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));
        }
示例#2
0
        public void Encode(ArithmeticCoder coder, long budget)
        {
            _coder  = coder;
            _budget = budget;

            Init();

            var thresholdBits = (int)Math.Floor(Math.Log(_threshold) / Math.Log(2) + 0.00001);

            _coder.EncodeSymbol(_thresholdModel, thresholdBits);

            _threshold = 1 << thresholdBits;

            for (; thresholdBits >= 0; thresholdBits--)
            {
                if (!SortingPass1())
                {
                    break;
                }
                if (!SortingPass2())
                {
                    break;
                }
                if (!RefinementPass())
                {
                    break;
                }

                _threshold >>= 1;

                GC.Collect();
            }

            EndEncoding();
        }
        /// <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);
        }
        public void LargeFileTest1()
        {
            var path      = TestUtil.GetTestDataDir(TestPathType.ClassName) + "test.wav";
            var inStream  = new FileStream(path, FileMode.Open, FileAccess.Read);
            var outStream = new MemoryStream();
            var stopwatch = Stopwatch.StartNew();

            ArithmeticCoder.EncodeStream(inStream, outStream, 65536, 16);
            var endpoint = stopwatch.Elapsed;

            Console.WriteLine(endpoint);
            Console.WriteLine("Encoded size is {0}", outStream.Position);
        }
        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);
        }
        /// <summary>
        /// Decodes a symbol using the <paramref name="coder"/> with the provided
        /// <paramref name="model"/>.
        /// </summary>
        public static TSymbolType Decode <TSymbolType>(this ArithmeticCoder coder, IModel <TSymbolType> model,
                                                       ReadBitDelegate bitReader)
            where TSymbolType : struct
        {
            // read value
            uint value = coder.DecodeTarget(model.TotalFrequencies);

            // determine symbol
            RangeSymbol <TSymbolType> rangeSymbol = model.Decode(value);

            // adapt decoder
            coder.Decode(rangeSymbol.Range, bitReader);

            // update model
            model.Update(rangeSymbol.Symbol);

            return(rangeSymbol.Symbol);
        }
        public void TestArithmeticStreamsRoundtrip1()
        {
            const string testString     = "ユチエフ-8は素晴らしいです";
            var          data           = Encoding.UTF8.GetBytes(testString);
            var          originalStream = new MemoryStream(data, false);
            var          encodedStream  = new MemoryStream();

            ArithmeticCoder.EncodeStream(originalStream, encodedStream);
            var decodedStream = new MemoryStream();

            encodedStream.Position = 0;
            ArithmeticCoder.DecodeStream(encodedStream, decodedStream);
            var decodedData  = decodedStream.ToArray();
            var encodedData  = encodedStream.ToArray();
            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 + 258);
            Assert.AreEqual(testString, resultString);
        }
        private static void CompressTest(HyperspectralImage image, string tempPath, string restoredPath, double compression)
        {
            var sw = new Stopwatch();

            sw.Start();

            IntPtr tempData     = Marshal.AllocHGlobal(image.SizeInBytes());
            IntPtr restoredData = Marshal.AllocHGlobal(image.SizeInBytes());

            var wavelet = new WaveletTransformationController(new Wavelet53RTransformation());

            wavelet.Encode3D(image.ToPointer(), image.ImageInfo.Width, image.ImageInfo.Height, image.ImageInfo.Bands,
                             image.ImageInfo.Width, image.ImageInfo.Height, 0, tempData);


            var budget = (long)(compression * image.SizeInBytes() * 8);

            using (var stream = File.Open(tempPath, FileMode.Create))
            {
                var coder      = new ArithmeticCoder(stream);
                var compressor = new Spiht3DCoder(tempData,
                                                  image.ImageInfo.Width,
                                                  image.ImageInfo.Height,
                                                  image.ImageInfo.Bands);

                compressor.Encode(coder, budget);
            }
            GC.Collect();

            using (var stream = File.Open(tempPath, FileMode.Open))
            {
                var decoder      = new ArithmeticDecoder(stream);
                var decompressor = new Spiht3DDecoder(tempData,
                                                      image.ImageInfo.Width,
                                                      image.ImageInfo.Height,
                                                      image.ImageInfo.Bands);

                decompressor.Decode(decoder, budget);
            }
            GC.Collect();



            wavelet.Decode3D(tempData, image.ImageInfo.Width, image.ImageInfo.Height, image.ImageInfo.Bands,
                             image.ImageInfo.Width, image.ImageInfo.Height, 0, restoredData);

            using (var stream = File.Open(restoredPath, FileMode.Create))
            {
                HyperspectralImage.Save(HyperspectralImage.Load(restoredData, image.ImageInfo), stream);
            }

            Console.WriteLine("Compression 1:{0}. PSNR = {1}", 1 / compression, PSNRCalculator.Calculate(image.ToPointer(), restoredData, image.ImageInfo));
            Console.WriteLine("Compression 1:{0}. MSE = {1}", 1 / compression, PSNRCalculator.CalculateMSE(image.ToPointer(), restoredData, image.ImageInfo));
            sw.Stop();

            Console.WriteLine("{0}:{1} (Ticks: {2})", sw.Elapsed.Seconds, sw.Elapsed.Milliseconds, sw.ElapsedTicks);


            Marshal.FreeHGlobal(tempData);
            Marshal.FreeHGlobal(restoredData);
        }