diff options
author | Tor Andersson <tor@ghostscript.com> | 2010-07-29 23:17:46 +0000 |
---|---|---|
committer | Tor Andersson <tor@ghostscript.com> | 2010-07-29 23:17:46 +0000 |
commit | d797d4707564bd9c0e1536d1d6355945aa1be740 (patch) | |
tree | b6aef992de0ce2aa306c4dd330512852c1a63ede /fitz/filt_jpxd.c | |
parent | 0b954421d7908c8b835d96b4a945418c2ae08de7 (diff) | |
download | mupdf-d797d4707564bd9c0e1536d1d6355945aa1be740.tar.xz |
Use chained reader like interface for filters instead of process interface.
Diffstat (limited to 'fitz/filt_jpxd.c')
-rw-r--r-- | fitz/filt_jpxd.c | 193 |
1 files changed, 91 insertions, 102 deletions
diff --git a/fitz/filt_jpxd.c b/fitz/filt_jpxd.c index 4580224a..01f15c1b 100644 --- a/fitz/filt_jpxd.c +++ b/fitz/filt_jpxd.c @@ -7,12 +7,8 @@ typedef struct fz_jpxd_s fz_jpxd; struct fz_jpxd_s { - fz_filter super; - opj_event_mgr_t evtmgr; - opj_dparameters_t params; - opj_dinfo_t *info; + fz_stream *chain; opj_image_t *image; - int stage; int x, y, k; }; @@ -31,136 +27,129 @@ static void fz_opj_info_callback(const char *msg, void *client_data) /* fprintf(stdout, "openjpeg info: %s", msg); */ } -fz_filter * -fz_newjpxd(fz_obj *params) -{ - FZ_NEWFILTER(fz_jpxd, d, jpxd); - - d->info = nil; - d->image = nil; - d->stage = 0; - - d->x = 0; - d->y = 0; - d->k = 0; - - return (fz_filter*)d; -} - -void -fz_dropjpxd(fz_filter *filter) +static int +readjpxd(fz_stream *stm, unsigned char *outbuf, int outlen) { - fz_jpxd *d = (fz_jpxd*)filter; - if (d->image) - opj_image_destroy(d->image); - if (d->info) - opj_destroy_decompress(d->info); -} - -fz_error -fz_processjpxd(fz_filter *filter, fz_buffer *in, fz_buffer *out) -{ - fz_jpxd *d = (fz_jpxd*)filter; + fz_jpxd *state = stm->state; + unsigned char *p = outbuf; + opj_event_mgr_t evtmgr; + opj_dparameters_t params; + opj_dinfo_t *info; + opj_cio_t *cio; int format; int n, w, h, depth, sgnd; int k, v; - opj_cio_t *cio; - - switch (d->stage) + if (!state->image) { - case 0: goto input; - case 1: goto decode; - case 2: goto output; - } - -input: - /* Wait until we have the entire file in the input buffer */ - if (!in->eof) - return fz_ioneedin; + fz_error error; + fz_buffer *buf; - d->stage = 1; + error = fz_readall(&buf, state->chain); + if (error) + return fz_throw("read error in jpx filter"); -decode: - memset(&d->evtmgr, 0, sizeof(d->evtmgr)); - d->evtmgr.error_handler = fz_opj_error_callback; - d->evtmgr.warning_handler = fz_opj_warning_callback; - d->evtmgr.info_handler = fz_opj_info_callback; + if (buf->len < 2) + { + fz_dropbuffer(buf); + return fz_throw("not enough data to determine image format"); + } - opj_set_default_decoder_parameters(&d->params); + /* 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; - if (in->wp - in->rp < 2) - return fz_throw("not enough data to determine image format"); + 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; - /* Check for SOC marker -- if found we have a bare J2K stream */ - if (in->rp[0] == 0xFF && in->rp[1] == 0x4F) - format = CODEC_J2K; - else - format = CODEC_JP2; + opj_set_default_decoder_parameters(¶ms); - d->info = opj_create_decompress(format); - if (!d->info) - fz_warn("assert: opj_create_decompress failed"); + info = opj_create_decompress(format); + opj_set_event_mgr((opj_common_ptr)info, &evtmgr, stderr); + opj_setup_decoder(info, ¶ms); - opj_set_event_mgr((opj_common_ptr)d->info, &d->evtmgr, stderr); - opj_setup_decoder(d->info, &d->params); + cio = opj_cio_open((opj_common_ptr)info, buf->data, buf->len); - cio = opj_cio_open((opj_common_ptr)d->info, in->rp, in->wp - in->rp); - in->rp = in->wp; + state->image = opj_decode(info, cio); - d->image = opj_decode(d->info, cio); - if (!d->image) - { opj_cio_close(cio); - return fz_throw("opj_decode failed"); - } + opj_destroy_decompress(info); + fz_dropbuffer(buf); - opj_cio_close(cio); + if (!state->image) + return fz_throw("opj_decode failed"); - for (k = 1; k < d->image->numcomps; k++) - { - if (d->image->comps[k].w != d->image->comps[0].w) - return fz_throw("image components have different width"); - if (d->image->comps[k].h != d->image->comps[0].h) - return fz_throw("image components have different height"); - if (d->image->comps[k].prec != d->image->comps[0].prec) - return fz_throw("image components have different precision"); + 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"); + } } - d->stage = 2; + 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; -output: - n = d->image->numcomps; - w = d->image->comps[0].w; - h = d->image->comps[0].h; - depth = d->image->comps[0].prec; - sgnd = d->image->comps[0].sgnd; - - while (d->y < h) + while (state->y < h) { - while (d->x < w) + while (state->x < w) { - while (d->k < n) + while (state->k < n) { - if (out->wp == out->ep) - return fz_ioneedout; + if (p == outbuf + outlen) + return p - outbuf; - v = d->image->comps[d->k].data[d->y * w + d->x]; + v = state->image->comps[state->k].data[state->y * w + state->x]; if (sgnd) v = v + (1 << (depth - 1)); if (depth > 8) v = v >> (depth - 8); - *out->wp++ = v; + *p++ = v; - d->k ++; + state->k ++; } - d->x ++; - d->k = 0; + state->x ++; + state->k = 0; } - d->y ++; - d->x = 0; + state->y ++; + state->x = 0; } - return fz_iodone; + 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; + + state = fz_malloc(sizeof(fz_jpxd)); + state->chain = chain; + state->image = nil; + state->x = 0; + state->y = 0; + state->k = 0; + + return fz_newstream(state, readjpxd, closejpxd); } |