Chromium Code Reviews| 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; |
| +} |