private int DecodeNextSymbol() { range = (ulong)(high - low) + 1; var cummulativeSum = (uint)(((code - low + 1) * (ulong)totalSum - 1) / range); var symbolIndex = GetSymbolIndexByCummulativeSum(cummulativeSum, sums); high = GetHighForSymbol(symbolIndex); low = GetLowForSymbol(symbolIndex); while (true) { if (Intervals.ValuesAreInTheSameHalf(low, high)) { high = BitwiseOperations.ShiftLeft1PositionAndFill(high, 1); low = BitwiseOperations.ShiftLeft1PositionAndFill(low, 0); } else if (Intervals.IsInTheSecondQuarter(low) && Intervals.IsInTheThirdQuarter(high)) { high = BitwiseOperations.ExtractSecondMostSignificantBitAndFill(high, 1); low = BitwiseOperations.ExtractSecondMostSignificantBitAndFill(low, 0); code ^= 0x40000000; } else { break; } code = BitwiseOperations.ShiftLeft1PositionAndFill(code, (byte)ReadNextBit()); } return(symbolIndex); }
public void EncodeSymbol(int symbolIndex) { range = (ulong)(high - low) + 1; high = GetHighForSymbol(symbolIndex); low = GetLowForSymbol(symbolIndex); while (true) { if (Intervals.ValuesAreInTheSameHalf(low, high)) { var bit = low >> 31; bitWriter.WriteNBits(1, bit); WriteUnderflowBits(~bit); high = BitwiseOperations.ShiftLeft1PositionAndFill(high, 1); low = BitwiseOperations.ShiftLeft1PositionAndFill(low, 0); } else if (Intervals.IsInTheSecondQuarter(low) && Intervals.IsInTheThirdQuarter(high)) { high = BitwiseOperations.ExtractSecondMostSignificantBitAndFill(high, 1); low = BitwiseOperations.ExtractSecondMostSignificantBitAndFill(low, 0); underflowBits++; } else { return; } } }