diff options
-rw-r--r-- | Makethird | 161 | ||||
-rw-r--r-- | docs/thirdparty.txt | 3 | ||||
-rw-r--r-- | source/fitz/load-jpx.c | 480 |
3 files changed, 590 insertions, 54 deletions
@@ -175,7 +175,7 @@ endif # --- LURATECH --- -ifneq "$(wildcard $(LURATECH_DIR)/ldf_jb2)" "" +ifneq "$(wildcard $(LURATECH_DIR)/ldf_jb2)$(wildcard $(LURATECH_DIR)/lwf_jp2)" "" LURATECH_OUT := $(OUT)/luratech LURATECH_SRC := \ @@ -248,7 +248,63 @@ LURATECH_SRC := \ jb2_adt_write_data.c \ jb2_adt_write_pdf.c \ jb2_common.c \ - jb2_license_dummy.c + jb2_license_dummy.c \ + jp2_adt_band_array.c \ + jp2_adt_band_buffer.c \ + jp2_adt_block_array.c \ + jp2_adt_cache.c \ + jp2_adt_comp.c \ + jp2_adt_component_array.c \ + jp2_adt_decomp.c \ + jp2_adt_ebcot_decoder.c \ + jp2_adt_external_cache.c \ + jp2_adt_image.c \ + jp2_adt_memory.c \ + jp2_adt_mq_decoder.c \ + jp2_adt_mq_state.c \ + jp2_adt_packet_decoder.c \ + jp2_adt_precinct_array.c \ + jp2_adt_rate.c \ + jp2_adt_rate_list.c \ + jp2_adt_read_bits.c \ + jp2_adt_read_data.c \ + jp2_adt_reader_requirements.c \ + jp2_adt_resolution_array.c \ + jp2_adt_tile_array.c \ + jp2_adt_tlm_marker_array.c \ + jp2_adt_write_data.c \ + jp2_buffer.c \ + jp2c_code_cb.c \ + jp2c_coder.c \ + jp2c_codestream.c \ + jp2c_file_format.c \ + jp2c_format.c \ + jp2c_memory.c \ + jp2_code_cb.c \ + jp2_common.c \ + jp2c_progression.c \ + jp2c_quant.c \ + jp2c_wavelet.c \ + jp2c_wavelet_lifting.c \ + jp2c_weights.c \ + jp2c_write.c \ + jp2d_codestream.c \ + jp2d_decoder.c \ + jp2d_file_format.c \ + jp2d_format.c \ + jp2d_image.c \ + jp2d_memory.c \ + jp2d_partial_decoding.c \ + jp2d_progression.c \ + jp2d_quant.c \ + jp2d_scale.c \ + jp2d_wavelet.c \ + jp2d_wavelet_lifting.c \ + jp2d_write.c \ + jp2_icc.c \ + jp2_license.c \ + jp2_packet.c \ + jp2_tag_tree.c LURATECH_OBJ := $(addprefix $(LURATECH_OUT)/, $(LURATECH_SRC:%.c=%.o)) @@ -256,24 +312,23 @@ $(LURATECH_OUT): $(MKDIR_CMD) $(LURATECH_OUT)/%.o: $(LURATECH_DIR)/ldf_jb2/source/common/%.c | $(LURATECH_OUT) $(CC_CMD) \ - -I$(LURATECH_DIR)/ldf_jb2/source/libraries \ - -I$(LURATECH_DIR)/ldf_jb2/source/compress \ -I$(LURATECH_DIR)/ldf_jb2/source/common \ -DLINUX $(LURATECH_OUT)/%.o: $(LURATECH_DIR)/ldf_jb2/source/compress/%.c | $(LURATECH_OUT) $(CC_CMD) \ - -I$(LURATECH_DIR)/ldf_jb2/source/libraries \ - -I$(LURATECH_DIR)/ldf_jb2/source/compress \ -I$(LURATECH_DIR)/ldf_jb2/source/common \ -DLINUX -$(LURATECH_OUT)/%.o: $(LURATECH_DIR)/lwf_jp2/%.c | $(LURATECH_OUT) +$(LURATECH_OUT)/%.o: $(LURATECH_DIR)/lwf_jp2/library/source/%.c | $(LURATECH_OUT) $(CC_CMD) \ - -I$(LURATECH_DIR)/ldf_jb2/source/libraries \ - -I$(LURATECH_DIR)/ldf_jb2/source/compress \ -I$(LURATECH_DIR)/ldf_jb2/source/common \ -DLINUX -LURATECH_CFLAGS := -I$(LURATECH_DIR)/ldf_jb2/source/libraries -DHAVE_LURATECH +LURATECH_CFLAGS := \ +-I$(LURATECH_DIR)/ldf_jb2/source/common \ + -I$(LURATECH_DIR)/ldf_jb2/source/libraries \ + -I$(LURATECH_DIR)/ldf_jb2/source/compress \ + -I$(LURATECH_DIR)/lwf_jp2/library/source \ + -DHAVE_LURATECH else # --- LURATECH --- @@ -312,6 +367,49 @@ JBIG2DEC_CFLAGS := $(SYS_JBIG2DEC_CFLAGS) JBIG2DEC_LIBS := $(SYS_JBIG2DEC_LIBS) endif +# --- OpenJPEG --- + +ifneq "$(wildcard $(OPENJPEG_DIR)/CMakeLists.txt)" "" + +OPENJPEG_OUT := $(OUT)/openjpeg +OPENJPEG_SRC := \ + bio.c \ + cidx_manager.c \ + cio.c \ + dwt.c \ + event.c \ + function_list.c \ + image.c \ + invert.c \ + j2k.c \ + jp2.c \ + mct.c \ + mqc.c \ + openjpeg.c \ + phix_manager.c \ + pi.c \ + ppix_manager.c \ + raw.c \ + t1.c \ + t2.c \ + tcd.c \ + tgt.c \ + thix_manager.c \ + tpix_manager.c \ + +OPENJPEG_OBJ := $(addprefix $(OPENJPEG_OUT)/, $(OPENJPEG_SRC:%.c=%.o)) + +$(OPENJPEG_OUT): + $(MKDIR_CMD) +$(OPENJPEG_OUT)/%.o: $(OPENJPEG_DIR)/%.c | $(OPENJPEG_OUT) + $(CC_CMD) -DOPJ_STATIC -DOPJ_HAVE_STDINT_H + +OPENJPEG_CFLAGS += -I$(OPENJPEG_DIR) -DOPJ_HAVE_INTTYPES_H=1 -DUSE_JPIP=1 +else +OPENJPEG_CFLAGS := $(SYS_OPENJPEG_CFLAGS) +OPENJPEG_LIBS := $(SYS_OPENJPEG_LIBS) +endif + endif # --- LURATECH --- # --- JPEG library from IJG --- @@ -364,49 +462,6 @@ JPEG_CFLAGS := $(SYS_JPEG_CFLAGS) -DSHARE_JPEG JPEG_LIBS := $(SYS_JPEG_LIBS) endif -# --- OpenJPEG --- - -ifneq "$(wildcard $(OPENJPEG_DIR)/CMakeLists.txt)" "" - -OPENJPEG_OUT := $(OUT)/openjpeg -OPENJPEG_SRC := \ - bio.c \ - cidx_manager.c \ - cio.c \ - dwt.c \ - event.c \ - function_list.c \ - image.c \ - invert.c \ - j2k.c \ - jp2.c \ - mct.c \ - mqc.c \ - openjpeg.c \ - phix_manager.c \ - pi.c \ - ppix_manager.c \ - raw.c \ - t1.c \ - t2.c \ - tcd.c \ - tgt.c \ - thix_manager.c \ - tpix_manager.c \ - -OPENJPEG_OBJ := $(addprefix $(OPENJPEG_OUT)/, $(OPENJPEG_SRC:%.c=%.o)) - -$(OPENJPEG_OUT): - $(MKDIR_CMD) -$(OPENJPEG_OUT)/%.o: $(OPENJPEG_DIR)/%.c | $(OPENJPEG_OUT) - $(CC_CMD) -DOPJ_STATIC -DOPJ_HAVE_STDINT_H - -OPENJPEG_CFLAGS += -I$(OPENJPEG_DIR) -DOPJ_HAVE_INTTYPES_H=1 -DUSE_JPIP=1 -else -OPENJPEG_CFLAGS := $(SYS_OPENJPEG_CFLAGS) -OPENJPEG_LIBS := $(SYS_OPENJPEG_LIBS) -endif - # --- ZLIB --- ifneq "$(wildcard $(ZLIB_DIR)/README)" "" diff --git a/docs/thirdparty.txt b/docs/thirdparty.txt index 491d76ee..e8dce82b 100644 --- a/docs/thirdparty.txt +++ b/docs/thirdparty.txt @@ -29,6 +29,9 @@ zlib 1.2.7 (De)Flate zlib License http://www.zlib.net/ curl 7.31.0 HTTP data MIT-style http://curl.haxx.se/ transfer +Luratech JP2 JPEG 2000 commercial http://www.luratech.com/ + decoding + Luratech JBIG2 JBIG2 commercial http://www.luratech.com/ decoding diff --git a/source/fitz/load-jpx.c b/source/fitz/load-jpx.c index c1ed831a..a79a268e 100644 --- a/source/fitz/load-jpx.c +++ b/source/fitz/load-jpx.c @@ -1,5 +1,480 @@ #include "mupdf/fitz.h" +#ifdef HAVE_LURATECH + +#include <lwf_jp2.h> + +typedef struct fz_jpxd_s fz_jpxd; + +struct fz_jpxd_s +{ + JP2_Decomp_Handle doc; + fz_context *ctx; + fz_pixmap *pix; + JP2_Palette_Params *palette; + JP2_Colorspace colorspace; + unsigned char *data; + int size; + JP2_Property_Value width; + JP2_Property_Value height; + fz_colorspace *cs; + int expand_indexed; + unsigned long xres; + unsigned long yres; + + JP2_Property_Value nchans; + JP2_Property_Value *widths; + JP2_Property_Value *heights; + JP2_Property_Value *hstep; + JP2_Property_Value *vstep; + JP2_Property_Value *bpss; + JP2_Property_Value *signs; +}; + +static void * JP2_Callback_Conv +jpx_alloc(long size, JP2_Callback_Param param) +{ + fz_jpxd *state = (fz_jpxd *) param; + return fz_malloc(state->ctx, size); +} + +static JP2_Error JP2_Callback_Conv +jpx_free(void *ptr, JP2_Callback_Param param) +{ + fz_jpxd *state = (fz_jpxd *) param; + fz_free(state->ctx, ptr); + return cJP2_Error_OK; +} + +static unsigned long JP2_Callback_Conv +jpx_read(unsigned char *pucData, + unsigned long ulPos, unsigned long ulSize, + JP2_Callback_Param param) +{ + fz_jpxd *state = (fz_jpxd *) param; + + if (ulPos < 0 || ulPos >= state->size) + return 0; + + ulSize = fz_mini(ulSize, state->size - ulPos); + memcpy(pucData, &state->data[ulPos], ulSize); + return ulSize; +} + +static JP2_Error JP2_Callback_Conv +jpx_write(unsigned char * pucData, short sComponent, unsigned long ulRow, + unsigned long ulStart, unsigned long ulNum, JP2_Callback_Param param) +{ + fz_jpxd *state = (fz_jpxd *) param; + unsigned char *row; + int x, y, i; + + if (ulRow >= state->pix->h || ulStart >= state->pix->w || sComponent >= state->pix->n) + return cJP2_Error_OK; + + ulNum = fz_mini(ulNum, state->pix->w - ulStart); + + if (state->palette) + { + + row = &state->pix->samples[state->pix->stride * ulRow * state->vstep[sComponent] + + state->pix->n * ulStart * state->hstep[sComponent] + + sComponent]; + + for (y = 0; ulRow * state->vstep[sComponent] + y < state->pix->h && y < state->vstep[sComponent]; y++) + { + unsigned char *p = row; + + for (i = 0; i < ulNum; i++) + { + for (x = 0; (ulStart + i) * state->hstep[sComponent] + x < state->pix->w && x < state->hstep[sComponent]; x++) + { + unsigned char v = fz_clampi(pucData[i], 0, state->palette->ulEntries); + + if (state->expand_indexed) + { + int k; + for (k = 0; k < state->pix->n; k++) + p[k] = state->palette->ppulPalette[k][v]; + p += state->pix->n; + } + else + { + *p= v; + p++; + } + } + } + + row += state->pix->stride; + } + } + else + { + unsigned int signedoffset; + + if (state->signs[sComponent]) + signedoffset = 1 << (state->bpss[sComponent] - 1); + else + signedoffset = 0; + + row = &state->pix->samples[state->pix->stride * ulRow * state->vstep[sComponent] + + state->pix->n * ulStart * state->hstep[sComponent] + + sComponent]; + + if (state->bpss[sComponent] > 8) + { + for (y = 0; ulRow * state->vstep[sComponent] + y < state->pix->h && y < state->vstep[sComponent]; y++) + { + unsigned char *p = row; + + for (i = 0; i < ulNum; i++) + { + for (x = 0; (ulStart + i) * state->hstep[sComponent] + x < state->pix->w && x < state->hstep[sComponent]; x++) + { + unsigned int v = (pucData[2 * i + 1] << 8) | pucData[2 * i + 0]; + v &= (1 << state->bpss[sComponent]) - 1; + v -= signedoffset; + *p = v >> (state->bpss[sComponent] - 8); + p += state->pix->n; + } + } + + row += state->pix->stride; + } + } + else if (state->bpss[sComponent] == 8) + { + for (y = 0; ulRow * state->vstep[sComponent] + y < state->pix->h && y < state->vstep[sComponent]; y++) + { + unsigned char *p = row; + + for (i = 0; i < ulNum; i++) + { + for (x = 0; (ulStart + i) * state->hstep[sComponent] + x < state->pix->w && x < state->hstep[sComponent]; x++) + { + unsigned int v = pucData[i]; + v &= (1 << state->bpss[sComponent]) - 1; + v -= signedoffset; + *p = v; + p += state->pix->n; + } + } + + row += state->pix->stride; + } + } + else + { + for (y = 0; ulRow * state->vstep[sComponent] + y < state->pix->h && y < state->vstep[sComponent]; y++) + { + unsigned char *p = row; + + for (i = 0; i < ulNum; i++) + { + for (x = 0; (ulStart + i) * state->hstep[sComponent] + x < state->pix->w && x < state->hstep[sComponent]; x++) + { + unsigned int v = pucData[i]; + v &= (1 << state->bpss[sComponent]) - 1; + v -= signedoffset; + *p = v << (8 - state->bpss[sComponent]); + p += state->pix->n; + } + } + + row += state->pix->stride; + } + } + } + + return cJP2_Error_OK; +} + +static void +jpx_ycc_to_rgb(fz_context *ctx, fz_jpxd *state) +{ + int x, y; + + for (y = 0; y < state->height; y++) + { + unsigned char * row = &state->pix->samples[state->pix->stride * y]; + for (x = 0; x < state->width; x++) + { + int ycc[3]; + ycc[0] = row[x * 3 + 0]; + ycc[1] = row[x * 3 + 1]; + ycc[2] = row[x * 3 + 2]; + + /* conciously skip Y */ + if (!state->signs[1]) + ycc[1] -= 128; + if (!state->signs[2]) + ycc[2] -= 128; + + row[x * 3 + 0] = fz_clampi((double)ycc[0] + 1.402 * ycc[2], 0, 255); + row[x * 3 + 1] = fz_clampi((double)ycc[0] - 0.34413 * ycc[1] - 0.71414 * ycc[2], 0, 255); + row[x * 3 + 2] = fz_clampi((double)ycc[0] + 1.772 * ycc[1], 0, 255); + } + } + +} + +struct indexed +{ + fz_colorspace *base; + int high; + unsigned char *lookup; +}; + +static fz_pixmap * +jpx_read_image(fz_context *ctx, fz_jpxd *state, unsigned char *data, size_t size, fz_colorspace *defcs, int indexed, int onlymeta) +{ + JP2_Channel_Def_Params *chans = NULL; + JP2_Error err; + int k, colors, alphas, prealphas; + + memset(state, 0x00, sizeof (fz_jpxd)); + state->ctx = ctx; + state->data = data; + state->size = size; + + fz_try(ctx) + { + err = JP2_Decompress_Start(&state->doc, + jpx_alloc, (JP2_Callback_Param) state, + jpx_free, (JP2_Callback_Param) state, + jpx_read, (JP2_Callback_Param) state); + if (err != cJP2_Error_OK) + fz_throw(ctx, FZ_ERROR_GENERIC, "cannot open image: %d", (int) err); + +#if defined(JP2_LICENSE_NUM_1) && defined(JP2_LICENSE_NUM_2) + err = JP2_Document_SetLicense(state->doc, JP2_LICENSE_NUM_1, JP2_LICENSE_NUM_2); + if (err != cJP2_Error_OK) + fz_throw(ctx, FZ_ERROR_GENERIC, "cannot set license: %d", (int) err); +#endif + + err = JP2_Decompress_GetProp(state->doc, cJP2_Prop_Extern_Colorspace, (unsigned long *) &state->colorspace, -1, -1); + if (err != cJP2_Error_OK) + fz_throw(ctx, FZ_ERROR_GENERIC, "cannot get colorspace: %d", (int) err); + + if (state->colorspace == cJP2_Colorspace_Palette_Gray || + state->colorspace == cJP2_Colorspace_Palette_RGBa || + state->colorspace == cJP2_Colorspace_Palette_RGB_YCCa || + state->colorspace == cJP2_Colorspace_Palette_CIE_LABa || + state->colorspace == cJP2_Colorspace_Palette_ICCa || + state->colorspace == cJP2_Colorspace_Palette_CMYKa) + { + err = JP2_Decompress_GetPalette(state->doc, &state->palette); + if (err != cJP2_Error_OK) + fz_throw(ctx, FZ_ERROR_GENERIC, "cannot get indexed palette: %d", (int) err); + + /* no available sample file */ + for (k = 0; k < state->palette->ulChannels; k++) + if (state->palette->pucSignedSample[k]) + fz_throw(ctx, FZ_ERROR_GENERIC, "signed palette compoments not yet supported"); + } + + err = JP2_Decompress_GetChannelDefs(state->doc, &chans, &state->nchans); + if (err != cJP2_Error_OK) + fz_throw(ctx, FZ_ERROR_GENERIC, "cannot get channel definitions: %d", (int) err); + + colors = 0; + alphas = 0; + prealphas = 0; + for (k = 0; k < state->nchans; k++) + { + switch (chans[k].ulType) + { + case cJP2_Channel_Type_Color: colors++; break; + case cJP2_Channel_Type_Opacity: alphas++; break; + case cJP2_Channel_Type_Opacity_Pre: prealphas++; break; + } + } + + if (prealphas> 0) + alphas = prealphas; + colors = fz_clampi(colors, 0, 4); + alphas = fz_clampi(alphas, 0, 1); + + state->nchans = colors + alphas; + + state->widths = fz_malloc(ctx, state->nchans * sizeof (JP2_Property_Value)); + state->heights = fz_malloc(ctx, state->nchans * sizeof (JP2_Property_Value)); + state->hstep = fz_malloc(ctx, state->nchans * sizeof (JP2_Property_Value)); + state->vstep = fz_malloc(ctx, state->nchans * sizeof (JP2_Property_Value)); + state->bpss = fz_malloc(ctx, state->nchans * sizeof (JP2_Property_Value)); + state->signs = fz_malloc(ctx, state->nchans * sizeof (JP2_Property_Value)); + + if (state->palette) + { + err = JP2_Decompress_GetProp(state->doc, cJP2_Prop_Width, &state->width, -1, 0); + if (err != cJP2_Error_OK) + fz_throw(ctx, FZ_ERROR_GENERIC, "cannot get width for palette indicies: %d", (int) err); + err = JP2_Decompress_GetProp(state->doc, cJP2_Prop_Height, &state->height, -1, 0); + if (err != cJP2_Error_OK) + fz_throw(ctx, FZ_ERROR_GENERIC, "cannot get height for palette indicies: %d", (int) err); + + for (k = 0; k < state->nchans; k++) + { + state->widths[k] = state->width; + state->heights[k] = state->height; + state->bpss[k] = state->palette->pucBitsPerSample[k]; + state->signs[k] = state->palette->pucSignedSample[k]; + } + } + else + { + for (k = 0; k < state->nchans; k++) + { + err = JP2_Decompress_GetProp(state->doc, cJP2_Prop_Width, &state->widths[k], -1, k); + if (err != cJP2_Error_OK) + fz_throw(ctx, FZ_ERROR_GENERIC, "cannot get width for compoment %d: %d", k, (int) err); + err = JP2_Decompress_GetProp(state->doc, cJP2_Prop_Height, &state->heights[k], -1, k); + if (err != cJP2_Error_OK) + fz_throw(ctx, FZ_ERROR_GENERIC, "cannot get height for compomment %d: %d", k, (int) err); + err = JP2_Decompress_GetProp(state->doc, cJP2_Prop_Bits_Per_Sample, &state->bpss[k], -1, k); + if (err != cJP2_Error_OK) + fz_throw(ctx, FZ_ERROR_GENERIC, "cannot get bits per sample for compomment %d: %d", k, (int) err); + err = JP2_Decompress_GetProp(state->doc, cJP2_Prop_Signed_Samples, &state->signs[k], -1, k); + if (err != cJP2_Error_OK) + fz_throw(ctx, FZ_ERROR_GENERIC, "cannot get signed for compomment %d: %d", k, (int) err); + + state->width = fz_maxi(state->width, state->widths[k]); + state->height = fz_maxi(state->height, state->heights[k]); + } + } + + for (k = 0; k < state->nchans; k++) + { + state->hstep[k] = (state->width + (state->widths[k] - 1)) / state->widths[k]; + state->vstep[k] = (state->height + (state->heights[k] - 1)) / state->heights[k]; + } + + err = JP2_Decompress_GetResolution(state->doc, &state->yres, &state->xres, NULL, + cJP2_Resolution_Dots_Per_Inch, cJP2_Resolution_Capture); + if (err != cJP2_Error_OK) + fz_throw(ctx, FZ_ERROR_GENERIC, "cannot get resolution: %d", (int) err); + + if (state->xres == 0 || state->yres == 0) + state->xres = state->yres = 72; + + if (defcs) + { + if (defcs->n == state->nchans) + { + state->cs = defcs; + } + else + { + fz_warn(ctx, "jpx file (%lu) and dict colorspace (%d, %s) do not match", state->nchans, defcs->n, defcs->name); + defcs = NULL; + } + } + + if (!defcs) + { + switch (colors) + { + case 4: state->cs = fz_device_cmyk(ctx); break; + case 3: if (state->colorspace == cJP2_Colorspace_CIE_LABa) + state->cs = fz_device_lab(ctx); + else + state->cs = fz_device_rgb(ctx); + break; + case 1: state->cs = fz_device_gray(ctx); break; + case 0: if (alphas == 1) + { + /* alpha only images are rendered as grayscale */ + state->cs = fz_device_gray(ctx); + colors = 1; + alphas = 0; + break; + } + /* fallthrough */ + default: fz_throw(ctx, FZ_ERROR_GENERIC, "unsupported number of components: %lu", state->nchans); + } + } + + if (state->palette && !fz_colorspace_is_indexed(ctx, state->cs)) + state->expand_indexed = 1; + + if (!onlymeta) + { + state->pix = fz_new_pixmap(ctx, state->cs, state->width, state->height, alphas); + fz_clear_pixmap_with_value(ctx, state->pix, 0); + + err = JP2_Decompress_SetProp(state->doc, cJP2_Prop_Output_Parameter, (JP2_Property_Value) state); + if (err != cJP2_Error_OK) + fz_throw(ctx, FZ_ERROR_GENERIC, "cannot set write callback userdata: %d", (int) err); + err = JP2_Decompress_SetProp(state->doc, cJP2_Prop_Output_Function, (JP2_Property_Value) jpx_write); + if (err != cJP2_Error_OK) + fz_throw(ctx, FZ_ERROR_GENERIC, "cannot set write callback: %d", (int) err); + + err = JP2_Decompress_Image(state->doc); + if (err != cJP2_Error_OK) + fz_throw(ctx, FZ_ERROR_GENERIC, "cannot decode image: %d", (int) err); + + if (state->colorspace == cJP2_Colorspace_RGB_YCCa) + jpx_ycc_to_rgb(ctx, state); + + if (state->pix->alpha && ! (state->palette && !state->expand_indexed)) + { + if (state->pix->n == 5) + { + fz_pixmap *tmp = fz_new_pixmap(ctx, fz_device_rgb(ctx), state->pix->w, state->pix->h, 1); + fz_convert_pixmap(ctx, tmp, state->pix); + fz_drop_pixmap(ctx, state->pix); + state->pix = tmp; + } + + if (alphas > 0 && prealphas == 0) + fz_premultiply_pixmap(ctx, state->pix); + } + + } + } + fz_always(ctx) + { + JP2_Decompress_End(state->doc); + fz_free(ctx, state->signs); + fz_free(ctx, state->widths); + fz_free(ctx, state->heights); + fz_free(ctx, state->hstep); + fz_free(ctx, state->vstep); + fz_free(ctx, state->bpss); + } + fz_catch(ctx) + { + fz_rethrow(ctx); + } + + return state->pix; +} + +fz_pixmap * +fz_load_jpx(fz_context *ctx, unsigned char *data, size_t size, fz_colorspace *defcs, int indexed) +{ + fz_jpxd state = { 0 }; + + return jpx_read_image(ctx, &state, data, size, defcs, indexed, 0); +} + +void +fz_load_jpx_info(fz_context *ctx, unsigned char *data, size_t size, int *wp, int *hp, int *xresp, int *yresp, fz_colorspace **cspacep) +{ + fz_jpxd state = { 0 }; + + jpx_read_image(ctx, &state, data, size, NULL, 0, 1); + + *cspacep = state.cs; + *wp = state.width; + *hp = state.height; + *xresp = state.xres; + *yresp = state.yres; +} + +#else /* HAVE_LURATECH */ + /* Without the definition of OPJ_STATIC, compilation fails on windows * due to the use of __stdcall. We believe it is required on some * linux toolchains too. */ @@ -185,7 +660,7 @@ jpx_read_image(fz_context *ctx, unsigned char *data, size_t size, fz_colorspace } else { - fz_warn(ctx, "jpx file and dict colorspaces do not match"); + fz_warn(ctx, "jpx file and dict colorspace do not match"); defcs = NULL; } } @@ -197,6 +672,7 @@ jpx_read_image(fz_context *ctx, unsigned char *data, size_t size, fz_colorspace case 1: colorspace = fz_device_gray(ctx); break; case 3: colorspace = fz_device_rgb(ctx); break; case 4: colorspace = fz_device_cmyk(ctx); break; + default: fz_throw(ctx, FZ_ERROR_GENERIC, "unsupported number of components: %d", n); } } @@ -268,3 +744,5 @@ fz_load_jpx_info(fz_context *ctx, unsigned char *data, size_t size, int *wp, int *xresp = 72; /* openjpeg does not read the JPEG 2000 resc box */ *yresp = 72; /* openjpeg does not read the JPEG 2000 resc box */ } + +#endif /* HAVE_LURATECH */ |