summaryrefslogtreecommitdiff
path: root/source/fitz/colorspace.c
diff options
context:
space:
mode:
Diffstat (limited to 'source/fitz/colorspace.c')
-rw-r--r--source/fitz/colorspace.c394
1 files changed, 315 insertions, 79 deletions
diff --git a/source/fitz/colorspace.c b/source/fitz/colorspace.c
index 29ad18d3..3e322bd9 100644
--- a/source/fitz/colorspace.c
+++ b/source/fitz/colorspace.c
@@ -32,10 +32,10 @@ fz_cmm_transform_color(fz_context *ctx, fz_icclink *link, unsigned short *dst, c
}
void
-fz_cmm_init_link(fz_context *ctx, fz_icclink *link, const fz_color_params *rend, int cmm_flags, int num_bytes, int extras, const fz_iccprofile *src, const fz_iccprofile *prf, const fz_iccprofile *des)
+fz_cmm_init_link(fz_context *ctx, fz_icclink *link, const fz_iccprofile *dst, int dst_extras, const fz_iccprofile *src, int src_extras, const fz_iccprofile *prf, const fz_color_params *rend, int cmm_flags, int num_bytes, int copy_spots)
{
if (ctx && ctx->colorspace && ctx->colorspace->cmm && ctx->cmm_instance)
- ctx->colorspace->cmm->init_link(ctx->cmm_instance, link, rend, cmm_flags, num_bytes, extras, src, prf, des);
+ ctx->colorspace->cmm->init_link(ctx->cmm_instance, link, dst, dst_extras, src, src_extras, prf, rend, cmm_flags, num_bytes, copy_spots);
}
void
@@ -201,7 +201,9 @@ struct fz_link_key_s {
unsigned char src_md5[16];
unsigned char dst_md5[16];
fz_color_params rend;
- int extras;
+ int src_extras;
+ int dst_extras;
+ int copy_spots;
int depth;
int proof;
};
@@ -227,7 +229,9 @@ fz_cmp_link_key(fz_context *ctx, void *k0_, void *k1_)
fz_link_key *k0 = (fz_link_key *)k0_;
fz_link_key *k1 = (fz_link_key *)k1_;
return k0->proof == k1->proof &&
- k0->extras == k1->extras &&
+ k0->src_extras == k1->src_extras &&
+ k0->dst_extras == k1->dst_extras &&
+ k0->copy_spots == k1->copy_spots &&
k0->depth == k1->depth &&
k0->rend.bp == k1->rend.bp &&
k0->rend.ri == k1->rend.ri &&
@@ -260,10 +264,13 @@ fz_make_hash_link_key(fz_context *ctx, fz_store_hash *hash, void *key_)
fz_link_key *key = (fz_link_key *)key_;
memcpy(hash->u.link.dst_md5, key->dst_md5, 16);
memcpy(hash->u.link.src_md5, key->src_md5, 16);
- hash->u.link.ri_bp = (key->rend.ri<<1) | key->rend.bp;
- hash->u.link.extras = key->extras;
- hash->u.link.depth = key->depth;
+ hash->u.link.ri = key->rend.ri;
+ hash->u.link.bp = key->rend.bp;
+ hash->u.link.src_extras = key->src_extras;
+ hash->u.link.dst_extras = key->dst_extras;
+ hash->u.link.bpp16 = key->depth == 2;
hash->u.link.proof = key->proof;
+ hash->u.link.copy_spots = key->copy_spots;
return 1;
}
@@ -319,14 +326,11 @@ get_base_icc_profile(fz_context *ctx, const fz_colorspace *cs)
}
static fz_icclink *
-fz_new_icc_link(fz_context *ctx, fz_iccprofile *src, fz_iccprofile *prf, fz_iccprofile *dst, const fz_color_params *rend, int num_bytes, int extras)
+fz_new_icc_link(fz_context *ctx, fz_iccprofile *dst, int dst_extras, fz_iccprofile *src, int src_extras, fz_iccprofile *prf, const fz_color_params *rend, int num_bytes, int copy_extras)
{
fz_icclink *link = fz_malloc_struct(ctx, fz_icclink);
FZ_INIT_STORABLE(link, 1, fz_drop_link_imp);
- link->num_in = src->num_devcomp;
- link->num_out = dst->num_devcomp;
-
if (memcmp(src->md5, dst->md5, 16) == 0 && prf == NULL)
{
link->is_identity = 1;
@@ -334,7 +338,7 @@ fz_new_icc_link(fz_context *ctx, fz_iccprofile *src, fz_iccprofile *prf, fz_iccp
}
fz_try(ctx)
- fz_cmm_init_link(ctx, link, rend, 0, num_bytes, extras, src, prf, dst);
+ fz_cmm_init_link(ctx, link, dst, dst_extras, src, src_extras, prf, rend, 0, num_bytes, copy_extras);
fz_catch(ctx)
{
fz_free(ctx, link);
@@ -378,7 +382,7 @@ fz_icc_from_cal(fz_context *ctx, const fz_colorspace *cs)
}
static fz_icclink *
-fz_get_icc_link(fz_context *ctx, const fz_colorspace *src, const fz_colorspace *prf, const fz_colorspace *dst, const fz_color_params *rend, int num_bytes, int extras, int *src_n)
+fz_get_icc_link(fz_context *ctx, const fz_colorspace *dst, int dst_extras, const fz_colorspace *src, int src_extras, const fz_colorspace *prf, const fz_color_params *rend, int num_bytes, int copy_spots, int *src_n)
{
fz_icclink *link = NULL;
fz_iccprofile *src_icc = NULL;
@@ -387,6 +391,8 @@ fz_get_icc_link(fz_context *ctx, const fz_colorspace *src, const fz_colorspace *
fz_link_key *key = NULL;
fz_icclink *new_link;
+ assert(!copy_spots || src_extras == dst_extras);
+
if (prf != NULL)
prf_icc = prf->data;
@@ -440,6 +446,9 @@ fz_get_icc_link(fz_context *ctx, const fz_colorspace *src, const fz_colorspace *
fz_var(link);
fz_var(key);
+ if (rend == NULL)
+ rend = fz_default_color_params(ctx);
+
fz_try(ctx)
{
/* Check the storable to see if we have a copy. */
@@ -449,15 +458,17 @@ fz_get_icc_link(fz_context *ctx, const fz_colorspace *src, const fz_colorspace *
memcpy(&key->src_md5, src_icc->md5, 16);
key->rend.ri = rend->ri;
key->rend.bp = rend->bp;
- key->extras = extras;
+ key->src_extras = src_extras;
+ key->dst_extras = dst_extras;
key->depth = num_bytes;
key->proof = (prf_icc != NULL);
+ key->copy_spots = copy_spots;
link = fz_find_item(ctx, fz_drop_link_imp, key, &fz_link_store_type);
/* Not found. Make new one add to store. */
if (link == NULL)
{
- link = fz_new_icc_link(ctx, src_icc, prf_icc, dst_icc, rend, num_bytes, extras);
+ link = fz_new_icc_link(ctx, dst_icc, dst_extras, src_icc, src_extras, prf_icc, rend, num_bytes, copy_spots);
new_link = fz_store_item(ctx, key, link, sizeof(fz_icclink), &fz_link_store_type);
if (new_link != NULL)
{
@@ -828,21 +839,23 @@ 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, const 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, int copy_spots)
{
unsigned char *s = src->samples;
unsigned char *d = dst->samples;
size_t w = src->w;
int h = src->h;
+ int sn = src->n;
int ss = src->s;
int sa = src->alpha;
+ int dn = dst->n;
int ds = dst->s;
int da = dst->alpha;
- ptrdiff_t d_line_inc = dst->stride - w * (da + ds + 3);
- ptrdiff_t s_line_inc = src->stride - w * (sa + ss + 1);
+ ptrdiff_t d_line_inc = dst->stride - w * dn;
+ ptrdiff_t s_line_inc = src->stride - w * sn;
- /* Spots must match, and we can never drop alpha (but we can invent it) */
- if (dst->n != 3 + ds + da || src->n != 1 + ss + sa || ss != ds || (!da && sa))
+ /* If copying spots, they must match, and we can never drop alpha (but we can invent it) */
+ if ((copy_spots && ss != ds) || (!da && sa))
{
assert("This should never happen" == NULL);
fz_throw(ctx, FZ_ERROR_GENERIC, "Cannot convert between incompatible pixmaps");
@@ -917,7 +930,7 @@ static void fast_gray_to_rgb(fz_context *ctx, fz_pixmap *dst, fz_pixmap *src, fz
}
}
}
- else
+ else if (copy_spots)
{
/* Slower, spots capable version */
int i;
@@ -940,23 +953,44 @@ static void fast_gray_to_rgb(fz_context *ctx, fz_pixmap *dst, fz_pixmap *src, fz
s += s_line_inc;
}
}
+ else
+ {
+ while (h--)
+ {
+ size_t ww = w;
+ while (ww--)
+ {
+ d[0] = s[0];
+ d[1] = s[0];
+ d[2] = s[0];
+ s += sn;
+ d += dn;
+ if (da)
+ d[-1] = sa ? s[-1] : 255;
+ }
+ d += d_line_inc;
+ s += s_line_inc;
+ }
+ }
}
-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)
+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, int copy_spots)
{
unsigned char *s = src->samples;
unsigned char *d = dst->samples;
size_t w = src->w;
int h = src->h;
+ int sn = src->n;
int ss = src->s;
int sa = src->alpha;
+ int dn = dst->n;
int ds = dst->s;
int da = dst->alpha;
- ptrdiff_t d_line_inc = dst->stride - w * (da + ds + 4);
- ptrdiff_t s_line_inc = src->stride - w * (sa + ss + 1);
+ ptrdiff_t d_line_inc = dst->stride - w * dn;
+ ptrdiff_t s_line_inc = src->stride - w * sn;
- /* Spots must match, and we can never drop alpha (but we can invent it) */
- if (dst->n != 4 + ds + da || src->n != 1 + ss + sa || ss != ds || (!da && sa))
+ /* If copying spots, they must match, and we can never drop alpha (but we can invent it) */
+ if ((copy_spots && ss != ds) || (!da && sa))
{
assert("This should never happen" == NULL);
fz_throw(ctx, FZ_ERROR_GENERIC, "Cannot convert between incompatible pixmaps");
@@ -1034,7 +1068,7 @@ static void fast_gray_to_cmyk(fz_context *ctx, fz_pixmap *dst, fz_pixmap *src, f
}
}
}
- else
+ else if (copy_spots)
{
/* Slower, spots capable version */
int i;
@@ -1058,23 +1092,45 @@ static void fast_gray_to_cmyk(fz_context *ctx, fz_pixmap *dst, fz_pixmap *src, f
s += s_line_inc;
}
}
+ else
+ {
+ while (h--)
+ {
+ size_t ww = w;
+ while (ww--)
+ {
+ d[0] = 0;
+ d[1] = 0;
+ d[2] = 0;
+ d[3] = s[0];
+ s += sn;
+ d += dn;
+ if (da)
+ d[-1] = sa ? s[-1] : 255;
+ }
+ d += d_line_inc;
+ s += s_line_inc;
+ }
+ }
}
-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)
+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, int copy_spots)
{
unsigned char *s = src->samples;
unsigned char *d = dst->samples;
size_t w = src->w;
int h = src->h;
+ int sn = src->n;
int ss = src->s;
int sa = src->alpha;
+ int dn = dst->n;
int ds = dst->s;
int da = dst->alpha;
- ptrdiff_t d_line_inc = dst->stride - w * (da + ds + 1);
- ptrdiff_t s_line_inc = src->stride - w * (sa + ss + 3);
+ ptrdiff_t d_line_inc = dst->stride - w * dn;
+ ptrdiff_t s_line_inc = src->stride - w * sn;
- /* Spots must match, and we can never drop alpha (but we can invent it) */
- if (dst->n != 1 + ds + da || src->n != 3 + ss + sa || ss != ds || (!da && sa))
+ /* If copying spots, they must match, and we can never drop alpha (but we can invent it) */
+ if ((copy_spots && ss != ds) || (!da && sa))
{
assert("This should never happen" == NULL);
fz_throw(ctx, FZ_ERROR_GENERIC, "Cannot convert between incompatible pixmaps");
@@ -1143,7 +1199,7 @@ static void fast_rgb_to_gray(fz_context *ctx, fz_pixmap *dst, fz_pixmap *src, fz
}
}
}
- else
+ else if (copy_spots)
{
/* Slower, spots capable version */
int i;
@@ -1164,23 +1220,42 @@ static void fast_rgb_to_gray(fz_context *ctx, fz_pixmap *dst, fz_pixmap *src, fz
s += s_line_inc;
}
}
+ else
+ {
+ while (h--)
+ {
+ size_t ww = w;
+ while (ww--)
+ {
+ d[0] = ((s[0]+1) * 77 + (s[1]+1) * 150 + (s[2]+1) * 28) >> 8;
+ s += sn;
+ d += dn;
+ if (da)
+ d[-1] = sa ? s[-1] : 255;
+ }
+ d += d_line_inc;
+ s += s_line_inc;
+ }
+ }
}
-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)
+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, int copy_spots)
{
unsigned char *s = src->samples;
unsigned char *d = dst->samples;
size_t w = src->w;
int h = src->h;
+ int sn = src->n;
int ss = src->s;
int sa = src->alpha;
+ int dn = dst->n;
int ds = dst->s;
int da = dst->alpha;
- ptrdiff_t d_line_inc = dst->stride - w * (da + ds + 1);
- ptrdiff_t s_line_inc = src->stride - w * (sa + ss + 3);
+ ptrdiff_t d_line_inc = dst->stride - w * dn;
+ ptrdiff_t s_line_inc = src->stride - w * sn;
- /* Spots must match, and we can never drop alpha (but we can invent it) */
- if (dst->n != 1 + ds + da || src->n != 3 + ss + sa || ss != ds || (!da && sa))
+ /* If copying spots, they must match, and we can never drop alpha (but we can invent it) */
+ if ((copy_spots && ss != ds) || (!da && sa))
{
assert("This should never happen" == NULL);
fz_throw(ctx, FZ_ERROR_GENERIC, "Cannot convert between incompatible pixmaps");
@@ -1251,7 +1326,7 @@ static void fast_bgr_to_gray(fz_context *ctx, fz_pixmap *dst, fz_pixmap *src, fz
}
}
}
- else
+ else if (copy_spots)
{
/* Slower, spots capable version */
while (h--)
@@ -1272,23 +1347,43 @@ static void fast_bgr_to_gray(fz_context *ctx, fz_pixmap *dst, fz_pixmap *src, fz
s += s_line_inc;
}
}
+ else
+ {
+ /* Slower, spots capable version */
+ while (h--)
+ {
+ size_t ww = w;
+ while (ww--)
+ {
+ d[0] = ((s[0]+1) * 28 + (s[1]+1) * 150 + (s[2]+1) * 77) >> 8;
+ s += sn;
+ d += dn;
+ if (da)
+ d[-1] = sa ? s[-1] : 255;
+ }
+ d += d_line_inc;
+ s += s_line_inc;
+ }
+ }
}
-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)
+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, int copy_spots)
{
unsigned char *s = src->samples;
unsigned char *d = dst->samples;
size_t w = src->w;
int h = src->h;
+ int sn = src->n;
int ss = src->s;
int sa = src->alpha;
+ int dn = dst->n;
int ds = dst->s;
int da = dst->alpha;
- ptrdiff_t d_line_inc = dst->stride - w * (da + ds + 4);
- ptrdiff_t s_line_inc = src->stride - w * (sa + ss + 3);
+ ptrdiff_t d_line_inc = dst->stride - w * dn;
+ ptrdiff_t s_line_inc = src->stride - w * sn;
/* Spots must match, and we can never drop alpha (but we can invent it) */
- if (dst->n != 4 + ds + da || src->n != 3 + ss + sa || ss != ds || (!da && sa))
+ if ((copy_spots || ss != ds) || (!da && sa))
{
assert("This should never happen" == NULL);
fz_throw(ctx, FZ_ERROR_GENERIC, "Cannot convert between incompatible pixmaps");
@@ -1378,7 +1473,7 @@ static void fast_rgb_to_cmyk(fz_context *ctx, fz_pixmap *dst, fz_pixmap *src, fz
}
}
}
- else
+ else if (copy_spots)
{
/* Slower, spots capable version */
while (h--)
@@ -1406,23 +1501,49 @@ static void fast_rgb_to_cmyk(fz_context *ctx, fz_pixmap *dst, fz_pixmap *src, fz
s += s_line_inc;
}
}
+ else
+ {
+ while (h--)
+ {
+ size_t ww = w;
+ while (ww--)
+ {
+ unsigned char c = s[0];
+ unsigned char m = s[1];
+ unsigned char y = s[2];
+ unsigned char k = (unsigned char)(255 - fz_maxi(c, fz_maxi(m, y)));
+ d[0] = c + k;
+ d[1] = m + k;
+ d[2] = y + k;
+ d[3] = 255 - k;
+ s += sn;
+ d += dn;
+ if (da)
+ d[-1] = sa ? s[-1] : 255;
+ }
+ d += d_line_inc;
+ s += s_line_inc;
+ }
+ }
}
-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)
+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, int copy_spots)
{
unsigned char *s = src->samples;
unsigned char *d = dst->samples;
size_t w = src->w;
int h = src->h;
+ int sn = src->n;
int ss = src->s;
int sa = src->alpha;
+ int dn = dst->n;
int ds = dst->s;
int da = dst->alpha;
- ptrdiff_t d_line_inc = dst->stride - w * (da + ds + 4);
- ptrdiff_t s_line_inc = src->stride - w * (sa + ss + 3);
+ ptrdiff_t d_line_inc = dst->stride - w * dn;
+ ptrdiff_t s_line_inc = src->stride - w * sn;
/* Spots must match, and we can never drop alpha (but we can invent it) */
- if (dst->n != 4 + ds + da || src->n != 3 + ss + sa || ss != ds || (!da && sa))
+ if ((copy_spots && ss != ds) || (!da && sa))
{
assert("This should never happen" == NULL);
fz_throw(ctx, FZ_ERROR_GENERIC, "Cannot convert between incompatible pixmaps");
@@ -1512,7 +1633,7 @@ static void fast_bgr_to_cmyk(fz_context *ctx, fz_pixmap *dst, fz_pixmap *src, fz
}
}
}
- else
+ else if (copy_spots)
{
/* Slower, spots capable version */
while (h--)
@@ -1540,23 +1661,49 @@ static void fast_bgr_to_cmyk(fz_context *ctx, fz_pixmap *dst, fz_pixmap *src, fz
s += s_line_inc;
}
}
+ else
+ {
+ while (h--)
+ {
+ size_t ww = w;
+ while (ww--)
+ {
+ unsigned char c = s[2];
+ unsigned char m = s[1];
+ unsigned char y = s[0];
+ unsigned char k = (unsigned char)(255 - fz_maxi(c, fz_maxi(m, y)));
+ d[0] = c + k;
+ d[1] = m + k;
+ d[2] = y + k;
+ d[3] = 255 - k;
+ s += sn;
+ d += dn;
+ if (da)
+ d[-1] = sa ? s[-1] : 255;
+ }
+ d += d_line_inc;
+ s += s_line_inc;
+ }
+ }
}
-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)
+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, int copy_spots)
{
unsigned char *s = src->samples;
unsigned char *d = dst->samples;
size_t w = src->w;
int h = src->h;
+ int sn = src->n;
int ss = src->s;
int sa = src->alpha;
+ int dn = dst->n;
int ds = dst->s;
int da = dst->alpha;
- ptrdiff_t d_line_inc = dst->stride - w * (da + ds + 1);
- ptrdiff_t s_line_inc = src->stride - w * (sa + ss + 4);
+ ptrdiff_t d_line_inc = dst->stride - w * dn;
+ ptrdiff_t s_line_inc = src->stride - w * sn;
/* Spots must match, and we can never drop alpha (but we can invent it) */
- if (dst->n != 1 + ds + da || src->n != 4 + ss + sa || ss != ds || (!da && sa))
+ if ((copy_spots && ss != ds) || (!da && sa))
{
assert("This should never happen" == NULL);
fz_throw(ctx, FZ_ERROR_GENERIC, "Cannot convert between incompatible pixmaps");
@@ -1634,7 +1781,7 @@ static void fast_cmyk_to_gray(fz_context *ctx, fz_pixmap *dst, fz_pixmap *src, f
}
}
}
- else
+ else if (copy_spots)
{
/* Slower, spots capable version */
while (h--)
@@ -1658,6 +1805,26 @@ static void fast_cmyk_to_gray(fz_context *ctx, fz_pixmap *dst, fz_pixmap *src, f
s += s_line_inc;
}
}
+ else
+ {
+ while (h--)
+ {
+ size_t ww = w;
+ while (ww--)
+ {
+ unsigned char c = fz_mul255(255 - s[0], 77);
+ unsigned char m = fz_mul255(255 - s[1], 150);
+ unsigned char y = fz_mul255(255 - s[2], 28);
+ d[0] = (unsigned char)fz_maxi(s[3] - c - m - y, 0);
+ s += sn;
+ d += dn;
+ if (da)
+ d[-1] = sa ? s[-1] : 255;
+ }
+ d += d_line_inc;
+ s += s_line_inc;
+ }
+ }
}
#ifdef ARCH_ARM
@@ -1987,23 +2154,25 @@ 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, const 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, int copy_spots)
{
unsigned char *s = src->samples;
unsigned char *d = dst->samples;
size_t w = src->w;
int h = src->h;
+ int sn = src->n;
int ss = src->s;
int sa = src->alpha;
+ int dn = dst->n;
int ds = dst->s;
int da = dst->alpha;
- ptrdiff_t d_line_inc = dst->stride - w * (da + ds + 3);
- ptrdiff_t s_line_inc = src->stride - w * (sa + ss + 4);
+ ptrdiff_t d_line_inc = dst->stride - w * dn;
+ ptrdiff_t s_line_inc = src->stride - w * sn;
unsigned int C,M,Y,K;
unsigned char r,g,b;
/* Spots must match, and we can never drop alpha (but we can invent it) */
- if (dst->n != 3 + ds + da || src->n != 4 + ss + sa || ss != ds || (!da && sa))
+ if ((copy_spots && ss != ds) || (!da && sa))
{
assert("This should never happen" == NULL);
fz_throw(ctx, FZ_ERROR_GENERIC, "Cannot convert between incompatible pixmaps");
@@ -2033,13 +2202,13 @@ static void fast_cmyk_to_rgb(fz_context *ctx, fz_pixmap *dst, fz_pixmap *src, fz
{
if (sa)
{
- #ifdef ARCH_ARM
+#ifdef ARCH_ARM
if (h == 1)
{
fast_cmyk_to_rgb_ARM(d, s, w);
return;
}
- #endif
+#endif
while (h--)
{
size_t ww = w;
@@ -2096,7 +2265,7 @@ static void fast_cmyk_to_rgb(fz_context *ctx, fz_pixmap *dst, fz_pixmap *src, fz
}
}
}
- else
+ else if (copy_spots)
{
/* Slower, spots capable version */
while (h--)
@@ -2120,25 +2289,48 @@ static void fast_cmyk_to_rgb(fz_context *ctx, fz_pixmap *dst, fz_pixmap *src, fz
s += s_line_inc;
}
}
+ else
+ {
+ /* Slower, spots capable version */
+ while (h--)
+ {
+ size_t ww = w;
+ while (ww--)
+ {
+ cached_cmyk_conv(&r, &g, &b, &C, &M, &Y, &K, s[0], s[1], s[2], s[3]);
+ d[0] = r;
+ d[1] = g;
+ d[2] = b;
+ s += sn;
+ d += dn;
+ if (da)
+ d[-1] = sa ? s[-1] : 255;
+ }
+ d += d_line_inc;
+ s += s_line_inc;
+ }
+ }
}
-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)
+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, int copy_spots)
{
unsigned char *s = src->samples;
unsigned char *d = dst->samples;
size_t w = src->w;
int h = src->h;
+ int sn = src->n;
int ss = src->s;
int sa = src->alpha;
+ int dn = dst->n;
int ds = dst->s;
int da = dst->alpha;
- ptrdiff_t d_line_inc = dst->stride - w * (da + ds + 3);
- ptrdiff_t s_line_inc = src->stride - w * (sa + ss + 4);
+ ptrdiff_t d_line_inc = dst->stride - w * dn;
+ ptrdiff_t s_line_inc = src->stride - w * sn;
unsigned int C,M,Y,K;
unsigned char r,g,b;
/* Spots must match, and we can never drop alpha (but we can invent it) */
- if (dst->n != 3 + ds + da || src->n != 4 + ss + sa || ss != ds || (!da && sa))
+ if ((copy_spots && ss != ds) || (!da && sa))
{
assert("This should never happen" == NULL);
fz_throw(ctx, FZ_ERROR_GENERIC, "Cannot convert between incompatible pixmaps");
@@ -2227,7 +2419,7 @@ static void fast_cmyk_to_bgr(fz_context *ctx, fz_pixmap *dst, fz_pixmap *src, fz
}
}
}
- else
+ else if (copy_spots)
{
/* Slower, spots capable version */
while (h--)
@@ -2251,23 +2443,46 @@ static void fast_cmyk_to_bgr(fz_context *ctx, fz_pixmap *dst, fz_pixmap *src, fz
s += s_line_inc;
}
}
+ else
+ {
+ /* Slower, spots capable version */
+ while (h--)
+ {
+ size_t ww = w;
+ while (ww--)
+ {
+ cached_cmyk_conv(&r, &g, &b, &C, &M, &Y, &K, s[0], s[1], s[2], s[3]);
+ d[0] = b;
+ d[1] = g;
+ d[2] = r;
+ s += sn;
+ d += dn;
+ if (da)
+ d[-1] = sa ? s[-1] : 255;
+ }
+ d += d_line_inc;
+ s += s_line_inc;
+ }
+ }
}
-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)
+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, int copy_spots)
{
unsigned char *s = src->samples;
unsigned char *d = dst->samples;
size_t w = src->w;
int h = src->h;
+ int sn = src->n;
int ss = src->s;
int sa = src->alpha;
+ int dn = dst->n;
int ds = dst->s;
int da = dst->alpha;
- ptrdiff_t d_line_inc = dst->stride - w * (da + ds + 3);
- ptrdiff_t s_line_inc = src->stride - w * (sa + ss + 3);
+ ptrdiff_t d_line_inc = dst->stride - w * dn;
+ ptrdiff_t s_line_inc = src->stride - w * sn;
- /* Spots must match, and we can never drop alpha (but we can invent it) */
- if (dst->n != 3 + ds + da || src->n != 3 + ss + sa || ss != ds || (!da && sa))
+ /* If copying spots, they must match, and we can never drop alpha (but we can invent it) */
+ if ((copy_spots && ss != ds) || (!da && sa))
{
assert("This should never happen" == NULL);
fz_throw(ctx, FZ_ERROR_GENERIC, "Cannot convert between incompatible pixmaps");
@@ -2336,7 +2551,7 @@ static void fast_rgb_to_bgr(fz_context *ctx, fz_pixmap *dst, fz_pixmap *src, fz_
}
}
}
- else
+ else if (copy_spots)
{
/* Slower, spots capable version */
while (h--)
@@ -2359,10 +2574,29 @@ static void fast_rgb_to_bgr(fz_context *ctx, fz_pixmap *dst, fz_pixmap *src, fz_
s += s_line_inc;
}
}
+ else
+ {
+ while (h--)
+ {
+ size_t ww = w;
+ while (ww--)
+ {
+ d[0] = s[2];
+ d[1] = s[1];
+ d[2] = s[0];
+ s += sn;
+ d += dn;
+ if (da)
+ d[-1] = sa ? s[-1] : 255;
+ }
+ d += d_line_inc;
+ s += s_line_inc;
+ }
+ }
}
static void
-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)
+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, int copy_spots)
{
fz_colorspace *srcs = src->colorspace;
fz_colorspace *dsts = dst->colorspace;
@@ -2394,7 +2628,7 @@ icc_conv_pixmap(fz_context *ctx, fz_pixmap *dst, fz_pixmap *src, fz_colorspace *
inputpos = src->samples;
outputpos = dst->samples;
- link = fz_get_icc_link(ctx, srcs, prf, dsts, color_params, 1, dst->alpha, &src_n);
+ link = fz_get_icc_link(ctx, dsts, dst->s + dst->alpha, srcs, src->s + src->alpha, prf, color_params, 1, copy_spots, &src_n);
if (link->is_identity)
{
@@ -2450,7 +2684,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, const 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, int copy_spots)
{
fz_colorspace *srcs = src->colorspace;
fz_colorspace *base_cs = get_base_icc_space(ctx, srcs);
@@ -2501,7 +2735,7 @@ icc_base_conv_pixmap(fz_context *ctx, fz_pixmap *dst, fz_pixmap *src, fz_colorsp
}
fz_try(ctx)
- icc_conv_pixmap(ctx, dst, base, prf, default_cs, color_params);
+ icc_conv_pixmap(ctx, dst, base, prf, default_cs, color_params, copy_spots);
fz_always(ctx)
fz_drop_pixmap(ctx, base);
fz_catch(ctx)
@@ -2509,7 +2743,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, const 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, int copy_spots)
{
float srcv[FZ_MAX_COLORS];
float dstv[FZ_MAX_COLORS];
@@ -2710,8 +2944,10 @@ 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, const 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, int copy_spots)
{
+ assert(copy_spots && dst->s == 0 && src->s == 0);
+
if (!src->alpha)
fz_clear_pixmap_with_value(ctx, dst, 255);
else
@@ -3060,7 +3296,7 @@ void fz_find_color_converter(fz_context *ctx, fz_color_converter *cc, const fz_c
cc->convert = icc_conv_color;
else
cc->convert = icc_base_conv_color;
- cc->link = fz_get_icc_link(ctx, ss_base, is, ds, params, 2, 0, &cc->n);
+ cc->link = fz_get_icc_link(ctx, ds, 0, ss_base, 0, is, params, 2, 0, &cc->n);
}
else
cc->convert = std_conv_color;