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