Soporte de compresión LZW

Panorama

HotPDF decodifica streams PDF heredados que usan el filtro LZWDecode y puede invertir los predictores TIFF o PNG que suelen acompañar a ese filtro

Características clave

  • Transiciones de ancho de código con EarlyChange=1 y EarlyChange=0 del PDF
  • Orden de relleno de bit más significativo y menos significativo
  • Manejo del reinicio por código clear, del fin de información y de la expansión KwKwK
  • Salida directa a un TStream sin construir una segunda cadena de resultado
  • Límites de salida configurables y comprobaciones estrictas opcionales de clear inicial y fin de información
  • TIFF Predictor 2 a 1, 2, 4, 8 o 16 bits por componente
  • Filtros de fila PNG None, Sub, Up, Average y Paeth
  • Estadísticas por decodificación de anchos de código, crecimiento del diccionario, reinicios, expansiones y bytes de salida

Tipos

  • TPDFLZWDecompressor es la clase de decodificador reutilizable
  • TPDFLZWCompressor es la clase de codificador correspondiente
  • TPDFLZWParms transporta la geometría del predictor PDF
  • TPDFLZWFillOrder selecciona el orden de bits foTop o foBottom
  • EHPDFLZWError informa de entrada malformada, geometría no soportada y fallos de límites configurados

Propiedades de configuración

  • FillOrder selecciona el orden de bits comprimido
  • EarlyChange selecciona la regla de transición de ancho de diccionario del PDF y por defecto es True
  • InitialCodeSize acepta valores de 2 a 9 y por defecto es 9 para PDF
  • Para alfabetos reducidos, cada byte sin comprimir debe ser menor que 1 shl (InitialCodeSize - 1); la compresión lanza EHPDFLZWError antes de escribir la salida si algún byte está fuera de ese rango
  • MaxOutputBytes detiene la expansión excesiva antes de cruzar el límite configurado; cero significa ilimitado
  • RequireInitialClear exige que el primer código reinicie el diccionario
  • RequireEndOfInformation rechaza un stream que termina sin su terminador

Métodos

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 lanza EHPDFLZWError ante entrada no válida
  • TryDecompress devuelve False y expone el motivo a través de LastError
  • DecompressToStream y DecompressStream devuelven el número de bytes decodificados escritos
  • DecompressStream lee desde la posición actual de entrada y restaura esa posición por defecto cuando el stream admite seek

Descompresión LZW básica

TPDFLZWCompressor.CompressToStream y CompressStream devuelven el número de bytes codificados escritos, incluidos el código clear y el código de fin de información para una entrada vacía; la configuración PDF por defecto escribe 3 bytes para una entrada vacía

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;

Salida a stream y diagnóstico

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;

Parámetros del predictor

  • Predictor=1 devuelve los bytes descomprimidos sin cambios
  • Predictor=2 invierte la diferenciación horizontal TIFF
  • Predictor=10..15 invierte la etiqueta de filtro PNG guardada al inicio de cada fila
  • Colors, BitsPerComponent y Columns definen la geometría exacta de la fila
  • ExpandedTo8Bit y ColorSpace siguen disponibles por compatibilidad de código fuente

Estadísticas de decodificación

  • CodesRead, ClearCodesRead y DictionaryAdds
  • KwKwKExpansions, PeakCodeSize y PeakDictionarySize
  • OutputBytes y EndedWithEndOfInformation

Manejo de errores

  • Los códigos más allá de la siguiente entrada del diccionario se rechazan
  • Las cadenas de prefijos rotas y un primer código no válido se rechazan
  • La entrada truncada se rechaza cuando RequireEndOfInformation está activo
  • La expansión de salida se comprueba antes de emitir cada frase
  • Las filas del predictor deben estar completas y usar una geometría y una etiqueta de fila PNG válidas

Ver también