[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