• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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