Ignore:
Timestamp:
Jul 7, 2009, 10:27:37 PM (15 years ago)
Author:
vdigital
Message:

Change: getid3 upgraded to -> 1.7.9

File:
1 edited

Legend:

Unmodified
Added
Removed
  • extensions/charlies_content/getid3/getid3/module.graphic.png.php

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