|
LZW Compression Support
Overview
HotPDF decodes legacy PDF streams that use the LZWDecode filter and can reverse the TIFF or PNG predictors commonly paired with that filter
Key Features
- PDF
EarlyChange=1 and EarlyChange=0 code-width transitions
- Most-significant-bit and least-significant-bit fill order
- Clear-code reset, end-of-information, and
KwKwK expansion handling
- Direct output to a
TStream without constructing a second result string
- Configurable output limits and optional strict initial-clear and end-of-information checks
- TIFF Predictor 2 at 1, 2, 4, 8, or 16 bits per component
- PNG None, Sub, Up, Average, and Paeth row filters
- Per-decode statistics for code widths, dictionary growth, resets, expansions, and output bytes
Types
TPDFLZWDecompressor is the reusable decoder class
TPDFLZWParms carries PDF predictor geometry
TPDFLZWFillOrder selects foTop or foBottom bit order
EHPDFLZWError reports malformed input, unsupported geometry, and configured-limit failures
Configuration Properties
FillOrder selects the compressed bit order
EarlyChange selects the PDF dictionary-width transition rule and defaults to True
InitialCodeSize accepts values from 2 through 9 and defaults to 9 for PDF
MaxOutputBytes stops excessive expansion before the configured limit is crossed, with zero meaning unlimited
RequireInitialClear requires the first code to reset the dictionary
RequireEndOfInformation rejects a stream that ends without its terminator
Methods
function Decompress(const Input: AnsiString): AnsiString; overload;
function Decompress(const Input: AnsiString;
Parms: TPDFLZWParms): AnsiString; overload;
function TryDecompress(const Input: AnsiString;
out Output: AnsiString): Boolean; overload;
function TryDecompress(const Input: AnsiString; Parms: TPDFLZWParms;
out Output: AnsiString): Boolean; overload;
function DecompressToStream(const Input: AnsiString;
OutputStream: TStream): Int64;
function DecompressStream(InputStream, OutputStream: TStream;
RestoreInputPosition: Boolean = True): Int64;
Decompress raises EHPDFLZWError on invalid input
TryDecompress returns False and exposes the reason through LastError
DecompressToStream and DecompressStream return the number of decoded bytes written
DecompressStream reads from the current input position and restores that position by default when the stream is seekable
Basic LZW Decompression
uses
HPDFLZW;
procedure DecompressLZWData;
var
Decompressor: TPDFLZWDecompressor;
CompressedData: AnsiString;
DecompressedData: AnsiString;
begin
Decompressor := TPDFLZWDecompressor.Create;
try
Decompressor.FillOrder := foTop;
Decompressor.EarlyChange := True;
Decompressor.MaxOutputBytes := 64 * 1024 * 1024;
DecompressedData := Decompressor.Decompress(CompressedData);
ProcessDecompressedData(DecompressedData);
finally
Decompressor.Free;
end;
end;
Stream Output and Diagnostics
procedure DecodeLZWToStream(const CompressedData: AnsiString;
Destination: TStream);
var
Decompressor: TPDFLZWDecompressor;
begin
Decompressor := TPDFLZWDecompressor.Create;
try
Decompressor.RequireInitialClear := True;
Decompressor.RequireEndOfInformation := True;
Decompressor.DecompressToStream(CompressedData, Destination);
LogDecodeStatistics(
Decompressor.CodesRead,
Decompressor.PeakCodeSize,
Decompressor.PeakDictionarySize,
Decompressor.OutputBytes);
finally
Decompressor.Free;
end;
end;
Predictor Parameters
Predictor=1 returns the decompressed bytes unchanged
Predictor=2 reverses TIFF horizontal differencing
Predictor=10..15 reverses the PNG filter tag stored at the start of each row
Colors, BitsPerComponent, and Columns define the exact row geometry
ExpandedTo8Bit and ColorSpace remain available for source compatibility
Decode Statistics
CodesRead, ClearCodesRead, and DictionaryAdds
KwKwKExpansions, PeakCodeSize, and PeakDictionarySize
OutputBytes and EndedWithEndOfInformation
Error Handling
- Codes beyond the next dictionary entry are rejected
- Broken prefix chains and an invalid first code are rejected
- Truncated input is rejected when
RequireEndOfInformation is enabled
- Output expansion is checked before each phrase is emitted
- Predictor rows must be complete and use a valid geometry and PNG row tag
See Also
|