public static void WriteMatch(int matchLen, int matchPos, OutputBuffer output)
        {
            Debug.Assert(matchLen >= FastEncoderWindow.MinMatch && matchLen <= FastEncoderWindow.MaxMatch,
                         "Illegal currentMatch length!");

            // Get the code information for a match code
            var codeInfo =
                FastEncoderStatics.FastEncoderLiteralCodeInfo[
                    (FastEncoderStatics.NumChars + 1 - FastEncoderWindow.MinMatch) + matchLen];
            var codeLen = (int)codeInfo & 31;

            Debug.Assert(codeLen != 0, "Invalid Match Length!");
            if (codeLen <= 16)
            {
                output.WriteBits(codeLen, codeInfo >> 5);
            }
            else
            {
                output.WriteBits(16, (codeInfo >> 5) & 65535);
                output.WriteBits(codeLen - 16, codeInfo >> (5 + 16));
            }

            // Get the code information for a distance code
            codeInfo = FastEncoderStatics.FastEncoderDistanceCodeInfo[FastEncoderStatics.GetSlot(matchPos)];
            output.WriteBits((int)(codeInfo & 15), codeInfo >> 8);
            var extraBits = (int)(codeInfo >> 4) & 15;

            if (extraBits != 0)
            {
                output.WriteBits(extraBits, (uint)matchPos & FastEncoderStatics.BitMask[extraBits]);
            }
        }
        // Copy the compressed bytes to output buffer as a block. maxBytesToCopy limits the number of
        // bytes we can copy from input. Set to any value < 1 if no limit
        public void GetBlock(DeflateInput input, OutputBuffer output, int maxBytesToCopy)
        {
            Debug.Assert(InputAvailable(input), "call SetInput before trying to compress!");

            WriteDeflatePreamble(output);
            GetCompressedOutput(input, output, maxBytesToCopy);
            WriteEndOfBlock(output);
        }
        // Copy the compressed bytes to output buffer as a block. maxBytesToCopy limits the number of 
        // bytes we can copy from input. Set to any value < 1 if no limit
        public void GetBlock(DeflateInput input, OutputBuffer output, int maxBytesToCopy)
        {
            Debug.Assert(InputAvailable(input), "call SetInput before trying to compress!");

            WriteDeflatePreamble(output);
            GetCompressedOutput(input, output, maxBytesToCopy);
            WriteEndOfBlock(output);
        }
Example #4
0
        internal Deflater()
        {
            _deflateEncoder = new FastEncoder();
            _copyEncoder    = new CopyEncoder();
            _input          = new DeflateInput();
            _output         = new OutputBuffer();

            _processingState = DeflaterState.NotStarted;
        }
        private static void WriteEndOfBlock(OutputBuffer output)
        {
            // The fast encoder outputs one long block, so it just needs to terminate this block
            const int endOfBlockCode = 256;
            var       codeInfo       = FastEncoderStatics.FastEncoderLiteralCodeInfo[endOfBlockCode];
            var       codeLen        = (int)(codeInfo & 31);

            output.WriteBits(codeLen, codeInfo >> 5);
        }
        // Output the block type and tree structure for our hard-coded trees.
        // Contains following data:
        //  "final" block flag 1 bit
        //  BLOCKTYPE_DYNAMIC 2 bits
        //  FastEncoderLiteralTreeLength
        //  FastEncoderDistanceTreeLength
        //
        public static void WriteDeflatePreamble(OutputBuffer output)
        {
            //Debug.Assert( bitCount == 0, "bitCount must be zero before writing tree bit!");

            output.WriteBytes(FastEncoderStatics.FastEncoderTreeStructureData, 0,
                              FastEncoderStatics.FastEncoderTreeStructureData.Length);
            output.WriteBits(FastEncoderStatics.FastEncoderPostTreeBitCount,
                             FastEncoderStatics.FastEncoderPostTreeBitBuf);
        }
Example #7
0
        internal Deflater()
        {
            _deflateEncoder = new FastEncoder();
            _copyEncoder = new CopyEncoder();
            _input = new DeflateInput();
            _output = new OutputBuffer();

            _processingState = DeflaterState.NotStarted;
        }
