Krita Source Code Documentation
Loading...
Searching...
No Matches
iccjpeg.c File Reference
#include "iccjpeg.h"
#include <stdlib.h>

Go to the source code of this file.

Macros

#define ICC_MARKER   (JPEG_APP0 + 2) /* JPEG marker code for ICC */
 
#define ICC_OVERHEAD_LEN   14 /* size of non-profile data in APP2 */
 
#define MAX_BYTES_IN_MARKER   65533 /* maximum data len of a JPEG marker */
 
#define MAX_DATA_BYTES_IN_MARKER   (MAX_BYTES_IN_MARKER - ICC_OVERHEAD_LEN)
 
#define MAX_SEQ_NO   255 /* sufficient since marker numbers are bytes */
 

Functions

static boolean marker_is_icc (jpeg_saved_marker_ptr marker)
 
boolean read_icc_profile (j_decompress_ptr cinfo, JOCTET **icc_data_ptr, unsigned int *icc_data_len)
 
void setup_read_icc_profile (j_decompress_ptr cinfo)
 
void write_icc_profile (j_compress_ptr cinfo, const JOCTET *icc_data_ptr, unsigned int icc_data_len)
 

Macro Definition Documentation

◆ ICC_MARKER

#define ICC_MARKER   (JPEG_APP0 + 2) /* JPEG marker code for ICC */

Definition at line 59 of file iccjpeg.c.

◆ ICC_OVERHEAD_LEN

#define ICC_OVERHEAD_LEN   14 /* size of non-profile data in APP2 */

Definition at line 60 of file iccjpeg.c.

◆ MAX_BYTES_IN_MARKER

#define MAX_BYTES_IN_MARKER   65533 /* maximum data len of a JPEG marker */

Definition at line 61 of file iccjpeg.c.

◆ MAX_DATA_BYTES_IN_MARKER

#define MAX_DATA_BYTES_IN_MARKER   (MAX_BYTES_IN_MARKER - ICC_OVERHEAD_LEN)

Definition at line 62 of file iccjpeg.c.

◆ MAX_SEQ_NO

#define MAX_SEQ_NO   255 /* sufficient since marker numbers are bytes */

Function Documentation

◆ marker_is_icc()

static boolean marker_is_icc ( jpeg_saved_marker_ptr marker)
static

Definition at line 146 of file iccjpeg.c.

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}
#define ICC_MARKER
Definition iccjpeg.c:59
#define ICC_OVERHEAD_LEN
Definition iccjpeg.c:60

References ICC_MARKER, and ICC_OVERHEAD_LEN.

◆ read_icc_profile()

boolean read_icc_profile ( j_decompress_ptr cinfo,
JOCTET ** icc_data_ptr,
unsigned int * icc_data_len )

Definition at line 187 of file iccjpeg.c.

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 MAX_SEQ_NO
static boolean marker_is_icc(jpeg_saved_marker_ptr marker)
Definition iccjpeg.c:146

References ICC_OVERHEAD_LEN, length(), marker_is_icc(), and MAX_SEQ_NO.

◆ setup_read_icc_profile()

void setup_read_icc_profile ( j_decompress_ptr cinfo)

Definition at line 134 of file iccjpeg.c.

135{
136 /* Tell the library to keep any APP2 data it may find */
137 jpeg_save_markers(cinfo, ICC_MARKER, 0xFFFF);
138}

References ICC_MARKER.

◆ write_icc_profile()

void write_icc_profile ( j_compress_ptr cinfo,
const JOCTET * icc_data_ptr,
unsigned int icc_data_len )

Definition at line 74 of file iccjpeg.c.

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}
#define MAX_DATA_BYTES_IN_MARKER
Definition iccjpeg.c:62

References ICC_MARKER, ICC_OVERHEAD_LEN, length(), and MAX_DATA_BYTES_IN_MARKER.