diff options
-rw-r--r-- | include/mupdf/fitz/colorspace.h | 64 | ||||
-rw-r--r-- | source/fitz/colorspace-imp.h | 9 | ||||
-rw-r--r-- | source/fitz/colorspace.c | 235 | ||||
-rw-r--r-- | source/fitz/draw-device.c | 32 | ||||
-rw-r--r-- | source/fitz/image.c | 2 | ||||
-rw-r--r-- | source/fitz/output-tga.c | 3 | ||||
-rw-r--r-- | source/fitz/test-device.c | 6 | ||||
-rw-r--r-- | source/fitz/util.c | 14 | ||||
-rw-r--r-- | source/pdf/pdf-colorspace.c | 7 | ||||
-rw-r--r-- | source/pdf/pdf-device.c | 19 | ||||
-rw-r--r-- | source/pdf/pdf-image.c | 81 | ||||
-rw-r--r-- | source/pdf/pdf-interpret.c | 2 | ||||
-rw-r--r-- | source/pdf/pdf-op-buffer.c | 2 | ||||
-rw-r--r-- | source/tools/mudraw.c | 8 |
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; } |