private static int GetCommand0ByteCount(byte[] buffer, int i) { int j = i + 1; // Forward iterator for buffer while (j < buffer.Length) { if ( #region A command is coming up ( // Matches command 3 (j + 2) < buffer.Length && (buffer[j] == ((buffer[j + 1] - 1) & 0xFF) && buffer[j + 2] == ((buffer[j + 1] + 1) & 0xFF)) ) || ( // Matches command 1 (j + 2) < buffer.Length && (buffer[j] == buffer[j + 1] && buffer[j] == buffer[j + 2]) ) || ( // Matches command 2 (j + 3) < buffer.Length && (buffer[j] == buffer[j + 2] && buffer[j + 1] == buffer[j + 3]) ) || // Matches command 4 or 6 OptimalCompressor.IsBackCommandComing(buffer, j) #endregion ) { break; } j++; } return(j - i); }
private static void CreateChildNodes(byte[] buffer, ChunkNodeCollection nodeCollection, int i, ChunkNode parentNode, ByteDictionary byteDictionary) { // NOTE: Command 5 (ie: the same as command 4 except it inverts each byte) // is not implemented, because it's almost never used. // Implementing it would complicate the code and slow down the compression for little to no benefit. // NOTE: Checking out command 0 every time (ie: putting it out of the if conditions) // can improve compression a tiny bit (like just one byte) in some rare cases, // but it's not worth the huge hit on compression speed. OptimalCompressor.CreateNodesFromBackCommands(nodeCollection, i, parentNode, byteDictionary); int command; int byteCount; if ((i + 1) < buffer.Length && buffer[i] == buffer[i + 1]) { command = 1; byteCount = OptimalCompressor.GetCommand1ByteCount(buffer, i); } else if ((i + 2) < buffer.Length && buffer[i] == buffer[i + 2]) { command = 2; byteCount = OptimalCompressor.GetCommand2ByteCount(buffer, i); } else if ((i + 1) < buffer.Length && ((buffer[i] + 1) & 0xFF) == buffer[i + 1]) { command = 3; byteCount = OptimalCompressor.GetCommand3ByteCount(buffer, i); } else { command = 0; byteCount = OptimalCompressor.GetCommand0ByteCount(buffer, i); } OptimalCompressor.CreateNodesFromCommand(command, byteCount, nodeCollection, i, parentNode); }
public byte[] Compress(byte[] buffer) { ByteDictionary byteDictionary = new ByteDictionary(buffer); ChunkNodeCollection nodeCollection = new ChunkNodeCollection(); while (nodeCollection.Count > 0) { if (nodeCollection.IsNextNodeOptimal()) { KeyValuePair <int, ChunkNode> parentNode = nodeCollection.GetNextNode(); if (parentNode.Key < buffer.Length) { OptimalCompressor.CreateChildNodes(buffer, nodeCollection, parentNode.Key, parentNode.Value, byteDictionary); } } } ChunkNode bestNode = nodeCollection[buffer.Length]; return(bestNode.GetCompressedBuffer(buffer)); }