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

rawSigProgPass() private method

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.

This method bypasses the arithmetic coder and reads "raw" symbols from the bit stream.

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 measn 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 rawSigProgPass ( CSJ2K.j2k.image.DataBlk cblk, CSJ2K.j2k.entropy.decoder.ByteToBitInput bin, int bp, int state, bool isterm ) : bool
cblk CSJ2K.j2k.image.DataBlk The code-block data to decode /// ///
bin CSJ2K.j2k.entropy.decoder.ByteToBitInput The raw bit based input /// ///
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 rawSigProgPass(DataBlk cblk, ByteToBitInput bin, 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 current and lower bit-planes to 1/2
            // approximation
            int sym; // The symbol to code
            int[] data; // The data buffer
            int s; // The stripe index
            bool 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
            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 = (3 << bp) >> 1;
            data = (int[]) cblk.Data;
            nstripes = (cblk.h + CSJ2K.j2k.entropy.StdEntropyCoderOptions.STRIPE_HEIGHT - 1) / CSJ2K.j2k.entropy.StdEntropyCoderOptions.STRIPE_HEIGHT;
            causal = (options & CSJ2K.j2k.entropy.StdEntropyCoderOptions.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)?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 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 (bin.readBit() != 0)
                            {
                                // Became significant
                                // Use sign coding
                                sym = bin.readBit();
                                // 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;
                        }
                        if ((csj & (STATE_SIG_R2 | STATE_NZ_CTXT_R2)) == STATE_NZ_CTXT_R2)
                        {
                            k += dscanw;
                            // Use zero coding
                            if (bin.readBit() != 0)
                            {
                                // Became significant
                                // Use sign coding
                                sym = bin.readBit();
                                // 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;
                                }
                            }
                            else
                            {
                                csj |= STATE_VISITED_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 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 + (dscanw << 1);
                        // Scan first row
                        if ((csj & (STATE_SIG_R1 | STATE_NZ_CTXT_R1)) == STATE_NZ_CTXT_R1)
                        {
                            // Use zero coding
                            if (bin.readBit() != 0)
                            {
                                // Became significant
                                // Use sign coding
                                sym = bin.readBit();
                                // 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_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;
                                    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;
                                    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 < 4)
                        {
                            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 (bin.readBit() != 0)
                            {
                                // Became significant
                                // Use sign coding
                                sym = bin.readBit();
                                // 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;
                                }
                            }
                            else
                            {
                                csj |= STATE_VISITED_R2;
                            }
                        }
                        state[j] = csj;
                    }
                }
            }

            error = false;

            // Check the byte padding if the pass is terminated and if the error
            // resilience predictable termination is signaled in COx marker.
            if (isterm && (options & CSJ2K.j2k.entropy.StdEntropyCoderOptions.OPT_PRED_TERM) != 0)
            {
                error = bin.checkBytePadding();
            }

            // Return error condition
            return error;
        }