From 105c94fc911b9468f0d7a25531dddfffdc0275b1 Mon Sep 17 00:00:00 2001 From: Michael Vrhel Date: Mon, 16 Oct 2017 16:47:27 -0700 Subject: Get ICC information from JPEG image --- source/fitz/load-jpeg.c | 47 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 46 insertions(+), 1 deletion(-) (limited to 'source') diff --git a/source/fitz/load-jpeg.c b/source/fitz/load-jpeg.c index 7a78e7ad..266cfc80 100644 --- a/source/fitz/load-jpeg.c +++ b/source/fitz/load-jpeg.c @@ -115,6 +115,41 @@ static inline int read_value(const unsigned char *data, int bytes, int is_big_en return value; } +/* FIXME: We may need to worry about profiles spread out + * across multiple markers. */ +static fz_colorspace *extract_icc_profile(fz_context *ctx, jpeg_saved_marker_ptr init_marker) +{ + const unsigned char *data; + int size; + jpeg_saved_marker_ptr marker = init_marker; + fz_buffer *buff = NULL; + fz_colorspace *cs = NULL; + + for (marker = init_marker; marker != NULL; marker = marker->next) + { + if (marker->marker == JPEG_APP0 + 2) + { + data = (const unsigned char *)marker->data + 14; + size = marker->data_length - 14; + break; + } + } + if (marker == NULL) + return NULL; + + fz_try(ctx) + { + buff = fz_new_buffer_from_copied_data(ctx, data, size); + cs = fz_new_icc_colorspace(ctx, NULL, 0, buff); + } + fz_always(ctx) + fz_drop_buffer(ctx, buff); + fz_catch(ctx) + fz_warn(ctx, "Failed to ICC Profile from JPEG"); + + return cs; +} + static int extract_exif_resolution(jpeg_saved_marker_ptr marker, int *xres, int *yres) { int is_big_endian; @@ -224,7 +259,7 @@ fz_load_jpeg(fz_context *ctx, const unsigned char *rbuf, size_t rlen) struct jpeg_error_mgr err; struct jpeg_source_mgr src; unsigned char *row[1], *sp, *dp; - fz_colorspace *colorspace; + fz_colorspace *colorspace, *cs = NULL; unsigned int x; int k, stride; fz_pixmap *image = NULL; @@ -271,6 +306,10 @@ fz_load_jpeg(fz_context *ctx, const unsigned char *rbuf, size_t rlen) else fz_throw(ctx, FZ_ERROR_GENERIC, "bad number of components in jpeg: %d", cinfo.num_components); + cs = extract_icc_profile(ctx, cinfo.marker_list); + if (cs != NULL) + colorspace = cs; + image = fz_new_pixmap(ctx, colorspace, cinfo.output_width, cinfo.output_height, NULL, 0); if (extract_exif_resolution(cinfo.marker_list, &image->xres, &image->yres)) @@ -339,6 +378,7 @@ fz_load_jpeg_info(fz_context *ctx, const unsigned char *rbuf, size_t rlen, int * struct jpeg_decompress_struct cinfo; struct jpeg_error_mgr err; struct jpeg_source_mgr src; + fz_colorspace *cs = NULL; fz_try(ctx) { @@ -363,6 +403,7 @@ fz_load_jpeg_info(fz_context *ctx, const unsigned char *rbuf, size_t rlen, int * jpeg_save_markers(&cinfo, JPEG_APP0+1, 0xffff); jpeg_save_markers(&cinfo, JPEG_APP0+13, 0xffff); + jpeg_save_markers(&cinfo, JPEG_APP0+2, 0xffff); jpeg_read_header(&cinfo, 1); @@ -398,6 +439,10 @@ fz_load_jpeg_info(fz_context *ctx, const unsigned char *rbuf, size_t rlen, int * *yresp = 0; } + cs = extract_icc_profile(ctx, cinfo.marker_list); + if (cs != NULL) + *cspacep = cs; + if (*xresp <= 0) *xresp = 96; if (*yresp <= 0) *yresp = 96; } -- cgit v1.2.3