Example #8
0
        private static void WriteLenNLen(ushort len, OutputBuffer output)
        {
            // len
            output.WriteUInt16(len);

            // nlen
            var onesComp = (ushort)(~len);

            output.WriteUInt16(onesComp);
        }
        private static void WriteLenNLen(ushort len, OutputBuffer output)
        {

            // len
            output.WriteUInt16(len);

            // nlen
            var onesComp = (ushort) (~len);
            output.WriteUInt16(onesComp);
        }
Example #10
0
        // null input means write an empty payload with formatting info. This is needed for the final block.
        public void GetBlock(DeflateInput input, OutputBuffer output, bool isFinal)
        {
            Debug.Assert(output != null);
            Debug.Assert(output.FreeBytes >= PaddingSize);

            // determine number of bytes to write
            var count = 0;

            if (input != null)
            {
                // allow space for padding and bits not yet flushed to buffer
                count = Math.Min(input.Count, output.FreeBytes - PaddingSize - output.BitsInBuffer);

                // we don't expect the output buffer to ever be this big (currently 4K), but we'll check this
                // just in case that changes.
                if (count > MaxUncompressedBlockSize - PaddingSize)
                {
                    count = MaxUncompressedBlockSize - PaddingSize;
                }
            }

            // write header and flush bits
            if (isFinal)
            {
                output.WriteBits(FastEncoderStatics.BFinalNoCompressionHeaderBitCount, FastEncoderStatics.BFinalNoCompressionHeader);
            }
            else
            {
                output.WriteBits(FastEncoderStatics.NoCompressionHeaderBitCount, FastEncoderStatics.NoCompressionHeader);
            }

            // now we're aligned
            output.FlushBits();

            // write len, nlen
            WriteLenNLen((ushort)count, output);
            if (input == null || count <= 0)
            {
                return;
            }

            // write uncompressed bytes
            output.WriteBytes(input.Buffer, input.StartIndex, count);
            input.ConsumeBytes(count);
        }
        // null input means write an empty payload with formatting info. This is needed for the final block.
        public void GetBlock(DeflateInput input, OutputBuffer output, bool isFinal)
        {
            Debug.Assert(output != null);
            Debug.Assert(output.FreeBytes >= PaddingSize);

            // determine number of bytes to write
            var count = 0;
            if (input != null)
            {

                // allow space for padding and bits not yet flushed to buffer
                count = Math.Min(input.Count, output.FreeBytes - PaddingSize - output.BitsInBuffer);

                // we don't expect the output buffer to ever be this big (currently 4K), but we'll check this
                // just in case that changes.
                if (count > MaxUncompressedBlockSize - PaddingSize)
                {
                    count = MaxUncompressedBlockSize - PaddingSize;
                }
            }

            // write header and flush bits
            if (isFinal)
            {
                output.WriteBits(FastEncoderStatics.BFinalNoCompressionHeaderBitCount, FastEncoderStatics.BFinalNoCompressionHeader);
            }
            else
            {
                output.WriteBits(FastEncoderStatics.NoCompressionHeaderBitCount, FastEncoderStatics.NoCompressionHeader);
            }

            // now we're aligned
            output.FlushBits();

            // write len, nlen
            WriteLenNLen((ushort) count, output);
            if (input == null || count <= 0) 
                return;

            // write uncompressed bytes            
            output.WriteBytes(input.Buffer, input.StartIndex, count);
            input.ConsumeBytes(count);
        }
        // maxBytesToCopy limits the number of bytes we can copy from input. Set to any value < 1 if no limit
        private void GetCompressedOutput(DeflateInput input, OutputBuffer output, int maxBytesToCopy)
        {
            // snapshot for compression ratio stats
            var bytesWrittenPre = output.BytesWritten;
            var bytesConsumedFromInput = 0;
            var inputBytesPre = BytesInHistory + input.Count;

            do
            {
                // read more input data into the window if there is space available
                var bytesToCopy = (input.Count < _inputWindow.FreeWindowSpace)
                    ? input.Count
                    : _inputWindow.FreeWindowSpace;
                if (maxBytesToCopy >= 1)
                {
                    bytesToCopy = Math.Min(bytesToCopy, maxBytesToCopy - bytesConsumedFromInput);
                }
                if (bytesToCopy > 0)
                {
                    // copy data into history window
                    _inputWindow.CopyBytes(input.Buffer, input.StartIndex, bytesToCopy);
                    input.ConsumeBytes(bytesToCopy);
                    bytesConsumedFromInput += bytesToCopy;
                }

                this.GetCompressedOutput(output);

            } 
            while (SafeToWriteTo(output) && InputAvailable(input) && (maxBytesToCopy < 1 || bytesConsumedFromInput < maxBytesToCopy));

            // determine compression ratio, save
            var bytesWrittenPost = output.BytesWritten;
            var bytesWritten = bytesWrittenPost - bytesWrittenPre;
            var inputBytesPost = BytesInHistory + input.Count;
            var totalBytesConsumed = inputBytesPre - inputBytesPost;
            if (bytesWritten != 0)
                this.LastCompressionRatio = bytesWritten / (double)totalBytesConsumed;            

        }
