Ejemplo n.º 1
0
        private uint DecodeSymbol()
        {
            Range = (ulong)(High - Low) + 1;

            uint code_sum = (uint)(((ulong)(Code - Low + 1) * arithmeticModel.GetSymbolTotalSum() - 1) / Range);
            uint symbol   = arithmeticModel.GetSymbolForSpecifiedSum(code_sum);

            High = Low + (uint)((Range * arithmeticModel.GetSymbolSumLimitH(symbol)) / arithmeticModel.GetSymbolTotalSum() - 1);
            Low  = Low + (uint)((Range * arithmeticModel.GetSymbolSumLimitL(symbol)) / arithmeticModel.GetSymbolTotalSum());


            for (; ;)
            {
                if ((High & firstShiftingMask) == (Low & firstShiftingMask))
                {
                    Low  <<= 1;
                    High <<= 1;
                    High  |= 1;
                    Code   = (Code << 1) | reader.ReadNBits(1);
                }
                else if ((Low & secondShiftingMask) == 0x40000000 && (High & secondShiftingMask) == 0x80000000)
                {
                    Code = ((Code ^ 0x40000000) << 1) | reader.ReadNBits(1);
                    High = ((High | 0x40000000) << 1) | 1;
                    Low  = (Low & 0x3FFFFFFF) << 1;
                }
                else
                {
                    break;
                }
            }
            return(symbol);
        }
        private void EncodeSymbol(uint symbol)
        {
            Range = (ulong)High - Low + 1;
            High  = Low + (uint)((Range * arithmeticModel.GetSymbolSumLimitH(symbol)) / arithmeticModel.GetSymbolTotalSum() - 1);
            Low   = Low + (uint)((Range * arithmeticModel.GetSymbolSumLimitL(symbol)) / arithmeticModel.GetSymbolTotalSum());

            for (; ;)
            {
                // Test First shift MSB(H) = MSB(L) = 0 or MSB(H) = MSB(L) = 1
                if ((High & firstShiftingMask) == (Low & firstShiftingMask))
                {
                    // Send the stabilized bit and the shiftings
                    uint msbFromHigh = (High >> 31);
                    WriteBitAndUnderflowBits(msbFromHigh);

                    // Set the last bit from High and Low
                    High <<= 1;
                    High  |= 1;
                    Low  <<= 1;
                }
                // Test Second shift (first 2 semnificative bits of H = 10; L = 01;)
                else if ((Low & secondShigtingMask) == 0x40000000 && (High & secondShigtingMask) == 0x80000000)
                {
                    UnderflowBits++;
                    High |= 0x40000000;
                    Low  &= 0x3FFFFFFF;

                    // Set the last bit from High and Low
                    High <<= 1;
                    High  |= 1;
                    Low  <<= 1;
                }
                else
                {
                    return;
                }
            }
        }