Расширенная поддержка сжатия ZLib

Обзор

HotPDF теперь включает всестороннюю поддержку ZLib-совместимого сжатия на базе встроенного zlib-ng для потоков и контента PDF. ZLib-совместимый API даёт эффективное deflate/inflate-сжатие, широко используемое в PDF-документах для операций фильтра FlateDecode и общего сжатия данных.

Ключевые возможности

  • ZLib-совместимый API на базе встроенного zlib-ng
  • Поддержка параметров FlateDecode PDF
  • Потоковые сжатие и распаковка
  • Расширенная обработка ошибок и отладочные возможности
  • Экономная по памяти обработка больших потоков данных
  • Win64 one-shot мост сжатия изображений ради ABI-безопасности длин zlib-ng
  • Win64x и диагностический MSVC Win64 runtime SIMD-диспетч zlib-ng с generic-фолбэками
  • Мост C-аллокации с выравниванием 32 байта для SIMD-дружелюбных нативных буферов
  • Кроссплатформенная интеграция C-библиотеки
  • Несколько уровней сжатия (нет, быстрейший, умолчальный, максимальный)

Техническая реализация

Расширенная поддержка ZLib реализована в юните HPDFZLib.pas, который даёт:

  • Полный ZLib API: Полная реализация функций ZLib
  • Потоковые классы: TCustomZStream и производные классы для потоковой обработки
  • Интеграция с PDF: TPDFFlateParms для PDF-специфичных параметров
  • Расширенные функции: InflateStr, InflateStrParms для упрощённого использования

64-битные наборы объектов zlib-ng включают выбираемые в рантайме пути SSE2, SSSE3, SSE4.1, SSE4.2, PCLMULQDQ и AVX2. Win32 использует generic-набор объектов zlib-ng ради совместимости с тулчейном bcc32c OMF, а объекты Win32 JPEG/TIFF остаются на классическом bcc32.

Регрессионное покрытие

Flate-бэкенд zlib-ng покрыт автоматическими регрессионными наборами Delphi и C++Builder. Текущий валидационный набор проходит 20 тестов Delphi DUnitX на Win32 и 20 на Win64 плюс 17 тестов C++Builder GoogleTest на Win32 и 17 на Win64x. Нативные пересборки объектов тоже проходят с чистого листа: 206 объектов Win32, 205 Win64x и 206 MSVC Win64. Покрытые сценарии включают сжатие потоков страниц, сжатие встроенных шрифтов и ToUnicode CMap, Flate-потоки изображений, стандартное размещение JPEG, импорт TIFF, вывод с обилием штрихкодов, сценарии копирования/слияния/правки и PDF из демо.

Уровни сжатия

  • Z_NO_COMPRESSION (0): Без сжатия
  • Z_BEST_SPEED (1): Быстрейшее сжатие
  • Z_BEST_COMPRESSION (9): Максимальное сжатие
  • Z_DEFAULT_COMPRESSION (-1): Умолчальный баланс скорости и сжатия

Примеры использования

Базовое сжатие/распаковка строк


// Delphi example - Basic string inflation
function DecompressString(const CompressedData: AnsiString): AnsiString;
begin
  // Simple decompression
  Result := InflateStr(CompressedData);

  // With debug output enabled
  Result := InflateStr(CompressedData, True);
end;
        

Потоковое сжатие


// Delphi example - Stream-based decompression
procedure DecompressStream(InStream, OutStream: TStream);
begin
  // Decompress from input stream to output stream
  PLZDecompressStream(InStream, OutStream);

  // For raw deflate data (without ZLib headers)
  PLZDecompressStreamRaw(InStream, OutStream);
end;
        

PDF FlateDecode с параметрами


// Delphi example - PDF FlateDecode with parameters
function DecompressPDFStream(const CompressedData: AnsiString;
  Predictor, Colors, BitsPerComponent, Columns: Integer): AnsiString;
var
  Parms: TPDFFlateParms;
begin
  // Configure PDF parameters
  Parms.Predictor := Predictor;
  Parms.Colors := Colors;
  Parms.BitsPerComponent := BitsPerComponent;
  Parms.Columns := Columns;
  Parms.ExpandedTo8Bit := True;
  Parms.ColorSpace := 'DeviceRGB';

  // Decompress with PDF parameters
  Result := InflateStrParms(CompressedData, Parms);
