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