summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobin Watts <robin.watts@artifex.com>2012-11-14 20:18:12 +0000
committerRobin Watts <robin.watts@artifex.com>2012-11-16 13:52:55 +0000
commitf3dd1b35afbb19fb4a5462ff4f4df9f9d5901f3f (patch)
tree0dfb4d90646057485c20c22e3c4b42a9cefccde7
parent3ec40a4dd9512eed2ee83bf3eb811cdbc1c3dae0 (diff)
downloadmupdf-f3dd1b35afbb19fb4a5462ff4f4df9f9d5901f3f.tar.xz
Implement fast_cmyk_to_rgb without calling cmyk_to_rgb.
Same algorithm, just implemented in fixed point with a 1 place cache and checks for trivial black/white rather than floating point.
-rw-r--r--fitz/res_colorspace.c139
1 files changed, 130 insertions, 9 deletions
diff --git a/fitz/res_colorspace.c b/fitz/res_colorspace.c
index 3ae8648e..7b36ac1e 100644
--- a/fitz/res_colorspace.c
+++ b/fitz/res_colorspace.c
@@ -321,18 +321,139 @@ static void fast_cmyk_to_rgb(fz_context *ctx, fz_pixmap *dst, fz_pixmap *src)
unsigned char *s = src->samples;
unsigned char *d = dst->samples;
int n = src->w * src->h;
+ unsigned int C,M,Y,K,r,g,b;
+
+ C = 0;
+ M = 0;
+ Y = 0;
+ K = 0;
+ r = 255;
+ g = 255;
+ b = 255;
+
while (n--)
{
#ifdef SLOWCMYK
- float cmyk[4], rgb[3];
- cmyk[0] = s[0] / 255.0f;
- cmyk[1] = s[1] / 255.0f;
- cmyk[2] = s[2] / 255.0f;
- cmyk[3] = s[3] / 255.0f;
- cmyk_to_rgb(ctx, NULL, cmyk, rgb);
- d[0] = rgb[0] * 255;
- d[1] = rgb[1] * 255;
- d[2] = rgb[2] * 255;
+ unsigned int c = s[0];
+ unsigned int m = s[1];
+ unsigned int y = s[2];
+ unsigned int k = s[3];
+ unsigned int cm, c1m, cm1, c1m1, c1m1y, c1m1y1, c1my, c1my1, cm1y, cm1y1, cmy, cmy1;
+ unsigned int x0, x1;
+
+ if (c == C && m == M && y == Y && k == K)
+ {
+ /* Nothing to do */
+ }
+ else if (k == 0 && c == 0 && m == 0 && y == 0)
+ {
+ r = g = b = 255;
+ }
+ else if (k == 255)
+ {
+ r = g = b = 0;
+ }
+ else
+ {
+ c += c>>7;
+ m += m>>7;
+ y += y>>7;
+ k += k>>7;
+ y >>= 1; /* Ditch 1 bit of Y to avoid overflow */
+ cm = c * m;
+ c1m = (m<<8) - cm;
+ cm1 = (c<<8) - cm;
+ c1m1 = ((256 - m)<<8) - cm1;
+ c1m1y = c1m1 * y;
+ c1m1y1 = (c1m1<<7) - c1m1y;
+ c1my = c1m * y;
+ c1my1 = (c1m<<7) - c1my;
+ cm1y = cm1 * y;
+ cm1y1 = (cm1<<7) - cm1y;
+ cmy = cm * y;
+ cmy1 = (cm<<7) - cmy;
+
+ /* this is a matrix multiplication, unrolled for performance */
+ x1 = c1m1y1 * k; /* 0 0 0 1 */
+ x0 = (c1m1y1<<8) - x1; /* 0 0 0 0 */
+ x1 = x1>>8; /* From 23 fractional bits to 15 */
+ r = g = b = x0;
+ r += 35 * x1; /* 0.1373 */
+ g += 31 * x1; /* 0.1216 */
+ b += 32 * x1; /* 0.1255 */
+
+ x1 = c1m1y * k; /* 0 0 1 1 */
+ x0 = (c1m1y<<8) - x1; /* 0 0 1 0 */
+ x1 >>= 8; /* From 23 fractional bits to 15 */
+ r += 28 * x1; /* 0.1098 */
+ g += 26 * x1; /* 0.1020 */
+ r += x0;
+ x0 >>= 8; /* From 23 fractional bits to 15 */
+ g += 243 * x0; /* 0.9490 */
+
+ x1 = c1my1 * k; /* 0 1 0 1 */
+ x0 = (c1my1<<8) - x1; /* 0 1 0 0 */
+ x1 >>= 8; /* From 23 fractional bits to 15 */
+ x0 >>= 8; /* From 23 fractional bits to 15 */
+ r += 36 * x1; /* 0.1412 */
+ r += 237 * x0; /* 0.9255 */
+ b += 141 * x0; /* 0.5490 */
+
+ x1 = c1my * k; /* 0 1 1 1 */
+ x0 = (c1my<<8) - x1; /* 0 1 1 0 */
+ x1 >>= 8; /* From 23 fractional bits to 15 */
+ x0 >>= 8; /* From 23 fractional bits to 15 */
+ r += 34 * x1; /* 0.1333 */
+ r += 238 * x0; /* 0.9294 */
+ g += 28 * x0; /* 0.1098 */
+ b += 36 * x0; /* 0.1412 */
+
+ x1 = cm1y1 * k; /* 1 0 0 1 */
+ x0 = (cm1y1<<8) - x1; /* 1 0 0 0 */
+ x1 >>= 8; /* From 23 fractional bits to 15 */
+ x0 >>= 8; /* From 23 fractional bits to 15 */
+ g += 15 * x1; /* 0.0588 */
+ b += 36 * x1; /* 0.1412 */
+ g += 174 * x0; /* 0.6784 */
+ b += 240 * x0; /* 0.9373 */
+
+ x1 = cm1y * k; /* 1 0 1 1 */
+ x0 = (cm1y<<8) - x1; /* 1 0 1 0 */
+ x1 >>= 8; /* From 23 fractional bits to 15 */
+ x0 >>= 8; /* From 23 fractional bits to 15 */
+ g += 19 * x1; /* 0.0745 */
+ g += 167 * x0; /* 0.6510 */
+ b += 80 * x0; /* 0.3137 */
+
+ x1 = cmy1 * k; /* 1 1 0 1 */
+ x0 = (cmy1<<8) - x1; /* 1 1 0 0 */
+ x1 >>= 8; /* From 23 fractional bits to 15 */
+ x0 >>= 8; /* From 23 fractional bits to 15 */
+ b += 2 * x1; /* 0.0078 */
+ r += 46 * x0; /* 0.1804 */
+ g += 49 * x0; /* 0.1922 */
+ b += 147 * x0; /* 0.5725 */
+
+ x0 = cmy * (256-k); /* 1 1 1 0 */
+ x0 >>= 8; /* From 23 fractional bits to 15 */
+ r += 54 * x0; /* 0.2118 */
+ g += 54 * x0; /* 0.2119 */
+ b += 57 * x0; /* 0.2235 */
+
+ r -= (r>>8);
+ g -= (g>>8);
+ b -= (b>>8);
+ r = r>>23;
+ g = g>>23;
+ b = b>>23;
+ C = c;
+ M = m;
+ Y = y;
+ K = k;
+ }
+ d[0] = r;
+ d[1] = g;
+ d[2] = b;
#else
d[0] = 255 - (unsigned char)fz_mini(s[0] + s[3], 255);
d[1] = 255 - (unsigned char)fz_mini(s[1] + s[3], 255);