📄 pktencoder.java
字号:
* @param hbuf The header buffer. If null a new BitOutputBuffer is created * and returned. This buffer is reset before anything is written to it. * * @param bbuf The body buffer. If null a new one is created. If not large * enough a new one is created. * * @param pIdx The precinct index. * * @return The buffer containing the packet header. * */ public BitOutputBuffer encodePacket(int ly,int c,int r,int t, CBlkRateDistStats cbs[][], int tIndx[][],BitOutputBuffer hbuf, byte bbuf[],int pIdx) { int b,i,maxi; int ncb; int thmax; int newtp; int cblen; int prednbits,nbits,deltabits; TagTreeEncoder cur_ttIncl,cur_ttMaxBP; // inclusion and bit-depth tag // trees int cur_prevtIdxs[]; // last encoded truncation points CBlkRateDistStats cur_cbs[]; int cur_tIndx[]; // truncation points to encode int minsb = (r==0) ? 0 : 1; int maxsb = (r==0) ? 1 : 4; Coord cbCoord = null; SubbandAn root = infoSrc.getAnSubbandTree(t,c); SubbandAn sb; roiInPkt = false; roiLen = 0; int mend,nend; // Checks if a precinct with such an index exists in this resolution // level if(pIdx>=ppinfo[t][c][r].length) { packetWritable = false; return hbuf; } PrecInfo prec = ppinfo[t][c][r][pIdx]; // First, we check if packet is empty (i.e precinct 'pIdx' has no // code-block in any of the subbands) boolean isPrecVoid = true; for(int s=minsb; s<maxsb; s++) { if(prec.nblk[s]==0) { // The precinct has no code-block in this subband. continue; } else { // The precinct is not empty in at least one subband -> // stop isPrecVoid = false; break; } } /** No code-block in this precinct. Write an empty packet. */ if(isPrecVoid) { packetWritable = true; if(hbuf==null) { hbuf = new BitOutputBuffer(); } else { hbuf.reset(); } if(bbuf==null) { lbbuf = bbuf = new byte[1]; } hbuf.writeBit(0); lblen = 0; return hbuf; } if(hbuf==null) { hbuf = new BitOutputBuffer(); } else { hbuf.reset(); } // Invalidate last body buffer lbbuf = null; lblen = 0; // Signal that packet is present hbuf.writeBit(1); for(int s=minsb; s<maxsb; s++) { // Loop on subbands sb = (SubbandAn)root.getSubbandByIdx(r,s); // Go directly to next subband if the precinct has no code-block // in the current one. if(prec.nblk[s]==0) { continue; } cur_ttIncl = ttIncl[t][c][r][pIdx][s]; cur_ttMaxBP = ttMaxBP[t][c][r][pIdx][s]; cur_prevtIdxs = prevtIdxs[t][c][r][s]; cur_cbs = cbs[s]; cur_tIndx = tIndx[s]; // Set tag tree values for code-blocks in this precinct mend = (prec.cblk[s]==null) ? 0 : prec.cblk[s].length; for(int m=0; m<mend; m++) { nend = (prec.cblk[s][m]==null) ? 0 : prec.cblk[s][m].length; for (int n=0; n<nend; n++) { cbCoord = prec.cblk[s][m][n].idx; b = cbCoord.x+cbCoord.y*sb.numCb.x; if (cur_tIndx[b]>cur_prevtIdxs[b] && cur_prevtIdxs[b]<0) { // First inclusion cur_ttIncl.setValue(m,n,ly-1); } if (ly==1) { // First layer, need to set the skip of MSBP cur_ttMaxBP.setValue(m,n,cur_cbs[b].skipMSBP); } } } // Now encode the information for(int m=0; m<prec.cblk[s].length; m++) { // Vertical code-blocks for(int n=0; n<prec.cblk[s][m].length; n++) { // Horiz. cblks cbCoord = prec.cblk[s][m][n].idx; b = cbCoord.x+cbCoord.y*sb.numCb.x; // 1) Inclusion information if(cur_tIndx[b]>cur_prevtIdxs[b]) { // Keep reference to the last coding-pass index cur_cbs[b].lastContribIdx = cur_tIndx[b]; // Code-block included in this layer if(cur_prevtIdxs[b]<0) { // First inclusion // Encode layer info cur_ttIncl.encode(m,n,ly,hbuf); // 2) Max bitdepth info. Encode value thmax = cur_cbs[b].skipMSBP+1; for(i=1; i<=thmax; i++) { cur_ttMaxBP.encode(m,n,i,hbuf); } // Count body size for packet lblen += cur_cbs[b]. truncRates[cur_cbs[b].truncIdxs[cur_tIndx[b]]]; } else { // Already in previous layer // Send "1" bit hbuf.writeBit(1); // Count body size for packet lblen += cur_cbs[b]. truncRates[cur_cbs[b]. truncIdxs[cur_tIndx[b]]] - cur_cbs[b]. truncRates[cur_cbs[b]. truncIdxs[cur_prevtIdxs[b]]]; } // 3) Truncation point information if(cur_prevtIdxs[b]<0) { newtp = cur_cbs[b].truncIdxs[cur_tIndx[b]]; } else { newtp = cur_cbs[b].truncIdxs[cur_tIndx[b]]- cur_cbs[b].truncIdxs[cur_prevtIdxs[b]]-1; } // Mix of switch and if is faster switch(newtp) { case 0: hbuf.writeBit(0); // Send one "0" bit break; case 1: hbuf.writeBits(2,2); // Send one "1" and one "0" break; case 2: case 3: case 4: // Send two "1" bits followed by 2 bits // representation of newtp-2 hbuf.writeBits((3<<2)|(newtp-2),4); break; default: if (newtp <= 35) { // Send four "1" bits followed by a five bits // representation of newtp-5 hbuf.writeBits((15<<5)|(newtp-5),9); } else if (newtp <= 163) { // Send nine "1" bits followed by a seven bits // representation of newtp-36 hbuf.writeBits((511<<7)|(newtp-36),16); } else { throw new ArithmeticException("Maximum number "+ "of truncation "+ "points exceeded"); } } } else { // Block not included in this layer if(cur_prevtIdxs[b]>=0) { // Already in previous layer. Send "0" bit hbuf.writeBit(0); } else { // Not in any previous layers cur_cbs[b].lastContribIdx = -1; cur_ttIncl.encode(m,n,ly,hbuf); } // Go to the next one. continue; } // Code-block length // We need to compute the maximum number of bits needed to // signal the length of each terminated segment and the // final truncation point. newtp = 1; maxi = cur_cbs[b].truncIdxs[cur_tIndx[b]]; cblen = (cur_prevtIdxs[b]<0) ? 0 : cur_cbs[b].truncRates[cur_cbs[b]. truncIdxs[cur_prevtIdxs[b]]]; // Loop on truncation points i = (cur_prevtIdxs[b]<0) ? 0 : cur_cbs[b].truncIdxs[cur_prevtIdxs[b]]+1; int minbits = 0; for (; i<maxi; i++, newtp++) { // If terminated truncation point calculate length if (cur_cbs[b].isTermPass != null && cur_cbs[b].isTermPass[i]) { // Calculate length cblen = cur_cbs[b].truncRates[i] - cblen; // Calculate number of needed bits prednbits = lblock[t][c][r][s][b] + MathUtil.log2(newtp); minbits = ((cblen>0) ? MathUtil.log2(cblen) : 0)+1; // Update Lblock increment if needed for(int j=prednbits; j<minbits; j++) { lblock[t][c][r][s][b]++; hbuf.writeBit(1); } // Initialize for next length newtp = 0; cblen = cur_cbs[b].truncRates[i]; } } // Last truncation point length always sent // Calculate length cblen = cur_cbs[b].truncRates[i] - cblen; // Calculate number of bits prednbits = lblock[t][c][r][s][b] + MathUtil.log2(newtp); minbits = ((cblen>0) ? MathUtil.log2(cblen) : 0)+1; // Update Lblock increment if needed for(int j=prednbits; j<minbits; j++) { lblock[t][c][r][s][b]++; hbuf.writeBit(1); } // End of comma-code increment hbuf.writeBit(0); // There can be terminated several segments, send length // info for all terminated truncation points in addition // to final one newtp = 1; maxi = cur_cbs[b].truncIdxs[cur_tIndx[b]]; cblen = (cur_prevtIdxs[b]<0) ? 0 : cur_cbs[b].truncRates[cur_cbs[b]. truncIdxs[cur_prevtIdxs[b]]]; // Loop on truncation points and count the groups i = (cur_prevtIdxs[b]<0) ? 0 : cur_cbs[b].truncIdxs[cur_prevtIdxs[b]]+1; for (; i<maxi; i++, newtp++) { // If terminated truncation point, send length if (cur_cbs[b].isTermPass != null && cur_cbs[b].isTermPass[i]) { cblen = cur_cbs[b].truncRates[i] - cblen; nbits = MathUtil.log2(newtp)+lblock[t][c][r][s][b]; hbuf.writeBits(cblen,nbits); // Initialize for next length newtp = 0; cblen = cur_cbs[b].truncRates[i]; } } // Last truncation point length is always signalled // First calculate number of bits needed to signal // Calculate length cblen = cur_cbs[b].truncRates[i] - cblen; nbits = MathUtil.log2(newtp) + lblock[t][c][r][s][b]; hbuf.writeBits(cblen,nbits); } // End loop on horizontal code-blocks } // End loop on vertical code-blocks } // End loop on subband // -> Copy the data to the body buffer // Ensure size for body data if (bbuf==null || bbuf.length<lblen){ bbuf = new byte[lblen]; } lbbuf = bbuf; lblen = 0; for (int s=minsb; s<maxsb; s++) { // Loop on subbands sb = (SubbandAn)root.getSubbandByIdx(r,s); cur_prevtIdxs = prevtIdxs[t][c][r][s]; cur_cbs = cbs[s]; cur_tIndx = tIndx[s]; ncb = cur_prevtIdxs.length; mend = (prec.cblk[s]==null) ? 0 : prec.cblk[s].length; for(int m=0; m<mend; m++) { // Vertical code-blocks nend = (prec.cblk[s][m]==null) ? 0 : prec.cblk[s][m].length; for (int n=0; n<nend; n++) { // Horiz. cblks cbCoord = prec.cblk[s][m][n].idx; b = cbCoord.x+cbCoord.y*sb.numCb.x; if (cur_tIndx[b]>cur_prevtIdxs[b]) { // Block included in this precinct -> Copy data to // body buffer and get code-size
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -