예제 #1
0
        // Sets the input to compress. The only buffer copy occurs when the input is copied
        // to the FastEncoderWindow
        void IDeflater.SetInput(byte[] inputBuffer, int startIndex, int count) {

            Debug.Assert(input.Count == 0, "We have something left in previous input!");

            input.Buffer = inputBuffer;
            input.Count = count;
            input.StartIndex = startIndex;

            if (count > 0 && count < MinBlockSize) {
                // user is writing small buffers. If buffer size is below MinBlockSize, we
                // need to switch to a small data mode, to avoid block headers and footers 
                // dominating the output.
                switch (processingState) {
                    case DeflaterState.NotStarted :
                    case DeflaterState.CheckingForIncompressible:
                        // clean states, needs a block header first
                        processingState = DeflaterState.StartingSmallData;
                        break;
                    case DeflaterState.CompressThenCheck:
                        // already has correct block header
                        processingState = DeflaterState.HandlingSmallData;
                        break;
                }
            }
        }
        // Sets the input to compress. The only buffer copy occurs when the input is copied
        // to the FastEncoderWindow
        void IDeflater.SetInput(byte[] inputBuffer, int startIndex, int count)
        {
            Debug.Assert(input.Count == 0, "We have something left in previous input!");

            input.Buffer     = inputBuffer;
            input.Count      = count;
            input.StartIndex = startIndex;

            if (count > 0 && count < MinBlockSize)
            {
                // user is writing small buffers. If buffer size is below MinBlockSize, we
                // need to switch to a small data mode, to avoid block headers and footers
                // dominating the output.
                switch (processingState)
                {
                case DeflaterState.NotStarted:
                case DeflaterState.CheckingForIncompressible:
                    // clean states, needs a block header first
                    processingState = DeflaterState.StartingSmallData;
                    break;

                case DeflaterState.CompressThenCheck:
                    // already has correct block header
                    processingState = DeflaterState.HandlingSmallData;
                    break;
                }
            }
        }
        internal DeflaterManaged() {
            deflateEncoder = new FastEncoder();
            copyEncoder = new CopyEncoder();
            input = new DeflateInput();
            output = new OutputBuffer();

            processingState = DeflaterState.NotStarted;
        }
        internal DeflaterManaged()
        {
            deflateEncoder = new FastEncoder();
            copyEncoder    = new CopyEncoder();
            input          = new DeflateInput();
            output         = new OutputBuffer();

            processingState = DeflaterState.NotStarted;
        }
예제 #5
0
        internal Deflater()
        {
            _deflateEncoder = new FastEncoder();
            _copyEncoder = new CopyEncoder();
            _input = new DeflateInput();
            _output = new OutputBuffer();

            _processingState = DeflaterState.NotStarted;
        }
예제 #6
0
        internal Deflater()
        {
            _deflateEncoder = new FastEncoder();
            _copyEncoder    = new CopyEncoder();
            _input          = new DeflateInput();
            _output         = new OutputBuffer();

            _processingState = DeflaterState.NotStarted;
        }
