Es hat sich für mich bewährt, Protokolle oder Dateiformate von Hand auseinanderzunehmen. So habe ich ein baseline TIFF erzeugt, welches im folgenden als Beispiel dienen soll. Die Datei ist 20x10 Pixel groß, s/w und gut geeignet die Besonderheiten kennenzulernen.
Beispiel-TIFF (hier als PNG) |
Kurzinfo zu 'Tagged Image File Format' (TIFF)
Magic Byte
"II" (little-endian): 0x49492a00"MM" (big-endian): 0x4d4d002a
Dateiendung
.TIF bzw. .TIFFMimeType
image/tiffSpezifikation
ftp://ftp.adobe.com/pub/adobe/devrelations/devtechnotes/pdffiles/tiff6.pdf bzw. http://partners.adobe.com/public/developer/tiff/index.htmlGeschichte
Ursprünglich entwickelt von Aldus und Microsoft. 1994 wurde Aldus von Adobe übernommen.Die aktuelle Version von TIFF ist 6.0 (1992) und wird moderat durch TIFF Technical Notes, zB. zu 'deflate'-Kompression ergänzt.
Aufbau
Eine TIFF-Datei ist im Wesentlich wie folgt aufgebaut:Aufbau TIFF Datei |
Sie besteht aus Header, Image File Directories und Streams.
Ich beziehe mich auf oben gezeigte mini TIFF-Datei (Ist mittlerweile unter https://github.com/SLUB-digitalpreservation/fixit_tiff/tree/master/examples zu finden) . Im folgenden ist die Datei als Hex-Dump zu sehen:
Byte | Hex (8 Byte) | (8 Byte) | ASCII |
---|---|---|---|
00000000
|
4949 2a00 2600 0000
|
0000 0000 0000 fd1e
|
II*.&...........
|
00000010
|
f011 1080 111c e011
|
1080 1110 8011 1080
|
................
|
00000020
|
0000 0000 0000 1000
|
fe00 0400 0100 0000
|
................
|
00000030
|
0000 0000 0001 0300
|
0100 0000 1400 0000
|
................
|
00000040
|
0101 0300 0100 0000
|
0a00 0000 0201 0300
|
................
|
00000050
|
0100 0000 0100 0000
|
0301 0300 0100 0000
|
................
|
00000060
|
0100 0000 0601 0300
|
0100 0000 0000 0000
|
................
|
00000070
|
0d01 0200 2500 0000
|
ec00 0000 1101 0400
|
....%...........
|
00000080
|
0100 0000 0800 0000
|
1201 0300 0100 0000
|
................
|
00000090
|
0100 0000 1501 0300
|
0100 0000 0100 0000
|
................
|
000000a0
|
1601 0300 0100 0000
|
4000 0000 1701 0400
|
........@.......
|
000000b0
|
0100 0000 1e00 0000
|
1a01 0500 0100 0000
|
................
|
000000c0
|
1201 0000 1b01 0500
|
0100 0000 1a01 0000
|
................
|
000000d0
|
1c01 0300 0100 0000
|
0100 0000 2801 0300
|
............(...
|
000000e0
|
0100 0000 0200 0000
|
0000 0000 2f68 6f6d
|
............/hom
|
000000f0
|
652f 726f 6d65 796b
|
652f 7469 6666 2f65
|
e/romeyke/tiff/e
|
00000100
|
7861 6d70 6c65 5f74
|
6966 662e 7469 6666
|
xample_tiff.tiff
|
00000110
|
0000 0000 0048 0000
|
0001 0000 0048 0000
|
.....H.......H..
|
00000120
|
0001
|
..
|
Header
Der Header einer TIFF-Datei ist
- 8 Byte groß
- enthält Magic Bytes
- und Offset des ersten IFD
- 0x4949 little endian (least significant to most significant byte)
- 0x4d4d big endian (most significant to least significant byte)
Die byte-order ist wichtig und zieht sich durch die gesamte TIFF-Datei.
Die nächsten zwei Bytes enthalten die Antwort auf den Sinn des Lebens und entsprechen der Zahl 42 (ebenfalls abhängig von der byte order).
Die Bytes 4-7 zeigen auf das erste Image File Directory (IFD), hier die Adresse
0x0000 0026. Baseline TIFFs enthalten nur ein IFD, mehr dazu später.
Image File Directory
Aufbau Image File Directory (IFD) in TIFF-Datei |
Das letzte IFD enthält als Offset den Wert 0x0000 0000 0000 0000.
Wenn wir den Hex-Dump einfärben, so daß die Tags abwechselnd gelb oder silber hinterlegt sind, wird die Struktur deutlicher:
Byte | Hex (8 Byte) | (8 Byte) | ASCII |
---|---|---|---|
00000000
|
4949 2a00 2600 0000
|
0000 0000 0000 fd1e
|
II*.&...........
|
00000010
|
f011 1080 111c e011
|
1080 1110 8011 1080
|
................
|
00000020
|
0000 0000 0000 1000
|
fe00 0400 0100 0000
|
................
|
00000030
|
0000 0000 0001 0300
|
0100 0000 1400 0000
|
................
|
00000040
|
0101 0300 0100 0000
|
0a00 0000 0201 0300
|
................
|
00000050
|
0100 0000 0100 0000
|
0301 0300 0100 0000
|
................
|
00000060
|
0100 0000 0601 0300
|
0100 0000 0000 0000
|
................
|
00000070
|
0d01 0200 2500 0000
|
ec00 0000 1101 0400
|
....%...........
|
00000080
|
0100 0000 0800 0000
|
1201 0300 0100 0000
|
................
|
00000090
|
0100 0000 1501 0300
|
0100 0000 0100 0000
|
................
|
000000a0
|
1601 0300 0100 0000
|
4000 0000 1701 0400
|
........@.......
|
000000b0
|
0100 0000 1e00 0000
|
1a01 0500 0100 0000
|
................
|
000000c0
|
1201 0000 1b01 0500
|
0100 0000 1a01 0000
|
................
|
000000d0
|
1c01 0300 0100 0000
|
0100 0000 2801 0300
|
............(...
|
000000e0
|
0100 0000 0200 0000
|
0000 0000 2f68 6f6d
|
............/hom
|
000000f0
|
652f 726f 6d65 796b
|
652f 7469 6666 2f65
|
e/romeyke/tiff/e
|
00000100
|
7861 6d70 6c65 5f74
|
6966 662e 7469 6666
|
xample_tiff.tiff
|
00000110
|
0000 0000 0048 0000
|
0001 0000 0048 0000
|
.....H.......H..
|
00000120
|
0001
|
..
|
Im Beispiel enthält die Adresse 0x00000026 den Wert 1000, sprich: das IFD enthält 16 Einträge. Da jeder Eintrag 12 Bytes enhält geht das IFD bis zur Adresse 0x00000026 + 2 + 16*12 + 4 = 38 + 2 + 192 + 4 = 236 = 0x0000 00ec.
IFD - Entries (Tags)
Ein IFD-Tageintrag beschreibt verschiedene Attribute eines Bildes oder der Kompressionsmethode. Es gibt viele verschiedene Tags die nicht alle verwendet werden müssen. Durch diese IFD-Einträge, kurz Tags, hat TIFF seinen Namen.
Die Tag-Einträge in der IFD sind alle 12 Bytes groß und wie folgt aufgebaut:
IFD Eintrag bzw Tag eines TIFFs |
Dabei gelten die Bereiche 0x8000-0xfde7 als "private" und 0xfde8-0xffff als "reusable". Für spezielle Anwendungen kann man von Adobe die Vergabe eine "private" Tag-ID anfordern. "reusable" Tags können frei verwendet werden.
Allerdings können zukünftige Versionen von TIFF die beiden Bereiche neu definieren.
'Field Type' beschreibt den Datentyp der Werte. Zur Zeit sind ff. definiert:
- 1 = BYTE (8-bit unsigned integer)
- 2 = ASCII (7-bit ASCII code, null-terminiert).
- 3 = SHORT (16-bit unsigned integer)
- 4 = LONG (32-bit unsigned integer)
- 5 = RATIONAL (Zähler und Nenner, je ein LONG)
- 6 = SBYTE (8-bit signed integer, 2-er Kompl.)
- 7 = UNDEFINED (8-bit, feldabhängig)
- 8 = SSHORT (16-bit signed integer, 2-er Kompl.)
- 9 = SLONG (32-bit signed integer, 2-er Kompl.)
- 10 = SRATIONAL (Zähler und Nenner, je ein SLONG)
- 11 = FLOAT (32-bit, single precision IEEE)
- 12 = DOUBLE (64-bit, double precision IEEE)
Wenn Werte eines IFD-Eintrages zusammen (Count mal FieldType) 4 Bytes nicht übersteigen, werden diese direkt im
Value/Offset-Bereich gespeichert. Andernfalls gibt Value/Offset die Adresse innerhalb der TIFF-Datei an.
Gehen wir nun mal die einzelnen IFD-Einträge, die im Beispiel verwendet werden, durch.
Die Tag-ID lautet 0x00fe und bedeutet TIFFTAG_SUBFILETYPE (Die jeweils aktuellen Werte, kann man sich aus der Header-Datei der libtiff heraussuchen, meist in /usr/include/tiff/tiff.h). Der Field Type lautet 0x0004 und bedeutet 32-Bit unsigned integer. Count steht auf 0x0000 0001. Da ein 32-Bit unsigned integer in 4 Bytes passt, handelt es sich um den Value 0x0000 0000.
Gehen wir nun mal die einzelnen IFD-Einträge, die im Beispiel verwendet werden, durch.
IFD Entry - 0x28
Der erste IFD-Eintrag an Adresse 0x28 sieht wie folgt aus:Byte | Hex (8 Byte) | (8 Byte) | ASCII |
---|---|---|---|
00000020
|
0000 0000 0000 1000
|
fe00 0400 0100 0000
|
................
|
00000030
|
0000 0000 0001 0300
|
0100 0000 1400 0000
|
................
|
Die Tag-ID lautet 0x00fe und bedeutet TIFFTAG_SUBFILETYPE (Die jeweils aktuellen Werte, kann man sich aus der Header-Datei der libtiff heraussuchen, meist in /usr/include/tiff/tiff.h). Der Field Type lautet 0x0004 und bedeutet 32-Bit unsigned integer. Count steht auf 0x0000 0001. Da ein 32-Bit unsigned integer in 4 Bytes passt, handelt es sich um den Value 0x0000 0000.
IFD Entry - 0x34
Der IFD-Eintrag an Adresse 0x34 sieht wie folgt aus:Byte | Hex (8 Byte) | (8 Byte) | ASCII |
---|---|---|---|
00000030
|
0000 0000 0001 0300
|
0100 0000 1400 0000
|
................
|
ergibt Tag-ID 0x0100, der für TIFFTAG_IMAGEWIDTH steht. Field Type ist 0x0003, also short 16-Bit unsigned integer. Count ist 0x0000 0001. Der Wert lautet damit 0x0014, welches 20 Pixel entspricht.
IFD Entry - 0x40
Der IFD-Eintrag an Adresse 0x40 sieht wie folgt aus:Byte | Hex (8 Byte) | (8 Byte) | ASCII |
---|---|---|---|
00000040
|
0101 0300 0100 0000
|
0a00 0000 0201 0300
|
................
|
steht für Tag-ID 0x0101 = TIFFTAG_IMAGELENGTH. Field Type ist ebenfalls 0x0003 und Count ebenso 1. Der Wert beträgt demnach 0x000a, also 10 Pixel.
IFD Entry - 0x4c
Der IFD-Eintrag an Adresse 0x4c sieht wie folgt aus:Byte | Hex (8 Byte) | (8 Byte) | ASCII |
---|---|---|---|
00000040
|
0101 0300 0100 0000
|
0a00 0000 0201 0300
|
................
|
00000050
|
0100 0000 0100 0000
|
0301 0300 0100 0000
|
................
|
steht für Tag-ID 0x0102 = BITS_PER_SAMPLE, Field Type ist 0x0003, Count ist 1. Der Wert ist dann 0x00000001, also 1.
IFD Entry - 0x58
Der IFD-Eintrag an Adresse 0x58 sieht wie folgt aus:Byte | Hex (8 Byte) | (8 Byte) | ASCII |
---|---|---|---|
00000050
|
0100 0000 0100 0000
|
0301 0300 0100 0000
|
................
|
00000060
|
0100 0000 0601 0300
|
0100 0000 0000 0000
|
................
|
steht für Tag-ID 0x0103 = TIFFTAG_COMPRESSION, Field-Type und Count wie oben. Der Wert lautet 0x0000 0001 und bedeutet No Compression.
IFD Entry - 0x64
Der IFD-Eintrag an Adresse 0x64 sieht wie folgt aus:Byte | Hex (8 Byte) | (8 Byte) | ASCII |
---|---|---|---|
00000060
|
0100 0000 0601 0300
|
0100 0000 0000 0000
|
................
|
steht für Tag-ID 0x0106 = TIFFTAG_PHOTOMETRIC. Der Field Type lautet 0x0003, also 16-Bit short unsigned integer. Count ist 0x0000 0001, also 1 und der Wert ist 0x0000 0000, also 'PHOTOMETRIC_MINISWHITE", sprich das nicht gesetzte Bit entspricht der Farbe Weiß.