private uint[] CalculateHuffmanCode() { uint[] numArray = new uint[0x11]; byte[] codeLengthArray = this.codeLengthArray; for (int i = 0; i < codeLengthArray.Length; i++) { int index = codeLengthArray[i]; numArray[index]++; } numArray[0] = 0; uint[] numArray2 = new uint[0x11]; uint num2 = 0; for (int j = 1; j <= 0x10; j++) { numArray2[j] = (num2 + numArray[j - 1]) << 1; } uint[] numArray3 = new uint[0x120]; for (int k = 0; k < this.codeLengthArray.Length; k++) { int length = this.codeLengthArray[k]; if (length > 0) { numArray3[k] = DecodeHelper.BitReverse(numArray2[length], length); numArray2[length]++; } } return(numArray3); }
// Calculate the huffman code for each character based on the code length for each character. // This algorithm is described in standard RFC 1951 uint[] CalculateHuffmanCode() { uint[] bitLengthCount = new uint[17]; foreach (int codeLength in codeLengthArray) { bitLengthCount[codeLength]++; } bitLengthCount[0] = 0; // clear count for length 0 uint[] nextCode = new uint[17]; uint tempCode = 0; for (int bits = 1; bits <= 16; bits++) { tempCode = (tempCode + bitLengthCount[bits - 1]) << 1; nextCode[bits] = tempCode; } uint[] code = new uint[MaxLiteralTreeElements]; for (int i = 0; i < codeLengthArray.Length; i++) { int len = codeLengthArray[i]; if (len > 0) { code[i] = DecodeHelper.BitReverse(nextCode[len], len); nextCode[len]++; } } return(code); }
public int Inflate(byte[] bytes, int offset, int length) { // copy bytes from output to outputbytes if we have aviable bytes // if buffer is not filled up. keep decoding until no input are available // if decodeBlock returns false. Throw an exception. int count = 0; do { int copied = output.CopyTo(bytes, offset, length); if (copied > 0) { if (using_gzip) { crc32 = DecodeHelper.UpdateCrc32(crc32, bytes, offset, copied); uint n = streamSize + (uint)copied; if (n < streamSize) // overflow, the gzip stream is probably malicious. { throw new InvalidDataException(SR.GetString(SR.StreamSizeOverflow)); } streamSize = n; } offset += copied; count += copied; length -= copied; } if (length == 0) // filled in the bytes array { break; } // Decode will return false when more input is needed } while (!Finished() && Decode()); if (state == InflaterState.VerifyingGZIPFooter) // finished reading CRC // In this case finished is true and output window has all the data. // But some data in output window might not be copied out. { if (output.AvailableBytes == 0) { if (crc32 != gZipDecoder.Crc32) { throw new InvalidDataException(SR.GetString(SR.InvalidCRC)); } if (streamSize != gZipDecoder.StreamSize) { throw new InvalidDataException(SR.GetString(SR.InvalidStreamSize)); } } } return(count); }
public int GetCompressedOutput(byte[] outputBuffer) { this.output.UpdateBuffer(outputBuffer); if (this.usingGzip && !this.hasGzipHeader) { this.output.WriteGzipHeader(3); this.hasGzipHeader = true; } if (!this.hasBlockHeader) { this.hasBlockHeader = true; this.output.WritePreamble(); } do { int count = (this.inputBuffer.Count < this.inputWindow.FreeWindowSpace) ? this.inputBuffer.Count : this.inputWindow.FreeWindowSpace; if (count > 0) { this.inputWindow.CopyBytes(this.inputBuffer.Buffer, this.inputBuffer.StartIndex, count); if (this.usingGzip) { this.gzipCrc32 = DecodeHelper.UpdateCrc32(this.gzipCrc32, this.inputBuffer.Buffer, this.inputBuffer.StartIndex, count); uint num2 = this.inputStreamSize + ((uint)count); if (num2 < this.inputStreamSize) { throw new InvalidDataException("The gzip stream can't contain more than 4GB data."); } this.inputStreamSize = num2; } this.inputBuffer.ConsumeBytes(count); } while ((this.inputWindow.BytesAvailable > 0) && this.output.SafeToWriteTo()) { this.inputWindow.GetNextSymbolOrMatch(this.currentMatch); if (this.currentMatch.State == MatchState.HasSymbol) { this.output.WriteChar(this.currentMatch.Symbol); } else { if (this.currentMatch.State == MatchState.HasMatch) { this.output.WriteMatch(this.currentMatch.Length, this.currentMatch.Position); continue; } this.output.WriteChar(this.currentMatch.Symbol); this.output.WriteMatch(this.currentMatch.Length, this.currentMatch.Position); } } }while (this.output.SafeToWriteTo() && !this.NeedsInput()); this.needsEOB = true; return(this.output.BytesWritten); }
public int Inflate(byte[] bytes, int offset, int length) { int num = 0; do { int num2 = this.output.CopyTo(bytes, offset, length); if (num2 > 0) { if (this.using_gzip) { this.crc32 = DecodeHelper.UpdateCrc32(this.crc32, bytes, offset, num2); uint num3 = this.streamSize + ((uint)num2); if (num3 < this.streamSize) { throw new InvalidDataException("The gzip stream can't contain more than 4GB data."); } this.streamSize = num3; } offset += num2; num += num2; length -= num2; } }while (((length != 0) && !this.Finished()) && this.Decode()); if ((this.state == InflaterState.VerifyingGZIPFooter) && (this.output.AvailableBytes == 0)) { if (this.crc32 != this.gZipDecoder.Crc32) { throw new InvalidDataException("The CRC in GZip footer does not match the CRC calculated from the decompressed data."); } if (this.streamSize != this.gZipDecoder.StreamSize) { throw new InvalidDataException("The stream size in GZip footer does not match the real stream size."); } } return(num); }
// // Copy the compressed byte to outputBuffer // Returns the bytes we have copied. The caller needs to provide the buffer // to avoid extra coping. // public int GetCompressedOutput(byte[] outputBuffer) { Debug.Assert(!NeedsInput(), "call SetInput before trying to compress!"); output.UpdateBuffer(outputBuffer); if (usingGzip && !hasGzipHeader) { // Write the GZIP header only once output.WriteGzipHeader(3); hasGzipHeader = true; } if (!hasBlockHeader) { // Output dynamic block header only once hasBlockHeader = true; output.WritePreamble(); } do { // read more input data into the window if there is space available int bytesToCopy = (inputBuffer.Count < inputWindow.FreeWindowSpace) ? inputBuffer.Count : inputWindow.FreeWindowSpace; if (bytesToCopy > 0) { // copy data into history window inputWindow.CopyBytes(inputBuffer.Buffer, inputBuffer.StartIndex, bytesToCopy); if (usingGzip) { // update CRC for gzip stream gzipCrc32 = DecodeHelper.UpdateCrc32(gzipCrc32, inputBuffer.Buffer, inputBuffer.StartIndex, bytesToCopy); uint n = inputStreamSize + (uint)bytesToCopy; if (n < inputStreamSize) // overflow, gzip doesn't support compressing more than Int32.Maxvalue bytes. { throw new InvalidDataException(SR.GetString(SR.StreamSizeOverflow)); } inputStreamSize = n; } inputBuffer.ConsumeBytes(bytesToCopy); } // compress the bytes in input history window while (inputWindow.BytesAvailable > 0 && output.SafeToWriteTo()) { // 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) { output.WriteChar(currentMatch.Symbol); } else if (currentMatch.State == MatchState.HasMatch) { output.WriteMatch(currentMatch.Length, currentMatch.Position); } else { output.WriteChar(currentMatch.Symbol); output.WriteMatch(currentMatch.Length, currentMatch.Position); } } } while (output.SafeToWriteTo() && !NeedsInput()); // update book keeping needed to write end of block data needsEOB = true; return(output.BytesWritten); // number of bytes we have written }