CSJ2K.j2k.entropy.encoder.MQCoder.codeSymbol C# (CSharp) Method

codeSymbol() public method

This function performs the arithmetic encoding of one symbol. The function receives a bit that is to be encoded and a context with which to encode it.

Each context has a current MPS and an index describing what the current probability is for the LPS. Each bit is encoded and if the probability of the LPS exceeds .5, the MPS and LPS are switched.

public codeSymbol ( int bit, int context ) : void
bit int The symbol to be encoded, must be 0 or 1. /// ///
context int the context with which to encode the symbol. /// ///
return void
        public void codeSymbol(int bit, int context)
        {
            int q;
            int li; // local cache of I[context]
            int la;
            int n;

            // NOTE: (a < 0x8000) is equivalent to ((a & 0x8000)==0)
            // since 'a' is always less than or equal to 0xFFFF

            // NOTE: conditional exchange guarantees that A for MPS is
            // always greater than 0x4000 (i.e. 0.375)
            // => one renormalization shift is enough for MPS
            // => no need to do a renormalization while loop for MPS

            li = I[context];
            q = qe[li]; // Retrieve current LPS prob.

            if (bit == mPS[context])
            {
                // -- Code MPS

                a -= q; // Interval division associated with MPS coding

                if (a >= 0x8000)
                {
                    // Interval big enough
                    c += q;
                }
                else
                {
                    // Interval too short
                    if (a < q)
                    {
                        // Probabilities are inverted
                        a = q;
                    }
                    else
                    {
                        c += q;
                    }

                    I[context] = nMPS[li];

                    // -- Renormalization (MPS: no need for while loop)
                    a <<= 1; // a is doubled
                    c <<= 1; // c is doubled
                    cT--;
                    if (cT == 0)
                    {
                        byteOut();
                    }
                    // -- End of renormalization
                }
            }
            else
            {
                // -- Code LPS

                la = a; // cache A register in local variable
                la -= q; // Interval division according to LPS coding

                if (la < q)
                {
                    c += q;
                }
                else
                {
                    la = q;
                }
                if (switchLM[li] != 0)
                {
                    mPS[context] = 1 - mPS[context];
                }
                I[context] = nLPS[li];

                // -- Renormalization

                // sligthly better than normal loop
                n = 0;
                do
                {
                    la <<= 1;
                    n++; // count number of necessary shifts
                }
                while (la < 0x8000);
                if (cT > n)
                {
                    c <<= n;
                    cT -= n;
                }
                else
                {
                    do
                    {
                        c <<= cT;
                        n -= cT;
                        // cT = 0; // not necessary
                        byteOut();
                    }
                    while (cT <= n);
                    c <<= n;
                    cT -= n;
                }

                // -- End of renormalization
                a = la; // save cached A register
            }
        }