diff options
author | Robin Watts <robin.watts@artifex.com> | 2012-11-14 20:18:12 +0000 |
---|---|---|
committer | Robin Watts <robin.watts@artifex.com> | 2012-11-16 13:52:55 +0000 |
commit | f3dd1b35afbb19fb4a5462ff4f4df9f9d5901f3f (patch) | |
tree | 0dfb4d90646057485c20c22e3c4b42a9cefccde7 | |
parent | 3ec40a4dd9512eed2ee83bf3eb811cdbc1c3dae0 (diff) | |
download | mupdf-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.c | 139 |
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); |