示例#1
0
        internal static void EncodeBinary(IDataCoder coder, byte[] ctx, int bits, int x, int offset = 0)
        {
            // Require 2^bits-1  contexts
            int n = 1;
            int m = (1 << bits);

            while (n < m)
            {
                x = (x & (m - 1)) << 1;
                int b = (x >> bits);
                coder.Encoder(b, ref ctx[n - 1 + offset]);
                n = (n << 1) | b;
            }
        }
示例#2
0
        internal static void EncodeRaw(IDataCoder coder, int bits, int x)
        {
            int n     = 1;
            int count = 0;
            int m     = (1 << bits);

            while (n < m)
            {
                x = (x & (m - 1)) << 1;
                int b = (x >> bits);
                coder.Encoder(b);
                n = (n << 1) | b;
                count++;
            }
        }
示例#3
0
        /// <summary>
        /// Encodes a sequence of buckets in a given block.
        /// </summary>
        /// <param name="zp"></param>
        /// <param name="bit"></param>
        /// <param name="band"></param>
        /// <param name="blk"></param>
        /// <param name="eblk"></param>
        /// <param name="fbucket"></param>
        /// <param name="nbucket"></param>
        public void EncodeBuckets(IDataCoder zp, int bit, int band,
                                  InterWaveBlock blk, InterWaveBlock eblk, int fbucket, int nbucket)
        {
            // compute state of all coefficients in all buckets
            int bbstate = EncodePrepare(band, fbucket, nbucket, blk, eblk);

            // code root bit
            if ((nbucket < 16) || (bbstate & Active) != 0)
            {
                bbstate |= New;
            }
            else if ((bbstate & Unk) != 0)
            {
                zp.Encoder((bbstate & New) != 0 ? 1 : 0, ref _CtxRoot);
            }

            // code bucket bits
            if ((bbstate & New) != 0)
            {
                for (int buckno = 0; buckno < nbucket; buckno++)
                {
                    // Code bucket bit
                    if ((_BucketState[buckno] & Unk) != 0)
                    {
                        // Context
                        int ctx = 0;
                        if (band > 0)
                        {
                            int     k = (fbucket + buckno) << 2;
                            short[] b = eblk.GetBlock(k >> 4);

                            if (b != null)
                            {
                                k = k & 0xf;
                                if (b[k] != 0)
                                {
                                    ctx += 1;
                                }
                                if (b[k + 1] != 0)
                                {
                                    ctx += 1;
                                }
                                if (b[k + 2] != 0)
                                {
                                    ctx += 1;
                                }
                                if (ctx < 3 && b[k + 3] != 0)
                                {
                                    ctx += 1;
                                }
                            }
                        }

                        if ((bbstate & Active) != 0)
                        {
                            ctx |= 4;
                        }

                        // Code
                        zp.Encoder((_BucketState[buckno] & New) != 0 ? 1 : 0, ref _CtxBucket[band][ctx]);
                    }
                }
            }

            // code new active coefficient (with their sign)
            if ((bbstate & New) != 0)
            {
                int     thres  = _QuantHigh[band];
                sbyte[] cstate = _CoefficientState;

                for (int buckno = 0, cidx = 0; buckno < nbucket; buckno++, cidx += 16)
                {
                    if ((_BucketState[buckno] & New) != 0)
                    {
                        int       i;
                        int       gotcha    = 0;
                        const int maxgotcha = 7;

                        for (i = 0; i < 16; i++)
                        {
                            if ((cstate[i + cidx] & Unk) != 0)
                            {
                                gotcha += 1;
                            }
                        }

                        short[] pcoeff  = blk.GetBlock(fbucket + buckno);
                        short[] epcoeff = eblk.GetInitializedBlock(fbucket + buckno);

                        // iterate within bucket
                        for (i = 0; i < 16; i++)
                        {
                            if ((cstate[i] & Unk) != 0)
                            {
                                // Prepare context
                                int ctx = 0;

                                if (gotcha >= maxgotcha)
                                {
                                    ctx = maxgotcha;
                                }
                                else
                                {
                                    ctx = gotcha;
                                }

                                if ((_BucketState[buckno] & Active) != 0)
                                {
                                    ctx |= 8;
                                }

                                // Code
                                zp.Encoder((cstate[i] & New) != 0 ? 1 : 0, ref _CtxStart[ctx]);

                                if ((cstate[i] & New) != 0)
                                {
                                    // Code sign
                                    zp.IWEncoder((pcoeff[i] < 0) ? true : false);

                                    // Set encoder state
                                    if (band == 0)
                                    {
                                        thres = _QuantLow[i];
                                    }

                                    epcoeff[i] = (short)(thres + (thres >> 1));
                                }

                                if ((cstate[i] & New) != 0)
                                {
                                    gotcha = 0;
                                }
                                else if (gotcha > 0)
                                {
                                    gotcha -= 1;
                                }
                            }
                        }
                    }
                }
            }

            // code mantissa bits
            if ((bbstate & Active) != 0)
            {
                int     thres  = _QuantHigh[band];
                sbyte[] cstate = _CoefficientState;

                for (int buckno = 0, cidx = 0; buckno < nbucket; buckno++, cidx += 16)
                {
                    if ((_BucketState[buckno] & Active) != 0)
                    {
                        short[] pcoeff  = blk.GetBlock(fbucket + buckno);
                        short[] epcoeff = eblk.GetInitializedBlock(fbucket + buckno);

                        for (int i = 0; i < 16; i++)
                        {
                            if ((cstate[i] & Active) != 0)
                            {
                                // get coefficient
                                int coeff  = pcoeff[i];
                                int ecoeff = epcoeff[i];
                                if (coeff < 0)
                                {
                                    coeff = -coeff;
                                }

                                // get band zero thresholds
                                if (band == 0)
                                {
                                    thres = _QuantLow[i];
                                }

                                // compute mantissa bit
                                int pix = 0;
                                if (coeff >= ecoeff)
                                {
                                    pix = 1;
                                }

                                // encode second or lesser mantissa bit
                                if (ecoeff <= 3 * thres)
                                {
                                    zp.Encoder(pix, ref _CtxMant);
                                }
                                else
                                {
                                    zp.IWEncoder(!!(pix != 0));
                                }

                                // adjust epcoeff
                                epcoeff[i] = (short)(ecoeff - (pix != 0 ? 0 : thres) + (thres >> 1));
                            }
                        }
                    }
                }
            }
        }