Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * iccprofile.c | 2 * iccprofile.c |
| 3 * | 3 * |
| 4 * This file provides code to read and write International Color Consortium | 4 * This file provides code to read and write International Color Consortium |
| 5 * (ICC) device profiles embedded in JFIF JPEG image files. The ICC has | 5 * (ICC) device profiles embedded in JFIF JPEG image files. The ICC has |
| 6 * defined a standard format for including such data in JPEG "APP2" markers. | 6 * defined a standard format for including such data in JPEG "APP2" markers. |
| 7 * The code given here does not know anything about the internal structure | 7 * The code given here does not know anything about the internal structure |
| 8 * of the ICC profile data; it just knows how to put the profile data into | 8 * of the ICC profile data; it just knows how to put the profile data into |
| 9 * a JPEG file being written, or get it back out when reading. | 9 * a JPEG file being written, or get it back out when reading. |
| 10 * | 10 * |
| (...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 239 *dst_ptr++ = *src_ptr++; | 239 *dst_ptr++ = *src_ptr++; |
| 240 } | 240 } |
| 241 } | 241 } |
| 242 } | 242 } |
| 243 | 243 |
| 244 *icc_data_ptr = icc_data; | 244 *icc_data_ptr = icc_data; |
| 245 *icc_data_len = total_length; | 245 *icc_data_len = total_length; |
| 246 | 246 |
| 247 return TRUE; | 247 return TRUE; |
| 248 } | 248 } |
| 249 | |
| 250 | |
| 251 /* | |
| 252 * ICCbis color profile: one APP2 marker containing the following data: | |
| 253 * Identifying string ASCII "ICC_BIS\0" (8 bytes) | |
| 254 * Profile data (remainder of APP2 data) (2 bytes) being: | |
| 255 * <id> (1 byte) and a <rendering-intent> (1 byte) | |
| 256 * where <id> is non-zero, <rendering-intent> values are: | |
| 257 * 0 Perceptual - for images preferring good adaptation to output device | |
| 258 * gamut at the expense of colorimetric accuracy, such as photographs. | |
| 259 * 1 Relative Colorimetric - for images requiring color appearance matching | |
| 260 * (relative to the output device white point), such as logos. | |
| 261 * 2 Saturation - for images preferring preservation of saturation at the | |
| 262 * expense of hue and lightness, such as charts and graphs. | |
| 263 * 3 Absolute Colorimetric - for images requiring preservation of absolute | |
| 264 * colorimetry, such as previews of images destined for a different | |
| 265 * output device (proofs). | |
| 266 * A JPEG image can contain an implicit profile (ICC_BIS marker), or an | |
| 267 * 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
| |
| 268 */ | |
| 269 | |
| 270 #define ICCBIS_OVERHEAD_LENGTH 8 /* length of non-profile data in APP2 */ | |
| 271 #define ICCBIS_PROFILE_LENGTH 2 /* length of profile data in APP2 */ | |
| 272 #define ICCBIS_MARKER ICC_MARKER | |
| 273 | |
| 274 | |
| 275 /* | |
| 276 * Write the given ICCbis profile data into a JPEG file. | |
| 277 * It *must* be called AFTER calling jpeg_start_compress() and BEFORE | |
| 278 * the first call to jpeg_write_scanlines(). | |
| 279 * (This ordering ensures that the APP2 marker(s) will appear after the | |
| 280 * SOI and JFIF or Adobe markers, but before all else.) | |
| 281 */ | |
| 282 | |
| 283 void | |
| 284 write_icc_profile_bis (j_compress_ptr cinfo, | |
| 285 JOCTET profile, | |
| 286 JOCTET intent) | |
| 287 { | |
| 288 if (profile) { | |
| 289 /* Write the JPEG marker header (APP2 code and marker length) */ | |
| 290 jpeg_write_m_header(cinfo, ICCBIS_MARKER, | |
| 291 (unsigned int) (ICCBIS_OVERHEAD_LENGTH + ICCBIS_PROFILE_LENGTH)); | |
| 292 | |
| 293 /* Write the identifier string "ICC_BIS" (null-terminated) */ | |
| 294 jpeg_write_m_byte(cinfo, 0x49); | |
| 295 jpeg_write_m_byte(cinfo, 0x43); | |
| 296 jpeg_write_m_byte(cinfo, 0x43); | |
| 297 jpeg_write_m_byte(cinfo, 0x5F); | |
| 298 jpeg_write_m_byte(cinfo, 0x42); | |
| 299 jpeg_write_m_byte(cinfo, 0x49); | |
| 300 jpeg_write_m_byte(cinfo, 0x53); | |
| 301 jpeg_write_m_byte(cinfo, 0x0); | |
| 302 | |
| 303 /* Write the ICCbis profile info */ | |
| 304 jpeg_write_m_byte(cinfo, profile); | |
| 305 jpeg_write_m_byte(cinfo, intent); | |
| 306 } | |
| 307 } | |
| 308 | |
| 309 | |
| 310 /* | |
| 311 * Subroutine to test whether a saved marker is an ICCbis marker. | |
| 312 */ | |
| 313 | |
| 314 static boolean | |
| 315 marker_is_icc_bis (jpeg_saved_marker_ptr marker) | |
| 316 { | |
| 317 return | |
| 318 marker->marker == ICCBIS_MARKER && | |
| 319 marker->data_length >= ICCBIS_OVERHEAD_LENGTH && | |
| 320 /* verify the identifying string */ | |
| 321 GETJOCTET(marker->data[0]) == 0x49 && | |
| 322 GETJOCTET(marker->data[1]) == 0x43 && | |
| 323 GETJOCTET(marker->data[2]) == 0x43 && | |
| 324 GETJOCTET(marker->data[3]) == 0x5F && | |
| 325 GETJOCTET(marker->data[4]) == 0x42 && | |
| 326 GETJOCTET(marker->data[5]) == 0x49 && | |
| 327 GETJOCTET(marker->data[6]) == 0x53 && | |
| 328 GETJOCTET(marker->data[7]) == 0x0; | |
| 329 } | |
| 330 | |
| 331 | |
| 332 /* | |
| 333 * See if there was an ICCbis profile in the JPEG file being read; the | |
| 334 * ICCbis profile is returned (0 for invalid / not found). If found, | |
| 335 * write the rendering-intent to *intent (if given). | |
| 336 */ | |
| 337 | |
| 338 unsigned int | |
| 339 read_icc_profile_bis (j_decompress_ptr cinfo, unsigned int *intent) | |
| 340 { | |
| 341 jpeg_saved_marker_ptr marker; | |
| 342 JOCTET FAR *src; | |
| 343 | |
| 344 for (marker = cinfo->marker_list; marker != NULL; marker = marker->next) { | |
| 345 /* find ICCbis marker */ | |
| 346 if (marker_is_icc_bis(marker)) { | |
| 347 unsigned int length = marker->data_length - ICCBIS_OVERHEAD_LENGTH; | |
| 348 if (length < ICCBIS_PROFILE_LENGTH) | |
| 349 return 0; /* bogus bis profile data length */ | |
| 350 | |
| 351 /* return the profile info */ | |
| 352 src = marker->data + ICCBIS_OVERHEAD_LENGTH; | |
| 353 if (intent && GETJOCTET(src[0])) | |
| 354 *intent = GETJOCTET(src[1]); | |
|
Noel Gordon
2016/04/04 08:37:54
Should we write the following here?
*intent = G
| |
| 355 return GETJOCTET(src[0]); | |
| 356 } | |
| 357 } | |
| 358 | |
| 359 return 0; | |
| 360 } | |
| OLD | NEW |