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

magRefPass() private method

Performs the magnitude refinement pass on the specified data and bit-plane. It decodes the samples which are significant and which do not have the "visited" state bit turned on, using the MR primitive. The "visited" state bit is not mofified for any samples.

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.

private magRefPass ( CSJ2K.j2k.image.DataBlk cblk, CSJ2K.j2k.entropy.decoder.MQDecoder mq, int bp, int state, bool isterm ) : bool
cblk CSJ2K.j2k.image.DataBlk The code-block data to decode /// ///
mq CSJ2K.j2k.entropy.decoder.MQDecoder The MQ-decoder to use /// ///
bp int The bit-plane to decode /// ///
state int The state information for the code-block /// ///
isterm bool If this pass has been terminated. If the pass has been /// terminated it can be used to check error resilience. /// ///
return bool
        private bool magRefPass(DataBlk cblk, MQDecoder mq, int bp, int[] state, bool 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 lower bit-planes to 1/2 approximation
            int resetmask; // The mask to reset approximation bit-planes
            int sym; // The symbol to decode
            int[] data; // The data buffer
            int s; // The stripe index
            int nstripes; // The number of stripes in the code-block
            int sheight; // Height of the current stripe
            bool error; // The error condition

            // Initialize local variables
            dscanw = cblk.scanw;
            sscanw = cblk.w + 2;
            jstep = sscanw * CSJ2K.j2k.entropy.StdEntropyCoderOptions.STRIPE_HEIGHT / 2 - cblk.w;
            kstep = dscanw * CSJ2K.j2k.entropy.StdEntropyCoderOptions.STRIPE_HEIGHT - cblk.w;
            setmask = (1 << bp) >> 1;
            resetmask = (- 1) << (bp + 1);
            data = (int[]) cblk.Data;
            nstripes = (cblk.h + CSJ2K.j2k.entropy.StdEntropyCoderOptions.STRIPE_HEIGHT - 1) / CSJ2K.j2k.entropy.StdEntropyCoderOptions.STRIPE_HEIGHT;

            // Decode stripe by stripe
            sk = cblk.offset;
            sj = sscanw + 1;
            for (s = nstripes - 1; s >= 0; s--, sk += kstep, sj += jstep)
            {
                sheight = (s != 0)?CSJ2K.j2k.entropy.StdEntropyCoderOptions.STRIPE_HEIGHT:cblk.h - (nstripes - 1) * CSJ2K.j2k.entropy.StdEntropyCoderOptions.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 significant and not yet
                    // visited in the current bit-plane we can not skip them
                    if ((((SupportClass.URShift(csj, 1)) & (~ csj)) & VSTD_MASK_R1R2) != 0)
                    {
                        k = sk;
                        // Scan first row
                        if ((csj & (STATE_SIG_R1 | STATE_VISITED_R1)) == STATE_SIG_R1)
                        {
                            // Use MR primitive
                            sym = mq.decodeSymbol(MR_LUT[csj & MR_MASK]);
                            // Update the data
                            data[k] &= resetmask;
                            data[k] |= (sym << bp) | setmask;
                            // Update the STATE_PREV_MR bit
                            csj |= STATE_PREV_MR_R1;
                        }
                        if (sheight < 2)
                        {
                            state[j] = csj;
                            continue;
                        }
                        // Scan second row
                        if ((csj & (STATE_SIG_R2 | STATE_VISITED_R2)) == STATE_SIG_R2)
                        {
                            k += dscanw;
                            // Use MR primitive
                            sym = mq.decodeSymbol(MR_LUT[(SupportClass.URShift(csj, STATE_SEP)) & MR_MASK]);
                            // Update the data
                            data[k] &= resetmask;
                            data[k] |= (sym << bp) | setmask;
                            // Update the STATE_PREV_MR bit
                            csj |= STATE_PREV_MR_R2;
                        }
                        state[j] = csj;
                    }
                    // Do half bottom of column
                    if (sheight < 3)
                        continue;
                    j += sscanw;
                    csj = state[j];
                    // If any of the two samples is significant and not yet
                    // visited in the current bit-plane we can not skip them
                    if ((((SupportClass.URShift(csj, 1)) & (~ csj)) & VSTD_MASK_R1R2) != 0)
                    {
                        k = sk + (dscanw << 1);
                        // Scan first row
                        if ((csj & (STATE_SIG_R1 | STATE_VISITED_R1)) == STATE_SIG_R1)
                        {
                            // Use MR primitive
                            sym = mq.decodeSymbol(MR_LUT[csj & MR_MASK]);
                            // Update the data
                            data[k] &= resetmask;
                            data[k] |= (sym << bp) | setmask;
                            // Update the STATE_PREV_MR bit
                            csj |= STATE_PREV_MR_R1;
                        }
                        if (sheight < 4)
                        {
                            state[j] = csj;
                            continue;
                        }
                        // Scan second row
                        if ((state[j] & (STATE_SIG_R2 | STATE_VISITED_R2)) == STATE_SIG_R2)
                        {
                            k += dscanw;
                            // Use MR primitive
                            sym = mq.decodeSymbol(MR_LUT[(SupportClass.URShift(csj, STATE_SEP)) & MR_MASK]);
                            // Update the data
                            data[k] &= resetmask;
                            data[k] |= (sym << bp) | setmask;
                            // Update the STATE_PREV_MR bit
                            csj |= STATE_PREV_MR_R2;
                        }
                        state[j] = csj;
                    }
                }
            }

            error = false;

            // Check the error resilient termination
            if (isterm && (options & CSJ2K.j2k.entropy.StdEntropyCoderOptions.OPT_PRED_TERM) != 0)
            {
                error = mq.checkPredTerm();
            }

            // Reset the MQ context states if we need to
            if ((options & CSJ2K.j2k.entropy.StdEntropyCoderOptions.OPT_RESET_MQ) != 0)
            {
                mq.resetCtxts();
            }

            // Return error condition
            return error;
        }