예제 #7
0
		// Sets the input to compress. The only buffer copy occurs when the input is copied
		// to the FastEncoderWindow
		void IDeflater.SetInput(byte[] inputBuffer, int startIndex, int count)
		{
			Debug.Assert(input.Count == 0, "We have something left in previous input!");

			input.Buffer = inputBuffer;
			input.Count = count;
			input.StartIndex = startIndex;

			if (count > 0 && count < MinBlockSize)
				switch (processingState)
				{
					case DeflaterState.NotStarted:
					case DeflaterState.CheckingForIncompressible:
						// clean states, needs a block header first
						processingState = DeflaterState.StartingSmallData;
						break;
					case DeflaterState.CompressThenCheck:
						// already has correct block header
						processingState = DeflaterState.HandlingSmallData;
						break;
				}
		}
        public void SetInput(byte[] inputBuffer, int startIndex, int count)
        {
            this.input.Buffer     = inputBuffer;
            this.input.Count      = count;
            this.input.StartIndex = startIndex;
            if ((count > 0) && (count < 0x100))
            {
                switch (this.processingState)
                {
                case DeflaterState.CompressThenCheck:
                    this.processingState = DeflaterState.HandlingSmallData;
                    break;

                case DeflaterState.CheckingForIncompressible:
                case DeflaterState.NotStarted:
                    this.processingState = DeflaterState.StartingSmallData;
                    return;

                default:
                    return;
                }
            }
        }
        int IDeflater.GetDeflateOutput(byte[] outputBuffer)
        {
            Debug.Assert(outputBuffer != null, "Can't pass in a null output buffer!");
            Debug.Assert(!NeedsInput(), "GetDeflateOutput should only be called after providing input");

            output.UpdateBuffer(outputBuffer);

            switch (processingState)
            {
            case DeflaterState.NotStarted: {
                // first call. Try to compress but if we get bad compression ratio, switch to uncompressed blocks.
                Debug.Assert(deflateEncoder.BytesInHistory == 0, "have leftover bytes in window");

                // save these in case we need to switch to uncompressed format
                DeflateInput.InputState  initialInputState  = input.DumpState();
                OutputBuffer.BufferState initialOutputState = output.DumpState();

                deflateEncoder.GetBlockHeader(output);
                deflateEncoder.GetCompressedData(input, output);

                if (!UseCompressed(deflateEncoder.LastCompressionRatio))
                {
                    // we're expanding; restore state and switch to uncompressed
                    input.RestoreState(initialInputState);
                    output.RestoreState(initialOutputState);
                    copyEncoder.GetBlock(input, output, false);
                    FlushInputWindows();
                    processingState = DeflaterState.CheckingForIncompressible;
                }
                else
                {
                    processingState = DeflaterState.CompressThenCheck;
                }

                break;
            }

            case DeflaterState.CompressThenCheck: {
                // continue assuming data is compressible. If we reach data that indicates otherwise
                // finish off remaining data in history and decide whether to compress on a
                // block-by-block basis
                deflateEncoder.GetCompressedData(input, output);

                if (!UseCompressed(deflateEncoder.LastCompressionRatio))
                {
                    processingState  = DeflaterState.SlowDownForIncompressible1;
                    inputFromHistory = deflateEncoder.UnprocessedInput;
                }
                break;
            }

            case DeflaterState.SlowDownForIncompressible1: {
                // finish off previous compressed block
                deflateEncoder.GetBlockFooter(output);

                processingState = DeflaterState.SlowDownForIncompressible2;
                goto case DeflaterState.SlowDownForIncompressible2;         // yeah I know, but there's no fallthrough
            }

            case DeflaterState.SlowDownForIncompressible2: {
                // clear out data from history, but add them as uncompressed blocks
                if (inputFromHistory.Count > 0)
                {
                    copyEncoder.GetBlock(inputFromHistory, output, false);
                }

                if (inputFromHistory.Count == 0)
                {
                    // now we're clean
                    deflateEncoder.FlushInput();
                    processingState = DeflaterState.CheckingForIncompressible;
                }
                break;
            }

            case DeflaterState.CheckingForIncompressible: {
                // decide whether to compress on a block-by-block basis
                Debug.Assert(deflateEncoder.BytesInHistory == 0, "have leftover bytes in window");

                // save these in case we need to store as uncompressed
                DeflateInput.InputState  initialInputState  = input.DumpState();
                OutputBuffer.BufferState initialOutputState = output.DumpState();

                // enforce max so we can ensure state between calls
                deflateEncoder.GetBlock(input, output, CleanCopySize);

                if (!UseCompressed(deflateEncoder.LastCompressionRatio))
                {
                    // we're expanding; restore state and switch to uncompressed
                    input.RestoreState(initialInputState);
                    output.RestoreState(initialOutputState);
                    copyEncoder.GetBlock(input, output, false);
                    FlushInputWindows();
                }

                break;
            }

            case DeflaterState.StartingSmallData: {
                // add compressed header and data, but not footer. Subsequent calls will keep
                // adding compressed data (no header and no footer). We're doing this to
                // avoid overhead of header and footer size relative to compressed payload.
                deflateEncoder.GetBlockHeader(output);

                processingState = DeflaterState.HandlingSmallData;
                goto case DeflaterState.HandlingSmallData;         // yeah I know, but there's no fallthrough
            }

            case DeflaterState.HandlingSmallData: {
                // continue adding compressed data
                deflateEncoder.GetCompressedData(input, output);
                break;
            }
            }

            return(output.BytesWritten);
        }
