summaryrefslogtreecommitdiff
path: root/source/fitz/color-lcms.c
diff options
context:
space:
mode:
authorRobin Watts <robin.watts@artifex.com>2017-07-05 10:35:12 +0100
committerRobin Watts <robin.watts@artifex.com>2017-07-19 19:41:23 +0100
commit5242318aae6b46777326eb4b10514aabd21d7eea (patch)
tree3eb9ac7b1a1d1b51c49d7754416b665306f29dba /source/fitz/color-lcms.c
parentf957eae764e6dbc74401b66d6a18ba3290fdb982 (diff)
downloadmupdf-5242318aae6b46777326eb4b10514aabd21d7eea.tar.xz
Add knowledge of spots to color conversions.
Diffstat (limited to 'source/fitz/color-lcms.c')
-rw-r--r--source/fitz/color-lcms.c44
1 files changed, 27 insertions, 17 deletions
diff --git a/source/fitz/color-lcms.c b/source/fitz/color-lcms.c
index 82d05c98..2c25e8e7 100644
--- a/source/fitz/color-lcms.c
+++ b/source/fitz/color-lcms.c
@@ -70,7 +70,7 @@ fz_lcms_num_devcomps(cmsContext cmm_ctx, fz_iccprofile *profile)
}
static void
-fz_lcms_premultiply_row(fz_context *ctx, int n, int w, unsigned char *s)
+fz_lcms_premultiply_row(fz_context *ctx, int n, int c, int w, unsigned char *s)
{
unsigned char a;
int k;
@@ -79,14 +79,14 @@ fz_lcms_premultiply_row(fz_context *ctx, int n, int w, unsigned char *s)
for (; w > 0; w--)
{
a = s[n1];
- for (k = 0; k < n1; k++)
+ for (k = 0; k < c; k++)
s[k] = fz_mul255(s[k], a);
s += n;
}
}
static void
-fz_lcms_unmultiply_row(fz_context *ctx, int n, int w, unsigned char *s, const unsigned char *in)
+fz_lcms_unmultiply_row(fz_context *ctx, int n, int c, int w, unsigned char *s, const unsigned char *in)
{
int a, inva;
int k;
@@ -96,8 +96,10 @@ fz_lcms_unmultiply_row(fz_context *ctx, int n, int w, unsigned char *s, const un
{
a = in[n1];
inva = a ? 255 * 256 / a : 0;
- for (k = 0; k < n1; k++)
+ for (k = 0; k < c; k++)
s[k] = (in[k] * inva) >> 8;
+ for (;k < n1; k++)
+ s[k] = in[k];
s[n1] = a;
s += n;
in += n;
@@ -111,7 +113,7 @@ fz_lcms_transform_pixmap(fz_cmm_instance *instance, fz_icclink *link, fz_pixmap
cmsContext cmm_ctx = (cmsContext)instance;
fz_context *ctx = (fz_context *)cmsGetContextUserData(cmm_ctx);
cmsHTRANSFORM hTransform = (cmsHTRANSFORM)link->cmm_handle;
- int cmm_num_src, cmm_num_des;
+ int cmm_num_src, cmm_num_des, cmm_extras;
unsigned char *inputpos, *outputpos, *buffer;
int ss = src->stride;
int ds = dst->stride;
@@ -121,27 +123,35 @@ fz_lcms_transform_pixmap(fz_cmm_instance *instance, fz_icclink *link, fz_pixmap
int dn = dst->n;
int sa = src->alpha;
int da = dst->alpha;
+ int ssp = src->s;
+ int dsp = dst->s;
+ int sc = sn - ssp - sa;
+ int dc = dn - dsp - da;
int h = src->h;
+ cmsUInt32Number src_format, dst_format;
DEBUG_LCMS_MEM(("@@@@@@@ Transform Pixmap Start:: mupdf ctx = %p lcms ctx = %p link = %p \n", (void*)ctx, (void*)cmm_ctx, (void*)link->cmm_handle));
/* check the channels. */
- cmm_num_src = T_CHANNELS(cmsGetTransformInputFormat(cmm_ctx, hTransform));
- cmm_num_des = T_CHANNELS(cmsGetTransformOutputFormat(cmm_ctx, hTransform));
- if (cmm_num_src != sn - sa || cmm_num_des != dn - da || sa != da)
- fz_throw(ctx, FZ_ERROR_GENERIC, "Mismatching color setup in cmm pixmap transformation: src: %d vs %d+%d, dst: %d vs %d+%d", cmm_num_src, sn-sa, sa, cmm_num_des, dn-da, da);
+ src_format = cmsGetTransformInputFormat(cmm_ctx, hTransform);
+ dst_format = cmsGetTransformOutputFormat(cmm_ctx, hTransform);
+ cmm_num_src = T_CHANNELS(src_format);
+ cmm_num_des = T_CHANNELS(dst_format);
+ cmm_extras = T_EXTRA(src_format);
+ if (cmm_num_src != sc || cmm_num_des != dc || cmm_extras != ssp+sa || sa != da || ssp != dsp)
+ fz_throw(ctx, FZ_ERROR_GENERIC, "Mismatching color setup in cmm pixmap transformation: src: %d vs %d+%d+%d, dst: %d vs %d+%d+%d", cmm_num_src, sc, ssp, sa, cmm_num_des, dc, dsp, da);
/* Transform */
inputpos = src->samples;
outputpos = dst->samples;
- if (src->alpha)
+ if (sa)
{
/* Allow for premultiplied alpha */
buffer = fz_malloc(ctx, ss);
for (; h > 0; h--)
{
- fz_lcms_unmultiply_row(ctx, sn, sw, buffer, inputpos);
+ fz_lcms_unmultiply_row(ctx, sn, sc, sw, buffer, inputpos);
cmsDoTransform(cmm_ctx, hTransform, buffer, outputpos, sw);
- fz_lcms_premultiply_row(ctx, dn, dw, outputpos);
+ fz_lcms_premultiply_row(ctx, dn, dc, dw, outputpos);
inputpos += ss;
outputpos += ds;
}
@@ -170,7 +180,7 @@ fz_lcms_transform_color(fz_cmm_instance *instance, fz_icclink *link, unsigned sh
}
void
-fz_lcms_init_link(fz_cmm_instance *instance, fz_icclink *link, const fz_color_params *rend, int cmm_flags, int num_bytes, int alpha, const fz_iccprofile *src, const fz_iccprofile *prf, const fz_iccprofile *dst)
+fz_lcms_init_link(fz_cmm_instance *instance, 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 *dst)
{
cmsContext cmm_ctx = (cmsContext)instance;
fz_context *ctx = (fz_context *)cmsGetContextUserData(cmm_ctx);
@@ -189,7 +199,7 @@ fz_lcms_init_link(fz_cmm_instance *instance, fz_icclink *link, const fz_color_pa
if (lcms_src_cs < 0)
lcms_src_cs = 0;
src_num_chan = cmsChannelsOf(cmm_ctx, src_cs);
- src_data_type = (COLORSPACE_SH(lcms_src_cs) | CHANNELS_SH(src_num_chan) | DOSWAP_SH(src->bgr) | BYTES_SH(num_bytes) | EXTRA_SH(alpha));
+ src_data_type = (COLORSPACE_SH(lcms_src_cs) | CHANNELS_SH(src_num_chan) | DOSWAP_SH(src->bgr) | BYTES_SH(num_bytes) | EXTRA_SH(extras));
/* dst */
des_cs = cmsGetColorSpace(cmm_ctx, dst->cmm_handle);
@@ -197,17 +207,17 @@ fz_lcms_init_link(fz_cmm_instance *instance, fz_icclink *link, const fz_color_pa
if (lcms_des_cs < 0)
lcms_des_cs = 0;
des_num_chan = cmsChannelsOf(cmm_ctx, des_cs);
- des_data_type = (COLORSPACE_SH(lcms_des_cs) | CHANNELS_SH(des_num_chan) | DOSWAP_SH(dst->bgr) | BYTES_SH(num_bytes) | EXTRA_SH(alpha));
+ des_data_type = (COLORSPACE_SH(lcms_des_cs) | CHANNELS_SH(des_num_chan) | DOSWAP_SH(dst->bgr) | BYTES_SH(num_bytes) | EXTRA_SH(extras));
/* flags */
if (rend->bp)
flag |= cmsFLAGS_BLACKPOINTCOMPENSATION;
- if (alpha)
+ if (extras)
flag |= cmsFLAGS_COPY_ALPHA;
link->depth = num_bytes;
- link->alpha = alpha;
+ link->extras = extras;
if (prf == NULL)
{