Source Code Cross Referenced for InvWTFull.java in  » 6.0-JDK-Modules » Java-Advanced-Imaging » jj2000 » j2k » wavelet » synthesis » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » 6.0 JDK Modules » Java Advanced Imaging » jj2000.j2k.wavelet.synthesis 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * $RCSfile: InvWTFull.java,v $
003:         * $Revision: 1.1 $
004:         * $Date: 2005/02/11 05:02:32 $
005:         * $State: Exp $
006:         *
007:         * Class:                   InvWTFull
008:         *
009:         * Description:             This class implements a full page inverse DWT for
010:         *                          int and float data.
011:         *
012:         *                          the InvWTFullInt and InvWTFullFloat
013:         *                          classes by Bertrand Berthelot, Apr-19-1999
014:         *
015:         *
016:         * COPYRIGHT:
017:         *
018:         * This software module was originally developed by Raphaël Grosbois and
019:         * Diego Santa Cruz (Swiss Federal Institute of Technology-EPFL); Joel
020:         * Askelöf (Ericsson Radio Systems AB); and Bertrand Berthelot, David
021:         * Bouchard, Félix Henry, Gerard Mozelle and Patrice Onno (Canon Research
022:         * Centre France S.A) in the course of development of the JPEG2000
023:         * standard as specified by ISO/IEC 15444 (JPEG 2000 Standard). This
024:         * software module is an implementation of a part of the JPEG 2000
025:         * Standard. Swiss Federal Institute of Technology-EPFL, Ericsson Radio
026:         * Systems AB and Canon Research Centre France S.A (collectively JJ2000
027:         * Partners) agree not to assert against ISO/IEC and users of the JPEG
028:         * 2000 Standard (Users) any of their rights under the copyright, not
029:         * including other intellectual property rights, for this software module
030:         * with respect to the usage by ISO/IEC and Users of this software module
031:         * or modifications thereof for use in hardware or software products
032:         * claiming conformance to the JPEG 2000 Standard. Those intending to use
033:         * this software module in hardware or software products are advised that
034:         * their use may infringe existing patents. The original developers of
035:         * this software module, JJ2000 Partners and ISO/IEC assume no liability
036:         * for use of this software module or modifications thereof. No license
037:         * or right to this software module is granted for non JPEG 2000 Standard
038:         * conforming products. JJ2000 Partners have full right to use this
039:         * software module for his/her own purpose, assign or donate this
040:         * software module to any third party and to inhibit third parties from
041:         * using this software module for non JPEG 2000 Standard conforming
042:         * products. This copyright notice must be included in all copies or
043:         * derivative works of this software module.
044:         *
045:         * Copyright (c) 1999/2000 JJ2000 Partners.
046:         * */
047:        package jj2000.j2k.wavelet.synthesis;
048:
049:        import java.awt.Point;
050:
051:        import jj2000.j2k.wavelet.*;
052:        import jj2000.j2k.decoder.*;
053:        import jj2000.j2k.image.*;
054:        import jj2000.j2k.util.*;
055:
056:        /**
057:         * This class implements the InverseWT with the full-page approach for int and
058:         * float data.
059:         *
060:         * <P>The image can be reconstructed at different (image) resolution levels
061:         * indexed from the lowest resolution available for each tile-component. This
062:         * is controlled by the setImgResLevel() method.
063:         *
064:         * <P>Note: Image resolution level indexes may differ from tile-component
065:         * resolution index. They are indeed indexed starting from the lowest number
066:         * of decomposition levels of each component of each tile.
067:         *
068:         * <P>Example: For an image (1 tile) with 2 components (component 0 having 2
069:         * decomposition levels and component 1 having 3 decomposition levels), the
070:         * first (tile-) component has 3 resolution levels and the second one has 4
071:         * resolution levels, whereas the image has only 3 resolution levels
072:         * available.
073:         *
074:         * <P>This implementation does not support progressive data, all data is
075:         * considered to be non-progressive (i.e. "final" data) and the 'progressive'
076:         * attribute of the 'DataBlk' class is always set to false, see the 'DataBlk'
077:         * class.
078:         *
079:         * @see DataBlk
080:         * */
081:        public class InvWTFull extends InverseWT {
082:
083:            /** Reference to the ProgressWatch instance if any */
084:            private ProgressWatch pw = null;
085:
086:            /** The total number of code-blocks to decode */
087:            private int cblkToDecode = 0;
088:
089:            /** The number of already decoded code-blocks */
090:            private int nDecCblk = 0;
091:
092:            /** the code-block buffer's source i.e. the quantizer */
093:            private CBlkWTDataSrcDec src;
094:
095:            /** Current data type */
096:            private int dtype;
097:
098:            /**
099:             * block storing the reconstructed image for each component
100:             */
101:            private DataBlk reconstructedComps[];
102:
103:            /** Number of decomposition levels in each component */
104:            private int[] ndl;
105:
106:            /**
107:             * The reversible flag for each component in each tile. The first index is
108:             * the tile index, the second one is the component index. The
109:             * reversibility of the components for each tile are calculated on a as
110:             * needed basis.
111:             * */
112:            private boolean reversible[][];
113:
114:            /**
115:             * Initializes this object with the given source of wavelet
116:             * coefficients. It initializes the resolution level for full resolutioin
117:             * reconstruction.
118:             *
119:             * @param src from where the wavelet coefficinets should be
120:             * obtained.
121:             *
122:             * @param decSpec The decoder specifications
123:             * */
124:            public InvWTFull(CBlkWTDataSrcDec src, DecoderSpecs decSpec) {
125:                super (src, decSpec);
126:                this .src = src;
127:
128:                int nc = src.getNumComps();
129:                reconstructedComps = new DataBlk[nc];
130:                ndl = new int[nc];
131:                pw = FacilityManager.getProgressWatch();
132:            }
133:
134:            /**
135:             * Returns the reversibility of the current subband. It computes
136:             * iteratively the reversibility of the child subbands. For each subband
137:             * it tests the reversibility of the horizontal and vertical synthesis
138:             * filters used to reconstruct this subband.
139:             *
140:             * @param subband The current subband.
141:             *
142:             * @return true if all the  filters used to reconstruct the current 
143:             * subband are reversible
144:             * */
145:            private boolean isSubbandReversible(Subband subband) {
146:                if (subband.isNode) {
147:                    // It's reversible if the filters to obtain the 4 subbands are
148:                    // reversible and the ones for this one are reversible too.
149:                    return isSubbandReversible(subband.getLL())
150:                            && isSubbandReversible(subband.getHL())
151:                            && isSubbandReversible(subband.getLH())
152:                            && isSubbandReversible(subband.getHH())
153:                            && ((SubbandSyn) subband).hFilter.isReversible()
154:                            && ((SubbandSyn) subband).vFilter.isReversible();
155:                } else {
156:                    // Leaf subband. Reversibility of data depends on source, so say
157:                    // it's true
158:                    return true;
159:                }
160:            }
161:
162:            /**
163:             * Returns the reversibility of the wavelet transform for the specified
164:             * component, in the current tile. A wavelet transform is reversible when
165:             * it is suitable for lossless and lossy-to-lossless compression.
166:             *
167:             * @param t The index of the tile.
168:             *
169:             * @param c The index of the component.
170:             *
171:             * @return true is the wavelet transform is reversible, false if not.
172:             * */
173:            public boolean isReversible(int t, int c) {
174:                if (reversible[t] == null) {
175:                    // Reversibility not yet calculated for this tile
176:                    reversible[t] = new boolean[getNumComps()];
177:                    for (int i = reversible.length - 1; i >= 0; i--) {
178:                        reversible[t][i] = isSubbandReversible(src
179:                                .getSynSubbandTree(t, i));
180:                    }
181:                }
182:                return reversible[t][c];
183:            }
184:
185:            /**
186:             * Returns the number of bits, referred to as the "range bits",
187:             * corresponding to the nominal range of the data in the specified
188:             * component.
189:             *
190:             * <P>The returned value corresponds to the nominal dynamic range of the
191:             * reconstructed image data, as long as the getNomRangeBits() method of
192:             * the source returns a value corresponding to the nominal dynamic range
193:             * of the image data and not not of the wavelet coefficients.
194:             *
195:             * <P>If this number is <i>b</b> then for unsigned data the nominal range
196:             * is between 0 and 2^b-1, and for signed data it is between -2^(b-1) and
197:             * 2^(b-1)-1.
198:             *
199:             * @param c The index of the component.
200:             *
201:             * @return The number of bits corresponding to the nominal range of the
202:             * data.
203:             * */
204:            public int getNomRangeBits(int c) {
205:                return src.getNomRangeBits(c);
206:            }
207:
208:            /**
209:             * Returns the position of the fixed point in the specified
210:             * component. This is the position of the least significant integral
211:             * (i.e. non-fractional) bit, which is equivalent to the number of
212:             * fractional bits. For instance, for fixed-point values with 2 fractional
213:             * bits, 2 is returned. For floating-point data this value does not apply
214:             * and 0 should be returned. Position 0 is the position of the least
215:             * significant bit in the data.
216:             *
217:             * <P>This default implementation assumes that the wavelet transform does
218:             * not modify the fixed point. If that were the case this method should be
219:             * overriden.
220:             *
221:             * @param c The index of the component.
222:             *
223:             * @return The position of the fixed-point, which is the same as the
224:             * number of fractional bits. For floating-point data 0 is returned.
225:             * */
226:            public int getFixedPoint(int c) {
227:                return src.getFixedPoint(c);
228:            }
229:
230:            /**
231:             * Returns a block of image data containing the specifed rectangular area,
232:             * in the specified component, as a reference to the internal buffer (see
233:             * below). The rectangular area is specified by the coordinates and
234:             * dimensions of the 'blk' object.
235:             *
236:             * <p>The area to return is specified by the 'ulx', 'uly', 'w' and 'h'
237:             * members of the 'blk' argument. These members are not modified by this
238:             * method.</p>
239:             *
240:             * <p>The data returned by this method can be the data in the internal
241:             * buffer of this object, if any, and thus can not be modified by the
242:             * caller. The 'offset' and 'scanw' of the returned data can be
243:             * arbitrary. See the 'DataBlk' class.</p>
244:             *
245:             * <p>The returned data has its 'progressive' attribute unset
246:             * (i.e. false).</p>
247:             *
248:             * @param blk Its coordinates and dimensions specify the area to return.
249:             *
250:             * @param c The index of the component from which to get the data.
251:             *
252:             * @return The requested DataBlk
253:             *
254:             * @see #getInternCompData
255:             * */
256:            public final DataBlk getInternCompData(DataBlk blk, int c) {
257:                int tIdx = getTileIdx();
258:                if (src.getSynSubbandTree(tIdx, c).getHorWFilter() == null) {
259:                    dtype = DataBlk.TYPE_INT;
260:                } else {
261:                    dtype = src.getSynSubbandTree(tIdx, c).getHorWFilter()
262:                            .getDataType();
263:                }
264:
265:                //If the source image has not been decomposed 
266:                if (reconstructedComps[c] == null) {
267:                    //Allocate component data buffer
268:                    switch (dtype) {
269:                    case DataBlk.TYPE_FLOAT:
270:                        reconstructedComps[c] = new DataBlkFloat(0, 0,
271:                                getTileCompWidth(tIdx, c), getTileCompHeight(
272:                                        tIdx, c));
273:                        break;
274:                    case DataBlk.TYPE_INT:
275:                        reconstructedComps[c] = new DataBlkInt(0, 0,
276:                                getTileCompWidth(tIdx, c), getTileCompHeight(
277:                                        tIdx, c));
278:                        break;
279:                    }
280:                    //Reconstruct source image
281:                    waveletTreeReconstruction(reconstructedComps[c], src
282:                            .getSynSubbandTree(tIdx, c), c);
283:                    if (pw != null && c == src.getNumComps() - 1) {
284:                        pw.terminateProgressWatch();
285:                    }
286:                }
287:
288:                if (blk.getDataType() != dtype) {
289:                    if (dtype == DataBlk.TYPE_INT) {
290:                        blk = new DataBlkInt(blk.ulx, blk.uly, blk.w, blk.h);
291:                    } else {
292:                        blk = new DataBlkFloat(blk.ulx, blk.uly, blk.w, blk.h);
293:                    }
294:                }
295:                // Set the reference to the internal buffer
296:                blk.setData(reconstructedComps[c].getData());
297:                blk.offset = reconstructedComps[c].w * blk.uly + blk.ulx;
298:                blk.scanw = reconstructedComps[c].w;
299:                blk.progressive = false;
300:                return blk;
301:            }
302:
303:            /**
304:             * Returns a block of image data containing the specifed rectangular area,
305:             * in the specified component, as a copy (see below). The rectangular area
306:             * is specified by the coordinates and dimensions of the 'blk' object.
307:             *
308:             * <P>The area to return is specified by the 'ulx', 'uly', 'w' and 'h'
309:             * members of the 'blk' argument. These members are not modified by this
310:             * method.
311:             *
312:             * <P>The data returned by this method is always a copy of the internal
313:             * data of this object, if any, and it can be modified "in place" without
314:             * any problems after being returned. The 'offset' of the returned data is
315:             * 0, and the 'scanw' is the same as the block's width. See the 'DataBlk'
316:             * class.
317:             *
318:             * <P>If the data array in 'blk' is <tt>null</tt>, then a new one is
319:             * created. If the data array is not <tt>null</tt> then it must be big
320:             * enough to contain the requested area.
321:             *
322:             * <P>The returned data always has its 'progressive' attribute unset (i.e
323:             * false)
324:             *
325:             * @param blk Its coordinates and dimensions specify the area to
326:             * return. If it contains a non-null data array, then it must be large
327:             * enough. If it contains a null data array a new one is created. The
328:             * fields in this object are modified to return the data.
329:             *
330:             * @param c The index of the component from which to get the data.
331:             *
332:             * @return The requested DataBlk
333:             *
334:             * @see #getCompData
335:             * */
336:            public DataBlk getCompData(DataBlk blk, int c) {
337:                int j;
338:                Object src_data, dst_data;
339:                int src_data_int[], dst_data_int[];
340:                float src_data_float[], dst_data_float[];
341:
342:                // To keep compiler happy
343:                dst_data = null;
344:
345:                // Ensure output buffer
346:                switch (blk.getDataType()) {
347:                case DataBlk.TYPE_INT:
348:                    dst_data_int = (int[]) blk.getData();
349:                    if (dst_data_int == null
350:                            || dst_data_int.length < blk.w * blk.h) {
351:                        dst_data_int = new int[blk.w * blk.h];
352:                    }
353:                    dst_data = dst_data_int;
354:                    break;
355:                case DataBlk.TYPE_FLOAT:
356:                    dst_data_float = (float[]) blk.getData();
357:                    if (dst_data_float == null
358:                            || dst_data_float.length < blk.w * blk.h) {
359:                        dst_data_float = new float[blk.w * blk.h];
360:                    }
361:                    dst_data = dst_data_float;
362:                    break;
363:                }
364:
365:                // Use getInternCompData() to get the data, since getInternCompData()
366:                // returns reference to internal buffer, we must copy it.
367:                blk = getInternCompData(blk, c);
368:
369:                // Copy the data
370:                blk.setData(dst_data);
371:                blk.offset = 0;
372:                blk.scanw = blk.w;
373:                return blk;
374:            }
375:
376:            /**
377:             * Performs the 2D inverse wavelet transform on a subband of the image, on
378:             * the specified component. This method will successively perform 1D
379:             * filtering steps on all columns and then all lines of the subband.
380:             *
381:             * @param db the buffer for the image/wavelet data.
382:             *
383:             * @param sb The subband to reconstruct.
384:             *
385:             * @param c The index of the component to reconstruct 
386:             * */
387:            private void wavelet2DReconstruction(DataBlk db, SubbandSyn sb,
388:                    int c) {
389:                Object data;
390:                Object buf;
391:                int ulx, uly, w, h;
392:                int i, j, k;
393:                int offset;
394:
395:                // If subband is empty (i.e. zero size) nothing to do
396:                if (sb.w == 0 || sb.h == 0) {
397:                    return;
398:                }
399:
400:                data = db.getData();
401:
402:                ulx = sb.ulx;
403:                uly = sb.uly;
404:                w = sb.w;
405:                h = sb.h;
406:
407:                buf = null; // To keep compiler happy
408:
409:                switch (sb.getHorWFilter().getDataType()) {
410:                case DataBlk.TYPE_INT:
411:                    buf = new int[(w >= h) ? w : h];
412:                    break;
413:                case DataBlk.TYPE_FLOAT:
414:                    buf = new float[(w >= h) ? w : h];
415:                    break;
416:                }
417:
418:                //Perform the horizontal reconstruction
419:                offset = (uly - db.uly) * db.w + ulx - db.ulx;
420:                if (sb.ulcx % 2 == 0) { // start index is even => use LPF
421:                    for (i = 0; i < h; i++, offset += db.w) {
422:                        System.arraycopy(data, offset, buf, 0, w);
423:                        sb.hFilter.synthetize_lpf(buf, 0, (w + 1) / 2, 1, buf,
424:                                (w + 1) / 2, w / 2, 1, data, offset, 1);
425:                    }
426:                } else { // start index is odd => use HPF
427:                    for (i = 0; i < h; i++, offset += db.w) {
428:                        System.arraycopy(data, offset, buf, 0, w);
429:                        sb.hFilter.synthetize_hpf(buf, 0, w / 2, 1, buf, w / 2,
430:                                (w + 1) / 2, 1, data, offset, 1);
431:                    }
432:                }
433:
434:                //Perform the vertical reconstruction 
435:                offset = (uly - db.uly) * db.w + ulx - db.ulx;
436:                switch (sb.getVerWFilter().getDataType()) {
437:                case DataBlk.TYPE_INT:
438:                    int data_int[],
439:                    buf_int[];
440:                    data_int = (int[]) data;
441:                    buf_int = (int[]) buf;
442:                    if (sb.ulcy % 2 == 0) { // start index is even => use LPF
443:                        for (j = 0; j < w; j++, offset++) {
444:                            for (i = h - 1, k = offset + i * db.w; i >= 0; i--, k -= db.w)
445:                                buf_int[i] = data_int[k];
446:                            sb.vFilter.synthetize_lpf(buf, 0, (h + 1) / 2, 1,
447:                                    buf, (h + 1) / 2, h / 2, 1, data, offset,
448:                                    db.w);
449:                        }
450:                    } else { // start index is odd => use HPF
451:                        for (j = 0; j < w; j++, offset++) {
452:                            for (i = h - 1, k = offset + i * db.w; i >= 0; i--, k -= db.w)
453:                                buf_int[i] = data_int[k];
454:                            sb.vFilter.synthetize_hpf(buf, 0, h / 2, 1, buf,
455:                                    h / 2, (h + 1) / 2, 1, data, offset, db.w);
456:                        }
457:                    }
458:                    break;
459:                case DataBlk.TYPE_FLOAT:
460:                    float data_float[],
461:                    buf_float[];
462:                    data_float = (float[]) data;
463:                    buf_float = (float[]) buf;
464:                    if (sb.ulcy % 2 == 0) { // start index is even => use LPF
465:                        for (j = 0; j < w; j++, offset++) {
466:                            for (i = h - 1, k = offset + i * db.w; i >= 0; i--, k -= db.w)
467:                                buf_float[i] = data_float[k];
468:                            sb.vFilter.synthetize_lpf(buf, 0, (h + 1) / 2, 1,
469:                                    buf, (h + 1) / 2, h / 2, 1, data, offset,
470:                                    db.w);
471:                        }
472:                    } else { // start index is odd => use HPF
473:                        for (j = 0; j < w; j++, offset++) {
474:                            for (i = h - 1, k = offset + i * db.w; i >= 0; i--, k -= db.w)
475:                                buf_float[i] = data_float[k];
476:                            sb.vFilter.synthetize_hpf(buf, 0, h / 2, 1, buf,
477:                                    h / 2, (h + 1) / 2, 1, data, offset, db.w);
478:                        }
479:                    }
480:                    break;
481:                }
482:            }
483:
484:            /**
485:             * Performs the inverse wavelet transform on the whole component. It
486:             * iteratively reconstructs the subbands from leaves up to the root
487:             * node. This method is recursive, the first call to it the 'sb' must be
488:             * the root of the subband tree. The method will then process the entire
489:             * subband tree by calling itslef recursively.
490:             *
491:             * @param img The buffer for the image/wavelet data.
492:             *
493:             * @param sb The subband to reconstruct.
494:             *
495:             * @param c The index of the component to reconstruct 
496:             * */
497:            private void waveletTreeReconstruction(DataBlk img, SubbandSyn sb,
498:                    int c) {
499:
500:                DataBlk subbData;
501:
502:                // If the current subband is a leaf then get the data from the source
503:                if (!sb.isNode) {
504:                    int i, m, n;
505:                    Object src_data, dst_data;
506:                    Point ncblks;
507:
508:                    if (sb.w == 0 || sb.h == 0) {
509:                        return; // If empty subband do nothing
510:                    }
511:
512:                    // Get all code-blocks in subband
513:                    if (dtype == DataBlk.TYPE_INT) {
514:                        subbData = new DataBlkInt();
515:                    } else {
516:                        subbData = new DataBlkFloat();
517:                    }
518:                    ncblks = sb.numCb;
519:                    dst_data = img.getData();
520:                    for (m = 0; m < ncblks.y; m++) {
521:                        for (n = 0; n < ncblks.x; n++) {
522:                            subbData = src.getInternCodeBlock(c, m, n, sb,
523:                                    subbData);
524:                            src_data = subbData.getData();
525:                            if (pw != null) {
526:                                nDecCblk++;
527:                                pw.updateProgressWatch(nDecCblk, null);
528:                            }
529:                            // Copy the data line by line
530:                            for (i = subbData.h - 1; i >= 0; i--) {
531:                                System.arraycopy(src_data, subbData.offset + i
532:                                        * subbData.scanw, dst_data,
533:                                        (subbData.uly + i) * img.w
534:                                                + subbData.ulx, subbData.w);
535:                            }
536:                        }
537:                    }
538:                } else if (sb.isNode) {
539:                    // Reconstruct the lower resolution levels if the current subbands
540:                    // is a node
541:
542:                    //Perform the reconstruction of the LL subband
543:                    waveletTreeReconstruction(img, (SubbandSyn) sb.getLL(), c);
544:
545:                    if (sb.resLvl <= reslvl - maxImgRes + ndl[c]) {
546:                        //Reconstruct the other subbands
547:                        waveletTreeReconstruction(img, (SubbandSyn) sb.getHL(),
548:                                c);
549:                        waveletTreeReconstruction(img, (SubbandSyn) sb.getLH(),
550:                                c);
551:                        waveletTreeReconstruction(img, (SubbandSyn) sb.getHH(),
552:                                c);
553:
554:                        //Perform the 2D wavelet decomposition of the current subband
555:                        wavelet2DReconstruction(img, (SubbandSyn) sb, c);
556:                    }
557:                }
558:            }
559:
560:            /**
561:             * Returns the implementation type of this wavelet transform, WT_IMPL_FULL
562:             * (full-page based transform). All components return the same.
563:             *
564:             * @param c The index of the component.
565:             *
566:             * @return WT_IMPL_FULL
567:             *
568:             * @see WaveletTransform#WT_IMPL_FULL
569:             * */
570:            public int getImplementationType(int c) {
571:                return WaveletTransform.WT_IMPL_FULL;
572:            }
573:
574:            /**
575:             * Changes the current tile, given the new indexes. An
576:             * IllegalArgumentException is thrown if the indexes do not correspond to
577:             * a valid tile.
578:             *
579:             * @param x The horizontal index of the tile.
580:             *
581:             * @param y The vertical index of the new tile.
582:             * */
583:            public void setTile(int x, int y) {
584:                int i;
585:
586:                // Change tile
587:                super .setTile(x, y);
588:
589:                int nc = src.getNumComps();
590:                int tIdx = src.getTileIdx();
591:                for (int c = 0; c < nc; c++) {
592:                    ndl[c] = src.getSynSubbandTree(tIdx, c).resLvl;
593:                }
594:
595:                // Reset the decomposed component buffers.
596:                if (reconstructedComps != null) {
597:                    for (i = reconstructedComps.length - 1; i >= 0; i--) {
598:                        reconstructedComps[i] = null;
599:                    }
600:                }
601:
602:                cblkToDecode = 0;
603:                SubbandSyn root, sb;
604:                for (int c = 0; c < nc; c++) {
605:                    root = src.getSynSubbandTree(tIdx, c);
606:                    for (int r = 0; r <= reslvl - maxImgRes + root.resLvl; r++) {
607:                        if (r == 0) {
608:                            sb = (SubbandSyn) root.getSubbandByIdx(0, 0);
609:                            if (sb != null)
610:                                cblkToDecode += sb.numCb.x * sb.numCb.y;
611:                        } else {
612:                            sb = (SubbandSyn) root.getSubbandByIdx(r, 1);
613:                            if (sb != null)
614:                                cblkToDecode += sb.numCb.x * sb.numCb.y;
615:                            sb = (SubbandSyn) root.getSubbandByIdx(r, 2);
616:                            if (sb != null)
617:                                cblkToDecode += sb.numCb.x * sb.numCb.y;
618:                            sb = (SubbandSyn) root.getSubbandByIdx(r, 3);
619:                            if (sb != null)
620:                                cblkToDecode += sb.numCb.x * sb.numCb.y;
621:                        }
622:                    } // Loop on resolution levels
623:                } // Loop on components
624:                nDecCblk = 0;
625:
626:                if (pw != null) {
627:                    pw.initProgressWatch(0, cblkToDecode, "Decoding tile "
628:                            + tIdx + "...");
629:                }
630:            }
631:
632:            /**
633:             * Advances to the next tile, in standard scan-line order (by rows then
634:             * columns). An 'NoNextElementException' is thrown if the current tile is
635:             * the last one (i.e. there is no next tile).
636:             * */
637:            public void nextTile() {
638:                int i;
639:
640:                // Change tile
641:                super .nextTile();
642:
643:                int nc = src.getNumComps();
644:                int tIdx = src.getTileIdx();
645:                for (int c = 0; c < nc; c++) {
646:                    ndl[c] = src.getSynSubbandTree(tIdx, c).resLvl;
647:                }
648:
649:                // Reset the decomposed component buffers.
650:                if (reconstructedComps != null) {
651:                    for (i = reconstructedComps.length - 1; i >= 0; i--) {
652:                        reconstructedComps[i] = null;
653:                    }
654:                }
655:            }
656:
657:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.