'; echo 'Full File URL: ' .$file . '
'; if ($orig_srcpath && $fileIsLocal && $check = @fopen($orig_srcpath,"rb")) { fclose($check); $file=$orig_srcpath; $data = file_get_contents($file); $type = _imageTypeFromString($data); echo 'File accessed using fopen on $orig_srcpath' . '
'; } if (!$data && $check = @fopen($file,"rb")) { fclose($check); $data = file_get_contents($file); $type = _imageTypeFromString($data); echo 'File accessed using fopen on $file' . '
'; } if ((!$data || !$type) && !ini_get('allow_url_fopen') ) { // only worth trying if remote file and !ini_get('allow_url_fopen') file_get_contents_by_socket($file, $data); // needs full url?? even on local (never needed for local) if ($data) { $type = _imageTypeFromString($data); } echo 'File accessed using socket ' . '
'; } if ((!$data || !$type) && !ini_get('allow_url_fopen') && function_exists("curl_init")) { file_get_contents_by_curl($file, $data); // needs full url?? even on local (never needed for local) if ($data) { $type = _imageTypeFromString($data); } echo 'File accessed using cURL ' . '
'; } if (!$data) { echo 'Could not access image file' . '
'; exit; } echo 'Image type determined: ' .strtoupper($type) . '
'; // JPEG if ($type == 'jpeg' || $type == 'jpg') { $hdr = _jpgHeaderFromString($data); if (!$hdr) { echo 'Error parsing JPG header' . '
'; exit; } $a = _jpgDataFromHeader($hdr); $channels = intval($a[4]); echo 'Width: ' . $a[0]. '
'; echo 'Height: ' . $a[1]. '
'; echo 'Colorspace: ' . $a[2]. '
'; echo 'BPC (bits per channel): ' . $a[3]. '
'; echo 'Channels: ' . $channels. '
'; $j = strpos($data,'JFIF'); if ($j) { //Read resolution $unitSp=ord(substr($data,($j+7),1)); if ($unitSp > 0) { $ppUx=_twobytes2int(substr($data,($j+8),2)); // horizontal pixels per meter, usually set to zero if ($unitSp == 2) { // = dots per cm (if == 1 set as dpi) $ppUx=round($ppUx/10 *25.4); } } echo 'Resolution ppUx: ' . $ppUx. '
'; } else echo 'JFIF not found in header' . '
'; // mPDF 6 ICC profile $offset = 0; $icc = array(); while (($pos = strpos($data, "ICC_PROFILE\0", $offset)) !== false) { // get ICC sequence length $length = _twobytes2int(substr($data, ($pos - 2),2)) - 16; $sn = max(1, ord($data[($pos + 12)])); $nom = max(1, ord($data[($pos + 13)])); $icc[($sn - 1)] = substr($data, ($pos + 14), $length); $offset = ($pos + 14 + $length); } // order and compact ICC segments if (count($icc) > 0) { echo 'ICC profile present' . '
'; ksort($icc); $icc = implode('', $icc); if (substr($icc, 36, 4) != 'acsp') { // invalid ICC profile echo 'ICC profile INVALID (no acsp flag)' . '
'; } $input = substr($icc, 16, 4); $output = substr($icc, 20, 4); echo 'ICC profile Input: ' . $input. '
'; echo 'ICC profile Output: ' . $output. '
'; // Ignore Color profiles for conversion to other colorspaces e.g. CMYK/Lab if ($input != 'RGB ' || $output != 'XYZ ') { echo 'ICC profile ignored by mPDF' . '
'; } } } // PNG else if ($type == 'png') { //Check signature if(substr($data,0,8)!=chr(137).'PNG'.chr(13).chr(10).chr(26).chr(10)) { echo 'Error parsing PNG identifier
'; exit; } //Read header chunk if(substr($data,12,4)!='IHDR') { echo 'Incorrect PNG file (no IHDR block found)
'; exit; } $w=_fourbytes2int(substr($data,16,4)); $h=_fourbytes2int(substr($data,20,4)); $bpc=ord(substr($data,24,1)); $errpng = false; $pngalpha = false; $channels = 0; echo 'Width: ' .$w . '
'; echo 'Height: ' .$h . '
'; echo 'BPC (bits per channel): ' .$bpc . '
'; $ct=ord(substr($data,25,1)); if($ct==0) { $colspace='DeviceGray'; $channels = 1; } elseif($ct==2) { $colspace='DeviceRGB'; $channels = 3; } elseif($ct==3) { $colspace='Indexed'; $channels = 1; } elseif($ct==4) { $colspace='DeviceGray'; $channels = 1; $errpng = 'alpha channel'; $pngalpha = true; } else { $colspace='DeviceRGB'; $channels = 3; $errpng = 'alpha channel'; $pngalpha = true; } echo 'Colorspace: ' . $colspace. '
'; echo 'Channels: ' . $channels. '
'; if ($pngalpha) echo 'Alpha channel detected'. '
'; if ($ct < 4 && strpos($data,'tRNS')!==false) { echo 'Transparency detected'. '
'; $errpng = 'transparency'; $pngalpha = true;} if ($ct == 3 && strpos($data,'iCCP')!==false) { echo 'Indexed plus ICC'. '
'; $errpng = 'indexed plus ICC'; } if(ord(substr($data,26,1))!=0) { echo 'compression method not set to zero
'; $errpng = 'compression method'; } // only 0 should be specified if(ord(substr($data,27,1))!=0) { echo 'filter method not set to zero
'; $errpng = 'filter method'; } // only 0 should be specified if(ord(substr($data,28,1))!=0) { echo 'interlaced file not set to zero
'; $errpng = 'interlaced file'; } $j = strpos($data,'pHYs'); if ($j) { //Read resolution $unitSp=ord(substr($data,($j+12),1)); if ($unitSp == 1) { $ppUx=_fourbytes2int(substr($data,($j+4),4)); // horizontal pixels per meter, usually set to zero $ppUx=round($ppUx/1000 *25.4); } echo 'Resolution ppUx: ' . $ppUx. '
'; } // mPDF 6 Gamma correction $gamma_correction = 0; $gAMA = 0; $j = strpos($data,'gAMA'); if ($j && strpos($data,'sRGB')===false) { // sRGB colorspace - overrides gAMA $gAMA=_fourbytes2int(substr($data,($j+4),4)); // Gamma value times 100000 $gAMA /= 100000; } if ($gAMA) { $gamma_correction = 1/$gAMA; } // Don't need to apply gamma correction if == default i.e. 2.2 if ($gamma_correction > 2.15 && $gamma_correction < 2.25) { $gamma_correction = 0; } if ($gamma_correction) { echo 'Gamma correction detected'. '
'; } // NOT supported at present if (strpos($data,'sRGB')!==false) echo 'sRGB colorspace - NOT supported at present'. '
'; if (strpos($data,'cHRM')!==false) echo 'Chromaticity and Whitepoint - NOT supported at present'. '
'; if (($errpng || $pngalpha || $gamma_correction)) { if (function_exists('gd_info')) { $gd = gd_info(); } else {$gd = array(); } if (!isset($gd['PNG Support'])) { echo 'GD library required for PNG image ('.$errpng.')'. '
';} $im = imagecreatefromstring($data); if (!$im) { echo 'Error creating GD image from PNG file ('.$errpng.')'. '
';} $w = imagesx($im); $h = imagesy($im); if ($im) { // Alpha channel set (including using tRNS for Paletted images) if ($pngalpha) { echo 'Alpha channel will be used by mPDF (including when tRNS present in Paletted images)
'; if ($colspace=='Indexed') { echo '...Generating Alpha channel values from tRNS (Indexed)
'; } else if ($ct===0 || $ct==2) { echo '...Generating Alpha channel values from tRNS (non-Indexed)
'; } else { echo '...Extracting Alpha channel
'; } } else { // No alpha/transparency set (but cannot read directly because e.g. bit-depth != 8, interlaced etc) echo 'No alpha/transparency set (but cannot read directly because e.g. bit-depth != 8, interlaced etc)
'; // ICC profile $icc = false; $p = strpos($data,'iCCP'); if ($p && $colspace=="Indexed") { $p += 4; $n=_fourbytes2int(substr($data,($p-8),4)); $nullsep = strpos(substr($data,$p,80), chr(0)); $icc = substr($data, ($p+$nullsep+2), ($n-($nullsep+2)) ); // Test if file is gzcompressed if (ord(substr($str, 0, 1)) == 0x1f && ord(substr($str, 1, 1)) == 0x8b) { $icc = @gzuncompress($icc); // Ignored if fails } if ($icc) { echo 'ICC profile present' . '
'; if (substr($icc, 36, 4) != 'acsp') { echo 'ICC profile INVALID (no acsp flag)' . '
'; $icc = false; } // invalid ICC profile else { $input = substr($icc, 16, 4); $output = substr($icc, 20, 4); echo 'ICC profile Input: ' . $input. '
'; echo 'ICC profile Output: ' . $output. '
'; // Ignore Color profiles for conversion to other colorspaces e.g. CMYK/Lab if ($input != 'RGB ' || $output != 'XYZ ') { $icc = false; echo 'ICC profile ignored by mPDF' . '
'; } } } // Convert to RGB colorspace so can use ICC Profile if ($icc) { echo 'ICC profile and Indexed colorspace both present - need to Convert to RGB colorspace so can use ICC Profile
'; } } } } echo 'PNG Image parsed on second pass' . '
'; // SECOND PASS imagealphablending($im, false); imagesavealpha($im, false); imageinterlace($im, false); ob_start(); $check = @imagepng($im); if (!$check) { echo 'Error creating temporary image object whilst using GD library to parse PNG image' . '
'; } $data = ob_get_contents(); ob_end_clean(); if (!$data) { echo 'Error parsing temporary file image object created with GD library to parse PNG image' . '
'; } imagedestroy($im); //Check signature if(substr($data,0,8)!=chr(137).'PNG'.chr(13).chr(10).chr(26).chr(10)) { echo 'Error parsing PNG identifier
'; exit; } //Read header chunk if(substr($data,12,4)!='IHDR') { echo 'Incorrect PNG file (no IHDR block found)
'; exit; } $w=_fourbytes2int(substr($data,16,4)); $h=_fourbytes2int(substr($data,20,4)); $bpc=ord(substr($data,24,1)); $errpng = false; $pngalpha = false; $channels = 0; echo 'Width: ' .$w . '
'; echo 'Height: ' .$h . '
'; echo 'BPC (bits per channel): ' .$bpc . '
'; $ct=ord(substr($data,25,1)); if($ct==0) { $colspace='DeviceGray'; $channels = 1; } elseif($ct==2) { $colspace='DeviceRGB'; $channels = 3; } elseif($ct==3) { $colspace='Indexed'; $channels = 1; } elseif($ct==4) { $colspace='DeviceGray'; $channels = 1; $errpng = 'alpha channel'; $pngalpha = true; } else { $colspace='DeviceRGB'; $channels = 3; $errpng = 'alpha channel'; $pngalpha = true; } echo 'Colorspace: ' . $colspace. '
'; echo 'Channels: ' . $channels. '
'; if ($pngalpha) echo 'Alpha channel detected'. '
'; if ($ct < 4 && strpos($data,'tRNS')!==false) { echo 'Transparency detected'. '
'; $errpng = 'transparency'; $pngalpha = true;} if ($ct == 3 && strpos($data,'iCCP')!==false) { echo 'Indexed plus ICC'. '
'; $errpng = 'indexed plus ICC'; } if(ord(substr($data,26,1))!=0) { echo 'compression method not set to zero
'; $errpng = 'compression method'; } // only 0 should be specified if(ord(substr($data,27,1))!=0) { echo 'filter method not set to zero
'; $errpng = 'filter method'; } // only 0 should be specified if(ord(substr($data,28,1))!=0) { echo 'interlaced file not set to zero
'; $errpng = 'interlaced file'; } $j = strpos($data,'pHYs'); if ($j) { //Read resolution $unitSp=ord(substr($data,($j+12),1)); if ($unitSp == 1) { $ppUx=_fourbytes2int(substr($data,($j+4),4)); // horizontal pixels per meter, usually set to zero $ppUx=round($ppUx/1000 *25.4); } echo 'Resolution ppUx: ' . $ppUx. '
'; } //Gamma correction $gamma_correction = 0; $gAMA = 0; $j = strpos($data,'gAMA'); if ($j && strpos($data,'sRGB')===false) { // sRGB colorspace - overrides gAMA $gAMA=_fourbytes2int(substr($data,($j+4),4)); // Gamma value times 100000 $gAMA /= 100000; } if ($gAMA) { $gamma_correction = 1/$gAMA; } // Don't need to apply gamma correction if == default i.e. 2.2 if ($gamma_correction > 2.15 && $gamma_correction < 2.25) { $gamma_correction = 0; } if ($gamma_correction) { echo 'Gamma correction detected'. '
'; } // NOT supported at present if (strpos($data,'sRGB')!==false) echo 'sRGB colorspace - NOT supported at present'. '
'; if (strpos($data,'cHRM')!==false) echo 'Chromaticity and Whitepoint - NOT supported at present'. '
'; } else { // PNG image with no need to convert alpha channels, bpc <> 8 etc. //Scan chunks looking for palette, transparency and image data $pal=''; $trns=''; $pngdata=''; $icc = false; $p = 33; do { $n=_fourbytes2int(substr($data,$p,4)); $p += 4; $type=substr($data,$p,4); $p += 4; if ($type=='PLTE') { //Read palette $pal=substr($data,$p,$n); $p += $n; $p += 4; } else if($type=='tRNS') { //Read transparency info $t=substr($data,$p,$n); $p += $n; if ($ct==0) $trns=array(ord(substr($t,1,1))); else if ($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); } $p += 4; } else if ($type=='IDAT') { $pngdata.=substr($data,$p,$n); $p += $n; $p += 4; } else if ($type=='iCCP') { $nullsep = strpos(substr($data,$p,80), chr(0)); $icc = substr($data, ($p+$nullsep+2), ($n-($nullsep+2)) ); // Test if file is gzcompressed if (ord(substr($str, 0, 1)) == 0x1f && ord(substr($str, 1, 1)) == 0x8b) { $icc = @gzuncompress($icc); // Ignored if fails } if ($icc) { echo 'ICC profile present' . '
'; if (substr($icc, 36, 4) != 'acsp') { echo 'ICC profile INVALID (no acsp flag)' . '
'; $icc = false; } // invalid ICC profile else { $input = substr($icc, 16, 4); $output = substr($icc, 20, 4); echo 'ICC profile Input: ' . $input. '
'; echo 'ICC profile Output: ' . $output. '
'; // Ignore Color profiles for conversion to other colorspaces e.g. CMYK/Lab if ($input != 'RGB ' || $output != 'XYZ ') { $icc = false; echo 'ICC profile ignored by mPDF' . '
'; } } } $p += $n; $p += 4; } else if($type=='IEND') { break; } else if (preg_match('/[a-zA-Z]{4}/',$type)) { $p += $n+4; } else { echo 'Error parsing PNG image data
'; } } while($n); if (!$pngdata) { echo 'Error parsing PNG image data - no IDAT data found
';} if ($colspace=='Indexed' && empty($pal)) { echo 'Error parsing PNG image data - missing colour palette
'; } echo 'PNG Image parsed directly' . '
'; } } // GIF else if ($type == 'gif') { } // BMP (Windows Bitmap) else if ($type == 'bmp') { } // WMF else if ($type == 'wmf') { } // UNKNOWN TYPE - try GD imagecreatefromstring else { if (function_exists('gd_info')) { $gd = gd_info(); } else {$gd = array(); } if (isset($gd['PNG Support']) && $gd['PNG Support']) { $im = @imagecreatefromstring($data); if ($im) { echo 'Image type not recognised, but image created from file using GD imagecreate' . '
'; } else { echo 'Error parsing image file - image type not recognised, and not supported by GD imagecreate' . '
'; } } } exit; //============================================================== function _fourbytes2int($s) { //Read a 4-byte integer from string return (ord($s[0])<<24) + (ord($s[1])<<16) + (ord($s[2])<<8) + ord($s[3]); } function _twobytes2int($s) { // equivalent to _get_ushort //Read a 2-byte integer from string return (ord(substr($s, 0, 1))<<8) + ord(substr($s, 1, 1)); } function _jpgHeaderFromString(&$data) { $p = 4; $p += _twobytes2int(substr($data, $p, 2)); // Length of initial marker block $marker = substr($data, $p, 2); while($marker != chr(255).chr(192) && $marker != chr(255).chr(194) && $p/is',$data)) { $type = 'svg'; } // BMP images else if (substr($data, 0, 2)== "BM") { $type = 'bmp'; } return $type; }