~paparazzi-uav/paparazzi/v5.0-manual

« back to all changes in this revision

Viewing changes to sw/ext/opencv_bebop/opencv/3rdparty/libjasper/jas_icc.c

  • Committer: Paparazzi buildbot
  • Date: 2016-05-18 15:00:29 UTC
  • Revision ID: felix.ruess+docbot@gmail.com-20160518150029-e8lgzi5kvb4p7un9
Manual import commit 4b8bbb730080dac23cf816b98908dacfabe2a8ec from v5.0 branch.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
 
 
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
 
 
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
 
 
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
 
 
253
void jas_iccprof_dump(jas_iccprof_t *prof, FILE *out)
 
254
{
 
255
    jas_iccattrtab_dump(prof->attrtab, out);
 
256
}
 
257
 
 
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
 
 
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
 
 
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
 
 
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
 
 
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
 
 
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
 
 
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
 
 
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
 
 
583
int jas_iccprof_gethdr(jas_iccprof_t *prof, jas_icchdr_t *hdr)
 
584
{
 
585
    *hdr = prof->hdr;
 
586
    return 0;
 
587
}
 
588
 
 
589
int jas_iccprof_sethdr(jas_iccprof_t *prof, jas_icchdr_t *hdr)
 
590
{
 
591
    prof->hdr = *hdr;
 
592
    return 0;
 
593
}
 
594
 
 
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
 
 
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
 
 
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
 
 
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
 
 
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
 
 
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
 
 
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
 
 
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
 
 
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
 
 
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
 
 
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
 
 
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
 
 
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
 
 
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
 
 
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
 
 
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
 
 
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
 
 
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
 
 
863
jas_iccattrval_t *jas_iccattrval_clone(jas_iccattrval_t *attrval)
 
864
{
 
865
    ++attrval->refcnt;
 
866
    return attrval;
 
867
}
 
868
 
 
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
 
 
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
 
 
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
 
 
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
 
 
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
 
 
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
 
 
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
 
 
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
 
 
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
 
 
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
 
 
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
 
 
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
 
 
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
 
 
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
 
 
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
 
 
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
 
 
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
 
 
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
 
 
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
 
 
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
 
 
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
 
 
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
 
 
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
 
 
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
 
 
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
 
 
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
 
 
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
 
 
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
 
 
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
 
 
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
 
 
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
 
 
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
 
 
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
 
 
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
 
 
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
 
 
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
 
 
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
 
 
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
 
 
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
 
 
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
 
 
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
 
 
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
 
 
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
 
 
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
 
 
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
 
 
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
 
 
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
 
 
1675
static long jas_iccpadtomult(long x, long y)
 
1676
{
 
1677
    return ((x + y - 1) / y) * y;
 
1678
}
 
1679
 
 
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
 
 
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
 
 
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
}