+ $data = substr($data, 12);
+ if (substr($data, 0, 4) != 'IHDR') {
+ $this->_push_error(6011, 'IHDR chunk missing');
+ return false;
+ }
+ $data = substr($data, 4);
+ $width = $this->_int_val(substr($data, 0, 4));
+ $height = $this->_int_val(substr($data, 4, 4));
+ $data = substr($data, 8);
+ $bpc = ord(substr($data, 0, 1));
+ $ct = ord(substr($data, 1, 1));
+ if ($bpc > 8) {
+ $this->_push_error(6014, '16 bit PNG unsupported');
+ return false;
+ }
+ switch ($ct) {
+ case 0 : $cspace = '/DeviceGray'; break;
+ case 2 : $cspace = '/DeviceRGB'; break;
+ case 3 : $cspace = '/Indexed'; break;
+ default:
+ $this->_push_error(6015, 'PNG with alpha not supported');
+ return false;
+ }
+ if (ord(substr($data, 2, 1)) != 0) {
+ $this->_push_error(6016, 'Unknown compression type');
+ return false;
+ }
+ if (ord(substr($data, 3, 1)) != 0) {
+ $this->_push_error(6017, 'Unknown PNG filter method');
+ return false;
+ }
+ if (ord(substr($data, 4, 1)) != 0) {
+ $this->_push_error(6018, 'PNG interlacing not supported');
+ return false;
+ }
+ $params['Predictor'] = '15';
+ $params['Colors'] = $ct == 2 ? 3 : 1;
+ $params['BitsPerComponent'] = $bpc;
+ $params['Columns'] = $width;
+ $additional['DecodeParms'] = $this->_makedictionary($params);
+ $data = substr($data, 9);
+ $pal = '';
+ $trns = '';
+ $rawdata = '';
+ do {
+ $n = $this->_int_val(substr($data, 0, 4));
+ $type = substr($data, 4, 4);
+ $data = substr($data, 8);
+ switch ($type) {
+ case 'PLTE' :
+ $pal = substr($data, 0, $n);
+ $data = substr($data, $n + 4);
+ break;
+
+ case 'tRNS' :
+ $t = substr($data, 0, $n);
+ if ($ct == 0)
+ $trns = array(ord(substr($t, 1, 1)));
+ elseif ($ct == 2)
+ $trns = array(ord(substr($t, 1, 1)),
+ ord(substr($t, 3, 1)),
+ ord(substr($t, 5, 1)));
+ else {
+ $pos = strpos($t, chr(0));
+ if (is_int($pos))
+ $trns = array($pos);
+ }
+ $data = substr($data, $n + 4);
+ break;
+
+ case 'IDAT' :
+ $rawdata .= substr($data, 0, $n);
+ $data = substr($data, $n + 4);
+ break;
+
+ case 'IEND' :
+ break 2;
+
+ default :
+ $data = substr($data, $n + 4);
+ }
+ } while ($n);
+ if ($cspace == '/Indexed') {
+ $this->_push_error(6011, 'Indexed without palette');
+ return false;
+ }
+ return $this->image_raw_embed($rawdata,
+ $cspace,
+ $bpc,
+ $height,
+ $width,
+ '/FlateDecode',
+ $additional);