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)); }
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); }