annotate e2gallerypro/e2upload/Backend/Assets/getid3/module.graphic.png.php @ 20:1038db2374ec judyates

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