summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
authorMichael Vrhel <michael.vrhel@artifex.com>2017-07-26 23:06:07 -0700
committerRobin Watts <robin.watts@artifex.com>2017-10-24 15:16:34 +0100
commitfee66b72d296ecdd9654109c31e9dbfa4811d034 (patch)
tree0ca19bbeed8aa6e385ef23fe3d3a5a8207630ca7 /source
parent8080868ad41df95ba376bd451612fcb23a4a3daf (diff)
downloadmupdf-fee66b72d296ecdd9654109c31e9dbfa4811d034.tar.xz
Logic for Sep and DeviceN colorspaces with C,M,Y, or K.
Special care is required when the DeviceN color space has cyan, magenta, yellow or black. For example, even if we support separations in the destination, if the color space has CMY or K as one of its colorants and we are drawing to an RGB or Gray pixmap we will want to do the tint transform. Also if the pixmap has no seps memember present, we support the separations if the destination is CMYK and the DeviceN colorspace has no "Spot" (non-CMYK) colorants.
Diffstat (limited to 'source')
-rw-r--r--source/fitz/colorspace-imp.h2
-rw-r--r--source/fitz/colorspace.c56
-rw-r--r--source/fitz/draw-device.c22
-rw-r--r--source/fitz/separation.c4
-rw-r--r--source/pdf/pdf-colorspace.c2
5 files changed, 75 insertions, 11 deletions
diff --git a/source/fitz/colorspace-imp.h b/source/fitz/colorspace-imp.h
index 7f4ecef6..886b8bb8 100644
--- a/source/fitz/colorspace-imp.h
+++ b/source/fitz/colorspace-imp.h
@@ -29,7 +29,7 @@ struct fz_colorspace_s
char name[24];
unsigned char n;
unsigned char is_subtractive;
- unsigned char is_device_n;
+ unsigned char device_n;
fz_colorspace_convert_fn *to_ccs;
fz_colorspace_convert_fn *from_ccs;
fz_colorspace_clamp_fn *clamp;
diff --git a/source/fitz/colorspace.c b/source/fitz/colorspace.c
index 7ec34f06..414ef097 100644
--- a/source/fitz/colorspace.c
+++ b/source/fitz/colorspace.c
@@ -157,7 +157,7 @@ clamp_default(const fz_colorspace *cs, const float *src, float *dst)
}
fz_colorspace *
-fz_new_colorspace(fz_context *ctx, const char *name, int n, int is_subtractive, int is_device_n, fz_colorspace_convert_fn *to_ccs, fz_colorspace_convert_fn *from_ccs, fz_colorspace_base_fn *base, fz_colorspace_clamp_fn *clamp, fz_colorspace_destruct_fn *destruct, void *data, size_t size)
+fz_new_colorspace(fz_context *ctx, const char *name, int n, int is_subtractive, int device_n, fz_colorspace_convert_fn *to_ccs, fz_colorspace_convert_fn *from_ccs, fz_colorspace_base_fn *base, fz_colorspace_clamp_fn *clamp, fz_colorspace_destruct_fn *destruct, void *data, size_t size)
{
fz_colorspace *cs = fz_malloc_struct(ctx, fz_colorspace);
FZ_INIT_KEY_STORABLE(cs, 1, fz_drop_colorspace_imp);
@@ -165,7 +165,7 @@ fz_new_colorspace(fz_context *ctx, const char *name, int n, int is_subtractive,
fz_strlcpy(cs->name, name ? name : "UNKNOWN", sizeof cs->name);
cs->n = n;
cs->is_subtractive = is_subtractive;
- cs->is_device_n = is_device_n;
+ cs->device_n = device_n;
cs->to_ccs = to_ccs;
cs->from_ccs = from_ccs;
cs->get_base = base;
@@ -3412,7 +3412,7 @@ fz_new_indexed_colorspace(fz_context *ctx, fz_colorspace *base, int high, unsign
idx->high = high;
fz_try(ctx)
- cs = fz_new_colorspace(ctx, "Indexed", 1, 0, 0, fz_colorspace_is_icc(ctx, fz_device_rgb(ctx)) ? indexed_to_alt : indexed_to_rgb, NULL, base_indexed, clamp_indexed, free_indexed, idx, sizeof(*idx) + (base->n * (idx->high + 1)) + base->size);
+ cs = fz_new_colorspace(ctx, "Indexed", 1, 0, FZ_NOT_DEVICE_N, fz_colorspace_is_icc(ctx, fz_device_rgb(ctx)) ? indexed_to_alt : indexed_to_rgb, NULL, base_indexed, clamp_indexed, free_indexed, idx, sizeof(*idx) + (base->n * (idx->high + 1)) + base->size);
fz_catch(ctx)
{
fz_free(ctx, idx);
@@ -3660,7 +3660,7 @@ fz_new_icc_colorspace(fz_context *ctx, const char *name, int num, fz_buffer *buf
}
fz_md5_icc(ctx, profile);
- cs = fz_new_colorspace(ctx, name, num, 0, 0, NULL, NULL, NULL, is_lab ? clamp_lab_icc : clamp_default_icc, free_icc, profile, sizeof(profile));
+ cs = fz_new_colorspace(ctx, name, num, 0, FZ_NOT_DEVICE_N, NULL, NULL, NULL, is_lab ? clamp_lab_icc : clamp_default_icc, free_icc, profile, sizeof(profile));
switch(profile->num_devcomp)
{
@@ -3755,7 +3755,7 @@ fz_new_cal_colorspace(fz_context *ctx, const char *name, float *wp, float *bp, f
cal_data->n = num;
fz_try(ctx)
- cs = fz_new_colorspace(ctx, "pdf-cal", num, 0, 0, NULL, NULL, NULL, NULL, free_cal, cal_data, sizeof(cal_data));
+ cs = fz_new_colorspace(ctx, "pdf-cal", num, 0, FZ_NOT_DEVICE_N, NULL, NULL, NULL, NULL, free_cal, cal_data, sizeof(cal_data));
fz_catch(ctx)
{
fz_free(ctx, cal_data);
@@ -3905,8 +3905,42 @@ void fz_colorspace_name_colorant(fz_context *ctx, fz_colorspace *cs, int i, cons
fz_free(ctx, cs->colorant[i]);
cs->colorant[i] = NULL;
if (name)
+ {
cs->colorant[i] = fz_strdup(ctx, name);
+ if (cs->device_n != FZ_NOT_DEVICE_N)
+ {
+ if (i == 0)
+ {
+ if (strcmp(name, "Cyan") == 0 ||
+ strcmp(name, "Magenta") == 0 ||
+ strcmp(name, "Yellow") == 0 ||
+ strcmp(name, "Black") == 0)
+ {
+ cs->device_n = FZ_DEVICE_N_CMYK_ONLY;
+ }
+ }
+ else
+ {
+ if (cs->device_n != FZ_DEVICE_N_WITH_CMYK)
+ {
+ if (strcmp(name, "Cyan") == 0 ||
+ strcmp(name, "Magenta") == 0 ||
+ strcmp(name, "Yellow") == 0 ||
+ strcmp(name, "Black") == 0)
+ {
+ if (cs->device_n == FZ_DEVICE_N_SPOTS_ONLY)
+ cs->device_n = FZ_DEVICE_N_WITH_CMYK;
+ }
+ else
+ {
+ if (cs->device_n == FZ_DEVICE_N_CMYK_ONLY)
+ cs->device_n = FZ_DEVICE_N_WITH_CMYK;
+ }
+ }
+ }
+ }
+ }
}
const char *fz_colorspace_colorant(fz_context *ctx, const fz_colorspace *cs, int i)
@@ -3919,5 +3953,15 @@ const char *fz_colorspace_colorant(fz_context *ctx, const fz_colorspace *cs, int
int fz_colorspace_is_device_n(fz_context *ctx, const fz_colorspace *cs)
{
- return (cs && cs->is_device_n);
+ return (cs && cs->device_n != FZ_NOT_DEVICE_N);
}
+
+int fz_colorspace_device_n_info(fz_context *ctx, const fz_colorspace *cs)
+{
+ return (cs == NULL ? 0 : cs->device_n);
+}
+
+int fz_colorspace_device_n_has_cmyk(fz_context *ctx, const fz_colorspace *cs)
+{
+ return (cs == NULL ? 0 : cs->device_n == FZ_DEVICE_N_WITH_CMYK || cs->device_n == FZ_DEVICE_N_CMYK_ONLY);
+} \ No newline at end of file
diff --git a/source/fitz/draw-device.c b/source/fitz/draw-device.c
index fdc9cd20..7a47e707 100644
--- a/source/fitz/draw-device.c
+++ b/source/fitz/draw-device.c
@@ -328,6 +328,26 @@ static inline fz_matrix concat(const fz_matrix *one, const fz_matrix *two)
return ctm;
}
+static int
+colors_supported(fz_context *ctx, fz_colorspace *cs, fz_pixmap *dest)
+{
+ /* Even if we support separations in the destination, if the color space has CMY or K as one of
+ * its colorants and we are in RGB or Gray we will want to do the tint transform */
+ if (!fz_colorspace_is_subtractive(ctx, dest->colorspace) && fz_colorspace_device_n_has_cmyk(ctx, cs))
+ return 0;
+
+ /* If we have separations then we should support it */
+ if (dest->seps)
+ return 1;
+
+ /* If our destination is CMYK and the source color space is only C, M, Y or K we support it
+ * even if we have no seps */
+ if (fz_colorspace_is_subtractive(ctx, dest->colorspace) && fz_colorspace_device_n_info(ctx, cs) == FZ_DEVICE_N_CMYK_ONLY)
+ return 1;
+
+ return 0;
+}
+
static void
resolve_color(fz_context *ctx, const float *color, fz_colorspace *colorspace, float alpha, const fz_color_params *color_params, unsigned char *colorbv, fz_pixmap *dest, fz_colorspace *prf)
{
@@ -344,7 +364,7 @@ resolve_color(fz_context *ctx, const float *color, fz_colorspace *colorspace, fl
if (n == 0)
i = 0;
- else if (fz_colorspace_is_device_n(ctx, colorspace) && dest->seps)
+ else if (fz_colorspace_is_device_n(ctx, colorspace) && colors_supported(ctx, colorspace, dest))
{
fz_convert_separation_colors(ctx, color_params, dest->colorspace, dest->seps, colorfv, colorspace, color);
for (i = 0; i < n; i++)
diff --git a/source/fitz/separation.c b/source/fitz/separation.c
index 3a26c288..45049951 100644
--- a/source/fitz/separation.c
+++ b/source/fitz/separation.c
@@ -712,11 +712,11 @@ void fz_convert_separation_colors(fz_context *ctx, const fz_color_params *color_
float remainders[FZ_MAX_COLORS];
int remaining = 0;
- assert(dst_cs && dst_seps && src_cs && dst_color && src_color);
+ assert(dst_cs && src_cs && dst_color && src_color);
assert(fz_colorspace_is_device_n(ctx, src_cs));
dc = fz_colorspace_n(ctx, dst_cs);
- ds = dst_seps->num_separations;
+ ds = (dst_seps == NULL ? 0: dst_seps->num_separations);
dn = dc + ds;
i = 0;
diff --git a/source/pdf/pdf-colorspace.c b/source/pdf/pdf-colorspace.c
index 4f910de3..8dec434e 100644
--- a/source/pdf/pdf-colorspace.c
+++ b/source/pdf/pdf-colorspace.c
@@ -204,7 +204,7 @@ load_devicen(fz_context *ctx, pdf_obj *array)
devn->base = fz_keep_colorspace(ctx, base); /* We drop it during the devn free... */
devn->tint = tint;
- cs = fz_new_colorspace(ctx, colorspace_name, n, 1, 1,
+ cs = fz_new_colorspace(ctx, colorspace_name, n, 1, FZ_DEVICE_N_SPOTS_ONLY,
fz_colorspace_is_icc(ctx, fz_device_rgb(ctx)) ? devicen_to_alt : devicen_to_rgb, NULL, base_devicen, NULL, free_devicen, devn,
sizeof(struct devicen) + base->size + pdf_function_size(ctx, tint));