PageRenderTime 60ms CodeModel.GetById 31ms RepoModel.GetById 0ms app.codeStats 1ms

/lib/tcpdf/include/tcpdf_images.php

https://bitbucket.org/moodle/moodle
PHP | 357 lines | 199 code | 12 blank | 146 comment | 59 complexity | 6659f41c204a3e6d2e8afd83efe4b780 MD5 | raw file
Possible License(s): Apache-2.0, LGPL-2.1, BSD-3-Clause, MIT, GPL-3.0
  1. <?php
  2. //============================================================+
  3. // File name : tcpdf_images.php
  4. // Version : 1.0.005
  5. // Begin : 2002-08-03
  6. // Last Update : 2014-11-15
  7. // Author : Nicola Asuni - Tecnick.com LTD - www.tecnick.com - info@tecnick.com
  8. // License : GNU-LGPL v3 (http://www.gnu.org/copyleft/lesser.html)
  9. // -------------------------------------------------------------------
  10. // Copyright (C) 2002-2014 Nicola Asuni - Tecnick.com LTD
  11. //
  12. // This file is part of TCPDF software library.
  13. //
  14. // TCPDF is free software: you can redistribute it and/or modify it
  15. // under the terms of the GNU Lesser General Public License as
  16. // published by the Free Software Foundation, either version 3 of the
  17. // License, or (at your option) any later version.
  18. //
  19. // TCPDF is distributed in the hope that it will be useful, but
  20. // WITHOUT ANY WARRANTY; without even the implied warranty of
  21. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  22. // See the GNU Lesser General Public License for more details.
  23. //
  24. // You should have received a copy of the License
  25. // along with TCPDF. If not, see
  26. // <http://www.tecnick.com/pagefiles/tcpdf/LICENSE.TXT>.
  27. //
  28. // See LICENSE.TXT file for more information.
  29. // -------------------------------------------------------------------
  30. //
  31. // Description :
  32. // Static image methods used by the TCPDF class.
  33. //
  34. //============================================================+
  35. /**
  36. * @file
  37. * This is a PHP class that contains static image methods for the TCPDF class.<br>
  38. * @package com.tecnick.tcpdf
  39. * @author Nicola Asuni
  40. * @version 1.0.005
  41. */
  42. /**
  43. * @class TCPDF_IMAGES
  44. * Static image methods used by the TCPDF class.
  45. * @package com.tecnick.tcpdf
  46. * @brief PHP class for generating PDF documents without requiring external extensions.
  47. * @version 1.0.005
  48. * @author Nicola Asuni - info@tecnick.com
  49. */
  50. class TCPDF_IMAGES {
  51. /**
  52. * Array of hinheritable SVG properties.
  53. * @since 5.0.000 (2010-05-02)
  54. * @public static
  55. */
  56. public static $svginheritprop = array('clip-rule', 'color', 'color-interpolation', 'color-interpolation-filters', 'color-profile', 'color-rendering', 'cursor', 'direction', 'display', 'fill', 'fill-opacity', 'fill-rule', 'font', 'font-family', 'font-size', 'font-size-adjust', 'font-stretch', 'font-style', 'font-variant', 'font-weight', 'glyph-orientation-horizontal', 'glyph-orientation-vertical', 'image-rendering', 'kerning', 'letter-spacing', 'marker', 'marker-end', 'marker-mid', 'marker-start', 'pointer-events', 'shape-rendering', 'stroke', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke-width', 'text-anchor', 'text-rendering', 'visibility', 'word-spacing', 'writing-mode');
  57. // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  58. /**
  59. * Return the image type given the file name or array returned by getimagesize() function.
  60. * @param $imgfile (string) image file name
  61. * @param $iminfo (array) array of image information returned by getimagesize() function.
  62. * @return string image type
  63. * @since 4.8.017 (2009-11-27)
  64. * @public static
  65. */
  66. public static function getImageFileType($imgfile, $iminfo=array()) {
  67. $type = '';
  68. if (isset($iminfo['mime']) AND !empty($iminfo['mime'])) {
  69. $mime = explode('/', $iminfo['mime']);
  70. if ((count($mime) > 1) AND ($mime[0] == 'image') AND (!empty($mime[1]))) {
  71. $type = strtolower(trim($mime[1]));
  72. }
  73. }
  74. if (empty($type)) {
  75. $type = strtolower(trim(pathinfo(parse_url($imgfile, PHP_URL_PATH), PATHINFO_EXTENSION)));
  76. }
  77. if ($type == 'jpg') {
  78. $type = 'jpeg';
  79. }
  80. return $type;
  81. }
  82. /**
  83. * Set the transparency for the given GD image.
  84. * @param $new_image (image) GD image object
  85. * @param $image (image) GD image object.
  86. * return GD image object.
  87. * @since 4.9.016 (2010-04-20)
  88. * @public static
  89. */
  90. public static function setGDImageTransparency($new_image, $image) {
  91. // default transparency color (white)
  92. $tcol = array('red' => 255, 'green' => 255, 'blue' => 255);
  93. // transparency index
  94. $tid = imagecolortransparent($image);
  95. $palletsize = imagecolorstotal($image);
  96. if (($tid >= 0) AND ($tid < $palletsize)) {
  97. // get the colors for the transparency index
  98. $tcol = imagecolorsforindex($image, $tid);
  99. }
  100. $tid = imagecolorallocate($new_image, $tcol['red'], $tcol['green'], $tcol['blue']);
  101. imagefill($new_image, 0, 0, $tid);
  102. imagecolortransparent($new_image, $tid);
  103. return $new_image;
  104. }
  105. /**
  106. * Convert the loaded image to a PNG and then return a structure for the PDF creator.
  107. * This function requires GD library and write access to the directory defined on K_PATH_CACHE constant.
  108. * @param $image (image) Image object.
  109. * @param $tempfile (string) Temporary file name.
  110. * return image PNG image object.
  111. * @since 4.9.016 (2010-04-20)
  112. * @public static
  113. */
  114. public static function _toPNG($image, $tempfile) {
  115. // turn off interlaced mode
  116. imageinterlace($image, 0);
  117. // create temporary PNG image
  118. imagepng($image, $tempfile);
  119. // remove image from memory
  120. imagedestroy($image);
  121. // get PNG image data
  122. $retvars = self::_parsepng($tempfile);
  123. // tidy up by removing temporary image
  124. unlink($tempfile);
  125. return $retvars;
  126. }
  127. /**
  128. * Convert the loaded image to a JPEG and then return a structure for the PDF creator.
  129. * This function requires GD library and write access to the directory defined on K_PATH_CACHE constant.
  130. * @param $image (image) Image object.
  131. * @param $quality (int) JPEG quality.
  132. * @param $tempfile (string) Temporary file name.
  133. * return image JPEG image object.
  134. * @public static
  135. */
  136. public static function _toJPEG($image, $quality, $tempfile) {
  137. imagejpeg($image, $tempfile, $quality);
  138. imagedestroy($image);
  139. $retvars = self::_parsejpeg($tempfile);
  140. // tidy up by removing temporary image
  141. unlink($tempfile);
  142. return $retvars;
  143. }
  144. /**
  145. * Extract info from a JPEG file without using the GD library.
  146. * @param $file (string) image file to parse
  147. * @return array structure containing the image data
  148. * @public static
  149. */
  150. public static function _parsejpeg($file) {
  151. // check if is a local file
  152. if (!@TCPDF_STATIC::file_exists($file)) {
  153. return false;
  154. }
  155. $a = getimagesize($file);
  156. if (empty($a)) {
  157. //Missing or incorrect image file
  158. return false;
  159. }
  160. if ($a[2] != 2) {
  161. // Not a JPEG file
  162. return false;
  163. }
  164. // bits per pixel
  165. $bpc = isset($a['bits']) ? intval($a['bits']) : 8;
  166. // number of image channels
  167. if (!isset($a['channels'])) {
  168. $channels = 3;
  169. } else {
  170. $channels = intval($a['channels']);
  171. }
  172. // default colour space
  173. switch ($channels) {
  174. case 1: {
  175. $colspace = 'DeviceGray';
  176. break;
  177. }
  178. case 3: {
  179. $colspace = 'DeviceRGB';
  180. break;
  181. }
  182. case 4: {
  183. $colspace = 'DeviceCMYK';
  184. break;
  185. }
  186. default: {
  187. $channels = 3;
  188. $colspace = 'DeviceRGB';
  189. break;
  190. }
  191. }
  192. // get file content
  193. $data = file_get_contents($file);
  194. // check for embedded ICC profile
  195. $icc = array();
  196. $offset = 0;
  197. while (($pos = strpos($data, "ICC_PROFILE\0", $offset)) !== false) {
  198. // get ICC sequence length
  199. $length = (TCPDF_STATIC::_getUSHORT($data, ($pos - 2)) - 16);
  200. // marker sequence number
  201. $msn = max(1, ord($data[($pos + 12)]));
  202. // number of markers (total of APP2 used)
  203. $nom = max(1, ord($data[($pos + 13)]));
  204. // get sequence segment
  205. $icc[($msn - 1)] = substr($data, ($pos + 14), $length);
  206. // move forward to next sequence
  207. $offset = ($pos + 14 + $length);
  208. }
  209. // order and compact ICC segments
  210. if (count($icc) > 0) {
  211. ksort($icc);
  212. $icc = implode('', $icc);
  213. if ((ord($icc[36]) != 0x61) OR (ord($icc[37]) != 0x63) OR (ord($icc[38]) != 0x73) OR (ord($icc[39]) != 0x70)) {
  214. // invalid ICC profile
  215. $icc = false;
  216. }
  217. } else {
  218. $icc = false;
  219. }
  220. return array('w' => $a[0], 'h' => $a[1], 'ch' => $channels, 'icc' => $icc, 'cs' => $colspace, 'bpc' => $bpc, 'f' => 'DCTDecode', 'data' => $data);
  221. }
  222. /**
  223. * Extract info from a PNG file without using the GD library.
  224. * @param $file (string) image file to parse
  225. * @return array structure containing the image data
  226. * @public static
  227. */
  228. public static function _parsepng($file) {
  229. $f = @fopen($file, 'rb');
  230. if ($f === false) {
  231. // Can't open image file
  232. return false;
  233. }
  234. //Check signature
  235. if (fread($f, 8) != chr(137).'PNG'.chr(13).chr(10).chr(26).chr(10)) {
  236. // Not a PNG file
  237. return false;
  238. }
  239. //Read header chunk
  240. fread($f, 4);
  241. if (fread($f, 4) != 'IHDR') {
  242. //Incorrect PNG file
  243. return false;
  244. }
  245. $w = TCPDF_STATIC::_freadint($f);
  246. $h = TCPDF_STATIC::_freadint($f);
  247. $bpc = ord(fread($f, 1));
  248. $ct = ord(fread($f, 1));
  249. if ($ct == 0) {
  250. $colspace = 'DeviceGray';
  251. } elseif ($ct == 2) {
  252. $colspace = 'DeviceRGB';
  253. } elseif ($ct == 3) {
  254. $colspace = 'Indexed';
  255. } else {
  256. // alpha channel
  257. fclose($f);
  258. return 'pngalpha';
  259. }
  260. if (ord(fread($f, 1)) != 0) {
  261. // Unknown compression method
  262. fclose($f);
  263. return false;
  264. }
  265. if (ord(fread($f, 1)) != 0) {
  266. // Unknown filter method
  267. fclose($f);
  268. return false;
  269. }
  270. if (ord(fread($f, 1)) != 0) {
  271. // Interlacing not supported
  272. fclose($f);
  273. return false;
  274. }
  275. fread($f, 4);
  276. $channels = ($ct == 2 ? 3 : 1);
  277. $parms = '/DecodeParms << /Predictor 15 /Colors '.$channels.' /BitsPerComponent '.$bpc.' /Columns '.$w.' >>';
  278. //Scan chunks looking for palette, transparency and image data
  279. $pal = '';
  280. $trns = '';
  281. $data = '';
  282. $icc = false;
  283. $n = TCPDF_STATIC::_freadint($f);
  284. do {
  285. $type = fread($f, 4);
  286. if ($type == 'PLTE') {
  287. // read palette
  288. $pal = TCPDF_STATIC::rfread($f, $n);
  289. fread($f, 4);
  290. } elseif ($type == 'tRNS') {
  291. // read transparency info
  292. $t = TCPDF_STATIC::rfread($f, $n);
  293. if ($ct == 0) { // DeviceGray
  294. $trns = array(ord($t[1]));
  295. } elseif ($ct == 2) { // DeviceRGB
  296. $trns = array(ord($t[1]), ord($t[3]), ord($t[5]));
  297. } else { // Indexed
  298. if ($n > 0) {
  299. $trns = array();
  300. for ($i = 0; $i < $n; ++ $i) {
  301. $trns[] = ord($t[$i]);
  302. }
  303. }
  304. }
  305. fread($f, 4);
  306. } elseif ($type == 'IDAT') {
  307. // read image data block
  308. $data .= TCPDF_STATIC::rfread($f, $n);
  309. fread($f, 4);
  310. } elseif ($type == 'iCCP') {
  311. // skip profile name
  312. $len = 0;
  313. while ((ord(fread($f, 1)) != 0) AND ($len < 80)) {
  314. ++$len;
  315. }
  316. // get compression method
  317. if (ord(fread($f, 1)) != 0) {
  318. // Unknown filter method
  319. fclose($f);
  320. return false;
  321. }
  322. // read ICC Color Profile
  323. $icc = TCPDF_STATIC::rfread($f, ($n - $len - 2));
  324. // decompress profile
  325. $icc = gzuncompress($icc);
  326. fread($f, 4);
  327. } elseif ($type == 'IEND') {
  328. break;
  329. } else {
  330. TCPDF_STATIC::rfread($f, $n + 4);
  331. }
  332. $n = TCPDF_STATIC::_freadint($f);
  333. } while ($n);
  334. if (($colspace == 'Indexed') AND (empty($pal))) {
  335. // Missing palette
  336. fclose($f);
  337. return false;
  338. }
  339. fclose($f);
  340. return array('w' => $w, 'h' => $h, 'ch' => $channels, 'icc' => $icc, 'cs' => $colspace, 'bpc' => $bpc, 'f' => 'FlateDecode', 'parms' => $parms, 'pal' => $pal, 'trns' => $trns, 'data' => $data);
  341. }
  342. } // END OF TCPDF_IMAGES CLASS
  343. //============================================================+
  344. // END OF FILE
  345. //============================================================+