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.StringTokenizer; 046import java.util.Vector; 047 048import jj2000.j2k.IntegerSpec; 049import jj2000.j2k.ModuleSpec; 050import jj2000.j2k.codestream.ProgressionType; 051 052import com.github.jaiimageio.jpeg2000.impl.J2KImageWriteParamJava; 053 054/** 055 * This class extends ModuleSpec class for progression type(s) and progression 056 * order changes holding purposes. 057 * 058 * <P>It stores the progression type(s) used in the codestream. There can be 059 * only one progression type or several ones if progression order changes are 060 * used (POC markers). 061 * */ 062public class ProgressionSpec extends ModuleSpec { 063 064 /** 065 * Creates a new ProgressionSpec object for the specified number of tiles 066 * and components. 067 * 068 * @param nt The number of tiles 069 * 070 * @param nc The number of components 071 * 072 * @param type the type of the specification module i.e. tile specific, 073 * component specific or both. The ProgressionSpec class should only be 074 * used only with the type ModuleSpec.SPEC_TYPE_TILE. 075 * */ 076 public ProgressionSpec(int nt, int nc, byte type) { 077 super(nt, nc, type); 078 if ( type != ModuleSpec.SPEC_TYPE_TILE ) { 079 throw new Error("Illegal use of class ProgressionSpec !"); 080 } 081 } 082 083 /** 084 * Creates a new ProgressionSpec object for the specified number of 085 * tiles, components and the J2KImageWriteParamJava instance. 086 * 087 * @param nt The number of tiles 088 * 089 * @param nc The number of components 090 * 091 * @param nl The number of layer 092 * 093 * @param dls The number of decomposition levels specifications 094 * 095 * @param type the type of the specification module. The ProgressionSpec 096 * class should only be used only with the type ModuleSpec.SPEC_TYPE_TILE. 097 * 098 * @param wp The J2KImageWriteParamJava instance 099 * */ 100 public ProgressionSpec(int nt,int nc,int nl,IntegerSpec dls,byte type, 101 J2KImageWriteParamJava wp, String values){ 102 super(nt,nc,type); 103 104 specified = values; 105 106 String param = values; 107 Progression[] prog; 108 int mode=-1; 109 110 if(values == null){ // No parameter specified 111 if(wp.getROIs() == null) { 112 mode = checkProgMode("res"); 113 } 114 else { 115 mode = checkProgMode("layer"); 116 } 117 118 if(mode==-1){ 119 String errMsg = "Unknown progression type : '"+param+"'"; 120 throw new IllegalArgumentException(errMsg); 121 } 122 prog = new Progression[1]; 123 prog[0] = new Progression(mode,0,nc,0,dls.getMax()+1,nl); 124 setDefault(prog); 125 return; 126 } 127 128 StringTokenizer stk = new StringTokenizer(param); 129 byte curSpecType = SPEC_DEF; // Specification type of the 130 // current parameter 131 boolean[] tileSpec = null; // Tiles concerned by the specification 132 String word = null; // current word 133 String errMsg = null; // Error message 134 boolean needInteger = false; // True if an integer value is expected 135 int intType = 0; // Type of read integer value (0=index of first 136 // component, 1= index of first resolution level, 2=index of last 137 // layer, 3= index of last component, 4= index of last resolution 138 // level) 139 Vector progression = new Vector(); 140 int tmp = 0; 141 Progression curProg = null; 142 143 while(stk.hasMoreTokens()){ 144 word = stk.nextToken(); 145 146 switch(word.charAt(0)){ 147 case 't': 148 // If progression were previously found, store them 149 if(progression.size()>0){ 150 // Ensure that all information has been taken 151 curProg.ce = nc; 152 curProg.lye = nl; 153 curProg.re = dls.getMax()+1; 154 prog = new Progression[progression.size()]; 155 progression.copyInto(prog); 156 if(curSpecType==SPEC_DEF){ 157 setDefault(prog); 158 } 159 else if(curSpecType==SPEC_TILE_DEF){ 160 for(int i=tileSpec.length-1; i>=0; i--) 161 if(tileSpec[i]){ 162 setTileDef(i,prog); 163 } 164 } 165 } 166 progression.removeAllElements(); 167 intType=-1; 168 needInteger = false; 169 170 // Tiles specification 171 tileSpec = parseIdx(word,nTiles); 172 curSpecType = SPEC_TILE_DEF; 173 break; 174 default: 175 // Here, words is either a Integer (progression bound 176 // index) or a String (progression order type). This 177 // is determined by the value of needInteger. 178 if(needInteger){ // Progression bound info 179 try{ 180 tmp = (new Integer(word)).intValue(); 181 } 182 catch(NumberFormatException e){ 183 // Progression has missing parameters 184 throw new IllegalArgumentException("Progression "+ 185 "order"+ 186 " specification "+ 187 "has missing "+ 188 "parameters: "+ 189 param); 190 } 191 192 switch(intType){ 193 case 0: // cs 194 if(tmp<0 || tmp>dls.getMax()+1) 195 throw new 196 IllegalArgumentException("Invalid comp_start "+ 197 "in '-Aptype' option"); 198 curProg.cs = tmp; break; 199 case 1: // rs 200 if(tmp<0 || tmp>nc) 201 throw new 202 IllegalArgumentException("Invalid res_start "+ 203 "in '-Aptype' option"); 204 205 curProg.rs = tmp; break; 206 case 2: // lye 207 if(tmp<0) 208 throw new 209 IllegalArgumentException("Invalid layer_end "+ 210 "in '-Aptype' option"); 211 if (tmp>nl) { 212 tmp = nl; 213 } 214 curProg.lye = tmp; break; 215 case 3: // ce 216 if(tmp<0) 217 throw new 218 IllegalArgumentException("Invalid comp_end "+ 219 "in '-Aptype' option"); 220 if( tmp>(dls.getMax()+1)) { 221 tmp = dls.getMax()+1; 222 } 223 curProg.ce = tmp; break; 224 case 4: // re 225 if(tmp<0) 226 throw new 227 IllegalArgumentException("Invalid res_end "+ 228 "in '-Aptype' option"); 229 if (tmp>nc) { 230 tmp = nc; 231 } 232 curProg.re = tmp; break; 233 } 234 235 if(intType<4){ 236 intType++; 237 needInteger = true; 238 break; 239 } 240 else if(intType==4){ 241 intType = 0; 242 needInteger = false; 243 break; 244 } 245 else{ 246 throw new Error("Error in usage of 'Aptype' "+ 247 "option: "+param); 248 } 249 } 250 251 if(!needInteger){ // Progression type info 252 mode = checkProgMode(word); 253 if(mode==-1 ){ 254 errMsg = "Unknown progression type : '"+word+"'"; 255 throw new IllegalArgumentException(errMsg); 256 } 257 needInteger = true; 258 intType = 0; 259 if(progression.size()==0) 260 curProg = new Progression(mode,0,nc,0,dls.getMax()+1, 261 nl); 262 else{ 263 curProg = new Progression(mode,0,nc,0,dls.getMax()+1, 264 nl); 265 } 266 progression.addElement(curProg); 267 } 268 } // switch 269 } // while 270 271 if(progression.size()==0){ // No progression defined 272 // Set it arbitrarily to layer progressive 273 if(wp.getROIs() == null) { 274 mode = checkProgMode("res"); 275 } 276 else { 277 mode = checkProgMode("layer"); 278 } 279 280 if(mode==-1){ 281 errMsg = "Unknown progression type : '"+param+"'"; 282 throw new IllegalArgumentException(errMsg); 283 } 284 prog = new Progression[1]; 285 prog[0] = new Progression(mode,0,nc,0,dls.getMax()+1,nl); 286 setDefault(prog); 287 return; 288 } 289 290 // Ensure that all information has been taken 291 curProg.ce = nc; 292 curProg.lye = nl; 293 curProg.re = dls.getMax()+1; 294 295 // Store found progression 296 prog = new Progression[progression.size()]; 297 progression.copyInto(prog); 298 299 if(curSpecType==SPEC_DEF){ 300 setDefault(prog); 301 } 302 else if(curSpecType==SPEC_TILE_DEF){ 303 for(int i=tileSpec.length-1; i>=0; i--) 304 if(tileSpec[i]){ 305 setTileDef(i,prog); 306 } 307 } 308 309 // Check that default value has been specified 310 if(getDefault()==null){ 311 int ndefspec = 0; 312 for(int t=nt-1; t>=0; t--){ 313 for(int c=nc-1; c>=0 ; c--){ 314 if(specValType[t][c] == SPEC_DEF){ 315 ndefspec++; 316 } 317 } 318 } 319 320 // If some tile-component have received no specification, they are 321 // arbitrarily set to 'layer' progressive. 322 if(ndefspec!=0){ 323 if(wp.getROIs() == null) { 324 mode = checkProgMode("res"); 325 } else { 326 mode = checkProgMode("layer"); 327 } 328 if(mode==-1){ 329 errMsg = "Unknown progression type : '"+param+"'"; 330 throw new IllegalArgumentException(errMsg); 331 } 332 prog = new Progression[1]; 333 prog[0] = new Progression(mode,0,nc,0,dls.getMax()+1,nl); 334 setDefault(prog); 335 } 336 else{ 337 // All tile-component have been specified, takes the first 338 // tile-component value as default. 339 setDefault(getTileCompVal(0,0)); 340 switch(specValType[0][0]){ 341 case SPEC_TILE_DEF: 342 for(int c=nc-1; c>=0; c--){ 343 if(specValType[0][c]==SPEC_TILE_DEF) 344 specValType[0][c] = SPEC_DEF; 345 } 346 tileDef[0] = null; 347 break; 348 case SPEC_COMP_DEF: 349 for(int t=nt-1; t>=0; t--){ 350 if(specValType[t][0]==SPEC_COMP_DEF) 351 specValType[t][0] = SPEC_DEF; 352 } 353 compDef[0] = null; 354 break; 355 case SPEC_TILE_COMP: 356 specValType[0][0] = SPEC_DEF; 357 tileCompVal.put("t0c0",null); 358 break; 359 } 360 } 361 } 362 } 363 364 /** 365 * Check if the progression mode exists and if so, return its integer 366 * value. It returns -1 otherwise. 367 * 368 * @param mode The progression mode stored in a string 369 * 370 * @return The integer value of the progression mode or -1 if the 371 * progression mode does not exist. 372 * 373 * @see ProgressionType 374 * */ 375 private int checkProgMode(String mode) { 376 if(mode.equals("res")){ 377 return ProgressionType.RES_LY_COMP_POS_PROG; 378 } 379 else if( mode.equals("layer") ) { 380 return ProgressionType.LY_RES_COMP_POS_PROG; 381 } 382 else if( mode.equals("pos-comp") ) { 383 return ProgressionType.POS_COMP_RES_LY_PROG; 384 } 385 else if ( mode.equals("comp-pos") ) { 386 return ProgressionType.COMP_POS_RES_LY_PROG; 387 } 388 else if ( mode.equals("res-pos") ) { 389 return ProgressionType.RES_POS_COMP_LY_PROG; 390 } 391 else { 392 // No corresponding progression mode, we return -1. 393 return -1; 394 } 395 } 396}