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