Filter in Streams

In den bisherigen Kapiteln sind wir nun mehrfach auf Filter gestossen. Es handelt sich dabei ganz generell um eine Funktion für Streams. Dabei werden die Bytes zwischen stream und endstream gelesen, dann vom Filter bearbeitet, und erst in der bearbeiteten Form verwendet.

die einzelnen Filter

PDF definiert verschiedene Filter. Folgende in PDF 1.4 vorhandenen Filter behandle ich hier:

/ASCIIHexDecode Dekodiert Hexcodes
/ASCII85Decode Dekodiert ASCII85 Codes
/DCTDecode Dekomprimiert JPEG
/FlateDecode Dekomprimiert Deflate

ASCIIHexDecode und ASCII85Decode haben wir bereits in Binäre Streams kennengelernt. Sie ermöglichen uns, binäre Daten in Form von druckbaren Zeichen im PDF einzubinden.

DCTDecode und FlateDecode ermöglichen es uns, Daten komprimiert abzulegen, die eigentlich in unkomprimierter Form erwartet werden. DCTDecode ist logischerweise vor allem für die Einbindung von JPEG Bildern nützlich. FlateDecode ist da universeller. „Deflate“ ist ein verbreiteter Kompressionsalgorithmus für alle möglichen Zwecke. Er wird unter anderem für ZIP verwendet.

Filterkombinationen

Es ist möglich, im selben Stream mehrere Filter einzusetzen. So können wir zum Beispiel den Inhalt mit Deflate komprimieren, und die resultierenden, binären Daten anschliessend mit ASCII85 in druckbare Zeichen umwandeln.

Um dies dem Interpreter mitzuteilen, verwenden wir wie bis anhin einen Eintrag /Filter im Dictionary des Streams. Statt als Wert einen einzelnen Filter anzugeben, müssen wir aber Array von Filternamen einsetzen. Die Reihenfolge der Filter im Array ist entscheidend: Die Filter müssen in der Folge angegeben werden, wie sie zur Dekodierung angewendet werden müssen. Das ist logischerweise die exakt umgekehrte Reihenfolge der Kodierung.

Beispiel:

10 0 obj
<<
/Length 73
/Filter [/ASCII85Decode /FlateDecode]
>>
stream
Gao/`86%&hbtQD`81Mb8cVmBXY>E:ibq2I\;91C`/Q*ttb3($N<@Xg*Vs>db$rPOT@&HnC~>
endstream
endobj

Dies entspricht dem Text „The quick brown fox jumped over the lazy dog. “ fünf mal wiederholt, mit Deflate komprimiert, und mit ASCII85 wieder in druckbare Zeichen umgewandelt.

Filterparamter

Manche Filter können noch Parameter haben. Namentlich /FlateDecode verfügt über optionale Parameter für die sogenannte Prediktorfunktion. Dabei handelt es sich um eine Erweiterung für verlustfrei komprimierte Bilder, welche die Kompression verbessert, und unter anderem von PNG eingesetzt wird.

Filterparameter werden im Dictionary des Streams unter /DecodeParms vermerkt. Ist nur ein Filter angegeben, so ist der Wert von /DecodeParms ein Dictionary mit den Parametern für den Filter. Sind mehrere Filter angegeben, so ist der Wert ein Array. Dieses Array muss für jeden Filter einen Eintrag habe, in derselben Reihenfolge, wie sie unter /Filter vermerkt sind. Der Eintrag für den Filter ist entweder ein Dictionary mit den Parametern, oder null, falls keine Parameter vorhanden sind oder geändert werden sollen.

Beispiel:

10 0 obj
<<
/Length 1234
/Filter [/ASCII85Decode /FlateDecode]
/DecodeParms [null << /Predictor 15 /Colors 3 /BitsPerComponent 8 /Columns 100 >>]
>>
stream
...~>
endstream
endobj

Hier haben wir wieder zwei Filter. /ASCII85Decode hat keine Parameter, daher ist der erste Eintrag in /DecodeParms auf null gesetzt. /FlateDecode hingegen hat in diesem Fall ein paar Parameter, die in einem Dictionary zusammengefasst sind.