summaryrefslogtreecommitdiff
path: root/fitz/filt_jpxd.c
diff options
context:
space:
mode:
authorTor Andersson <tor@ghostscript.com>2010-07-30 01:16:14 +0000
committerTor Andersson <tor@ghostscript.com>2010-07-30 01:16:14 +0000
commit39ebb88a7bed4d0963895debb80a7462530e4c91 (patch)
treed5f3f000462542c6bc9bb63710da9d1ce0a615b9 /fitz/filt_jpxd.c
parentd797d4707564bd9c0e1536d1d6355945aa1be740 (diff)
downloadmupdf-39ebb88a7bed4d0963895debb80a7462530e4c91.tar.xz
Treat JPXDecode images as a special case bypassing the regular filter logic.
Diffstat (limited to 'fitz/filt_jpxd.c')
-rw-r--r--fitz/filt_jpxd.c188
1 files changed, 89 insertions, 99 deletions
diff --git a/fitz/filt_jpxd.c b/fitz/filt_jpxd.c
index 01f15c1b..f4530ad5 100644
--- a/fitz/filt_jpxd.c
+++ b/fitz/filt_jpxd.c
@@ -1,17 +1,9 @@
#include "fitz.h"
+#include "mupdf.h"
#define OPJ_STATIC
#include <openjpeg.h>
-typedef struct fz_jpxd_s fz_jpxd;
-
-struct fz_jpxd_s
-{
- fz_stream *chain;
- opj_image_t *image;
- int x, y, k;
-};
-
static void fz_opj_error_callback(const char *msg, void *client_data)
{
fprintf(stderr, "openjpeg error: %s", msg);
@@ -24,132 +16,130 @@ static void fz_opj_warning_callback(const char *msg, void *client_data)
static void fz_opj_info_callback(const char *msg, void *client_data)
{
- /* fprintf(stdout, "openjpeg info: %s", msg); */
+ char buf[80];
+ int len = fz_strlcpy(buf, msg, sizeof buf);
+ if (len > 0) buf[len-1] = 0;
+ pdf_logimage("%s\n", buf);
}
-static int
-readjpxd(fz_stream *stm, unsigned char *outbuf, int outlen)
+fz_error
+pdf_loadjpximage(pdf_image **imgp, pdf_xref *xref, fz_obj *rdb, fz_obj *dict)
{
- fz_jpxd *state = stm->state;
- unsigned char *p = outbuf;
+ pdf_image *img;
opj_event_mgr_t evtmgr;
opj_dparameters_t params;
opj_dinfo_t *info;
opj_cio_t *cio;
+ opj_image_t *jpx;
+ fz_error error;
+ fz_buffer *buf;
+ unsigned char *p;
int format;
int n, w, h, depth, sgnd;
- int k, v;
+ int x, y, k, v;
- if (!state->image)
- {
- fz_error error;
- fz_buffer *buf;
+ pdf_logimage("load jpx image (%d %d R) {\n", fz_tonum(dict), fz_togen(dict));
- error = fz_readall(&buf, state->chain);
- if (error)
- return fz_throw("read error in jpx filter");
+ error = pdf_loadstream(&buf, xref, fz_tonum(dict), fz_togen(dict));
+ if (error)
+ return fz_throw("read error in jpx image");
- if (buf->len < 2)
- {
- fz_dropbuffer(buf);
- return fz_throw("not enough data to determine image format");
- }
+ if (buf->len < 2)
+ {
+ fz_dropbuffer(buf);
+ return fz_throw("not enough data to determine image format");
+ }
- /* Check for SOC marker -- if found we have a bare J2K stream */
- if (buf->data[0] == 0xFF && buf->data[1] == 0x4F)
- format = CODEC_J2K;
- else
- format = CODEC_JP2;
+ /* Check for SOC marker -- if found we have a bare J2K stream */
+ if (buf->data[0] == 0xFF && buf->data[1] == 0x4F)
+ format = CODEC_J2K;
+ else
+ format = CODEC_JP2;
- memset(&evtmgr, 0, sizeof(evtmgr));
- evtmgr.error_handler = fz_opj_error_callback;
- evtmgr.warning_handler = fz_opj_warning_callback;
- evtmgr.info_handler = fz_opj_info_callback;
+ memset(&evtmgr, 0, sizeof(evtmgr));
+ evtmgr.error_handler = fz_opj_error_callback;
+ evtmgr.warning_handler = fz_opj_warning_callback;
+ evtmgr.info_handler = fz_opj_info_callback;
- opj_set_default_decoder_parameters(&params);
+ opj_set_default_decoder_parameters(&params);
- info = opj_create_decompress(format);
- opj_set_event_mgr((opj_common_ptr)info, &evtmgr, stderr);
- opj_setup_decoder(info, &params);
+ info = opj_create_decompress(format);
+ opj_set_event_mgr((opj_common_ptr)info, &evtmgr, stderr);
+ opj_setup_decoder(info, &params);
- cio = opj_cio_open((opj_common_ptr)info, buf->data, buf->len);
+ cio = opj_cio_open((opj_common_ptr)info, buf->data, buf->len);
- state->image = opj_decode(info, cio);
+ jpx = opj_decode(info, cio);
- opj_cio_close(cio);
- opj_destroy_decompress(info);
- fz_dropbuffer(buf);
+ opj_cio_close(cio);
+ opj_destroy_decompress(info);
+ fz_dropbuffer(buf);
- if (!state->image)
- return fz_throw("opj_decode failed");
+ if (!jpx)
+ return fz_throw("opj_decode failed");
- for (k = 1; k < state->image->numcomps; k++)
- {
- if (state->image->comps[k].w != state->image->comps[0].w)
- return fz_throw("image components have different width");
- if (state->image->comps[k].h != state->image->comps[0].h)
- return fz_throw("image components have different height");
- if (state->image->comps[k].prec != state->image->comps[0].prec)
- return fz_throw("image components have different precision");
- }
+ for (k = 1; k < jpx->numcomps; k++)
+ {
+ if (jpx->comps[k].w != jpx->comps[0].w)
+ return fz_throw("image components have different width");
+ if (jpx->comps[k].h != jpx->comps[0].h)
+ return fz_throw("image components have different height");
+ if (jpx->comps[k].prec != jpx->comps[0].prec)
+ return fz_throw("image components have different precision");
}
- n = state->image->numcomps;
- w = state->image->comps[0].w;
- h = state->image->comps[0].h;
- depth = state->image->comps[0].prec;
- sgnd = state->image->comps[0].sgnd;
+ n = jpx->numcomps;
+ w = jpx->comps[0].w;
+ h = jpx->comps[0].h;
+ depth = jpx->comps[0].prec;
+ sgnd = jpx->comps[0].sgnd;
+
+ img = fz_malloc(sizeof(pdf_image));
+ memset(img, 0, sizeof(pdf_image));
+ img->refs = 1;
+ img->w = w;
+ img->h = h;
+ img->bpc = 8;
+ img->n = n;
+ img->stride = w * n;
+ img->samples = fz_newbuffer(w * n * h);
+ img->samples->len = img->samples->cap;
+
+ switch (n)
+ {
+ default:
+ case 1: img->colorspace = fz_devicegray; break;
+ case 3: img->colorspace = fz_devicergb; break;
+ case 4: img->colorspace = fz_devicecmyk; break;
+ }
+
+ for (k = 0; k < n; k++)
+ {
+ img->decode[k * 2] = 0;
+ img->decode[k * 2 + 1] = 1;
+ }
- while (state->y < h)
+ p = img->samples->data;
+ for (y = 0; y < h; y++)
{
- while (state->x < w)
+ for (x = 0; x < w; x++)
{
- while (state->k < n)
+ for (k = 0; k < n; k++)
{
- if (p == outbuf + outlen)
- return p - outbuf;
-
- v = state->image->comps[state->k].data[state->y * w + state->x];
+ v = jpx->comps[k].data[y * w + x];
if (sgnd)
v = v + (1 << (depth - 1));
if (depth > 8)
v = v >> (depth - 8);
-
*p++ = v;
-
- state->k ++;
}
- state->x ++;
- state->k = 0;
}
- state->y ++;
- state->x = 0;
}
- return p - outbuf;
-}
-
-static void
-closejpxd(fz_stream *stm)
-{
- fz_jpxd *state = stm->state;
- if (state->image)
- opj_image_destroy(state->image);
- fz_close(state->chain);
- fz_free(state);
-}
-
-fz_stream *
-fz_openjpxd(fz_stream *chain)
-{
- fz_jpxd *state;
+ opj_image_destroy(jpx);
- state = fz_malloc(sizeof(fz_jpxd));
- state->chain = chain;
- state->image = nil;
- state->x = 0;
- state->y = 0;
- state->k = 0;
+ pdf_logimage("}\n");
- return fz_newstream(state, readjpxd, closejpxd);
+ *imgp = img;
+ return fz_okay;
}