001/* 002 * $RCSfile: PktDecoder.java,v $ 003 * $Revision: 1.1 $ 004 * $Date: 2005/02/11 05:02:01 $ 005 * $State: Exp $ 006 * 007 * Class: PktDecoder 008 * 009 * Description: Reads packets heads and keeps location of 010 * code-blocks' codewords 011 * 012 * 013 * 014 * COPYRIGHT: 015 * 016 * This software module was originally developed by Raphaël Grosbois and 017 * Diego Santa Cruz (Swiss Federal Institute of Technology-EPFL); Joel 018 * Askelöf (Ericsson Radio Systems AB); and Bertrand Berthelot, David 019 * Bouchard, Félix Henry, Gerard Mozelle and Patrice Onno (Canon Research 020 * Centre France S.A) in the course of development of the JPEG2000 021 * standard as specified by ISO/IEC 15444 (JPEG 2000 Standard). This 022 * software module is an implementation of a part of the JPEG 2000 023 * Standard. Swiss Federal Institute of Technology-EPFL, Ericsson Radio 024 * Systems AB and Canon Research Centre France S.A (collectively JJ2000 025 * Partners) agree not to assert against ISO/IEC and users of the JPEG 026 * 2000 Standard (Users) any of their rights under the copyright, not 027 * including other intellectual property rights, for this software module 028 * with respect to the usage by ISO/IEC and Users of this software module 029 * or modifications thereof for use in hardware or software products 030 * claiming conformance to the JPEG 2000 Standard. Those intending to use 031 * this software module in hardware or software products are advised that 032 * their use may infringe existing patents. The original developers of 033 * this software module, JJ2000 Partners and ISO/IEC assume no liability 034 * for use of this software module or modifications thereof. No license 035 * or right to this software module is granted for non JPEG 2000 Standard 036 * conforming products. JJ2000 Partners have full right to use this 037 * software module for his/her own purpose, assign or donate this 038 * software module to any third party and to inhibit third parties from 039 * using this software module for non JPEG 2000 Standard conforming 040 * products. This copyright notice must be included in all copies or 041 * derivative works of this software module. 042 * 043 * Copyright (c) 1999/2000 JJ2000 Partners. 044 * */ 045package jj2000.j2k.codestream.reader; 046import java.awt.Point; 047import java.io.ByteArrayInputStream; 048import java.io.EOFException; 049import java.io.IOException; 050import java.util.Vector; 051 052import jj2000.j2k.codestream.CBlkCoordInfo; 053import jj2000.j2k.codestream.Markers; 054import jj2000.j2k.codestream.PrecInfo; 055import jj2000.j2k.decoder.DecoderSpecs; 056import jj2000.j2k.entropy.StdEntropyCoderOptions; 057import jj2000.j2k.io.RandomAccessIO; 058import jj2000.j2k.util.ArrayUtil; 059import jj2000.j2k.util.MathUtil; 060import jj2000.j2k.wavelet.synthesis.SubbandSyn; 061 062/** 063 * This class is used to read packet's head and body. All the members must be 064 * re-initialized at the beginning of each tile thanks to the restart() 065 * method. 066 * */ 067public class PktDecoder implements StdEntropyCoderOptions{ 068 069 /** Reference to the codestream reader agent */ 070 private BitstreamReaderAgent src; 071 072 /** Flag indicating whether packed packet header was used for this tile*/ 073 private boolean pph=false; 074 075 /** The packed packet header if it was used */ 076 private ByteArrayInputStream pphbais; 077 078 /** Reference to decoder specifications */ 079 private DecoderSpecs decSpec; 080 081 /** Reference to the HeaderDecoder */ 082 private HeaderDecoder hd; 083 084 /** Initial value of the state variable associated with code-block 085 * length. */ 086 private final int INIT_LBLOCK = 3; 087 088 /** The wrapper to read bits for the packet heads */ 089 private PktHeaderBitReader bin; 090 091 /** Reference to the stream where to read from */ 092 private RandomAccessIO ehs; 093 094 /** 095 * Maximum number of precincts : 096 * 097 * <ul> 098 * <li> 1st dim: component index.</li> 099 * <li> 2nd dim: resolution level index.</li> 100 * </ul> 101 * */ 102 private Point[][] numPrec; 103 104 /** Index of the current tile */ 105 private int tIdx; 106 107 /** 108 * Array containing the coordinates, width, height, indexes, ... of the 109 * precincts in the current tile: 110 * 111 * <ul> 112 * <li> 1st dim: component index.</li> 113 * <li> 2nd dim: resolution level index.</li> 114 * <li> 3rd dim: precinct index.</li> 115 * </ul> 116 * */ 117 private PrecInfo[][][] ppinfo; 118 119 /** 120 * Lblock value used to read code size information in each packet head: 121 * 122 * <ul> 123 * <li> 1st dim: component index.</li> 124 * <li> 2nd dim: resolution level index.</li> 125 * <li> 3rd dim: subband index.</li> 126 * <li> 4th/5th dim: code-block index (vert. and horiz.).</li> 127 * </ul> 128 * */ 129 private int[][][][][] lblock; 130 131 /** 132 * Tag tree used to read inclusion informations in packet's head: 133 * 134 * <ul> 135 * <li> 1st dim: component index.</li> 136 * <li> 2nd dim: resolution level index.</li> 137 * <li> 3rd dim: precinct index.</li> 138 * <li> 4th dim: subband index.</li> 139 * */ 140 private TagTreeDecoder[][][][] ttIncl; 141 142 /** 143 * Tag tree used to read bit-depth information in packet's head: 144 * 145 * <ul> 146 * <li> 1st dim: component index.</li> 147 * <li> 2nd dim: resolution level index.</li> 148 * <li> 3rd dim: precinct index.</li> 149 * <li> 4th dim: subband index.</li> 150 * </ul> 151 * */ 152 private TagTreeDecoder[][][][] ttMaxBP; 153 154 /** Number of layers in t he current tile */ 155 private int nl = 0; 156 157 /** The number of components */ 158 private int nc; 159 160 /** Whether or not SOP marker segment are used */ 161 private boolean sopUsed = false; 162 163 /** Whether or not EPH marker are used */ 164 private boolean ephUsed = false; 165 166 /** Index of the current packet in the tile. Used with SOP marker 167 segment*/ 168 private int pktIdx; 169 170 /** List of code-blocks found in last read packet head (one list 171 * per subband) */ 172 private Vector[] cblks; 173 174 /** Number of codeblocks encountered. used for ncb quit condition*/ 175 private int ncb; 176 177 /** Maximum number of codeblocks to read before ncb quit condition is 178 * reached */ 179 private int maxCB; 180 181 /** Flag indicating whether ncb quit condition has been reached */ 182 private boolean ncbQuit; 183 184 /** The tile in which the ncb quit condition was reached */ 185 private int tQuit; 186 187 /** The component in which the ncb quit condition was reached */ 188 private int cQuit; 189 190 /** The subband in which the ncb quit condition was reached */ 191 private int sQuit; 192 193 /** The resolution in which the ncb quit condition was reached */ 194 private int rQuit; 195 196 /** The x position of the last code block before ncb quit reached */ 197 private int xQuit; 198 199 /** The y position of the last code block before ncb quit reached */ 200 private int yQuit; 201 202 /** True if truncation mode is used. False if it is parsing mode */ 203 private boolean isTruncMode; 204 205 /** 206 * Creates an empty PktDecoder object associated with given decoder 207 * specifications and HeaderDecoder. This object must be initialized 208 * thanks to the restart method before being used. 209 * 210 * @param decSpec The decoder specifications. 211 * 212 * @param hd The HeaderDecoder instance. 213 * 214 * @param ehs The stream where to read data from. 215 * 216 * @param src The bit stream reader agent. 217 * 218 * @param isTruncMode Whether or not truncation mode is required. 219 * 220 * @param maxCB The maximum number of code-blocks to read before ncbquit 221 * 222 * */ 223 public PktDecoder(DecoderSpecs decSpec,HeaderDecoder hd, 224 RandomAccessIO ehs,BitstreamReaderAgent src, 225 boolean isTruncMode, int maxCB) { 226 this.decSpec = decSpec; 227 this.hd = hd; 228 this.ehs = ehs; 229 this.isTruncMode = isTruncMode; 230 bin = new PktHeaderBitReader(ehs); 231 this.src = src; 232 ncb = 0; 233 ncbQuit = false; 234 this.maxCB = maxCB; 235 } 236 237 /** 238 * Re-initialize the PktDecoder instance at the beginning of a new tile. 239 * 240 * @param nc The number of components in this tile 241 * 242 * @param mdl The maximum number of decomposition level in each component 243 * of this tile 244 * 245 * @param nl The number of layers in this tile 246 * 247 * @param cbI The code-blocks array 248 * 249 * @param pph Flag indicating whether packed packet headers was used 250 * 251 * @param pphbais Stream containing the packed packet headers 252 * */ 253 public CBlkInfo[][][][][] restart(int nc,int[] mdl,int nl, 254 CBlkInfo[][][][][] cbI, boolean pph, 255 ByteArrayInputStream pphbais) { 256 this.nc = nc; 257 this.nl = nl; 258 this.tIdx = src.getTileIdx(); 259 this.pph = pph; 260 this.pphbais = pphbais; 261 262 sopUsed = ((Boolean)decSpec.sops.getTileDef(tIdx)).booleanValue(); 263 pktIdx = 0; 264 ephUsed = ((Boolean)decSpec.ephs.getTileDef(tIdx)).booleanValue(); 265 266 cbI = new CBlkInfo[nc][][][][]; 267 lblock = new int[nc][][][][]; 268 ttIncl = new TagTreeDecoder[nc][][][]; 269 ttMaxBP = new TagTreeDecoder[nc][][][]; 270 numPrec = new Point[nc][]; 271 ppinfo = new PrecInfo[nc][][]; 272 273 // Used to compute the maximum number of precincts for each resolution 274 // level 275 int tcx0, tcy0, tcx1, tcy1; // Current tile position in the domain of 276 // the image component 277 int trx0, try0, trx1, try1; // Current tile position in the reduced 278 // resolution image domain 279 int xrsiz, yrsiz; // Component sub-sampling factors 280 281 SubbandSyn root,sb; 282 int mins,maxs; 283 Point nBlk = null; 284 int cb0x = src.getCbULX(); 285 int cb0y = src.getCbULY(); 286 287 for(int c=0; c<nc; c++) { 288 cbI[c] = new CBlkInfo[mdl[c]+1][][][]; 289 lblock[c] = new int[mdl[c]+1][][][]; 290 ttIncl[c] = new TagTreeDecoder[mdl[c]+1][][]; 291 ttMaxBP[c] = new TagTreeDecoder[mdl[c]+1][][]; 292 numPrec[c] = new Point[mdl[c]+1]; 293 ppinfo[c] = new PrecInfo[mdl[c]+1][]; 294 295 // Get the tile-component coordinates on the reference grid 296 tcx0 = src.getResULX(c,mdl[c]); 297 tcy0 = src.getResULY(c,mdl[c]); 298 tcx1 = tcx0 + src.getTileCompWidth(tIdx,c,mdl[c]); 299 tcy1 = tcy0 + src.getTileCompHeight(tIdx,c,mdl[c]); 300 301 for(int r=0; r<=mdl[c]; r++) { 302 303 // Tile's coordinates in the reduced resolution image domain 304 trx0 = (int)Math.ceil(tcx0/(double)(1<<(mdl[c]-r))); 305 try0 = (int)Math.ceil(tcy0/(double)(1<<(mdl[c]-r))); 306 trx1 = (int)Math.ceil(tcx1/(double)(1<<(mdl[c]-r))); 307 try1 = (int)Math.ceil(tcy1/(double)(1<<(mdl[c]-r))); 308 309 // Calculate the maximum number of precincts for each 310 // resolution level taking into account tile specific options. 311 double twoppx = (double)getPPX(tIdx,c,r); 312 double twoppy = (double)getPPY(tIdx,c,r); 313 numPrec[c][r] = new Point(); 314 if (trx1>trx0) { 315 numPrec[c][r].x = (int)Math.ceil((trx1-cb0x)/twoppx) 316 - (int)Math.floor((trx0-cb0x)/twoppx); 317 } else { 318 numPrec[c][r].x = 0; 319 } 320 if (try1>try0) { 321 numPrec[c][r].y = (int)Math.ceil((try1-cb0y)/twoppy) 322 - (int)Math.floor((try0-cb0y)/twoppy); 323 } else { 324 numPrec[c][r].y = 0; 325 } 326 327 // First and last subbands indexes 328 mins = (r==0) ? 0 : 1; 329 maxs = (r==0) ? 1 : 4; 330 331 int maxPrec = numPrec[c][r].x * numPrec[c][r].y; 332 333 ttIncl[c][r] = new TagTreeDecoder[maxPrec][maxs+1]; 334 ttMaxBP[c][r] = new TagTreeDecoder[maxPrec][maxs+1]; 335 cbI[c][r] = new CBlkInfo[maxs+1][][]; 336 lblock[c][r] = new int[maxs+1][][]; 337 338 ppinfo[c][r] = new PrecInfo[maxPrec]; 339 fillPrecInfo(c,r,mdl[c]); 340 341 root = (SubbandSyn)src.getSynSubbandTree(tIdx,c); 342 for(int s=mins; s<maxs; s++){ 343 sb = (SubbandSyn)root.getSubbandByIdx(r,s); 344 nBlk = sb.numCb; 345 346 cbI[c][r][s] = new CBlkInfo[nBlk.y][nBlk.x]; 347 lblock[c][r][s] = new int[nBlk.y][nBlk.x]; 348 349 for(int i=nBlk.y-1;i>=0;i--) { 350 ArrayUtil.intArraySet(lblock[c][r][s][i],INIT_LBLOCK); 351 } 352 } // loop on subbands 353 } // End loop on resolution levels 354 } // End loop on components 355 356 return cbI; 357 } 358 359 /** 360 * Retrives precincts and code-blocks coordinates in the given resolution, 361 * level and component. Finishes TagTreeEncoder initialization as well. 362 * 363 * @param c Component index. 364 * 365 * @param r Resolution level index. 366 * 367 * @param mdl Number of decomposition level in component <tt>c</tt>. 368 * */ 369 private void fillPrecInfo(int c,int r,int mdl) { 370 if(ppinfo[c][r].length==0) return; // No precinct in this 371 // resolution level 372 373 Point tileI = src.getTile(null); 374 Point nTiles = src.getNumTiles(null); 375 376 int xsiz,ysiz,x0siz,y0siz; 377 int xt0siz,yt0siz; 378 int xtsiz,ytsiz; 379 380 xt0siz = src.getTilePartULX(); 381 yt0siz = src.getTilePartULY(); 382 xtsiz = src.getNomTileWidth(); 383 ytsiz = src.getNomTileHeight(); 384 x0siz = hd.getImgULX(); 385 y0siz = hd.getImgULY(); 386 xsiz = hd.getImgWidth(); 387 ysiz = hd.getImgHeight(); 388 389 int tx0 = (tileI.x==0) ? x0siz : xt0siz+tileI.x*xtsiz; 390 int ty0 = (tileI.y==0) ? y0siz : yt0siz+tileI.y*ytsiz; 391 int tx1 = (tileI.x!=nTiles.x-1) ? xt0siz+(tileI.x+1)*xtsiz : xsiz; 392 int ty1 = (tileI.y!=nTiles.y-1) ? yt0siz+(tileI.y+1)*ytsiz : ysiz; 393 394 int xrsiz = hd.getCompSubsX(c); 395 int yrsiz = hd.getCompSubsY(c); 396 397 int tcx0 = src.getResULX(c,mdl); 398 int tcy0 = src.getResULY(c,mdl); 399 int tcx1 = tcx0 + src.getTileCompWidth(tIdx,c,mdl); 400 int tcy1 = tcy0 + src.getTileCompHeight(tIdx,c,mdl); 401 402 int ndl = mdl-r; 403 int trx0 = (int)Math.ceil(tcx0/(double)(1<<ndl)); 404 int try0 = (int)Math.ceil(tcy0/(double)(1<<ndl)); 405 int trx1 = (int)Math.ceil(tcx1/(double)(1<<ndl)); 406 int try1 = (int)Math.ceil(tcy1/(double)(1<<ndl)); 407 408 int cb0x = src.getCbULX(); 409 int cb0y = src.getCbULY(); 410 411 double twoppx = (double)getPPX(tIdx,c,r); 412 double twoppy = (double)getPPY(tIdx,c,r); 413 int twoppx2 = (int)(twoppx/2); 414 int twoppy2 = (int)(twoppy/2); 415 416 // Precincts are located at (cb0x+i*twoppx,cb0y+j*twoppy) 417 // Valid precincts are those which intersect with the current 418 // resolution level 419 int maxPrec = ppinfo[c][r].length; 420 int nPrec = 0; 421 422 int istart = (int)Math.floor((try0-cb0y)/twoppy); 423 int iend = (int)Math.floor((try1-1-cb0y)/twoppy); 424 int jstart = (int)Math.floor((trx0-cb0x)/twoppx); 425 int jend = (int)Math.floor((trx1-1-cb0x)/twoppx); 426 427 int acb0x,acb0y; 428 429 SubbandSyn root = src.getSynSubbandTree(tIdx,c); 430 SubbandSyn sb = null; 431 432 int p0x,p0y,p1x,p1y; // Precinct projection in subband 433 int s0x,s0y,s1x,s1y; // Active subband portion 434 int cw,ch; 435 int kstart,kend,lstart,lend,k0,l0; 436 int prg_ulx,prg_uly; 437 int prg_w = (int)twoppx<<ndl; 438 int prg_h = (int)twoppy<<ndl; 439 int tmp1,tmp2; 440 441 CBlkCoordInfo cb; 442 443 for(int i=istart; i<=iend; i++) { // Vertical precincts 444 for(int j=jstart; j<=jend; j++,nPrec++) { // Horizontal precincts 445 if(j==jstart && (trx0-cb0x)%(xrsiz*((int)twoppx))!=0) { 446 prg_ulx = tx0; 447 } else { 448 prg_ulx = cb0x+j*xrsiz*((int)twoppx<<ndl); 449 } 450 if(i==istart && (try0-cb0y)%(yrsiz*((int)twoppy))!=0) { 451 prg_uly = ty0; 452 } else { 453 prg_uly = cb0y+i*yrsiz*((int)twoppy<<ndl); 454 } 455 456 ppinfo[c][r][nPrec] = 457 new PrecInfo(r,(int)(cb0x+j*twoppx),(int)(cb0y+i*twoppy), 458 (int)twoppx,(int)twoppy, 459 prg_ulx,prg_uly,prg_w,prg_h); 460 461 if(r==0) { // LL subband 462 acb0x = cb0x; 463 acb0y = cb0y; 464 465 p0x = acb0x+j*(int)twoppx; 466 p1x = p0x + (int)twoppx; 467 p0y = acb0y+i*(int)twoppy; 468 p1y = p0y + (int)twoppy; 469 470 sb = (SubbandSyn)root.getSubbandByIdx(0,0); 471 s0x = (p0x<sb.ulcx) ? sb.ulcx : p0x; 472 s1x = (p1x>sb.ulcx+sb.w) ? sb.ulcx+sb.w : p1x; 473 s0y = (p0y<sb.ulcy) ? sb.ulcy : p0y; 474 s1y = (p1y>sb.ulcy+sb.h) ? sb.ulcy+sb.h : p1y; 475 476 // Code-blocks are located at (acb0x+k*cw,acb0y+l*ch) 477 cw = sb.nomCBlkW; 478 ch = sb.nomCBlkH; 479 k0 = (int)Math.floor((sb.ulcy-acb0y)/(double)ch); 480 kstart = (int)Math.floor((s0y-acb0y)/(double)ch); 481 kend = (int)Math.floor((s1y-1-acb0y)/(double)ch); 482 l0 = (int)Math.floor((sb.ulcx-acb0x)/(double)cw); 483 lstart = (int)Math.floor((s0x-acb0x)/(double)cw); 484 lend = (int)Math.floor((s1x-1-acb0x)/(double)cw); 485 486 if(s1x-s0x<=0 || s1y-s0y<=0) { 487 ppinfo[c][r][nPrec].nblk[0] = 0; 488 ttIncl[c][r][nPrec][0] = new TagTreeDecoder(0,0); 489 ttMaxBP[c][r][nPrec][0] = new TagTreeDecoder(0,0); 490 } else { 491 ttIncl[c][r][nPrec][0] = 492 new TagTreeDecoder(kend-kstart+1,lend-lstart+1); 493 ttMaxBP[c][r][nPrec][0] = 494 new TagTreeDecoder(kend-kstart+1,lend-lstart+1); 495 ppinfo[c][r][nPrec].cblk[0] = 496 new CBlkCoordInfo[kend-kstart+1][lend-lstart+1]; 497 ppinfo[c][r][nPrec]. 498 nblk[0] = (kend-kstart+1)*(lend-lstart+1); 499 500 for(int k=kstart; k<=kend; k++) { // Vertical cblks 501 for(int l=lstart; l<=lend; l++) { // Horiz. cblks 502 cb = new CBlkCoordInfo(k-k0,l-l0); 503 if(l==l0) { 504 cb.ulx = sb.ulx; 505 } else { 506 cb.ulx = sb.ulx+l*cw-(sb.ulcx-acb0x); 507 } 508 if(k==k0) { 509 cb.uly = sb.uly; 510 } else { 511 cb.uly = sb.uly+k*ch-(sb.ulcy-acb0y); 512 } 513 tmp1 = acb0x+l*cw; 514 tmp1 = (tmp1>sb.ulcx) ? tmp1 : sb.ulcx; 515 tmp2 = acb0x+(l+1)*cw; 516 tmp2 = (tmp2>sb.ulcx+sb.w) ? 517 sb.ulcx+sb.w : tmp2; 518 cb.w = tmp2-tmp1; 519 tmp1 = acb0y+k*ch; 520 tmp1 = (tmp1>sb.ulcy) ? tmp1 : sb.ulcy; 521 tmp2 = acb0y+(k+1)*ch; 522 tmp2 = (tmp2>sb.ulcy+sb.h) ? 523 sb.ulcy+sb.h : tmp2; 524 cb.h = tmp2-tmp1; 525 ppinfo[c][r][nPrec]. 526 cblk[0][k-kstart][l-lstart] = cb; 527 } // Horizontal code-blocks 528 } // Vertical code-blocks 529 } 530 } else { // HL, LH and HH subbands 531 // HL subband 532 acb0x = 0; 533 acb0y = cb0y; 534 535 p0x = acb0x+j*twoppx2; 536 p1x = p0x + twoppx2; 537 p0y = acb0y+i*twoppy2; 538 p1y = p0y + twoppy2; 539 540 sb = (SubbandSyn)root.getSubbandByIdx(r,1); 541 s0x = (p0x<sb.ulcx) ? sb.ulcx : p0x; 542 s1x = (p1x>sb.ulcx+sb.w) ? sb.ulcx+sb.w : p1x; 543 s0y = (p0y<sb.ulcy) ? sb.ulcy : p0y; 544 s1y = (p1y>sb.ulcy+sb.h) ? sb.ulcy+sb.h : p1y; 545 546 // Code-blocks are located at (acb0x+k*cw,acb0y+l*ch) 547 cw = sb.nomCBlkW; 548 ch = sb.nomCBlkH; 549 k0 = (int)Math.floor((sb.ulcy-acb0y)/(double)ch); 550 kstart = (int)Math.floor((s0y-acb0y)/(double)ch); 551 kend = (int)Math.floor((s1y-1-acb0y)/(double)ch); 552 l0 = (int)Math.floor((sb.ulcx-acb0x)/(double)cw); 553 lstart = (int)Math.floor((s0x-acb0x)/(double)cw); 554 lend = (int)Math.floor((s1x-1-acb0x)/(double)cw); 555 556 if(s1x-s0x<=0 || s1y-s0y<=0) { 557 ppinfo[c][r][nPrec].nblk[1] = 0; 558 ttIncl[c][r][nPrec][1] = new TagTreeDecoder(0,0); 559 ttMaxBP[c][r][nPrec][1] = new TagTreeDecoder(0,0); 560 } else { 561 ttIncl[c][r][nPrec][1] = 562 new TagTreeDecoder(kend-kstart+1,lend-lstart+1); 563 ttMaxBP[c][r][nPrec][1] = 564 new TagTreeDecoder(kend-kstart+1,lend-lstart+1); 565 ppinfo[c][r][nPrec].cblk[1] = 566 new CBlkCoordInfo[kend-kstart+1][lend-lstart+1]; 567 ppinfo[c][r][nPrec]. 568 nblk[1] = (kend-kstart+1)*(lend-lstart+1); 569 570 for(int k=kstart; k<=kend; k++) { // Vertical cblks 571 for(int l=lstart; l<=lend; l++) { // Horiz. cblks 572 cb = new CBlkCoordInfo(k-k0,l-l0); 573 if(l==l0) { 574 cb.ulx = sb.ulx; 575 } else { 576 cb.ulx = sb.ulx+l*cw-(sb.ulcx-acb0x); 577 } 578 if(k==k0) { 579 cb.uly = sb.uly; 580 } else { 581 cb.uly = sb.uly+k*ch-(sb.ulcy-acb0y); 582 } 583 tmp1 = acb0x+l*cw; 584 tmp1 = (tmp1>sb.ulcx) ? tmp1 : sb.ulcx; 585 tmp2 = acb0x+(l+1)*cw; 586 tmp2 = (tmp2>sb.ulcx+sb.w) ? 587 sb.ulcx+sb.w : tmp2; 588 cb.w = tmp2-tmp1; 589 tmp1 = acb0y+k*ch; 590 tmp1 = (tmp1>sb.ulcy) ? tmp1 : sb.ulcy; 591 tmp2 = acb0y+(k+1)*ch; 592 tmp2 = (tmp2>sb.ulcy+sb.h) ? 593 sb.ulcy+sb.h : tmp2; 594 cb.h = tmp2-tmp1; 595 ppinfo[c][r][nPrec]. 596 cblk[1][k-kstart][l-lstart] = cb; 597 } // Horizontal code-blocks 598 } // Vertical code-blocks 599 } 600 601 // LH subband 602 acb0x = cb0x; 603 acb0y = 0; 604 605 p0x = acb0x+j*twoppx2; 606 p1x = p0x + twoppx2; 607 p0y = acb0y+i*twoppy2; 608 p1y = p0y + twoppy2; 609 610 sb = (SubbandSyn)root.getSubbandByIdx(r,2); 611 s0x = (p0x<sb.ulcx) ? sb.ulcx : p0x; 612 s1x = (p1x>sb.ulcx+sb.w) ? sb.ulcx+sb.w : p1x; 613 s0y = (p0y<sb.ulcy) ? sb.ulcy : p0y; 614 s1y = (p1y>sb.ulcy+sb.h) ? sb.ulcy+sb.h : p1y; 615 616 // Code-blocks are located at (acb0x+k*cw,acb0y+l*ch) 617 cw = sb.nomCBlkW; 618 ch = sb.nomCBlkH; 619 k0 = (int)Math.floor((sb.ulcy-acb0y)/(double)ch); 620 kstart = (int)Math.floor((s0y-acb0y)/(double)ch); 621 kend = (int)Math.floor((s1y-1-acb0y)/(double)ch); 622 l0 = (int)Math.floor((sb.ulcx-acb0x)/(double)cw); 623 lstart = (int)Math.floor((s0x-acb0x)/(double)cw); 624 lend = (int)Math.floor((s1x-1-acb0x)/(double)cw); 625 626 if(s1x-s0x<=0 || s1y-s0y<=0) { 627 ppinfo[c][r][nPrec].nblk[2] = 0; 628 ttIncl[c][r][nPrec][2] = new TagTreeDecoder(0,0); 629 ttMaxBP[c][r][nPrec][2] = new TagTreeDecoder(0,0); 630 } else { 631 ttIncl[c][r][nPrec][2] = 632 new TagTreeDecoder(kend-kstart+1,lend-lstart+1); 633 ttMaxBP[c][r][nPrec][2] = 634 new TagTreeDecoder(kend-kstart+1,lend-lstart+1); 635 ppinfo[c][r][nPrec].cblk[2] = 636 new CBlkCoordInfo[kend-kstart+1][lend-lstart+1]; 637 ppinfo[c][r][nPrec]. 638 nblk[2] = (kend-kstart+1)*(lend-lstart+1); 639 640 for(int k=kstart; k<=kend; k++) { // Vertical cblks 641 for(int l=lstart; l<=lend; l++) { // Horiz cblks 642 cb = new CBlkCoordInfo(k-k0,l-l0); 643 if(l==l0) { 644 cb.ulx = sb.ulx; 645 } else { 646 cb.ulx = sb.ulx+l*cw-(sb.ulcx-acb0x); 647 } 648 if(k==k0) { 649 cb.uly = sb.uly; 650 } else { 651 cb.uly = sb.uly+k*ch-(sb.ulcy-acb0y); 652 } 653 tmp1 = acb0x+l*cw; 654 tmp1 = (tmp1>sb.ulcx) ? tmp1 : sb.ulcx; 655 tmp2 = acb0x+(l+1)*cw; 656 tmp2 = (tmp2>sb.ulcx+sb.w) ? 657 sb.ulcx+sb.w : tmp2; 658 cb.w = tmp2-tmp1; 659 tmp1 = acb0y+k*ch; 660 tmp1 = (tmp1>sb.ulcy) ? tmp1 : sb.ulcy; 661 tmp2 = acb0y+(k+1)*ch; 662 tmp2 = (tmp2>sb.ulcy+sb.h) ? 663 sb.ulcy+sb.h : tmp2; 664 cb.h = tmp2-tmp1; 665 ppinfo[c][r][nPrec]. 666 cblk[2][k-kstart][l-lstart] = cb; 667 } // Horizontal code-blocks 668 } // Vertical code-blocks 669 } 670 671 // HH subband 672 acb0x = 0; 673 acb0y = 0; 674 675 p0x = acb0x+j*twoppx2; 676 p1x = p0x + twoppx2; 677 p0y = acb0y+i*twoppy2; 678 p1y = p0y + twoppy2; 679 680 sb = (SubbandSyn)root.getSubbandByIdx(r,3); 681 s0x = (p0x<sb.ulcx) ? sb.ulcx : p0x; 682 s1x = (p1x>sb.ulcx+sb.w) ? sb.ulcx+sb.w : p1x; 683 s0y = (p0y<sb.ulcy) ? sb.ulcy : p0y; 684 s1y = (p1y>sb.ulcy+sb.h) ? sb.ulcy+sb.h : p1y; 685 686 // Code-blocks are located at (acb0x+k*cw,acb0y+l*ch) 687 cw = sb.nomCBlkW; 688 ch = sb.nomCBlkH; 689 k0 = (int)Math.floor((sb.ulcy-acb0y)/(double)ch); 690 kstart = (int)Math.floor((s0y-acb0y)/(double)ch); 691 kend = (int)Math.floor((s1y-1-acb0y)/(double)ch); 692 l0 = (int)Math.floor((sb.ulcx-acb0x)/(double)cw); 693 lstart = (int)Math.floor((s0x-acb0x)/(double)cw); 694 lend = (int)Math.floor((s1x-1-acb0x)/(double)cw); 695 696 if(s1x-s0x<=0 || s1y-s0y<=0) { 697 ppinfo[c][r][nPrec].nblk[3] = 0; 698 ttIncl[c][r][nPrec][3] = new TagTreeDecoder(0,0); 699 ttMaxBP[c][r][nPrec][3] = new TagTreeDecoder(0,0); 700 } else { 701 ttIncl[c][r][nPrec][3] = 702 new TagTreeDecoder(kend-kstart+1,lend-lstart+1); 703 ttMaxBP[c][r][nPrec][3] = 704 new TagTreeDecoder(kend-kstart+1,lend-lstart+1); 705 ppinfo[c][r][nPrec].cblk[3] = 706 new CBlkCoordInfo[kend-kstart+1][lend-lstart+1]; 707 ppinfo[c][r][nPrec]. 708 nblk[3] = (kend-kstart+1)*(lend-lstart+1); 709 710 for(int k=kstart; k<=kend; k++) { // Vertical cblks 711 for(int l=lstart; l<=lend; l++) { // Horiz cblks 712 cb = new CBlkCoordInfo(k-k0,l-l0); 713 if(l==l0) { 714 cb.ulx = sb.ulx; 715 } else { 716 cb.ulx = sb.ulx+l*cw-(sb.ulcx-acb0x); 717 } 718 if(k==k0) { 719 cb.uly = sb.uly; 720 } else { 721 cb.uly = sb.uly+k*ch-(sb.ulcy-acb0y); 722 } 723 tmp1 = acb0x+l*cw; 724 tmp1 = (tmp1>sb.ulcx) ? tmp1 : sb.ulcx; 725 tmp2 = acb0x+(l+1)*cw; 726 tmp2 = (tmp2>sb.ulcx+sb.w) ? 727 sb.ulcx+sb.w : tmp2; 728 cb.w = tmp2-tmp1; 729 tmp1 = acb0y+k*ch; 730 tmp1 = (tmp1>sb.ulcy) ? tmp1 : sb.ulcy; 731 tmp2 = acb0y+(k+1)*ch; 732 tmp2 = (tmp2>sb.ulcy+sb.h) ? 733 sb.ulcy+sb.h : tmp2; 734 cb.h = tmp2-tmp1; 735 ppinfo[c][r][nPrec]. 736 cblk[3][k-kstart][l-lstart] = cb; 737 } // Horizontal code-blocks 738 } // Vertical code-blocks 739 } 740 741 } 742 } // Horizontal precincts 743 } // Vertical precincts 744 } 745 746 /** 747 * Gets the number of precincts in a given component and resolution level. 748 * 749 * @param c Component index 750 * 751 * @param r Resolution index 752 * */ 753 public int getNumPrecinct(int c,int r) { 754 return numPrec[c][r].x*numPrec[c][r].y; 755 } 756 757 /** 758 * Read specified packet head and found length of each code-block's piece 759 * of codewords as well as number of skipped most significant bit-planes. 760 * 761 * @param l layer index 762 * 763 * @param r Resolution level index 764 * 765 * @param c Component index 766 * 767 * @param p Precinct index 768 * 769 * @param cbI CBlkInfo array of relevant component and resolution 770 * level. 771 * 772 * @param nb The number of bytes to read in each tile before reaching 773 * output rate (used by truncation mode) 774 * 775 * @return True if specified output rate or EOF is reached. 776 * */ 777 public boolean readPktHead(int l,int r,int c,int p,CBlkInfo[][][] cbI, 778 int[] nb) throws IOException { 779 780 CBlkInfo ccb; 781 int nSeg; // number of segment to read 782 int cbLen; // Length of cblk's code-words 783 int ltp; // last truncation point index 784 int passtype; // coding pass type 785 TagTreeDecoder tdIncl,tdBD; 786 int tmp,tmp2,totnewtp,lblockCur,tpidx; 787 int sumtotnewtp = 0; 788 Point cbc; 789 int startPktHead = ehs.getPos(); 790 if(startPktHead>=ehs.length()) { 791 // EOF reached at the beginning of this packet head 792 return true; 793 } 794 int tIdx = src.getTileIdx(); 795 PktHeaderBitReader bin; 796 int mend,nend; 797 int b; 798 SubbandSyn sb; 799 SubbandSyn root = src.getSynSubbandTree(tIdx,c); 800 801 // If packed packet headers was used, use separate stream for reading 802 // of packet headers 803 if(pph) { 804 bin = new PktHeaderBitReader(pphbais); 805 } else { 806 bin = this.bin; 807 } 808 809 int mins = (r==0) ? 0 : 1; 810 int maxs = (r==0) ? 1 : 4; 811 812 boolean precFound = false; 813 for(int s=mins; s<maxs; s++) { 814 if(p<ppinfo[c][r].length) { 815 precFound = true; 816 } 817 } 818 if(!precFound) { 819 return false; 820 } 821 822 PrecInfo prec = ppinfo[c][r][p]; 823 824 // Synchronize for bit reading 825 bin.sync(); 826 827 // If packet is empty there is no info in it (i.e. no code-blocks) 828 if(bin.readBit()==0) { 829 // No code-block is included 830 cblks = new Vector[maxs+1]; 831 for(int s=mins; s<maxs; s++){ 832 cblks[s] = new Vector(); 833 } 834 pktIdx++; 835 836 // If truncation mode, checks if output rate is reached 837 // unless ncb quit condition is used in which case headers 838 // are not counted 839 if(isTruncMode && maxCB == -1) { 840 tmp = ehs.getPos()-startPktHead; 841 if(tmp>nb[tIdx]) { 842 nb[tIdx] = 0; 843 return true; 844 } else { 845 nb[tIdx] -= tmp; 846 } 847 } 848 849 // Read EPH marker if needed 850 if(ephUsed) { 851 readEPHMarker(bin); 852 } 853 return false; 854 } 855 856 // Packet is not empty => decode info 857 // Loop on each subband in this resolution level 858 if(cblks==null || cblks.length<maxs+1) { 859 cblks = new Vector[maxs+1]; 860 } 861 862 for(int s=mins; s<maxs; s++) { 863 if(cblks[s]==null) { 864 cblks[s] = new Vector(); 865 } else { 866 cblks[s].removeAllElements(); 867 } 868 sb = (SubbandSyn)root.getSubbandByIdx(r,s); 869 // No code-block in this precinct 870 if(prec.nblk[s]==0) { 871 // Go to next subband 872 continue; 873 } 874 875 tdIncl = ttIncl[c][r][p][s]; 876 tdBD = ttMaxBP[c][r][p][s]; 877 878 mend = (prec.cblk[s]==null) ? 0 : prec.cblk[s].length; 879 for(int m=0; m<mend; m++) { // Vertical code-blocks 880 nend = (prec.cblk[s][m]==null) ? 0 : prec.cblk[s][m].length; 881 for (int n=0; n<nend; n++) { // Horizontal code-blocks 882 cbc = prec.cblk[s][m][n].idx; 883 b = cbc.x+cbc.y*sb.numCb.x; 884 885 ccb = cbI[s][cbc.y][cbc.x]; 886 887 try { 888 // If code-block not included in previous layer(s) 889 if(ccb==null || ccb.ctp==0) { 890 if(ccb==null) { 891 ccb = cbI[s][cbc.y][cbc.x] = 892 new CBlkInfo(prec.cblk[s][m][n].ulx, 893 prec.cblk[s][m][n].uly, 894 prec.cblk[s][m][n].w, 895 prec.cblk[s][m][n].h,nl); 896 } 897 ccb.pktIdx[l] = pktIdx; 898 899 // Read inclusion using tag-tree 900 tmp = tdIncl.update(m,n,l+1,bin); 901 if(tmp>l) { // Not included 902 continue; 903 } 904 905 // Read bitdepth using tag-tree 906 tmp = 1;// initialization 907 for(tmp2=1; tmp>=tmp2; tmp2++) { 908 tmp = tdBD.update(m,n,tmp2,bin); 909 } 910 ccb.msbSkipped = tmp2-2; 911 912 // New code-block => at least one truncation point 913 totnewtp = 1; 914 ccb.addNTP(l,0); 915 916 // Check whether ncb quit condition is reached 917 ncb++; 918 if(maxCB != -1 && !ncbQuit && ncb == maxCB){ 919 // ncb quit contidion reached 920 ncbQuit = true; 921 tQuit = tIdx; 922 cQuit = c; 923 sQuit = s; 924 rQuit = r; 925 xQuit = cbc.x; 926 yQuit = cbc.y; 927 } 928 929 } else { // If code-block already included in one of 930 // the previous layers. 931 932 ccb.pktIdx[l] = pktIdx; 933 934 // If not inclused 935 if(bin.readBit()!=1) { 936 continue; 937 } 938 939 // At least 1 more truncation point than 940 // prev. packet 941 totnewtp = 1; 942 } 943 944 // Read new truncation points 945 if(bin.readBit()==1) {// if bit is 1 946 totnewtp++; 947 948 // if next bit is 0 do nothing 949 if(bin.readBit()==1) {//if is 1 950 totnewtp++; 951 952 tmp = bin.readBits(2); 953 totnewtp += tmp; 954 // If next 2 bits are not 11 do nothing 955 if(tmp==0x3) { //if 11 956 tmp = bin.readBits(5); 957 totnewtp += tmp; 958 959 // If next 5 bits are not 11111 do nothing 960 if(tmp==0x1F) { //if 11111 961 totnewtp += bin.readBits(7); 962 } 963 } 964 } 965 } 966 ccb.addNTP(l,totnewtp); 967 sumtotnewtp += totnewtp; 968 cblks[s].addElement(prec.cblk[s][m][n]); 969 970 // Code-block length 971 972 // -- Compute the number of bit to read to obtain 973 // code-block length. 974 // numBits = betaLamda + log2(totnewtp); 975 976 // The length is signalled for each segment in 977 // addition to the final one. The total length is the 978 // sum of all segment lengths. 979 980 // If regular termination in use, then there is one 981 // segment per truncation point present. Otherwise, if 982 // selective arithmetic bypass coding mode is present, 983 // then there is one termination per bypass/MQ and 984 // MQ/bypass transition. Otherwise the only 985 // termination is at the end of the code-block. 986 int options = 987 ((Integer)decSpec.ecopts.getTileCompVal(tIdx,c)). 988 intValue(); 989 990 if( (options&OPT_TERM_PASS) != 0) { 991 // Regular termination in use, one segment per new 992 // pass (i.e. truncation point) 993 nSeg = totnewtp; 994 } else if( (options&OPT_BYPASS) != 0) { 995 // Selective arithmetic coding bypass coding mode 996 // in use, but no regular termination 1 segment up 997 // to the end of the last pass of the 4th most 998 // significant bit-plane, and, in each following 999 // bit-plane, one segment upto the end of the 2nd 1000 // pass and one upto the end of the 3rd pass. 1001 1002 if(ccb.ctp<=FIRST_BYPASS_PASS_IDX) { 1003 nSeg = 1; 1004 } else { 1005 nSeg = 1; // One at least for last pass 1006 // And one for each other terminated pass 1007 for(tpidx = ccb.ctp-totnewtp; 1008 tpidx < ccb.ctp-1; tpidx++) { 1009 if(tpidx >= FIRST_BYPASS_PASS_IDX-1) { 1010 passtype = 1011 (tpidx+NUM_EMPTY_PASSES_IN_MS_BP)% 1012 NUM_PASSES; 1013 if (passtype==1 || passtype==2) { 1014 // bypass coding just before MQ 1015 // pass or MQ pass just before 1016 // bypass coding => terminated 1017 nSeg++; 1018 } 1019 } 1020 } 1021 } 1022 } else { 1023 // Nothing special in use, just one segment 1024 nSeg = 1; 1025 } 1026 1027 // Reads lblock increment (common to all segments) 1028 while(bin.readBit()!=0) { 1029 lblock[c][r][s][cbc.y][cbc.x]++; 1030 } 1031 1032 if(nSeg==1) { // Only one segment in packet 1033 cbLen = bin.readBits(lblock[c][r][s][cbc.y][cbc.x]+ 1034 MathUtil.log2(totnewtp)); 1035 } else { 1036 // We must read one length per segment 1037 ccb.segLen[l] = new int[nSeg]; 1038 cbLen = 0; 1039 int j; 1040 if((options&OPT_TERM_PASS) != 0) { 1041 // Regular termination: each pass is terminated 1042 for(tpidx=ccb.ctp-totnewtp,j=0; 1043 tpidx<ccb.ctp;tpidx++,j++) { 1044 1045 lblockCur = lblock[c][r][s][cbc.y][cbc.x]; 1046 1047 tmp = bin.readBits(lblockCur); 1048 ccb.segLen[l][j] = tmp; 1049 cbLen += tmp; 1050 } 1051 } else { 1052 // Bypass coding: only some passes are 1053 // terminated 1054 ltp = ccb.ctp-totnewtp-1; 1055 for(tpidx = ccb.ctp-totnewtp, j=0; 1056 tpidx<ccb.ctp-1;tpidx++) { 1057 if(tpidx >= FIRST_BYPASS_PASS_IDX-1) { 1058 passtype = 1059 (tpidx+NUM_EMPTY_PASSES_IN_MS_BP)% 1060 NUM_PASSES; 1061 if (passtype==0) continue; 1062 1063 lblockCur = 1064 lblock[c][r][s][cbc.y][cbc.x]; 1065 tmp = 1066 bin. 1067 readBits(lblockCur+ 1068 MathUtil.log2(tpidx-ltp)); 1069 ccb.segLen[l][j] = tmp; 1070 cbLen += tmp; 1071 ltp = tpidx; 1072 j++; 1073 } 1074 } 1075 // Last pass has always the length sent 1076 lblockCur = lblock[c][r][s][cbc.y][cbc.x]; 1077 tmp = bin.readBits(lblockCur+ 1078 MathUtil.log2(tpidx-ltp)); 1079 cbLen += tmp; 1080 ccb.segLen[l][j] = tmp; 1081 } 1082 } 1083 ccb.len[l] = cbLen; 1084 1085 // If truncation mode, checks if output rate is reached 1086 // unless ncb and lbody quit contitions used. 1087 if(isTruncMode && maxCB==-1) { 1088 tmp = ehs.getPos()-startPktHead; 1089 if(tmp>nb[tIdx]) { 1090 nb[tIdx] = 0; 1091 // Remove found information in this code-block 1092 if(l==0) { 1093 cbI[s][cbc.y][cbc.x] = null; 1094 } else { 1095 ccb.off[l]=ccb.len[l]=0; 1096 ccb.ctp -= ccb.ntp[l]; 1097 ccb.ntp[l] = 0; 1098 ccb.pktIdx[l] = -1; 1099 } 1100 return true; 1101 } 1102 } 1103 1104 } catch(EOFException e) { 1105 // Remove found information in this code-block 1106 if(l==0) { 1107 cbI[s][cbc.y][cbc.x] = null; 1108 } else { 1109 ccb.off[l]=ccb.len[l]=0; 1110 ccb.ctp -= ccb.ntp[l]; 1111 ccb.ntp[l] = 0; 1112 ccb.pktIdx[l] = -1; 1113 } 1114// throw new EOFException(); 1115 return true; 1116 } 1117 } // End loop on horizontal code-blocks 1118 } // End loop on vertical code-blocks 1119 } // End loop on subbands 1120 1121 // Read EPH marker if needed 1122 if(ephUsed) { 1123 readEPHMarker(bin); 1124 } 1125 1126 pktIdx++; 1127 1128 // If truncation mode, checks if output rate is reached 1129 if(isTruncMode && maxCB == -1) { 1130 tmp = ehs.getPos()-startPktHead; 1131 if(tmp>nb[tIdx]) { 1132 nb[tIdx] = 0; 1133 return true; 1134 } else { 1135 nb[tIdx] -= tmp; 1136 } 1137 } 1138 return false; 1139 } 1140 1141 /** 1142 * Reads specificied packet body in order to find offset of each 1143 * code-block's piece of codeword. This use the list of found code-blocks 1144 * in previous red packet head. 1145 * 1146 * @param l layer index 1147 * 1148 * @param r Resolution level index 1149 * 1150 * @param c Component index 1151 * 1152 * @param p Precinct index 1153 * 1154 * @param cbI CBlkInfo array of relevant component and resolution 1155 * level. 1156 * 1157 * @param nb The remainding number of bytes to read from the bit stream in 1158 * each tile before reaching the decoding rate (in truncation mode) 1159 * 1160 * @return True if decoding rate is reached 1161 * */ 1162 public boolean readPktBody(int l,int r,int c,int p,CBlkInfo[][][] cbI, 1163 int[] nb) throws IOException { 1164 int curOff = ehs.getPos(); 1165 Point curCB; 1166 CBlkInfo ccb; 1167 boolean stopRead = false; 1168 int tIdx = src.getTileIdx(); 1169 Point cbc; 1170 1171 boolean precFound = false; 1172 int mins = (r==0) ? 0 : 1; 1173 int maxs = (r==0) ? 1 : 4; 1174 for(int s=mins; s<maxs; s++) { 1175 if(p<ppinfo[c][r].length) { 1176 precFound = true; 1177 } 1178 } 1179 if(!precFound) { 1180 return false; 1181 } 1182 1183 for(int s=mins; s<maxs; s++) { 1184 for(int numCB=0; numCB<cblks[s].size(); numCB++) { 1185 cbc = ((CBlkCoordInfo)cblks[s].elementAt(numCB)).idx; 1186 ccb = cbI[s][cbc.y][cbc.x]; 1187 ccb.off[l] = curOff; 1188 curOff += ccb.len[l]; 1189 try { 1190 ehs.seek(curOff); 1191 } catch(EOFException e) { 1192 if(l==0) { 1193 cbI[s][cbc.y][cbc.x] = null; 1194 } else { 1195 ccb.off[l] = ccb.len[l]=0; 1196 ccb.ctp -= ccb.ntp[l]; 1197 ccb.ntp[l] = 0; 1198 ccb.pktIdx[l] = -1; 1199 } 1200 throw new EOFException(); 1201 } 1202 1203 // If truncation mode 1204 if(isTruncMode) { 1205 if(stopRead || ccb.len[l]>nb[tIdx]) { 1206 // Remove found information in this code-block 1207 if(l==0) { 1208 cbI[s][cbc.y][cbc.x] = null; 1209 } else { 1210 ccb.off[l] = ccb.len[l] = 0; 1211 ccb.ctp -= ccb.ntp[l]; 1212 ccb.ntp[l] = 0; 1213 ccb.pktIdx[l] = -1; 1214 } 1215 stopRead = true; 1216 } 1217 if(!stopRead) { 1218 nb[tIdx] -= ccb.len[l]; 1219 } 1220 } 1221 // If ncb quit condition reached 1222 if(ncbQuit && r == rQuit && s == sQuit && cbc.x == xQuit && 1223 cbc.y == yQuit && tIdx == tQuit && c == cQuit) { 1224 cbI[s][cbc.y][cbc.x] = null; 1225 stopRead = true; 1226 } 1227 } // Loop on code-blocks 1228 } // End loop on subbands 1229 1230 // Seek to the end of the packet 1231 ehs.seek(curOff); 1232 1233 if(stopRead) { 1234 return true; 1235 } else { 1236 return false; 1237 } 1238 } 1239 1240 /** 1241 * Returns the precinct partition width for the specified component, 1242 * resolution level and tile. 1243 * 1244 * @param t the tile index 1245 * 1246 * @param c The index of the component (between 0 and C-1) 1247 * 1248 * @param r The resolution level, from 0 to L. 1249 * 1250 * @return the precinct partition width for the specified component, 1251 * resolution level and tile. 1252 * */ 1253 public final int getPPX(int t,int c,int r){ 1254 return decSpec.pss.getPPX(t,c,r); 1255 } 1256 1257 /** 1258 * Returns the precinct partition height for the specified component, 1259 * resolution level and tile. 1260 * 1261 * @param t the tile index 1262 * 1263 * @param c The index of the component (between 0 and C-1) 1264 * 1265 * @param rl The resolution level, from 0 to L. 1266 * 1267 * @return the precinct partition height in the specified component, for 1268 * the specified resolution level, for the current tile. 1269 * */ 1270 public final int getPPY(int t,int c,int rl) { 1271 return decSpec.pss.getPPY(t,c,rl); 1272 } 1273 1274 /** 1275 * Try to read a SOP marker and check that its sequence number if not out 1276 * of sequence. If so, an error is thrown. 1277 * 1278 * @param nBytes The number of bytes left to read from each tile 1279 * 1280 * @param p Precinct index 1281 * 1282 * @param r Resolution level index 1283 * 1284 * @param c Component index 1285 * */ 1286 public boolean readSOPMarker(int[] nBytes,int p,int c,int r) 1287 throws IOException { 1288 int val; 1289 byte sopArray[] = new byte[6]; 1290 int tIdx = src.getTileIdx(); 1291 int mins = (r==0) ? 0 : 1; 1292 int maxs = (r==0) ? 1 : 4; 1293 boolean precFound = false; 1294 for(int s=mins; s<maxs; s++) { 1295 if(p<ppinfo[c][r].length) { 1296 precFound = true; 1297 } 1298 } 1299 if(!precFound) { 1300 return false; 1301 } 1302 1303 // If SOP markers are not used, return 1304 if(!sopUsed) { 1305 return false; 1306 } 1307 1308 // Check if SOP is used for this packet 1309 int pos = ehs.getPos(); 1310 if( (short)((ehs.read()<<8) | ehs.read()) != Markers.SOP ) { 1311 ehs.seek(pos); 1312 return false; 1313 } 1314 ehs.seek(pos); 1315 1316 // If length of SOP marker greater than remaining bytes to read for 1317 // this tile return true 1318 if(nBytes[tIdx]<6) { 1319 return true; 1320 } 1321 nBytes[tIdx] -= 6; 1322 1323 // Read marker into array 'sopArray' 1324 ehs.readFully(sopArray,0,Markers.SOP_LENGTH); 1325 1326 // Check if this is the correct marker 1327 val = sopArray[0]; 1328 val <<= 8; 1329 val |= sopArray[1]; 1330 if(val!=Markers.SOP) { 1331 throw new Error("Corrupted Bitstream: Could not parse SOP "+ 1332 "marker !"); 1333 } 1334 1335 // Check if length is correct 1336 val = (sopArray[2]&0xff); 1337 val <<= 8; 1338 val |= (sopArray[3]&0xff); 1339 if(val!=4) { 1340 throw new Error("Corrupted Bitstream: Corrupted SOP marker !"); 1341 } 1342 1343 // Check if sequence number if ok 1344 val = (sopArray[4]&0xff); 1345 val <<= 8; 1346 val |= (sopArray[5]&0xff); 1347 1348 if(!pph && val!=pktIdx) { 1349 throw new Error("Corrupted Bitstream: SOP marker out of " 1350 +"sequence !"); 1351 } 1352 if(pph && val!=pktIdx-1) { 1353 // if packed packet headers are used, packet header was read 1354 // before SOP marker segment 1355 throw new Error("Corrupted Bitstream: SOP marker out of " 1356 +"sequence !"); 1357 } 1358 return false; 1359 } 1360 1361 /** 1362 * Try to read an EPH marker. If it is not possible then an Error is 1363 * thrown. 1364 * 1365 * @param bin The packet header reader to read the EPH marker from 1366 * */ 1367 public void readEPHMarker(PktHeaderBitReader bin) throws IOException { 1368 int val; 1369 byte ephArray[] = new byte[2]; 1370 1371 if(bin.usebais) { 1372 bin.bais.read(ephArray,0,Markers.EPH_LENGTH); 1373 } else { 1374 bin.in.readFully(ephArray,0,Markers.EPH_LENGTH); 1375 } 1376 1377 // Check if this is the correct marker 1378 val = ephArray[0]; 1379 val <<= 8; 1380 val |= ephArray[1]; 1381 if (val!=Markers.EPH) { 1382 throw new Error("Corrupted Bitstream: Could not parse EPH " 1383 +"marker ! "); 1384 } 1385 } 1386 1387 /** 1388 * Get PrecInfo instance of the specified resolution level, component and 1389 * precinct. 1390 * 1391 * @param c Component index. 1392 * 1393 * @param r Resolution level index. 1394 * 1395 * @param p Precinct index. 1396 * */ 1397 public PrecInfo getPrecInfo(int c,int r,int p) { 1398 return ppinfo[c][r][p]; 1399 } 1400 1401}