public DataFile Compress(DataFile toCompress)
        {
            var ppmTables = new PPMTables(_maxOrder);
            var ac        = new ArithmeticCoder();

            for (int i = 0; i < toCompress.Length; i++)
            {
                if (i % _cleanUpLimit == 0)
                {
                    ppmTables.CleanUp();
                }

                var entry = new Entry(toCompress.GetByte(i), GetContextFromFile(toCompress, i));
                ContextTable.ToEncode toEncode;
                EncodeInfo            encodeInfo;

                while ((toEncode = ppmTables.LookUpAndUpdate(entry, out encodeInfo)) !=
                       ContextTable.ToEncode.EncodeSymbol)
                {
                    if (toEncode == ContextTable.ToEncode.EncodeEscape)
                    {
                        ac.Encode(encodeInfo.Count, encodeInfo.CumulativeCount, encodeInfo.TotalCount);
                    }
                    entry.NextContext();
                }
                ac.Encode(encodeInfo.Count, encodeInfo.CumulativeCount, encodeInfo.TotalCount);
            }

            ac.FinalizeInterval();
            var output = ac.GetEncodedBitString().ToArray();

            return(new DataFile(output));
        }
        /// <summary>
        /// Encodes <paramref name="symbol"/> using the <paramref name="coder"/> with
        /// the provided <paramref name="model"/>.
        /// </summary>
        public static void Encode <TSymbolType>(this ArithmeticCoder coder, TSymbolType symbol, IModel <TSymbolType> model,
                                                WriteBitDelegate bitWriter)
            where TSymbolType : struct
        {
            // cumulate frequencies
            Range count = model.GetRange(symbol);

            // encode symbol
            coder.Encode(count, model.TotalFrequencies, bitWriter);

            // update model
            model.Update(symbol);
        }
Ejemplo n.º 3
0
        public void TestBasicArithmeticCodingRoundtrip2()
        {
            const string testString   = "ユチエフ-8は素晴らしいです";
            var          data         = Encoding.UTF8.GetBytes(testString);
            var          frequencies  = ArithmeticCoder.CalculateFrequencies(data);
            var          encodedData  = ArithmeticCoder.Encode(data, frequencies);
            var          decodedData  = ArithmeticCoder.Decode(encodedData, frequencies, data.Length);
            var          resultString = Encoding.UTF8.GetString(decodedData);

            Console.WriteLine("{0} {1} {2}", data.Length, encodedData.Length, decodedData.Length);
            Console.WriteLine(encodedData.Aggregate("", (s, b) => s + ", " + b));
            Console.WriteLine(testString);
            Console.WriteLine(resultString);
            Assert.LessOrEqual(encodedData.Length, data.Length);
            Assert.AreEqual(testString, resultString);
        }