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