Source Code Cross Referenced for ROIScaler.java in  » 6.0-JDK-Modules » Java-Advanced-Imaging » jj2000 » j2k » roi » encoder » 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.roi.encoder 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * $RCSfile: ROIScaler.java,v $
003:         * $Revision: 1.1 $
004:         * $Date: 2005/02/11 05:02:23 $
005:         * $State: Exp $
006:         *
007:         * Class:                   ROIScaler
008:         *
009:         * Description:             This class takes care of the scaling of the
010:         *                          samples
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.roi.encoder;
046:
047:        import java.awt.Point;
048:
049:        import jj2000.j2k.quantization.quantizer.*;
050:        import jj2000.j2k.codestream.writer.*;
051:        import jj2000.j2k.wavelet.analysis.*;
052:        import jj2000.j2k.quantization.*;
053:        import jj2000.j2k.image.input.*;
054:        import jj2000.j2k.wavelet.*;
055:        import jj2000.j2k.image.*;
056:        import jj2000.j2k.util.*;
057:        import jj2000.j2k.roi.*;
058:        import jj2000.j2k.*;
059:
060:        import java.util.*;
061:        import java.io.*;
062:
063:        import com.sun.media.imageioimpl.plugins.jpeg2000.J2KImageWriteParamJava;
064:
065:        /**
066:         * This class deals with the ROI functionality.
067:         *
068:         * <p>The ROI method is the Maxshift method. The ROIScaler works by scaling
069:         * the quantized wavelet coefficients that do not affect the ROI (i.e
070:         * background coefficients) so that these samples get a lower significance
071:         * than the ROI ones. By scaling the coefficients sufficiently, the ROI
072:         * coefficients can be recognized by their amplitude alone and no ROI mask
073:         * needs to be generated at the decoder side.
074:         *
075:         * <p>The source module must be a quantizer and code-block's data is exchange
076:         * with thanks to CBlkWTData instances.
077:         *
078:         * @see Quantizer
079:         * @see CBlkWTData
080:         * */
081:        public class ROIScaler extends ImgDataAdapter implements 
082:                CBlkQuantDataSrcEnc {
083:
084:            /** The prefix for ROI Scaler options: 'R' */
085:            public final static char OPT_PREFIX = 'R';
086:
087:            /** The list of parameters that are accepted for ROI coding. Options
088:             * for ROI Scaler start with 'R'. */
089:            private final static String[][] pinfo = {
090:                    {
091:                            "Rroi",
092:                            "[<component idx>] R <left> <top> <width> <height>"
093:                                    + " or [<component idx>] C <centre column> <centre row> "
094:                                    + "<radius> or [<component idx>] A <filename>",
095:                            "Specifies ROIs shape and location. The shape can be either "
096:                                    + "rectangular 'R', or circular 'C' or arbitrary 'A'. "
097:                                    + "Each new occurrence of an 'R', a 'C' or an 'A' is a new ROI. "
098:                                    + "For circular and rectangular ROIs, all values are "
099:                                    + "given as their pixel values relative to the canvas origin. "
100:                                    + "Arbitrary shapes must be included in a PGM file where non 0 "
101:                                    + "values correspond to ROI coefficients. The PGM file must have "
102:                                    + "the size as the image. "
103:                                    + "The component idx specifies which components "
104:                                    + "contain the ROI. The component index is specified as described "
105:                                    + "by points 3 and 4 in the general comment on tile-component idx. "
106:                                    + "If this option is used, the codestream is layer progressive by "
107:                                    + "default unless it is overridden by the 'Aptype' option.",
108:                            null },
109:                    {
110:                            "Ralign",
111:                            "[true|false]",
112:                            "By specifying this argument, the ROI mask will be "
113:                                    + "limited to covering only entire code-blocks. The ROI coding can "
114:                                    + "then be performed without any actual scaling of the coefficients "
115:                                    + "but by instead scaling the distortion estimates.",
116:                            "false" },
117:                    {
118:                            "Rstart_level",
119:                            "<level>",
120:                            "This argument forces the lowest <level> resolution levels to "
121:                                    + "belong to the ROI. By doing this, it is possible to avoid only "
122:                                    + "getting information for the ROI at an early stage of "
123:                                    + "transmission.<level> = 0 means the lowest resolution level "
124:                                    + "belongs to the ROI, 1 means the two lowest etc. (-1 deactivates"
125:                                    + " the option)", "-1" },
126:                    {
127:                            "Rno_rect",
128:                            "[true|false]",
129:                            "This argument makes sure that the ROI mask generation is not done "
130:                                    + "using the fast ROI mask generation for rectangular ROIs "
131:                                    + "regardless of whether the specified ROIs are rectangular or not",
132:                            "false" }, };
133:
134:            /** The maximum number of magnitude bit-planes in any subband. One value
135:             *  for each tile-component */
136:            private int maxMagBits[][];
137:
138:            /** Flag indicating the presence of ROIs */
139:            private boolean roi;
140:
141:            /** Flag indicating if block aligned ROIs are used */
142:            private boolean blockAligned;
143:
144:            /** Number of resolution levels to include in ROI mask */
145:            private int useStartLevel;
146:
147:            /** The class generating the ROI mask */
148:            private ROIMaskGenerator mg;
149:
150:            /** The ROI mask */
151:            private DataBlkInt roiMask;
152:
153:            /** The source of quantized wavelet transform coefficients */
154:            private Quantizer src;
155:
156:            /**
157:             * Constructor of the ROI scaler, takes a Quantizer as source of data to
158:             * scale.
159:             *
160:             * @param src The quantizer that is the source of data.
161:             *
162:             * @param mg The mask generator that will be used for all components
163:             *
164:             * @param roi Flag indicating whether there are rois specified.
165:             *
166:             * @param sLev The resolution levels that belong entirely to ROI
167:             *
168:             * @param uba Flag indicating whether block aligning is used.
169:             *
170:             * @param encSpec The encoder specifications for addition of roi specs
171:             * */
172:            public ROIScaler(Quantizer src, ROIMaskGenerator mg, boolean roi,
173:                    int sLev, boolean uba, J2KImageWriteParamJava wp) {
174:                super (src);
175:                this .src = src;
176:                this .roi = roi;
177:                this .useStartLevel = sLev;
178:                if (roi) {
179:                    // If there is no ROI, no need to do this
180:                    this .mg = mg;
181:                    roiMask = new DataBlkInt();
182:                    calcMaxMagBits(wp);
183:                    blockAligned = uba;
184:                }
185:            }
186:
187:            /**
188:             * Since ROI scaling is always a reversible operation, it calls
189:             * isReversible() method of it source (the quantizer module).
190:             *
191:             * @param t The tile to test for reversibility
192:             *
193:             * @param c The component to test for reversibility
194:             *
195:             * @return True if the quantized data is reversible, false if not.
196:             * */
197:            public boolean isReversible(int t, int c) {
198:                return src.isReversible(t, c);
199:            }
200:
201:            /**
202:             * Returns a reference to the subband tree structure representing the
203:             * subband decomposition for the specified tile-component.
204:             *
205:             * @param t The index of the tile.
206:             *
207:             * @param c The index of the component.
208:             *
209:             * @return The subband tree structure, see SubbandAn.
210:             *
211:             * @see SubbandAn
212:             *
213:             * @see Subband
214:             * */
215:            public SubbandAn getAnSubbandTree(int t, int c) {
216:                return src.getAnSubbandTree(t, c);
217:            }
218:
219:            /**
220:             * Returns the horizontal offset of the code-block partition. Allowable
221:             * values are 0 and 1, nothing else.
222:             * */
223:            public int getCbULX() {
224:                return src.getCbULX();
225:            }
226:
227:            /**
228:             * Returns the vertical offset of the code-block partition. Allowable
229:             * values are 0 and 1, nothing else.
230:             * */
231:            public int getCbULY() {
232:                return src.getCbULY();
233:            }
234:
235:            /**
236:             * Creates a ROIScaler object. The Quantizer is the source of data to
237:             * scale.
238:             *
239:             * <P> The ROI Scaler creates a ROIMaskGenerator depending on what ROI
240:             * information is in the J2KImageWriteParamJava. If only rectangular ROI are used,
241:             * the fast mask generator for rectangular ROI can be used.
242:             *
243:             * @param src The source of data to scale
244:             *
245:             * @param pl The parameter list (or options).
246:             *
247:             * @param encSpec The encoder specifications for addition of roi specs
248:             *
249:             * @exception IllegalArgumentException If an error occurs while parsing
250:             * the options in 'pl'
251:             * */
252:            public static ROIScaler createInstance(Quantizer src,
253:                    J2KImageWriteParamJava wp) {
254:                Vector roiVector = new Vector();
255:                ROIMaskGenerator maskGen = null;
256:
257:                /*   XXX: need investigation
258:                // Check parameters
259:                pl.checkList(OPT_PREFIX,pl.toNameArray(pinfo));
260:                 */
261:
262:                // Get parameters and check if there are and ROIs specified
263:                String roiopt = wp.getROIs().getSpecified();
264:                if (roiopt == null) {
265:                    // No ROIs specified! Create ROIScaler with no mask generator
266:                    return new ROIScaler(src, null, false, -1, false, wp);
267:                }
268:
269:                // Check if the lowest resolution levels should belong to the ROI
270:                int sLev = wp.getStartLevelROI();
271:
272:                // Check if the ROIs are block-aligned
273:                boolean useBlockAligned = wp.getAlignROI();
274:
275:                // Check if generic mask generation is specified
276:                boolean onlyRect = false;
277:
278:                // Parse the ROIs
279:                parseROIs(roiopt, src.getNumComps(), roiVector);
280:                ROI[] roiArray = new ROI[roiVector.size()];
281:                roiVector.copyInto(roiArray);
282:
283:                // If onlyRect has been forced, check if there are any non-rectangular
284:                // ROIs specified.  Currently, only the presence of circular ROIs will
285:                // make this false
286:                if (onlyRect) {
287:                    for (int i = roiArray.length - 1; i >= 0; i--)
288:                        if (!roiArray[i].rect) {
289:                            onlyRect = false;
290:                            break;
291:                        }
292:                }
293:
294:                if (onlyRect) {
295:                    // It's possible to use the fast ROI mask generation when only
296:                    // rectangular ROIs are specified.
297:                    maskGen = new RectROIMaskGenerator(roiArray, src
298:                            .getNumComps());
299:                } else {
300:                    // It's necessary to use the generic mask generation
301:                    maskGen = new ArbROIMaskGenerator(roiArray, src
302:                            .getNumComps(), src);
303:                }
304:
305:                return new ROIScaler(src, maskGen, true, sLev, useBlockAligned,
306:                        wp);
307:            }
308:
309:            /**
310:             * This function parses the values given for the ROIs with the argument
311:             * -Rroi. Currently only circular and rectangular ROIs are supported.
312:             *
313:             * <P> A rectangular ROI is indicated by a 'R' followed the coordinates
314:             * for the upper left corner of the ROI and then its width and height.
315:             *
316:             * <P> A circular ROI is indicated by a 'C' followed by the coordinates of
317:             * the circle center and then the radius.
318:             *
319:             * <P> Before the R and C values, the component that are affected by the
320:             * ROI are indicated.
321:             *
322:             * @param roiopt The info on the ROIs
323:             *
324:             * @param nc number of components
325:             *
326:             * @param roiVector The vcector containing the ROI parsed from the cmd line
327:             *
328:             * @return The ROIs specified in roiopt
329:             * */
330:            protected static Vector parseROIs(String roiopt, int nc,
331:                    Vector roiVector) {
332:                ROI[] ROIs;
333:                ROI roi;
334:                StringTokenizer stok;
335:                char tok;
336:                int nrOfROIs = 0;
337:                char c;
338:                int comp, ulx, uly, w, h, x, y, rad;
339:                boolean[] roiInComp = null;
340:
341:                stok = new StringTokenizer(roiopt);
342:
343:                String word;
344:                while (stok.hasMoreTokens()) {
345:                    word = stok.nextToken();
346:
347:                    switch (word.charAt(0)) {
348:                    case 'c': // Components specification
349:                        roiInComp = ModuleSpec.parseIdx(word, nc);
350:                        break;
351:                    case 'R': // Rectangular ROI to be read
352:                        nrOfROIs++;
353:                        try {
354:                            word = stok.nextToken();
355:                            ulx = (new Integer(word)).intValue();
356:                            word = stok.nextToken();
357:                            uly = (new Integer(word)).intValue();
358:                            word = stok.nextToken();
359:                            w = (new Integer(word)).intValue();
360:                            word = stok.nextToken();
361:                            h = (new Integer(word)).intValue();
362:                        } catch (NumberFormatException e) {
363:                            throw new IllegalArgumentException(
364:                                    "Bad parameter for "
365:                                            + "'-Rroi R' option : " + word);
366:                        } catch (NoSuchElementException f) {
367:                            throw new IllegalArgumentException(
368:                                    "Wrong number of " + "parameters for  "
369:                                            + "h'-Rroi R' option.");
370:                        }
371:
372:                        // If the ROI is component-specific, check which comps.
373:                        if (roiInComp != null)
374:                            for (int i = 0; i < nc; i++) {
375:                                if (roiInComp[i]) {
376:                                    roi = new ROI(i, ulx, uly, w, h);
377:                                    roiVector.addElement(roi);
378:                                }
379:                            }
380:                        else { // Otherwise add ROI for all components
381:                            for (int i = 0; i < nc; i++) {
382:                                roi = new ROI(i, ulx, uly, w, h);
383:                                roiVector.addElement(roi);
384:                            }
385:                        }
386:                        break;
387:                    case 'C': // Circular ROI to be read
388:                        nrOfROIs++;
389:
390:                        try {
391:                            word = stok.nextToken();
392:                            x = (new Integer(word)).intValue();
393:                            word = stok.nextToken();
394:                            y = (new Integer(word)).intValue();
395:                            word = stok.nextToken();
396:                            rad = (new Integer(word)).intValue();
397:                        } catch (NumberFormatException e) {
398:                            throw new IllegalArgumentException(
399:                                    "Bad parameter for "
400:                                            + "'-Rroi C' option : " + word);
401:                        } catch (NoSuchElementException f) {
402:                            throw new IllegalArgumentException(
403:                                    "Wrong number of " + "parameters for "
404:                                            + "'-Rroi C' option.");
405:                        }
406:
407:                        // If the ROI is component-specific, check which comps.
408:                        if (roiInComp != null)
409:                            for (int i = 0; i < nc; i++) {
410:                                if (roiInComp[i]) {
411:                                    roi = new ROI(i, x, y, rad);
412:                                    roiVector.addElement(roi);
413:                                }
414:                            }
415:                        else { // Otherwise add ROI for all components
416:                            for (int i = 0; i < nc; i++) {
417:                                roi = new ROI(i, x, y, rad);
418:                                roiVector.addElement(roi);
419:                            }
420:                        }
421:                        break;
422:                    case 'A': // ROI wth arbitrary shape
423:                        nrOfROIs++;
424:
425:                        String filename;
426:                        ImgReaderPGM maskPGM = null;
427:
428:                        try {
429:                            filename = stok.nextToken();
430:                        } catch (NoSuchElementException e) {
431:                            throw new IllegalArgumentException(
432:                                    "Wrong number of " + "parameters for "
433:                                            + "'-Rroi A' option.");
434:                        }
435:                        try {
436:                            maskPGM = new ImgReaderPGM(filename);
437:                        } catch (IOException e) {
438:                            throw new Error("Cannot read PGM file with ROI");
439:                        }
440:
441:                        // If the ROI is component-specific, check which comps.
442:                        if (roiInComp != null)
443:                            for (int i = 0; i < nc; i++) {
444:                                if (roiInComp[i]) {
445:                                    roi = new ROI(i, maskPGM);
446:                                    roiVector.addElement(roi);
447:                                }
448:                            }
449:                        else { // Otherwise add ROI for all components
450:                            for (int i = 0; i < nc; i++) {
451:                                roi = new ROI(i, maskPGM);
452:                                roiVector.addElement(roi);
453:                            }
454:                        }
455:                        break;
456:                    default:
457:                        throw new Error("Bad parameters for ROI nr "
458:                                + roiVector.size());
459:                    }
460:                }
461:
462:                return roiVector;
463:            }
464:
465:            /**
466:             * This function gets a datablk from the entropy coder. The sample sin the
467:             * block, which consists of  the quantized coefficients from the quantizer,
468:             * are scaled by the values given for any ROIs specified.
469:             *
470:             * <P>The function calls on a ROIMaskGenerator to get the mask for
471:             * scaling the coefficients in the current block.
472:             *
473:             * <P>The data returned by this method is a copy of the orignal
474:             * data. Therfore it can be modified "in place" without any problems after
475:             * being returned. The 'offset' of the returned data is 0, and the 'scanw'
476:             * is the same as the code-block width. See the 'CBlkWTData' class.
477:             *
478:             * @param n The component for which to return the next code-block.
479:             *
480:             * @param cblk If non-null this object will be used to return the new
481:             * code-block. If null a new one will be allocated and returned. If the
482:             * "data" array of the object is non-null it will be reused, if possible,
483:             * to return the data.
484:             *
485:             * @return The next code-block in the current tile for component 'n', or
486:             * null if all code-blocks for the current tile have been returned.
487:             *
488:             * @see CBlkWTData
489:             * */
490:            public CBlkWTData getNextCodeBlock(int n, CBlkWTData cblk) {
491:                return getNextInternCodeBlock(n, cblk);
492:            }
493:
494:            /**
495:             * This function gets a datablk from the entropy coder. The sample sin the
496:             * block, which consists of  the quantized coefficients from the quantizer,
497:             * are scaled by the values given for any ROIs specified.
498:             *
499:             * <P>The function calls on a ROIMaskGenerator to get the mask for
500:             * scaling the coefficients in the current block.
501:             *
502:             * @param c The component for which to return the next code-block.
503:             *
504:             * @param cblk If non-null this object will be used to return the new
505:             * code-block. If null a new one will be allocated and returned. If the
506:             * "data" array of the object is non-null it will be reused, if possible,
507:             * to return the data.
508:             *
509:             * @return The next code-block in the current tile for component 'n', or
510:             * null if all code-blocks for the current tile have been returned.
511:             *
512:             * @see CBlkWTData
513:             * */
514:            public CBlkWTData getNextInternCodeBlock(int c, CBlkWTData cblk) {
515:                int mi, i, j, k, wrap;
516:                int ulx, uly, w, h;
517:                DataBlkInt mask = roiMask; // local copy of mask
518:                int[] maskData; // local copy of mask data
519:                int[] data; // local copy of quantized data
520:                int tmp;
521:                int bitMask = 0x7FFFFFFF;
522:                SubbandAn root, sb;
523:                int maxBits = 0; // local copy
524:                boolean roiInTile;
525:                boolean sbInMask;
526:                int nROIcoeff = 0;
527:
528:                // Get codeblock's data from quantizer
529:                cblk = src.getNextCodeBlock(c, cblk);
530:
531:                // If there is no ROI in the image, or if we already got all
532:                // code-blocks
533:                if (!roi || cblk == null) {
534:                    return cblk;
535:                }
536:
537:                data = (int[]) cblk.getData();
538:                sb = cblk.sb;
539:                ulx = cblk.ulx;
540:                uly = cblk.uly;
541:                w = cblk.w;
542:                h = cblk.h;
543:                sbInMask = (sb.resLvl <= useStartLevel);
544:
545:                // Check that there is an array for the mask and set it to zero
546:                maskData = mask.getDataInt(); // local copy of mask data
547:                if (maskData == null || w * h > maskData.length) {
548:                    maskData = new int[w * h];
549:                    mask.setDataInt(maskData);
550:                } else {
551:                    for (i = w * h - 1; i >= 0; i--)
552:                        maskData[i] = 0;
553:                }
554:                mask.ulx = ulx;
555:                mask.uly = uly;
556:                mask.w = w;
557:                mask.h = h;
558:
559:                // Get ROI mask from generator
560:                root = src.getAnSubbandTree(tIdx, c);
561:                maxBits = maxMagBits[tIdx][c];
562:                roiInTile = mg.getROIMask(mask, root, maxBits, c);
563:
564:                // If there is no ROI in this tile, return the code-block untouched
565:                if (!roiInTile && (!sbInMask)) {
566:                    cblk.nROIbp = 0;
567:                    return cblk;
568:                }
569:
570:                // Update field containing the number of ROI magnitude bit-planes
571:                cblk.nROIbp = cblk.magbits;
572:
573:                // If the ROI should adhere to the code-block's boundaries or if the
574:                // entire subband belongs to the ROI mask, The code-block is set to
575:                // belong entirely to the ROI with the highest scaling value
576:                if (sbInMask) {
577:                    // Scale the wmse so that instead of scaling the coefficients, the
578:                    // wmse is scaled.
579:                    cblk.wmseScaling *= (float) (1 << (maxBits << 1));
580:                    cblk.nROIcoeff = w * h;
581:                    return cblk;
582:                }
583:
584:                // In 'block aligned' mode, the code-block is set to belong entirely
585:                // to the ROI with the highest scaling value if one coefficient, at
586:                // least, belongs to the ROI
587:                if (blockAligned) {
588:                    wrap = cblk.scanw - w;
589:                    mi = h * w - 1;
590:                    i = cblk.offset + cblk.scanw * (h - 1) + w - 1;
591:                    int nroicoeff = 0;
592:                    for (j = h; j > 0; j--) {
593:                        for (k = w - 1; k >= 0; k--, i--, mi--) {
594:                            if (maskData[mi] != 0) {
595:                                nroicoeff++;
596:                            }
597:                        }
598:                        i -= wrap;
599:                    }
600:                    if (nroicoeff != 0) { // Include the subband
601:                        cblk.wmseScaling *= (float) (1 << (maxBits << 1));
602:                        cblk.nROIcoeff = w * h;
603:                    }
604:                    return cblk;
605:                }
606:
607:                // Scale background coefficients
608:                bitMask = (((1 << cblk.magbits) - 1) << (31 - cblk.magbits));
609:                wrap = cblk.scanw - w;
610:                mi = h * w - 1;
611:                i = cblk.offset + cblk.scanw * (h - 1) + w - 1;
612:                for (j = h; j > 0; j--) {
613:                    for (k = w; k > 0; k--, i--, mi--) {
614:                        tmp = data[i];
615:                        if (maskData[mi] != 0) {
616:                            // ROI coeff. We need to erase fractional bits to ensure
617:                            // that they do not conflict with BG coeffs. This is only
618:                            // strictly necessary for ROI coeffs. which non-fractional
619:                            // magnitude is zero, but much better BG quality can be
620:                            // achieved if done if reset to zero since coding zeros is
621:                            // much more efficient (the entropy coder knows nothing
622:                            // about ROI and cannot avoid coding the ROI fractional
623:                            // bits, otherwise this would not be necessary).
624:                            data[i] = (0x80000000 & tmp) | (tmp & bitMask);
625:                            nROIcoeff++;
626:                        } else {
627:                            // BG coeff. it is not necessary to erase fractional bits
628:                            data[i] = (0x80000000 & tmp)
629:                                    | ((tmp & 0x7FFFFFFF) >> maxBits);
630:                        }
631:                    }
632:                    i -= wrap;
633:                }
634:
635:                // Modify the number of significant bit-planes in the code-block
636:                cblk.magbits += maxBits;
637:
638:                // Store the number of ROI coefficients present in the code-block
639:                cblk.nROIcoeff = nROIcoeff;
640:
641:                return cblk;
642:            }
643:
644:            /**
645:             * This function returns the ROI mask generator.
646:             *
647:             * @return The roi mask generator
648:             */
649:            public ROIMaskGenerator getROIMaskGenerator() {
650:                return mg;
651:            }
652:
653:            /**
654:             * This function returns the blockAligned flag
655:             *
656:             * @return Flag indicating whether the ROIs were block aligned
657:             */
658:            public boolean getBlockAligned() {
659:                return blockAligned;
660:            }
661:
662:            /**
663:             * This function returns the flag indicating if any ROI functionality used
664:             *
665:             * @return Flag indicating whether there are ROIs in the image
666:             */
667:            public boolean useRoi() {
668:                return roi;
669:            }
670:
671:            /**
672:             * Returns the parameters that are used in this class and
673:             * implementing classes. It returns a 2D String array. Each of the
674:             * 1D arrays is for a different option, and they have 3
675:             * elements. The first element is the option name, the second one
676:             * is the synopsis, the third one is a long description of what
677:             * the parameter is and the fourth is its default value. The
678:             * synopsis or description may be 'null', in which case it is
679:             * assumed that there is no synopsis or description of the option,
680:             * respectively. Null may be returned if no options are supported.
681:             *
682:             * @return the options name, their synopsis and their explanation,
683:             * or null if no options are supported.
684:             * */
685:            public static String[][] getParameterInfo() {
686:                return pinfo;
687:            }
688:
689:            /**
690:             * Changes the current tile, given the new indexes. An
691:             * IllegalArgumentException is thrown if the indexes do not
692:             * correspond to a valid tile.
693:             *
694:             * @param x The horizontal index of the tile.
695:             *
696:             * @param y The vertical index of the new tile.
697:             * */
698:            public void setTile(int x, int y) {
699:                super .setTile(x, y);
700:                if (roi)
701:                    mg.tileChanged();
702:            }
703:
704:            /**
705:             * Advances to the next tile, in standard scan-line order (by rows then
706:             * columns). An NoNextElementException is thrown if the current tile is
707:             * the last one (i.e. there is no next tile).
708:             * */
709:            public void nextTile() {
710:                super .nextTile();
711:                if (roi)
712:                    mg.tileChanged();
713:            }
714:
715:            /**
716:             * Calculates the maximum amount of magnitude bits for each
717:             * tile-component, and stores it in the 'maxMagBits' array. This is called
718:             * by the constructor
719:             *
720:             * @param encSpec The encoder specifications for addition of roi specs
721:             * */
722:            private void calcMaxMagBits(J2KImageWriteParamJava wp) {
723:                int tmp;
724:                MaxShiftSpec rois = wp.getROIs();
725:
726:                int nt = src.getNumTiles();
727:                int nc = src.getNumComps();
728:
729:                maxMagBits = new int[nt][nc];
730:
731:                src.setTile(0, 0);
732:                for (int t = 0; t < nt; t++) {
733:                    for (int c = nc - 1; c >= 0; c--) {
734:                        tmp = src.getMaxMagBits(c);
735:                        maxMagBits[t][c] = tmp;
736:                        rois.setTileCompVal(t, c, new Integer(tmp));
737:                    }
738:                    if (t < nt - 1)
739:                        src.nextTile();
740:                }
741:                // Reset to current initial tile position
742:                src.setTile(0, 0);
743:            }
744:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.