const int ChunkSize = 128 * 1024; // 128Kb throttling public EncodingToken CreateEncodingToken(IEncodingInputStream inputStream, CancellationToken cancellationToken) { Guard.IsNotNull(inputStream, nameof(inputStream)); WeightsTable weightsTable = BuildWeightsTable(inputStream, cancellationToken); HuffmanTreeBase huffmanTree = BuildHuffmanTree(weightsTable); CodingTable codingTable = BuildCodingTable(huffmanTree); return(new EncodingToken(weightsTable, huffmanTree, codingTable)); }
public void Decode(IDecodingInputStream inputStream, WeightsTable weightsTable, IDecodingOutputStream outputStream, long sequenceLength, CancellationToken cancellationToken, IProgressHandler progress) { Guard.IsNotNull(inputStream, nameof(inputStream)); Guard.IsNotNull(weightsTable, nameof(weightsTable)); Guard.IsNotNull(outputStream, nameof(outputStream)); Guard.IsNotNegative(sequenceLength, nameof(sequenceLength)); HuffmanTreeBase tree = new HuffmanEncoder().BuildHuffmanTree(weightsTable); Decode(inputStream, tree, outputStream, sequenceLength, cancellationToken, progress); }
public WeightsTable BuildWeightsTable(IEncodingInputStream inputStream, CancellationToken cancellationToken) { Guard.IsNotNull(inputStream, nameof(inputStream)); WeightsTable weightsTable = new WeightsTable(); int currentChunkSz = 0; while (inputStream.ReadSymbol(out byte symbol)) { weightsTable.TrackSymbol(symbol); if (++currentChunkSz == ChunkSize) { cancellationToken.ThrowIfCancellationRequested(); currentChunkSz = 0; } } return(weightsTable); }
public HuffmanTreeBase BuildHuffmanTree(WeightsTable weightsTable) { Guard.IsNotNull(weightsTable, nameof(weightsTable)); HuffmanTreeNodePriorityQueue priorityQueue = new HuffmanTreeNodePriorityQueue(); foreach (WeightedSymbol weightedSymbol in weightsTable) { priorityQueue.Insert(weightedSymbol.Weight, new HuffmanTreeNode(weightedSymbol)); } if (priorityQueue.Size == 0) { return(EmptyHuffmanTree.Instance); } while (priorityQueue.Size > 1) { var lNode = priorityQueue.DeleteMinimumValue(); var rNode = priorityQueue.DeleteMinimumValue(); long weight = lNode.Value.Weight + rNode.Value.Weight; var internalNode = new HuffmanTreeNode(new WeightedSymbol(0, weight), lNode, rNode); priorityQueue.Insert(weight, internalNode); } return(new HuffmanTree(priorityQueue.GetMinimumValue())); }
public EncodingToken(WeightsTable weightsTable, HuffmanTreeBase huffmanTree, CodingTable codingTable) { CodingTable = codingTable; WeightsTable = weightsTable; HuffmanTree = huffmanTree; }