end;
        

Низкоуровневые операции ZLib


// Delphi example - Low-level ZLib operations
procedure CompressData;
var
  strm: z_stream;
  ret: Integer;
  input: AnsiString;
  output: AnsiString;
begin
  input := 'Data to compress';
  SetLength(output, Length(input) * 2);

  // Initialize stream
  FillChar(strm, SizeOf(strm), 0);
  ret := deflateInit(strm, Z_DEFAULT_COMPRESSION);

  if ret = Z_OK then
  try
    // Set input
    strm.next_in := PByte(PAnsiChar(input));
    strm.avail_in := Length(input);

    // Set output
    strm.next_out := PByte(PAnsiChar(output));
    strm.avail_out := Length(output);

    // Compress
    ret := deflate(strm, Z_FINISH);

    if ret = Z_STREAM_END then
    begin
      // Compression successful
      SetLength(output, Length(output) - strm.avail_out);
    end;
  finally
    deflateEnd(strm);
  end;
end;
        

Параметры PDF FlateDecode

Структура TPDFFlateParms

  • Predictor: Функция предиктора (1=без предсказания, 2=TIFF, 10-15=PNG)
  • Colors: Число цветовых компонент
  • BitsPerComponent: 1, 2, 4, 8 или 16 бит на цветовую компоненту
  • Columns: Число выборок на строку
  • ExpandedTo8Bit: Поле совместимости, оставленное для существующих вызывающих
  • ColorSpace: Поле совместимости для идентификатора исходного цветового пространства

Разделяемый API предиктора

Добавляйте юнит HPDFPredictor, когда обращение предиктора нужно независимо от декодирования Flate или LZW

function HPDFDecodePredictor(const Data: AnsiString; Predictor, Colors,
  BitsPerComponent, Columns: Integer;
  MaxOutputBytes: Int64 = 0): AnsiString;

function HPDFTryDecodePredictor(const Data: AnsiString; Predictor, Colors,
  BitsPerComponent, Columns: Integer; MaxOutputBytes: Int64;
  out Output: AnsiString; out ErrorMessage: string): Boolean;
  • HPDFDecodePredictor вызывает EHPDFPredictorError когда строка обрезана, тег PNG-строки вне диапазона 0-4, геометрия переполняется или превышен предел вывода
  • HPDFTryDecodePredictor возвращает тот же результат валидации без исключения и даёт сообщение об ошибке для логирования
  • Декодирование TIFF сохраняет неиспользуемые биты выравнивания и применяет горизонтальное дифференцирование по компонентам на упакованных и 16-битных глубинах
  • Декодирование PNG использует явный тег фильтра в начале каждой строки для значений Predictor 10-15
  • InflateStrParms применяет этот разделяемый декодер после чтения фактического вывода Flate и сообщает об отказах предиктора как EZDecompressionError

Расширенные возможности

  • Управление памятью: Оптимизированные выделение и освобождение памяти
  • Обработка ошибок: Всесторонняя проверка и отчёт об ошибках
  • Отладочная поддержка: Опциональный отладочный вывод для поиска проблем
  • Оптимизация производительности: Высокооптимизированные алгоритмы сжатия
  • Интеграция с потоками: Бесшовная интеграция с потоковыми классами Delphi

Преимущества производительности

  • Быстрые скорости сжатия и распаковки
  • Отличные коэффициенты сжатия для текста и простой графики
  • Низкий след памяти при обработке
  • Оптимизация под контентные потоки PDF
  • Минимальные накладные расходы CPU

Соответствие стандартам

  • RFC 1950 (спецификация формата ZLib)
  • RFC 1951 (алгоритм сжатия Deflate)
  • Спецификация фильтра PDF FlateDecode
  • Поддержка алгоритма PNG-предиктора
  • Поддержка алгоритма TIFF-предиктора

Коды ошибок и их обработка

  • Z_OK (0): Успех
  • Z_STREAM_END (1): Достигнут конец потока
  • Z_NEED_DICT (2): Требуется словарь
  • Z_ERRNO (-1): Ошибка файла
  • Z_STREAM_ERROR (-2): Ошибка состояния потока
  • Z_DATA_ERROR (-3): Ошибка целостности данных
  • Z_MEM_ERROR (-4): Ошибка выделения памяти
  • Z_BUF_ERROR (-5): Ошибка размера буфера

См. также