summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/mupdf/fitz/colorspace.h64
-rw-r--r--source/fitz/colorspace-imp.h9
-rw-r--r--source/fitz/colorspace.c235
-rw-r--r--source/fitz/draw-device.c32
-rw-r--r--source/fitz/image.c2
-rw-r--r--source/fitz/output-tga.c3
-rw-r--r--source/fitz/test-device.c6
-rw-r--r--source/fitz/util.c14
-rw-r--r--source/pdf/pdf-colorspace.c7
-rw-r--r--source/pdf/pdf-device.c19
-rw-r--r--source/pdf/pdf-image.c81
-rw-r--r--source/pdf/pdf-interpret.c2
-rw-r--r--source/pdf/pdf-op-buffer.c2
-rw-r--r--source/tools/mudraw.c8
14 files changed, 307 insertions, 177 deletions
diff --git a/include/mupdf/fitz/colorspace.h b/include/mupdf/fitz/colorspace.h
index 32a8f846..d5d4e46b 100644
--- a/include/mupdf/fitz/colorspace.h
+++ b/include/mupdf/fitz/colorspace.h
@@ -16,6 +16,14 @@ enum
FZ_RI_ABSOLUTE_COLORIMETRIC,
};
+enum
+{
+ FZ_COLORSPACE_IS_DEVICE = 1,
+ FZ_COLORSPACE_IS_ICC = 2,
+ FZ_COLORSPACE_IS_CAL = 4,
+ FZ_COLORSPACE_LAST_PUBLIC_FLAG = 8,
+};
+
typedef struct fz_color_params_s fz_color_params;
struct fz_color_params_s
@@ -26,7 +34,6 @@ struct fz_color_params_s
uint8_t opm;
};
-
int fz_lookup_rendering_intent(const char *name);
char *fz_rendering_intent_name(int ri);
@@ -39,6 +46,20 @@ char *fz_rendering_intent_name(int ri);
*/
typedef struct fz_colorspace_s fz_colorspace;
+enum fz_colorspace_type
+{
+ FZ_COLORSPACE_NONE,
+ FZ_COLORSPACE_GRAY,
+ FZ_COLORSPACE_RGB,
+ FZ_COLORSPACE_BGR,
+ FZ_COLORSPACE_CMYK,
+ FZ_COLORSPACE_LAB,
+ FZ_COLORSPACE_INDEXED,
+ FZ_COLORSPACE_SEPARATION,
+};
+
+enum fz_colorspace_type fz_colorspace_type(fz_context *ctx, fz_colorspace *cs);
+
/*
A fz_iccprofile object encapsulates details about the icc profile. It
also includes the profile handle provided by the cmm and as such is used
@@ -64,13 +85,6 @@ typedef struct fz_default_colorspaces_s fz_default_colorspaces;
int fz_colorspace_is_subtractive(fz_context *ctx, const fz_colorspace *cs);
/*
- fz_colorspace_is_device_n: Return true if a colorspace is separation or devicen.
-
- True for Separation and DeviceN colorspaces.
-*/
-int fz_colorspace_is_device_n(fz_context *ctx, const fz_colorspace *cs);
-
-/*
fz_colorspace_device_n_has_only_cmyk: Return true if devicen color space
has only colorants from the cmyk set.
*/
@@ -83,10 +97,24 @@ int fz_colorspace_device_n_has_only_cmyk(fz_context *ctx, const fz_colorspace *c
int fz_colorspace_device_n_has_cmyk(fz_context *ctx, const fz_colorspace *cs);
/*
- fz_colorspace_is_device_gray: Return true if the color space is
- device gray.
+ Colorspace feature test functions.
*/
+int fz_colorspace_is_gray(fz_context *ctx, const fz_colorspace *cs);
+int fz_colorspace_is_rgb(fz_context *ctx, const fz_colorspace *cs);
+int fz_colorspace_is_bgr(fz_context *ctx, const fz_colorspace *cs);
+int fz_colorspace_is_cmyk(fz_context *ctx, const fz_colorspace *cs);
+int fz_colorspace_is_lab(fz_context *ctx, const fz_colorspace *cs);
+int fz_colorspace_is_indexed(fz_context *ctx, const fz_colorspace *cs);
+int fz_colorspace_is_device_n(fz_context *ctx, const fz_colorspace *cs);
+
+int fz_colorspace_is_device(fz_context *ctx, const fz_colorspace *cs);
+int fz_colorspace_is_icc(fz_context *ctx, const fz_colorspace *cs);
+int fz_colorspace_is_cal(fz_context *ctx, const fz_colorspace *cs);
+
int fz_colorspace_is_device_gray(fz_context *ctx, const fz_colorspace *cs);
+int fz_colorspace_is_device_cmyk(fz_context *ctx, const fz_colorspace *cs);
+
+int fz_colorspace_is_lab_icc(fz_context *ctx, const fz_colorspace *cs);
/*
fz_device_gray: Get colorspace representing device specific gray.
@@ -126,16 +154,7 @@ typedef fz_colorspace *(fz_colorspace_base_fn)(const fz_colorspace *cs);
typedef void (fz_colorspace_clamp_fn)(const fz_colorspace *cs, const float *src, float *dst);
-enum
-{
- FZ_CS_DEVICE_GRAY = 1,
- FZ_CS_DEVICE_N = 2,
- FZ_CS_SUBTRACTIVE = 4,
-
- FZ_CS_LAST_PUBLIC_FLAG = 4
-};
-
-fz_colorspace *fz_new_colorspace(fz_context *ctx, const char *name, int n, int flags, 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 *fz_new_colorspace(fz_context *ctx, const char *name, enum fz_colorspace_type type, int flags, int 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);
void fz_colorspace_name_colorant(fz_context *ctx, fz_colorspace *cs, int n, const char *name);
const char *fz_colorspace_colorant(fz_context *ctx, const fz_colorspace *cs, int n);
fz_colorspace *fz_new_indexed_colorspace(fz_context *ctx, fz_colorspace *base, int high, unsigned char *lookup);
@@ -147,11 +166,6 @@ void fz_drop_colorspace(fz_context *ctx, fz_colorspace *colorspace);
void fz_drop_colorspace_imp(fz_context *ctx, fz_storable *colorspace);
fz_colorspace *fz_colorspace_base(fz_context *ctx, const fz_colorspace *cs);
-int fz_colorspace_is_icc(fz_context *ctx, const fz_colorspace *cs);
-int fz_colorspace_is_lab(fz_context *ctx, const fz_colorspace *cs);
-int fz_colorspace_is_lab_icc(fz_context *ctx, const fz_colorspace *cs);
-int fz_colorspace_is_cal(fz_context *ctx, const fz_colorspace *cs);
-int fz_colorspace_is_indexed(fz_context *ctx, const fz_colorspace *cs);
void fz_set_icc_bgr(fz_context *ctx, fz_colorspace *cs);
int fz_colorspace_n(fz_context *ctx, const fz_colorspace *cs);
int fz_colorspace_devicen_n(fz_context *ctx, const fz_colorspace *cs);
diff --git a/source/fitz/colorspace-imp.h b/source/fitz/colorspace-imp.h
index c369c165..5fd1ffd0 100644
--- a/source/fitz/colorspace-imp.h
+++ b/source/fitz/colorspace-imp.h
@@ -24,8 +24,8 @@ void fz_cmm_fin_profile(fz_context *ctx, fz_iccprofile *profile);
enum
{
- FZ_CS_HAS_CMYK = (FZ_CS_LAST_PUBLIC_FLAG<<1),
- FZ_CS_HAS_SPOTS = (FZ_CS_LAST_PUBLIC_FLAG<<2),
+ FZ_CS_HAS_CMYK = (FZ_COLORSPACE_LAST_PUBLIC_FLAG<<1),
+ FZ_CS_HAS_SPOTS = (FZ_COLORSPACE_LAST_PUBLIC_FLAG<<2),
FZ_CS_HAS_CMYK_AND_SPOTS = FZ_CS_HAS_CMYK|FZ_CS_HAS_SPOTS
};
@@ -34,8 +34,9 @@ struct fz_colorspace_s
fz_key_storable key_storable;
size_t size;
char name[24];
- unsigned char n;
- unsigned char flags;
+ enum fz_colorspace_type type;
+ int flags;
+ int 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 515f50fb..c099297a 100644
--- a/source/fitz/colorspace.c
+++ b/source/fitz/colorspace.c
@@ -7,6 +7,88 @@
#include <math.h>
#include <string.h>
+/* Colorspace feature tests */
+
+int fz_colorspace_is_gray(fz_context *ctx, const fz_colorspace *cs)
+{
+ return cs && cs->type == FZ_COLORSPACE_GRAY;
+}
+
+int fz_colorspace_is_rgb(fz_context *ctx, const fz_colorspace *cs)
+{
+ return cs && cs->type == FZ_COLORSPACE_RGB;
+}
+
+int fz_colorspace_is_bgr(fz_context *ctx, const fz_colorspace *cs)
+{
+ return cs && cs->type == FZ_COLORSPACE_BGR;
+}
+
+int fz_colorspace_is_cmyk(fz_context *ctx, const fz_colorspace *cs)
+{
+ return cs && cs->type == FZ_COLORSPACE_CMYK;
+}
+
+int fz_colorspace_is_lab(fz_context *ctx, const fz_colorspace *cs)
+{
+ return cs && cs->type == FZ_COLORSPACE_LAB;
+}
+
+int fz_colorspace_is_indexed(fz_context *ctx, const fz_colorspace *cs)
+{
+ return cs && (cs->type == FZ_COLORSPACE_INDEXED);
+}
+
+int fz_colorspace_is_device_n(fz_context *ctx, const fz_colorspace *cs)
+{
+ return cs && (cs->type == FZ_COLORSPACE_SEPARATION);
+}
+
+int fz_colorspace_is_subtractive(fz_context *ctx, const fz_colorspace *cs)
+{
+ return cs && (cs->type == FZ_COLORSPACE_CMYK || cs->type == FZ_COLORSPACE_SEPARATION);
+}
+
+int fz_colorspace_is_device(fz_context *ctx, const fz_colorspace *cs)
+{
+ return cs && (cs->flags & FZ_COLORSPACE_IS_DEVICE);
+}
+
+int fz_colorspace_is_icc(fz_context *ctx, const fz_colorspace *cs)
+{
+ return cs && (cs->flags & FZ_COLORSPACE_IS_ICC);
+}
+
+int fz_colorspace_is_cal(fz_context *ctx, const fz_colorspace *cs)
+{
+ return cs && (cs->flags & FZ_COLORSPACE_IS_CAL);
+}
+
+int fz_colorspace_is_lab_icc(fz_context *ctx, const fz_colorspace *cs)
+{
+ return fz_colorspace_is_lab(ctx, cs) && fz_colorspace_is_icc(ctx, cs);
+}
+
+int fz_colorspace_is_device_gray(fz_context *ctx, const fz_colorspace *cs)
+{
+ return fz_colorspace_is_device(ctx, cs) && fz_colorspace_is_gray(ctx, cs);
+}
+
+int fz_colorspace_is_device_cmyk(fz_context *ctx, const fz_colorspace *cs)
+{
+ return fz_colorspace_is_device(ctx, cs) && fz_colorspace_is_cmyk(ctx, cs);
+}
+
+int fz_colorspace_device_n_has_only_cmyk(fz_context *ctx, const fz_colorspace *cs)
+{
+ return cs && ((cs->flags & FZ_CS_HAS_CMYK_AND_SPOTS) == FZ_CS_HAS_CMYK);
+}
+
+int fz_colorspace_device_n_has_cmyk(fz_context *ctx, const fz_colorspace *cs)
+{
+ return cs && (cs->flags & FZ_CS_HAS_CMYK);
+}
+
/* CMM module */
int
@@ -157,14 +239,23 @@ 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 flags, 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,
+ enum fz_colorspace_type type, int flags, int 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);
cs->size = sizeof(fz_colorspace) + size;
fz_strlcpy(cs->name, name ? name : "UNKNOWN", sizeof cs->name);
+ cs->type = type;
+ cs->flags = flags;
cs->n = n;
- cs->flags = (unsigned char)flags;
cs->to_ccs = to_ccs;
cs->from_ccs = from_ccs;
cs->get_base = base;
@@ -203,6 +294,12 @@ fz_drop_colorspace_store_key(fz_context *ctx, fz_colorspace *cs)
fz_drop_key_storable_key(ctx, &cs->key_storable);
}
+enum fz_colorspace_type
+fz_colorspace_type(fz_context *ctx, fz_colorspace *cs)
+{
+ return cs ? cs->type : FZ_COLORSPACE_NONE;
+}
+
/* icc links */
typedef struct fz_link_key_s fz_link_key;
@@ -679,22 +776,12 @@ clamp_lab(const fz_colorspace *cs, const float *src, float *dst)
dst[i] = fz_clamp(src[i], i ? -128 : 0, i ? 127 : 100);
}
-int fz_colorspace_is_lab(fz_context *ctx, const fz_colorspace *cs)
-{
- return cs && cs->to_ccs == lab_to_rgb;
-}
-
-int
-fz_colorspace_is_subtractive(fz_context *ctx, const fz_colorspace *cs)
-{
- return (cs && !!(cs->flags & FZ_CS_SUBTRACTIVE));
-}
+static fz_colorspace k_default_gray = { { {-1, fz_drop_colorspace_imp}, 0 }, 0, "DeviceGray", FZ_COLORSPACE_GRAY, FZ_COLORSPACE_IS_DEVICE, 1, gray_to_rgb, rgb_to_gray, clamp_default, NULL, NULL, NULL, { "Gray" } };
+static fz_colorspace k_default_rgb = { { {-1, fz_drop_colorspace_imp}, 0 }, 0, "DeviceRGB", FZ_COLORSPACE_RGB, FZ_COLORSPACE_IS_DEVICE, 3, rgb_to_rgb, rgb_to_rgb, clamp_default, NULL, NULL, NULL, { "Red", "Green", "Blue" } };
+static fz_colorspace k_default_bgr = { { {-1, fz_drop_colorspace_imp}, 0 }, 0, "DeviceBGR", FZ_COLORSPACE_BGR, FZ_COLORSPACE_IS_DEVICE, 3, bgr_to_rgb, rgb_to_bgr, clamp_default, NULL, NULL, NULL, { "Blue", "Green", "Red" } };
+static fz_colorspace k_default_cmyk = { { {-1, fz_drop_colorspace_imp}, 0 }, 0, "DeviceCMYK", FZ_COLORSPACE_CMYK, FZ_COLORSPACE_IS_DEVICE, 4, cmyk_to_rgb, rgb_to_cmyk, clamp_default, NULL, NULL, NULL, { "Cyan", "Magenta", "Yellow", "Black" } };
+static fz_colorspace k_default_lab = { { {-1, fz_drop_colorspace_imp}, 0 }, 0, "Lab", FZ_COLORSPACE_LAB, 0, 3, lab_to_rgb, rgb_to_lab, clamp_lab, NULL, NULL, NULL, { "L*", "a*", "b*" } };
-static fz_colorspace k_default_gray = { { {-1, fz_drop_colorspace_imp}, 0 }, 0, "DeviceGray", 1, FZ_CS_DEVICE_GRAY, gray_to_rgb, rgb_to_gray, clamp_default, NULL, NULL, NULL, { "Gray" } };
-static fz_colorspace k_default_rgb = { { {-1, fz_drop_colorspace_imp}, 0 }, 0, "DeviceRGB", 3, 0, rgb_to_rgb, rgb_to_rgb, clamp_default, NULL, NULL, NULL, { "Red", "Green", "Blue" } };
-static fz_colorspace k_default_bgr = { { {-1, fz_drop_colorspace_imp}, 0 }, 0, "DeviceBGR", 3, 0, bgr_to_rgb, rgb_to_bgr, clamp_default, NULL, NULL, NULL, { "Blue", "Green", "Red" } };
-static fz_colorspace k_default_cmyk = { { {-1, fz_drop_colorspace_imp}, 0 }, 0, "DeviceCMYK", 4, FZ_CS_SUBTRACTIVE, cmyk_to_rgb, rgb_to_cmyk, clamp_default, NULL, NULL, NULL, { "Cyan", "Magenta", "Yellow", "Black" } };
-static fz_colorspace k_default_lab = { { {-1, fz_drop_colorspace_imp}, 0 }, 0, "Lab", 3, 0, lab_to_rgb, rgb_to_lab, clamp_lab, NULL, NULL, NULL, { "L*", "a*", "b*" } };
static fz_color_params k_default_color_params = { FZ_RI_RELATIVE_COLORIMETRIC, 1, 0, 0 };
static fz_colorspace *default_gray = &k_default_gray;
@@ -2616,8 +2703,8 @@ icc_conv_pixmap(fz_context *ctx, fz_pixmap *dst, fz_pixmap *src, fz_colorspace *
unsigned char *inputpos, *outputpos;
int src_n;
- /* Handle DeviceGray->CMYK as K only. See note in Section 6.3 of PDF spec.*/
- if (fz_colorspace_is_device_gray(ctx, src->colorspace) && fz_colorspace_is_subtractive(ctx, dst->colorspace))
+ /* Handle DeviceGray to CMYK as K only. See note in Section 6.3 of PDF spec 1.7. */
+ if (fz_colorspace_is_device_gray(ctx, srcs) && fz_colorspace_is_cmyk(ctx, dsts))
{
fast_gray_to_cmyk(ctx, dst, src, prf, default_cs, color_params, copy_spots);
return;
@@ -2626,20 +2713,22 @@ icc_conv_pixmap(fz_context *ctx, fz_pixmap *dst, fz_pixmap *src, fz_colorspace *
/* Check if we have to do a color space default substitution */
if (default_cs)
{
- switch (fz_colorspace_n(ctx, src->colorspace))
+ switch (fz_colorspace_type(ctx, src->colorspace))
{
- case 1:
+ case FZ_COLORSPACE_GRAY:
if (src->colorspace == fz_device_gray(ctx))
srcs = fz_default_gray(ctx, default_cs);
break;
- case 3:
+ case FZ_COLORSPACE_RGB:
if (src->colorspace == fz_device_rgb(ctx))
srcs = fz_default_rgb(ctx, default_cs);
break;
- case 4:
+ case FZ_COLORSPACE_CMYK:
if (src->colorspace == fz_device_cmyk(ctx))
srcs = fz_default_cmyk(ctx, default_cs);
break;
+ default:
+ break;
}
}
@@ -3336,8 +3425,9 @@ void fz_find_color_converter(fz_context *ctx, fz_color_converter *cc, const fz_c
else
cc->convert = icc_base_conv_color;
- /* Special case. Do not set link if we are doing DeviceGray to CMYK */
- if (!(fz_colorspace_is_device_gray(ctx, ss_base) && fz_colorspace_is_subtractive(ctx, ds)))
+ /* Special case: Do not set link if we are doing DeviceGray to CMYK. */
+ /* Handle DeviceGray to CMYK as K only. See note in Section 6.3 of PDF spec 1.7. */
+ if (!(fz_colorspace_is_device_gray(ctx, ss_base) && fz_colorspace_is_cmyk(ctx, ds)))
cc->link = fz_get_icc_link(ctx, ds, 0, ss_base, 0, is, params, 2, 0, &cc->n);
}
else
@@ -3421,11 +3511,6 @@ clamp_indexed(const fz_colorspace *cs, const float *in, float *out)
*out = fz_clamp(*in, 0, idx->high) / 255.0f; /* To do, avoid 255 divide */
}
-int fz_colorspace_is_indexed(fz_context *ctx, const fz_colorspace *cs)
-{
- return cs && cs->clamp == clamp_indexed;
-}
-
fz_colorspace *
fz_new_indexed_colorspace(fz_context *ctx, fz_colorspace *base, int high, unsigned char *lookup)
{
@@ -3438,7 +3523,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, 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", FZ_COLORSPACE_INDEXED, 0, 1, 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);
@@ -3640,16 +3725,6 @@ clamp_default_icc(const fz_colorspace *cs, const float *src, float *dst)
dst[i] = fz_clamp(src[i], 0, 1);
}
-int fz_colorspace_is_icc(fz_context *ctx, const fz_colorspace *cs)
-{
- return cs && cs->free_data == free_icc;
-}
-
-int fz_colorspace_is_lab_icc(fz_context *ctx, const fz_colorspace *cs)
-{
- return cs && cs->clamp == clamp_lab_icc;
-}
-
void fz_set_icc_bgr(fz_context *ctx, fz_colorspace *cs)
{
fz_iccprofile *profile;
@@ -3671,7 +3746,8 @@ fz_new_icc_colorspace(fz_context *ctx, const char *name, int num, fz_buffer *buf
fz_colorspace *cs = NULL;
fz_iccprofile *profile;
int is_lab = 0;
- int flags = 0;
+ enum fz_colorspace_type type = FZ_COLORSPACE_NONE;
+ int flags = FZ_COLORSPACE_IS_ICC;
profile = fz_malloc_struct(ctx, fz_iccprofile);
fz_try(ctx)
@@ -3683,9 +3759,8 @@ fz_new_icc_colorspace(fz_context *ctx, const char *name, int num, fz_buffer *buf
data = fz_lookup_icc(ctx, name, &size);
profile->buffer = fz_new_buffer_from_shared_data(ctx, data, size);
is_lab = (strcmp(name, FZ_ICC_PROFILE_LAB) == 0);
- if (strcmp(name, FZ_ICC_PROFILE_GRAY) == 0)
- flags = FZ_CS_DEVICE_GRAY;
profile->bgr = (strcmp(name, FZ_ICC_PROFILE_BGR) == 0);
+ flags |= FZ_COLORSPACE_IS_DEVICE;
}
else
{
@@ -3704,9 +3779,29 @@ fz_new_icc_colorspace(fz_context *ctx, const char *name, int num, fz_buffer *buf
}
fz_md5_icc(ctx, profile);
- if (profile->num_devcomp == 4)
- flags |= FZ_CS_SUBTRACTIVE;
- cs = fz_new_colorspace(ctx, name, profile->num_devcomp, flags, NULL, NULL, NULL, is_lab ? clamp_lab_icc : clamp_default_icc, free_icc, profile, sizeof(profile));
+
+ switch (profile->num_devcomp)
+ {
+ default:
+ type = FZ_COLORSPACE_SEPARATION;
+ break;
+ case 1:
+ type = FZ_COLORSPACE_GRAY;
+ break;
+ case 3:
+ if (is_lab)
+ type = FZ_COLORSPACE_LAB;
+ else if (profile->bgr)
+ type = FZ_COLORSPACE_BGR;
+ else
+ type = FZ_COLORSPACE_RGB;
+ break;
+ case 4:
+ type = FZ_COLORSPACE_CMYK;
+ break;
+ }
+
+ cs = fz_new_colorspace(ctx, name, type, flags, profile->num_devcomp, NULL, NULL, NULL, is_lab ? clamp_lab_icc : clamp_default_icc, free_icc, profile, sizeof(profile));
switch (profile->num_devcomp)
{
@@ -3798,19 +3893,27 @@ free_cal(fz_context *ctx, fz_colorspace *cs)
fz_free(ctx, cal_data);
}
-int fz_colorspace_is_cal(fz_context *ctx, const fz_colorspace *cs)
-{
- return cs && cs->free_data == free_cal;
-}
-
/* Profile created if needed during draw command. */
fz_colorspace *
fz_new_cal_colorspace(fz_context *ctx, const char *name, float *wp, float *bp, float *gamma, float *matrix)
{
fz_colorspace *cs = NULL;
- int num = (matrix == NULL ? 1 : 3);
- fz_cal_colorspace *cal_data = fz_malloc_struct(ctx, fz_cal_colorspace);
+ enum fz_colorspace_type type;
+ int num;
+ fz_cal_colorspace *cal_data;
+
+ if (matrix)
+ {
+ type = FZ_COLORSPACE_RGB;
+ num = 3;
+ }
+ else
+ {
+ type = FZ_COLORSPACE_GRAY;
+ num = 1;
+ }
+ cal_data = fz_malloc_struct(ctx, fz_cal_colorspace);
memcpy(&cal_data->bp, bp, sizeof(float) * 3);
memcpy(&cal_data->wp, wp, sizeof(float) * 3);
memcpy(&cal_data->gamma, gamma, sizeof(float) * num);
@@ -3819,7 +3922,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, NULL, NULL, NULL, NULL, free_cal, cal_data, sizeof(cal_data));
+ cs = fz_new_colorspace(ctx, name, type, FZ_COLORSPACE_IS_CAL, num, NULL, NULL, NULL, NULL, free_cal, cal_data, sizeof(cal_data));
fz_catch(ctx)
{
fz_free(ctx, cal_data);
@@ -3993,7 +4096,7 @@ void fz_colorspace_name_colorant(fz_context *ctx, fz_colorspace *cs, int i, cons
{
cs->colorant[i] = fz_strdup(ctx, name);
- if (cs->flags & FZ_CS_DEVICE_N)
+ if (cs->type == FZ_COLORSPACE_SEPARATION)
{
if (i == 0)
{
@@ -4029,23 +4132,3 @@ const char *fz_colorspace_colorant(fz_context *ctx, const fz_colorspace *cs, int
return cs->colorant[i];
}
-
-int fz_colorspace_is_device_n(fz_context *ctx, const fz_colorspace *cs)
-{
- return (cs && !!(cs->flags & FZ_CS_DEVICE_N));
-}
-
-int fz_colorspace_device_n_has_only_cmyk(fz_context *ctx, const fz_colorspace *cs)
-{
- return (cs == NULL ? 0 : ((cs->flags & FZ_CS_HAS_CMYK_AND_SPOTS) == FZ_CS_HAS_CMYK));
-}
-
-int fz_colorspace_device_n_has_cmyk(fz_context *ctx, const fz_colorspace *cs)
-{
- return (cs == NULL ? 0 : !!(cs->flags & FZ_CS_HAS_CMYK));
-}
-
-int fz_colorspace_is_device_gray(fz_context *ctx, const fz_colorspace *cs)
-{
- return (cs == NULL ? 0 : !!(cs->flags & FZ_CS_DEVICE_GRAY));
-}
diff --git a/source/fitz/draw-device.c b/source/fitz/draw-device.c
index 09470ea5..7d4f3114 100644
--- a/source/fitz/draw-device.c
+++ b/source/fitz/draw-device.c
@@ -125,20 +125,22 @@ static fz_colorspace *fz_default_colorspace(fz_context *ctx, fz_default_colorspa
if (default_cs == NULL)
return cs;
- switch (fz_colorspace_n(ctx, cs))
+ switch (fz_colorspace_type(ctx, cs))
{
- case 1:
+ case FZ_COLORSPACE_GRAY:
if (cs == fz_device_gray(ctx))
return fz_default_gray(ctx, default_cs);
break;
- case 3:
+ case FZ_COLORSPACE_RGB:
if (cs == fz_device_rgb(ctx))
return fz_default_rgb(ctx, default_cs);
break;
- case 4:
+ case FZ_COLORSPACE_CMYK:
if (cs == fz_device_cmyk(ctx))
return fz_default_cmyk(ctx, default_cs);
break;
+ default:
+ break;
}
return cs;
}
@@ -1667,7 +1669,7 @@ convert_pixmap_for_painting(fz_context *ctx, fz_pixmap *pixmap, fz_colorspace *m
converted = fz_convert_pixmap(ctx, pixmap, model, NULL, dev->default_cs, color_params, 1);
if (*eop)
{
- if (fz_colorspace_n(ctx, model) != 4)
+ if (fz_colorspace_type(ctx, model) != FZ_COLORSPACE_CMYK)
{
/* Can only overprint to CMYK based spaces */
*eop = NULL;
@@ -1773,13 +1775,21 @@ fz_draw_fill_image(fz_context *ctx, fz_device *devp, fz_image *image, const fz_m
if (state->blendmode & FZ_BLEND_KNOCKOUT)
state = fz_knockout_begin(ctx, dev);
- after = 0;
- if (src_cs == fz_device_gray(ctx))
- after = 1;
- else if (fz_colorspace_is_indexed(ctx, src_cs))
- {}
- else if (fz_colorspace_n(ctx, src_cs) <= fz_colorspace_n(ctx, model))
+ switch (fz_colorspace_type(ctx, src_cs))
+ {
+ case FZ_COLORSPACE_GRAY:
after = 1;
+ break;
+ case FZ_COLORSPACE_INDEXED:
+ after = 0;
+ break;
+ default:
+ if (fz_colorspace_n(ctx, src_cs) <= fz_colorspace_n(ctx, model))
+ after = 1;
+ else
+ after = 0;
+ break;
+ }
if (conversion_required && !after)
pixmap = convert_pixmap_for_painting(ctx, pixmap, model, src_cs, state->dest, color_params, dev, &eop);
diff --git a/source/fitz/image.c b/source/fitz/image.c
index 6cf000b2..b61a606d 100644
--- a/source/fitz/image.c
+++ b/source/fitz/image.c
@@ -542,7 +542,7 @@ compressed_image_get_pixmap(fz_context *ctx, fz_image *image_, fz_irect *subarea
/* CMYK JPEGs in XPS documents have to be inverted */
if (image->super.invert_cmyk_jpeg &&
image->buffer->params.type == FZ_IMAGE_JPEG &&
- image->super.colorspace == fz_device_cmyk(ctx) &&
+ fz_colorspace_is_cmyk(ctx, image->super.colorspace) &&
image->buffer->params.u.jpeg.color_transform)
{
fz_invert_pixmap(ctx, tile);
diff --git a/source/fitz/output-tga.c b/source/fitz/output-tga.c
index 44b9ed88..51ebe5db 100644
--- a/source/fitz/output-tga.c
+++ b/source/fitz/output-tga.c
@@ -74,8 +74,7 @@ fz_save_pixmap_as_tga(fz_context *ctx, fz_pixmap *pixmap, const char *filename)
void
fz_write_pixmap_as_tga(fz_context *ctx, fz_output *out, fz_pixmap *pixmap)
{
- fz_band_writer *writer = fz_new_tga_band_writer(ctx, out, pixmap->colorspace == fz_device_bgr(ctx));
-
+ fz_band_writer *writer = fz_new_tga_band_writer(ctx, out, fz_colorspace_is_bgr(ctx, pixmap->colorspace));
fz_try(ctx)
{
fz_write_header(ctx, writer, pixmap->w, pixmap->h, pixmap->n, pixmap->alpha, pixmap->xres, pixmap->yres, 0, pixmap->colorspace, pixmap->seps);
diff --git a/source/fitz/test-device.c b/source/fitz/test-device.c
index f299613e..8b2a7639 100644
--- a/source/fitz/test-device.c
+++ b/source/fitz/test-device.c
@@ -31,7 +31,7 @@ is_rgb_color_u8(int threshold_u8, int r, int g, int b)
static void
fz_test_color(fz_context *ctx, fz_test_device *t, fz_colorspace *colorspace, const float *color, const fz_color_params *color_params)
{
- if (!*t->is_color && colorspace && colorspace != fz_device_gray(ctx))
+ if (!*t->is_color && colorspace && fz_colorspace_type(ctx, colorspace) != FZ_COLORSPACE_GRAY)
{
if (colorspace == fz_device_rgb(ctx))
{
@@ -153,7 +153,7 @@ fz_test_fill_shade(fz_context *ctx, fz_device *dev_, fz_shade *shade, const fz_m
{
if ((dev->options & FZ_TEST_OPT_SHADINGS) == 0)
{
- if (shade->colorspace != fz_device_gray(ctx))
+ if (fz_colorspace_type(ctx, shade->colorspace) != FZ_COLORSPACE_GRAY)
{
/* Don't test every pixel. Upgrade us from "black and white" to "probably color" */
if (*dev->is_color == 0)
@@ -197,7 +197,7 @@ fz_test_fill_image(fz_context *ctx, fz_device *dev_, fz_image *image, const fz_m
unsigned char *s;
fz_compressed_buffer *buffer;
- if (*dev->is_color || !image->colorspace || image->colorspace == fz_device_gray(ctx))
+ if (*dev->is_color || !image->colorspace || fz_colorspace_is_gray(ctx, image->colorspace))
break;
if ((dev->options & FZ_TEST_OPT_IMAGES) == 0)
diff --git a/source/fitz/util.c b/source/fitz/util.c
index 02dc92c4..c78ab641 100644
--- a/source/fitz/util.c
+++ b/source/fitz/util.c
@@ -477,16 +477,18 @@ fz_write_image_as_data_uri(fz_context *ctx, fz_output *out, fz_image *image)
{
fz_compressed_buffer *cbuf;
fz_buffer *buf;
- int n;
- n = fz_colorspace_n(ctx, image->colorspace);
cbuf = fz_compressed_image_buffer(ctx, image);
- if (cbuf && cbuf->params.type == FZ_IMAGE_JPEG && (n == 1 || n == 3))
+ if (cbuf && cbuf->params.type == FZ_IMAGE_JPEG)
{
- fz_write_string(ctx, out, "image/jpeg;base64,");
- fz_write_base64_buffer(ctx, out, cbuf->buffer, 1);
- return;
+ int type = fz_colorspace_type(ctx, image->colorspace);
+ if (type == FZ_COLORSPACE_GRAY || type == FZ_COLORSPACE_RGB)
+ {
+ fz_write_string(ctx, out, "image/jpeg;base64,");
+ fz_write_base64_buffer(ctx, out, cbuf->buffer, 1);
+ return;
+ }
}
if (cbuf && cbuf->params.type == FZ_IMAGE_PNG)
{
diff --git a/source/pdf/pdf-colorspace.c b/source/pdf/pdf-colorspace.c
index 44105f7b..44615977 100644
--- a/source/pdf/pdf-colorspace.c
+++ b/source/pdf/pdf-colorspace.c
@@ -173,14 +173,17 @@ load_devicen(fz_context *ctx, pdf_obj *array)
pdf_obj *tintobj = pdf_array_get(ctx, array, 3);
fz_colorspace *base;
pdf_function *tint = NULL;
+ char *colorspace_name;
int i, n;
- char *colorspace_name = "DeviceN";
fz_var(tint);
fz_var(devn);
if (pdf_is_array(ctx, nameobj))
+ {
n = pdf_array_len(ctx, nameobj);
+ colorspace_name = "DeviceN";
+ }
else
{
n = 1;
@@ -204,7 +207,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, FZ_CS_SUBTRACTIVE | FZ_CS_DEVICE_N,
+ cs = fz_new_colorspace(ctx, colorspace_name, FZ_COLORSPACE_SEPARATION, 0, n,
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));
diff --git a/source/pdf/pdf-device.c b/source/pdf/pdf-device.c
index 314dc85e..c45dda40 100644
--- a/source/pdf/pdf-device.c
+++ b/source/pdf/pdf-device.c
@@ -567,19 +567,24 @@ pdf_dev_new_form(fz_context *ctx, pdf_obj **form_ref, pdf_device *pdev, const fz
group = pdf_new_dict(ctx, doc, 5);
fz_try(ctx)
{
- int n = fz_colorspace_n(ctx, colorspace);
pdf_dict_put_drop(ctx, group, PDF_NAME_Type, PDF_NAME_Group);
pdf_dict_put_drop(ctx, group, PDF_NAME_S, PDF_NAME_Transparency);
pdf_dict_put_drop(ctx, group, PDF_NAME_K, pdf_new_bool(ctx, doc, knockout));
pdf_dict_put_drop(ctx, group, PDF_NAME_I, pdf_new_bool(ctx, doc, isolated));
- if (n == 0)
- {}
- if (n == 1)
+ switch (fz_colorspace_type(ctx, colorspace))
+ {
+ case FZ_COLORSPACE_GRAY:
pdf_dict_put_drop(ctx, group, PDF_NAME_CS, PDF_NAME_DeviceGray);
- else if (n == 4)
- pdf_dict_put_drop(ctx, group, PDF_NAME_CS, PDF_NAME_DeviceCMYK);
- else
+ break;
+ case FZ_COLORSPACE_RGB:
pdf_dict_put_drop(ctx, group, PDF_NAME_CS, PDF_NAME_DeviceRGB);
+ break;
+ case FZ_COLORSPACE_CMYK:
+ pdf_dict_put_drop(ctx, group, PDF_NAME_CS, PDF_NAME_DeviceCMYK);
+ break;
+ default:
+ break;
+ }
group_ref = pdev->groups[num].ref = pdf_add_object(ctx, doc, group);
}
fz_always(ctx)
diff --git a/source/pdf/pdf-image.c b/source/pdf/pdf-image.c
index b7768074..eeb4f0f2 100644
--- a/source/pdf/pdf-image.c
+++ b/source/pdf/pdf-image.c
@@ -468,47 +468,58 @@ raw_or_unknown_compression:
pdf_dict_put_drop(ctx, imobj, PDF_NAME_BitsPerComponent, pdf_new_int(ctx, doc, image->bpc));
cs = pixmap ? pixmap->colorspace : image->colorspace;
- n = fz_colorspace_n(ctx, cs);
-
- if (fz_colorspace_is_indexed(ctx, cs))
+ switch (fz_colorspace_type(ctx, cs))
{
- fz_colorspace *basecs;
- unsigned char *lookup = NULL;
- int high = 0;
- int basen;
- pdf_obj *arr;
-
- lookup = fz_indexed_colorspace_palette(ctx, cs, &high);
- basecs = fz_colorspace_base(ctx, cs);
- basen = fz_colorspace_n(ctx, basecs);
-
- pdf_dict_put_drop(ctx, imobj, PDF_NAME_ColorSpace, arr = pdf_new_array(ctx, doc, 4));
-
- pdf_array_put_drop(ctx, arr, 0, PDF_NAME_Indexed);
- if (basen <= 1)
- pdf_array_put_drop(ctx, arr, 1, PDF_NAME_DeviceGray);
- else if (basen == 3)
- // TODO: Lab colorspace?
- pdf_array_put_drop(ctx, arr, 1, PDF_NAME_DeviceRGB);
- else if (basen == 4)
- pdf_array_put_drop(ctx, arr, 1, PDF_NAME_DeviceCMYK);
- else
- // TODO: convert to RGB!
- fz_throw(ctx, FZ_ERROR_GENERIC, "only indexed Gray, RGB, and CMYK colorspaces supported");
-
- pdf_array_put_drop(ctx, arr, 2, pdf_new_int(ctx, doc, high));
- pdf_array_put_drop(ctx, arr, 3, pdf_new_string(ctx, doc, (char *) lookup, basen * (high + 1)));
- }
- else if (n <= 1)
+ case FZ_COLORSPACE_INDEXED:
+ {
+ fz_colorspace *basecs;
+ unsigned char *lookup = NULL;
+ int high = 0;
+ int basen;
+ pdf_obj *arr;
+
+ lookup = fz_indexed_colorspace_palette(ctx, cs, &high);
+ basecs = fz_colorspace_base(ctx, cs);
+ basen = fz_colorspace_n(ctx, basecs);
+
+ pdf_dict_put_drop(ctx, imobj, PDF_NAME_ColorSpace, arr = pdf_new_array(ctx, doc, 4));
+
+ pdf_array_put_drop(ctx, arr, 0, PDF_NAME_Indexed);
+ switch (fz_colorspace_type(ctx, basecs))
+ {
+ case FZ_COLORSPACE_GRAY:
+ pdf_array_put_drop(ctx, arr, 1, PDF_NAME_DeviceGray);
+ break;
+ case FZ_COLORSPACE_RGB:
+ pdf_array_put_drop(ctx, arr, 1, PDF_NAME_DeviceRGB);
+ break;
+ case FZ_COLORSPACE_CMYK:
+ pdf_array_put_drop(ctx, arr, 1, PDF_NAME_DeviceCMYK);
+ break;
+ default:
+ // TODO: convert to RGB!
+ fz_throw(ctx, FZ_ERROR_GENERIC, "only indexed Gray, RGB, and CMYK colorspaces supported");
+ break;
+ }
+
+ pdf_array_put_drop(ctx, arr, 2, pdf_new_int(ctx, doc, high));
+ pdf_array_put_drop(ctx, arr, 3, pdf_new_string(ctx, doc, (char *) lookup, basen * (high + 1)));
+ }
+ break;
+ case FZ_COLORSPACE_GRAY:
pdf_dict_put_drop(ctx, imobj, PDF_NAME_ColorSpace, PDF_NAME_DeviceGray);
- else if (n == 3)
- // TODO: Lab colorspace?
+ break;
+ case FZ_COLORSPACE_RGB:
pdf_dict_put_drop(ctx, imobj, PDF_NAME_ColorSpace, PDF_NAME_DeviceRGB);
- else if (n == 4)
+ break;
+ case FZ_COLORSPACE_CMYK:
pdf_dict_put_drop(ctx, imobj, PDF_NAME_ColorSpace, PDF_NAME_DeviceCMYK);
- else
+ break;
+ default:
// TODO: convert to RGB!
fz_throw(ctx, FZ_ERROR_GENERIC, "only Gray, RGB, and CMYK colorspaces supported");
+ break;
+ }
}
if (image->mask)
diff --git a/source/pdf/pdf-interpret.c b/source/pdf/pdf-interpret.c
index 8b44079e..6ce63eb6 100644
--- a/source/pdf/pdf-interpret.c
+++ b/source/pdf/pdf-interpret.c
@@ -280,7 +280,7 @@ pdf_process_extgstate(fz_context *ctx, pdf_processor *proc, pdf_csi *csi, pdf_ob
/* Which in CMYK means not all zeros! This should really be
* a test for subtractive color spaces, but this will have
* to do for now. */
- if (colorspace == fz_device_cmyk(ctx))
+ if (fz_colorspace_is_cmyk(ctx, colorspace))
softmask_bc[3] = 1.0f;
fz_drop_colorspace(ctx, colorspace);
diff --git a/source/pdf/pdf-op-buffer.c b/source/pdf/pdf-op-buffer.c
index 69707843..95edea46 100644
--- a/source/pdf/pdf-op-buffer.c
+++ b/source/pdf/pdf-op-buffer.c
@@ -599,6 +599,8 @@ pdf_out_BI(fz_context *ctx, pdf_processor *proc, fz_image *img)
fz_write_string(ctx, out, "/CS/CMYK\n");
else if (fz_colorspace_is_indexed(ctx, img->colorspace))
fz_write_string(ctx, out, "/CS/I\n");
+ else
+ fz_throw(ctx, FZ_ERROR_GENERIC, "BI operator can only show mask, Gray, RGB, CMYK, or Indexed images");
if (img->interpolate)
fz_write_string(ctx, out, "/I true\n");
fz_write_string(ctx, out, "/D[");
diff --git a/source/tools/mudraw.c b/source/tools/mudraw.c
index ccae16a2..c9650993 100644
--- a/source/tools/mudraw.c
+++ b/source/tools/mudraw.c
@@ -848,7 +848,7 @@ static void dodrawpage(fz_context *ctx, fz_page *page, fz_display_list *list, in
else if (output_format == OUT_PSD)
bander = fz_new_psd_band_writer(ctx, out);
else if (output_format == OUT_TGA)
- bander = fz_new_tga_band_writer(ctx, out, colorspace == fz_device_bgr(ctx));
+ bander = fz_new_tga_band_writer(ctx, out, fz_colorspace_is_bgr(ctx, colorspace));
else if (output_format == OUT_PWG)
{
if (out_cs == CS_MONO)
@@ -1798,17 +1798,17 @@ int mudraw_main(int argc, char **argv)
case CS_MONO:
case CS_GRAY:
case CS_GRAY_ALPHA:
- if (fz_colorspace_n(ctx, colorspace) == 1)
+ if (fz_colorspace_is_gray(ctx, colorspace))
okay = 1;
break;
case CS_RGB:
case CS_RGB_ALPHA:
- if (fz_colorspace_n(ctx, colorspace) == 3)
+ if (fz_colorspace_is_rgb(ctx, colorspace))
okay = 1;
break;
case CS_CMYK:
case CS_CMYK_ALPHA:
- if (fz_colorspace_n(ctx, colorspace) == 4)
+ if (fz_colorspace_is_cmyk(ctx, colorspace))
okay = 1;
break;
}