summaryrefslogtreecommitdiff
path: root/fitz
diff options
context:
space:
mode:
Diffstat (limited to 'fitz')
-rw-r--r--fitz/fitz-internal.h16
-rw-r--r--fitz/res_colorspace.c236
2 files changed, 164 insertions, 88 deletions
diff --git a/fitz/fitz-internal.h b/fitz/fitz-internal.h
index 569fc694..c90474dd 100644
--- a/fitz/fitz-internal.h
+++ b/fitz/fitz-internal.h
@@ -984,6 +984,22 @@ void fz_free_colorspace_imp(fz_context *ctx, fz_storable *colorspace);
void fz_convert_color(fz_context *ctx, fz_colorspace *dsts, float *dstv, fz_colorspace *srcs, float *srcv);
+typedef struct fz_color_converter_s fz_color_converter;
+
+/* This structure is public because it allows us to avoid dynamic allocations.
+ * Callers should only rely on the convert entry - the rest of the structure
+ * is subject to change without notice.
+ */
+struct fz_color_converter_s
+{
+ void (*convert)(fz_color_converter *, float *, float *);
+ fz_context *ctx;
+ fz_colorspace *ds;
+ fz_colorspace *ss;
+};
+
+void fz_find_color_converter(fz_color_converter *cc, fz_context *ctx, fz_colorspace *ds, fz_colorspace *ss);
+
/*
* Fonts come in two variants:
* Regular fonts are handled by FreeType.
diff --git a/fitz/res_colorspace.c b/fitz/res_colorspace.c
index 655f664b..2076f348 100644
--- a/fitz/res_colorspace.c
+++ b/fitz/res_colorspace.c
@@ -731,13 +731,16 @@ fz_std_conv_pixmap(fz_context *ctx, fz_pixmap *dst, fz_pixmap *src)
/* Special case for Lab colorspace (scaling of components to float) */
if (!strcmp(ss->name, "Lab") && srcn == 3)
{
+ fz_color_converter cc;
+
+ fz_find_color_converter(&cc, ctx, ds, ss);
for (; xy > 0; xy--)
{
srcv[0] = *s++ / 255.0f * 100;
srcv[1] = *s++ - 128;
srcv[2] = *s++ - 128;
- fz_convert_color(ctx, ds, dstv, ss, srcv);
+ cc.convert(&cc, dstv, srcv);
for (k = 0; k < dstn; k++)
*d++ = dstv[k] * 255;
@@ -749,12 +752,15 @@ fz_std_conv_pixmap(fz_context *ctx, fz_pixmap *dst, fz_pixmap *src)
/* Brute-force for small images */
else if (xy < 256)
{
+ fz_color_converter cc;
+
+ fz_find_color_converter(&cc, ctx, ds, ss);
for (; xy > 0; xy--)
{
for (k = 0; k < srcn; k++)
srcv[k] = *s++ / 255.0f;
- fz_convert_color(ctx, ds, dstv, ss, srcv);
+ cc.convert(&cc, dstv, srcv);
for (k = 0; k < dstn; k++)
*d++ = dstv[k] * 255;
@@ -767,11 +773,13 @@ fz_std_conv_pixmap(fz_context *ctx, fz_pixmap *dst, fz_pixmap *src)
else if (srcn == 1)
{
unsigned char lookup[FZ_MAX_COLORS * 256];
+ fz_color_converter cc;
+ fz_find_color_converter(&cc, ctx, ds, ss);
for (i = 0; i < 256; i++)
{
srcv[0] = i / 255.0f;
- fz_convert_color(ctx, ds, dstv, ss, srcv);
+ cc.convert(&cc, dstv, srcv);
for (k = 0; k < dstn; k++)
lookup[i * dstn + k] = dstv[k] * 255;
}
@@ -792,7 +800,9 @@ fz_std_conv_pixmap(fz_context *ctx, fz_pixmap *dst, fz_pixmap *src)
unsigned char *color;
unsigned char dummy = s[0] ^ 255;
unsigned char *sold = &dummy;
+ fz_color_converter cc;
+ fz_find_color_converter(&cc, ctx, ds, ss);
lookup = fz_new_hash_table(ctx, 509, srcn, -1);
for (; xy > 0; xy--)
@@ -820,7 +830,7 @@ fz_std_conv_pixmap(fz_context *ctx, fz_pixmap *dst, fz_pixmap *src)
{
for (k = 0; k < srcn; k++)
srcv[k] = *s++ / 255.0f;
- fz_convert_color(ctx, ds, dstv, ss, srcv);
+ cc.convert(&cc, dstv, srcv);
for (k = 0; k < dstn; k++)
*d++ = dstv[k] * 255;
@@ -883,10 +893,13 @@ fz_convert_pixmap(fz_context *ctx, fz_pixmap *dp, fz_pixmap *sp)
/* Convert a single color */
static void
-fz_std_conv_color(fz_context *ctx, fz_colorspace *srcs, float *srcv, fz_colorspace *dsts, float *dstv)
+std_conv_color(fz_color_converter *cc, float *dstv, float *srcv)
{
float rgb[3];
int i;
+ fz_colorspace *srcs = cc->ss;
+ fz_colorspace *dsts = cc->ds;
+ fz_context *ctx = cc->ctx;
if (srcs != dsts)
{
@@ -903,119 +916,166 @@ fz_std_conv_color(fz_context *ctx, fz_colorspace *srcs, float *srcv, fz_colorspa
}
}
-void
-fz_convert_color(fz_context *ctx, fz_colorspace *ds, float *dv, fz_colorspace *ss, float *sv)
+static void
+g2rgb(fz_color_converter *cc, float *dv, float *sv)
+{
+ dv[0] = sv[0];
+ dv[1] = sv[0];
+ dv[2] = sv[0];
+}
+
+static void
+g2cmyk(fz_color_converter *cc, float *dv, float *sv)
+{
+ dv[0] = 0;
+ dv[1] = 0;
+ dv[2] = 0;
+ dv[3] = sv[0];
+}
+
+static void
+rgb2g(fz_color_converter *cc, float *dv, float *sv)
+{
+ dv[0] = sv[0] * 0.3f + sv[1] * 0.59f + sv[2] * 0.11f;
+}
+
+static void
+rgb2bgr(fz_color_converter *cc, float *dv, float *sv)
+{
+ dv[0] = sv[2];
+ dv[1] = sv[1];
+ dv[2] = sv[0];
+}
+
+static void
+rgb2cmyk(fz_color_converter *cc, float *dv, float *sv)
+{
+ float c = 1 - sv[0];
+ float m = 1 - sv[1];
+ float y = 1 - sv[2];
+ float k = fz_min(c, fz_min(m, y));
+ dv[0] = c - k;
+ dv[1] = m - k;
+ dv[2] = y - k;
+ dv[3] = k;
+}
+
+static void
+bgr2g(fz_color_converter *cc, float *dv, float *sv)
+{
+ dv[0] = sv[0] * 0.11f + sv[1] * 0.59f + sv[2] * 0.3f;
+}
+
+static void
+bgr2cmyk(fz_color_converter *cc, float *dv, float *sv)
+{
+ float c = 1 - sv[2];
+ float m = 1 - sv[1];
+ float y = 1 - sv[0];
+ float k = fz_min(c, fz_min(m, y));
+ dv[0] = c - k;
+ dv[1] = m - k;
+ dv[2] = y - k;
+ dv[3] = k;
+}
+
+static void
+cmyk2g(fz_color_converter *cc, float *dv, float *sv)
+{
+ float c = sv[0] * 0.3f;
+ float m = sv[1] * 0.59f;
+ float y = sv[2] * 0.11f;
+ dv[0] = 1 - fz_min(c + m + y + sv[3], 1);
+}
+
+static void
+cmyk2rgb(fz_color_converter *cc, float *dv, float *sv)
+{
+#ifdef SLOWCMYK
+ cmyk_to_rgb(cc->ctx, NULL, sv, dv);
+#else
+ dv[0] = 1 - fz_min(sv[0] + sv[3], 1);
+ dv[1] = 1 - fz_min(sv[1] + sv[3], 1);
+ dv[2] = 1 - fz_min(sv[2] + sv[3], 1);
+#endif
+}
+
+static void
+cmyk2bgr(fz_color_converter *cc, float *dv, float *sv)
{
+#ifdef SLOWCMYK
+ float rgb[3];
+ cmyk_to_rgb(cc->ctx, NULL, sv, rgb);
+ dv[0] = rgb[2];
+ dv[1] = rgb[1];
+ dv[2] = rgb[0];
+#else
+ dv[0] = 1 - fz_min(sv[2] + sv[3], 1);
+ dv[1] = 1 - fz_min(sv[1] + sv[3], 1);
+ dv[2] = 1 - fz_min(sv[0] + sv[3], 1);
+#endif
+}
+
+void fz_find_color_converter(fz_color_converter *cc, fz_context *ctx, fz_colorspace *ds, fz_colorspace *ss)
+{
+ cc->ctx = ctx;
+ cc->ds = ds;
+ cc->ss = ss;
if (ss == fz_device_gray)
{
if ((ds == fz_device_rgb) || (ds == fz_device_bgr))
- {
- dv[0] = sv[0];
- dv[1] = sv[0];
- dv[2] = sv[0];
- }
+ cc->convert = g2rgb;
else if (ds == fz_device_cmyk)
- {
- dv[0] = 0;
- dv[1] = 0;
- dv[2] = 0;
- dv[3] = sv[0];
- }
+ cc->convert = g2cmyk;
else
- fz_std_conv_color(ctx, ss, sv, ds, dv);
+ cc->convert = std_conv_color;
}
else if (ss == fz_device_rgb)
{
if (ds == fz_device_gray)
- {
- dv[0] = sv[0] * 0.3f + sv[1] * 0.59f + sv[2] * 0.11f;
- }
+ cc->convert = rgb2g;
else if (ds == fz_device_bgr)
- {
- dv[0] = sv[2];
- dv[1] = sv[1];
- dv[2] = sv[0];
- }
+ cc->convert = rgb2bgr;
else if (ds == fz_device_cmyk)
- {
- float c = 1 - sv[0];
- float m = 1 - sv[1];
- float y = 1 - sv[2];
- float k = fz_min(c, fz_min(m, y));
- dv[0] = c - k;
- dv[1] = m - k;
- dv[2] = y - k;
- dv[3] = k;
- }
+ cc->convert = rgb2cmyk;
else
- fz_std_conv_color(ctx, ss, sv, ds, dv);
+ cc->convert = std_conv_color;
}
else if (ss == fz_device_bgr)
{
if (ds == fz_device_gray)
- {
- dv[0] = sv[0] * 0.11f + sv[1] * 0.59f + sv[2] * 0.3f;
- }
- else if (ds == fz_device_bgr)
- {
- dv[0] = sv[2];
- dv[1] = sv[1];
- dv[2] = sv[0];
- }
+ cc->convert = bgr2g;
+ else if (ds == fz_device_rgb)
+ cc->convert = rgb2bgr;
else if (ds == fz_device_cmyk)
- {
- float c = 1 - sv[2];
- float m = 1 - sv[1];
- float y = 1 - sv[0];
- float k = fz_min(c, fz_min(m, y));
- dv[0] = c - k;
- dv[1] = m - k;
- dv[2] = y - k;
- dv[3] = k;
- }
+ cc->convert = bgr2cmyk;
else
- fz_std_conv_color(ctx, ss, sv, ds, dv);
+ cc->convert = std_conv_color;
}
else if (ss == fz_device_cmyk)
{
if (ds == fz_device_gray)
- {
- float c = sv[0] * 0.3f;
- float m = sv[1] * 0.59f;
- float y = sv[2] * 0.11f;
- dv[0] = 1 - fz_min(c + m + y + sv[3], 1);
- }
+ cc->convert = cmyk2g;
else if (ds == fz_device_rgb)
- {
-#ifdef SLOWCMYK
- cmyk_to_rgb(ctx, NULL, sv, dv);
-#else
- dv[0] = 1 - fz_min(sv[0] + sv[3], 1);
- dv[1] = 1 - fz_min(sv[1] + sv[3], 1);
- dv[2] = 1 - fz_min(sv[2] + sv[3], 1);
-#endif
- }
+ cc->convert = cmyk2rgb;
else if (ds == fz_device_bgr)
- {
-#ifdef SLOWCMYK
- float rgb[3];
- cmyk_to_rgb(ctx, NULL, sv, rgb);
- dv[0] = rgb[2];
- dv[1] = rgb[1];
- dv[2] = rgb[0];
-#else
- dv[0] = 1 - fz_min(sv[2] + sv[3], 1);
- dv[1] = 1 - fz_min(sv[1] + sv[3], 1);
- dv[2] = 1 - fz_min(sv[0] + sv[3], 1);
-#endif
- }
+ cc->convert = cmyk2bgr;
else
- fz_std_conv_color(ctx, ss, sv, ds, dv);
+ cc->convert = std_conv_color;
}
else
- fz_std_conv_color(ctx, ss, sv, ds, dv);
+ cc->convert = std_conv_color;
+}
+
+void
+fz_convert_color(fz_context *ctx, fz_colorspace *ds, float *dv, fz_colorspace *ss, float *sv)
+{
+ fz_color_converter cc;
+
+ fz_find_color_converter(&cc, ctx, ds, ss);
+ cc.convert(&cc, dv, sv);
}