001/* 002 * $RCSfile: AnWTFilter.java,v $ 003 * $Revision: 1.1 $ 004 * $Date: 2005/02/11 05:02:28 $ 005 * $State: Exp $ 006 * 007 * Class: AnWTFilter 008 * 009 * Description: The abstract class for all analysis wavelet filters 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 * 045 * 046 */ 047package jj2000.j2k.wavelet.analysis; 048 049import jj2000.j2k.wavelet.FilterTypes; 050import jj2000.j2k.wavelet.WaveletFilter; 051 052/** 053 * This abstract class defines the methods of all analysis wavelet 054 * filters. Specialized abstract classes that work on particular data 055 * types (int, float) provide more specific method calls while 056 * retaining the generality of this one. See the AnWTFilterInt 057 * and AnWTFilterFloat classes. Implementations of analysis 058 * filters should inherit from one of those classes. 059 * 060 * <P>All analysis wavelet filters should follow the following conventions: 061 * 062 * <P>- The first sample to filter is the low-pass one. As a 063 * consequence, if the input signal is of odd-length then the low-pass 064 * output signal is one sample longer than the high-pass output 065 * one. Therefore, if the length of input signal is N, the low-pass 066 * output signal is of length N/2 if N is even and N/2+1/2 if N is 067 * odd, while the high-pass output signal is of length N/2 if N is 068 * even and N/2-1/2 if N is odd. 069 * 070 * <P>- The normalization is 1 for the DC gain and 2 for the Nyquist 071 * gain (Type I normalization), for both reversible and non-reversible 072 * filters. 073 * 074 * <P>If the length of input signal is N, the low-pass output signal 075 * is of length N/2 if N is even and N/2+1/2 if N is odd, while the 076 * high-pass output sample is of length N/2 if N is even and N/2-1/2 077 * if N is odd. 078 * 079 * <P>The analyze method may seem very complicated, but is designed to 080 * minimize the amount of data copying and redundant calculations when 081 * used for block-based or line-based wavelet transform 082 * implementations, while being applicable to full-frame transforms as 083 * well. 084 * 085 * <P>All filters should implement the equals() method of the Object 086 * class. The call x.equals(y) should test if the 'x' and 'y' filters are the 087 * same or not, in what concerns the bit stream header syntax (two filters are 088 * the same if the same filter code should be output to the bit stream). 089 * 090 * @see AnWTFilterInt 091 * 092 * @see AnWTFilterFloat 093 * */ 094public abstract class AnWTFilter implements WaveletFilter{ 095 096 /** The prefix for wavelet filter options: 'F' */ 097 public final static char OPT_PREFIX = 'F'; 098 099 /** The list of parameters that is accepted for wavelet filters. Options 100 * for wavelet filters start with a 'F'. */ 101 private final static String [][] pinfo = { 102 { "Ffilters", "[<tile-component idx>] <id> "+ 103 "[ [<tile-component idx>] <id> ...]", 104 "Specifies which filters to use for specified tile-component.\n"+ 105 "<tile-component idx>: see general note\n"+ 106 "<id>: ',' separates horizontal and vertical filters, ':' separates"+ 107 " decomposition levels filters. JPEG 2000 part I only supports w5x3"+ 108 " and w9x7 filters.",null}, 109 }; 110 111 /** 112 * Filters the input signal by this analysis filter, decomposing 113 * it in a low-pass and a high-pass signal. This method performs 114 * the filtering and the subsampling with the low pass first 115 * filtering convention. 116 * 117 * <P>The input signal resides in the inSig array. The index of 118 * the first sample to filter (i.e. that will generate the first 119 * low-pass output sample) is given by inOff. The number of 120 * samples to filter is given by inLen. This array must be of the 121 * same type as the one for which the particular implementation 122 * works with (which is returned by the getDataType() method). 123 * 124 * <P>The input signal can be interleaved with other signals in 125 * the same inSig array, and this is determined by the inStep 126 * argument. This means that the first sample of the input signal 127 * is inSig[inOff], the second is inSig[inOff+inStep], the third 128 * is inSig[inOff+2*inStep], and so on. Therefore if inStep is 1 129 * there is no interleaving. This feature allows to filter columns 130 * of a 2-D signal, when it is stored in a line by line order in 131 * inSig, without having to copy the data, in this case the inStep 132 * argument should be the line width. 133 * 134 * <P>This method also allows to apply the analysis wavelet filter 135 * by parts in the input signal using an overlap and thus 136 * producing the same coefficients at the output. The tailOvrlp 137 * argument specifies how many samples in the input signal, before 138 * the first one to be filtered, can be used for overlap. Then, 139 * the filter instead of extending the input signal will use those 140 * samples to calculate the first output samples. The argument 141 * tailOvrlp can be 0 for no overlap, or some value that provides 142 * partial or full overlap. There should be enough samples in the 143 * input signal, before the first sample to be filtered, to 144 * support the overlap. The headOvrlp provides the same 145 * functionality but at the end of the input signal. The inStep 146 * argument also applies to samples used for overlap. This overlap 147 * feature can be used for line-based wavelet transforms (in which 148 * case it will only be used when filtering the columns) or for 149 * overlapping block-based wavelet transforms (in which case it 150 * will be used when filtering lines and columns). 151 * 152 * <P>The low-pass output signal is placed in the lowSig 153 * array. The lowOff and lowStep arguments are analogous to the 154 * inOff and inStep ones, but they apply to the lowSig array. The 155 * lowSig array must be long enough to hold the low-pass output 156 * signal. 157 * 158 * <P>The high-pass output signal is placed in the highSig 159 * array. The highOff and highStep arguments are analogous to the 160 * inOff and inStep ones, but they apply to the highSig array. The 161 * highSig array must be long enough to hold the high-pass output 162 * signal. 163 * 164 * @param inSig This is the array that contains the input 165 * signal. It must be of the correct type (e.g., it must be int[] 166 * if getDataType() returns TYPE_INT). 167 * 168 * @param inOff This is the index in inSig of the first sample to 169 * filter. 170 * 171 * @param inLen This is the number of samples in the input signal 172 * to filter. 173 * 174 * @param inStep This is the step, or interleave factor, of the 175 * input signal samples in the inSig array. See above. 176 * 177 * @param tailOvrlp This is the number of samples in the input 178 * signal before the first sample to filter that can be used for 179 * overlap. See above. 180 * 181 * @param headOvrlp This is the number of samples in the input 182 * signal after the last sample to filter that can be used for 183 * overlap. See above. 184 * 185 * @param lowSig This is the array where the low-pass output 186 * signal is placed. It must be of the same type as inSig and it 187 * should be long enough to contain the output signal. 188 * 189 * @param lowOff This is the index in lowSig of the element where 190 * to put the first low-pass output sample. 191 * 192 * @param lowStep This is the step, or interleave factor, of the 193 * low-pass output samples in the lowSig array. See above. 194 * 195 * @param highSig This is the array where the high-pass output 196 * signal is placed. It must be of the same type as inSig and it 197 * should be long enough to contain the output signal. 198 * 199 * @param highOff This is the index in highSig of the element where 200 * to put the first high-pass output sample. 201 * 202 * @param highStep This is the step, or interleave factor, of the 203 * high-pass output samples in the highSig array. See above. 204 * 205 * @see WaveletFilter#getDataType 206 * 207 * 208 * 209 * 210 * */ 211 public abstract 212 void analyze_lpf(Object inSig, int inOff, int inLen, int inStep, 213 Object lowSig, int lowOff, int lowStep, 214 Object highSig, int highOff, int highStep); 215 216 /** 217 * Filters the input signal by this analysis filter, decomposing 218 * it in a low-pass and a high-pass signal. This method performs 219 * the filtering and the subsampling with the high pass first filtering 220 * convention. 221 * 222 * <P>The input signal resides in the inSig array. The index of 223 * the first sample to filter (i.e. that will generate the first 224 * high-pass output sample) is given by inOff. The number of 225 * samples to filter is given by inLen. This array must be of the 226 * same type as the one for which the particular implementation 227 * works with (which is returned by the getDataType() method). 228 * 229 * <P>The input signal can be interleaved with other signals in 230 * the same inSig array, and this is determined by the inStep 231 * argument. This means that the first sample of the input signal 232 * is inSig[inOff], the second is inSig[inOff+inStep], the third 233 * is inSig[inOff+2*inStep], and so on. Therefore if inStep is 1 234 * there is no interleaving. This feature allows to filter columns 235 * of a 2-D signal, when it is stored in a line by line order in 236 * inSig, without having to copy the data, in this case the inStep 237 * argument should be the line width. 238 * 239 * <P>The low-pass output signal is placed in the lowSig 240 * array. The lowOff and lowStep arguments are analogous to the 241 * inOff and inStep ones, but they apply to the lowSig array. The 242 * lowSig array must be long enough to hold the low-pass output 243 * signal. 244 * 245 * <P>The high-pass output signal is placed in the highSig 246 * array. The highOff and highStep arguments are analogous to the 247 * inOff and inStep ones, but they apply to the highSig array. The 248 * highSig array must be long enough to hold the high-pass output 249 * signal. 250 * 251 * @param inSig This is the array that contains the input 252 * signal. It must be of the correct type (e.g., it must be int[] 253 * if getDataType() returns TYPE_INT). 254 * 255 * @param inOff This is the index in inSig of the first sample to 256 * filter. 257 * 258 * @param inLen This is the number of samples in the input signal 259 * to filter. 260 * 261 * @param inStep This is the step, or interleave factor, of the 262 * input signal samples in the inSig array. See above. 263 * 264 * @param lowSig This is the array where the low-pass output 265 * signal is placed. It must be of the same type as inSig and it 266 * should be long enough to contain the output signal. 267 * 268 * @param lowOff This is the index in lowSig of the element where 269 * to put the first low-pass output sample. 270 * 271 * @param lowStep This is the step, or interleave factor, of the 272 * low-pass output samples in the lowSig array. See above. 273 * 274 * @param highSig This is the array where the high-pass output 275 * signal is placed. It must be of the same type as inSig and it 276 * should be long enough to contain the output signal. 277 * 278 * @param highOff This is the index in highSig of the element where 279 * to put the first high-pass output sample. 280 * 281 * @param highStep This is the step, or interleave factor, of the 282 * high-pass output samples in the highSig array. See above. 283 * 284 * @see WaveletFilter#getDataType 285 * 286 * 287 * 288 * 289 * */ 290 public abstract 291 void analyze_hpf(Object inSig, int inOff, int inLen, int inStep, 292 Object lowSig, int lowOff, int lowStep, 293 Object highSig, int highOff, int highStep); 294 295 /** 296 * Returns the time-reversed low-pass synthesis waveform of the 297 * filter, which is the low-pass filter. This is the time-reversed 298 * impulse response of the low-pass synthesis filter. It is used 299 * to calculate the L2-norm of the synthesis basis functions for a 300 * particular subband (also called energy weight). 301 * 302 * <P>The returned array may not be modified (i.e. a reference to 303 * the internal array may be returned by the implementation of 304 * this method). 305 * 306 * @return The time-reversed low-pass synthesis waveform of the 307 * filter. 308 * 309 * 310 * */ 311 public abstract float[] getLPSynthesisFilter(); 312 313 /** 314 * Returns the time-reversed high-pass synthesis waveform of the 315 * filter, which is the high-pass filter. This is the 316 * time-reversed impulse response of the high-pass synthesis 317 * filter. It is used to calculate the L2-norm of the synthesis 318 * basis functions for a particular subband (also called energy 319 * weight). 320 * 321 * <P>The returned array may not be modified (i.e. a reference to 322 * the internal array may be returned by the implementation of 323 * this method). 324 * 325 * @return The time-reversed high-pass synthesis waveform of the 326 * filter. 327 * 328 * 329 * */ 330 public abstract float[] getHPSynthesisFilter(); 331 332 /** 333 * Returns the equivalent low-pass synthesis waveform of a cascade 334 * of filters, given the syhthesis waveform of the previous 335 * stage. This is the result of upsampling 'in' by 2, and 336 * concolving it with the low-pass synthesis waveform of the 337 * filter. The length of the returned signal is 2*in_l+lp_l-2, 338 * where in_l is the length of 'in' and 'lp_l' is the lengthg of 339 * the low-pass synthesis filter. 340 * 341 * <P>The length of the low-pass synthesis filter is 342 * getSynLowNegSupport()+getSynLowPosSupport(). 343 * 344 * @param in The synthesis waveform of the previous stage. 345 * 346 * @param out If non-null this array is used to store the 347 * resulting signal. It must be long enough, or an 348 * IndexOutOfBoundsException is thrown. 349 * 350 * @see #getSynLowNegSupport 351 * 352 * @see #getSynLowPosSupport 353 * 354 * 355 * */ 356 public float[] getLPSynWaveForm(float in[], float out[]) { 357 return upsampleAndConvolve(in,getLPSynthesisFilter(),out); 358 } 359 360 /** 361 * Returns the equivalent high-pass synthesis waveform of a 362 * cascade of filters, given the syhthesis waveform of the 363 * previous stage. This is the result of upsampling 'in' by 2, and 364 * concolving it with the high-pass synthesis waveform of the 365 * filter. The length of the returned signal is 2*in_l+hp_l-2, 366 * where in_l is the length of 'in' and 'hp_l' is the lengthg of 367 * the high-pass synthesis filter. 368 * 369 * <P>The length of the high-pass synthesis filter is 370 * getSynHighNegSupport()+getSynHighPosSupport(). 371 * 372 * @param in The synthesis waveform of the previous stage. 373 * 374 * @param out If non-null this array is used to store the 375 * resulting signal. It must be long enough, or an 376 * IndexOutOfBoundsException is thrown. 377 * 378 * @see #getSynHighNegSupport 379 * 380 * @see #getSynHighPosSupport 381 * 382 * 383 * */ 384 public float[] getHPSynWaveForm(float in[], float out[]) { 385 return upsampleAndConvolve(in,getHPSynthesisFilter(),out); 386 } 387 388 /** 389 * Returns the signal resulting of upsampling (by 2) the input 390 * signal 'in' and then convolving it with the time-reversed 391 * signal 'wf'. The returned signal is of length l_in*2+l_wf-2, 392 * where l_in is the length of 'in', and l_wf is the length of 393 * 'wf'. 394 * 395 * <P>The 'wf' signal has to be already time-reversed, therefore 396 * only a dot-product is performed (instead of a 397 * convolution). This is equivalent to convolving with the 398 * non-time-reversed 'wf' signal. 399 * 400 * @param in The signal to upsample and filter. If null it is 401 * considered to be a dirac. 402 * 403 * @param wf The time-reversed impulse response used for 404 * filtering. 405 * 406 * @param out If non-null this array is used to store the 407 * resulting signal, it must be of length in.length*2+wf.length-2 408 * at least. An IndexOutOfBoundsException is thrown if this is not 409 * the case. 410 * 411 * @return The resulting signal, of length in.length*2+wf.length-2 412 * 413 * 414 * */ 415 private static 416 float[] upsampleAndConvolve(float in[], float wf[], float out[]) { 417 // NOTE: the effective length of the signal 'in' upsampled by 418 // 2 is 2*in.length-1 (not 2*in.length), so the resulting signal 419 // (after convolution) is of length 2*in.length-1+wf.length-1, 420 // which is 2*in.length+wf.length-2 421 422 int i,k,j; 423 float tmp; 424 int maxi,maxk; 425 426 // If in null, then simulate dirac 427 if (in == null) { 428 in = new float[1]; 429 in[0] = 1.0f; 430 } 431 432 // Get output buffer if necessary 433 if (out == null) { 434 out = new float[in.length*2+wf.length-2]; 435 } 436 // Convolve the signals 437 for (i=0, maxi=in.length*2+wf.length-2; i<maxi; i++) { 438 tmp = 0.0f; 439 440 // Calculate limits of loop below 441 k = (i-wf.length+2)/2; 442 if (k<0) k = 0; 443 maxk = i/2+1; 444 if (maxk > in.length) maxk = in.length; 445 446 // Calculate dot-product with upsampling of 'in' by 2. 447 for (j = 2*k-i+wf.length-1; k<maxk; k++, j+=2) { 448 tmp += in[k]*wf[j]; 449 } 450 // Store result 451 out[i] = tmp; 452 } 453 454 return out; 455 } 456 457 /** 458 * Returns the type of filter used according to the FilterTypes 459 * interface. 460 * 461 * @see FilterTypes 462 * 463 * @return The filter type. 464 * 465 */ 466 public abstract int getFilterType(); 467 468 /** 469 * Returns the parameters that are used in this class and 470 * implementing classes. It returns a 2D String array. Each of the 471 * 1D arrays is for a different option, and they have 3 472 * elements. The first element is the option name, the second one 473 * is the synopsis, the third one is a long description of what 474 * the parameter is and the fourth is its default value. The 475 * synopsis or description may be 'null', in which case it is 476 * assumed that there is no synopsis or description of the option, 477 * respectively. Null may be returned if no options are supported. 478 * 479 * @return the options name, their synopsis and their explanation, 480 * or null if no options are supported. 481 * 482 * 483 * */ 484 public static String[][] getParameterInfo() { 485 return pinfo; 486 } 487 488}