001/* 002 * $RCSfile: SynWTFilterFloatLift9x7.java,v $ 003 * $Revision: 1.1 $ 004 * $Date: 2005/02/11 05:02:34 $ 005 * $State: Exp $ 006 * 007 * Class: SynWTFilterFloatLift9x7 008 * 009 * Description: A synthetizing 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 * */ 045 046package jj2000.j2k.wavelet.synthesis; 047 048 049/** 050 * This class inherits from the synthesis wavelet filter definition for int 051 * data. It implements the inverse wavelet transform specifically for the 9x7 052 * filter. The implementation is based on the lifting scheme. 053 * 054 * <P>See the SynWTFilter class for details such as normalization, how to 055 * split odd-length signals, etc. In particular, this method assumes that the 056 * low-pass coefficient is computed first. 057 * 058 * @see SynWTFilter 059 * @see SynWTFilterFloat 060 * */ 061public class SynWTFilterFloatLift9x7 extends SynWTFilterFloat { 062 063 /** The value of the first lifting step coefficient */ 064 public final static float ALPHA = -1.586134342f; 065 066 /** The value of the second lifting step coefficient */ 067 public final static float BETA = -0.05298011854f; 068 069 /** The value of the third lifting step coefficient */ 070 public final static float GAMMA = 0.8829110762f; 071 072 /** The value of the fourth lifting step coefficient */ 073 public final static float DELTA = 0.4435068522f; 074 075 /** The value of the low-pass subband normalization factor */ 076 public final static float KL = 0.8128930655f; 077 078 /** The value of the high-pass subband normalization factor */ 079 public final static float KH = 1.230174106f; 080 081 /** 082 * An implementation of the synthetize_lpf() method that works on int 083 * data, for the inverse 9x7 wavelet transform using the lifting 084 * scheme. See the general description of the synthetize_lpf() method in 085 * the SynWTFilter class for more details. 086 * 087 * <P>The low-pass and high-pass subbands are normalized by respectively a 088 * factor of 1/KL and a factor of 1/KH 089 * 090 * <P>The coefficients of the first lifting step are [-DELTA 1 -DELTA]. 091 * 092 * <P>The coefficients of the second lifting step are [-GAMMA 1 -GAMMA]. 093 * 094 * <P>The coefficients of the third lifting step are [-BETA 1 -BETA]. 095 * 096 * <P>The coefficients of the fourth lifting step are [-ALPHA 1 -ALPHA]. 097 * 098 * @param lowSig This is the array that contains the low-pass input 099 * signal. 100 * 101 * @param lowOff This is the index in lowSig of the first sample to 102 * filter. 103 * 104 * @param lowLen This is the number of samples in the low-pass input 105 * signal to filter. 106 * 107 * @param lowStep This is the step, or interleave factor, of the low-pass 108 * input signal samples in the lowSig array. 109 * 110 * @param highSig This is the array that contains the high-pass input 111 * signal. 112 * 113 * @param highOff This is the index in highSig of the first sample to 114 * filter. 115 * 116 * @param highLen This is the number of samples in the high-pass input 117 * signal to filter. 118 * 119 * @param highStep This is the step, or interleave factor, of the 120 * high-pass input signal samples in the highSig array. 121 * 122 * @param outSig This is the array where the output signal is placed. It 123 * should be long enough to contain the output signal. 124 * 125 * @param outOff This is the index in outSig of the element where to put 126 * the first output sample. 127 * 128 * @param outStep This is the step, or interleave factor, of the output 129 * samples in the outSig array. 130 * 131 * @see SynWTFilter#synthetize_lpf 132 * */ 133 public 134 void synthetize_lpf(float[] lowSig,int lowOff,int lowLen,int lowStep, 135 float[] highSig,int highOff,int highLen, 136 int highStep, 137 float[] outSig, int outOff, int outStep) { 138 139 int i; 140 int outLen = lowLen + highLen; //Length of the output signal 141 int iStep = 2*outStep; //Upsampling in outSig 142 int ik; //Indexing outSig 143 int lk; //Indexing lowSig 144 int hk; //Indexing highSig 145 146 // Generate intermediate low frequency subband 147 float sample = 0; 148 149 //Initialize counters 150 lk = lowOff; 151 hk = highOff; 152 ik = outOff; 153 154 //Handle tail boundary effect. Use symmetric extension 155 if(outLen>1) { 156 outSig[ik] = lowSig[lk]/KL - 2*DELTA*highSig[hk]/KH; 157 } 158 else { 159 outSig[ik] = lowSig[lk]; 160 } 161 162 lk += lowStep; 163 hk += highStep; 164 ik += iStep; 165 166 //Apply lifting step to each "inner" sample 167 for(i=2; i<outLen-1; i+=2, ik+=iStep, lk+=lowStep, hk+=highStep) { 168 outSig[ik] = lowSig[lk]/KL - 169 DELTA*(highSig[hk-highStep] + highSig[hk])/KH; 170 } 171 172 //Handle head boundary effect if input signal has odd length 173 if(outLen%2 == 1) { 174 if(outLen>2){ 175 outSig[ik] = lowSig[lk]/KL - 176 2*DELTA*highSig[hk-highStep]/KH; 177 } 178 } 179 180 // Generate intermediate high frequency subband 181 182 //Initialize counters 183 lk = lowOff; 184 hk = highOff; 185 ik = outOff + outStep; 186 187 //Apply lifting step to each "inner" sample 188 for(i = 1; i<outLen-1; i+=2, ik+=iStep, hk+=highStep, lk+=lowStep) { 189 outSig[ik] = highSig[hk]/KH - 190 GAMMA*(outSig[ik-outStep] + outSig[ik+outStep]); 191 } 192 193 //Handle head boundary effect if output signal has even length 194 if(outLen % 2 == 0) { 195 outSig[ik] = highSig[hk]/KH - 2*GAMMA*outSig[ik-outStep]; 196 } 197 198 // Generate even samples (inverse low-pass filter) 199 200 //Initialize counters 201 ik = outOff; 202 203 //Handle tail boundary effect 204 //If access the overlap then perform the lifting step. 205 if(outLen>1) { 206 outSig[ik] -= 2*BETA*outSig[ik+outStep]; 207 } 208 ik += iStep; 209 210 //Apply lifting step to each "inner" sample 211 for(i=2; i<outLen-1; i+=2, ik+=iStep) { 212 outSig[ik] -= BETA*(outSig[ik-outStep] + outSig[ik+outStep]); 213 } 214 215 //Handle head boundary effect if input signal has odd length 216 if(outLen%2 == 1 && outLen>2) { 217 outSig[ik] -= 2*BETA*outSig[ik-outStep]; 218 } 219 220 // Generate odd samples (inverse high pass-filter) 221 222 //Initialize counters 223 ik = outOff + outStep; 224 225 //Apply first lifting step to each "inner" sample 226 for(i=1; i<outLen-1; i+=2, ik+=iStep) { 227 outSig[ik] -= ALPHA*(outSig[ik-outStep] + outSig[ik+outStep]); 228 } 229 230 //Handle head boundary effect if input signal has even length 231 if(outLen%2 == 0) { 232 outSig[ik] -= 2*ALPHA*outSig[ik-outStep]; 233 } 234 } 235 236 /** 237 * An implementation of the synthetize_hpf() method that works on int 238 * data, for the inverse 9x7 wavelet transform using the lifting 239 * scheme. See the general description of the synthetize_hpf() method in 240 * the SynWTFilter class for more details. 241 * 242 * <P>The low-pass and high-pass subbands are normalized by respectively 243 * a factor of 1/KL and a factor of 1/KH 244 * 245 * <P>The coefficients of the first lifting step are [-DELTA 1 -DELTA]. 246 * 247 * <P>The coefficients of the second lifting step are [-GAMMA 1 -GAMMA]. 248 * 249 * <P>The coefficients of the third lifting step are [-BETA 1 -BETA]. 250 * 251 * <P>The coefficients of the fourth lifting step are [-ALPHA 1 -ALPHA]. 252 * 253 * @param lowSig This is the array that contains the low-pass 254 * input signal. 255 * 256 * @param lowOff This is the index in lowSig of the first sample to 257 * filter. 258 * 259 * @param lowLen This is the number of samples in the low-pass input 260 * signal to filter. 261 * 262 * @param lowStep This is the step, or interleave factor, of the low-pass 263 * input signal samples in the lowSig array. 264 * 265 * @param highSig This is the array that contains the high-pass input 266 * signal. 267 * 268 * @param highOff This is the index in highSig of the first sample to 269 * filter. 270 * 271 * @param highLen This is the number of samples in the high-pass input 272 * signal to filter. 273 * 274 * @param highStep This is the step, or interleave factor, of the 275 * high-pass input signal samples in the highSig array. 276 * 277 * @param outSig This is the array where the output signal is placed. It 278 * should be long enough to contain the output signal. 279 * 280 * @param outOff This is the index in outSig of the element where to put 281 * the first output sample. 282 * 283 * @param outStep This is the step, or interleave factor, of the output 284 * samples in the outSig array. 285 * 286 * @see SynWTFilter#synthetize_hpf 287 * */ 288 public 289 void synthetize_hpf(float[] lowSig,int lowOff,int lowLen,int lowStep, 290 float[] highSig,int highOff,int highLen, 291 int highStep,float[] outSig,int outOff, 292 int outStep) { 293 294 int i; 295 int outLen = lowLen + highLen; //Length of the output signal 296 int iStep = 2*outStep; //Upsampling in outSig 297 int ik; //Indexing outSig 298 int lk; //Indexing lowSig 299 int hk; //Indexing highSig 300 301 // Initialize counters 302 lk = lowOff; 303 hk = highOff; 304 305 if(outLen!=1) { 306 int outLen2 = outLen>>1; 307 // "Inverse normalize" each sample 308 for(i=0; i<outLen2; i++) { 309 lowSig[lk] /= KL; 310 highSig[hk] /= KH; 311 lk += lowStep; 312 hk += highStep; 313 } 314 // "Inverse normalise" last high pass coefficient 315 if(outLen%2==1) { 316 highSig[hk] /= KH; 317 } 318 } else { 319 // Normalize for Nyquist gain 320 highSig[highOff] /= 2; 321 } 322 323 // Generate intermediate low frequency subband 324 325 //Initialize counters 326 lk = lowOff; 327 hk = highOff; 328 ik = outOff + outStep; 329 330 //Apply lifting step to each "inner" sample 331 for(i=1; i<outLen-1; i+=2 ) { 332 outSig[ik] = lowSig[lk] - 333 DELTA*(highSig[hk] + highSig[hk+highStep]); 334 ik += iStep; 335 lk += lowStep; 336 hk += highStep; 337 } 338 339 if(outLen%2==0 && outLen>1) { 340 //Use symmetric extension 341 outSig[ik] = lowSig[lk] - 2*DELTA*highSig[hk]; 342 } 343 344 // Generate intermediate high frequency subband 345 346 //Initialize counters 347 hk = highOff; 348 ik = outOff; 349 350 if(outLen>1) { 351 outSig[ik] = highSig[hk] - 2*GAMMA*outSig[ik+outStep]; 352 } else { 353 outSig[ik] = highSig[hk]; 354 } 355 356 ik += iStep; 357 hk += highStep; 358 359 //Apply lifting step to each "inner" sample 360 for(i=2; i<outLen-1; i+=2 ) { 361 outSig[ik] = highSig[hk] - 362 GAMMA*(outSig[ik-outStep] + outSig[ik+outStep]); 363 ik += iStep; 364 hk += highStep; 365 } 366 367 //Handle head boundary effect if output signal has even length 368 if(outLen%2==1 && outLen>1) { 369 //Use symmetric extension 370 outSig[ik] = highSig[hk] - 2*GAMMA*outSig[ik-outStep]; 371 } 372 373 // Generate even samples (inverse low-pass filter) 374 375 //Initialize counters 376 ik = outOff + outStep; 377 378 //Apply lifting step to each "inner" sample 379 for(i=1; i<outLen-1; i+=2 ) { 380 outSig[ik] -= BETA*(outSig[ik-outStep] + outSig[ik+outStep]); 381 ik += iStep; 382 } 383 384 if(outLen%2==0 && outLen>1) { 385 // symmetric extension. 386 outSig[ik] -= 2*BETA*outSig[ik-outStep]; 387 } 388 389 // Generate odd samples (inverse high pass-filter) 390 391 //Initialize counters 392 ik = outOff; 393 394 if(outLen>1) { 395 // symmetric extension. 396 outSig[ik] -= 2*ALPHA*outSig[ik+outStep]; 397 } 398 ik += iStep; 399 400 //Apply first lifting step to each "inner" sample 401 for(i=2; i<outLen-1 ; i+=2) { 402 outSig[ik] -= ALPHA*(outSig[ik-outStep] + outSig[ik+outStep]); 403 ik += iStep; 404 } 405 406 //Handle head boundary effect if input signal has even length 407 if((outLen%2==1) && (outLen>1)) { 408 //Use symmetric extension 409 outSig[ik] -= 2*ALPHA*outSig[ik-outStep]; 410 } 411 } 412 413 /** 414 * Returns the negative support of the low-pass analysis filter. That is 415 * the number of taps of the filter in the negative direction. 416 * 417 * @return 2 418 * */ 419 public int getAnLowNegSupport() { 420 return 4; 421 } 422 423 /** 424 * Returns the positive support of the low-pass analysis filter. That is 425 * the number of taps of the filter in the negative direction. 426 * 427 * @return The number of taps of the low-pass analysis filter in the 428 * positive direction 429 * */ 430 public int getAnLowPosSupport() { 431 return 4; 432 } 433 434 /** 435 * Returns the negative support of the high-pass analysis filter. That is 436 * the number of taps of the filter in the negative direction. 437 * 438 * @return The number of taps of the high-pass analysis filter in 439 * the negative direction 440 * */ 441 public int getAnHighNegSupport() { 442 return 3; 443 } 444 445 /** 446 * Returns the positive support of the high-pass analysis filter. That is 447 * the number of taps of the filter in the negative direction. 448 * 449 * @return The number of taps of the high-pass analysis filter in the 450 * positive direction 451 * */ 452 public int getAnHighPosSupport() { 453 return 3; 454 } 455 456 /** 457 * Returns the negative support of the low-pass synthesis filter. That is 458 * the number of taps of the filter in the negative direction. 459 * 460 * <P>A MORE PRECISE DEFINITION IS NEEDED 461 * 462 * @return The number of taps of the low-pass synthesis filter in the 463 * negative direction 464 * */ 465 public int getSynLowNegSupport() { 466 return 3; 467 } 468 469 /** 470 * Returns the positive support of the low-pass synthesis filter. That is 471 * the number of taps of the filter in the negative direction. 472 * 473 * <P>A MORE PRECISE DEFINITION IS NEEDED 474 * 475 * @return The number of taps of the low-pass synthesis filter in the 476 * positive direction 477 * */ 478 public int getSynLowPosSupport() { 479 return 3; 480 } 481 482 /** 483 * Returns the negative support of the high-pass synthesis filter. That is 484 * the number of taps of the filter in the negative direction. 485 * 486 * <P>A MORE PRECISE DEFINITION IS NEEDED 487 * 488 * @return The number of taps of the high-pass synthesis filter in the 489 * negative direction 490 * */ 491 public int getSynHighNegSupport() { 492 return 4; 493 } 494 495 /** 496 * Returns the positive support of the high-pass synthesis filter. That is 497 * the number of taps of the filter in the negative direction. 498 * 499 * <P>A MORE PRECISE DEFINITION IS NEEDED 500 * 501 * @return The number of taps of the high-pass synthesis filter in the 502 * positive direction 503 * */ 504 public int getSynHighPosSupport() { 505 return 4; 506 } 507 508 /** 509 * Returns the implementation type of this filter, as defined in this 510 * class, such as WT_FILTER_INT_LIFT, WT_FILTER_FLOAT_LIFT, 511 * WT_FILTER_FLOAT_CONVOL. 512 * 513 * @return WT_FILTER_INT_LIFT. 514 * */ 515 public int getImplType() { 516 return WT_FILTER_FLOAT_LIFT; 517 } 518 519 /** 520 * Returns the reversibility of the filter. A filter is considered 521 * reversible if it is suitable for lossless coding. 522 * 523 * @return true since the 9x7 is reversible, provided the appropriate 524 * rounding is performed. 525 * */ 526 public boolean isReversible() { 527 return false; 528 } 529 530 /** 531 * Returns true if the wavelet filter computes or uses the 532 * same "inner" subband coefficient as the full frame wavelet transform, 533 * and false otherwise. In particular, for block based transforms with 534 * reduced overlap, this method should return false. The term "inner" 535 * indicates that this applies only with respect to the coefficient that 536 * are not affected by image boundaries processings such as symmetric 537 * extension, since there is not reference method for this. 538 * 539 * <P>The result depends on the length of the allowed overlap when 540 * compared to the overlap required by the wavelet filter. It also 541 * depends on how overlap processing is implemented in the wavelet 542 * filter. 543 * 544 * @param tailOvrlp This is the number of samples in the input 545 * signal before the first sample to filter that can be used for 546 * overlap. 547 * 548 * @param headOvrlp This is the number of samples in the input 549 * signal after the last sample to filter that can be used for 550 * overlap. 551 * 552 * @param inLen This is the lenght of the input signal to filter.The 553 * required number of samples in the input signal after the last sample 554 * depends on the length of the input signal. 555 * 556 * @return true if both overlaps are greater than 2, and correct 557 * processing is applied in the analyze() method. 558 * 559 * 560 * 561 */ 562 public boolean isSameAsFullWT(int tailOvrlp, int headOvrlp, int inLen) { 563 564 //If the input signal has even length. 565 if(inLen % 2 == 0) { 566 if(tailOvrlp >= 2 && headOvrlp >= 1) return true; 567 else return false; 568 } 569 //Else if the input signal has odd length. 570 else { 571 if(tailOvrlp >= 2 && headOvrlp >= 2) return true; 572 else return false; 573 } 574 } 575 576 /** 577 * Returns a string of information about the synthesis wavelet filter 578 * 579 * @return wavelet filter type. 580 * 581 * 582 */ 583 public String toString(){ 584 return "w9x7 (lifting)"; 585 } 586}