1 /*
2 * Copyright (c) 2002-2003 Michael David Adams.
3 * All rights reserved.
4 */
5
6 /* __START_OF_JASPER_LICENSE__
7 *
8 * JasPer License Version 2.0
9 *
10 * Copyright (c) 2001-2006 Michael David Adams
11 * Copyright (c) 1999-2000 Image Power, Inc.
12 * Copyright (c) 1999-2000 The University of British Columbia
13 *
14 * All rights reserved.
15 *
16 * Permission is hereby granted, free of charge, to any person (the
17 * "User") obtaining a copy of this software and associated documentation
18 * files (the "Software"), to deal in the Software without restriction,
19 * including without limitation the rights to use, copy, modify, merge,
20 * publish, distribute, and/or sell copies of the Software, and to permit
21 * persons to whom the Software is furnished to do so, subject to the
22 * following conditions:
23 *
24 * 1. The above copyright notices and this permission notice (which
25 * includes the disclaimer below) shall be included in all copies or
26 * substantial portions of the Software.
27 *
28 * 2. The name of a copyright holder shall not be used to endorse or
29 * promote products derived from the Software without specific prior
30 * written permission.
31 *
32 * THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS
33 * LICENSE. NO USE OF THE SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER
34 * THIS DISCLAIMER. THE SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS
35 * "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
36 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
37 * PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO
38 * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL
39 * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING
40 * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
41 * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
42 * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. NO ASSURANCES ARE
43 * PROVIDED BY THE COPYRIGHT HOLDERS THAT THE SOFTWARE DOES NOT INFRINGE
44 * THE PATENT OR OTHER INTELLECTUAL PROPERTY RIGHTS OF ANY OTHER ENTITY.
45 * EACH COPYRIGHT HOLDER DISCLAIMS ANY LIABILITY TO THE USER FOR CLAIMS
46 * BROUGHT BY ANY OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL
47 * PROPERTY RIGHTS OR OTHERWISE. AS A CONDITION TO EXERCISING THE RIGHTS
48 * GRANTED HEREUNDER, EACH USER HEREBY ASSUMES SOLE RESPONSIBILITY TO SECURE
49 * ANY OTHER INTELLECTUAL PROPERTY RIGHTS NEEDED, IF ANY. THE SOFTWARE
50 * IS NOT FAULT-TOLERANT AND IS NOT INTENDED FOR USE IN MISSION-CRITICAL
51 * SYSTEMS, SUCH AS THOSE USED IN THE OPERATION OF NUCLEAR FACILITIES,
52 * AIRCRAFT NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL
53 * SYSTEMS, DIRECT LIFE SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH
54 * THE FAILURE OF THE SOFTWARE OR SYSTEM COULD LEAD DIRECTLY TO DEATH,
55 * PERSONAL INJURY, OR SEVERE PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH
56 * RISK ACTIVITIES"). THE COPYRIGHT HOLDERS SPECIFICALLY DISCLAIM ANY
57 * EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR HIGH RISK ACTIVITIES.
58 *
59 * __END_OF_JASPER_LICENSE__
60 */
61
62 #include <assert.h>
63 #include <jasper/jas_config.h>
64 #include <jasper/jas_types.h>
65 #include <jasper/jas_malloc.h>
66 #include <jasper/jas_debug.h>
67 #include <jasper/jas_icc.h>
68 #include <jasper/jas_cm.h>
69 #include <jasper/jas_stream.h>
70 #include <jasper/jas_string.h>
71
72 #include <stdlib.h>
73 #include <ctype.h>
74
75 #define jas_iccputuint8(out, val) jas_iccputuint(out, 1, val)
76 #define jas_iccputuint16(out, val) jas_iccputuint(out, 2, val)
77 #define jas_iccputsint32(out, val) jas_iccputsint(out, 4, val)
78 #define jas_iccputuint32(out, val) jas_iccputuint(out, 4, val)
79 #define jas_iccputuint64(out, val) jas_iccputuint(out, 8, val)
80
81 static jas_iccattrval_t *jas_iccattrval_create0(void);
82
83 static int jas_iccgetuint(jas_stream_t *in, int n, ulonglong *val);
84 static int jas_iccgetuint8(jas_stream_t *in, jas_iccuint8_t *val);
85 static int jas_iccgetuint16(jas_stream_t *in, jas_iccuint16_t *val);
86 static int jas_iccgetsint32(jas_stream_t *in, jas_iccsint32_t *val);
87 static int jas_iccgetuint32(jas_stream_t *in, jas_iccuint32_t *val);
88 static int jas_iccgetuint64(jas_stream_t *in, jas_iccuint64_t *val);
89 static int jas_iccputuint(jas_stream_t *out, int n, ulonglong val);
90 static int jas_iccputsint(jas_stream_t *out, int n, longlong val);
91 static jas_iccprof_t *jas_iccprof_create(void);
92 static int jas_iccprof_readhdr(jas_stream_t *in, jas_icchdr_t *hdr);
93 static int jas_iccprof_writehdr(jas_stream_t *out, jas_icchdr_t *hdr);
94 static int jas_iccprof_gettagtab(jas_stream_t *in, jas_icctagtab_t *tagtab);
95 static void jas_iccprof_sorttagtab(jas_icctagtab_t *tagtab);
96 static int jas_iccattrtab_lookup(jas_iccattrtab_t *attrtab, jas_iccuint32_t name);
97 static jas_iccattrtab_t *jas_iccattrtab_copy(jas_iccattrtab_t *attrtab);
98 static jas_iccattrvalinfo_t *jas_iccattrvalinfo_lookup(jas_iccsig_t name);
99 static int jas_iccgettime(jas_stream_t *in, jas_icctime_t *time);
100 static int jas_iccgetxyz(jas_stream_t *in, jas_iccxyz_t *xyz);
101 static int jas_icctagtabent_cmp(const void *src, const void *dst);
102
103 static void jas_icccurv_destroy(jas_iccattrval_t *attrval);
104 static int jas_icccurv_copy(jas_iccattrval_t *attrval,
105 jas_iccattrval_t *othattrval);
106 static int jas_icccurv_input(jas_iccattrval_t *attrval, jas_stream_t *in,
107 int cnt);
108 static int jas_icccurv_getsize(jas_iccattrval_t *attrval);
109 static int jas_icccurv_output(jas_iccattrval_t *attrval, jas_stream_t *out);
110 static void jas_icccurv_dump(jas_iccattrval_t *attrval, FILE *out);
111
112 static void jas_icctxtdesc_destroy(jas_iccattrval_t *attrval);
113 static int jas_icctxtdesc_copy(jas_iccattrval_t *attrval,
114 jas_iccattrval_t *othattrval);
115 static int jas_icctxtdesc_input(jas_iccattrval_t *attrval, jas_stream_t *in,
116 int cnt);
117 static int jas_icctxtdesc_getsize(jas_iccattrval_t *attrval);
118 static int jas_icctxtdesc_output(jas_iccattrval_t *attrval, jas_stream_t *out);
119 static void jas_icctxtdesc_dump(jas_iccattrval_t *attrval, FILE *out);
120
121 static void jas_icctxt_destroy(jas_iccattrval_t *attrval);
122 static int jas_icctxt_copy(jas_iccattrval_t *attrval,
123 jas_iccattrval_t *othattrval);
124 static int jas_icctxt_input(jas_iccattrval_t *attrval, jas_stream_t *in,
125 int cnt);
126 static int jas_icctxt_getsize(jas_iccattrval_t *attrval);
127 static int jas_icctxt_output(jas_iccattrval_t *attrval, jas_stream_t *out);
128 static void jas_icctxt_dump(jas_iccattrval_t *attrval, FILE *out);
129
130 static int jas_iccxyz_input(jas_iccattrval_t *attrval, jas_stream_t *in,
131 int cnt);
132 static int jas_iccxyz_getsize(jas_iccattrval_t *attrval);
133 static int jas_iccxyz_output(jas_iccattrval_t *attrval, jas_stream_t *out);
134 static void jas_iccxyz_dump(jas_iccattrval_t *attrval, FILE *out);
135
136 static jas_iccattrtab_t *jas_iccattrtab_create(void);
137 static void jas_iccattrtab_destroy(jas_iccattrtab_t *tab);
138 static int jas_iccattrtab_resize(jas_iccattrtab_t *tab, int maxents);
139 static int jas_iccattrtab_add(jas_iccattrtab_t *attrtab, int i,
140 jas_iccuint32_t name, jas_iccattrval_t *val);
141 static int jas_iccattrtab_replace(jas_iccattrtab_t *attrtab, int i,
142 jas_iccuint32_t name, jas_iccattrval_t *val);
143 static void jas_iccattrtab_delete(jas_iccattrtab_t *attrtab, int i);
144 static long jas_iccpadtomult(long x, long y);
145 static int jas_iccattrtab_get(jas_iccattrtab_t *attrtab, int i,
146 jas_iccattrname_t *name, jas_iccattrval_t **val);
147 static int jas_iccprof_puttagtab(jas_stream_t *out, jas_icctagtab_t *tagtab);
148
149 static void jas_icclut16_destroy(jas_iccattrval_t *attrval);
150 static int jas_icclut16_copy(jas_iccattrval_t *attrval,
151 jas_iccattrval_t *othattrval);
152 static int jas_icclut16_input(jas_iccattrval_t *attrval, jas_stream_t *in,
153 int cnt);
154 static int jas_icclut16_getsize(jas_iccattrval_t *attrval);
155 static int jas_icclut16_output(jas_iccattrval_t *attrval, jas_stream_t *out);
156 static void jas_icclut16_dump(jas_iccattrval_t *attrval, FILE *out);
157
158 static void jas_icclut8_destroy(jas_iccattrval_t *attrval);
159 static int jas_icclut8_copy(jas_iccattrval_t *attrval,
160 jas_iccattrval_t *othattrval);
161 static int jas_icclut8_input(jas_iccattrval_t *attrval, jas_stream_t *in,
162 int cnt);
163 static int jas_icclut8_getsize(jas_iccattrval_t *attrval);
164 static int jas_icclut8_output(jas_iccattrval_t *attrval, jas_stream_t *out);
165 static void jas_icclut8_dump(jas_iccattrval_t *attrval, FILE *out);
166
167 static int jas_iccputtime(jas_stream_t *out, jas_icctime_t *ctime);
168 static int jas_iccputxyz(jas_stream_t *out, jas_iccxyz_t *xyz);
169
170 static long jas_iccpowi(int x, int n);
171
172 static char *jas_iccsigtostr(int sig, char *buf);
173
174
175 jas_iccattrvalinfo_t jas_iccattrvalinfos[] = {
176 {JAS_ICC_TYPE_CURV, {jas_icccurv_destroy, jas_icccurv_copy,
177 jas_icccurv_input, jas_icccurv_output, jas_icccurv_getsize,
178 jas_icccurv_dump}},
179 {JAS_ICC_TYPE_XYZ, {0, 0, jas_iccxyz_input, jas_iccxyz_output,
180 jas_iccxyz_getsize, jas_iccxyz_dump}},
181 {JAS_ICC_TYPE_TXTDESC, {jas_icctxtdesc_destroy,
182 jas_icctxtdesc_copy, jas_icctxtdesc_input, jas_icctxtdesc_output,
183 jas_icctxtdesc_getsize, jas_icctxtdesc_dump}},
184 {JAS_ICC_TYPE_TXT, {jas_icctxt_destroy, jas_icctxt_copy,
185 jas_icctxt_input, jas_icctxt_output, jas_icctxt_getsize,
186 jas_icctxt_dump}},
187 {JAS_ICC_TYPE_LUT8, {jas_icclut8_destroy, jas_icclut8_copy,
188 jas_icclut8_input, jas_icclut8_output, jas_icclut8_getsize,
189 jas_icclut8_dump}},
190 {JAS_ICC_TYPE_LUT16, {jas_icclut16_destroy, jas_icclut16_copy,
191 jas_icclut16_input, jas_icclut16_output, jas_icclut16_getsize,
192 jas_icclut16_dump}},
193 {0, {0, 0, 0, 0, 0, 0}}
194 };
195
196 typedef struct {
197 jas_iccuint32_t tag;
198 char *name;
199 } jas_icctaginfo_t;
200
201 /******************************************************************************\
202 * profile class
203 \******************************************************************************/
204
jas_iccprof_create()205 static jas_iccprof_t *jas_iccprof_create()
206 {
207 jas_iccprof_t *prof;
208 prof = 0;
209 if (!(prof = jas_malloc(sizeof(jas_iccprof_t)))) {
210 goto error;
211 }
212 if (!(prof->attrtab = jas_iccattrtab_create()))
213 goto error;
214 memset(&prof->hdr, 0, sizeof(jas_icchdr_t));
215 prof->tagtab.numents = 0;
216 prof->tagtab.ents = 0;
217 return prof;
218 error:
219 if (prof)
220 jas_iccprof_destroy(prof);
221 return 0;
222 }
223
jas_iccprof_copy(jas_iccprof_t * prof)224 jas_iccprof_t *jas_iccprof_copy(jas_iccprof_t *prof)
225 {
226 jas_iccprof_t *newprof;
227 newprof = 0;
228 if (!(newprof = jas_iccprof_create()))
229 goto error;
230 newprof->hdr = prof->hdr;
231 newprof->tagtab.numents = 0;
232 newprof->tagtab.ents = 0;
233 assert(newprof->attrtab);
234 jas_iccattrtab_destroy(newprof->attrtab);
235 if (!(newprof->attrtab = jas_iccattrtab_copy(prof->attrtab)))
236 goto error;
237 return newprof;
238 error:
239 if (newprof)
240 jas_iccprof_destroy(newprof);
241 return 0;
242 }
243
jas_iccprof_destroy(jas_iccprof_t * prof)244 void jas_iccprof_destroy(jas_iccprof_t *prof)
245 {
246 if (prof->attrtab)
247 jas_iccattrtab_destroy(prof->attrtab);
248 if (prof->tagtab.ents)
249 jas_free(prof->tagtab.ents);
250 jas_free(prof);
251 }
252
jas_iccprof_dump(jas_iccprof_t * prof,FILE * out)253 void jas_iccprof_dump(jas_iccprof_t *prof, FILE *out)
254 {
255 jas_iccattrtab_dump(prof->attrtab, out);
256 }
257
jas_iccprof_load(jas_stream_t * in)258 jas_iccprof_t *jas_iccprof_load(jas_stream_t *in)
259 {
260 jas_iccprof_t *prof;
261 int numtags;
262 long curoff;
263 long reloff;
264 long prevoff;
265 jas_iccsig_t type;
266 jas_iccattrval_t *attrval;
267 jas_iccattrval_t *prevattrval;
268 jas_icctagtabent_t *tagtabent;
269 jas_iccattrvalinfo_t *attrvalinfo;
270 int i;
271 int len;
272
273 prof = 0;
274 attrval = 0;
275
276 if (!(prof = jas_iccprof_create())) {
277 goto error;
278 }
279
280 if (jas_iccprof_readhdr(in, &prof->hdr)) {
281 jas_eprintf("cannot get header\n");
282 goto error;
283 }
284 if (jas_iccprof_gettagtab(in, &prof->tagtab)) {
285 jas_eprintf("cannot get tab table\n");
286 goto error;
287 }
288 jas_iccprof_sorttagtab(&prof->tagtab);
289
290 numtags = prof->tagtab.numents;
291 curoff = JAS_ICC_HDRLEN + 4 + 12 * numtags;
292 prevoff = 0;
293 prevattrval = 0;
294 for (i = 0; i < numtags; ++i) {
295 tagtabent = &prof->tagtab.ents[i];
296 if (tagtabent->off == JAS_CAST(jas_iccuint32_t, prevoff)) {
297 if (prevattrval) {
298 if (!(attrval = jas_iccattrval_clone(prevattrval)))
299 goto error;
300 if (jas_iccprof_setattr(prof, tagtabent->tag, attrval))
301 goto error;
302 jas_iccattrval_destroy(attrval);
303 } else {
304 #if 0
305 jas_eprintf("warning: skipping unknown tag type\n");
306 #endif
307 }
308 continue;
309 }
310 reloff = tagtabent->off - curoff;
311 if (reloff > 0) {
312 if (jas_stream_gobble(in, reloff) != reloff)
313 goto error;
314 curoff += reloff;
315 } else if (reloff < 0) {
316 /* This should never happen since we read the tagged
317 element data in a single pass. */
318 abort();
319 }
320 prevoff = curoff;
321 if (jas_iccgetuint32(in, &type)) {
322 goto error;
323 }
324 if (jas_stream_gobble(in, 4) != 4) {
325 goto error;
326 }
327 curoff += 8;
328 if (!(attrvalinfo = jas_iccattrvalinfo_lookup(type))) {
329 #if 0
330 jas_eprintf("warning: skipping unknown tag type\n");
331 #endif
332 prevattrval = 0;
333 continue;
334 }
335 if (!(attrval = jas_iccattrval_create(type))) {
336 goto error;
337 }
338 len = tagtabent->len - 8;
339 if ((*attrval->ops->input)(attrval, in, len)) {
340 goto error;
341 }
342 curoff += len;
343 if (jas_iccprof_setattr(prof, tagtabent->tag, attrval)) {
344 goto error;
345 }
346 prevattrval = attrval; /* This is correct, but slimey. */
347 jas_iccattrval_destroy(attrval);
348 attrval = 0;
349 }
350
351 return prof;
352
353 error:
354 if (prof)
355 jas_iccprof_destroy(prof);
356 if (attrval)
357 jas_iccattrval_destroy(attrval);
358 return 0;
359 }
360
jas_iccprof_save(jas_iccprof_t * prof,jas_stream_t * out)361 int jas_iccprof_save(jas_iccprof_t *prof, jas_stream_t *out)
362 {
363 long curoff;
364 long reloff;
365 long newoff;
366 int i;
367 int j;
368 jas_icctagtabent_t *tagtabent;
369 jas_icctagtabent_t *sharedtagtabent;
370 jas_icctagtabent_t *tmptagtabent;
371 jas_iccuint32_t attrname;
372 jas_iccattrval_t *attrval;
373 jas_icctagtab_t *tagtab;
374
375 tagtab = &prof->tagtab;
376 if (!(tagtab->ents = jas_alloc2(prof->attrtab->numattrs,
377 sizeof(jas_icctagtabent_t))))
378 goto error;
379 tagtab->numents = prof->attrtab->numattrs;
380 curoff = JAS_ICC_HDRLEN + 4 + 12 * tagtab->numents;
381 for (i = 0; i < JAS_CAST(int, tagtab->numents); ++i) {
382 tagtabent = &tagtab->ents[i];
383 if (jas_iccattrtab_get(prof->attrtab, i, &attrname, &attrval))
384 goto error;
385 assert(attrval->ops->output);
386 tagtabent->tag = attrname;
387 tagtabent->data = &attrval->data;
388 sharedtagtabent = 0;
389 for (j = 0; j < i; ++j) {
390 tmptagtabent = &tagtab->ents[j];
391 if (tagtabent->data == tmptagtabent->data) {
392 sharedtagtabent = tmptagtabent;
393 break;
394 }
395 }
396 if (sharedtagtabent) {
397 tagtabent->off = sharedtagtabent->off;
398 tagtabent->len = sharedtagtabent->len;
399 tagtabent->first = sharedtagtabent;
400 } else {
401 tagtabent->off = curoff;
402 tagtabent->len = (*attrval->ops->getsize)(attrval) + 8;
403 tagtabent->first = 0;
404 if (i < JAS_CAST(int, tagtab->numents - 1)) {
405 curoff = jas_iccpadtomult(curoff + tagtabent->len, 4);
406 } else {
407 curoff += tagtabent->len;
408 }
409 }
410 jas_iccattrval_destroy(attrval);
411 }
412 prof->hdr.size = curoff;
413 if (jas_iccprof_writehdr(out, &prof->hdr))
414 goto error;
415 if (jas_iccprof_puttagtab(out, &prof->tagtab))
416 goto error;
417 curoff = JAS_ICC_HDRLEN + 4 + 12 * tagtab->numents;
418 for (i = 0; i < JAS_CAST(int, tagtab->numents);) {
419 tagtabent = &tagtab->ents[i];
420 assert(curoff == JAS_CAST(long, tagtabent->off));
421 if (jas_iccattrtab_get(prof->attrtab, i, &attrname, &attrval))
422 goto error;
423 if (jas_iccputuint32(out, attrval->type) || jas_stream_pad(out,
424 4, 0) != 4)
425 goto error;
426 if ((*attrval->ops->output)(attrval, out))
427 goto error;
428 jas_iccattrval_destroy(attrval);
429 curoff += tagtabent->len;
430 ++i;
431 while (i < JAS_CAST(int, tagtab->numents) &&
432 tagtab->ents[i].first)
433 ++i;
434 newoff = (i < JAS_CAST(int, tagtab->numents)) ?
435 tagtab->ents[i].off : prof->hdr.size;
436 reloff = newoff - curoff;
437 assert(reloff >= 0);
438 if (reloff > 0) {
439 if (jas_stream_pad(out, reloff, 0) != reloff)
440 goto error;
441 curoff += reloff;
442 }
443 }
444 return 0;
445 error:
446 /* XXX - need to free some resources here */
447 return -1;
448 }
449
jas_iccprof_writehdr(jas_stream_t * out,jas_icchdr_t * hdr)450 static int jas_iccprof_writehdr(jas_stream_t *out, jas_icchdr_t *hdr)
451 {
452 if (jas_iccputuint32(out, hdr->size) ||
453 jas_iccputuint32(out, hdr->cmmtype) ||
454 jas_iccputuint32(out, hdr->version) ||
455 jas_iccputuint32(out, hdr->clas) ||
456 jas_iccputuint32(out, hdr->colorspc) ||
457 jas_iccputuint32(out, hdr->refcolorspc) ||
458 jas_iccputtime(out, &hdr->ctime) ||
459 jas_iccputuint32(out, hdr->magic) ||
460 jas_iccputuint32(out, hdr->platform) ||
461 jas_iccputuint32(out, hdr->flags) ||
462 jas_iccputuint32(out, hdr->maker) ||
463 jas_iccputuint32(out, hdr->model) ||
464 jas_iccputuint64(out, hdr->attr) ||
465 jas_iccputuint32(out, hdr->intent) ||
466 jas_iccputxyz(out, &hdr->illum) ||
467 jas_iccputuint32(out, hdr->creator) ||
468 jas_stream_pad(out, 44, 0) != 44)
469 return -1;
470 return 0;
471 }
472
jas_iccprof_puttagtab(jas_stream_t * out,jas_icctagtab_t * tagtab)473 static int jas_iccprof_puttagtab(jas_stream_t *out, jas_icctagtab_t *tagtab)
474 {
475 int i;
476 jas_icctagtabent_t *tagtabent;
477 if (jas_iccputuint32(out, tagtab->numents))
478 goto error;
479 for (i = 0; i < JAS_CAST(int, tagtab->numents); ++i) {
480 tagtabent = &tagtab->ents[i];
481 if (jas_iccputuint32(out, tagtabent->tag) ||
482 jas_iccputuint32(out, tagtabent->off) ||
483 jas_iccputuint32(out, tagtabent->len))
484 goto error;
485 }
486 return 0;
487 error:
488 return -1;
489 }
490
jas_iccprof_readhdr(jas_stream_t * in,jas_icchdr_t * hdr)491 static int jas_iccprof_readhdr(jas_stream_t *in, jas_icchdr_t *hdr)
492 {
493 if (jas_iccgetuint32(in, &hdr->size) ||
494 jas_iccgetuint32(in, &hdr->cmmtype) ||
495 jas_iccgetuint32(in, &hdr->version) ||
496 jas_iccgetuint32(in, &hdr->clas) ||
497 jas_iccgetuint32(in, &hdr->colorspc) ||
498 jas_iccgetuint32(in, &hdr->refcolorspc) ||
499 jas_iccgettime(in, &hdr->ctime) ||
500 jas_iccgetuint32(in, &hdr->magic) ||
501 jas_iccgetuint32(in, &hdr->platform) ||
502 jas_iccgetuint32(in, &hdr->flags) ||
503 jas_iccgetuint32(in, &hdr->maker) ||
504 jas_iccgetuint32(in, &hdr->model) ||
505 jas_iccgetuint64(in, &hdr->attr) ||
506 jas_iccgetuint32(in, &hdr->intent) ||
507 jas_iccgetxyz(in, &hdr->illum) ||
508 jas_iccgetuint32(in, &hdr->creator) ||
509 jas_stream_gobble(in, 44) != 44)
510 return -1;
511 return 0;
512 }
513
jas_iccprof_gettagtab(jas_stream_t * in,jas_icctagtab_t * tagtab)514 static int jas_iccprof_gettagtab(jas_stream_t *in, jas_icctagtab_t *tagtab)
515 {
516 int i;
517 jas_icctagtabent_t *tagtabent;
518
519 if (tagtab->ents) {
520 jas_free(tagtab->ents);
521 tagtab->ents = 0;
522 }
523 if (jas_iccgetuint32(in, &tagtab->numents))
524 goto error;
525 if (!(tagtab->ents = jas_alloc2(tagtab->numents,
526 sizeof(jas_icctagtabent_t))))
527 goto error;
528 tagtabent = tagtab->ents;
529 for (i = 0; i < JAS_CAST(long, tagtab->numents); ++i) {
530 if (jas_iccgetuint32(in, &tagtabent->tag) ||
531 jas_iccgetuint32(in, &tagtabent->off) ||
532 jas_iccgetuint32(in, &tagtabent->len))
533 goto error;
534 ++tagtabent;
535 }
536 return 0;
537 error:
538 if (tagtab->ents) {
539 jas_free(tagtab->ents);
540 tagtab->ents = 0;
541 }
542 return -1;
543 }
544
jas_iccprof_getattr(jas_iccprof_t * prof,jas_iccattrname_t name)545 jas_iccattrval_t *jas_iccprof_getattr(jas_iccprof_t *prof,
546 jas_iccattrname_t name)
547 {
548 int i;
549 jas_iccattrval_t *attrval;
550 if ((i = jas_iccattrtab_lookup(prof->attrtab, name)) < 0)
551 goto error;
552 if (!(attrval = jas_iccattrval_clone(prof->attrtab->attrs[i].val)))
553 goto error;
554 return attrval;
555 error:
556 return 0;
557 }
558
jas_iccprof_setattr(jas_iccprof_t * prof,jas_iccattrname_t name,jas_iccattrval_t * val)559 int jas_iccprof_setattr(jas_iccprof_t *prof, jas_iccattrname_t name,
560 jas_iccattrval_t *val)
561 {
562 int i;
563 if ((i = jas_iccattrtab_lookup(prof->attrtab, name)) >= 0) {
564 if (val) {
565 if (jas_iccattrtab_replace(prof->attrtab, i, name, val))
566 goto error;
567 } else {
568 jas_iccattrtab_delete(prof->attrtab, i);
569 }
570 } else {
571 if (val) {
572 if (jas_iccattrtab_add(prof->attrtab, -1, name, val))
573 goto error;
574 } else {
575 /* NOP */
576 }
577 }
578 return 0;
579 error:
580 return -1;
581 }
582
jas_iccprof_gethdr(jas_iccprof_t * prof,jas_icchdr_t * hdr)583 int jas_iccprof_gethdr(jas_iccprof_t *prof, jas_icchdr_t *hdr)
584 {
585 *hdr = prof->hdr;
586 return 0;
587 }
588
jas_iccprof_sethdr(jas_iccprof_t * prof,jas_icchdr_t * hdr)589 int jas_iccprof_sethdr(jas_iccprof_t *prof, jas_icchdr_t *hdr)
590 {
591 prof->hdr = *hdr;
592 return 0;
593 }
594
jas_iccprof_sorttagtab(jas_icctagtab_t * tagtab)595 static void jas_iccprof_sorttagtab(jas_icctagtab_t *tagtab)
596 {
597 qsort(tagtab->ents, tagtab->numents, sizeof(jas_icctagtabent_t),
598 jas_icctagtabent_cmp);
599 }
600
jas_icctagtabent_cmp(const void * src,const void * dst)601 static int jas_icctagtabent_cmp(const void *src, const void *dst)
602 {
603 jas_icctagtabent_t *srctagtabent = JAS_CAST(jas_icctagtabent_t *, src);
604 jas_icctagtabent_t *dsttagtabent = JAS_CAST(jas_icctagtabent_t *, dst);
605 if (srctagtabent->off > dsttagtabent->off) {
606 return 1;
607 } else if (srctagtabent->off < dsttagtabent->off) {
608 return -1;
609 }
610 return 0;
611 }
612
jas_iccattrvalinfo_lookup(jas_iccsig_t type)613 static jas_iccattrvalinfo_t *jas_iccattrvalinfo_lookup(jas_iccsig_t type)
614 {
615 jas_iccattrvalinfo_t *info;
616 info = jas_iccattrvalinfos;
617 for (info = jas_iccattrvalinfos; info->type; ++info) {
618 if (info->type == type) {
619 return info;
620 }
621 }
622 return 0;
623 }
624
jas_iccgettime(jas_stream_t * in,jas_icctime_t * time)625 static int jas_iccgettime(jas_stream_t *in, jas_icctime_t *time)
626 {
627 if (jas_iccgetuint16(in, &time->year) ||
628 jas_iccgetuint16(in, &time->month) ||
629 jas_iccgetuint16(in, &time->day) ||
630 jas_iccgetuint16(in, &time->hour) ||
631 jas_iccgetuint16(in, &time->min) ||
632 jas_iccgetuint16(in, &time->sec)) {
633 return -1;
634 }
635 return 0;
636 }
637
jas_iccgetxyz(jas_stream_t * in,jas_iccxyz_t * xyz)638 static int jas_iccgetxyz(jas_stream_t *in, jas_iccxyz_t *xyz)
639 {
640 if (jas_iccgetsint32(in, &xyz->x) ||
641 jas_iccgetsint32(in, &xyz->y) ||
642 jas_iccgetsint32(in, &xyz->z)) {
643 return -1;
644 }
645 return 0;
646 }
647
jas_iccputtime(jas_stream_t * out,jas_icctime_t * time)648 static int jas_iccputtime(jas_stream_t *out, jas_icctime_t *time)
649 {
650 jas_iccputuint16(out, time->year);
651 jas_iccputuint16(out, time->month);
652 jas_iccputuint16(out, time->day);
653 jas_iccputuint16(out, time->hour);
654 jas_iccputuint16(out, time->min);
655 jas_iccputuint16(out, time->sec);
656 return 0;
657 }
658
jas_iccputxyz(jas_stream_t * out,jas_iccxyz_t * xyz)659 static int jas_iccputxyz(jas_stream_t *out, jas_iccxyz_t *xyz)
660 {
661 jas_iccputuint32(out, xyz->x);
662 jas_iccputuint32(out, xyz->y);
663 jas_iccputuint32(out, xyz->z);
664 return 0;
665 }
666
667 /******************************************************************************\
668 * attribute table class
669 \******************************************************************************/
670
jas_iccattrtab_create()671 static jas_iccattrtab_t *jas_iccattrtab_create()
672 {
673 jas_iccattrtab_t *tab;
674 tab = 0;
675 if (!(tab = jas_malloc(sizeof(jas_iccattrtab_t))))
676 goto error;
677 tab->maxattrs = 0;
678 tab->numattrs = 0;
679 tab->attrs = 0;
680 if (jas_iccattrtab_resize(tab, 32))
681 goto error;
682 return tab;
683 error:
684 if (tab)
685 jas_iccattrtab_destroy(tab);
686 return 0;
687 }
688
jas_iccattrtab_copy(jas_iccattrtab_t * attrtab)689 static jas_iccattrtab_t *jas_iccattrtab_copy(jas_iccattrtab_t *attrtab)
690 {
691 jas_iccattrtab_t *newattrtab;
692 int i;
693 if (!(newattrtab = jas_iccattrtab_create()))
694 goto error;
695 for (i = 0; i < attrtab->numattrs; ++i) {
696 if (jas_iccattrtab_add(newattrtab, i, attrtab->attrs[i].name,
697 attrtab->attrs[i].val))
698 goto error;
699 }
700 return newattrtab;
701 error:
702 return 0;
703 }
704
jas_iccattrtab_destroy(jas_iccattrtab_t * tab)705 static void jas_iccattrtab_destroy(jas_iccattrtab_t *tab)
706 {
707 if (tab->attrs) {
708 while (tab->numattrs > 0) {
709 jas_iccattrtab_delete(tab, 0);
710 }
711 jas_free(tab->attrs);
712 }
713 jas_free(tab);
714 }
715
jas_iccattrtab_dump(jas_iccattrtab_t * attrtab,FILE * out)716 void jas_iccattrtab_dump(jas_iccattrtab_t *attrtab, FILE *out)
717 {
718 int i;
719 jas_iccattr_t *attr;
720 jas_iccattrval_t *attrval;
721 jas_iccattrvalinfo_t *info;
722 char buf[16];
723 fprintf(out, "numattrs=%d\n", attrtab->numattrs);
724 fprintf(out, "---\n");
725 for (i = 0; i < attrtab->numattrs; ++i) {
726 attr = &attrtab->attrs[i];
727 attrval = attr->val;
728 info = jas_iccattrvalinfo_lookup(attrval->type);
729 if (!info) abort();
730 fprintf(out, "attrno=%d; attrname=\"%s\"(0x%08x); attrtype=\"%s\"(0x%08x)\n",
731 i,
732 jas_iccsigtostr(attr->name, &buf[0]),
733 (unsigned)attr->name,
734 jas_iccsigtostr(attrval->type, &buf[8]),
735 (unsigned)attrval->type
736 );
737 jas_iccattrval_dump(attrval, out);
738 fprintf(out, "---\n");
739 }
740 }
741
jas_iccattrtab_resize(jas_iccattrtab_t * tab,int maxents)742 static int jas_iccattrtab_resize(jas_iccattrtab_t *tab, int maxents)
743 {
744 jas_iccattr_t *newattrs;
745 assert(maxents >= tab->numattrs);
746 newattrs = jas_realloc2(tab->attrs, maxents, sizeof(jas_iccattr_t));
747 if (!newattrs)
748 return -1;
749 tab->attrs = newattrs;
750 tab->maxattrs = maxents;
751 return 0;
752 }
753
jas_iccattrtab_add(jas_iccattrtab_t * attrtab,int i,jas_iccuint32_t name,jas_iccattrval_t * val)754 static int jas_iccattrtab_add(jas_iccattrtab_t *attrtab, int i,
755 jas_iccuint32_t name, jas_iccattrval_t *val)
756 {
757 int n;
758 jas_iccattr_t *attr;
759 jas_iccattrval_t *tmpattrval;
760 tmpattrval = 0;
761 if (i < 0) {
762 i = attrtab->numattrs;
763 }
764 assert(i >= 0 && i <= attrtab->numattrs);
765 if (attrtab->numattrs >= attrtab->maxattrs) {
766 if (jas_iccattrtab_resize(attrtab, attrtab->numattrs + 32)) {
767 goto error;
768 }
769 }
770 if (!(tmpattrval = jas_iccattrval_clone(val)))
771 goto error;
772 n = attrtab->numattrs - i;
773 if (n > 0)
774 memmove(&attrtab->attrs[i + 1], &attrtab->attrs[i],
775 n * sizeof(jas_iccattr_t));
776 attr = &attrtab->attrs[i];
777 attr->name = name;
778 attr->val = tmpattrval;
779 ++attrtab->numattrs;
780 return 0;
781 error:
782 if (tmpattrval)
783 jas_iccattrval_destroy(tmpattrval);
784 return -1;
785 }
786
jas_iccattrtab_replace(jas_iccattrtab_t * attrtab,int i,jas_iccuint32_t name,jas_iccattrval_t * val)787 static int jas_iccattrtab_replace(jas_iccattrtab_t *attrtab, int i,
788 jas_iccuint32_t name, jas_iccattrval_t *val)
789 {
790 jas_iccattrval_t *newval;
791 jas_iccattr_t *attr;
792 if (!(newval = jas_iccattrval_clone(val)))
793 goto error;
794 attr = &attrtab->attrs[i];
795 jas_iccattrval_destroy(attr->val);
796 attr->name = name;
797 attr->val = newval;
798 return 0;
799 error:
800 return -1;
801 }
802
jas_iccattrtab_delete(jas_iccattrtab_t * attrtab,int i)803 static void jas_iccattrtab_delete(jas_iccattrtab_t *attrtab, int i)
804 {
805 int n;
806 jas_iccattrval_destroy(attrtab->attrs[i].val);
807 if ((n = attrtab->numattrs - i - 1) > 0)
808 memmove(&attrtab->attrs[i], &attrtab->attrs[i + 1],
809 n * sizeof(jas_iccattr_t));
810 --attrtab->numattrs;
811 }
812
jas_iccattrtab_get(jas_iccattrtab_t * attrtab,int i,jas_iccattrname_t * name,jas_iccattrval_t ** val)813 static int jas_iccattrtab_get(jas_iccattrtab_t *attrtab, int i,
814 jas_iccattrname_t *name, jas_iccattrval_t **val)
815 {
816 jas_iccattr_t *attr;
817 if (i < 0 || i >= attrtab->numattrs)
818 goto error;
819 attr = &attrtab->attrs[i];
820 *name = attr->name;
821 if (!(*val = jas_iccattrval_clone(attr->val)))
822 goto error;
823 return 0;
824 error:
825 return -1;
826 }
827
jas_iccattrtab_lookup(jas_iccattrtab_t * attrtab,jas_iccuint32_t name)828 static int jas_iccattrtab_lookup(jas_iccattrtab_t *attrtab,
829 jas_iccuint32_t name)
830 {
831 int i;
832 jas_iccattr_t *attr;
833 for (i = 0; i < attrtab->numattrs; ++i) {
834 attr = &attrtab->attrs[i];
835 if (attr->name == name)
836 return i;
837 }
838 return -1;
839 }
840
841 /******************************************************************************\
842 * attribute value class
843 \******************************************************************************/
844
jas_iccattrval_create(jas_iccuint32_t type)845 jas_iccattrval_t *jas_iccattrval_create(jas_iccuint32_t type)
846 {
847 jas_iccattrval_t *attrval;
848 jas_iccattrvalinfo_t *info;
849
850 if (!(info = jas_iccattrvalinfo_lookup(type)))
851 goto error;
852 if (!(attrval = jas_iccattrval_create0()))
853 goto error;
854 attrval->ops = &info->ops;
855 attrval->type = type;
856 ++attrval->refcnt;
857 memset(&attrval->data, 0, sizeof(attrval->data));
858 return attrval;
859 error:
860 return 0;
861 }
862
jas_iccattrval_clone(jas_iccattrval_t * attrval)863 jas_iccattrval_t *jas_iccattrval_clone(jas_iccattrval_t *attrval)
864 {
865 ++attrval->refcnt;
866 return attrval;
867 }
868
jas_iccattrval_destroy(jas_iccattrval_t * attrval)869 void jas_iccattrval_destroy(jas_iccattrval_t *attrval)
870 {
871 #if 0
872 jas_eprintf("refcnt=%d\n", attrval->refcnt);
873 #endif
874 if (--attrval->refcnt <= 0) {
875 if (attrval->ops->destroy)
876 (*attrval->ops->destroy)(attrval);
877 jas_free(attrval);
878 }
879 }
880
jas_iccattrval_dump(jas_iccattrval_t * attrval,FILE * out)881 void jas_iccattrval_dump(jas_iccattrval_t *attrval, FILE *out)
882 {
883 char buf[8];
884 jas_iccsigtostr(attrval->type, buf);
885 fprintf(out, "refcnt = %d; type = 0x%08x %s\n", attrval->refcnt,
886 (unsigned)attrval->type, jas_iccsigtostr(attrval->type, &buf[0]));
887 if (attrval->ops->dump) {
888 (*attrval->ops->dump)(attrval, out);
889 }
890 }
891
jas_iccattrval_allowmodify(jas_iccattrval_t ** attrvalx)892 int jas_iccattrval_allowmodify(jas_iccattrval_t **attrvalx)
893 {
894 jas_iccattrval_t *newattrval;
895 jas_iccattrval_t *attrval = *attrvalx;
896 newattrval = 0;
897 if (attrval->refcnt > 1) {
898 if (!(newattrval = jas_iccattrval_create0()))
899 goto error;
900 newattrval->ops = attrval->ops;
901 newattrval->type = attrval->type;
902 ++newattrval->refcnt;
903 if (newattrval->ops->copy) {
904 if ((*newattrval->ops->copy)(newattrval, attrval))
905 goto error;
906 } else {
907 memcpy(&newattrval->data, &attrval->data,
908 sizeof(newattrval->data));
909 }
910 *attrvalx = newattrval;
911 }
912 return 0;
913 error:
914 if (newattrval) {
915 jas_free(newattrval);
916 }
917 return -1;
918 }
919
jas_iccattrval_create0()920 static jas_iccattrval_t *jas_iccattrval_create0()
921 {
922 jas_iccattrval_t *attrval;
923 if (!(attrval = jas_malloc(sizeof(jas_iccattrval_t))))
924 return 0;
925 memset(attrval, 0, sizeof(jas_iccattrval_t));
926 attrval->refcnt = 0;
927 attrval->ops = 0;
928 attrval->type = 0;
929 return attrval;
930 }
931
932 /******************************************************************************\
933 *
934 \******************************************************************************/
935
jas_iccxyz_input(jas_iccattrval_t * attrval,jas_stream_t * in,int len)936 static int jas_iccxyz_input(jas_iccattrval_t *attrval, jas_stream_t *in,
937 int len)
938 {
939 if (len != 4 * 3) abort();
940 return jas_iccgetxyz(in, &attrval->data.xyz);
941 }
942
jas_iccxyz_output(jas_iccattrval_t * attrval,jas_stream_t * out)943 static int jas_iccxyz_output(jas_iccattrval_t *attrval, jas_stream_t *out)
944 {
945 jas_iccxyz_t *xyz = &attrval->data.xyz;
946 if (jas_iccputuint32(out, xyz->x) ||
947 jas_iccputuint32(out, xyz->y) ||
948 jas_iccputuint32(out, xyz->z))
949 return -1;
950 return 0;
951 }
952
jas_iccxyz_getsize(jas_iccattrval_t * attrval)953 static int jas_iccxyz_getsize(jas_iccattrval_t *attrval)
954 {
955 /* Avoid compiler warnings about unused parameters. */
956 attrval = 0;
957
958 return 12;
959 }
960
jas_iccxyz_dump(jas_iccattrval_t * attrval,FILE * out)961 static void jas_iccxyz_dump(jas_iccattrval_t *attrval, FILE *out)
962 {
963 jas_iccxyz_t *xyz = &attrval->data.xyz;
964 fprintf(out, "(%f, %f, %f)\n", xyz->x / 65536.0, xyz->y / 65536.0, xyz->z / 65536.0);
965 }
966
967 /******************************************************************************\
968 * attribute table class
969 \******************************************************************************/
970
jas_icccurv_destroy(jas_iccattrval_t * attrval)971 static void jas_icccurv_destroy(jas_iccattrval_t *attrval)
972 {
973 jas_icccurv_t *curv = &attrval->data.curv;
974 if (curv->ents)
975 jas_free(curv->ents);
976 }
977
jas_icccurv_copy(jas_iccattrval_t * attrval,jas_iccattrval_t * othattrval)978 static int jas_icccurv_copy(jas_iccattrval_t *attrval,
979 jas_iccattrval_t *othattrval)
980 {
981 /* Avoid compiler warnings about unused parameters. */
982 attrval = 0;
983 othattrval = 0;
984
985 /* Not yet implemented. */
986 abort();
987 return -1;
988 }
989
jas_icccurv_input(jas_iccattrval_t * attrval,jas_stream_t * in,int cnt)990 static int jas_icccurv_input(jas_iccattrval_t *attrval, jas_stream_t *in,
991 int cnt)
992 {
993 jas_icccurv_t *curv = &attrval->data.curv;
994 unsigned int i;
995
996 curv->numents = 0;
997 curv->ents = 0;
998
999 if (jas_iccgetuint32(in, &curv->numents))
1000 goto error;
1001 if (!(curv->ents = jas_alloc2(curv->numents, sizeof(jas_iccuint16_t))))
1002 goto error;
1003 for (i = 0; i < curv->numents; ++i) {
1004 if (jas_iccgetuint16(in, &curv->ents[i]))
1005 goto error;
1006 }
1007
1008 if (JAS_CAST(int, 4 + 2 * curv->numents) != cnt)
1009 goto error;
1010 return 0;
1011
1012 error:
1013 jas_icccurv_destroy(attrval);
1014 return -1;
1015 }
1016
jas_icccurv_getsize(jas_iccattrval_t * attrval)1017 static int jas_icccurv_getsize(jas_iccattrval_t *attrval)
1018 {
1019 jas_icccurv_t *curv = &attrval->data.curv;
1020 return 4 + 2 * curv->numents;
1021 }
1022
jas_icccurv_output(jas_iccattrval_t * attrval,jas_stream_t * out)1023 static int jas_icccurv_output(jas_iccattrval_t *attrval, jas_stream_t *out)
1024 {
1025 jas_icccurv_t *curv = &attrval->data.curv;
1026 unsigned int i;
1027
1028 if (jas_iccputuint32(out, curv->numents))
1029 goto error;
1030 for (i = 0; i < curv->numents; ++i) {
1031 if (jas_iccputuint16(out, curv->ents[i]))
1032 goto error;
1033 }
1034 return 0;
1035 error:
1036 return -1;
1037 }
1038
jas_icccurv_dump(jas_iccattrval_t * attrval,FILE * out)1039 static void jas_icccurv_dump(jas_iccattrval_t *attrval, FILE *out)
1040 {
1041 int i;
1042 jas_icccurv_t *curv = &attrval->data.curv;
1043 fprintf(out, "number of entires = %d\n", (int)curv->numents);
1044 if (curv->numents == 1) {
1045 fprintf(out, "gamma = %f\n", curv->ents[0] / 256.0);
1046 } else {
1047 for (i = 0; i < JAS_CAST(int, curv->numents); ++i) {
1048 if (i < 3 || i >= JAS_CAST(int, curv->numents) - 3) {
1049 fprintf(out, "entry[%d] = %f\n", i, curv->ents[i] / 65535.0);
1050 }
1051 }
1052 }
1053 }
1054
1055 /******************************************************************************\
1056 *
1057 \******************************************************************************/
1058
jas_icctxtdesc_destroy(jas_iccattrval_t * attrval)1059 static void jas_icctxtdesc_destroy(jas_iccattrval_t *attrval)
1060 {
1061 jas_icctxtdesc_t *txtdesc = &attrval->data.txtdesc;
1062 if (txtdesc->ascdata)
1063 jas_free(txtdesc->ascdata);
1064 if (txtdesc->ucdata)
1065 jas_free(txtdesc->ucdata);
1066 }
1067
jas_icctxtdesc_copy(jas_iccattrval_t * attrval,jas_iccattrval_t * othattrval)1068 static int jas_icctxtdesc_copy(jas_iccattrval_t *attrval,
1069 jas_iccattrval_t *othattrval)
1070 {
1071 jas_icctxtdesc_t *txtdesc = &attrval->data.txtdesc;
1072
1073 /* Avoid compiler warnings about unused parameters. */
1074 attrval = 0;
1075 othattrval = 0;
1076 txtdesc = 0;
1077
1078 /* Not yet implemented. */
1079 abort();
1080 return -1;
1081 }
1082
jas_icctxtdesc_input(jas_iccattrval_t * attrval,jas_stream_t * in,int cnt)1083 static int jas_icctxtdesc_input(jas_iccattrval_t *attrval, jas_stream_t *in,
1084 int cnt)
1085 {
1086 int n;
1087 int c;
1088 jas_icctxtdesc_t *txtdesc = &attrval->data.txtdesc;
1089 txtdesc->ascdata = 0;
1090 txtdesc->ucdata = 0;
1091 if (jas_iccgetuint32(in, &txtdesc->asclen))
1092 goto error;
1093 if (!(txtdesc->ascdata = jas_malloc(txtdesc->asclen)))
1094 goto error;
1095 if (jas_stream_read(in, txtdesc->ascdata, txtdesc->asclen) !=
1096 JAS_CAST(int, txtdesc->asclen))
1097 goto error;
1098 txtdesc->ascdata[txtdesc->asclen - 1] = '\0';
1099 if (jas_iccgetuint32(in, &txtdesc->uclangcode) ||
1100 jas_iccgetuint32(in, &txtdesc->uclen))
1101 goto error;
1102 if (!(txtdesc->ucdata = jas_alloc2(txtdesc->uclen, 2)))
1103 goto error;
1104 if (jas_stream_read(in, txtdesc->ucdata, txtdesc->uclen * 2) !=
1105 JAS_CAST(int, txtdesc->uclen * 2))
1106 goto error;
1107 if (jas_iccgetuint16(in, &txtdesc->sccode))
1108 goto error;
1109 if ((c = jas_stream_getc(in)) == EOF)
1110 goto error;
1111 txtdesc->maclen = c;
1112 if (jas_stream_read(in, txtdesc->macdata, 67) != 67)
1113 goto error;
1114 txtdesc->asclen = strlen(txtdesc->ascdata) + 1;
1115 #define WORKAROUND_BAD_PROFILES
1116 #ifdef WORKAROUND_BAD_PROFILES
1117 n = txtdesc->asclen + txtdesc->uclen * 2 + 15 + 67;
1118 if (n > cnt) {
1119 return -1;
1120 }
1121 if (n < cnt) {
1122 if (jas_stream_gobble(in, cnt - n) != cnt - n)
1123 goto error;
1124 }
1125 #else
1126 if (txtdesc->asclen + txtdesc->uclen * 2 + 15 + 67 != cnt)
1127 return -1;
1128 #endif
1129 return 0;
1130 error:
1131 jas_icctxtdesc_destroy(attrval);
1132 return -1;
1133 }
1134
jas_icctxtdesc_getsize(jas_iccattrval_t * attrval)1135 static int jas_icctxtdesc_getsize(jas_iccattrval_t *attrval)
1136 {
1137 jas_icctxtdesc_t *txtdesc = &attrval->data.txtdesc;
1138 return strlen(txtdesc->ascdata) + 1 + txtdesc->uclen * 2 + 15 + 67;
1139 }
1140
jas_icctxtdesc_output(jas_iccattrval_t * attrval,jas_stream_t * out)1141 static int jas_icctxtdesc_output(jas_iccattrval_t *attrval, jas_stream_t *out)
1142 {
1143 jas_icctxtdesc_t *txtdesc = &attrval->data.txtdesc;
1144 if (jas_iccputuint32(out, txtdesc->asclen) ||
1145 jas_stream_puts(out, txtdesc->ascdata) ||
1146 jas_stream_putc(out, 0) == EOF ||
1147 jas_iccputuint32(out, txtdesc->uclangcode) ||
1148 jas_iccputuint32(out, txtdesc->uclen) ||
1149 jas_stream_write(out, txtdesc->ucdata, txtdesc->uclen * 2) != JAS_CAST(int, txtdesc->uclen * 2) ||
1150 jas_iccputuint16(out, txtdesc->sccode) ||
1151 jas_stream_putc(out, txtdesc->maclen) == EOF)
1152 goto error;
1153 if (txtdesc->maclen > 0) {
1154 if (jas_stream_write(out, txtdesc->macdata, 67) != 67)
1155 goto error;
1156 } else {
1157 if (jas_stream_pad(out, 67, 0) != 67)
1158 goto error;
1159 }
1160 return 0;
1161 error:
1162 return -1;
1163 }
1164
jas_icctxtdesc_dump(jas_iccattrval_t * attrval,FILE * out)1165 static void jas_icctxtdesc_dump(jas_iccattrval_t *attrval, FILE *out)
1166 {
1167 jas_icctxtdesc_t *txtdesc = &attrval->data.txtdesc;
1168 fprintf(out, "ascii = \"%s\"\n", txtdesc->ascdata);
1169 fprintf(out, "uclangcode = %d; uclen = %d\n", (int)txtdesc->uclangcode,
1170 (int)txtdesc->uclen);
1171 fprintf(out, "sccode = %d\n", (int)txtdesc->sccode);
1172 fprintf(out, "maclen = %d\n", txtdesc->maclen);
1173 }
1174
1175 /******************************************************************************\
1176 *
1177 \******************************************************************************/
1178
jas_icctxt_destroy(jas_iccattrval_t * attrval)1179 static void jas_icctxt_destroy(jas_iccattrval_t *attrval)
1180 {
1181 jas_icctxt_t *txt = &attrval->data.txt;
1182 if (txt->string)
1183 jas_free(txt->string);
1184 }
1185
jas_icctxt_copy(jas_iccattrval_t * attrval,jas_iccattrval_t * othattrval)1186 static int jas_icctxt_copy(jas_iccattrval_t *attrval,
1187 jas_iccattrval_t *othattrval)
1188 {
1189 jas_icctxt_t *txt = &attrval->data.txt;
1190 jas_icctxt_t *othtxt = &othattrval->data.txt;
1191 if (!(txt->string = jas_strdup(othtxt->string)))
1192 return -1;
1193 return 0;
1194 }
1195
jas_icctxt_input(jas_iccattrval_t * attrval,jas_stream_t * in,int cnt)1196 static int jas_icctxt_input(jas_iccattrval_t *attrval, jas_stream_t *in,
1197 int cnt)
1198 {
1199 jas_icctxt_t *txt = &attrval->data.txt;
1200 txt->string = 0;
1201 if (!(txt->string = jas_malloc(cnt)))
1202 goto error;
1203 if (jas_stream_read(in, txt->string, cnt) != cnt)
1204 goto error;
1205 txt->string[cnt - 1] = '\0';
1206 if (JAS_CAST(int, strlen(txt->string)) + 1 != cnt)
1207 goto error;
1208 return 0;
1209 error:
1210 if (txt->string)
1211 jas_free(txt->string);
1212 return -1;
1213 }
1214
jas_icctxt_getsize(jas_iccattrval_t * attrval)1215 static int jas_icctxt_getsize(jas_iccattrval_t *attrval)
1216 {
1217 jas_icctxt_t *txt = &attrval->data.txt;
1218 return strlen(txt->string) + 1;
1219 }
1220
jas_icctxt_output(jas_iccattrval_t * attrval,jas_stream_t * out)1221 static int jas_icctxt_output(jas_iccattrval_t *attrval, jas_stream_t *out)
1222 {
1223 jas_icctxt_t *txt = &attrval->data.txt;
1224 if (jas_stream_puts(out, txt->string) ||
1225 jas_stream_putc(out, 0) == EOF)
1226 return -1;
1227 return 0;
1228 }
1229
jas_icctxt_dump(jas_iccattrval_t * attrval,FILE * out)1230 static void jas_icctxt_dump(jas_iccattrval_t *attrval, FILE *out)
1231 {
1232 jas_icctxt_t *txt = &attrval->data.txt;
1233 fprintf(out, "string = \"%s\"\n", txt->string);
1234 }
1235
1236 /******************************************************************************\
1237 *
1238 \******************************************************************************/
1239
jas_icclut8_destroy(jas_iccattrval_t * attrval)1240 static void jas_icclut8_destroy(jas_iccattrval_t *attrval)
1241 {
1242 jas_icclut8_t *lut8 = &attrval->data.lut8;
1243 if (lut8->clut)
1244 jas_free(lut8->clut);
1245 if (lut8->intabs)
1246 jas_free(lut8->intabs);
1247 if (lut8->intabsbuf)
1248 jas_free(lut8->intabsbuf);
1249 if (lut8->outtabs)
1250 jas_free(lut8->outtabs);
1251 if (lut8->outtabsbuf)
1252 jas_free(lut8->outtabsbuf);
1253 }
1254
jas_icclut8_copy(jas_iccattrval_t * attrval,jas_iccattrval_t * othattrval)1255 static int jas_icclut8_copy(jas_iccattrval_t *attrval,
1256 jas_iccattrval_t *othattrval)
1257 {
1258 jas_icclut8_t *lut8 = &attrval->data.lut8;
1259 /* Avoid compiler warnings about unused parameters. */
1260 attrval = 0;
1261 othattrval = 0;
1262 lut8 = 0;
1263 abort();
1264 return -1;
1265 }
1266
jas_icclut8_input(jas_iccattrval_t * attrval,jas_stream_t * in,int cnt)1267 static int jas_icclut8_input(jas_iccattrval_t *attrval, jas_stream_t *in,
1268 int cnt)
1269 {
1270 int i;
1271 int j;
1272 int clutsize;
1273 jas_icclut8_t *lut8 = &attrval->data.lut8;
1274 lut8->clut = 0;
1275 lut8->intabs = 0;
1276 lut8->intabsbuf = 0;
1277 lut8->outtabs = 0;
1278 lut8->outtabsbuf = 0;
1279 if (jas_iccgetuint8(in, &lut8->numinchans) ||
1280 jas_iccgetuint8(in, &lut8->numoutchans) ||
1281 jas_iccgetuint8(in, &lut8->clutlen) ||
1282 jas_stream_getc(in) == EOF)
1283 goto error;
1284 for (i = 0; i < 3; ++i) {
1285 for (j = 0; j < 3; ++j) {
1286 if (jas_iccgetsint32(in, &lut8->e[i][j]))
1287 goto error;
1288 }
1289 }
1290 if (jas_iccgetuint16(in, &lut8->numintabents) ||
1291 jas_iccgetuint16(in, &lut8->numouttabents))
1292 goto error;
1293 clutsize = jas_iccpowi(lut8->clutlen, lut8->numinchans) * lut8->numoutchans;
1294 if (!(lut8->clut = jas_alloc2(clutsize, sizeof(jas_iccuint8_t))) ||
1295 !(lut8->intabsbuf = jas_alloc3(lut8->numinchans,
1296 lut8->numintabents, sizeof(jas_iccuint8_t))) ||
1297 !(lut8->intabs = jas_alloc2(lut8->numinchans,
1298 sizeof(jas_iccuint8_t *))))
1299 goto error;
1300 for (i = 0; i < lut8->numinchans; ++i)
1301 lut8->intabs[i] = &lut8->intabsbuf[i * lut8->numintabents];
1302 if (!(lut8->outtabsbuf = jas_alloc3(lut8->numoutchans,
1303 lut8->numouttabents, sizeof(jas_iccuint8_t))) ||
1304 !(lut8->outtabs = jas_alloc2(lut8->numoutchans,
1305 sizeof(jas_iccuint8_t *))))
1306 goto error;
1307 for (i = 0; i < lut8->numoutchans; ++i)
1308 lut8->outtabs[i] = &lut8->outtabsbuf[i * lut8->numouttabents];
1309 for (i = 0; i < lut8->numinchans; ++i) {
1310 for (j = 0; j < JAS_CAST(int, lut8->numintabents); ++j) {
1311 if (jas_iccgetuint8(in, &lut8->intabs[i][j]))
1312 goto error;
1313 }
1314 }
1315 for (i = 0; i < lut8->numoutchans; ++i) {
1316 for (j = 0; j < JAS_CAST(int, lut8->numouttabents); ++j) {
1317 if (jas_iccgetuint8(in, &lut8->outtabs[i][j]))
1318 goto error;
1319 }
1320 }
1321 for (i = 0; i < clutsize; ++i) {
1322 if (jas_iccgetuint8(in, &lut8->clut[i]))
1323 goto error;
1324 }
1325 if (JAS_CAST(int, 44 + lut8->numinchans * lut8->numintabents +
1326 lut8->numoutchans * lut8->numouttabents +
1327 jas_iccpowi(lut8->clutlen, lut8->numinchans) * lut8->numoutchans) !=
1328 cnt)
1329 goto error;
1330 return 0;
1331 error:
1332 jas_icclut8_destroy(attrval);
1333 return -1;
1334 }
1335
jas_icclut8_getsize(jas_iccattrval_t * attrval)1336 static int jas_icclut8_getsize(jas_iccattrval_t *attrval)
1337 {
1338 jas_icclut8_t *lut8 = &attrval->data.lut8;
1339 return 44 + lut8->numinchans * lut8->numintabents +
1340 lut8->numoutchans * lut8->numouttabents +
1341 jas_iccpowi(lut8->clutlen, lut8->numinchans) * lut8->numoutchans;
1342 }
1343
jas_icclut8_output(jas_iccattrval_t * attrval,jas_stream_t * out)1344 static int jas_icclut8_output(jas_iccattrval_t *attrval, jas_stream_t *out)
1345 {
1346 jas_icclut8_t *lut8 = &attrval->data.lut8;
1347 int i;
1348 int j;
1349 int n;
1350 lut8->clut = 0;
1351 lut8->intabs = 0;
1352 lut8->intabsbuf = 0;
1353 lut8->outtabs = 0;
1354 lut8->outtabsbuf = 0;
1355 if (jas_stream_putc(out, lut8->numinchans) == EOF ||
1356 jas_stream_putc(out, lut8->numoutchans) == EOF ||
1357 jas_stream_putc(out, lut8->clutlen) == EOF ||
1358 jas_stream_putc(out, 0) == EOF)
1359 goto error;
1360 for (i = 0; i < 3; ++i) {
1361 for (j = 0; j < 3; ++j) {
1362 if (jas_iccputsint32(out, lut8->e[i][j]))
1363 goto error;
1364 }
1365 }
1366 if (jas_iccputuint16(out, lut8->numintabents) ||
1367 jas_iccputuint16(out, lut8->numouttabents))
1368 goto error;
1369 n = lut8->numinchans * lut8->numintabents;
1370 for (i = 0; i < n; ++i) {
1371 if (jas_iccputuint8(out, lut8->intabsbuf[i]))
1372 goto error;
1373 }
1374 n = lut8->numoutchans * lut8->numouttabents;
1375 for (i = 0; i < n; ++i) {
1376 if (jas_iccputuint8(out, lut8->outtabsbuf[i]))
1377 goto error;
1378 }
1379 n = jas_iccpowi(lut8->clutlen, lut8->numinchans) * lut8->numoutchans;
1380 for (i = 0; i < n; ++i) {
1381 if (jas_iccputuint8(out, lut8->clut[i]))
1382 goto error;
1383 }
1384 return 0;
1385 error:
1386 return -1;
1387 }
1388
jas_icclut8_dump(jas_iccattrval_t * attrval,FILE * out)1389 static void jas_icclut8_dump(jas_iccattrval_t *attrval, FILE *out)
1390 {
1391 jas_icclut8_t *lut8 = &attrval->data.lut8;
1392 int i;
1393 int j;
1394 fprintf(out, "numinchans=%d, numoutchans=%d, clutlen=%d\n",
1395 lut8->numinchans, lut8->numoutchans, lut8->clutlen);
1396 for (i = 0; i < 3; ++i) {
1397 for (j = 0; j < 3; ++j) {
1398 fprintf(out, "e[%d][%d]=%f ", i, j, lut8->e[i][j] / 65536.0);
1399 }
1400 fprintf(out, "\n");
1401 }
1402 fprintf(out, "numintabents=%d, numouttabents=%d\n",
1403 (int)lut8->numintabents, (int)lut8->numouttabents);
1404 }
1405
1406 /******************************************************************************\
1407 *
1408 \******************************************************************************/
1409
jas_icclut16_destroy(jas_iccattrval_t * attrval)1410 static void jas_icclut16_destroy(jas_iccattrval_t *attrval)
1411 {
1412 jas_icclut16_t *lut16 = &attrval->data.lut16;
1413 if (lut16->clut)
1414 jas_free(lut16->clut);
1415 if (lut16->intabs)
1416 jas_free(lut16->intabs);
1417 if (lut16->intabsbuf)
1418 jas_free(lut16->intabsbuf);
1419 if (lut16->outtabs)
1420 jas_free(lut16->outtabs);
1421 if (lut16->outtabsbuf)
1422 jas_free(lut16->outtabsbuf);
1423 }
1424
jas_icclut16_copy(jas_iccattrval_t * attrval,jas_iccattrval_t * othattrval)1425 static int jas_icclut16_copy(jas_iccattrval_t *attrval,
1426 jas_iccattrval_t *othattrval)
1427 {
1428 /* Avoid compiler warnings about unused parameters. */
1429 attrval = 0;
1430 othattrval = 0;
1431 /* Not yet implemented. */
1432 abort();
1433 return -1;
1434 }
1435
jas_icclut16_input(jas_iccattrval_t * attrval,jas_stream_t * in,int cnt)1436 static int jas_icclut16_input(jas_iccattrval_t *attrval, jas_stream_t *in,
1437 int cnt)
1438 {
1439 int i;
1440 int j;
1441 int clutsize;
1442 jas_icclut16_t *lut16 = &attrval->data.lut16;
1443 lut16->clut = 0;
1444 lut16->intabs = 0;
1445 lut16->intabsbuf = 0;
1446 lut16->outtabs = 0;
1447 lut16->outtabsbuf = 0;
1448 if (jas_iccgetuint8(in, &lut16->numinchans) ||
1449 jas_iccgetuint8(in, &lut16->numoutchans) ||
1450 jas_iccgetuint8(in, &lut16->clutlen) ||
1451 jas_stream_getc(in) == EOF)
1452 goto error;
1453 for (i = 0; i < 3; ++i) {
1454 for (j = 0; j < 3; ++j) {
1455 if (jas_iccgetsint32(in, &lut16->e[i][j]))
1456 goto error;
1457 }
1458 }
1459 if (jas_iccgetuint16(in, &lut16->numintabents) ||
1460 jas_iccgetuint16(in, &lut16->numouttabents))
1461 goto error;
1462 clutsize = jas_iccpowi(lut16->clutlen, lut16->numinchans) * lut16->numoutchans;
1463 if (!(lut16->clut = jas_alloc2(clutsize, sizeof(jas_iccuint16_t))) ||
1464 !(lut16->intabsbuf = jas_alloc3(lut16->numinchans,
1465 lut16->numintabents, sizeof(jas_iccuint16_t))) ||
1466 !(lut16->intabs = jas_alloc2(lut16->numinchans,
1467 sizeof(jas_iccuint16_t *))))
1468 goto error;
1469 for (i = 0; i < lut16->numinchans; ++i)
1470 lut16->intabs[i] = &lut16->intabsbuf[i * lut16->numintabents];
1471 if (!(lut16->outtabsbuf = jas_alloc3(lut16->numoutchans,
1472 lut16->numouttabents, sizeof(jas_iccuint16_t))) ||
1473 !(lut16->outtabs = jas_alloc2(lut16->numoutchans,
1474 sizeof(jas_iccuint16_t *))))
1475 goto error;
1476 for (i = 0; i < lut16->numoutchans; ++i)
1477 lut16->outtabs[i] = &lut16->outtabsbuf[i * lut16->numouttabents];
1478 for (i = 0; i < lut16->numinchans; ++i) {
1479 for (j = 0; j < JAS_CAST(int, lut16->numintabents); ++j) {
1480 if (jas_iccgetuint16(in, &lut16->intabs[i][j]))
1481 goto error;
1482 }
1483 }
1484 for (i = 0; i < lut16->numoutchans; ++i) {
1485 for (j = 0; j < JAS_CAST(int, lut16->numouttabents); ++j) {
1486 if (jas_iccgetuint16(in, &lut16->outtabs[i][j]))
1487 goto error;
1488 }
1489 }
1490 for (i = 0; i < clutsize; ++i) {
1491 if (jas_iccgetuint16(in, &lut16->clut[i]))
1492 goto error;
1493 }
1494 if (JAS_CAST(int, 44 + 2 * (lut16->numinchans * lut16->numintabents +
1495 lut16->numoutchans * lut16->numouttabents +
1496 jas_iccpowi(lut16->clutlen, lut16->numinchans) *
1497 lut16->numoutchans)) != cnt)
1498 goto error;
1499 return 0;
1500 error:
1501 jas_icclut16_destroy(attrval);
1502 return -1;
1503 }
1504
jas_icclut16_getsize(jas_iccattrval_t * attrval)1505 static int jas_icclut16_getsize(jas_iccattrval_t *attrval)
1506 {
1507 jas_icclut16_t *lut16 = &attrval->data.lut16;
1508 return 44 + 2 * (lut16->numinchans * lut16->numintabents +
1509 lut16->numoutchans * lut16->numouttabents +
1510 jas_iccpowi(lut16->clutlen, lut16->numinchans) * lut16->numoutchans);
1511 }
1512
jas_icclut16_output(jas_iccattrval_t * attrval,jas_stream_t * out)1513 static int jas_icclut16_output(jas_iccattrval_t *attrval, jas_stream_t *out)
1514 {
1515 jas_icclut16_t *lut16 = &attrval->data.lut16;
1516 int i;
1517 int j;
1518 int n;
1519 if (jas_stream_putc(out, lut16->numinchans) == EOF ||
1520 jas_stream_putc(out, lut16->numoutchans) == EOF ||
1521 jas_stream_putc(out, lut16->clutlen) == EOF ||
1522 jas_stream_putc(out, 0) == EOF)
1523 goto error;
1524 for (i = 0; i < 3; ++i) {
1525 for (j = 0; j < 3; ++j) {
1526 if (jas_iccputsint32(out, lut16->e[i][j]))
1527 goto error;
1528 }
1529 }
1530 if (jas_iccputuint16(out, lut16->numintabents) ||
1531 jas_iccputuint16(out, lut16->numouttabents))
1532 goto error;
1533 n = lut16->numinchans * lut16->numintabents;
1534 for (i = 0; i < n; ++i) {
1535 if (jas_iccputuint16(out, lut16->intabsbuf[i]))
1536 goto error;
1537 }
1538 n = lut16->numoutchans * lut16->numouttabents;
1539 for (i = 0; i < n; ++i) {
1540 if (jas_iccputuint16(out, lut16->outtabsbuf[i]))
1541 goto error;
1542 }
1543 n = jas_iccpowi(lut16->clutlen, lut16->numinchans) * lut16->numoutchans;
1544 for (i = 0; i < n; ++i) {
1545 if (jas_iccputuint16(out, lut16->clut[i]))
1546 goto error;
1547 }
1548 return 0;
1549 error:
1550 return -1;
1551 }
1552
jas_icclut16_dump(jas_iccattrval_t * attrval,FILE * out)1553 static void jas_icclut16_dump(jas_iccattrval_t *attrval, FILE *out)
1554 {
1555 jas_icclut16_t *lut16 = &attrval->data.lut16;
1556 int i;
1557 int j;
1558 fprintf(out, "numinchans=%d, numoutchans=%d, clutlen=%d\n",
1559 lut16->numinchans, lut16->numoutchans, lut16->clutlen);
1560 for (i = 0; i < 3; ++i) {
1561 for (j = 0; j < 3; ++j) {
1562 fprintf(out, "e[%d][%d]=%f ", i, j, lut16->e[i][j] / 65536.0);
1563 }
1564 fprintf(out, "\n");
1565 }
1566 fprintf(out, "numintabents=%d, numouttabents=%d\n",
1567 (int)lut16->numintabents, (int)lut16->numouttabents);
1568 }
1569
1570 /******************************************************************************\
1571 *
1572 \******************************************************************************/
1573
jas_iccgetuint(jas_stream_t * in,int n,ulonglong * val)1574 static int jas_iccgetuint(jas_stream_t *in, int n, ulonglong *val)
1575 {
1576 int i;
1577 int c;
1578 ulonglong v;
1579 v = 0;
1580 for (i = n; i > 0; --i) {
1581 if ((c = jas_stream_getc(in)) == EOF)
1582 return -1;
1583 v = (v << 8) | c;
1584 }
1585 *val = v;
1586 return 0;
1587 }
1588
jas_iccgetuint8(jas_stream_t * in,jas_iccuint8_t * val)1589 static int jas_iccgetuint8(jas_stream_t *in, jas_iccuint8_t *val)
1590 {
1591 int c;
1592 if ((c = jas_stream_getc(in)) == EOF)
1593 return -1;
1594 *val = c;
1595 return 0;
1596 }
1597
jas_iccgetuint16(jas_stream_t * in,jas_iccuint16_t * val)1598 static int jas_iccgetuint16(jas_stream_t *in, jas_iccuint16_t *val)
1599 {
1600 ulonglong tmp;
1601 if (jas_iccgetuint(in, 2, &tmp))
1602 return -1;
1603 *val = tmp;
1604 return 0;
1605 }
1606
jas_iccgetsint32(jas_stream_t * in,jas_iccsint32_t * val)1607 static int jas_iccgetsint32(jas_stream_t *in, jas_iccsint32_t *val)
1608 {
1609 ulonglong tmp;
1610 if (jas_iccgetuint(in, 4, &tmp))
1611 return -1;
1612 *val = (tmp & 0x80000000) ? (-JAS_CAST(longlong, (((~tmp) &
1613 0x7fffffff) + 1))) : JAS_CAST(longlong, tmp);
1614 return 0;
1615 }
1616
jas_iccgetuint32(jas_stream_t * in,jas_iccuint32_t * val)1617 static int jas_iccgetuint32(jas_stream_t *in, jas_iccuint32_t *val)
1618 {
1619 ulonglong tmp;
1620 if (jas_iccgetuint(in, 4, &tmp))
1621 return -1;
1622 *val = tmp;
1623 return 0;
1624 }
1625
jas_iccgetuint64(jas_stream_t * in,jas_iccuint64_t * val)1626 static int jas_iccgetuint64(jas_stream_t *in, jas_iccuint64_t *val)
1627 {
1628 ulonglong tmp;
1629 if (jas_iccgetuint(in, 8, &tmp))
1630 return -1;
1631 *val = tmp;
1632 return 0;
1633 }
1634
jas_iccputuint(jas_stream_t * out,int n,ulonglong val)1635 static int jas_iccputuint(jas_stream_t *out, int n, ulonglong val)
1636 {
1637 int i;
1638 int c;
1639 for (i = n; i > 0; --i) {
1640 c = (val >> (8 * (i - 1))) & 0xff;
1641 if (jas_stream_putc(out, c) == EOF)
1642 return -1;
1643 }
1644 return 0;
1645 }
1646
jas_iccputsint(jas_stream_t * out,int n,longlong val)1647 static int jas_iccputsint(jas_stream_t *out, int n, longlong val)
1648 {
1649 ulonglong tmp;
1650 tmp = (val < 0) ? (abort(), 0) : val;
1651 return jas_iccputuint(out, n, tmp);
1652 }
1653
1654 /******************************************************************************\
1655 *
1656 \******************************************************************************/
1657
jas_iccsigtostr(int sig,char * buf)1658 static char *jas_iccsigtostr(int sig, char *buf)
1659 {
1660 int n;
1661 int c;
1662 char *bufptr;
1663 bufptr = buf;
1664 for (n = 4; n > 0; --n) {
1665 c = (sig >> 24) & 0xff;
1666 if (isalpha(c) || isdigit(c)) {
1667 *bufptr++ = c;
1668 }
1669 sig <<= 8;
1670 }
1671 *bufptr = '\0';
1672 return buf;
1673 }
1674
jas_iccpadtomult(long x,long y)1675 static long jas_iccpadtomult(long x, long y)
1676 {
1677 return ((x + y - 1) / y) * y;
1678 }
1679
jas_iccpowi(int x,int n)1680 static long jas_iccpowi(int x, int n)
1681 {
1682 long y;
1683 y = 1;
1684 while (--n >= 0)
1685 y *= x;
1686 return y;
1687 }
1688
1689
jas_iccprof_createfrombuf(uchar * buf,int len)1690 jas_iccprof_t *jas_iccprof_createfrombuf(uchar *buf, int len)
1691 {
1692 jas_stream_t *in;
1693 jas_iccprof_t *prof;
1694 if (!(in = jas_stream_memopen(JAS_CAST(char *, buf), len)))
1695 goto error;
1696 if (!(prof = jas_iccprof_load(in)))
1697 goto error;
1698 jas_stream_close(in);
1699 return prof;
1700 error:
1701 return 0;
1702 }
1703
jas_iccprof_createfromclrspc(int clrspc)1704 jas_iccprof_t *jas_iccprof_createfromclrspc(int clrspc)
1705 {
1706 jas_iccprof_t *prof;
1707 switch (clrspc) {
1708 case JAS_CLRSPC_SRGB:
1709 prof = jas_iccprof_createfrombuf(jas_iccprofdata_srgb,
1710 jas_iccprofdata_srgblen);
1711 break;
1712 case JAS_CLRSPC_SGRAY:
1713 prof = jas_iccprof_createfrombuf(jas_iccprofdata_sgray,
1714 jas_iccprofdata_sgraylen);
1715 break;
1716 default:
1717 prof = 0;
1718 break;
1719 }
1720 return prof;
1721 }
1722