public inflate ( FlushStrategy flush ) : int | ||
flush | FlushStrategy | |
return | int |
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); }
public static string decompress([BytesConversion]IList<byte> data, [DefaultParameterValue(MAX_WBITS)]int wbits, [DefaultParameterValue(DEFAULTALLOC)]int bufsize) { byte[] input = data.ToArray(); byte[] outputBuffer = new byte[bufsize]; byte[] output = new byte[bufsize]; int outputOffset = 0; ZStream zst = new ZStream(); zst.next_in = input; zst.avail_in = input.Length; zst.next_out = outputBuffer; zst.avail_out = outputBuffer.Length; int err = zst.inflateInit(wbits); if(err != Z_OK) { zst.inflateEnd(); throw zlib_error(zst, err, "while preparing to decompress data"); } do { err = zst.inflate(FlushStrategy.Z_FINISH); if(err != Z_STREAM_END) { if(err == Z_BUF_ERROR && zst.avail_out > 0) { zst.inflateEnd(); throw zlib_error(zst, err, "while decompressing data"); } else if(err == Z_OK || (err == Z_BUF_ERROR && zst.avail_out == 0)) { // copy to the output and reset the buffer if(outputOffset + outputBuffer.Length > output.Length) Array.Resize(ref output, output.Length * 2); Array.Copy(outputBuffer, 0, output, outputOffset, outputBuffer.Length); outputOffset += outputBuffer.Length; zst.next_out = outputBuffer; zst.avail_out = outputBuffer.Length; zst.next_out_index = 0; } else { zst.inflateEnd(); throw zlib_error(zst, err, "while decompressing data"); } } } while(err != Z_STREAM_END); err = zst.inflateEnd(); if(err != Z_OK) { throw zlib_error(zst, err, "while finishing data decompression"); } if(outputOffset + outputBuffer.Length - zst.avail_out > output.Length) Array.Resize(ref output, output.Length * 2); Array.Copy(outputBuffer, 0, output, outputOffset, outputBuffer.Length - zst.avail_out); outputOffset += outputBuffer.Length - zst.avail_out; return PythonAsciiEncoding.Instance.GetString(output, 0, outputOffset); }
/// <summary> /// Reads a number of decompressed bytes into the specified byte array. /// </summary> /// <param name="buffer">The array used to store decompressed bytes.</param> /// <param name="offset">The location in the array to begin reading.</param> /// <param name="count">The number of decompressed bytes to read.</param> /// <returns>The number of bytes that were decompressed into the byte array.</returns> /// <example> The following code demonstrates how to use the <c>ZInputStream</c> to decompresses data /// <code> /// [C#] /// private void decompressFile(string inFile, string outFile) /// { /// /* Create a file to store decompressed data */ /// System.IO.FileStream decompressedFile = new System.IO.FileStream(@"c:\data\decompressed.dat", System.IO.FileMode.Create); /// /* Open a file containing compressed data */ /// System.IO.FileStream compressedFile = new System.IO.FileStream(@"c:\data\compressed.dat", System.IO.FileMode.Open); /// /* Create ZInputStream for decompression */ /// ZInputStream decompressionStream = new ZInputStream(compressedFile); /// /// try /// { /// byte[] buffer = new byte[2000]; /// int len; /// /* Read and decompress data */ /// while ((len = decompressionStream.Read(buffer, 0, 2000)) > 0) /// { /// /* Store decompressed data */ /// decompressedFile.Write(buffer, 0, len); /// } /// } /// finally /// { /// decompressionStream.Close(); /// decompressedFile.Close(); /// compressedFile.Close(); /// } /// } /// </code> /// </example> public override int Read(byte[] buffer, int offset, int count) { if (count == 0) { return(0); } if (this.needCopyArrays && ZLibUtil.CopyLargeArrayToSmall.GetRemainingDataSize() > 0) { return(ZLibUtil.CopyLargeArrayToSmall.CopyData()); } else { this.needCopyArrays = false; } bool call_finish = false; int err; z.next_out = buffer; z.next_out_index = offset; z.avail_out = count; do { if ((z.avail_in == 0) && (!nomoreinput)) { // if buffer is empty and more input is available, refill it z.next_in_index = 0; z.avail_in = ZLibUtil.ReadInput(_stream, buf, 0, ZLibUtil.zLibBufSize); //(ZLibUtil.zLibBufSize<z._avail_out ? ZLibUtil.zLibBufSize : z._avail_out)); if (z.avail_in == -1) { z.avail_in = 0; nomoreinput = true; } } if ((z.avail_in == 0) && nomoreinput) { call_finish = true; break; } err = z.inflate(flush); if (nomoreinput && (err == (int)ZLibResultCode.Z_BUF_ERROR)) { return(-1); } if (err != (int)ZLibResultCode.Z_OK && err != (int)ZLibResultCode.Z_STREAM_END) { throw new ZStreamException("inflating: " + z.msg); } if (nomoreinput && (z.avail_out == count)) { return(-1); } }while (z.avail_out == count && err == (int)ZLibResultCode.Z_OK); if (call_finish) { return(Finish(buffer, offset, count)); } return(count - z.avail_out); }
internal static byte[] Decompress(byte[] input, int wbits=MAX_WBITS, int bufsize=DEFAULTALLOC) { byte[] outputBuffer = new byte[bufsize]; byte[] output = new byte[bufsize]; int outputOffset = 0; ZStream zst = new ZStream(); zst.next_in = input; zst.avail_in = input.Length; zst.next_out = outputBuffer; zst.avail_out = outputBuffer.Length; int err = zst.inflateInit(wbits); if(err != Z_OK) { zst.inflateEnd(); throw zlib_error(zst, err, "while preparing to decompress data"); } do { err = zst.inflate(FlushStrategy.Z_FINISH); if(err != Z_STREAM_END) { if(err == Z_BUF_ERROR && zst.avail_out > 0) { zst.inflateEnd(); throw zlib_error(zst, err, "while decompressing data"); } else if(err == Z_OK || (err == Z_BUF_ERROR && zst.avail_out == 0)) { // copy to the output and reset the buffer if(outputOffset + outputBuffer.Length > output.Length) Array.Resize(ref output, output.Length * 2); Array.Copy(outputBuffer, 0, output, outputOffset, outputBuffer.Length); outputOffset += outputBuffer.Length; zst.next_out = outputBuffer; zst.avail_out = outputBuffer.Length; zst.next_out_index = 0; } else { zst.inflateEnd(); throw zlib_error(zst, err, "while decompressing data"); } } } while(err != Z_STREAM_END); err = zst.inflateEnd(); if(err != Z_OK) { throw zlib_error(zst, err, "while finishing data decompression"); } if(outputOffset + outputBuffer.Length - zst.avail_out > output.Length) Array.Resize(ref output, output.Length * 2); Array.Copy(outputBuffer, 0, output, outputOffset, outputBuffer.Length - zst.avail_out); outputOffset += outputBuffer.Length - zst.avail_out; return output.Take(outputOffset).ToArray(); }