Krita Source Code Documentation
Loading...
Searching...
No Matches
iccjpeg.c
Go to the documentation of this file.
1/*
2 * Little cms
3 * Copyright (C) 1998-2004 Marti Maria <x@unknown.com>
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining
6 * a copy of this software and associated documentation files (the
7 * "Software"), to deal in the Software without restriction, including
8 * without limitation the rights to use, copy, modify, merge, publish,
9 * distribute, sublicense, and/or sell copies of the Software, and to
10 * permit persons to whom the Software is furnished to do so, subject to
11 * the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included
14 * in all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
17 * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
18 * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 *
24 * iccprofile.c
25 *
26 * This file provides code to read and write International Color Consortium
27 * (ICC) device profiles embedded in JFIF JPEG image files. The ICC has
28 * defined a standard format for including such data in JPEG "APP2" markers.
29 * The code given here does not know anything about the internal structure
30 * of the ICC profile data; it just knows how to put the profile data into
31 * a JPEG file being written, or get it back out when reading.
32 *
33 * This code depends on new features added to the IJG JPEG library as of
34 * IJG release 6b; it will not compile or work with older IJG versions.
35 *
36 * NOTE: this code would need surgery to work on 16-bit-int machines
37 * with ICC profiles exceeding 64K bytes in size. If you need to do that,
38 * change all the "unsigned int" variables to "INT32". You'll also need
39 * to find a malloc() replacement that can allocate more than 64K.
40 */
41
42#include "iccjpeg.h"
43#include <stdlib.h> /* define malloc() */
44
45
46/*
47 * Since an ICC profile can be larger than the maximum size of a JPEG marker
48 * (64K), we need provisions to split it into multiple markers. The format
49 * defined by the ICC specifies one or more APP2 markers containing the
50 * following data:
51 * Identifying string ASCII "ICC_PROFILE\0" (12 bytes)
52 * Marker sequence number 1 for first APP2, 2 for next, etc (1 byte)
53 * Number of markers Total number of APP2's used (1 byte)
54 * Profile data (remainder of APP2 data)
55 * Decoders should use the marker sequence numbers to reassemble the profile,
56 * rather than assuming that the APP2 markers appear in the correct sequence.
57 */
58
59#define ICC_MARKER (JPEG_APP0 + 2) /* JPEG marker code for ICC */
60#define ICC_OVERHEAD_LEN 14 /* size of non-profile data in APP2 */
61#define MAX_BYTES_IN_MARKER 65533 /* maximum data len of a JPEG marker */
62#define MAX_DATA_BYTES_IN_MARKER (MAX_BYTES_IN_MARKER - ICC_OVERHEAD_LEN)
63
64
65/*
66 * This routine writes the given ICC profile data into a JPEG file.
67 * It *must* be called AFTER calling jpeg_start_compress() and BEFORE
68 * the first call to jpeg_write_scanlines().
69 * (This ordering ensures that the APP2 marker(s) will appear after the
70 * SOI and JFIF or Adobe markers, but before all else.)
71 */
72
73void
74write_icc_profile (j_compress_ptr cinfo,
75 const JOCTET *icc_data_ptr,
76 unsigned int icc_data_len)
77{
78 unsigned int num_markers; /* total number of markers we'll write */
79 int cur_marker = 1; /* per spec, counting starts at 1 */
80 unsigned int length; /* number of bytes to write in this marker */
81
82 /* Calculate the number of markers we'll need, rounding up of course */
83 num_markers = icc_data_len / MAX_DATA_BYTES_IN_MARKER;
84 if (num_markers * MAX_DATA_BYTES_IN_MARKER != icc_data_len)
85 num_markers++;
86
87 while (icc_data_len > 0) {
88 /* length of profile to put in this marker */
89 length = icc_data_len;
92 icc_data_len -= length;
93
94 /* Write the JPEG marker header (APP2 code and marker length) */
95 jpeg_write_m_header(cinfo, ICC_MARKER,
96 (unsigned int) (length + ICC_OVERHEAD_LEN));
97
98 /* Write the marker identifying string "ICC_PROFILE" (null-terminated).
99 * We code it in this less-than-transparent way so that the code works
100 * even if the local character set is not ASCII.
101 */
102 jpeg_write_m_byte(cinfo, 0x49);
103 jpeg_write_m_byte(cinfo, 0x43);
104 jpeg_write_m_byte(cinfo, 0x43);
105 jpeg_write_m_byte(cinfo, 0x5F);
106 jpeg_write_m_byte(cinfo, 0x50);
107 jpeg_write_m_byte(cinfo, 0x52);
108 jpeg_write_m_byte(cinfo, 0x4F);
109 jpeg_write_m_byte(cinfo, 0x46);
110 jpeg_write_m_byte(cinfo, 0x49);
111 jpeg_write_m_byte(cinfo, 0x4C);
112 jpeg_write_m_byte(cinfo, 0x45);
113 jpeg_write_m_byte(cinfo, 0x0);
114
115 /* Add the sequencing info */
116 jpeg_write_m_byte(cinfo, cur_marker);
117 jpeg_write_m_byte(cinfo, (int) num_markers);
118
119 /* Add the profile data */
120 while (length--) {
121 jpeg_write_m_byte(cinfo, *icc_data_ptr);
122 icc_data_ptr++;
123 }
124 cur_marker++;
125 }
126}
127
128
129/*
130 * Prepare for reading an ICC profile
131 */
132
133void
134setup_read_icc_profile (j_decompress_ptr cinfo)
135{
136 /* Tell the library to keep any APP2 data it may find */
137 jpeg_save_markers(cinfo, ICC_MARKER, 0xFFFF);
138}
139
140
141/*
142 * Handy subroutine to test whether a saved marker is an ICC profile marker.
143 */
144
145static boolean
146marker_is_icc (jpeg_saved_marker_ptr marker)
147{
148 return
149 marker->marker == ICC_MARKER &&
150 marker->data_length >= ICC_OVERHEAD_LEN &&
151 /* verify the identifying string */
152 GETJOCTET(marker->data[0]) == 0x49 &&
153 GETJOCTET(marker->data[1]) == 0x43 &&
154 GETJOCTET(marker->data[2]) == 0x43 &&
155 GETJOCTET(marker->data[3]) == 0x5F &&
156 GETJOCTET(marker->data[4]) == 0x50 &&
157 GETJOCTET(marker->data[5]) == 0x52 &&
158 GETJOCTET(marker->data[6]) == 0x4F &&
159 GETJOCTET(marker->data[7]) == 0x46 &&
160 GETJOCTET(marker->data[8]) == 0x49 &&
161 GETJOCTET(marker->data[9]) == 0x4C &&
162 GETJOCTET(marker->data[10]) == 0x45 &&
163 GETJOCTET(marker->data[11]) == 0x0;
164}
165
166
167/*
168 * See if there was an ICC profile in the JPEG file being read;
169 * if so, reassemble and return the profile data.
170 *
171 * TRUE is returned if an ICC profile was found, FALSE if not.
172 * If TRUE is returned, *icc_data_ptr is set to point to the
173 * returned data, and *icc_data_len is set to its length.
174 *
175 * IMPORTANT: the data at **icc_data_ptr has been allocated with malloc()
176 * and must be freed by the caller with free() when the caller no longer
177 * needs it. (Alternatively, we could write this routine to use the
178 * IJG library's memory allocator, so that the data would be freed implicitly
179 * at jpeg_finish_decompress() time. But it seems likely that many apps
180 * will prefer to have the data stick around after decompression finishes.)
181 *
182 * NOTE: if the file contains invalid ICC APP2 markers, we just silently
183 * return FALSE. You might want to issue an error message instead.
184 */
185
186boolean
187read_icc_profile (j_decompress_ptr cinfo,
188 JOCTET **icc_data_ptr,
189 unsigned int *icc_data_len)
190{
191 jpeg_saved_marker_ptr marker;
192 int num_markers = 0;
193 int seq_no;
194 JOCTET *icc_data;
195 unsigned int total_length;
196#define MAX_SEQ_NO 255 /* sufficient since marker numbers are bytes */
197 char marker_present[MAX_SEQ_NO+1]; /* 1 if marker found */
198 unsigned int data_length[MAX_SEQ_NO+1]; /* size of profile data in marker */
199 unsigned int data_offset[MAX_SEQ_NO+1]; /* offset for data in marker */
200
201 *icc_data_ptr = 0; /* avoid confusion if FALSE return */
202 *icc_data_len = 0;
203
204 /* This first pass over the saved markers discovers whether there are
205 * any ICC markers and verifies the consistency of the marker numbering.
206 */
207
208 for (seq_no = 1; seq_no <= MAX_SEQ_NO; seq_no++)
209 marker_present[seq_no] = 0;
210
211 for (marker = cinfo->marker_list; marker != 0; marker = marker->next) {
212 if (marker_is_icc(marker)) {
213 if (num_markers == 0)
214 num_markers = GETJOCTET(marker->data[13]);
215 else if (num_markers != GETJOCTET(marker->data[13]))
216 return FALSE; /* inconsistent num_markers fields */
217 seq_no = GETJOCTET(marker->data[12]);
218 if (seq_no <= 0 || seq_no > num_markers)
219 return FALSE; /* bogus sequence number */
220 if (marker_present[seq_no])
221 return FALSE; /* duplicate sequence numbers */
222 marker_present[seq_no] = 1;
223 data_length[seq_no] = marker->data_length - ICC_OVERHEAD_LEN;
224 }
225 }
226
227 if (num_markers == 0)
228 return FALSE;
229
230 /* Check for missing markers, count total space needed,
231 * compute offset of each marker's part of the data.
232 */
233
234 total_length = 0;
235 for (seq_no = 1; seq_no <= num_markers; seq_no++) {
236 if (marker_present[seq_no] == 0)
237 return FALSE; /* missing sequence number */
238 data_offset[seq_no] = total_length;
239 total_length += data_length[seq_no];
240 }
241
242 if (total_length <= 0)
243 return FALSE; /* found only empty markers? */
244
245 /* Allocate space for assembled data */
246 icc_data = (JOCTET *) malloc(total_length * sizeof(JOCTET));
247 if (icc_data == 0)
248 return FALSE; /* oops, out of memory */
249
250 /* and fill it in */
251 for (marker = cinfo->marker_list; marker != 0; marker = marker->next) {
252 if (marker_is_icc(marker)) {
253 JOCTET FAR *src_ptr;
254 JOCTET *dst_ptr;
255 unsigned int length;
256 seq_no = GETJOCTET(marker->data[12]);
257 dst_ptr = icc_data + data_offset[seq_no];
258 src_ptr = marker->data + ICC_OVERHEAD_LEN;
259 length = data_length[seq_no];
260 while (length--) {
261 *dst_ptr++ = *src_ptr++;
262 }
263 }
264 }
265
266 *icc_data_ptr = icc_data;
267 *icc_data_len = total_length;
268
269 return TRUE;
270}
qreal length(const QPointF &vec)
Definition Ellipse.cc:82
#define ICC_MARKER
Definition iccjpeg.c:59
#define MAX_SEQ_NO
static boolean marker_is_icc(jpeg_saved_marker_ptr marker)
Definition iccjpeg.c:146
void setup_read_icc_profile(j_decompress_ptr cinfo)
Definition iccjpeg.c:134
boolean read_icc_profile(j_decompress_ptr cinfo, JOCTET **icc_data_ptr, unsigned int *icc_data_len)
Definition iccjpeg.c:187
void write_icc_profile(j_compress_ptr cinfo, const JOCTET *icc_data_ptr, unsigned int icc_data_len)
Definition iccjpeg.c:74
#define MAX_DATA_BYTES_IN_MARKER
Definition iccjpeg.c:62
#define ICC_OVERHEAD_LEN
Definition iccjpeg.c:60