1 /* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- */
2 /* EXIFPROBE - TIFF/JPEG/EXIF image file probe */
3 /* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- */
4 /* Copyright (C) 2005 by Duane H. Hesser. All rights reserved. */
5 /* */
6 /* See the file LICENSE.EXIFPROBE for terms of use. */
7 /* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- */
8
9 #ifndef lint
10 static char *ModuleId = "@(#) $Id: jp2000.c,v 1.10 2005/07/24 19:54:04 alex Exp $";
11 #endif
12
13 /* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- */
14 /* JP2/Jpeg2000 routines */
15 /* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- */
16 /* The information coded here is derived from the public version of */
17 /* the Jpeg2000 specification (badly outdated) and from the jasper */
18 /* code at */
19 /* http://www.ece.uvic.ca/~mdadams/jasper/ */
20
21 /* Some items, such as the ipr, xml, uuid, and uinf boxes, are not */
22 /* exposed in the jasper implementation, and are implemented from the */
23 /* public version of the spec. A few test images containing xml and */
24 /* uuid boxes have been found; the rest are thoroughly untested. */
25
26 /* 64-bit addressing is not yet supported */
27 /* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- */
28
29 #include <stdio.h>
30 #include <string.h>
31 #include <time.h>
32 #include <math.h>
33 #include <ctype.h>
34
35 #include "defs.h"
36 #include "datadefs.h"
37 #include "summary.h"
38 #include "misc.h"
39 #include "tags.h"
40
41 #include "jp2.h"
42 #include "jp2_extern.h"
43 #include "jpegtags.h"
44 #include "jp2tags.h"
45 #include "extern.h"
46
47 struct jp2box *
read_jp2box(FILE * inptr,unsigned long offset)48 read_jp2box(FILE *inptr,unsigned long offset)
49 {
50 static struct jp2box box;
51 struct jp2box *newbox = NULL;
52
53 if(inptr)
54 {
55 box.boxoffset = offset;
56 box.lbox = read_ulong(inptr,TIFF_MOTOROLA,offset);
57 if(!feof(inptr) && !(ferror(inptr)))
58 {
59 box.tbox = read_ulong(inptr,TIFF_MOTOROLA,HERE);
60 if(!feof(inptr) && !(ferror(inptr)))
61 {
62 if(box.lbox == 1)
63 {
64 #if 0
65 box.boxlength = read_ulong64(inptr,TIFF_MOTOROLA,HERE);
66 box.dataoffset = 16;
67 #else
68 PUSHCOLOR(RED);
69 printf("%s: cannot read 64 bit sizes/offsets yet",Progname);
70 POPCOLOR();
71 newbox = NULL;
72 #endif
73 }
74 else
75 {
76 box.boxlength = box.lbox;
77 box.dataoffset = 8;
78 }
79 newbox = &box;
80 }
81 else
82 newbox = NULL;
83 }
84 else
85 newbox = NULL;
86 }
87 return(newbox);
88 }
89
90 /* Print the content of the JP2 file signature box iff allowed by */
91 /* print options. */
92
93 int
print_jp2_header(struct fileheader * fileheader,unsigned long section_id)94 print_jp2_header(struct fileheader *fileheader,unsigned long section_id)
95 {
96 struct jp2_header jp2header;
97 int status = -1;
98 int chpr = 0;
99
100 if(Print_options & section_id)
101 {
102 if(fileheader && (fileheader->probe_magic == PROBE_JP2MAGIC))
103 {
104 jp2header = fileheader->jp2_header;
105 if(jp2header.magic == PROBE_JP2MAGIC)
106 {
107 /* Ok, I'm convinced... */
108 print_jp2type(jp2header.type,0);
109 chpr += printf(" <%#lx> magic %#lx, length %lu",jp2header.type,
110 jp2header.magic,jp2header.length);
111 chpr = newline(chpr);
112 status = 0;
113 }
114 else
115 chpr += printf(" NOT A JP2 HEADER");
116 }
117 else
118 chpr += printf(" NOT A JP2 HEADER");
119 }
120 chpr = newline(chpr);
121 return(status);
122 }
123
124
125 /* Print a jp2 box identifier, with its length and offset to the box */
126 /* data, if SECTIONS are enabled in print options. */
127
128 void
print_jp2box(FILE * inptr,struct jp2box * box,int indent)129 print_jp2box(FILE *inptr,struct jp2box *box,int indent)
130 {
131 unsigned long boxlength = 0UL;
132 int chpr = 0;
133
134 if(box)
135 {
136 if(box->boxlength == 0UL)
137 box->boxlength = get_filesize(inptr) - box->boxoffset;
138 else
139 boxlength = box->boxlength;
140 if(PRINT_SECTION)
141 {
142 print_tag_address(SECTION,box->boxoffset,indent,"@");
143 print_jp2type(box->tbox,0);
144 chpr += printf(" <%#lx>",box->tbox);
145 chpr += printf(" length %lu",boxlength);
146 /* Indicate that this is lastbox */
147 if(box->boxlength == 0UL)
148 chpr += printf(" (0)");
149 chpr += printf(" data offset %lu",box->dataoffset);
150 }
151 }
152 chpr = newline(chpr);
153 }
154
155 int
list_jp2box(FILE * inptr,struct jp2box * box,char * parent_name,int indent,int donl)156 list_jp2box(FILE *inptr,struct jp2box *box,char *parent_name,int indent,int donl)
157 {
158 unsigned long boxlength = 0UL;
159 int chpr = 0;
160
161 if(box)
162 {
163 if(box->boxlength == 0UL)
164 boxlength = get_filesize(inptr) - box->boxoffset;
165 else
166 boxlength = box->boxlength;
167 if((LIST_MODE))
168 {
169 print_tag_address(ENTRY,box->boxoffset,indent,"@");
170 if((PRINT_TAGINFO))
171 {
172 if((PRINT_LONGNAMES))
173 printf("%s",parent_name);
174 print_jp2type(box->tbox,0);
175 }
176 if((PRINT_VALUE))
177 {
178 chpr += printf(" = @%lu:%-4lu",box->boxoffset,boxlength);
179 /* Indicate that this is lastbox */
180 if(box->boxlength == 0UL)
181 chpr += printf(":0");
182 }
183 }
184 }
185 if(donl)
186 chpr = newline(chpr);
187 return(chpr);
188 }
189
190 /* Report the type of a JP2 box. Types are normally printable ascii */
191 /* (stored in 4 byte unsigned integers), but this routine is prepared */
192 /* to print garbled 'types', which may indicate that the program has */
193 /* gone astray, or that the file is garbled. Unprintable bytes, */
194 /* including newlines and such, are printed in escaped octal */
195 /* notation. */
196
197 /* Box type names are enclosed in []. */
198
199 void
print_jp2type(unsigned long type,int atend)200 print_jp2type(unsigned long type,int atend)
201 {
202 int i;
203 char *p;
204 int chpr = 0;
205
206 p = (char *)&type + 3;
207
208 if(!(LIST_MODE))
209 {
210 putchar('[');
211 ++chpr;
212 }
213 /* 'atend' declares that the output marks the last byte of the */
214 /* box; this is indicated by prepending a '/' to the box name */
215 if(atend)
216 {
217 putchar('/');
218 ++chpr;
219 }
220 for(i = 0; i < 4; ++i,--p)
221 {
222 if(isascii(*p) && isprint(*p))
223 {
224 putchar(*p);
225 ++chpr;
226 }
227 else if(*p)
228 chpr += printf("\\%03u",*p & 0xff);
229 else
230 chpr += printf("\\0");
231 }
232 if(!(LIST_MODE))
233 {
234 putchar(']');
235 ++chpr;
236 }
237 setcharsprinted(chpr);
238 }
239
240 /* The top level JP2 processor. */
241
242 unsigned long
process_jp2(FILE * inptr,unsigned long offset,struct image_summary * summary_entry,char * parent_name,int indent)243 process_jp2(FILE *inptr,unsigned long offset,struct image_summary *summary_entry,
244 char *parent_name,int indent)
245 {
246 struct jp2box *box;
247 unsigned long max_offset = 0L;
248 unsigned long lastbox = 0L;
249 unsigned long dumplength;
250
251 while(!feof(inptr) && !lastbox)
252 {
253 box = read_jp2box(inptr,offset);
254 if(box)
255 {
256 /* This routine is currently called only from main(), */
257 /* where the summary_entry will already have been created */
258
259 /* nonetheless... */
260 if((summary_entry == NULL) || summary_entry->entry_lock)
261 summary_entry = new_summary_entry(summary_entry,0,IMGFMT_JPEG2000);
262 switch(box->tbox)
263 {
264 case JP2_FTYP:
265 max_offset = process_jp2_ftyp(inptr,box,summary_entry,indent);
266 break;
267 case JP2_XML:
268 max_offset = process_jp2_xml(inptr,box,indent);
269 break;
270 case JP2_JP2I:
271 max_offset = process_jp2_jp2i(inptr,box,indent);
272 break;
273 case JP2_JP2H:
274 max_offset = process_jp2_jp2h(inptr,box,summary_entry,indent);
275 break;
276 case JP2_UUID:
277 max_offset = process_jp2_uuid(inptr,box,summary_entry,indent);
278 break;
279 case JP2_JP2C:
280 if(box->boxlength == 0)
281 ++lastbox;
282 max_offset = process_jp2_jp2c(inptr,box,summary_entry,indent);
283 break;
284 case JP2_UINF:
285 max_offset = process_jp2_uinf(inptr,box,summary_entry,indent);
286 break;
287 case JP2_PRFL: /* apparently not in the final spec */
288 default:
289 if((box->boxlength == 0) || ateof(inptr))
290 ++lastbox;
291 if((LIST_MODE))
292 setcharsprinted(list_jp2box(inptr,box,"JP2.",indent,1));
293 else
294 print_jp2box(inptr,box,indent);
295 max_offset = box->boxoffset + box->boxlength;
296 if((PRINT_SECTION))
297 {
298 /* Dump unrecognized boxes. */
299 if(Max_undefined > 0)
300 {
301 if(Max_undefined == DUMPALL)
302 dumplength = box->boxlength;
303 else if(Max_undefined > box->boxlength)
304 dumplength = box->boxlength;
305 else
306 dumplength = Max_undefined;
307 }
308 else
309 {
310 /* Always dump a little of undefined */
311 /* boxes */
312 if(box->boxlength < 48)
313 dumplength = box->boxlength;
314 else
315 dumplength = 48;
316 }
317
318 (void)newline(0);
319 hexdump(inptr,box->boxoffset,dumplength,dumplength,
320 16,indent,SUBINDENT);
321 (void)newline(1);
322 }
323 if((PRINT_SECTION))
324 {
325 (void)newline(0);
326 print_tag_address(SECTION,max_offset - 1,indent,"@");
327 print_jp2type(box->tbox,1);
328 }
329 break;
330 }
331 (void)newline(0);
332 offset = max_offset;
333 if(ateof(inptr))
334 ++lastbox;
335 }
336 else
337 break;
338 }
339 return(max_offset);
340 }
341
342 unsigned long
process_jp2_ftyp(FILE * inptr,struct jp2box * box,struct image_summary * summary_entry,int indent)343 process_jp2_ftyp(FILE *inptr,struct jp2box *box,struct image_summary *summary_entry,
344 int indent)
345 {
346 unsigned long boxoffset,max_offset,dataoffset;
347 unsigned long boxlength;
348 unsigned long mjv,mnv,cl,ncl;
349 int compat = 0;
350 int chpr = 0;
351 int i;
352
353 if((LIST_MODE))
354 chpr = list_jp2box(inptr,box,"JP2.",indent,1);
355 else
356 print_jp2box(inptr,box,indent);
357 boxoffset = box->boxoffset;
358 boxlength = box->boxlength;
359
360 dataoffset = boxoffset + box->dataoffset;
361 max_offset = boxoffset + boxlength;
362
363
364 mjv = read_ulong(inptr,TIFF_MOTOROLA,dataoffset);
365 dataoffset += 4;
366 print_tag_address(ENTRY,dataoffset,indent + 8,"=");
367 if((PRINT_TAGINFO))
368 {
369 if((PRINT_LONGNAMES))
370 chpr += printf("JP2.ftyp.");
371 chpr += printf("MajorVersion");
372 }
373 if((PRINT_VALUE))
374 {
375 chpr += printf(" = %#-10lx = ",mjv);
376 print_jp2type(mjv,0);
377 if(mjv != JP2_BR)
378 printred( " (INVALID MAJOR VERSION");
379 }
380 chpr = newline(chpr);
381 print_tag_address(ENTRY,dataoffset,indent + 8,"=");
382 mnv = read_ulong(inptr,TIFF_MOTOROLA,dataoffset);
383 dataoffset += 4;
384 if((PRINT_TAGINFO))
385 {
386 if((PRINT_LONGNAMES))
387 chpr += printf("JP2.ftyp.");
388 chpr += printf("MinorVersion");
389 }
390 if((PRINT_VALUE))
391 {
392 chpr += printf(" = %#-10lx = ",mnv);
393 print_jp2type(mnv,0);
394 }
395 chpr = newline(chpr);
396 ncl = box->boxlength - box->dataoffset - 8;
397 ncl /= 4;
398 for(i = 0; i < ncl; ++i)
399 {
400 print_tag_address(ENTRY,dataoffset,indent + 8,"=");
401 cl = read_ulong(inptr,TIFF_MOTOROLA,dataoffset);
402 dataoffset += 4;
403 if((PRINT_TAGINFO))
404 {
405 if((PRINT_LONGNAMES))
406 chpr += printf("JP2.ftyp.");
407 chpr += printf("Compat");
408 }
409 if((PRINT_VALUE))
410 {
411 chpr += printf(" = %#-10lx = ",cl);
412 print_jp2type(cl,0);
413 }
414 chpr = newline(chpr);
415 if(cl == JP2_BR)
416 compat++;
417 }
418 if((PRINT_SECTION))
419 {
420 chpr = newline(chpr);
421 print_tag_address(SECTION,dataoffset - 1,indent,"@");
422 print_jp2type(box->tbox,1);
423 }
424 chpr = newline(chpr);
425 return(max_offset);
426 }
427
428 /* The xml box. The xml is printed if Print_options includes SECTION, */
429 /* but the text is not examined for information which might go in the */
430 /* image summary. Even though image information may be recorded in */
431 /* the xml, the information need not be correct or pertain to the */
432 /* current image (the original image may have been modified without */
433 /* updating the xml. */
434
435 unsigned long
process_jp2_xml(FILE * inptr,struct jp2box * box,int indent)436 process_jp2_xml(FILE *inptr,struct jp2box *box,int indent)
437 {
438 unsigned long boxoffset,max_offset,dataoffset;
439 unsigned long readsize;
440 unsigned long boxlength,size;
441 int chpr = 0;
442
443 print_jp2box(inptr,box,indent);
444 boxoffset = box->boxoffset;
445 boxlength = box->boxlength;
446
447 dataoffset = boxoffset + box->dataoffset;
448 max_offset = box->boxoffset + box->boxlength;
449 size = boxlength - 8;
450
451 if((PRINT_SECTION))
452 {
453 print_tag_address(VALUE,dataoffset,indent + 10,"=");
454 if((PRINT_VALUE))
455 {
456 if((inptr && (fseek(inptr,dataoffset,0)) != -1))
457 {
458 while(size > 0ULL)
459 {
460 if(size > READSIZE)
461 readsize = READSIZE;
462 else
463 readsize = size;
464 /* Print as ascii */
465 setcharsprinted(chpr);
466 print_ascii(inptr,readsize,dataoffset);
467 dataoffset += readsize;
468 size -= readsize;
469 }
470 }
471 }
472 chpr = newline(chpr);
473 print_tag_address(SECTION,dataoffset - 1,indent,"=");
474 print_jp2type(box->tbox,1);
475 }
476 else if((LIST_MODE))
477 chpr = list_jp2box(inptr,box,"JP2.",indent,1);
478 chpr = newline(chpr);
479 return(max_offset);
480 }
481
482
483 /* The "Intellectual Property Rights" box, which records information */
484 /* which may have nothing to do with intellect, property, or any */
485 /* logical concept of rights. */
486
487 unsigned long
process_jp2_jp2i(FILE * inptr,struct jp2box * box,int indent)488 process_jp2_jp2i(FILE *inptr,struct jp2box *box,int indent)
489 {
490 unsigned long boxoffset,max_offset,dataoffset;
491 unsigned long readsize;
492 unsigned long boxlength,size;
493 int chpr = 0;
494
495 print_jp2box(inptr,box,indent);
496 boxoffset = box->boxoffset;
497 boxlength = box->boxlength;
498
499 dataoffset = boxoffset + box->dataoffset;
500 max_offset = boxoffset + boxlength;
501
502 if((PRINT_SECTION))
503 {
504 print_tag_address(SECTION,dataoffset,indent + 8,"=");
505 size = boxlength - 8;
506 if((inptr && (fseek(inptr,dataoffset,0)) != -1))
507 {
508 while(size > 0ULL)
509 {
510 if(size > READSIZE)
511 readsize = READSIZE;
512 else
513 readsize = size;
514 /* Print as ascii... */
515 setcharsprinted(chpr);
516 print_ascii(inptr,readsize,dataoffset);
517 dataoffset += readsize;
518 size -= readsize;
519 }
520 }
521 chpr = newline(chpr);
522 print_tag_address(SECTION,dataoffset - 1,indent,"=");
523 print_jp2type(box->tbox,1);
524 }
525 else if((LIST_MODE))
526 chpr = list_jp2box(inptr,box,"JP2.",indent,1);
527 chpr = newline(chpr);
528 return(max_offset);
529 }
530
531 /* The header superbox; this box has lots of human-interest stuff */
532
533 unsigned long
process_jp2_jp2h(FILE * inptr,struct jp2box * box,struct image_summary * summary_entry,int indent)534 process_jp2_jp2h(FILE *inptr,struct jp2box *box,struct image_summary *summary_entry,
535 int indent)
536 {
537 unsigned long lastbox = 0L;
538 unsigned long boxoffset,max_offset,dataoffset,tbox;
539 unsigned long boxlength;
540 int chpr = 0;
541
542 if((LIST_MODE))
543 chpr = list_jp2box(inptr,box,"JP2.",indent,1);
544 else
545 print_jp2box(inptr,box,indent);
546 boxoffset = box->boxoffset;
547 boxlength = box->boxlength;
548 tbox = box->tbox;
549
550 dataoffset = boxoffset + box->dataoffset;
551 max_offset = boxoffset + boxlength;
552
553
554 while(!feof(inptr) && !lastbox && (dataoffset < max_offset))
555 {
556 box = read_jp2box(inptr,dataoffset);
557 if(box)
558 {
559 switch(box->tbox)
560 {
561 case JP2_ihdr:
562 dataoffset = process_jp2_ihdr(inptr,box,summary_entry,indent + SUBINDENT);
563 break;
564 case JP2_colr:
565 dataoffset = process_jp2_colr(inptr,box,indent + SUBINDENT);
566 break;
567 case JP2_res:
568 dataoffset = process_jp2_res(inptr,box,indent + SUBINDENT);
569 break;
570 case JP2_bpcc:
571 case JP2_pclr:
572 case JP2_cdef:
573 case JP2_resc: /* handled in process_jp2_res(). */
574 case JP2_resd: /* handled in process_jp2_res(). */
575 /* These fields are reported but not expanded */
576 print_jp2box(inptr,box,indent + SUBINDENT);
577 if(boxlength)
578 dataoffset += boxlength;
579 else
580 ++lastbox;
581 chpr = newline(chpr);
582 break;
583 default:
584 /* report the unknown box and try to continue. If */
585 /* the box is properly constructed, that may be */
586 /* possible; most likely this is garbled data. */
587 print_jp2box(inptr,box,indent + SUBINDENT);
588 if(ferror(inptr) || feof(inptr))
589 {
590 clearerr(inptr);
591 ++lastbox;
592 }
593 if(boxlength)
594 dataoffset += boxlength;
595 else
596 ++lastbox;
597 chpr = newline(chpr);
598 break;
599 }
600 }
601 }
602 if((PRINT_SECTION))
603 {
604 chpr = newline(chpr);
605 print_tag_address(SECTION,dataoffset - 1,indent,"@");
606 print_jp2type(tbox,1);
607 }
608 chpr = newline(chpr);
609 return(max_offset);
610 }
611
612 /* The ihdr box, within the jp2h box, wherein we find the image size. */
613
614 unsigned long
process_jp2_ihdr(FILE * inptr,struct jp2box * box,struct image_summary * summary_entry,int indent)615 process_jp2_ihdr(FILE *inptr,struct jp2box *box,struct image_summary *summary_entry,
616 int indent)
617 {
618 unsigned long boxoffset,max_offset,dataoffset;
619 unsigned long boxlength;
620 unsigned long imgheight = 0UL;
621 unsigned long imgwidth = 0UL;
622 unsigned short nc = 0;
623 unsigned short bpc = 0;
624 unsigned short comp = 0;
625 unsigned short hasUNK = 0;
626 unsigned short hasIPR = 0;
627 int chpr = 0;
628
629 if((LIST_MODE))
630 chpr = list_jp2box(inptr,box,"JP2.jp2h.",indent,1);
631 else
632 print_jp2box(inptr,box,indent);
633 boxoffset = box->boxoffset;
634 boxlength = box->boxlength;
635
636 dataoffset = boxoffset + box->dataoffset;
637 max_offset = boxoffset + boxlength;
638
639 imgheight = read_ulong(inptr,TIFF_MOTOROLA,dataoffset);
640 print_tag_address(ENTRY,dataoffset,indent + 8,"=");
641 if((PRINT_TAGINFO))
642 {
643 if((PRINT_LONGNAMES))
644 chpr += printf("JP2.jp2h.ihdr.");
645 chpr += printf("ImageHeight");
646 }
647 if((PRINT_VALUE))
648 chpr += printf(" = %lu",imgheight);
649 chpr = newline(chpr);
650 dataoffset += 4;
651
652 imgwidth = read_ulong(inptr,TIFF_MOTOROLA,dataoffset);
653 print_tag_address(ENTRY,dataoffset,indent + 8,"=");
654 if((PRINT_TAGINFO))
655 {
656 if((PRINT_LONGNAMES))
657 chpr += printf("JP2.jp2h.ihdr.");
658 chpr += printf("ImageWidth");
659 }
660 if((PRINT_VALUE))
661 chpr += printf(" = %lu",imgwidth);
662 chpr = newline(chpr);
663 dataoffset += 4;
664 if(summary_entry && (imgheight > 0) &&
665 (summary_entry->pixel_height < imgheight))
666 {
667 summary_entry->pixel_height = imgheight;
668 }
669 if(summary_entry && (imgwidth > 0) &&
670 (summary_entry->pixel_width < imgwidth))
671 {
672 summary_entry->pixel_width = imgwidth;
673 }
674
675 nc = read_ushort(inptr,TIFF_MOTOROLA,dataoffset);
676 print_tag_address(ENTRY,dataoffset,indent + 8,"=");
677 if((PRINT_TAGINFO))
678 {
679 if((PRINT_LONGNAMES))
680 chpr += printf("JP2.jp2h.ihdr.");
681 chpr += printf("NumberOfComponents");
682 }
683 if((PRINT_VALUE))
684 chpr += printf(" = %u",nc);
685 chpr = newline(chpr);
686 dataoffset += 2;
687
688 bpc = read_ubyte(inptr,dataoffset);
689 print_tag_address(ENTRY,dataoffset,indent + 8,"=");
690 if((PRINT_TAGINFO))
691 {
692 if((PRINT_LONGNAMES))
693 chpr += printf("JP2.jp2h.ihdr.");
694 chpr += printf("BitsPerComponent");
695 }
696 if((PRINT_VALUE))
697 chpr += printf(" = %u",bpc);
698 chpr = newline(chpr);
699 dataoffset++;
700
701 comp = read_ubyte(inptr,dataoffset);
702 print_tag_address(ENTRY,dataoffset,indent + 8,"=");
703 if((PRINT_TAGINFO))
704 {
705 if((PRINT_LONGNAMES))
706 chpr += printf("JP2.jp2h.ihdr.");
707 chpr += printf("Compression");
708 }
709 if((PRINT_VALUE))
710 chpr += printf(" = %u",comp);
711 chpr = newline(chpr);
712 /* This is always 7 according to spec, and tells us nothing; */
713 /* it will be over-written with the transform type from a COD */
714 /* segement, if one is found. I imagine that "extensions" to */
715 /* the spec will quickly overwhelm this. */
716 if((summary_entry) && (summary_entry->compression <= 0))
717 summary_entry->compression = comp;
718 dataoffset++;
719
720 hasUNK = read_ubyte(inptr,dataoffset);
721 print_tag_address(ENTRY,dataoffset,indent + 8,"=");
722 if((PRINT_TAGINFO))
723 {
724 if((PRINT_LONGNAMES))
725 chpr += printf("JP2.jp2h.ihdr.");
726 chpr += printf("Colorspace");
727 }
728 if((PRINT_VALUE))
729 chpr += printf(" = %#x = %sknown",hasUNK,hasUNK ? "un" : "");
730 chpr = newline(chpr);
731 dataoffset++;
732
733 hasIPR = read_ubyte(inptr,dataoffset);
734 print_tag_address(ENTRY,dataoffset,indent + 8,"=");
735 if((PRINT_TAGINFO))
736 {
737 if((PRINT_LONGNAMES))
738 chpr += printf("JP2.jp2h.ihdr.");
739 chpr += printf("IPRbox");
740 }
741 if((PRINT_VALUE))
742 chpr += printf(" = %#x = %s",hasIPR,hasIPR ? "yes" : "no");
743 chpr = newline(chpr);
744 dataoffset++;
745
746 if((PRINT_SECTION))
747 {
748 print_tag_address(SECTION,dataoffset - 1,indent,"@");
749 print_jp2type(box->tbox,1);
750 chpr = newline(chpr);
751 }
752 return(max_offset);
753 }
754
755 unsigned long
process_jp2_uuid(FILE * inptr,struct jp2box * box,struct image_summary * summary_entry,int indent)756 process_jp2_uuid(FILE *inptr,struct jp2box *box,struct image_summary *summary_entry,
757 int indent)
758 {
759 unsigned long boxoffset,max_offset,dataoffset;
760 unsigned long boxlength,dumplength;
761 unsigned long ifd_offset = 0UL;
762 unsigned short idbyte,byte;
763 struct fileheader *header = NULL;
764 int chpr = 0;
765 int i;
766
767 if((LIST_MODE))
768 chpr = list_jp2box(inptr,box,"JP2.",indent,0);
769 else
770 print_jp2box(inptr,box,indent);
771 boxoffset = box->boxoffset;
772 boxlength = box->boxlength;
773
774 dataoffset = boxoffset + box->dataoffset;
775 max_offset = boxoffset + boxlength;
776
777 idbyte = byte = read_ubyte(inptr,dataoffset);
778 print_tag_address(SECTION,dataoffset,indent + 4,"*");
779 if((LIST_MODE))
780 {
781 if((PRINT_VALUE))
782 chpr += printf(" # ID: ");
783 }
784 else
785 chpr += printf("ID: ");
786 if(!(LIST_MODE) || (PRINT_VALUE))
787 {
788 if(!feof(inptr) && !ferror(inptr))
789 {
790 chpr += printf("%02x",(unsigned int)byte & 0xff);
791 for(i = 1; i < 16; ++i)
792 {
793 byte = read_ubyte(inptr,HERE);
794 if(feof(inptr) || ferror(inptr))
795 break;
796 chpr += printf(",%02x",(unsigned int)byte & 0xff);
797 }
798 chpr = newline(chpr);
799 }
800 }
801 dataoffset += 16;
802
803 /* No idea what the 16 "ID" bytes mean, or how to track */
804 /* registered types through the OID register. For now, a leading */
805 /* byte of 0x5 seems to signal a TIFF IFD. Dump a little bit of */
806 /* anything else. Probably need to check more of the ID... */
807
808 /* ...ok, now I've seen *two* ids that introduce TIFF sections... */
809 if((idbyte != 5) && (idbyte != 0xb1))
810 {
811 if((PRINT_SECTION))
812 {
813 dumplength = max_offset - dataoffset;
814 if(dumplength > 48)
815 dumplength = 48;
816 chpr = newline(chpr);
817 hexdump(inptr,dataoffset,dumplength,dumplength,16,indent,SUBINDENT);
818 chpr = newline(1);
819 }
820 }
821
822 /* So far I've seen these with recognizable "magic" */
823 /* 96,a9,f1,f1,... MSIG - ??? what is this? */
824 /* 2c,4c,01,00,... 8BIM Adobe PhotoShop - should handle this... */
825 /* 05,37,cd,ab,... TIFF - this we can do... */
826 /* b1,4b,f8,bd.... also TIFF */
827 header = read_imageheader(inptr,dataoffset);
828 if(header && (header->probe_magic == PROBE_TIFFMAGIC))
829 {
830 if((PRINT_SECTION))
831 {
832 chpr = newline(chpr);
833 print_tag_address(SECTION,dataoffset,indent + 4,"@");
834 print_header(header,SECTION);
835 ifd_offset = read_ulong(inptr,header->file_marker,HERE);
836 chpr += printf(" ifd offset = %#lx/%lu",ifd_offset,ifd_offset);
837 chpr += printf(" (+ %lu = %#lx/%lu)",dataoffset,
838 dataoffset + ifd_offset,
839 dataoffset + ifd_offset);
840 chpr = newline(0);
841 }
842 dataoffset = process_tiff_ifd(inptr,header->file_marker,
843 8,dataoffset,max_offset,summary_entry,"JP2.uuid",
844 TIFF_IFD,0,-1,indent + 4);
845 }
846 dataoffset = boxoffset + boxlength;
847
848 if((PRINT_SECTION))
849 {
850 chpr = newline(0);
851 print_tag_address(SECTION,dataoffset - 1,indent,"@");
852 print_jp2type(box->tbox,1);
853 chpr = newline(chpr);
854 }
855 return(max_offset);
856 }
857
858 /* The uinf superbox, presumably containing a list of uuids and urls */
859 /* pointing to data to describe them. */
860
861 /* This is from the outdated public Jpeg2000 spec; jasper doesn't */
862 /* appear to handle it. Haven't seen one in the wild yet. */
863
864 unsigned long
process_jp2_uinf(FILE * inptr,struct jp2box * box,struct image_summary * summary_entry,int indent)865 process_jp2_uinf(FILE *inptr,struct jp2box *box,struct image_summary *summary_entry,
866 int indent)
867 {
868 unsigned long boxoffset,max_offset,dataoffset,tbox;
869 unsigned long boxlength;
870 int chpr = 0;
871
872 if((LIST_MODE))
873 chpr = list_jp2box(inptr,box,"JP2.",indent,1);
874 else
875 print_jp2box(inptr,box,indent);
876 boxoffset = box->boxoffset;
877 boxlength = box->boxlength;
878 tbox = box->tbox;
879
880 dataoffset = boxoffset + box->dataoffset;
881 max_offset = boxoffset + boxlength;
882
883 box = read_jp2box(inptr,dataoffset);
884 if(box)
885 {
886 if((box->tbox) == JP2_ulst)
887 dataoffset = process_jp2_ulst(inptr,box,indent);
888 else
889 {
890 print_jp2box(inptr,box,indent);
891 chpr += printf(" NOT a ULST box!");
892 dataoffset += box->boxlength;
893 }
894 box = read_jp2box(inptr,dataoffset);
895 if(box)
896 dataoffset = process_jp2_de(inptr,box,indent);
897 else
898 {
899 print_jp2box(inptr,box,indent);
900 chpr += printf(" NOT a DE box!");
901 dataoffset += box->boxlength;
902 }
903 }
904
905 if((PRINT_SECTION))
906 {
907 chpr = newline(chpr);
908 print_tag_address(SECTION,dataoffset - 1,indent,"@");
909 print_jp2type(box->tbox,1);
910 }
911 chpr = newline(chpr);
912 return(max_offset);
913 }
914
915 /* The uuid list (ulst) box of the uinf superbox. */
916
917 unsigned long
process_jp2_ulst(FILE * inptr,struct jp2box * box,int indent)918 process_jp2_ulst(FILE *inptr,struct jp2box *box,int indent)
919 {
920 unsigned long boxoffset,max_offset,dataoffset,tbox;
921 unsigned long boxlength;
922 unsigned short nuuid,byte;
923 int chpr = 0;
924 int i,j;
925
926 if((LIST_MODE))
927 chpr = list_jp2box(inptr,box,"JP2.uinf.",indent,1);
928 else
929 print_jp2box(inptr,box,indent);
930 boxoffset = box->boxoffset;
931 boxlength = box->boxlength;
932 tbox = box->tbox;
933
934 dataoffset = boxoffset + box->dataoffset;
935 max_offset = boxoffset + boxlength;
936
937 nuuid = read_ushort(inptr,TIFF_MOTOROLA,dataoffset);
938 print_tag_address(ENTRY,dataoffset,indent + 8,"=");
939 if((PRINT_TAGINFO))
940 {
941 if((PRINT_LONGNAMES))
942 chpr += printf("JP2.uinf.ulst.");
943 chpr += printf("NumberOfUuids");
944 }
945 if((PRINT_VALUE))
946 chpr += printf(" = %u",nuuid);
947 chpr = newline(chpr);
948 dataoffset += 2;
949
950 /* Print the uuid list, in hex */
951 for(i = 0; i < nuuid; ++i)
952 {
953 print_tag_address(SECTION|ENTRY,dataoffset,indent + 4,"*");
954 if((PRINT_TAGINFO))
955 {
956 if((PRINT_LONGNAMES))
957 chpr += printf("JP2.uinf.ulst.");
958 chpr += printf("ID%d = ",i);
959 }
960 if((PRINT_VALUE))
961 chpr += printf(" = ");
962 if(!feof(inptr) && !ferror(inptr))
963 {
964 for(j = 0; j < 16; ++i)
965 {
966 byte = read_ubyte(inptr,dataoffset++);
967 if(feof(inptr) || ferror(inptr))
968 break;
969 if((PRINT_VALUE))
970 chpr += printf(",%02x",(unsigned int)byte & 0xff);
971 }
972 }
973 else
974 break;
975 chpr = newline(chpr);
976 }
977 if((PRINT_SECTION))
978 {
979 chpr = newline(chpr);
980 print_tag_address(SECTION,dataoffset - 1,indent,"@");
981 print_jp2type(box->tbox,1);
982 }
983 chpr = newline(chpr);
984 return(max_offset);
985 }
986
987 /* The data entry URL box of the uinf superbox. */
988
989 unsigned long
process_jp2_de(FILE * inptr,struct jp2box * box,int indent)990 process_jp2_de(FILE *inptr,struct jp2box *box,int indent)
991 {
992 unsigned long boxoffset,max_offset,dataoffset,tbox;
993 unsigned long boxlength;
994 unsigned short vers;
995 unsigned long flag;
996 int chpr = 0;
997
998 if((LIST_MODE))
999 chpr = list_jp2box(inptr,box,"JP2.uinf.",indent,1);
1000 else
1001 print_jp2box(inptr,box,indent);
1002 boxoffset = box->boxoffset;
1003 boxlength = box->boxlength;
1004 tbox = box->tbox;
1005
1006 dataoffset = boxoffset + box->dataoffset;
1007 max_offset = boxoffset + boxlength;
1008
1009 vers = read_ubyte(inptr,dataoffset);
1010 print_tag_address(ENTRY,dataoffset,indent + 8,"=");
1011 if((PRINT_TAGINFO))
1012 {
1013 if((PRINT_LONGNAMES))
1014 chpr += printf("JP2.jp2h.uinf.de.");
1015 chpr += printf("Version");
1016 }
1017 if((PRINT_VALUE))
1018 chpr += printf(" = %u",vers);
1019 chpr = newline(chpr);
1020 dataoffset ++;
1021 flag = read_ulong(inptr,TIFF_MOTOROLA,dataoffset);
1022 flag = (flag >> 8) & 0xfff;
1023 print_tag_address(ENTRY,dataoffset,indent + 8,"=");
1024 if((PRINT_TAGINFO))
1025 {
1026 if((PRINT_LONGNAMES))
1027 chpr += printf("JP2.jp2h.uinf.de.");
1028 chpr += printf("flags");
1029 }
1030 if((PRINT_VALUE))
1031 chpr += printf(" = %lu",flag);
1032 chpr = newline(chpr);
1033 dataoffset += 3;
1034 print_tag_address(ENTRY,dataoffset,indent + 8,"=");
1035 if((PRINT_TAGINFO))
1036 {
1037 if((PRINT_LONGNAMES))
1038 chpr += printf("JP2.jp2h.uinf.de.");
1039 chpr += printf("Location");
1040 }
1041 if((PRINT_VALUE))
1042 {
1043 chpr += printf(" (length %lu) = ",max_offset - dataoffset);
1044 /* This should be UTF-8 ###%%% */
1045 setcharsprinted(chpr);
1046 print_ascii(inptr,max_offset - dataoffset,dataoffset);
1047 }
1048 if((PRINT_SECTION))
1049 {
1050 chpr = newline(chpr);
1051 print_tag_address(SECTION,dataoffset - 1,indent,"@");
1052 print_jp2type(tbox,1);
1053 }
1054 chpr = newline(chpr);
1055 return(max_offset);
1056 }
1057
1058 /* The colorspace (colr) of the jp2h superbox. */
1059
1060 unsigned long
process_jp2_colr(FILE * inptr,struct jp2box * box,int indent)1061 process_jp2_colr(FILE *inptr,struct jp2box *box,int indent)
1062 {
1063 unsigned long boxoffset,dataoffset;
1064 unsigned long boxlength,proflength;
1065 unsigned short meth = 0;
1066 unsigned short prec = 0;
1067 unsigned short approx = 0;
1068 unsigned short csenum = 0;
1069 int chpr = 0;
1070
1071 if((LIST_MODE))
1072 chpr = list_jp2box(inptr,box,"JP2.jp2h.",indent,1);
1073 else
1074 print_jp2box(inptr,box,indent);
1075 boxoffset = box->boxoffset;
1076 dataoffset = boxoffset + box->dataoffset;
1077 boxlength = box->boxlength;
1078
1079 meth = read_ubyte(inptr,dataoffset);
1080 print_tag_address(ENTRY,dataoffset,indent + 8,"=");
1081 if((PRINT_TAGINFO))
1082 {
1083 if((PRINT_LONGNAMES))
1084 chpr += printf("JP2.jp2h.colr.");
1085 chpr += printf("Method");
1086 }
1087 if((PRINT_VALUE))
1088 chpr += printf(" = %u",meth);
1089 chpr = newline(chpr);
1090 dataoffset ++;
1091
1092 prec = read_ubyte(inptr,dataoffset);
1093 print_tag_address(ENTRY,dataoffset,indent + 8,"=");
1094 if((PRINT_TAGINFO))
1095 {
1096 if((PRINT_LONGNAMES))
1097 chpr += printf("JP2.jp2h.colr.");
1098 chpr += printf("Precedence");
1099 }
1100 if((PRINT_VALUE))
1101 chpr += printf(" = %u",prec);
1102 chpr = newline(chpr);
1103 dataoffset ++;
1104
1105 approx = read_ubyte(inptr,dataoffset);
1106 print_tag_address(ENTRY,dataoffset,indent + 8,"=");
1107 if((PRINT_TAGINFO))
1108 {
1109 if((PRINT_LONGNAMES))
1110 chpr += printf("JP2.jp2h.colr.");
1111 chpr += printf("ColorSpaceAproximation");
1112 }
1113 if((PRINT_VALUE))
1114 chpr += printf(" = %u",approx);
1115 chpr = newline(chpr);
1116 dataoffset ++;
1117
1118 if(meth == 1)
1119 {
1120 csenum = read_ulong(inptr,TIFF_MOTOROLA,dataoffset);
1121 print_tag_address(ENTRY,dataoffset,indent + 8,"=");
1122 if((PRINT_TAGINFO))
1123 {
1124 if((PRINT_LONGNAMES))
1125 chpr += printf("JP2.jp2h.colr.");
1126 chpr += printf("EnumeratedColorSpace");
1127 }
1128 if((PRINT_VALUE))
1129 {
1130 chpr += printf(" = %u",csenum);
1131 switch(csenum)
1132 {
1133 case 16: chpr += printf(" = sRGB"); break;
1134 case 17: chpr += printf(" = greyscale"); break;
1135 default: chpr += printf(" = undefined"); break;
1136 }
1137 }
1138 chpr = newline(chpr);
1139 dataoffset += 4;
1140 }
1141 else
1142 {
1143 print_tag_address(ENTRY,dataoffset,indent + 8,"=");
1144 proflength = boxoffset + boxlength - dataoffset;
1145 if((PRINT_TAGINFO))
1146 {
1147 if((PRINT_LONGNAMES))
1148 chpr += printf("JP2.jp2h.colr.");
1149 chpr += printf("ICCProfileLength");
1150 }
1151 if((PRINT_VALUE))
1152 chpr += printf(" = %lu",proflength);
1153 chpr = newline(chpr);
1154 /* ###%%% display this as soon as we have some ICC routines */
1155 dataoffset = boxoffset + boxlength;
1156 }
1157 dataoffset = boxoffset + boxlength;
1158 if((PRINT_SECTION))
1159 {
1160 chpr = newline(chpr);
1161 print_tag_address(SECTION,dataoffset - 1,indent,"@");
1162 print_jp2type(box->tbox,1);
1163 }
1164 chpr = newline(chpr);
1165 return(dataoffset);
1166 }
1167
1168 /* The resolution superbox (res ). May contain one or two sub-boxes. */
1169 /* This routine handles the sub-boxes directly. */
1170
1171 unsigned long
process_jp2_res(FILE * inptr,struct jp2box * box,int indent)1172 process_jp2_res(FILE *inptr,struct jp2box *box,int indent)
1173 {
1174 unsigned long boxoffset,max_offset,resboxoffset;
1175 unsigned long dataoffset,resdataoffset;
1176 unsigned long resboxlength = 0UL;
1177 unsigned long boxlength;
1178 unsigned long tbox;
1179 unsigned short vrcn = 0;
1180 unsigned short vrcd = 0;
1181 unsigned short hrcn = 0;
1182 unsigned short hrcd = 0;
1183 unsigned short vrce = 0;
1184 unsigned short hrce = 0;
1185 double vrc = 0.0;
1186 double hrc = 0.0;
1187 char *rtype;
1188 char id;
1189 int chpr = 0;
1190
1191 if((LIST_MODE))
1192 chpr = list_jp2box(inptr,box,"JP2.jp2h.",indent,1);
1193 else
1194 print_jp2box(inptr,box,indent);
1195
1196 /* Save the parent box params. */
1197 boxoffset = box->boxoffset;
1198 dataoffset = boxoffset + box->dataoffset;
1199 boxlength = box->boxlength;
1200 tbox = box->tbox;
1201 max_offset = boxoffset + boxlength;
1202
1203 /* There may be one or two sub-boxes, resc, and resd. */
1204 boxlength -= box->dataoffset;
1205
1206 indent += SUBINDENT;
1207 if(boxlength >= 14ULL) /* sub-box must be this long */
1208 {
1209 box = read_jp2box(inptr,dataoffset);
1210
1211 if((PRINT_LONGNAMES))
1212 chpr = list_jp2box(inptr,box,"JP2.jp2h.res.",indent,1);
1213 else
1214 print_jp2box(inptr,box,indent + SUBINDENT);
1215 resboxoffset = box->boxoffset;
1216 resdataoffset = resboxoffset + box->dataoffset;
1217 resboxlength = box->boxlength;
1218 boxlength -= resboxlength;
1219
1220 id = box->tbox & 0xff;
1221 vrcn = read_ushort(inptr,TIFF_MOTOROLA,resdataoffset);
1222 if(!(LIST_MODE))
1223 {
1224 print_tag_address(ENTRY,resdataoffset,indent + 8,"=");
1225 if((PRINT_TAGINFO))
1226 chpr += printf("vr%cn",id);
1227 if((PRINT_VALUE))
1228 chpr += printf(" = %u",vrcn);
1229 }
1230 chpr = newline(chpr);
1231 resdataoffset += 2;
1232
1233 vrcd = read_ushort(inptr,TIFF_MOTOROLA,resdataoffset);
1234 if(!(LIST_MODE))
1235 {
1236 print_tag_address(ENTRY,resdataoffset,indent + 8,"=");
1237 if((PRINT_TAGINFO))
1238 chpr += printf("vr%cd",id);
1239 if((PRINT_VALUE))
1240 chpr += printf(" = %u",vrcd);
1241 }
1242 chpr = newline(chpr);
1243 resdataoffset += 2;
1244
1245 hrcn = read_ushort(inptr,TIFF_MOTOROLA,resdataoffset);
1246 if(!(LIST_MODE))
1247 {
1248 print_tag_address(ENTRY,resdataoffset,indent + 8,"=");
1249 if((PRINT_TAGINFO))
1250 chpr += printf("hr%cn",id);
1251 if((PRINT_VALUE))
1252 chpr += printf(" = %u",hrcn);
1253 }
1254 chpr = newline(chpr);
1255 resdataoffset += 2;
1256
1257 hrcd = read_ushort(inptr,TIFF_MOTOROLA,resdataoffset);
1258 if(!(LIST_MODE))
1259 {
1260 print_tag_address(ENTRY,resdataoffset,indent + 8,"=");
1261 if((PRINT_TAGINFO))
1262 chpr += printf("hr%cd",id);
1263 if((PRINT_VALUE))
1264 chpr += printf(" = %u",hrcd);
1265 }
1266 chpr = newline(chpr);
1267 resdataoffset += 2;
1268
1269 vrce = read_ubyte(inptr,resdataoffset);
1270 if(!(LIST_MODE))
1271 {
1272 print_tag_address(ENTRY,resdataoffset,indent + 8,"=");
1273 if((PRINT_TAGINFO))
1274 chpr += printf("vr%ce",id);
1275 if((PRINT_VALUE))
1276 chpr += printf(" = %u",vrce);
1277 }
1278 resdataoffset ++;
1279
1280 if(id == 'c')
1281 rtype = "Capture";
1282 else if(id == 'd')
1283 rtype = "Display";
1284 else
1285 rtype = "Illegitimate";
1286
1287 vrc = (double)vrcn * pow(10.0,(double)vrce) / (double)vrcd ;
1288 if((LIST_MODE))
1289 print_tag_address(ENTRY,HERE,indent + 8,"*");
1290 if((PRINT_TAGINFO))
1291 {
1292 if((LIST_MODE))
1293 {
1294 if((PRINT_LONGNAMES))
1295 {
1296 chpr += printf("JP2.jp2h.res.");
1297 print_jp2type(box->tbox,0);
1298 chpr += printf(".");
1299 }
1300 chpr += printf("Vertical%sResolution",rtype);
1301 }
1302 else
1303 chpr += printf(" ==> Vertical %s Resolution",rtype);
1304 }
1305 if((PRINT_VALUE))
1306 chpr += printf(" = %3.2f samples/meter",vrc);
1307 chpr = newline(chpr);
1308
1309 hrce = read_ubyte(inptr,resdataoffset);
1310 if(!(LIST_MODE))
1311 {
1312 print_tag_address(ENTRY,resdataoffset,indent + 8,"=");
1313 if((PRINT_TAGINFO))
1314 chpr += printf("hr%ce",id);
1315 if((PRINT_VALUE))
1316 chpr += printf(" = %u",hrce);
1317 }
1318 resdataoffset ++;
1319
1320 hrc = (double)hrcn * pow(10.0,(double)hrce) / (double)hrcd ;
1321 if((LIST_MODE))
1322 print_tag_address(ENTRY,HERE,indent + 8,"*");
1323 if((PRINT_TAGINFO))
1324 {
1325 if((LIST_MODE))
1326 {
1327 if((PRINT_LONGNAMES))
1328 {
1329 chpr += printf("JP2.jp2h.res.");
1330 print_jp2type(box->tbox,0);
1331 chpr += printf(".");
1332 }
1333 chpr += printf("Horizontal%sResolution",rtype);
1334 }
1335 else
1336 chpr += printf(" ==> Horizontal %s resolution",rtype);
1337 }
1338 if((PRINT_VALUE))
1339 chpr += printf(" = %3.2f samples/meter",vrc);
1340 chpr = newline(chpr);
1341 if((PRINT_SECTION))
1342 {
1343 print_tag_address(SECTION,resdataoffset - 1,indent + SUBINDENT,"=");
1344 print_jp2type(box->tbox,1);
1345 chpr = newline(chpr);
1346 }
1347 }
1348 chpr = newline(chpr);
1349 dataoffset += resboxlength;
1350
1351 /* Sometimes both sub-boxes are present; do it again. */
1352 if(boxlength >= 14ULL)
1353 {
1354 box = read_jp2box(inptr,dataoffset);
1355
1356 if((PRINT_LONGNAMES))
1357 chpr = list_jp2box(inptr,box,"JP2.jp2h.res.",indent,1);
1358 else
1359 print_jp2box(inptr,box,indent + SUBINDENT);
1360 resboxoffset = box->boxoffset;
1361 resdataoffset = resboxoffset + box->dataoffset;
1362 resboxlength = box->boxlength;
1363 boxlength -= resboxlength;
1364
1365 id = box->tbox & 0xff;
1366 vrcn = read_ushort(inptr,TIFF_MOTOROLA,resdataoffset);
1367 if(!(LIST_MODE))
1368 {
1369 print_tag_address(ENTRY,resdataoffset,indent + 8,"=");
1370 if((PRINT_TAGINFO))
1371 chpr += printf("vr%cn",id);
1372 if((PRINT_VALUE))
1373 chpr += printf(" = %u",vrcn);
1374 }
1375 chpr = newline(chpr);
1376 resdataoffset += 2;
1377
1378 vrcd = read_ushort(inptr,TIFF_MOTOROLA,resdataoffset);
1379 if(!(LIST_MODE))
1380 {
1381 print_tag_address(ENTRY,resdataoffset,indent + 8,"=");
1382 if((PRINT_TAGINFO))
1383 chpr += printf("vr%cd",id);
1384 if((PRINT_VALUE))
1385 chpr += printf(" = %u",vrcd);
1386 }
1387 chpr = newline(chpr);
1388 resdataoffset += 2;
1389
1390 hrcn = read_ushort(inptr,TIFF_MOTOROLA,resdataoffset);
1391 if(!(LIST_MODE))
1392 {
1393 print_tag_address(ENTRY,resdataoffset,indent + 8,"=");
1394 if((PRINT_TAGINFO))
1395 chpr += printf("hr%cn",id);
1396 if((PRINT_VALUE))
1397 chpr += printf(" = %u",hrcn);
1398 }
1399 chpr = newline(chpr);
1400 resdataoffset += 2;
1401
1402 hrcd = read_ushort(inptr,TIFF_MOTOROLA,resdataoffset);
1403 if(!(LIST_MODE))
1404 {
1405 print_tag_address(ENTRY,resdataoffset,indent + 8,"=");
1406 if((PRINT_TAGINFO))
1407 chpr += printf("hr%cd",id);
1408 if((PRINT_VALUE))
1409 chpr += printf(" = %u",hrcd);
1410 }
1411 chpr = newline(chpr);
1412 resdataoffset += 2;
1413
1414 vrce = read_ubyte(inptr,resdataoffset);
1415 if(!(LIST_MODE))
1416 {
1417 print_tag_address(ENTRY,resdataoffset,indent + 8,"=");
1418 if((PRINT_TAGINFO))
1419 chpr += printf("vr%ce",id);
1420 if((PRINT_VALUE))
1421 chpr += printf(" = %u",vrce);
1422 }
1423 resdataoffset ++;
1424
1425 if(id == 'c')
1426 rtype = "Capture";
1427 else if(id == 'd')
1428 rtype = "Display";
1429 else
1430 rtype = "Illegitimate";
1431
1432 vrc = (double)vrcn * pow(10.0,(double)vrce) / (double)vrcd ;
1433 if((PRINT_TAGINFO))
1434 {
1435 if((LIST_MODE))
1436 {
1437 if((PRINT_LONGNAMES))
1438 {
1439 chpr += printf("JP2.jp2h.res.");
1440 print_jp2type(box->tbox,0);
1441 chpr += printf(".");
1442 }
1443 chpr += printf("Vertical%sResolution",rtype);
1444 }
1445 else
1446 chpr += printf(" ==> Vertical %s Resolution",rtype);
1447 }
1448 if((PRINT_VALUE))
1449 chpr += printf(" = %3.2f samples/meter",vrc);
1450 chpr = newline(chpr);
1451
1452 hrce = read_ubyte(inptr,resdataoffset);
1453 if(!(LIST_MODE))
1454 {
1455 print_tag_address(ENTRY,resdataoffset,indent + 8,"=");
1456 if((PRINT_TAGINFO))
1457 chpr += printf("hr%ce",id);
1458 if((PRINT_VALUE))
1459 chpr += printf(" = %u",hrce);
1460 }
1461 resdataoffset ++;
1462
1463 hrc = (double)hrcn * pow(10.0,(double)hrce) / (double)hrcd ;
1464 if((PRINT_TAGINFO))
1465 {
1466 if((LIST_MODE))
1467 {
1468 if((PRINT_LONGNAMES))
1469 {
1470 chpr += printf("JP2.jp2h.res.");
1471 print_jp2type(box->tbox,0);
1472 chpr += printf(".");
1473 }
1474 chpr += printf("Horizontal%sResolution",rtype);
1475 }
1476 else
1477 chpr += printf(" ==> Horizontal %s resolution",rtype);
1478 }
1479 if((PRINT_VALUE))
1480 chpr += printf(" = %3.2f samples/meter",vrc);
1481 chpr = newline(chpr);
1482 if((PRINT_SECTION))
1483 {
1484 print_tag_address(SECTION,resdataoffset - 1,indent + SUBINDENT,"@");
1485 print_jp2type(box->tbox,1);
1486 chpr = newline(chpr);
1487 }
1488 }
1489 indent -= SUBINDENT;
1490
1491 if((PRINT_SECTION))
1492 {
1493 chpr = newline(chpr);
1494 print_tag_address(SECTION|ENTRY,max_offset - 1,indent,"=");
1495 print_jp2type(tbox,1);
1496 }
1497 chpr = newline(chpr);
1498 return(max_offset);
1499 }
1500
1501 /* Process the jp2 codestream box. */
1502
1503 unsigned long
process_jp2_jp2c(FILE * inptr,struct jp2box * box,struct image_summary * summary_entry,int indent)1504 process_jp2_jp2c(FILE *inptr,struct jp2box *box,struct image_summary *summary_entry,
1505 int indent)
1506 {
1507 unsigned long boxoffset,dataoffset;
1508 unsigned long boxlength;
1509 unsigned long tbox;
1510 int chpr = 0;
1511
1512 if((LIST_MODE))
1513 chpr = list_jp2box(inptr,box,"JP2.",indent,1);
1514 else
1515 print_jp2box(inptr,box,indent);
1516 boxoffset = box->boxoffset;
1517 dataoffset = boxoffset + box->dataoffset;
1518 boxlength = box->boxlength;
1519 tbox = box->tbox;
1520
1521 dataoffset = process_jpeg2000_codestream(inptr,dataoffset,boxlength,
1522 summary_entry,indent + 8);
1523 chpr = newline(chpr);
1524 if((PRINT_SECTION))
1525 {
1526 print_tag_address(SECTION,dataoffset - 1,indent,"@");
1527 print_jp2type(tbox,1);
1528 }
1529 chpr = newline(chpr);
1530 return(dataoffset);
1531 }
1532
1533 /* Process the jpeg2000 codestream itself */
1534
1535 unsigned long
process_jpeg2000_codestream(FILE * inptr,unsigned long marker_offset,unsigned long data_length,struct image_summary * summary_entry,int indent)1536 process_jpeg2000_codestream(FILE *inptr,unsigned long marker_offset,
1537 unsigned long data_length,
1538 struct image_summary *summary_entry,
1539 int indent)
1540 {
1541 unsigned long max_offset = 0L;
1542 unsigned long start_of_jp2c_data = marker_offset;
1543 unsigned long start_of_tile = 0;
1544 unsigned long tile_length = 0;
1545 unsigned short seg_length,tmp;
1546 unsigned short tilenum = 0;
1547 unsigned short part_index = 0;
1548 unsigned short nparts = 0;
1549 unsigned short regvalue = 0;
1550 unsigned short tag = 0;
1551 int chpr = 0;
1552 int tagindent,dataindent;
1553 char *name;
1554
1555 if(inptr)
1556 {
1557 PUSHCOLOR(JPEG_COLOR);
1558 tag = read_ushort(inptr,TIFF_MOTOROLA,marker_offset);
1559 tagindent = indent;
1560 while(tag != 0)
1561 {
1562 switch(tag)
1563 {
1564 case JP2C_SOC: /* Start of code stream */
1565 start_of_jp2c_data = marker_offset;
1566 if((summary_entry == NULL) || summary_entry->entry_lock)
1567 summary_entry = new_summary_entry(summary_entry,0,IMGFMT_JPEG2000);
1568 if(summary_entry)
1569 {
1570 if(summary_entry->length <= 0)
1571 summary_entry->length = data_length;
1572 if(summary_entry->offset <= 0)
1573 summary_entry->offset = start_of_jp2c_data;
1574 summary_entry->imageformat = IMGFMT_JPEG2000;
1575 summary_entry->entry_lock = lock_number(summary_entry);
1576 }
1577 name = jp2000tagname(tag);
1578 print_tag_address(SECTION|ENTRY,marker_offset,tagindent,"@");
1579 dataindent = charsprinted();
1580 if((LIST_MODE))
1581 {
1582 if((PRINT_TAGINFO))
1583 {
1584 if((PRINT_LONGNAMES))
1585 chpr += printf("JP2.jp2c.");
1586 chpr += printf("%s",name);
1587 }
1588 if((PRINT_VALUE))
1589 chpr += printf(" = @%lu",marker_offset);
1590 chpr = newline(chpr);
1591 }
1592 else
1593 chpr += printf("<%#x=%s> Start of codestream",tag,name);
1594 chpr = newline(chpr);
1595 marker_offset += 2;
1596 break;
1597 case JP2C_SOT: /* Start of tile-part */
1598 name = jp2000tagname(tag);
1599 start_of_tile = marker_offset;
1600 seg_length = read_ushort(inptr,TIFF_MOTOROLA,marker_offset + 2);
1601 print_tag_address(SEGMENT,marker_offset,tagindent,"@");
1602 if((PRINT_SEGMENT) && (PRINT_SECTION))
1603 {
1604 if((LIST_MODE))
1605 {
1606 if((PRINT_TAGINFO))
1607 {
1608 if((PRINT_LONGNAMES))
1609 chpr += printf("JP2.jp2c.");
1610 chpr += printf("%s",name);
1611 }
1612 if((PRINT_VALUE))
1613 chpr += printf(" = @%lu:%u",marker_offset,seg_length);
1614 chpr = newline(chpr);
1615 }
1616 else
1617 chpr += printf("<%#x=%s> length %u",tag,name,seg_length);
1618 }
1619
1620 tilenum = read_ushort(inptr,TIFF_MOTOROLA,marker_offset + 4);
1621 if((PRINT_SEGMENT) && (PRINT_ENTRY) && !(LIST_MODE))
1622 chpr += printf(" tile number %u",tilenum);
1623 tile_length = read_ulong(inptr,TIFF_MOTOROLA,marker_offset + 6);
1624 if((PRINT_SEGMENT) && (PRINT_ENTRY) && !(LIST_MODE))
1625 chpr += printf(" tile_length = %lu",tile_length);
1626 part_index = read_ubyte(inptr,HERE);
1627 if((PRINT_SEGMENT) && (PRINT_ENTRY) && !(LIST_MODE))
1628 chpr += printf(" tile index = %u",part_index);
1629 nparts = read_ubyte(inptr,HERE);
1630 if((PRINT_SEGMENT) && (PRINT_ENTRY) && !(LIST_MODE))
1631 chpr += printf(" [of %u tile parts]",nparts);
1632 chpr = newline(chpr);
1633
1634 if(ferror(inptr))
1635 {
1636 tag = 0;
1637 continue;
1638 }
1639 marker_offset += seg_length + 2;
1640 break;
1641 case JP2C_EPH: /* End of packet header */
1642 case JP2C_SOD: /* Start of data */
1643 name = jp2000tagname(tag);
1644 if((PRINT_SEGMENT) && (PRINT_SECTION))
1645 {
1646 print_tag_address(SEGMENT,marker_offset,tagindent,"@");
1647 if((LIST_MODE))
1648 {
1649 if((PRINT_TAGINFO))
1650 {
1651 if((PRINT_LONGNAMES))
1652 chpr += printf("JP2.jp2c.");
1653 chpr += printf("%s",name);
1654 }
1655 if((PRINT_VALUE))
1656 chpr += printf(" = @%lu",marker_offset);
1657 chpr = newline(chpr);
1658 }
1659 else
1660 chpr += printf("<%#x=%s>",tag,name);
1661 chpr = newline(chpr);
1662 }
1663 marker_offset = start_of_tile + tile_length;
1664 break;
1665 case JP2C_COM:
1666 name = jp2000tagname(tag);
1667 print_tag_address(SECTION|ENTRY,marker_offset,tagindent,"@");
1668 if((LIST_MODE))
1669 {
1670 if((PRINT_TAGINFO))
1671 {
1672 if((PRINT_LONGNAMES))
1673 chpr += printf("JP2.jpc.");
1674 chpr += printf("Comment");
1675 }
1676 }
1677 else
1678 chpr += printf("<%#x=%s>",tag,name);
1679 seg_length = read_ushort(inptr,TIFF_MOTOROLA,marker_offset + 2);
1680 tmp = read_ushort(inptr,TIFF_MOTOROLA,marker_offset + 4);
1681
1682 if(ferror(inptr) == 0)
1683 {
1684 if(!(LIST_MODE))
1685 chpr += printf(" length %u, reg %u",seg_length,
1686 regvalue);
1687 if((PRINT_VALUE))
1688 {
1689 chpr += printf(" = ");
1690 setcharsprinted(chpr);
1691 (void)print_ascii(inptr,seg_length - 6,marker_offset + 6);
1692 }
1693 chpr = newline(chpr);
1694 marker_offset += seg_length + 2;
1695 }
1696 else
1697 {
1698 tag = 0;
1699 clearerr(inptr);
1700 }
1701 break;
1702 case JP2C_SIZ:
1703 marker_offset = process_jpc_siz(inptr,marker_offset,tag,
1704 summary_entry,tagindent);
1705 break;
1706 case JP2C_COD:
1707 marker_offset = process_jpc_cod(inptr,marker_offset,tag,
1708 summary_entry,tagindent);
1709 break;
1710 case JP2C_QCD:
1711 marker_offset = process_jpc_qcd(inptr,marker_offset,tag,
1712 summary_entry,tagindent);
1713 break;
1714 case JP2C_EOC:
1715 name = jp2000tagname(tag);
1716 print_tag_address(SECTION|ENTRY,marker_offset,tagindent,"@");
1717 if((LIST_MODE))
1718 {
1719 if((PRINT_TAGINFO))
1720 {
1721 if((PRINT_LONGNAMES))
1722 chpr += printf("JP2.jp2c.");
1723 chpr += printf("%s",name);
1724 }
1725 if((PRINT_VALUE))
1726 chpr += printf(" = @%lu",marker_offset);
1727 chpr = newline(chpr);
1728 }
1729 else
1730 chpr += printf("<%#x=%s> End of codestream",tag,name);
1731 chpr = newline(chpr);
1732 tag = 0;
1733 continue;
1734 break;
1735 /* All of these fall through to the default */
1736 case JP2C_CRG:
1737 case JP2C_SOP:
1738 case JP2C_POC:
1739 case JP2C_QCC:
1740 case JP2C_TLM: /* Tile-part lengths, main header */
1741 case JP2C_PLM: /* Packet length, main header */
1742 case JP2C_PLT: /* Packet length, tile-part header */
1743 case JP2C_PPM: /* Packed packet headers; main header */
1744 case JP2C_PPT: /* Packed packet headers; part header */
1745 default:
1746 name = jp2000tagname(tag);
1747 print_tag_address(SEGMENT,marker_offset,tagindent,"@");
1748 /* These are exclude from LIST mode unless */
1749 /* SEGMENTS are explicitly enabled */
1750 if((PRINT_SEGMENT))
1751 {
1752 if((LIST_MODE))
1753 {
1754 if((PRINT_TAGINFO))
1755 {
1756 if((PRINT_LONGNAMES))
1757 chpr += printf("JP2.jp2c.");
1758 chpr += printf("%s",name);
1759 }
1760 if((PRINT_VALUE))
1761 chpr += printf(" = @%lu",marker_offset);
1762 }
1763 else
1764 chpr += printf("<%#x=%s>",tag,name);
1765 }
1766 if((tag & 0xff00) != 0xff00)
1767 {
1768 tag = 0;
1769 continue;
1770 }
1771 seg_length = read_ushort(inptr,TIFF_MOTOROLA,marker_offset + 2);
1772 if(ferror(inptr) == 0)
1773 {
1774 if((PRINT_SEGMENT))
1775 {
1776 if((LIST_MODE))
1777 chpr += printf(":%u",seg_length);
1778 else
1779 chpr += printf(" length %u",seg_length);
1780 chpr = newline(chpr);
1781 }
1782 marker_offset += seg_length + 2;
1783 }
1784 else
1785 {
1786 tag = 0;
1787 clearerr(inptr);
1788 }
1789 break;
1790 }
1791 tag = read_ushort(inptr,TIFF_MOTOROLA,marker_offset);
1792 if(ferror(inptr) == 0)
1793 {
1794 max_offset = ftell(inptr);
1795 }
1796 else
1797 {
1798 tag = 0;
1799 clearerr(inptr);
1800 }
1801 }
1802 POPCOLOR();
1803 if((summary_entry) && (summary_entry->length <= 0))
1804 summary_entry->length = max_offset - start_of_jp2c_data;
1805 }
1806 setcharsprinted(chpr);
1807 return(max_offset);
1808 }
1809
1810 /* SIZ header. Prints everything. */
1811
1812 unsigned long
process_jpc_siz(FILE * inptr,unsigned long marker_offset,unsigned short tag,struct image_summary * summary_entry,int indent)1813 process_jpc_siz(FILE *inptr,unsigned long marker_offset,unsigned short tag,
1814 struct image_summary *summary_entry,
1815 int indent)
1816 {
1817 unsigned long max_offset;
1818 unsigned long gridwidth;
1819 unsigned long gridheight;
1820 unsigned long Ximgoffset;
1821 unsigned long Yimgoffset;
1822 unsigned long tilewidth;
1823 unsigned long tileheight;
1824 unsigned long Xtileoffset;
1825 unsigned long Ytileoffset;
1826 unsigned short seg_length;
1827 unsigned short caps;
1828 unsigned short ncomps;
1829 unsigned short precision;
1830 unsigned short hsep;
1831 unsigned short vsep;
1832 int chpr = 0;
1833 int i;
1834 char *name,*uns;
1835
1836 name = jp2000tagname(tag);
1837 seg_length = read_ushort(inptr,TIFF_MOTOROLA,marker_offset + 2);
1838 print_tag_address(SECTION|ENTRY,marker_offset,indent,"@");
1839
1840 if((LIST_MODE))
1841 {
1842 if((PRINT_TAGINFO))
1843 {
1844 if((PRINT_LONGNAMES))
1845 chpr += printf("JP2.jp2c.");
1846 chpr += printf("%s",name);
1847 }
1848 if((PRINT_VALUE))
1849 chpr += printf(" = @%lu:%u",marker_offset,seg_length + 2);
1850 }
1851 else
1852 chpr += printf("<%#x=%s> length %u",tag,name,seg_length);
1853 max_offset = marker_offset + seg_length + 2;
1854 marker_offset += 4;
1855
1856 caps = read_ushort(inptr,TIFF_MOTOROLA,marker_offset);
1857 chpr = newline(chpr);
1858 print_tag_address(ENTRY,marker_offset,indent + 8,"=");
1859 if((PRINT_TAGINFO))
1860 {
1861 if((PRINT_LONGNAMES))
1862 chpr += printf("JP2.jp2c.siz.");
1863 chpr += printf("Capabilities");
1864 }
1865 if((PRINT_VALUE))
1866 chpr += printf(" = %u",caps);
1867 marker_offset += 2;
1868 gridwidth = read_ulong(inptr,TIFF_MOTOROLA,marker_offset);
1869 chpr = newline(chpr);
1870 print_tag_address(ENTRY,marker_offset,indent + 8,"=");
1871 if((PRINT_TAGINFO))
1872 {
1873 if((PRINT_LONGNAMES))
1874 chpr += printf("JP2.jp2c.siz.");
1875 chpr += printf("GridWidth");
1876 }
1877 if((PRINT_VALUE))
1878 chpr += printf(" = %lu",gridwidth);
1879 marker_offset += 4;
1880 gridheight = read_ulong(inptr,TIFF_MOTOROLA,marker_offset);
1881 chpr = newline(chpr);
1882 print_tag_address(ENTRY,marker_offset,indent + 8,"=");
1883 if((PRINT_TAGINFO))
1884 {
1885 if((PRINT_LONGNAMES))
1886 chpr += printf("JP2.jp2c.siz.");
1887 chpr += printf("GridHeight");
1888 }
1889 if((PRINT_VALUE))
1890 chpr += printf(" = %lu",gridheight);
1891 marker_offset += 4;
1892 Ximgoffset = read_ulong(inptr,TIFF_MOTOROLA,marker_offset);
1893 chpr = newline(chpr);
1894 print_tag_address(ENTRY,marker_offset,indent + 8,"=");
1895 if((PRINT_TAGINFO))
1896 {
1897 if((PRINT_LONGNAMES))
1898 chpr += printf("JP2.jp2c.siz.");
1899 chpr += printf("XImageOffset");
1900 }
1901 if((PRINT_VALUE))
1902 chpr += printf(" = %lu",Ximgoffset);
1903
1904 /* Image height and width are normally taken from the ihdr box; */
1905 /* if this is a bare codestream encapsulated in e.g. a TIFF file, */
1906 /* compute image size from grid size and offset */
1907 if(summary_entry && (summary_entry->pixel_width <= 0) &&
1908 (gridwidth > Ximgoffset))
1909 {
1910 summary_entry->pixel_width = gridwidth - Ximgoffset;
1911 }
1912
1913 marker_offset += 4;
1914 Yimgoffset = read_ulong(inptr,TIFF_MOTOROLA,marker_offset);
1915 chpr = newline(chpr);
1916 print_tag_address(ENTRY,marker_offset,indent + 8,"=");
1917 if((PRINT_TAGINFO))
1918 {
1919 if((PRINT_LONGNAMES))
1920 chpr += printf("JP2.jp2c.siz.");
1921 chpr += printf("YImageOffset");
1922 }
1923 if((PRINT_VALUE))
1924 chpr += printf(" = %lu",Yimgoffset);
1925
1926 /* Image height and width are normally taken from the ihdr box; */
1927 /* if this is a bare codestream encapsulated in e.g. a TIFF file, */
1928 /* compute image size from grid size and offset */
1929 if(summary_entry && (summary_entry->pixel_height <= 0) &&
1930 (gridheight > Yimgoffset))
1931 {
1932 summary_entry->pixel_height = gridheight - Yimgoffset;
1933 }
1934
1935 marker_offset += 4;
1936 tilewidth = read_ulong(inptr,TIFF_MOTOROLA,marker_offset);
1937 chpr = newline(chpr);
1938 print_tag_address(ENTRY,marker_offset,indent + 8,"=");
1939 if((PRINT_TAGINFO))
1940 {
1941 if((PRINT_LONGNAMES))
1942 chpr += printf("JP2.jp2c.siz.");
1943 chpr += printf("TileWidth");
1944 }
1945 if((PRINT_VALUE))
1946 chpr += printf(" = %lu",tilewidth);
1947 marker_offset += 4;
1948 tileheight = read_ulong(inptr,TIFF_MOTOROLA,marker_offset);
1949 chpr = newline(chpr);
1950 print_tag_address(ENTRY,marker_offset,indent + 8,"=");
1951 if((PRINT_TAGINFO))
1952 {
1953 if((PRINT_LONGNAMES))
1954 chpr += printf("JP2.jp2c.siz.");
1955 chpr += printf("TileHeight");
1956 }
1957 if((PRINT_VALUE))
1958 chpr += printf(" = %lu",tileheight);
1959 marker_offset += 4;
1960 Xtileoffset = read_ulong(inptr,TIFF_MOTOROLA,marker_offset);
1961 chpr = newline(chpr);
1962 print_tag_address(ENTRY,marker_offset,indent + 8,"=");
1963 if((PRINT_TAGINFO))
1964 {
1965 if((PRINT_LONGNAMES))
1966 chpr += printf("JP2.jp2c.siz.");
1967 chpr += printf("Xtileoffset");
1968 }
1969 if((PRINT_VALUE))
1970 chpr += printf(" = %lu",Xtileoffset);
1971 marker_offset += 4;
1972 Ytileoffset = read_ulong(inptr,TIFF_MOTOROLA,marker_offset);
1973 chpr = newline(chpr);
1974 print_tag_address(ENTRY,marker_offset,indent + 8,"=");
1975 if((PRINT_TAGINFO))
1976 {
1977 if((PRINT_LONGNAMES))
1978 chpr += printf("JP2.jp2c.siz.");
1979 chpr += printf("Ytileoffset");
1980 }
1981 if((PRINT_VALUE))
1982 chpr += printf(" = %lu",Ytileoffset);
1983 marker_offset += 4;
1984 ncomps = read_ushort(inptr,TIFF_MOTOROLA,marker_offset);
1985 if(summary_entry)
1986 summary_entry->spp = ncomps;
1987 chpr = newline(chpr);
1988 print_tag_address(ENTRY,marker_offset,indent + 8,"=");
1989 if((PRINT_TAGINFO))
1990 {
1991 if((PRINT_LONGNAMES))
1992 chpr += printf("JP2.jp2c.siz.");
1993 chpr += printf("NumberOfComponents");
1994 }
1995 if((PRINT_VALUE))
1996 chpr += printf(" = %u",ncomps);
1997 marker_offset += 2;
1998 for(i = 0; i < ncomps; ++i)
1999 {
2000 precision = read_ubyte(inptr,marker_offset);
2001 if(summary_entry)
2002 summary_entry->bps[i] = precision;
2003 chpr = newline(chpr);
2004 if(precision & 0x80)
2005 uns = NULLSTRING;
2006 else
2007 uns = "un";
2008 print_tag_address(ENTRY,marker_offset,indent + 8,"=");
2009 if((PRINT_TAGINFO))
2010 {
2011 if((PRINT_LONGNAMES))
2012 chpr += printf("JP2.jp2c.siz.");
2013 chpr += printf("Component%dPrecision",i);
2014 }
2015 if((PRINT_VALUE))
2016 chpr += printf(" = %#x = %u bits %ssigned",precision,
2017 (precision & 0x7f) + 1,uns);
2018 marker_offset++;
2019 /* ###%%% print these as separate lines? */
2020 hsep = read_ubyte(inptr,marker_offset);
2021 if((PRINT_SEGMENT) && (PRINT_VALUE) && !(LIST_MODE))
2022 chpr += printf(", hsep = %u",hsep);
2023 marker_offset++;
2024 vsep = read_ubyte(inptr,marker_offset);
2025 if((PRINT_SEGMENT) && (PRINT_VALUE) && !(LIST_MODE))
2026 chpr += printf(", vsep = %u",vsep);
2027 marker_offset++;
2028 }
2029 if(!(LIST_MODE))
2030 {
2031 chpr = newline(chpr);
2032 print_tag_address(SECTION|ENTRY,marker_offset - 1,indent,"@");
2033 chpr += printf("</%#x=%s> ",tag,name);
2034 }
2035 if(marker_offset > max_offset)
2036 printred(" READ PAST END OF BOX");
2037 chpr = newline(chpr);
2038 return(max_offset);
2039 }
2040
2041
2042 /* Coding style header. Prints pretty much everything */
2043 /* The public spec is way out of date and utterly wrong on this one; */
2044 /* this is from jasper. */
2045
2046 unsigned long
process_jpc_cod(FILE * inptr,unsigned long marker_offset,unsigned short tag,struct image_summary * summary_entry,int indent)2047 process_jpc_cod(FILE *inptr,unsigned long marker_offset,unsigned short tag,
2048 struct image_summary *summary_entry,
2049 int indent)
2050 {
2051 unsigned long max_offset;
2052 unsigned short seg_length;
2053 unsigned short cstyle;
2054 unsigned short decomp;
2055 unsigned short progorder;
2056 unsigned short nlayers;
2057 unsigned short cbw;
2058 unsigned short cbh;
2059 unsigned short cbstyle;
2060 unsigned short transform;
2061 unsigned short qmfbid;
2062 unsigned short part_wh;
2063 char *name;
2064 int chpr = 0;
2065 int i;
2066
2067 name = jp2000tagname(tag);
2068 seg_length = read_ushort(inptr,TIFF_MOTOROLA,marker_offset + 2);
2069 print_tag_address(SECTION|ENTRY,marker_offset,indent,"@");
2070 if((LIST_MODE))
2071 {
2072 if((PRINT_TAGINFO))
2073 {
2074 if((PRINT_LONGNAMES))
2075 chpr += printf("JP2.jp2c.");
2076 chpr += printf("%s",name);
2077 }
2078 if((PRINT_VALUE))
2079 chpr += printf(" = @%lu:%u",marker_offset,seg_length + 2);
2080 }
2081 else
2082 chpr += printf("<%#x=%s> length %u",tag,name,seg_length);
2083 max_offset = marker_offset + seg_length + 2;
2084 marker_offset += 4;
2085
2086 cstyle = read_ubyte(inptr,marker_offset);
2087 chpr = newline(chpr);
2088 print_tag_address(ENTRY,marker_offset,indent + 8,"=");
2089 if((PRINT_TAGINFO))
2090 {
2091 if((PRINT_LONGNAMES))
2092 chpr += printf("JP2.jp2c.cod.");
2093 chpr += printf("codingStyle");
2094 }
2095 if((PRINT_VALUE))
2096 {
2097 chpr += printf(" = %#x",cstyle & 0xff);
2098 chpr += printf(" = entropy coder with");
2099 if((cstyle & 1) == 0)
2100 chpr += printf("out");
2101 chpr += printf(" partitions,");
2102 if(cstyle & 2)
2103 chpr += printf(" with SOP markers and");
2104 else
2105 chpr += printf(" without SOP markers and");
2106 if(cstyle & 4)
2107 chpr += printf(" with EPH markers");
2108 else
2109 chpr += printf(" without EPH markers");
2110 }
2111 marker_offset++;
2112 progorder = read_ubyte(inptr,marker_offset);
2113 chpr = newline(chpr);
2114 print_tag_address(ENTRY,marker_offset,indent + 8,"=");
2115 if((PRINT_TAGINFO))
2116 {
2117 if((PRINT_LONGNAMES))
2118 chpr += printf("JP2.jp2c.cod.");
2119 chpr += printf("ProgressionOrder");
2120 }
2121 if((PRINT_VALUE))
2122 chpr += printf(" = %#x",progorder & 0xff);
2123 marker_offset++;
2124 nlayers = read_ushort(inptr,TIFF_MOTOROLA,marker_offset);
2125 chpr = newline(chpr);
2126 print_tag_address(ENTRY,marker_offset,indent + 8,"=");
2127 if((PRINT_TAGINFO))
2128 {
2129 if((PRINT_LONGNAMES))
2130 chpr += printf("JP2.jp2c.cod.");
2131 chpr += printf("NumberOfLayers");
2132 }
2133 if((PRINT_VALUE))
2134 chpr += printf(" = %#x",nlayers & 0xff);
2135 marker_offset += 2;
2136 transform = read_ubyte(inptr,marker_offset);
2137 chpr = newline(chpr);
2138 print_tag_address(ENTRY,marker_offset,indent + 8,"=");
2139 if((PRINT_TAGINFO))
2140 {
2141 if((PRINT_LONGNAMES))
2142 chpr += printf("JP2.jp2c.cod.");
2143 chpr += printf("MultiComponentTransform");
2144 }
2145 if((PRINT_VALUE))
2146 {
2147 chpr += printf(" = %#x",transform & 0xff);
2148 if(transform & 1)
2149 chpr += printf(" = 5/3 reversible");
2150 else
2151 chpr += printf(" = 9/7 irreversible");
2152 }
2153 /* Record transform in the first byte of */
2154 /* summary_entry->compression; quantization will be recorded */
2155 /* in the second byte. This overwrites the useless */
2156 /* "compression" indicator in ihdr. */
2157 if(summary_entry)
2158 summary_entry->compression = transform & 1;
2159 marker_offset++;
2160 decomp = read_ubyte(inptr,marker_offset);
2161 chpr = newline(chpr);
2162 print_tag_address(ENTRY,marker_offset,indent + 8,"=");
2163 if((PRINT_TAGINFO))
2164 {
2165 if((PRINT_LONGNAMES))
2166 chpr += printf("JP2.jp2c.cod.");
2167 chpr += printf("DecompLevels");
2168 }
2169 if((PRINT_VALUE))
2170 chpr += printf(" = %u",decomp & 0xff);
2171 marker_offset++;
2172 cbw = read_ubyte(inptr,marker_offset);
2173 chpr = newline(chpr);
2174 print_tag_address(ENTRY,marker_offset,indent + 8,"=");
2175 if((PRINT_TAGINFO))
2176 {
2177 if((PRINT_LONGNAMES))
2178 chpr += printf("JP2.jp2c.cod.");
2179 chpr += printf("CodeBlockWidthExponent");
2180 }
2181 if((PRINT_VALUE))
2182 {
2183 if((LIST_MODE))
2184 {
2185 chpr += printf(" = %#x",(cbw & 0xff) + 2);
2186 chpr = newline(chpr);
2187 /* pseudotag */
2188 print_tag_address(ENTRY,HERE,indent + 8,"*");
2189 if((PRINT_TAGINFO))
2190 {
2191 if((PRINT_LONGNAMES))
2192 chpr += printf("JP2.jp2c.cod.");
2193 chpr += printf("CodeBlockWidth");
2194 }
2195 if((PRINT_VALUE))
2196 chpr += printf(" = %g",pow(2.0,(double)(cbw + 2)));
2197 }
2198 else
2199 chpr += printf(" = %#x + 2 # cbw -> %g",cbw & 0xff,
2200 pow(2.0,(double)(cbw + 2)));
2201 }
2202 marker_offset++;
2203 cbh = read_ubyte(inptr,marker_offset);
2204 chpr = newline(chpr);
2205 print_tag_address(ENTRY,marker_offset,indent + 8,"=");
2206 if((PRINT_TAGINFO))
2207 {
2208 if((PRINT_LONGNAMES))
2209 chpr += printf("JP2.jp2c.cod.");
2210 chpr += printf("CodeBlockHeightExponent");
2211 }
2212 if((PRINT_VALUE))
2213 {
2214 if((LIST_MODE))
2215 {
2216 chpr += printf(" = %#x",(cbh & 0xff) + 2);
2217 chpr = newline(chpr);
2218 /* pseudotag */
2219 print_tag_address(ENTRY,HERE,indent + 8,"*");
2220 if((PRINT_TAGINFO))
2221 {
2222 if((PRINT_LONGNAMES))
2223 chpr += printf("JP2.jp2c.cod.");
2224 chpr += printf("CodeBlockHeight");
2225 }
2226 if((PRINT_VALUE))
2227 chpr += printf(" = %g",pow(2.0,(double)(cbh + 2)));
2228 }
2229 else
2230 chpr += printf(" = %#x + 2 # cbh -> %g",cbh & 0xff,
2231 pow(2.0,(double)(cbh + 2)));
2232 }
2233 marker_offset++;
2234 cbstyle = read_ubyte(inptr,marker_offset);
2235 chpr = newline(chpr);
2236 print_tag_address(ENTRY,marker_offset,indent + 8,"=");
2237 if((PRINT_TAGINFO))
2238 {
2239 if((PRINT_LONGNAMES))
2240 chpr += printf("JP2.jp2c.cod.");
2241 chpr += printf("CodeBLockStyle");
2242 }
2243 if((PRINT_VALUE))
2244 chpr += printf(" = %#x",cbstyle & 0xff);
2245 marker_offset++;
2246 qmfbid = read_ubyte(inptr,marker_offset);
2247 chpr = newline(chpr);
2248 print_tag_address(ENTRY,marker_offset,indent + 8,"=");
2249 if((PRINT_TAGINFO))
2250 {
2251 if((PRINT_LONGNAMES))
2252 chpr += printf("JP2.jp2c.cod.");
2253 chpr += printf("QMIFBankId");
2254 }
2255 if((PRINT_VALUE))
2256 chpr += printf(" = %#x",qmfbid & 0xff);
2257 marker_offset++;
2258 if(cstyle & 1)
2259 {
2260 for(i = 0; i <= decomp; ++i)
2261 {
2262 part_wh = read_ubyte(inptr,marker_offset++);
2263 chpr = newline(chpr);
2264 print_tag_address(ENTRY,marker_offset,indent + 8,"=");
2265 if((LIST_MODE))
2266 {
2267 if((PRINT_TAGINFO))
2268 {
2269 if((PRINT_LONGNAMES))
2270 chpr += printf("JP2.jp2c.cod.");
2271 chpr += printf("Partition%dWidth",i);
2272 }
2273 if((PRINT_VALUE))
2274 chpr += printf(" = %u",part_wh & 0xf);
2275 chpr = newline(chpr);
2276
2277 print_tag_address(ENTRY,marker_offset,indent + 8,"=");
2278 if((PRINT_TAGINFO))
2279 {
2280 if((PRINT_LONGNAMES))
2281 chpr += printf("JP2.jp2c.cod.");
2282 chpr += printf("Partition%dHeight",i);
2283 }
2284 if((PRINT_VALUE))
2285 chpr += printf(" = %u",(part_wh >> 4) & 0xf);
2286 }
2287 else
2288 {
2289 if((PRINT_TAGINFO))
2290 chpr += printf("partition %d width",i);
2291 if((PRINT_VALUE))
2292 chpr += printf(" = %u,",part_wh & 0xf);
2293
2294 if((PRINT_TAGINFO))
2295 chpr += printf(" height = ");
2296 if((PRINT_VALUE))
2297 chpr += printf(" = %u",(part_wh >> 4) & 0xf);
2298 }
2299 }
2300 }
2301 if(!(LIST_MODE))
2302 {
2303 chpr = newline(chpr);
2304 print_tag_address(SECTION|ENTRY,marker_offset - 1,indent,"@");
2305 chpr += printf("</%#x=%s> ",tag,name);
2306 }
2307 if(marker_offset > max_offset)
2308 printred(" READ PAST END OF BOX");
2309 chpr = newline(chpr);
2310
2311 return(max_offset);
2312 }
2313
2314 /* Main quantization header. Prints just the quantization style. */
2315
2316 unsigned long
process_jpc_qcd(FILE * inptr,unsigned long marker_offset,unsigned short tag,struct image_summary * summary_entry,int indent)2317 process_jpc_qcd(FILE *inptr,unsigned long marker_offset,unsigned short tag,
2318 struct image_summary *summary_entry,
2319 int indent)
2320 {
2321 unsigned long max_offset;
2322 unsigned short seg_length;
2323 unsigned short qstyle;
2324 unsigned short guardbits;
2325 unsigned short stepsize,rawstepsize;
2326 char *name;
2327 int chpr = 0;
2328 int i;
2329
2330 name = jp2000tagname(tag);
2331 seg_length = read_ushort(inptr,TIFF_MOTOROLA,marker_offset +2 );
2332 print_tag_address(SECTION|ENTRY,marker_offset,indent,"@");
2333
2334 if((LIST_MODE))
2335 {
2336 if((PRINT_TAGINFO))
2337 {
2338 if((PRINT_LONGNAMES))
2339 chpr += printf("JP2.jp2c.");
2340 chpr += printf("%s",name);
2341 }
2342 if((PRINT_VALUE))
2343 chpr += printf(" = @%lu:%u",marker_offset,seg_length + 2);
2344 }
2345 else
2346 chpr += printf("<%#x=%s> length %u",tag,name,seg_length);
2347 max_offset = marker_offset + seg_length + 2;
2348 marker_offset += 4;
2349
2350 qstyle = read_ubyte(inptr,marker_offset);
2351 ++marker_offset;
2352 chpr = newline(chpr);
2353 print_tag_address(ENTRY,marker_offset,indent + 8,"=");
2354 if((PRINT_TAGINFO))
2355 {
2356 if((PRINT_LONGNAMES))
2357 chpr += printf("JP2.jp2c.qcd.");
2358 chpr += printf("QuantizationStyle");
2359 }
2360 if((PRINT_VALUE))
2361 {
2362 chpr += printf(" = %#x",qstyle & 0xff);
2363 chpr += printf(" = ");
2364 if((qstyle & 0x1f) == 0)
2365 chpr += printf("no quantization");
2366 else if((qstyle & 0x1f) == 1)
2367 chpr += printf("implicit quantization");
2368 else if((qstyle & 0x1f) == 2)
2369 chpr += printf("explicit quantization");
2370 guardbits = (qstyle >> 5) & 0x7;
2371
2372 chpr += printf(", %u guard bit%s",guardbits,guardbits > 1 ? "s" : "");
2373 }
2374 /* Record quantization in the second byte of the summary */
2375 /* compression */
2376 if(summary_entry)
2377 summary_entry->compression |= (((qstyle & 3) << 8) & 0xff00);
2378 for(i = 0;marker_offset < (max_offset - 1); ++i)
2379 {
2380 chpr = newline(chpr);
2381 print_tag_address(ENTRY,marker_offset,indent + 8,"=");
2382 if((qstyle & 0x1f) == 0)
2383 {
2384 rawstepsize = read_ubyte(inptr,marker_offset);
2385 stepsize = rawstepsize >> 3;
2386 if(stepsize & ~0x1f)
2387 {
2388 PUSHCOLOR(RED);
2389 print_tag_address(ENTRY,marker_offset,indent + SUBINDENT,"@");
2390 chpr += printf("# WARNING: stepsize exponent %d out of range (%#x => %#x)",
2391 i,rawstepsize,stepsize);
2392 POPCOLOR();
2393 marker_offset++;
2394 continue;
2395 break;
2396 }
2397 stepsize <<= 11;
2398 if((PRINT_TAGINFO))
2399 {
2400 if((PRINT_LONGNAMES))
2401 chpr += printf("JP2.jp2c.");
2402 chpr += printf("qcd.Stepsize[%d]",i);
2403 }
2404 if((PRINT_VALUE))
2405 chpr += printf(" = %#x -> %u",rawstepsize,stepsize);
2406 marker_offset++;
2407 }
2408 else
2409 {
2410 stepsize = read_ushort(inptr,TIFF_MOTOROLA,marker_offset);
2411 marker_offset += 2;
2412 if((PRINT_TAGINFO))
2413 {
2414 if((PRINT_LONGNAMES))
2415 chpr += printf("JP2.jp2c.qcd.");
2416 chpr += printf("Stepsize[%d]",i);
2417 }
2418 if((PRINT_VALUE))
2419 chpr += printf(" = %u",stepsize);
2420 }
2421 }
2422 if(!(LIST_MODE))
2423 {
2424 chpr = newline(chpr);
2425 print_tag_address(SECTION|ENTRY,marker_offset - 1,indent,"@");
2426 chpr += printf("</%#x=%s> ",tag,name);
2427 }
2428 if(marker_offset > max_offset)
2429 printred(" READ PAST END OF BOX");
2430 chpr = newline(chpr);
2431
2432 return(max_offset);
2433 }
2434