📄 mzlib.pas
字号:
unit MZLib;
{$TYPEDADDRESS OFF}
// Original copyright of the creators:
//
// zlib.H -- interface of the 'zlib' general purpose compression library version 1.1.0, Feb 24th, 1998
//
// Copyright (C) 1995-1998 Jean-loup Gailly and Mark Adler
//
// This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held
// liable for any damages arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter
// it and redistribute it freely, subject to the following restrictions:
// 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software.
// If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is
// not required.
// 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
// 3. This notice may not be removed or altered from any Source distribution.
//
// Jean-loup Gailly Mark Adler
// jloup@gzip.org madler@alumni.caltech.edu
//
// The data format used by the zlib library is described by RFCs (Request for Comments) 1950 to 1952 in the files
// ftp://deststate.internic.net/rfc/rfc1950.txt (zlib format), rfc1951.txt (Deflate format) and rfc1952.txt (gzip format).
//
// patch 112 from the zlib home page is implicitly applied here
//
// Delphi translation: (C) 2000 by Dipl. Ing. Mike Lischke (www.delphi-gems.com)
interface
uses
Windows;
// The 'zlib' compression library provides in-memory compression and decompression functions, including integrity checks
// of the uncompressed data. This version of the library supports only one compression method (deflation) but other
// algorithms will be added later and will have the same stream interface.
//
// Compression can be done in a single step if the buffers are large enough (for example if an input file is mmap'ed),
// or can be done by repeated calls of the compression function. In the latter case, the application must provide more
// input and/or consume the output (providing more output space) before each call.
//
// The library also supports reading and writing files in gzip (.gz) format.
//
// The library does not install any signal handler. The decoder checks
// the consistency of the compressed data, so the library should never
// crash even in case of corrupted input.
//----------------- general library stuff ------------------------------------------------------------------------------
resourcestring
SNeedDict = 'need dictionary';
SStreamEnd = 'stream end';
SFileError = 'file error';
SStreamError = 'stream error';
SDataError = 'data error';
SInsufficientMemory = 'insufficient memory';
SBufferError = 'buffer error';
SIncompatibleVersion = 'incompatible version';
SInvalidDistanceCode = 'invalid distance code';
SInvalidLengthCode = 'invalid literal/length code';
SOversubscribedDBLTree = 'oversubscribed dynamic bit lengths tree';
SIncompleteDBLTree = 'incomplete dynamic bit lengths tree';
SOversubscribedLLTree = 'oversubscribed literal/length tree';
SIncompleteLLTree = 'incomplete literal/length tree';
SEmptyDistanceTree = 'empty distance tree with lengths';
SInvalidBlockType = 'invalid block type';
SInvalidStoredBlockLengths = 'invalid stored block lengths';
STooManyLDSymbols = 'too many length or distance symbols';
SInvalidBitLengthRepeat = 'invalid bit length repeat';
SIncorrectDataCheck = 'incorrect data check';
SUnknownCompression = 'unknown compression method';
SInvalidWindowSize = 'invalid window size';
SIncorrectHeaderCheck = 'incorrect header check';
SNeedDictionary = 'need dictionary';
type
PWord = ^Word;
PInteger = ^Integer;
PCardinal = ^Cardinal;
type
TByteArray = array[0..(MaxInt div SizeOf(Byte)) - 1] of Byte;
PByteArray = ^TByteArray;
TWordArray = array[0..(MaxInt div SizeOf(Word)) - 1] of Word;
PWordArray = ^TWordArray;
TIntegerArray = array[0..(MaxInt div SizeOf(Integer)) - 1] of Integer;
PIntegerArray = ^TIntegerArray;
TCardinalArray = array[0..(MaxInt div SizeOf(Cardinal)) - 1] of Cardinal;
PCardinalArray = ^TCardinalArray;
const
// maximum value for MemLevel in DeflateInit2
MAX_MEM_LEVEL = 9;
DEF_MEM_LEVEL = 8;
// maximum value for WindowBits in DeflateInit2 and InflateInit2
MAX_WBITS = 15; // 32K LZ77 window
// default WindowBits for decompression, MAX_WBITS is for compression only
DEF_WBITS = MAX_WBITS;
type
PInflateHuft = ^TInflateHuft;
TInflateHuft = record
Exop, // number of extra bits or operation
Bits: Byte; // number of bits in this code or subcode
Base: Cardinal; // literal, Length base, or distance base or table offset
end;
THuftField = array[0..(MaxInt div SizeOf(TInflateHuft)) - 1] of TInflateHuft;
PHuftField = ^THuftField;
PPInflateHuft = ^PInflateHuft;
TInflateCodesMode = ( // waiting for "I:"=input, "O:"=output, "X:"=nothing
icmStart, // X: set up for Len
icmLen, // I: get length/literal/eob next
icmLenNext, // I: getting length extra (have base)
icmDistance, // I: get distance next
icmDistExt, // I: getting distance extra
icmCopy, // O: copying bytes in window, waiting for space
icmLit, // O: got literal, waiting for output space
icmWash, // O: got eob, possibly still output waiting
icmZEnd, // X: got eob and all data flushed
icmBadCode // X: got error
);
// inflate codes private state
PInflateCodesState = ^TInflateCodesState;
TInflateCodesState = record
Mode: TInflateCodesMode; // current inflate codes mode
// mode dependent information
Len: Cardinal;
Sub: record // submode
case Byte of
0:
(Code: record // if Len or Distance, where in tree
Tree: PInflateHuft; // pointer into tree
need: Cardinal; // bits needed
end);
1:
(lit: Cardinal); // if icmLit, literal
2:
(copy: record // if EXT or icmCopy, where and how much
get: Cardinal; // bits to get for extra
Distance: Cardinal; // distance back to copy from
end);
end;
// mode independent information
LiteralTreeBits: Byte; // LiteralTree bits decoded per branch
DistanceTreeBits: Byte; // DistanceTree bits decoder per branch
LiteralTree: PInflateHuft; // literal/length/eob tree
DistanceTree: PInflateHuft; // distance tree
end;
TCheckFunction = function(Check: Cardinal; Buffer: PByte; Len: Cardinal): Cardinal;
TInflateBlockMode = (
ibmZType, // get type bits (3, including end bit)
ibmLens, // get lengths for stored
ibmStored, // processing stored block
ibmTable, // get table lengths
ibmBitTree, // get bit lengths tree for a dynamic block
ibmDistTree, // get length, distance trees for a dynamic block
ibmCodes, // processing fixed or dynamic block
ibmDry, // output remaining window bytes
ibmBlockDone, // finished last block, done
ibmBlockBad // got a data error -> stuck here
);
// inflate blocks semi-private state
PInflateBlocksState = ^TInflateBlocksState;
TInflateBlocksState = record
Mode: TInflateBlockMode; // current inflate block mode
// mode dependent information
Sub: record // submode
case Byte of
0:
(left: Cardinal); // if ibmStored, bytes left to copy
1:
(Trees: record // if DistanceTree, decoding info for trees
Table: Cardinal; // table lengths (14 Bits)
Index: Cardinal; // index into blens (or BitOrder)
blens: PCardinalArray; // bit lengths of codes
BB: Cardinal; // bit length tree depth
TB: PInflateHuft; // bit length decoding tree
end);
2:
(decode: record // if ibmCodes, current state
TL: PInflateHuft;
TD: PInflateHuft; // trees to free
codes: PInflateCodesState;
end);
end;
Last: Boolean; // True if this block is the last block
// mode independent information
bitk: Cardinal; // bits in bit buffer
bitb: Cardinal; // bit buffer
hufts: PHuftField; // single allocation for tree space
window: PByte; // sliding window
zend: PByte; // one byte after sliding window
read: PByte; // window read pointer
write: PByte; // window write pointer
CheckFunction: TCheckFunction; // check function
Check: Cardinal; // check on output
end;
TInflateMode = (
imMethod, // waiting for imMethod Byte
imFlag, // waiting for flag byte
imDict4, // four dictionary check bytes to go
imDict3, // three dictionary check bytes to go
imDict2, // two dictionary check bytes to go
imDict1, // one dictionary check byte to go
imDict0, // waiting for InflateSetDictionary
imBlocks, // decompressing blocks
imCheck4, // four check bytes to go
imCheck3, // three check bytes to go
imCheck2, // two check bytes to go
imCheck1, // one check byte to go
imDone, // finished check, done
imBad // got an error -> stay here
);
// inflate private state
PInternalState = ^TInternalState;
TInternalState = record
Mode: TInflateMode; // current inflate mode
// mode dependent information
Sub: record // submode
case Byte of
0:
(imMethod: Cardinal); // if FLAGS, imMethod byte
1:
(Check: record // if check, check values to compare
was: Cardinal; // computed check value
need: Cardinal; // stream check value
end);
2:
(marker: Cardinal); // if imBad, InflateSync's marker bytes count
end;
// mode independent information
nowrap: Boolean; // flag for no wrapper
wbits: Cardinal; // log2(window Size) (8..15, defaults to 15)
blocks: PInflateBlocksState; // current InflateBlocks state
end;
// The application must update NextInput and AvailableInput when AvailableInput has dropped to zero. It must update
// NextOutput and AvailableOutput when AvailableOutput has dropped to zero. All other fields are set by the
// compression library and must not be updated by the application.
//
// The fields TotalInput and TotalOutput can be used for statistics or progress reports. After compression, TotalInput
// holds the total size of the uncompressed data and may be saved for use in the decompressor
// (particularly if the decompressor wants to decompress everything in a single step).
PZState = ^TZState;
TZState = record
NextInput: PByte; // next input byte
AvailableInput: Cardinal; // number of bytes available at NextInput
TotalInput: Cardinal; // total number of input bytes read so far
NextOutput: PByte; // next output byte should be put there
AvailableOutput: Cardinal; // remaining free space at NextOutput
TotalOutput: Cardinal; // total number of bytes output so far
Msg: String; // last error message, '' if no error
State: PInternalState; // not visible by applications
DataType: Integer; // best guess about the data type: ASCII or binary
Adler: Cardinal; // Adler32 value of the uncompressed data
end;
const
// allowed flush values, see Deflate below for details
Z_NO_FLUSH = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -