diff options
-rw-r--r-- | mupdf/colorspace2.c | 201 |
1 files changed, 201 insertions, 0 deletions
diff --git a/mupdf/colorspace2.c b/mupdf/colorspace2.c new file mode 100644 index 00000000..1574c801 --- /dev/null +++ b/mupdf/colorspace2.c @@ -0,0 +1,201 @@ +#include <fitz.h> +#include <mupdf.h> + +/* + * Optimized color conversions for Device colorspaces + */ + +static void fastgraytorgb(fz_pixmap *src, fz_pixmap *dst) +{ + unsigned char *s = src->samples; + unsigned char *d = dst->samples; + int n = src->w * src->h; + while (n--) + { + d[0] = s[0]; + d[1] = s[1]; + d[2] = s[1]; + d[3] = s[1]; + s += 2; + d += 4; + } +} + +static void fastgraytocmyk(fz_pixmap *src, fz_pixmap *dst) +{ + unsigned char *s = src->samples; + unsigned char *d = dst->samples; + int n = src->w * src->h; + while (n--) + { + d[0] = s[0]; + d[1] = 0; + d[2] = 0; + d[3] = 0; + d[4] = s[1]; + s += 2; + d += 5; + } +} + +static void fastrgbtogray(fz_pixmap *src, fz_pixmap *dst) +{ + unsigned char *s = src->samples; + unsigned char *d = dst->samples; + int n = src->w * src->h; + while (n--) + { + d[0] = s[0]; + d[1] = ((s[1]+1) * 77 + (s[2]+1) * 150 + (s[3]+1) * 28) >> 8; + s += 4; + d += 2; + } +} + +static void fastrgbtocmyk(fz_pixmap *src, fz_pixmap *dst) +{ + unsigned char *s = src->samples; + unsigned char *d = dst->samples; + int n = src->w * src->h; + while (n--) + { + unsigned char c = 255 - s[1]; + unsigned char m = 255 - s[2]; + unsigned char y = 255 - s[3]; + unsigned char k = MIN(c, MIN(y, k)); + d[0] = s[0]; + d[1] = c - k; + d[2] = m - k; + d[3] = y - k; + d[4] = k; + s += 4; + d += 5; + } +} + +static void fastcmyktogray(fz_pixmap *src, fz_pixmap *dst) +{ + unsigned char *s = src->samples; + unsigned char *d = dst->samples; + int n = src->w * src->h; + while (n--) + { + unsigned char c = fz_mul255(s[1], 77); + unsigned char m = fz_mul255(s[2], 150); + unsigned char y = fz_mul255(s[3], 28); + d[0] = s[0]; + d[1] = 255 - MIN(c + m + y + s[4], 255); + s += 5; + d += 2; + } +} + +static void fastcmyktorgb(fz_pixmap *src, fz_pixmap *dst) +{ + unsigned char *s = src->samples; + unsigned char *d = dst->samples; + int n = src->w * src->h; + while (n--) + { + d[0] = s[0]; + d[1] = 255 - MIN(s[1] + s[4], 255); + d[2] = 255 - MIN(s[2] + s[4], 255); + d[3] = 255 - MIN(s[3] + s[4], 255); + s += 5; + d += 4; + } +} + +void pdf_convpixmap(fz_colorspace *ss, fz_pixmap *sp, fz_colorspace *ds, fz_pixmap *dp) +{ + if (ss == pdf_devicegray) + { + if (ds == pdf_devicergb) fastgraytorgb(sp, dp); + else if (ds == pdf_devicecmyk) fastgraytocmyk(sp, dp); + else fz_stdconvpixmap(ss, sp, ds, dp); + } + + else if (ss == pdf_devicergb) + { + if (ds == pdf_devicegray) fastrgbtogray(sp, dp); + else if (ds == pdf_devicecmyk) fastrgbtocmyk(sp, dp); + else fz_stdconvpixmap(ss, sp, ds, dp); + + } + + else if (ss == pdf_devicecmyk) + { + if (ds == pdf_devicegray) fastcmyktogray(sp, dp); + else if (ds == pdf_devicergb) fastcmyktorgb(sp, dp); + else fz_stdconvpixmap(ss, sp, ds, dp); + } + + else fz_stdconvpixmap(ss, sp, ds, dp); +} + +void pdf_convcolor(fz_colorspace *ss, float *sv, fz_colorspace *ds, float *dv) +{ + + if (ss == pdf_devicegray) + { + if (ds == pdf_devicergb) + { + dv[0] = sv[0]; + dv[1] = sv[0]; + dv[2] = sv[0]; + } + else if (ds == pdf_devicecmyk) + { + dv[0] = 0; + dv[1] = 0; + dv[2] = 0; + dv[3] = sv[0]; + } + else + fz_stdconvcolor(ss, sv, ds, dv); + } + + else if (ss == pdf_devicergb) + { + if (ds == pdf_devicegray) + { + dv[0] = sv[0] * 0.3 + sv[1] * 0.59 + sv[2] * 0.11; + } + else if (ds == pdf_devicecmyk) + { + float c = 1.0 - sv[1]; + float m = 1.0 - sv[2]; + float y = 1.0 - sv[3]; + float k = MIN(c, MIN(y, k)); + dv[0] = c - k; + dv[1] = m - k; + dv[2] = y - k; + dv[3] = k; + } + else + fz_stdconvcolor(ss, sv, ds, dv); + } + + else if (ss == pdf_devicecmyk) + { + if (ds == pdf_devicegray) + { + float c = sv[1] * 0.3; + float m = sv[2] * 0.59; + float y = sv[2] * 0.11; + dv[0] = 1.0 - MIN(c + m + y + sv[3], 1.0); + } + else if (ds == pdf_devicergb) + { + dv[0] = 1.0 - MIN(sv[0] + sv[3], 1.0); + dv[1] = 1.0 - MIN(sv[1] + sv[3], 1.0); + dv[2] = 1.0 - MIN(sv[2] + sv[3], 1.0); + } + else + fz_stdconvcolor(ss, sv, ds, dv); + } + + else + fz_stdconvcolor(ss, sv, ds, dv); +} + |