[cairo-commit] src/cairo-image-info.c src/cairo-image-info-private.h src/cairo-pdf-surface.c

Adrian Johnson ajohnson at kemper.freedesktop.org
Fri Sep 9 13:07:33 UTC 2016


 src/cairo-image-info-private.h |    1 +
 src/cairo-image-info.c         |   21 +++++++++++++++++++++
 src/cairo-pdf-surface.c        |    2 ++
 3 files changed, 24 insertions(+)

New commits:
commit b207a932a2d3740984319dffd58a0791580597cd
Author: Peter TB Brett <peter.brett at livecode.com>
Date:   Fri Sep 9 22:35:55 2016 +0930

    Correctly decode Adobe CMYK JPEGs in PDF export
    
    Adobe PhotoShop generates CMYK JPEG files with inverted CMYK.  When a
    JPEG file with this format is included in a PDF file, a `/Decode`
    array must be included to convert to "normal" CMYK.
    
    These JPEG files can be detected via the presence of the APP14 "Adobe"
    marker.  However, PDF viewers are not required to detect and handle
    this private marker, so it must be detected and handled (by adding a
    `/Decode`) by the PDF generator.
    
    Signed-Off-By: Peter TB Brett <peter.brett at livecode.com>

diff --git a/src/cairo-image-info-private.h b/src/cairo-image-info-private.h
index e64928e..99cbbcc 100644
--- a/src/cairo-image-info-private.h
+++ b/src/cairo-image-info-private.h
@@ -43,6 +43,7 @@ typedef struct _cairo_image_info {
     int		 height;
     int		 num_components;
     int		 bits_per_component;
+    int		 is_adobe_jpeg;
 } cairo_image_info_t;
 
 cairo_private cairo_int_status_t
diff --git a/src/cairo-image-info.c b/src/cairo-image-info.c
index 26e7ae5..2ecce95 100644
--- a/src/cairo-image-info.c
+++ b/src/cairo-image-info.c
@@ -67,6 +67,9 @@
 #define SOF14 0xce
 #define SOF15 0xcf
 
+/* Start of tag markers */
+#define APP14 0xee	/* Adobe */
+
 static const unsigned char *
 _jpeg_skip_segment (const unsigned char *p)
 {
@@ -94,6 +97,8 @@ _cairo_image_info_get_jpeg_info (cairo_image_info_t	*info,
 {
     const unsigned char *p = data;
 
+    info->is_adobe_jpeg = FALSE;
+
     while (p + 1 < data + length) {
 	if (*p != 0xff)
 	    return CAIRO_INT_STATUS_UNSUPPORTED;
@@ -131,6 +136,18 @@ _cairo_image_info_get_jpeg_info (cairo_image_info_t	*info,
 	    _jpeg_extract_info (info, p);
 	    return CAIRO_STATUS_SUCCESS;
 
+	case APP14:
+	    /* "Adobe" tags segment indicates inverted CMYK (in
+	     * CMYK images). */
+	    if (p + 12 > data + length)
+		return CAIRO_INT_STATUS_UNSUPPORTED;
+
+	    info->is_adobe_jpeg =
+		(0 == strncmp((const char *)(p + 3), "Adobe", 5));
+
+	    p = _jpeg_skip_segment(p);
+	    break;
+
 	default:
 	    if (*p >= RST_begin && *p <= RST_end) {
 		p++;
@@ -206,6 +223,7 @@ _jpx_extract_info (const unsigned char *p, cairo_image_info_t *info)
     info->width = get_unaligned_be32 (p + 4);
     info->num_components = (p[8] << 8) + p[9];
     info->bits_per_component = p[10];
+    info->is_adobe_jpeg = FALSE;
 }
 
 cairo_int_status_t
@@ -283,6 +301,8 @@ _cairo_image_info_get_png_info (cairo_image_info_t     *info,
     p += 4;
     info->height = get_unaligned_be32 (p);
 
+    info->is_adobe_jpeg = FALSE;
+
     return CAIRO_STATUS_SUCCESS;
 }
 
@@ -395,6 +415,7 @@ _jbig2_extract_info (cairo_image_info_t *info, const unsigned char *p)
     info->height = get_unaligned_be32 (p + 4);
     info->num_components = 1;
     info->bits_per_component = 1;
+    info->is_adobe_jpeg = FALSE;
 }
 
 cairo_int_status_t
diff --git a/src/cairo-pdf-surface.c b/src/cairo-pdf-surface.c
index 09094ff..944e9d6 100644
--- a/src/cairo-pdf-surface.c
+++ b/src/cairo-pdf-surface.c
@@ -2959,6 +2959,7 @@ _cairo_pdf_surface_emit_jpeg_image (cairo_pdf_surface_t              *surface,
 						 "   /Height %d\n"
 						 "   /ColorSpace %s\n"
 						 "   /Interpolate %s\n"
+						 "%s"
 						 "   /BitsPerComponent %d\n"
 						 "%s"
 						 "   /Filter /DCTDecode\n",
@@ -2966,6 +2967,7 @@ _cairo_pdf_surface_emit_jpeg_image (cairo_pdf_surface_t              *surface,
 						 info.height,
 						 colorspace,
 						 surface_entry->interpolate ? "true" : "false",
+						 info.is_adobe_jpeg && info.num_components == 4 ? "   /Decode [ 1 0 1 0 1 0 1 0 ]\n" : "",
 						 info.bits_per_component,
 						 smask_buf);
     }


More information about the cairo-commit mailing list