Example #13
0
        // maxBytesToCopy limits the number of bytes we can copy from input. Set to any value < 1 if no limit
        private void GetCompressedOutput(DeflateInput input, OutputBuffer output, int maxBytesToCopy)
        {
            // snapshot for compression ratio stats
            var bytesWrittenPre        = output.BytesWritten;
            var bytesConsumedFromInput = 0;
            var inputBytesPre          = BytesInHistory + input.Count;

            do
            {
                // read more input data into the window if there is space available
                var bytesToCopy = (input.Count < _inputWindow.FreeWindowSpace)
                    ? input.Count
                    : _inputWindow.FreeWindowSpace;
                if (maxBytesToCopy >= 1)
                {
                    bytesToCopy = Math.Min(bytesToCopy, maxBytesToCopy - bytesConsumedFromInput);
                }
                if (bytesToCopy > 0)
                {
                    // copy data into history window
                    _inputWindow.CopyBytes(input.Buffer, input.StartIndex, bytesToCopy);
                    input.ConsumeBytes(bytesToCopy);
                    bytesConsumedFromInput += bytesToCopy;
                }

                this.GetCompressedOutput(output);
            }while (SafeToWriteTo(output) && InputAvailable(input) && (maxBytesToCopy < 1 || bytesConsumedFromInput < maxBytesToCopy));

            // determine compression ratio, save
            var bytesWrittenPost   = output.BytesWritten;
            var bytesWritten       = bytesWrittenPost - bytesWrittenPre;
            var inputBytesPost     = BytesInHistory + input.Count;
            var totalBytesConsumed = inputBytesPre - inputBytesPost;

            if (bytesWritten != 0)
            {
                this.LastCompressionRatio = bytesWritten / (double)totalBytesConsumed;
            }
        }
Example #14
0
        // compress the bytes in input history window
        private void GetCompressedOutput(OutputBuffer output)
        {
            while (_inputWindow.BytesAvailable > 0 && SafeToWriteTo(output))
            {
                // Find next match. A match can be a symbol,
                // a distance/length pair, a symbol followed by a distance/Length pair
                _inputWindow.GetNextSymbolOrMatch(_currentMatch);

                if (_currentMatch.State == MatchState.HasSymbol)
                {
                    WriteChar(_currentMatch.Symbol, output);
                }
                else if (_currentMatch.State == MatchState.HasMatch)
                {
                    WriteMatch(_currentMatch.Length, _currentMatch.Position, output);
                }
                else
                {
                    WriteChar(_currentMatch.Symbol, output);
                    WriteMatch(_currentMatch.Length, _currentMatch.Position, output);
                }
            }
        }
 public static void WriteChar(byte b, OutputBuffer output)
 {
     var code = FastEncoderStatics.FastEncoderLiteralCodeInfo[b];
     output.WriteBits((int)code & 31, code >> 5);
 }
Example #16
0
 public void GetBlockFooter(OutputBuffer output)
 {
     WriteEndOfBlock(output);
 }
Example #17
0
 public void GetBlockHeader(OutputBuffer output)
 {
     WriteDeflatePreamble(output);
 }
Example #18
0
 // Compress data but don't format as block (doesn't have header and footer)
 public void GetCompressedData(DeflateInput input, OutputBuffer output)
 {
     this.GetCompressedOutput(input, output, -1);
 }
 private static bool SafeToWriteTo(OutputBuffer output)
 {
     // can we safely continue writing to output buffer
     return output.FreeBytes > FastEncoderStatics.MaxCodeLen;
 }
 private static void WriteEndOfBlock(OutputBuffer output)
 {
     // The fast encoder outputs one long block, so it just needs to terminate this block
     const int endOfBlockCode = 256;
     var codeInfo = FastEncoderStatics.FastEncoderLiteralCodeInfo[endOfBlockCode];
     var codeLen = (int)(codeInfo & 31);
     output.WriteBits(codeLen, codeInfo >> 5);
 }
