24                $info = &$this->getid3->info;
 
   27                $info[
'png'] = array();
 
   28                $thisfile_png = &
$info[
'png'];
 
   30                $info[
'fileformat']          = 
'png';
 
   31                $info[
'video'][
'dataformat'] = 
'png';
 
   32                $info[
'video'][
'lossless']   = 
false;
 
   35                $PNGfiledata = $this->
fread($this->getid3->fread_buffer_size());
 
   38                $PNGidentifier = substr($PNGfiledata, $offset, 8); 
 
   41                if ($PNGidentifier != 
"\x89\x50\x4E\x47\x0D\x0A\x1A\x0A") {
 
   43                        unset(
$info[
'fileformat']);
 
   47                while ((($this->
ftell() - (strlen($PNGfiledata) - $offset)) < 
$info[
'filesize'])) {
 
   49                        if ($chunk[
'data_length'] === 
false) {
 
   50                                $this->
error(
'Failed to read data_length at offset '.$offset);
 
   54                        $truncated_data = 
false;
 
   55                        while (((strlen($PNGfiledata) - $offset) < ($chunk[
'data_length'] + 4)) && ($this->
ftell() < 
$info[
'filesize'])) {
 
   56                                if (strlen($PNGfiledata) < $this->max_data_bytes) {
 
   57                                        $PNGfiledata .= $this->
fread($this->getid3->fread_buffer_size());
 
   59                                        $this->
warning(
'At offset '.$offset.
' chunk "'.substr($PNGfiledata, $offset, 4).
'" exceeded max_data_bytes value of '.$this->max_data_bytes.
', data chunk will be truncated at '.(strlen($PNGfiledata) - 8).
' bytes');
 
   63                        $chunk[
'type_text']   =                           substr($PNGfiledata, $offset, 4);
 
   66                        $chunk[
'data']        =                           substr($PNGfiledata, $offset, $chunk[
'data_length']);
 
   67                        $offset += $chunk[
'data_length'];
 
   71                        $chunk[
'flags'][
'ancilliary']   = (bool) ($chunk[
'type_raw'] & 0x20000000);
 
   72                        $chunk[
'flags'][
'private']      = (bool) ($chunk[
'type_raw'] & 0x00200000);
 
   73                        $chunk[
'flags'][
'reserved']     = (bool) ($chunk[
'type_raw'] & 0x00002000);
 
   74                        $chunk[
'flags'][
'safe_to_copy'] = (bool) ($chunk[
'type_raw'] & 0x00000020);
 
   77                        $thisfile_png[$chunk[
'type_text']] = array();
 
   78                        $thisfile_png_chunk_type_text = &$thisfile_png[$chunk[
'type_text']];
 
   80                        switch ($chunk[
'type_text']) {
 
   83                                        $thisfile_png_chunk_type_text[
'header'] = $chunk;
 
   92                                        $thisfile_png_chunk_type_text[
'compression_method_text']   = $this->
PNGcompressionMethodLookup($thisfile_png_chunk_type_text[
'raw'][
'compression_method']);
 
   93                                        $thisfile_png_chunk_type_text[
'color_type'][
'palette']     = (bool) ($thisfile_png_chunk_type_text[
'raw'][
'color_type'] & 0x01);
 
   94                                        $thisfile_png_chunk_type_text[
'color_type'][
'true_color']  = (bool) ($thisfile_png_chunk_type_text[
'raw'][
'color_type'] & 0x02);
 
   95                                        $thisfile_png_chunk_type_text[
'color_type'][
'alpha']       = (bool) ($thisfile_png_chunk_type_text[
'raw'][
'color_type'] & 0x04);
 
   97                                        $info[
'video'][
'resolution_x']    = $thisfile_png_chunk_type_text[
'width'];
 
   98                                        $info[
'video'][
'resolution_y']    = $thisfile_png_chunk_type_text[
'height'];
 
  100                                        $info[
'video'][
'bits_per_sample'] = $this->
IHDRcalculateBitsPerSample($thisfile_png_chunk_type_text[
'raw'][
'color_type'], $thisfile_png_chunk_type_text[
'raw'][
'bit_depth']);
 
  105                                        $thisfile_png_chunk_type_text[
'header'] = $chunk;
 
  107                                        for (
$i = 0; 
$i <= 255; 
$i++) {
 
  120                                        $thisfile_png_chunk_type_text[
'header'] = $chunk;
 
  121                                        switch ($thisfile_png[
'IHDR'][
'raw'][
'color_type']) {
 
  133                                                        for (
$i = 0; 
$i < strlen($chunk[
'data']); 
$i++) {
 
  140                                                        $this->
error(
'Invalid color_type in tRNS chunk: '.$thisfile_png[
'IHDR'][
'raw'][
'color_type']);
 
  143                                                        $this->
warning(
'Unhandled color_type in tRNS chunk: '.$thisfile_png[
'IHDR'][
'raw'][
'color_type']);
 
  150                                        $thisfile_png_chunk_type_text[
'header'] = $chunk;
 
  156                                        $thisfile_png_chunk_type_text[
'header']  = $chunk;
 
  169                                        $thisfile_png_chunk_type_text[
'header']                 = $chunk;
 
  171                                        $thisfile_png_chunk_type_text[
'reindering_intent_text'] = $this->
PNGsRGBintentLookup($thisfile_png_chunk_type_text[
'reindering_intent']);
 
  176                                        $thisfile_png_chunk_type_text[
'header']                  = $chunk;
 
  177                                        list($profilename, $compressiondata)                     = explode(
"\x00", $chunk[
'data'], 2);
 
  178                                        $thisfile_png_chunk_type_text[
'profile_name']            = $profilename;
 
  180                                        $thisfile_png_chunk_type_text[
'compression_profile']     = substr($compressiondata, 1);
 
  182                                        $thisfile_png_chunk_type_text[
'compression_method_text'] = $this->
PNGcompressionMethodLookup($thisfile_png_chunk_type_text[
'compression_method']);
 
  187                                        $thisfile_png_chunk_type_text[
'header']  = $chunk;
 
  188                                        list($keyword, 
$text) = explode(
"\x00", $chunk[
'data'], 2);
 
  189                                        $thisfile_png_chunk_type_text[
'keyword'] = $keyword;
 
  190                                        $thisfile_png_chunk_type_text[
'text']    = 
$text;
 
  192                                        $thisfile_png[
'comments'][$thisfile_png_chunk_type_text[
'keyword']][] = $thisfile_png_chunk_type_text[
'text'];
 
  197                                        $thisfile_png_chunk_type_text[
'header']                  = $chunk;
 
  198                                        list($keyword, $otherdata)                               = explode(
"\x00", $chunk[
'data'], 2);
 
  199                                        $thisfile_png_chunk_type_text[
'keyword']                 = $keyword;
 
  201                                        $thisfile_png_chunk_type_text[
'compressed_text']         = substr($otherdata, 1);
 
  202                                        $thisfile_png_chunk_type_text[
'compression_method_text'] = $this->
PNGcompressionMethodLookup($thisfile_png_chunk_type_text[
'compression_method']);
 
  203                                        switch ($thisfile_png_chunk_type_text[
'compression_method']) {
 
  205                                                        $thisfile_png_chunk_type_text[
'text']            = gzuncompress($thisfile_png_chunk_type_text[
'compressed_text']);
 
  213                                        if (isset($thisfile_png_chunk_type_text[
'text'])) {
 
  214                                                $thisfile_png[
'comments'][$thisfile_png_chunk_type_text[
'keyword']][] = $thisfile_png_chunk_type_text[
'text'];
 
  220                                        $thisfile_png_chunk_type_text[
'header']                  = $chunk;
 
  221                                        list($keyword, $otherdata)                               = explode(
"\x00", $chunk[
'data'], 2);
 
  222                                        $thisfile_png_chunk_type_text[
'keyword']                 = $keyword;
 
  225                                        $thisfile_png_chunk_type_text[
'compression_method_text'] = $this->
PNGcompressionMethodLookup($thisfile_png_chunk_type_text[
'compression_method']);
 
  226                                        list($languagetag, $translatedkeyword, 
$text)                        = explode(
"\x00", substr($otherdata, 2), 3);
 
  227                                        $thisfile_png_chunk_type_text[
'language_tag']            = $languagetag;
 
  228                                        $thisfile_png_chunk_type_text[
'translated_keyword']      = $translatedkeyword;
 
  230                                        if ($thisfile_png_chunk_type_text[
'compression']) {
 
  232                                                switch ($thisfile_png_chunk_type_text[
'compression_method']) {
 
  234                                                                $thisfile_png_chunk_type_text[
'text']        = gzuncompress(
$text);
 
  244                                                $thisfile_png_chunk_type_text[
'text']                = 
$text;
 
  248                                        if (isset($thisfile_png_chunk_type_text[
'text'])) {
 
  249                                                $thisfile_png[
'comments'][$thisfile_png_chunk_type_text[
'keyword']][] = $thisfile_png_chunk_type_text[
'text'];
 
  255                                        $thisfile_png_chunk_type_text[
'header']                   = $chunk;
 
  256                                        switch ($thisfile_png[
'IHDR'][
'raw'][
'color_type']) {
 
  264                                                        $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']));
 
  265                                                        $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']));
 
  266                                                        $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']));
 
  280                                        $thisfile_png_chunk_type_text[
'header']                 = $chunk;
 
  284                                        $thisfile_png_chunk_type_text[
'unit']                   = $this->
PNGpHYsUnitLookup($thisfile_png_chunk_type_text[
'unit_specifier']);
 
  289                                        $thisfile_png_chunk_type_text[
'header'] = $chunk;
 
  290                                        switch ($thisfile_png[
'IHDR'][
'raw'][
'color_type']) {
 
  321                                        $thisfile_png_chunk_type_text[
'header']                           = $chunk;
 
  322                                        list($palettename, $otherdata)                                    = explode(
"\x00", $chunk[
'data'], 2);
 
  323                                        $thisfile_png_chunk_type_text[
'palette_name']                     = $palettename;
 
  327                                        $thisfile_png_chunk_type_text[
'sample_depth_bytes']               = $thisfile_png_chunk_type_text[
'sample_depth_bits'] / 8;
 
  329                                        while ($sPLToffset < strlen($otherdata)) {
 
  330                                                $thisfile_png_chunk_type_text[
'red'][$paletteCounter]       = 
getid3_lib::BigEndian2Int(substr($otherdata, $sPLToffset, $thisfile_png_chunk_type_text[
'sample_depth_bytes']));
 
  331                                                $sPLToffset += $thisfile_png_chunk_type_text[
'sample_depth_bytes'];
 
  332                                                $thisfile_png_chunk_type_text[
'green'][$paletteCounter]     = 
getid3_lib::BigEndian2Int(substr($otherdata, $sPLToffset, $thisfile_png_chunk_type_text[
'sample_depth_bytes']));
 
  333                                                $sPLToffset += $thisfile_png_chunk_type_text[
'sample_depth_bytes'];
 
  334                                                $thisfile_png_chunk_type_text[
'blue'][$paletteCounter]      = 
getid3_lib::BigEndian2Int(substr($otherdata, $sPLToffset, $thisfile_png_chunk_type_text[
'sample_depth_bytes']));
 
  335                                                $sPLToffset += $thisfile_png_chunk_type_text[
'sample_depth_bytes'];
 
  336                                                $thisfile_png_chunk_type_text[
'alpha'][$paletteCounter]     = 
getid3_lib::BigEndian2Int(substr($otherdata, $sPLToffset, $thisfile_png_chunk_type_text[
'sample_depth_bytes']));
 
  337                                                $sPLToffset += $thisfile_png_chunk_type_text[
'sample_depth_bytes'];
 
  338                                                $thisfile_png_chunk_type_text[
'frequency'][$paletteCounter] = 
getid3_lib::BigEndian2Int(substr($otherdata, $sPLToffset, 2));
 
  346                                        $thisfile_png_chunk_type_text[
'header'] = $chunk;
 
  348                                        while ($hISTcounter < strlen($chunk[
'data'])) {
 
  356                                        $thisfile_png_chunk_type_text[
'header'] = $chunk;
 
  363                                        $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']);
 
  368                                        $thisfile_png_chunk_type_text[
'header']         = $chunk;
 
  372                                        $thisfile_png_chunk_type_text[
'unit']           = $this->
PNGoFFsUnitLookup($thisfile_png_chunk_type_text[
'unit_specifier']);
 
  377                                        $thisfile_png_chunk_type_text[
'header']             = $chunk;
 
  378                                        list($calibrationname, $otherdata)                              = explode(
"\x00", $chunk[
'data'], 2);
 
  379                                        $thisfile_png_chunk_type_text[
'calibration_name']   = $calibrationname;
 
  381                                        $thisfile_png_chunk_type_text[
'original_zero']      = 
getid3_lib::BigEndian2Int(substr($chunk[
'data'], $pCALoffset, 4), 
false, 
true);
 
  383                                        $thisfile_png_chunk_type_text[
'original_max']       = 
getid3_lib::BigEndian2Int(substr($chunk[
'data'], $pCALoffset, 4), 
false, 
true);
 
  387                                        $thisfile_png_chunk_type_text[
'equation_type_text'] = $this->
PNGpCALequationTypeLookup($thisfile_png_chunk_type_text[
'equation_type']);
 
  390                                        $thisfile_png_chunk_type_text[
'parameters']         = explode(
"\x00", substr($chunk[
'data'], $pCALoffset));
 
  395                                        $thisfile_png_chunk_type_text[
'header']         = $chunk;
 
  397                                        $thisfile_png_chunk_type_text[
'unit']           = $this->
PNGsCALUnitLookup($thisfile_png_chunk_type_text[
'unit_specifier']);
 
  398                                        list($pixelwidth, $pixelheight)                             = explode(
"\x00", substr($chunk[
'data'], 1));
 
  399                                        $thisfile_png_chunk_type_text[
'pixel_width']    = $pixelwidth;
 
  400                                        $thisfile_png_chunk_type_text[
'pixel_height']   = $pixelheight;
 
  406                                        if (isset($thisfile_png_chunk_type_text) && is_array($thisfile_png_chunk_type_text)) {
 
  407                                                $gIFgCounter = count($thisfile_png_chunk_type_text);
 
  409                                        $thisfile_png_chunk_type_text[$gIFgCounter][
'header']          = $chunk;
 
  410                                        $thisfile_png_chunk_type_text[$gIFgCounter][
'disposal_method'] = 
getid3_lib::BigEndian2Int(substr($chunk[
'data'], 0, 1));
 
  411                                        $thisfile_png_chunk_type_text[$gIFgCounter][
'user_input_flag'] = 
getid3_lib::BigEndian2Int(substr($chunk[
'data'], 1, 1));
 
  418                                        if (isset($thisfile_png_chunk_type_text) && is_array($thisfile_png_chunk_type_text)) {
 
  419                                                $gIFxCounter = count($thisfile_png_chunk_type_text);
 
  421                                        $thisfile_png_chunk_type_text[$gIFxCounter][
'header']                 = $chunk;
 
  422                                        $thisfile_png_chunk_type_text[$gIFxCounter][
'application_identifier'] = substr($chunk[
'data'],  0, 8);
 
  423                                        $thisfile_png_chunk_type_text[$gIFxCounter][
'authentication_code']    = substr($chunk[
'data'],  8, 3);
 
  424                                        $thisfile_png_chunk_type_text[$gIFxCounter][
'application_data']       = substr($chunk[
'data'], 11);
 
  429                                        $idatinformationfieldindex = 0;
 
  430                                        if (isset($thisfile_png[
'IDAT']) && is_array($thisfile_png[
'IDAT'])) {
 
  431                                                $idatinformationfieldindex = count($thisfile_png[
'IDAT']);
 
  433                                        unset($chunk[
'data']);
 
  434                                        $thisfile_png_chunk_type_text[$idatinformationfieldindex][
'header'] = $chunk;
 
  439                                        $thisfile_png_chunk_type_text[
'header'] = $chunk;
 
  445                                        $thisfile_png_chunk_type_text[
'header'] = $chunk;
 
  446                                        $this->
warning(
'Unhandled chunk type: '.$chunk[
'type_text']);
 
  455                static $PNGsRGBintentLookup = array(
 
  457                        1 => 
'Relative colorimetric',
 
  459                        3 => 
'Absolute colorimetric' 
  461                return (isset($PNGsRGBintentLookup[$sRGB]) ? $PNGsRGBintentLookup[$sRGB] : 
'invalid');
 
  465                static $PNGcompressionMethodLookup = array(
 
  466                        0 => 
'deflate/inflate' 
  468                return (isset($PNGcompressionMethodLookup[$compressionmethod]) ? $PNGcompressionMethodLookup[$compressionmethod] : 
'invalid');
 
  472                static $PNGpHYsUnitLookup = array(
 
  476                return (isset($PNGpHYsUnitLookup[$unitid]) ? $PNGpHYsUnitLookup[$unitid] : 
'invalid');
 
  480                static $PNGoFFsUnitLookup = array(
 
  484                return (isset($PNGoFFsUnitLookup[$unitid]) ? $PNGoFFsUnitLookup[$unitid] : 
'invalid');
 
  488                static $PNGpCALequationTypeLookup = array(
 
  489                        0 => 
'Linear mapping',
 
  490                        1 => 
'Base-e exponential mapping',
 
  491                        2 => 
'Arbitrary-base exponential mapping',
 
  492                        3 => 
'Hyperbolic mapping' 
  494                return (isset($PNGpCALequationTypeLookup[$equationtype]) ? $PNGpCALequationTypeLookup[$equationtype] : 
'invalid');
 
  498                static $PNGsCALUnitLookup = array(
 
  502                return (isset($PNGsCALUnitLookup[$unitid]) ? $PNGsCALUnitLookup[$unitid] : 
'invalid');
 
  506                switch ($color_type) {
 
  512                                return 3 * $bit_depth;
 
  520                                return 2 * $bit_depth;
 
  524                                return 4 * $bit_depth;
 
An exception for terminatinating execution or to throw for unit testing.
fseek($bytes, $whence=SEEK_SET)
static PrintHexBytes($string, $hex=true, $spaces=true, $htmlencoding='UTF-8')
static BigEndian2Int($byteword, $synchsafe=false, $signed=false)
getID3() by James Heinrich info@getid3.org //
PNGsRGBintentLookup($sRGB)
IHDRcalculateBitsPerSample($color_type, $bit_depth)
PNGpHYsUnitLookup($unitid)
PNGpCALequationTypeLookup($equationtype)
PNGcompressionMethodLookup($compressionmethod)
PNGoFFsUnitLookup($unitid)
PNGsCALUnitLookup($unitid)