Soporte de compresión LZW

Visión general

HotPDF decodifica streams PDF legados que usan el filtro LZWDecode y puede invertir los predictores TIFF o PNG habitualmente emparejados con ese filtro

Características principales

  • Transiciones de ancho de código PDF EarlyChange=1 y EarlyChange=0
  • Orden de relleno de bit más significativo y de bit menos significativo
  • Reinicio por código de limpieza, fin de información y manejo de la expansión KwKwK
  • Salida directa a un TStream sin construir una segunda cadena de resultado
  • Límites de salida configurables y comprobaciones opcionales estrictas de limpieza 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 entradas malformadas, 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 anchura de diccionario del PDF y vale True por defecto
  • InitialCodeSize acepta valores de 2 a 9 y por defecto 9 en 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, con cero significando sin límite
  • 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 con entrada no válida
  • TryDecompress devuelve False y expone el motivo mediante LastError
  • DecompressToStream y DecompressStream devuelven el número de bytes decodificados escritos
  • DecompressStream lee desde la posición de entrada actual y, por defecto, restaura esa posición cuando el stream es seekable

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 end-of-information para 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 almacenada al inicio de cada fila
  • Colors, BitsPerComponent y Columns definen la geometría exacta de fila
  • ExpandedTo8Bit y ColorSpace siguen disponibles por compatibilidad de origen

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 etiqueta de fila PNG válidas

Véase también