예제 #10
0
        int IDeflater.GetDeflateOutput(byte[] outputBuffer)
        {
            Debug.Assert(outputBuffer != null, "Can't pass in a null output buffer!");
            Debug.Assert(!NeedsInput(), "GetDeflateOutput should only be called after providing input");

            _output.UpdateBuffer(outputBuffer);

            switch (_processingState)
            {
                case DeflaterState.NotStarted:
                    {
                        // first call. Try to compress but if we get bad compression ratio, switch to uncompressed blocks. 
                        Debug.Assert(_deflateEncoder.BytesInHistory == 0, "have leftover bytes in window");

                        // save these in case we need to switch to uncompressed format
                        DeflateInput.InputState initialInputState = _input.DumpState();
                        OutputBuffer.BufferState initialOutputState = _output.DumpState();

                        _deflateEncoder.GetBlockHeader(_output);
                        _deflateEncoder.GetCompressedData(_input, _output);

                        if (!UseCompressed(_deflateEncoder.LastCompressionRatio))
                        {
                            // we're expanding; restore state and switch to uncompressed
                            _input.RestoreState(initialInputState);
                            _output.RestoreState(initialOutputState);
                            _copyEncoder.GetBlock(_input, _output, false);
                            FlushInputWindows();
                            _processingState = DeflaterState.CheckingForIncompressible;
                        }
                        else
                        {
                            _processingState = DeflaterState.CompressThenCheck;
                        }

                        break;
                    }
                case DeflaterState.CompressThenCheck:
                    {
                        // continue assuming data is compressible. If we reach data that indicates otherwise
                        // finish off remaining data in history and decide whether to compress on a 
                        // block-by-block basis
                        _deflateEncoder.GetCompressedData(_input, _output);

                        if (!UseCompressed(_deflateEncoder.LastCompressionRatio))
                        {
                            _processingState = DeflaterState.SlowDownForIncompressible1;
                            _inputFromHistory = _deflateEncoder.UnprocessedInput;
                        }
                        break;
                    }
                case DeflaterState.SlowDownForIncompressible1:
                    {
                        // finish off previous compressed block
                        _deflateEncoder.GetBlockFooter(_output);

                        _processingState = DeflaterState.SlowDownForIncompressible2;
                        goto case DeflaterState.SlowDownForIncompressible2; // yeah I know, but there's no fallthrough
                    }

                case DeflaterState.SlowDownForIncompressible2:
                    {
                        // clear out data from history, but add them as uncompressed blocks
                        if (_inputFromHistory.Count > 0)
                        {
                            _copyEncoder.GetBlock(_inputFromHistory, _output, false);
                        }

                        if (_inputFromHistory.Count == 0)
                        {
                            // now we're clean
                            _deflateEncoder.FlushInput();
                            _processingState = DeflaterState.CheckingForIncompressible;
                        }
                        break;
                    }

                case DeflaterState.CheckingForIncompressible:
                    {
                        // decide whether to compress on a block-by-block basis
                        Debug.Assert(_deflateEncoder.BytesInHistory == 0, "have leftover bytes in window");

                        // save these in case we need to store as uncompressed
                        DeflateInput.InputState initialInputState = _input.DumpState();
                        OutputBuffer.BufferState initialOutputState = _output.DumpState();

                        // enforce max so we can ensure state between calls
                        _deflateEncoder.GetBlock(_input, _output, CleanCopySize);

                        if (!UseCompressed(_deflateEncoder.LastCompressionRatio))
                        {
                            // we're expanding; restore state and switch to uncompressed
                            _input.RestoreState(initialInputState);
                            _output.RestoreState(initialOutputState);
                            _copyEncoder.GetBlock(_input, _output, false);
                            FlushInputWindows();
                        }

                        break;
                    }

                case DeflaterState.StartingSmallData:
                    {
                        // add compressed header and data, but not footer. Subsequent calls will keep 
                        // adding compressed data (no header and no footer). We're doing this to 
                        // avoid overhead of header and footer size relative to compressed payload.
                        _deflateEncoder.GetBlockHeader(_output);

                        _processingState = DeflaterState.HandlingSmallData;
                        goto case DeflaterState.HandlingSmallData; // yeah I know, but there's no fallthrough
                    }

                case DeflaterState.HandlingSmallData:
                    {
                        // continue adding compressed data
                        _deflateEncoder.GetCompressedData(_input, _output);
                        break;
                    }
            }

            return _output.BytesWritten;
        }
        public int GetDeflateOutput(byte[] outputBuffer)
        {
            this.output.UpdateBuffer(outputBuffer);
            switch (this.processingState)
            {
            case DeflaterState.NotStarted:
            {
                DeflateInput.InputState  state  = this.input.DumpState();
                OutputBuffer.BufferState state2 = this.output.DumpState();
                this.deflateEncoder.GetBlockHeader(this.output);
                this.deflateEncoder.GetCompressedData(this.input, this.output);
                if (this.UseCompressed(this.deflateEncoder.LastCompressionRatio))
                {
                    this.processingState = DeflaterState.CompressThenCheck;
                }
                else
                {
                    this.input.RestoreState(state);
                    this.output.RestoreState(state2);
                    this.copyEncoder.GetBlock(this.input, this.output, false);
                    this.FlushInputWindows();
                    this.processingState = DeflaterState.CheckingForIncompressible;
                }
                goto Label_023A;
            }

            case DeflaterState.SlowDownForIncompressible1:
                this.deflateEncoder.GetBlockFooter(this.output);
                this.processingState = DeflaterState.SlowDownForIncompressible2;
                break;

            case DeflaterState.SlowDownForIncompressible2:
                break;

            case DeflaterState.StartingSmallData:
                this.deflateEncoder.GetBlockHeader(this.output);
                this.processingState = DeflaterState.HandlingSmallData;
                goto Label_0223;

            case DeflaterState.CompressThenCheck:
                this.deflateEncoder.GetCompressedData(this.input, this.output);
                if (!this.UseCompressed(this.deflateEncoder.LastCompressionRatio))
                {
                    this.processingState  = DeflaterState.SlowDownForIncompressible1;
                    this.inputFromHistory = this.deflateEncoder.UnprocessedInput;
                }
                goto Label_023A;

            case DeflaterState.CheckingForIncompressible:
            {
                DeflateInput.InputState  state3 = this.input.DumpState();
                OutputBuffer.BufferState state4 = this.output.DumpState();
                this.deflateEncoder.GetBlock(this.input, this.output, 0xf88);
                if (!this.UseCompressed(this.deflateEncoder.LastCompressionRatio))
                {
                    this.input.RestoreState(state3);
                    this.output.RestoreState(state4);
                    this.copyEncoder.GetBlock(this.input, this.output, false);
                    this.FlushInputWindows();
                }
                goto Label_023A;
            }

            case DeflaterState.HandlingSmallData:
                goto Label_0223;

            default:
                goto Label_023A;
            }
            if (this.inputFromHistory.Count > 0)
            {
                this.copyEncoder.GetBlock(this.inputFromHistory, this.output, false);
            }
            if (this.inputFromHistory.Count == 0)
            {
                this.deflateEncoder.FlushInput();
                this.processingState = DeflaterState.CheckingForIncompressible;
            }
            goto Label_023A;
Label_0223:
            this.deflateEncoder.GetCompressedData(this.input, this.output);
Label_023A:
            return(this.output.BytesWritten);
        }
        public int GetDeflateOutput(byte[] outputBuffer)
        {
            this.output.UpdateBuffer(outputBuffer);
            switch (this.processingState)
            {
                case DeflaterState.NotStarted:
                {
                    DeflateInput.InputState state = this.input.DumpState();
                    OutputBuffer.BufferState state2 = this.output.DumpState();
                    this.deflateEncoder.GetBlockHeader(this.output);
                    this.deflateEncoder.GetCompressedData(this.input, this.output);
                    if (this.UseCompressed(this.deflateEncoder.LastCompressionRatio))
                    {
                        this.processingState = DeflaterState.CompressThenCheck;
                    }
                    else
                    {
                        this.input.RestoreState(state);
                        this.output.RestoreState(state2);
                        this.copyEncoder.GetBlock(this.input, this.output, false);
                        this.FlushInputWindows();
                        this.processingState = DeflaterState.CheckingForIncompressible;
                    }
                    goto Label_023A;
                }
                case DeflaterState.SlowDownForIncompressible1:
                    this.deflateEncoder.GetBlockFooter(this.output);
                    this.processingState = DeflaterState.SlowDownForIncompressible2;
                    break;

                case DeflaterState.SlowDownForIncompressible2:
                    break;

                case DeflaterState.StartingSmallData:
                    this.deflateEncoder.GetBlockHeader(this.output);
                    this.processingState = DeflaterState.HandlingSmallData;
                    goto Label_0223;

                case DeflaterState.CompressThenCheck:
                    this.deflateEncoder.GetCompressedData(this.input, this.output);
                    if (!this.UseCompressed(this.deflateEncoder.LastCompressionRatio))
                    {
                        this.processingState = DeflaterState.SlowDownForIncompressible1;
                        this.inputFromHistory = this.deflateEncoder.UnprocessedInput;
                    }
                    goto Label_023A;

                case DeflaterState.CheckingForIncompressible:
                {
                    DeflateInput.InputState state3 = this.input.DumpState();
                    OutputBuffer.BufferState state4 = this.output.DumpState();
                    this.deflateEncoder.GetBlock(this.input, this.output, 0xf88);
                    if (!this.UseCompressed(this.deflateEncoder.LastCompressionRatio))
                    {
                        this.input.RestoreState(state3);
                        this.output.RestoreState(state4);
                        this.copyEncoder.GetBlock(this.input, this.output, false);
                        this.FlushInputWindows();
                    }
                    goto Label_023A;
                }
                case DeflaterState.HandlingSmallData:
                    goto Label_0223;

                default:
                    goto Label_023A;
            }
            if (this.inputFromHistory.Count > 0)
            {
                this.copyEncoder.GetBlock(this.inputFromHistory, this.output, false);
            }
            if (this.inputFromHistory.Count == 0)
            {
                this.deflateEncoder.FlushInput();
                this.processingState = DeflaterState.CheckingForIncompressible;
            }
            goto Label_023A;
        Label_0223:
            this.deflateEncoder.GetCompressedData(this.input, this.output);
        Label_023A:
            return this.output.BytesWritten;
        }
        public void SetInput(byte[] inputBuffer, int startIndex, int count)
        {
            this.input.Buffer = inputBuffer;
            this.input.Count = count;
            this.input.StartIndex = startIndex;
            if ((count > 0) && (count < 0x100))
            {
                switch (this.processingState)
                {
                    case DeflaterState.CompressThenCheck:
                        this.processingState = DeflaterState.HandlingSmallData;
                        break;

                    case DeflaterState.CheckingForIncompressible:
                    case DeflaterState.NotStarted:
                        this.processingState = DeflaterState.StartingSmallData;
                        return;

                    default:
                        return;
                }
            }
        }