diff options
Diffstat (limited to 'filter/jpxd.c')
-rw-r--r-- | filter/jpxd.c | 144 |
1 files changed, 144 insertions, 0 deletions
diff --git a/filter/jpxd.c b/filter/jpxd.c new file mode 100644 index 00000000..26ec743b --- /dev/null +++ b/filter/jpxd.c @@ -0,0 +1,144 @@ +#include <fitz.h> + +/* TODO: bpc */ + +/* + * We use the Jasper JPEG2000 coder for now. + */ + +#include <jasper/jasper.h> + +static char *colorspacename(jas_clrspc_t clrspc) +{ + switch (jas_clrspc_fam(clrspc)) + { + case JAS_CLRSPC_FAM_UNKNOWN: return "Unknown"; + case JAS_CLRSPC_FAM_XYZ: return "XYZ"; + case JAS_CLRSPC_FAM_LAB: return "Lab"; + case JAS_CLRSPC_FAM_GRAY: return "Gray"; + case JAS_CLRSPC_FAM_RGB: return "RGB"; + case JAS_CLRSPC_FAM_YCBCR: return "YCbCr"; + } + return "Unknown"; +} + +typedef struct fz_jpxd_s fz_jpxd; + +struct fz_jpxd_s +{ + fz_filter super; + jas_stream_t *stream; + jas_image_t *image; + int offset; + int stage; +}; + +fz_error * +fz_newjpxd(fz_filter **fp, fz_obj *params) +{ + int err; + + FZ_NEWFILTER(fz_jpxd, d, jpxd); + + err = jas_init(); + if (err) { + fz_free(d); + return fz_throw("ioerror in jpxd: jas_init()"); + } + + d->stream = jas_stream_memopen(nil, 0); + if (!d->stream) { + fz_free(d); + return fz_throw("ioerror in jpxd: jas_stream_memopen()"); + } + + d->image = nil; + d->offset = 0; + d->stage = 0; + + return nil; +} + +void +fz_freejpxd(fz_filter *filter) +{ + fz_jpxd *d = (fz_jpxd*)filter; + if (d->stream) jas_stream_close(d->stream); + if (d->image) jas_image_destroy(d->image); + fz_free(d); +} + +fz_error * +fz_processjpxd(fz_filter *filter, fz_buffer *in, fz_buffer *out) +{ + fz_jpxd *d = (fz_jpxd*)filter; + int n, bpc, w, h; + int i, x, y; + + switch (d->stage) + { + case 0: goto input; + case 1: goto decode; + case 2: goto output; + } + +input: + while (in->rp < in->wp) { + n = jas_stream_write(d->stream, in->rp, in->wp - in->rp); + in->rp += n; + } + + if (!in->eof) + return fz_ioneedin; + + d->stage = 1; + +decode: + jas_stream_seek(d->stream, 0, 0); + + d->image = jas_image_decode(d->stream, -1, 0); + if (!d->image) + return fz_throw("ioerror in jpxd: unable to decode image data"); + + fprintf(stderr, "P%c\n# JPX %d x %d n=%d bpc=%d colorspace=%04x %s\n%d %d\n%d\n", + jas_image_numcmpts(d->image) == 1 ? '5' : '6', + + jas_image_width(d->image), + jas_image_height(d->image), + jas_image_numcmpts(d->image), + jas_image_cmptprec(d->image, 0), + jas_image_clrspc(d->image), + colorspacename(jas_image_clrspc(d->image)), + + jas_image_width(d->image), + jas_image_height(d->image), + (1 << jas_image_cmptprec(d->image, 0)) - 1); + + d->stage = 2; + +output: + w = jas_image_width(d->image); + h = jas_image_height(d->image); + n = jas_image_numcmpts(d->image); + bpc = jas_image_cmptprec(d->image, 0); /* use precision of first component for all... */ + + while (d->offset < w * h) + { + y = d->offset / w; + x = d->offset - y * w; + + /* FIXME bpc != 8 */ + + if (out->wp + n >= out->ep) + return fz_ioneedout; + + for (i = 0; i < n; i++) + *out->wp++ = jas_image_readcmptsample(d->image, i, x, y); + + d->offset ++; + } + + out->eof = 1; + return fz_iodone; +} + |