📄 stdentropydecoder.java
字号:
MR_LUT[0] = 16; // One or more significant, prev MR off for (i=1; i<(1<<(MR_LUT_BITS-1)); i++) { MR_LUT[i] = 17; } // Previous MR on, significance irrelevant for (; i<(1<<MR_LUT_BITS); i++) { MR_LUT[i] = 18; } } /** * Instantiates a new entropy decoder engine, with the specified source of * data, nominal block width and height. * * @param src The source of data * * @param opt The options to use for this encoder. It is a mix of the * 'OPT_REG_TERM', 'OPT_RESET_MQ', 'OPT_VERT_STR_CAUSAL', 'OPT_BYPASS' and * 'OPT_SEG_MARKERS' option flags. * * @param doer If true error detection will be performed, if any error * detection features have been enabled. * * @param verber This flag indicates if the entropy decoder should be * verbose about bit stream errors that are detected and concealed. * */ public StdEntropyDecoder(CodedCBlkDataSrcDec src, DecoderSpecs decSpec, boolean doer, boolean verber) { super(src); this.decSpec = decSpec; this.doer = doer; this.verber = verber; // If we do timing create necessary structures if (DO_TIMING) { time = new long[src.getNumComps()]; // If we are timing make sure that 'finalize' gets called. System.runFinalizersOnExit(true); } // Initialize internal variables state = new int[(decSpec.cblks.getMaxCBlkWidth()+2) * ((decSpec.cblks.getMaxCBlkHeight()+1)/2+2)]; } /** * Prints the timing information, if collected, and calls 'finalize' on * the super class. * */ public void finalize() throws Throwable { if (DO_TIMING) { int c; StringBuffer sb; sb = new StringBuffer("StdEntropyDecoder decompression wall "+ "clock time:"); for (c=0; c<time.length; c++) { sb.append("\n component "); sb.append(c); sb.append(": "); sb.append(time[c]); sb.append(" ms"); } FacilityManager.getMsgLogger(). printmsg(MsgLogger.INFO,sb.toString()); } super.finalize(); } /** * Returns the number of code-blocks in a subband, along the * horizontal and vertical dimensions. * * @param sb The subband for which to return the number of blocks. * * @param n The component where the subband is. * * @param co If not null the values are returned in this * object. If null a new object is allocated and returned. * * @return The number of code-blocks along the horizontal * dimension in 'Coord.x' and the number of code-blocks along the * vertical dimension in 'Coord.y'. * */ public Coord getNumCodeBlocks(SubbandSyn sb, int n, Coord co) { return src.getNumCodeBlocks(sb,n,co); } /** * Returns the specified code-block in the current tile for the specified * component, as a copy (see below). * * <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 is always a copy of the internal * data of this object, if any, and it can be modified "in place" without * any problems after being returned. The 'offset' of the returned data is * 0, and the 'scanw' is the same as the code-block width. 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 getCodeBlock(int c, int m, int n, SubbandSyn sb, DataBlk cblk) { long stime = 0L; // Start time for timed sections int zc_lut[]; // The ZC lookup table to use int out_data[]; // The outupt data buffer int npasses; // The number of coding passes to perform int curbp; // The current magnitude bit-plane (starts at 30) boolean error; // Error indicator int tslen; // Length of first terminated segment int tsidx; // Index of current terminated segment ByteInputBuffer in = null; boolean isterm; // Get the code-block to decode srcblk = src.getCodeBlock(c,m,n,sb,1,-1,srcblk); if (DO_TIMING) stime = System.currentTimeMillis(); // Retrieve options from decSpec options = ((Integer)decSpec.ecopts. getTileCompVal(tIdx,c)).intValue(); // Reset state ArrayUtil.intArraySet(state,0); // Initialize output code-block if (cblk==null) { cblk = new DataBlkInt(); } cblk.progressive = srcblk.prog; cblk.ulx = srcblk.ulx; cblk.uly = srcblk.uly; cblk.w = srcblk.w; cblk.h = srcblk.h; cblk.offset = 0; cblk.scanw = cblk.w; out_data = (int[])cblk.getData(); if (out_data == null || out_data.length < srcblk.w*srcblk.h) { out_data = new int[srcblk.w*srcblk.h]; cblk.setData(out_data); } // Set data values to 0 ArrayUtil.intArraySet(out_data,0); if (srcblk.nl <= 0 || srcblk.nTrunc <= 0) { // 0 layers => no data to decode => return all 0s return cblk; } // Get the length of the first terminated segment tslen = (srcblk.tsLengths == null) ? srcblk.dl : srcblk.tsLengths[0]; tsidx = 0; // Initialize for decoding npasses = srcblk.nTrunc; if (mq == null) { in = new ByteInputBuffer(srcblk.data,0,tslen); mq = new MQDecoder(in ,NUM_CTXTS,MQ_INIT); } else { // We always start by an MQ segment mq.nextSegment(srcblk.data,0,tslen); mq.resetCtxts(); } error = false; if ((options & OPT_BYPASS) != 0) { if(bin==null){ if (in == null) in = mq.getByteInputBuffer(); bin = new ByteToBitInput(in); } } // Choose correct ZC lookup table for global orientation switch (sb.gOrient) { case Subband.WT_ORIENT_HL: zc_lut = ZC_LUT_HL; break; case Subband.WT_ORIENT_LH: case Subband.WT_ORIENT_LL: zc_lut = ZC_LUT_LH; break; case Subband.WT_ORIENT_HH: zc_lut = ZC_LUT_HH; break; default: throw new Error("JJ2000 internal error"); } // NOTE: we don't currently detect which is the last magnitude // bit-plane so that 'isterm' is true for the last pass of it. Doing so // would aid marginally in error detection with the predictable error // resilient MQ termination. However, determining which is the last // magnitude bit-plane is quite hard (due to ROI, quantization, etc.) // and in any case the predictable error resilient termination used // without the arithmetic coding bypass and/or regular termination // modes is almost useless. // Loop on bit-planes and passes curbp = 30-srcblk.skipMSBP; // First bit-plane has only the cleanup pass if (curbp >= 0 && npasses > 0) { 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) curbp--; } // Other bit-planes have the three coding passes if (!error || !doer) { while (curbp >= 0 && npasses > 0) { if((options & OPT_BYPASS) != 0 && (curbp < 31-NUM_NON_BYPASS_MS_BP-srcblk.skipMSBP)){ // Use bypass decoding mode (only all bit-planes // after the first 4 bit-planes). // Here starts a new raw segment bin.setByteArray(null,-1,srcblk.tsLengths[++tsidx]); isterm = (options & OPT_REG_TERM) != 0; error = rawSigProgPass(cblk,bin,curbp,state,isterm); npasses--; if (npasses <= 0 || (error && doer)) break; if ((options & OPT_REG_TERM) != 0) { // Start a new raw segment bin.setByteArray(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 = rawMagRefPass(cblk,bin,curbp,state,isterm); } else {// Do not use bypass decoding mode if ((options & OPT_REG_TERM) != 0) { // Here starts a new MQ segment mq.nextSegment(null,-1,srcblk.tsLengths[++tsidx]); } isterm = (options & OPT_REG_TERM) != 0; error = sigProgPass(cblk,mq,curbp,state,zc_lut,isterm); npasses--; if (npasses <= 0 || (error && doer)) break; if ((options & OPT_REG_TERM) != 0) { // 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 = magRefPass(cblk,mq,curbp,state,isterm); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -