deflate() public method

Deflate compresses as much data as possible, and stops when the input buffer becomes empty or the output buffer becomes full. It may introduce some output latency (reading input without producing any output) except when forced to flush.

The detailed semantics are as follows. deflate performs one or both of the following actions: Compress more input starting at next_in and update next_in and avail_in accordingly. If not all input can be processed (because there is not enough room in the output buffer), next_in and avail_in are updated and processing will resume at this point for the next call of deflate. Provide more output starting at next_out and update next_out and avail_out accordingly. This action is forced if the parameter flush is non zero. Forcing flush frequently degrades the compression ratio, so this parameter should be set only when necessary (in interactive applications). Some output may be provided even if flush is not set.

Before the call of , the application should ensure that at least one of the actions is possible, by providing more input and/or consuming more output, and updating avail_in or avail_out accordingly ; avail_out should never be zero before the call. The application can consume the compressed output when it wants, for example when the output buffer is full (avail_out == 0), or after each call of deflate. If deflate returns ZLibResultCode.Z_OK and with zero avail_out, it must be called again after making room in the output buffer because there might be more output pending.

If the parameter flush is set to FlushStrategy.Z_SYNC_FLUSH, all pending output is flushed to the output buffer and the output is aligned on a byte boundary, so that the decompressor can get all input data available so far. (In particular avail_in is zero after the call if enough output space has been provided before the call.) Flushing may degrade compression for some compression algorithms and so it should be used only when necessary.

If flush is set to FlushStrategy.Z_FULL_FLUSH, all output is flushed as with FlushStrategy.Z_SYNC_FLUSH, and the compression state is reset so that decompression can restart from this point if previous compressed data has been damaged or if random access is desired. Using FlushStrategy.Z_FULL_FLUSH too often can seriously degrade the compression.

public deflate ( FlushStrategy flush ) : int
flush FlushStrategy The flush strategy to use.
return int
Example #1
0
        /// <summary>
        /// Writes a byte array to the stream. This block of data is compressed and stored in the stream passed as a parameter to the <see cref="ZOutputStream(Stream,int)">class constructor</see>.
        /// </summary>
        /// <param name="buffer">A byte array to compress.</param>
        /// <param name="offset">Offset of the first byte to compress.</param>
        /// <param name="count">The number of bytes to compress from the buffer.</param>
        /// <example> The following code demonstrates how to use the <c>ZOutputStream</c> to compress data
        /// <code>
        /// [C#]
        /// private void compressFile(string inFile, string outFile)
        ///	{
        ///	    /* Create a file to store compressed data */
        ///		System.IO.FileStream compressedFile = new System.IO.FileStream(@"c:\data\compressed.dat", System.IO.FileMode.Create);
        ///		/* Open a file containing source data */
        ///		System.IO.FileStream sourceFile = new System.IO.FileStream(@"c:\data\source.dat", System.IO.FileMode.Open);
        ///		/* Create ZOutputStream for compression */
        ///		ZOutputStream compressionStream = new ZOutputStream(compressedFile);
        ///
        ///		try
        ///		{
        ///				byte[] buffer = new byte[2000];
        ///				int len;
        ///				/* Read and compress data */
        ///				while ((len = sourceFile.Read(buffer, 0, 2000)) > 0)
        ///				{
        ///				  /* Store compressed data */
        ///					compressionStream.Write(buffer, 0, len);
        ///				}
        ///		}
        ///		finally
        ///		{
        ///			compressionStream.Close();
        ///			sourceFile.Close();
        ///			compressedFile.Close();
        ///		}
        ///	}
        /// </code>
        /// </example>
        public override void Write(byte[] buffer, int offset, int count)
        {
            if (count == 0)
            {
                return;
            }

            if (buffer == null)
            {
                throw new ArgumentNullException("buffer");
            }

            int err;

            byte[] b = new byte[buffer.Length];
            System.Array.Copy(buffer, 0, b, 0, buffer.Length);
            z.next_in       = b;
            z.next_in_index = offset;
            z.avail_in      = count;
            do
            {
                z.next_out       = buf;
                z.next_out_index = 0;
                z.avail_out      = ZLibUtil.zLibBufSize;
                err = z.deflate(flush);
                if (err != (int)ZLibResultCode.Z_OK && err != (int)ZLibResultCode.Z_STREAM_END)
                {
                    throw new ZStreamException("deflating: " + z.msg);
                }
                _stream.Write(buf, 0, ZLibUtil.zLibBufSize - z.avail_out);

                //fixed infinite loop where z.istate.mode == 12, but z.avail_in != 0.
                if (z.istate != null)
                {
                    if (z.istate.mode == InflateMode.DONE)
                    {
                        if (z.avail_in > 0)
                        {
                            z.avail_in = 0;
                        }
                    }
                }
            }while (z.avail_in > 0 || z.avail_out == 0);
        }
Example #2
0
        /// <summary>
        /// Sets deflate algorithm parameters
        /// </summary>
        internal int deflateParams(ZStream strm, int level, CompressionStrategy strategy)
        {
            int err = (int)ZLibResultCode.Z_OK;

            if (level == Z_DEFAULT_COMPRESSION)
            {
                level = 6;
            }
            if (level < 0 || level > 9 || strategy < 0 || strategy > CompressionStrategy.Z_HUFFMAN_ONLY)
            {
                return (int)ZLibResultCode.Z_STREAM_ERROR;
            }

            if (config_table[this._level].func != config_table[level].func && strm.total_in != 0)
            {
                // Flush the last buffer:
                err = strm.deflate(FlushStrategy.Z_PARTIAL_FLUSH);
            }

            if (this._level != level)
            {
                this._level = level;
                max_lazy_match = config_table[this._level].max_lazy;
                good_match = config_table[this._level].good_length;
                nice_match = config_table[this._level].nice_length;
                max_chain_length = config_table[this._level].max_chain;
            }
            this.strategy = strategy;
            return err;
        }
Example #3
0
            private static int Process(zlib.ZStream /*!*/ zst, zlib.FlushStrategy flush, bool compress,
                                       ref MutableString trailingUncompressedData)
            {
                if (zst.next_out == null)
                {
                    zst.next_out       = new byte[DEFAULTALLOC];
                    zst.next_out_index = 0;
                    zst.avail_out      = zst.next_out.Length;
                }

                int result = compress ? zst.deflate(flush) : zst.inflate(flush);

                while (result == Z_OK && zst.avail_out == 0)
                {
                    byte[] output    = zst.next_out;
                    int    oldLength = output.Length;

                    Array.Resize(ref output, oldLength * 2);

                    zst.next_out  = output;
                    zst.avail_out = oldLength;
                    result        = compress ? zst.deflate(flush) : zst.inflate(flush);
                }

                if (!compress && (result == Z_STREAM_END || result == Z_STREAM_ERROR && !zst.IsInitialized))
                {
                    // MRI hack: any data left in the stream are saved into a separate buffer and returned when "finish" is called
                    // This is weird behavior, one would expect the rest of the stream is either ignored or copied to the output buffer.
#if COPY_UNCOMPRESSED_DATA_TO_OUTPUT_BUFFER
                    Debug.Assert(zst.next_in_index + zst.avail_in <= zst.next_in.Length);
                    Debug.Assert(zst.next_out_index + zst.avail_out <= zst.next_out.Length);

                    if (zst.avail_in > zst.avail_out)
                    {
                        byte[] output    = zst.next_out;
                        int    oldLength = output.Length;

                        Array.Resize(ref output, Math.Max(zst.next_out_index + zst.avail_in, oldLength * 2));
                        zst.next_out = output;
                    }

                    Buffer.BlockCopy(zst.next_in, zst.next_in_index, zst.next_out, zst.next_out_index, zst.avail_in);

                    // MRI subtracts till 0 is reached:
                    zst.avail_out       = Math.Max(zst.avail_out - zst.avail_in, 0);
                    zst.next_out_index += zst.avail_in;
                    zst.avail_in        = 0;
#else
                    if (trailingUncompressedData == null)
                    {
                        trailingUncompressedData = MutableString.CreateBinary();
                    }

                    trailingUncompressedData.Append(zst.next_in, zst.next_in_index, zst.avail_in);

                    // MRI subtracts till 0 is reached:
                    zst.avail_out = Math.Max(zst.avail_out - zst.avail_in, 0);
                    zst.avail_in  = 0;
#endif
                    result = Z_STREAM_END;
                }

                return(result);
            }
Example #4
0
        public static string compress([BytesConversion]IList<byte> data,
            [DefaultParameterValue(Z_DEFAULT_COMPRESSION)]int level)
        {
            byte[] input = data.ToArray();
            byte[] output = new byte[input.Length + input.Length / 1000 + 12 + 1];

            ZStream zst = new ZStream();
            zst.next_in = input;
            zst.avail_in = input.Length;
            zst.next_out = output;
            zst.avail_out = output.Length;

            int err = zst.deflateInit(level);
            switch(err)
            {
                case (Z_OK):
                    break;
                
                case (Z_STREAM_ERROR):
                    throw PythonOps.CreateThrowable(error,
                                    "Bad compression level");
                
                default:
                    zst.deflateEnd();
                    zlib_error(zst, err, "while compressing data");
                    return null;
            }

            err = zst.deflate(FlushStrategy.Z_FINISH);

            if(err != Z_STREAM_END)
            {
                zst.deflateEnd();
                throw zlib_error(zst, err, "while compressing data");
            }

            err = zst.deflateEnd();

            if(err == Z_OK)
                return PythonAsciiEncoding.Instance.GetString(output, 0, (int)zst.total_out);
            else
                throw zlib_error(zst, err, "while finishing compression");
        }