フィルタ

フィルタ
ストリームでは、フィルタを使用することによって、データを圧縮したり、バイナリを ASCII 文字で記述することができます。

フィルタを使用する場合は、ストリーム辞書に Filter エントリを含めて、そこでフィルタのタイプを指定します。

また、フィルタのデコード時にパラメータが必要な場合は、DecodeParms エントリも含めます。

Length エントリでは、フィルタを適用した後のサイズを指定します。
(元のファイルサイズは基本的に指定する必要はありません)
フィルタのタイプ
フィルタ名パラメータの有無説明
ASCIIHexDecode-ASCII 16進数
ASCII85Decode-ASCII base-85 表現
RunLengthDecode-ランレングス圧縮
LZWDecodeoLZW (Lempel-Ziv-Welch) 圧縮。
PDF/X ではこのフィルタは禁止されているため、説明は省略します。
FlateDecodeo(PDF 1.2) zlib 圧縮
CCITTFaxDecodeoCCITT ファクシミリ圧縮 (1bit 画像データ)
DCTDecodeoJPEG 圧縮
JBIG2Decodeo(PDF 1.4) JBIG2 圧縮 (1bit 画像データ)
JPXDecode-(PDF 1.5) JPEG2000 圧縮
Crypto(PDF 1.5) 暗号化

Filter エントリで指定する際は、前に '/' を付けて、名前オブジェクトにします。

画像データで使われるフィルタが多いですが、画像以外での圧縮では、主に FlateDecode が使われます。
Filter エントリ
Filter エントリは、適用するフィルタが一つの場合は、そのフィルタの名前を指定します。

複数のフィルタでエンコードした場合は、配列で、各フィルタの名前を指定します。

フィルタを複数指定する場合、指定するフィルタ名の順番は、"デコード時に適用する順番" で指定する必要があります。
例えば、暗号化後に FlateDecode で圧縮した場合、まずは FlateDecode でデコードしてから暗号化を解除するため、
[ /FlateDecode /Crypt ] となります。

1 0 obj
<< /Length 100
   /Filter /FlateDecode
>>
stream
...data...
endstream
endobj
ASCIIHexDecode
ASCIIHexDecode フィルタは、バイナリデータを ASCII 文字で表現するために使います。
データサイズが単純に2倍になるので、実際に使われることはあまりありません。

1 byte を 16進数の2文字 [0-9, A-F, a-f] で表し、'>' でデータを終了します。
('>' が出現した地点が、明確にデータの終了位置となります)

空白文字はすべて無視され、他の対象外の文字はエラーとなります。
文字の長さが奇数で終わった場合、最後の文字は '0' として扱います。

stream
03FFAF
010203>
endstream
ASCII85Decode
ASCII85Decode フィルタは、バイナリデータを ASCII base-85 で記述します。

ASCIIHexDecode と同じく ASCII 文字のみを使って表記しますが、こちらは 85 進数として扱うため、ASCIIHexDecode よりもエンコードサイズを減らすことができます。

エンコード方法は以下のとおりです。

4 byte の入力データから 32 bit の数値を生成し、その値を5つの 85 進数値として分け、それぞれを5文字の ASCII 文字にします。

0〜84 の値を「'!' (33) 〜 'u' (117)」の文字に対応させますが、
入力の 32 bit 値が 0 の場合は、"!!!!!" とする代わりに、'z' の1文字を使います。

"~>" で、データの終了となります。
空白文字はすべて無視され、他の対象外の文字はエラーとなります。

入力のデータを b1,b2,b3,b4 とし、エンコード後の文字を c1〜c5 とすると、以下のようになります。

n  = (b1 << 24) + (b2 << 16) + (b3 << 8) + b4

c1 = n / (85 * 85 * 85 * 85)
N  = n - c1 * (85 * 85 * 85 * 85)

c2 = N / (85 * 85 * 85)
N -= c2 * (85 * 85 * 85)

c3 = N / (85 * 85)
N -= c3 * (85 * 85)

c1 += 33
c2 += 33
c3 += 33
c4 = N / 85 + 33
c5 = N % 85 + 33

なお、エンコード時、入力の全体のバイト数が4の倍数ではない場合 (余りが出る場合)、余った残りデータを n byte とすると、まずは、終端に (4 - n) byte の 0 を追加して、5文字分をエンコードします。

その後、結果の5文字のうち、先頭から (n + 1) 文字のみを書き込んで、データの終了とします。

※この時、最後の 32 bit 値が 0 となった場合は、'z' の1文字にしないでください。
デコード後に、終端に追加した分のサイズが増加してしまいます。
RunLengthDecode
RunLengthDecode フィルタは、ランレングスによって圧縮されたデータです。

[長さ (1byte)] + [1〜128 byte のデータ] で構成されます。

実際にはあまり使われることはないと思うので、詳細は省略します。

長さの値説明
0〜127[len + 1] 個の非連続データ
129〜255[257 - len] 個の連続データ
128データの終了
FlateDecode [PDF 1.2]
FlateDecode フィルタは、zlib によって圧縮されたデータです。
(ZIP の圧縮アルゴリズムと同じ)

zlib でエンコードしたデータを、バイナリデータとして、そのままセットします (zlib ヘッダ付き)。

画像データの圧縮として使う場合は、PNG 画像で使用できるフィルタと同じように、あらかじめ画像データにフィルタを掛けて、データを圧縮しやすい状態にした上で、圧縮することもできます。
DCTDecode
DCTDecode フィルタは、JPEG 画像のデータです。

JPEG 画像のファイルデータを、そのまま丸ごとセットして、画像として使います。