summaryrefslogtreecommitdiff
path: root/fitz/res_colorspace.c
diff options
context:
space:
mode:
authorRobin Watts <robin.watts@artifex.com>2013-04-05 15:49:10 +0100
committerRobin Watts <robin.watts@artifex.com>2013-04-11 19:00:39 +0100
commit53b5ede268394d651df1f12da490884bf870006a (patch)
tree72145964ff775415674c73b1e05ea18669238278 /fitz/res_colorspace.c
parent05f9887c211fff4195b5959bc71d2ef4b773fdc2 (diff)
downloadmupdf-53b5ede268394d651df1f12da490884bf870006a.tar.xz
Move pdf_image to fz_image.
In order to be able to output images (either in the pdfwrite device or in the html conversion), we need to be able to get to the original compressed data stream (or else we're going to end up recompressing images). To do that, we need to expose all of the contents of pdf_image into fz_image, so it makes sense to just amalgamate the two. This has knock on effects for the creation of indexed colorspaces, requiring some of that logic to be moved. Also, we need to make xps use the same structures; this means pushing PNG and TIFF support into the decoding code. Also we need to be able to load just the headers from PNG/TIFF/JPEGs as xps doesn't include dimension/resolution information. Also, separate out all the fz_image stuff into fitz/res_image.c rather than having it in res_pixmap.
Diffstat (limited to 'fitz/res_colorspace.c')
-rw-r--r--fitz/res_colorspace.c100
1 files changed, 100 insertions, 0 deletions
diff --git a/fitz/res_colorspace.c b/fitz/res_colorspace.c
index a2ce19b8..5d8c3b02 100644
--- a/fitz/res_colorspace.c
+++ b/fitz/res_colorspace.c
@@ -1085,3 +1085,103 @@ fz_convert_color(fz_context *ctx, fz_colorspace *ds, float *dv, fz_colorspace *s
fz_find_color_converter(&cc, ctx, ds, ss);
cc.convert(&cc, dv, sv);
}
+
+
+/* Indexed */
+
+struct indexed
+{
+ fz_colorspace *base;
+ int high;
+ unsigned char *lookup;
+};
+
+static void
+indexed_to_rgb(fz_context *ctx, fz_colorspace *cs, float *color, float *rgb)
+{
+ struct indexed *idx = cs->data;
+ float alt[FZ_MAX_COLORS];
+ int i, k;
+ i = color[0] * 255;
+ i = fz_clampi(i, 0, idx->high);
+ for (k = 0; k < idx->base->n; k++)
+ alt[k] = idx->lookup[i * idx->base->n + k] / 255.0f;
+ idx->base->to_rgb(ctx, idx->base, alt, rgb);
+}
+
+static void
+free_indexed(fz_context *ctx, fz_colorspace *cs)
+{
+ struct indexed *idx = cs->data;
+ if (idx->base)
+ fz_drop_colorspace(ctx, idx->base);
+ fz_free(ctx, idx->lookup);
+ fz_free(ctx, idx);
+}
+
+fz_colorspace *
+fz_new_indexed_colorspace(fz_context *ctx, fz_colorspace *base, int high, unsigned char *lookup)
+{
+ fz_colorspace *cs;
+ struct indexed *idx;
+
+ idx = fz_malloc_struct(ctx, struct indexed);
+ idx->lookup = lookup;
+ idx->base = base;
+ idx->high = high;
+
+ fz_try(ctx)
+ {
+ cs = fz_new_colorspace(ctx, "Indexed", 1);
+ cs->to_rgb = indexed_to_rgb;
+ cs->free_data = free_indexed;
+ cs->data = idx;
+ cs->size += sizeof(*idx) + (base->n * (idx->high + 1)) + base->size;
+ }
+ fz_catch(ctx)
+ {
+ fz_free(ctx, idx);
+ fz_throw(ctx, "failed to create indexed colorspace");
+ }
+ return cs;
+}
+
+fz_pixmap *
+fz_expand_indexed_pixmap(fz_context *ctx, fz_pixmap *src)
+{
+ struct indexed *idx;
+ fz_pixmap *dst;
+ unsigned char *s, *d;
+ int y, x, k, n, high;
+ unsigned char *lookup;
+ fz_irect bbox;
+
+ assert(src->colorspace->to_rgb == indexed_to_rgb);
+ assert(src->n == 2);
+
+ idx = src->colorspace->data;
+ high = idx->high;
+ lookup = idx->lookup;
+ n = idx->base->n;
+
+ dst = fz_new_pixmap_with_bbox(ctx, idx->base, fz_pixmap_bbox(ctx, src, &bbox));
+ s = src->samples;
+ d = dst->samples;
+
+ for (y = 0; y < src->h; y++)
+ {
+ for (x = 0; x < src->w; x++)
+ {
+ int v = *s++;
+ int a = *s++;
+ v = fz_mini(v, high);
+ for (k = 0; k < n; k++)
+ *d++ = fz_mul255(lookup[v * n + k], a);
+ *d++ = a;
+ }
+ }
+
+ dst->interpolate = src->interpolate;
+
+ return dst;
+}