1 | <?php |
---|
2 | // +----------------------------------------------------------------------+ |
---|
3 | // | PHP version 5 | |
---|
4 | // +----------------------------------------------------------------------+ |
---|
5 | // | Copyright (c) 2002-2006 James Heinrich, Allan Hansen | |
---|
6 | // +----------------------------------------------------------------------+ |
---|
7 | // | This source file is subject to version 2 of the GPL license, | |
---|
8 | // | that is bundled with this package in the file license.txt and is | |
---|
9 | // | available through the world-wide-web at the following url: | |
---|
10 | // | http://www.gnu.org/copyleft/gpl.html | |
---|
11 | // +----------------------------------------------------------------------+ |
---|
12 | // | getID3() - http://getid3.sourceforge.net or http://www.getid3.org | |
---|
13 | // +----------------------------------------------------------------------+ |
---|
14 | // | Authors: James Heinrich <infoØgetid3*org> | |
---|
15 | // | Allan Hansen <ahØartemis*dk> | |
---|
16 | // +----------------------------------------------------------------------+ |
---|
17 | // | module.graphic.tiff.php | |
---|
18 | // | Module for analyzing TIFF graphic files. | |
---|
19 | // | dependencies: NONE | |
---|
20 | // +----------------------------------------------------------------------+ |
---|
21 | // |
---|
22 | // $Id: module.graphic.tiff.php 3318 2009-05-20 21:54:10Z vdigital $ |
---|
23 | |
---|
24 | |
---|
25 | |
---|
26 | class getid3_tiff extends getid3_handler |
---|
27 | { |
---|
28 | |
---|
29 | public function Analyze() { |
---|
30 | |
---|
31 | $getid3 = $this->getid3; |
---|
32 | |
---|
33 | fseek($getid3->fp, $getid3->info['avdataoffset'], SEEK_SET); |
---|
34 | $tiff_header = fread($getid3->fp, 4); |
---|
35 | |
---|
36 | $getid3->info['tiff']['byte_order'] = substr($tiff_header, 0, 2) == 'II' ? 'Intel' : 'Motorola'; |
---|
37 | $endian2int = substr($tiff_header, 0, 2) == 'II' ? 'LittleEndian2Int' : 'BigEndian2Int'; |
---|
38 | |
---|
39 | $getid3->info['fileformat'] = 'tiff'; |
---|
40 | $getid3->info['video']['dataformat'] = 'tiff'; |
---|
41 | $getid3->info['video']['lossless'] = true; |
---|
42 | $getid3->info['tiff']['ifd'] = array (); |
---|
43 | $current_ifd = array (); |
---|
44 | |
---|
45 | $field_type_byte_length = array (1=>1, 2=>1, 3=>2, 4=>4, 5=>8); |
---|
46 | |
---|
47 | $next_ifd_offset = getid3_lib::$endian2int(fread($getid3->fp, 4)); |
---|
48 | |
---|
49 | while ($next_ifd_offset > 0) { |
---|
50 | |
---|
51 | $current_ifd['offset'] = $next_ifd_offset; |
---|
52 | |
---|
53 | fseek($getid3->fp, $getid3->info['avdataoffset'] + $next_ifd_offset, SEEK_SET); |
---|
54 | $current_ifd['fieldcount'] = getid3_lib::$endian2int(fread($getid3->fp, 2)); |
---|
55 | |
---|
56 | for ($i = 0; $i < $current_ifd['fieldcount']; $i++) { |
---|
57 | |
---|
58 | // shortcut |
---|
59 | $current_ifd['fields'][$i] = array (); |
---|
60 | $current_ifd_fields_i = &$current_ifd['fields'][$i]; |
---|
61 | |
---|
62 | $current_ifd_fields_i['raw']['tag'] = getid3_lib::$endian2int(fread($getid3->fp, 2)); |
---|
63 | $current_ifd_fields_i['raw']['type'] = getid3_lib::$endian2int(fread($getid3->fp, 2)); |
---|
64 | $current_ifd_fields_i['raw']['length'] = getid3_lib::$endian2int(fread($getid3->fp, 4)); |
---|
65 | $current_ifd_fields_i['raw']['offset'] = fread($getid3->fp, 4); |
---|
66 | |
---|
67 | switch ($current_ifd_fields_i['raw']['type']) { |
---|
68 | case 1: // BYTE An 8-bit unsigned integer. |
---|
69 | if ($current_ifd_fields_i['raw']['length'] <= 4) { |
---|
70 | $current_ifd_fields_i['value'] = getid3_lib::$endian2int(substr($current_ifd_fields_i['raw']['offset'], 0, 1)); |
---|
71 | } else { |
---|
72 | $current_ifd_fields_i['offset'] = getid3_lib::$endian2int($current_ifd_fields_i['raw']['offset']); |
---|
73 | } |
---|
74 | break; |
---|
75 | |
---|
76 | case 2: // ASCII 8-bit bytes that store ASCII codes; the last byte must be null. |
---|
77 | if ($current_ifd_fields_i['raw']['length'] <= 4) { |
---|
78 | $current_ifd_fields_i['value'] = substr($current_ifd_fields_i['raw']['offset'], 3); |
---|
79 | } else { |
---|
80 | $current_ifd_fields_i['offset'] = getid3_lib::$endian2int($current_ifd_fields_i['raw']['offset']); |
---|
81 | } |
---|
82 | break; |
---|
83 | |
---|
84 | case 3: // SHORT A 16-bit (2-byte) unsigned integer. |
---|
85 | if ($current_ifd_fields_i['raw']['length'] <= 2) { |
---|
86 | $current_ifd_fields_i['value'] = getid3_lib::$endian2int(substr($current_ifd_fields_i['raw']['offset'], 0, 2)); |
---|
87 | } else { |
---|
88 | $current_ifd_fields_i['offset'] = getid3_lib::$endian2int($current_ifd_fields_i['raw']['offset']); |
---|
89 | } |
---|
90 | break; |
---|
91 | |
---|
92 | case 4: // LONG A 32-bit (4-byte) unsigned integer. |
---|
93 | if ($current_ifd_fields_i['raw']['length'] <= 1) { |
---|
94 | $current_ifd_fields_i['value'] = getid3_lib::$endian2int($current_ifd_fields_i['raw']['offset']); |
---|
95 | } else { |
---|
96 | $current_ifd_fields_i['offset'] = getid3_lib::$endian2int($current_ifd_fields_i['raw']['offset']); |
---|
97 | } |
---|
98 | break; |
---|
99 | |
---|
100 | case 5: // RATIONAL Two LONG_s: the first represents the numerator of a fraction, the second the denominator. |
---|
101 | break; |
---|
102 | } |
---|
103 | } |
---|
104 | |
---|
105 | $getid3->info['tiff']['ifd'][] = $current_ifd; |
---|
106 | $current_ifd = array (); |
---|
107 | $next_ifd_offset = getid3_lib::$endian2int(fread($getid3->fp, 4)); |
---|
108 | |
---|
109 | } |
---|
110 | |
---|
111 | foreach ($getid3->info['tiff']['ifd'] as $ifd_id => $ifd_array) { |
---|
112 | foreach ($ifd_array['fields'] as $key => $field_array) { |
---|
113 | switch ($field_array['raw']['tag']) { |
---|
114 | case 256: // ImageWidth |
---|
115 | case 257: // ImageLength |
---|
116 | case 258: // BitsPerSample |
---|
117 | case 259: // Compression |
---|
118 | if (!isset($field_array['value'])) { |
---|
119 | fseek($getid3->fp, $field_array['offset'], SEEK_SET); |
---|
120 | $getid3->info['tiff']['ifd'][$ifd_id]['fields'][$key]['raw']['data'] = fread($getid3->fp, $field_array['raw']['length'] * $field_type_byte_length[$field_array['raw']['type']]); |
---|
121 | } |
---|
122 | break; |
---|
123 | |
---|
124 | case 270: // ImageDescription |
---|
125 | case 271: // Make |
---|
126 | case 272: // Model |
---|
127 | case 305: // Software |
---|
128 | case 306: // DateTime |
---|
129 | case 315: // Artist |
---|
130 | case 316: // HostComputer |
---|
131 | if (isset($field_array['value'])) { |
---|
132 | $getid3->info['tiff']['ifd'][$ifd_id]['fields'][$key]['raw']['data'] = $field_array['value']; |
---|
133 | } else { |
---|
134 | fseek($getid3->fp, $field_array['offset'], SEEK_SET); |
---|
135 | $getid3->info['tiff']['ifd'][$ifd_id]['fields'][$key]['raw']['data'] = fread($getid3->fp, $field_array['raw']['length'] * $field_type_byte_length[$field_array['raw']['type']]); |
---|
136 | } |
---|
137 | break; |
---|
138 | } |
---|
139 | switch ($field_array['raw']['tag']) { |
---|
140 | case 256: // ImageWidth |
---|
141 | $getid3->info['video']['resolution_x'] = $field_array['value']; |
---|
142 | break; |
---|
143 | |
---|
144 | case 257: // ImageLength |
---|
145 | $getid3->info['video']['resolution_y'] = $field_array['value']; |
---|
146 | break; |
---|
147 | |
---|
148 | case 258: // BitsPerSample |
---|
149 | if (isset($field_array['value'])) { |
---|
150 | $getid3->info['video']['bits_per_sample'] = $field_array['value']; |
---|
151 | } else { |
---|
152 | $getid3->info['video']['bits_per_sample'] = 0; |
---|
153 | for ($i = 0; $i < $field_array['raw']['length']; $i++) { |
---|
154 | $getid3->info['video']['bits_per_sample'] += getid3_lib::$endian2int(substr($getid3->info['tiff']['ifd'][$ifd_id]['fields'][$key]['raw']['data'], $i * $field_type_byte_length[$field_array['raw']['type']], $field_type_byte_length[$field_array['raw']['type']])); |
---|
155 | } |
---|
156 | } |
---|
157 | break; |
---|
158 | |
---|
159 | case 259: // Compression |
---|
160 | $getid3->info['video']['codec'] = getid3_tiff::TIFFcompressionMethod($field_array['value']); |
---|
161 | break; |
---|
162 | |
---|
163 | case 270: // ImageDescription |
---|
164 | case 271: // Make |
---|
165 | case 272: // Model |
---|
166 | case 305: // Software |
---|
167 | case 306: // DateTime |
---|
168 | case 315: // Artist |
---|
169 | case 316: // HostComputer |
---|
170 | @$getid3->info['tiff']['comments'][getid3_tiff::TIFFcommentName($field_array['raw']['tag'])][] = $getid3->info['tiff']['ifd'][$ifd_id]['fields'][$key]['raw']['data']; |
---|
171 | break; |
---|
172 | |
---|
173 | default: |
---|
174 | break; |
---|
175 | } |
---|
176 | } |
---|
177 | } |
---|
178 | |
---|
179 | return true; |
---|
180 | } |
---|
181 | |
---|
182 | |
---|
183 | |
---|
184 | public static function TIFFcompressionMethod($id) { |
---|
185 | |
---|
186 | static $lookup = array ( |
---|
187 | 1 => 'Uncompressed', |
---|
188 | 2 => 'Huffman', |
---|
189 | 3 => 'Fax - CCITT 3', |
---|
190 | 5 => 'LZW', |
---|
191 | 32773 => 'PackBits', |
---|
192 | ); |
---|
193 | return (isset($lookup[$id]) ? $lookup[$id] : 'unknown/invalid ('.$id.')'); |
---|
194 | } |
---|
195 | |
---|
196 | |
---|
197 | |
---|
198 | public static function TIFFcommentName($id) { |
---|
199 | |
---|
200 | static $lookup = array ( |
---|
201 | 270 => 'imagedescription', |
---|
202 | 271 => 'make', |
---|
203 | 272 => 'model', |
---|
204 | 305 => 'software', |
---|
205 | 306 => 'datetime', |
---|
206 | 315 => 'artist', |
---|
207 | 316 => 'hostcomputer', |
---|
208 | ); |
---|
209 | return (isset($lookup[$id]) ? $lookup[$id] : 'unknown/invalid ('.$id.')'); |
---|
210 | } |
---|
211 | |
---|
212 | } |
---|
213 | |
---|
214 | |
---|
215 | ?> |
---|