image_details.php 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520
  1. <?php
  2. $orig_srcpath='../tests/tiger.png'; // as specified in your file (could be full URL)
  3. $file = 'http://127.0.0.1/MPDF1.com/common/mpdf/tests/tiger.png'; // Full URL
  4. $fileIsLocal = true; // is the file in the same domain?
  5. //======================================================================
  6. $ppUx = 0;
  7. $type = '';
  8. $data = '';
  9. echo 'File: ' .$orig_srcpath . '<br />';
  10. echo 'Full File URL: ' .$file . '<br />';
  11. if ($orig_srcpath && $fileIsLocal && $check = @fopen($orig_srcpath,"rb")) {
  12. fclose($check);
  13. $file=$orig_srcpath;
  14. $data = file_get_contents($file);
  15. $type = _imageTypeFromString($data);
  16. echo 'File accessed using fopen on $orig_srcpath' . '<br />';
  17. }
  18. if (!$data && $check = @fopen($file,"rb")) {
  19. fclose($check);
  20. $data = file_get_contents($file);
  21. $type = _imageTypeFromString($data);
  22. echo 'File accessed using fopen on $file' . '<br />';
  23. }
  24. if ((!$data || !$type) && !ini_get('allow_url_fopen') ) { // only worth trying if remote file and !ini_get('allow_url_fopen')
  25. file_get_contents_by_socket($file, $data); // needs full url?? even on local (never needed for local)
  26. if ($data) { $type = _imageTypeFromString($data); }
  27. echo 'File accessed using socket ' . '<br />';
  28. }
  29. if ((!$data || !$type) && !ini_get('allow_url_fopen') && function_exists("curl_init")) {
  30. file_get_contents_by_curl($file, $data); // needs full url?? even on local (never needed for local)
  31. if ($data) { $type = _imageTypeFromString($data); }
  32. echo 'File accessed using cURL ' . '<br />';
  33. }
  34. if (!$data) { echo 'Could not access image file' . '<br />'; exit; }
  35. echo 'Image type determined: ' .strtoupper($type) . '<br />';
  36. // JPEG
  37. if ($type == 'jpeg' || $type == 'jpg') {
  38. $hdr = _jpgHeaderFromString($data);
  39. if (!$hdr) { echo 'Error parsing JPG header' . '<br />'; exit; }
  40. $a = _jpgDataFromHeader($hdr);
  41. $channels = intval($a[4]);
  42. echo 'Width: ' . $a[0]. '<br />';
  43. echo 'Height: ' . $a[1]. '<br />';
  44. echo 'Colorspace: ' . $a[2]. '<br />';
  45. echo 'BPC (bits per channel): ' . $a[3]. '<br />';
  46. echo 'Channels: ' . $channels. '<br />';
  47. $j = strpos($data,'JFIF');
  48. if ($j) {
  49. //Read resolution
  50. $unitSp=ord(substr($data,($j+7),1));
  51. if ($unitSp > 0) {
  52. $ppUx=_twobytes2int(substr($data,($j+8),2)); // horizontal pixels per meter, usually set to zero
  53. if ($unitSp == 2) { // = dots per cm (if == 1 set as dpi)
  54. $ppUx=round($ppUx/10 *25.4);
  55. }
  56. }
  57. echo 'Resolution ppUx: ' . $ppUx. '<br />';
  58. }
  59. else echo 'JFIF not found in header' . '<br />';
  60. // mPDF 6 ICC profile
  61. $offset = 0;
  62. $icc = array();
  63. while (($pos = strpos($data, "ICC_PROFILE\0", $offset)) !== false) {
  64. // get ICC sequence length
  65. $length = _twobytes2int(substr($data, ($pos - 2),2)) - 16;
  66. $sn = max(1, ord($data[($pos + 12)]));
  67. $nom = max(1, ord($data[($pos + 13)]));
  68. $icc[($sn - 1)] = substr($data, ($pos + 14), $length);
  69. $offset = ($pos + 14 + $length);
  70. }
  71. // order and compact ICC segments
  72. if (count($icc) > 0) {
  73. echo 'ICC profile present' . '<br />';
  74. ksort($icc);
  75. $icc = implode('', $icc);
  76. if (substr($icc, 36, 4) != 'acsp') {
  77. // invalid ICC profile
  78. echo 'ICC profile INVALID (no acsp flag)' . '<br />';
  79. }
  80. $input = substr($icc, 16, 4);
  81. $output = substr($icc, 20, 4);
  82. echo 'ICC profile Input: ' . $input. '<br />';
  83. echo 'ICC profile Output: ' . $output. '<br />';
  84. // Ignore Color profiles for conversion to other colorspaces e.g. CMYK/Lab
  85. if ($input != 'RGB ' || $output != 'XYZ ') { echo 'ICC profile ignored by mPDF' . '<br />'; }
  86. }
  87. }
  88. // PNG
  89. else if ($type == 'png') {
  90. //Check signature
  91. if(substr($data,0,8)!=chr(137).'PNG'.chr(13).chr(10).chr(26).chr(10)) {
  92. echo 'Error parsing PNG identifier<br />'; exit;
  93. }
  94. //Read header chunk
  95. if(substr($data,12,4)!='IHDR') {
  96. echo 'Incorrect PNG file (no IHDR block found)<br />'; exit;
  97. }
  98. $w=_fourbytes2int(substr($data,16,4));
  99. $h=_fourbytes2int(substr($data,20,4));
  100. $bpc=ord(substr($data,24,1));
  101. $errpng = false;
  102. $pngalpha = false;
  103. $channels = 0;
  104. echo 'Width: ' .$w . '<br />';
  105. echo 'Height: ' .$h . '<br />';
  106. echo 'BPC (bits per channel): ' .$bpc . '<br />';
  107. $ct=ord(substr($data,25,1));
  108. if($ct==0) { $colspace='DeviceGray'; $channels = 1; }
  109. elseif($ct==2) { $colspace='DeviceRGB'; $channels = 3; }
  110. elseif($ct==3) { $colspace='Indexed'; $channels = 1; }
  111. elseif($ct==4) { $colspace='DeviceGray'; $channels = 1; $errpng = 'alpha channel'; $pngalpha = true; }
  112. else { $colspace='DeviceRGB'; $channels = 3; $errpng = 'alpha channel'; $pngalpha = true; }
  113. echo 'Colorspace: ' . $colspace. '<br />';
  114. echo 'Channels: ' . $channels. '<br />';
  115. if ($pngalpha) echo 'Alpha channel detected'. '<br />';
  116. if ($ct < 4 && strpos($data,'tRNS')!==false) { echo 'Transparency detected'. '<br />'; $errpng = 'transparency'; $pngalpha = true;}
  117. if ($ct == 3 && strpos($data,'iCCP')!==false) { echo 'Indexed plus ICC'. '<br />'; $errpng = 'indexed plus ICC'; }
  118. if(ord(substr($data,26,1))!=0) { echo 'compression method not set to zero<br />'; $errpng = 'compression method'; } // only 0 should be specified
  119. if(ord(substr($data,27,1))!=0) { echo 'filter method not set to zero<br />'; $errpng = 'filter method'; } // only 0 should be specified
  120. if(ord(substr($data,28,1))!=0) { echo 'interlaced file not set to zero<br />'; $errpng = 'interlaced file'; }
  121. $j = strpos($data,'pHYs');
  122. if ($j) {
  123. //Read resolution
  124. $unitSp=ord(substr($data,($j+12),1));
  125. if ($unitSp == 1) {
  126. $ppUx=_fourbytes2int(substr($data,($j+4),4)); // horizontal pixels per meter, usually set to zero
  127. $ppUx=round($ppUx/1000 *25.4);
  128. }
  129. echo 'Resolution ppUx: ' . $ppUx. '<br />';
  130. }
  131. // mPDF 6 Gamma correction
  132. $gamma_correction = 0;
  133. $gAMA = 0;
  134. $j = strpos($data,'gAMA');
  135. if ($j && strpos($data,'sRGB')===false) { // sRGB colorspace - overrides gAMA
  136. $gAMA=_fourbytes2int(substr($data,($j+4),4)); // Gamma value times 100000
  137. $gAMA /= 100000;
  138. }
  139. if ($gAMA) { $gamma_correction = 1/$gAMA; }
  140. // Don't need to apply gamma correction if == default i.e. 2.2
  141. if ($gamma_correction > 2.15 && $gamma_correction < 2.25) { $gamma_correction = 0; }
  142. if ($gamma_correction) { echo 'Gamma correction detected'. '<br />'; }
  143. // NOT supported at present
  144. if (strpos($data,'sRGB')!==false) echo 'sRGB colorspace - NOT supported at present'. '<br />';
  145. if (strpos($data,'cHRM')!==false) echo 'Chromaticity and Whitepoint - NOT supported at present'. '<br />';
  146. if (($errpng || $pngalpha || $gamma_correction)) {
  147. if (function_exists('gd_info')) { $gd = gd_info(); }
  148. else {$gd = array(); }
  149. if (!isset($gd['PNG Support'])) { echo 'GD library required for PNG image ('.$errpng.')'. '<br />';}
  150. $im = imagecreatefromstring($data);
  151. if (!$im) { echo 'Error creating GD image from PNG file ('.$errpng.')'. '<br />';}
  152. $w = imagesx($im);
  153. $h = imagesy($im);
  154. if ($im) {
  155. // Alpha channel set (including using tRNS for Paletted images)
  156. if ($pngalpha) {
  157. echo 'Alpha channel will be used by mPDF (including when tRNS present in Paletted images)<br />';
  158. if ($colspace=='Indexed') { echo '...Generating Alpha channel values from tRNS (Indexed)<br />'; }
  159. else if ($ct===0 || $ct==2) { echo '...Generating Alpha channel values from tRNS (non-Indexed)<br />'; }
  160. else { echo '...Extracting Alpha channel<br />'; }
  161. }
  162. else { // No alpha/transparency set (but cannot read directly because e.g. bit-depth != 8, interlaced etc)
  163. echo 'No alpha/transparency set (but cannot read directly because e.g. bit-depth != 8, interlaced etc)<br />';
  164. // ICC profile
  165. $icc = false;
  166. $p = strpos($data,'iCCP');
  167. if ($p && $colspace=="Indexed") {
  168. $p += 4;
  169. $n=_fourbytes2int(substr($data,($p-8),4));
  170. $nullsep = strpos(substr($data,$p,80), chr(0));
  171. $icc = substr($data, ($p+$nullsep+2), ($n-($nullsep+2)) );
  172. // Test if file is gzcompressed
  173. if (ord(substr($str, 0, 1)) == 0x1f && ord(substr($str, 1, 1)) == 0x8b) {
  174. $icc = @gzuncompress($icc); // Ignored if fails
  175. }
  176. if ($icc) {
  177. echo 'ICC profile present' . '<br />';
  178. if (substr($icc, 36, 4) != 'acsp') { echo 'ICC profile INVALID (no acsp flag)' . '<br />'; $icc = false; } // invalid ICC profile
  179. else {
  180. $input = substr($icc, 16, 4);
  181. $output = substr($icc, 20, 4);
  182. echo 'ICC profile Input: ' . $input. '<br />';
  183. echo 'ICC profile Output: ' . $output. '<br />';
  184. // Ignore Color profiles for conversion to other colorspaces e.g. CMYK/Lab
  185. if ($input != 'RGB ' || $output != 'XYZ ') { $icc = false; echo 'ICC profile ignored by mPDF' . '<br />'; }
  186. }
  187. }
  188. // Convert to RGB colorspace so can use ICC Profile
  189. if ($icc) { echo 'ICC profile and Indexed colorspace both present - need to Convert to RGB colorspace so can use ICC Profile<br />'; }
  190. }
  191. }
  192. }
  193. echo 'PNG Image parsed on second pass' . '<br />';
  194. // SECOND PASS
  195. imagealphablending($im, false);
  196. imagesavealpha($im, false);
  197. imageinterlace($im, false);
  198. ob_start();
  199. $check = @imagepng($im);
  200. if (!$check) { echo 'Error creating temporary image object whilst using GD library to parse PNG image' . '<br />'; }
  201. $data = ob_get_contents();
  202. ob_end_clean();
  203. if (!$data) { echo 'Error parsing temporary file image object created with GD library to parse PNG image' . '<br />'; }
  204. imagedestroy($im);
  205. //Check signature
  206. if(substr($data,0,8)!=chr(137).'PNG'.chr(13).chr(10).chr(26).chr(10)) {
  207. echo 'Error parsing PNG identifier<br />'; exit;
  208. }
  209. //Read header chunk
  210. if(substr($data,12,4)!='IHDR') {
  211. echo 'Incorrect PNG file (no IHDR block found)<br />'; exit;
  212. }
  213. $w=_fourbytes2int(substr($data,16,4));
  214. $h=_fourbytes2int(substr($data,20,4));
  215. $bpc=ord(substr($data,24,1));
  216. $errpng = false;
  217. $pngalpha = false;
  218. $channels = 0;
  219. echo 'Width: ' .$w . '<br />';
  220. echo 'Height: ' .$h . '<br />';
  221. echo 'BPC (bits per channel): ' .$bpc . '<br />';
  222. $ct=ord(substr($data,25,1));
  223. if($ct==0) { $colspace='DeviceGray'; $channels = 1; }
  224. elseif($ct==2) { $colspace='DeviceRGB'; $channels = 3; }
  225. elseif($ct==3) { $colspace='Indexed'; $channels = 1; }
  226. elseif($ct==4) { $colspace='DeviceGray'; $channels = 1; $errpng = 'alpha channel'; $pngalpha = true; }
  227. else { $colspace='DeviceRGB'; $channels = 3; $errpng = 'alpha channel'; $pngalpha = true; }
  228. echo 'Colorspace: ' . $colspace. '<br />';
  229. echo 'Channels: ' . $channels. '<br />';
  230. if ($pngalpha) echo 'Alpha channel detected'. '<br />';
  231. if ($ct < 4 && strpos($data,'tRNS')!==false) { echo 'Transparency detected'. '<br />'; $errpng = 'transparency'; $pngalpha = true;}
  232. if ($ct == 3 && strpos($data,'iCCP')!==false) { echo 'Indexed plus ICC'. '<br />'; $errpng = 'indexed plus ICC'; }
  233. if(ord(substr($data,26,1))!=0) { echo 'compression method not set to zero<br />'; $errpng = 'compression method'; } // only 0 should be specified
  234. if(ord(substr($data,27,1))!=0) { echo 'filter method not set to zero<br />'; $errpng = 'filter method'; } // only 0 should be specified
  235. if(ord(substr($data,28,1))!=0) { echo 'interlaced file not set to zero<br />'; $errpng = 'interlaced file'; }
  236. $j = strpos($data,'pHYs');
  237. if ($j) {
  238. //Read resolution
  239. $unitSp=ord(substr($data,($j+12),1));
  240. if ($unitSp == 1) {
  241. $ppUx=_fourbytes2int(substr($data,($j+4),4)); // horizontal pixels per meter, usually set to zero
  242. $ppUx=round($ppUx/1000 *25.4);
  243. }
  244. echo 'Resolution ppUx: ' . $ppUx. '<br />';
  245. }
  246. //Gamma correction
  247. $gamma_correction = 0;
  248. $gAMA = 0;
  249. $j = strpos($data,'gAMA');
  250. if ($j && strpos($data,'sRGB')===false) { // sRGB colorspace - overrides gAMA
  251. $gAMA=_fourbytes2int(substr($data,($j+4),4)); // Gamma value times 100000
  252. $gAMA /= 100000;
  253. }
  254. if ($gAMA) { $gamma_correction = 1/$gAMA; }
  255. // Don't need to apply gamma correction if == default i.e. 2.2
  256. if ($gamma_correction > 2.15 && $gamma_correction < 2.25) { $gamma_correction = 0; }
  257. if ($gamma_correction) { echo 'Gamma correction detected'. '<br />'; }
  258. // NOT supported at present
  259. if (strpos($data,'sRGB')!==false) echo 'sRGB colorspace - NOT supported at present'. '<br />';
  260. if (strpos($data,'cHRM')!==false) echo 'Chromaticity and Whitepoint - NOT supported at present'. '<br />';
  261. }
  262. else { // PNG image with no need to convert alpha channels, bpc <> 8 etc.
  263. //Scan chunks looking for palette, transparency and image data
  264. $pal='';
  265. $trns='';
  266. $pngdata='';
  267. $icc = false;
  268. $p = 33;
  269. do {
  270. $n=_fourbytes2int(substr($data,$p,4)); $p += 4;
  271. $type=substr($data,$p,4); $p += 4;
  272. if ($type=='PLTE') {
  273. //Read palette
  274. $pal=substr($data,$p,$n); $p += $n;
  275. $p += 4;
  276. }
  277. else if($type=='tRNS') {
  278. //Read transparency info
  279. $t=substr($data,$p,$n); $p += $n;
  280. if ($ct==0) $trns=array(ord(substr($t,1,1)));
  281. else if ($ct==2) $trns=array(ord(substr($t,1,1)),ord(substr($t,3,1)),ord(substr($t,5,1)));
  282. else {
  283. $pos=strpos($t,chr(0));
  284. if(is_int($pos)) $trns=array($pos);
  285. }
  286. $p += 4;
  287. }
  288. else if ($type=='IDAT') {
  289. $pngdata.=substr($data,$p,$n); $p += $n;
  290. $p += 4;
  291. }
  292. else if ($type=='iCCP') {
  293. $nullsep = strpos(substr($data,$p,80), chr(0));
  294. $icc = substr($data, ($p+$nullsep+2), ($n-($nullsep+2)) );
  295. // Test if file is gzcompressed
  296. if (ord(substr($str, 0, 1)) == 0x1f && ord(substr($str, 1, 1)) == 0x8b) {
  297. $icc = @gzuncompress($icc); // Ignored if fails
  298. }
  299. if ($icc) {
  300. echo 'ICC profile present' . '<br />';
  301. if (substr($icc, 36, 4) != 'acsp') { echo 'ICC profile INVALID (no acsp flag)' . '<br />'; $icc = false; } // invalid ICC profile
  302. else {
  303. $input = substr($icc, 16, 4);
  304. $output = substr($icc, 20, 4);
  305. echo 'ICC profile Input: ' . $input. '<br />';
  306. echo 'ICC profile Output: ' . $output. '<br />';
  307. // Ignore Color profiles for conversion to other colorspaces e.g. CMYK/Lab
  308. if ($input != 'RGB ' || $output != 'XYZ ') { $icc = false; echo 'ICC profile ignored by mPDF' . '<br />'; }
  309. }
  310. }
  311. $p += $n;
  312. $p += 4;
  313. }
  314. else if($type=='IEND') { break; }
  315. else if (preg_match('/[a-zA-Z]{4}/',$type)) { $p += $n+4; }
  316. else { echo 'Error parsing PNG image data<br />'; }
  317. }
  318. while($n);
  319. if (!$pngdata) { echo 'Error parsing PNG image data - no IDAT data found<br />';}
  320. if ($colspace=='Indexed' && empty($pal)) { echo 'Error parsing PNG image data - missing colour palette<br />'; }
  321. echo 'PNG Image parsed directly' . '<br />';
  322. }
  323. }
  324. // GIF
  325. else if ($type == 'gif') {
  326. }
  327. // BMP (Windows Bitmap)
  328. else if ($type == 'bmp') {
  329. }
  330. // WMF
  331. else if ($type == 'wmf') {
  332. }
  333. // UNKNOWN TYPE - try GD imagecreatefromstring
  334. else {
  335. if (function_exists('gd_info')) { $gd = gd_info(); }
  336. else {$gd = array(); }
  337. if (isset($gd['PNG Support']) && $gd['PNG Support']) {
  338. $im = @imagecreatefromstring($data);
  339. if ($im) { echo 'Image type not recognised, but image created from file using GD imagecreate' . '<br />'; }
  340. else { echo 'Error parsing image file - image type not recognised, and not supported by GD imagecreate' . '<br />'; }
  341. }
  342. }
  343. exit;
  344. //==============================================================
  345. function _fourbytes2int($s) {
  346. //Read a 4-byte integer from string
  347. return (ord($s[0])<<24) + (ord($s[1])<<16) + (ord($s[2])<<8) + ord($s[3]);
  348. }
  349. function _twobytes2int($s) { // equivalent to _get_ushort
  350. //Read a 2-byte integer from string
  351. return (ord(substr($s, 0, 1))<<8) + ord(substr($s, 1, 1));
  352. }
  353. function _jpgHeaderFromString(&$data) {
  354. $p = 4;
  355. $p += _twobytes2int(substr($data, $p, 2)); // Length of initial marker block
  356. $marker = substr($data, $p, 2);
  357. while($marker != chr(255).chr(192) && $marker != chr(255).chr(194) && $p<strlen($data)) {
  358. // Start of frame marker (FFC0) or (FFC2) mPDF 4.4.004
  359. $p += (_twobytes2int(substr($data, $p+2, 2))) + 2; // Length of marker block
  360. $marker = substr($data, $p, 2);
  361. }
  362. if ($marker != chr(255).chr(192) && $marker != chr(255).chr(194)) { return false; }
  363. return substr($data, $p+2, 10);
  364. }
  365. function _jpgDataFromHeader($hdr) {
  366. $bpc = ord(substr($hdr, 2, 1));
  367. if (!$bpc) { $bpc = 8; }
  368. $h = _twobytes2int(substr($hdr, 3, 2));
  369. $w = _twobytes2int(substr($hdr, 5, 2));
  370. $channels = ord(substr($hdr, 7, 1));
  371. if ($channels==3) { $colspace='DeviceRGB'; }
  372. elseif($channels==4) { $colspace='DeviceCMYK'; }
  373. else { $colspace='DeviceGray'; }
  374. return array($w, $h, $colspace, $bpc, $channels);
  375. }
  376. function file_get_contents_by_curl($url, &$data) {
  377. $timeout = 5;
  378. $ch = curl_init($url);
  379. curl_setopt($ch, CURLOPT_HEADER, 0);
  380. curl_setopt($ch, CURLOPT_NOBODY, 0);
  381. curl_setopt ( $ch , CURLOPT_RETURNTRANSFER , 1 );
  382. curl_setopt ( $ch , CURLOPT_CONNECTTIMEOUT , $timeout );
  383. $data = curl_exec($ch);
  384. curl_close($ch);
  385. }
  386. function file_get_contents_by_socket($url, &$data) {
  387. // mPDF 5.7.3
  388. $timeout = 1;
  389. $p = parse_url($url);
  390. $file = $p['path'];
  391. if ($p['scheme']=='https') {
  392. $prefix = 'ssl://';
  393. $port = ($p['port'] ? $p['port'] : 443);
  394. }
  395. else {
  396. $prefix = '';
  397. $port = ($p['port'] ? $p['port'] : 80);
  398. }
  399. if ($p['query']) { $file .= '?'.$p['query']; }
  400. if(!($fh = @fsockopen($prefix.$p['host'], $port, $errno, $errstr, $timeout))) { return false; }
  401. $getstring =
  402. "GET ".$file." HTTP/1.0 \r\n" .
  403. "Host: ".$p['host']." \r\n" .
  404. "Connection: close\r\n\r\n";
  405. fwrite($fh, $getstring);
  406. // Get rid of HTTP header
  407. $s = fgets($fh, 1024);
  408. if (!$s) { return false; }
  409. $httpheader .= $s;
  410. while (!feof($fh)) {
  411. $s = fgets($fh, 1024);
  412. if ( $s == "\r\n" ) { break; }
  413. }
  414. $data = '';
  415. while (!feof($fh)) {
  416. $data .= fgets($fh, 1024);
  417. }
  418. fclose($fh);
  419. }
  420. //==============================================================
  421. function _imageTypeFromString(&$data) {
  422. $type = '';
  423. if (substr($data, 6, 4)== 'JFIF' || substr($data, 6, 4)== 'Exif' || substr($data, 0, 2)== chr(255).chr(216)) { // 0xFF 0xD8
  424. $type = 'jpeg';
  425. }
  426. else if (substr($data, 0, 6)== "GIF87a" || substr($data, 0, 6)== "GIF89a") {
  427. $type = 'gif';
  428. }
  429. else if (substr($data, 0, 8)== chr(137).'PNG'.chr(13).chr(10).chr(26).chr(10)) {
  430. $type = 'png';
  431. }
  432. /*-- IMAGES-WMF --*/
  433. else if (substr($data, 0, 4)== chr(215).chr(205).chr(198).chr(154)) {
  434. $type = 'wmf';
  435. }
  436. /*-- END IMAGES-WMF --*/
  437. else if (preg_match('/<svg.*<\/svg>/is',$data)) {
  438. $type = 'svg';
  439. }
  440. // BMP images
  441. else if (substr($data, 0, 2)== "BM") {
  442. $type = 'bmp';
  443. }
  444. return $type;
  445. }