summaryrefslogtreecommitdiff
path: root/source/fitz
diff options
context:
space:
mode:
authorMichael Vrhel <michael.vrhel@artifex.com>2017-10-16 16:47:27 -0700
committerRobin Watts <robin.watts@artifex.com>2017-10-25 10:58:35 +0100
commit105c94fc911b9468f0d7a25531dddfffdc0275b1 (patch)
tree5caadb4bc95bd0d3a4530c24c9a66c695237217b /source/fitz
parent43222aff82944fd4f59281287390cea9cafea282 (diff)
downloadmupdf-105c94fc911b9468f0d7a25531dddfffdc0275b1.tar.xz
Get ICC information from JPEG image
Diffstat (limited to 'source/fitz')
-rw-r--r--source/fitz/load-jpeg.c47
1 files changed, 46 insertions, 1 deletions
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;
}