📄 pktdecoder.java
字号:
intArraySet(lblock[c][r][s][i], INIT_LBLOCK); } } // Collect code-blocks and precinct coordinates buildCBlkPrecCoord(c,r); } // End loop on resolution levels } // End loop on components return cbI; } /** * Get the number of precinct in given component and resolution. * * @param c Component index * * @param r Resolution index * */ public int getNumPrecinct(int c,int r){ return maxNumPrecincts[c][r].x*maxNumPrecincts[c][r].y; } /** * Read specified packet head and found length of each code-block's piece * of codewords as well as number of skipped most significant bit-planes. * * @param l layer index * * @param r Resolution level index * * @param c Component index * * @param p Precinct index * * @param cbI CBlkInfo array of relevant component and resolution * level. * * @param nb The number of bytes to read in each tile before reaching * output rate (used by truncation mode) * * @return True if output rate is reached * */ public boolean readPktHead(int l,int r,int c,int p,CBlkInfo[][][] cbI, int[] nb) throws IOException{ CBlkInfo ccb; Coord curCB,firstCB; int nSeg; // number of segment to read int cbLen; // Length of cblk's code-words int ltp; // last truncation point index int passtype; // coding pass type TagTreeDecoder tdIncl,tdBD; int tmp,tmp2,totnewtp,lblockCur,tpidx; int sumtotnewtp = 0; CBlkCoordInfo ccbCoord; int startPktHead = ehs.getPos(); int tIdx = src.getTileIdx(); PktHeaderBitReader bin; // If packed packet headers was used, use separate stream for reading // of packet headers if(pph){ bin = new PktHeaderBitReader(pphbais); } else{ bin = this.bin; } boolean precFound = false; for(int s=subRange[c][r][0];s<=subRange[c][r][1];s++){ if(p<precCoord[c][r][s].length){ precFound = true; } } if(!precFound) { return false; } // Synchronize for bit reading bin.sync(); // If packet is empty there is no info in it (i.e. no code-blocks) int firstBit = bin.readBit(); if(firstBit == 0){ // No code-block is included cblks = new Vector[subRange[c][r][1]+1]; for(int s=subRange[c][r][0];s<=subRange[c][r][1];s++){ cblks[s] = new Vector(); } pktIdx++; // If truncation mode, checks if output rate is reached if(isTruncMode){ tmp = ehs.getPos()-startPktHead; if(tmp>nb[tIdx]){ nb[tIdx] = 0; return true; } else nb[tIdx] -= tmp; } // Read EPH marker if needed if(ephUsed) { readEPHMarker(bin); } return false; } // Packet is not empty => decode info // Loop on each subband in this resolution level cblks = new Vector[subRange[c][r][1]+1]; for(int s=subRange[c][r][0];s<=subRange[c][r][1];s++){ cblks[s] = getCBlkInPrecinct(c,r,s,p); // No code-block in this precinct if(cblks[s].size()==1){ // Go to next subband cblks[s].removeAllElements(); continue; } curCB = (Coord)cblks[s].elementAt(0); tdIncl = tdInclA[c][r][s][p]; tdBD = tdBDA[c][r][s][p]; if(tdIncl==null){ tdIncl = tdInclA[c][r][s][p] = new TagTreeDecoder(curCB.y,curCB.x); } if(tdBD==null){ tdBD = tdBDA[c][r][s][p] = new TagTreeDecoder(curCB.y,curCB.x); } firstCB = (Coord)cblks[s].elementAt(1); for(int numCB=1; numCB<cblks[s].size();){ curCB = (Coord)cblks[s].elementAt(numCB); ccb = cbI[s][curCB.x][curCB.y]; try{ // If code-block not included in previous layer(s) if(ccb==null || ccb.ctp==0){ if(ccb==null){ ccbCoord = cbCoord[c][r][s][curCB.x][curCB.y]; ccb = cbI[s][curCB.x][curCB.y] = new CBlkInfo(ccbCoord.ulx,ccbCoord.uly, ccbCoord.w,ccbCoord.h,nl); } ccb.pktIdx[l] = pktIdx; // Read inclusion using tag-tree tmp = tdIncl.update(curCB.x-firstCB.x, curCB.y-firstCB.y,l+1,bin); if(tmp>l){ // Not included cblks[s].removeElementAt(numCB); continue; } // Read bitdepth using tag-tree tmp = 1;// initialization for(tmp2=1; tmp>=tmp2; tmp2++){ tmp = tdBD.update(curCB.x-firstCB.x, curCB.y-firstCB.y,tmp2,bin); } ccb.msbSkipped = tmp2-2; // New code-block => at least one truncation point totnewtp = 1; ccb.addNTP(l,0); } else{// If code-block already included in one of // the previous layers. ccb.pktIdx[l] = pktIdx; // If not inclused if(bin.readBit()!=1){ cblks[s].removeElementAt(numCB); continue; } // At least 1 more truncation point than prev. packet totnewtp = 1; } // Read new truncation points if(bin.readBit()==1){// if bit is 1 totnewtp++; // if next bit is 0 do nothing if(bin.readBit()==1){//if is 1 totnewtp++; tmp = bin.readBits(2); totnewtp += tmp; // If next 2 bits are not 11 do nothing if(tmp==0x3){ //if 11 tmp = bin.readBits(5); totnewtp += tmp; // If next 5 bits are not 11111 do nothing if(tmp==0x1F){//if 11111 totnewtp += bin.readBits(7); } } } } ccb.addNTP(l,totnewtp); sumtotnewtp += totnewtp; // Code-block length // -- Compute the number of bit to read to obtain // code-block length. // numBits = betaLamda + log2(totnewtp); // The length is signalled for each segment in addition to // the final one. The total length is the sum of all // segment lengths. // If regular termination in use, then there is one // segment per truncation point present. Otherwise, if // selective arithmetic bypass coding mode is present, // then there is one termination per bypass/MQ // and MQ/bypass transition. Otherwise the only termination // is at the end of the code-block. int options = ((Integer)decSpec.ecopts.getTileCompVal(tIdx,c)). intValue(); if( (options & OPT_REG_TERM) != 0) { // Regular termination in use, one segment per new // pass (i.e. truncation point) nSeg = totnewtp; } else if( (options & OPT_BYPASS) != 0) { // Selective arithmetic coding bypass coding mode in // use, but no regular termination 1 segment up to the // end of the last pass of the 4th most significant // bit-plane, and, in each following bit-plane, one // segment upto the end of the 2nd pass and one upto // the end of the 3rd pass. if(ccb.ctp <= FIRST_BYPASS_PASS_IDX) { nSeg = 1; } else { nSeg = 1; // One at least for last pass // And one for each other terminated pass for(tpidx = ccb.ctp-totnewtp; tpidx < ccb.ctp-1; tpidx++) { if(tpidx >= FIRST_BYPASS_PASS_IDX-1) { passtype = (tpidx+NUM_EMPTY_PASSES_IN_MS_BP)% NUM_PASSES; if (passtype == 1 || passtype == 2) { // bypass coding just before MQ pass // or MQ pass just before bypass // coding => terminated nSeg++; } } } } } else { // Nothing special in use, just one segment nSeg = 1; } // Reads lblock increment (common to all segments) while(bin.readBit()!=0){ lblock[c][r][s][curCB.x][curCB.y]++; } if(nSeg == 1){ // Only one segment in packet cbLen = bin.readBits(lblock[c][r][s] [curCB.x][curCB.y]+ MathUtil.log2(totnewtp)); } else { // We must read one length per segment ccb.segLen[l] = new int[nSeg]; cbLen = 0; int j; if((options & OPT_REG_TERM) != 0){ // Regular termination: each pass is terminated for(tpidx=ccb.ctp-totnewtp, j=0; tpidx<ccb.ctp;tpidx++,j++){ lblockCur = lblock[c][r][s][curCB.x][curCB.y]; tmp = bin.readBits(lblockCur); ccb.segLen[l][j] = tmp; cbLen += tmp; } } else { // Bypass coding: only some passes are terminated ltp = ccb.ctp-totnewtp-1; for(tpidx = ccb.ctp-totnewtp, j=0; tpidx<ccb.ctp-1;tpidx++){ if(tpidx >= FIRST_BYPASS_PASS_IDX-1) { passtype = (tpidx+NUM_EMPTY_PASSES_IN_MS_BP)% NUM_PASSES; if (passtype == 0) continue; lblockCur = lblock[c][r][s][curCB.x][curCB.y]; tmp = bin.readBits(lblockCur+ MathUtil.log2(tpidx-ltp)); ccb.segLen[l][j] = tmp; cbLen += tmp; ltp = tpidx; j++; } } // Last pass has always the length sent lblockCur = lblock[c][r][s][curCB.x][curCB.y]; tmp = bin.readBits(lblockCur+ MathUtil.log2(tpidx-ltp)); cbLen += tmp; ccb.segLen[l][j] = tmp; } } ccb.len[l] = cbLen; // If truncation mode, checks if output rate is reached if(isTruncMode){ tmp = ehs.getPos()-startPktHead; if(tmp>nb[tIdx]){ nb[tIdx] = 0; // Remove found information in this code-block if(l==0) cbI[s][curCB.x][curCB.y] = null; else{ ccb.off[l]=ccb.len[l]=0; ccb.ctp -= ccb.ntp[l]; ccb.ntp[l] = 0; ccb.pktIdx[l] = -1; } return true; } } numCB++; } catch(EOFException e){ // Remove found information in this code-block if(l==0) cbI[s][curCB.x][curCB.y] = null; else{ ccb.off[l]=ccb.len[l]=0; ccb.ctp -= ccb.ntp[l]; ccb.ntp[l] = 0; ccb.pktIdx[l] = -1; } throw new EOFException(); } } // End loop on code-blocks cblks[s].removeElementAt(0); } // End loop on subbands // Read EPH marker if needed if(ephUsed) readEPHMarker(bin); pktIdx++; // If truncation mode, checks if output rate is reached if(isTruncMode){ tmp = ehs.getPos()-startPktHead; if(tmp>nb[tIdx]){ nb[tIdx] = 0; return true; } else nb[tIdx] -= tmp; } return false; } /** * Reads specificied packet body in order to find offset of each * code-block's piece of codeword. This use the list of found code-blocks * in previous red packet head. * * @param l layer index * * @param r Resolution level index * * @param c Component index *
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -