001: /*
002: * $RCSfile: HeaderInfo.java,v $
003: * $Revision: 1.1 $
004: * $Date: 2005/02/11 05:02:00 $
005: * $State: Exp $
006: *
007: * Class: HeaderInfo
008: *
009: * Description: Holds information found in main and tile-part
010: * headers
011: *
012: *
013: *
014: * COPYRIGHT:
015: *
016: * This software module was originally developed by Raphaël Grosbois and
017: * Diego Santa Cruz (Swiss Federal Institute of Technology-EPFL); Joel
018: * Askelöf (Ericsson Radio Systems AB); and Bertrand Berthelot, David
019: * Bouchard, Félix Henry, Gerard Mozelle and Patrice Onno (Canon Research
020: * Centre France S.A) in the course of development of the JPEG2000
021: * standard as specified by ISO/IEC 15444 (JPEG 2000 Standard). This
022: * software module is an implementation of a part of the JPEG 2000
023: * Standard. Swiss Federal Institute of Technology-EPFL, Ericsson Radio
024: * Systems AB and Canon Research Centre France S.A (collectively JJ2000
025: * Partners) agree not to assert against ISO/IEC and users of the JPEG
026: * 2000 Standard (Users) any of their rights under the copyright, not
027: * including other intellectual property rights, for this software module
028: * with respect to the usage by ISO/IEC and Users of this software module
029: * or modifications thereof for use in hardware or software products
030: * claiming conformance to the JPEG 2000 Standard. Those intending to use
031: * this software module in hardware or software products are advised that
032: * their use may infringe existing patents. The original developers of
033: * this software module, JJ2000 Partners and ISO/IEC assume no liability
034: * for use of this software module or modifications thereof. No license
035: * or right to this software module is granted for non JPEG 2000 Standard
036: * conforming products. JJ2000 Partners have full right to use this
037: * software module for his/her own purpose, assign or donate this
038: * software module to any third party and to inhibit third parties from
039: * using this software module for non JPEG 2000 Standard conforming
040: * products. This copyright notice must be included in all copies or
041: * derivative works of this software module.
042: *
043: * Copyright (c) 1999/2000 JJ2000 Partners.
044: * */
045: package jj2000.j2k.codestream;
046:
047: import jj2000.j2k.wavelet.*;
048:
049: import java.util.*;
050:
051: /**
052: * Classe that holds information found in the marker segments of the main and
053: * tile-part headers. There is one inner-class per marker segment type found
054: * in these headers.
055: * */
056: public class HeaderInfo implements Markers, ProgressionType,
057: FilterTypes, Cloneable {
058:
059: /** Internal class holding information found in the SIZ marker segment */
060: public class SIZ implements Cloneable {
061: public int lsiz;
062: public int rsiz;
063: public int xsiz;
064: public int ysiz;
065: public int x0siz;
066: public int y0siz;
067: public int xtsiz;
068: public int ytsiz;
069: public int xt0siz;
070: public int yt0siz;
071: public int csiz;
072: public int[] ssiz;
073: public int[] xrsiz;
074: public int[] yrsiz;
075:
076: /** Component widths */
077: private int[] compWidth = null;
078: /** Maximum width among all components */
079: private int maxCompWidth = -1;
080: /** Component heights */
081: private int[] compHeight = null;
082: /** Maximum height among all components */
083: private int maxCompHeight = -1;
084:
085: /**
086: * Width of the specified tile-component
087: *
088: * @param t Tile index
089: *
090: * @param c Component index
091: * */
092: public int getCompImgWidth(int c) {
093: if (compWidth == null) {
094: compWidth = new int[csiz];
095: for (int cc = 0; cc < csiz; cc++) {
096: compWidth[cc] = (int) (Math.ceil((xsiz)
097: / (double) xrsiz[cc]) - Math.ceil(x0siz
098: / (double) xrsiz[cc]));
099: }
100: }
101: return compWidth[c];
102: }
103:
104: public int getMaxCompWidth() {
105: if (compWidth == null) {
106: compWidth = new int[csiz];
107: for (int cc = 0; cc < csiz; cc++) {
108: compWidth[cc] = (int) (Math.ceil((xsiz)
109: / (double) xrsiz[cc]) - Math.ceil(x0siz
110: / (double) xrsiz[cc]));
111: }
112: }
113: if (maxCompWidth == -1) {
114: for (int c = 0; c < csiz; c++) {
115: if (compWidth[c] > maxCompWidth) {
116: maxCompWidth = compWidth[c];
117: }
118: }
119: }
120: return maxCompWidth;
121: }
122:
123: public int getCompImgHeight(int c) {
124: if (compHeight == null) {
125: compHeight = new int[csiz];
126: for (int cc = 0; cc < csiz; cc++) {
127: compHeight[cc] = (int) (Math.ceil((ysiz)
128: / (double) yrsiz[cc]) - Math.ceil(y0siz
129: / (double) yrsiz[cc]));
130: }
131: }
132: return compHeight[c];
133: }
134:
135: public int getMaxCompHeight() {
136: if (compHeight == null) {
137: compHeight = new int[csiz];
138: for (int cc = 0; cc < csiz; cc++) {
139: compHeight[cc] = (int) (Math.ceil((ysiz)
140: / (double) yrsiz[cc]) - Math.ceil(y0siz
141: / (double) yrsiz[cc]));
142: }
143: }
144: if (maxCompHeight == -1) {
145: for (int c = 0; c < csiz; c++) {
146: if (compHeight[c] != maxCompHeight) {
147: maxCompHeight = compHeight[c];
148: }
149: }
150: }
151: return maxCompHeight;
152: }
153:
154: private int numTiles = -1;
155:
156: public int getNumTiles() {
157: if (numTiles == -1) {
158: numTiles = ((xsiz - xt0siz + xtsiz - 1) / xtsiz)
159: * ((ysiz - yt0siz + ytsiz - 1) / ytsiz);
160: }
161: return numTiles;
162: }
163:
164: private boolean[] origSigned = null;
165:
166: public boolean isOrigSigned(int c) {
167: if (origSigned == null) {
168: origSigned = new boolean[csiz];
169: for (int cc = 0; cc < csiz; cc++) {
170: origSigned[cc] = ((ssiz[cc] >>> SSIZ_DEPTH_BITS) == 1);
171: }
172: }
173: return origSigned[c];
174: }
175:
176: private int[] origBitDepth = null;
177:
178: public int getOrigBitDepth(int c) {
179: if (origBitDepth == null) {
180: origBitDepth = new int[csiz];
181: for (int cc = 0; cc < csiz; cc++) {
182: origBitDepth[cc] = (ssiz[cc] & ((1 << SSIZ_DEPTH_BITS) - 1)) + 1;
183: }
184: }
185: return origBitDepth[c];
186: }
187:
188: public SIZ getCopy() {
189: SIZ ms = null;
190: try {
191: ms = (SIZ) this .clone();
192: } catch (CloneNotSupportedException e) {
193: throw new Error("Cannot clone SIZ marker segment");
194: }
195: return ms;
196: }
197:
198: /** Display information found in SIZ marker segment */
199: public String toString() {
200: String str = "\n --- SIZ (" + lsiz + " bytes) ---\n";
201: str += " Capabilities : " + rsiz + "\n";
202: str += " Image dim. : " + (xsiz - x0siz) + "x"
203: + (ysiz - y0siz) + ", (off=" + x0siz + "," + y0siz
204: + ")\n";
205: str += " Tile dim. : " + xtsiz + "x" + ytsiz + ", (off="
206: + xt0siz + "," + yt0siz + ")\n";
207: str += " Component(s) : " + csiz + "\n";
208: str += " Orig. depth : ";
209: for (int i = 0; i < csiz; i++) {
210: str += getOrigBitDepth(i) + " ";
211: }
212: str += "\n";
213: str += " Orig. signed : ";
214: for (int i = 0; i < csiz; i++) {
215: str += isOrigSigned(i) + " ";
216: }
217: str += "\n";
218: str += " Subs. factor : ";
219: for (int i = 0; i < csiz; i++) {
220: str += xrsiz[i] + "," + yrsiz[i] + " ";
221: }
222: str += "\n";
223: return str;
224: }
225: }
226:
227: /** Returns a new instance of SIZ */
228: public SIZ getNewSIZ() {
229: return new SIZ();
230: }
231:
232: /** Internal class holding information found in the SOt marker segments */
233: public class SOT {
234: public int lsot;
235: public int isot;
236: public int psot;
237: public int tpsot;
238: public int tnsot;
239:
240: /** Display information found in this SOT marker segment */
241: public String toString() {
242: String str = "\n --- SOT (" + lsot + " bytes) ---\n";
243: str += "Tile index : " + isot + "\n";
244: str += "Tile-part length : " + psot + " bytes\n";
245: str += "Tile-part index : " + tpsot + "\n";
246: str += "Num. of tile-parts : " + tnsot + "\n";
247: str += "\n";
248: return str;
249: }
250: }
251:
252: /** Returns a new instance of SOT */
253: public SOT getNewSOT() {
254: return new SOT();
255: }
256:
257: /** Internal class holding information found in the COD marker segments */
258: public class COD implements Cloneable {
259: public int lcod;
260: public int scod;
261: public int sgcod_po; // Progression order
262: public int sgcod_nl; // Number of layers
263: public int sgcod_mct; // Multiple component transformation
264: public int spcod_ndl; // Number of decomposition levels
265: public int spcod_cw; // Code-blocks width
266: public int spcod_ch; // Code-blocks height
267: public int spcod_cs; // Code-blocks style
268: public int[] spcod_t = new int[1]; // Transformation
269: public int[] spcod_ps; // Precinct size
270:
271: public COD getCopy() {
272: COD ms = null;
273: try {
274: ms = (COD) this .clone();
275: } catch (CloneNotSupportedException e) {
276: throw new Error("Cannot clone SIZ marker segment");
277: }
278: return ms;
279: }
280:
281: /** Display information found in this COD marker segment */
282: public String toString() {
283: String str = "\n --- COD (" + lcod + " bytes) ---\n";
284: str += " Coding style : ";
285: if (scod == 0) {
286: str += "Default";
287: } else {
288: if ((scod & SCOX_PRECINCT_PARTITION) != 0)
289: str += "Precints ";
290: if ((scod & SCOX_USE_SOP) != 0)
291: str += "SOP ";
292: if ((scod & SCOX_USE_EPH) != 0)
293: str += "EPH ";
294: int cb0x = ((scod & SCOX_HOR_CB_PART) != 0) ? 1 : 0;
295: int cb0y = ((scod & SCOX_VER_CB_PART) != 0) ? 1 : 0;
296: if (cb0x != 0 || cb0y != 0) {
297: str += "Code-blocks offset";
298: str += "\n Cblk partition : " + cb0x + "," + cb0y;
299: }
300: }
301: str += "\n";
302: str += " Cblk style : ";
303: if (spcod_cs == 0) {
304: str += "Default";
305: } else {
306: if ((spcod_cs & 0x1) != 0)
307: str += "Bypass ";
308: if ((spcod_cs & 0x2) != 0)
309: str += "Reset ";
310: if ((spcod_cs & 0x4) != 0)
311: str += "Terminate ";
312: if ((spcod_cs & 0x8) != 0)
313: str += "Vert_causal ";
314: if ((spcod_cs & 0x10) != 0)
315: str += "Predict ";
316: if ((spcod_cs & 0x20) != 0)
317: str += "Seg_symb ";
318: }
319: str += "\n";
320: str += " Num. of levels : " + spcod_ndl + "\n";
321: switch (sgcod_po) {
322: case LY_RES_COMP_POS_PROG:
323: str += " Progress. type : LY_RES_COMP_POS_PROG\n";
324: break;
325: case RES_LY_COMP_POS_PROG:
326: str += " Progress. type : RES_LY_COMP_POS_PROG\n";
327: break;
328: case RES_POS_COMP_LY_PROG:
329: str += " Progress. type : RES_POS_COMP_LY_PROG\n";
330: break;
331: case POS_COMP_RES_LY_PROG:
332: str += " Progress. type : POS_COMP_RES_LY_PROG\n";
333: break;
334: case COMP_POS_RES_LY_PROG:
335: str += " Progress. type : COMP_POS_RES_LY_PROG\n";
336: break;
337: }
338: str += " Num. of layers : " + sgcod_nl + "\n";
339: str += " Cblk dimension : " + (1 << (spcod_cw + 2)) + "x"
340: + (1 << (spcod_ch + 2)) + "\n";
341: switch (spcod_t[0]) {
342: case W9X7:
343: str += " Filter : 9-7 irreversible\n";
344: break;
345: case W5X3:
346: str += " Filter : 5-3 reversible\n";
347: break;
348: }
349: str += " Multi comp tr. : " + (sgcod_mct == 1) + "\n";
350: if (spcod_ps != null) {
351: str += " Precincts : ";
352: for (int i = 0; i < spcod_ps.length; i++) {
353: str += (1 << (spcod_ps[i] & 0x000F)) + "x"
354: + (1 << (((spcod_ps[i] & 0x00F0) >> 4)))
355: + " ";
356: }
357: }
358: str += "\n";
359: return str;
360: }
361: }
362:
363: /** Returns a new instance of COD */
364: public COD getNewCOD() {
365: return new COD();
366: }
367:
368: /** Internal class holding information found in the COC marker segments */
369: public class COC {
370: public int lcoc;
371: public int ccoc;
372: public int scoc;
373: public int spcoc_ndl; // Number of decomposition levels
374: public int spcoc_cw;
375: public int spcoc_ch;
376: public int spcoc_cs;
377: public int[] spcoc_t = new int[1];
378: public int[] spcoc_ps;
379:
380: /** Display information found in this COC marker segment */
381: public String toString() {
382: String str = "\n --- COC (" + lcoc + " bytes) ---\n";
383: str += " Component : " + ccoc + "\n";
384: str += " Coding style : ";
385: if (scoc == 0) {
386: str += "Default";
387: } else {
388: if ((scoc & 0x1) != 0)
389: str += "Precints ";
390: if ((scoc & 0x2) != 0)
391: str += "SOP ";
392: if ((scoc & 0x4) != 0)
393: str += "EPH ";
394: }
395: str += "\n";
396: str += " Cblk style : ";
397: if (spcoc_cs == 0) {
398: str += "Default";
399: } else {
400: if ((spcoc_cs & 0x1) != 0)
401: str += "Bypass ";
402: if ((spcoc_cs & 0x2) != 0)
403: str += "Reset ";
404: if ((spcoc_cs & 0x4) != 0)
405: str += "Terminate ";
406: if ((spcoc_cs & 0x8) != 0)
407: str += "Vert_causal ";
408: if ((spcoc_cs & 0x10) != 0)
409: str += "Predict ";
410: if ((spcoc_cs & 0x20) != 0)
411: str += "Seg_symb ";
412: }
413: str += "\n";
414: str += " Num. of levels : " + spcoc_ndl + "\n";
415: str += " Cblk dimension : " + (1 << (spcoc_cw + 2)) + "x"
416: + (1 << (spcoc_ch + 2)) + "\n";
417: switch (spcoc_t[0]) {
418: case W9X7:
419: str += " Filter : 9-7 irreversible\n";
420: break;
421: case W5X3:
422: str += " Filter : 5-3 reversible\n";
423: break;
424: }
425: if (spcoc_ps != null) {
426: str += " Precincts : ";
427: for (int i = 0; i < spcoc_ps.length; i++) {
428: str += (1 << (spcoc_ps[i] & 0x000F)) + "x"
429: + (1 << (((spcoc_ps[i] & 0x00F0) >> 4)))
430: + " ";
431: }
432: }
433: str += "\n";
434: return str;
435: }
436: }
437:
438: /** Returns a new instance of COC */
439: public COC getNewCOC() {
440: return new COC();
441: }
442:
443: /** Internal class holding information found in the RGN marker segments */
444: public class RGN {
445: public int lrgn;
446: public int crgn;
447: public int srgn;
448: public int sprgn;
449:
450: /** Display information found in this RGN marker segment */
451: public String toString() {
452: String str = "\n --- RGN (" + lrgn + " bytes) ---\n";
453: str += " Component : " + crgn + "\n";
454: if (srgn == 0) {
455: str += " ROI style : Implicit\n";
456: } else {
457: str += " ROI style : Unsupported\n";
458: }
459: str += " ROI shift : " + sprgn + "\n";
460: str += "\n";
461: return str;
462: }
463: }
464:
465: /** Returns a new instance of RGN */
466: public RGN getNewRGN() {
467: return new RGN();
468: }
469:
470: /** Internal class holding information found in the QCD marker segments */
471: public class QCD {
472: public int lqcd;
473: public int sqcd;
474: public int[][] spqcd;
475:
476: private int qType = -1;
477:
478: public int getQuantType() {
479: if (qType == -1) {
480: qType = sqcd & ~(SQCX_GB_MSK << SQCX_GB_SHIFT);
481: }
482: return qType;
483: }
484:
485: private int gb = -1;
486:
487: public int getNumGuardBits() {
488: if (gb == -1) {
489: gb = (sqcd >> SQCX_GB_SHIFT) & SQCX_GB_MSK;
490: }
491: return gb;
492: }
493:
494: /** Display information found in this QCD marker segment */
495: public String toString() {
496: String str = "\n --- QCD (" + lqcd + " bytes) ---\n";
497: str += " Quant. type : ";
498: int qt = getQuantType();
499: if (qt == SQCX_NO_QUANTIZATION)
500: str += "No quantization \n";
501: else if (qt == SQCX_SCALAR_DERIVED)
502: str += "Scalar derived\n";
503: else if (qt == SQCX_SCALAR_EXPOUNDED)
504: str += "Scalar expounded\n";
505: str += " Guard bits : " + getNumGuardBits() + "\n";
506: if (qt == SQCX_NO_QUANTIZATION) {
507: str += " Exponents :\n";
508: int exp;
509: for (int i = 0; i < spqcd.length; i++) {
510: for (int j = 0; j < spqcd[i].length; j++) {
511: if (i == 0 && j == 0) {
512: exp = (spqcd[0][0] >> SQCX_EXP_SHIFT)
513: & SQCX_EXP_MASK;
514: str += "\tr=0 : " + exp + "\n";
515: } else if (i != 0 && j > 0) {
516: exp = (spqcd[i][j] >> SQCX_EXP_SHIFT)
517: & SQCX_EXP_MASK;
518: str += "\tr=" + i + ",s=" + j + " : " + exp
519: + "\n";
520: }
521: }
522: }
523: } else {
524: str += " Exp / Mantissa : \n";
525: int exp;
526: double mantissa;
527: for (int i = 0; i < spqcd.length; i++) {
528: for (int j = 0; j < spqcd[i].length; j++) {
529: if (i == 0 && j == 0) {
530: exp = (spqcd[0][0] >> 11) & 0x1f;
531: mantissa = (-1f - ((float) (spqcd[0][0] & 0x07ff))
532: / (1 << 11))
533: / (-1 << exp);
534: str += "\tr=0 : " + exp + " / " + mantissa
535: + "\n";
536: } else if (i != 0 && j > 0) {
537: exp = (spqcd[i][j] >> 11) & 0x1f;
538: mantissa = (-1f - ((float) (spqcd[i][j] & 0x07ff))
539: / (1 << 11))
540: / (-1 << exp);
541: str += "\tr=" + i + ",s=" + j + " : " + exp
542: + " / " + mantissa + "\n";
543: }
544: }
545: }
546: }
547: str += "\n";
548: return str;
549: }
550: }
551:
552: /** Returns a new instance of QCD */
553: public QCD getNewQCD() {
554: return new QCD();
555: }
556:
557: /** Internal class holding information found in the QCC marker segments */
558: public class QCC {
559: public int lqcc;
560: public int cqcc;
561: public int sqcc;
562: public int[][] spqcc;
563:
564: private int qType = -1;
565:
566: public int getQuantType() {
567: if (qType == -1) {
568: qType = sqcc & ~(SQCX_GB_MSK << SQCX_GB_SHIFT);
569: }
570: return qType;
571: }
572:
573: private int gb = -1;
574:
575: public int getNumGuardBits() {
576: if (gb == -1) {
577: gb = (sqcc >> SQCX_GB_SHIFT) & SQCX_GB_MSK;
578: }
579: return gb;
580: }
581:
582: /** Display information found in this QCC marker segment */
583: public String toString() {
584: String str = "\n --- QCC (" + lqcc + " bytes) ---\n";
585: str += " Component : " + cqcc + "\n";
586: str += " Quant. type : ";
587: int qt = getQuantType();
588: if (qt == SQCX_NO_QUANTIZATION)
589: str += "No quantization \n";
590: else if (qt == SQCX_SCALAR_DERIVED)
591: str += "Scalar derived\n";
592: else if (qt == SQCX_SCALAR_EXPOUNDED)
593: str += "Scalar expounded\n";
594: str += " Guard bits : " + getNumGuardBits() + "\n";
595: if (qt == SQCX_NO_QUANTIZATION) {
596: str += " Exponents :\n";
597: int exp;
598: for (int i = 0; i < spqcc.length; i++) {
599: for (int j = 0; j < spqcc[i].length; j++) {
600: if (i == 0 && j == 0) {
601: exp = (spqcc[0][0] >> SQCX_EXP_SHIFT)
602: & SQCX_EXP_MASK;
603: str += "\tr=0 : " + exp + "\n";
604: } else if (i != 0 && j > 0) {
605: exp = (spqcc[i][j] >> SQCX_EXP_SHIFT)
606: & SQCX_EXP_MASK;
607: str += "\tr=" + i + ",s=" + j + " : " + exp
608: + "\n";
609: }
610: }
611: }
612: } else {
613: str += " Exp / Mantissa : \n";
614: int exp;
615: double mantissa;
616: for (int i = 0; i < spqcc.length; i++) {
617: for (int j = 0; j < spqcc[i].length; j++) {
618: if (i == 0 && j == 0) {
619: exp = (spqcc[0][0] >> 11) & 0x1f;
620: mantissa = (-1f - ((float) (spqcc[0][0] & 0x07ff))
621: / (1 << 11))
622: / (-1 << exp);
623: str += "\tr=0 : " + exp + " / " + mantissa
624: + "\n";
625: } else if (i != 0 && j > 0) {
626: exp = (spqcc[i][j] >> 11) & 0x1f;
627: mantissa = (-1f - ((float) (spqcc[i][j] & 0x07ff))
628: / (1 << 11))
629: / (-1 << exp);
630: str += "\tr=" + i + ",s=" + j + " : " + exp
631: + " / " + mantissa + "\n";
632: }
633: }
634: }
635: }
636: str += "\n";
637: return str;
638: }
639: }
640:
641: /** Returns a new instance of QCC */
642: public QCC getNewQCC() {
643: return new QCC();
644: }
645:
646: /** Internal class holding information found in the POC marker segments */
647: public class POC {
648: public int lpoc;
649: public int[] rspoc;
650: public int[] cspoc;
651: public int[] lyepoc;
652: public int[] repoc;
653: public int[] cepoc;
654: public int[] ppoc;
655:
656: /** Display information found in this POC marker segment */
657: public String toString() {
658: String str = "\n --- POC (" + lpoc + " bytes) ---\n";
659: str += " Chg_idx RSpoc CSpoc LYEpoc REpoc CEpoc Ppoc\n";
660: for (int chg = 0; chg < rspoc.length; chg++) {
661: str += " " + chg + " " + rspoc[chg] + " "
662: + cspoc[chg] + " " + lyepoc[chg] + " "
663: + repoc[chg] + " " + cepoc[chg];
664: switch (ppoc[chg]) {
665: case ProgressionType.LY_RES_COMP_POS_PROG:
666: str += " LY_RES_COMP_POS_PROG\n";
667: break;
668: case ProgressionType.RES_LY_COMP_POS_PROG:
669: str += " RES_LY_COMP_POS_PROG\n";
670: break;
671: case ProgressionType.RES_POS_COMP_LY_PROG:
672: str += " RES_POS_COMP_LY_PROG\n";
673: break;
674: case ProgressionType.POS_COMP_RES_LY_PROG:
675: str += " POS_COMP_RES_LY_PROG\n";
676: break;
677: case ProgressionType.COMP_POS_RES_LY_PROG:
678: str += " COMP_POS_RES_LY_PROG\n";
679: break;
680: }
681: }
682: str += "\n";
683: return str;
684: }
685: }
686:
687: /** Returns a new instance of POC */
688: public POC getNewPOC() {
689: return new POC();
690: }
691:
692: /** Internal class holding information found in the CRG marker segment */
693: public class CRG {
694: public int lcrg;
695: public int[] xcrg;
696: public int[] ycrg;
697:
698: /** Display information found in the CRG marker segment */
699: public String toString() {
700: String str = "\n --- CRG (" + lcrg + " bytes) ---\n";
701: for (int c = 0; c < xcrg.length; c++) {
702: str += " Component " + c + " offset : " + xcrg[c] + ","
703: + ycrg[c] + "\n";
704: }
705: str += "\n";
706: return str;
707: }
708: }
709:
710: /** Returns a new instance of CRG */
711: public CRG getNewCRG() {
712: return new CRG();
713: }
714:
715: /** Internal class holding information found in the COM marker segments */
716: public class COM {
717: public int lcom;
718: public int rcom;
719: public byte[] ccom;
720:
721: /** Display information found in the COM marker segment */
722: public String toString() {
723: String str = "\n --- COM (" + lcom + " bytes) ---\n";
724: if (rcom == 0) {
725: str += " Registration : General use (binary values)\n";
726: } else if (rcom == 1) {
727: str += " Registration : General use (IS 8859-15:1999 "
728: + "(Latin) values)\n";
729: str += " Text : " + (new String(ccom)) + "\n";
730: } else {
731: str += " Registration : Unknown\n";
732: }
733: str += "\n";
734: return str;
735: }
736: }
737:
738: /** Returns a new instance of COM */
739: public COM getNewCOM() {
740: ncom++;
741: return new COM();
742: }
743:
744: /** Returns the number of found COM marker segments */
745: public int getNumCOM() {
746: return ncom;
747: }
748:
749: /** Reference to the SIZ marker segment found in main header */
750: public SIZ siz;
751:
752: /** Reference to the SOT marker segments found in tile-part headers. The
753: * kwy is given by "t"+tileIdx"_tp"+tilepartIndex. */
754: public Hashtable sot = new Hashtable();
755:
756: /** Reference to the COD marker segments found in main and first tile-part
757: * header. The key is either "main" or "t"+tileIdx.*/
758: public Hashtable cod = new Hashtable();
759:
760: /** Reference to the COC marker segments found in main and first tile-part
761: * header. The key is either "main_c"+componentIndex or
762: * "t"+tileIdx+"_c"+component_index. */
763: public Hashtable coc = new Hashtable();
764:
765: /** Reference to the RGN marker segments found in main and first tile-part
766: * header. The key is either "main_c"+componentIndex or
767: * "t"+tileIdx+"_c"+component_index. */
768: public Hashtable rgn = new Hashtable();
769:
770: /** Reference to the QCD marker segments found in main and first tile-part
771: * header. The key is either "main" or "t"+tileIdx. */
772: public Hashtable qcd = new Hashtable();
773:
774: /** Reference to the QCC marker segments found in main and first tile-part
775: * header. They key is either "main_c"+componentIndex or
776: * "t"+tileIdx+"_c"+component_index. */
777: public Hashtable qcc = new Hashtable();
778:
779: /** Reference to the POC marker segments found in main and first tile-part
780: * header. They key is either "main" or "t"+tileIdx. */
781: public Hashtable poc = new Hashtable();
782:
783: /** Reference to the CRG marker segment found in main header */
784: public CRG crg;
785:
786: /** Reference to the COM marker segments found in main and tile-part
787: * headers. The key is either "main_"+comIdx or "t"+tileIdx+"_"+comIdx. */
788: public Hashtable com = new Hashtable();
789:
790: /** Number of found COM marker segment */
791: private int ncom = 0;
792:
793: /** Display information found in the different marker segments of the main
794: * header */
795: public String toStringMainHeader() {
796: int nc = siz.csiz;
797: // SIZ
798: String str = "" + siz;
799: // COD
800: if (cod.get("main") != null) {
801: str += "" + (COD) cod.get("main");
802: }
803: // COCs
804: for (int c = 0; c < nc; c++) {
805: if (coc.get("main_c" + c) != null) {
806: str += "" + (COC) coc.get("main_c" + c);
807: }
808: }
809: // QCD
810: if (qcd.get("main") != null) {
811: str += "" + (QCD) qcd.get("main");
812: }
813: // QCCs
814: for (int c = 0; c < nc; c++) {
815: if (qcc.get("main_c" + c) != null) {
816: str += "" + (QCC) qcc.get("main_c" + c);
817: }
818: }
819: // RGN
820: for (int c = 0; c < nc; c++) {
821: if (rgn.get("main_c" + c) != null) {
822: str += "" + (RGN) rgn.get("main_c" + c);
823: }
824: }
825: // POC
826: if (poc.get("main") != null) {
827: str += "" + (POC) poc.get("main");
828: }
829: // CRG
830: if (crg != null) {
831: str += "" + crg;
832: }
833: // COM
834: for (int i = 0; i < ncom; i++) {
835: if (com.get("main_" + i) != null) {
836: str += "" + (COM) com.get("main_" + i);
837: }
838: }
839: return str;
840: }
841:
842: /**
843: * Returns information found in the tile-part headers of a given tile.
844: *
845: * @param t index of the tile
846: *
847: * @param tp Number of tile-parts
848: * */
849: public String toStringTileHeader(int t, int ntp) {
850: int nc = siz.csiz;
851: String str = "";
852: // SOT
853: for (int i = 0; i < ntp; i++) {
854: str += "Tile-part " + i + ", tile " + t + ":\n";
855: str += "" + (SOT) sot.get("t" + t + "_tp" + i);
856: }
857: // COD
858: if (cod.get("t" + t) != null) {
859: str += "" + (COD) cod.get("t" + t);
860: }
861: // COCs
862: for (int c = 0; c < nc; c++) {
863: if (coc.get("t" + t + "_c" + c) != null) {
864: str += "" + (COC) coc.get("t" + t + "_c" + c);
865: }
866: }
867: // QCD
868: if (qcd.get("t" + t) != null) {
869: str += "" + (QCD) qcd.get("t" + t);
870: }
871: // QCCs
872: for (int c = 0; c < nc; c++) {
873: if (qcc.get("t" + t + "_c" + c) != null) {
874: str += "" + (QCC) qcc.get("t" + t + "_c" + c);
875: }
876: }
877: // RGN
878: for (int c = 0; c < nc; c++) {
879: if (rgn.get("t" + t + "_c" + c) != null) {
880: str += "" + (RGN) rgn.get("t" + t + "_c" + c);
881: }
882: }
883: // POC
884: if (poc.get("t" + t) != null) {
885: str += "" + (POC) poc.get("t" + t);
886: }
887: return str;
888: }
889:
890: /**
891: * Returns information found in the tile-part headers of a given tile
892: * exception the SOT marker segment.
893: *
894: * @param t index of the tile
895: *
896: * @param tp Number of tile-parts
897: * */
898: public String toStringThNoSOT(int t, int ntp) {
899: int nc = siz.csiz;
900: String str = "";
901: // COD
902: if (cod.get("t" + t) != null) {
903: str += "" + (COD) cod.get("t" + t);
904: }
905: // COCs
906: for (int c = 0; c < nc; c++) {
907: if (coc.get("t" + t + "_c" + c) != null) {
908: str += "" + (COC) coc.get("t" + t + "_c" + c);
909: }
910: }
911: // QCD
912: if (qcd.get("t" + t) != null) {
913: str += "" + (QCD) qcd.get("t" + t);
914: }
915: // QCCs
916: for (int c = 0; c < nc; c++) {
917: if (qcc.get("t" + t + "_c" + c) != null) {
918: str += "" + (QCC) qcc.get("t" + t + "_c" + c);
919: }
920: }
921: // RGN
922: for (int c = 0; c < nc; c++) {
923: if (rgn.get("t" + t + "_c" + c) != null) {
924: str += "" + (RGN) rgn.get("t" + t + "_c" + c);
925: }
926: }
927: // POC
928: if (poc.get("t" + t) != null) {
929: str += "" + (POC) poc.get("t" + t);
930: }
931: return str;
932: }
933:
934: /** Returns a copy of this object */
935: public HeaderInfo getCopy(int nt) {
936: HeaderInfo nhi = null;
937: // SIZ
938: try {
939: nhi = (HeaderInfo) clone();
940: } catch (CloneNotSupportedException e) {
941: throw new Error("Cannot clone HeaderInfo instance");
942: }
943: nhi.siz = siz.getCopy();
944: // COD
945: if (cod.get("main") != null) {
946: COD ms = (COD) cod.get("main");
947: nhi.cod.put("main", ms.getCopy());
948: }
949: for (int t = 0; t < nt; t++) {
950: if (cod.get("t" + t) != null) {
951: COD ms = (COD) cod.get("t" + t);
952: nhi.cod.put("t" + t, ms.getCopy());
953: }
954: }
955: return nhi;
956: }
957: }
|