LZW 压缩支持

概述

HotPDF 解码使用 LZWDecode 过滤器的旧式 PDF 流,并能反演常与该过滤器搭配的 TIFF 或 PNG predictor

关键特性

  • PDF EarlyChange=1 与 EarlyChange=0 两种码宽切换规则
  • 可配置的 predictor 支持,用于增强压缩
  • 清除码重置、end-of-information 与 KwKwK 展开处理
  • 直接输出到 TStream,无需再构造一个结果字符串
  • 省内存的流式处理
  • 每分量 1、2、4、8 或 16 位的 TIFF Predictor 2
  • PNG None、Sub、Up、Average 和 Paeth 行过滤器
  • 每次解码的统计信息:码宽、字典增长、重置、展开和输出字节数

类型

  • TPDFLZWDecompressor 是可复用的解码器类
  • TPDFLZWCompressor 是与之配套的编码器类
  • TPDFLZWParms 携带 PDF predictor 几何参数
  • TPDFLZWFillOrder 选择 foTop 或 foBottom 位序
  • EHPDFLZWError 报告畸形输入、不受支持的几何以及触及配置上限的失败

Methods:

  • FillOrder 选择压缩数据的位序
  • EarlyChange 选择 PDF 的字典宽度切换规则,默认 True
  • InitialCodeSize 接受 2 到 9 的值,PDF 场景默认 9
  • 对缩减字母表而言,每个未压缩字节都必须小于 1 shl (InitialCodeSize - 1);只要有字节超出该范围,压缩就会在写出输出之前抛出 EHPDFLZWError
  • MaxOutputBytes 在越过配置上限前阻止过度膨胀,0 表示不限制
  • RequireInitialClear 要求首个码重置字典
  • RequireEndOfInformation 拒绝没有终止符就结束的流

使用示例

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 遇到无效输入时抛出 EHPDFLZWError
  • TryDecompress 返回 False,出错原因经 LastError 提供
  • DecompressToStream 与 DecompressStream 返回已写出的解码字节数
  • DecompressStream 从当前输入位置读取,流可 seek 时默认还原该位置

Basic LZW Decompression

TPDFLZWCompressor.CompressToStream 和 CompressStream 返回已写出的编码字节数,空输入也包含 clear code 与 end-of-information code;默认 PDF 配置对空输入写出 3 字节


// Delphi example - Basic LZW decompression
procedure DecompressLZWData;
var
  Decompressor: TPDFLZWDecompressor;
  CompressedData: AnsiString;
  DecompressedData: AnsiString;
begin
  Decompressor := TPDFLZWDecompressor.Create;
  try
    // Configure decompressor
    Decompressor.FillOrder := foTop;
    Decompressor.EarlyChange := True;
    Decompressor.InitialCodeSize := 9;

    // Decompress data
    DecompressedData := Decompressor.Decompress(CompressedData);

    // Use decompressed data
    ProcessDecompressedData(DecompressedData);
  finally
    Decompressor.Free;
  end;
end;
        

Advanced LZW Decompression with PDF Parameters


// Delphi example - Advanced LZW decompression with PDF parameters
procedure DecompressLZWWithParms;
var
  Decompressor: TPDFLZWDecompressor;
  CompressedData: AnsiString;
  DecompressedData: AnsiString;
  Parms: TPDFLZWParms;
begin
  Decompressor := TPDFLZWDecompressor.Create;
  try
    // Configure PDF parameters
    Parms.Predictor := 2;           // Horizontal differencing predictor
    Parms.Colors := 3;              // RGB color space
    Parms.BitsPerComponent := 8;    // 8 bits per component
    Parms.Columns := 100;           // Image width in pixels
    Parms.ExpandedTo8Bit := True;   // Expand to 8-bit components
    Parms.ColorSpace := 'DeviceRGB';

    // Decompress with parameters
    DecompressedData := Decompressor.Decompress(CompressedData, Parms);

    // Process the decompressed image data
    ProcessImageData(DecompressedData, Parms);
  finally
    Decompressor.Free;
  end;
end;
        

Predictor 参数

  • Predictor=1 原样返回解压后的字节
  • Predictor=2 反演 TIFF 水平差分
  • Predictor=10..15 反演每行开头存储的 PNG 过滤器标签
  • Colors、BitsPerComponent 与 Columns 定义精确的行几何
  • ExpandedTo8Bit 与 ColorSpace 为源码兼容性保留

解码统计

  • CodesRead、ClearCodesRead 与 DictionaryAdds
  • KwKwKExpansions、PeakCodeSize 与 PeakDictionarySize
  • OutputBytes 与 EndedWithEndOfInformation

Error Handling

  • 无效的码序列
  • 损坏的数据流
  • 启用 RequireEndOfInformation 时,被截断的输入会被拒绝
  • 每输出一个短语前都会检查输出膨胀
  • Predictor 行必须完整,并使用有效的几何与 PNG 行标签

另请参阅