/// <summary> /// Method to rebuild the Huffman tree /// </summary> /// <param name="BIS"></param> /// <param name="numNodes"></param> /// <returns></returns> private BinaryTreeNode <byte> ReadHuffManTree(BitInputStream BIS, int numNodes) { BinaryTreeNode <byte>[] nodeArray = new BinaryTreeNode <byte> [numNodes]; int numBits = numNodes * 14 - 5; int counter = 0; while (counter != numNodes) { long k = ReadGivenBits(1, BIS); if (k == 0) { long byteValue = ReadGivenBits(8, BIS); BinaryTreeNode <byte> newLeafNode = new BinaryTreeNode <byte>((byte)byteValue, null, null); nodeArray[counter] = newLeafNode; } else { long leftChildIndex = ReadGivenBits(9, BIS); long rightChildIndex = ReadGivenBits(9, BIS); BinaryTreeNode <byte> newBinNode = new BinaryTreeNode <byte>(0, nodeArray[leftChildIndex], nodeArray[rightChildIndex]); nodeArray[counter] = newBinNode; } counter++; } return(nodeArray[numNodes - 1]); }
public HZIPReader(Stream bin) { codeTree = new HuffmanTree( ); codeTree.ReadEncodingTable(bin); bitstream = new BitInputStream(bin); }
public void BitStream_IntDelta_Random() { var buffer = new byte[1024 * 64]; var output = new BitOutputStream(buffer); var values = new int[1024]; var random = new Random(1032); long previous = 0; for (int i = 0; i < 1024; ++i) { values[i] = random.Next(int.MinValue, int.MaxValue); output.WriteIntDelta(values[i], previous); previous = values[i]; } output.Flush(); var input = new BitInputStream(buffer); previous = 0; for (int i = 0; i < 1024; ++i) { var value = input.ReadIntDelta(previous); Assert.AreEqual(values[i], value); previous = value; } }
public (string, HuffmanTree) CondenseToTree(string w) { var tree = HuffmanTree.AssembleTree(CharCountDeterminer.GetAllFromString(w)); var b = new BitInputStream(); var charArray = w.ToCharArray(); var first = charArray[0]; b.AddFromStringSource(tree[first]); for (var i = 1; i < charArray.Length; i++) { var current = charArray[i]; var relPath = tree[current]; b.AddFromStringSource(relPath); } var output = new StringBuilder(); b.Flush(); output.Append(b.ToChars()); return(output.ToString(), tree); }
public (string, HuffmanChain) Condense(string w) { var chain = new HuffmanChain(w); if (w.Length == 0) { return("", chain); } var b = new BitInputStream(); var charArray = w.ToCharArray(); char first = charArray[0], pre = first; b.AddFromStringSource(chain[first]); for (var i = 1; i < charArray.Length; i++) { var current = charArray[i]; var relPath = chain[current, pre]; b.AddFromStringSource(relPath); pre = current; } var output = new StringBuilder(); b.Flush(); output.Append(b.ToChars()); return(output.ToString(), chain); }
// Decompression part------------------------------------------------------------------ /// <summary> /// Read the given number of bits /// </summary> /// <param name="numBits"></param> /// <param name="BIS"></param> /// <returns></returns> private long ReadGivenBits(int numBits, BitInputStream BIS) { int bitsRead = 0; long check = BIS.ReadBits(numBits, out bitsRead); if (numBits != bitsRead) { throw new IOException(); } return(check); }
/// <summary> /// Method to Decompress the file /// </summary> /// <param name="BIS"></param> /// <param name="fn"></param> /// <param name="numbytes"></param> /// <param name="HuffTree"></param> private void DecompressFile(BitInputStream BIS, string fn, long numbytes, BinaryTreeNode <byte> HuffTree) { using (FileStream fs = new FileStream(fn, FileMode.Create, FileAccess.Write)) { int counter = 0; while (counter != numbytes) { byte DataToWrite = ReadCompressedByte(BIS, HuffTree); fs.WriteByte(DataToWrite); counter++; } } }
public void CopyByteArray(ref BitInputStream input) { var count = (int)input.ReadUIntPacked(); WriteUIntPacked((uint)count); if (count > 0) { Align(); input.Align(); input.ReadBytes(m_Buffer, m_CurrentByteIdx, count); m_CurrentByteIdx += count; } }
/// <summary> /// Read to get the values for each huffman leave /// </summary> /// <param name="BIS"></param> /// <param name="huffTree"></param> /// <returns></returns> private byte ReadCompressedByte(BitInputStream BIS, BinaryTreeNode <byte> huffTree) { while (true) { if (huffTree.LeftChild == null && huffTree.RightChild == null) { return(huffTree.Data); } if (ReadGivenBits(1, BIS) == 0) { huffTree = huffTree.LeftChild; } else { huffTree = huffTree.RightChild; } } }
public ArithmeticDecoder(BitInputStream inputStream) { const long fullRange = 1L << 32; _halfRange = fullRange >> 1; _quarterRange = _halfRange >> 1; _stateMask = fullRange - 1; _low = 0; _high = _stateMask; Input = inputStream; _code = 0; for (var i = 0; i < 32; i++) { _code = _code << 1 | ReadCodeBit(); } }
public void BitStream_AlignAndByteArray() { var random = new Random(1293); var numbers = new int[1024]; var payload = new byte[32]; var payloadCompare = new byte[32]; random.NextBytes(payload); var buffer = new byte[1024 * 1024]; for (int runs = 0; runs < 1; ++runs) { for (int i = 0; i < 1024; ++i) { numbers[i] = random.Next(1, 33); } var output = new BitOutputStream(buffer); for (int i = 0; i < 1024; ++i) { output.WriteBits((uint)numbers[i], numbers[i]); if (i % 3 == 0) { output.WriteBytes(payload, 0, numbers[i]); } } var input = new BitInputStream(buffer); for (int i = 0; i < 1024; ++i) { var value = input.ReadBits(numbers[i]); Assert.AreEqual((uint)numbers[i], value); if (i % 3 == 0) { input.ReadBytes(payloadCompare, 0, numbers[i]); Assert.AreEqual(0, NetworkUtils.MemCmp(payload, 0, payloadCompare, 0, numbers[i])); } } } }
public static float[] getCompressedFloatsArray(byte[] data, float precision) { if (data == null || data.Length == 0) { return(new float[0]); } BitInputStream bitInputStream = new BitInputStream(data); int min = bitInputStream.ReadBits(24) - MIDDLE_VALUE; int bitsSize = bitInputStream.ReadBits(8); int size = bitInputStream.ReadBits(24); float[] values = new float[size]; for (int i = 0; i < values.Length; i++) { int read = bitInputStream.ReadBits(bitsSize); values[i] = (min + read) * precision; } return(values); }
public void BitStream_UIntPacked_RandomUInt() { var buffer = new byte[1024 * 64]; var output = new BitOutputStream(buffer); var values = new uint[1024]; var random = new Random(1032); for (int i = 0; i < 1024; ++i) { values[i] = (uint)random.Next(int.MaxValue); output.WriteUIntPacked(values[i]); } output.Flush(); var input = new BitInputStream(buffer); for (int i = 0; i < 1024; ++i) { var value = input.ReadUIntPacked(); Assert.AreEqual(values[i], value); } }
/// <summary> /// Event Handler for Decompression Button /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void uxDecompressButton_Click(object sender, EventArgs e) { try { if (uxOpenFileDialog2.ShowDialog() == DialogResult.OK) { string OpenFile = uxOpenFileDialog2.FileName; using (BitInputStream BIS = new BitInputStream(OpenFile)) { long first63Bits = ReadGivenBits(63, BIS); long next9Bits = ReadGivenBits(9, BIS); BinaryTreeNode <byte> huffTree; // If file length is 0, use a null HuffMan Tree if (first63Bits == 0) { huffTree = null; } else { huffTree = ReadHuffManTree(BIS, (int)next9Bits); } if (uxSaveFileDialog2.ShowDialog() == DialogResult.OK) { string SaveFile = uxSaveFileDialog2.FileName; DecompressFile(BIS, SaveFile, first63Bits, huffTree); MessageBox.Show("Decompressed File Written"); } } } } catch (Exception ex) { MessageBox.Show(ex.ToString()); } }
public void BitStream_Align() { var random = new Random(1293); var numbers = new int[1024]; var buffer = new byte[1024 * 64]; for (int runs = 0; runs < 1000; ++runs) { for (int i = 0; i < 1024; ++i) { numbers[i] = random.Next(1, 33); } var output = new BitOutputStream(buffer); for (int i = 0; i < 1024; ++i) { output.WriteBits((uint)numbers[i], numbers[i]); if (i % 3 == 0) { output.Align(); } } var input = new BitInputStream(buffer); for (int i = 0; i < 1024; ++i) { var value = input.ReadBits(numbers[i]); Assert.AreEqual((uint)numbers[i], value); if (i % 3 == 0) { input.Align(); } } } }
public int ProcessPackageHeader(byte[] packageData, out NetworkMessage content, out int headerSize) { counters.packagesIn++; var input = new BitInputStream(packageData); headerSize = 0; int headerStartInBits = input.GetBitPosition(); content = (NetworkMessage)input.ReadBits(8); var inSequenceNew = Sequence.FromUInt16((ushort)input.ReadBits(16), inSequence); var outSequenceAckNew = Sequence.FromUInt16((ushort)input.ReadBits(16), outSequenceAck); var outSequenceAckMaskNew = (ushort)input.ReadBits(16); if (inSequenceNew > inSequence) { // If we have a hole in the package sequence that will fall off the ack mask that // means the package (inSequenceNew-15 and before) will be considered lost (either it will never come or we will // reject it as being stale if we get it at a later point in time) var distance = inSequenceNew - inSequence; for (var i = 0; i < Math.Min(distance, 15); ++i) // TODO : Fix this contant { if ((inSequenceAckMask & 1 << (15 - i)) == 0) { counters.packagesLostIn++; } } // If there is a really big hole then those packages are considered lost as well // Update the incoming ack mask. if (distance > 15) { counters.packagesLostIn += distance - 15; inSequenceAckMask = 1; // all is lost except current package } else { inSequenceAckMask <<= distance; inSequenceAckMask |= 1; } inSequence = inSequenceNew; inSequenceTime = NetworkUtils.stopwatch.ElapsedMilliseconds; } else if (inSequenceNew < inSequence) { // Package is out of order // Check if the package is stale var distance = inSequence - inSequenceNew; if (distance > 15) // TODO : Fix this constant { counters.packagesStaleIn++; return(0); } // Check if the package is a duplicate var ackBit = 1 << distance; if ((ackBit & inSequenceAckMask) != 0) { // Duplicate package counters.packagesDuplicateIn++; return(0); } // Accept the package out of order //counters.packagesOutOfOrderIn++; inSequenceAckMask |= (ushort)ackBit; } else { // Duplicate package counters.packagesDuplicateIn++; return(0); } if (inSequenceNew % 3 == 0) { var timeOnServer = (ushort)input.ReadBits(8); TPackageInfo info; if (outstandingPackages.TryGetValue(outSequenceAckNew, out info)) { var now = NetworkUtils.stopwatch.ElapsedMilliseconds; rtt = (int)(now - info.SentTime - timeOnServer); } } // If the ack sequence is not higher we have nothing new to do if (outSequenceAckNew <= outSequenceAck) { headerSize = input.Align(); return(inSequenceNew); } // Find the sequence numbers that we have to consider lost var seqsBeforeThisAlreadyNotifedAsLost = outSequenceAck - 15; var seqsBeforeThisAreLost = outSequenceAckNew - 15; for (int sequence = seqsBeforeThisAlreadyNotifedAsLost; sequence <= seqsBeforeThisAreLost; ++sequence) { // Handle conditions before first 15 packets if (sequence < 0) { continue; } // If seqence covered by old ack mask, we may already have received it (and notified) int bitnum = outSequenceAck - sequence; var ackBit = bitnum >= 0 ? 1 << bitnum : 0; var notNotified = (ackBit & outSequenceAckMask) == 0; if (outstandingPackages.Exists(sequence) && notNotified) { var info = outstandingPackages[sequence]; NotifyDelivered(sequence, info, false); counters.packagesLostOut++; info.Reset(); outstandingPackages.Remove(sequence); } } outSequenceAck = outSequenceAckNew; outSequenceAckMask = outSequenceAckMaskNew; // Ack packages if they haven't been acked already for (var sequence = Math.Max(outSequenceAck - 15, 0); sequence <= outSequenceAck; ++sequence) { var ackBit = 1 << outSequenceAck - sequence; if (outstandingPackages.Exists(sequence) && (ackBit & outSequenceAckMask) != 0) { var info = outstandingPackages[sequence]; NotifyDelivered(sequence, info, true); info.Reset(); outstandingPackages.Remove(sequence); } } headerSize = input.Align(); return(inSequenceNew); }
/// <summary> /// General method which takes an Input and Output file and rebuilds a Huffman trees and takes the compressed data and uses the Huffman tree to decompress it. /// </summary> /// <param name="inputStream">Compressed file stream to decompress</param> /// <param name="outputStream">Uncompressed file stream to write decompressed bytes to</param> private void DecompressStream(BitInputStream inputStream, FileStream outputStream) { long numBytes = ReadBits(inputStream, 63); long numNodes = ReadBits(inputStream, 9); if (numBytes > 0 && numNodes == 0) throw new IOException(_errorMessage); BinaryTreeNode<byte> huffTree = RecontstructHuffmanTree(inputStream, numNodes); for (int i = 0; i < numBytes; i++) WriteDecompressedByte(inputStream, outputStream, huffTree); }
/// <summary> /// Reads Bits from given BitInputStream /// </summary> /// <param name="inputStream">Stream to read from</param> /// <param name="numberToRead">Number of bits to read from the stream.</param> /// <returns>A long of the bits in the stream.</returns> private long ReadBits(BitInputStream inputStream, int numberToRead) { int numRead = 0; long results = inputStream.ReadBits(numberToRead, out numRead); if (numRead == 0) throw new IOException(_errorMessage); else return results; }
/// <summary> /// Event Handler for Decompression Button /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void uxDecompressButton_Click(object sender, EventArgs e) { try { if(uxOpenFileDialog2.ShowDialog() == DialogResult.OK) { string OpenFile = uxOpenFileDialog2.FileName; using (BitInputStream BIS = new BitInputStream(OpenFile)) { long first63Bits = ReadGivenBits(63, BIS); long next9Bits = ReadGivenBits(9, BIS); BinaryTreeNode<byte> huffTree; // If file length is 0, use a null HuffMan Tree if (first63Bits == 0) { huffTree = null; } else { huffTree = ReadHuffManTree(BIS, (int)next9Bits); } if (uxSaveFileDialog2.ShowDialog() == DialogResult.OK) { string SaveFile = uxSaveFileDialog2.FileName; DecompressFile(BIS, SaveFile, first63Bits, huffTree); MessageBox.Show("Decompressed File Written"); } } } } catch (Exception ex) { MessageBox.Show(ex.ToString()); } }
/// <summary> /// Method to rebuild the Huffman tree /// </summary> /// <param name="BIS"></param> /// <param name="numNodes"></param> /// <returns></returns> private BinaryTreeNode<byte> ReadHuffManTree(BitInputStream BIS, int numNodes) { BinaryTreeNode<byte>[] nodeArray = new BinaryTreeNode<byte>[numNodes]; int numBits = numNodes * 14 - 5; int counter = 0; while(counter != numNodes) { long k = ReadGivenBits(1, BIS); if (k == 0) { long byteValue = ReadGivenBits(8, BIS); BinaryTreeNode<byte> newLeafNode = new BinaryTreeNode<byte>((byte)byteValue, null, null); nodeArray[counter] = newLeafNode; } else { long leftChildIndex = ReadGivenBits(9, BIS); long rightChildIndex = ReadGivenBits(9, BIS); BinaryTreeNode<byte> newBinNode = new BinaryTreeNode<byte>(0,nodeArray[leftChildIndex], nodeArray[rightChildIndex]); nodeArray[counter] = newBinNode; } counter++; } return nodeArray[numNodes - 1]; }
// Decompression part------------------------------------------------------------------ /// <summary> /// Read the given number of bits /// </summary> /// <param name="numBits"></param> /// <param name="BIS"></param> /// <returns></returns> private long ReadGivenBits(int numBits, BitInputStream BIS) { int bitsRead = 0; long check = BIS.ReadBits(numBits, out bitsRead); if(numBits != bitsRead) { throw new IOException(); } return check; }
/// <summary> /// Read to get the values for each huffman leave /// </summary> /// <param name="BIS"></param> /// <param name="huffTree"></param> /// <returns></returns> private byte ReadCompressedByte(BitInputStream BIS, BinaryTreeNode<byte> huffTree) { while(true) { if (huffTree.LeftChild == null && huffTree.RightChild == null) { return huffTree.Data; } if(ReadGivenBits(1,BIS) == 0) { huffTree = huffTree.LeftChild; } else { huffTree = huffTree.RightChild; } } }
/// <summary> /// Method to Decompress the file /// </summary> /// <param name="BIS"></param> /// <param name="fn"></param> /// <param name="numbytes"></param> /// <param name="HuffTree"></param> private void DecompressFile(BitInputStream BIS, string fn, long numbytes, BinaryTreeNode<byte> HuffTree) { using (FileStream fs = new FileStream(fn, FileMode.Create, FileAccess.Write)) { int counter = 0; while(counter != numbytes) { byte DataToWrite = ReadCompressedByte(BIS, HuffTree); fs.WriteByte(DataToWrite); counter++; } } }
/// <summary> /// Reconstructs a Huffman tree from BitInputStreams /// </summary> /// <param name="inputStream">InputStream to read bits from to construct tree from.</param> /// <param name="numberOfNodes">Number of nodes to construct in tree.</param> /// <returns>A fully generated Huffman Tree</returns> private BinaryTreeNode<byte> RecontstructHuffmanTree(BitInputStream inputStream, long numberOfNodes) { BinaryTreeNode<byte>[] nodes = new BinaryTreeNode<byte>[numberOfNodes]; int index = 0; foreach(BinaryTreeNode<byte> node in nodes) { if (ReadBits(inputStream, 1) == 1) { BinaryTreeNode<byte> tmp = new BinaryTreeNode<byte>(); tmp.IsEmpty = false; tmp.RootValue = (byte)ReadBits(inputStream, 8); nodes[index] = tmp; index++; } else { BinaryTreeNode<byte> tmp = new BinaryTreeNode<byte>(); tmp.IsEmpty = false; tmp.LeftChild = RetrieveHuffmanTree(inputStream, nodes, index); tmp.RightChild = RetrieveHuffmanTree(inputStream, nodes, index); nodes[index] = tmp; index++; } } return nodes[index - 1]; }
public void Initialize(byte[] buffer) { this = new BitInputStream(buffer); }
// Returns the 'wide' packageSequenceNumber (i.e. 32 bit reconstructed from the 16bits sent over wire) protected int ProcessPackageHeader(byte[] packageData, int packageSize, out NetworkMessage content, out byte[] assembledData, out int assembledSize, out int headerSize) { counters.packagesIn++; assembledData = packageData; assembledSize = packageSize; headerSize = 0; var input = new BitInputStream(packageData); int headerStartInBits = input.GetBitPosition(); content = (NetworkMessage)input.ReadBits(8); // TODO: Possible improvement is to ack on individual fragments not just entire message if ((content & NetworkMessage.FRAGMENT) != 0) { // Package fragment var fragmentPackageSequence = Sequence.FromUInt16((ushort)input.ReadBits(16), inSequence); var numFragments = (int)input.ReadBits(8); var fragmentIndex = (int)input.ReadBits(8); var fragmentSize = (int)input.ReadBits(16); FragmentReassemblyInfo assembly; if (!m_FragmentReassembly.TryGetValue(fragmentPackageSequence, out assembly)) { // If we run out of room in the reassembly buffer we will not be able to reassemble this package if (!m_FragmentReassembly.Available(fragmentPackageSequence)) { counters.fragmentedPackagesLostIn++; } GameDebug.Assert(numFragments <= NetworkConfig.maxFragments); assembly = m_FragmentReassembly.Acquire(fragmentPackageSequence); assembly.numFragments = numFragments; assembly.receivedMask = 0; assembly.receivedCount = 0; } GameDebug.Assert(assembly.numFragments == numFragments); GameDebug.Assert(fragmentIndex < assembly.numFragments); counters.headerBitsIn += input.GetBitPosition() - headerStartInBits; if ((assembly.receivedMask & (1U << fragmentIndex)) != 0) { // Duplicate package fragment counters.packagesDuplicateIn++; return(0); } assembly.receivedMask |= 1U << fragmentIndex; assembly.receivedCount++; input.ReadBytes(assembly.data, fragmentIndex * NetworkConfig.packageFragmentSize, fragmentSize); if (assembly.receivedCount < assembly.numFragments) { return(0); // Not fully assembled } // Continue processing package as we have now reassembled the package assembledData = assembly.data; assembledSize = fragmentIndex * NetworkConfig.packageFragmentSize + fragmentSize; input.Initialize(assembledData); headerStartInBits = 0; content = (NetworkMessage)input.ReadBits(8); } var inSequenceNew = Sequence.FromUInt16((ushort)input.ReadBits(16), inSequence); var outSequenceAckNew = Sequence.FromUInt16((ushort)input.ReadBits(16), outSequenceAck); var outSequenceAckMaskNew = (ushort)input.ReadBits(16); if (inSequenceNew > inSequence) { // If we have a hole in the package sequence that will fall off the ack mask that // means the package (inSequenceNew-15 and before) will be considered lost (either it will never come or we will // reject it as being stale if we get it at a later point in time) var distance = inSequenceNew - inSequence; for (var i = 0; i < Math.Min(distance, 15); ++i) // TODO : Fix this contant { if ((inSequenceAckMask & 1 << (15 - i)) == 0) { counters.packagesLostIn++; } } // If there is a really big hole then those packages are considered lost as well // Update the incoming ack mask. if (distance > 15) { counters.packagesLostIn += distance - 15; inSequenceAckMask = 1; // all is lost except current package } else { inSequenceAckMask <<= distance; inSequenceAckMask |= 1; } inSequence = inSequenceNew; inSequenceTime = NetworkUtils.stopwatch.ElapsedMilliseconds; } else if (inSequenceNew < inSequence) { // Package is out of order // Check if the package is stale // NOTE : We rely on the fact that we will reject packages that we cannot ack due to the size // of the ack mask, so we don't have to worry about resending messages as long as we do that // after the original package has fallen off the ack mask. var distance = inSequence - inSequenceNew; if (distance > 15) // TODO : Fix this constant { counters.packagesStaleIn++; return(0); } // Check if the package is a duplicate var ackBit = 1 << distance; if ((ackBit & inSequenceAckMask) != 0) { // Duplicate package counters.packagesDuplicateIn++; return(0); } // Accept the package out of order counters.packagesOutOfOrderIn++; inSequenceAckMask |= (ushort)ackBit; } else { // Duplicate package counters.packagesDuplicateIn++; return(0); } if (inSequenceNew % 3 == 0) { var timeOnServer = (ushort)input.ReadBits(8); TPackageInfo info; if (outstandingPackages.TryGetValue(outSequenceAckNew, out info)) { var now = NetworkUtils.stopwatch.ElapsedMilliseconds; rtt = (int)(now - info.sentTime - timeOnServer); } } // If the ack sequence is not higher we have nothing new to do if (outSequenceAckNew <= outSequenceAck) { headerSize = input.Align(); return(inSequenceNew); } // Find the sequence numbers that we have to consider lost var seqsBeforeThisAlreadyNotifedAsLost = outSequenceAck - 15; var seqsBeforeThisAreLost = outSequenceAckNew - 15; for (int sequence = seqsBeforeThisAlreadyNotifedAsLost; sequence <= seqsBeforeThisAreLost; ++sequence) { // Handle conditions before first 15 packets if (sequence < 0) { continue; } // If seqence covered by old ack mask, we may already have received it (and notified) int bitnum = outSequenceAck - sequence; var ackBit = bitnum >= 0 ? 1 << bitnum : 0; var notNotified = (ackBit & outSequenceAckMask) == 0; if (outstandingPackages.Exists(sequence) && notNotified) { var info = outstandingPackages[sequence]; NotifyDelivered(sequence, info, false); counters.packagesLostOut++; if (info.fragmented) { counters.fragmentedPackagesLostOut++; } info.Reset(); outstandingPackages.Remove(sequence); } } outSequenceAck = outSequenceAckNew; outSequenceAckMask = outSequenceAckMaskNew; // Ack packages if they haven't been acked already for (var sequence = Math.Max(outSequenceAck - 15, 0); sequence <= outSequenceAck; ++sequence) { var ackBit = 1 << outSequenceAck - sequence; if (outstandingPackages.Exists(sequence) && (ackBit & outSequenceAckMask) != 0) { var info = outstandingPackages[sequence]; NotifyDelivered(sequence, info, true); info.Reset(); outstandingPackages.Remove(sequence); } } counters.headerBitsIn += input.GetBitPosition() - headerStartInBits; headerSize = input.Align(); return(inSequenceNew); }
/// <summary> /// Retrieves a specific Huffman tree from the array of them. /// </summary> /// <param name="inputStream">Stream to read bits from</param> /// <param name="huffTrees">Array of Huffman trees to choose from</param> /// <param name="numberOfTrees">Number of filled trees in the array</param> /// <returns>Returns the Huffman tree that is needed that is requested in the BitStream.</returns> private BinaryTreeNode<byte> RetrieveHuffmanTree(BitInputStream inputStream, BinaryTreeNode<byte>[] huffTrees, int numberOfTrees) { int bitsRead = 0; int spot = (int)inputStream.ReadBits(9, out bitsRead); if (bitsRead < 9) throw new IOException(_errorMessage); return huffTrees[spot]; }
/// <summary> /// Handles a decompress button click. /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void uxDecompress_Click(object sender, EventArgs e) { if (uxOpenFileDialog.ShowDialog() == DialogResult.OK) { if (uxSaveFileDialog.ShowDialog() == DialogResult.OK) { try { using (BitInputStream input = new BitInputStream(uxOpenFileDialog.FileName)) { using (FileStream output = File.OpenWrite(uxSaveFileDialog.FileName)) { DecompressStream(input, output); } } } catch (Exception ex) { DisplayError(ex); } } } }
/// <summary> /// Decompressses and writes the current byte in the inputStream to the outputstream. /// </summary> /// <param name="inputStream">File of compressed data to decompress.</param> /// <param name="outputStream">File to write uncompressed data to.</param> /// <param name="huffTree">Huffman tree used to decode with</param> private void WriteDecompressedByte(BitInputStream inputStream, FileStream outputStream, BinaryTreeNode<byte> huffTree) { while (huffTree.LeftChild != null || huffTree.RightChild != null) { if (ReadBits(inputStream, 1) == 0) huffTree = huffTree.LeftChild; else huffTree = huffTree.RightChild; } outputStream.WriteByte(huffTree.RootValue); }