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


0001:        /*
0002:         * $RCSfile: PktDecoder.java,v $
0003:         * $Revision: 1.1 $
0004:         * $Date: 2005/02/11 05:02:01 $
0005:         * $State: Exp $
0006:         *
0007:         * Class:                   PktDecoder
0008:         *
0009:         * Description:             Reads packets heads and keeps location of
0010:         *                          code-blocks' codewords
0011:         *
0012:         *
0013:         *
0014:         * COPYRIGHT:
0015:         *
0016:         * This software module was originally developed by Raphaël Grosbois and
0017:         * Diego Santa Cruz (Swiss Federal Institute of Technology-EPFL); Joel
0018:         * Askelöf (Ericsson Radio Systems AB); and Bertrand Berthelot, David
0019:         * Bouchard, Félix Henry, Gerard Mozelle and Patrice Onno (Canon Research
0020:         * Centre France S.A) in the course of development of the JPEG2000
0021:         * standard as specified by ISO/IEC 15444 (JPEG 2000 Standard). This
0022:         * software module is an implementation of a part of the JPEG 2000
0023:         * Standard. Swiss Federal Institute of Technology-EPFL, Ericsson Radio
0024:         * Systems AB and Canon Research Centre France S.A (collectively JJ2000
0025:         * Partners) agree not to assert against ISO/IEC and users of the JPEG
0026:         * 2000 Standard (Users) any of their rights under the copyright, not
0027:         * including other intellectual property rights, for this software module
0028:         * with respect to the usage by ISO/IEC and Users of this software module
0029:         * or modifications thereof for use in hardware or software products
0030:         * claiming conformance to the JPEG 2000 Standard. Those intending to use
0031:         * this software module in hardware or software products are advised that
0032:         * their use may infringe existing patents. The original developers of
0033:         * this software module, JJ2000 Partners and ISO/IEC assume no liability
0034:         * for use of this software module or modifications thereof. No license
0035:         * or right to this software module is granted for non JPEG 2000 Standard
0036:         * conforming products. JJ2000 Partners have full right to use this
0037:         * software module for his/her own purpose, assign or donate this
0038:         * software module to any third party and to inhibit third parties from
0039:         * using this software module for non JPEG 2000 Standard conforming
0040:         * products. This copyright notice must be included in all copies or
0041:         * derivative works of this software module.
0042:         *
0043:         * Copyright (c) 1999/2000 JJ2000 Partners.
0044:         * */
0045:        package jj2000.j2k.codestream.reader;
0046:
0047:        import java.awt.Point;
0048:
0049:        import jj2000.j2k.wavelet.synthesis.*;
0050:        import jj2000.j2k.codestream.*;
0051:        import jj2000.j2k.entropy.*;
0052:        import jj2000.j2k.wavelet.*;
0053:        import jj2000.j2k.decoder.*;
0054:        import jj2000.j2k.image.*;
0055:        import jj2000.j2k.util.*;
0056:        import jj2000.j2k.io.*;
0057:
0058:        import java.util.*;
0059:        import java.io.*;
0060:
0061:        /**
0062:         * This class is used to read packet's head and body. All the members must be
0063:         * re-initialized at the beginning of each tile thanks to the restart()
0064:         * method.
0065:         * */
0066:        public class PktDecoder implements  StdEntropyCoderOptions {
0067:
0068:            /** Reference to the codestream reader agent */
0069:            private BitstreamReaderAgent src;
0070:
0071:            /** Flag indicating whether packed packet header was used for this tile*/
0072:            private boolean pph = false;
0073:
0074:            /** The packed packet header if it was used */
0075:            private ByteArrayInputStream pphbais;
0076:
0077:            /** Reference to decoder specifications */
0078:            private DecoderSpecs decSpec;
0079:
0080:            /** Reference to the HeaderDecoder */
0081:            private HeaderDecoder hd;
0082:
0083:            /** Initial value of the state variable associated with code-block
0084:             * length. */
0085:            private final int INIT_LBLOCK = 3;
0086:
0087:            /** The wrapper to read bits for the packet heads */
0088:            private PktHeaderBitReader bin;
0089:
0090:            /** Reference to the stream where to read from */
0091:            private RandomAccessIO ehs;
0092:
0093:            /**
0094:             * Maximum number of precincts :
0095:             *
0096:             * <ul>
0097:             * <li> 1st dim: component index.</li>
0098:             * <li> 2nd dim: resolution level index.</li>
0099:             * </ul>
0100:             * */
0101:            private Point[][] numPrec;
0102:
0103:            /** Index of the current tile */
0104:            private int tIdx;
0105:
0106:            /** 
0107:             * Array containing the coordinates, width, height, indexes, ... of the
0108:             * precincts in the current tile:
0109:             * 
0110:             * <ul>
0111:             * <li> 1st dim: component index.</li>
0112:             * <li> 2nd dim: resolution level index.</li>
0113:             * <li> 3rd dim: precinct index.</li>
0114:             * </ul>
0115:             * */
0116:            private PrecInfo[][][] ppinfo;
0117:
0118:            /**
0119:             * Lblock value used to read code size information in each packet head:
0120:             *
0121:             * <ul>
0122:             * <li> 1st dim: component index.</li>
0123:             * <li> 2nd dim: resolution level index.</li>
0124:             * <li> 3rd dim: subband index.</li>
0125:             * <li> 4th/5th dim: code-block index (vert. and horiz.).</li>
0126:             * </ul>
0127:             * */
0128:            private int[][][][][] lblock;
0129:
0130:            /** 
0131:             * Tag tree used to read inclusion informations in packet's head:
0132:             *
0133:             * <ul>   
0134:             * <li> 1st dim: component index.</li>
0135:             * <li> 2nd dim: resolution level index.</li>
0136:             * <li> 3rd dim: precinct index.</li> 
0137:             * <li> 4th dim: subband index.</li>
0138:             * */
0139:            private TagTreeDecoder[][][][] ttIncl;
0140:
0141:            /** 
0142:             * Tag tree used to read bit-depth information in packet's head:
0143:             * 
0144:             * <ul>
0145:             * <li> 1st dim: component index.</li>
0146:             * <li> 2nd dim: resolution level index.</li>
0147:             * <li> 3rd dim: precinct index.</li>
0148:             * <li> 4th dim: subband index.</li>
0149:             * </ul>
0150:             * */
0151:            private TagTreeDecoder[][][][] ttMaxBP;
0152:
0153:            /** Number of layers in t he current tile */
0154:            private int nl = 0;
0155:
0156:            /** The number of components */
0157:            private int nc;
0158:
0159:            /** Whether or not SOP marker segment are used */
0160:            private boolean sopUsed = false;
0161:
0162:            /** Whether or not EPH marker are used */
0163:            private boolean ephUsed = false;
0164:
0165:            /** Index of the current packet in the tile. Used with SOP marker
0166:                segment*/
0167:            private int pktIdx;
0168:
0169:            /** List of code-blocks found in last read packet head (one list
0170:             * per subband) */
0171:            private Vector[] cblks;
0172:
0173:            /** Number of codeblocks encountered. used for ncb quit condition*/
0174:            private int ncb;
0175:
0176:            /** Maximum number of codeblocks to read before ncb quit condition is
0177:             * reached */
0178:            private int maxCB;
0179:
0180:            /** Flag indicating whether ncb quit condition has been reached */
0181:            private boolean ncbQuit;
0182:
0183:            /** The tile in which the ncb quit condition was reached */
0184:            private int tQuit;
0185:
0186:            /** The component in which the ncb quit condition was reached */
0187:            private int cQuit;
0188:
0189:            /** The subband in which the ncb quit condition was reached */
0190:            private int sQuit;
0191:
0192:            /** The resolution in which the ncb quit condition was reached */
0193:            private int rQuit;
0194:
0195:            /** The x position of the last code block before ncb quit reached */
0196:            private int xQuit;
0197:
0198:            /** The y position of the last code block before ncb quit reached  */
0199:            private int yQuit;
0200:
0201:            /** True if truncation mode is used. False if it is parsing mode */
0202:            private boolean isTruncMode;
0203:
0204:            /** 
0205:             * Creates an empty PktDecoder object associated with given decoder
0206:             * specifications and HeaderDecoder. This object must be initialized
0207:             * thanks to the restart method before being used.
0208:             *
0209:             * @param decSpec The decoder specifications.
0210:             *
0211:             * @param hd The HeaderDecoder instance.
0212:             *
0213:             * @param ehs The stream where to read data from.
0214:             *
0215:             * @param src The bit stream reader agent.
0216:             *
0217:             * @param isTruncMode Whether or not truncation mode is required.
0218:             *
0219:             * @param maxCB The maximum number of code-blocks to read before ncbquit
0220:             *
0221:             * */
0222:            public PktDecoder(DecoderSpecs decSpec, HeaderDecoder hd,
0223:                    RandomAccessIO ehs, BitstreamReaderAgent src,
0224:                    boolean isTruncMode, int maxCB) {
0225:                this .decSpec = decSpec;
0226:                this .hd = hd;
0227:                this .ehs = ehs;
0228:                this .isTruncMode = isTruncMode;
0229:                bin = new PktHeaderBitReader(ehs);
0230:                this .src = src;
0231:                ncb = 0;
0232:                ncbQuit = false;
0233:                this .maxCB = maxCB;
0234:            }
0235:
0236:            /** 
0237:             * Re-initialize the PktDecoder instance at the beginning of a new tile.
0238:             * 
0239:             * @param nc The number of components in this tile
0240:             *
0241:             * @param mdl The maximum number of decomposition level in each component
0242:             * of this tile
0243:             *
0244:             * @param nl The number of layers in  this tile
0245:             *
0246:             * @param cbI The code-blocks array
0247:             *
0248:             * @param pph Flag indicating whether packed packet headers was used
0249:             *
0250:             * @param pphbais Stream containing the packed packet headers
0251:             * */
0252:            public CBlkInfo[][][][][] restart(int nc, int[] mdl, int nl,
0253:                    CBlkInfo[][][][][] cbI, boolean pph,
0254:                    ByteArrayInputStream pphbais) {
0255:                this .nc = nc;
0256:                this .nl = nl;
0257:                this .tIdx = src.getTileIdx();
0258:                this .pph = pph;
0259:                this .pphbais = pphbais;
0260:
0261:                sopUsed = ((Boolean) decSpec.sops.getTileDef(tIdx))
0262:                        .booleanValue();
0263:                pktIdx = 0;
0264:                ephUsed = ((Boolean) decSpec.ephs.getTileDef(tIdx))
0265:                        .booleanValue();
0266:
0267:                cbI = new CBlkInfo[nc][][][][];
0268:                lblock = new int[nc][][][][];
0269:                ttIncl = new TagTreeDecoder[nc][][][];
0270:                ttMaxBP = new TagTreeDecoder[nc][][][];
0271:                numPrec = new Point[nc][];
0272:                ppinfo = new PrecInfo[nc][][];
0273:
0274:                // Used to compute the maximum number of precincts for each resolution
0275:                // level
0276:                int tcx0, tcy0, tcx1, tcy1; // Current tile position in the domain of
0277:                // the image component
0278:                int trx0, try0, trx1, try1; // Current tile position in the reduced
0279:                // resolution image domain
0280:                int xrsiz, yrsiz; // Component sub-sampling factors
0281:
0282:                SubbandSyn root, sb;
0283:                int mins, maxs;
0284:                Point nBlk = null;
0285:                int cb0x = src.getCbULX();
0286:                int cb0y = src.getCbULY();
0287:
0288:                for (int c = 0; c < nc; c++) {
0289:                    cbI[c] = new CBlkInfo[mdl[c] + 1][][][];
0290:                    lblock[c] = new int[mdl[c] + 1][][][];
0291:                    ttIncl[c] = new TagTreeDecoder[mdl[c] + 1][][];
0292:                    ttMaxBP[c] = new TagTreeDecoder[mdl[c] + 1][][];
0293:                    numPrec[c] = new Point[mdl[c] + 1];
0294:                    ppinfo[c] = new PrecInfo[mdl[c] + 1][];
0295:
0296:                    // Get the tile-component coordinates on the reference grid
0297:                    tcx0 = src.getResULX(c, mdl[c]);
0298:                    tcy0 = src.getResULY(c, mdl[c]);
0299:                    tcx1 = tcx0 + src.getTileCompWidth(tIdx, c, mdl[c]);
0300:                    tcy1 = tcy0 + src.getTileCompHeight(tIdx, c, mdl[c]);
0301:
0302:                    for (int r = 0; r <= mdl[c]; r++) {
0303:
0304:                        // Tile's coordinates in the reduced resolution image domain
0305:                        trx0 = (int) Math.ceil(tcx0
0306:                                / (double) (1 << (mdl[c] - r)));
0307:                        try0 = (int) Math.ceil(tcy0
0308:                                / (double) (1 << (mdl[c] - r)));
0309:                        trx1 = (int) Math.ceil(tcx1
0310:                                / (double) (1 << (mdl[c] - r)));
0311:                        try1 = (int) Math.ceil(tcy1
0312:                                / (double) (1 << (mdl[c] - r)));
0313:
0314:                        // Calculate the maximum number of precincts for each
0315:                        // resolution level taking into account tile specific options.
0316:                        double twoppx = (double) getPPX(tIdx, c, r);
0317:                        double twoppy = (double) getPPY(tIdx, c, r);
0318:                        numPrec[c][r] = new Point();
0319:                        if (trx1 > trx0) {
0320:                            numPrec[c][r].x = (int) Math.ceil((trx1 - cb0x)
0321:                                    / twoppx)
0322:                                    - (int) Math.floor((trx0 - cb0x) / twoppx);
0323:                        } else {
0324:                            numPrec[c][r].x = 0;
0325:                        }
0326:                        if (try1 > try0) {
0327:                            numPrec[c][r].y = (int) Math.ceil((try1 - cb0y)
0328:                                    / twoppy)
0329:                                    - (int) Math.floor((try0 - cb0y) / twoppy);
0330:                        } else {
0331:                            numPrec[c][r].y = 0;
0332:                        }
0333:
0334:                        // First and last subbands indexes
0335:                        mins = (r == 0) ? 0 : 1;
0336:                        maxs = (r == 0) ? 1 : 4;
0337:
0338:                        int maxPrec = numPrec[c][r].x * numPrec[c][r].y;
0339:
0340:                        ttIncl[c][r] = new TagTreeDecoder[maxPrec][maxs + 1];
0341:                        ttMaxBP[c][r] = new TagTreeDecoder[maxPrec][maxs + 1];
0342:                        cbI[c][r] = new CBlkInfo[maxs + 1][][];
0343:                        lblock[c][r] = new int[maxs + 1][][];
0344:
0345:                        ppinfo[c][r] = new PrecInfo[maxPrec];
0346:                        fillPrecInfo(c, r, mdl[c]);
0347:
0348:                        root = (SubbandSyn) src.getSynSubbandTree(tIdx, c);
0349:                        for (int s = mins; s < maxs; s++) {
0350:                            sb = (SubbandSyn) root.getSubbandByIdx(r, s);
0351:                            nBlk = sb.numCb;
0352:
0353:                            cbI[c][r][s] = new CBlkInfo[nBlk.y][nBlk.x];
0354:                            lblock[c][r][s] = new int[nBlk.y][nBlk.x];
0355:
0356:                            for (int i = nBlk.y - 1; i >= 0; i--) {
0357:                                ArrayUtil.intArraySet(lblock[c][r][s][i],
0358:                                        INIT_LBLOCK);
0359:                            }
0360:                        } // loop on subbands
0361:                    } // End loop on resolution levels
0362:                } // End loop on components
0363:
0364:                return cbI;
0365:            }
0366:
0367:            /** 
0368:             * Retrives precincts and code-blocks coordinates in the given resolution,
0369:             * level and component. Finishes TagTreeEncoder initialization as well.
0370:             *
0371:             * @param c Component index.
0372:             *
0373:             * @param r Resolution level index.
0374:             *
0375:             * @param mdl Number of decomposition level in component <tt>c</tt>.
0376:             * */
0377:            private void fillPrecInfo(int c, int r, int mdl) {
0378:                if (ppinfo[c][r].length == 0)
0379:                    return; // No precinct in this
0380:                // resolution level
0381:
0382:                Point tileI = src.getTile(null);
0383:                Point nTiles = src.getNumTiles(null);
0384:
0385:                int xsiz, ysiz, x0siz, y0siz;
0386:                int xt0siz, yt0siz;
0387:                int xtsiz, ytsiz;
0388:
0389:                xt0siz = src.getTilePartULX();
0390:                yt0siz = src.getTilePartULY();
0391:                xtsiz = src.getNomTileWidth();
0392:                ytsiz = src.getNomTileHeight();
0393:                x0siz = hd.getImgULX();
0394:                y0siz = hd.getImgULY();
0395:                xsiz = hd.getImgWidth();
0396:                ysiz = hd.getImgHeight();
0397:
0398:                int tx0 = (tileI.x == 0) ? x0siz : xt0siz + tileI.x * xtsiz;
0399:                int ty0 = (tileI.y == 0) ? y0siz : yt0siz + tileI.y * ytsiz;
0400:                int tx1 = (tileI.x != nTiles.x - 1) ? xt0siz + (tileI.x + 1)
0401:                        * xtsiz : xsiz;
0402:                int ty1 = (tileI.y != nTiles.y - 1) ? yt0siz + (tileI.y + 1)
0403:                        * ytsiz : ysiz;
0404:
0405:                int xrsiz = hd.getCompSubsX(c);
0406:                int yrsiz = hd.getCompSubsY(c);
0407:
0408:                int tcx0 = src.getResULX(c, mdl);
0409:                int tcy0 = src.getResULY(c, mdl);
0410:                int tcx1 = tcx0 + src.getTileCompWidth(tIdx, c, mdl);
0411:                int tcy1 = tcy0 + src.getTileCompHeight(tIdx, c, mdl);
0412:
0413:                int ndl = mdl - r;
0414:                int trx0 = (int) Math.ceil(tcx0 / (double) (1 << ndl));
0415:                int try0 = (int) Math.ceil(tcy0 / (double) (1 << ndl));
0416:                int trx1 = (int) Math.ceil(tcx1 / (double) (1 << ndl));
0417:                int try1 = (int) Math.ceil(tcy1 / (double) (1 << ndl));
0418:
0419:                int cb0x = src.getCbULX();
0420:                int cb0y = src.getCbULY();
0421:
0422:                double twoppx = (double) getPPX(tIdx, c, r);
0423:                double twoppy = (double) getPPY(tIdx, c, r);
0424:                int twoppx2 = (int) (twoppx / 2);
0425:                int twoppy2 = (int) (twoppy / 2);
0426:
0427:                // Precincts are located at (cb0x+i*twoppx,cb0y+j*twoppy)
0428:                // Valid precincts are those which intersect with the current
0429:                // resolution level
0430:                int maxPrec = ppinfo[c][r].length;
0431:                int nPrec = 0;
0432:
0433:                int istart = (int) Math.floor((try0 - cb0y) / twoppy);
0434:                int iend = (int) Math.floor((try1 - 1 - cb0y) / twoppy);
0435:                int jstart = (int) Math.floor((trx0 - cb0x) / twoppx);
0436:                int jend = (int) Math.floor((trx1 - 1 - cb0x) / twoppx);
0437:
0438:                int acb0x, acb0y;
0439:
0440:                SubbandSyn root = src.getSynSubbandTree(tIdx, c);
0441:                SubbandSyn sb = null;
0442:
0443:                int p0x, p0y, p1x, p1y; // Precinct projection in subband
0444:                int s0x, s0y, s1x, s1y; // Active subband portion
0445:                int cw, ch;
0446:                int kstart, kend, lstart, lend, k0, l0;
0447:                int prg_ulx, prg_uly;
0448:                int prg_w = (int) twoppx << ndl;
0449:                int prg_h = (int) twoppy << ndl;
0450:                int tmp1, tmp2;
0451:
0452:                CBlkCoordInfo cb;
0453:
0454:                for (int i = istart; i <= iend; i++) { // Vertical precincts
0455:                    for (int j = jstart; j <= jend; j++, nPrec++) { // Horizontal precincts
0456:                        if (j == jstart
0457:                                && (trx0 - cb0x) % (xrsiz * ((int) twoppx)) != 0) {
0458:                            prg_ulx = tx0;
0459:                        } else {
0460:                            prg_ulx = cb0x + j * xrsiz * ((int) twoppx << ndl);
0461:                        }
0462:                        if (i == istart
0463:                                && (try0 - cb0y) % (yrsiz * ((int) twoppy)) != 0) {
0464:                            prg_uly = ty0;
0465:                        } else {
0466:                            prg_uly = cb0y + i * yrsiz * ((int) twoppy << ndl);
0467:                        }
0468:
0469:                        ppinfo[c][r][nPrec] = new PrecInfo(r, (int) (cb0x + j
0470:                                * twoppx), (int) (cb0y + i * twoppy),
0471:                                (int) twoppx, (int) twoppy, prg_ulx, prg_uly,
0472:                                prg_w, prg_h);
0473:
0474:                        if (r == 0) { // LL subband
0475:                            acb0x = cb0x;
0476:                            acb0y = cb0y;
0477:
0478:                            p0x = acb0x + j * (int) twoppx;
0479:                            p1x = p0x + (int) twoppx;
0480:                            p0y = acb0y + i * (int) twoppy;
0481:                            p1y = p0y + (int) twoppy;
0482:
0483:                            sb = (SubbandSyn) root.getSubbandByIdx(0, 0);
0484:                            s0x = (p0x < sb.ulcx) ? sb.ulcx : p0x;
0485:                            s1x = (p1x > sb.ulcx + sb.w) ? sb.ulcx + sb.w : p1x;
0486:                            s0y = (p0y < sb.ulcy) ? sb.ulcy : p0y;
0487:                            s1y = (p1y > sb.ulcy + sb.h) ? sb.ulcy + sb.h : p1y;
0488:
0489:                            // Code-blocks are located at (acb0x+k*cw,acb0y+l*ch)
0490:                            cw = sb.nomCBlkW;
0491:                            ch = sb.nomCBlkH;
0492:                            k0 = (int) Math.floor((sb.ulcy - acb0y)
0493:                                    / (double) ch);
0494:                            kstart = (int) Math.floor((s0y - acb0y)
0495:                                    / (double) ch);
0496:                            kend = (int) Math.floor((s1y - 1 - acb0y)
0497:                                    / (double) ch);
0498:                            l0 = (int) Math.floor((sb.ulcx - acb0x)
0499:                                    / (double) cw);
0500:                            lstart = (int) Math.floor((s0x - acb0x)
0501:                                    / (double) cw);
0502:                            lend = (int) Math.floor((s1x - 1 - acb0x)
0503:                                    / (double) cw);
0504:
0505:                            if (s1x - s0x <= 0 || s1y - s0y <= 0) {
0506:                                ppinfo[c][r][nPrec].nblk[0] = 0;
0507:                                ttIncl[c][r][nPrec][0] = new TagTreeDecoder(0,
0508:                                        0);
0509:                                ttMaxBP[c][r][nPrec][0] = new TagTreeDecoder(0,
0510:                                        0);
0511:                            } else {
0512:                                ttIncl[c][r][nPrec][0] = new TagTreeDecoder(
0513:                                        kend - kstart + 1, lend - lstart + 1);
0514:                                ttMaxBP[c][r][nPrec][0] = new TagTreeDecoder(
0515:                                        kend - kstart + 1, lend - lstart + 1);
0516:                                ppinfo[c][r][nPrec].cblk[0] = new CBlkCoordInfo[kend
0517:                                        - kstart + 1][lend - lstart + 1];
0518:                                ppinfo[c][r][nPrec].nblk[0] = (kend - kstart + 1)
0519:                                        * (lend - lstart + 1);
0520:
0521:                                for (int k = kstart; k <= kend; k++) { // Vertical cblks
0522:                                    for (int l = lstart; l <= lend; l++) { // Horiz. cblks
0523:                                        cb = new CBlkCoordInfo(k - k0, l - l0);
0524:                                        if (l == l0) {
0525:                                            cb.ulx = sb.ulx;
0526:                                        } else {
0527:                                            cb.ulx = sb.ulx + l * cw
0528:                                                    - (sb.ulcx - acb0x);
0529:                                        }
0530:                                        if (k == k0) {
0531:                                            cb.uly = sb.uly;
0532:                                        } else {
0533:                                            cb.uly = sb.uly + k * ch
0534:                                                    - (sb.ulcy - acb0y);
0535:                                        }
0536:                                        tmp1 = acb0x + l * cw;
0537:                                        tmp1 = (tmp1 > sb.ulcx) ? tmp1
0538:                                                : sb.ulcx;
0539:                                        tmp2 = acb0x + (l + 1) * cw;
0540:                                        tmp2 = (tmp2 > sb.ulcx + sb.w) ? sb.ulcx
0541:                                                + sb.w
0542:                                                : tmp2;
0543:                                        cb.w = tmp2 - tmp1;
0544:                                        tmp1 = acb0y + k * ch;
0545:                                        tmp1 = (tmp1 > sb.ulcy) ? tmp1
0546:                                                : sb.ulcy;
0547:                                        tmp2 = acb0y + (k + 1) * ch;
0548:                                        tmp2 = (tmp2 > sb.ulcy + sb.h) ? sb.ulcy
0549:                                                + sb.h
0550:                                                : tmp2;
0551:                                        cb.h = tmp2 - tmp1;
0552:                                        ppinfo[c][r][nPrec].cblk[0][k - kstart][l
0553:                                                - lstart] = cb;
0554:                                    } // Horizontal code-blocks
0555:                                } // Vertical code-blocks
0556:                            }
0557:                        } else { // HL, LH and HH subbands
0558:                            // HL subband
0559:                            acb0x = 0;
0560:                            acb0y = cb0y;
0561:
0562:                            p0x = acb0x + j * twoppx2;
0563:                            p1x = p0x + twoppx2;
0564:                            p0y = acb0y + i * twoppy2;
0565:                            p1y = p0y + twoppy2;
0566:
0567:                            sb = (SubbandSyn) root.getSubbandByIdx(r, 1);
0568:                            s0x = (p0x < sb.ulcx) ? sb.ulcx : p0x;
0569:                            s1x = (p1x > sb.ulcx + sb.w) ? sb.ulcx + sb.w : p1x;
0570:                            s0y = (p0y < sb.ulcy) ? sb.ulcy : p0y;
0571:                            s1y = (p1y > sb.ulcy + sb.h) ? sb.ulcy + sb.h : p1y;
0572:
0573:                            // Code-blocks are located at (acb0x+k*cw,acb0y+l*ch)
0574:                            cw = sb.nomCBlkW;
0575:                            ch = sb.nomCBlkH;
0576:                            k0 = (int) Math.floor((sb.ulcy - acb0y)
0577:                                    / (double) ch);
0578:                            kstart = (int) Math.floor((s0y - acb0y)
0579:                                    / (double) ch);
0580:                            kend = (int) Math.floor((s1y - 1 - acb0y)
0581:                                    / (double) ch);
0582:                            l0 = (int) Math.floor((sb.ulcx - acb0x)
0583:                                    / (double) cw);
0584:                            lstart = (int) Math.floor((s0x - acb0x)
0585:                                    / (double) cw);
0586:                            lend = (int) Math.floor((s1x - 1 - acb0x)
0587:                                    / (double) cw);
0588:
0589:                            if (s1x - s0x <= 0 || s1y - s0y <= 0) {
0590:                                ppinfo[c][r][nPrec].nblk[1] = 0;
0591:                                ttIncl[c][r][nPrec][1] = new TagTreeDecoder(0,
0592:                                        0);
0593:                                ttMaxBP[c][r][nPrec][1] = new TagTreeDecoder(0,
0594:                                        0);
0595:                            } else {
0596:                                ttIncl[c][r][nPrec][1] = new TagTreeDecoder(
0597:                                        kend - kstart + 1, lend - lstart + 1);
0598:                                ttMaxBP[c][r][nPrec][1] = new TagTreeDecoder(
0599:                                        kend - kstart + 1, lend - lstart + 1);
0600:                                ppinfo[c][r][nPrec].cblk[1] = new CBlkCoordInfo[kend
0601:                                        - kstart + 1][lend - lstart + 1];
0602:                                ppinfo[c][r][nPrec].nblk[1] = (kend - kstart + 1)
0603:                                        * (lend - lstart + 1);
0604:
0605:                                for (int k = kstart; k <= kend; k++) { // Vertical cblks
0606:                                    for (int l = lstart; l <= lend; l++) { // Horiz. cblks
0607:                                        cb = new CBlkCoordInfo(k - k0, l - l0);
0608:                                        if (l == l0) {
0609:                                            cb.ulx = sb.ulx;
0610:                                        } else {
0611:                                            cb.ulx = sb.ulx + l * cw
0612:                                                    - (sb.ulcx - acb0x);
0613:                                        }
0614:                                        if (k == k0) {
0615:                                            cb.uly = sb.uly;
0616:                                        } else {
0617:                                            cb.uly = sb.uly + k * ch
0618:                                                    - (sb.ulcy - acb0y);
0619:                                        }
0620:                                        tmp1 = acb0x + l * cw;
0621:                                        tmp1 = (tmp1 > sb.ulcx) ? tmp1
0622:                                                : sb.ulcx;
0623:                                        tmp2 = acb0x + (l + 1) * cw;
0624:                                        tmp2 = (tmp2 > sb.ulcx + sb.w) ? sb.ulcx
0625:                                                + sb.w
0626:                                                : tmp2;
0627:                                        cb.w = tmp2 - tmp1;
0628:                                        tmp1 = acb0y + k * ch;
0629:                                        tmp1 = (tmp1 > sb.ulcy) ? tmp1
0630:                                                : sb.ulcy;
0631:                                        tmp2 = acb0y + (k + 1) * ch;
0632:                                        tmp2 = (tmp2 > sb.ulcy + sb.h) ? sb.ulcy
0633:                                                + sb.h
0634:                                                : tmp2;
0635:                                        cb.h = tmp2 - tmp1;
0636:                                        ppinfo[c][r][nPrec].cblk[1][k - kstart][l
0637:                                                - lstart] = cb;
0638:                                    } // Horizontal code-blocks
0639:                                } // Vertical code-blocks
0640:                            }
0641:
0642:                            // LH subband
0643:                            acb0x = cb0x;
0644:                            acb0y = 0;
0645:
0646:                            p0x = acb0x + j * twoppx2;
0647:                            p1x = p0x + twoppx2;
0648:                            p0y = acb0y + i * twoppy2;
0649:                            p1y = p0y + twoppy2;
0650:
0651:                            sb = (SubbandSyn) root.getSubbandByIdx(r, 2);
0652:                            s0x = (p0x < sb.ulcx) ? sb.ulcx : p0x;
0653:                            s1x = (p1x > sb.ulcx + sb.w) ? sb.ulcx + sb.w : p1x;
0654:                            s0y = (p0y < sb.ulcy) ? sb.ulcy : p0y;
0655:                            s1y = (p1y > sb.ulcy + sb.h) ? sb.ulcy + sb.h : p1y;
0656:
0657:                            // Code-blocks are located at (acb0x+k*cw,acb0y+l*ch)
0658:                            cw = sb.nomCBlkW;
0659:                            ch = sb.nomCBlkH;
0660:                            k0 = (int) Math.floor((sb.ulcy - acb0y)
0661:                                    / (double) ch);
0662:                            kstart = (int) Math.floor((s0y - acb0y)
0663:                                    / (double) ch);
0664:                            kend = (int) Math.floor((s1y - 1 - acb0y)
0665:                                    / (double) ch);
0666:                            l0 = (int) Math.floor((sb.ulcx - acb0x)
0667:                                    / (double) cw);
0668:                            lstart = (int) Math.floor((s0x - acb0x)
0669:                                    / (double) cw);
0670:                            lend = (int) Math.floor((s1x - 1 - acb0x)
0671:                                    / (double) cw);
0672:
0673:                            if (s1x - s0x <= 0 || s1y - s0y <= 0) {
0674:                                ppinfo[c][r][nPrec].nblk[2] = 0;
0675:                                ttIncl[c][r][nPrec][2] = new TagTreeDecoder(0,
0676:                                        0);
0677:                                ttMaxBP[c][r][nPrec][2] = new TagTreeDecoder(0,
0678:                                        0);
0679:                            } else {
0680:                                ttIncl[c][r][nPrec][2] = new TagTreeDecoder(
0681:                                        kend - kstart + 1, lend - lstart + 1);
0682:                                ttMaxBP[c][r][nPrec][2] = new TagTreeDecoder(
0683:                                        kend - kstart + 1, lend - lstart + 1);
0684:                                ppinfo[c][r][nPrec].cblk[2] = new CBlkCoordInfo[kend
0685:                                        - kstart + 1][lend - lstart + 1];
0686:                                ppinfo[c][r][nPrec].nblk[2] = (kend - kstart + 1)
0687:                                        * (lend - lstart + 1);
0688:
0689:                                for (int k = kstart; k <= kend; k++) { // Vertical cblks
0690:                                    for (int l = lstart; l <= lend; l++) { // Horiz cblks
0691:                                        cb = new CBlkCoordInfo(k - k0, l - l0);
0692:                                        if (l == l0) {
0693:                                            cb.ulx = sb.ulx;
0694:                                        } else {
0695:                                            cb.ulx = sb.ulx + l * cw
0696:                                                    - (sb.ulcx - acb0x);
0697:                                        }
0698:                                        if (k == k0) {
0699:                                            cb.uly = sb.uly;
0700:                                        } else {
0701:                                            cb.uly = sb.uly + k * ch
0702:                                                    - (sb.ulcy - acb0y);
0703:                                        }
0704:                                        tmp1 = acb0x + l * cw;
0705:                                        tmp1 = (tmp1 > sb.ulcx) ? tmp1
0706:                                                : sb.ulcx;
0707:                                        tmp2 = acb0x + (l + 1) * cw;
0708:                                        tmp2 = (tmp2 > sb.ulcx + sb.w) ? sb.ulcx
0709:                                                + sb.w
0710:                                                : tmp2;
0711:                                        cb.w = tmp2 - tmp1;
0712:                                        tmp1 = acb0y + k * ch;
0713:                                        tmp1 = (tmp1 > sb.ulcy) ? tmp1
0714:                                                : sb.ulcy;
0715:                                        tmp2 = acb0y + (k + 1) * ch;
0716:                                        tmp2 = (tmp2 > sb.ulcy + sb.h) ? sb.ulcy
0717:                                                + sb.h
0718:                                                : tmp2;
0719:                                        cb.h = tmp2 - tmp1;
0720:                                        ppinfo[c][r][nPrec].cblk[2][k - kstart][l
0721:                                                - lstart] = cb;
0722:                                    } // Horizontal code-blocks
0723:                                } // Vertical code-blocks
0724:                            }
0725:
0726:                            // HH subband
0727:                            acb0x = 0;
0728:                            acb0y = 0;
0729:
0730:                            p0x = acb0x + j * twoppx2;
0731:                            p1x = p0x + twoppx2;
0732:                            p0y = acb0y + i * twoppy2;
0733:                            p1y = p0y + twoppy2;
0734:
0735:                            sb = (SubbandSyn) root.getSubbandByIdx(r, 3);
0736:                            s0x = (p0x < sb.ulcx) ? sb.ulcx : p0x;
0737:                            s1x = (p1x > sb.ulcx + sb.w) ? sb.ulcx + sb.w : p1x;
0738:                            s0y = (p0y < sb.ulcy) ? sb.ulcy : p0y;
0739:                            s1y = (p1y > sb.ulcy + sb.h) ? sb.ulcy + sb.h : p1y;
0740:
0741:                            // Code-blocks are located at (acb0x+k*cw,acb0y+l*ch)
0742:                            cw = sb.nomCBlkW;
0743:                            ch = sb.nomCBlkH;
0744:                            k0 = (int) Math.floor((sb.ulcy - acb0y)
0745:                                    / (double) ch);
0746:                            kstart = (int) Math.floor((s0y - acb0y)
0747:                                    / (double) ch);
0748:                            kend = (int) Math.floor((s1y - 1 - acb0y)
0749:                                    / (double) ch);
0750:                            l0 = (int) Math.floor((sb.ulcx - acb0x)
0751:                                    / (double) cw);
0752:                            lstart = (int) Math.floor((s0x - acb0x)
0753:                                    / (double) cw);
0754:                            lend = (int) Math.floor((s1x - 1 - acb0x)
0755:                                    / (double) cw);
0756:
0757:                            if (s1x - s0x <= 0 || s1y - s0y <= 0) {
0758:                                ppinfo[c][r][nPrec].nblk[3] = 0;
0759:                                ttIncl[c][r][nPrec][3] = new TagTreeDecoder(0,
0760:                                        0);
0761:                                ttMaxBP[c][r][nPrec][3] = new TagTreeDecoder(0,
0762:                                        0);
0763:                            } else {
0764:                                ttIncl[c][r][nPrec][3] = new TagTreeDecoder(
0765:                                        kend - kstart + 1, lend - lstart + 1);
0766:                                ttMaxBP[c][r][nPrec][3] = new TagTreeDecoder(
0767:                                        kend - kstart + 1, lend - lstart + 1);
0768:                                ppinfo[c][r][nPrec].cblk[3] = new CBlkCoordInfo[kend
0769:                                        - kstart + 1][lend - lstart + 1];
0770:                                ppinfo[c][r][nPrec].nblk[3] = (kend - kstart + 1)
0771:                                        * (lend - lstart + 1);
0772:
0773:                                for (int k = kstart; k <= kend; k++) { // Vertical cblks
0774:                                    for (int l = lstart; l <= lend; l++) { // Horiz cblks
0775:                                        cb = new CBlkCoordInfo(k - k0, l - l0);
0776:                                        if (l == l0) {
0777:                                            cb.ulx = sb.ulx;
0778:                                        } else {
0779:                                            cb.ulx = sb.ulx + l * cw
0780:                                                    - (sb.ulcx - acb0x);
0781:                                        }
0782:                                        if (k == k0) {
0783:                                            cb.uly = sb.uly;
0784:                                        } else {
0785:                                            cb.uly = sb.uly + k * ch
0786:                                                    - (sb.ulcy - acb0y);
0787:                                        }
0788:                                        tmp1 = acb0x + l * cw;
0789:                                        tmp1 = (tmp1 > sb.ulcx) ? tmp1
0790:                                                : sb.ulcx;
0791:                                        tmp2 = acb0x + (l + 1) * cw;
0792:                                        tmp2 = (tmp2 > sb.ulcx + sb.w) ? sb.ulcx
0793:                                                + sb.w
0794:                                                : tmp2;
0795:                                        cb.w = tmp2 - tmp1;
0796:                                        tmp1 = acb0y + k * ch;
0797:                                        tmp1 = (tmp1 > sb.ulcy) ? tmp1
0798:                                                : sb.ulcy;
0799:                                        tmp2 = acb0y + (k + 1) * ch;
0800:                                        tmp2 = (tmp2 > sb.ulcy + sb.h) ? sb.ulcy
0801:                                                + sb.h
0802:                                                : tmp2;
0803:                                        cb.h = tmp2 - tmp1;
0804:                                        ppinfo[c][r][nPrec].cblk[3][k - kstart][l
0805:                                                - lstart] = cb;
0806:                                    } // Horizontal code-blocks
0807:                                } // Vertical code-blocks
0808:                            }
0809:
0810:                        }
0811:                    } // Horizontal precincts
0812:                } // Vertical precincts
0813:            }
0814:
0815:            /** 
0816:             * Gets the number of precincts in a given component and resolution level.
0817:             *
0818:             * @param c Component index
0819:             *
0820:             * @param r Resolution index
0821:             * */
0822:            public int getNumPrecinct(int c, int r) {
0823:                return numPrec[c][r].x * numPrec[c][r].y;
0824:            }
0825:
0826:            /** 
0827:             * Read specified packet head and found length of each code-block's piece
0828:             * of codewords as well as number of skipped most significant bit-planes.
0829:             *
0830:             * @param l layer index
0831:             *
0832:             * @param r Resolution level index
0833:             *
0834:             * @param c Component index
0835:             *
0836:             * @param p Precinct index
0837:             *
0838:             * @param cbI CBlkInfo array of relevant component and resolution
0839:             * level.
0840:             *
0841:             * @param nb The number of bytes to read in each tile before reaching
0842:             * output rate (used by truncation mode)
0843:             *
0844:             * @return True if specified output rate or EOF is reached.
0845:             * */
0846:            public boolean readPktHead(int l, int r, int c, int p,
0847:                    CBlkInfo[][][] cbI, int[] nb) throws IOException {
0848:
0849:                CBlkInfo ccb;
0850:                int nSeg; // number of segment to read
0851:                int cbLen; // Length of cblk's code-words
0852:                int ltp; // last truncation point index
0853:                int passtype; // coding pass type
0854:                TagTreeDecoder tdIncl, tdBD;
0855:                int tmp, tmp2, totnewtp, lblockCur, tpidx;
0856:                int sumtotnewtp = 0;
0857:                Point cbc;
0858:                int startPktHead = ehs.getPos();
0859:                if (startPktHead >= ehs.length()) {
0860:                    // EOF reached at the beginning of this packet head
0861:                    return true;
0862:                }
0863:                int tIdx = src.getTileIdx();
0864:                PktHeaderBitReader bin;
0865:                int mend, nend;
0866:                int b;
0867:                SubbandSyn sb;
0868:                SubbandSyn root = src.getSynSubbandTree(tIdx, c);
0869:
0870:                // If packed packet headers was used, use separate stream for reading
0871:                // of packet headers
0872:                if (pph) {
0873:                    bin = new PktHeaderBitReader(pphbais);
0874:                } else {
0875:                    bin = this .bin;
0876:                }
0877:
0878:                int mins = (r == 0) ? 0 : 1;
0879:                int maxs = (r == 0) ? 1 : 4;
0880:
0881:                boolean precFound = false;
0882:                for (int s = mins; s < maxs; s++) {
0883:                    if (p < ppinfo[c][r].length) {
0884:                        precFound = true;
0885:                    }
0886:                }
0887:                if (!precFound) {
0888:                    return false;
0889:                }
0890:
0891:                PrecInfo prec = ppinfo[c][r][p];
0892:
0893:                // Synchronize for bit reading
0894:                bin.sync();
0895:
0896:                // If packet is empty there is no info in it (i.e. no code-blocks)
0897:                if (bin.readBit() == 0) {
0898:                    // No code-block is included
0899:                    cblks = new Vector[maxs + 1];
0900:                    for (int s = mins; s < maxs; s++) {
0901:                        cblks[s] = new Vector();
0902:                    }
0903:                    pktIdx++;
0904:
0905:                    // If truncation mode, checks if output rate is reached
0906:                    // unless ncb quit condition is used in which case headers
0907:                    // are not counted
0908:                    if (isTruncMode && maxCB == -1) {
0909:                        tmp = ehs.getPos() - startPktHead;
0910:                        if (tmp > nb[tIdx]) {
0911:                            nb[tIdx] = 0;
0912:                            return true;
0913:                        } else {
0914:                            nb[tIdx] -= tmp;
0915:                        }
0916:                    }
0917:
0918:                    // Read EPH marker if needed
0919:                    if (ephUsed) {
0920:                        readEPHMarker(bin);
0921:                    }
0922:                    return false;
0923:                }
0924:
0925:                // Packet is not empty => decode info
0926:                // Loop on each subband in this resolution level
0927:                if (cblks == null || cblks.length < maxs + 1) {
0928:                    cblks = new Vector[maxs + 1];
0929:                }
0930:
0931:                for (int s = mins; s < maxs; s++) {
0932:                    if (cblks[s] == null) {
0933:                        cblks[s] = new Vector();
0934:                    } else {
0935:                        cblks[s].removeAllElements();
0936:                    }
0937:                    sb = (SubbandSyn) root.getSubbandByIdx(r, s);
0938:                    // No code-block in this precinct
0939:                    if (prec.nblk[s] == 0) {
0940:                        // Go to next subband
0941:                        continue;
0942:                    }
0943:
0944:                    tdIncl = ttIncl[c][r][p][s];
0945:                    tdBD = ttMaxBP[c][r][p][s];
0946:
0947:                    mend = (prec.cblk[s] == null) ? 0 : prec.cblk[s].length;
0948:                    for (int m = 0; m < mend; m++) { // Vertical code-blocks
0949:                        nend = (prec.cblk[s][m] == null) ? 0
0950:                                : prec.cblk[s][m].length;
0951:                        for (int n = 0; n < nend; n++) { // Horizontal code-blocks
0952:                            cbc = prec.cblk[s][m][n].idx;
0953:                            b = cbc.x + cbc.y * sb.numCb.x;
0954:
0955:                            ccb = cbI[s][cbc.y][cbc.x];
0956:
0957:                            try {
0958:                                // If code-block not included in previous layer(s)
0959:                                if (ccb == null || ccb.ctp == 0) {
0960:                                    if (ccb == null) {
0961:                                        ccb = cbI[s][cbc.y][cbc.x] = new CBlkInfo(
0962:                                                prec.cblk[s][m][n].ulx,
0963:                                                prec.cblk[s][m][n].uly,
0964:                                                prec.cblk[s][m][n].w,
0965:                                                prec.cblk[s][m][n].h, nl);
0966:                                    }
0967:                                    ccb.pktIdx[l] = pktIdx;
0968:
0969:                                    // Read inclusion using tag-tree
0970:                                    tmp = tdIncl.update(m, n, l + 1, bin);
0971:                                    if (tmp > l) { // Not included
0972:                                        continue;
0973:                                    }
0974:
0975:                                    // Read bitdepth using tag-tree
0976:                                    tmp = 1;// initialization
0977:                                    for (tmp2 = 1; tmp >= tmp2; tmp2++) {
0978:                                        tmp = tdBD.update(m, n, tmp2, bin);
0979:                                    }
0980:                                    ccb.msbSkipped = tmp2 - 2;
0981:
0982:                                    // New code-block => at least one truncation point
0983:                                    totnewtp = 1;
0984:                                    ccb.addNTP(l, 0);
0985:
0986:                                    // Check whether ncb quit condition is reached
0987:                                    ncb++;
0988:                                    if (maxCB != -1 && !ncbQuit && ncb == maxCB) {
0989:                                        // ncb quit contidion reached
0990:                                        ncbQuit = true;
0991:                                        tQuit = tIdx;
0992:                                        cQuit = c;
0993:                                        sQuit = s;
0994:                                        rQuit = r;
0995:                                        xQuit = cbc.x;
0996:                                        yQuit = cbc.y;
0997:                                    }
0998:
0999:                                } else { // If code-block already included in one of
1000:                                    // the previous layers.
1001:
1002:                                    ccb.pktIdx[l] = pktIdx;
1003:
1004:                                    // If not inclused
1005:                                    if (bin.readBit() != 1) {
1006:                                        continue;
1007:                                    }
1008:
1009:                                    // At least 1 more truncation point than
1010:                                    // prev. packet
1011:                                    totnewtp = 1;
1012:                                }
1013:
1014:                                // Read new truncation points
1015:                                if (bin.readBit() == 1) {// if bit is 1
1016:                                    totnewtp++;
1017:
1018:                                    // if next bit is 0 do nothing
1019:                                    if (bin.readBit() == 1) {//if is 1
1020:                                        totnewtp++;
1021:
1022:                                        tmp = bin.readBits(2);
1023:                                        totnewtp += tmp;
1024:                                        // If next 2 bits are not 11 do nothing
1025:                                        if (tmp == 0x3) { //if 11
1026:                                            tmp = bin.readBits(5);
1027:                                            totnewtp += tmp;
1028:
1029:                                            // If next 5 bits are not 11111 do nothing
1030:                                            if (tmp == 0x1F) { //if 11111
1031:                                                totnewtp += bin.readBits(7);
1032:                                            }
1033:                                        }
1034:                                    }
1035:                                }
1036:                                ccb.addNTP(l, totnewtp);
1037:                                sumtotnewtp += totnewtp;
1038:                                cblks[s].addElement(prec.cblk[s][m][n]);
1039:
1040:                                // Code-block length
1041:
1042:                                // -- Compute the number of bit to read to obtain
1043:                                // code-block length.  
1044:                                // numBits = betaLamda + log2(totnewtp);
1045:
1046:                                // The length is signalled for each segment in
1047:                                // addition to the final one. The total length is the
1048:                                // sum of all segment lengths.
1049:
1050:                                // If regular termination in use, then there is one
1051:                                // segment per truncation point present. Otherwise, if
1052:                                // selective arithmetic bypass coding mode is present,
1053:                                // then there is one termination per bypass/MQ and
1054:                                // MQ/bypass transition. Otherwise the only
1055:                                // termination is at the end of the code-block.
1056:                                int options = ((Integer) decSpec.ecopts
1057:                                        .getTileCompVal(tIdx, c)).intValue();
1058:
1059:                                if ((options & OPT_TERM_PASS) != 0) {
1060:                                    // Regular termination in use, one segment per new
1061:                                    // pass (i.e. truncation point)
1062:                                    nSeg = totnewtp;
1063:                                } else if ((options & OPT_BYPASS) != 0) {
1064:                                    // Selective arithmetic coding bypass coding mode
1065:                                    // in use, but no regular termination 1 segment up
1066:                                    // to the end of the last pass of the 4th most
1067:                                    // significant bit-plane, and, in each following
1068:                                    // bit-plane, one segment upto the end of the 2nd
1069:                                    // pass and one upto the end of the 3rd pass.
1070:
1071:                                    if (ccb.ctp <= FIRST_BYPASS_PASS_IDX) {
1072:                                        nSeg = 1;
1073:                                    } else {
1074:                                        nSeg = 1; // One at least for last pass
1075:                                        // And one for each other terminated pass
1076:                                        for (tpidx = ccb.ctp - totnewtp; tpidx < ccb.ctp - 1; tpidx++) {
1077:                                            if (tpidx >= FIRST_BYPASS_PASS_IDX - 1) {
1078:                                                passtype = (tpidx + NUM_EMPTY_PASSES_IN_MS_BP)
1079:                                                        % NUM_PASSES;
1080:                                                if (passtype == 1
1081:                                                        || passtype == 2) {
1082:                                                    // bypass coding just before MQ
1083:                                                    // pass or MQ pass just before
1084:                                                    // bypass coding => terminated
1085:                                                    nSeg++;
1086:                                                }
1087:                                            }
1088:                                        }
1089:                                    }
1090:                                } else {
1091:                                    // Nothing special in use, just one segment
1092:                                    nSeg = 1;
1093:                                }
1094:
1095:                                // Reads lblock increment (common to all segments)
1096:                                while (bin.readBit() != 0) {
1097:                                    lblock[c][r][s][cbc.y][cbc.x]++;
1098:                                }
1099:
1100:                                if (nSeg == 1) { // Only one segment in packet
1101:                                    cbLen = bin
1102:                                            .readBits(lblock[c][r][s][cbc.y][cbc.x]
1103:                                                    + MathUtil.log2(totnewtp));
1104:                                } else {
1105:                                    // We must read one length per segment
1106:                                    ccb.segLen[l] = new int[nSeg];
1107:                                    cbLen = 0;
1108:                                    int j;
1109:                                    if ((options & OPT_TERM_PASS) != 0) {
1110:                                        // Regular termination: each pass is terminated
1111:                                        for (tpidx = ccb.ctp - totnewtp, j = 0; tpidx < ccb.ctp; tpidx++, j++) {
1112:
1113:                                            lblockCur = lblock[c][r][s][cbc.y][cbc.x];
1114:
1115:                                            tmp = bin.readBits(lblockCur);
1116:                                            ccb.segLen[l][j] = tmp;
1117:                                            cbLen += tmp;
1118:                                        }
1119:                                    } else {
1120:                                        // Bypass coding: only some passes are
1121:                                        // terminated
1122:                                        ltp = ccb.ctp - totnewtp - 1;
1123:                                        for (tpidx = ccb.ctp - totnewtp, j = 0; tpidx < ccb.ctp - 1; tpidx++) {
1124:                                            if (tpidx >= FIRST_BYPASS_PASS_IDX - 1) {
1125:                                                passtype = (tpidx + NUM_EMPTY_PASSES_IN_MS_BP)
1126:                                                        % NUM_PASSES;
1127:                                                if (passtype == 0)
1128:                                                    continue;
1129:
1130:                                                lblockCur = lblock[c][r][s][cbc.y][cbc.x];
1131:                                                tmp = bin.readBits(lblockCur
1132:                                                        + MathUtil.log2(tpidx
1133:                                                                - ltp));
1134:                                                ccb.segLen[l][j] = tmp;
1135:                                                cbLen += tmp;
1136:                                                ltp = tpidx;
1137:                                                j++;
1138:                                            }
1139:                                        }
1140:                                        // Last pass has always the length sent
1141:                                        lblockCur = lblock[c][r][s][cbc.y][cbc.x];
1142:                                        tmp = bin.readBits(lblockCur
1143:                                                + MathUtil.log2(tpidx - ltp));
1144:                                        cbLen += tmp;
1145:                                        ccb.segLen[l][j] = tmp;
1146:                                    }
1147:                                }
1148:                                ccb.len[l] = cbLen;
1149:
1150:                                // If truncation mode, checks if output rate is reached
1151:                                // unless ncb and lbody quit contitions used.
1152:                                if (isTruncMode && maxCB == -1) {
1153:                                    tmp = ehs.getPos() - startPktHead;
1154:                                    if (tmp > nb[tIdx]) {
1155:                                        nb[tIdx] = 0;
1156:                                        // Remove found information in this code-block
1157:                                        if (l == 0) {
1158:                                            cbI[s][cbc.y][cbc.x] = null;
1159:                                        } else {
1160:                                            ccb.off[l] = ccb.len[l] = 0;
1161:                                            ccb.ctp -= ccb.ntp[l];
1162:                                            ccb.ntp[l] = 0;
1163:                                            ccb.pktIdx[l] = -1;
1164:                                        }
1165:                                        return true;
1166:                                    }
1167:                                }
1168:
1169:                            } catch (EOFException e) {
1170:                                // Remove found information in this code-block
1171:                                if (l == 0) {
1172:                                    cbI[s][cbc.y][cbc.x] = null;
1173:                                } else {
1174:                                    ccb.off[l] = ccb.len[l] = 0;
1175:                                    ccb.ctp -= ccb.ntp[l];
1176:                                    ccb.ntp[l] = 0;
1177:                                    ccb.pktIdx[l] = -1;
1178:                                }
1179:                                //                         throw new EOFException();
1180:                                return true;
1181:                            }
1182:                        } // End loop on horizontal code-blocks
1183:                    } // End loop on vertical code-blocks
1184:                } // End loop on subbands
1185:
1186:                // Read EPH marker if needed
1187:                if (ephUsed) {
1188:                    readEPHMarker(bin);
1189:                }
1190:
1191:                pktIdx++;
1192:
1193:                // If truncation mode, checks if output rate is reached
1194:                if (isTruncMode && maxCB == -1) {
1195:                    tmp = ehs.getPos() - startPktHead;
1196:                    if (tmp > nb[tIdx]) {
1197:                        nb[tIdx] = 0;
1198:                        return true;
1199:                    } else {
1200:                        nb[tIdx] -= tmp;
1201:                    }
1202:                }
1203:                return false;
1204:            }
1205:
1206:            /** 
1207:             * Reads specificied packet body in order to find offset of each
1208:             * code-block's piece of codeword. This use the list of found code-blocks
1209:             * in previous red packet head.
1210:             *
1211:             * @param l layer index
1212:             *
1213:             * @param r Resolution level index
1214:             *
1215:             * @param c Component index
1216:             *
1217:             * @param p Precinct index
1218:             *
1219:             * @param cbI CBlkInfo array of relevant component and resolution
1220:             * level.
1221:             *
1222:             * @param nb The remainding number of bytes to read from the bit stream in
1223:             * each tile before reaching the decoding rate (in truncation mode)
1224:             *
1225:             * @return True if decoding rate is reached 
1226:             * */
1227:            public boolean readPktBody(int l, int r, int c, int p,
1228:                    CBlkInfo[][][] cbI, int[] nb) throws IOException {
1229:                int curOff = ehs.getPos();
1230:                Point curCB;
1231:                CBlkInfo ccb;
1232:                boolean stopRead = false;
1233:                int tIdx = src.getTileIdx();
1234:                Point cbc;
1235:
1236:                boolean precFound = false;
1237:                int mins = (r == 0) ? 0 : 1;
1238:                int maxs = (r == 0) ? 1 : 4;
1239:                for (int s = mins; s < maxs; s++) {
1240:                    if (p < ppinfo[c][r].length) {
1241:                        precFound = true;
1242:                    }
1243:                }
1244:                if (!precFound) {
1245:                    return false;
1246:                }
1247:
1248:                for (int s = mins; s < maxs; s++) {
1249:                    for (int numCB = 0; numCB < cblks[s].size(); numCB++) {
1250:                        cbc = ((CBlkCoordInfo) cblks[s].elementAt(numCB)).idx;
1251:                        ccb = cbI[s][cbc.y][cbc.x];
1252:                        ccb.off[l] = curOff;
1253:                        curOff += ccb.len[l];
1254:                        try {
1255:                            ehs.seek(curOff);
1256:                        } catch (EOFException e) {
1257:                            if (l == 0) {
1258:                                cbI[s][cbc.y][cbc.x] = null;
1259:                            } else {
1260:                                ccb.off[l] = ccb.len[l] = 0;
1261:                                ccb.ctp -= ccb.ntp[l];
1262:                                ccb.ntp[l] = 0;
1263:                                ccb.pktIdx[l] = -1;
1264:                            }
1265:                            throw new EOFException();
1266:                        }
1267:
1268:                        // If truncation mode
1269:                        if (isTruncMode) {
1270:                            if (stopRead || ccb.len[l] > nb[tIdx]) {
1271:                                // Remove found information in this code-block
1272:                                if (l == 0) {
1273:                                    cbI[s][cbc.y][cbc.x] = null;
1274:                                } else {
1275:                                    ccb.off[l] = ccb.len[l] = 0;
1276:                                    ccb.ctp -= ccb.ntp[l];
1277:                                    ccb.ntp[l] = 0;
1278:                                    ccb.pktIdx[l] = -1;
1279:                                }
1280:                                stopRead = true;
1281:                            }
1282:                            if (!stopRead) {
1283:                                nb[tIdx] -= ccb.len[l];
1284:                            }
1285:                        }
1286:                        // If ncb quit condition reached
1287:                        if (ncbQuit && r == rQuit && s == sQuit
1288:                                && cbc.x == xQuit && cbc.y == yQuit
1289:                                && tIdx == tQuit && c == cQuit) {
1290:                            cbI[s][cbc.y][cbc.x] = null;
1291:                            stopRead = true;
1292:                        }
1293:                    } // Loop on code-blocks
1294:                } // End loop on subbands
1295:
1296:                // Seek to the end of the packet
1297:                ehs.seek(curOff);
1298:
1299:                if (stopRead) {
1300:                    return true;
1301:                } else {
1302:                    return false;
1303:                }
1304:            }
1305:
1306:            /**
1307:             * Returns the precinct partition width for the specified component,
1308:             * resolution level and tile.
1309:             *
1310:             * @param t the tile index
1311:             *
1312:             * @param c The index of the component (between 0 and C-1)
1313:             *
1314:             * @param r The resolution level, from 0 to L.
1315:             *
1316:             * @return the precinct partition width for the specified component,
1317:             * resolution level and tile.
1318:             * */
1319:            public final int getPPX(int t, int c, int r) {
1320:                return decSpec.pss.getPPX(t, c, r);
1321:            }
1322:
1323:            /**
1324:             * Returns the precinct partition height for the specified component,
1325:             * resolution level and tile.
1326:             *
1327:             * @param t the tile index
1328:             *
1329:             * @param c The index of the component (between 0 and C-1)
1330:             *
1331:             * @param rl The resolution level, from 0 to L.
1332:             *
1333:             * @return the precinct partition height in the specified component, for
1334:             * the specified resolution level, for the current tile.
1335:             * */
1336:            public final int getPPY(int t, int c, int rl) {
1337:                return decSpec.pss.getPPY(t, c, rl);
1338:            }
1339:
1340:            /**
1341:             * Try to read a SOP marker and check that its sequence number if not out
1342:             * of sequence. If so, an error is thrown.
1343:             *
1344:             * @param nBytes The number of bytes left to read from each tile
1345:             *
1346:             * @param p Precinct index
1347:             *
1348:             * @param r Resolution level index
1349:             *
1350:             * @param c Component index
1351:             * */
1352:            public boolean readSOPMarker(int[] nBytes, int p, int c, int r)
1353:                    throws IOException {
1354:                int val;
1355:                byte sopArray[] = new byte[6];
1356:                int tIdx = src.getTileIdx();
1357:                int mins = (r == 0) ? 0 : 1;
1358:                int maxs = (r == 0) ? 1 : 4;
1359:                boolean precFound = false;
1360:                for (int s = mins; s < maxs; s++) {
1361:                    if (p < ppinfo[c][r].length) {
1362:                        precFound = true;
1363:                    }
1364:                }
1365:                if (!precFound) {
1366:                    return false;
1367:                }
1368:
1369:                // If SOP markers are not used, return
1370:                if (!sopUsed) {
1371:                    return false;
1372:                }
1373:
1374:                // Check if SOP is used for this packet
1375:                int pos = ehs.getPos();
1376:                if ((short) ((ehs.read() << 8) | ehs.read()) != Markers.SOP) {
1377:                    ehs.seek(pos);
1378:                    return false;
1379:                }
1380:                ehs.seek(pos);
1381:
1382:                // If length of SOP marker greater than remaining bytes to read for
1383:                // this tile return true
1384:                if (nBytes[tIdx] < 6) {
1385:                    return true;
1386:                }
1387:                nBytes[tIdx] -= 6;
1388:
1389:                // Read marker into array 'sopArray'
1390:                ehs.readFully(sopArray, 0, Markers.SOP_LENGTH);
1391:
1392:                // Check if this is the correct marker
1393:                val = sopArray[0];
1394:                val <<= 8;
1395:                val |= sopArray[1];
1396:                if (val != Markers.SOP) {
1397:                    throw new Error("Corrupted Bitstream: Could not parse SOP "
1398:                            + "marker !");
1399:                }
1400:
1401:                // Check if length is correct
1402:                val = (sopArray[2] & 0xff);
1403:                val <<= 8;
1404:                val |= (sopArray[3] & 0xff);
1405:                if (val != 4) {
1406:                    throw new Error(
1407:                            "Corrupted Bitstream: Corrupted SOP marker !");
1408:                }
1409:
1410:                // Check if sequence number if ok
1411:                val = (sopArray[4] & 0xff);
1412:                val <<= 8;
1413:                val |= (sopArray[5] & 0xff);
1414:
1415:                if (!pph && val != pktIdx) {
1416:                    throw new Error("Corrupted Bitstream: SOP marker out of "
1417:                            + "sequence !");
1418:                }
1419:                if (pph && val != pktIdx - 1) {
1420:                    // if packed packet headers are used, packet header was read
1421:                    // before SOP marker segment
1422:                    throw new Error("Corrupted Bitstream: SOP marker out of "
1423:                            + "sequence !");
1424:                }
1425:                return false;
1426:            }
1427:
1428:            /**
1429:             * Try to read an EPH marker. If it is not possible then an Error is
1430:             * thrown.
1431:             *
1432:             * @param bin The packet header reader to read the EPH marker from
1433:             * */
1434:            public void readEPHMarker(PktHeaderBitReader bin)
1435:                    throws IOException {
1436:                int val;
1437:                byte ephArray[] = new byte[2];
1438:
1439:                if (bin.usebais) {
1440:                    bin.bais.read(ephArray, 0, Markers.EPH_LENGTH);
1441:                } else {
1442:                    bin.in.readFully(ephArray, 0, Markers.EPH_LENGTH);
1443:                }
1444:
1445:                // Check if this is the correct marker
1446:                val = ephArray[0];
1447:                val <<= 8;
1448:                val |= ephArray[1];
1449:                if (val != Markers.EPH) {
1450:                    throw new Error("Corrupted Bitstream: Could not parse EPH "
1451:                            + "marker ! ");
1452:                }
1453:            }
1454:
1455:            /** 
1456:             * Get PrecInfo instance of the specified resolution level, component and
1457:             * precinct.
1458:             *
1459:             * @param c Component index.
1460:             *
1461:             * @param r Resolution level index.
1462:             *
1463:             * @param p Precinct index.
1464:             * */
1465:            public PrecInfo getPrecInfo(int c, int r, int p) {
1466:                return ppinfo[c][r][p];
1467:            }
1468:
1469:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.