summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTor Andersson <tor.andersson@artifex.com>2011-04-06 01:50:08 +0200
committerTor Andersson <tor.andersson@artifex.com>2011-04-06 02:21:38 +0200
commit4156e3fd2e8c70faea1d5f39170e7629ed451a2a (patch)
treef90daa9eeea431b42653b68f9e9d3c34e7c9e631
parent65af65d1e82fd2bda7ba05ecea0b8d586c25c6c1 (diff)
downloadmupdf-4156e3fd2e8c70faea1d5f39170e7629ed451a2a.tar.xz
Improve handling of JPX colorspaces.
-rw-r--r--fitz/filt_jpxd.c56
-rw-r--r--fitz/fitz.h2
-rw-r--r--pdf/pdf_image.c48
3 files changed, 61 insertions, 45 deletions
diff --git a/fitz/filt_jpxd.c b/fitz/filt_jpxd.c
index f5a65851..097d34de 100644
--- a/fitz/filt_jpxd.c
+++ b/fitz/filt_jpxd.c
@@ -19,7 +19,7 @@ static void fz_opj_info_callback(const char *msg, void *client_data)
}
fz_error
-fz_load_jpx_image(fz_pixmap **imgp, unsigned char *data, int size)
+fz_load_jpx_image(fz_pixmap **imgp, unsigned char *data, int size, fz_colorspace *defcs)
{
fz_pixmap *img;
opj_event_mgr_t evtmgr;
@@ -30,7 +30,7 @@ fz_load_jpx_image(fz_pixmap **imgp, unsigned char *data, int size)
fz_colorspace *colorspace;
unsigned char *p;
int format;
- int n, w, h, depth, sgnd;
+ int a, n, w, h, depth, sgnd;
int x, y, k, v;
if (size < 2)
@@ -79,15 +79,34 @@ fz_load_jpx_image(fz_pixmap **imgp, unsigned char *data, int size)
depth = jpx->comps[0].prec;
sgnd = jpx->comps[0].sgnd;
- switch (n)
+ if (jpx->color_space == CLRSPC_SRGB && n == 4) { n = 3; a = 1; }
+ else if (jpx->color_space == CLRSPC_SYCC && n == 4) { n = 3; a = 1; }
+ else if (n == 2) { n = 1; a = 1; }
+ else if (n > 4) { n = 4; a = 1; }
+ else { a = 0; }
+
+ if (defcs)
{
- case 1: colorspace = fz_device_gray; break;
- case 3: colorspace = fz_device_rgb; break;
- case 4: colorspace = fz_device_cmyk; break;
- default:
- /* TODO: SMaskInData */
- opj_image_destroy(jpx);
- return fz_throw("unknown jpx colorspace (%d components)", n);
+ if (defcs->n == n)
+ {
+ colorspace = defcs;
+ }
+ else
+ {
+ fz_warn("jpx file and dict colorspaces do not match");
+ fz_drop_colorspace(defcs);
+ defcs = NULL;
+ }
+ }
+
+ if (!defcs)
+ {
+ switch (n)
+ {
+ case 1: colorspace = fz_device_gray; break;
+ case 3: colorspace = fz_device_rgb; break;
+ case 4: colorspace = fz_device_cmyk; break;
+ }
}
img = fz_new_pixmap(colorspace, 0, 0, w, h);
@@ -97,7 +116,7 @@ fz_load_jpx_image(fz_pixmap **imgp, unsigned char *data, int size)
{
for (x = 0; x < w; x++)
{
- for (k = 0; k < n; k++)
+ for (k = 0; k < n + a; k++)
{
v = jpx->comps[k].data[y * w + x];
if (sgnd)
@@ -106,8 +125,21 @@ fz_load_jpx_image(fz_pixmap **imgp, unsigned char *data, int size)
v = v >> (depth - 8);
*p++ = v;
}
- *p++ = 255; /* TODO: SMaskInData */
+ if (!a)
+ *p++ = 255;
+ }
+ }
+
+ if (a)
+ {
+ if (n == 4)
+ {
+ fz_pixmap *tmp = fz_new_pixmap(fz_device_rgb, 0, 0, w, h);
+ fz_convert_pixmap(img, tmp);
+ fz_drop_pixmap(img);
+ img = tmp;
}
+ fz_premultiply_pixmap(img);
}
opj_image_destroy(jpx);
diff --git a/fitz/fitz.h b/fitz/fitz.h
index f0f3ecdb..4833ffd6 100644
--- a/fitz/fitz.h
+++ b/fitz/fitz.h
@@ -697,7 +697,7 @@ fz_error fz_write_pnm(fz_pixmap *pixmap, char *filename);
fz_error fz_write_pam(fz_pixmap *pixmap, char *filename, int savealpha);
fz_error fz_write_png(fz_pixmap *pixmap, char *filename, int savealpha);
-fz_error fz_load_jpx_image(fz_pixmap **imgp, unsigned char *data, int size);
+fz_error fz_load_jpx_image(fz_pixmap **imgp, unsigned char *data, int size, fz_colorspace *dcs);
/*
* Colorspace resources.
diff --git a/pdf/pdf_image.c b/pdf/pdf_image.c
index dc12c232..0b2f2547 100644
--- a/pdf/pdf_image.c
+++ b/pdf/pdf_image.c
@@ -304,22 +304,37 @@ pdf_load_jpx_image(fz_pixmap **imgp, pdf_xref *xref, fz_obj *dict)
{
fz_error error;
fz_buffer *buf;
+ fz_colorspace *colorspace;
fz_pixmap *img;
fz_obj *obj;
pdf_log_image("jpeg2000\n");
+ colorspace = NULL;
+
error = pdf_load_stream(&buf, xref, fz_to_num(dict), fz_to_gen(dict));
if (error)
return fz_rethrow(error, "cannot load jpx image data");
- error = fz_load_jpx_image(&img, buf->data, buf->len);
+ obj = fz_dict_gets(dict, "ColorSpace");
+ if (obj)
+ {
+ error = pdf_load_colorspace(&colorspace, xref, obj);
+ if (error)
+ fz_catch(error, "cannot load image colorspace");
+ }
+
+ error = fz_load_jpx_image(&img, buf->data, buf->len, colorspace);
if (error)
{
+ if (colorspace)
+ fz_drop_colorspace(colorspace);
fz_drop_buffer(buf);
return fz_rethrow(error, "cannot load jpx image");
}
+ if (colorspace)
+ fz_drop_colorspace(colorspace);
fz_drop_buffer(buf);
obj = fz_dict_getsa(dict, "SMask", "Mask");
@@ -333,37 +348,6 @@ pdf_load_jpx_image(fz_pixmap **imgp, pdf_xref *xref, fz_obj *dict)
}
}
- obj = fz_dict_gets(dict, "ColorSpace");
- if (obj)
- {
- fz_colorspace *original = img->colorspace;
- img->colorspace = NULL;
-
- error = pdf_load_colorspace(&img->colorspace, xref, obj);
- if (error)
- {
- fz_drop_colorspace(original);
- return fz_rethrow(error, "cannot load image colorspace");
- }
-
- if (original->n != img->colorspace->n)
- {
- fz_warn("jpeg-2000 colorspace (%s) does not match promised colorspace (%s)", original->name, img->colorspace->name);
- fz_drop_colorspace(img->colorspace);
- img->colorspace = original;
- }
- else
- fz_drop_colorspace(original);
-
- if (!strcmp(img->colorspace->name, "Indexed"))
- {
- fz_pixmap *conv;
- conv = pdf_expand_indexed_pixmap(img);
- fz_drop_pixmap(img);
- img = conv;
- }
- }
-
*imgp = img;
return fz_okay;
}