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 * */ 043package jj2000.j2k.entropy; 044 045import java.util.*; 046 047import jj2000.j2k.codestream.*; 048import jj2000.j2k.wavelet.*; 049import jj2000.j2k.image.*; 050import jj2000.j2k.util.*; 051import jj2000.j2k.*; 052 053import 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 * */ 063public 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,byte type, 102 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 } 115 else { 116 mode = checkProgMode("layer"); 117 } 118 119 if(mode==-1){ 120 String errMsg = "Unknown progression type : '"+param+"'"; 121 throw new IllegalArgumentException(errMsg); 122 } 123 prog = new Progression[1]; 124 prog[0] = new Progression(mode,0,nc,0,dls.getMax()+1,nl); 125 setDefault(prog); 126 return; 127 } 128 129 StringTokenizer stk = new StringTokenizer(param); 130 byte curSpecType = SPEC_DEF; // Specification type of the 131 // current parameter 132 boolean[] tileSpec = null; // Tiles concerned by the specification 133 String word = null; // current word 134 String errMsg = null; // Error message 135 boolean needInteger = false; // True if an integer value is expected 136 int intType = 0; // Type of read integer value (0=index of first 137 // component, 1= index of first resolution level, 2=index of last 138 // layer, 3= index of last component, 4= index of last resolution 139 // level) 140 Vector progression = new Vector(); 141 int tmp = 0; 142 Progression curProg = null; 143 144 while(stk.hasMoreTokens()){ 145 word = stk.nextToken(); 146 147 switch(word.charAt(0)){ 148 case 't': 149 // If progression were previously found, store them 150 if(progression.size()>0){ 151 // Ensure that all information has been taken 152 curProg.ce = nc; 153 curProg.lye = nl; 154 curProg.re = dls.getMax()+1; 155 prog = new Progression[progression.size()]; 156 progression.copyInto(prog); 157 if(curSpecType==SPEC_DEF){ 158 setDefault(prog); 159 } 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 } 183 catch(NumberFormatException e){ 184 // Progression has missing parameters 185 throw new IllegalArgumentException("Progression "+ 186 "order"+ 187 " specification "+ 188 "has missing "+ 189 "parameters: "+ 190 param); 191 } 192 193 switch(intType){ 194 case 0: // cs 195 if(tmp<0 || tmp>dls.getMax()+1) 196 throw new 197 IllegalArgumentException("Invalid comp_start "+ 198 "in '-Aptype' option"); 199 curProg.cs = tmp; break; 200 case 1: // rs 201 if(tmp<0 || tmp>nc) 202 throw new 203 IllegalArgumentException("Invalid res_start "+ 204 "in '-Aptype' option"); 205 206 curProg.rs = tmp; break; 207 case 2: // lye 208 if(tmp<0) 209 throw new 210 IllegalArgumentException("Invalid layer_end "+ 211 "in '-Aptype' option"); 212 if (tmp>nl) { 213 tmp = nl; 214 } 215 curProg.lye = tmp; break; 216 case 3: // ce 217 if(tmp<0) 218 throw new 219 IllegalArgumentException("Invalid comp_end "+ 220 "in '-Aptype' option"); 221 if( tmp>(dls.getMax()+1)) { 222 tmp = dls.getMax()+1; 223 } 224 curProg.ce = tmp; break; 225 case 4: // re 226 if(tmp<0) 227 throw new 228 IllegalArgumentException("Invalid res_end "+ 229 "in '-Aptype' option"); 230 if (tmp>nc) { 231 tmp = nc; 232 } 233 curProg.re = tmp; break; 234 } 235 236 if(intType<4){ 237 intType++; 238 needInteger = true; 239 break; 240 } 241 else if(intType==4){ 242 intType = 0; 243 needInteger = false; 244 break; 245 } 246 else{ 247 throw new Error("Error in usage of 'Aptype' "+ 248 "option: "+param); 249 } 250 } 251 252 if(!needInteger){ // Progression type info 253 mode = checkProgMode(word); 254 if(mode==-1 ){ 255 errMsg = "Unknown progression type : '"+word+"'"; 256 throw new IllegalArgumentException(errMsg); 257 } 258 needInteger = true; 259 intType = 0; 260 if(progression.size()==0) 261 curProg = new Progression(mode,0,nc,0,dls.getMax()+1, 262 nl); 263 else{ 264 curProg = new Progression(mode,0,nc,0,dls.getMax()+1, 265 nl); 266 } 267 progression.addElement(curProg); 268 } 269 } // switch 270 } // while 271 272 if(progression.size()==0){ // No progression defined 273 // Set it arbitrarily to layer progressive 274 if(wp.getROIs() == null) { 275 mode = checkProgMode("res"); 276 } 277 else { 278 mode = checkProgMode("layer"); 279 } 280 281 if(mode==-1){ 282 errMsg = "Unknown progression type : '"+param+"'"; 283 throw new IllegalArgumentException(errMsg); 284 } 285 prog = new Progression[1]; 286 prog[0] = new Progression(mode,0,nc,0,dls.getMax()+1,nl); 287 setDefault(prog); 288 return; 289 } 290 291 // Ensure that all information has been taken 292 curProg.ce = nc; 293 curProg.lye = nl; 294 curProg.re = dls.getMax()+1; 295 296 // Store found progression 297 prog = new Progression[progression.size()]; 298 progression.copyInto(prog); 299 300 if(curSpecType==SPEC_DEF){ 301 setDefault(prog); 302 } 303 else if(curSpecType==SPEC_TILE_DEF){ 304 for(int i=tileSpec.length-1; i>=0; i--) 305 if(tileSpec[i]){ 306 setTileDef(i,prog); 307 } 308 } 309 310 // Check that default value has been specified 311 if(getDefault()==null){ 312 int ndefspec = 0; 313 for(int t=nt-1; t>=0; t--){ 314 for(int c=nc-1; c>=0 ; c--){ 315 if(specValType[t][c] == SPEC_DEF){ 316 ndefspec++; 317 } 318 } 319 } 320 321 // If some tile-component have received no specification, they are 322 // arbitrarily set to 'layer' progressive. 323 if(ndefspec!=0){ 324 if(wp.getROIs() == null) { 325 mode = checkProgMode("res"); 326 } else { 327 mode = checkProgMode("layer"); 328 } 329 if(mode==-1){ 330 errMsg = "Unknown progression type : '"+param+"'"; 331 throw new IllegalArgumentException(errMsg); 332 } 333 prog = new Progression[1]; 334 prog[0] = new Progression(mode,0,nc,0,dls.getMax()+1,nl); 335 setDefault(prog); 336 } 337 else{ 338 // All tile-component have been specified, takes the first 339 // tile-component value as default. 340 setDefault(getTileCompVal(0,0)); 341 switch(specValType[0][0]){ 342 case SPEC_TILE_DEF: 343 for(int c=nc-1; c>=0; c--){ 344 if(specValType[0][c]==SPEC_TILE_DEF) 345 specValType[0][c] = SPEC_DEF; 346 } 347 tileDef[0] = null; 348 break; 349 case SPEC_COMP_DEF: 350 for(int t=nt-1; t>=0; t--){ 351 if(specValType[t][0]==SPEC_COMP_DEF) 352 specValType[t][0] = SPEC_DEF; 353 } 354 compDef[0] = null; 355 break; 356 case SPEC_TILE_COMP: 357 specValType[0][0] = SPEC_DEF; 358 tileCompVal.put("t0c0",null); 359 break; 360 } 361 } 362 } 363 } 364 365 /** 366 * Check if the progression mode exists and if so, return its integer 367 * value. It returns -1 otherwise. 368 * 369 * @param mode The progression mode stored in a string 370 * 371 * @return The integer value of the progression mode or -1 if the 372 * progression mode does not exist. 373 * 374 * @see ProgressionType 375 * */ 376 private int checkProgMode(String mode) { 377 if(mode.equals("res")){ 378 return ProgressionType.RES_LY_COMP_POS_PROG; 379 } 380 else if( mode.equals("layer") ) { 381 return ProgressionType.LY_RES_COMP_POS_PROG; 382 } 383 else if( mode.equals("pos-comp") ) { 384 return ProgressionType.POS_COMP_RES_LY_PROG; 385 } 386 else if ( mode.equals("comp-pos") ) { 387 return ProgressionType.COMP_POS_RES_LY_PROG; 388 } 389 else if ( mode.equals("res-pos") ) { 390 return ProgressionType.RES_POS_COMP_LY_PROG; 391 } 392 else { 393 // No corresponding progression mode, we return -1. 394 return -1; 395 } 396 } 397}