diff options
author | Sebastian Rasmussen <sebras@gmail.com> | 2016-10-29 15:53:58 +0800 |
---|---|---|
committer | Sebastian Rasmussen <sebras@gmail.com> | 2016-12-14 20:36:25 +0100 |
commit | d53ab7a97c018aaa0e0adcaabcebcc72c080f724 (patch) | |
tree | e0627cf3dcfb6c286bfadf9dedc40547875083e6 | |
parent | 5ad76a1961559904bbb9312d92dd15c3ed0c67b5 (diff) | |
download | mupdf-d53ab7a97c018aaa0e0adcaabcebcc72c080f724.tar.xz |
Let pixmap colorspace conversion create new pixmap.
This moves dropping the converted pixmap into fz_convert_pixmap(),
which relieves every caller from doing so. Moreover resolution,
position and interpolation are kept.
-rw-r--r-- | include/mupdf/fitz/pixmap.h | 14 | ||||
-rw-r--r-- | source/fitz/colorspace.c | 13 | ||||
-rw-r--r-- | source/fitz/draw-device.c | 74 | ||||
-rw-r--r-- | source/fitz/load-jpx.c | 22 | ||||
-rw-r--r-- | source/fitz/load-jxr.c | 14 | ||||
-rw-r--r-- | source/fitz/load-pnm.c | 14 | ||||
-rw-r--r-- | source/fitz/load-tiff.c | 14 | ||||
-rw-r--r-- | source/fitz/output-png.c | 3 | ||||
-rw-r--r-- | source/fitz/pixmap.c | 30 | ||||
-rw-r--r-- | source/pdf/pdf-image.c | 12 | ||||
-rw-r--r-- | source/tools/pdfextract.c | 4 |
11 files changed, 75 insertions, 139 deletions
diff --git a/include/mupdf/fitz/pixmap.h b/include/mupdf/fitz/pixmap.h index 90b876b6..b2a47407 100644 --- a/include/mupdf/fitz/pixmap.h +++ b/include/mupdf/fitz/pixmap.h @@ -262,14 +262,18 @@ void fz_gamma_pixmap(fz_context *ctx, fz_pixmap *pix, float gamma); void fz_unmultiply_pixmap(fz_context *ctx, fz_pixmap *pix); /* - fz_convert_pixmap: Convert from one pixmap to another (assumed to be - the same size, but possibly with a different colorspace). + fz_convert_pixmap: Convert an existing pixmap to a desired + colorspace. Other properties of the pixmap, such as resolution + and position are are copied to the converted pixmap. - dst: the source pixmap. + pix: The pixmap to convert. - src: the destination pixmap. + cs: Desired colorspace, may be NULL to denote alpha-only. + + keep_alpha: If 0 any alpha component is removed, otherwise + alpha is kept if present in the pixmap. */ -void fz_convert_pixmap(fz_context *ctx, fz_pixmap *dst, fz_pixmap *src); +fz_pixmap *fz_convert_pixmap(fz_context *ctx, fz_pixmap *pix, fz_colorspace *src, int keep_alpha); /* Pixmaps represent a set of pixels for a 2 dimensional region of a diff --git a/source/fitz/colorspace.c b/source/fitz/colorspace.c index 2a356020..1a32258b 100644 --- a/source/fitz/colorspace.c +++ b/source/fitz/colorspace.c @@ -1769,19 +1769,6 @@ fz_pixmap_converter *fz_lookup_pixmap_converter(fz_context *ctx, fz_colorspace * else return fz_std_conv_pixmap; } -void -fz_convert_pixmap(fz_context *ctx, fz_pixmap *dp, fz_pixmap *sp) -{ - fz_colorspace *ss = sp->colorspace; - fz_colorspace *ds = dp->colorspace; - fz_pixmap_converter *converter; - - dp->interpolate = sp->interpolate; - - converter = fz_lookup_pixmap_converter(ctx, ds, ss); - converter(ctx, dp, sp); -} - /* Convert a single color */ static void diff --git a/source/fitz/draw-device.c b/source/fitz/draw-device.c index 28e64839..c15a5296 100644 --- a/source/fitz/draw-device.c +++ b/source/fitz/draw-device.c @@ -1235,10 +1235,7 @@ fz_draw_fill_image(fz_context *ctx, fz_device *devp, fz_image *image, const fz_m { fz_draw_device *dev = (fz_draw_device*)devp; fz_matrix local_ctm = concat(in_ctm, &dev->transform); - fz_pixmap *converted = NULL; - fz_pixmap *scaled = NULL; fz_pixmap *pixmap; - fz_pixmap *orig_pixmap; int after; int dx, dy; fz_draw_state *state = &dev->stack[dev->top]; @@ -1249,8 +1246,6 @@ fz_draw_fill_image(fz_context *ctx, fz_device *devp, fz_image *image, const fz_m fz_intersect_irect(fz_pixmap_bbox(ctx, state->dest, &clip), &state->scissor); - fz_var(scaled); - if (image->w == 0 || image->h == 0) return; @@ -1290,12 +1285,13 @@ fz_draw_fill_image(fz_context *ctx, fz_device *devp, fz_image *image, const fz_m } pixmap = fz_get_pixmap_from_image(ctx, image, &src_area, &local_ctm, &dx, &dy); - orig_pixmap = pixmap; /* convert images with more components (cmyk->rgb) before scaling */ /* convert images with fewer components (gray->rgb) after scaling */ /* convert images with expensive colorspace transforms after scaling */ + fz_var(pixmap); + fz_try(ctx) { if (state->blendmode & FZ_BLEND_KNOCKOUT) @@ -1307,17 +1303,15 @@ fz_draw_fill_image(fz_context *ctx, fz_device *devp, fz_image *image, const fz_m if (pixmap->colorspace != model && !after) { - fz_irect bbox; - fz_pixmap_bbox(ctx, pixmap, &bbox); - converted = fz_new_pixmap_with_bbox(ctx, model, &bbox, (model ? pixmap->alpha : 1)); - fz_convert_pixmap(ctx, converted, pixmap); + fz_pixmap *converted = fz_convert_pixmap(ctx, pixmap, model, 1); + fz_drop_pixmap(ctx, pixmap); pixmap = converted; } if (!(devp->hints & FZ_DONT_INTERPOLATE_IMAGES) && ctx->tuning->image_scale(ctx->tuning->image_scale_arg, dx, dy, pixmap->w, pixmap->h)) { int gridfit = alpha == 1.0f && !(dev->flags & FZ_DRAWDEV_FLAGS_TYPE3); - scaled = fz_transform_pixmap(ctx, dev, pixmap, &local_ctm, state->dest->x, state->dest->y, dx, dy, gridfit, &clip); + fz_pixmap *scaled = fz_transform_pixmap(ctx, dev, pixmap, &local_ctm, state->dest->x, state->dest->y, dx, dy, gridfit, &clip); if (!scaled) { if (dx < 1) @@ -1327,7 +1321,10 @@ fz_draw_fill_image(fz_context *ctx, fz_device *devp, fz_image *image, const fz_m scaled = fz_scale_pixmap_cached(ctx, pixmap, pixmap->x, pixmap->y, dx, dy, NULL, dev->cache_x, dev->cache_y); } if (scaled) + { + fz_drop_pixmap(ctx, pixmap); pixmap = scaled; + } } if (pixmap->colorspace != model) @@ -1341,10 +1338,8 @@ fz_draw_fill_image(fz_context *ctx, fz_device *devp, fz_image *image, const fz_m else #endif { - fz_irect bbox; - fz_pixmap_bbox(ctx, pixmap, &bbox); - converted = fz_new_pixmap_with_bbox(ctx, model, &bbox, pixmap->alpha); - fz_convert_pixmap(ctx, converted, pixmap); + fz_pixmap *converted = fz_convert_pixmap(ctx, pixmap, model, 1); + fz_drop_pixmap(ctx, pixmap); pixmap = converted; } } @@ -1355,15 +1350,9 @@ fz_draw_fill_image(fz_context *ctx, fz_device *devp, fz_image *image, const fz_m fz_knockout_end(ctx, dev); } fz_always(ctx) - { - fz_drop_pixmap(ctx, scaled); - fz_drop_pixmap(ctx, converted); - fz_drop_pixmap(ctx, orig_pixmap); - } + fz_drop_pixmap(ctx, pixmap); fz_catch(ctx) - { fz_rethrow(ctx); - } } static void @@ -1376,7 +1365,6 @@ fz_draw_fill_image_mask(fz_context *ctx, fz_device *devp, fz_image *image, const float colorfv[FZ_MAX_COLORS]; fz_pixmap *scaled = NULL; fz_pixmap *pixmap; - fz_pixmap *orig_pixmap; int dx, dy; int i, n; fz_draw_state *state = &dev->stack[dev->top]; @@ -1430,7 +1418,8 @@ fz_draw_fill_image_mask(fz_context *ctx, fz_device *devp, fz_image *image, const } pixmap = fz_get_pixmap_from_image(ctx, image, &src_area, &local_ctm, &dx, &dy); - orig_pixmap = pixmap; + + fz_var(pixmap); fz_try(ctx) { @@ -1450,7 +1439,10 @@ fz_draw_fill_image_mask(fz_context *ctx, fz_device *devp, fz_image *image, const scaled = fz_scale_pixmap_cached(ctx, pixmap, pixmap->x, pixmap->y, dx, dy, NULL, dev->cache_x, dev->cache_y); } if (scaled) + { + fz_drop_pixmap(ctx, pixmap); pixmap = scaled; + } } n = fz_colorspace_n(ctx, model); @@ -1471,14 +1463,9 @@ fz_draw_fill_image_mask(fz_context *ctx, fz_device *devp, fz_image *image, const fz_knockout_end(ctx, dev); } fz_always(ctx) - { - fz_drop_pixmap(ctx, scaled); - fz_drop_pixmap(ctx, orig_pixmap); - } + fz_drop_pixmap(ctx, pixmap); fz_catch(ctx) - { fz_rethrow(ctx); - } } static void @@ -1492,7 +1479,6 @@ fz_draw_clip_image_mask(fz_context *ctx, fz_device *devp, fz_image *image, const fz_pixmap *shape = NULL; fz_pixmap *scaled = NULL; fz_pixmap *pixmap = NULL; - fz_pixmap *orig_pixmap = NULL; int dx, dy; fz_draw_state *state = push_stack(ctx, dev); fz_colorspace *model = state->dest->colorspace; @@ -1503,12 +1489,6 @@ fz_draw_clip_image_mask(fz_context *ctx, fz_device *devp, fz_image *image, const fz_pixmap_bbox(ctx, state->dest, &clip); fz_intersect_irect(&clip, &state->scissor); - fz_var(mask); - fz_var(dest); - fz_var(shape); - fz_var(pixmap); - fz_var(orig_pixmap); - if (image->w == 0 || image->h == 0) { #ifdef DUMP_GROUP_BLENDS @@ -1534,11 +1514,15 @@ fz_draw_clip_image_mask(fz_context *ctx, fz_device *devp, fz_image *image, const fz_intersect_irect(&bbox, fz_irect_from_rect(&bbox2, &tscissor)); } + pixmap = fz_get_pixmap_from_image(ctx, image, NULL, &local_ctm, &dx, &dy); + + fz_var(mask); + fz_var(dest); + fz_var(shape); + fz_var(pixmap); + fz_try(ctx) { - pixmap = fz_get_pixmap_from_image(ctx, image, NULL, &local_ctm, &dx, &dy); - orig_pixmap = pixmap; - state[1].mask = mask = fz_new_pixmap_with_bbox(ctx, NULL, &bbox, 1); fz_clear_pixmap(ctx, mask); @@ -1573,7 +1557,10 @@ fz_draw_clip_image_mask(fz_context *ctx, fz_device *devp, fz_image *image, const scaled = fz_scale_pixmap_cached(ctx, pixmap, pixmap->x, pixmap->y, dx, dy, NULL, dev->cache_x, dev->cache_y); } if (scaled) + { + fz_drop_pixmap(ctx, pixmap); pixmap = scaled; + } } #ifdef DUMP_GROUP_BLENDS dump_spaces(dev->top, ""); @@ -1592,14 +1579,9 @@ fz_draw_clip_image_mask(fz_context *ctx, fz_device *devp, fz_image *image, const #endif } fz_always(ctx) - { - fz_drop_pixmap(ctx, scaled); - fz_drop_pixmap(ctx, orig_pixmap); - } + fz_drop_pixmap(ctx, pixmap); fz_catch(ctx) - { emergency_pop_stack(ctx, dev, state); - } } static void diff --git a/source/fitz/load-jpx.c b/source/fitz/load-jpx.c index b94a6392..2469fbc7 100644 --- a/source/fitz/load-jpx.c +++ b/source/fitz/load-jpx.c @@ -427,16 +427,7 @@ jpx_read_image(fz_context *ctx, fz_jpxd *state, unsigned char *data, size_t size /* CMYK is a subtractive colorspace, we want additive for premul alpha */ if (state->pix->n == 5) { - fz_pixmap *rgb = fz_new_pixmap(ctx, fz_device_rgb(ctx), state->pix->w, state->pix->h, 1); - - fz_try(ctx) - fz_convert_pixmap(ctx, rgb, state->pix); - fz_catch(ctx) - { - fz_drop_pixmap(ctx, rgb); - fz_rethrow(ctx); - } - + fz_pixmap *rgb = fz_convert_pixmap(ctx, state->pix, fz_device_rgb(ctx), 1); fz_drop_pixmap(ctx, state->pix); state->pix = rgb; } @@ -922,16 +913,7 @@ jpx_read_image(fz_context *ctx, unsigned char *data, size_t size, fz_colorspace /* CMYK is a subtractive colorspace, we want additive for premul alpha */ if (n == 4) { - fz_pixmap *rgb = fz_new_pixmap(ctx, fz_device_rgb(ctx), w, h, 1); - - fz_try(ctx) - fz_convert_pixmap(ctx, rgb, img); - fz_catch(ctx) - { - fz_drop_pixmap(ctx, rgb); - fz_rethrow(ctx); - } - + fz_pixmap *rgb = fz_convert_pixmap(ctx, img, fz_device_rgb(ctx), 1); fz_drop_pixmap(ctx, img); img = rgb; } diff --git a/source/fitz/load-jxr.c b/source/fitz/load-jxr.c index e61d6e7a..8bff2833 100644 --- a/source/fitz/load-jxr.c +++ b/source/fitz/load-jxr.c @@ -413,19 +413,7 @@ fz_load_jxr(fz_context *ctx, unsigned char *data, size_t size) /* CMYK is a subtractive colorspace, we want additive for premul alpha */ if (info.comps >= 4) { - fz_pixmap *rgb = fz_new_pixmap(ctx, fz_device_rgb(ctx), image->w, image->h, 1); - - rgb->xres = image->xres; - rgb->yres = image->yres; - - fz_try(ctx) - fz_convert_pixmap(ctx, rgb, image); - fz_catch(ctx) - { - fz_drop_pixmap(ctx, rgb); - fz_rethrow(ctx); - } - + fz_pixmap *rgb = fz_convert_pixmap(ctx, image, fz_device_rgb(ctx), 1); fz_drop_pixmap(ctx, image); image = rgb; } diff --git a/source/fitz/load-pnm.c b/source/fitz/load-pnm.c index f724eb09..2874689a 100644 --- a/source/fitz/load-pnm.c +++ b/source/fitz/load-pnm.c @@ -567,19 +567,7 @@ pam_binary_read_image(fz_context *ctx, struct info *pnm, unsigned char *p, unsig /* CMYK is a subtractive colorspace, we want additive for premul alpha */ if (img->n > 4) { - fz_pixmap *rgb = fz_new_pixmap(ctx, fz_device_rgb(ctx), img->w, img->h, 1); - - rgb->xres = img->xres; - rgb->yres = img->yres; - - fz_try(ctx) - fz_convert_pixmap(ctx, rgb, img); - fz_catch(ctx) - { - fz_drop_pixmap(ctx, rgb); - fz_rethrow(ctx); - } - + fz_pixmap *rgb = fz_convert_pixmap(ctx, img, fz_device_rgb(ctx), 1); fz_drop_pixmap(ctx, img); img = rgb; } diff --git a/source/fitz/load-tiff.c b/source/fitz/load-tiff.c index 117b9816..7262b23e 100644 --- a/source/fitz/load-tiff.c +++ b/source/fitz/load-tiff.c @@ -1286,19 +1286,7 @@ fz_load_tiff_subimage(fz_context *ctx, unsigned char *buf, size_t len, int subim /* CMYK is a subtractive colorspace, we want additive for premul alpha */ if (image->n == 5) { - fz_pixmap *rgb = fz_new_pixmap(ctx, fz_device_rgb(ctx), image->w, image->h, 1); - - rgb->xres = image->xres; - rgb->yres = image->yres; - - fz_try(ctx) - fz_convert_pixmap(ctx, rgb, image); - fz_catch(ctx) - { - fz_drop_pixmap(ctx, rgb); - fz_rethrow(ctx); - } - + fz_pixmap *rgb = fz_convert_pixmap(ctx, image, fz_device_rgb(ctx), 1); fz_drop_pixmap(ctx, image); image = rgb; } diff --git a/source/fitz/output-png.c b/source/fitz/output-png.c index 12eec89f..24e9394f 100644 --- a/source/fitz/output-png.c +++ b/source/fitz/output-png.c @@ -260,8 +260,7 @@ png_from_pixmap(fz_context *ctx, fz_pixmap *pix, int drop) { if (pix->colorspace && pix->colorspace != fz_device_gray(ctx) && pix->colorspace != fz_device_rgb(ctx)) { - pix2 = fz_new_pixmap(ctx, fz_device_rgb(ctx), pix->w, pix->h, pix->alpha); - fz_convert_pixmap(ctx, pix2, pix); + pix2 = fz_convert_pixmap(ctx, pix, fz_device_rgb(ctx), 1); if (drop) fz_drop_pixmap(ctx, pix); pix = pix2; diff --git a/source/fitz/pixmap.c b/source/fitz/pixmap.c index 9131a7a1..1d080576 100644 --- a/source/fitz/pixmap.c +++ b/source/fitz/pixmap.c @@ -860,6 +860,36 @@ fz_pixmap_size(fz_context *ctx, fz_pixmap * pix) } fz_pixmap * +fz_convert_pixmap(fz_context *ctx, fz_pixmap *pix, fz_colorspace *ds, int keep_alpha) +{ + fz_pixmap *cvt; + + if (!ds && !keep_alpha) + fz_throw(ctx, FZ_ERROR_GENERIC, "cannot both throw away and keep alpha"); + + cvt = fz_new_pixmap(ctx, ds, pix->w, pix->h, keep_alpha && pix->alpha); + + cvt->xres = pix->xres; + cvt->yres = pix->yres; + cvt->x = pix->x; + cvt->y = pix->y; + cvt->interpolate = pix->interpolate; + + fz_try(ctx) + { + fz_pixmap_converter *pc = fz_lookup_pixmap_converter(ctx, ds, pix->colorspace); + pc(ctx, cvt, pix); + } + fz_catch(ctx) + { + fz_drop_pixmap(ctx, cvt); + fz_rethrow(ctx); + } + + return cvt; +} + +fz_pixmap * fz_new_pixmap_from_8bpp_data(fz_context *ctx, int x, int y, int w, int h, unsigned char *sp, int span) { fz_pixmap *pixmap = fz_new_pixmap(ctx, NULL, w, h, 1); diff --git a/source/pdf/pdf-image.c b/source/pdf/pdf-image.c index 141ee171..11ab856f 100644 --- a/source/pdf/pdf-image.c +++ b/source/pdf/pdf-image.c @@ -43,19 +43,9 @@ pdf_load_image_imp(fz_context *ctx, pdf_document *doc, pdf_obj *rdb, pdf_obj *di if (tile->n != 1) { fz_pixmap *gray; - fz_irect bbox; if (tile->n != 2) fz_warn(ctx, "soft mask should be grayscale"); - gray = fz_new_pixmap_with_bbox(ctx, fz_device_gray(ctx), fz_pixmap_bbox(ctx, tile, &bbox), 0); - - fz_try(ctx) - fz_convert_pixmap(ctx, gray, tile); - fz_catch(ctx) - { - fz_drop_pixmap(ctx, gray); - fz_rethrow(ctx); - } - + gray = fz_convert_pixmap(ctx, tile, fz_device_gray(ctx), 0); fz_drop_pixmap(ctx, tile); tile = gray; } diff --git a/source/tools/pdfextract.c b/source/tools/pdfextract.c index e8e03965..ff26229d 100644 --- a/source/tools/pdfextract.c +++ b/source/tools/pdfextract.c @@ -38,9 +38,7 @@ static void writepixmap(fz_context *ctx, fz_pixmap *pix, char *file, int dorgb) if (dorgb && pix->colorspace && pix->colorspace != fz_device_rgb(ctx)) { - fz_irect bbox; - rgb = fz_new_pixmap_with_bbox(ctx, fz_device_rgb(ctx), fz_pixmap_bbox(ctx, pix, &bbox), pix->alpha); - fz_convert_pixmap(ctx, rgb, pix); + rgb = fz_convert_pixmap(ctx, pix, fz_device_rgb(ctx), 1); pix = rgb; } |