1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/image/decoders/iccjpeg.c Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,187 @@ 1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.6 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.7 + 1.8 +/* 1.9 + * iccprofile.c 1.10 + * 1.11 + * This file provides code to read and write International Color Consortium 1.12 + * (ICC) device profiles embedded in JFIF JPEG image files. The ICC has 1.13 + * defined a standard format for including such data in JPEG "APP2" markers. 1.14 + * The code given here does not know anything about the internal structure 1.15 + * of the ICC profile data; it just knows how to put the profile data into 1.16 + * a JPEG file being written, or get it back out when reading. 1.17 + * 1.18 + * This code depends on new features added to the IJG JPEG library as of 1.19 + * IJG release 6b; it will not compile or work with older IJG versions. 1.20 + * 1.21 + * NOTE: this code would need surgery to work on 16-bit-int machines 1.22 + * with ICC profiles exceeding 64K bytes in size. If you need to do that, 1.23 + * change all the "unsigned int" variables to "INT32". You'll also need 1.24 + * to find a malloc() replacement that can allocate more than 64K. 1.25 + */ 1.26 + 1.27 +#include "iccjpeg.h" 1.28 +#include <stdlib.h> /* define malloc() */ 1.29 + 1.30 + 1.31 +/* 1.32 + * Since an ICC profile can be larger than the maximum size of a JPEG marker 1.33 + * (64K), we need provisions to split it into multiple markers. The format 1.34 + * defined by the ICC specifies one or more APP2 markers containing the 1.35 + * following data: 1.36 + * Identifying string ASCII "ICC_PROFILE\0" (12 bytes) 1.37 + * Marker sequence number 1 for first APP2, 2 for next, etc (1 byte) 1.38 + * Number of markers Total number of APP2's used (1 byte) 1.39 + * Profile data (remainder of APP2 data) 1.40 + * Decoders should use the marker sequence numbers to reassemble the profile, 1.41 + * rather than assuming that the APP2 markers appear in the correct sequence. 1.42 + */ 1.43 + 1.44 +#define ICC_MARKER (JPEG_APP0 + 2) /* JPEG marker code for ICC */ 1.45 +#define ICC_OVERHEAD_LEN 14 /* size of non-profile data in APP2 */ 1.46 +#define MAX_BYTES_IN_MARKER 65533 /* maximum data len of a JPEG marker */ 1.47 +#define MAX_DATA_BYTES_IN_MARKER (MAX_BYTES_IN_MARKER - ICC_OVERHEAD_LEN) 1.48 + 1.49 +/* 1.50 + * Prepare for reading an ICC profile 1.51 + */ 1.52 + 1.53 +void 1.54 +setup_read_icc_profile (j_decompress_ptr cinfo) 1.55 +{ 1.56 + /* Tell the library to keep any APP2 data it may find */ 1.57 + jpeg_save_markers(cinfo, ICC_MARKER, 0xFFFF); 1.58 +} 1.59 + 1.60 + 1.61 +/* 1.62 + * Handy subroutine to test whether a saved marker is an ICC profile marker. 1.63 + */ 1.64 + 1.65 +static boolean 1.66 +marker_is_icc (jpeg_saved_marker_ptr marker) 1.67 +{ 1.68 + return 1.69 + marker->marker == ICC_MARKER && 1.70 + marker->data_length >= ICC_OVERHEAD_LEN && 1.71 + /* verify the identifying string */ 1.72 + GETJOCTET(marker->data[0]) == 0x49 && 1.73 + GETJOCTET(marker->data[1]) == 0x43 && 1.74 + GETJOCTET(marker->data[2]) == 0x43 && 1.75 + GETJOCTET(marker->data[3]) == 0x5F && 1.76 + GETJOCTET(marker->data[4]) == 0x50 && 1.77 + GETJOCTET(marker->data[5]) == 0x52 && 1.78 + GETJOCTET(marker->data[6]) == 0x4F && 1.79 + GETJOCTET(marker->data[7]) == 0x46 && 1.80 + GETJOCTET(marker->data[8]) == 0x49 && 1.81 + GETJOCTET(marker->data[9]) == 0x4C && 1.82 + GETJOCTET(marker->data[10]) == 0x45 && 1.83 + GETJOCTET(marker->data[11]) == 0x0; 1.84 +} 1.85 + 1.86 + 1.87 +/* 1.88 + * See if there was an ICC profile in the JPEG file being read; 1.89 + * if so, reassemble and return the profile data. 1.90 + * 1.91 + * TRUE is returned if an ICC profile was found, FALSE if not. 1.92 + * If TRUE is returned, *icc_data_ptr is set to point to the 1.93 + * returned data, and *icc_data_len is set to its length. 1.94 + * 1.95 + * IMPORTANT: the data at **icc_data_ptr has been allocated with malloc() 1.96 + * and must be freed by the caller with free() when the caller no longer 1.97 + * needs it. (Alternatively, we could write this routine to use the 1.98 + * IJG library's memory allocator, so that the data would be freed implicitly 1.99 + * at jpeg_finish_decompress() time. But it seems likely that many apps 1.100 + * will prefer to have the data stick around after decompression finishes.) 1.101 + * 1.102 + * NOTE: if the file contains invalid ICC APP2 markers, we just silently 1.103 + * return FALSE. You might want to issue an error message instead. 1.104 + */ 1.105 + 1.106 +boolean 1.107 +read_icc_profile (j_decompress_ptr cinfo, 1.108 + JOCTET **icc_data_ptr, 1.109 + unsigned int *icc_data_len) 1.110 +{ 1.111 + jpeg_saved_marker_ptr marker; 1.112 + int num_markers = 0; 1.113 + int seq_no; 1.114 + JOCTET *icc_data; 1.115 + unsigned int total_length; 1.116 +#define MAX_SEQ_NO 255 /* sufficient since marker numbers are bytes */ 1.117 + char marker_present[MAX_SEQ_NO+1]; /* 1 if marker found */ 1.118 + unsigned int data_length[MAX_SEQ_NO+1]; /* size of profile data in marker */ 1.119 + unsigned int data_offset[MAX_SEQ_NO+1]; /* offset for data in marker */ 1.120 + 1.121 + *icc_data_ptr = NULL; /* avoid confusion if FALSE return */ 1.122 + *icc_data_len = 0; 1.123 + 1.124 + /* This first pass over the saved markers discovers whether there are 1.125 + * any ICC markers and verifies the consistency of the marker numbering. 1.126 + */ 1.127 + 1.128 + for (seq_no = 1; seq_no <= MAX_SEQ_NO; seq_no++) 1.129 + marker_present[seq_no] = 0; 1.130 + 1.131 + for (marker = cinfo->marker_list; marker != NULL; marker = marker->next) { 1.132 + if (marker_is_icc(marker)) { 1.133 + if (num_markers == 0) 1.134 + num_markers = GETJOCTET(marker->data[13]); 1.135 + else if (num_markers != GETJOCTET(marker->data[13])) 1.136 + return FALSE; /* inconsistent num_markers fields */ 1.137 + seq_no = GETJOCTET(marker->data[12]); 1.138 + if (seq_no <= 0 || seq_no > num_markers) 1.139 + return FALSE; /* bogus sequence number */ 1.140 + if (marker_present[seq_no]) 1.141 + return FALSE; /* duplicate sequence numbers */ 1.142 + marker_present[seq_no] = 1; 1.143 + data_length[seq_no] = marker->data_length - ICC_OVERHEAD_LEN; 1.144 + } 1.145 + } 1.146 + 1.147 + if (num_markers == 0) 1.148 + return FALSE; 1.149 + 1.150 + /* Check for missing markers, count total space needed, 1.151 + * compute offset of each marker's part of the data. 1.152 + */ 1.153 + 1.154 + total_length = 0; 1.155 + for (seq_no = 1; seq_no <= num_markers; seq_no++) { 1.156 + if (marker_present[seq_no] == 0) 1.157 + return FALSE; /* missing sequence number */ 1.158 + data_offset[seq_no] = total_length; 1.159 + total_length += data_length[seq_no]; 1.160 + } 1.161 + 1.162 + if (total_length <= 0) 1.163 + return FALSE; /* found only empty markers? */ 1.164 + 1.165 + /* Allocate space for assembled data */ 1.166 + icc_data = (JOCTET *) malloc(total_length * sizeof(JOCTET)); 1.167 + if (icc_data == NULL) 1.168 + return FALSE; /* oops, out of memory */ 1.169 + 1.170 + /* and fill it in */ 1.171 + for (marker = cinfo->marker_list; marker != NULL; marker = marker->next) { 1.172 + if (marker_is_icc(marker)) { 1.173 + JOCTET FAR *src_ptr; 1.174 + JOCTET *dst_ptr; 1.175 + unsigned int length; 1.176 + seq_no = GETJOCTET(marker->data[12]); 1.177 + dst_ptr = icc_data + data_offset[seq_no]; 1.178 + src_ptr = marker->data + ICC_OVERHEAD_LEN; 1.179 + length = data_length[seq_no]; 1.180 + while (length--) { 1.181 + *dst_ptr++ = *src_ptr++; 1.182 + } 1.183 + } 1.184 + } 1.185 + 1.186 + *icc_data_ptr = icc_data; 1.187 + *icc_data_len = total_length; 1.188 + 1.189 + return TRUE; 1.190 +}