int xps_decode_jpegxr(xps_context_t *ctx, byte *buf, int len, xps_image_t *output) { FILE *file; char *name = xps_alloc(ctx, gp_file_name_sizeof); struct state state; jxr_container_t container; jxr_image_t image; int offset, alpha_offset; int rc; if (!name) { return gs_throw(gs_error_VMerror, "cannot allocate scratch file name buffer"); } memset(output, 0, sizeof(*output)); file = gp_open_scratch_file(ctx->memory, "jpegxr-scratch-", name, "wb+"); if (!file) { xps_free(ctx, name); return gs_throw(gs_error_invalidfileaccess, "cannot open scratch file"); } rc = fwrite(buf, 1, len, file); if (rc != len) { xps_free(ctx, name); return gs_throw(gs_error_invalidfileaccess, "cannot write to scratch file"); } fseek(file, 0, SEEK_SET); container = jxr_create_container(); rc = jxr_read_image_container(container, file); if (rc < 0) { xps_free(ctx, name); return gs_throw1(-1, "jxr_read_image_container: %s", jxr_error_string(rc)); } offset = jxrc_image_offset(container, 0); alpha_offset = jxrc_alpha_offset(container, 0); output->xres = jxrc_width_resolution(container, 0); output->yres = jxrc_height_resolution(container, 0); image = jxr_create_input(); jxr_set_PROFILE_IDC(image, 111); jxr_set_LEVEL_IDC(image, 255); jxr_set_pixel_format(image, jxrc_image_pixelformat(container, 0)); jxr_set_container_parameters(image, jxrc_image_pixelformat(container, 0), jxrc_image_width(container, 0), jxrc_image_height(container, 0), jxrc_alpha_offset(container, 0), jxrc_image_band_presence(container, 0), jxrc_alpha_band_presence(container, 0), 0); jxr_set_block_output(image, xps_decode_jpegxr_block); state.ctx = ctx; state.output = output; jxr_set_user_data(image, &state); fseek(file, offset, SEEK_SET); rc = jxr_read_image_bitstream(image, file); if (rc < 0) { xps_free(ctx, name); return gs_throw1(-1, "jxr_read_image_bitstream: %s", jxr_error_string(rc)); } jxr_destroy(image); if (alpha_offset > 0) { image = jxr_create_input(); jxr_set_PROFILE_IDC(image, 111); jxr_set_LEVEL_IDC(image, 255); jxr_set_pixel_format(image, jxrc_image_pixelformat(container, 0)); jxr_set_container_parameters(image, jxrc_image_pixelformat(container, 0), jxrc_image_width(container, 0), jxrc_image_height(container, 0), jxrc_alpha_offset(container, 0), jxrc_image_band_presence(container, 0), jxrc_alpha_band_presence(container, 0), 0); jxr_set_block_output(image, xps_decode_jpegxr_alpha_block); state.ctx = ctx; state.output = output; jxr_set_user_data(image, &state); fseek(file, alpha_offset, SEEK_SET); rc = jxr_read_image_bitstream(image, file); if (rc < 0) { xps_free(ctx, name); return gs_throw1(-1, "jxr_read_image_bitstream: %s", jxr_error_string(rc)); } jxr_destroy(image); } jxr_destroy_container(container); fclose(file); unlink(name); xps_free(ctx, name); return gs_okay; }
static void jxr_read_image(fz_context *ctx, unsigned char *data, int size, struct info *info, int only_metadata) { jxr_container_t container; jxr_image_t image = NULL; jxr_image_t alpha = NULL; int rc, i; fz_try(ctx) { container = jxr_create_container(); rc = jxr_read_image_container_memory(container, data, size); if (rc < 0) fz_throw(ctx, FZ_ERROR_GENERIC, "cannot read jxr image container: %s", jxr_error_string(rc)); info->xres = jxrc_width_resolution(container, 0); info->yres = jxrc_height_resolution(container, 0); info->width = jxrc_image_width(container, 0); info->height = jxrc_image_height(container, 0); info->format = jxrc_image_pixelformat(container, 0); for (i = 0; i < nelem(pixelformats); i++) if (pixelformats[i].format == info->format) { info->comps = pixelformats[i].comps; break; } if (i == nelem(pixelformats)) fz_throw(ctx, FZ_ERROR_GENERIC, "unsupported pixel format: %u", info->format); if (info->comps == 1) info->cspace = fz_device_gray(ctx); else if (info->comps == 3) info->cspace = fz_device_rgb(ctx); else if (info->comps >= 4) info->cspace = fz_device_cmyk(ctx); info->stride = info->width * (fz_colorspace_n(ctx, info->cspace) + 1); if (!only_metadata) { unsigned long image_offset; unsigned char image_band; unsigned long alpha_offset; unsigned char alpha_band; info->ctx = ctx; info->samples = fz_malloc(ctx, info->stride * info->height); memset(info->samples, 0xff, info->stride * info->height); image_offset = jxrc_image_offset(container, 0); image_band = jxrc_image_band_presence(container, 0); alpha_offset = jxrc_alpha_offset(container, 0); alpha_band = jxrc_alpha_band_presence(container, 0); image = jxr_create_input(); jxr_set_PROFILE_IDC(image, 111); jxr_set_LEVEL_IDC(image, 255); jxr_set_pixel_format(image, info->format); jxr_set_container_parameters(image, info->format, info->width, info->height, alpha_offset, image_band, alpha_band, 0); jxr_set_user_data(image, info); jxr_set_block_output(image, jxr_decode_block); rc = jxr_read_image_bitstream_memory(image, data + image_offset, size - image_offset); if (rc < 0) fz_throw(ctx, FZ_ERROR_GENERIC, "cannot read jxr image: %s", jxr_error_string(rc)); if (info->format == JXRC_FMT_32bppPBGRA || info->format == JXRC_FMT_64bppPRGBA || info->format == JXRC_FMT_128bppPRGBAFloat) info->has_premul = 1; if (jxr_get_ALPHACHANNEL_FLAG(image)) info->has_alpha = 1; if (alpha_offset > 0) { info->has_alpha = 1; alpha = jxr_create_input(); jxr_set_PROFILE_IDC(alpha, 111); jxr_set_LEVEL_IDC(alpha, 255); jxr_set_pixel_format(alpha, info->format); jxr_set_container_parameters(alpha, info->format, info->width, info->height, alpha_offset, image_band, alpha_band, 1); jxr_set_user_data(alpha, info); jxr_set_block_output(alpha, jxr_decode_block_alpha); rc = jxr_read_image_bitstream_memory(alpha, data + alpha_offset, size - alpha_offset); if (rc < 0) fz_throw(ctx, FZ_ERROR_GENERIC, "cannot read jxr image: %s", jxr_error_string(rc)); } } } fz_always(ctx) { if (alpha) jxr_destroy(alpha); if (image) jxr_destroy(image); jxr_destroy_container(container); } fz_catch(ctx) { fz_rethrow(ctx); } }