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)); }
private static void AddRange(BitsBuffer chunk) { foreach (var b in chunk.buffer) { globalBuffer.Add(new BitsWithLength { Bits = b, BitsCount = 8 }, 8); } globalBuffer.Add(chunk.unfinishedBits); }
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)); }