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