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