diff options
author | Robin Watts <robin.watts@artifex.com> | 2017-10-16 13:44:52 +0100 |
---|---|---|
committer | Robin Watts <robin.watts@artifex.com> | 2017-10-24 15:16:36 +0100 |
commit | c413f4db6a54846ae85393a87fa1b53b93a966ee (patch) | |
tree | 3a06363e8f0570cc139e8cf486f2d9b00c0c52cd /source | |
parent | c7c407b57a6e1aa5b1a11034ec7cb308cf4ad3c4 (diff) | |
download | mupdf-c413f4db6a54846ae85393a87fa1b53b93a966ee.tar.xz |
Add support for use of proofing profile.
This is a first cut to get us to demo-ability. There will
likely be a few changes as we do a bit more testing with different
scenarios with Gray, RGB, CMYK combos of destination, proof and
output intent ICC profiles.
Diffstat (limited to 'source')
-rw-r--r-- | source/fitz/draw-device.c | 61 | ||||
-rw-r--r-- | source/fitz/separation.c | 13 | ||||
-rw-r--r-- | source/tools/mudraw.c | 26 |
3 files changed, 63 insertions, 37 deletions
diff --git a/source/fitz/draw-device.c b/source/fitz/draw-device.c index ff6097fb..64de42ae 100644 --- a/source/fitz/draw-device.c +++ b/source/fitz/draw-device.c @@ -46,6 +46,7 @@ struct fz_draw_device_s fz_matrix transform; fz_rasterizer *rast; fz_default_colorspaces *default_cs; + fz_colorspace *proof_cs; int flags; int resolve_spots; int top; @@ -114,21 +115,6 @@ static void stack_change(fz_context *ctx, fz_draw_device *dev, char *s) #define STACK_CONVERT(A) do {} while (0) #endif -/* Based upon the existence of a proof color space, and if we happen to be - * in a color space that is our target color space or a transparency group - * color space decide if we should be using the proof color space at this time */ -static fz_colorspace * -fz_proof_cs(fz_context *ctx, fz_draw_device *dev) -{ - fz_colorspace *prf = fz_default_output_intent(ctx, dev->default_cs); - fz_draw_state *state = &dev->stack[dev->top]; - fz_colorspace *model = state->dest->colorspace; - - if (prf == NULL || model == prf) - return NULL; - return prf; -} - /* Logic below assumes that default cs is set to color context cs if there * was not a default in the document for that particular cs */ @@ -510,9 +496,24 @@ static fz_draw_state * push_group_for_separations(fz_context *ctx, fz_draw_device *dev, const fz_color_params *color_params, fz_default_colorspaces *default_cs) { fz_separations *clone = fz_clone_separations_for_overprint(ctx, dev->stack[0].dest->seps); + fz_colorspace *oi = fz_default_output_intent(ctx, default_cs); + fz_colorspace *dcs = fz_device_cmyk(ctx); + + /* Pick sep target CMYK based upon proof and output intent settings. Priority + * is oi, proof, devicecmyk. */ + /* FIXME: Look into non-CMYK proofing profiles */ + if (dev->proof_cs && fz_colorspace_n(ctx, dev->proof_cs) == 4) + { + dcs = dev->proof_cs; + } + /* FIXME : We need to create a file with an RGB output intent at some point and test a few things */ + if (oi && fz_colorspace_n(ctx, oi) == 4) + { + dcs = oi; + } /* Not needed */ - if (clone == NULL) + if (clone == NULL && dev->proof_cs == NULL) { dev->resolve_spots = 0; return &dev->stack[0]; @@ -523,7 +524,7 @@ push_group_for_separations(fz_context *ctx, fz_draw_device *dev, const fz_color_ { dev->stack[1] = dev->stack[0]; dev->stack[1].dest = NULL; /* So we are safe to destroy */ - dev->stack[1].dest = fz_clone_pixmap_area_with_different_seps(ctx, dev->stack[0].dest, &dev->stack[0].scissor, fz_device_cmyk(ctx), clone, color_params, default_cs); + dev->stack[1].dest = fz_clone_pixmap_area_with_different_seps(ctx, dev->stack[0].dest, &dev->stack[0].scissor, dcs, clone, color_params, default_cs); dev->top++; } fz_always(ctx) @@ -1641,6 +1642,7 @@ fz_draw_fill_image(fz_context *ctx, fz_device *devp, fz_image *image, const fz_m if (dev->top == 0 && dev->resolve_spots) state = push_group_for_separations(ctx, dev, color_params, dev->default_cs); + model = state->dest->colorspace; model = state->dest->colorspace; @@ -2817,7 +2819,6 @@ static void fz_draw_close_device(fz_context *ctx, fz_device *devp) { fz_draw_device *dev = (fz_draw_device*)devp; - fz_colorspace *prf = fz_proof_cs(ctx, dev); /* pop and free the stacks */ if (dev->top > dev->resolve_spots) @@ -2839,7 +2840,7 @@ fz_draw_close_device(fz_context *ctx, fz_device *devp) if (dev->resolve_spots && dev->top) { fz_draw_state *state = &dev->stack[--dev->top]; - fz_copy_pixmap_area_converting_seps(ctx, state[0].dest, state[1].dest, fz_default_color_params(ctx)/* FIXME */, prf, dev->default_cs); + fz_copy_pixmap_area_converting_seps(ctx, state[0].dest, state[1].dest, fz_default_color_params(ctx)/* FIXME */, dev->proof_cs, dev->default_cs); fz_drop_pixmap(ctx, state[1].dest); assert(state[1].mask == NULL); assert(state[1].shape == NULL); @@ -2854,6 +2855,7 @@ fz_draw_drop_device(fz_context *ctx, fz_device *devp) fz_rasterizer *rast = dev->rast; fz_drop_default_colorspaces(ctx, dev->default_cs); + fz_drop_colorspace(ctx, dev->proof_cs); /* pop and free the stacks */ if (dev->top > 0) @@ -2884,7 +2886,7 @@ fz_draw_drop_device(fz_context *ctx, fz_device *devp) } fz_device * -new_draw_device(fz_context *ctx, const fz_matrix *transform, fz_pixmap *dest, const fz_aa_context *aa, const fz_irect *clip) +new_draw_device(fz_context *ctx, const fz_matrix *transform, fz_pixmap *dest, const fz_aa_context *aa, const fz_irect *clip, fz_colorspace *proof_cs) { fz_draw_device *dev = fz_new_derived_device(ctx, fz_draw_device); @@ -2920,6 +2922,7 @@ new_draw_device(fz_context *ctx, const fz_matrix *transform, fz_pixmap *dest, co dev->super.render_flags = fz_draw_render_flags; dev->super.set_default_colorspaces = fz_draw_set_default_colorspaces; + dev->proof_cs = fz_keep_colorspace(ctx, proof_cs); dev->transform = transform ? *transform : fz_identity; dev->flags = 0; dev->resolve_spots = 0; @@ -2965,7 +2968,7 @@ new_draw_device(fz_context *ctx, const fz_matrix *transform, fz_pixmap *dest, co * the default_colorspaces etc are, so set a flag for us * to trigger on later. */ - if (dest->seps) + if (dest->seps || dev->proof_cs != NULL) #ifdef FZ_ENABLE_SPOT_RENDERING dev->resolve_spots = 1; #else @@ -2990,13 +2993,25 @@ new_draw_device(fz_context *ctx, const fz_matrix *transform, fz_pixmap *dest, co fz_device * fz_new_draw_device(fz_context *ctx, const fz_matrix *transform, fz_pixmap *dest) { - return new_draw_device(ctx, transform, dest, NULL, NULL); + return new_draw_device(ctx, transform, dest, NULL, NULL, NULL); } fz_device * fz_new_draw_device_with_bbox(fz_context *ctx, const fz_matrix *transform, fz_pixmap *dest, const fz_irect *clip) { - return new_draw_device(ctx, transform, dest, NULL, clip); + return new_draw_device(ctx, transform, dest, NULL, clip, NULL); +} + +fz_device * +fz_new_draw_device_with_proof(fz_context *ctx, const fz_matrix *transform, fz_pixmap *dest, fz_colorspace *cs) +{ + return new_draw_device(ctx, transform, dest, NULL, NULL, cs); +} + +fz_device * +fz_new_draw_device_with_bbox_proof(fz_context *ctx, const fz_matrix *transform, fz_pixmap *dest, const fz_irect *clip, fz_colorspace *cs) +{ + return new_draw_device(ctx, transform, dest, NULL, clip, cs); } fz_device * diff --git a/source/fitz/separation.c b/source/fitz/separation.c index ba3ab96e..5f8fee41 100644 --- a/source/fitz/separation.c +++ b/source/fitz/separation.c @@ -242,10 +242,6 @@ fz_clone_pixmap_area_with_different_seps(fz_context *ctx, fz_pixmap *src, const { fz_irect local_bbox; fz_pixmap *dst; - fz_colorspace *oi = fz_default_output_intent(ctx, default_cs); - - if (fz_colorspace_n(ctx, dcs) == fz_colorspace_n(ctx, oi)) - dcs = oi; if (bbox == NULL) { @@ -291,6 +287,7 @@ fz_copy_pixmap_area_converting_seps(fz_context *ctx, fz_pixmap *dst, fz_pixmap * unsigned char mapped[FZ_MAX_COLORS]; int unmapped = sseps_n; int device_n = 0; + fz_colorspace *proof_cs = (prf == src->colorspace ? NULL : prf); assert(da == sa); assert(ss == fz_count_active_separations(ctx, sseps)); @@ -300,7 +297,7 @@ fz_copy_pixmap_area_converting_seps(fz_context *ctx, fz_pixmap *dst, fz_pixmap * sstride -= sn * dw; /* Process colorants first */ - if (dst->colorspace == src->colorspace) + if (dst->colorspace == src->colorspace && proof_cs == NULL) { /* Simple copy */ unsigned char *dd = ddata; @@ -327,7 +324,7 @@ fz_copy_pixmap_area_converting_seps(fz_context *ctx, fz_pixmap *dst, fz_pixmap * { fz_pixmap_converter *pc = fz_lookup_pixmap_converter(ctx, dst->colorspace, src->colorspace); - pc(ctx, dst, src, prf, default_cs, NULL, 0); + pc(ctx, dst, src, proof_cs, default_cs, NULL, 0); } } @@ -398,7 +395,7 @@ fz_copy_pixmap_area_converting_seps(fz_context *ctx, fz_pixmap *dst, fz_pixmap * if (mapped[i]) continue; /* Src spot i is not mapped. We need to convert that down. */ - fz_separation_equivalent(ctx, sseps, i, color_params, dst->colorspace, prf, convert); + fz_separation_equivalent(ctx, sseps, i, color_params, dst->colorspace, proof_cs, convert); if (fz_colorspace_is_subtractive(ctx, dst->colorspace)) { @@ -491,7 +488,7 @@ fz_copy_pixmap_area_converting_seps(fz_context *ctx, fz_pixmap *dst, fz_pixmap * int n = fz_colorspace_n(ctx, src->colorspace); fz_color_converter cc; - fz_find_color_converter(ctx, &cc, prf, dst->colorspace, src->colorspace, color_params); + fz_find_color_converter(ctx, &cc, proof_cs, dst->colorspace, src->colorspace, color_params); fz_try(ctx) { diff --git a/source/tools/mudraw.c b/source/tools/mudraw.c index 8f3547b7..6382e95c 100644 --- a/source/tools/mudraw.c +++ b/source/tools/mudraw.c @@ -246,6 +246,8 @@ static int alphabits_text = 8; static int alphabits_graphics = 8; static int out_cs = CS_UNSET; +static const char *proof_filename = NULL; +fz_colorspace *proof_cs = NULL; static const char *icc_filename = NULL; static float gamma_value = 1; static int invert = 0; @@ -333,7 +335,8 @@ static void usage(void) "\t-U -\tfile name of user stylesheet for EPUB layout\n" "\t-X\tdisable document styles for EPUB layout\n" "\n" - "\t-c -\tcolorspace (mono, gray, grayalpha, rgb, rgba, cmyk, cmykalpha)\n" + "\t-c -\tcolorspace (mono, gray, grayalpha, rgb, rgba, cmyk, cmykalpha, filename of ICC profile)\n" + "\t-e -\tproof icc profile (filename of ICC profile)\n" "\t-G -\tapply gamma correction\n" "\t-I\tinvert colors\n" "\n" @@ -462,7 +465,7 @@ static void drawband(fz_context *ctx, fz_page *page, fz_display_list *list, cons else fz_clear_pixmap_with_value(ctx, pix, 255); - dev = fz_new_draw_device(ctx, NULL, pix); + dev = fz_new_draw_device_with_proof(ctx, NULL, pix, proof_cs); if (lowmemory) fz_enable_device_hints(ctx, dev, FZ_NO_CACHE); if (alphabits_graphics == 0) @@ -1440,7 +1443,7 @@ int mudraw_main(int argc, char **argv) fz_var(doc); - while ((c = fz_getopt(argc, argv, "p:o:F:R:r:w:h:fB:c:G:Is:A:DiW:H:S:T:U:XLvPl:y:NO:")) != -1) + while ((c = fz_getopt(argc, argv, "p:o:F:R:r:w:h:fB:c:e:G:Is:A:DiW:H:S:T:U:XLvPl:y:NO:")) != -1) { switch (c) { @@ -1459,6 +1462,7 @@ int mudraw_main(int argc, char **argv) case 'B': band_height = atoi(fz_optarg); break; case 'c': out_cs = parse_colorspace(fz_optarg); break; + case 'e': proof_filename = fz_optarg; break; case 'G': gamma_value = fz_atof(fz_optarg); break; case 'I': invert++; break; @@ -1561,6 +1565,9 @@ int mudraw_main(int argc, char **argv) exit(1); } + if (proof_filename) + proof_cs = fz_new_icc_colorspace_from_file(ctx, NULL, proof_filename); + fz_set_text_aa_level(ctx, alphabits_text); fz_set_graphics_aa_level(ctx, alphabits_graphics); fz_set_graphics_min_line_width(ctx, min_line_width); @@ -1841,10 +1848,16 @@ int mudraw_main(int argc, char **argv) oi = fz_document_output_intent(ctx, doc); if (oi) { - if (fz_colorspace_n(ctx, oi) == fz_colorspace_n(ctx, colorspace)) + /* See if we had explicitly set a profile to render */ + if (out_cs != CS_ICC) { - fz_drop_colorspace(ctx, colorspace); - colorspace = fz_keep_colorspace(ctx, oi); + /* In this case, we want to render to the output intent + * color space if the number of channels is the same */ + if (fz_colorspace_n(ctx, oi) == fz_colorspace_n(ctx, colorspace)) + { + fz_drop_colorspace(ctx, colorspace); + colorspace = fz_keep_colorspace(ctx, oi); + } } } @@ -1980,6 +1993,7 @@ int mudraw_main(int argc, char **argv) #endif /* DISABLE_MUTHREADS */ fz_drop_colorspace(ctx, colorspace); + fz_drop_colorspace(ctx, proof_cs); fz_drop_context(ctx); #ifndef DISABLE_MUTHREADS |