public static byte[] Decode(byte[] encodedData, ConcurrentDictionary <BitsWithLength, byte> decodeTable, long bitsCount, int degreeOfParallelism) { var result = new List <byte>(); var sample = new BitsWithLength { Bits = 0, BitsCount = 0 }; for (var byteNum = 0; byteNum < encodedData.Length; byteNum++) { var b = encodedData[byteNum]; for (var bitNum = 0; bitNum < 8 && byteNum * 8 + bitNum < bitsCount; bitNum++) { sample.Bits = (sample.Bits << 1) + ((b & (1 << (8 - bitNum - 1))) != 0 ? 1 : 0); sample.BitsCount++; byte decodedByte; if (decodeTable.TryGetValue(sample, out decodedByte)) { result.Add(decodedByte); sample.BitsCount = 0; sample.Bits = 0; } } } return(result.ToArray()); }
public static byte[] Encode(byte[] data, out ConcurrentDictionary <BitsWithLength, byte> decodeTable, out long bitsCount, int degreeOfParallelism) { var frequences = CalcFrequences(data, degreeOfParallelism); var root = BuildHuffmanTree(frequences); var encodeTable = new BitsWithLength[byte.MaxValue + 1]; FillEncodeTable(root, encodeTable); var dataSize = data.Length; var chunkLength = dataSize / degreeOfParallelism; ParallelEnumerable.Range(0, degreeOfParallelism + 1) .AsOrdered() .WithDegreeOfParallelism(degreeOfParallelism) .Select( i => { var chunk = new BitsBuffer(); var lower = chunkLength * i; var upper = Math.Min(chunkLength * (i + 1), dataSize); for (var j = lower; j < upper; j++) { chunk.Add(encodeTable[data[j]]); } return(chunk); }) .ForEach(AddRange); decodeTable = CreateDecodeTable(encodeTable, degreeOfParallelism); return(globalBuffer.ToArray(out bitsCount)); }
public void Add(BitsWithLength bitsWithLength, int bitsCount = 0) { if (bitsCount == 0) { bitsCount = bitsWithLength.BitsCount; } var bits = bitsWithLength.Bits; var neededBits = 8 - unfinishedBits.BitsCount; while (bitsCount >= neededBits) { bitsCount -= neededBits; buffer.Add((byte)((unfinishedBits.Bits << neededBits) + (bits >> bitsCount))); bits = bits & ((1 << bitsCount) - 1); unfinishedBits.Bits = 0; unfinishedBits.BitsCount = 0; neededBits = 8; } unfinishedBits.BitsCount += bitsCount; unfinishedBits.Bits = (unfinishedBits.Bits << bitsCount) + bits; }
public static byte[] EncodeSequential(byte[] data, out ConcurrentDictionary <BitsWithLength, byte> decodeTable, out long bitsCount, int degreeOfParallelism) { var frequences = CalcFrequences(data, degreeOfParallelism); var root = BuildHuffmanTree(frequences); var encodeTable = new BitsWithLength[byte.MaxValue + 1]; FillEncodeTable(root, encodeTable); var bitsBuffer = new BitsBuffer(); foreach (var b in data) { bitsBuffer.Add(encodeTable[b]); } decodeTable = CreateDecodeTable(encodeTable, degreeOfParallelism); return(bitsBuffer.ToArray(out bitsCount)); }