2
* Copyright (c) 2002-2003 Michael David Adams.
6
/* __START_OF_JASPER_LICENSE__
8
* JasPer License Version 2.0
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
14
* All rights reserved.
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:
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.
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
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.
59
* __END_OF_JASPER_LICENSE__
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>
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)
81
static jas_iccattrval_t *jas_iccattrval_create0(void);
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);
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,
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);
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,
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);
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,
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);
130
static int jas_iccxyz_input(jas_iccattrval_t *attrval, jas_stream_t *in,
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);
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);
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,
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);
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,
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);
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);
170
static long jas_iccpowi(int x, int n);
172
static char *jas_iccsigtostr(int sig, char *buf);
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,
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,
187
{JAS_ICC_TYPE_LUT8, {jas_icclut8_destroy, jas_icclut8_copy,
188
jas_icclut8_input, jas_icclut8_output, jas_icclut8_getsize,
190
{JAS_ICC_TYPE_LUT16, {jas_icclut16_destroy, jas_icclut16_copy,
191
jas_icclut16_input, jas_icclut16_output, jas_icclut16_getsize,
193
{0, {0, 0, 0, 0, 0, 0}}
201
/******************************************************************************\
203
\******************************************************************************/
205
static jas_iccprof_t *jas_iccprof_create()
209
if (!(prof = jas_malloc(sizeof(jas_iccprof_t)))) {
212
if (!(prof->attrtab = jas_iccattrtab_create()))
214
memset(&prof->hdr, 0, sizeof(jas_icchdr_t));
215
prof->tagtab.numents = 0;
216
prof->tagtab.ents = 0;
220
jas_iccprof_destroy(prof);
224
jas_iccprof_t *jas_iccprof_copy(jas_iccprof_t *prof)
226
jas_iccprof_t *newprof;
228
if (!(newprof = jas_iccprof_create()))
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)))
240
jas_iccprof_destroy(newprof);
244
void jas_iccprof_destroy(jas_iccprof_t *prof)
247
jas_iccattrtab_destroy(prof->attrtab);
248
if (prof->tagtab.ents)
249
jas_free(prof->tagtab.ents);
253
void jas_iccprof_dump(jas_iccprof_t *prof, FILE *out)
255
jas_iccattrtab_dump(prof->attrtab, out);
258
jas_iccprof_t *jas_iccprof_load(jas_stream_t *in)
266
jas_iccattrval_t *attrval;
267
jas_iccattrval_t *prevattrval;
268
jas_icctagtabent_t *tagtabent;
269
jas_iccattrvalinfo_t *attrvalinfo;
276
if (!(prof = jas_iccprof_create())) {
280
if (jas_iccprof_readhdr(in, &prof->hdr)) {
281
jas_eprintf("cannot get header\n");
284
if (jas_iccprof_gettagtab(in, &prof->tagtab)) {
285
jas_eprintf("cannot get tab table\n");
288
jas_iccprof_sorttagtab(&prof->tagtab);
290
numtags = prof->tagtab.numents;
291
curoff = JAS_ICC_HDRLEN + 4 + 12 * numtags;
294
for (i = 0; i < numtags; ++i) {
295
tagtabent = &prof->tagtab.ents[i];
296
if (tagtabent->off == JAS_CAST(jas_iccuint32_t, prevoff)) {
298
if (!(attrval = jas_iccattrval_clone(prevattrval)))
300
if (jas_iccprof_setattr(prof, tagtabent->tag, attrval))
302
jas_iccattrval_destroy(attrval);
305
jas_eprintf("warning: skipping unknown tag type\n");
310
reloff = tagtabent->off - curoff;
312
if (jas_stream_gobble(in, reloff) != reloff)
315
} else if (reloff < 0) {
316
/* This should never happen since we read the tagged
317
element data in a single pass. */
321
if (jas_iccgetuint32(in, &type)) {
324
if (jas_stream_gobble(in, 4) != 4) {
328
if (!(attrvalinfo = jas_iccattrvalinfo_lookup(type))) {
330
jas_eprintf("warning: skipping unknown tag type\n");
335
if (!(attrval = jas_iccattrval_create(type))) {
338
len = tagtabent->len - 8;
339
if ((*attrval->ops->input)(attrval, in, len)) {
343
if (jas_iccprof_setattr(prof, tagtabent->tag, attrval)) {
346
prevattrval = attrval; /* This is correct, but slimey. */
347
jas_iccattrval_destroy(attrval);
355
jas_iccprof_destroy(prof);
357
jas_iccattrval_destroy(attrval);
361
int jas_iccprof_save(jas_iccprof_t *prof, jas_stream_t *out)
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;
375
tagtab = &prof->tagtab;
376
if (!(tagtab->ents = jas_alloc2(prof->attrtab->numattrs,
377
sizeof(jas_icctagtabent_t))))
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))
385
assert(attrval->ops->output);
386
tagtabent->tag = attrname;
387
tagtabent->data = &attrval->data;
389
for (j = 0; j < i; ++j) {
390
tmptagtabent = &tagtab->ents[j];
391
if (tagtabent->data == tmptagtabent->data) {
392
sharedtagtabent = tmptagtabent;
396
if (sharedtagtabent) {
397
tagtabent->off = sharedtagtabent->off;
398
tagtabent->len = sharedtagtabent->len;
399
tagtabent->first = sharedtagtabent;
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);
407
curoff += tagtabent->len;
410
jas_iccattrval_destroy(attrval);
412
prof->hdr.size = curoff;
413
if (jas_iccprof_writehdr(out, &prof->hdr))
415
if (jas_iccprof_puttagtab(out, &prof->tagtab))
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))
423
if (jas_iccputuint32(out, attrval->type) || jas_stream_pad(out,
426
if ((*attrval->ops->output)(attrval, out))
428
jas_iccattrval_destroy(attrval);
429
curoff += tagtabent->len;
431
while (i < JAS_CAST(int, tagtab->numents) &&
432
tagtab->ents[i].first)
434
newoff = (i < JAS_CAST(int, tagtab->numents)) ?
435
tagtab->ents[i].off : prof->hdr.size;
436
reloff = newoff - curoff;
439
if (jas_stream_pad(out, reloff, 0) != reloff)
446
/* XXX - need to free some resources here */
450
static int jas_iccprof_writehdr(jas_stream_t *out, jas_icchdr_t *hdr)
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)
473
static int jas_iccprof_puttagtab(jas_stream_t *out, jas_icctagtab_t *tagtab)
476
jas_icctagtabent_t *tagtabent;
477
if (jas_iccputuint32(out, tagtab->numents))
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))
491
static int jas_iccprof_readhdr(jas_stream_t *in, jas_icchdr_t *hdr)
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)
514
static int jas_iccprof_gettagtab(jas_stream_t *in, jas_icctagtab_t *tagtab)
517
jas_icctagtabent_t *tagtabent;
520
jas_free(tagtab->ents);
523
if (jas_iccgetuint32(in, &tagtab->numents))
525
if (!(tagtab->ents = jas_alloc2(tagtab->numents,
526
sizeof(jas_icctagtabent_t))))
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))
539
jas_free(tagtab->ents);
545
jas_iccattrval_t *jas_iccprof_getattr(jas_iccprof_t *prof,
546
jas_iccattrname_t name)
549
jas_iccattrval_t *attrval;
550
if ((i = jas_iccattrtab_lookup(prof->attrtab, name)) < 0)
552
if (!(attrval = jas_iccattrval_clone(prof->attrtab->attrs[i].val)))
559
int jas_iccprof_setattr(jas_iccprof_t *prof, jas_iccattrname_t name,
560
jas_iccattrval_t *val)
563
if ((i = jas_iccattrtab_lookup(prof->attrtab, name)) >= 0) {
565
if (jas_iccattrtab_replace(prof->attrtab, i, name, val))
568
jas_iccattrtab_delete(prof->attrtab, i);
572
if (jas_iccattrtab_add(prof->attrtab, -1, name, val))
583
int jas_iccprof_gethdr(jas_iccprof_t *prof, jas_icchdr_t *hdr)
589
int jas_iccprof_sethdr(jas_iccprof_t *prof, jas_icchdr_t *hdr)
595
static void jas_iccprof_sorttagtab(jas_icctagtab_t *tagtab)
597
qsort(tagtab->ents, tagtab->numents, sizeof(jas_icctagtabent_t),
598
jas_icctagtabent_cmp);
601
static int jas_icctagtabent_cmp(const void *src, const void *dst)
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) {
607
} else if (srctagtabent->off < dsttagtabent->off) {
613
static jas_iccattrvalinfo_t *jas_iccattrvalinfo_lookup(jas_iccsig_t type)
615
jas_iccattrvalinfo_t *info;
616
info = jas_iccattrvalinfos;
617
for (info = jas_iccattrvalinfos; info->type; ++info) {
618
if (info->type == type) {
625
static int jas_iccgettime(jas_stream_t *in, jas_icctime_t *time)
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)) {
638
static int jas_iccgetxyz(jas_stream_t *in, jas_iccxyz_t *xyz)
640
if (jas_iccgetsint32(in, &xyz->x) ||
641
jas_iccgetsint32(in, &xyz->y) ||
642
jas_iccgetsint32(in, &xyz->z)) {
648
static int jas_iccputtime(jas_stream_t *out, jas_icctime_t *time)
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);
659
static int jas_iccputxyz(jas_stream_t *out, jas_iccxyz_t *xyz)
661
jas_iccputuint32(out, xyz->x);
662
jas_iccputuint32(out, xyz->y);
663
jas_iccputuint32(out, xyz->z);
667
/******************************************************************************\
668
* attribute table class
669
\******************************************************************************/
671
static jas_iccattrtab_t *jas_iccattrtab_create()
673
jas_iccattrtab_t *tab;
675
if (!(tab = jas_malloc(sizeof(jas_iccattrtab_t))))
680
if (jas_iccattrtab_resize(tab, 32))
685
jas_iccattrtab_destroy(tab);
689
static jas_iccattrtab_t *jas_iccattrtab_copy(jas_iccattrtab_t *attrtab)
691
jas_iccattrtab_t *newattrtab;
693
if (!(newattrtab = jas_iccattrtab_create()))
695
for (i = 0; i < attrtab->numattrs; ++i) {
696
if (jas_iccattrtab_add(newattrtab, i, attrtab->attrs[i].name,
697
attrtab->attrs[i].val))
705
static void jas_iccattrtab_destroy(jas_iccattrtab_t *tab)
708
while (tab->numattrs > 0) {
709
jas_iccattrtab_delete(tab, 0);
711
jas_free(tab->attrs);
716
void jas_iccattrtab_dump(jas_iccattrtab_t *attrtab, FILE *out)
720
jas_iccattrval_t *attrval;
721
jas_iccattrvalinfo_t *info;
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];
728
info = jas_iccattrvalinfo_lookup(attrval->type);
730
fprintf(out, "attrno=%d; attrname=\"%s\"(0x%08x); attrtype=\"%s\"(0x%08x)\n",
732
jas_iccsigtostr(attr->name, &buf[0]),
733
(unsigned)attr->name,
734
jas_iccsigtostr(attrval->type, &buf[8]),
735
(unsigned)attrval->type
737
jas_iccattrval_dump(attrval, out);
738
fprintf(out, "---\n");
742
static int jas_iccattrtab_resize(jas_iccattrtab_t *tab, int maxents)
744
jas_iccattr_t *newattrs;
745
assert(maxents >= tab->numattrs);
746
newattrs = jas_realloc2(tab->attrs, maxents, sizeof(jas_iccattr_t));
749
tab->attrs = newattrs;
750
tab->maxattrs = maxents;
754
static int jas_iccattrtab_add(jas_iccattrtab_t *attrtab, int i,
755
jas_iccuint32_t name, jas_iccattrval_t *val)
759
jas_iccattrval_t *tmpattrval;
762
i = attrtab->numattrs;
764
assert(i >= 0 && i <= attrtab->numattrs);
765
if (attrtab->numattrs >= attrtab->maxattrs) {
766
if (jas_iccattrtab_resize(attrtab, attrtab->numattrs + 32)) {
770
if (!(tmpattrval = jas_iccattrval_clone(val)))
772
n = attrtab->numattrs - i;
774
memmove(&attrtab->attrs[i + 1], &attrtab->attrs[i],
775
n * sizeof(jas_iccattr_t));
776
attr = &attrtab->attrs[i];
778
attr->val = tmpattrval;
783
jas_iccattrval_destroy(tmpattrval);
787
static int jas_iccattrtab_replace(jas_iccattrtab_t *attrtab, int i,
788
jas_iccuint32_t name, jas_iccattrval_t *val)
790
jas_iccattrval_t *newval;
792
if (!(newval = jas_iccattrval_clone(val)))
794
attr = &attrtab->attrs[i];
795
jas_iccattrval_destroy(attr->val);
803
static void jas_iccattrtab_delete(jas_iccattrtab_t *attrtab, int i)
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));
813
static int jas_iccattrtab_get(jas_iccattrtab_t *attrtab, int i,
814
jas_iccattrname_t *name, jas_iccattrval_t **val)
817
if (i < 0 || i >= attrtab->numattrs)
819
attr = &attrtab->attrs[i];
821
if (!(*val = jas_iccattrval_clone(attr->val)))
828
static int jas_iccattrtab_lookup(jas_iccattrtab_t *attrtab,
829
jas_iccuint32_t name)
833
for (i = 0; i < attrtab->numattrs; ++i) {
834
attr = &attrtab->attrs[i];
835
if (attr->name == name)
841
/******************************************************************************\
842
* attribute value class
843
\******************************************************************************/
845
jas_iccattrval_t *jas_iccattrval_create(jas_iccuint32_t type)
847
jas_iccattrval_t *attrval;
848
jas_iccattrvalinfo_t *info;
850
if (!(info = jas_iccattrvalinfo_lookup(type)))
852
if (!(attrval = jas_iccattrval_create0()))
854
attrval->ops = &info->ops;
855
attrval->type = type;
857
memset(&attrval->data, 0, sizeof(attrval->data));
863
jas_iccattrval_t *jas_iccattrval_clone(jas_iccattrval_t *attrval)
869
void jas_iccattrval_destroy(jas_iccattrval_t *attrval)
872
jas_eprintf("refcnt=%d\n", attrval->refcnt);
874
if (--attrval->refcnt <= 0) {
875
if (attrval->ops->destroy)
876
(*attrval->ops->destroy)(attrval);
881
void jas_iccattrval_dump(jas_iccattrval_t *attrval, FILE *out)
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);
892
int jas_iccattrval_allowmodify(jas_iccattrval_t **attrvalx)
894
jas_iccattrval_t *newattrval;
895
jas_iccattrval_t *attrval = *attrvalx;
897
if (attrval->refcnt > 1) {
898
if (!(newattrval = jas_iccattrval_create0()))
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))
907
memcpy(&newattrval->data, &attrval->data,
908
sizeof(newattrval->data));
910
*attrvalx = newattrval;
915
jas_free(newattrval);
920
static jas_iccattrval_t *jas_iccattrval_create0()
922
jas_iccattrval_t *attrval;
923
if (!(attrval = jas_malloc(sizeof(jas_iccattrval_t))))
925
memset(attrval, 0, sizeof(jas_iccattrval_t));
932
/******************************************************************************\
934
\******************************************************************************/
936
static int jas_iccxyz_input(jas_iccattrval_t *attrval, jas_stream_t *in,
939
if (len != 4 * 3) abort();
940
return jas_iccgetxyz(in, &attrval->data.xyz);
943
static int jas_iccxyz_output(jas_iccattrval_t *attrval, jas_stream_t *out)
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))
953
static int jas_iccxyz_getsize(jas_iccattrval_t *attrval)
955
/* Avoid compiler warnings about unused parameters. */
961
static void jas_iccxyz_dump(jas_iccattrval_t *attrval, FILE *out)
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);
967
/******************************************************************************\
968
* attribute table class
969
\******************************************************************************/
971
static void jas_icccurv_destroy(jas_iccattrval_t *attrval)
973
jas_icccurv_t *curv = &attrval->data.curv;
975
jas_free(curv->ents);
978
static int jas_icccurv_copy(jas_iccattrval_t *attrval,
979
jas_iccattrval_t *othattrval)
981
/* Avoid compiler warnings about unused parameters. */
985
/* Not yet implemented. */
990
static int jas_icccurv_input(jas_iccattrval_t *attrval, jas_stream_t *in,
993
jas_icccurv_t *curv = &attrval->data.curv;
999
if (jas_iccgetuint32(in, &curv->numents))
1001
if (!(curv->ents = jas_alloc2(curv->numents, sizeof(jas_iccuint16_t))))
1003
for (i = 0; i < curv->numents; ++i) {
1004
if (jas_iccgetuint16(in, &curv->ents[i]))
1008
if (JAS_CAST(int, 4 + 2 * curv->numents) != cnt)
1013
jas_icccurv_destroy(attrval);
1017
static int jas_icccurv_getsize(jas_iccattrval_t *attrval)
1019
jas_icccurv_t *curv = &attrval->data.curv;
1020
return 4 + 2 * curv->numents;
1023
static int jas_icccurv_output(jas_iccattrval_t *attrval, jas_stream_t *out)
1025
jas_icccurv_t *curv = &attrval->data.curv;
1028
if (jas_iccputuint32(out, curv->numents))
1030
for (i = 0; i < curv->numents; ++i) {
1031
if (jas_iccputuint16(out, curv->ents[i]))
1039
static void jas_icccurv_dump(jas_iccattrval_t *attrval, FILE *out)
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);
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);
1055
/******************************************************************************\
1057
\******************************************************************************/
1059
static void jas_icctxtdesc_destroy(jas_iccattrval_t *attrval)
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);
1068
static int jas_icctxtdesc_copy(jas_iccattrval_t *attrval,
1069
jas_iccattrval_t *othattrval)
1071
jas_icctxtdesc_t *txtdesc = &attrval->data.txtdesc;
1073
/* Avoid compiler warnings about unused parameters. */
1078
/* Not yet implemented. */
1083
static int jas_icctxtdesc_input(jas_iccattrval_t *attrval, jas_stream_t *in,
1088
jas_icctxtdesc_t *txtdesc = &attrval->data.txtdesc;
1089
txtdesc->ascdata = 0;
1090
txtdesc->ucdata = 0;
1091
if (jas_iccgetuint32(in, &txtdesc->asclen))
1093
if (!(txtdesc->ascdata = jas_malloc(txtdesc->asclen)))
1095
if (jas_stream_read(in, txtdesc->ascdata, txtdesc->asclen) !=
1096
JAS_CAST(int, txtdesc->asclen))
1098
txtdesc->ascdata[txtdesc->asclen - 1] = '\0';
1099
if (jas_iccgetuint32(in, &txtdesc->uclangcode) ||
1100
jas_iccgetuint32(in, &txtdesc->uclen))
1102
if (!(txtdesc->ucdata = jas_alloc2(txtdesc->uclen, 2)))
1104
if (jas_stream_read(in, txtdesc->ucdata, txtdesc->uclen * 2) !=
1105
JAS_CAST(int, txtdesc->uclen * 2))
1107
if (jas_iccgetuint16(in, &txtdesc->sccode))
1109
if ((c = jas_stream_getc(in)) == EOF)
1111
txtdesc->maclen = c;
1112
if (jas_stream_read(in, txtdesc->macdata, 67) != 67)
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;
1122
if (jas_stream_gobble(in, cnt - n) != cnt - n)
1126
if (txtdesc->asclen + txtdesc->uclen * 2 + 15 + 67 != cnt)
1131
jas_icctxtdesc_destroy(attrval);
1135
static int jas_icctxtdesc_getsize(jas_iccattrval_t *attrval)
1137
jas_icctxtdesc_t *txtdesc = &attrval->data.txtdesc;
1138
return strlen(txtdesc->ascdata) + 1 + txtdesc->uclen * 2 + 15 + 67;
1141
static int jas_icctxtdesc_output(jas_iccattrval_t *attrval, jas_stream_t *out)
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)
1153
if (txtdesc->maclen > 0) {
1154
if (jas_stream_write(out, txtdesc->macdata, 67) != 67)
1157
if (jas_stream_pad(out, 67, 0) != 67)
1165
static void jas_icctxtdesc_dump(jas_iccattrval_t *attrval, FILE *out)
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);
1175
/******************************************************************************\
1177
\******************************************************************************/
1179
static void jas_icctxt_destroy(jas_iccattrval_t *attrval)
1181
jas_icctxt_t *txt = &attrval->data.txt;
1183
jas_free(txt->string);
1186
static int jas_icctxt_copy(jas_iccattrval_t *attrval,
1187
jas_iccattrval_t *othattrval)
1189
jas_icctxt_t *txt = &attrval->data.txt;
1190
jas_icctxt_t *othtxt = &othattrval->data.txt;
1191
if (!(txt->string = jas_strdup(othtxt->string)))
1196
static int jas_icctxt_input(jas_iccattrval_t *attrval, jas_stream_t *in,
1199
jas_icctxt_t *txt = &attrval->data.txt;
1201
if (!(txt->string = jas_malloc(cnt)))
1203
if (jas_stream_read(in, txt->string, cnt) != cnt)
1205
txt->string[cnt - 1] = '\0';
1206
if (JAS_CAST(int, strlen(txt->string)) + 1 != cnt)
1211
jas_free(txt->string);
1215
static int jas_icctxt_getsize(jas_iccattrval_t *attrval)
1217
jas_icctxt_t *txt = &attrval->data.txt;
1218
return strlen(txt->string) + 1;
1221
static int jas_icctxt_output(jas_iccattrval_t *attrval, jas_stream_t *out)
1223
jas_icctxt_t *txt = &attrval->data.txt;
1224
if (jas_stream_puts(out, txt->string) ||
1225
jas_stream_putc(out, 0) == EOF)
1230
static void jas_icctxt_dump(jas_iccattrval_t *attrval, FILE *out)
1232
jas_icctxt_t *txt = &attrval->data.txt;
1233
fprintf(out, "string = \"%s\"\n", txt->string);
1236
/******************************************************************************\
1238
\******************************************************************************/
1240
static void jas_icclut8_destroy(jas_iccattrval_t *attrval)
1242
jas_icclut8_t *lut8 = &attrval->data.lut8;
1244
jas_free(lut8->clut);
1246
jas_free(lut8->intabs);
1247
if (lut8->intabsbuf)
1248
jas_free(lut8->intabsbuf);
1250
jas_free(lut8->outtabs);
1251
if (lut8->outtabsbuf)
1252
jas_free(lut8->outtabsbuf);
1255
static int jas_icclut8_copy(jas_iccattrval_t *attrval,
1256
jas_iccattrval_t *othattrval)
1258
jas_icclut8_t *lut8 = &attrval->data.lut8;
1259
/* Avoid compiler warnings about unused parameters. */
1267
static int jas_icclut8_input(jas_iccattrval_t *attrval, jas_stream_t *in,
1273
jas_icclut8_t *lut8 = &attrval->data.lut8;
1276
lut8->intabsbuf = 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)
1284
for (i = 0; i < 3; ++i) {
1285
for (j = 0; j < 3; ++j) {
1286
if (jas_iccgetsint32(in, &lut8->e[i][j]))
1290
if (jas_iccgetuint16(in, &lut8->numintabents) ||
1291
jas_iccgetuint16(in, &lut8->numouttabents))
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 *))))
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 *))))
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]))
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]))
1321
for (i = 0; i < clutsize; ++i) {
1322
if (jas_iccgetuint8(in, &lut8->clut[i]))
1325
if (JAS_CAST(int, 44 + lut8->numinchans * lut8->numintabents +
1326
lut8->numoutchans * lut8->numouttabents +
1327
jas_iccpowi(lut8->clutlen, lut8->numinchans) * lut8->numoutchans) !=
1332
jas_icclut8_destroy(attrval);
1336
static int jas_icclut8_getsize(jas_iccattrval_t *attrval)
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;
1344
static int jas_icclut8_output(jas_iccattrval_t *attrval, jas_stream_t *out)
1346
jas_icclut8_t *lut8 = &attrval->data.lut8;
1352
lut8->intabsbuf = 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)
1360
for (i = 0; i < 3; ++i) {
1361
for (j = 0; j < 3; ++j) {
1362
if (jas_iccputsint32(out, lut8->e[i][j]))
1366
if (jas_iccputuint16(out, lut8->numintabents) ||
1367
jas_iccputuint16(out, lut8->numouttabents))
1369
n = lut8->numinchans * lut8->numintabents;
1370
for (i = 0; i < n; ++i) {
1371
if (jas_iccputuint8(out, lut8->intabsbuf[i]))
1374
n = lut8->numoutchans * lut8->numouttabents;
1375
for (i = 0; i < n; ++i) {
1376
if (jas_iccputuint8(out, lut8->outtabsbuf[i]))
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]))
1389
static void jas_icclut8_dump(jas_iccattrval_t *attrval, FILE *out)
1391
jas_icclut8_t *lut8 = &attrval->data.lut8;
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);
1402
fprintf(out, "numintabents=%d, numouttabents=%d\n",
1403
(int)lut8->numintabents, (int)lut8->numouttabents);
1406
/******************************************************************************\
1408
\******************************************************************************/
1410
static void jas_icclut16_destroy(jas_iccattrval_t *attrval)
1412
jas_icclut16_t *lut16 = &attrval->data.lut16;
1414
jas_free(lut16->clut);
1416
jas_free(lut16->intabs);
1417
if (lut16->intabsbuf)
1418
jas_free(lut16->intabsbuf);
1420
jas_free(lut16->outtabs);
1421
if (lut16->outtabsbuf)
1422
jas_free(lut16->outtabsbuf);
1425
static int jas_icclut16_copy(jas_iccattrval_t *attrval,
1426
jas_iccattrval_t *othattrval)
1428
/* Avoid compiler warnings about unused parameters. */
1431
/* Not yet implemented. */
1436
static int jas_icclut16_input(jas_iccattrval_t *attrval, jas_stream_t *in,
1442
jas_icclut16_t *lut16 = &attrval->data.lut16;
1445
lut16->intabsbuf = 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)
1453
for (i = 0; i < 3; ++i) {
1454
for (j = 0; j < 3; ++j) {
1455
if (jas_iccgetsint32(in, &lut16->e[i][j]))
1459
if (jas_iccgetuint16(in, &lut16->numintabents) ||
1460
jas_iccgetuint16(in, &lut16->numouttabents))
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 *))))
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 *))))
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]))
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]))
1490
for (i = 0; i < clutsize; ++i) {
1491
if (jas_iccgetuint16(in, &lut16->clut[i]))
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)
1501
jas_icclut16_destroy(attrval);
1505
static int jas_icclut16_getsize(jas_iccattrval_t *attrval)
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);
1513
static int jas_icclut16_output(jas_iccattrval_t *attrval, jas_stream_t *out)
1515
jas_icclut16_t *lut16 = &attrval->data.lut16;
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)
1524
for (i = 0; i < 3; ++i) {
1525
for (j = 0; j < 3; ++j) {
1526
if (jas_iccputsint32(out, lut16->e[i][j]))
1530
if (jas_iccputuint16(out, lut16->numintabents) ||
1531
jas_iccputuint16(out, lut16->numouttabents))
1533
n = lut16->numinchans * lut16->numintabents;
1534
for (i = 0; i < n; ++i) {
1535
if (jas_iccputuint16(out, lut16->intabsbuf[i]))
1538
n = lut16->numoutchans * lut16->numouttabents;
1539
for (i = 0; i < n; ++i) {
1540
if (jas_iccputuint16(out, lut16->outtabsbuf[i]))
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]))
1553
static void jas_icclut16_dump(jas_iccattrval_t *attrval, FILE *out)
1555
jas_icclut16_t *lut16 = &attrval->data.lut16;
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);
1566
fprintf(out, "numintabents=%d, numouttabents=%d\n",
1567
(int)lut16->numintabents, (int)lut16->numouttabents);
1570
/******************************************************************************\
1572
\******************************************************************************/
1574
static int jas_iccgetuint(jas_stream_t *in, int n, ulonglong *val)
1580
for (i = n; i > 0; --i) {
1581
if ((c = jas_stream_getc(in)) == EOF)
1589
static int jas_iccgetuint8(jas_stream_t *in, jas_iccuint8_t *val)
1592
if ((c = jas_stream_getc(in)) == EOF)
1598
static int jas_iccgetuint16(jas_stream_t *in, jas_iccuint16_t *val)
1601
if (jas_iccgetuint(in, 2, &tmp))
1607
static int jas_iccgetsint32(jas_stream_t *in, jas_iccsint32_t *val)
1610
if (jas_iccgetuint(in, 4, &tmp))
1612
*val = (tmp & 0x80000000) ? (-JAS_CAST(longlong, (((~tmp) &
1613
0x7fffffff) + 1))) : JAS_CAST(longlong, tmp);
1617
static int jas_iccgetuint32(jas_stream_t *in, jas_iccuint32_t *val)
1620
if (jas_iccgetuint(in, 4, &tmp))
1626
static int jas_iccgetuint64(jas_stream_t *in, jas_iccuint64_t *val)
1629
if (jas_iccgetuint(in, 8, &tmp))
1635
static int jas_iccputuint(jas_stream_t *out, int n, ulonglong val)
1639
for (i = n; i > 0; --i) {
1640
c = (val >> (8 * (i - 1))) & 0xff;
1641
if (jas_stream_putc(out, c) == EOF)
1647
static int jas_iccputsint(jas_stream_t *out, int n, longlong val)
1650
tmp = (val < 0) ? (abort(), 0) : val;
1651
return jas_iccputuint(out, n, tmp);
1654
/******************************************************************************\
1656
\******************************************************************************/
1658
static char *jas_iccsigtostr(int sig, char *buf)
1664
for (n = 4; n > 0; --n) {
1665
c = (sig >> 24) & 0xff;
1666
if (isalpha(c) || isdigit(c)) {
1675
static long jas_iccpadtomult(long x, long y)
1677
return ((x + y - 1) / y) * y;
1680
static long jas_iccpowi(int x, int n)
1690
jas_iccprof_t *jas_iccprof_createfrombuf(uchar *buf, int len)
1693
jas_iccprof_t *prof;
1694
if (!(in = jas_stream_memopen(JAS_CAST(char *, buf), len)))
1696
if (!(prof = jas_iccprof_load(in)))
1698
jas_stream_close(in);
1704
jas_iccprof_t *jas_iccprof_createfromclrspc(int clrspc)
1706
jas_iccprof_t *prof;
1708
case JAS_CLRSPC_SRGB:
1709
prof = jas_iccprof_createfrombuf(jas_iccprofdata_srgb,
1710
jas_iccprofdata_srgblen);
1712
case JAS_CLRSPC_SGRAY:
1713
prof = jas_iccprof_createfrombuf(jas_iccprofdata_sgray,
1714
jas_iccprofdata_sgraylen);