CSJ2K.j2k.entropy.decoder.StdEntropyDecoder.getCodeBlock C# (CSharp) Method

getCodeBlock() public method

Returns the specified code-block in the current tile for the specified component, as a copy (see below).

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.

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.

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.

public getCodeBlock ( int c, int m, int n, CSJ2K.j2k.wavelet.synthesis.SubbandSyn sb, CSJ2K.j2k.image.DataBlk cblk ) : CSJ2K.j2k.image.DataBlk
c int The component for which to return the next code-block. /// ///
m int The vertical index of the code-block to return, in the /// specified subband. /// ///
n int The horizontal index of the code-block to return, in the /// specified subband. /// ///
sb CSJ2K.j2k.wavelet.synthesis.SubbandSyn The subband in which the code-block to return is. /// ///
cblk CSJ2K.j2k.image.DataBlk 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 CSJ2K.j2k.image.DataBlk
        public override 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)
            bool error; // Error indicator
            int tslen; // Length of first terminated segment
            int tsidx; // Index of current terminated segment
            ByteInputBuffer in_Renamed = null;

            bool isterm;

            // Get the code-block to decode
            srcblk = src.getCodeBlock(c, m, n, sb, 1, - 1, srcblk);

            #if DO_TIMING
            stime = (System.DateTime.Now.Ticks - 621355968000000000) / 10000;
            #endif

            // Retrieve options from decSpec
            options = ((System.Int32) decSpec.ecopts.getTileCompVal(tIdx, c));

            // 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.Data;

            if (out_data == null || out_data.Length < srcblk.w * srcblk.h)
            {
                out_data = new int[srcblk.w * srcblk.h];
                cblk.Data = out_data;
            }
            else
            {
                // 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_Renamed = new ByteInputBuffer(srcblk.data, 0, tslen);
                mq = new MQDecoder(in_Renamed, NUM_CTXTS, MQ_INIT);
            }
            else
            {
                // We always start by an MQ segment
                mq.nextSegment(srcblk.data, 0, tslen);
                mq.resetCtxts();
            }
            error = false;

            if ((options & CSJ2K.j2k.entropy.StdEntropyCoderOptions.OPT_BYPASS) != 0)
            {
                if (bin == null)
                {
                    if (in_Renamed == null)
                        in_Renamed = mq.ByteInputBuffer;
                    bin = new ByteToBitInput(in_Renamed);
                }
            }

            // Choose correct ZC lookup table for global orientation
            switch (sb.orientation)
            {

                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 System.InvalidOperationException("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;

            // Check for maximum number of bitplanes quit condition
            if (mQuit != - 1 && (mQuit * 3 - 2) < npasses)
            {
                npasses = mQuit * 3 - 2;
            }

            // First bit-plane has only the cleanup pass
            if (curbp >= 0 && npasses > 0)
            {
                isterm = (options & CSJ2K.j2k.entropy.StdEntropyCoderOptions.OPT_TERM_PASS) != 0 || ((options & CSJ2K.j2k.entropy.StdEntropyCoderOptions.OPT_BYPASS) != 0 && (31 - CSJ2K.j2k.entropy.StdEntropyCoderOptions.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 & CSJ2K.j2k.entropy.StdEntropyCoderOptions.OPT_BYPASS) != 0 && (curbp < 31 - CSJ2K.j2k.entropy.StdEntropyCoderOptions.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 & CSJ2K.j2k.entropy.StdEntropyCoderOptions.OPT_TERM_PASS) != 0;
                        error = rawSigProgPass(cblk, bin, curbp, state, isterm);
                        npasses--;
                        if (npasses <= 0 || (error && doer))
                            break;

                        if ((options & CSJ2K.j2k.entropy.StdEntropyCoderOptions.OPT_TERM_PASS) != 0)
                        {
                            // Start a new raw segment
                            bin.setByteArray(null, - 1, srcblk.tsLengths[++tsidx]);
                        }
                        isterm = (options & CSJ2K.j2k.entropy.StdEntropyCoderOptions.OPT_TERM_PASS) != 0 || ((options & CSJ2K.j2k.entropy.StdEntropyCoderOptions.OPT_BYPASS) != 0 && (31 - CSJ2K.j2k.entropy.StdEntropyCoderOptions.NUM_NON_BYPASS_MS_BP - srcblk.skipMSBP > curbp));
                        error = rawMagRefPass(cblk, bin, curbp, state, isterm);
                    }
                    else
                    {
                        // Do not use bypass decoding mode
                        if ((options & CSJ2K.j2k.entropy.StdEntropyCoderOptions.OPT_TERM_PASS) != 0)
                        {
                            // Here starts a new MQ segment
                            mq.nextSegment(null, - 1, srcblk.tsLengths[++tsidx]);
                        }
                        isterm = (options & CSJ2K.j2k.entropy.StdEntropyCoderOptions.OPT_TERM_PASS) != 0;
                        error = sigProgPass(cblk, mq, curbp, state, zc_lut, isterm);
                        npasses--;
                        if (npasses <= 0 || (error && doer))
                            break;

                        if ((options & CSJ2K.j2k.entropy.StdEntropyCoderOptions.OPT_TERM_PASS) != 0)
                        {
                            // Here starts a new MQ segment
                            mq.nextSegment(null, - 1, srcblk.tsLengths[++tsidx]);
                        }
                        isterm = (options & CSJ2K.j2k.entropy.StdEntropyCoderOptions.OPT_TERM_PASS) != 0 || ((options & CSJ2K.j2k.entropy.StdEntropyCoderOptions.OPT_BYPASS) != 0 && (31 - CSJ2K.j2k.entropy.StdEntropyCoderOptions.NUM_NON_BYPASS_MS_BP - srcblk.skipMSBP > curbp));
                        error = magRefPass(cblk, mq, curbp, state, isterm);
                    }

                    npasses--;
                    if (npasses <= 0 || (error && doer))
                        break;

                    if ((options & CSJ2K.j2k.entropy.StdEntropyCoderOptions.OPT_TERM_PASS) != 0 || ((options & CSJ2K.j2k.entropy.StdEntropyCoderOptions.OPT_BYPASS) != 0 && (curbp < 31 - CSJ2K.j2k.entropy.StdEntropyCoderOptions.NUM_NON_BYPASS_MS_BP - srcblk.skipMSBP)))
                    {
                        // Here starts a new MQ segment
                        mq.nextSegment(null, - 1, srcblk.tsLengths[++tsidx]);
                    }
                    isterm = (options & CSJ2K.j2k.entropy.StdEntropyCoderOptions.OPT_TERM_PASS) != 0 || ((options & CSJ2K.j2k.entropy.StdEntropyCoderOptions.OPT_BYPASS) != 0 && (31 - CSJ2K.j2k.entropy.StdEntropyCoderOptions.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(CSJ2K.j2k.util.MsgLogger_Fields.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.DateTime.Now.Ticks - 621355968000000000) / 10000 - stime;
            #endif

            // Return decoded block
            return cblk;
        }