LZW Compression Support

Omówienie

Obsługa kompresji LZW jest implementowana przez unit HPDFLZW.pas, który zapewnia:

Class Reference

  • Przejścia szerokości kodu PDF EarlyChange=1 i EarlyChange=0
  • Kolejność wypełniania od najbardziej i od najmniej znaczącego bitu
  • Obsługa resetu kodem clear, end-of-information i ekspansji KwKwK
  • Bezpośrednie zapisywanie do TStream bez budowania drugiego ciągu wynikowego
  • Konfigurowalne limity wyjścia oraz opcjonalne ścisłe kontrole initial-clear i end-of-information
  • TIFF Predictor 2 przy 1, 2, 4, 8 albo 16 bitach na komponent
  • Filtry wierszy PNG None, Sub, Up, Average i Paeth
  • Statystyki per dekodowanie: szerokości kodów, wzrost słownika, resety, ekspansje i bajty wyjścia

TPDFLZWDecompressor

  • TPDFLZWDecompressor to reużywalna klasa dekodera
  • TPDFLZWCompressor to pasująca klasa enkodera
  • TPDFLZWParms niesie geometrię predyktora PDF
  • TPDFLZWFillOrder wybiera kolejność bitów foTop albo foBottom
  • EHPDFLZWError raportuje zniekształcone wejście, nieobsługiwaną geometrię i przekroczenia skonfigurowanych limitów

Główna klasa operacji dekompresji LZW

  • FillOrder wybiera kolejność bitów w danych skompresowanych
  • EarlyChange wybiera regułę przejścia szerokości kodu ze słownika PDF i domyślnie ma True
  • InitialCodeSize przyjmuje wartości od 2 do 9 i dla PDF domyślnie 9
  • Dla zredukowanych alfabetów każdy bajt nieskompresowany musi być mniejszy niż 1 shl (InitialCodeSize - 1); kompresja podnosi EHPDFLZWError przed zapisem wyjścia, gdy bajt wypada poza tym zakresem
  • MaxOutputBytes zatrzymuje nadmierną ekspansję przed przekroczeniem skonfigurowanego limitu; zero oznacza brak limitu
  • RequireInitialClear wymaga, by pierwszy kod resetował słownik
  • RequireEndOfInformation odrzuca strumień zakończony bez terminatora

Properties:

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 podnosi EHPDFLZWError przy nieprawidłowym wejściu
  • TryDecompress zwraca False i udostępnia przyczynę przez LastError
  • DecompressToStream i DecompressStream zwracają liczbę zapisanych zdekodowanych bajtów
  • DecompressStream czyta od bieżącej pozycji wejścia i domyślnie przywraca tę pozycję, gdy strumień pozwala na seek

Basic LZW Decompression

TPDFLZWCompressor.CompressToStream i CompressStream zwracają liczbę zapisanych zakodowanych bajtów, łącznie z kodem clear i kodem end-of-information dla pustego wejścia; domyślna konfiguracja PDF zapisuje 3 bajty dla pustego wejścia


// 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;
        

PDF Parameter Support

  • Predictor=1 zwraca bajty po dekompresji bez zmian
  • Predictor=2 odwraca różnicowanie poziome TIFF
  • Predictor=10..15 odwraca tag filtru PNG zapisany na początku każdego wiersza
  • Colors, BitsPerComponent i Columns definiują dokładną geometrię wiersza
  • ExpandedTo8Bit i ColorSpace pozostają dostępne dla kompatybilności źródeł

TPDFLZWParms Structure

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

Algorithm Details

  • Kody wykraczające poza kolejny wpis słownika są odrzucane
  • Złamane łańcuchy prefiksów i nieprawidłowy pierwszy kod są odrzucane
  • Ucięte wejście jest odrzucane, gdy włączono RequireEndOfInformation
  • Ekspansja wyjścia jest sprawdzana przed emisją każdej frazy
  • Wiersze predyktora muszą być kompletne i używać poprawnej geometrii oraz tagu wiersza PNG

Common Use Cases

  • PDF content stream decompression
  • Image data decompression in PDF files
  • Text stream decompression
  • Form data decompression
  • PostScript stream decompression