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 |