Exemple #1
0
        private static void CreateNodesFromCommand(int command, int byteCount, ChunkNodeCollection nodeCollection, int i, ChunkNode parentNode)
        {
            byteCount = Codec.GetValidatedSuperCommandSize(byteCount);

            if (byteCount > Codec.NormalCommandMax)
            {
                int reducedByteCount = Math.Min(byteCount, Codec.NormalCommandMax);
                nodeCollection.Add(i + reducedByteCount, new ChunkNode(parentNode, command, i, reducedByteCount));
            }

            nodeCollection.Add(i + byteCount, new ChunkNode(parentNode, command, i, byteCount));
        }
Exemple #2
0
        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);
        }
Exemple #3
0
        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));
        }
Exemple #4
0
        private static void CreateNodesFromBackCommands(ChunkNodeCollection nodeCollection, int i, ChunkNode parentNode, ByteDictionary byteDictionary)
        {
            Range[] ranges = byteDictionary.GetMaxBackRanges(i);

            if (ranges[0].Length > 0)
            {
                nodeCollection.Add(i + ranges[0].Length, new ChunkNode(parentNode, 4, ranges[0].Start, ranges[0].Length));
            }
            if (ranges[1].Length > 0)
            {
                nodeCollection.Add(i + ranges[1].Length, new ChunkNode(parentNode, 4, ranges[1].Start, ranges[1].Length));
            }

            if (ranges[2].Length > 0)
            {
                nodeCollection.Add(i + ranges[2].Length, new ChunkNode(parentNode, 6, i - ranges[2].Start, ranges[2].Length));
            }
            if (ranges[3].Length > 0)
            {
                nodeCollection.Add(i + ranges[3].Length, new ChunkNode(parentNode, 6, i - ranges[3].Start, ranges[3].Length));
            }
        }