From 9b714248bc871502d9e80dfcd72404e69fcc234c Mon Sep 17 00:00:00 2001 From: Robin Watts Date: Thu, 13 Jul 2017 18:11:38 +0100 Subject: Fix fz_copy_pixmap_rect to work properly in all cases. --- source/fitz/colorspace.c | 36 ++++++++++---------- source/fitz/draw-device.c | 18 +++++----- source/fitz/pixmap.c | 87 +++++++---------------------------------------- 3 files changed, 39 insertions(+), 102 deletions(-) (limited to 'source/fitz') diff --git a/source/fitz/colorspace.c b/source/fitz/colorspace.c index 6f010a13..92367ff8 100644 --- a/source/fitz/colorspace.c +++ b/source/fitz/colorspace.c @@ -825,7 +825,7 @@ fz_default_color_params(fz_context *ctx) /* Fast pixmap color conversions */ -static void fast_gray_to_rgb(fz_context *ctx, fz_pixmap *dst, fz_pixmap *src, fz_colorspace *prf, fz_default_colorspaces *default_cs, const fz_color_params *color_params) +static void fast_gray_to_rgb(fz_context *ctx, fz_pixmap *dst, fz_pixmap *src, fz_colorspace *prf, const fz_default_colorspaces *default_cs, const fz_color_params *color_params) { unsigned char *s = src->samples; unsigned char *d = dst->samples; @@ -903,7 +903,7 @@ static void fast_gray_to_rgb(fz_context *ctx, fz_pixmap *dst, fz_pixmap *src, fz } } -static void fast_gray_to_cmyk(fz_context *ctx, fz_pixmap *dst, fz_pixmap *src, fz_colorspace *prf, fz_default_colorspaces *default_cs, const fz_color_params *color_params) +static void fast_gray_to_cmyk(fz_context *ctx, fz_pixmap *dst, fz_pixmap *src, fz_colorspace *prf, const fz_default_colorspaces *default_cs, const fz_color_params *color_params) { unsigned char *s = src->samples; unsigned char *d = dst->samples; @@ -984,7 +984,7 @@ static void fast_gray_to_cmyk(fz_context *ctx, fz_pixmap *dst, fz_pixmap *src, f } } -static void fast_rgb_to_gray(fz_context *ctx, fz_pixmap *dst, fz_pixmap *src, fz_colorspace *prf, fz_default_colorspaces *default_cs, const fz_color_params *color_params) +static void fast_rgb_to_gray(fz_context *ctx, fz_pixmap *dst, fz_pixmap *src, fz_colorspace *prf, const fz_default_colorspaces *default_cs, const fz_color_params *color_params) { unsigned char *s = src->samples; unsigned char *d = dst->samples; @@ -1056,7 +1056,7 @@ static void fast_rgb_to_gray(fz_context *ctx, fz_pixmap *dst, fz_pixmap *src, fz } } -static void fast_bgr_to_gray(fz_context *ctx, fz_pixmap *dst, fz_pixmap *src, fz_colorspace *prf, fz_default_colorspaces *default_cs, const fz_color_params *color_params) +static void fast_bgr_to_gray(fz_context *ctx, fz_pixmap *dst, fz_pixmap *src, fz_colorspace *prf, const fz_default_colorspaces *default_cs, const fz_color_params *color_params) { unsigned char *s = src->samples; unsigned char *d = dst->samples; @@ -1128,7 +1128,7 @@ static void fast_bgr_to_gray(fz_context *ctx, fz_pixmap *dst, fz_pixmap *src, fz } } -static void fast_rgb_to_cmyk(fz_context *ctx, fz_pixmap *dst, fz_pixmap *src, fz_colorspace *prf, fz_default_colorspaces *default_cs, const fz_color_params *color_params) +static void fast_rgb_to_cmyk(fz_context *ctx, fz_pixmap *dst, fz_pixmap *src, fz_colorspace *prf, const fz_default_colorspaces *default_cs, const fz_color_params *color_params) { unsigned char *s = src->samples; unsigned char *d = dst->samples; @@ -1221,7 +1221,7 @@ static void fast_rgb_to_cmyk(fz_context *ctx, fz_pixmap *dst, fz_pixmap *src, fz } } -static void fast_bgr_to_cmyk(fz_context *ctx, fz_pixmap *dst, fz_pixmap *src, fz_colorspace *prf, fz_default_colorspaces *default_cs, const fz_color_params *color_params) +static void fast_bgr_to_cmyk(fz_context *ctx, fz_pixmap *dst, fz_pixmap *src, fz_colorspace *prf, const fz_default_colorspaces *default_cs, const fz_color_params *color_params) { unsigned char *s = src->samples; unsigned char *d = dst->samples; @@ -1314,7 +1314,7 @@ static void fast_bgr_to_cmyk(fz_context *ctx, fz_pixmap *dst, fz_pixmap *src, fz } } -static void fast_cmyk_to_gray(fz_context *ctx, fz_pixmap *dst, fz_pixmap *src, fz_colorspace *prf, fz_default_colorspaces *default_cs, const fz_color_params *color_params) +static void fast_cmyk_to_gray(fz_context *ctx, fz_pixmap *dst, fz_pixmap *src, fz_colorspace *prf, const fz_default_colorspaces *default_cs, const fz_color_params *color_params) { unsigned char *s = src->samples; unsigned char *d = dst->samples; @@ -1721,7 +1721,7 @@ static inline void cached_cmyk_conv(unsigned char *restrict const pr, unsigned c #endif } -static void fast_cmyk_to_rgb(fz_context *ctx, fz_pixmap *dst, fz_pixmap *src, fz_colorspace *prf, fz_default_colorspaces *default_cs, const fz_color_params *color_params) +static void fast_cmyk_to_rgb(fz_context *ctx, fz_pixmap *dst, fz_pixmap *src, fz_colorspace *prf, const fz_default_colorspaces *default_cs, const fz_color_params *color_params) { unsigned char *s = src->samples; unsigned char *d = dst->samples; @@ -1820,7 +1820,7 @@ static void fast_cmyk_to_rgb(fz_context *ctx, fz_pixmap *dst, fz_pixmap *src, fz } } -static void fast_cmyk_to_bgr(fz_context *ctx, fz_pixmap *dst, fz_pixmap *src, fz_colorspace *prf, fz_default_colorspaces *default_cs, const fz_color_params *color_params) +static void fast_cmyk_to_bgr(fz_context *ctx, fz_pixmap *dst, fz_pixmap *src, fz_colorspace *prf, const fz_default_colorspaces *default_cs, const fz_color_params *color_params) { unsigned char *s = src->samples; unsigned char *d = dst->samples; @@ -1912,7 +1912,7 @@ static void fast_cmyk_to_bgr(fz_context *ctx, fz_pixmap *dst, fz_pixmap *src, fz } } -static void fast_rgb_to_bgr(fz_context *ctx, fz_pixmap *dst, fz_pixmap *src, fz_colorspace *prf, fz_default_colorspaces *default_cs, const fz_color_params *color_params) +static void fast_rgb_to_bgr(fz_context *ctx, fz_pixmap *dst, fz_pixmap *src, fz_colorspace *prf, const fz_default_colorspaces *default_cs, const fz_color_params *color_params) { unsigned char *s = src->samples; unsigned char *d = dst->samples; @@ -1986,7 +1986,7 @@ static void fast_rgb_to_bgr(fz_context *ctx, fz_pixmap *dst, fz_pixmap *src, fz_ } static void -icc_conv_pixmap(fz_context *ctx, fz_pixmap *dst, fz_pixmap *src, fz_colorspace *prf, fz_default_colorspaces *default_cs, const fz_color_params *color_params) +icc_conv_pixmap(fz_context *ctx, fz_pixmap *dst, fz_pixmap *src, fz_colorspace *prf, const fz_default_colorspaces *default_cs, const fz_color_params *color_params) { fz_colorspace *srcs = src->colorspace; fz_colorspace *dsts = dst->colorspace; @@ -2074,7 +2074,7 @@ convert_to_icc_base(fz_context *ctx, fz_colorspace *srcs, float *src_f, float *d * be handled. Realize those can map from index->devn->pdf-cal->icc for * example. */ static void -icc_base_conv_pixmap(fz_context *ctx, fz_pixmap *dst, fz_pixmap *src, fz_colorspace *prf, fz_default_colorspaces *default_cs, const fz_color_params *color_params) +icc_base_conv_pixmap(fz_context *ctx, fz_pixmap *dst, fz_pixmap *src, fz_colorspace *prf, const fz_default_colorspaces *default_cs, const fz_color_params *color_params) { fz_colorspace *srcs = src->colorspace; fz_colorspace *base_cs = get_base_icc_space(ctx, srcs); @@ -2127,7 +2127,7 @@ icc_base_conv_pixmap(fz_context *ctx, fz_pixmap *dst, fz_pixmap *src, fz_colorsp } static void -std_conv_pixmap(fz_context *ctx, fz_pixmap *dst, fz_pixmap *src, fz_colorspace *prf, fz_default_colorspaces *default_cs, const fz_color_params *color_params) +std_conv_pixmap(fz_context *ctx, fz_pixmap *dst, fz_pixmap *src, fz_colorspace *prf, const fz_default_colorspaces *default_cs, const fz_color_params *color_params) { float srcv[FZ_MAX_COLORS]; float dstv[FZ_MAX_COLORS]; @@ -2328,7 +2328,7 @@ std_conv_pixmap(fz_context *ctx, fz_pixmap *dst, fz_pixmap *src, fz_colorspace * } } -static void fast_any_to_alpha(fz_context *ctx, fz_pixmap *dst, fz_pixmap *src, fz_colorspace *prf, fz_default_colorspaces *default_cs, const fz_color_params *color_params) +static void fast_any_to_alpha(fz_context *ctx, fz_pixmap *dst, fz_pixmap *src, fz_colorspace *prf, const fz_default_colorspaces *default_cs, const fz_color_params *color_params) { if (!src->alpha) fz_clear_pixmap_with_value(ctx, dst, 255); @@ -3152,7 +3152,7 @@ fz_set_default_output_intent(fz_context *ctx, fz_default_colorspaces *default_cs } fz_colorspace * -fz_default_gray(fz_context *ctx, fz_default_colorspaces *default_cs) +fz_default_gray(fz_context *ctx, const fz_default_colorspaces *default_cs) { if (default_cs) return default_cs->gray; @@ -3161,7 +3161,7 @@ fz_default_gray(fz_context *ctx, fz_default_colorspaces *default_cs) } fz_colorspace * -fz_default_rgb(fz_context *ctx, fz_default_colorspaces *default_cs) +fz_default_rgb(fz_context *ctx, const fz_default_colorspaces *default_cs) { if (default_cs) return default_cs->rgb; @@ -3170,7 +3170,7 @@ fz_default_rgb(fz_context *ctx, fz_default_colorspaces *default_cs) } fz_colorspace * -fz_default_cmyk(fz_context *ctx, fz_default_colorspaces *default_cs) +fz_default_cmyk(fz_context *ctx, const fz_default_colorspaces *default_cs) { if (default_cs) return default_cs->cmyk; @@ -3179,7 +3179,7 @@ fz_default_cmyk(fz_context *ctx, fz_default_colorspaces *default_cs) } fz_colorspace * -fz_default_output_intent(fz_context *ctx, fz_default_colorspaces *default_cs) +fz_default_output_intent(fz_context *ctx, const fz_default_colorspaces *default_cs) { if (default_cs) return default_cs->oi; diff --git a/source/fitz/draw-device.c b/source/fitz/draw-device.c index 908350e7..5a1b1ea2 100644 --- a/source/fitz/draw-device.c +++ b/source/fitz/draw-device.c @@ -233,7 +233,7 @@ fz_knockout_begin(fz_context *ctx, fz_draw_device *dev) break; } if (prev) - fz_copy_pixmap_rect(ctx, dest, prev, &bbox); + fz_copy_pixmap_rect(ctx, dest, prev, &bbox, dev->default_cs); else fz_clear_pixmap(ctx, dest); } @@ -509,7 +509,7 @@ fz_draw_clip_path(fz_context *ctx, fz_device *devp, const fz_path *path, int eve state[1].mask = fz_new_pixmap_with_bbox(ctx, NULL, &bbox, 1); fz_clear_pixmap(ctx, state[1].mask); state[1].dest = fz_new_pixmap_with_bbox(ctx, model, &bbox, state[0].dest->alpha); - fz_copy_pixmap_rect(ctx, state[1].dest, state[0].dest, &bbox); + fz_copy_pixmap_rect(ctx, state[1].dest, state[0].dest, &bbox, dev->default_cs); if (state[1].shape) { state[1].shape = fz_new_pixmap_with_bbox(ctx, NULL, &bbox, 1); @@ -588,7 +588,7 @@ fz_draw_clip_stroke_path(fz_context *ctx, fz_device *devp, const fz_path *path, if (state[0].dest->alpha) fz_clear_pixmap(ctx, state[1].dest); else - fz_copy_pixmap_rect(ctx, state[1].dest, state[0].dest, &bbox); + fz_copy_pixmap_rect(ctx, state[1].dest, state[0].dest, &bbox, dev->default_cs); if (state->shape) { state[1].shape = fz_new_pixmap_with_bbox(ctx, NULL, &bbox, 1); @@ -908,7 +908,7 @@ fz_draw_clip_text(fz_context *ctx, fz_device *devp, const fz_text *text, const f if (state[0].dest->alpha) fz_clear_pixmap(ctx, dest); else - fz_copy_pixmap_rect(ctx, dest, state[0].dest, &bbox); + fz_copy_pixmap_rect(ctx, dest, state[0].dest, &bbox, dev->default_cs); if (state->shape) { shape = fz_new_pixmap_with_bbox(ctx, NULL, &bbox, 1); @@ -1034,7 +1034,7 @@ fz_draw_clip_stroke_text(fz_context *ctx, fz_device *devp, const fz_text *text, if (state[0].dest->alpha) fz_clear_pixmap(ctx, state[1].dest); else - fz_copy_pixmap_rect(ctx, state[1].dest, state[0].dest, &bbox); + fz_copy_pixmap_rect(ctx, state[1].dest, state[0].dest, &bbox, dev->default_cs); if (state->shape) { state[1].shape = shape = fz_new_pixmap_with_bbox(ctx, NULL, &bbox, 1); @@ -1158,7 +1158,7 @@ fz_draw_fill_shade(fz_context *ctx, fz_device *devp, fz_shade *shade, const fz_m if (state->dest->alpha) fz_clear_pixmap(ctx, dest); else - fz_copy_pixmap_rect(ctx, dest, state[0].dest, &bbox); + fz_copy_pixmap_rect(ctx, dest, state[0].dest, &bbox, dev->default_cs); if (shape) { shape = fz_new_pixmap_with_bbox(ctx, NULL, &bbox, 1); @@ -1609,7 +1609,7 @@ fz_draw_clip_image_mask(fz_context *ctx, fz_device *devp, fz_image *image, const if (state[0].dest->alpha) fz_clear_pixmap(ctx, state[1].dest); else - fz_copy_pixmap_rect(ctx, state[1].dest, state[0].dest, &bbox); + fz_copy_pixmap_rect(ctx, state[1].dest, state[0].dest, &bbox, dev->default_cs); if (state->shape) { state[1].shape = shape = fz_new_pixmap_with_bbox(ctx, NULL, &bbox, 1); @@ -1833,7 +1833,7 @@ fz_draw_end_mask(fz_context *ctx, fz_device *devp) /* create new dest scratch buffer */ fz_pixmap_bbox(ctx, temp, &bbox); dest = fz_new_pixmap_with_bbox(ctx, state->dest->colorspace, &bbox, state->dest->alpha); - fz_copy_pixmap_rect(ctx, dest, state->dest, &bbox); + fz_copy_pixmap_rect(ctx, dest, state->dest, &bbox, dev->default_cs); /* push soft mask as clip mask */ state[1].dest = dest; @@ -1889,7 +1889,7 @@ fz_draw_begin_group(fz_context *ctx, fz_device *devp, const fz_rect *rect, fz_co } else { - fz_copy_pixmap_rect(ctx, dest, state[0].dest, &bbox); + fz_copy_pixmap_rect(ctx, dest, state[0].dest, &bbox, dev->default_cs); } if (blendmode == 0 && alpha == 1.0f && isolated) diff --git a/source/fitz/pixmap.c b/source/fitz/pixmap.c index 296a4dee..b568c842 100644 --- a/source/fitz/pixmap.c +++ b/source/fitz/pixmap.c @@ -492,11 +492,11 @@ fz_clear_pixmap_with_value(fz_context *ctx, fz_pixmap *pix, int value) } void -fz_copy_pixmap_rect(fz_context *ctx, fz_pixmap *dest, fz_pixmap *src, const fz_irect *b) +fz_copy_pixmap_rect(fz_context *ctx, fz_pixmap *dest, fz_pixmap *src, const fz_irect *b, const fz_default_colorspaces *default_cs) { - const unsigned char *srcp; + unsigned char *srcp; unsigned char *destp; - int x, y, w, destspan, srcspan; + int y, w, destspan, srcspan; fz_irect local_b, bb; local_b = *b; @@ -523,81 +523,18 @@ fz_copy_pixmap_rect(fz_context *ctx, fz_pixmap *dest, fz_pixmap *src, const fz_i } while (--y); } - else if (src->n == 2 && dest->n == 4) - { - /* Copy, and convert from grey+alpha to rgb+alpha */ - srcspan -= w*2; - destspan -= w*4; - do - { - for (x = w; x > 0; x--) - { - unsigned char v = *srcp++; - unsigned char a = *srcp++; - *destp++ = v; - *destp++ = v; - *destp++ = v; - *destp++ = a; - } - srcp += srcspan; - destp += destspan; - } - while (--y); - } - else if (src->n == 1 + src->alpha && dest->n == 3 + dest->alpha) - { - assert("FIXME" == NULL); - } - else if (src->n == 4 && dest->n == 2) - { - /* Copy, and convert from rgb+alpha to grey+alpha */ - srcspan -= w*4; - destspan -= w*2; - do - { - for (x = w; x > 0; x--) - { - int v; - v = *srcp++; - v += *srcp++; - v += *srcp++; - *destp++ = (unsigned char)((v+1)/3); - *destp++ = *srcp++; - } - srcp += srcspan; - destp += destspan; - } - while (--y); - } - else if (src->n == 3 + src->alpha && dest->n == 1 + dest->alpha) - { - assert("FIXME" == NULL); - } else { - /* FIXME: Crap conversion */ - int z; - int sn = src->n-1; - int dn = dest->n-1; + fz_pixmap_converter *pc = fz_lookup_pixmap_converter(ctx, dest->colorspace, src->colorspace); + fz_pixmap fake_src = *src; - srcspan -= w*src->n; - destspan -= w*dest->n; - do - { - for (x = w; x > 0; x--) - { - int v = 0; - for (z = sn; z > 0; z--) - v += *srcp++; - v = (v * dn + (sn>>1)) / sn; - for (z = dn; z > 0; z--) - *destp++ = (unsigned char)v; - *destp++ = *srcp++; - } - srcp += srcspan; - destp += destspan; - } - while (--y); + fake_src.x = local_b.x0; + fake_src.y = local_b.y0; + fake_src.w = w; + fake_src.h = y; + fake_src.samples = srcp; + + pc(ctx, dest, &fake_src, NULL, default_cs, fz_default_color_params(ctx)); } } -- cgit v1.2.3