source: extensions/charlies_content/getid3/getid3/module.graphic.png.php @ 3544

Last change on this file since 3544 was 3544, checked in by vdigital, 15 years ago

Change: getid3 upgraded to -> 1.7.9

  • Property svn:eol-style set to LF
  • Property svn:keywords set to Author Date Id Revision
File size: 25.0 KB
Line 
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/////////////////////////////////////////////////////////////////
7// See readme.txt for more details                             //
8/////////////////////////////////////////////////////////////////
9//                                                             //
10// module.graphic.png.php                                      //
11// module for analyzing PNG Image files                        //
12// dependencies: NONE                                          //
13//                                                            ///
14/////////////////////////////////////////////////////////////////
15
16
17class getid3_png
18{
19
20        function getid3_png(&$fd, &$ThisFileInfo) {
21
22            // shortcut
23            $ThisFileInfo['png'] = array();
24            $thisfile_png = &$ThisFileInfo['png'];
25
26                $ThisFileInfo['fileformat']          = 'png';
27                $ThisFileInfo['video']['dataformat'] = 'png';
28                $ThisFileInfo['video']['lossless']   = false;
29
30                fseek($fd, $ThisFileInfo['avdataoffset'], SEEK_SET);
31                $PNGfiledata = fread($fd, GETID3_FREAD_BUFFER_SIZE);
32                $offset = 0;
33
34                $PNGidentifier = substr($PNGfiledata, $offset, 8); // $89 $50 $4E $47 $0D $0A $1A $0A
35                $offset += 8;
36
37                if ($PNGidentifier != "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A") {
38                        $ThisFileInfo['error'][] = 'First 8 bytes of file ('.getid3_lib::PrintHexBytes($PNGidentifier).') did not match expected PNG identifier';
39                        unset($ThisFileInfo['fileformat']);
40                        return false;
41                }
42
43                while (((ftell($fd) - (strlen($PNGfiledata) - $offset)) < $ThisFileInfo['filesize'])) {
44                        $chunk['data_length'] = getid3_lib::BigEndian2Int(substr($PNGfiledata, $offset, 4));
45                        $offset += 4;
46                        while (((strlen($PNGfiledata) - $offset) < ($chunk['data_length'] + 4)) && (ftell($fd) < $ThisFileInfo['filesize'])) {
47                                $PNGfiledata .= fread($fd, GETID3_FREAD_BUFFER_SIZE);
48                        }
49                        $chunk['type_text']   =               substr($PNGfiledata, $offset, 4);
50                        $offset += 4;
51                        $chunk['type_raw']    = getid3_lib::BigEndian2Int($chunk['type_text']);
52                        $chunk['data']        =               substr($PNGfiledata, $offset, $chunk['data_length']);
53                        $offset += $chunk['data_length'];
54                        $chunk['crc']         = getid3_lib::BigEndian2Int(substr($PNGfiledata, $offset, 4));
55                        $offset += 4;
56
57                        $chunk['flags']['ancilliary']   = (bool) ($chunk['type_raw'] & 0x20000000);
58                        $chunk['flags']['private']      = (bool) ($chunk['type_raw'] & 0x00200000);
59                        $chunk['flags']['reserved']     = (bool) ($chunk['type_raw'] & 0x00002000);
60                        $chunk['flags']['safe_to_copy'] = (bool) ($chunk['type_raw'] & 0x00000020);
61
62                        // shortcut
63                        $thisfile_png[$chunk['type_text']] = array();
64                        $thisfile_png_chunk_type_text = &$thisfile_png[$chunk['type_text']];
65
66                        switch ($chunk['type_text']) {
67
68                                case 'IHDR': // Image Header
69                                        $thisfile_png_chunk_type_text['header'] = $chunk;
70                                        $thisfile_png_chunk_type_text['width']                     = getid3_lib::BigEndian2Int(substr($chunk['data'],  0, 4));
71                                        $thisfile_png_chunk_type_text['height']                    = getid3_lib::BigEndian2Int(substr($chunk['data'],  4, 4));
72                                        $thisfile_png_chunk_type_text['raw']['bit_depth']          = getid3_lib::BigEndian2Int(substr($chunk['data'],  8, 1));
73                                        $thisfile_png_chunk_type_text['raw']['color_type']         = getid3_lib::BigEndian2Int(substr($chunk['data'],  9, 1));
74                                        $thisfile_png_chunk_type_text['raw']['compression_method'] = getid3_lib::BigEndian2Int(substr($chunk['data'], 10, 1));
75                                        $thisfile_png_chunk_type_text['raw']['filter_method']      = getid3_lib::BigEndian2Int(substr($chunk['data'], 11, 1));
76                                        $thisfile_png_chunk_type_text['raw']['interlace_method']   = getid3_lib::BigEndian2Int(substr($chunk['data'], 12, 1));
77
78                                        $thisfile_png_chunk_type_text['compression_method_text']   = $this->PNGcompressionMethodLookup($thisfile_png_chunk_type_text['raw']['compression_method']);
79                                        $thisfile_png_chunk_type_text['color_type']['palette']     = (bool) ($thisfile_png_chunk_type_text['raw']['color_type'] & 0x01);
80                                        $thisfile_png_chunk_type_text['color_type']['true_color']  = (bool) ($thisfile_png_chunk_type_text['raw']['color_type'] & 0x02);
81                                        $thisfile_png_chunk_type_text['color_type']['alpha']       = (bool) ($thisfile_png_chunk_type_text['raw']['color_type'] & 0x04);
82
83                                        $ThisFileInfo['video']['resolution_x']    = $thisfile_png_chunk_type_text['width'];
84                                        $ThisFileInfo['video']['resolution_y']    = $thisfile_png_chunk_type_text['height'];
85
86                                        $ThisFileInfo['video']['bits_per_sample'] = $this->IHDRcalculateBitsPerSample($thisfile_png_chunk_type_text['raw']['color_type'], $thisfile_png_chunk_type_text['raw']['bit_depth']);
87                                        break;
88
89
90                                case 'PLTE': // Palette
91                                        $thisfile_png_chunk_type_text['header'] = $chunk;
92                                        $paletteoffset = 0;
93                                        for ($i = 0; $i <= 255; $i++) {
94                                                //$thisfile_png_chunk_type_text['red'][$i]   = getid3_lib::BigEndian2Int(substr($chunk['data'], $paletteoffset++, 1));
95                                                //$thisfile_png_chunk_type_text['green'][$i] = getid3_lib::BigEndian2Int(substr($chunk['data'], $paletteoffset++, 1));
96                                                //$thisfile_png_chunk_type_text['blue'][$i]  = getid3_lib::BigEndian2Int(substr($chunk['data'], $paletteoffset++, 1));
97                                                $red   = getid3_lib::BigEndian2Int(substr($chunk['data'], $paletteoffset++, 1));
98                                                $green = getid3_lib::BigEndian2Int(substr($chunk['data'], $paletteoffset++, 1));
99                                                $blue  = getid3_lib::BigEndian2Int(substr($chunk['data'], $paletteoffset++, 1));
100                                                $thisfile_png_chunk_type_text[$i] = (($red << 16) | ($green << 8) | ($blue));
101                                        }
102                                        break;
103
104
105                                case 'tRNS': // Transparency
106                                        $thisfile_png_chunk_type_text['header'] = $chunk;
107                                        switch ($thisfile_png['IHDR']['raw']['color_type']) {
108                                                case 0:
109                                                        $thisfile_png_chunk_type_text['transparent_color_gray']  = getid3_lib::BigEndian2Int(substr($chunk['data'], 0, 2));
110                                                        break;
111
112                                                case 2:
113                                                        $thisfile_png_chunk_type_text['transparent_color_red']   = getid3_lib::BigEndian2Int(substr($chunk['data'], 0, 2));
114                                                        $thisfile_png_chunk_type_text['transparent_color_green'] = getid3_lib::BigEndian2Int(substr($chunk['data'], 2, 2));
115                                                        $thisfile_png_chunk_type_text['transparent_color_blue']  = getid3_lib::BigEndian2Int(substr($chunk['data'], 4, 2));
116                                                        break;
117
118                                                case 3:
119                                                        for ($i = 0; $i < strlen($chunk['data']); $i++) {
120                                                                $thisfile_png_chunk_type_text['palette_opacity'][$i] = getid3_lib::BigEndian2Int(substr($chunk['data'], $i, 1));
121                                                        }
122                                                        break;
123
124                                                case 4:
125                                                case 6:
126                                                        $ThisFileInfo['error'][] = 'Invalid color_type in tRNS chunk: '.$thisfile_png['IHDR']['raw']['color_type'];
127
128                                                default:
129                                                        $ThisFileInfo['warning'][] = 'Unhandled color_type in tRNS chunk: '.$thisfile_png['IHDR']['raw']['color_type'];
130                                                        break;
131                                        }
132                                        break;
133
134
135                                case 'gAMA': // Image Gamma
136                                        $thisfile_png_chunk_type_text['header'] = $chunk;
137                                        $thisfile_png_chunk_type_text['gamma']  = getid3_lib::BigEndian2Int($chunk['data']) / 100000;
138                                        break;
139
140
141                                case 'cHRM': // Primary Chromaticities
142                                        $thisfile_png_chunk_type_text['header']  = $chunk;
143                                        $thisfile_png_chunk_type_text['white_x'] = getid3_lib::BigEndian2Int(substr($chunk['data'],  0, 4)) / 100000;
144                                        $thisfile_png_chunk_type_text['white_y'] = getid3_lib::BigEndian2Int(substr($chunk['data'],  4, 4)) / 100000;
145                                        $thisfile_png_chunk_type_text['red_y']   = getid3_lib::BigEndian2Int(substr($chunk['data'],  8, 4)) / 100000;
146                                        $thisfile_png_chunk_type_text['red_y']   = getid3_lib::BigEndian2Int(substr($chunk['data'], 12, 4)) / 100000;
147                                        $thisfile_png_chunk_type_text['green_y'] = getid3_lib::BigEndian2Int(substr($chunk['data'], 16, 4)) / 100000;
148                                        $thisfile_png_chunk_type_text['green_y'] = getid3_lib::BigEndian2Int(substr($chunk['data'], 20, 4)) / 100000;
149                                        $thisfile_png_chunk_type_text['blue_y']  = getid3_lib::BigEndian2Int(substr($chunk['data'], 24, 4)) / 100000;
150                                        $thisfile_png_chunk_type_text['blue_y']  = getid3_lib::BigEndian2Int(substr($chunk['data'], 28, 4)) / 100000;
151                                        break;
152
153
154                                case 'sRGB': // Standard RGB Color Space
155                                        $thisfile_png_chunk_type_text['header']                 = $chunk;
156                                        $thisfile_png_chunk_type_text['reindering_intent']      = getid3_lib::BigEndian2Int($chunk['data']);
157                                        $thisfile_png_chunk_type_text['reindering_intent_text'] = $this->PNGsRGBintentLookup($thisfile_png_chunk_type_text['reindering_intent']);
158                                        break;
159
160
161                                case 'iCCP': // Embedded ICC Profile
162                                        $thisfile_png_chunk_type_text['header']                  = $chunk;
163                                        list($profilename, $compressiondata)                                 = explode("\x00", $chunk['data'], 2);
164                                        $thisfile_png_chunk_type_text['profile_name']            = $profilename;
165                                        $thisfile_png_chunk_type_text['compression_method']      = getid3_lib::BigEndian2Int(substr($compressiondata, 0, 1));
166                                        $thisfile_png_chunk_type_text['compression_profile']     = substr($compressiondata, 1);
167
168                                        $thisfile_png_chunk_type_text['compression_method_text'] = $this->PNGcompressionMethodLookup($thisfile_png_chunk_type_text['compression_method']);
169                                        break;
170
171
172                                case 'tEXt': // Textual Data
173                                        $thisfile_png_chunk_type_text['header']  = $chunk;
174                                        list($keyword, $text)                                = explode("\x00", $chunk['data'], 2);
175                                        $thisfile_png_chunk_type_text['keyword'] = $keyword;
176                                        $thisfile_png_chunk_type_text['text']    = $text;
177
178                                        $thisfile_png['comments'][$thisfile_png_chunk_type_text['keyword']][] = $thisfile_png_chunk_type_text['text'];
179                                        break;
180
181
182                                case 'zTXt': // Compressed Textual Data
183                                        $thisfile_png_chunk_type_text['header']                  = $chunk;
184                                        list($keyword, $otherdata)                                           = explode("\x00", $chunk['data'], 2);
185                                        $thisfile_png_chunk_type_text['keyword']                 = $keyword;
186                                        $thisfile_png_chunk_type_text['compression_method']      = getid3_lib::BigEndian2Int(substr($otherdata, 0, 1));
187                                        $thisfile_png_chunk_type_text['compressed_text']         = substr($otherdata, 1);
188                                        $thisfile_png_chunk_type_text['compression_method_text'] = $this->PNGcompressionMethodLookup($thisfile_png_chunk_type_text['compression_method']);
189                                        switch ($thisfile_png_chunk_type_text['compression_method']) {
190                                                case 0:
191                                                        $thisfile_png_chunk_type_text['text']            = gzuncompress($thisfile_png_chunk_type_text['compressed_text']);
192                                                        break;
193
194                                                default:
195                                                        // unknown compression method
196                                                        break;
197                                        }
198
199                                        if (isset($thisfile_png_chunk_type_text['text'])) {
200                                                $thisfile_png['comments'][$thisfile_png_chunk_type_text['keyword']][] = $thisfile_png_chunk_type_text['text'];
201                                        }
202                                        break;
203
204
205                                case 'iTXt': // International Textual Data
206                                        $thisfile_png_chunk_type_text['header']                  = $chunk;
207                                        list($keyword, $otherdata)                                           = explode("\x00", $chunk['data'], 2);
208                                        $thisfile_png_chunk_type_text['keyword']                 = $keyword;
209                                        $thisfile_png_chunk_type_text['compression']             = (bool) getid3_lib::BigEndian2Int(substr($otherdata, 0, 1));
210                                        $thisfile_png_chunk_type_text['compression_method']      = getid3_lib::BigEndian2Int(substr($otherdata, 1, 1));
211                                        $thisfile_png_chunk_type_text['compression_method_text'] = $this->PNGcompressionMethodLookup($thisfile_png_chunk_type_text['compression_method']);
212                                        list($languagetag, $translatedkeyword, $text)                        = explode("\x00", substr($otherdata, 2), 3);
213                                        $thisfile_png_chunk_type_text['language_tag']            = $languagetag;
214                                        $thisfile_png_chunk_type_text['translated_keyword']      = $translatedkeyword;
215
216                                        if ($thisfile_png_chunk_type_text['compression']) {
217
218                                                switch ($thisfile_png_chunk_type_text['compression_method']) {
219                                                        case 0:
220                                                                $thisfile_png_chunk_type_text['text']        = gzuncompress($text);
221                                                                break;
222
223                                                        default:
224                                                                // unknown compression method
225                                                                break;
226                                                }
227
228                                        } else {
229
230                                                $thisfile_png_chunk_type_text['text']                = $text;
231
232                                        }
233
234                                        if (isset($thisfile_png_chunk_type_text['text'])) {
235                                                $thisfile_png['comments'][$thisfile_png_chunk_type_text['keyword']][] = $thisfile_png_chunk_type_text['text'];
236                                        }
237                                        break;
238
239
240                                case 'bKGD': // Background Color
241                                        $thisfile_png_chunk_type_text['header']                   = $chunk;
242                                        switch ($thisfile_png['IHDR']['raw']['color_type']) {
243                                                case 0:
244                                                case 4:
245                                                        $thisfile_png_chunk_type_text['background_gray']  = getid3_lib::BigEndian2Int($chunk['data']);
246                                                        break;
247
248                                                case 2:
249                                                case 6:
250                                                        $thisfile_png_chunk_type_text['background_red']   = getid3_lib::BigEndian2Int(substr($chunk['data'], 0 * $thisfile_png['IHDR']['raw']['bit_depth'], $thisfile_png['IHDR']['raw']['bit_depth']));
251                                                        $thisfile_png_chunk_type_text['background_green'] = getid3_lib::BigEndian2Int(substr($chunk['data'], 1 * $thisfile_png['IHDR']['raw']['bit_depth'], $thisfile_png['IHDR']['raw']['bit_depth']));
252                                                        $thisfile_png_chunk_type_text['background_blue']  = getid3_lib::BigEndian2Int(substr($chunk['data'], 2 * $thisfile_png['IHDR']['raw']['bit_depth'], $thisfile_png['IHDR']['raw']['bit_depth']));
253                                                        break;
254
255                                                case 3:
256                                                        $thisfile_png_chunk_type_text['background_index'] = getid3_lib::BigEndian2Int($chunk['data']);
257                                                        break;
258
259                                                default:
260                                                        break;
261                                        }
262                                        break;
263
264
265                                case 'pHYs': // Physical Pixel Dimensions
266                                        $thisfile_png_chunk_type_text['header']                 = $chunk;
267                                        $thisfile_png_chunk_type_text['pixels_per_unit_x']      = getid3_lib::BigEndian2Int(substr($chunk['data'], 0, 4));
268                                        $thisfile_png_chunk_type_text['pixels_per_unit_y']      = getid3_lib::BigEndian2Int(substr($chunk['data'], 4, 4));
269                                        $thisfile_png_chunk_type_text['unit_specifier']         = getid3_lib::BigEndian2Int(substr($chunk['data'], 8, 1));
270                                        $thisfile_png_chunk_type_text['unit']                   = $this->PNGpHYsUnitLookup($thisfile_png_chunk_type_text['unit_specifier']);
271                                        break;
272
273
274                                case 'sBIT': // Significant Bits
275                                        $thisfile_png_chunk_type_text['header'] = $chunk;
276                                        switch ($thisfile_png['IHDR']['raw']['color_type']) {
277                                                case 0:
278                                                        $thisfile_png_chunk_type_text['significant_bits_gray']  = getid3_lib::BigEndian2Int(substr($chunk['data'], 0, 1));
279                                                        break;
280
281                                                case 2:
282                                                case 3:
283                                                        $thisfile_png_chunk_type_text['significant_bits_red']   = getid3_lib::BigEndian2Int(substr($chunk['data'], 0, 1));
284                                                        $thisfile_png_chunk_type_text['significant_bits_green'] = getid3_lib::BigEndian2Int(substr($chunk['data'], 1, 1));
285                                                        $thisfile_png_chunk_type_text['significant_bits_blue']  = getid3_lib::BigEndian2Int(substr($chunk['data'], 2, 1));
286                                                        break;
287
288                                                case 4:
289                                                        $thisfile_png_chunk_type_text['significant_bits_gray']  = getid3_lib::BigEndian2Int(substr($chunk['data'], 0, 1));
290                                                        $thisfile_png_chunk_type_text['significant_bits_alpha'] = getid3_lib::BigEndian2Int(substr($chunk['data'], 1, 1));
291                                                        break;
292
293                                                case 6:
294                                                        $thisfile_png_chunk_type_text['significant_bits_red']   = getid3_lib::BigEndian2Int(substr($chunk['data'], 0, 1));
295                                                        $thisfile_png_chunk_type_text['significant_bits_green'] = getid3_lib::BigEndian2Int(substr($chunk['data'], 1, 1));
296                                                        $thisfile_png_chunk_type_text['significant_bits_blue']  = getid3_lib::BigEndian2Int(substr($chunk['data'], 2, 1));
297                                                        $thisfile_png_chunk_type_text['significant_bits_alpha'] = getid3_lib::BigEndian2Int(substr($chunk['data'], 3, 1));
298                                                        break;
299
300                                                default:
301                                                        break;
302                                        }
303                                        break;
304
305
306                                case 'sPLT': // Suggested Palette
307                                        $thisfile_png_chunk_type_text['header']                           = $chunk;
308                                        list($palettename, $otherdata)                                                = explode("\x00", $chunk['data'], 2);
309                                        $thisfile_png_chunk_type_text['palette_name']                     = $palettename;
310                                        $sPLToffset = 0;
311                                        $thisfile_png_chunk_type_text['sample_depth_bits']                = getid3_lib::BigEndian2Int(substr($otherdata, $sPLToffset, 1));
312                                        $sPLToffset += 1;
313                                        $thisfile_png_chunk_type_text['sample_depth_bytes']               = $thisfile_png_chunk_type_text['sample_depth_bits'] / 8;
314                                        $paletteCounter = 0;
315                                        while ($sPLToffset < strlen($otherdata)) {
316                                                $thisfile_png_chunk_type_text['red'][$paletteCounter]       = getid3_lib::BigEndian2Int(substr($otherdata, $sPLToffset, $thisfile_png_chunk_type_text['sample_depth_bytes']));
317                                                $sPLToffset += $thisfile_png_chunk_type_text['sample_depth_bytes'];
318                                                $thisfile_png_chunk_type_text['green'][$paletteCounter]     = getid3_lib::BigEndian2Int(substr($otherdata, $sPLToffset, $thisfile_png_chunk_type_text['sample_depth_bytes']));
319                                                $sPLToffset += $thisfile_png_chunk_type_text['sample_depth_bytes'];
320                                                $thisfile_png_chunk_type_text['blue'][$paletteCounter]      = getid3_lib::BigEndian2Int(substr($otherdata, $sPLToffset, $thisfile_png_chunk_type_text['sample_depth_bytes']));
321                                                $sPLToffset += $thisfile_png_chunk_type_text['sample_depth_bytes'];
322                                                $thisfile_png_chunk_type_text['alpha'][$paletteCounter]     = getid3_lib::BigEndian2Int(substr($otherdata, $sPLToffset, $thisfile_png_chunk_type_text['sample_depth_bytes']));
323                                                $sPLToffset += $thisfile_png_chunk_type_text['sample_depth_bytes'];
324                                                $thisfile_png_chunk_type_text['frequency'][$paletteCounter] = getid3_lib::BigEndian2Int(substr($otherdata, $sPLToffset, 2));
325                                                $sPLToffset += 2;
326                                                $paletteCounter++;
327                                        }
328                                        break;
329
330
331                                case 'hIST': // Palette Histogram
332                                        $thisfile_png_chunk_type_text['header'] = $chunk;
333                                        $hISTcounter = 0;
334                                        while ($hISTcounter < strlen($chunk['data'])) {
335                                                $thisfile_png_chunk_type_text[$hISTcounter] = getid3_lib::BigEndian2Int(substr($chunk['data'], $hISTcounter / 2, 2));
336                                                $hISTcounter += 2;
337                                        }
338                                        break;
339
340
341                                case 'tIME': // Image Last-Modification Time
342                                        $thisfile_png_chunk_type_text['header'] = $chunk;
343                                        $thisfile_png_chunk_type_text['year']   = getid3_lib::BigEndian2Int(substr($chunk['data'], 0, 2));
344                                        $thisfile_png_chunk_type_text['month']  = getid3_lib::BigEndian2Int(substr($chunk['data'], 2, 1));
345                                        $thisfile_png_chunk_type_text['day']    = getid3_lib::BigEndian2Int(substr($chunk['data'], 3, 1));
346                                        $thisfile_png_chunk_type_text['hour']   = getid3_lib::BigEndian2Int(substr($chunk['data'], 4, 1));
347                                        $thisfile_png_chunk_type_text['minute'] = getid3_lib::BigEndian2Int(substr($chunk['data'], 5, 1));
348                                        $thisfile_png_chunk_type_text['second'] = getid3_lib::BigEndian2Int(substr($chunk['data'], 6, 1));
349                                        $thisfile_png_chunk_type_text['unix']   = gmmktime($thisfile_png_chunk_type_text['hour'], $thisfile_png_chunk_type_text['minute'], $thisfile_png_chunk_type_text['second'], $thisfile_png_chunk_type_text['month'], $thisfile_png_chunk_type_text['day'], $thisfile_png_chunk_type_text['year']);
350                                        break;
351
352
353                                case 'oFFs': // Image Offset
354                                        $thisfile_png_chunk_type_text['header']         = $chunk;
355                                        $thisfile_png_chunk_type_text['position_x']     = getid3_lib::BigEndian2Int(substr($chunk['data'], 0, 4), false, true);
356                                        $thisfile_png_chunk_type_text['position_y']     = getid3_lib::BigEndian2Int(substr($chunk['data'], 4, 4), false, true);
357                                        $thisfile_png_chunk_type_text['unit_specifier'] = getid3_lib::BigEndian2Int(substr($chunk['data'], 8, 1));
358                                        $thisfile_png_chunk_type_text['unit']           = $this->PNGoFFsUnitLookup($thisfile_png_chunk_type_text['unit_specifier']);
359                                        break;
360
361
362                                case 'pCAL': // Calibration Of Pixel Values
363                                        $thisfile_png_chunk_type_text['header']             = $chunk;
364                                        list($calibrationname, $otherdata)                              = explode("\x00", $chunk['data'], 2);
365                                        $thisfile_png_chunk_type_text['calibration_name']   = $calibrationname;
366                                        $pCALoffset = 0;
367                                        $thisfile_png_chunk_type_text['original_zero']      = getid3_lib::BigEndian2Int(substr($chunk['data'], $pCALoffset, 4), false, true);
368                                        $pCALoffset += 4;
369                                        $thisfile_png_chunk_type_text['original_max']       = getid3_lib::BigEndian2Int(substr($chunk['data'], $pCALoffset, 4), false, true);
370                                        $pCALoffset += 4;
371                                        $thisfile_png_chunk_type_text['equation_type']      = getid3_lib::BigEndian2Int(substr($chunk['data'], $pCALoffset, 1));
372                                        $pCALoffset += 1;
373                                        $thisfile_png_chunk_type_text['equation_type_text'] = $this->PNGpCALequationTypeLookup($thisfile_png_chunk_type_text['equation_type']);
374                                        $thisfile_png_chunk_type_text['parameter_count']    = getid3_lib::BigEndian2Int(substr($chunk['data'], $pCALoffset, 1));
375                                        $pCALoffset += 1;
376                                        $thisfile_png_chunk_type_text['parameters']         = explode("\x00", substr($chunk['data'], $pCALoffset));
377                                        break;
378
379
380                                case 'sCAL': // Physical Scale Of Image Subject
381                                        $thisfile_png_chunk_type_text['header']         = $chunk;
382                                        $thisfile_png_chunk_type_text['unit_specifier'] = getid3_lib::BigEndian2Int(substr($chunk['data'], 0, 1));
383                                        $thisfile_png_chunk_type_text['unit']           = $this->PNGsCALUnitLookup($thisfile_png_chunk_type_text['unit_specifier']);
384                                        list($pixelwidth, $pixelheight)                             = explode("\x00", substr($chunk['data'], 1));
385                                        $thisfile_png_chunk_type_text['pixel_width']    = $pixelwidth;
386                                        $thisfile_png_chunk_type_text['pixel_height']   = $pixelheight;
387                                        break;
388
389
390                                case 'gIFg': // GIF Graphic Control Extension
391                                        $gIFgCounter = 0;
392                                        if (isset($thisfile_png_chunk_type_text) && is_array($thisfile_png_chunk_type_text)) {
393                                                $gIFgCounter = count($thisfile_png_chunk_type_text);
394                                        }
395                                        $thisfile_png_chunk_type_text[$gIFgCounter]['header']          = $chunk;
396                                        $thisfile_png_chunk_type_text[$gIFgCounter]['disposal_method'] = getid3_lib::BigEndian2Int(substr($chunk['data'], 0, 1));
397                                        $thisfile_png_chunk_type_text[$gIFgCounter]['user_input_flag'] = getid3_lib::BigEndian2Int(substr($chunk['data'], 1, 1));
398                                        $thisfile_png_chunk_type_text[$gIFgCounter]['delay_time']      = getid3_lib::BigEndian2Int(substr($chunk['data'], 2, 2));
399                                        break;
400
401
402                                case 'gIFx': // GIF Application Extension
403                                        $gIFxCounter = 0;
404                                        if (isset($thisfile_png_chunk_type_text) && is_array($thisfile_png_chunk_type_text)) {
405                                                $gIFxCounter = count($thisfile_png_chunk_type_text);
406                                        }
407                                        $thisfile_png_chunk_type_text[$gIFxCounter]['header']                 = $chunk;
408                                        $thisfile_png_chunk_type_text[$gIFxCounter]['application_identifier'] = substr($chunk['data'],  0, 8);
409                                        $thisfile_png_chunk_type_text[$gIFxCounter]['authentication_code']    = substr($chunk['data'],  8, 3);
410                                        $thisfile_png_chunk_type_text[$gIFxCounter]['application_data']       = substr($chunk['data'], 11);
411                                        break;
412
413
414                                case 'IDAT': // Image Data
415                                        $idatinformationfieldindex = 0;
416                                        if (isset($thisfile_png['IDAT']) && is_array($thisfile_png['IDAT'])) {
417                                                $idatinformationfieldindex = count($thisfile_png['IDAT']);
418                                        }
419                                        unset($chunk['data']);
420                                        $thisfile_png_chunk_type_text[$idatinformationfieldindex]['header'] = $chunk;
421                                        break;
422
423
424                                case 'IEND': // Image Trailer
425                                        $thisfile_png_chunk_type_text['header'] = $chunk;
426                                        break;
427
428
429                                default:
430                                        //unset($chunk['data']);
431                                        $thisfile_png_chunk_type_text['header'] = $chunk;
432                                        $ThisFileInfo['warning'][] = 'Unhandled chunk type: '.$chunk['type_text'];
433                                        break;
434                        }
435                }
436
437                return true;
438        }
439
440        function PNGsRGBintentLookup($sRGB) {
441                static $PNGsRGBintentLookup = array(
442                        0 => 'Perceptual',
443                        1 => 'Relative colorimetric',
444                        2 => 'Saturation',
445                        3 => 'Absolute colorimetric'
446                );
447                return (isset($PNGsRGBintentLookup[$sRGB]) ? $PNGsRGBintentLookup[$sRGB] : 'invalid');
448        }
449
450        function PNGcompressionMethodLookup($compressionmethod) {
451                static $PNGcompressionMethodLookup = array(
452                        0 => 'deflate/inflate'
453                );
454                return (isset($PNGcompressionMethodLookup[$compressionmethod]) ? $PNGcompressionMethodLookup[$compressionmethod] : 'invalid');
455        }
456
457        function PNGpHYsUnitLookup($unitid) {
458                static $PNGpHYsUnitLookup = array(
459                        0 => 'unknown',
460                        1 => 'meter'
461                );
462                return (isset($PNGpHYsUnitLookup[$unitid]) ? $PNGpHYsUnitLookup[$unitid] : 'invalid');
463        }
464
465        function PNGoFFsUnitLookup($unitid) {
466                static $PNGoFFsUnitLookup = array(
467                        0 => 'pixel',
468                        1 => 'micrometer'
469                );
470                return (isset($PNGoFFsUnitLookup[$unitid]) ? $PNGoFFsUnitLookup[$unitid] : 'invalid');
471        }
472
473        function PNGpCALequationTypeLookup($equationtype) {
474                static $PNGpCALequationTypeLookup = array(
475                        0 => 'Linear mapping',
476                        1 => 'Base-e exponential mapping',
477                        2 => 'Arbitrary-base exponential mapping',
478                        3 => 'Hyperbolic mapping'
479                );
480                return (isset($PNGpCALequationTypeLookup[$equationtype]) ? $PNGpCALequationTypeLookup[$equationtype] : 'invalid');
481        }
482
483        function PNGsCALUnitLookup($unitid) {
484                static $PNGsCALUnitLookup = array(
485                        0 => 'meter',
486                        1 => 'radian'
487                );
488                return (isset($PNGsCALUnitLookup[$unitid]) ? $PNGsCALUnitLookup[$unitid] : 'invalid');
489        }
490
491        function IHDRcalculateBitsPerSample($color_type, $bit_depth) {
492                switch ($color_type) {
493                        case 0: // Each pixel is a grayscale sample.
494                                return $bit_depth;
495                                break;
496
497                        case 2: // Each pixel is an R,G,B triple
498                                return 3 * $bit_depth;
499                                break;
500
501                        case 3: // Each pixel is a palette index; a PLTE chunk must appear.
502                                return $bit_depth;
503                                break;
504
505                        case 4: // Each pixel is a grayscale sample, followed by an alpha sample.
506                                return 2 * $bit_depth;
507                                break;
508
509                        case 6: // Each pixel is an R,G,B triple, followed by an alpha sample.
510                                return 4 * $bit_depth;
511                                break;
512                }
513                return false;
514        }
515
516}
517
518
519?>
Note: See TracBrowser for help on using the repository browser.