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: * */
045: package jj2000.j2k.wavelet.synthesis;
046:
047: import jj2000.j2k.wavelet.*;
048: import jj2000.j2k.image.*;
049: import 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: * */
063: public 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 void synthetize_lpf(int[] lowSig, int lowOff, int lowLen,
111: int lowStep, int[] highSig, int highOff, int highLen,
112: int highStep, int[] outSig, int outOff, int outStep) {
113:
114: int i;
115: int outLen = lowLen + highLen; //Length of the output signal
116: int iStep = 2 * outStep; //Upsampling in outSig
117: int ik; //Indexing outSig
118: int lk; //Indexing lowSig
119: int hk; //Indexing highSig
120:
121: /*
122: *Generate even samples (inverse low-pass filter)
123: */
124:
125: //Initialize counters
126: lk = lowOff;
127: hk = highOff;
128: ik = outOff;
129:
130: //Handle tail boundary effect. Use symmetric extension.
131: if (outLen > 1) {
132: outSig[ik] = lowSig[lk] - ((highSig[hk] + 1) >> 1);
133: } else {
134: outSig[ik] = lowSig[lk];
135: }
136:
137: lk += lowStep;
138: hk += highStep;
139: ik += iStep;
140:
141: //Apply lifting step to each "inner" sample.
142: for (i = 2; i < outLen - 1; i += 2) {
143: outSig[ik] = lowSig[lk]
144: - ((highSig[hk - highStep] + highSig[hk] + 2) >> 2);
145:
146: lk += lowStep;
147: hk += highStep;
148: ik += iStep;
149: }
150:
151: //Handle head boundary effect if input signal has odd length.
152: if ((outLen % 2 == 1) && (outLen > 2)) {
153: outSig[ik] = lowSig[lk]
154: - ((2 * highSig[hk - highStep] + 2) >> 2);
155: }
156:
157: /*
158: *Generate odd samples (inverse high pass-filter)
159: */
160:
161: //Initialize counters
162: hk = highOff;
163: ik = outOff + outStep;
164:
165: //Apply first lifting step to each "inner" sample.
166: for (i = 1; i < outLen - 1; i += 2) {
167: // Since signs are inversed (add instead of substract)
168: // the +1 rounding dissapears.
169: outSig[ik] = highSig[hk]
170: + ((outSig[ik - outStep] + outSig[ik + outStep]) >> 1);
171:
172: hk += highStep;
173: ik += iStep;
174: }
175:
176: //Handle head boundary effect if input signal has even length.
177: if (outLen % 2 == 0 && outLen > 1) {
178: outSig[ik] = highSig[hk] + outSig[ik - outStep];
179: }
180: }
181:
182: /**
183: * An implementation of the synthetize_hpf() method that works on int
184: * data, for the inverse 5x3 wavelet transform using thelifting
185: * scheme. See the general description of the synthetize_hpf() method in
186: * the SynWTFilter class for more details.
187: *
188: * <P>The coefficients of the first lifting step are [-1/4 1 -1/4].
189: *
190: * <P>The coefficients of the second lifting step are [1/2 1 1/2].
191: *
192: * @param lowSig This is the array that contains the low-pass
193: * input signal.
194: *
195: * @param lowOff This is the index in lowSig of the first sample to
196: * filter.
197: *
198: * @param lowLen This is the number of samples in the low-pass
199: * input signal to filter.
200: *
201: * @param lowStep This is the step, or interleave factor, of the
202: * low-pass input signal samples in the lowSig array.
203: *
204: * @param highSig This is the array that contains the high-pass
205: * input signal.
206: *
207: * @param highOff This is the index in highSig of the first sample to
208: * filter.
209: *
210: * @param highLen This is the number of samples in the high-pass
211: * input signal to filter.
212: *
213: * @param highStep This is the step, or interleave factor, of the
214: * high-pass input signal samples in the highSig array.
215: *
216: * @param outSig This is the array where the output signal is
217: * placed. It should be long enough to contain the output signal.
218: *
219: * @param outOff This is the index in outSig of the element where
220: * to put the first output sample.
221: *
222: * @param outStep This is the step, or interleave factor, of the
223: * output samples in the outSig array.
224: *
225: * @see SynWTFilter#synthetize_hpf
226: * */
227: public void synthetize_hpf(int[] lowSig, int lowOff, int lowLen,
228: int lowStep, int[] highSig, int highOff, int highLen,
229: int highStep, int[] outSig, int outOff, int outStep) {
230:
231: int i;
232: int outLen = lowLen + highLen; //Length of the output signal
233: int iStep = 2 * outStep; //Upsampling in outSig
234: int ik; //Indexing outSig
235: int lk; //Indexing lowSig
236: int hk; //Indexing highSig
237:
238: /*
239: *Generate even samples (inverse low-pass filter)
240: */
241:
242: //Initialize counters
243: lk = lowOff;
244: hk = highOff;
245: ik = outOff + outStep;
246:
247: //Apply lifting step to each "inner" sample.
248: for (i = 1; i < outLen - 1; i += 2) {
249: outSig[ik] = lowSig[lk]
250: - ((highSig[hk] + highSig[hk + highStep] + 2) >> 2);
251:
252: lk += lowStep;
253: hk += highStep;
254: ik += iStep;
255: }
256:
257: if ((outLen > 1) && (outLen % 2 == 0)) {
258: // symmetric extension.
259: outSig[ik] = lowSig[lk] - ((2 * highSig[hk] + 2) >> 2);
260: }
261: /*
262: *Generate odd samples (inverse high pass-filter)
263: */
264:
265: //Initialize counters
266: hk = highOff;
267: ik = outOff;
268:
269: if (outLen > 1) {
270: outSig[ik] = highSig[hk] + outSig[ik + outStep];
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,
439: int inLen) {
440:
441: //If the input signal has even length.
442: if (inLen % 2 == 0) {
443: if (tailOvrlp >= 2 && headOvrlp >= 1)
444: return true;
445: else
446: return false;
447: }
448: //Else if the input signal has odd length.
449: else {
450: if (tailOvrlp >= 2 && headOvrlp >= 2)
451: return true;
452: else
453: return false;
454: }
455: }
456:
457: /**
458: * Returns a string of information about the synthesis wavelet filter
459: *
460: * @return wavelet filter type.
461: * */
462: public String toString() {
463: return "w5x3 (lifting)";
464: }
465:
466: }
|