📄 stdentropydecoder.java
字号:
npasses--; if (npasses <= 0 || (error && doer)) break; if ((options & OPT_REG_TERM) != 0 || ((options & OPT_BYPASS) != 0 && (curbp < 31-NUM_NON_BYPASS_MS_BP-srcblk.skipMSBP))) { // Here starts a new MQ segment mq.nextSegment(null,-1,srcblk.tsLengths[++tsidx]); } isterm = (options & OPT_REG_TERM) != 0 || ((options & OPT_BYPASS) != 0 && (31-NUM_NON_BYPASS_MS_BP-srcblk.skipMSBP)>=curbp); error = cleanuppass(cblk,mq,curbp,state,zc_lut,isterm); npasses--; if (error && doer) break; // Goto next bit-plane curbp--; } } // If an error ocurred conceal it if (error && doer) { if (verber) { FacilityManager.getMsgLogger(). printmsg(MsgLogger.WARNING, "Error detected at bit-plane "+curbp+ " in code-block ("+m+","+n+"), sb_idx "+ sb.sbandIdx+", res. level "+sb.resLvl+ ". Concealing..."); } conceal(cblk,curbp); } if (DO_TIMING) time[c] += System.currentTimeMillis()-stime; // Return decoded block return cblk; } /** * Returns the specified code-block in the current tile for the specified * component (as a reference or copy). * * <P>The returned code-block may be progressive, which is indicated by * the 'progressive' variable of the returned 'DataBlk' * object. If a code-block is progressive it means that in a later request * to this method for the same code-block it is possible to retrieve data * which is a better approximation, since meanwhile more data to decode * for the code-block could have been received. If the code-block is not * progressive then later calls to this method for the same code-block * will return the exact same data values. * * <P>The data returned by this method can be the data in the internal * buffer of this object, if any, and thus can not be modified by the * caller. The 'offset' and 'scanw' of the returned data can be * arbitrary. See the 'DataBlk' class. * * <P>The 'ulx' and 'uly' members of the returned 'DataBlk' object * contain the coordinates of the top-left corner of the block, with * respect to the tile, not the subband. * * @param c The component for which to return the next code-block. * * @param m The vertical index of the code-block to return, in the * specified subband. * * @param n The horizontal index of the code-block to return, in the * specified subband. * * @param sb The subband in which the code-block to return is. * * @param cblk If non-null this object will be used to return the new * code-block. If null a new one will be allocated and returned. If the * "data" array of the object is non-null it will be reused, if possible, * to return the data. * * @return The next code-block in the current tile for component 'n', or * null if all code-blocks for the current tile have been returned. * * @see DataBlk * */ public DataBlk getInternCodeBlock(int c, int m, int n, SubbandSyn sb, DataBlk cblk) { return getCodeBlock(c,m,n,sb,cblk); } /** * Performs the significance propagation pass on the specified data and * bit-plane. It decodes all insignificant samples which have, at least, * one of its immediate eight neighbors already significant, using the ZC * and SC primitives as needed. It toggles the "visited" state bit to 1 * for all those samples. * * <P>This method also checks for segmentation markers if those are * present and returns true if an error is detected, or false * otherwise. If an error is detected it means that the bit stream contains * some erroneous bit that have led to the decoding of incorrect * data. This data affects the whole last decoded bit-plane (i.e. 'bp'). If * 'true' is returned the 'conceal' method should be called and no more * passes should be decoded for this code-block's bit stream. * * @param cblk The code-block data to decode * * @param mq The MQ-coder to use * * @param bp The bit-plane to decode * * @param state The state information for the code-block * * @param zc_lut The ZC lookup table to use in ZC. * * @param isterm If this pass has been terminated. If the pass has been * terminated it can be used to check error resilience. * * @return True if an error was detected in the bit stream, false otherwise. * */ private boolean sigProgPass(DataBlk cblk, MQDecoder mq, int bp, int state[], int zc_lut[], boolean isterm) { int j,sj; // The state index for line and stripe int k,sk; // The data index for line and stripe int dscanw; // The data scan-width int sscanw; // The state scan-width int jstep; // Stripe to stripe step for 'sj' int kstep; // Stripe to stripe step for 'sk' int stopsk; // The loop limit on the variable sk int csj; // Local copy (i.e. cached) of 'state[j]' int setmask; // The mask to set current and lower bit-planes to 1/2 // approximation int sym; // The symbol to code int ctxt; // The context to use int data[]; // The data buffer int s; // The stripe index boolean causal; // Flag to indicate if stripe-causal context // formation is to be used int nstripes; // The number of stripes in the code-block int sheight; // Height of the current stripe int off_ul,off_ur,off_dr,off_dl; // offsets boolean error; // The error condition // Initialize local variables dscanw = cblk.scanw; sscanw = cblk.w+2; jstep = sscanw*STRIPE_HEIGHT/2-cblk.w; kstep = dscanw*STRIPE_HEIGHT-cblk.w; setmask = (3<<bp)>>1; data = (int[]) cblk.getData(); nstripes = (cblk.h+STRIPE_HEIGHT-1)/STRIPE_HEIGHT; causal = (options & OPT_VERT_STR_CAUSAL) != 0; // Pre-calculate offsets in 'state' for diagonal neighbors off_ul = -sscanw-1; // up-left off_ur = -sscanw+1; // up-right off_dr = sscanw+1; // down-right off_dl = sscanw-1; // down-left // Decode stripe by stripe sk = cblk.offset; sj = sscanw+1; for (s = nstripes-1; s >= 0; s--, sk+=kstep, sj+=jstep) { sheight = (s != 0) ? STRIPE_HEIGHT : cblk.h-(nstripes-1)*STRIPE_HEIGHT; stopsk = sk+cblk.w; // Scan by set of 1 stripe column at a time for (; sk < stopsk; sk++, sj++) { // Do half top of column j = sj; csj = state[j]; // If any of the two samples is not significant and has a // non-zero context (i.e. some neighbor is significant) we can // not skip them if ((((~csj) & (csj<<2)) & SIG_MASK_R1R2) != 0) { k = sk; // Scan first row if ((csj & (STATE_SIG_R1|STATE_NZ_CTXT_R1)) == STATE_NZ_CTXT_R1) { // Use zero coding if (mq.decodeSymbol(zc_lut[csj&ZC_MASK]) != 0) { // Became significant // Use sign coding ctxt = SC_LUT[(csj>>>SC_SHIFT_R1)&SC_MASK]; sym = mq.decodeSymbol(ctxt & SC_LUT_MASK) ^ (ctxt>>>SC_SPRED_SHIFT); // Update data data[k] = (sym<<31) | setmask; // Update state information (significant bit, // visited bit, neighbor significant bit of // neighbors, non zero context of neighbors, sign // of neighbors) if (!causal) { // If in causal mode do not change contexts of // previous stripe. state[j+off_ul] |= STATE_NZ_CTXT_R2|STATE_D_DR_R2; state[j+off_ur] |= STATE_NZ_CTXT_R2|STATE_D_DL_R2; } // Update sign state information of neighbors if (sym != 0) { csj |= STATE_SIG_R1|STATE_VISITED_R1| STATE_NZ_CTXT_R2| STATE_V_U_R2|STATE_V_U_SIGN_R2; if (!causal) { // If in causal mode do not change // contexts of previous stripe. state[j-sscanw] |= STATE_NZ_CTXT_R2| STATE_V_D_R2|STATE_V_D_SIGN_R2; } state[j+1] |= STATE_NZ_CTXT_R1|STATE_NZ_CTXT_R2| STATE_H_L_R1|STATE_H_L_SIGN_R1| STATE_D_UL_R2; state[j-1] |= STATE_NZ_CTXT_R1|STATE_NZ_CTXT_R2| STATE_H_R_R1|STATE_H_R_SIGN_R1| STATE_D_UR_R2; } else { csj |= STATE_SIG_R1|STATE_VISITED_R1| STATE_NZ_CTXT_R2|STATE_V_U_R2; if (!causal) { // If in causal mode do not change // contexts of previous stripe. state[j-sscanw] |= STATE_NZ_CTXT_R2| STATE_V_D_R2; } state[j+1] |= STATE_NZ_CTXT_R1|STATE_NZ_CTXT_R2| STATE_H_L_R1|STATE_D_UL_R2; state[j-1] |= STATE_NZ_CTXT_R1|STATE_NZ_CTXT_R2| STATE_H_R_R1|STATE_D_UR_R2; } } else { csj |= STATE_VISITED_R1; } } if (sheight < 2) { state[j] = csj; continue; } // Scan second row if ((csj & (STATE_SIG_R2|STATE_NZ_CTXT_R2)) == STATE_NZ_CTXT_R2) { k += dscanw; // Use zero coding if (mq.decodeSymbol(zc_lut[(csj>>>STATE_SEP)& ZC_MASK]) != 0) { // Became significant // Use sign coding ctxt = SC_LUT[(csj>>>SC_SHIFT_R2)&SC_MASK]; sym = mq.decodeSymbol(ctxt & SC_LUT_MASK) ^ (ctxt>>>SC_SPRED_SHIFT); // Update data data[k] = (sym<<31) | setmask; // Update state information (significant bit, // visited bit, neighbor significant bit of // neighbors, non zero context of neighbors, sign // of neighbors) state[j+off_dl] |= STATE_NZ_CTXT_R1|STATE_D_UR_R1; state[j+off_dr] |= STATE_NZ_CTXT_R1|STATE_D_UL_R1; // Update sign state information of neighbors if (sym != 0) { csj |= STATE_SIG_R2|STATE_VISITED_R2| STATE_NZ_CTXT_R1| STATE_V_D_R1|STATE_V_D_SIGN_R1; state[j+sscanw] |= STATE_NZ_CTXT_R1| STATE_V_U_R1|STATE_V_U_SIGN_R1; state[j+1] |= STATE_NZ_CTXT_R1|STATE_NZ_CTXT_R2| STATE_D_DL_R1| STATE_H_L_R2|STATE_H_L_SIGN_R2; state[j-1] |= STATE_NZ_CTXT_R1|STATE_NZ_CTXT_R2| STATE_D_DR_R1| STATE_H_R_R2|STATE_H_R_SIGN_R2; } else { csj |= STATE_SIG_R2|STATE_VISITED_R2| STATE_NZ_CTXT_R1|STATE_V_D_R1; state[j+sscanw] |= STATE_NZ_CTXT_R1| STATE_V_U_R1; state[j+1] |= STATE_NZ_CTXT_R1|STATE_NZ_CTXT_R2| STATE_D_DL_R1|STATE_H_L_R2; state[j-1] |= STATE_NZ_CTXT_R1|STATE_NZ_CTXT_R2| STATE_D_DR_R1|STATE_H_R_R2; } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -