001: /*
002: * $RCSfile: CBlkSizeSpec.java,v $
003: * $Revision: 1.1 $
004: * $Date: 2005/02/11 05:02:04 $
005: * $State: Exp $
006: *
007: * Class: CBlkSizeSpec
008: *
009: * Description: Specification of the code-blocks size
010: *
011: *
012: *
013: * COPYRIGHT:
014: *
015: * This software module was originally developed by Raphaël Grosbois and
016: * Diego Santa Cruz (Swiss Federal Institute of Technology-EPFL); Joel
017: * Askelöf (Ericsson Radio Systems AB); and Bertrand Berthelot, David
018: * Bouchard, Félix Henry, Gerard Mozelle and Patrice Onno (Canon Research
019: * Centre France S.A) in the course of development of the JPEG2000
020: * standard as specified by ISO/IEC 15444 (JPEG 2000 Standard). This
021: * software module is an implementation of a part of the JPEG 2000
022: * Standard. Swiss Federal Institute of Technology-EPFL, Ericsson Radio
023: * Systems AB and Canon Research Centre France S.A (collectively JJ2000
024: * Partners) agree not to assert against ISO/IEC and users of the JPEG
025: * 2000 Standard (Users) any of their rights under the copyright, not
026: * including other intellectual property rights, for this software module
027: * with respect to the usage by ISO/IEC and Users of this software module
028: * or modifications thereof for use in hardware or software products
029: * claiming conformance to the JPEG 2000 Standard. Those intending to use
030: * this software module in hardware or software products are advised that
031: * their use may infringe existing patents. The original developers of
032: * this software module, JJ2000 Partners and ISO/IEC assume no liability
033: * for use of this software module or modifications thereof. No license
034: * or right to this software module is granted for non JPEG 2000 Standard
035: * conforming products. JJ2000 Partners have full right to use this
036: * software module for his/her own purpose, assign or donate this
037: * software module to any third party and to inhibit third parties from
038: * using this software module for non JPEG 2000 Standard conforming
039: * products. This copyright notice must be included in all copies or
040: * derivative works of this software module.
041: *
042: * Copyright (c) 1999/2000 JJ2000 Partners.
043: * */
044: package jj2000.j2k.entropy;
045:
046: import jj2000.j2k.codestream.*;
047: import jj2000.j2k.wavelet.*;
048: import jj2000.j2k.image.*;
049: import jj2000.j2k.util.*;
050: import jj2000.j2k.*;
051:
052: import java.util.*;
053:
054: import com.sun.media.imageioimpl.plugins.jpeg2000.J2KImageWriteParamJava;
055:
056: /**
057: * This class extends ModuleSpec class for code-blocks sizes holding purposes.
058: *
059: * <P>It stores the size a of code-block.
060: * */
061: public class CBlkSizeSpec extends ModuleSpec {
062:
063: private String defaultValue = "64 64";
064:
065: /** Name of the option */
066: private static final String optName = "Cblksiz";
067:
068: /** The maximum code-block width */
069: private int maxCBlkWidth = 0;
070:
071: /** The maximum code-block height */
072: private int maxCBlkHeight = 0;
073:
074: /**
075: * Creates a new CBlkSizeSpec object for the specified number of tiles and
076: * components.
077: *
078: * @param nt The number of tiles
079: *
080: * @param nc The number of components
081: *
082: * @param type the type of the specification module i.e. tile specific,
083: * component specific or both.
084: * */
085: public CBlkSizeSpec(int nt, int nc, byte type) {
086: super (nt, nc, type);
087: }
088:
089: /**
090: * Creates a new CBlkSizeSpec object for the specified number of tiles and
091: * components and the ParameterList instance.
092: *
093: * @param nt The number of tiles
094: *
095: * @param nc The number of components
096: *
097: * @param type the type of the specification module i.e. tile specific,
098: * component specific or both.
099: *
100: * @param imgsrc The image source (used to get the image size)
101: *
102: * @param pl The ParameterList instance
103: * */
104: public CBlkSizeSpec(int nt, int nc, byte type,
105: J2KImageWriteParamJava wp, String values) {
106: super (nt, nc, type);
107:
108: boolean firstVal = true;
109: specified = values;
110:
111: String param = values; //"64 64";
112: if (param == null)
113: param = defaultValue; // the default
114: //pl.getParameter(optName);
115:
116: // Precinct partition is used : parse arguments
117: StringTokenizer stk = new StringTokenizer(param);
118: byte curSpecType = SPEC_DEF; // Specification type of the
119: // current parameter
120: boolean[] tileSpec = null; // Tiles concerned by the specification
121: boolean[] compSpec = null; // Components concerned by the specification
122: int i, xIdx, ci, ti;
123: String word = null; // current word
124: String errMsg = null;
125:
126: while (stk.hasMoreTokens()) {
127: word = stk.nextToken();
128:
129: switch (word.charAt(0)) {
130:
131: case 't': // Tiles specification
132: tileSpec = parseIdx(word, nTiles);
133: if (curSpecType == SPEC_COMP_DEF) {
134: curSpecType = SPEC_TILE_COMP;
135: } else {
136: curSpecType = SPEC_TILE_DEF;
137: }
138: break;
139:
140: case 'c': // Components specification
141: compSpec = parseIdx(word, nComp);
142: if (curSpecType == SPEC_TILE_DEF) {
143: curSpecType = SPEC_TILE_COMP;
144: } else {
145: curSpecType = SPEC_COMP_DEF;
146: }
147: break;
148:
149: default:
150: if (!Character.isDigit(word.charAt(0))) {
151: errMsg = "Bad construction for parameter: " + word;
152: throw new IllegalArgumentException(errMsg);
153: }
154: Integer dim[] = new Integer[2];
155: // Get code-block's width
156: try {
157: dim[0] = new Integer(word);
158: // Check that width is not >
159: // StdEntropyCoderOptions.MAX_CB_DIM
160: if (dim[0].intValue() > StdEntropyCoderOptions.MAX_CB_DIM) {
161: errMsg = "'" + optName
162: + "' option : the code-block's "
163: + "width cannot be greater than "
164: + StdEntropyCoderOptions.MAX_CB_DIM;
165: throw new IllegalArgumentException(errMsg);
166: }
167: // Check that width is not <
168: // StdEntropyCoderOptions.MIN_CB_DIM
169: if (dim[0].intValue() < StdEntropyCoderOptions.MIN_CB_DIM) {
170: errMsg = "'" + optName
171: + "' option : the code-block's "
172: + "width cannot be less than "
173: + StdEntropyCoderOptions.MIN_CB_DIM;
174: throw new IllegalArgumentException(errMsg);
175: }
176: // Check that width is a power of 2
177: if (dim[0].intValue() != (1 << MathUtil.log2(dim[0]
178: .intValue()))) {
179: errMsg = "'" + optName
180: + "' option : the code-block's "
181: + "width must be a power of 2";
182: throw new IllegalArgumentException(errMsg);
183: }
184: } catch (NumberFormatException e) {
185: errMsg = "'" + optName
186: + "' option : the code-block's "
187: + "width could not be parsed.";
188: throw new IllegalArgumentException(errMsg);
189: }
190: // Get the next word in option
191: try {
192: word = stk.nextToken();
193: } catch (NoSuchElementException e) {
194: errMsg = "'" + optName
195: + "' option : could not parse the "
196: + "code-block's height";
197: throw new IllegalArgumentException(errMsg);
198:
199: }
200: // Get the code-block's height
201: try {
202: dim[1] = new Integer(word);
203: // Check that height is not >
204: // StdEntropyCoderOptions.MAX_CB_DIM
205: if (dim[1].intValue() > StdEntropyCoderOptions.MAX_CB_DIM) {
206: errMsg = "'" + optName
207: + "' option : the code-block's "
208: + "height cannot be greater than "
209: + StdEntropyCoderOptions.MAX_CB_DIM;
210: throw new IllegalArgumentException(errMsg);
211: }
212: // Check that height is not <
213: // StdEntropyCoderOptions.MIN_CB_DIM
214: if (dim[1].intValue() < StdEntropyCoderOptions.MIN_CB_DIM) {
215: errMsg = "'" + optName
216: + "' option : the code-block's "
217: + "height cannot be less than "
218: + StdEntropyCoderOptions.MIN_CB_DIM;
219: throw new IllegalArgumentException(errMsg);
220: }
221: // Check that height is a power of 2
222: if (dim[1].intValue() != (1 << MathUtil.log2(dim[1]
223: .intValue()))) {
224: errMsg = "'" + optName
225: + "' option : the code-block's "
226: + "height must be a power of 2";
227: throw new IllegalArgumentException(errMsg);
228: }
229: // Check that the code-block 'area' (i.e. width*height) is
230: // not greater than StdEntropyCoderOptions.MAX_CB_AREA
231: if (dim[0].intValue() * dim[1].intValue() > StdEntropyCoderOptions.MAX_CB_AREA) {
232: errMsg = "'"
233: + optName
234: + "' option : The "
235: + "code-block's area (i.e. width*height) "
236: + "cannot be greater than "
237: + StdEntropyCoderOptions.MAX_CB_AREA;
238: throw new IllegalArgumentException(errMsg);
239: }
240: } catch (NumberFormatException e) {
241: errMsg = "'" + optName
242: + "' option : the code-block's height "
243: + "could not be parsed.";
244: throw new IllegalArgumentException(errMsg);
245: }
246:
247: // Store the maximum dimensions if necessary
248: if (dim[0].intValue() > maxCBlkWidth) {
249: maxCBlkWidth = dim[0].intValue();
250: }
251:
252: if (dim[1].intValue() > maxCBlkHeight) {
253: maxCBlkHeight = dim[1].intValue();
254: }
255:
256: if (firstVal) {
257: // This is the first time a value is given so we set it as
258: // the default one
259: setDefault(dim);
260: firstVal = false;
261: }
262:
263: switch (curSpecType) {
264: case SPEC_DEF:
265: setDefault(dim);
266: break;
267: case SPEC_TILE_DEF:
268: for (ti = tileSpec.length - 1; ti >= 0; ti--) {
269: if (tileSpec[ti]) {
270: setTileDef(ti, dim);
271: }
272: }
273: break;
274: case SPEC_COMP_DEF:
275: for (ci = compSpec.length - 1; ci >= 0; ci--) {
276: if (compSpec[ci]) {
277: setCompDef(ci, dim);
278: }
279: }
280: break;
281: default:
282: for (ti = tileSpec.length - 1; ti >= 0; ti--) {
283: for (ci = compSpec.length - 1; ci >= 0; ci--) {
284: if (tileSpec[ti] && compSpec[ci]) {
285: setTileCompVal(ti, ci, dim);
286: }
287: }
288: }
289: break;
290: }
291: } // end switch
292: }
293: }
294:
295: /**
296: * Returns the maximum code-block's width
297: *
298: */
299: public int getMaxCBlkWidth() {
300: return maxCBlkWidth;
301: }
302:
303: /**
304: * Returns the maximum code-block's height
305: *
306: */
307: public int getMaxCBlkHeight() {
308: return maxCBlkHeight;
309: }
310:
311: /**
312: * Returns the code-block width :
313: *
314: * <ul>
315: * <li>for the specified tile/component</li>
316: * <li>for the specified tile</li>
317: * <li>for the specified component</li>
318: * <li>default value</li>
319: * </ul>
320: *
321: * The value returned depends on the value of the variable 'type' which
322: * can take the following values :<br>
323: *
324: * <ul>
325: * <li>SPEC_DEF -> Default value is returned. t and c values are
326: * ignored</li>
327: * <li>SPEC_COMP_DEF -> Component default value is returned. t value is
328: * ignored</li>
329: * <li>SPEC_TILE_DEF -> Tile default value is returned. c value is
330: * ignored</li>
331: * <li>SPEC_TILE_COMP -> Tile/Component value is returned.</li>
332: * </ul>
333: *
334: * @param type The type of the value we want to be returned
335: *
336: * @param t The tile index
337: *
338: * @param c the component index
339: *
340: * @return The code-block width for the specified tile and component
341: * */
342: public int getCBlkWidth(byte type, int t, int c) {
343: Integer dim[] = null;
344: switch (type) {
345: case SPEC_DEF:
346: dim = (Integer[]) getDefault();
347: break;
348: case SPEC_COMP_DEF:
349: dim = (Integer[]) getCompDef(c);
350: break;
351: case SPEC_TILE_DEF:
352: dim = (Integer[]) getTileDef(t);
353: break;
354: case SPEC_TILE_COMP:
355: dim = (Integer[]) getTileCompVal(t, c);
356: }
357: return dim[0].intValue();
358: }
359:
360: /**
361: * Returns the code-block height:
362: *
363: * <ul>
364: * <li>for the specified tile/component</li>
365: * <li>for the specified tile</li>
366: * <li>for the specified component</li>
367: * <li>default value</li>
368: * </ul>
369: *
370: * The value returned depends on the value of the variable 'type' which
371: * can take the following values :
372: *
373: * <ul>
374: * <li>SPEC_DEF -> Default value is returned. t and c values are
375: * ignored</li>
376: * <li>SPEC_COMP_DEF -> Component default value is returned. t value is
377: * ignored</li>
378: * <li>SPEC_TILE_DEF -> Tile default value is returned. c value is
379: * ignored</li>
380: * <li>SPEC_TILE_COMP -> Tile/Component value is returned.</li>
381: * </ul>
382: *
383: * @param type The type of the value we want to be returned
384: *
385: * @param t The tile index
386: *
387: * @param c the component index
388: *
389: * @return The code-block height for the specified tile and component
390: * */
391: public int getCBlkHeight(byte type, int t, int c) {
392: Integer dim[] = null;
393: switch (type) {
394: case SPEC_DEF:
395: dim = (Integer[]) getDefault();
396: break;
397: case SPEC_COMP_DEF:
398: dim = (Integer[]) getCompDef(c);
399: break;
400: case SPEC_TILE_DEF:
401: dim = (Integer[]) getTileDef(t);
402: break;
403: case SPEC_TILE_COMP:
404: dim = (Integer[]) getTileCompVal(t, c);
405: }
406: return dim[1].intValue();
407: }
408:
409: /**
410: * Sets default value for this module
411: *
412: * @param value Default value
413: * */
414: public void setDefault(Object value) {
415: super .setDefault(value);
416:
417: // Store the biggest code-block dimensions
418: storeHighestDims((Integer[]) value);
419: }
420:
421: /**
422: * Sets default value for specified tile and specValType tag if allowed by
423: * its priority.
424: *
425: * @param c Tile index.
426: *
427: * @param value Tile's default value
428: * */
429: public void setTileDef(int t, Object value) {
430: super .setTileDef(t, value);
431:
432: // Store the biggest code-block dimensions
433: storeHighestDims((Integer[]) value);
434: }
435:
436: /**
437: * Sets default value for specified component and specValType tag if
438: * allowed by its priority.
439: *
440: * @param c Component index
441: *
442: * @param value Component's default value
443: * */
444: public void setCompDef(int c, Object value) {
445: super .setCompDef(c, value);
446:
447: // Store the biggest code-block dimensions
448: storeHighestDims((Integer[]) value);
449: }
450:
451: /**
452: * Sets value for specified tile-component.
453: *
454: * @param t Tie index
455: *
456: * @param c Component index
457: *
458: * @param value Tile-component's value
459: * */
460: public void setTileCompVal(int t, int c, Object value) {
461: super .setTileCompVal(t, c, value);
462:
463: // Store the biggest code-block dimensions
464: storeHighestDims((Integer[]) value);
465: }
466:
467: /**
468: * Stores the highest code-block width and height
469: *
470: * @param dim The 2 elements array that contains the code-block width and
471: * height.
472: * */
473: private void storeHighestDims(Integer[] dim) {
474: // Store the biggest code-block dimensions
475: if (dim[0].intValue() > maxCBlkWidth) {
476: maxCBlkWidth = dim[0].intValue();
477: }
478: if (dim[1].intValue() > maxCBlkHeight) {
479: maxCBlkHeight = dim[1].intValue();
480: }
481: }
482: }
|