001/* 002 * $RCSfile: AnWTFilterFloatLift9x7.java,v $ 003 * $Revision: 1.1 $ 004 * $Date: 2005/02/11 05:02:29 $ 005 * $State: Exp $ 006 * 007 * Class: AnWTFilterFloatLift9x7 008 * 009 * Description: An analyzing wavelet filter implementing the 010 * lifting 9x7 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.FilterTypes; 048 049/** 050 * This class inherits from the analysis wavelet filter definition 051 * for int data. It implements the forward wavelet transform 052 * specifically for the 9x7 filter. The implementation is based on 053 * the lifting scheme. 054 * 055 * <P>See the AnWTFilter class for details such as 056 * normalization, how to split odd-length signals, etc. In particular, 057 * this method assumes that the low-pass coefficient is computed first. 058 * 059 * @see AnWTFilter 060 * @see AnWTFilterFloat 061 * */ 062public class AnWTFilterFloatLift9x7 extends AnWTFilterFloat { 063 064 /** The low-pass synthesis filter of the 9x7 wavelet transform */ 065 private final static float LPSynthesisFilter[] = 066 { -0.091272f, -0.057544f, 0.591272f, 1.115087f, 067 0.591272f, -0.057544f, -0.091272f}; 068 069 /** The high-pass synthesis filter of the 9x7 wavelet transform */ 070 private final static float HPSynthesisFilter[] = 071 { 0.026749f, 0.016864f, -0.078223f, -0.266864f, 072 0.602949f, 073 -0.266864f, -0.078223f, 0.016864f, 0.026749f }; 074 075 /** The value of the first lifting step coefficient */ 076 public final static float ALPHA = -1.586134342f; 077 078 /** The value of the second lifting step coefficient */ 079 public final static float BETA = -0.05298011854f; 080 081 /** The value of the third lifting step coefficient */ 082 public final static float GAMMA = 0.8829110762f; 083 084 /** The value of the fourth lifting step coefficient */ 085 public final static float DELTA = 0.443568522f; 086 087 /** The value of the low-pass subband normalization factor */ 088 public final static float KL = 0.8128930655f;//1.149604398f; 089 090 /** The value of the high-pass subband normalization factor */ 091 public final static float KH = 1.230174106f;//0.8698644523f; 092 093 /** 094 * An implementation of the analyze_lpf() method that works on int 095 * data, for the forward 9x7 wavelet transform using the 096 * lifting scheme. See the general description of the analyze_lpf() 097 * method in the AnWTFilter class for more details. 098 * 099 * <P>The coefficients of the first lifting step are [ALPHA 1 ALPHA]. 100 * 101 * <P>The coefficients of the second lifting step are [BETA 1 BETA]. 102 * 103 * <P>The coefficients of the third lifting step are [GAMMA 1 GAMMA]. 104 * 105 * <P>The coefficients of the fourth lifting step are [DELTA 1 DELTA]. 106 * 107 * <P>The low-pass and high-pass subbands are normalized by respectively 108 * a factor of KL and a factor of KH 109 * 110 * @param inSig This is the array that contains the input 111 * signal. 112 * 113 * @param inOff This is the index in inSig of the first sample to 114 * filter. 115 * 116 * @param inLen This is the number of samples in the input signal 117 * to filter. 118 * 119 * @param inStep This is the step, or interleave factor, of the 120 * input signal samples in the inSig array. 121 * 122 * @param lowSig This is the array where the low-pass output 123 * signal is placed. 124 * 125 * @param lowOff This is the index in lowSig of the element where 126 * to put the first low-pass output sample. 127 * 128 * @param lowStep This is the step, or interleave factor, of the 129 * low-pass output samples in the lowSig array. 130 * 131 * @param highSig This is the array where the high-pass output 132 * signal is placed. 133 * 134 * @param highOff This is the index in highSig of the element where 135 * to put the first high-pass output sample. 136 * 137 * @param highStep This is the step, or interleave factor, of the 138 * high-pass output samples in the highSig array. 139 * */ 140 public 141 void analyze_lpf(float inSig[], int inOff, int inLen, int inStep, 142 float lowSig[], int lowOff, int lowStep, 143 float highSig[], int highOff, int highStep) { 144 int i,maxi; 145 int iStep = 2 * inStep; //Subsampling in inSig 146 int ik; //Indexing inSig 147 int lk; //Indexing lowSig 148 int hk; //Indexing highSig 149 150 // Generate intermediate high frequency subband 151 152 //Initialize counters 153 ik = inOff + inStep; 154 lk = lowOff; 155 hk = highOff; 156 157 //Apply first lifting step to each "inner" sample 158 for( i = 1, maxi = inLen-1; i < maxi; i += 2 ) { 159 highSig[hk] = inSig[ik] + 160 ALPHA*(inSig[ik-inStep] + inSig[ik+inStep]); 161 162 ik += iStep; 163 hk += highStep; 164 } 165 166 //Handle head boundary effect if input signal has even length 167 if(inLen % 2 == 0) { 168 highSig[hk] = inSig[ik] + 2*ALPHA*inSig[ik-inStep]; 169 } 170 171 // Generate intermediate low frequency subband 172 173 //Initialize counters 174 ik = inOff; 175 lk = lowOff; 176 hk = highOff; 177 178 if(inLen>1) { 179 lowSig[lk] = inSig[ik] + 2*BETA*highSig[hk]; 180 } 181 else { 182 lowSig[lk] = inSig[ik]; 183 } 184 185 ik += iStep; 186 lk += lowStep; 187 hk += highStep; 188 189 //Apply lifting step to each "inner" sample 190 for( i = 2, maxi = inLen-1; i < maxi; i += 2 ) { 191 lowSig[lk] = inSig[ik] + 192 BETA*(highSig[hk-highStep] + highSig[hk]); 193 194 ik += iStep; 195 lk += lowStep; 196 hk += highStep; 197 } 198 199 //Handle head boundary effect if input signal has odd length 200 if((inLen % 2 == 1)&&(inLen>2)) { 201 lowSig[lk] = inSig[ik] + 2*BETA*highSig[hk-highStep]; 202 } 203 204 // Generate high frequency subband 205 206 //Initialize counters 207 lk = lowOff; 208 hk = highOff; 209 210 //Apply first lifting step to each "inner" sample 211 for(i = 1, maxi = inLen-1; i < maxi; i += 2) { 212 highSig[hk] += GAMMA*(lowSig[lk] + lowSig[lk+lowStep]); 213 214 lk += lowStep; 215 hk += highStep; 216 } 217 218 //Handle head boundary effect if input signal has even length 219 if(inLen % 2 == 0) { 220 highSig[hk] += 2*GAMMA*lowSig[lk]; 221 } 222 223 // Generate low frequency subband 224 225 //Initialize counters 226 lk = lowOff; 227 hk = highOff; 228 229 //Handle tail boundary effect 230 //If access the overlap then perform the lifting step 231 if(inLen>1){ 232 lowSig[lk] += 2*DELTA*highSig[hk]; 233 } 234 235 lk += lowStep; 236 hk += highStep; 237 238 //Apply lifting step to each "inner" sample 239 for(i = 2, maxi = inLen-1; i < maxi; i += 2) { 240 lowSig[lk] += 241 DELTA*(highSig[hk - highStep] + highSig[hk]); 242 243 lk += lowStep; 244 hk += highStep; 245 } 246 247 //Handle head boundary effect if input signal has odd length 248 if((inLen % 2 == 1)&&(inLen>2)) { 249 lowSig[lk] += 2*DELTA*highSig[hk-highStep]; 250 } 251 252 // Normalize low and high frequency subbands 253 254 //Re-initialize counters 255 lk = lowOff; 256 hk = highOff; 257 258 //Normalize each sample 259 for( i=0 ; i<(inLen>>1); i++ ) { 260 lowSig[lk] *= KL; 261 highSig[hk] *= KH; 262 lk += lowStep; 263 hk += highStep; 264 } 265 //If the input signal has odd length then normalize the last low-pass 266 //coefficient (if input signal is length one filter is identity) 267 if( inLen%2==1 && inLen != 1) { 268 lowSig[lk] *= KL; 269 } 270 } 271 272 /** 273 * An implementation of the analyze_hpf() method that works on int 274 * data, for the forward 9x7 wavelet transform using the 275 * lifting scheme. See the general description of the analyze_hpf() method 276 * in the AnWTFilter class for more details. 277 * 278 * <P>The coefficients of the first lifting step are [ALPHA 1 ALPHA]. 279 * 280 * <P>The coefficients of the second lifting step are [BETA 1 BETA]. 281 * 282 * <P>The coefficients of the third lifting step are [GAMMA 1 GAMMA]. 283 * 284 * <P>The coefficients of the fourth lifting step are [DELTA 1 DELTA]. 285 * 286 * <P>The low-pass and high-pass subbands are normalized by respectively 287 * a factor of KL and a factor of KH 288 * 289 * @param inSig This is the array that contains the input 290 * signal. 291 * 292 * @param inOff This is the index in inSig of the first sample to 293 * filter. 294 * 295 * @param inLen This is the number of samples in the input signal 296 * to filter. 297 * 298 * @param inStep This is the step, or interleave factor, of the 299 * input signal samples in the inSig array. 300 * 301 * @param lowSig This is the array where the low-pass output 302 * signal is placed. 303 * 304 * @param lowOff This is the index in lowSig of the element where 305 * to put the first low-pass output sample. 306 * 307 * @param lowStep This is the step, or interleave factor, of the 308 * low-pass output samples in the lowSig array. 309 * 310 * @param highSig This is the array where the high-pass output 311 * signal is placed. 312 * 313 * @param highOff This is the index in highSig of the element where 314 * to put the first high-pass output sample. 315 * 316 * @param highStep This is the step, or interleave factor, of the 317 * high-pass output samples in the highSig array. 318 * 319 * @see AnWTFilter#analyze_hpf 320 * */ 321 public void analyze_hpf(float inSig[], int inOff, int inLen, int inStep, 322 float lowSig[], int lowOff, int lowStep, 323 float highSig[], int highOff, int highStep) { 324 325 int i,maxi; 326 int iStep = 2 * inStep; //Subsampling in inSig 327 int ik; //Indexing inSig 328 int lk; //Indexing lowSig 329 int hk; //Indexing highSig 330 331 // Generate intermediate high frequency subband 332 333 //Initialize counters 334 ik = inOff; 335 lk = lowOff; 336 hk = highOff; 337 338 if ( inLen>1 ) { 339 // apply symmetric extension. 340 highSig[hk] = inSig[ik] + 2*ALPHA*inSig[ik+inStep]; 341 } 342 else { 343 // Normalize for Nyquist gain 344 highSig[hk] = inSig[ik]*2; 345 } 346 347 ik += iStep; 348 hk += highStep; 349 350 //Apply first lifting step to each "inner" sample 351 for( i = 2 ; i < inLen-1 ; i += 2 ) { 352 highSig[hk] = inSig[ik] + 353 ALPHA*(inSig[ik-inStep] + inSig[ik+inStep]); 354 ik += iStep; 355 hk += highStep; 356 } 357 358 //If input signal has odd length then we perform the lifting step 359 // i.e. apply a symmetric extension. 360 if( (inLen%2==1) && (inLen>1) ) { 361 highSig[hk] = inSig[ik] + 2*ALPHA*inSig[ik-inStep]; 362 } 363 364 // Generate intermediate low frequency subband 365 366 //Initialize counters 367 //ik = inOff + inStep; 368 ik = inOff + inStep; 369 lk = lowOff; 370 hk = highOff; 371 372 //Apply lifting step to each "inner" sample 373 // we are at the component boundary 374 for(i = 1; i < inLen-1; i += 2) { 375 lowSig[lk] = inSig[ik] + 376 BETA*(highSig[hk] + highSig[hk+highStep]); 377 378 ik += iStep; 379 lk += lowStep; 380 hk += highStep; 381 } 382 if ( inLen>1 && inLen%2==0 ) { 383 // symetric extension 384 lowSig[lk] = inSig[ik]+2*BETA*highSig[hk]; 385 } 386 387 // Generate high frequency subband 388 389 //Initialize counters 390 lk = lowOff; 391 hk = highOff; 392 393 if ( inLen>1 ) { 394 // symmetric extension. 395 highSig[hk] += GAMMA*2*lowSig[lk]; 396 } 397 //lk += lowStep; 398 hk += highStep; 399 400 //Apply first lifting step to each "inner" sample 401 for(i = 2 ; i < inLen-1 ; i += 2) { 402 highSig[hk] += GAMMA*(lowSig[lk] + lowSig[lk+lowStep]); 403 lk += lowStep; 404 hk += highStep; 405 } 406 407 //Handle head boundary effect 408 if ( inLen>1 && inLen%2==1 ) { 409 // symmetric extension. 410 highSig[hk] += GAMMA*2*lowSig[lk]; 411 } 412 413 // Generate low frequency subband 414 415 //Initialize counters 416 lk = lowOff; 417 hk = highOff; 418 419 // we are at the component boundary 420 for(i = 1 ; i < inLen-1; i += 2) { 421 lowSig[lk] += DELTA*(highSig[hk] + highSig[hk+highStep]); 422 lk += lowStep; 423 hk += highStep; 424 } 425 426 if ( inLen>1 && inLen%2==0 ) { 427 lowSig[lk] += DELTA*2*highSig[hk]; 428 } 429 430 // Normalize low and high frequency subbands 431 432 //Re-initialize counters 433 lk = lowOff; 434 hk = highOff; 435 436 //Normalize each sample 437 for( i=0 ; i<(inLen>>1); i++ ) { 438 lowSig[lk] *= KL; 439 highSig[hk] *= KH; 440 lk += lowStep; 441 hk += highStep; 442 } 443 //If the input signal has odd length then normalize the last high-pass 444 //coefficient (if input signal is length one filter is identity) 445 if( inLen%2==1 && inLen != 1) { 446 highSig[hk] *= KH; 447 } 448 } 449 450 /** 451 * Returns the negative support of the low-pass analysis 452 * filter. That is the number of taps of the filter in the 453 * negative direction. 454 * 455 * @return 2 456 * */ 457 public int getAnLowNegSupport() { 458 return 4; 459 } 460 461 /** 462 * Returns the positive support of the low-pass analysis 463 * filter. That is the number of taps of the filter in the 464 * negative direction. 465 * 466 * @return The number of taps of the low-pass analysis filter in 467 * the positive direction 468 * */ 469 public int getAnLowPosSupport() { 470 return 4; 471 } 472 473 /** 474 * Returns the negative support of the high-pass analysis 475 * filter. That is the number of taps of the filter in the 476 * negative direction. 477 * 478 * @return The number of taps of the high-pass analysis filter in 479 * the negative direction 480 * */ 481 public int getAnHighNegSupport() { 482 return 3; 483 } 484 485 /** 486 * Returns the positive support of the high-pass analysis 487 * filter. That is the number of taps of the filter in the 488 * negative direction. 489 * 490 * @return The number of taps of the high-pass analysis filter in 491 * the positive direction 492 * */ 493 public int getAnHighPosSupport() { 494 return 3; 495 } 496 497 /** 498 * Returns the negative support of the low-pass synthesis 499 * filter. That is the number of taps of the filter in the 500 * negative direction. 501 * 502 * <P>A MORE PRECISE DEFINITION IS NEEDED 503 * 504 * @return The number of taps of the low-pass synthesis filter in 505 * the negative direction 506 * */ 507 public int getSynLowNegSupport() { 508 return 3; 509 } 510 511 /** 512 * Returns the positive support of the low-pass synthesis 513 * filter. That is the number of taps of the filter in the 514 * negative direction. 515 * 516 * <P>A MORE PRECISE DEFINITION IS NEEDED 517 * 518 * @return The number of taps of the low-pass synthesis filter in 519 * the positive direction 520 * */ 521 public int getSynLowPosSupport() { 522 return 3; 523 } 524 525 /** 526 * Returns the negative support of the high-pass synthesis 527 * filter. That is the number of taps of the filter in the 528 * negative direction. 529 * 530 * <P>A MORE PRECISE DEFINITION IS NEEDED 531 * 532 * @return The number of taps of the high-pass synthesis filter in 533 * the negative direction 534 * */ 535 public int getSynHighNegSupport() { 536 return 4; 537 } 538 539 /** 540 * Returns the positive support of the high-pass synthesis 541 * filter. That is the number of taps of the filter in the 542 * negative direction. 543 * 544 * <P>A MORE PRECISE DEFINITION IS NEEDED 545 * 546 * @return The number of taps of the high-pass synthesis filter in 547 * the positive direction 548 * */ 549 public int getSynHighPosSupport() { 550 return 4; 551 } 552 553 /** 554 * Returns the time-reversed low-pass synthesis waveform of the 555 * filter, which is the low-pass filter. This is the time-reversed 556 * impulse response of the low-pass synthesis filter. It is used 557 * to calculate the L2-norm of the synthesis basis functions for a 558 * particular subband (also called energy weight). 559 * 560 * <P>The returned array may not be modified (i.e. a reference to 561 * the internal array may be returned by the implementation of 562 * this method). 563 * 564 * @return The time-reversed low-pass synthesis waveform of the 565 * filter. 566 * */ 567 public float[] getLPSynthesisFilter() { 568 return LPSynthesisFilter; 569 } 570 571 /** 572 * Returns the time-reversed high-pass synthesis waveform of the 573 * filter, which is the high-pass filter. This is the 574 * time-reversed impulse response of the high-pass synthesis 575 * filter. It is used to calculate the L2-norm of the synthesis 576 * basis functions for a particular subband (also called energy 577 * weight). 578 * 579 * <P>The returned array may not be modified (i.e. a reference to 580 * the internal array may be returned by the implementation of 581 * this method). 582 * 583 * @return The time-reversed high-pass synthesis waveform of the 584 * filter. 585 * */ 586 public float[] getHPSynthesisFilter() { 587 return HPSynthesisFilter; 588 } 589 590 /** 591 * Returns the implementation type of this filter, as defined in 592 * this class, such as WT_FILTER_INT_LIFT, WT_FILTER_FLOAT_LIFT, 593 * WT_FILTER_FLOAT_CONVOL. 594 * 595 * @return WT_FILTER_INT_LIFT. 596 * */ 597 public int getImplType() { 598 return WT_FILTER_FLOAT_LIFT; 599 } 600 601 /** 602 * Returns the reversibility of the filter. A filter is considered 603 * reversible if it is suitable for lossless coding. 604 * 605 * @return true since the 9x7 is reversible, provided the appropriate 606 * rounding is performed. 607 * */ 608 public boolean isReversible() { 609 return false; 610 } 611 612 /** 613 * Returns true if the wavelet filter computes or uses the 614 * same "inner" subband coefficient as the full frame wavelet transform, 615 * and false otherwise. In particular, for block based transforms with 616 * reduced overlap, this method should return false. The term "inner" 617 * indicates that this applies only with respect to the coefficient that 618 * are not affected by image boundaries processings such as symmetric 619 * extension, since there is not reference method for this. 620 * 621 * <P>The result depends on the length of the allowed overlap when 622 * compared to the overlap required by the wavelet filter. It also 623 * depends on how overlap processing is implemented in the wavelet 624 * filter. 625 * 626 * @param tailOvrlp This is the number of samples in the input 627 * signal before the first sample to filter that can be used for 628 * overlap. 629 * 630 * @param headOvrlp This is the number of samples in the input 631 * signal after the last sample to filter that can be used for 632 * overlap. 633 * 634 * @param inLen This is the lenght of the input signal to filter.The 635 * required number of samples in the input signal after the last sample 636 * depends on the length of the input signal. 637 * 638 * @return true if both overlaps are greater than 2, and correct 639 * processing is applied in the analyze() method. 640 * */ 641 public boolean isSameAsFullWT(int tailOvrlp, int headOvrlp, int inLen) { 642 643 //If the input signal has even length. 644 if( inLen % 2 == 0) { 645 if( tailOvrlp >= 4 && headOvrlp >= 3 ) return true; 646 else return false; 647 } 648 //Else if the input signal has odd length. 649 else { 650 if( tailOvrlp >= 4 && headOvrlp >= 4 ) return true; 651 else return false; 652 } 653 } 654 655 /** 656 * Tests if the 'obj' object is the same filter as this one. Two filters 657 * are the same if the same filter code should be output for both filters 658 * by the encodeFilterCode() method. 659 * 660 * <P>Currently the implementation of this method only tests if 'obj' is 661 * also of the class AnWTFilterFloatLift9x7 662 * 663 * @param The object against which to test inequality. 664 * */ 665 public boolean equals(Object obj) { 666 // To spped up test, first test for reference equality 667 return obj == this || 668 obj instanceof AnWTFilterFloatLift9x7; 669 } 670 671 /** 672 * Returns the type of filter used according to the FilterTypes 673 * interface(W9x7). 674 * 675 * @see FilterTypes 676 * 677 * @return The filter type. 678 * */ 679 public int getFilterType(){ 680 return FilterTypes.W9X7; 681 } 682 683 /** Debugging method */ 684 public String toString(){ 685 return "w9x7"; 686 } 687}