Example #21
0
        public static void WriteChar(byte b, OutputBuffer output)
        {
            var code = FastEncoderStatics.FastEncoderLiteralCodeInfo[b];

            output.WriteBits((int)code & 31, code >> 5);
        }
 public void GetBlockHeader(OutputBuffer output)
 {
     WriteDeflatePreamble(output);
 }
 public void GetBlockFooter(OutputBuffer output)
 {
     WriteEndOfBlock(output);
 }
Example #24
0
 private static bool SafeToWriteTo(OutputBuffer output)
 {
     // can we safely continue writing to output buffer
     return(output.FreeBytes > FastEncoderStatics.MaxCodeLen);
 }
        // compress the bytes in input history window
        private void GetCompressedOutput(OutputBuffer output)
        {
            while (_inputWindow.BytesAvailable > 0 && SafeToWriteTo(output))
            {

                // Find next match. A match can be a symbol, 
                // a distance/length pair, a symbol followed by a distance/Length pair
                _inputWindow.GetNextSymbolOrMatch(_currentMatch);

                if (_currentMatch.State == MatchState.HasSymbol)
                {
                    WriteChar(_currentMatch.Symbol, output);
                }
                else if (_currentMatch.State == MatchState.HasMatch)
                {
                    WriteMatch(_currentMatch.Length, _currentMatch.Position, output);
                }
                else
                {
                    WriteChar(_currentMatch.Symbol, output);
                    WriteMatch(_currentMatch.Length, _currentMatch.Position, output);
                }
            }
        }
        // Output the block type and tree structure for our hard-coded trees.
        // Contains following data:
        //  "final" block flag 1 bit
        //  BLOCKTYPE_DYNAMIC 2 bits
        //  FastEncoderLiteralTreeLength
        //  FastEncoderDistanceTreeLength
        //
        public static void WriteDeflatePreamble(OutputBuffer output)
        {
            //Debug.Assert( bitCount == 0, "bitCount must be zero before writing tree bit!");

            output.WriteBytes(FastEncoderStatics.FastEncoderTreeStructureData, 0,
                FastEncoderStatics.FastEncoderTreeStructureData.Length);
            output.WriteBits(FastEncoderStatics.FastEncoderPostTreeBitCount,
                FastEncoderStatics.FastEncoderPostTreeBitBuf);
        }
        public static void WriteMatch(int matchLen, int matchPos, OutputBuffer output)
        {
            Debug.Assert(matchLen >= FastEncoderWindow.MinMatch && matchLen <= FastEncoderWindow.MaxMatch,
                "Illegal currentMatch length!");

            // Get the code information for a match code
            var codeInfo =
                FastEncoderStatics.FastEncoderLiteralCodeInfo[
                    (FastEncoderStatics.NumChars + 1 - FastEncoderWindow.MinMatch) + matchLen];
            var codeLen = (int)codeInfo & 31;
            Debug.Assert(codeLen != 0, "Invalid Match Length!");
            if (codeLen <= 16)
            {
                output.WriteBits(codeLen, codeInfo >> 5);
            }
            else
            {
                output.WriteBits(16, (codeInfo >> 5) & 65535);
                output.WriteBits(codeLen - 16, codeInfo >> (5 + 16));
            }

            // Get the code information for a distance code
            codeInfo = FastEncoderStatics.FastEncoderDistanceCodeInfo[FastEncoderStatics.GetSlot(matchPos)];
            output.WriteBits((int)(codeInfo & 15), codeInfo >> 8);
            var extraBits = (int)(codeInfo >> 4) & 15;
            if (extraBits != 0)
            {
                output.WriteBits(extraBits, (uint)matchPos & FastEncoderStatics.BitMask[extraBits]);
            }
        }
 // Compress data but don't format as block (doesn't have header and footer)
 public void GetCompressedData(DeflateInput input, OutputBuffer output)
 {
     this.GetCompressedOutput(input, output, -1);
 }