001/* 002 * $RCSfile: AnWTFilterIntLift5x3.java,v $ 003 * $Revision: 1.1 $ 004 * $Date: 2005/02/11 05:02:29 $ 005 * $State: Exp $ 006 * 007 * Class: AnWTFilterIntLift5x3 008 * 009 * Description: An analyzing wavelet filter implementing the 010 * lifting 5x3 transform. 011 * 012 * 013 * 014 * COPYRIGHT: 015 * 016 * This software module was originally developed by Raphaël Grosbois and 017 * Diego Santa Cruz (Swiss Federal Institute of Technology-EPFL); Joel 018 * Askelöf (Ericsson Radio Systems AB); and Bertrand Berthelot, David 019 * Bouchard, Félix Henry, Gerard Mozelle and Patrice Onno (Canon Research 020 * Centre France S.A) in the course of development of the JPEG2000 021 * standard as specified by ISO/IEC 15444 (JPEG 2000 Standard). This 022 * software module is an implementation of a part of the JPEG 2000 023 * Standard. Swiss Federal Institute of Technology-EPFL, Ericsson Radio 024 * Systems AB and Canon Research Centre France S.A (collectively JJ2000 025 * Partners) agree not to assert against ISO/IEC and users of the JPEG 026 * 2000 Standard (Users) any of their rights under the copyright, not 027 * including other intellectual property rights, for this software module 028 * with respect to the usage by ISO/IEC and Users of this software module 029 * or modifications thereof for use in hardware or software products 030 * claiming conformance to the JPEG 2000 Standard. Those intending to use 031 * this software module in hardware or software products are advised that 032 * their use may infringe existing patents. The original developers of 033 * this software module, JJ2000 Partners and ISO/IEC assume no liability 034 * for use of this software module or modifications thereof. No license 035 * or right to this software module is granted for non JPEG 2000 Standard 036 * conforming products. JJ2000 Partners have full right to use this 037 * software module for his/her own purpose, assign or donate this 038 * software module to any third party and to inhibit third parties from 039 * using this software module for non JPEG 2000 Standard conforming 040 * products. This copyright notice must be included in all copies or 041 * derivative works of this software module. 042 * 043 * Copyright (c) 1999/2000 JJ2000 Partners. 044 * */ 045package jj2000.j2k.wavelet.analysis; 046 047import jj2000.j2k.wavelet.*; 048import jj2000.j2k.image.*; 049import jj2000.j2k.*; 050import jj2000.j2k.codestream.writer.*; 051 052/** 053 * This class inherits from the analysis wavelet filter definition for int 054 * data. It implements the forward wavelet transform specifically for the 5x3 055 * filter. The implementation is based on the lifting scheme. 056 * 057 * <P>See the AnWTFilter class for details such as normalization, how to split 058 * odd-length signals, etc. In particular, this method assumes that the 059 * low-pass coefficient is computed first. 060 * 061 * @see AnWTFilter 062 * @see AnWTFilterInt 063 * */ 064public class AnWTFilterIntLift5x3 extends AnWTFilterInt { 065 066 /** The low-pass synthesis filter of the 5x3 wavelet transform */ 067 private final static float LPSynthesisFilter[] = 068 { 0.5f, 1f, 0.5f }; 069 070 /** The high-pass synthesis filter of the 5x3 wavelet transform */ 071 private final static float HPSynthesisFilter[] = 072 { -0.125f, -0.25f, 0.75f, -0.25f, -0.125f }; 073 074 /** 075 * An implementation of the analyze_lpf() method that works on int data, 076 * for the forward 5x3 wavelet transform using the lifting scheme. See the 077 * general description of the analyze_lpf() method in the AnWTFilter class 078 * for more details. 079 * 080 * <P>The coefficients of the first lifting step are [-1/2 1 -1/2]. 081 * 082 * <P>The coefficients of the second lifting step are [1/4 1 1/4]. 083 * 084 * @param inSig This is the array that contains the input 085 * signal. 086 * 087 * @param inOff This is the index in inSig of the first sample to 088 * filter. 089 * 090 * @param inLen This is the number of samples in the input signal 091 * to filter. 092 * 093 * @param inStep This is the step, or interleave factor, of the 094 * input signal samples in the inSig array. 095 * 096 * @param lowSig This is the array where the low-pass output 097 * signal is placed. 098 * 099 * @param lowOff This is the index in lowSig of the element where 100 * to put the first low-pass output sample. 101 * 102 * @param lowStep This is the step, or interleave factor, of the 103 * low-pass output samples in the lowSig array. 104 * 105 * @param highSig This is the array where the high-pass output 106 * signal is placed. 107 * 108 * @param highOff This is the index in highSig of the element where 109 * to put the first high-pass output sample. 110 * 111 * @param highStep This is the step, or interleave factor, of the 112 * high-pass output samples in the highSig array. 113 * */ 114 public 115 void analyze_lpf(int inSig[], int inOff, int inLen, int inStep, 116 int lowSig[], int lowOff, int lowStep, 117 int highSig[], int highOff, int highStep) { 118 int i; 119 int iStep = 2 * inStep; //Subsampling in inSig 120 int ik; //Indexing inSig 121 int lk; //Indexing lowSig 122 int hk; //Indexing highSig 123 124 /* 125 *Generate high frequency subband 126 */ 127 128 //Initialize counters 129 ik = inOff + inStep; 130 hk = highOff; 131 132 //Apply first lifting step to each "inner" sample. 133 for(i = 1; i < inLen-1; i += 2) { 134 highSig[hk] = inSig[ik] - 135 ((inSig[ik-inStep] + inSig[ik+inStep])>>1); 136 137 ik += iStep; 138 hk += highStep; 139 } 140 141 //Handle head boundary effect if input signal has even length. 142 if( inLen % 2 == 0 ) { 143 highSig[hk] = inSig[ik] - ((2*inSig[ik-inStep])>>1); 144 } 145 146 /* 147 *Generate low frequency subband 148 */ 149 150 //Initialize counters 151 ik = inOff; 152 lk = lowOff; 153 hk = highOff; 154 155 if(inLen>1) { 156 lowSig[lk] = inSig[ik] + ((highSig[hk] + 1)>>1); 157 } 158 else { 159 lowSig[lk] = inSig[ik]; 160 } 161 162 ik += iStep; 163 lk += lowStep; 164 hk += highStep; 165 166 //Apply lifting step to each "inner" sample. 167 for(i = 2; i < inLen-1; i += 2) { 168 lowSig[lk] = inSig[ik] + 169 ((highSig[hk-highStep] + highSig[hk] + 2)>> 2); 170 171 ik += iStep; 172 lk += lowStep; 173 hk += highStep; 174 } 175 176 //Handle head boundary effect if input signal has odd length. 177 if(inLen % 2 == 1) { 178 if(inLen>2) { 179 lowSig[lk] = inSig[ik] + ((2*highSig[hk-highStep]+2)>>2); 180 } 181 } 182 } 183 184 /** 185 * An implementation of the analyze_hpf() method that works on int data, 186 * for the forward 5x3 wavelet transform using the lifting scheme. See the 187 * general description of the analyze_hpf() method in the AnWTFilter class 188 * for more details. 189 * 190 * <P>The coefficients of the first lifting step are [-1/2 1 -1/2]. 191 * 192 * <P>The coefficients of the second lifting step are [1/4 1 1/4]. 193 * 194 * @param inSig This is the array that contains the input 195 * signal. 196 * 197 * @param inOff This is the index in inSig of the first sample to 198 * filter. 199 * 200 * @param inLen This is the number of samples in the input signal 201 * to filter. 202 * 203 * @param inStep This is the step, or interleave factor, of the 204 * input signal samples in the inSig array. 205 * 206 * @param lowSig This is the array where the low-pass output 207 * signal is placed. 208 * 209 * @param lowOff This is the index in lowSig of the element where 210 * to put the first low-pass output sample. 211 * 212 * @param lowStep This is the step, or interleave factor, of the 213 * low-pass output samples in the lowSig array. 214 * 215 * @param highSig This is the array where the high-pass output 216 * signal is placed. 217 * 218 * @param highOff This is the index in highSig of the element where 219 * to put the first high-pass output sample. 220 * 221 * @param highStep This is the step, or interleave factor, of the 222 * high-pass output samples in the highSig array. 223 * 224 * @see AnWTFilter#analyze_hpf 225 * */ 226 public 227 void analyze_hpf(int inSig[], int inOff, int inLen, int inStep, 228 int lowSig[], int lowOff, int lowStep, 229 int highSig[], int highOff, int highStep) { 230 int i; 231 int iStep = 2 * inStep; //Subsampling in inSig 232 int ik; //Indexing inSig 233 int lk; //Indexing lowSig 234 int hk; //Indexing highSig 235 236 /* 237 *Generate high frequency subband 238 */ 239 240 //Initialize counters 241 ik = inOff; 242 hk = highOff; 243 244 if ( inLen>1 ) { 245 // apply a symmetric extension. 246 highSig[hk] = inSig[ik] - inSig[ik+inStep]; 247 } 248 else { 249 // Normalize for Nyquist gain 250 highSig[hk] = inSig[ik]<<1; 251 } 252 253 ik += iStep; 254 hk += highStep; 255 256 //Apply first lifting step to each "inner" sample. 257 if ( inLen>3 ) { 258 for(i = 2; i < inLen-1; i += 2) { 259 highSig[hk] = inSig[ik] - 260 ((inSig[ik-inStep] + inSig[ik+inStep])>>1); 261 ik += iStep; 262 hk += highStep; 263 } 264 } 265 266 //If input signal has odd length then we perform the lifting step 267 // i.e. apply a symmetric extension. 268 if( inLen%2==1 && inLen>1 ) { 269 highSig[hk] = inSig[ik] - inSig[ik-inStep]; 270 } 271 272 /* 273 *Generate low frequency subband 274 */ 275 276 //Initialize counters 277 ik = inOff + inStep; 278 lk = lowOff; 279 hk = highOff; 280 281 for (i=1 ; i<inLen-1 ; i+=2) { 282 283 lowSig[lk] = inSig[ik] + 284 ((highSig[hk] + highSig[hk+highStep] + 2)>> 2); 285 286 ik += iStep; 287 lk += lowStep; 288 hk += highStep; 289 } 290 291 if ( inLen>1 && inLen%2==0) { 292 // apply a symmetric extension. 293 lowSig[lk] = inSig[ik]+((2*highSig[hk]+2)>>2); 294 } 295 } 296 /** 297 * Returns the negative support of the low-pass analysis 298 * filter. That is the number of taps of the filter in the 299 * negative direction. 300 * 301 * @return 2 302 * */ 303 public int getAnLowNegSupport() { 304 return 2; 305 } 306 307 /** 308 * Returns the positive support of the low-pass analysis filter. That is 309 * the number of taps of the filter in the negative direction. 310 * 311 * @return The number of taps of the low-pass analysis filter in the 312 * positive direction 313 * */ 314 public int getAnLowPosSupport() { 315 return 2; 316 } 317 318 /** 319 * Returns the negative support of the high-pass analysis filter. That is 320 * the number of taps of the filter in the negative direction. 321 * 322 * @return The number of taps of the high-pass analysis filter in 323 * the negative direction 324 * */ 325 public int getAnHighNegSupport() { 326 return 1; 327 } 328 329 /** 330 * Returns the positive support of the high-pass analysis filter. That is 331 * the number of taps of the filter in the negative direction. 332 * 333 * @return The number of taps of the high-pass analysis filter in the 334 * positive direction 335 * */ 336 public int getAnHighPosSupport() { 337 return 1; 338 } 339 340 /** 341 * Returns the negative support of the low-pass synthesis filter. That is 342 * the number of taps of the filter in the negative direction. 343 * 344 * <P>A MORE PRECISE DEFINITION IS NEEDED 345 * 346 * @return The number of taps of the low-pass synthesis filter in the 347 * negative direction 348 * */ 349 public int getSynLowNegSupport() { 350 return 1; 351 } 352 353 /** 354 * Returns the positive support of the low-pass synthesis filter. That is 355 * the number of taps of the filter in the negative direction. 356 * 357 * <P>A MORE PRECISE DEFINITION IS NEEDED 358 * 359 * @return The number of taps of the low-pass synthesis filter in 360 * the positive direction 361 * */ 362 public int getSynLowPosSupport() { 363 return 1; 364 } 365 366 /** 367 * Returns the negative support of the high-pass synthesis filter. That is 368 * the number of taps of the filter in the negative direction. 369 * 370 * <P>A MORE PRECISE DEFINITION IS NEEDED 371 * 372 * @return The number of taps of the high-pass synthesis filter in the 373 * negative direction 374 * */ 375 public int getSynHighNegSupport() { 376 return 2; 377 } 378 379 /** 380 * Returns the positive support of the high-pass synthesis filter. That is 381 * the number of taps of the filter in the negative direction. 382 * 383 * <P>A MORE PRECISE DEFINITION IS NEEDED 384 * 385 * @return The number of taps of the high-pass synthesis filter in the 386 * positive direction 387 * */ 388 public int getSynHighPosSupport() { 389 return 2; 390 } 391 392 /** 393 * Returns the time-reversed low-pass synthesis waveform of the filter, 394 * which is the low-pass filter. This is the time-reversed impulse 395 * response of the low-pass synthesis filter. It is used to calculate the 396 * L2-norm of the synthesis basis functions for a particular subband (also 397 * called energy weight). 398 * 399 * <P>The returned array may not be modified (i.e. a reference to the 400 * internal array may be returned by the implementation of this method). 401 * 402 * @return The time-reversed low-pass synthesis waveform of the filter. 403 * */ 404 public float[] getLPSynthesisFilter() { 405 return LPSynthesisFilter; 406 } 407 408 /** 409 * Returns the time-reversed high-pass synthesis waveform of the filter, 410 * which is the high-pass filter. This is the time-reversed impulse 411 * response of the high-pass synthesis filter. It is used to calculate the 412 * L2-norm of the synthesis basis functions for a particular subband (also 413 * called energy weight). 414 * 415 * <P>The returned array may not be modified (i.e. a reference to the 416 * internal array may be returned by the implementation of this method). 417 * 418 * @return The time-reversed high-pass synthesis waveform of the filter. 419 * */ 420 public float[] getHPSynthesisFilter() { 421 return HPSynthesisFilter; 422 } 423 424 425 /** 426 * Returns the implementation type of this filter, as defined in this 427 * class, such as WT_FILTER_INT_LIFT, WT_FILTER_FLOAT_LIFT, 428 * WT_FILTER_FLOAT_CONVOL. 429 * 430 * @return WT_FILTER_INT_LIFT. 431 * */ 432 public int getImplType() { 433 return WT_FILTER_INT_LIFT; 434 } 435 436 /** 437 * Returns the reversibility of the filter. A filter is considered 438 * reversible if it is suitable for lossless coding. 439 * 440 * @return true since the 5x3 is reversible, provided the appropriate 441 * rounding is performed. 442 * */ 443 public boolean isReversible() { 444 return true; 445 } 446 447 /** 448 * Returns true if the wavelet filter computes or uses the same "inner" 449 * subband coefficient as the full frame wavelet transform, and false 450 * otherwise. In particular, for block based transforms with reduced 451 * overlap, this method should return false. The term "inner" indicates 452 * that this applies only with respect to the coefficient that are not 453 * affected by image boundaries processings such as symmetric extension, 454 * since there is not reference method for this. 455 * 456 * <P>The result depends on the length of the allowed overlap when 457 * compared to the overlap required by the wavelet filter. It also depends 458 * on how overlap processing is implemented in the wavelet filter. 459 * 460 * @param tailOvrlp This is the number of samples in the input signal 461 * before the first sample to filter that can be used for overlap. 462 * 463 * @param headOvrlp This is the number of samples in the input signal 464 * after the last sample to filter that can be used for overlap. 465 * 466 * @param inLen This is the lenght of the input signal to filter.The 467 * required number of samples in the input signal after the last sample 468 * depends on the length of the input signal. 469 * 470 * @return true if both overlaps are greater than 2, and correct 471 * processing is applied in the analyze() method. 472 * */ 473 public boolean isSameAsFullWT(int tailOvrlp, int headOvrlp, int inLen) { 474 475 //If the input signal has even length. 476 if( inLen % 2 == 0) { 477 if( tailOvrlp >= 2 && headOvrlp >= 1 ) return true; 478 else return false; 479 } 480 //Else if the input signal has odd length. 481 else { 482 if( tailOvrlp >= 2 && headOvrlp >= 2 ) return true; 483 else return false; 484 } 485 } 486 487 /** 488 * Tests if the 'obj' object is the same filter as this one. Two filters 489 * are the same if the same filter code should be output for both filters 490 * by the encodeFilterCode() method. 491 * 492 * <P>Currently the implementation of this method only tests if 'obj' is 493 * also of the class AnWTFilterIntLift5x3. 494 * 495 * @param The object against which to test inequality. 496 * */ 497 public boolean equals(Object obj) { 498 // To speed up test, first test for reference equality 499 return obj == this || 500 obj instanceof AnWTFilterIntLift5x3; 501 } 502 503 /** 504 * Returns the type of filter used according to the FilterTypes interface 505 * (W5x3). 506 * 507 * @see FilterTypes 508 * 509 * @return The filter type. 510 * */ 511 public int getFilterType(){ 512 return FilterTypes.W5X3; 513 } 514 515 /** Debugging method */ 516 public String toString(){ 517 return "w5x3"; 518 } 519}