/// <summary> /// Return an int giving the node number of the root /// </summary> /// <param name="huffTree"></param> /// <param name="BOS"></param> /// <param name="NodesWritten"></param> /// <returns></returns> private int FindNodeNumber(BinaryTreeNode <byte> huffTree, BitOutputStream BOS, int NodesWritten) { if (huffTree.LeftChild == null && huffTree.RightChild == null) { BOS.WriteBits(0, 1); BOS.WriteBits(huffTree.Data, 8); NodesWritten++; return(NodesWritten); } else { // Recursively write the children int leftChild = FindNodeNumber(huffTree.LeftChild, BOS, NodesWritten); int rightChild = FindNodeNumber(huffTree.RightChild, BOS, leftChild); // Parent node will be +1 from right child NodesWritten = rightChild + 1; BOS.WriteBits(1, 1); BOS.WriteBits(leftChild, 9); BOS.WriteBits(rightChild, 9); return(NodesWritten); } }
public void Close( ) { byte[] theInput = byteOut.ToArray( ); Console.WriteLine("Read " + theInput.Length + " bytes"); MemoryStream byteIn = new MemoryStream(theInput); CharCounter countObj = new CharCounter(byteIn); byteIn.Close( ); HuffmanTree codeTree = new HuffmanTree(countObj); codeTree.WriteEncodingTable(dout); BitOutputStream bout = new BitOutputStream(dout); for (int i = 0; i < theInput.Length; i++) { bout.WriteBits(codeTree.GetCode(theInput[i] & (0xff))); } bout.WriteBits(codeTree.GetCode(BitUtils.EOF)); bout.Close( ); byteOut.Close( ); }
public void BeginSendPackage(ref BitOutputStream output, out TPackageInfo info) { output.WriteBits(0, 8); // Package content flags (will set later as we add messages) output.WriteBits(Sequence.ToUInt16(outSequence), 16); output.WriteBits(Sequence.ToUInt16(inSequence), 16); output.WriteBits(inSequenceAckMask, 16); // Send rtt info every 3th package. We calculate the RTT as the time from sending the package // and receiving the ack for the package minus the time the package spent on the server if (outSequence % 3 == 0) { var now = NetworkUtils.stopwatch.ElapsedMilliseconds; var timeOnServer = (byte)Math.Min(now - inSequenceTime, 255); output.WriteBits(timeOnServer, 8); } info = outstandingPackages.Acquire(outSequence); }
/// <summary> /// Event handler for compression button /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void uxCompressButton_Click(object sender, EventArgs e) { try { if (uxOpenFileDialog1.ShowDialog() == DialogResult.OK) { string openFile = uxOpenFileDialog1.FileName; long numBytes; long[] ByteArray = BuildFrequencyTable(openFile, out numBytes); MinPriorityQueue <long, BinaryTreeNode <byte> > q = BuildHuffmanTreeLeaves(ByteArray); int numNodes = q.Count * 2 - 1; BinaryTreeNode <byte> huffTree = BuildHuffmanTree(q); long[] bitPaths = new long[256]; int[] pathLengths = new int[256]; GetVariableWidthEncoding(huffTree, 0, 0, bitPaths, pathLengths); string saveFile = null; if (uxSaveFileDialog1.ShowDialog() == DialogResult.OK) { saveFile = uxSaveFileDialog1.FileName; using (BitOutputStream BOS = new BitOutputStream(saveFile)) { // Writes first 63 bits, which describes length of file BOS.WriteBits(numBytes, 63); // Writes 9 bits, number of nodes BOS.WriteBits(numNodes, 9); // Post order tree traversal to assign node numbers int rootNumber = FindNodeNumber(huffTree, BOS, -1); CompressFile(openFile, BOS, bitPaths, pathLengths); } MessageBox.Show("Compressed File Written"); } } } catch (Exception ex) { MessageBox.Show(ex.ToString()); } }
public static byte[] compressFloatsArray(float[] data, float precision) { float recPrecision = 1.0f / precision; int size = data.Length; int maxIndex = size > 0 ? floatToInt(data[0], recPrecision, precision) : 0; int minIndex = maxIndex; for (int i = 0; i < size; i++) { int value = floatToInt(data[i], recPrecision, precision); maxIndex = value < maxIndex ? maxIndex : value; minIndex = value > minIndex ? minIndex : value; } int bitSize = CPShortArrayData.getBitSize(maxIndex - minIndex); /* 7 bytes * 3 for minIndex * 1 for bitSize * 3 for size * 1 for rounding ((size * bitSize) >> 3) */ int bytesSize = ((size * bitSize) >> 3) + 8; BitOutputStream bitOutputStream = new BitOutputStream(bytesSize); bitOutputStream.WriteBits(24, minIndex); bitOutputStream.WriteBits(8, bitSize); bitOutputStream.WriteBits(24, size); for (int i = 0; i < size; i++) { int value = floatToInt(data[i], recPrecision, precision); bitOutputStream.WriteBits(bitSize, value - minIndex); } return(bitOutputStream.GetData()); }
protected void BeginSendPackage(ref BitOutputStream output, out TPackageInfo info) { GameDebug.Assert(outstandingPackages.Available(outSequence), "NetworkConnection.BeginSendPackage : package info not available for sequence : {0}", outSequence); output.WriteBits(0, 8); // Package content flags (will set later as we add messages) output.WriteBits(Sequence.ToUInt16(outSequence), 16); output.WriteBits(Sequence.ToUInt16(inSequence), 16); output.WriteBits(inSequenceAckMask, 16); // Send rtt info every 3th package. We calculate the RTT as the time from sending the package // and receiving the ack for the package minus the time the package spent on the server // TODO should this be sent from client to server? if (outSequence % 3 == 0) { var now = NetworkUtils.stopwatch.ElapsedMilliseconds; // TOULF Is 255 enough? var timeOnServer = (byte)Math.Min(now - inSequenceTime, 255); output.WriteBits(timeOnServer, 8); } info = outstandingPackages.Acquire(outSequence); }
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])); } } } }
/// <summary> /// Method to compress the file /// </summary> /// <param name="fn"></param> /// <param name="BOS"></param> /// <param name="VarWidEnc"></param> /// <param name="lengths"></param> private void CompressFile(string fn, BitOutputStream BOS, long[] VarWidEnc, int[] lengths) { using (FileStream fs = new FileStream(fn, FileMode.Open, FileAccess.Read)) { // Read and append to Output stream int k; while ((k = fs.ReadByte()) != -1) { if (lengths[k] == 0) { return; } else { BOS.WriteBits(VarWidEnc[k], lengths[k]); } } } }
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(); } } } }
/// <summary> /// Event handler for compression button /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void uxCompressButton_Click(object sender, EventArgs e) { try { if (uxOpenFileDialog1.ShowDialog() == DialogResult.OK) { string openFile = uxOpenFileDialog1.FileName; long numBytes; long[] ByteArray = BuildFrequencyTable(openFile, out numBytes); MinPriorityQueue<long, BinaryTreeNode<byte>> q = BuildHuffmanTreeLeaves(ByteArray); int numNodes = q.Count * 2 - 1; BinaryTreeNode<byte> huffTree = BuildHuffmanTree(q); long[] bitPaths = new long[256]; int[] pathLengths = new int[256]; GetVariableWidthEncoding(huffTree,0,0,bitPaths,pathLengths); string saveFile = null; if (uxSaveFileDialog1.ShowDialog() == DialogResult.OK) { saveFile = uxSaveFileDialog1.FileName; using (BitOutputStream BOS = new BitOutputStream(saveFile)) { // Writes first 63 bits, which describes length of file BOS.WriteBits(numBytes, 63); // Writes 9 bits, number of nodes BOS.WriteBits(numNodes, 9); // Post order tree traversal to assign node numbers int rootNumber = FindNodeNumber(huffTree, BOS, -1); CompressFile(openFile, BOS, bitPaths, pathLengths); } MessageBox.Show("Compressed File Written"); } } } catch (Exception ex) { MessageBox.Show(ex.ToString()); } }
/// <summary> /// Return an int giving the node number of the root /// </summary> /// <param name="huffTree"></param> /// <param name="BOS"></param> /// <param name="NodesWritten"></param> /// <returns></returns> private int FindNodeNumber(BinaryTreeNode<byte> huffTree, BitOutputStream BOS, int NodesWritten) { if(huffTree.LeftChild == null && huffTree.RightChild == null) { BOS.WriteBits(0, 1); BOS.WriteBits(huffTree.Data, 8); NodesWritten++; return NodesWritten; } else { // Recursively write the children int leftChild = FindNodeNumber(huffTree.LeftChild, BOS, NodesWritten); int rightChild = FindNodeNumber(huffTree.RightChild, BOS, leftChild); // Parent node will be +1 from right child NodesWritten = rightChild + 1; BOS.WriteBits(1, 1); BOS.WriteBits(leftChild, 9); BOS.WriteBits(rightChild, 9); return NodesWritten; } }
/// <summary> /// Method to compress the file /// </summary> /// <param name="fn"></param> /// <param name="BOS"></param> /// <param name="VarWidEnc"></param> /// <param name="lengths"></param> private void CompressFile(string fn, BitOutputStream BOS, long[] VarWidEnc, int[] lengths) { using (FileStream fs = new FileStream(fn, FileMode.Open, FileAccess.Read)) { // Read and append to Output stream int k; while((k=fs.ReadByte()) != -1) { if(lengths[k] == 0) { return; } else { BOS.WriteBits(VarWidEnc[k], lengths[k]); } } } }
protected int CompleteSendPackage(TPackageInfo info, ref BitOutputStream output) { Profiler.BeginSample("NetworkConnection.CompleteSendPackage()"); info.sentTime = NetworkUtils.stopwatch.ElapsedMilliseconds; info.content = (NetworkMessage)m_PackageBuffer[0]; int packageSize = output.Flush(); GameDebug.Assert(packageSize < NetworkConfig.maxPackageSize, "packageSize < NetworkConfig.maxPackageSize"); if (debugSendStreamWriter != null) { debugSendStreamWriter.Write(m_PackageBuffer, 0, packageSize); debugSendStreamWriter.Write((UInt32)0xedededed); } if (packageSize > NetworkConfig.packageFragmentSize) { // Package is too big and needs to be sent as fragments var numFragments = packageSize / NetworkConfig.packageFragmentSize; //GameDebug.Log("FRAGMENTING: " + connectionId + ": " + packageSize + " (" + numFragments + ")"); var lastFragmentSize = packageSize % NetworkConfig.packageFragmentSize; if (lastFragmentSize != 0) { ++numFragments; } else { lastFragmentSize = NetworkConfig.packageFragmentSize; } for (var i = 0; i < numFragments; ++i) { var fragmentSize = i < numFragments - 1 ? NetworkConfig.packageFragmentSize : lastFragmentSize; var fragmentOutput = new BitOutputStream(m_FragmentBuffer); fragmentOutput.WriteBits((uint)NetworkMessage.FRAGMENT, 8); // Package fragment identifier fragmentOutput.WriteBits(Sequence.ToUInt16(outSequence), 16); fragmentOutput.WriteBits((uint)numFragments, 8); fragmentOutput.WriteBits((uint)i, 8); fragmentOutput.WriteBits((uint)fragmentSize, 16); fragmentOutput.WriteBytes(m_PackageBuffer, i * NetworkConfig.packageFragmentSize, fragmentSize); int fragmentPackageSize = fragmentOutput.Flush(); transport.SendData(connectionId, m_FragmentBuffer, fragmentPackageSize); counters.packagesOut++; counters.bytesOut += fragmentPackageSize; } counters.fragmentedPackagesOut++; } else { transport.SendData(connectionId, m_PackageBuffer, packageSize); counters.packagesOut++; counters.bytesOut += packageSize; } ++outSequence; Profiler.EndSample(); return(packageSize); }
/// <summary> /// Writes the Huffman tree to the given OutputStream /// </summary> /// <param name="huff">Huffman tree to write</param> /// <param name="numberWritten">Amount of nodes written.</param> /// <param name="outputStream">BitOutputStream of file to write to.</param> /// <returns>An integer of the number of that node.</returns> private int WriteHuffmanTree(BinaryTreeNode<byte> huff, int numberWritten, BitOutputStream outputStream) { if (huff.LeftChild == null && huff.RightChild == null) { outputStream.WriteBits(1L, 1); outputStream.WriteBits(huff.RootValue, 8); return numberWritten; } else { int num1 = WriteHuffmanTree(huff.LeftChild, numberWritten++, outputStream); int num2 = WriteHuffmanTree(huff.RightChild, num1 + 1, outputStream); outputStream.WriteBits(0 << 1, 1); outputStream.WriteBits((byte)num1,9); outputStream.WriteBits((byte)num2,9); return num2 + 1; } }
/// <summary> /// Writes the encodings generated for each byte in FileStream to a outputstream. /// </summary> /// <param name="fs">FileStream of uncompressed data</param> /// <param name="outputStream">BitOutputStream of file to write compressed data to</param> private void WriteEncodings(FileStream fs, BitOutputStream outputStream) { int b = fs.ReadByte(); while (b != -1) { if (_encodingLength[b] > 0) { outputStream.WriteBits(_encodings[b], _encodingLength[b]); } b = fs.ReadByte(); } }
/// <summary> /// Takes an in and out file, and configures all other methods to build the huffman tree and write it, as well as compress data. /// </summary> /// <param name="fs">Input file</param> /// <param name="outputStream">Output File</param> private void CompressStream(FileStream fs, BitOutputStream outputStream) { _encodingLength = new int[256]; _encodings = new long[256]; int numberOfNodes = 0; int inputLength; long[] frequency = GetFrequency(fs, out inputLength); outputStream.WriteBits(inputLength, 63); if(inputLength != 0) { BinaryTreeNode<byte> huff = BuildHuffmanTree(frequency, out numberOfNodes);/* TreeForm t = new TreeForm(huff, 100); t.Show();*/ ComputeEncodings(huff, 0, 0L); outputStream.WriteBits((2*numberOfNodes) - 1, 9); WriteHuffmanTree(huff, 0, outputStream); fs.Seek(0, SeekOrigin.Begin); WriteEncodings(fs, outputStream); } }