001/*
002 * $RCSfile: SynWTFilterIntLift5x3.java,v $
003 * $Revision: 1.1 $
004 * $Date: 2005/02/11 05:02:34 $
005 * $State: Exp $
006 *
007 * Class:                   SynWTFilterIntLift5x3
008 *
009 * Description:             A synthetizing 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.synthesis;
046
047
048/**
049 * This class inherits from the synthesis wavelet filter definition for int
050 * data. It implements the inverse wavelet transform specifically for the 5x3
051 * filter. The implementation is based on the lifting scheme.
052 *
053 * <P>See the SynWTFilter class for details such as normalization, how to
054 * split odd-length signals, etc. In particular, this method assumes that the
055 * low-pass coefficient is computed first.
056 *
057 * @see SynWTFilter
058 * @see SynWTFilterInt
059 * */
060public class SynWTFilterIntLift5x3 extends SynWTFilterInt {
061
062    /**
063     * An implementation of the synthetize_lpf() method that works on int
064     * data, for the inverse 5x3 wavelet transform using the lifting
065     * scheme. See the general description of the synthetize_lpf() method in
066     * the SynWTFilter class for more details.
067     *
068     * <P>The coefficients of the first lifting step are [-1/4 1 -1/4].
069     *
070     * <P>The coefficients of the second lifting step are [1/2 1 1/2].
071     *
072     * @param lowSig This is the array that contains the low-pass
073     * input signal.
074     *
075     * @param lowOff This is the index in lowSig of the first sample to
076     * filter.
077     *
078     * @param lowLen This is the number of samples in the low-pass
079     * input signal to filter.
080     *
081     * @param lowStep This is the step, or interleave factor, of the
082     * low-pass input signal samples in the lowSig array.
083     *
084     * @param highSig This is the array that contains the high-pass
085     * input signal.
086     *
087     * @param highOff This is the index in highSig of the first sample to
088     * filter.
089     *
090     * @param highLen This is the number of samples in the high-pass
091     * input signal to filter.
092     *
093     * @param highStep This is the step, or interleave factor, of the
094     * high-pass input signal samples in the highSig array.
095     *
096     * @param outSig This is the array where the output signal is
097     * placed. It should be long enough to contain the output signal.
098     *
099     * @param outOff This is the index in outSig of the element where
100     * to put the first output sample.
101     *
102     * @param outStep This is the step, or interleave factor, of the
103     * output samples in the outSig array.
104     *
105     * @see SynWTFilter#synthetize_lpf
106     * */
107    public
108        void synthetize_lpf(int[] lowSig, int lowOff, int lowLen, int lowStep,
109                        int[] highSig, int highOff, int highLen, int highStep,
110                        int[] outSig, int outOff, int outStep) {
111
112        int i;
113        int outLen = lowLen + highLen; //Length of the output signal
114        int iStep = 2*outStep; //Upsampling in outSig
115        int ik; //Indexing outSig
116        int lk; //Indexing lowSig
117        int hk; //Indexing highSig
118
119        /*
120         *Generate even samples (inverse low-pass filter)
121         */
122
123        //Initialize counters
124        lk = lowOff;
125        hk = highOff;
126        ik = outOff;
127
128        //Handle tail boundary effect. Use symmetric extension.
129        if(outLen>1) {
130            outSig[ik] = lowSig[lk] - ((highSig[hk]+1)>>1);
131        }
132        else {
133            outSig[ik] = lowSig[lk];
134        }
135
136        lk += lowStep;
137        hk += highStep;
138        ik += iStep;
139
140        //Apply lifting step to each "inner" sample.
141        for(i = 2; i < outLen-1; i += 2) {
142            outSig[ik] = lowSig[lk] -
143                ((highSig[hk-highStep] + highSig[hk] + 2)>>2);
144
145            lk += lowStep;
146            hk += highStep;
147            ik += iStep;
148        }
149
150        //Handle head boundary effect if input signal has odd length.
151        if((outLen % 2 == 1)&&(outLen>2)) {
152            outSig[ik] = lowSig[lk] - ((2*highSig[hk-highStep]+2)>>2);
153        }
154
155        /*
156         *Generate odd samples (inverse high pass-filter)
157         */
158
159        //Initialize counters
160        hk = highOff;
161        ik = outOff + outStep;
162
163        //Apply first lifting step to each "inner" sample.
164        for(i = 1; i < outLen-1; i += 2) {
165            // Since signs are inversed (add instead of substract)
166            // the +1 rounding dissapears.
167            outSig[ik] = highSig[hk] +
168                ((outSig[ik-outStep] + outSig[ik+outStep]) >> 1);
169
170            hk += highStep;
171            ik += iStep;
172        }
173
174        //Handle head boundary effect if input signal has even length.
175        if( outLen%2==0 && outLen>1) {
176            outSig[ik] = highSig[hk] + outSig[ik-outStep];
177        }
178    }
179
180    /**
181     * An implementation of the synthetize_hpf() method that works on int
182     * data, for the inverse 5x3 wavelet transform using thelifting
183     * scheme. See the general description of the synthetize_hpf() method in
184     * the SynWTFilter class for more details.
185     *
186     * <P>The coefficients of the first lifting step are [-1/4 1 -1/4].
187     *
188     * <P>The coefficients of the second lifting step are [1/2 1 1/2].
189     *
190     * @param lowSig This is the array that contains the low-pass
191     * input signal.
192     *
193     * @param lowOff This is the index in lowSig of the first sample to
194     * filter.
195     *
196     * @param lowLen This is the number of samples in the low-pass
197     * input signal to filter.
198     *
199     * @param lowStep This is the step, or interleave factor, of the
200     * low-pass input signal samples in the lowSig array.
201     *
202     * @param highSig This is the array that contains the high-pass
203     * input signal.
204     *
205     * @param highOff This is the index in highSig of the first sample to
206     * filter.
207     *
208     * @param highLen This is the number of samples in the high-pass
209     * input signal to filter.
210     *
211     * @param highStep This is the step, or interleave factor, of the
212     * high-pass input signal samples in the highSig array.
213     *
214     * @param outSig This is the array where the output signal is
215     * placed. It should be long enough to contain the output signal.
216     *
217     * @param outOff This is the index in outSig of the element where
218     * to put the first output sample.
219     *
220     * @param outStep This is the step, or interleave factor, of the
221     * output samples in the outSig array.
222     *
223     * @see SynWTFilter#synthetize_hpf
224     * */
225    public
226        void synthetize_hpf(int[] lowSig, int lowOff, int lowLen, int lowStep,
227                        int[] highSig, int highOff, int highLen, int highStep,
228                        int[] outSig, int outOff, int outStep) {
229
230        int i;
231        int outLen = lowLen + highLen; //Length of the output signal
232        int iStep = 2*outStep; //Upsampling in outSig
233        int ik; //Indexing outSig
234        int lk; //Indexing lowSig
235        int hk; //Indexing highSig
236
237        /*
238         *Generate even samples (inverse low-pass filter)
239         */
240
241        //Initialize counters
242        lk = lowOff;
243        hk = highOff;
244        ik = outOff + outStep;
245
246        //Apply lifting step to each "inner" sample.
247        for(i = 1; i<outLen-1; i += 2) {
248            outSig[ik] = lowSig[lk] -
249                ((highSig[hk] + highSig[hk+highStep] + 2)>>2);
250
251            lk += lowStep;
252            hk += highStep;
253            ik += iStep;
254        }
255
256        if ( (outLen>1) && (outLen%2==0) ) {
257            // symmetric extension.
258            outSig[ik] = lowSig[lk] - ((2*highSig[hk]+2)>>2);
259        }
260        /*
261         *Generate odd samples (inverse high pass-filter)
262         */
263
264        //Initialize counters
265        hk = highOff;
266        ik = outOff;
267
268        if ( outLen>1 ) {
269            outSig[ik] = highSig[hk] + outSig[ik+outStep];
270        }
271        else {
272            // Normalize for Nyquist gain
273            outSig[ik] = highSig[hk]>>1;
274        }
275
276        hk += highStep;
277        ik += iStep;
278
279        //Apply first lifting step to each "inner" sample.
280        for(i = 2; i < outLen-1; i += 2) {
281            // Since signs are inversed (add instead of substract)
282            // the +1 rounding dissapears.
283            outSig[ik] = highSig[hk] +
284                ((outSig[ik-outStep] + outSig[ik+outStep]) >> 1);
285            hk += highStep;
286            ik += iStep;
287        }
288
289        //Handle head boundary effect if input signal has odd length.
290        if(outLen%2==1 && outLen>1) {
291            outSig[ik] = highSig[hk] + outSig[ik-outStep];
292        }
293    }
294
295    /**
296     * Returns the negative support of the low-pass analysis filter. That is
297     * the number of taps of the filter in the negative direction.
298     *
299     * @return 2
300     * */
301    public int getAnLowNegSupport() {
302        return 2;
303    }
304
305    /**
306     * Returns the positive support of the low-pass analysis filter. That is
307     * the number of taps of the filter in the negative direction.
308     *
309     * @return The number of taps of the low-pass analysis filter in the
310     * positive direction
311     * */
312    public int getAnLowPosSupport() {
313        return 2;
314    }
315
316    /**
317     * Returns the negative support of the high-pass analysis filter. That is
318     * the number of taps of the filter in the negative direction.
319     *
320     * @return The number of taps of the high-pass analysis filter in
321     * the negative direction
322     * */
323    public int getAnHighNegSupport() {
324        return 1;
325    }
326
327    /**
328     * Returns the positive support of the high-pass analysis filter. That is
329     * the number of taps of the filter in the negative direction.
330     *
331     * @return The number of taps of the high-pass analysis filter in
332     * the positive direction
333     * */
334    public int getAnHighPosSupport() {
335        return 1;
336    }
337
338    /**
339     * Returns the negative support of the low-pass synthesis filter. That is
340     * the number of taps of the filter in the negative direction.
341     *
342     * <P>A MORE PRECISE DEFINITION IS NEEDED
343     *
344     * @return The number of taps of the low-pass synthesis filter in the
345     * negative direction
346     * */
347    public int getSynLowNegSupport() {
348        return 1;
349    }
350
351    /**
352     * Returns the positive support of the low-pass synthesis filter. That is
353     * the number of taps of the filter in the negative direction.
354     *
355     * <P>A MORE PRECISE DEFINITION IS NEEDED
356     *
357     * @return The number of taps of the low-pass synthesis filter in the
358     * positive direction
359     * */
360    public int getSynLowPosSupport() {
361        return 1;
362    }
363
364    /**
365     * Returns the negative support of the high-pass synthesis filter. That is
366     * the number of taps of the filter in the negative direction.
367     *
368     * <P>A MORE PRECISE DEFINITION IS NEEDED
369     *
370     * @return The number of taps of the high-pass synthesis filter in the
371     * negative direction
372     * */
373    public int getSynHighNegSupport() {
374        return 2;
375    }
376
377    /**
378     * Returns the positive support of the high-pass synthesis filter. That is
379     * the number of taps of the filter in the negative direction.
380     *
381     * <P>A MORE PRECISE DEFINITION IS NEEDED
382     *
383     * @return The number of taps of the high-pass synthesis filter in the
384     * positive direction
385     * */
386    public int getSynHighPosSupport() {
387        return 2;
388    }
389
390    /**
391     * Returns the implementation type of this filter, as defined in this
392     * class, such as WT_FILTER_INT_LIFT, WT_FILTER_FLOAT_LIFT,
393     * WT_FILTER_FLOAT_CONVOL.
394     *
395     * @return WT_FILTER_INT_LIFT.
396     * */
397    public int getImplType() {
398        return WT_FILTER_INT_LIFT;
399    }
400
401    /**
402     * Returns the reversibility of the filter. A filter is considered
403     * reversible if it is suitable for lossless coding.
404     *
405     * @return true since the 5x3 is reversible, provided the appropriate
406     * rounding is performed.
407     * */
408    public boolean isReversible() {
409        return true;
410    }
411
412    /**
413     * Returns true if the wavelet filter computes or uses the same "inner"
414     * subband coefficient as the full frame wavelet transform, and false
415     * otherwise. In particular, for block based transforms with reduced
416     * overlap, this method should return false. The term "inner" indicates
417     * that this applies only with respect to the coefficient that are not
418     * affected by image boundaries processings such as symmetric extension,
419     * since there is not reference method for this.
420     *
421     * <P>The result depends on the length of the allowed overlap when
422     * compared to the overlap required by the wavelet filter. It also depends
423     * on how overlap processing is implemented in the wavelet filter.
424     *
425     * @param tailOvrlp This is the number of samples in the input signal
426     * before the first sample to filter that can be used for overlap.
427     *
428     * @param headOvrlp This is the number of samples in the input signal
429     * after the last sample to filter that can be used for overlap.
430     *
431     * @param inLen This is the lenght of the input signal to filter.The
432     * required number of samples in the input signal after the last sample
433     * depends on the length of the input signal.
434     *
435     * @return true if both overlaps are greater than 2, and correct
436     * processing is applied in the analyze() method.
437     * */
438    public boolean isSameAsFullWT(int tailOvrlp, int headOvrlp, int inLen) {
439
440        //If the input signal has even length.
441        if(inLen % 2 == 0) {
442            if(tailOvrlp >= 2 && headOvrlp >= 1) return true;
443            else return false;
444        }
445        //Else if the input signal has odd length.
446        else {
447            if(tailOvrlp >= 2 && headOvrlp >= 2) return true;
448            else return false;
449        }
450    }
451
452    /**
453     * Returns a string of information about the synthesis wavelet filter
454     *
455     * @return wavelet filter type.
456     * */
457    public String toString(){
458        return "w5x3 (lifting)";
459    }
460
461}