summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastian Rasmussen <sebras@gmail.com>2016-10-29 15:53:58 +0800
committerSebastian Rasmussen <sebras@gmail.com>2016-12-14 20:36:25 +0100
commitd53ab7a97c018aaa0e0adcaabcebcc72c080f724 (patch)
treee0627cf3dcfb6c286bfadf9dedc40547875083e6
parent5ad76a1961559904bbb9312d92dd15c3ed0c67b5 (diff)
downloadmupdf-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.h14
-rw-r--r--source/fitz/colorspace.c13
-rw-r--r--source/fitz/draw-device.c74
-rw-r--r--source/fitz/load-jpx.c22
-rw-r--r--source/fitz/load-jxr.c14
-rw-r--r--source/fitz/load-pnm.c14
-rw-r--r--source/fitz/load-tiff.c14
-rw-r--r--source/fitz/output-png.c3
-rw-r--r--source/fitz/pixmap.c30
-rw-r--r--source/pdf/pdf-image.c12
-rw-r--r--source/tools/pdfextract.c4
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;
}