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