001/* 002 * $RCSfile: Dequantizer.java,v $ 003 * $Revision: 1.1 $ 004 * $Date: 2005/02/11 05:02:18 $ 005 * $State: Exp $ 006 * 007 * Class: Dequantizer 008 * 009 * Description: The abstract class for all dequantizers. 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 */ 044package jj2000.j2k.quantization.dequantizer; 045import jj2000.j2k.image.invcomptransf.*; 046import jj2000.j2k.wavelet.synthesis.*; 047import jj2000.j2k.entropy.decoder.*; 048import jj2000.j2k.codestream.*; 049import jj2000.j2k.entropy.*; 050import jj2000.j2k.decoder.*; 051import jj2000.j2k.wavelet.*; 052import jj2000.j2k.image.*; 053import jj2000.j2k.io.*; 054import jj2000.j2k.*; 055 056import java.io.*; 057 058/** 059 * This is the abstract class from which all dequantizers must inherit. This 060 * class has the concept of a current tile and all operations are performed on 061 * the current tile. 062 * 063 * <p>This class provides default implemenations for most of the methods 064 * (wherever it makes sense), under the assumption that the image and 065 * component dimensions, and the tiles, are not modifed by the dequantizer. If 066 * that is not the case for a particular implementation then the methods 067 * should be overriden.</p> 068 * 069 * <p>Sign magnitude representation is used (instead of two's complement) for 070 * the input data. The most significant bit is used for the sign (0 if 071 * positive, 1 if negative). Then the magnitude of the quantized coefficient 072 * is stored in the next most significat bits. The most significant magnitude 073 * bit corresponds to the most significant bit-plane and so on.</p> 074 * 075 * <p>The output data is either in floating-point, or in fixed-point two's 076 * complement. In case of floating-point data the the value returned by 077 * getFixedPoint() must be 0. If the case of fixed-point data the number of 078 * fractional bits must be defined at the constructor of the implementing 079 * class and all operations must be performed accordingly. Each component may 080 * have a different number of fractional bits.</p> 081 * */ 082public abstract class Dequantizer extends MultiResImgDataAdapter 083 implements CBlkWTDataSrcDec { 084 085 /** The prefix for dequantizer options: 'Q' */ 086 public final static char OPT_PREFIX = 'Q'; 087 088 /** The list of parameters that is accepted by the bit stream 089 * readers. They start with 'Q' */ 090 private static final String [][] pinfo = null; 091 092 /** The entropy decoder from where to get the quantized data (the 093 * source). */ 094 protected CBlkQuantDataSrcDec src; 095 096 /** The "range bits" for each transformed component */ 097 protected int rb[] = null; 098 099 /** The "range bits" for each un-transformed component */ 100 protected int utrb[] = null; 101 102 /** The inverse component transformation specifications */ 103 private CompTransfSpec cts; 104 105 /** Reference to the wavelet filter specifications */ 106 private SynWTFilterSpec wfs; 107 108 /** 109 * Initializes the source of compressed data. 110 * 111 * @param src From where to obtain the quantized data. 112 * 113 * @param rb The number of "range bits" for each component (must be the 114 * "range bits" of the un-transformed components. For a definition of 115 * "range bits" see the getNomRangeBits() method. 116 * 117 * @see #getNomRangeBits 118 * */ 119 public Dequantizer(CBlkQuantDataSrcDec src,int utrb[], 120 DecoderSpecs decSpec) { 121 super(src); 122 if (utrb.length != src.getNumComps()) { 123 throw new IllegalArgumentException(); 124 } 125 this.src = src; 126 this.utrb = utrb; 127 this.cts = decSpec.cts; 128 this.wfs = decSpec.wfs; 129 } 130 131 /** 132 * Returns the number of bits, referred to as the "range bits", 133 * corresponding to the nominal range of the data in the specified 134 * component. 135 * 136 * <p>The returned value corresponds to the nominal dynamic range of the 137 * reconstructed image data, not of the wavelet coefficients 138 * themselves. This is because different subbands have different gains and 139 * thus different nominal ranges. To have an idea of the nominal range in 140 * each subband the subband analysis gain value from the subband tree 141 * structure, returned by the getSynSubbandTree() method, can be used. See 142 * the Subband class for more details.</p> 143 * 144 * <p>If this number is <i>b</b> then for unsigned data the nominal range 145 * is between 0 and 2^b-1, and for signed data it is between -2^(b-1) and 146 * 2^(b-1)-1.</p> 147 * 148 * @param c The index of the component 149 * 150 * @return The number of bits corresponding to the nominal range of the 151 * data. 152 * 153 * @see Subband 154 * */ 155 public int getNomRangeBits(int c) { 156 return rb[c]; 157 } 158 159 /** 160 * Returns the subband tree, for the specified tile-component. This method 161 * returns the root element of the subband tree structure, see Subband and 162 * SubbandSyn. The tree comprises all the available resolution levels. 163 * 164 * <P>The number of magnitude bits ('magBits' member variable) for each 165 * subband may have not been not initialized (it depends on the actual 166 * dequantizer and its implementation). However, they are not necessary 167 * for the subsequent steps in the decoder chain. 168 * 169 * @param t The index of the tile, from 0 to T-1. 170 * 171 * @param c The index of the component, from 0 to C-1. 172 * 173 * @return The root of the tree structure. 174 * */ 175 public SubbandSyn getSynSubbandTree(int t,int c) { 176 return src.getSynSubbandTree(t,c); 177 } 178 179 /** 180 * Returns the horizontal code-block partition origin. Allowable values 181 * are 0 and 1, nothing else. 182 * */ 183 public int getCbULX() { 184 return src.getCbULX(); 185 } 186 187 /** 188 * Returns the vertical code-block partition origin. Allowable values are 189 * 0 and 1, nothing else. 190 * */ 191 public int getCbULY() { 192 return src.getCbULY(); 193 } 194 195 /** 196 * Returns the parameters that are used in this class and 197 * implementing classes. It returns a 2D String array. Each of the 198 * 1D arrays is for a different option, and they have 3 199 * elements. The first element is the option name, the second one 200 * is the synopsis and the third one is a long description of what 201 * the parameter is. The synopsis or description may be 'null', in 202 * which case it is assumed that there is no synopsis or 203 * description of the option, respectively. Null may be returned 204 * if no options are supported. 205 * 206 * @return the options name, their synopsis and their explanation, 207 * or null if no options are supported. 208 * */ 209 public static String[][] getParameterInfo() { 210 return pinfo; 211 } 212 213 /** 214 * Changes the current tile, given the new indexes. An 215 * IllegalArgumentException is thrown if the indexes do not 216 * correspond to a valid tile. 217 * 218 * <P>This default implementation changes the tile in the source 219 * and re-initializes properly component transformation variables.. 220 * 221 * @param x The horizontal index of the tile. 222 * 223 * @param y The vertical index of the new tile. 224 * */ 225 public void setTile(int x, int y) { 226 src.setTile(x,y); 227 tIdx = getTileIdx(); // index of the current tile 228 229 // initializations 230 int cttype = 0; 231 if( ((Integer)cts.getTileDef(tIdx)).intValue()==InvCompTransf.NONE ) 232 cttype = InvCompTransf.NONE; 233 else { 234 int nc = src.getNumComps() > 3 ? 3 : src.getNumComps(); 235 int rev = 0; 236 for(int c=0; c<nc; c++) 237 rev += (wfs.isReversible(tIdx,c)?1:0); 238 if(rev==3){ 239 // All WT are reversible 240 cttype = InvCompTransf.INV_RCT; 241 } 242 else if(rev==0){ 243 // All WT irreversible 244 cttype = InvCompTransf.INV_ICT; 245 } 246 else{ 247 // Error 248 throw new IllegalArgumentException("Wavelet transformation "+ 249 "and "+ 250 "component transformation"+ 251 " not coherent in tile"+ 252 tIdx); 253 } 254 } 255 256 switch(cttype){ 257 case InvCompTransf.NONE: 258 rb = utrb; 259 break; 260 case InvCompTransf.INV_RCT: 261 rb = InvCompTransf. 262 calcMixedBitDepths(utrb,InvCompTransf.INV_RCT,null); 263 break; 264 case InvCompTransf.INV_ICT: 265 rb = InvCompTransf. 266 calcMixedBitDepths(utrb,InvCompTransf.INV_ICT,null); 267 break; 268 default: 269 throw new IllegalArgumentException("Non JPEG 2000 part I "+ 270 "component"+ 271 " transformation for tile: "+ 272 tIdx); 273 } 274 } 275 276 /** 277 * Advances to the next tile, in standard scan-line order (by rows then 278 * columns). An NoNextElementException is thrown if the current tile is 279 * the last one (i.e. there is no next tile). 280 * 281 * <P>This default implementation just advances to the next tile in the 282 * source and re-initializes properly component transformation variables. 283 * */ 284 public void nextTile() { 285 src.nextTile(); 286 tIdx = getTileIdx(); // index of the current tile 287 288 // initializations 289 int cttype = ((Integer)cts.getTileDef(tIdx)).intValue(); 290 switch(cttype){ 291 case InvCompTransf.NONE: 292 rb = utrb; 293 break; 294 case InvCompTransf.INV_RCT: 295 rb = InvCompTransf. 296 calcMixedBitDepths(utrb,InvCompTransf.INV_RCT,null); 297 break; 298 case InvCompTransf.INV_ICT: 299 rb = InvCompTransf. 300 calcMixedBitDepths(utrb,InvCompTransf.INV_ICT,null); 301 break; 302 default: 303 throw new IllegalArgumentException("Non JPEG 2000 part I "+ 304 "component"+ 305 " transformation for tile: "+ 306 tIdx); 307 } 308 } 309 310}