ILIAS  release_5-1 Revision 5.0.0-5477-g43f3e3fab5f
module.graphic.tiff.php
Go to the documentation of this file.
1<?php
4// available at http://getid3.sourceforge.net //
5// or http://www.getid3.org //
7// See readme.txt for more details //
9// //
10// module.archive.tiff.php //
11// module for analyzing TIFF files //
12// dependencies: NONE //
13// ///
15
16
18{
19
20 function getid3_tiff(&$fd, &$ThisFileInfo) {
21
22 fseek($fd, $ThisFileInfo['avdataoffset'], SEEK_SET);
23 $TIFFheader = fread($fd, 4);
24
25 switch (substr($TIFFheader, 0, 2)) {
26 case 'II':
27 $ThisFileInfo['tiff']['byte_order'] = 'Intel';
28 break;
29 case 'MM':
30 $ThisFileInfo['tiff']['byte_order'] = 'Motorola';
31 break;
32 default:
33 $ThisFileInfo['error'][] = 'Invalid TIFF byte order identifier ('.substr($TIFFheader, 0, 2).') at offset '.$ThisFileInfo['avdataoffset'];
34 return false;
35 break;
36 }
37
38 $ThisFileInfo['fileformat'] = 'tiff';
39 $ThisFileInfo['video']['dataformat'] = 'tiff';
40 $ThisFileInfo['video']['lossless'] = true;
41 $ThisFileInfo['tiff']['ifd'] = array();
42 $CurrentIFD = array();
43
44 $FieldTypeByteLength = array(1=>1, 2=>1, 3=>2, 4=>4, 5=>8);
45
46 $nextIFDoffset = $this->TIFFendian2Int(fread($fd, 4), $ThisFileInfo['tiff']['byte_order']);
47
48 while ($nextIFDoffset > 0) {
49
50 $CurrentIFD['offset'] = $nextIFDoffset;
51
52 fseek($fd, $ThisFileInfo['avdataoffset'] + $nextIFDoffset, SEEK_SET);
53 $CurrentIFD['fieldcount'] = $this->TIFFendian2Int(fread($fd, 2), $ThisFileInfo['tiff']['byte_order']);
54
55 for ($i = 0; $i < $CurrentIFD['fieldcount']; $i++) {
56 $CurrentIFD['fields'][$i]['raw']['tag'] = $this->TIFFendian2Int(fread($fd, 2), $ThisFileInfo['tiff']['byte_order']);
57 $CurrentIFD['fields'][$i]['raw']['type'] = $this->TIFFendian2Int(fread($fd, 2), $ThisFileInfo['tiff']['byte_order']);
58 $CurrentIFD['fields'][$i]['raw']['length'] = $this->TIFFendian2Int(fread($fd, 4), $ThisFileInfo['tiff']['byte_order']);
59 $CurrentIFD['fields'][$i]['raw']['offset'] = fread($fd, 4);
60
61 switch ($CurrentIFD['fields'][$i]['raw']['type']) {
62 case 1: // BYTE An 8-bit unsigned integer.
63 if ($CurrentIFD['fields'][$i]['raw']['length'] <= 4) {
64 $CurrentIFD['fields'][$i]['value'] = $this->TIFFendian2Int(substr($CurrentIFD['fields'][$i]['raw']['offset'], 0, 1), $ThisFileInfo['tiff']['byte_order']);
65 } else {
66 $CurrentIFD['fields'][$i]['offset'] = $this->TIFFendian2Int($CurrentIFD['fields'][$i]['raw']['offset'], $ThisFileInfo['tiff']['byte_order']);
67 }
68 break;
69
70 case 2: // ASCII 8-bit bytes that store ASCII codes; the last byte must be null.
71 if ($CurrentIFD['fields'][$i]['raw']['length'] <= 4) {
72 $CurrentIFD['fields'][$i]['value'] = substr($CurrentIFD['fields'][$i]['raw']['offset'], 3);
73 } else {
74 $CurrentIFD['fields'][$i]['offset'] = $this->TIFFendian2Int($CurrentIFD['fields'][$i]['raw']['offset'], $ThisFileInfo['tiff']['byte_order']);
75 }
76 break;
77
78 case 3: // SHORT A 16-bit (2-byte) unsigned integer.
79 if ($CurrentIFD['fields'][$i]['raw']['length'] <= 2) {
80 $CurrentIFD['fields'][$i]['value'] = $this->TIFFendian2Int(substr($CurrentIFD['fields'][$i]['raw']['offset'], 0, 2), $ThisFileInfo['tiff']['byte_order']);
81 } else {
82 $CurrentIFD['fields'][$i]['offset'] = $this->TIFFendian2Int($CurrentIFD['fields'][$i]['raw']['offset'], $ThisFileInfo['tiff']['byte_order']);
83 }
84 break;
85
86 case 4: // LONG A 32-bit (4-byte) unsigned integer.
87 if ($CurrentIFD['fields'][$i]['raw']['length'] <= 1) {
88 $CurrentIFD['fields'][$i]['value'] = $this->TIFFendian2Int($CurrentIFD['fields'][$i]['raw']['offset'], $ThisFileInfo['tiff']['byte_order']);
89 } else {
90 $CurrentIFD['fields'][$i]['offset'] = $this->TIFFendian2Int($CurrentIFD['fields'][$i]['raw']['offset'], $ThisFileInfo['tiff']['byte_order']);
91 }
92 break;
93
94 case 5: // RATIONAL Two LONG_s: the first represents the numerator of a fraction, the second the denominator.
95 break;
96 }
97 }
98
99 $ThisFileInfo['tiff']['ifd'][] = $CurrentIFD;
100 $CurrentIFD = array();
101 $nextIFDoffset = $this->TIFFendian2Int(fread($fd, 4), $ThisFileInfo['tiff']['byte_order']);
102
103 }
104
105 foreach ($ThisFileInfo['tiff']['ifd'] as $IFDid => $IFDarray) {
106 foreach ($IFDarray['fields'] as $key => $fieldarray) {
107 switch ($fieldarray['raw']['tag']) {
108 case 256: // ImageWidth
109 case 257: // ImageLength
110 case 258: // BitsPerSample
111 case 259: // Compression
112 if (!isset($fieldarray['value'])) {
113 fseek($fd, $fieldarray['offset'], SEEK_SET);
114 $ThisFileInfo['tiff']['ifd'][$IFDid]['fields'][$key]['raw']['data'] = fread($fd, $fieldarray['raw']['length'] * $FieldTypeByteLength[$fieldarray['raw']['type']]);
115
116 }
117 break;
118
119 case 270: // ImageDescription
120 case 271: // Make
121 case 272: // Model
122 case 305: // Software
123 case 306: // DateTime
124 case 315: // Artist
125 case 316: // HostComputer
126 if (isset($fieldarray['value'])) {
127 $ThisFileInfo['tiff']['ifd'][$IFDid]['fields'][$key]['raw']['data'] = $fieldarray['value'];
128 } else {
129 fseek($fd, $fieldarray['offset'], SEEK_SET);
130 $ThisFileInfo['tiff']['ifd'][$IFDid]['fields'][$key]['raw']['data'] = fread($fd, $fieldarray['raw']['length'] * $FieldTypeByteLength[$fieldarray['raw']['type']]);
131
132 }
133 break;
134 }
135 switch ($fieldarray['raw']['tag']) {
136 case 256: // ImageWidth
137 $ThisFileInfo['video']['resolution_x'] = $fieldarray['value'];
138 break;
139
140 case 257: // ImageLength
141 $ThisFileInfo['video']['resolution_y'] = $fieldarray['value'];
142 break;
143
144 case 258: // BitsPerSample
145 if (isset($fieldarray['value'])) {
146 $ThisFileInfo['video']['bits_per_sample'] = $fieldarray['value'];
147 } else {
148 $ThisFileInfo['video']['bits_per_sample'] = 0;
149 for ($i = 0; $i < $fieldarray['raw']['length']; $i++) {
150 $ThisFileInfo['video']['bits_per_sample'] += $this->TIFFendian2Int(substr($ThisFileInfo['tiff']['ifd'][$IFDid]['fields'][$key]['raw']['data'], $i * $FieldTypeByteLength[$fieldarray['raw']['type']], $FieldTypeByteLength[$fieldarray['raw']['type']]), $ThisFileInfo['tiff']['byte_order']);
151 }
152 }
153 break;
154
155 case 259: // Compression
156 $ThisFileInfo['video']['codec'] = $this->TIFFcompressionMethod($fieldarray['value']);
157 break;
158
159 case 270: // ImageDescription
160 case 271: // Make
161 case 272: // Model
162 case 305: // Software
163 case 306: // DateTime
164 case 315: // Artist
165 case 316: // HostComputer
166 @$ThisFileInfo['tiff']['comments'][$this->TIFFcommentName($fieldarray['raw']['tag'])][] = $ThisFileInfo['tiff']['ifd'][$IFDid]['fields'][$key]['raw']['data'];
167 break;
168
169 default:
170 break;
171 }
172 }
173 }
174
175 return true;
176 }
177
178
179 function TIFFendian2Int($bytestring, $byteorder) {
180 if ($byteorder == 'Intel') {
181 return getid3_lib::LittleEndian2Int($bytestring);
182 } elseif ($byteorder == 'Motorola') {
183 return getid3_lib::BigEndian2Int($bytestring);
184 }
185 return false;
186 }
187
188 function TIFFcompressionMethod($id) {
189 static $TIFFcompressionMethod = array();
190 if (empty($TIFFcompressionMethod)) {
191 $TIFFcompressionMethod = array(
192 1 => 'Uncompressed',
193 2 => 'Huffman',
194 3 => 'Fax - CCITT 3',
195 5 => 'LZW',
196 32773 => 'PackBits',
197 );
198 }
199 return (isset($TIFFcompressionMethod[$id]) ? $TIFFcompressionMethod[$id] : 'unknown/invalid ('.$id.')');
200 }
201
202 function TIFFcommentName($id) {
203 static $TIFFcommentName = array();
204 if (empty($TIFFcommentName)) {
205 $TIFFcommentName = array(
206 270 => 'imagedescription',
207 271 => 'make',
208 272 => 'model',
209 305 => 'software',
210 306 => 'datetime',
211 315 => 'artist',
212 316 => 'hostcomputer',
213 );
214 }
215 return (isset($TIFFcommentName[$id]) ? $TIFFcommentName[$id] : 'unknown/invalid ('.$id.')');
216 }
217
218}
219
220
221?>
fseek($bytes, $whence=SEEK_SET)
Definition: getid3.php:1697
fread($bytes)
Definition: getid3.php:1685
LittleEndian2Int($byteword, $signed=false)
Definition: getid3.lib.php:266
BigEndian2Int($byteword, $synchsafe=false, $signed=false)
Definition: getid3.lib.php:234
getID3() by James Heinrich info@getid3.org //
getid3_tiff(&$fd, &$ThisFileInfo)
TIFFendian2Int($bytestring, $byteorder)