001: /*
002: * $RCSfile: ProgressionSpec.java,v $
003: * $Revision: 1.1 $
004: * $Date: 2005/02/11 05:02:05 $
005: * $State: Exp $
006: *
007: * Class: ProgressionSpec
008: *
009: * Description: Specification of the progression(s) type(s) and
010: * changes of progression.
011: *
012: * COPYRIGHT:
013: *
014: * This software module was originally developed by Raphaël Grosbois and
015: * Diego Santa Cruz (Swiss Federal Institute of Technology-EPFL); Joel
016: * Askelöf (Ericsson Radio Systems AB); and Bertrand Berthelot, David
017: * Bouchard, Félix Henry, Gerard Mozelle and Patrice Onno (Canon Research
018: * Centre France S.A) in the course of development of the JPEG2000
019: * standard as specified by ISO/IEC 15444 (JPEG 2000 Standard). This
020: * software module is an implementation of a part of the JPEG 2000
021: * Standard. Swiss Federal Institute of Technology-EPFL, Ericsson Radio
022: * Systems AB and Canon Research Centre France S.A (collectively JJ2000
023: * Partners) agree not to assert against ISO/IEC and users of the JPEG
024: * 2000 Standard (Users) any of their rights under the copyright, not
025: * including other intellectual property rights, for this software module
026: * with respect to the usage by ISO/IEC and Users of this software module
027: * or modifications thereof for use in hardware or software products
028: * claiming conformance to the JPEG 2000 Standard. Those intending to use
029: * this software module in hardware or software products are advised that
030: * their use may infringe existing patents. The original developers of
031: * this software module, JJ2000 Partners and ISO/IEC assume no liability
032: * for use of this software module or modifications thereof. No license
033: * or right to this software module is granted for non JPEG 2000 Standard
034: * conforming products. JJ2000 Partners have full right to use this
035: * software module for his/her own purpose, assign or donate this
036: * software module to any third party and to inhibit third parties from
037: * using this software module for non JPEG 2000 Standard conforming
038: * products. This copyright notice must be included in all copies or
039: * derivative works of this software module.
040: *
041: * Copyright (c) 1999/2000 JJ2000 Partners.
042: * */
043: package jj2000.j2k.entropy;
044:
045: import java.util.*;
046:
047: import jj2000.j2k.codestream.*;
048: import jj2000.j2k.wavelet.*;
049: import jj2000.j2k.image.*;
050: import jj2000.j2k.util.*;
051: import jj2000.j2k.*;
052:
053: import com.sun.media.imageioimpl.plugins.jpeg2000.J2KImageWriteParamJava;
054:
055: /**
056: * This class extends ModuleSpec class for progression type(s) and progression
057: * order changes holding purposes.
058: *
059: * <P>It stores the progression type(s) used in the codestream. There can be
060: * only one progression type or several ones if progression order changes are
061: * used (POC markers).
062: * */
063: public class ProgressionSpec extends ModuleSpec {
064:
065: /**
066: * Creates a new ProgressionSpec object for the specified number of tiles
067: * and components.
068: *
069: * @param nt The number of tiles
070: *
071: * @param nc The number of components
072: *
073: * @param type the type of the specification module i.e. tile specific,
074: * component specific or both. The ProgressionSpec class should only be
075: * used only with the type ModuleSpec.SPEC_TYPE_TILE.
076: * */
077: public ProgressionSpec(int nt, int nc, byte type) {
078: super (nt, nc, type);
079: if (type != ModuleSpec.SPEC_TYPE_TILE) {
080: throw new Error("Illegal use of class ProgressionSpec !");
081: }
082: }
083:
084: /**
085: * Creates a new ProgressionSpec object for the specified number of
086: * tiles, components and the J2KImageWriteParamJava instance.
087: *
088: * @param nt The number of tiles
089: *
090: * @param nc The number of components
091: *
092: * @param nl The number of layer
093: *
094: * @param dls The number of decomposition levels specifications
095: *
096: * @param type the type of the specification module. The ProgressionSpec
097: * class should only be used only with the type ModuleSpec.SPEC_TYPE_TILE.
098: *
099: * @param wp The J2KImageWriteParamJava instance
100: * */
101: public ProgressionSpec(int nt, int nc, int nl, IntegerSpec dls,
102: byte type, J2KImageWriteParamJava wp, String values) {
103: super (nt, nc, type);
104:
105: specified = values;
106:
107: String param = values;
108: Progression[] prog;
109: int mode = -1;
110:
111: if (values == null) { // No parameter specified
112: if (wp.getROIs() == null) {
113: mode = checkProgMode("res");
114: } else {
115: mode = checkProgMode("layer");
116: }
117:
118: if (mode == -1) {
119: String errMsg = "Unknown progression type : '" + param
120: + "'";
121: throw new IllegalArgumentException(errMsg);
122: }
123: prog = new Progression[1];
124: prog[0] = new Progression(mode, 0, nc, 0, dls.getMax() + 1,
125: nl);
126: setDefault(prog);
127: return;
128: }
129:
130: StringTokenizer stk = new StringTokenizer(param);
131: byte curSpecType = SPEC_DEF; // Specification type of the
132: // current parameter
133: boolean[] tileSpec = null; // Tiles concerned by the specification
134: String word = null; // current word
135: String errMsg = null; // Error message
136: boolean needInteger = false; // True if an integer value is expected
137: int intType = 0; // Type of read integer value (0=index of first
138: // component, 1= index of first resolution level, 2=index of last
139: // layer, 3= index of last component, 4= index of last resolution
140: // level)
141: Vector progression = new Vector();
142: int tmp = 0;
143: Progression curProg = null;
144:
145: while (stk.hasMoreTokens()) {
146: word = stk.nextToken();
147:
148: switch (word.charAt(0)) {
149: case 't':
150: // If progression were previously found, store them
151: if (progression.size() > 0) {
152: // Ensure that all information has been taken
153: curProg.ce = nc;
154: curProg.lye = nl;
155: curProg.re = dls.getMax() + 1;
156: prog = new Progression[progression.size()];
157: progression.copyInto(prog);
158: if (curSpecType == SPEC_DEF) {
159: setDefault(prog);
160: } else if (curSpecType == SPEC_TILE_DEF) {
161: for (int i = tileSpec.length - 1; i >= 0; i--)
162: if (tileSpec[i]) {
163: setTileDef(i, prog);
164: }
165: }
166: }
167: progression.removeAllElements();
168: intType = -1;
169: needInteger = false;
170:
171: // Tiles specification
172: tileSpec = parseIdx(word, nTiles);
173: curSpecType = SPEC_TILE_DEF;
174: break;
175: default:
176: // Here, words is either a Integer (progression bound
177: // index) or a String (progression order type). This
178: // is determined by the value of needInteger.
179: if (needInteger) { // Progression bound info
180: try {
181: tmp = (new Integer(word)).intValue();
182: } catch (NumberFormatException e) {
183: // Progression has missing parameters
184: throw new IllegalArgumentException(
185: "Progression " + "order"
186: + " specification "
187: + "has missing "
188: + "parameters: " + param);
189: }
190:
191: switch (intType) {
192: case 0: // cs
193: if (tmp < 0 || tmp > dls.getMax() + 1)
194: throw new IllegalArgumentException(
195: "Invalid comp_start "
196: + "in '-Aptype' option");
197: curProg.cs = tmp;
198: break;
199: case 1: // rs
200: if (tmp < 0 || tmp > nc)
201: throw new IllegalArgumentException(
202: "Invalid res_start "
203: + "in '-Aptype' option");
204:
205: curProg.rs = tmp;
206: break;
207: case 2: // lye
208: if (tmp < 0)
209: throw new IllegalArgumentException(
210: "Invalid layer_end "
211: + "in '-Aptype' option");
212: if (tmp > nl) {
213: tmp = nl;
214: }
215: curProg.lye = tmp;
216: break;
217: case 3: // ce
218: if (tmp < 0)
219: throw new IllegalArgumentException(
220: "Invalid comp_end "
221: + "in '-Aptype' option");
222: if (tmp > (dls.getMax() + 1)) {
223: tmp = dls.getMax() + 1;
224: }
225: curProg.ce = tmp;
226: break;
227: case 4: // re
228: if (tmp < 0)
229: throw new IllegalArgumentException(
230: "Invalid res_end "
231: + "in '-Aptype' option");
232: if (tmp > nc) {
233: tmp = nc;
234: }
235: curProg.re = tmp;
236: break;
237: }
238:
239: if (intType < 4) {
240: intType++;
241: needInteger = true;
242: break;
243: } else if (intType == 4) {
244: intType = 0;
245: needInteger = false;
246: break;
247: } else {
248: throw new Error("Error in usage of 'Aptype' "
249: + "option: " + param);
250: }
251: }
252:
253: if (!needInteger) { // Progression type info
254: mode = checkProgMode(word);
255: if (mode == -1) {
256: errMsg = "Unknown progression type : '" + word
257: + "'";
258: throw new IllegalArgumentException(errMsg);
259: }
260: needInteger = true;
261: intType = 0;
262: if (progression.size() == 0)
263: curProg = new Progression(mode, 0, nc, 0, dls
264: .getMax() + 1, nl);
265: else {
266: curProg = new Progression(mode, 0, nc, 0, dls
267: .getMax() + 1, nl);
268: }
269: progression.addElement(curProg);
270: }
271: } // switch
272: } // while
273:
274: if (progression.size() == 0) { // No progression defined
275: // Set it arbitrarily to layer progressive
276: if (wp.getROIs() == null) {
277: mode = checkProgMode("res");
278: } else {
279: mode = checkProgMode("layer");
280: }
281:
282: if (mode == -1) {
283: errMsg = "Unknown progression type : '" + param + "'";
284: throw new IllegalArgumentException(errMsg);
285: }
286: prog = new Progression[1];
287: prog[0] = new Progression(mode, 0, nc, 0, dls.getMax() + 1,
288: nl);
289: setDefault(prog);
290: return;
291: }
292:
293: // Ensure that all information has been taken
294: curProg.ce = nc;
295: curProg.lye = nl;
296: curProg.re = dls.getMax() + 1;
297:
298: // Store found progression
299: prog = new Progression[progression.size()];
300: progression.copyInto(prog);
301:
302: if (curSpecType == SPEC_DEF) {
303: setDefault(prog);
304: } else if (curSpecType == SPEC_TILE_DEF) {
305: for (int i = tileSpec.length - 1; i >= 0; i--)
306: if (tileSpec[i]) {
307: setTileDef(i, prog);
308: }
309: }
310:
311: // Check that default value has been specified
312: if (getDefault() == null) {
313: int ndefspec = 0;
314: for (int t = nt - 1; t >= 0; t--) {
315: for (int c = nc - 1; c >= 0; c--) {
316: if (specValType[t][c] == SPEC_DEF) {
317: ndefspec++;
318: }
319: }
320: }
321:
322: // If some tile-component have received no specification, they are
323: // arbitrarily set to 'layer' progressive.
324: if (ndefspec != 0) {
325: if (wp.getROIs() == null) {
326: mode = checkProgMode("res");
327: } else {
328: mode = checkProgMode("layer");
329: }
330: if (mode == -1) {
331: errMsg = "Unknown progression type : '" + param
332: + "'";
333: throw new IllegalArgumentException(errMsg);
334: }
335: prog = new Progression[1];
336: prog[0] = new Progression(mode, 0, nc, 0,
337: dls.getMax() + 1, nl);
338: setDefault(prog);
339: } else {
340: // All tile-component have been specified, takes the first
341: // tile-component value as default.
342: setDefault(getTileCompVal(0, 0));
343: switch (specValType[0][0]) {
344: case SPEC_TILE_DEF:
345: for (int c = nc - 1; c >= 0; c--) {
346: if (specValType[0][c] == SPEC_TILE_DEF)
347: specValType[0][c] = SPEC_DEF;
348: }
349: tileDef[0] = null;
350: break;
351: case SPEC_COMP_DEF:
352: for (int t = nt - 1; t >= 0; t--) {
353: if (specValType[t][0] == SPEC_COMP_DEF)
354: specValType[t][0] = SPEC_DEF;
355: }
356: compDef[0] = null;
357: break;
358: case SPEC_TILE_COMP:
359: specValType[0][0] = SPEC_DEF;
360: tileCompVal.put("t0c0", null);
361: break;
362: }
363: }
364: }
365: }
366:
367: /**
368: * Check if the progression mode exists and if so, return its integer
369: * value. It returns -1 otherwise.
370: *
371: * @param mode The progression mode stored in a string
372: *
373: * @return The integer value of the progression mode or -1 if the
374: * progression mode does not exist.
375: *
376: * @see ProgressionType
377: * */
378: private int checkProgMode(String mode) {
379: if (mode.equals("res")) {
380: return ProgressionType.RES_LY_COMP_POS_PROG;
381: } else if (mode.equals("layer")) {
382: return ProgressionType.LY_RES_COMP_POS_PROG;
383: } else if (mode.equals("pos-comp")) {
384: return ProgressionType.POS_COMP_RES_LY_PROG;
385: } else if (mode.equals("comp-pos")) {
386: return ProgressionType.COMP_POS_RES_LY_PROG;
387: } else if (mode.equals("res-pos")) {
388: return ProgressionType.RES_POS_COMP_LY_PROG;
389: } else {
390: // No corresponding progression mode, we return -1.
391: return -1;
392: }
393: }
394: }
|