]> scripts.mit.edu Git - autoinstalls/mediawiki.git/blob - vendor/james-heinrich/getid3/getid3/module.graphic.tiff.php
MediaWiki 1.30.2
[autoinstalls/mediawiki.git] / vendor / james-heinrich / getid3 / getid3 / module.graphic.tiff.php
1 <?php
2 /////////////////////////////////////////////////////////////////
3 /// getID3() by James Heinrich <info@getid3.org>               //
4 //  available at http://getid3.sourceforge.net                 //
5 //            or http://www.getid3.org                         //
6 //          also https://github.com/JamesHeinrich/getID3       //
7 /////////////////////////////////////////////////////////////////
8 // See readme.txt for more details                             //
9 /////////////////////////////////////////////////////////////////
10 //                                                             //
11 // module.archive.tiff.php                                     //
12 // module for analyzing TIFF files                             //
13 // dependencies: NONE                                          //
14 //                                                            ///
15 /////////////////////////////////////////////////////////////////
16
17
18 class getid3_tiff extends getid3_handler
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 }