/// <summary> /// Encode given data using LZ coding and given dictionary /// </summary> /// <param name="input">Byte array to encode</param> /// <param name="encoderDic">Dictionary implementation</param> /// <returns>Encoded byte array</returns> private static byte[] _asLZEncoded(this byte[] input, ILZ78CodingTable <int> encoderDic) { var twoPass = true; for (int i = 0; i < 256; i++) { var searchKey = new[] { (byte)i }; var codeWord = i; encoderDic.Insert(searchKey, codeWord); } var addedCodeWords = 0; using (var encodedOutput = new ByteMemoryStream((int)(input.Length / 0.6))) { var P = new byte[] { input[0] }; for (int i = 1; i < input.Length; i++) { var C = new byte[] { input[i] }; var PC = P.Concatenate(C); var item = encoderDic.Search(PC); if (item != null) { P = PC; } else { var item2 = encoderDic.Search(P); encodedOutput.AddBytes(item2.CodeWord.AsBytes()); addedCodeWords++; encoderDic.Insert(PC, encoderDic.Count); P = C; } } var item3 = encoderDic.Search(P); encodedOutput.AddBytes(item3.CodeWord.AsBytes()); addedCodeWords++; var encodedBytes = encodedOutput.ReadBytes(); if (twoPass) { return(encodedBytes.AsCompressed(encoderDic.Count - 1, addedCodeWords)); } else { return(encodedBytes); } } }
/// <summary> /// Compress bytes using .Net Core impl. of GZip /// Just for benchmark reason /// </summary> /// <param name="image"></param> /// <returns></returns> public static GZipImageFrame AsGZipEncoded <T>(this T image) where T : ImageFrame { var ret = default(byte[]); using (var outputMs = new ByteMemoryStream(1024)) { using (GZipStream compressionStream = new GZipStream(outputMs.MemoryStream, CompressionMode.Compress)) using (var inputMs = new ByteMemoryStream(image.Image)) { inputMs.MemoryStream.CopyTo(compressionStream); } ret = outputMs.ReadBytes(); } return(new GZipImageFrame(ret)); }
/// <summary> /// Decodes LZ compressed bytes /// </summary> /// <param name="codes">Compressed bytes</param> /// <param name="decoderDic">Dictionary to use in decoding</param> /// <returns>Decompressed data</returns> private static byte[] _asLZDecoded(byte[] codes, ILZ78CodingTable <byte[]> decoderDic) { for (int i = 0; i < 256; i++) { var searchKey = i.AsBytes(); var codeWord = new[] { (byte)i }; decoderDic.Insert(searchKey, codeWord); } //decompress compressed codes as int 32 byte array var decompressedCodes = codes.AsDecompressed(); using (var decodedOutPut = new ByteMemoryStream(decompressedCodes.Length * 2)) { var O = decompressedCodes.AsInt(0).AsBytes(); var S = new byte[0]; var C2 = new byte[0]; var item = decoderDic.Search(O); decodedOutPut.AddBytes(item.CodeWord); for (int i = 4; i < decompressedCodes.Length; i += 4) { var N = decompressedCodes.AsInt(i).AsBytes(); var itemN = decoderDic.Search(N); var itemO = decoderDic.Search(O); if (itemN == null) { S = itemO.CodeWord.Concatenate(C2); } else { S = itemN.CodeWord; } decodedOutPut.AddBytes(S); C2 = new byte[] { S[0] }; var C3 = itemO.CodeWord.Concatenate(C2); decoderDic.Insert(((decoderDic.Count)).AsBytes(), C3); O = N; } return(decodedOutPut.ReadBytes()); } }
/// <summary> /// Decodes compressed image /// </summary> /// <typeparam name="T">Type of image</typeparam> /// <param name="encodedImage">Image encoded bytes</param> /// <returns></returns> public static T AsImageFrame <T>(this GZipImageFrame encodedImage) where T : ImageFrame, new() { var ret2 = new T(); var ret = default(byte[]); using (var inputMs = new ByteMemoryStream(encodedImage.Data)) using (GZipStream decompressionStream = new GZipStream(inputMs.MemoryStream, CompressionMode.Decompress)) using (var outputMs = new ByteMemoryStream(1024)) { decompressionStream.CopyTo(outputMs.MemoryStream); ret = outputMs.ReadBytes(); } ret2.FromBytes(ret); return(ret2); }