Index: third_party/iccjpeg/iccjpeg.c |
diff --git a/third_party/iccjpeg/iccjpeg.c b/third_party/iccjpeg/iccjpeg.c |
index aa96c8bebf4a596559089d4d0750dbf87760879e..384bf8162f7700ac52d36c9db3b06ceba4d49e6e 100644 |
--- a/third_party/iccjpeg/iccjpeg.c |
+++ b/third_party/iccjpeg/iccjpeg.c |
@@ -246,3 +246,115 @@ read_icc_profile (j_decompress_ptr cinfo, |
return TRUE; |
} |
+ |
+ |
+/* |
+ * ICCbis color profile: one APP2 marker containing the following data: |
+ * Identifying string ASCII "ICC_BIS\0" (8 bytes) |
+ * Profile data (remainder of APP2 data) (2 bytes) being: |
+ * <id> (1 byte) and a <rendering-intent> (1 byte) |
+ * where <id> is non-zero, <rendering-intent> values are: |
+ * 0 Perceptual - for images preferring good adaptation to output device |
+ * gamut at the expense of colorimetric accuracy, such as photographs. |
+ * 1 Relative Colorimetric - for images requiring color appearance matching |
+ * (relative to the output device white point), such as logos. |
+ * 2 Saturation - for images preferring preservation of saturation at the |
+ * expense of hue and lightness, such as charts and graphs. |
+ * 3 Absolute Colorimetric - for images requiring preservation of absolute |
+ * colorimetry, such as previews of images destined for a different |
+ * output device (proofs). |
+ * A JPEG image can contain an implicit profile (ICC_BIS marker), or an |
+ * explicit profile (ICC_PROFILE markers), but not both. |
Noel Gordon
2016/04/04 08:37:54
Another option here might be to allow both markers
|
+ */ |
+ |
+#define ICCBIS_OVERHEAD_LENGTH 8 /* length of non-profile data in APP2 */ |
+#define ICCBIS_PROFILE_LENGTH 2 /* length of profile data in APP2 */ |
+#define ICCBIS_MARKER ICC_MARKER |
+ |
+ |
+/* |
+ * Write the given ICCbis profile data into a JPEG file. |
+ * It *must* be called AFTER calling jpeg_start_compress() and BEFORE |
+ * the first call to jpeg_write_scanlines(). |
+ * (This ordering ensures that the APP2 marker(s) will appear after the |
+ * SOI and JFIF or Adobe markers, but before all else.) |
+ */ |
+ |
+void |
+write_icc_profile_bis (j_compress_ptr cinfo, |
+ JOCTET profile, |
+ JOCTET intent) |
+{ |
+ if (profile) { |
+ /* Write the JPEG marker header (APP2 code and marker length) */ |
+ jpeg_write_m_header(cinfo, ICCBIS_MARKER, |
+ (unsigned int) (ICCBIS_OVERHEAD_LENGTH + ICCBIS_PROFILE_LENGTH)); |
+ |
+ /* Write the identifier string "ICC_BIS" (null-terminated) */ |
+ jpeg_write_m_byte(cinfo, 0x49); |
+ jpeg_write_m_byte(cinfo, 0x43); |
+ jpeg_write_m_byte(cinfo, 0x43); |
+ jpeg_write_m_byte(cinfo, 0x5F); |
+ jpeg_write_m_byte(cinfo, 0x42); |
+ jpeg_write_m_byte(cinfo, 0x49); |
+ jpeg_write_m_byte(cinfo, 0x53); |
+ jpeg_write_m_byte(cinfo, 0x0); |
+ |
+ /* Write the ICCbis profile info */ |
+ jpeg_write_m_byte(cinfo, profile); |
+ jpeg_write_m_byte(cinfo, intent); |
+ } |
+} |
+ |
+ |
+/* |
+ * Subroutine to test whether a saved marker is an ICCbis marker. |
+ */ |
+ |
+static boolean |
+marker_is_icc_bis (jpeg_saved_marker_ptr marker) |
+{ |
+ return |
+ marker->marker == ICCBIS_MARKER && |
+ marker->data_length >= ICCBIS_OVERHEAD_LENGTH && |
+ /* verify the identifying string */ |
+ GETJOCTET(marker->data[0]) == 0x49 && |
+ GETJOCTET(marker->data[1]) == 0x43 && |
+ GETJOCTET(marker->data[2]) == 0x43 && |
+ GETJOCTET(marker->data[3]) == 0x5F && |
+ GETJOCTET(marker->data[4]) == 0x42 && |
+ GETJOCTET(marker->data[5]) == 0x49 && |
+ GETJOCTET(marker->data[6]) == 0x53 && |
+ GETJOCTET(marker->data[7]) == 0x0; |
+} |
+ |
+ |
+/* |
+ * See if there was an ICCbis profile in the JPEG file being read; the |
+ * ICCbis profile is returned (0 for invalid / not found). If found, |
+ * write the rendering-intent to *intent (if given). |
+ */ |
+ |
+unsigned int |
+read_icc_profile_bis (j_decompress_ptr cinfo, unsigned int *intent) |
+{ |
+ jpeg_saved_marker_ptr marker; |
+ JOCTET FAR *src; |
+ |
+ for (marker = cinfo->marker_list; marker != NULL; marker = marker->next) { |
+ /* find ICCbis marker */ |
+ if (marker_is_icc_bis(marker)) { |
+ unsigned int length = marker->data_length - ICCBIS_OVERHEAD_LENGTH; |
+ if (length < ICCBIS_PROFILE_LENGTH) |
+ return 0; /* bogus bis profile data length */ |
+ |
+ /* return the profile info */ |
+ src = marker->data + ICCBIS_OVERHEAD_LENGTH; |
+ if (intent && GETJOCTET(src[0])) |
+ *intent = GETJOCTET(src[1]); |
Noel Gordon
2016/04/04 08:37:54
Should we write the following here?
*intent = G
|
+ return GETJOCTET(src[0]); |
+ } |
+ } |
+ |
+ return 0; |
+} |