|
LZW Compression Support
概要
HotPDF は LZWDecode フィルターを使うレガシー PDF ストリームをデコードでき、そのフィルターと共に使われることが多い TIFF / PNG プレディクターも逆算できます
主な特徴
- PDF
EarlyChange=1 / EarlyChange=0 のコード幅遷移
- MSB / LSB の両フィル順
- クリアコードリセット、end-of-information、
KwKwK 展開の処理
- 2 つ目の結果文字列を構築せず
TStream へ直接出力
- 設定可能な出力上限と、オプションの厳格な初期クリア / end-of-information チェック
- コンポーネントあたり 1 / 2 / 4 / 8 / 16 ビットの TIFF Predictor 2
- PNG の None、Sub、Up、Average、Paeth の各行フィルター
- コード幅、辞書成長、リセット、展開、出力バイトのデコードごとの統計
型
TPDFLZWDecompressor は再利用可能なデコーダークラスです
TPDFLZWCompressor は対応するエンコーダークラスです
TPDFLZWParms は PDF プレディクターのジオメトリを運びます
TPDFLZWFillOrder が foTop / foBottom のビット順を選びます
EHPDFLZWError が不正入力、未対応ジオメトリ、設定上限超過を報告します
設定プロパティ
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 は現在の入力位置から読み、シーク可能なストリームでは既定でその位置を復元します
基本的な LZW 展開
TPDFLZWCompressor.CompressToStream と CompressStream は書き込まれたエンコード済みバイト数を返します。空の入力に対してもクリアコードと end-of-information コードを含み、既定の PDF 設定では空の入力に 3 バイトを書き込みます
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;
ストリーム出力と診断
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;
プレディクターパラメータ
Predictor=1 はデコード済みバイトをそのまま返します
Predictor=2 は TIFF の水平差分を逆算します
Predictor=10..15 は各行の先頭に格納された PNG フィルタータグを逆算します
Colors、BitsPerComponent、Columns が正確な行ジオメトリを定義します
ExpandedTo8Bit と ColorSpace はソース互換のために残されています
デコード統計
CodesRead、ClearCodesRead、DictionaryAdds
KwKwKExpansions、PeakCodeSize、PeakDictionarySize
OutputBytes と EndedWithEndOfInformation
エラー処理
- 次の辞書エントリを超えるコードは拒否されます
- 壊れたプレフィックスチェーンと不正な最初のコードは拒否されます
RequireEndOfInformation 有効時は、切り詰められた入力を拒否します
- 出力の展開はフレーズを Emit する前に毎回チェックされます
- プレディクターの行は完全で、有効なジオメトリと PNG 行タグを使う必要があります
関連項目
|