diff options
author | Tor Andersson <tor@ghostscript.com> | 2010-07-30 01:16:14 +0000 |
---|---|---|
committer | Tor Andersson <tor@ghostscript.com> | 2010-07-30 01:16:14 +0000 |
commit | 39ebb88a7bed4d0963895debb80a7462530e4c91 (patch) | |
tree | d5f3f000462542c6bc9bb63710da9d1ce0a615b9 /fitz | |
parent | d797d4707564bd9c0e1536d1d6355945aa1be740 (diff) | |
download | mupdf-39ebb88a7bed4d0963895debb80a7462530e4c91.tar.xz |
Treat JPXDecode images as a special case bypassing the regular filter logic.
Diffstat (limited to 'fitz')
-rw-r--r-- | fitz/filt_jpxd.c | 188 | ||||
-rw-r--r-- | fitz/fitz.h | 1 |
2 files changed, 89 insertions, 100 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(¶ms); + opj_set_default_decoder_parameters(¶ms); - info = opj_create_decompress(format); - opj_set_event_mgr((opj_common_ptr)info, &evtmgr, stderr); - opj_setup_decoder(info, ¶ms); + info = opj_create_decompress(format); + opj_set_event_mgr((opj_common_ptr)info, &evtmgr, stderr); + opj_setup_decoder(info, ¶ms); - 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; } diff --git a/fitz/fitz.h b/fitz/fitz.h index 696a9017..1af70f6a 100644 --- a/fitz/fitz.h +++ b/fitz/fitz.h @@ -546,7 +546,6 @@ fz_stream * fz_openflated(fz_stream *chain); fz_stream * fz_openlzwd(fz_stream *chain, fz_obj *param); fz_stream * fz_openpredict(fz_stream *chain, fz_obj *param); fz_stream * fz_openjbig2d(fz_stream *chain, fz_buffer *global); -fz_stream * fz_openjpxd(fz_stream *chain); /* * Resources and other graphics related objects. |