📄 pktdecoder.java
字号:
* @param p Precinct index * * @param cbI CBlkInfo array of relevant component and resolution * level. * * @param nb The remainding number of bytes to read from the bit stream in * each tile before reaching the decoding rate (in truncation mode) * * @return True if decoding rate is reached * */ public boolean readPktBody(int l,int r,int c,int p,CBlkInfo[][][] cbI, int[] nb) throws IOException{ int curOff = ehs.getPos(); Coord curCB; CBlkInfo ccb; boolean stopRead = false; int tIdx = src.getTileIdx(); 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; } for(int s=subRange[c][r][0]; s<=subRange[c][r][1]; s++){ for(int numCB=0; numCB<cblks[s].size(); numCB++){ curCB = (Coord)cblks[s].elementAt(numCB); ccb = cbI[s][curCB.x][curCB.y]; ccb.off[l] = curOff; curOff += ccb.len[l]; try{ ehs.seek(curOff); } catch(EOFException e){ 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(); } // If truncation mode if(isTruncMode){ if(stopRead || ccb.len[l]>nb[tIdx]){ // 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; } stopRead = true; } if(!stopRead) nb[tIdx] -= ccb.len[l]; } } cblks[s].removeAllElements(); }// End loop on subbands // Seek to the end of the packet ehs.seek(curOff); if(stopRead) return true; else return false; } /** * Creates the arrays sotEotArray and sotEotArrayMax. The first array * contains the start/end of tile coordinates at each resolution level and * the second array contains the start/end of tile coordinates for the * highest resolution level using the smallest increment step * * @param c the component index * */ private void buildSotEotArrays(int c) { // Create and initialise the maximum increment array. Allocate and // initialise if elements do not exist sotEotArrayMax[c][0] = new Coord(); // start of tile sotEotArrayMax[c][1] = new Coord(); // end of tile // Calculate the start/enf of tile for the highest resolution and // smallest increment step if(incArrayMax[c].x == 0){ sotEotArrayMax[c][0].x = 0; sotEotArrayMax[c][1].x = 1; incArrayMax[c].x = 1; } else { sotEotArrayMax[c][0].x = src.getULX(c,mdl[c]); sotEotArrayMax[c][1].x = sotEotArrayMax[c][0].x + src.getCompWidth(c,mdl[c]); sotEotArrayMax[c][0].x &= ~(incArrayMax[c].x-1); } if(incArrayMax[c].y == 0){ sotEotArrayMax[c][0].y = 0; sotEotArrayMax[c][1].y = 1; incArrayMax[c].y = 1; } else { sotEotArrayMax[c][0].y = src.getULY(c,mdl[c]); sotEotArrayMax[c][1].y = sotEotArrayMax[c][0].y + src.getCompHeight(c,mdl[c]); sotEotArrayMax[c][0].y &= ~(incArrayMax[c].y-1); } // Create and initialise the increment array for each resolution level for(int r=0;r<=mdl[c];r++){ sotEotArray[c][r][0] = new Coord(); // start of tile sotEotArray[c][r][1] = new Coord(); // end of tile // Calculate the start/enf of tile for the resolution l and // associated increment if(incArray[c][r].x == 0){ sotEotArray[c][r][0].x = 0; sotEotArray[c][r][1].x = 1; incArray[c][r].x = 1; } else{ sotEotArray[c][r][0].x = src.getULX(c,mdl[c]); sotEotArray[c][r][1].x = sotEotArray[c][r][0].x + src.getCompWidth(c,mdl[c]); sotEotArray[c][r][0].x &= ~(incArray[c][r].x-1); } if(incArray[c][r].y == 0){ sotEotArray[c][r][0].y = 0; sotEotArray[c][r][1].y = 1; incArray[c][r].y = 1; } else{ sotEotArray[c][r][0].y = src.getULY(c,mdl[c]); sotEotArray[c][r][1].y = sotEotArray[c][r][0].y + src.getCompHeight(c,mdl[c]); sotEotArray[c][r][0].y &= ~(incArray[c][r].y-1); } } } /** * Creates the arrays incArray and incArrayMax. The first array (incArray) * contains the increment step used for each component, each tile and each * resolution level. The second one (incArrayMax) contains the smallest * increment. This is used when looking for packet inclusion. * * @param c the component index * */ private void buildIncArrays(int c) { int ppx, ppy; // Precinct partition dimensions // Allocate maximum increment array incArrayMax[c] = new Coord(); for(int r=0 ;r<=mdl[c];r++){ // Get precinct partition dimensions ppx = getPPX(tIdx,c,r); ppy = getPPY(tIdx,c,r); // Allocate increment array for resolution level 'r' incArray[c][r] = new Coord(); incArray[c][r].x = src.getCompSubsX(c); incArray[c][r].x <<= MathUtil.log2(ppx) + mdl[c] - r; if( incArrayMax[c].x==0 || incArray[c][r].x<incArrayMax[c].x ){ // Save smallest horizontal increment incArrayMax[c].x = incArray[c][r].x; } incArray[c][r].y = src.getCompSubsY(c); incArray[c][r].y <<= MathUtil.log2(ppy) + mdl[c] - r; if ( incArrayMax[c].y==0 || incArray[c][r].y<incArrayMax[c].y ){ // Save smallest vertical increment incArrayMax[c].y = incArray[c][r].y; } } } /** * Builds the lists containing the ulx, uly, width, height and indexes of * the code-blocks and of the precincts for each component, resolution * level and subband. First, we compute the projected anchor point for * the code-block partition. Then, the array containing the code-blocks * coordinates is built. Finally, the array containing the precincts * coordinates is built. * * @param c the component index * * @param r The resolution level * */ private void buildCBlkPrecCoord(int c,int r){ int cn, cm,tmp; int apox, apoy; // projected anchor point for the code-block partition SubbandSyn sb; for(int s=subRange[c][r][0];s<=subRange[c][r][1];s++){ sb = (SubbandSyn)src.getSubbandTree(tIdx,c).getSubbandByIdx(r,s); // Compute the projected anchor point for the code-block partition apox = src.getPartitionULX(); apoy = src.getPartitionULY(); Subband sb2; switch (sb.gOrient) { case Subband.WT_ORIENT_LL: // No need to project since all low-pass => nothing to do break; case Subband.WT_ORIENT_HL: // There is at least a high-pass step on the horizontal // decomposition => project to 0 apox = 0; // We need to find out if there has been a high-pass // step on the vertical decomposition sb2 = sb; do { if (sb2.orientation == Subband.WT_ORIENT_HH || sb2.orientation == Subband.WT_ORIENT_LH) { // Vertical high-pass step => project to 0 and done apoy = 0; break; } if (sb2.gOrient == Subband.WT_ORIENT_LL) { // Only low-pass steps left, no need to continue // checking break; } sb2 = sb2.getParent(); } while (sb2 != null); break; case Subband.WT_ORIENT_LH: // We need to find out if there has been a high-pass // step on the horizontal decomposition sb2 = sb; do { if (sb2.orientation == Subband.WT_ORIENT_HH || sb2.orientation == Subband.WT_ORIENT_HL) { // Horizontal high-pass step => project to 0 and done apox = 0; break; } if (sb2.gOrient == Subband.WT_ORIENT_LL) { // Only low-pass steps left, no need to continue // checking break; } sb2 = sb2.getParent(); } while (sb2 != null); // There is at least a high-pass step on the vertical // decomposition => project to 0 apoy = 0; break; case Subband.WT_ORIENT_HH: // There is at least a high-pass step on the // horiz. and vertical decomposition => project to 0 apox = 0; apoy = 0; break; default: throw new Error("Internal JJ2000 error"); } // end switch // If there is at least one code-block CBlkCoordInfo ccb = null; if(cbCoord[c][r][s]!=null){ int nBlkY = cbCoord[c][r][s].length; int nBlkX = (nBlkY!=0) ? cbCoord[c][r][s][0].length : 0; for(int m=0; m<nBlkY; m++){ for(int n=0; n<nBlkX; n++){ ccb = cbCoord[c][r][s][m][n] = new CBlkCoordInfo(); ccb.idx = new Coord(n,m); cn = (sb.ulcx-apox+sb.nomCBlkW)/sb.nomCBlkW-1; cm = (sb.ulcy-apoy+sb.nomCBlkH)/sb.nomCBlkH-1; if(n==0){ // Left-most code-block, starts where // subband starts ccb.ulx = sb.ulx; } else{ // Calculate starting canvas coordinate // and convert to subband coords ccb.ulx = (cn+n)*sb.nomCBlkW - (sb.ulcx-apox)+ sb.ulx; } if(m==0){ // Bottom-most code-block, starts where // subband starts ccb.uly = sb.uly; } else{ ccb.uly = (cm+m)*sb.nomCBlkH - (sb.ulcy-apoy) + sb.uly; } if(n < nBlkX-1){ // Calculate where next code-block starts // => width ccb.w = (cn+n+1)*sb.nomCBlkW - (sb.ulcx-apox) + sb.ulx - ccb.ulx; } else{ // Right-most code-block, ends where // subband ends ccb.w = sb.ulx+sb.w - ccb.ulx; } if(m < nBlkY-1){ // Calculate where next code-block starts // => height ccb.h = (cm+m+1)*sb.nomCBlkH - (sb.ulcy-apoy) + sb.uly - ccb.uly; } else{ // Bottom-most code-block, ends where // subband ends ccb.h = sb.uly+sb.h- ccb.uly; } } // End loop on horizontal code-blocks } // End loop on vertical code-blocks } } // Loop on subbands // ------------------------------------------------- // Now deal with precincts // ------------------------------------------------- int nl, ppx, ppy; int x_inc, y_inc; int Px=0; int Py=0; int precIdx = -1; int hIdx, vIdx; int precIdxA[] = new int[subRange[c][r][1]+1]; boolean incrPrecIdx = false; x_inc = incArray[c][r].x; y_inc = incArray[c][r].y; for(int yr=sotEotArrayMax[c][0].y ; yr<sotEotArrayMax[c][1].y; yr+=incArrayMax[c].y ) { for(int xr=sotEotArrayMax[c][0].x ; xr<sotEotArrayMax[c][1].x ; xr+=incArrayMax[c].x ) { // Loop on highest resolution grid using the smallest increment if( ( (xr==sotEotArrayMax[c][0].x) || ((xr)%x_inc==0) ) && ( (yr==sotEotArrayMax[c][0].y) || ((yr)%y_inc==0) ) ) { // Packet exists in the resolution level incrPrecIdx = false; for(int s=subRange[c][r][0];s<=subRange[c][r][1];s++){ sb = (SubbandSyn) src.getSubbandTree(tIdx,c). getSubbandByIdx(r,s); if( !hd.precinctPartitionUsed() ){ // If the precinct partition is not used, // create the precinct if it exists sb = (SubbandSyn) src.getSubbandTree(tIdx,c). getSubbandByIdx(r,s); if(precCoord[c][r][s][0]==null ){ precCoord[c][r][s][0] = new PrecCoordInfo(0,0,sb.w,sb.h, xr,yr); } } else{ // Precinct partition is used // Get precinct partition sizes ppx = src.getPPX(tIdx,c,r); ppy = src.getPPY(tIdx,c,r); precIdx = precIdxA[s]; if( precIdx<0 || precIdx>(maxNumPrecincts[c][r].x *maxNumPrecincts[c][r].y)-1 ){ // Wrong packet index continue; } // Calculate horizontal coordinate within subband // (including missing image)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -