Coverage Report

Created: 2026-04-01 07:17

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/ghostpdl/jpegxr/cr_parse.c
Line
Count
Source
1
2
3
/*************************************************************************
4
*
5
* This software module was originally contributed by Microsoft
6
* Corporation in the course of development of the
7
* ITU-T T.832 | ISO/IEC 29199-2 ("JPEG XR") format standard for
8
* reference purposes and its performance may not have been optimized.
9
*
10
* This software module is an implementation of one or more
11
* tools as specified by the JPEG XR standard.
12
*
13
* ITU/ISO/IEC give You a royalty-free, worldwide, non-exclusive
14
* copyright license to copy, distribute, and make derivative works
15
* of this software module or modifications thereof for use in
16
* products claiming conformance to the JPEG XR standard as
17
* specified by ITU-T T.832 | ISO/IEC 29199-2.
18
*
19
* ITU/ISO/IEC give users the same free license to this software
20
* module or modifications thereof for research purposes and further
21
* ITU/ISO/IEC standardization.
22
*
23
* Those intending to use this software module in products are advised
24
* that its use may infringe existing patents. ITU/ISO/IEC have no
25
* liability for use of this software module or modifications thereof.
26
*
27
* Copyright is not released for products that do not conform to
28
* to the JPEG XR standard as specified by ITU-T T.832 |
29
* ISO/IEC 29199-2.
30
*
31
* Microsoft Corporation retains full right to modify and use the code
32
* for its own purpose, to assign or donate the code to a third party,
33
* and to inhibit third parties from using the code for products that
34
* do not conform to the JPEG XR standard as specified by ITU-T T.832 |
35
* ISO/IEC 29199-2.
36
*
37
* This copyright notice must be included in all copies or derivative
38
* works.
39
*
40
* Copyright (c) ITU-T/ISO/IEC 2008, 2009.
41
***********************************************************************/
42
43
#ifdef _MSC_VER
44
#pragma comment (user,"$Id: cr_parse.c,v 1.9 2008/03/21 21:23:14 steve Exp $")
45
#else
46
#ident "$Id: cr_parse.c,v 1.9 2008/03/21 21:23:14 steve Exp $"
47
#endif
48
49
# include "jxr_priv.h"
50
# include <string.h>
51
# include <stdlib.h>
52
# include <assert.h>
53
54
static int read_ifd(jxr_container_t container, FILE*fd, int image_number, uint32_t*ifd_next);
55
56
jxr_container_t jxr_create_container(void)
57
0
{
58
0
    jxr_container_t res = (jxr_container_t)
59
0
        calloc(1, sizeof (struct jxr_container));
60
0
    return res;
61
0
}
62
63
void jxr_destroy_container(jxr_container_t container)
64
0
{
65
0
    if(container == NULL)
66
0
        return;
67
0
    free(container);
68
0
}
69
70
int jxr_read_image_container(jxr_container_t container, FILE*fd)
71
0
{
72
0
    unsigned char buf[4];
73
0
    size_t rc;
74
0
    uint32_t ifd_off;
75
76
0
    rc = fread(buf, 1, 4, fd);
77
0
    if (rc < 4)
78
0
        return JXR_EC_BADMAGIC;
79
80
0
    if (buf[0] != 0x49) return JXR_EC_BADMAGIC;
81
0
    if (buf[1] != 0x49) return JXR_EC_BADMAGIC;
82
0
    if (buf[2] != 0xbc) return JXR_EC_BADMAGIC;
83
0
    if (buf[3] > 0x01) return JXR_EC_BADMAGIC; /* Version. */
84
85
0
    rc = fread(buf, 1, 4, fd);
86
0
    if (rc != 4) return JXR_EC_IO;
87
88
0
    ifd_off = (buf[3] << 24) + (buf[2]<<16) + (buf[1]<<8) + (buf[0]<<0);
89
0
    container->image_count = 0;
90
91
0
    while (ifd_off != 0) {
92
0
        uint32_t ifd_next;
93
94
0
        container->image_count += 1;
95
0
        container->table_cnt = (unsigned*)realloc(container->table_cnt,
96
0
            container->image_count * sizeof(unsigned));
97
0
        container->table = (struct ifd_table**) realloc(container->table,
98
0
            container->image_count * sizeof(struct ifd_table*));
99
100
0
        if (ifd_off & 0x1) return JXR_EC_IO;
101
0
        rc = fseek(fd, ifd_off, SEEK_SET);
102
0
        rc = read_ifd(container, fd, container->image_count-1, &ifd_next);
103
0
        if (rc < 0) return (int) rc;
104
105
0
        ifd_off = ifd_next;
106
0
    }
107
108
0
    return 0;
109
0
}
110
111
int jxrc_image_count(jxr_container_t container)
112
0
{
113
0
    return container->image_count;
114
0
}
115
116
int jxrc_document_name(jxr_container_t container, int image, char ** string)
117
0
{
118
119
0
    unsigned ifd_cnt;
120
0
    struct ifd_table*ifd;
121
0
    unsigned idx;
122
123
0
    assert(image < container->image_count);
124
125
0
    ifd_cnt = container->table_cnt[image];
126
0
    ifd = container->table[image];
127
128
0
    for (idx = 0 ; idx < ifd_cnt ; idx += 1) {
129
0
        if (ifd[idx].tag == 0x010d)
130
0
            break;
131
0
    }
132
    
133
0
    if (idx >= ifd_cnt) return -1; 
134
0
    if (ifd[idx].tag != 0x010d) return -1;
135
0
    assert(ifd[idx].type == 2);
136
137
0
    assert(string[0] == 0);
138
0
    string[0] = (char *) malloc(ifd[idx].cnt * sizeof(char));
139
0
    assert(string[0] != 0);
140
141
0
    if (ifd[idx].cnt <= 4) {
142
0
        unsigned i;
143
0
        for (i = 0 ; i < ifd[idx].cnt ; i++)
144
0
            string[0][i] = ifd[idx].value_.v_sbyte[i];
145
0
    }
146
0
    else {
147
0
        unsigned i;
148
0
        for (i = 0 ; i < ifd[idx].cnt ; i++)
149
0
            string[0][i] = ifd[idx].value_.p_sbyte[i];
150
0
    }
151
152
0
    return 0;
153
0
}
154
155
int jxrc_image_description(jxr_container_t container, int image, char ** string)
156
0
{
157
0
    unsigned ifd_cnt;
158
0
    struct ifd_table*ifd;
159
0
    unsigned idx;
160
161
0
    assert(image < container->image_count);
162
163
0
    ifd_cnt = container->table_cnt[image];
164
0
    ifd = container->table[image];
165
166
0
    for (idx = 0 ; idx < ifd_cnt ; idx += 1) {
167
0
        if (ifd[idx].tag == 0x010e)
168
0
            break;
169
0
    }
170
    
171
0
    if (idx >= ifd_cnt) return -1; 
172
0
    if (ifd[idx].tag != 0x010e) return -1;
173
0
    assert(ifd[idx].type == 2);
174
175
0
    assert(string[0] == 0);
176
0
    string[0] = (char *) malloc(ifd[idx].cnt * sizeof(char));
177
0
    assert(string[0] != 0);
178
179
0
    if (ifd[idx].cnt <= 4) {
180
0
        unsigned i;
181
0
        for (i = 0 ; i < ifd[idx].cnt ; i++)
182
0
            string[0][i] = ifd[idx].value_.v_sbyte[i];
183
0
    }
184
0
    else {
185
0
        unsigned i;
186
0
        for (i = 0 ; i < ifd[idx].cnt ; i++)
187
0
            string[0][i] = ifd[idx].value_.p_sbyte[i];
188
0
    }
189
190
0
    return 0;
191
0
}
192
193
int jxrc_equipment_make(jxr_container_t container, int image, char ** string)
194
0
{
195
0
    unsigned ifd_cnt;
196
0
    struct ifd_table*ifd;
197
0
    unsigned idx;
198
199
0
    assert(image < container->image_count);
200
201
0
    ifd_cnt = container->table_cnt[image];
202
0
    ifd = container->table[image];
203
204
0
    for (idx = 0 ; idx < ifd_cnt ; idx += 1) {
205
0
        if (ifd[idx].tag == 0x010f)
206
0
            break;
207
0
    }
208
    
209
0
    if (idx >= ifd_cnt) return -1; 
210
0
    if (ifd[idx].tag != 0x010f) return -1;
211
0
    assert(ifd[idx].type == 2);
212
213
0
    assert(string[0] == 0);
214
0
    string[0] = (char *) malloc(ifd[idx].cnt * sizeof(char));
215
0
    assert(string[0] != 0);
216
217
0
    if (ifd[idx].cnt <= 4) {
218
0
        unsigned i;
219
0
        for (i = 0 ; i < ifd[idx].cnt ; i++)
220
0
            string[0][i] = ifd[idx].value_.v_sbyte[i];
221
0
    }
222
0
    else {
223
0
        unsigned i;
224
0
        for (i = 0 ; i < ifd[idx].cnt ; i++)
225
0
            string[0][i] = ifd[idx].value_.p_sbyte[i];
226
0
    }
227
228
0
    return 0;
229
0
}
230
231
int jxrc_equipment_model(jxr_container_t container, int image, char ** string)
232
0
{
233
0
    unsigned ifd_cnt;
234
0
    struct ifd_table*ifd;
235
0
    unsigned idx;
236
237
0
    assert(image < container->image_count);
238
239
0
    ifd_cnt = container->table_cnt[image];
240
0
    ifd = container->table[image];
241
242
0
    for (idx = 0 ; idx < ifd_cnt ; idx += 1) {
243
0
        if (ifd[idx].tag == 0x0110)
244
0
            break;
245
0
    }
246
    
247
0
    if (idx >= ifd_cnt) return -1; 
248
0
    if (ifd[idx].tag != 0x0110) return -1;
249
0
    assert(ifd[idx].type == 2);
250
251
0
    assert(string[0] == 0);
252
0
    string[0] = (char *) malloc(ifd[idx].cnt * sizeof(char));
253
0
    assert(string[0] != 0);
254
255
0
    if (ifd[idx].cnt <= 4) {
256
0
        unsigned i;
257
0
        for (i = 0 ; i < ifd[idx].cnt ; i++)
258
0
            string[0][i] = ifd[idx].value_.v_sbyte[i];
259
0
    }
260
0
    else {
261
0
        unsigned i;
262
0
        for (i = 0 ; i < ifd[idx].cnt ; i++)
263
0
            string[0][i] = ifd[idx].value_.p_sbyte[i];
264
0
    }
265
266
0
    return 0;
267
0
}
268
269
int jxrc_page_name(jxr_container_t container, int image, char ** string)
270
0
{
271
0
    unsigned ifd_cnt;
272
0
    struct ifd_table*ifd;
273
0
    unsigned idx;
274
275
0
    assert(image < container->image_count);
276
277
0
    ifd_cnt = container->table_cnt[image];
278
0
    ifd = container->table[image];
279
280
0
    for (idx = 0 ; idx < ifd_cnt ; idx += 1) {
281
0
        if (ifd[idx].tag == 0x011d)
282
0
            break;
283
0
    }
284
    
285
0
    if (idx >= ifd_cnt) return -1; 
286
0
    if (ifd[idx].tag != 0x011d) return -1;
287
0
    assert(ifd[idx].type == 2);
288
289
0
    assert(string[0] == 0);
290
0
    string[0] = (char *) malloc(ifd[idx].cnt * sizeof(char));
291
0
    assert(string[0] != 0);
292
293
0
    if (ifd[idx].cnt <= 4) {
294
0
        unsigned i;
295
0
        for (i = 0 ; i < ifd[idx].cnt ; i++)
296
0
            string[0][i] = ifd[idx].value_.v_sbyte[i];
297
0
    }
298
0
    else {
299
0
        unsigned i;
300
0
        for (i = 0 ; i < ifd[idx].cnt ; i++)
301
0
            string[0][i] = ifd[idx].value_.p_sbyte[i];
302
0
    }
303
304
0
    return 0;
305
0
}
306
307
int jxrc_page_number(jxr_container_t container, int image, unsigned short * value)
308
0
{
309
0
    unsigned ifd_cnt;
310
0
    struct ifd_table*ifd;
311
0
    unsigned idx;
312
313
0
    assert(image < container->image_count);
314
315
0
    ifd_cnt = container->table_cnt[image];
316
0
    ifd = container->table[image];
317
318
0
    for (idx = 0 ; idx < ifd_cnt ; idx += 1) {
319
0
        if (ifd[idx].tag == 0x0129)
320
0
            break;
321
0
    }
322
    
323
0
    if (idx >= ifd_cnt) return -1; 
324
0
    if (ifd[idx].tag != 0x0129) return -1;
325
0
    assert(ifd[idx].cnt == 2);
326
0
    assert(ifd[idx].type == 3);
327
328
0
    value[0] = ifd[idx].value_.v_short[0];
329
0
    value[1] = ifd[idx].value_.v_short[1];
330
331
0
    return 0;
332
0
}
333
334
int jxrc_software_name_version(jxr_container_t container, int image, char ** string)
335
0
{
336
0
    unsigned ifd_cnt;
337
0
    struct ifd_table*ifd;
338
0
    unsigned idx;
339
340
0
    assert(image < container->image_count);
341
342
0
    ifd_cnt = container->table_cnt[image];
343
0
    ifd = container->table[image];
344
345
0
    for (idx = 0 ; idx < ifd_cnt ; idx += 1) {
346
0
        if (ifd[idx].tag == 0x0131)
347
0
            break;
348
0
    }
349
    
350
0
    if (idx >= ifd_cnt) return -1; 
351
0
    if (ifd[idx].tag != 0x0131) return -1;
352
0
    assert(ifd[idx].type == 2);
353
354
0
    assert(string[0] == 0);
355
0
    string[0] = (char *) malloc(ifd[idx].cnt * sizeof(char));
356
0
    assert(string[0] != 0);
357
358
0
    if (ifd[idx].cnt <= 4) {
359
0
        unsigned i;
360
0
        for (i = 0 ; i < ifd[idx].cnt ; i++)
361
0
            string[0][i] = ifd[idx].value_.v_sbyte[i];
362
0
    }
363
0
    else {
364
0
        unsigned i;
365
0
        for (i = 0 ; i < ifd[idx].cnt ; i++)
366
0
            string[0][i] = ifd[idx].value_.p_sbyte[i];
367
0
    }
368
369
0
    return 0;
370
0
}
371
372
int jxrc_date_time(jxr_container_t container, int image, char ** string)
373
0
{
374
0
    unsigned ifd_cnt;
375
0
    struct ifd_table*ifd;
376
0
    unsigned idx;
377
0
    unsigned i;
378
0
    assert(image < container->image_count);
379
380
0
    ifd_cnt = container->table_cnt[image];
381
0
    ifd = container->table[image];
382
383
0
    for (idx = 0 ; idx < ifd_cnt ; idx += 1) {
384
0
        if (ifd[idx].tag == 0x0132)
385
0
            break;
386
0
    }
387
    
388
0
    if (idx >= ifd_cnt) return -1; 
389
0
    if (ifd[idx].tag != 0x0132) return -1;
390
0
    assert(ifd[idx].type == 2);
391
392
0
    assert(string[0] == 0);
393
0
    string[0] = (char *) malloc(ifd[idx].cnt * sizeof(char));
394
0
    assert(string[0] != 0);
395
0
    assert(ifd[idx].cnt == 20);
396
397
0
    for (i = 0 ; i < ifd[idx].cnt ; i++)
398
0
        string[0][i] = ifd[idx].value_.p_sbyte[i];
399
400
0
    assert(string[0][4] == 0x3a && string[0][7] == 0x3a && string[0][13] == 0x3a && string[0][16] == 0x3a);
401
0
    assert(string[0][10] == 0x20);
402
0
    assert((string[0][5] == '0' && (string[0][6] >= '1' && string[0][6] <= '9')) || (string[0][5] == '1' && (string[0][6] >= '0' && string[0][6] <= '2')));
403
0
    assert((string[0][8] == '0' && (string[0][9] >= '1' && string[0][9] <= '9')) || ((string[0][8] == '1' || string[0][8] == '2') && (string[0][9] >= '0' && string[0][9] <= '9')) || (string[0][8] == '3' && (string[0][9] >= '0' && string[0][9] <= '1')));
404
0
    assert(((string[0][11] == '0' || string[0][11] == '1') && (string[0][12] >= '0' && string[0][12] <= '9')) || (string[0][11] == '2' && (string[0][12] >= '0' && string[0][12] <= '3')));
405
0
    assert(string[0][14] >= '0' && string[0][14] < '6');
406
0
    assert(string[0][15] >= '0' && string[0][15] <= '9');
407
0
    assert(string[0][17] >= '0' && string[0][17] < '6');
408
0
    assert(string[0][18] >= '0' && string[0][18] <= '9');
409
410
0
    return 0;
411
0
}
412
413
int jxrc_artist_name(jxr_container_t container, int image, char ** string)
414
0
{
415
0
    unsigned ifd_cnt;
416
0
    struct ifd_table*ifd;
417
0
    unsigned idx;
418
419
0
    assert(image < container->image_count);
420
421
0
    ifd_cnt = container->table_cnt[image];
422
0
    ifd = container->table[image];
423
424
0
    for (idx = 0 ; idx < ifd_cnt ; idx += 1) {
425
0
        if (ifd[idx].tag == 0x013b)
426
0
            break;
427
0
    }
428
    
429
0
    if (idx >= ifd_cnt) return -1; 
430
0
    if (ifd[idx].tag != 0x013b) return -1;
431
0
    assert(ifd[idx].type == 2);
432
433
0
    assert(string[0] == 0);
434
0
    string[0] = (char *) malloc(ifd[idx].cnt * sizeof(char));
435
0
    assert(string[0] != 0);
436
437
0
    if (ifd[idx].cnt <= 4) {
438
0
        unsigned i;
439
0
        for (i = 0 ; i < ifd[idx].cnt ; i++)
440
0
            string[0][i] = ifd[idx].value_.v_sbyte[i];
441
0
    }
442
0
    else {
443
0
        unsigned i;
444
0
        for (i = 0 ; i < ifd[idx].cnt ; i++)
445
0
            string[0][i] = ifd[idx].value_.p_sbyte[i];
446
0
    }
447
448
0
    return 0;
449
0
}
450
451
int jxrc_host_computer(jxr_container_t container, int image, char ** string)
452
0
{
453
0
    unsigned ifd_cnt;
454
0
    struct ifd_table*ifd;
455
0
    unsigned idx;
456
457
0
    assert(image < container->image_count);
458
459
0
    ifd_cnt = container->table_cnt[image];
460
0
    ifd = container->table[image];
461
462
0
    for (idx = 0 ; idx < ifd_cnt ; idx += 1) {
463
0
        if (ifd[idx].tag == 0x013c)
464
0
            break;
465
0
    }
466
    
467
0
    if (idx >= ifd_cnt) return -1; 
468
0
    if (ifd[idx].tag != 0x013c) return -1;
469
0
    assert(ifd[idx].type == 2);
470
471
0
    assert(string[0] == 0);
472
0
    string[0] = (char *) malloc(ifd[idx].cnt * sizeof(char));
473
0
    assert(string[0] != 0);
474
475
0
    if (ifd[idx].cnt <= 4) {
476
0
        unsigned i;
477
0
        for (i = 0 ; i < ifd[idx].cnt ; i++)
478
0
            string[0][i] = ifd[idx].value_.v_sbyte[i];
479
0
    }
480
0
    else {
481
0
        unsigned i;
482
0
        for (i = 0 ; i < ifd[idx].cnt ; i++)
483
0
            string[0][i] = ifd[idx].value_.p_sbyte[i];
484
0
    }
485
486
0
    return 0;
487
0
}
488
489
int jxrc_copyright_notice(jxr_container_t container, int image, char ** string)
490
0
{
491
0
    unsigned ifd_cnt;
492
0
    struct ifd_table*ifd;
493
0
    unsigned idx;
494
495
0
    assert(image < container->image_count);
496
497
0
    ifd_cnt = container->table_cnt[image];
498
0
    ifd = container->table[image];
499
500
0
    for (idx = 0 ; idx < ifd_cnt ; idx += 1) {
501
0
        if (ifd[idx].tag == 0x8298)
502
0
            break;
503
0
    }
504
    
505
0
    if (idx >= ifd_cnt) return -1; 
506
0
    if (ifd[idx].tag != 0x8298) return -1;
507
0
    assert(ifd[idx].type == 2);
508
509
0
    assert(string[0] == 0);
510
0
    string[0] = (char *) malloc(ifd[idx].cnt * sizeof(char));
511
0
    assert(string[0] != 0);
512
513
0
    if (ifd[idx].cnt <= 4) {
514
0
        unsigned i;
515
0
        for (i = 0 ; i < ifd[idx].cnt ; i++)
516
0
            string[0][i] = ifd[idx].value_.v_sbyte[i];
517
0
    }
518
0
    else {
519
0
        unsigned i;
520
0
        for (i = 0 ; i < ifd[idx].cnt ; i++)
521
0
            string[0][i] = ifd[idx].value_.p_sbyte[i];
522
0
    }
523
524
0
    return 0;
525
0
}
526
527
unsigned short jxrc_color_space(jxr_container_t container, int image)
528
0
{
529
0
    unsigned ifd_cnt;
530
0
    struct ifd_table*ifd;
531
0
    unsigned idx;
532
0
    unsigned short value;
533
534
0
    assert(image < container->image_count);
535
536
0
    ifd_cnt = container->table_cnt[image];
537
0
    ifd = container->table[image];
538
539
0
    for (idx = 0 ; idx < ifd_cnt ; idx += 1) {
540
0
        if (ifd[idx].tag == 0xa001)
541
0
            break;
542
0
    }
543
    
544
0
    if (idx >= ifd_cnt) return 0; 
545
0
    if (ifd[idx].tag != 0xa001) return 0;
546
0
    assert(ifd[idx].cnt == 1);
547
0
    assert(ifd[idx].type == 3);
548
549
0
    value = ifd[idx].value_.v_short[0];
550
0
    if (value != 0x0001)
551
0
        value = 0xffff;
552
0
    if (value == 0x0001) {
553
0
        switch(jxrc_image_pixelformat(container, image)) {
554
0
            case JXRC_FMT_24bppRGB:
555
0
            case JXRC_FMT_24bppBGR:
556
0
            case JXRC_FMT_32bppBGR:
557
0
            case JXRC_FMT_48bppRGB:
558
0
            case JXRC_FMT_32bppBGRA:
559
0
            case JXRC_FMT_64bppRGBA:
560
0
            case JXRC_FMT_32bppPBGRA:
561
0
            case JXRC_FMT_64bppPRGBA:
562
0
            case JXRC_FMT_32bppCMYK:
563
0
            case JXRC_FMT_40bppCMYKAlpha:
564
0
            case JXRC_FMT_64bppCMYK:
565
0
            case JXRC_FMT_80bppCMYKAlpha:
566
0
            case JXRC_FMT_24bpp3Channels:
567
0
            case JXRC_FMT_32bpp4Channels:
568
0
            case JXRC_FMT_40bpp5Channels:
569
0
            case JXRC_FMT_48bpp6Channels:
570
0
            case JXRC_FMT_56bpp7Channels:
571
0
            case JXRC_FMT_64bpp8Channels:
572
0
            case JXRC_FMT_32bpp3ChannelsAlpha:
573
0
            case JXRC_FMT_40bpp4ChannelsAlpha:
574
0
            case JXRC_FMT_48bpp5ChannelsAlpha:
575
0
            case JXRC_FMT_56bpp6ChannelsAlpha:
576
0
            case JXRC_FMT_64bpp7ChannelsAlpha:
577
0
            case JXRC_FMT_72bpp8ChannelsAlpha:
578
0
            case JXRC_FMT_48bpp3Channels:
579
0
            case JXRC_FMT_64bpp4Channels:
580
0
            case JXRC_FMT_80bpp5Channels:
581
0
            case JXRC_FMT_96bpp6Channels:
582
0
            case JXRC_FMT_112bpp7Channels:
583
0
            case JXRC_FMT_128bpp8Channels:
584
0
            case JXRC_FMT_64bpp3ChannelsAlpha:
585
0
            case JXRC_FMT_80bpp4ChannelsAlpha:
586
0
            case JXRC_FMT_96bpp5ChannelsAlpha:
587
0
            case JXRC_FMT_112bpp6ChannelsAlpha:
588
0
            case JXRC_FMT_128bpp7ChannelsAlpha:
589
0
            case JXRC_FMT_144bpp8ChannelsAlpha:
590
0
            case JXRC_FMT_8bppGray:
591
0
            case JXRC_FMT_16bppGray:
592
0
            case JXRC_FMT_BlackWhite:
593
0
            case JXRC_FMT_16bppBGR555:
594
0
            case JXRC_FMT_16bppBGR565:
595
0
            case JXRC_FMT_32bppBGR101010:
596
0
            case JXRC_FMT_32bppCMYKDIRECT:
597
0
            case JXRC_FMT_64bppCMYKDIRECT:
598
0
            case JXRC_FMT_40bppCMYKDIRECTAlpha:
599
0
            case JXRC_FMT_80bppCMYKDIRECTAlpha:
600
0
            case JXRC_FMT_12bppYCC420:
601
0
            case JXRC_FMT_16bppYCC422:
602
0
            case JXRC_FMT_20bppYCC422:
603
0
            case JXRC_FMT_32bppYCC422:
604
0
            case JXRC_FMT_24bppYCC444:
605
0
            case JXRC_FMT_30bppYCC444:
606
0
            case JXRC_FMT_48bppYCC444:
607
0
            case JXRC_FMT_20bppYCC420Alpha:
608
0
            case JXRC_FMT_24bppYCC422Alpha:
609
0
            case JXRC_FMT_30bppYCC422Alpha:
610
0
            case JXRC_FMT_48bppYCC422Alpha:
611
0
            case JXRC_FMT_32bppYCC444Alpha:
612
0
            case JXRC_FMT_40bppYCC444Alpha:
613
0
            case JXRC_FMT_64bppYCC444Alpha:
614
0
                break;
615
0
            default:
616
                /* Color space tag can equal 1 only if format is UINT  */
617
0
                assert(0);
618
0
                break;
619
0
        }
620
0
    }
621
0
    return value;
622
0
}
623
624
jxrc_t_pixelFormat jxrc_image_pixelformat(jxr_container_t container, int imagenum)
625
0
{
626
0
    unsigned ifd_cnt;
627
0
    struct ifd_table*ifd;
628
0
    unsigned idx;
629
630
0
    unsigned char guid[16];
631
0
    int i;
632
0
    assert(imagenum < container->image_count);
633
634
0
    ifd_cnt = container->table_cnt[imagenum];
635
0
    ifd = container->table[imagenum];
636
637
0
    for (idx = 0 ; idx < ifd_cnt ; idx += 1) {
638
0
        if (ifd[idx].tag == 0xbc01)
639
0
            break;
640
0
    }
641
642
0
    assert(idx < ifd_cnt);
643
0
    assert(ifd[idx].tag == 0xbc01);
644
0
    assert(ifd[idx].cnt == 16);
645
0
    memcpy(guid, ifd[idx].value_.p_byte, 16);
646
0
    for(i=0; i< NUM_GUIDS; i++)
647
0
    {
648
0
        if(isEqualGUID(guid, jxr_guids[i]))
649
0
        {
650
0
            break;
651
0
        }
652
0
    }
653
0
    if(i==NUM_GUIDS)
654
0
        assert(0);
655
0
    return (jxrc_t_pixelFormat)i;
656
    
657
0
}
658
659
unsigned long jxrc_spatial_xfrm_primary(jxr_container_t container, int image)
660
0
{
661
0
    unsigned ifd_cnt;
662
0
    struct ifd_table*ifd;
663
0
    unsigned idx;
664
0
    unsigned long spatial_xfrm;
665
666
0
    assert(image < container->image_count);
667
668
0
    ifd_cnt = container->table_cnt[image];
669
0
    ifd = container->table[image];
670
671
0
    for (idx = 0 ; idx < ifd_cnt ; idx += 1) {
672
0
        if (ifd[idx].tag == 0xbc02)
673
0
            break;
674
0
    }
675
676
0
    if (idx >= ifd_cnt) return 0;
677
0
    if (ifd[idx].tag != 0xbc02) return 0;
678
0
    assert(ifd[idx].cnt == 1);
679
680
0
    switch (ifd[idx].type) {
681
0
        case 4: /* ULONG */
682
0
            spatial_xfrm = (unsigned long) ifd[idx].value_.v_long;
683
0
            break;
684
0
        case 3: /* USHORT */
685
0
            spatial_xfrm = (unsigned long) ifd[idx].value_.v_short[0];
686
0
            break;
687
0
        case 1: /* BYTE */
688
0
            spatial_xfrm = (unsigned long) ifd[idx].value_.v_byte[0];
689
0
            break;
690
0
        default:
691
0
            assert(0);
692
0
            break;
693
0
    }
694
695
0
    if (spatial_xfrm > 7 || spatial_xfrm < 0)
696
0
        spatial_xfrm = 0;
697
0
    return spatial_xfrm;
698
0
}
699
700
unsigned long jxrc_image_type(jxr_container_t container, int image)
701
0
{
702
0
    unsigned ifd_cnt;
703
0
    struct ifd_table*ifd;
704
0
    unsigned idx;
705
0
    unsigned long image_type;
706
707
0
    assert(image < container->image_count);
708
709
0
    ifd_cnt = container->table_cnt[image];
710
0
    ifd = container->table[image];
711
712
0
    for (idx = 0 ; idx < ifd_cnt ; idx += 1) {
713
0
        if (ifd[idx].tag == 0xbc04)
714
0
            break;
715
0
    }
716
    
717
0
    if (idx >= ifd_cnt) return 0; 
718
0
    if (ifd[idx].tag != 0xbc04) return 0;
719
0
    assert(ifd[idx].cnt == 1);
720
0
    assert(ifd[idx].type == 4);
721
722
0
    image_type = ifd[idx].value_.v_long;
723
0
    image_type &= 0x00000003;
724
0
    return image_type;
725
0
}
726
727
int jxrc_ptm_color_info(jxr_container_t container, int image, unsigned char * buf)
728
0
{
729
0
    unsigned ifd_cnt;
730
0
    struct ifd_table*ifd;
731
0
    unsigned idx;
732
0
    uint32_t i;
733
734
0
    assert(image < container->image_count);
735
0
    assert(buf);
736
737
0
    ifd_cnt = container->table_cnt[image];
738
0
    ifd = container->table[image];
739
740
0
    for (idx = 0 ; idx < ifd_cnt ; idx += 1) {
741
0
        if (ifd[idx].tag == 0xbc05)
742
0
            break;
743
0
    }
744
    
745
0
    if (idx >= ifd_cnt) return -1; 
746
0
    if (ifd[idx].tag != 0xbc05) return -1;
747
0
    assert(ifd[idx].cnt == 4);
748
0
    assert(ifd[idx].type == 1);
749
750
0
    for (i = 0 ; i < 4 ; i += 1)
751
0
        buf[i] = ifd[idx].value_.v_byte[i];
752
753
0
    return 0;
754
0
}
755
756
int jxrc_profile_level_container(jxr_container_t container, int image, unsigned char * profile, unsigned char * level)
757
0
{
758
0
    unsigned ifd_cnt;
759
0
    struct ifd_table*ifd;
760
0
    unsigned idx;
761
0
    unsigned char * data;
762
0
    uint32_t count_remaining;
763
0
    uint8_t last, last_flag;
764
765
0
    assert(image < container->image_count);
766
0
    assert(profile);
767
0
    assert(level);
768
769
0
    ifd_cnt = container->table_cnt[image];
770
0
    ifd = container->table[image];
771
772
0
    data = 0;
773
774
0
    for (idx = 0 ; idx < ifd_cnt ; idx += 1) {
775
0
        if (ifd[idx].tag == 0xbc06)
776
0
            break;
777
0
    }
778
    
779
0
    if (idx >= ifd_cnt) return -1; 
780
0
    if (ifd[idx].tag != 0xbc06) return -1;
781
0
    assert(ifd[idx].type == 1);
782
0
    assert(ifd[idx].cnt > 3);
783
784
0
    if (ifd[idx].cnt <= 4) {
785
0
        data = (unsigned char *) (ifd[idx].value_.v_sbyte);
786
0
    }
787
0
    else {
788
0
        data = (unsigned char *) (ifd[idx].value_.p_sbyte);
789
0
    }
790
791
0
    count_remaining = ifd[idx].cnt;
792
0
    for (last = 0 ; last == 0 ; last = last_flag) {
793
0
        profile[0] = data[0];
794
0
        level[0] = data[1];
795
0
        last_flag = (data[3] & 0x1);
796
0
        data += 4;
797
0
        count_remaining -= 4;
798
0
        assert(count_remaining == 0 || count_remaining > 3);
799
0
    }
800
801
0
    return 0;
802
0
}
803
804
unsigned long jxrc_image_width(jxr_container_t container, int image)
805
0
{
806
0
    unsigned ifd_cnt;
807
0
    struct ifd_table*ifd;
808
0
    unsigned idx;
809
0
    unsigned long width;
810
811
0
    assert(image < container->image_count);
812
813
0
    ifd_cnt = container->table_cnt[image];
814
0
    ifd = container->table[image];
815
816
0
    for (idx = 0 ; idx < ifd_cnt ; idx += 1) {
817
0
        if (ifd[idx].tag == 0xbc80)
818
0
            break;
819
0
    }
820
821
0
    assert(idx < ifd_cnt);
822
0
    assert(ifd[idx].tag == 0xbc80);
823
0
    assert(ifd[idx].cnt == 1);
824
825
0
    switch (ifd[idx].type) {
826
0
        case 4: /* ULONG */
827
0
            width = (unsigned long) ifd[idx].value_.v_long;
828
0
            break;
829
0
        case 3: /* USHORT */
830
0
            width = (unsigned long) ifd[idx].value_.v_short[0];
831
0
            break;
832
0
        case 1: /* BYTE */
833
0
            width = (unsigned long) ifd[idx].value_.v_byte[0];
834
0
            break;
835
0
        default:
836
0
            assert(0);
837
0
            break;
838
0
    }
839
840
0
    return width;
841
0
}
842
843
unsigned long jxrc_image_height(jxr_container_t container, int image)
844
0
{
845
0
    unsigned ifd_cnt;
846
0
    struct ifd_table*ifd;
847
0
    unsigned idx;
848
0
    unsigned long height;
849
850
0
    assert(image < container->image_count);
851
852
0
    ifd_cnt = container->table_cnt[image];
853
0
    ifd = container->table[image];
854
855
0
    for (idx = 0 ; idx < ifd_cnt ; idx += 1) {
856
0
        if (ifd[idx].tag == 0xbc81)
857
0
            break;
858
0
    }
859
860
0
    assert(idx < ifd_cnt);
861
0
    assert(ifd[idx].tag == 0xbc81);
862
0
    assert(ifd[idx].cnt == 1);
863
864
0
    switch (ifd[idx].type) {
865
0
        case 4: /* ULONG */
866
0
            height = (unsigned long) ifd[idx].value_.v_long;
867
0
            break;
868
0
        case 3: /* USHORT */
869
0
            height = (unsigned long) ifd[idx].value_.v_short[0];
870
0
            break;
871
0
        case 1: /* BYTE */
872
0
            height = (unsigned long) ifd[idx].value_.v_byte[0];
873
0
            break;
874
0
        default:
875
0
            assert(0);
876
0
            break;
877
0
    }
878
879
0
    return height;
880
0
}
881
882
float jxrc_width_resolution(jxr_container_t container, int image)
883
0
{
884
0
    unsigned ifd_cnt;
885
0
    struct ifd_table*ifd;
886
0
    unsigned idx;
887
0
    float width_resolution;
888
889
0
    assert(image < container->image_count);
890
891
0
    ifd_cnt = container->table_cnt[image];
892
0
    ifd = container->table[image];
893
894
0
    for (idx = 0 ; idx < ifd_cnt ; idx += 1) {
895
0
        if (ifd[idx].tag == 0xbc82)
896
0
            break;
897
0
    }
898
899
0
    if (idx >= ifd_cnt) return 96.0;
900
0
    if (ifd[idx].tag != 0xbc82) return 96.0;
901
0
    assert(ifd[idx].cnt == 1);
902
0
    assert(ifd[idx].type == 11);
903
904
0
    width_resolution = ifd[idx].value_.v_float;
905
0
    if (width_resolution == 0.0)
906
0
        width_resolution = 96.0;
907
0
    return width_resolution;
908
0
}
909
910
float jxrc_height_resolution(jxr_container_t container, int image)
911
0
{
912
0
    unsigned ifd_cnt;
913
0
    struct ifd_table*ifd;
914
0
    unsigned idx;
915
0
    float height_resolution;
916
917
0
    assert(image < container->image_count);
918
919
0
    ifd_cnt = container->table_cnt[image];
920
0
    ifd = container->table[image];
921
922
0
    for (idx = 0 ; idx < ifd_cnt ; idx += 1) {
923
0
        if (ifd[idx].tag == 0xbc83)
924
0
            break;
925
0
    }
926
927
0
    if (idx >= ifd_cnt) return 96.0;
928
0
    if (ifd[idx].tag != 0xbc83) return 96.0;
929
0
    assert(ifd[idx].cnt == 1);
930
0
    assert(ifd[idx].type == 11);
931
932
0
    height_resolution = ifd[idx].value_.v_float;
933
0
    if (height_resolution == 0.0)
934
0
        height_resolution = 96.0;
935
0
    return height_resolution;
936
0
}
937
938
unsigned long jxrc_image_offset(jxr_container_t container, int image)
939
0
{
940
0
    unsigned ifd_cnt;
941
0
    struct ifd_table*ifd;
942
0
    unsigned idx;
943
0
    unsigned long pos;
944
945
0
    assert(image < container->image_count);
946
947
0
    ifd_cnt = container->table_cnt[image];
948
0
    ifd = container->table[image];
949
950
0
    for (idx = 0 ; idx < ifd_cnt ; idx += 1) {
951
0
        if (ifd[idx].tag == 0xbcc0)
952
0
            break;
953
0
    }
954
955
0
    assert(idx < ifd_cnt);
956
0
    assert(ifd[idx].tag == 0xbcc0);
957
0
    assert(ifd[idx].cnt == 1);
958
959
0
    switch (ifd[idx].type) {
960
0
        case 4: /* ULONG */
961
0
            pos = (unsigned long) ifd[idx].value_.v_long;
962
0
            break;
963
0
        case 3: /* USHORT */
964
0
            pos = (unsigned long) ifd[idx].value_.v_short[0];
965
0
            break;
966
0
        case 1: /* BYTE */
967
0
            pos = (unsigned long) ifd[idx].value_.v_byte[0];
968
0
            break;
969
0
        default:
970
0
            assert(0);
971
0
            break;
972
0
    }
973
974
0
    return pos;
975
0
}
976
977
unsigned long jxrc_image_bytecount(jxr_container_t container, int image)
978
0
{
979
0
    unsigned ifd_cnt;
980
0
    struct ifd_table*ifd;
981
0
    unsigned idx;
982
0
    unsigned long pos;
983
984
0
    assert(image < container->image_count);
985
986
0
    ifd_cnt = container->table_cnt[image];
987
0
    ifd = container->table[image];
988
989
0
    for (idx = 0 ; idx < ifd_cnt ; idx += 1) {
990
0
        if (ifd[idx].tag == 0xbcc1)
991
0
            break;
992
0
    }
993
994
0
    assert(idx < ifd_cnt);
995
0
    assert(ifd[idx].tag == 0xbcc1);
996
0
    assert(ifd[idx].cnt == 1);
997
998
0
    switch (ifd[idx].type) {
999
0
        case 4: /* ULONG */
1000
0
            pos = (unsigned long) ifd[idx].value_.v_long;
1001
0
            break;
1002
0
        case 3: /* USHORT */
1003
0
            pos = (unsigned long) ifd[idx].value_.v_short[0];
1004
0
            break;
1005
0
        case 1: /* BYTE */
1006
0
            pos = (unsigned long) ifd[idx].value_.v_byte[0];
1007
0
            break;
1008
0
        default:
1009
0
            assert(0);
1010
0
            break;
1011
0
    }
1012
1013
0
    return pos;
1014
0
}
1015
1016
unsigned long jxrc_alpha_offset(jxr_container_t container, int image)
1017
0
{
1018
0
    unsigned ifd_cnt;
1019
0
    struct ifd_table*ifd;
1020
0
    unsigned idx;
1021
0
    unsigned long pos;
1022
1023
0
    assert(image < container->image_count);
1024
1025
0
    ifd_cnt = container->table_cnt[image];
1026
0
    ifd = container->table[image];
1027
1028
0
    for (idx = 0 ; idx < ifd_cnt ; idx += 1) {
1029
0
        if (ifd[idx].tag == 0xBCC2)
1030
0
            break;
1031
0
    }
1032
1033
0
    if (idx >= ifd_cnt) return 0; /* No alpha coded image */
1034
0
    if (ifd[idx].tag != 0xbcc2) return 0;
1035
0
    assert(ifd[idx].cnt == 1);
1036
1037
0
    switch (ifd[idx].type) {
1038
0
        case 4: /* ULONG */
1039
0
            pos = (unsigned long) ifd[idx].value_.v_long;
1040
0
            break;
1041
0
        case 3: /* USHORT */
1042
0
            pos = (unsigned long) ifd[idx].value_.v_short[0];
1043
0
            break;
1044
0
        case 1: /* BYTE */
1045
0
            pos = (unsigned long) ifd[idx].value_.v_byte[0];
1046
0
            break;
1047
0
        default:
1048
0
            assert(0);
1049
0
            break;
1050
0
    }
1051
1052
0
    return pos;
1053
0
}
1054
1055
unsigned long jxrc_alpha_bytecount(jxr_container_t container, int image)
1056
0
{
1057
0
    unsigned ifd_cnt;
1058
0
    struct ifd_table*ifd;
1059
0
    unsigned idx;
1060
0
    unsigned long pos;
1061
1062
0
    assert(image < container->image_count);
1063
1064
0
    ifd_cnt = container->table_cnt[image];
1065
0
    ifd = container->table[image];
1066
1067
0
    for (idx = 0 ; idx < ifd_cnt ; idx += 1) {
1068
0
        if (ifd[idx].tag == 0xbcc3)
1069
0
            break;
1070
0
    }
1071
1072
    
1073
0
    if (idx >= ifd_cnt) return 0; /* No alpha coded image */
1074
0
    if (ifd[idx].tag != 0xbcc3) return 0;
1075
0
    assert(ifd[idx].cnt == 1);
1076
1077
0
    switch (ifd[idx].type) {
1078
0
        case 4: /* ULONG */
1079
0
            pos = (unsigned long) ifd[idx].value_.v_long;
1080
0
            break;
1081
0
        case 3: /* USHORT */
1082
0
            pos = (unsigned long) ifd[idx].value_.v_short[0];
1083
0
            break;
1084
0
        case 1: /* BYTE */
1085
0
            pos = (unsigned long) ifd[idx].value_.v_byte[0];
1086
0
            break;
1087
0
        default:
1088
0
            assert(0);
1089
0
            break;
1090
0
    }
1091
1092
0
    return pos;
1093
0
}
1094
1095
unsigned char jxrc_image_band_presence(jxr_container_t container, int image)
1096
0
{
1097
0
    unsigned ifd_cnt;
1098
0
    struct ifd_table*ifd;
1099
0
    unsigned idx;
1100
1101
0
    assert(image < container->image_count);
1102
1103
0
    ifd_cnt = container->table_cnt[image];
1104
0
    ifd = container->table[image];
1105
1106
0
    for (idx = 0 ; idx < ifd_cnt ; idx += 1) {
1107
0
        if (ifd[idx].tag == 0xbcc4)
1108
0
            break;
1109
0
    }
1110
1111
    
1112
0
    if (idx >= ifd_cnt) return -1; 
1113
0
    if (ifd[idx].tag != 0xbcc4) return -1;
1114
0
    assert(ifd[idx].cnt == 1);
1115
0
    assert(ifd[idx].type == 1);
1116
1117
0
    return ifd[idx].value_.v_byte[0];
1118
0
}
1119
1120
unsigned char jxrc_alpha_band_presence(jxr_container_t container, int image)
1121
0
{
1122
0
    unsigned ifd_cnt;
1123
0
    struct ifd_table*ifd;
1124
0
    unsigned idx;
1125
1126
0
    assert(image < container->image_count);
1127
1128
0
    ifd_cnt = container->table_cnt[image];
1129
0
    ifd = container->table[image];
1130
1131
0
    for (idx = 0 ; idx < ifd_cnt ; idx += 1) {
1132
0
        if (ifd[idx].tag == 0xbcc5)
1133
0
            break;
1134
0
    }
1135
1136
    
1137
0
    if (idx >= ifd_cnt) return -1; /* tag is not present */
1138
0
    if (ifd[idx].tag != 0xbcc5) return -1;
1139
0
    assert(ifd[idx].cnt == 1);
1140
0
    assert(ifd[idx].type == 1);
1141
1142
0
    return ifd[idx].value_.v_byte[0];
1143
0
}
1144
1145
int jxrc_padding_data(jxr_container_t container, int image)
1146
0
{
1147
0
    unsigned ifd_cnt;
1148
0
    struct ifd_table*ifd;
1149
0
    unsigned idx;
1150
0
    unsigned char * data;
1151
0
    unsigned i;
1152
1153
0
    assert(image < container->image_count);
1154
1155
0
    ifd_cnt = container->table_cnt[image];
1156
0
    ifd = container->table[image];
1157
1158
0
    for (idx = 0 ; idx < ifd_cnt ; idx += 1) {
1159
0
        if (ifd[idx].tag == 0xea1c)
1160
0
            break;
1161
0
    }
1162
    
1163
0
    if (idx >= ifd_cnt) return -1; 
1164
0
    if (ifd[idx].tag != 0xea1c) return -1;
1165
0
    assert(ifd[idx].type == 7);
1166
0
    assert(ifd[idx].cnt > 1);
1167
1168
0
    if (ifd[idx].cnt <= 4)
1169
0
        data = (unsigned char *) ifd[idx].value_.v_sbyte;
1170
0
    else
1171
0
        data = (unsigned char *) ifd[idx].value_.p_sbyte;
1172
1173
0
    assert(data[0] == 0x1c);
1174
0
    assert(data[1] == 0xea);
1175
1176
0
    return 0;
1177
0
}
1178
1179
uint16_t bytes2_to_off(uint8_t*bp)
1180
0
{
1181
0
    return (bp[1]<<8) + (bp[0]);
1182
0
}
1183
1184
uint32_t bytes4_to_off(uint8_t*bp)
1185
0
{
1186
0
    return (bp[3]<<24) + (bp[2]<<16) + (bp[1]<<8) + (bp[0]);
1187
0
}
1188
1189
static int read_ifd(jxr_container_t container, FILE*fd, int image_number, uint32_t*ifd_next)
1190
0
{
1191
0
    unsigned char buf[16];
1192
0
    size_t rc;
1193
0
    int idx;
1194
0
    int ifd_tag_prev = 0;
1195
0
    int alpha_tag_check = 0;
1196
0
    uint32_t ifd_off;
1197
0
    struct ifd_table*cur;
1198
0
    uint16_t entry_count;
1199
1200
0
    *ifd_next = 0;
1201
1202
0
    rc = fread(buf, 1, 2, fd);
1203
0
    if (rc != 2) return -1;
1204
1205
0
    entry_count = (buf[1]<<8) + (buf[0]<<0);
1206
0
    container->table_cnt[image_number] = entry_count;
1207
1208
0
    cur = (struct ifd_table*)calloc(entry_count, sizeof(struct ifd_table));
1209
0
    assert(cur != 0);
1210
1211
0
    container->table[image_number] = cur;
1212
1213
    /* First read in the entire directory. Don't interpret the
1214
    types yet, just save the values as v_bytes. We will go
1215
    through the types later and interpret the values more
1216
    precisely. */
1217
0
    for (idx = 0 ; idx < entry_count ; idx += 1) {
1218
0
        uint16_t ifd_tag;
1219
0
        uint16_t ifd_type;
1220
0
        uint32_t ifd_cnt;
1221
1222
0
        rc = fread(buf, 1, 12, fd);
1223
0
        assert(rc == 12);
1224
1225
0
        ifd_tag = (buf[1]<<8) + (buf[0]<<0);
1226
0
        if (ifd_tag == 0xbcc2)
1227
0
            alpha_tag_check += 1;
1228
0
        if (ifd_tag == 0xbcc3)
1229
0
            alpha_tag_check += 2;
1230
0
        if (ifd_tag == 0xbcc5)
1231
0
            alpha_tag_check += 4;
1232
0
        ifd_type = (buf[3]<<8) + (buf[2]<<0);
1233
0
        if (ifd_type == 7)
1234
0
            assert (ifd_tag == 0x8773 || ifd_tag == 0xea1c);
1235
0
        ifd_cnt = (buf[7]<<24) + (buf[6]<<16) + (buf[5]<<8) + buf[4];
1236
1237
0
        assert(ifd_tag > ifd_tag_prev);
1238
0
        ifd_tag_prev = ifd_tag;
1239
1240
0
        cur[idx].tag = ifd_tag;
1241
0
        cur[idx].type = ifd_type;
1242
0
        cur[idx].cnt = ifd_cnt;
1243
        
1244
0
        cur[idx].value_.v_byte[0] = buf[8];
1245
0
        cur[idx].value_.v_byte[1] = buf[9];
1246
0
        cur[idx].value_.v_byte[2] = buf[10];
1247
0
        cur[idx].value_.v_byte[3] = buf[11];
1248
0
    }
1249
    /* verify alpha ifd tags appear only in allowed combinations */
1250
0
    assert(alpha_tag_check == 0 || alpha_tag_check == 3 || alpha_tag_check == 7);
1251
1252
0
    rc = fread(buf, 1, 4, fd);
1253
0
    assert(rc == 4);
1254
1255
    /* Now interpret the tag types/values for easy access later. */
1256
0
    for (idx = 0 ; idx < entry_count ; idx += 1) {
1257
0
        switch (cur[idx].type) {
1258
1259
0
        case 1: /* BYTE */
1260
0
        case 2: /* UTF8 */
1261
0
        case 6: /* SBYTE */
1262
0
        case 7: /* UNDEFINED */
1263
0
            DEBUG("Container %d: tag 0x%04x BYTE:", image_number, cur[idx].tag);
1264
0
            if (cur[idx].cnt > 4) {
1265
0
                ifd_off = bytes4_to_off(cur[idx].value_.v_byte);
1266
0
                assert((ifd_off & 1) == 0);
1267
0
                fseek(fd, ifd_off, SEEK_SET);
1268
0
                cur[idx].value_.p_byte = (uint8_t*)malloc(cur[idx].cnt);
1269
0
                fread(cur[idx].value_.p_byte, 1, cur[idx].cnt, fd);
1270
#if defined(DETAILED_DEBUG)
1271
                {
1272
                  int bb;
1273
                  for (bb = 0 ; bb < cur[idx].cnt ; bb += 1)
1274
                      DEBUG("%02x", cur[idx].value_.p_byte[bb]);
1275
                }
1276
#endif
1277
0
                if (cur[idx].type == 2) {
1278
0
                    int cc;
1279
0
                    for (cc = 1 ; cc < cur[idx].cnt ; cc += 1)
1280
0
                        assert((cur[idx].value_.p_byte[cc - 1] != 0) || (cur[idx].value_.p_byte[cc] != 0));
1281
0
                }
1282
0
            }
1283
0
            else {
1284
0
                if (cur[idx].type == 2) {
1285
0
                    int cc;
1286
0
                    for (cc = 1 ; cc < cur[idx].cnt ; cc += 1)
1287
0
                        assert((cur[idx].value_.v_byte[cc - 1] != 0) || (cur[idx].value_.v_byte[cc] != 0));
1288
0
                }
1289
0
            }
1290
            /* No action required to access individual bytes */
1291
0
            DEBUG("\n");
1292
0
            break;
1293
1294
0
        case 3: /* USHORT */
1295
0
        case 8: /* SSHORT */
1296
0
            if (cur[idx].cnt <= 2) {
1297
0
                cur[idx].value_.v_short[0] = bytes2_to_off(cur[idx].value_.v_byte + 0);
1298
0
                cur[idx].value_.v_short[1] = bytes2_to_off(cur[idx].value_.v_byte + 2);
1299
0
                DEBUG("Container %d: tag 0x%04x SHORT %u SHORT %u\n", image_number,
1300
0
                    cur[idx].tag, cur[idx].value_.v_short[0], cur[idx].value_.v_short[1]);
1301
0
            } else {
1302
0
                uint16_t cdx;
1303
1304
0
                ifd_off = bytes4_to_off(cur[idx].value_.v_byte);
1305
0
                assert((ifd_off & 1) == 0);
1306
0
                fseek(fd, ifd_off, SEEK_SET);
1307
0
                cur[idx].value_.p_short = (uint16_t*) calloc(cur[idx].cnt, sizeof(uint16_t));
1308
1309
0
                DEBUG("Container %d: tag 0x%04x SHORT\n", image_number,
1310
0
                    cur[idx].tag);
1311
0
                for (cdx = 0 ; cdx < cur[idx].cnt ; cdx += 1) {
1312
0
                    uint8_t buf[2];
1313
0
                    fread(buf, 1, 2, fd);
1314
0
                    cur[idx].value_.p_short[cdx] = bytes2_to_off(buf);
1315
0
                    DEBUG(" %u", cur[idx].value_.p_short[cdx]);
1316
0
                }
1317
0
                DEBUG("\n");
1318
0
            }
1319
0
            break;
1320
1321
0
        case 4: /* ULONG */
1322
0
        case 9: /* SLONG */
1323
0
        case 11: /* FLOAT */
1324
0
            if (cur[idx].cnt == 1) {
1325
0
                cur[idx].value_.v_long = bytes4_to_off(cur[idx].value_.v_byte);
1326
0
                DEBUG("Container %d: tag 0x%04x LONG %u\n", image_number,
1327
0
                    cur[idx].tag, cur[idx].value_.v_long);
1328
0
            } else {
1329
0
                uint32_t cdx;
1330
1331
0
                ifd_off = bytes4_to_off(cur[idx].value_.v_byte);
1332
0
                assert((ifd_off & 1) == 0);
1333
0
                fseek(fd, ifd_off, SEEK_SET);
1334
0
                cur[idx].value_.p_long = (uint32_t*) calloc(cur[idx].cnt, sizeof(uint32_t));
1335
1336
0
                DEBUG("Container %d: tag 0x%04x LONG\n", image_number,
1337
0
                    cur[idx].tag);
1338
0
                for (cdx = 0 ; cdx < cur[idx].cnt ; cdx += 1) {
1339
0
                    uint8_t buf[4];
1340
0
                    fread(buf, 1, 4, fd);
1341
0
                    cur[idx].value_.p_long[cdx] = bytes4_to_off(buf);
1342
0
                    DEBUG(" %u", cur[idx].value_.p_long[cdx]);
1343
0
                }
1344
0
                DEBUG("\n");
1345
0
            }
1346
0
            break;
1347
1348
0
        case 5: /* URATIONAL */
1349
0
        case 10: /* SRATIONAL */
1350
0
        case 12: /* DOUBLE */
1351
0
          {
1352
0
            uint64_t cdx;
1353
1354
            /* Always offset */
1355
0
            ifd_off = bytes4_to_off(cur[idx].value_.v_byte);
1356
0
            assert((ifd_off & 1) == 0);
1357
0
            fseek(fd, ifd_off, SEEK_SET);
1358
0
            cur[idx].value_.p_rational = (uint64_t*) calloc(cur[idx].cnt, sizeof(uint64_t));
1359
1360
0
            DEBUG("Container %d: tag 0x%04x LONG\n", image_number,
1361
0
                cur[idx].tag);
1362
0
            for (cdx = 0 ; cdx < cur[idx].cnt ; cdx += 1) {
1363
0
                uint8_t buf[4];
1364
0
                fread(buf, 1, 4, fd);
1365
0
                cur[idx].value_.p_long[2 * cdx + 0] = bytes4_to_off(buf);
1366
0
                fread(buf, 1, 4, fd);
1367
0
                cur[idx].value_.p_long[2 * cdx + 1] = bytes4_to_off(buf);
1368
0
                DEBUG(" %u", cur[idx].value_.p_rational[cdx]);
1369
0
            }
1370
0
            DEBUG("\n");
1371
0
          }
1372
0
            break;
1373
1374
0
        default:
1375
0
            DEBUG("Container %d: tag 0x%04x type=%u\n", image_number, cur[idx].tag, cur[idx].type);
1376
0
            break;
1377
0
        }
1378
0
    }
1379
1380
    /* Tell the caller about the next ifd. */
1381
0
    *ifd_next = (buf[3] << 24) + (buf[2]<<16) + (buf[1]<<8) + (buf[0]<<0);
1382
1383
0
    return 0;
1384
0
}
1385
1386
1387
/*
1388
* $Log: cr_parse.c,v $
1389
* Revision 1.11 2009/05/29 12:00:00 microsoft
1390
* Reference Software v1.6 updates.
1391
*
1392
* Revision 1.10 2009/04/13 12:00:00 microsoft
1393
* Reference Software v1.5 updates.
1394
*
1395
* Revision 1.9 2008/03/21 21:23:14 steve
1396
* Some debug dump of the container.
1397
*
1398
* Revision 1.8 2008/03/05 19:32:02 gus
1399
* *** empty log message ***
1400
*
1401
* Revision 1.7 2008/03/01 02:46:08 steve
1402
* Add support for JXR container.
1403
*
1404
* Revision 1.6 2008/02/28 18:50:31 steve
1405
* Portability fixes.
1406
*
1407
* Revision 1.5 2008/02/26 23:52:44 steve
1408
* Remove ident for MS compilers.
1409
*
1410
* Revision 1.4 2007/11/26 01:47:15 steve
1411
* Add copyright notices per MS request.
1412
*
1413
* Revision 1.3 2007/11/07 18:11:35 steve
1414
* Accept magic number version 0
1415
*
1416
* Revision 1.2 2007/07/30 23:09:57 steve
1417
* Interleave FLEXBITS within HP block.
1418
*
1419
* Revision 1.1 2007/06/06 17:19:12 steve
1420
* Introduce to CVS.
1421
*
1422
*/
1423