38 $info = &$this->getid3->info;
42 $thisfile_png = &
$info[
'png'];
44 $info[
'fileformat'] =
'png';
45 $info[
'video'][
'dataformat'] =
'png';
46 $info[
'video'][
'lossless'] =
false;
48 fseek($this->getid3->fp,
$info[
'avdataoffset'], SEEK_SET);
49 $PNGfiledata =
fread($this->getid3->fp, $this->getid3->fread_buffer_size());
52 $PNGidentifier = substr($PNGfiledata, $offset, 8);
55 if ($PNGidentifier !=
"\x89\x50\x4E\x47\x0D\x0A\x1A\x0A") {
56 $info[
'error'][] =
'First 8 bytes of file ('.Helper::PrintHexBytes($PNGidentifier).
') did not match expected PNG identifier';
57 unset(
$info[
'fileformat']);
62 while (((
ftell($this->getid3->fp) - (strlen($PNGfiledata) - $offset)) <
$info[
'filesize'])) {
65 while (((strlen($PNGfiledata) - $offset) < ($chunk[
'data_length'] + 4)) && (
ftell($this->getid3->fp) <
$info[
'filesize'])) {
66 $PNGfiledata .=
fread($this->getid3->fp, $this->getid3->fread_buffer_size());
68 $chunk[
'type_text'] = substr($PNGfiledata, $offset, 4);
71 $chunk[
'data'] = substr($PNGfiledata, $offset, $chunk[
'data_length']);
72 $offset += $chunk[
'data_length'];
76 $chunk[
'flags'][
'ancilliary'] = (bool) ($chunk[
'type_raw'] & 0x20000000);
77 $chunk[
'flags'][
'private'] = (bool) ($chunk[
'type_raw'] & 0x00200000);
78 $chunk[
'flags'][
'reserved'] = (bool) ($chunk[
'type_raw'] & 0x00002000);
79 $chunk[
'flags'][
'safe_to_copy'] = (bool) ($chunk[
'type_raw'] & 0x00000020);
82 $thisfile_png[$chunk[
'type_text']] =
array();
83 $thisfile_png_chunk_type_text = &$thisfile_png[$chunk[
'type_text']];
85 switch ($chunk[
'type_text']) {
88 $thisfile_png_chunk_type_text[
'header'] = $chunk;
91 $thisfile_png_chunk_type_text[
'raw'][
'bit_depth'] =
Helper::BigEndian2Int(substr($chunk[
'data'], 8, 1));
92 $thisfile_png_chunk_type_text[
'raw'][
'color_type'] =
Helper::BigEndian2Int(substr($chunk[
'data'], 9, 1));
93 $thisfile_png_chunk_type_text[
'raw'][
'compression_method'] =
Helper::BigEndian2Int(substr($chunk[
'data'], 10, 1));
94 $thisfile_png_chunk_type_text[
'raw'][
'filter_method'] =
Helper::BigEndian2Int(substr($chunk[
'data'], 11, 1));
95 $thisfile_png_chunk_type_text[
'raw'][
'interlace_method'] =
Helper::BigEndian2Int(substr($chunk[
'data'], 12, 1));
97 $thisfile_png_chunk_type_text[
'compression_method_text'] = $this->
PNGcompressionMethodLookup($thisfile_png_chunk_type_text[
'raw'][
'compression_method']);
98 $thisfile_png_chunk_type_text[
'color_type'][
'palette'] = (bool) ($thisfile_png_chunk_type_text[
'raw'][
'color_type'] & 0x01);
99 $thisfile_png_chunk_type_text[
'color_type'][
'true_color'] = (bool) ($thisfile_png_chunk_type_text[
'raw'][
'color_type'] & 0x02);
100 $thisfile_png_chunk_type_text[
'color_type'][
'alpha'] = (bool) ($thisfile_png_chunk_type_text[
'raw'][
'color_type'] & 0x04);
102 $info[
'video'][
'resolution_x'] = $thisfile_png_chunk_type_text[
'width'];
103 $info[
'video'][
'resolution_y'] = $thisfile_png_chunk_type_text[
'height'];
105 $info[
'video'][
'bits_per_sample'] = $this->
IHDRcalculateBitsPerSample($thisfile_png_chunk_type_text[
'raw'][
'color_type'], $thisfile_png_chunk_type_text[
'raw'][
'bit_depth']);
109 $thisfile_png_chunk_type_text[
'header'] = $chunk;
111 for ($i = 0; $i <= 255; $i++) {
118 $thisfile_png_chunk_type_text[$i] = ((
$red << 16) | (
$green << 8) | (
$blue));
123 $thisfile_png_chunk_type_text[
'header'] = $chunk;
124 switch ($thisfile_png[
'IHDR'][
'raw'][
'color_type']) {
126 $thisfile_png_chunk_type_text[
'transparent_color_gray'] =
Helper::BigEndian2Int(substr($chunk[
'data'], 0, 2));
130 $thisfile_png_chunk_type_text[
'transparent_color_red'] =
Helper::BigEndian2Int(substr($chunk[
'data'], 0, 2));
131 $thisfile_png_chunk_type_text[
'transparent_color_green'] =
Helper::BigEndian2Int(substr($chunk[
'data'], 2, 2));
132 $thisfile_png_chunk_type_text[
'transparent_color_blue'] =
Helper::BigEndian2Int(substr($chunk[
'data'], 4, 2));
136 for ($i = 0; $i < strlen($chunk[
'data']); $i++) {
137 $thisfile_png_chunk_type_text[
'palette_opacity'][$i] =
Helper::BigEndian2Int(substr($chunk[
'data'], $i, 1));
143 $info[
'error'][] =
'Invalid color_type in tRNS chunk: '.$thisfile_png[
'IHDR'][
'raw'][
'color_type'];
146 $info[
'warning'][] =
'Unhandled color_type in tRNS chunk: '.$thisfile_png[
'IHDR'][
'raw'][
'color_type'];
152 $thisfile_png_chunk_type_text[
'header'] = $chunk;
157 $thisfile_png_chunk_type_text[
'header'] = $chunk;
158 $thisfile_png_chunk_type_text[
'white_x'] =
Helper::BigEndian2Int(substr($chunk[
'data'], 0, 4)) / 100000;
159 $thisfile_png_chunk_type_text[
'white_y'] =
Helper::BigEndian2Int(substr($chunk[
'data'], 4, 4)) / 100000;
160 $thisfile_png_chunk_type_text[
'red_y'] =
Helper::BigEndian2Int(substr($chunk[
'data'], 8, 4)) / 100000;
161 $thisfile_png_chunk_type_text[
'red_y'] =
Helper::BigEndian2Int(substr($chunk[
'data'], 12, 4)) / 100000;
162 $thisfile_png_chunk_type_text[
'green_y'] =
Helper::BigEndian2Int(substr($chunk[
'data'], 16, 4)) / 100000;
163 $thisfile_png_chunk_type_text[
'green_y'] =
Helper::BigEndian2Int(substr($chunk[
'data'], 20, 4)) / 100000;
164 $thisfile_png_chunk_type_text[
'blue_y'] =
Helper::BigEndian2Int(substr($chunk[
'data'], 24, 4)) / 100000;
165 $thisfile_png_chunk_type_text[
'blue_y'] =
Helper::BigEndian2Int(substr($chunk[
'data'], 28, 4)) / 100000;
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']);
175 $thisfile_png_chunk_type_text[
'header'] = $chunk;
176 list($profilename, $compressiondata) = explode(
"\x00", $chunk[
'data'], 2);
177 $thisfile_png_chunk_type_text[
'profile_name'] = $profilename;
178 $thisfile_png_chunk_type_text[
'compression_method'] =
Helper::BigEndian2Int(substr($compressiondata, 0, 1));
179 $thisfile_png_chunk_type_text[
'compression_profile'] = substr($compressiondata, 1);
181 $thisfile_png_chunk_type_text[
'compression_method_text'] = $this->
PNGcompressionMethodLookup($thisfile_png_chunk_type_text[
'compression_method']);
185 $thisfile_png_chunk_type_text[
'header'] = $chunk;
186 list($keyword,
$text) = explode(
"\x00", $chunk[
'data'], 2);
187 $thisfile_png_chunk_type_text[
'keyword'] = $keyword;
188 $thisfile_png_chunk_type_text[
'text'] =
$text;
190 $thisfile_png[
'comments'][$thisfile_png_chunk_type_text[
'keyword']][] = $thisfile_png_chunk_type_text[
'text'];
194 $thisfile_png_chunk_type_text[
'header'] = $chunk;
195 list($keyword, $otherdata) = explode(
"\x00", $chunk[
'data'], 2);
196 $thisfile_png_chunk_type_text[
'keyword'] = $keyword;
197 $thisfile_png_chunk_type_text[
'compression_method'] =
Helper::BigEndian2Int(substr($otherdata, 0, 1));
198 $thisfile_png_chunk_type_text[
'compressed_text'] = substr($otherdata, 1);
199 $thisfile_png_chunk_type_text[
'compression_method_text'] = $this->
PNGcompressionMethodLookup($thisfile_png_chunk_type_text[
'compression_method']);
200 switch ($thisfile_png_chunk_type_text[
'compression_method']) {
202 $thisfile_png_chunk_type_text[
'text'] = gzuncompress($thisfile_png_chunk_type_text[
'compressed_text']);
210 if (isset($thisfile_png_chunk_type_text[
'text'])) {
211 $thisfile_png[
'comments'][$thisfile_png_chunk_type_text[
'keyword']][] = $thisfile_png_chunk_type_text[
'text'];
216 $thisfile_png_chunk_type_text[
'header'] = $chunk;
217 list($keyword, $otherdata) = explode(
"\x00", $chunk[
'data'], 2);
218 $thisfile_png_chunk_type_text[
'keyword'] = $keyword;
219 $thisfile_png_chunk_type_text[
'compression'] = (bool)
Helper::BigEndian2Int(substr($otherdata, 0, 1));
220 $thisfile_png_chunk_type_text[
'compression_method'] =
Helper::BigEndian2Int(substr($otherdata, 1, 1));
221 $thisfile_png_chunk_type_text[
'compression_method_text'] = $this->
PNGcompressionMethodLookup($thisfile_png_chunk_type_text[
'compression_method']);
222 list($languagetag, $translatedkeyword,
$text) = explode(
"\x00", substr($otherdata, 2), 3);
223 $thisfile_png_chunk_type_text[
'language_tag'] = $languagetag;
224 $thisfile_png_chunk_type_text[
'translated_keyword'] = $translatedkeyword;
226 if ($thisfile_png_chunk_type_text[
'compression']) {
228 switch ($thisfile_png_chunk_type_text[
'compression_method']) {
230 $thisfile_png_chunk_type_text[
'text'] = gzuncompress(
$text);
240 $thisfile_png_chunk_type_text[
'text'] =
$text;
244 if (isset($thisfile_png_chunk_type_text[
'text'])) {
245 $thisfile_png[
'comments'][$thisfile_png_chunk_type_text[
'keyword']][] = $thisfile_png_chunk_type_text[
'text'];
250 $thisfile_png_chunk_type_text[
'header'] = $chunk;
251 switch ($thisfile_png[
'IHDR'][
'raw'][
'color_type']) {
259 $thisfile_png_chunk_type_text[
'background_red'] =
Helper::BigEndian2Int(substr($chunk[
'data'], 0 * $thisfile_png[
'IHDR'][
'raw'][
'bit_depth'], $thisfile_png[
'IHDR'][
'raw'][
'bit_depth']));
260 $thisfile_png_chunk_type_text[
'background_green'] =
Helper::BigEndian2Int(substr($chunk[
'data'], 1 * $thisfile_png[
'IHDR'][
'raw'][
'bit_depth'], $thisfile_png[
'IHDR'][
'raw'][
'bit_depth']));
261 $thisfile_png_chunk_type_text[
'background_blue'] =
Helper::BigEndian2Int(substr($chunk[
'data'], 2 * $thisfile_png[
'IHDR'][
'raw'][
'bit_depth'], $thisfile_png[
'IHDR'][
'raw'][
'bit_depth']));
274 $thisfile_png_chunk_type_text[
'header'] = $chunk;
275 $thisfile_png_chunk_type_text[
'pixels_per_unit_x'] =
Helper::BigEndian2Int(substr($chunk[
'data'], 0, 4));
276 $thisfile_png_chunk_type_text[
'pixels_per_unit_y'] =
Helper::BigEndian2Int(substr($chunk[
'data'], 4, 4));
277 $thisfile_png_chunk_type_text[
'unit_specifier'] =
Helper::BigEndian2Int(substr($chunk[
'data'], 8, 1));
278 $thisfile_png_chunk_type_text[
'unit'] = $this->
PNGpHYsUnitLookup($thisfile_png_chunk_type_text[
'unit_specifier']);
282 $thisfile_png_chunk_type_text[
'header'] = $chunk;
283 switch ($thisfile_png[
'IHDR'][
'raw'][
'color_type']) {
285 $thisfile_png_chunk_type_text[
'significant_bits_gray'] =
Helper::BigEndian2Int(substr($chunk[
'data'], 0, 1));
290 $thisfile_png_chunk_type_text[
'significant_bits_red'] =
Helper::BigEndian2Int(substr($chunk[
'data'], 0, 1));
291 $thisfile_png_chunk_type_text[
'significant_bits_green'] =
Helper::BigEndian2Int(substr($chunk[
'data'], 1, 1));
292 $thisfile_png_chunk_type_text[
'significant_bits_blue'] =
Helper::BigEndian2Int(substr($chunk[
'data'], 2, 1));
296 $thisfile_png_chunk_type_text[
'significant_bits_gray'] =
Helper::BigEndian2Int(substr($chunk[
'data'], 0, 1));
297 $thisfile_png_chunk_type_text[
'significant_bits_alpha'] =
Helper::BigEndian2Int(substr($chunk[
'data'], 1, 1));
301 $thisfile_png_chunk_type_text[
'significant_bits_red'] =
Helper::BigEndian2Int(substr($chunk[
'data'], 0, 1));
302 $thisfile_png_chunk_type_text[
'significant_bits_green'] =
Helper::BigEndian2Int(substr($chunk[
'data'], 1, 1));
303 $thisfile_png_chunk_type_text[
'significant_bits_blue'] =
Helper::BigEndian2Int(substr($chunk[
'data'], 2, 1));
304 $thisfile_png_chunk_type_text[
'significant_bits_alpha'] =
Helper::BigEndian2Int(substr($chunk[
'data'], 3, 1));
313 $thisfile_png_chunk_type_text[
'header'] = $chunk;
314 list($palettename, $otherdata) = explode(
"\x00", $chunk[
'data'], 2);
315 $thisfile_png_chunk_type_text[
'palette_name'] = $palettename;
317 $thisfile_png_chunk_type_text[
'sample_depth_bits'] =
Helper::BigEndian2Int(substr($otherdata, $sPLToffset, 1));
319 $thisfile_png_chunk_type_text[
'sample_depth_bytes'] = $thisfile_png_chunk_type_text[
'sample_depth_bits'] / 8;
321 while ($sPLToffset < strlen($otherdata)) {
322 $thisfile_png_chunk_type_text[
'red'][$paletteCounter] =
Helper::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[
'green'][$paletteCounter] =
Helper::BigEndian2Int(substr($otherdata, $sPLToffset, $thisfile_png_chunk_type_text[
'sample_depth_bytes']));
325 $sPLToffset += $thisfile_png_chunk_type_text[
'sample_depth_bytes'];
326 $thisfile_png_chunk_type_text[
'blue'][$paletteCounter] =
Helper::BigEndian2Int(substr($otherdata, $sPLToffset, $thisfile_png_chunk_type_text[
'sample_depth_bytes']));
327 $sPLToffset += $thisfile_png_chunk_type_text[
'sample_depth_bytes'];
328 $thisfile_png_chunk_type_text[
'alpha'][$paletteCounter] =
Helper::BigEndian2Int(substr($otherdata, $sPLToffset, $thisfile_png_chunk_type_text[
'sample_depth_bytes']));
329 $sPLToffset += $thisfile_png_chunk_type_text[
'sample_depth_bytes'];
330 $thisfile_png_chunk_type_text[
'frequency'][$paletteCounter] =
Helper::BigEndian2Int(substr($otherdata, $sPLToffset, 2));
337 $thisfile_png_chunk_type_text[
'header'] = $chunk;
339 while ($hISTcounter < strlen($chunk[
'data'])) {
340 $thisfile_png_chunk_type_text[$hISTcounter] =
Helper::BigEndian2Int(substr($chunk[
'data'], $hISTcounter / 2, 2));
346 $thisfile_png_chunk_type_text[
'header'] = $chunk;
353 $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']);
357 $thisfile_png_chunk_type_text[
'header'] = $chunk;
358 $thisfile_png_chunk_type_text[
'position_x'] =
Helper::BigEndian2Int(substr($chunk[
'data'], 0, 4),
false,
true);
359 $thisfile_png_chunk_type_text[
'position_y'] =
Helper::BigEndian2Int(substr($chunk[
'data'], 4, 4),
false,
true);
360 $thisfile_png_chunk_type_text[
'unit_specifier'] =
Helper::BigEndian2Int(substr($chunk[
'data'], 8, 1));
361 $thisfile_png_chunk_type_text[
'unit'] = $this->
PNGoFFsUnitLookup($thisfile_png_chunk_type_text[
'unit_specifier']);
365 $thisfile_png_chunk_type_text[
'header'] = $chunk;
366 list($calibrationname, $otherdata) = explode(
"\x00", $chunk[
'data'], 2);
367 $thisfile_png_chunk_type_text[
'calibration_name'] = $calibrationname;
369 $thisfile_png_chunk_type_text[
'original_zero'] =
Helper::BigEndian2Int(substr($chunk[
'data'], $pCALoffset, 4),
false,
true);
371 $thisfile_png_chunk_type_text[
'original_max'] =
Helper::BigEndian2Int(substr($chunk[
'data'], $pCALoffset, 4),
false,
true);
373 $thisfile_png_chunk_type_text[
'equation_type'] =
Helper::BigEndian2Int(substr($chunk[
'data'], $pCALoffset, 1));
375 $thisfile_png_chunk_type_text[
'equation_type_text'] = $this->
PNGpCALequationTypeLookup($thisfile_png_chunk_type_text[
'equation_type']);
376 $thisfile_png_chunk_type_text[
'parameter_count'] =
Helper::BigEndian2Int(substr($chunk[
'data'], $pCALoffset, 1));
378 $thisfile_png_chunk_type_text[
'parameters'] = explode(
"\x00", substr($chunk[
'data'], $pCALoffset));
382 $thisfile_png_chunk_type_text[
'header'] = $chunk;
383 $thisfile_png_chunk_type_text[
'unit_specifier'] =
Helper::BigEndian2Int(substr($chunk[
'data'], 0, 1));
384 $thisfile_png_chunk_type_text[
'unit'] = $this->
PNGsCALUnitLookup($thisfile_png_chunk_type_text[
'unit_specifier']);
385 list($pixelwidth, $pixelheight) = explode(
"\x00", substr($chunk[
'data'], 1));
386 $thisfile_png_chunk_type_text[
'pixel_width'] = $pixelwidth;
387 $thisfile_png_chunk_type_text[
'pixel_height'] = $pixelheight;
392 if (isset($thisfile_png_chunk_type_text) && is_array($thisfile_png_chunk_type_text)) {
393 $gIFgCounter = count($thisfile_png_chunk_type_text);
395 $thisfile_png_chunk_type_text[$gIFgCounter][
'header'] = $chunk;
396 $thisfile_png_chunk_type_text[$gIFgCounter][
'disposal_method'] =
Helper::BigEndian2Int(substr($chunk[
'data'], 0, 1));
397 $thisfile_png_chunk_type_text[$gIFgCounter][
'user_input_flag'] =
Helper::BigEndian2Int(substr($chunk[
'data'], 1, 1));
398 $thisfile_png_chunk_type_text[$gIFgCounter][
'delay_time'] =
Helper::BigEndian2Int(substr($chunk[
'data'], 2, 2));
403 if (isset($thisfile_png_chunk_type_text) && is_array($thisfile_png_chunk_type_text)) {
404 $gIFxCounter = count($thisfile_png_chunk_type_text);
406 $thisfile_png_chunk_type_text[$gIFxCounter][
'header'] = $chunk;
407 $thisfile_png_chunk_type_text[$gIFxCounter][
'application_identifier'] = substr($chunk[
'data'], 0, 8);
408 $thisfile_png_chunk_type_text[$gIFxCounter][
'authentication_code'] = substr($chunk[
'data'], 8, 3);
409 $thisfile_png_chunk_type_text[$gIFxCounter][
'application_data'] = substr($chunk[
'data'], 11);
413 $idatinformationfieldindex = 0;
414 if (isset($thisfile_png[
'IDAT']) && is_array($thisfile_png[
'IDAT'])) {
415 $idatinformationfieldindex = count($thisfile_png[
'IDAT']);
417 unset($chunk[
'data']);
418 $thisfile_png_chunk_type_text[$idatinformationfieldindex][
'header'] = $chunk;
422 $thisfile_png_chunk_type_text[
'header'] = $chunk;
427 $thisfile_png_chunk_type_text[
'header'] = $chunk;
428 $info[
'warning'][] =
'Unhandled chunk type: '.$chunk[
'type_text'];
444 static $PNGsRGBintentLookup =
array(
446 1 =>
'Relative colorimetric',
448 3 =>
'Absolute colorimetric' 451 return (isset($PNGsRGBintentLookup[$sRGB]) ? $PNGsRGBintentLookup[$sRGB] :
'invalid');
462 static $PNGcompressionMethodLookup =
array(
463 0 =>
'deflate/inflate' 466 return (isset($PNGcompressionMethodLookup[$compressionmethod]) ? $PNGcompressionMethodLookup[$compressionmethod] :
'invalid');
477 static $PNGpHYsUnitLookup =
array(
482 return (isset($PNGpHYsUnitLookup[$unitid]) ? $PNGpHYsUnitLookup[$unitid] :
'invalid');
493 static $PNGoFFsUnitLookup =
array(
498 return (isset($PNGoFFsUnitLookup[$unitid]) ? $PNGoFFsUnitLookup[$unitid] :
'invalid');
509 static $PNGpCALequationTypeLookup =
array(
510 0 =>
'Linear mapping',
511 1 =>
'Base-e exponential mapping',
512 2 =>
'Arbitrary-base exponential mapping',
513 3 =>
'Hyperbolic mapping' 516 return (isset($PNGpCALequationTypeLookup[$equationtype]) ? $PNGpCALequationTypeLookup[$equationtype] :
'invalid');
527 static $PNGsCALUnitLookup =
array(
532 return (isset($PNGsCALUnitLookup[$unitid]) ? $PNGsCALUnitLookup[$unitid] :
'invalid');
543 switch ($color_type) {
551 return 3 * $bit_depth;
561 return 2 * $bit_depth;
566 return 4 * $bit_depth;
GetId3() by James Heinrich info@getid3.org //.
fseek($bytes, $whence=SEEK_SET)
PNGpCALequationTypeLookup($equationtype)
array $PNGpCALequationTypeLookup
PNGsCALUnitLookup($unitid)
array $PNGsCALUnitLookup
PNGsRGBintentLookup($sRGB)
array $PNGsRGBintentLookup
PNGcompressionMethodLookup($compressionmethod)
array $PNGcompressionMethodLookup
GetId3() by James Heinrich info@getid3.org //.
Create styles array
The data for the language used.
PNGpHYsUnitLookup($unitid)
array $PNGpHYsUnitLookup
static BigEndian2Int($byteword, $synchsafe=false, $signed=false)
IHDRcalculateBitsPerSample($color_type, $bit_depth)
PNGoFFsUnitLookup($unitid)
array $PNGoFFsUnitLookup