PageRenderTime 58ms CodeModel.GetById 10ms RepoModel.GetById 1ms app.codeStats 0ms

/cms113/phpthumb.class.php

http://cmsfromscratch.googlecode.com/
PHP | 2388 lines | 1927 code | 323 blank | 138 comment | 426 complexity | 290e8cf2252daf3dd0edfdff5db0ae68 MD5 | raw file
Possible License(s): GPL-3.0, LGPL-2.1
  1. <?php
  2. //////////////////////////////////////////////////////////////
  3. /// phpthumb() by James Heinrich <info@silisoftware.com> //
  4. // available at http://phpthumb.sourceforge.net ///
  5. //////////////////////////////////////////////////////////////
  6. /// //
  7. // See: phpthumb.readme.txt for usage instructions //
  8. // ///
  9. //////////////////////////////////////////////////////////////
  10. ob_start();
  11. if (!include_once(dirname(__FILE__).'/phpthumb.functions.php')) {
  12. ob_end_flush();
  13. die('(phpthumb.class.php) failed to include_once("'.realpath(dirname(__FILE__).'/phpthumb.functions.php').'")');
  14. }
  15. ob_end_clean();
  16. class phpthumb {
  17. // public:
  18. // START PARAMETERS (for object mode and phpthumb.php)
  19. // See phpthumb.readme.txt for descriptions of what each of these values are
  20. var $src = null; // SouRCe filename
  21. var $new = null; // NEW image (phpthumb.php only)
  22. var $w = null; // Width
  23. var $h = null; // Height
  24. var $f = null; // Format
  25. var $q = 75; // Quality
  26. var $sx = null; // Source crop top-left X position
  27. var $sy = null; // Source crop top-left Y position
  28. var $sw = null; // Source crop Width
  29. var $sh = null; // Source crop Height
  30. var $zc = null; // Zoom Crop
  31. var $bc = null; // Border Color
  32. var $bg = null; // BackGround color
  33. var $fltr = array(); // FiLTeRs
  34. var $file = null; // render-to FILEname
  35. var $goto = null; // GO TO url after processing
  36. var $err = null; // default ERRor image filename
  37. var $xto = null; // extract eXif Thumbnail Only
  38. var $ra = null; // Rotate by Angle
  39. var $ar = null; // Auto Rotate
  40. var $aoe = null; // Allow Output Enlargement
  41. var $far = null; // Fixed Aspect Ratio
  42. var $iar = null; // Ignore Aspect Ratio
  43. var $maxb = null; // MAXimum Bytes
  44. var $down = null; // DOWNload thumbnail
  45. var $md5s = null; // MD5 hash of Source image
  46. var $phpthumbDebug = null;
  47. // END PARAMETERS
  48. // public:
  49. // START CONFIGURATION OPTIONS (for object mode only)
  50. // See phpthumb.config.php for descriptions of what each of these settings do
  51. // * Directory Configuration
  52. var $config_cache_directory = null;
  53. var $config_cache_disable_warning = true;
  54. var $config_cache_source_enabled = false;
  55. var $config_cache_source_directory = null;
  56. var $config_temp_directory = null;
  57. var $config_document_root = null;
  58. // * Default output configuration:
  59. var $config_output_format = 'jpeg';
  60. var $config_output_maxwidth = 0;
  61. var $config_output_maxheight = 0;
  62. var $config_output_interlace = true;
  63. // * Error message configuration
  64. var $config_error_image_width = 400;
  65. var $config_error_image_height = 100;
  66. var $config_error_message_image_default = '';
  67. var $config_error_bgcolor = 'CCCCFF';
  68. var $config_error_textcolor = 'FF0000';
  69. var $config_error_fontsize = 1;
  70. var $config_error_die_on_error = true;
  71. var $config_error_silent_die_on_error = false;
  72. var $config_error_die_on_source_failure = true;
  73. // * Anti-Hotlink Configuration:
  74. var $config_nohotlink_enabled = true;
  75. var $config_nohotlink_valid_domains = array();
  76. var $config_nohotlink_erase_image = true;
  77. var $config_nohotlink_text_message = 'Off-server thumbnailing is not allowed';
  78. // * Off-server Linking Configuration:
  79. var $config_nooffsitelink_enabled = false;
  80. var $config_nooffsitelink_valid_domains = array();
  81. var $config_nooffsitelink_require_refer = false;
  82. var $config_nooffsitelink_erase_image = true;
  83. var $config_nooffsitelink_text_message = 'Off-server linking is not allowed';
  84. // * Border & Background default colors
  85. var $config_border_hexcolor = '000000';
  86. var $config_background_hexcolor = 'FFFFFF';
  87. // * TrueType Fonts
  88. var $config_ttf_directory = '.';
  89. var $config_max_source_pixels = 0;
  90. var $config_use_exif_thumbnail_for_speed = true;
  91. var $config_output_allow_enlarging = false;
  92. var $config_imagemagick_path = null;
  93. var $config_cache_maxage = null;
  94. var $config_cache_maxsize = null;
  95. var $config_cache_maxfiles = null;
  96. var $config_cache_source_filemtime_ignore_local = false;
  97. var $config_cache_source_filemtime_ignore_remote = false;
  98. var $config_disable_debug = false;
  99. // END CONFIGURATION OPTIONS
  100. // public: error messages (read-only)
  101. var $debugmessages = array();
  102. var $fatalerror = null;
  103. // private: (should not be modified directly)
  104. var $thumbnailQuality = 75;
  105. var $thumbnailFormat = null;
  106. var $sourceFilename = null;
  107. var $rawImageData = null;
  108. var $gdimg_output = null;
  109. var $gdimg_source = null;
  110. var $getimagesizeinfo = null;
  111. var $source_width = null;
  112. var $source_height = null;
  113. var $thumbnailCropX = null;
  114. var $thumbnailCropY = null;
  115. var $thumbnailCropW = null;
  116. var $thumbnailCropH = null;
  117. var $exif_thumbnail_width = null;
  118. var $exif_thumbnail_height = null;
  119. var $exif_thumbnail_type = null;
  120. var $exif_thumbnail_data = null;
  121. var $thumbnail_width = null;
  122. var $thumbnail_height = null;
  123. var $thumbnail_image_width = null;
  124. var $thumbnail_image_height = null;
  125. var $cache_filename = null;
  126. var $is_alpha = false;
  127. var $iswindows = null;
  128. var $osslash = null;
  129. var $phpthumb_version = '1.5.4-200505261715';
  130. //////////////////////////////////////////////////////////////////////
  131. // public: constructor
  132. function phpthumb() {
  133. if (phpthumb_functions::gd_version() < 1) {
  134. die('No GD support detected');
  135. }
  136. if (strtoupper(substr(PHP_OS, 0, 3)) == 'WIN') {
  137. $this->iswindows = true;
  138. $this->osslash = '\\';
  139. } else {
  140. $this->iswindows = false;
  141. $this->osslash = '/';
  142. }
  143. if (!empty($_SERVER['DOCUMENT_ROOT'])) {
  144. $this->config_document_root = $_SERVER['DOCUMENT_ROOT'];
  145. }
  146. }
  147. // public:
  148. function setSourceFilename($sourceFilename) {
  149. $this->rawImageData = null;
  150. $this->sourceFilename = $sourceFilename;
  151. return true;
  152. }
  153. // public:
  154. function setSourceData($rawImageData, $sourceFilename='') {
  155. $this->sourceFilename = null;
  156. $this->rawImageData = $rawImageData;
  157. if ($this->config_cache_source_enabled) {
  158. $sourceFilename = ($sourceFilename ? $sourceFilename : md5($rawImageData));
  159. if (!is_dir($this->config_cache_source_directory) && !$this->phpthumbDebug) {
  160. $this->ErrorImage('$this->config_cache_source_directory ('.$this->config_cache_source_directory.') is not a directory');
  161. } elseif (!is_writable($this->config_cache_source_directory) && !$this->phpthumbDebug) {
  162. $this->ErrorImage('$this->config_cache_source_directory ('.$this->config_cache_source_directory.') is not writable');
  163. }
  164. $this->DebugMessage('setSourceData() attempting to save source image to "'.$this->config_cache_source_directory.'/'.urlencode($sourceFilename).'"', __FILE__, __LINE__);
  165. if ($fp = @fopen($this->config_cache_source_directory.'/'.urlencode($sourceFilename), 'wb')) {
  166. fwrite($fp, $rawImageData);
  167. fclose($fp);
  168. } elseif (!$this->phpthumbDebug) {
  169. $this->ErrorImage('setSourceData() failed to write to source cache ('.$this->config_cache_source_directory.'/'.urlencode($sourceFilename).')');
  170. }
  171. }
  172. return true;
  173. }
  174. // public:
  175. function setSourceImageResource($gdimg) {
  176. $this->gdimg_source = $gdimg;
  177. return true;
  178. }
  179. // public:
  180. function GenerateThumbnail() {
  181. $this->setOutputFormat();
  182. $this->ResolveSource();
  183. $this->SetCacheFilename();
  184. $this->ExtractEXIFgetImageSize();
  185. if (!$this->SourceImageToGD()) {
  186. return false;
  187. }
  188. $this->Rotate();
  189. $this->CreateGDoutput();
  190. // copy/resize image to appropriate dimensions (either nearest-neighbor or resample, depending on GD version)
  191. phpthumb_functions::ImageResizeFunction(
  192. $this->gdimg_output,
  193. $this->gdimg_source,
  194. round(($this->thumbnail_width - $this->thumbnail_image_width) / 2),
  195. round(($this->thumbnail_height - $this->thumbnail_image_height) / 2),
  196. $this->thumbnailCropX,
  197. $this->thumbnailCropY,
  198. $this->thumbnail_image_width,
  199. $this->thumbnail_image_height,
  200. $this->thumbnailCropW,
  201. $this->thumbnailCropH
  202. );
  203. $this->AntiOffsiteLinking();
  204. $this->ApplyFilters();
  205. $this->AlphaChannelFlatten();
  206. $this->MaxFileSize();
  207. return true;
  208. }
  209. // public:
  210. function RenderToFile($filename) {
  211. if (!is_resource($this->gdimg_output)) {
  212. $this->DebugMessage('RenderToFile('.$filename.') failed because !is_resource($this->gdimg_output)', __FILE__, __LINE__);
  213. return false;
  214. }
  215. if (!$this->thumbnailFormat) {
  216. $this->DebugMessage('RenderToFile() failed because $this->thumbnailFormat is empty', __FILE__, __LINE__);
  217. return false;
  218. }
  219. // render thumbnail to this file only, do not cache, do not output to browser
  220. $ImageOutFunction = 'image'.$this->thumbnailFormat;
  221. //$renderfilename = $this->ResolveFilenameToAbsolute(dirname($filename)).'/'.basename($filename);
  222. $renderfilename = $filename;
  223. if (($filename{0} != '/') && ($filename{0} != '\\') && ($filename{1} != ':')) {
  224. $renderfilename = $this->ResolveFilenameToAbsolute($filename);
  225. }
  226. $this->DebugMessage('RenderToFile('.$filename.') attempting '.$ImageOutFunction.'($this->gdimg_output, '.$renderfilename.')', __FILE__, __LINE__);
  227. ob_start();
  228. switch ($this->thumbnailFormat) {
  229. case 'jpeg':
  230. $ImageOutFunction($this->gdimg_output, $renderfilename, $this->thumbnailQuality);
  231. break;
  232. case 'png':
  233. case 'gif':
  234. $ImageOutFunction($this->gdimg_output, $renderfilename);
  235. break;
  236. }
  237. $errormessage = strip_tags(ob_get_contents());
  238. ob_end_clean();
  239. if ($errormessage) {
  240. $this->DebugMessage('RenderToFile ['.$ImageOutFunction.'('.$renderfilename.')] failed with message "'.$errormessage.'"', __FILE__, __LINE__);
  241. return false;
  242. } elseif (!file_exists($renderfilename)) {
  243. $this->DebugMessage('RenderToFile ['.$ImageOutFunction.'('.$renderfilename.')] did not appear to fail, but the output image does not exist either...', __FILE__, __LINE__);
  244. }
  245. return true;
  246. }
  247. // public:
  248. function OutputThumbnail() {
  249. if (!is_resource($this->gdimg_output)) {
  250. $this->DebugMessage('OutputThumbnail() failed because !is_resource($this->gdimg_output)', __FILE__, __LINE__);
  251. return false;
  252. }
  253. if (headers_sent()) {
  254. return $this->ErrorImage('OutputThumbnail() failed - headers already sent');
  255. exit;
  256. }
  257. if (!empty($this->down)) {
  258. $downloadfilename = ereg_replace('[/\\:\*\?"<>|]', '_', $this->down);
  259. if (phpthumb_functions::version_compare_replacement(phpversion(), '4.1.0', '>=')) {
  260. $downloadfilename = trim($downloadfilename, '.');
  261. }
  262. if ($downloadfilename != $this->down) {
  263. $this->DebugMessage('renaming output file for "down" from "'.$this->down.'" to "'.$downloadfilename.'"', __FILE__, __LINE__);
  264. }
  265. if ($downloadfilename) {
  266. header('Content-Disposition: attachment; filename="'.$downloadfilename.'"');
  267. } else {
  268. $this->DebugMessage('failed to send Content-Disposition header because $downloadfilename is empty', __FILE__, __LINE__);
  269. }
  270. }
  271. ImageInterlace($this->gdimg_output, intval($this->config_output_interlace));
  272. $ImageOutFunction = 'image'.$this->thumbnailFormat;
  273. switch ($this->thumbnailFormat) {
  274. case 'jpeg':
  275. header('Content-Type: image/'.$this->thumbnailFormat);
  276. @$ImageOutFunction($this->gdimg_output, '', $this->thumbnailQuality);
  277. break;
  278. case 'png':
  279. case 'gif':
  280. header('Content-Type: image/'.$this->thumbnailFormat);
  281. @$ImageOutFunction($this->gdimg_output);
  282. break;
  283. default:
  284. return false;
  285. break;
  286. }
  287. ImageDestroy($this->gdimg_output);
  288. return true;
  289. }
  290. // public:
  291. function CleanUpCacheDirectory() {
  292. if (($this->config_cache_maxage > 0) || ($this->config_cache_maxsize > 0) || ($this->config_cache_maxfiles > 0)) {
  293. $CacheDirOldFilesAge = array();
  294. $CacheDirOldFilesSize = array();
  295. if ($dirhandle = opendir($this->config_cache_directory)) {
  296. while ($oldcachefile = readdir($dirhandle)) {
  297. if (eregi('^phpthumb_cache_', $oldcachefile)) {
  298. $CacheDirOldFilesAge[$oldcachefile] = fileatime($this->config_cache_directory.'/'.$oldcachefile);
  299. if ($CacheDirOldFilesAge[$oldcachefile] == 0) {
  300. $CacheDirOldFilesAge[$oldcachefile] = filemtime($this->config_cache_directory.'/'.$oldcachefile);
  301. }
  302. $CacheDirOldFilesSize[$oldcachefile] = filesize($this->config_cache_directory.'/'.$oldcachefile);
  303. }
  304. }
  305. }
  306. asort($CacheDirOldFilesAge);
  307. if ($this->config_cache_maxfiles > 0) {
  308. $TotalCachedFiles = count($CacheDirOldFilesAge);
  309. $DeletedKeys = array();
  310. foreach ($CacheDirOldFilesAge as $oldcachefile => $filedate) {
  311. if ($TotalCachedFiles > $this->config_cache_maxfiles) {
  312. $TotalCachedFiles--;
  313. if (@unlink($this->config_cache_directory.'/'.$oldcachefile)) {
  314. $DeletedKeys[] = $oldcachefile;
  315. }
  316. } else {
  317. // there are few enough files to keep the rest
  318. break;
  319. }
  320. }
  321. foreach ($DeletedKeys as $oldcachefile) {
  322. unset($CacheDirOldFilesAge[$oldcachefile]);
  323. unset($CacheDirOldFilesSize[$oldcachefile]);
  324. }
  325. }
  326. if ($this->config_cache_maxage > 0) {
  327. $mindate = time() - $this->config_cache_maxage;
  328. $DeletedKeys = array();
  329. foreach ($CacheDirOldFilesAge as $oldcachefile => $filedate) {
  330. if ($filedate > 0) {
  331. if ($filedate < $mindate) {
  332. if (@unlink($this->config_cache_directory.'/'.$oldcachefile)) {
  333. $DeletedKeys[] = $oldcachefile;
  334. }
  335. } else {
  336. // the rest of the files are new enough to keep
  337. break;
  338. }
  339. }
  340. }
  341. foreach ($DeletedKeys as $oldcachefile) {
  342. unset($CacheDirOldFilesAge[$oldcachefile]);
  343. unset($CacheDirOldFilesSize[$oldcachefile]);
  344. }
  345. }
  346. if ($this->config_cache_maxsize > 0) {
  347. $TotalCachedFileSize = array_sum($CacheDirOldFilesSize);
  348. $DeletedKeys = array();
  349. foreach ($CacheDirOldFilesAge as $oldcachefile => $filedate) {
  350. if ($TotalCachedFileSize > $this->config_cache_maxsize) {
  351. $TotalCachedFileSize -= $CacheDirOldFilesSize[$oldcachefile];
  352. if (@unlink($this->config_cache_directory.'/'.$oldcachefile)) {
  353. $DeletedKeys[] = $oldcachefile;
  354. }
  355. } else {
  356. // the total filesizes are small enough to keep the rest of the files
  357. break;
  358. }
  359. }
  360. foreach ($DeletedKeys as $oldcachefile) {
  361. unset($CacheDirOldFilesAge[$oldcachefile]);
  362. unset($CacheDirOldFilesSize[$oldcachefile]);
  363. }
  364. }
  365. }
  366. return true;
  367. }
  368. //////////////////////////////////////////////////////////////////////
  369. function ResolveSource() {
  370. if (is_resource($this->gdimg_source)) {
  371. return true;
  372. }
  373. if (empty($this->sourceFilename) && empty($this->rawImageData)) {
  374. $this->sourceFilename = $this->ResolveFilenameToAbsolute($this->src);
  375. }
  376. return true;
  377. }
  378. function setOutputFormat() {
  379. static $alreadyCalled = false;
  380. if ($this->thumbnailFormat && $alreadyCalled) {
  381. return true;
  382. }
  383. $alreadyCalled = true;
  384. $AvailableImageOutputFormats = array();
  385. $AvailableImageOutputFormats[] = 'text';
  386. $this->thumbnailFormat = 'text';
  387. // Set default output format based on what image types are available
  388. if (!function_exists('ImageTypes')) {
  389. return $this->ErrorImage('ImageTypes() does not exist - GD support might not be enabled?');
  390. }
  391. $imagetypes = ImageTypes();
  392. if ($imagetypes & IMG_WBMP) {
  393. $this->thumbnailFormat = 'wbmp';
  394. $AvailableImageOutputFormats[] = 'wbmp';
  395. }
  396. if ($imagetypes & IMG_GIF) {
  397. $this->thumbnailFormat = 'gif';
  398. $AvailableImageOutputFormats[] = 'gif';
  399. }
  400. if ($imagetypes & IMG_PNG) {
  401. $this->thumbnailFormat = 'png';
  402. $AvailableImageOutputFormats[] = 'png';
  403. }
  404. if ($imagetypes & IMG_JPG) {
  405. $this->thumbnailFormat = 'jpeg';
  406. $AvailableImageOutputFormats[] = 'jpeg';
  407. }
  408. $this->DebugMessage('$AvailableImageOutputFormats = array('.implode(';', $AvailableImageOutputFormats).')', __FILE__, __LINE__);
  409. if (strtolower($this->config_output_format) == 'jpg') {
  410. $this->config_output_format = 'jpeg';
  411. }
  412. if (strtolower($this->f) == 'jpg') {
  413. $this->f = 'jpeg';
  414. }
  415. if (in_array(strtolower($this->config_output_format), $AvailableImageOutputFormats)) {
  416. // set output format to config default if that format is available
  417. $this->DebugMessage('$this->thumbnailFormat set to $this->config_output_format "'.strtolower($this->config_output_format).'"', __FILE__, __LINE__);
  418. $this->thumbnailFormat = strtolower($this->config_output_format);
  419. } else {
  420. $this->DebugMessage('$this->thumbnailFormat staying as "'.$this->thumbnailFormat.'" because "'.strtolower($this->config_output_format).'" ($this->config_output_format) is not in $AvailableImageOutputFormats', __FILE__, __LINE__);
  421. }
  422. if ($this->f && (in_array(strtolower($this->f), $AvailableImageOutputFormats))) {
  423. // override output format if $this->f is set and that format is available
  424. $this->DebugMessage('$this->thumbnailFormat set to $this->f "'.strtolower($this->f).'"', __FILE__, __LINE__);
  425. $this->thumbnailFormat = strtolower($this->f);
  426. } else {
  427. $this->DebugMessage('$this->thumbnailFormat staying as "'.$this->thumbnailFormat.'" because "'.strtolower($this->f).'" ($this->f) is not in $AvailableImageOutputFormats', __FILE__, __LINE__);
  428. }
  429. // for JPEG images, quality 1 (worst) to 99 (best)
  430. // quality < 25 is nasty, with not much size savings - not recommended
  431. // problems with 100 - invalid JPEG?
  432. $this->thumbnailQuality = max(1, min(99, (!empty($this->q) ? $this->q : 75)));
  433. $this->DebugMessage('$this->thumbnailQuality set to "'.$this->thumbnailQuality.'"', __FILE__, __LINE__);
  434. return true;
  435. }
  436. function setCacheDirectory() {
  437. // resolve cache directory to absolute pathname
  438. if (substr($this->config_cache_directory, 0, 1) == '.') {
  439. if (eregi('^(f|ht)tp[s]?://', $this->src)) {
  440. if (!$this->config_cache_disable_warning && !$this->phpthumbDebug) {
  441. $this->ErrorImage('$this->config_cache_directory ('.$this->config_cache_directory.') cannot be used for remote images. Adjust "cache_directory" or "cache_disable_warning" in phpthumb.config.php');
  442. }
  443. } elseif ($this->src) {
  444. // resolve relative cache directory to source image
  445. $this->config_cache_directory = dirname($this->ResolveFilenameToAbsolute($this->src)).'/'.$this->config_cache_directory;
  446. } else {
  447. // $this->new is probably set
  448. }
  449. }
  450. if (substr($this->config_cache_directory, -1) == '/') {
  451. $this->config_cache_directory = substr($this->config_cache_directory, 0, -1);
  452. }
  453. if ($this->iswindows) {
  454. $this->config_cache_directory = str_replace('/', $this->osslash, $this->config_cache_directory);
  455. }
  456. if (!empty($this->config_cache_directory)) {
  457. $real_cache_path = realpath($this->config_cache_directory);
  458. if (!$real_cache_path) {
  459. $this->DebugMessage('realpath($this->config_cache_directory) failed for "'.$this->config_cache_directory.'"', __FILE__, __LINE__);
  460. if (!is_dir($this->config_cache_directory)) {
  461. $this->DebugMessage('!is_dir('.$this->config_cache_directory.')', __FILE__, __LINE__);
  462. }
  463. }
  464. if ($real_cache_path) {
  465. $this->config_cache_directory = $real_cache_path;
  466. }
  467. }
  468. if (!is_dir($this->config_cache_directory)) {
  469. if (!$this->config_cache_disable_warning && !$this->phpthumbDebug) {
  470. $this->ErrorImage('$this->config_cache_directory ('.$this->config_cache_directory.') does not exist. Adjust "cache_directory" or "cache_disable_warning" in phpthumb.config.php');
  471. }
  472. $this->DebugMessage('$this->config_cache_directory ('.$this->config_cache_directory.') is not a directory', __FILE__, __LINE__);
  473. $this->config_cache_directory = null;
  474. } elseif (!is_writable($this->config_cache_directory)) {
  475. $this->DebugMessage('$this->config_cache_directory is not writable ('.$this->config_cache_directory.')', __FILE__, __LINE__);
  476. }
  477. return true;
  478. }
  479. function ResolveFilenameToAbsolute($filename) {
  480. if (eregi('^(f|ht)tp[s]?://', $filename)) {
  481. // URL
  482. $AbsoluteFilename = $filename;
  483. } elseif ($this->iswindows && ($filename{1} == ':')) {
  484. // absolute pathname (Windows)
  485. $AbsoluteFilename = $filename;
  486. } elseif ($this->iswindows && ((substr($filename, 0, 2) == '//') || (substr($filename, 0, 2) == '\\\\'))) {
  487. // absolute pathname (Windows)
  488. $AbsoluteFilename = $filename;
  489. } elseif ($filename{0} == '/') {
  490. if (@is_readable($filename) && !@is_readable($this->config_document_root.$filename)) {
  491. // absolute filename (*nix)
  492. $AbsoluteFilename = $filename;
  493. } elseif ($filename{1} == '~') {
  494. // /~user/path
  495. if ($ApacheLookupURIarray = phpthumb_functions::ApacheLookupURIarray($filename)) {
  496. $AbsoluteFilename = $ApacheLookupURIarray['filename'];
  497. } else {
  498. $AbsoluteFilename = realpath($filename);
  499. if (@is_readable($AbsoluteFilename)) {
  500. $this->DebugMessage('phpthumb_functions::ApacheLookupURIarray() failed for "'.$filename.'", but the correct filename ('.$AbsoluteFilename.') seems to have been resolved with realpath($filename)', __FILE__, __LINE__);
  501. } else {
  502. if ($this->phpthumbDebug) {
  503. $this->DebugMessage('phpthumb_functions::ApacheLookupURIarray() failed for "'.$filename.'". This has been known to fail on Apache2 - try using the absolute filename for the source image');
  504. return false;
  505. } else {
  506. return $this->ErrorImage('phpthumb_functions::ApacheLookupURIarray() failed for "'.$filename.'". This has been known to fail on Apache2 - try using the absolute filename for the source image');
  507. }
  508. }
  509. }
  510. } else {
  511. // relative filename (any OS)
  512. $AbsoluteFilename = $this->config_document_root.$filename;
  513. }
  514. } else {
  515. // relative to current directory (any OS)
  516. $AbsoluteFilename = $this->config_document_root.dirname(@$_SERVER['PHP_SELF']).'/'.$filename;
  517. //if (!file_exists($AbsoluteFilename) && file_exists(realpath($this->DotPadRelativeDirectoryPath($filename)))) {
  518. // $AbsoluteFilename = realpath($this->DotPadRelativeDirectoryPath($filename));
  519. //}
  520. if (substr(dirname(@$_SERVER['PHP_SELF']), 0, 2) == '/~') {
  521. if ($ApacheLookupURIarray = phpthumb_functions::ApacheLookupURIarray(dirname(@$_SERVER['PHP_SELF']))) {
  522. $AbsoluteFilename = $ApacheLookupURIarray['filename'].'/'.$filename;
  523. } else {
  524. $AbsoluteFilename = realpath('.').'/'.$filename;
  525. if (@is_readable($AbsoluteFilename)) {
  526. $this->DebugMessage('phpthumb_functions::ApacheLookupURIarray() failed for "'.dirname(@$_SERVER['PHP_SELF']).'", but the correct filename ('.$AbsoluteFilename.') seems to have been resolved with realpath(.)/$filename', __FILE__, __LINE__);
  527. } else {
  528. return $this->ErrorImage('phpthumb_functions::ApacheLookupURIarray() failed for "'.dirname(@$_SERVER['PHP_SELF']).'". This has been known to fail on Apache2 - try using the absolute filename for the source image');
  529. }
  530. }
  531. }
  532. }
  533. return $AbsoluteFilename;
  534. }
  535. function ImageMagickCommandlineBase() {
  536. static $commandline = null;
  537. if (is_null($commandline)) {
  538. $commandline = '';
  539. $which_convert = trim(phpthumb_functions::SafeBackTick('which convert'));
  540. if ($this->config_imagemagick_path && ($this->config_imagemagick_path != realpath($this->config_imagemagick_path))) {
  541. $this->DebugMessage('Changing $this->config_imagemagick_path ('.$this->config_imagemagick_path.') to realpath($this->config_imagemagick_path) ('.realpath($this->config_imagemagick_path).')', __FILE__, __LINE__);
  542. $this->config_imagemagick_path = realpath($this->config_imagemagick_path);
  543. }
  544. if (file_exists($this->config_imagemagick_path)) {
  545. $this->DebugMessage('using ImageMagick path from $this->config_imagemagick_path ('.$this->config_imagemagick_path.')', __FILE__, __LINE__);
  546. if ($this->iswindows) {
  547. $commandline = substr($this->config_imagemagick_path, 0, 2).' && cd "'.substr(dirname($this->config_imagemagick_path), 2).'" && '.basename($this->config_imagemagick_path);
  548. } else {
  549. $commandline = '"'.$this->config_imagemagick_path.'"';
  550. }
  551. } elseif ($which_convert && ($which_convert{0} == '/') && @file_exists($which_convert)) {
  552. // `which convert` *should* return the path if "convert" exist, or nothing if it doesn't
  553. // other things *may* get returned, like "sh: convert: not found" or "no convert in /usr/local/bin /usr/sbin /usr/bin /usr/ccs/bin"
  554. // so only do this if the value returned exists as a file
  555. $this->DebugMessage('using ImageMagick path from `which convert` ('.$which_convert.')', __FILE__, __LINE__);
  556. $commandline = 'convert';
  557. } else {
  558. $this->DebugMessage('ImageMagickThumbnailToGD() aborting because cannot find convert in $this->config_imagemagick_path ('.$this->config_imagemagick_path.'), and `which convert` returned ('.$which_convert.')', __FILE__, __LINE__);
  559. }
  560. }
  561. return $commandline;
  562. }
  563. function ImageMagickVersion() {
  564. $commandline = $this->ImageMagickCommandlineBase();
  565. if (!empty($commandline)) {
  566. $commandline .= ' -version';
  567. $versionstring = phpthumb_functions::SafeBackTick($commandline);
  568. if (eregi('^Version: (.*) http', $versionstring, $matches)) {
  569. return $matches[1];
  570. }
  571. $this->DebugMessage('ImageMagick did not return recognized version string ('.$versionstring.')', __FILE__, __LINE__);
  572. return $versionstring;
  573. }
  574. return false;
  575. }
  576. function ImageMagickThumbnailToGD() {
  577. // http://freealter.org/doc_distrib/ImageMagick-5.1.1/www/convert.html
  578. if (ini_get('safe_mode')) {
  579. $this->DebugMessage('ImageMagickThumbnailToGD() aborting because safe_mode is enabled', __FILE__, __LINE__);
  580. return false;
  581. }
  582. if (!function_exists('ImageCreateFromPNG')) {
  583. // ImageMagickThumbnailToGD() depends on ImageCreateFromPNG()
  584. $this->DebugMessage('ImageMagickThumbnailToGD() aborting because ImageCreateFromPNG() is not available', __FILE__, __LINE__);
  585. return false;
  586. }
  587. $commandline = $this->ImageMagickCommandlineBase();
  588. if (!empty($commandline)) {
  589. if ($IMtempfilename = $this->phpthumb_tempnam()) {
  590. $IMtempfilename = realpath($IMtempfilename);
  591. $IMwidth = ((intval($this->w) > 0) ? intval($this->w) : 640);
  592. $IMheight = ((intval($this->h) > 0) ? intval($this->h) : 480);
  593. if (!$this->aoe && !$this->iar && ($getimagesize = @GetImageSize($this->sourceFilename))) {
  594. // limit output size to input size unless AllowOutputEnlargement is enabled
  595. $IMwidth = min($IMwidth, $getimagesize[0]);
  596. $IMheight = min($IMheight, $getimagesize[1]);
  597. }
  598. //$commandline .= ' -resize '.$IMwidth.'x'.$IMheight; // behaves badly with IM v5.3.x
  599. $commandline .= ' -geometry '.$IMwidth.'x'.$IMheight;
  600. if (!empty($this->iar) && (intval($this->w) > 0) && (intval($this->h) > 0)) {
  601. $commandline .= '!';
  602. }
  603. $commandline .= ' "'.str_replace('/', $this->osslash, $this->sourceFilename).'"';
  604. $commandline .= ' png:'.$IMtempfilename;
  605. $commandline .= ' 2>&1';
  606. $IMresult = phpthumb_functions::SafeBackTick($commandline);
  607. if (!empty($IMresult)) {
  608. //return $this->ErrorImage('ImageMagick was called as:'."\n".$commandline."\n\n".'but failed with message:'."\n".$IMresult);
  609. $this->DebugMessage('ImageMagick was called as ('.$commandline.') but failed with message ('.$IMresult.')', __FILE__, __LINE__);
  610. } elseif ($this->gdimg_source = @ImageCreateFromPNG($IMtempfilename)) {
  611. unlink($IMtempfilename);
  612. $this->source_width = ImageSX($this->gdimg_source);
  613. $this->source_height = ImageSY($this->gdimg_source);
  614. $this->DebugMessage('ImageMagickThumbnailToGD() succeeded, $this->gdimg_source is now ('.$this->source_width.'x'.$this->source_height.')', __FILE__, __LINE__);
  615. return true;
  616. }
  617. unlink($IMtempfilename);
  618. } else {
  619. $this->DebugMessage('ImageMagickThumbnailToGD() aborting, phpthumb_tempnam() failed', __FILE__, __LINE__);
  620. }
  621. }
  622. $this->DebugMessage('ImageMagickThumbnailToGD() aborting because ImageMagickCommandlineBase() failed', __FILE__, __LINE__);
  623. return false;
  624. }
  625. function Rotate() {
  626. if (!empty($this->ra) || !empty($this->ar)) {
  627. if (!function_exists('ImageRotate')) {
  628. $this->DebugMessage('!function_exists(ImageRotate)', __FILE__, __LINE__);
  629. return false;
  630. }
  631. if (!include_once(dirname(__FILE__).'/phpthumb.filters.php')) {
  632. $this->DebugMessage('Error including "'.dirname(__FILE__).'/phpthumb.filters.php" which is required for applying filters ('.implode(';', $this->fltr).')', __FILE__, __LINE__);
  633. return false;
  634. }
  635. $this->config_background_hexcolor = (!empty($this->bg) ? $this->bg : $this->config_background_hexcolor);
  636. if (!phpthumb_functions::IsHexColor($this->config_background_hexcolor)) {
  637. return $this->ErrorImage('Invalid hex color string "'.$this->config_background_hexcolor.'" for parameter "bg"');
  638. }
  639. $rotate_angle = 0;
  640. if (!empty($this->ra)) {
  641. $rotate_angle = floatval($this->ra);
  642. } else {
  643. if ($this->ar == 'x') {
  644. if (phpthumb_functions::version_compare_replacement(phpversion(), '4.2.0', '>=')) {
  645. if ($this->sourceFilename) {
  646. if (function_exists('exif_read_data')) {
  647. if ($exif_data = @exif_read_data($this->sourceFilename, 'IFD0')) {
  648. // http://sylvana.net/jpegcrop/exif_orientation.html
  649. switch (@$exif_data['Orientation']) {
  650. case 1:
  651. $rotate_angle = 0;
  652. break;
  653. case 3:
  654. $rotate_angle = 180;
  655. break;
  656. case 6:
  657. $rotate_angle = 270;
  658. break;
  659. case 8:
  660. $rotate_angle = 90;
  661. break;
  662. default:
  663. $this->DebugMessage('EXIF auto-rotate failed because unknown $exif_data[Orientation] "'.@$exif_data['Orientation'].'"', __FILE__, __LINE__);
  664. return false;
  665. break;
  666. }
  667. $this->DebugMessage('EXIF auto-rotate set to '.$rotate_angle.' degrees ($exif_data[Orientation] = "'.@$exif_data['Orientation'].'")', __FILE__, __LINE__);
  668. } else {
  669. $this->DebugMessage('failed: exif_read_data('.$this->sourceFilename.')', __FILE__, __LINE__);
  670. return false;
  671. }
  672. } else {
  673. $this->DebugMessage('!function_exists(exif_read_data)', __FILE__, __LINE__);
  674. return false;
  675. }
  676. } else {
  677. $this->DebugMessage('Cannot auto-rotate from EXIF data because $this->sourceFilename is empty', __FILE__, __LINE__);
  678. return false;
  679. }
  680. } else {
  681. $this->DebugMessage('Cannot auto-rotate from EXIF data because PHP is less than v4.2.0 ('.phpversion().')', __FILE__, __LINE__);
  682. return false;
  683. }
  684. } elseif (($this->ar == 'l') && ($this->source_height > $this->source_width)) {
  685. $rotate_angle = 270;
  686. } elseif (($this->ar == 'L') && ($this->source_height > $this->source_width)) {
  687. $rotate_angle = 90;
  688. } elseif (($this->ar == 'p') && ($this->source_width > $this->source_height)) {
  689. $rotate_angle = 90;
  690. } elseif (($this->ar == 'P') && ($this->source_width > $this->source_height)) {
  691. $rotate_angle = 270;
  692. }
  693. }
  694. while ($rotate_angle < 0) {
  695. $rotate_angle += 360;
  696. }
  697. $rotate_angle = $rotate_angle % 360;
  698. if ($rotate_angle != 0) {
  699. $background_color = phpthumb_functions::ImageHexColorAllocate($this->gdimg_source, $this->config_background_hexcolor);
  700. if ((phpthumb_functions::gd_version() >= 2) && ($this->thumbnailFormat == 'png') && !$this->bg && ($rotate_angle % 90)) {
  701. if ($gdimg_rotate_mask = phpthumb_functions::ImageCreateFunction(ImageSX($this->gdimg_source), ImageSY($this->gdimg_source))) {
  702. $this->gdimg_source = ImageRotate($this->gdimg_source, $rotate_angle, $background_color);
  703. $color_mask_opaque = ImageColorAllocate($gdimg_rotate_mask, 0xFF, 0xFF, 0xFF);
  704. $color_mask_transparent = ImageColorAllocate($gdimg_rotate_mask, 0x00, 0x00, 0x00);
  705. ImageFilledRectangle($gdimg_rotate_mask, 0, 0, ImageSX($gdimg_rotate_mask), ImageSY($gdimg_rotate_mask), $color_mask_opaque);
  706. $gdimg_rotate_mask = ImageRotate($gdimg_rotate_mask, $rotate_angle, $color_mask_transparent);
  707. ImageAlphaBlending($this->gdimg_source, false);
  708. if (phpthumb_functions::version_compare_replacement(phpversion(), '4.3.2', '>=')) {
  709. ImageSaveAlpha($this->gdimg_source, true);
  710. }
  711. $this->is_alpha = true;
  712. phpthumb_filters::ApplyMask($gdimg_rotate_mask, $this->gdimg_source);
  713. ImageDestroy($gdimg_rotate_mask);
  714. $this->source_width = ImageSX($this->gdimg_source);
  715. $this->source_height = ImageSY($this->gdimg_source);
  716. } else {
  717. $this->DebugMessage('ImageCreateFromStringReplacement() failed for "'.$MaskFilename.'"', __FILE__, __LINE__);
  718. }
  719. } else {
  720. if (phpthumb_functions::gd_version() >= 2) {
  721. $this->DebugMessage('Using non-alpha rotate because gd_version is "'.phpthumb_functions::gd_version().'"', __FILE__, __LINE__);
  722. } else {
  723. $this->DebugMessage('Using non-alpha rotate because $this->thumbnailFormat is "'.$this->thumbnailFormat.'"', __FILE__, __LINE__);
  724. }
  725. if (ImageColorTransparent($this->gdimg_source) >= 0) {
  726. // ImageRotate() forgets all about an image's transparency and sets the transparent color to black
  727. // To compensate, flood-fill the transparent color of the source image with the specified background color first
  728. // then rotate and the colors should match
  729. if (!function_exists('ImageIsTrueColor') || !ImageIsTrueColor($this->gdimg_source)) {
  730. // convert paletted image to true-color before rotating to prevent nasty aliasing artifacts
  731. $this->source_width = ImageSX($this->gdimg_source);
  732. $this->source_height = ImageSY($this->gdimg_source);
  733. $gdimg_newsrc = phpthumb_functions::ImageCreateFunction($this->source_width, $this->source_height);
  734. $background_color = phpthumb_functions::ImageHexColorAllocate($gdimg_newsrc, $this->config_background_hexcolor);
  735. ImageFilledRectangle($gdimg_newsrc, 0, 0, $this->source_width, $this->source_height, phpthumb_functions::ImageHexColorAllocate($gdimg_newsrc, $this->config_background_hexcolor));
  736. ImageCopy($gdimg_newsrc, $this->gdimg_source, 0, 0, 0, 0, $this->source_width, $this->source_height);
  737. ImageDestroy($this->gdimg_source);
  738. unset($this->gdimg_source);
  739. $this->gdimg_source = $gdimg_newsrc;
  740. unset($gdimg_newsrc);
  741. } else {
  742. ImageColorSet(
  743. $this->gdimg_source,
  744. ImageColorTransparent($this->gdimg_source),
  745. hexdec(substr($this->config_background_hexcolor, 0, 2)),
  746. hexdec(substr($this->config_background_hexcolor, 2, 2)),
  747. hexdec(substr($this->config_background_hexcolor, 4, 2)));
  748. ImageColorTransparent($this->gdimg_source, -1);
  749. }
  750. }
  751. $this->gdimg_source = ImageRotate($this->gdimg_source, $rotate_angle, $background_color);
  752. $this->source_width = ImageSX($this->gdimg_source);
  753. $this->source_height = ImageSY($this->gdimg_source);
  754. }
  755. }
  756. }
  757. return true;
  758. }
  759. function FixedAspectRatio() {
  760. // optional fixed-dimension images (regardless of aspect ratio)
  761. if (isset($this->far)) {
  762. $this->is_alpha;
  763. if ($this->thumbnail_image_width >= $this->thumbnail_width) {
  764. if (isset($this->w)) {
  765. $aspectratio = $this->thumbnail_image_height / $this->thumbnail_image_width;
  766. $this->thumbnail_image_height = round($this->thumbnail_image_width * $aspectratio);
  767. if (!isset($this->h)) {
  768. $this->thumbnail_height = $this->thumbnail_image_height;
  769. }
  770. } elseif ($this->thumbnail_image_height < $this->thumbnail_height) {
  771. $this->thumbnail_image_height = $this->thumbnail_height;
  772. $this->thumbnail_image_width = round($this->thumbnail_image_height / $aspectratio);
  773. }
  774. } else {
  775. if (isset($this->h)) {
  776. $aspectratio = $this->thumbnail_image_width / $this->thumbnail_image_height;
  777. $this->thumbnail_image_width = round($this->thumbnail_image_height * $aspectratio);
  778. } elseif ($this->thumbnail_image_width < $this->thumbnail_width) {
  779. $this->thumbnail_image_width = $this->thumbnail_width;
  780. $this->thumbnail_image_height = round($this->thumbnail_image_width / $aspectratio);
  781. }
  782. }
  783. }
  784. return true;
  785. }
  786. function AntiOffsiteLinking() {
  787. // Optional anti-offsite hijacking of the thumbnail script
  788. $allow = true;
  789. if ($allow && $this->config_nooffsitelink_enabled && $this->config_nooffsitelink_require_refer) {
  790. $this->DebugMessage('AntiOffsiteLinking() checking $_SERVER[HTTP_REFERER] "'.@$_SERVER['HTTP_REFERER'].'"', __FILE__, __LINE__);
  791. $parsed_url = parse_url(@$_SERVER['HTTP_REFERER']);
  792. if (!in_array(@$parsed_url['host'], $this->config_nooffsitelink_valid_domains)) {
  793. $allow = false;
  794. $erase = $this->config_nooffsitelink_erase_image;
  795. $message = $this->config_nooffsitelink_text_message;
  796. $this->DebugMessage('AntiOffsiteLinking() - "'.@$parsed_url['host'].'" is NOT in $this->config_nooffsitelink_valid_domains ('.implode(';', $this->config_nooffsitelink_valid_domains).')', __FILE__, __LINE__);
  797. } else {
  798. $this->DebugMessage('AntiOffsiteLinking() - "'.@$parsed_url['host'].'" is in $this->config_nooffsitelink_valid_domains ('.implode(';', $this->config_nooffsitelink_valid_domains).')', __FILE__, __LINE__);
  799. }
  800. }
  801. if ($allow && $this->config_nohotlink_enabled && eregi('^(f|ht)tp[s]?://', $this->src)) {
  802. $parsed_url = parse_url($this->src);
  803. if (!in_array(@$parsed_url['host'], $this->config_nohotlink_valid_domains)) {
  804. // This domain is not allowed
  805. $allow = false;
  806. $erase = $this->config_nohotlink_erase_image;
  807. $message = $this->config_nohotlink_text_message;
  808. $this->DebugMessage('AntiOffsiteLinking() - "'.$parsed_url['host'].'" is NOT in $this->config_nohotlink_valid_domains ('.implode(';', $this->config_nohotlink_valid_domains).')', __FILE__, __LINE__);
  809. } else {
  810. $this->DebugMessage('AntiOffsiteLinking() - "'.$parsed_url['host'].'" is in $this->config_nohotlink_valid_domains ('.implode(';', $this->config_nohotlink_valid_domains).')', __FILE__, __LINE__);
  811. }
  812. }
  813. if ($allow) {
  814. $this->DebugMessage('AntiOffsiteLinking() says this is allowed', __FILE__, __LINE__);
  815. return true;
  816. }
  817. if (!phpthumb_functions::IsHexColor($this->config_error_bgcolor)) {
  818. return $this->ErrorImage('Invalid hex color string "'.$this->config_error_bgcolor.'" for $this->config_error_bgcolor');
  819. }
  820. if (!phpthumb_functions::IsHexColor($this->config_error_textcolor)) {
  821. return $this->ErrorImage('Invalid hex color string "'.$this->config_error_textcolor.'" for $this->config_error_textcolor');
  822. }
  823. if ($erase) {
  824. return $this->ErrorImage($message, $this->thumbnail_width, $this->thumbnail_height, $this->config_error_bgcolor, $this->config_error_textcolor, $this->config_error_fontsize);
  825. } else {
  826. $nohotlink_text_array = explode("\n", wordwrap($message, floor($this->thumbnail_width / ImageFontWidth($this->config_error_fontsize)), "\n"));
  827. $nohotlink_text_color = phpthumb_functions::ImageHexColorAllocate($this->gdimg_output, $this->config_error_textcolor);
  828. $topoffset = round(($this->thumbnail_height - (count($nohotlink_text_array) * ImageFontHeight($this->config_error_fontsize))) / 2);
  829. $rowcounter = 0;
  830. $this->DebugMessage('AntiOffsiteLinking() writing '.count($nohotlink_text_array).' lines of text "'.$message.'" (in #'.$this->config_error_textcolor.') on top of image', __FILE__, __LINE__);
  831. foreach ($nohotlink_text_array as $textline) {
  832. $leftoffset = max(0, round(($this->thumbnail_width - (strlen($textline) * ImageFontWidth($this->config_error_fontsize))) / 2));
  833. ImageString($this->gdimg_output, $this->config_error_fontsize, $leftoffset, $topoffset + ($rowcounter++ * ImageFontHeight($this->config_error_fontsize)), $textline, $nohotlink_text_color);
  834. }
  835. }
  836. return true;
  837. }
  838. function AlphaChannelFlatten() {
  839. if (!$this->is_alpha) {
  840. // image doesn't have alpha transparency, no need to flatten
  841. $this->DebugMessage('skipping AlphaChannelFlatten() because !$this->is_alpha', __FILE__, __LINE__);
  842. return false;
  843. }
  844. if ($this->thumbnailFormat == 'png') {
  845. // image has alpha transparency, but output as PNG which can handle it
  846. $this->DebugMessage('skipping AlphaChannelFlatten() because ($this->thumbnailFormat == "'.$this->thumbnailFormat.'")', __FILE__, __LINE__);
  847. return false;
  848. } elseif ($this->thumbnailFormat == 'gif') {
  849. // image has alpha transparency, but output as GIF which can handle only single-color transparency
  850. $CurrentImageColorTransparent = ImageColorTransparent($this->gdimg_output);
  851. if ($CurrentImageColorTransparent == -1) {
  852. // no transparent color defined
  853. if (phpthumb_functions::gd_version() < 2.0) {
  854. $this->DebugMessage('AlphaChannelFlatten() failed because GD version is "'.phpthumb_functions::gd_version().'"', __FILE__, __LINE__);
  855. return false;
  856. }
  857. if ($img_alpha_mixdown_dither = @ImageCreateTrueColor(ImageSX($this->gdimg_output), ImageSY($this->gdimg_output))) {
  858. for ($i = 0; $i <= 255; $i++) {
  859. $dither_color[$i] = ImageColorAllocate($img_alpha_mixdown_dither, $i, $i, $i);
  860. }
  861. // scan through current truecolor image copy alpha channel to temp image as grayscale
  862. for ($x = 0; $x < $this->thumbnail_width; $x++) {
  863. for ($y = 0; $y < $this->thumbnail_height; $y++) {
  864. $PixelColor = phpthumb_functions::GetPixelColor($this->gdimg_output, $x, $y);
  865. ImageSetPixel($img_alpha_mixdown_dither, $x, $y, $dither_color[($PixelColor['alpha'] * 2)]);
  866. }
  867. }
  868. // dither alpha channel grayscale version down to 2 colors
  869. ImageTrueColorToPalette($img_alpha_mixdown_dither, true, 2);
  870. // reduce color palette to 256-1 colors (leave one palette position for transparent color)
  871. ImageTrueColorToPalette($this->gdimg_output, true, 255);
  872. // allocate a new color for transparent color index
  873. $TransparentColor = ImageColorAllocate($this->gdimg_output, 1, 254, 253);
  874. ImageColorTransparent($this->gdimg_output, $TransparentColor);
  875. // scan through alpha channel image and note pixels with >50% transparency
  876. $TransparentPixels = array();
  877. for ($x = 0; $x < $this->thumbnail_width; $x++) {
  878. for ($y = 0; $y < $this->thumbnail_height; $y++) {
  879. $AlphaChannelPixel = phpthumb_functions::GetPixelColor($img_alpha_mixdown_dither, $x, $y);
  880. if ($AlphaChannelPixel['red'] > 127) {
  881. ImageSetPixel($this->gdimg_output, $x, $y, $TransparentColor);
  882. }
  883. }
  884. }
  885. ImageDestroy($img_alpha_mixdown_dither);
  886. $this->DebugMessage('AlphaChannelFlatten() set image to 255+1 colors with transparency for GIF output', __FILE__, __LINE__);
  887. return true;
  888. } else {
  889. $this->DebugMessage('AlphaChannelFlatten() failed ImageCreate('.ImageSX($this->gdimg_output).', '.ImageSY($this->gdimg_output).')', __FILE__, __LINE__);
  890. return false;
  891. }
  892. } else {
  893. // a single transparent color already defined, leave as-is
  894. $this->DebugMessage('skipping AlphaChannelFlatten() because ($this->thumbnailFormat == "'.$this->thumbnailFormat.'") and ImageColorTransparent returned "'.$CurrentImageColorTransparent.'"', __FILE__, __LINE__);
  895. return true;
  896. }
  897. }
  898. $this->DebugMessage('continuing AlphaChannelFlatten() for output format "'.$this->thumbnailFormat.'"', __FILE__, __LINE__);
  899. // image has alpha transparency, and is being output in a format that doesn't support it -- flatten
  900. if ($gdimg_flatten_temp = phpthumb_functions::ImageCreateFunction($this->thumbnail_width, $this->thumbnail_height)) {
  901. $this->config_background_hexcolor = (!empty($this->bg) ? $this->bg : $this->config_background_hexcolor);
  902. if (!phpthumb_functions::IsHexColor($this->config_background_hexcolor)) {
  903. return $this->ErrorImage('Invalid hex color string "'.$this->config_background_hexcolor.'" for parameter "bg"');
  904. }
  905. $background_color = phpthumb_functions::ImageHexColorAllocate($this->gdimg_output, $this->config_background_hexcolor);
  906. ImageFilledRectangle($gdimg_flatten_temp, 0, 0, $this->thumbnail_width, $this->thumbnail_height, $background_color);
  907. ImageCopy($gdimg_flatten_temp, $this->gdimg_output, 0, 0, 0, 0, $this->thumbnail_width, $this->thumbnail_height);
  908. ImageAlphaBlending($this->gdimg_output, true);
  909. if (phpthumb_functions::version_compare_replacement(phpversion(), '4.3.2', '>=')) {
  910. ImageSaveAlpha($this->gdimg_output, false);
  911. }
  912. ImageColorTransparent($this->gdimg_output, -1);
  913. ImageCopy($this->gdimg_output, $gdimg_flatten_temp, 0, 0, 0, 0, $this->thumbnail_width, $this->thumbnail_height);
  914. ImageDestroy($gdimg_flatten_temp);
  915. return true;
  916. } else {
  917. $this->DebugMessage('ImageCreateFunction() failed', __FILE__, __LINE__);
  918. }
  919. return false;
  920. }
  921. function ApplyFilters() {
  922. if (!empty($this->fltr) && is_array($this->fltr)) {
  923. if (!include_once(dirname(__FILE__).'/phpthumb.filters.php')) {
  924. $this->DebugMessage('Error including "'.dirname(__FILE__).'/phpthumb.filters.php" which is required for applying filters ('.implode(';', $this->fltr).')', __FILE__, __LINE__);
  925. return false;
  926. }
  927. foreach ($this->fltr as $filtercommand) {
  928. @list($command, $parameter) = explode('|', $filtercommand, 2);
  929. $this->DebugMessage('Attempting to process filter command "'.$command.'"', __FILE__, __LINE__);
  930. switch ($command) {
  931. case 'ds':
  932. phpthumb_filters::Desaturate($this->gdimg_output, $parameter, '');
  933. break;
  934. case 'gray':
  935. phpthumb_filters::Desaturate($this->gdimg_output, 100, '');
  936. break;
  937. case 'clr':
  938. if (phpthumb_functions::gd_version() < 2) {
  939. $this->DebugMessage('Skipping Colorize() because gd_version is "'.phpthumb_functions::gd_version().'"', __FILE__, __LINE__);
  940. break;
  941. }
  942. @list($amount, $color) = explode('|', $parameter);
  943. phpthumb_filters::Colorize($this->gdimg_output, $amount, $color);
  944. break;
  945. case 'sep':
  946. if (phpthumb_functions::gd_version() < 2) {
  947. $this->DebugMessage('Skipping Sepia() because gd_version is "'.phpthumb_functions::gd_version().'"', __FILE__, __LINE__);
  948. break;
  949. }
  950. @list($amount, $color) = explode('|', $parameter);
  951. phpthumb_filters::Sepia($this->gdimg_output, $amount, $color);
  952. break;
  953. case 'gam':
  954. phpthumb_filters::Gamma($this->gdimg_output, $parameter);
  955. break;
  956. case 'neg':
  957. phpthumb_filters::Negative($this->gdimg_output);
  958. break;
  959. case 'th':
  960. phpthumb_filters::Threshold($this->gdimg_output, $parameter);
  961. break;
  962. case 'flip':
  963. phpthumb_filters::Flip($this->gdimg_output, (strpos(strtolower($parameter), 'x') !== false), (strpos(strtolower($parameter), 'y') !== false));
  964. break;
  965. case 'bvl':
  966. @list($width, $color1, $color2) = explode('|', $parameter);
  967. phpthumb_filters::Bevel($this->gdimg_output, $width, $color1, $color2);
  968. break;
  969. case 'lvl':
  970. @list($band, $min, $max) = explode('|', $parameter);
  971. $band = ($band ? $band : '*');
  972. $min = ((strlen($min) > 0) ? $min : '-1');
  973. $max = ((strlen($max) > 0) ? $max : '-1');
  974. phpthumb_filters::HistogramStretch($this->gdimg_output, $band, $min, $max);
  975. break;
  976. case 'wb':
  977. phpthumb_filters::WhiteBalance($this->gdimg_output, $parameter);
  978. break;
  979. case 'hist':
  980. if (phpthumb_functions::gd_version() < 2) {
  981. $this->DebugMessage('Skipping HistogramOverlay() because gd_version is "'.phpthumb_functions::gd_version().'"', __FILE__, __LINE__);
  982. break;
  983. }
  984. @list($bands, $colors, $width, $height, $alignment, $opacity, $margin) = explode('|', $parameter);
  985. $bands = ($bands ? $bands : '*');
  986. $colors = ($colors ? $colors : '');
  987. $width = ($width ? $width : 0.25);
  988. $height = ($height ? $height : 0.25);
  989. $alignment = ($alignment ? $alignment : 'BR');
  990. $opacity = ($opacity ? $opacity : 50);
  991. $margin = ($margin ? $margin : 5);
  992. phpthumb_filters::HistogramOverlay($this->gdimg_output, $bands, $colors, $width, $height, $alignment, $opacity, $margin);
  993. break;
  994. case 'fram':
  995. @list($frame_width, $edge_width, $color_frame, $color1, $color2) = explode('|', $parameter);
  996. phpthumb_filters::Frame($this->gdimg_output, $frame_width, $edge_width, $color_frame, $color1, $color2);
  997. break;
  998. case 'drop':
  999. if (phpthumb_functions::gd_version() < 2) {
  1000. $this->DebugMessage('Skipping DropShadow() because gd_version is "'.phpthumb_functions::gd_version().'"', __FILE__, __LINE__);
  1001. return false;
  1002. }
  1003. $this->is_alpha = true;
  1004. @list($distance, $width, $color, $angle, $fade) = explode('|', $parameter);
  1005. phpthumb_filters::DropShadow($this->gdimg_output, $distance, $width, $color, $angle, $fade);
  1006. break;
  1007. case 'mask':
  1008. if (phpthumb_functions::gd_version() < 2) {
  1009. $this->DebugMessage('Skipping Mask() because gd_version is "'.phpthumb_functions::gd_version().'"', __FILE__, __LINE__);
  1010. return false;
  1011. }
  1012. $mask_filename = $this->ResolveFilenameToAbsolute($parameter);
  1013. if (@is_readable($mask_filename) && ($fp_mask = @fopen($mask_filename, 'rb'))) {
  1014. $MaskImageData = fread($fp_mask, filesize($mask_filename));
  1015. fclose($fp_mask);
  1016. if ($gdimg_mask = $this->ImageCreateFromStringReplacement($MaskImageData)) {
  1017. $this->is_alpha = true;
  1018. phpthumb_filters::ApplyMask($gdimg_mask, $this->gdimg_output);
  1019. ImageDestroy($gdimg_mask);
  1020. } else {
  1021. $this->DebugMessage('ImageCreateFromStringReplacement() failed for "'.$mask_filename.'"', __FILE__, __LINE__);
  1022. }
  1023. } else {
  1024. $this->DebugMessage('Cannot open mask file "'.$mask_filename.'"', __FILE__, __LINE__);
  1025. }
  1026. break;
  1027. case 'elip':
  1028. if (phpthumb_functions::gd_version() < 2) {
  1029. $this->DebugMessage('Skipping Elipse() because gd_version is "'.phpthumb_functions::gd_version().'"', __FILE__, __LINE__);
  1030. return false;
  1031. }
  1032. $this->is_alpha = true;
  1033. phpthumb_filters::Elipse($this->gdimg_output);
  1034. break;
  1035. case 'ric':
  1036. if (phpthumb_functions::gd_version() < 2) {
  1037. $this->DebugMessage('Skipping RoundedImageCorners() because gd_version is "'.phpthumb_functions::gd_version().'"', __FILE__, __LINE__);
  1038. return false;
  1039. }
  1040. @list($radius_x, $radius_y) = explode('|', $parameter);
  1041. if (($radius_x < 1) || ($radius_y < 1)) {
  1042. $this->DebugMessage('Skipping RoundedImageCorners('.$radius_x.', '.$radius_y.') because x/y radius is less than 1', __FILE__, __LINE__);
  1043. break;
  1044. }
  1045. $this->is_alpha = true;
  1046. phpthumb_filters::RoundedImageCorners($this->gdimg_output, $radius_x, $radius_y);
  1047. break;
  1048. case 'bord':
  1049. @list($border_width, $radius_x, $radius_y, $hexcolor_border) = explode('|', $parameter);
  1050. $this->is_alpha = true;
  1051. phpthumb_filters::ImageBorder($this->gdimg_output, $border_width, $radius_x, $radius_y, $hexcolor_border);
  1052. break;
  1053. case 'over':
  1054. @list($filename, $underlay, $margin, $opacity) = explode('|', $parameter);
  1055. $underlay = (bool) ($underlay ? $underlay : false);
  1056. $margin = ((strlen($margin) > 0) ? $margin : ($underlay ? 0.1 : 0.0));
  1057. $opacity = ((strlen($opacity) > 0) ? $opacity : 100);
  1058. if (($margin > 0) && ($margin < 1)) {
  1059. $margin = min(0.499, $margin);
  1060. } elseif (($margin > -1) && ($margin < 0)) {
  1061. $margin = max(-0.499, $margin);
  1062. }
  1063. $filename = $this->ResolveFilenameToAbsolute($filename);
  1064. if (@is_readable($filename) && ($fp_watermark = @fopen($filename, 'rb'))) {
  1065. $WatermarkImageData = fread($fp_watermark, filesize($filename));
  1066. fclose($fp_watermark);
  1067. if ($img_watermark = $this->ImageCreateFromStringReplacement($WatermarkImageData)) {
  1068. if ($margin < 1) {
  1069. $resized_x = max(1, ImageSX($this->gdimg_output) - round(2 * (ImageSX($this->gdimg_output) * $margin)));
  1070. $resized_y = max(1, ImageSY($this->gdimg_output) - round(2 * (ImageSY($this->gdimg_output) * $margin)));
  1071. } else {
  1072. $resized_x = max(1, ImageSX($this->gdimg_output) - round(2 * $margin));
  1073. $resized_y = max(1, ImageSY($this->gdimg_output) - round(2 * $margin));
  1074. }
  1075. if ($underlay) {
  1076. if ($img_watermark_resized = phpthumb_functions::ImageCreateFunction(ImageSX($this->gdimg_output), ImageSY($this->gdimg_output))) {
  1077. ImageAlphaBlending($img_watermark_resized, false);
  1078. ImageSaveAlpha($img_watermark_resized, true);
  1079. phpthumb_functions::ImageResizeFunction($img_watermark_resized, $img_watermark, 0, 0, 0, 0, ImageSX($img_watermark_resized), ImageSY($img_watermark_resized), ImageSX($img_watermark), ImageSY($img_watermark));
  1080. if ($img_source_resized = phpthumb_functions::ImageCreateFunction($resized_x, $resized_y)) {
  1081. ImageAlphaBlending($img_source_resized, false);
  1082. ImageSaveAlpha($img_source_resized, true);
  1083. phpthumb_functions::ImageResizeFunction($img_source_resized, $this->gdimg_output, 0, 0, 0, 0, ImageSX($img_source_resized), ImageSY($img_source_resized), ImageSX($this->gdimg_output), ImageSY($this->gdimg_output));
  1084. phpthumb_filters::WatermarkOverlay($img_watermark_resized, $img_source_resized, 'C', $opacity, $margin);
  1085. ImageCopy($this->gdimg_output, $img_watermark_resized, 0, 0, 0, 0, ImageSX($this->gdimg_output), ImageSY($this->gdimg_output));
  1086. } else {
  1087. $this->DebugMessage('phpthumb_functions::ImageCreateFunction('.$resized_x.', '.$resized_y.')', __FILE__, __LINE__);
  1088. }
  1089. ImageDestroy($img_watermark_resized);
  1090. } else {
  1091. $this->DebugMessage('phpthumb_functions::ImageCreateFunction('.ImageSX($this->gdimg_output).', '.ImageSY($this->gdimg_output).')', __FILE__, __LINE__);
  1092. }
  1093. } else { // overlay
  1094. if ($img_watermark_resized = phpthumb_functions::ImageCreateFunction($resized_x, $resized_y)) {
  1095. ImageAlphaBlending($img_watermark_resized, false);
  1096. ImageSaveAlpha($img_watermark_resized, true);
  1097. phpthumb_functions::ImageResizeFunction($img_watermark_resized, $img_watermark, 0, 0, 0, 0, ImageSX($img_watermark_resized), ImageSY($img_watermark_resized), ImageSX($img_watermark), ImageSY($img_watermark));
  1098. phpthumb_filters::WatermarkOverlay($this->gdimg_output, $img_watermark_resized, 'C', $opacity, $margin);
  1099. ImageDestroy($img_watermark_resized);
  1100. } else {
  1101. $this->DebugMessage('phpthumb_functions::ImageCreateFunction('.$resized_x.', '.$resized_y.')', __FILE__, __LINE__);
  1102. }
  1103. }
  1104. ImageDestroy($img_watermark);
  1105. } else {
  1106. $this->DebugMessage('ImageCreateFromStringReplacement() failed for "'.$filename.'"', __FILE__, __LINE__);
  1107. }
  1108. } else {
  1109. $this->DebugMessage('Cannot open overlay file "'.$filename.'"', __FILE__, __LINE__);
  1110. }
  1111. break;
  1112. case 'wmi':
  1113. @list($filename, $alignment, $opacity, $margin) = explode('|', $parameter);
  1114. $alignment = ($alignment ? $alignment : 'BR');
  1115. $opacity = (isset($opacity) ? $opacity : 50);
  1116. $margin = (isset($margin) ? $margin : 5);
  1117. $filename = $this->ResolveFilenameToAbsolute($filename);
  1118. if (@is_readable($filename) && ($fp_watermark = @fopen($filename, 'rb'))) {
  1119. $WatermarkImageData = fread($fp_watermark, filesize($filename));
  1120. fclose($fp_watermark);
  1121. if ($img_watermark = $this->ImageCreateFromStringReplacement($WatermarkImageData)) {
  1122. // great
  1123. phpthumb_filters::WatermarkOverlay($this->gdimg_output, $img_watermark, $alignment, $opacity, $margin);
  1124. ImageDestroy($img_watermark);
  1125. } else {
  1126. $this->DebugMessage('ImageCreateFromStringReplacement() failed for "'.$filename.'"', __FILE__, __LINE__);
  1127. }
  1128. } else {
  1129. $this->DebugMessage('Cannot open watermark file "'.$filename.'"', __FILE__, __LINE__);
  1130. }
  1131. break;
  1132. case 'wmt':
  1133. @list($text, $size, $alignment, $hex_color, $ttffont, $opacity, $margin, $angle) = explode('|', $parameter);
  1134. $text = ($text ? $text : '');
  1135. $size = ($size ? $size : 3);
  1136. $alignment = ($alignment ? $alignment : 'BR');
  1137. $hex_color = ($hex_color ? $hex_color : '000000');
  1138. $ttffont = ($ttffont ? $ttffont : '');
  1139. $opacity = (isset($opacity) ? $opacity : 50);
  1140. $margin = (isset($margin) ? $margin : 5);
  1141. $angle = (isset($angle) ? $angle : 0);
  1142. if (basename($ttffont) == $ttffont) {
  1143. $ttffont = realpath($this->config_ttf_directory.'/'.$ttffont);
  1144. } else {
  1145. $ttffont = $this->ResolveFilenameToAbsolute($ttffont);
  1146. }
  1147. phpthumb_filters::WatermarkText($this->gdimg_output, $text, $size, $alignment, $hex_color, $ttffont, $opacity, $margin, $angle);
  1148. break;
  1149. case 'blur':
  1150. @list($radius) = explode('|', $parameter);
  1151. $radius = ($radius ? $radius : 1);
  1152. if (phpthumb_functions::gd_version() < 2) {
  1153. $this->DebugMessage('Skipping Blur() because gd_version is "'.phpthumb_functions::gd_version().'"', __FILE__, __LINE__);
  1154. return false;
  1155. }
  1156. phpthumb_filters::Blur($this->gdimg_output, $radius);
  1157. break;
  1158. case 'usm':
  1159. @list($amount, $radius, $threshold) = explode('|', $parameter);
  1160. $amount = ($amount ? $amount : 80);
  1161. $radius = ($radius ? $radius : 0.5);
  1162. $threshold = (isset($threshold) ? $threshold : 3);
  1163. if (phpthumb_functions::gd_version() >= 2.0) {
  1164. ob_start();
  1165. if (!@include_once(dirname(__FILE__).'/phpthumb.unsharp.php')) {
  1166. $include_error = ob_get_contents();
  1167. if ($include_error) {
  1168. $this->DebugMessage('include_once("'.dirname(__FILE__).'/phpthumb.unsharp.php") generated message: "'.$include_error.'"', __FILE__, __LINE__);
  1169. }
  1170. ob_end_clean();
  1171. $this->DebugMessage('Error including "'.dirname(__FILE__).'/phpthumb.unsharp.php" which is required for unsharp masking', __FILE__, __LINE__);
  1172. return false;
  1173. }
  1174. ob_end_clean();
  1175. phpUnsharpMask::applyUnsharpMask($this->gdimg_output, $amount, $radius, $threshold);
  1176. } else {
  1177. $this->DebugMessage('Skipping unsharp mask because gd_version is "'.phpthumb_functions::gd_version().'"', __FILE__, __LINE__);
  1178. return false;
  1179. }
  1180. break;
  1181. }
  1182. }
  1183. }
  1184. return true;
  1185. }
  1186. function MaxFileSize() {
  1187. if (phpthumb_functions::gd_version() < 2) {
  1188. $this->DebugMessage('Skipping MaxFileSize() because gd_version is "'.phpthumb_functions::gd_version().'"', __FILE__, __LINE__);
  1189. return false;
  1190. }
  1191. if (!empty($this->maxb) && ($this->maxb > 0)) {
  1192. switch ($this->thumbnailFormat) {
  1193. case 'png':
  1194. case 'gif':
  1195. $imgRenderFunction = 'image'.$this->thumbnailFormat;
  1196. ob_start();
  1197. $imgRenderFunction($this->gdimg_output);
  1198. $imgdata = ob_get_contents();
  1199. ob_end_clean();
  1200. if (strlen($imgdata) > $this->maxb) {
  1201. for ($i = 8; $i >= 1; $i--) {
  1202. $tempIMG = ImageCreateTrueColor(ImageSX($this->gdimg_output), ImageSY($this->gdimg_output));
  1203. ImageCopy($tempIMG, $this->gdimg_output, 0, 0, 0, 0, ImageSX($this->gdimg_output), ImageSY($this->gdimg_output));
  1204. ImageTrueColorToPalette($tempIMG, true, pow(2, $i));
  1205. ob_start();
  1206. $imgRenderFunction($tempIMG);
  1207. $imgdata = ob_get_contents();
  1208. ob_end_clean();
  1209. if (strlen($imgdata) <= $this->maxb) {
  1210. ImageTrueColorToPalette($this->gdimg_output, true, pow(2, $i));
  1211. break;
  1212. }
  1213. }
  1214. }
  1215. if (strlen($imgdata) > $this->maxb) {
  1216. ImageTrueColorToPalette($this->gdimg_output, true, pow(2, $i));
  1217. return false;
  1218. }
  1219. break;
  1220. case 'jpeg':
  1221. ob_start();
  1222. ImageJPEG($this->gdimg_output);
  1223. $imgdata = ob_get_contents();
  1224. ob_end_clean();
  1225. $OriginalJPEGquality = $this->thumbnailQuality;
  1226. if (strlen($imgdata) > $this->maxb) {
  1227. for ($i = 3; $i < 20; $i++) {
  1228. $q = round(100 * (1 - log10($i / 2)));
  1229. ob_start();
  1230. ImageJPEG($this->gdimg_output, '', $q);
  1231. $imgdata = ob_get_contents();
  1232. ob_end_clean();
  1233. $this->thumbnailQuality = $q;
  1234. if (strlen($imgdata) <= $this->maxb) {
  1235. break;
  1236. }
  1237. }
  1238. }
  1239. if (strlen($imgdata) > $this->maxb) {
  1240. return false;
  1241. }
  1242. break;
  1243. default:
  1244. return false;
  1245. break;
  1246. }
  1247. }
  1248. return true;
  1249. }
  1250. function CalculateThumbnailDimensions() {
  1251. $this->thumbnailCropX = (!empty($this->sx) ? (($this->sx >= 1) ? $this->sx : round($this->sx * $this->source_width)) : 0);
  1252. $this->thumbnailCropY = (!empty($this->sy) ? (($this->sy >= 1) ? $this->sy : round($this->sy * $this->source_height)) : 0);
  1253. $this->thumbnailCropW = (!empty($this->sw) ? (($this->sw >= 1) ? $this->sw : round($this->sw * $this->source_width)) : $this->source_width);
  1254. $this->thumbnailCropH = (!empty($this->sh) ? (($this->sh >= 1) ? $this->sh : round($this->sh * $this->source_height)) : $this->source_height);
  1255. // limit source area to original image area
  1256. $this->thumbnailCropW = max(1, min($this->thumbnailCropW, $this->source_width - $this->thumbnailCropX));
  1257. $this->thumbnailCropH = max(1, min($this->thumbnailCropH, $this->source_height - $this->thumbnailCropY));
  1258. $this->DebugMessage('CalculateThumbnailDimensions() [x,y,w,h] initially set to ['.$this->thumbnailCropX.','.$this->thumbnailCropY.','.$this->thumbnailCropW.','.$this->thumbnailCropH.']', __FILE__, __LINE__);
  1259. if (!empty($this->zc) && !empty($this->w) && !empty($this->h)) {
  1260. // Zoom Crop
  1261. // retain proportional resizing we did above, but crop off larger dimension so smaller
  1262. // dimension fully fits available space
  1263. $scaling_X = $this->source_width / $this->w;
  1264. $scaling_Y = $this->source_height / $this->h;
  1265. if ($scaling_X > $scaling_Y) {
  1266. // some of the width will need to be cropped
  1267. $allowable_width = $this->source_width / $scaling_X * $scaling_Y;
  1268. $this->thumbnailCropW = round($allowable_width);
  1269. $this->thumbnailCropX = round(($this->source_width - $allowable_width) / 2);
  1270. } elseif ($scaling_Y > $scaling_X) {
  1271. // some of the height will need to be cropped
  1272. $allowable_height = $this->source_height / $scaling_Y * $scaling_X;
  1273. $this->thumbnailCropH = round($allowable_height);
  1274. $this->thumbnailCropY = round(($this->source_height - $allowable_height) / 2);
  1275. } else {
  1276. // image fits perfectly, no cropping needed
  1277. }
  1278. }
  1279. if (!empty($this->iar) && !empty($this->w) && !empty($this->h)) {
  1280. // Ignore Aspect Ratio
  1281. // forget all the careful proportional resizing we did above, stretch image to fit 'w' && 'h'
  1282. $this->thumbnail_width = $this->w;
  1283. $this->thumbnail_height = $this->h;
  1284. $this->thumbnail_image_width = $this->thumbnail_width;
  1285. $this->thumbnail_image_height = $this->thumbnail_height;
  1286. } else {
  1287. // default new width and height to source area
  1288. $this->thumbnail_image_width = $this->thumbnailCropW;
  1289. $this->thumbnail_image_height = $this->thumbnailCropH;
  1290. if (($this->config_output_maxwidth > 0) && ($this->thumbnail_image_width > $this->config_output_maxwidth)) {
  1291. if (($this->config_output_maxwidth < $this->thumbnailCropW) || $this->config_output_allow_enlarging) {
  1292. $maxwidth = $this->config_output_maxwidth;
  1293. $this->thumbnail_image_width = $maxwidth;
  1294. $this->thumbnail_image_height = round($this->thumbnailCropH * ($this->thumbnail_image_width / $this->thumbnailCropW));
  1295. }
  1296. }
  1297. // if user sets width, save as max width
  1298. // and compute new height based on source area aspect ratio
  1299. if (!empty($this->w)) {
  1300. if (($this->w < $this->thumbnailCropW) || $this->config_output_allow_enlarging) {
  1301. $maxwidth = $this->w;
  1302. $this->thumbnail_image_width = $this->w;
  1303. $this->thumbnail_image_height = round($this->thumbnailCropH * $this->w / $this->thumbnailCropW);
  1304. }
  1305. }
  1306. // if user sets height, save as max height
  1307. // if the max width has already been set and the new image is too tall,
  1308. // compute new width based on source area aspect ratio
  1309. // otherwise, use max height and compute new width
  1310. if (!empty($this->h) || ($this->config_output_maxheight > 0)) {
  1311. $maxheight = (!empty($this->h) ? $this->h : $this->config_output_maxheight);
  1312. if (($maxheight < $this->thumbnailCropH) || $this->config_output_allow_enlarging) {
  1313. if (isset($maxwidth)) {
  1314. if ($this->thumbnail_image_height > $maxheight) {
  1315. $this->thumbnail_image_width = round($this->thumbnailCropW * $maxheight / $this->thumbnailCropH);
  1316. $this->thumbnail_image_height = $maxheight;
  1317. }
  1318. } else {
  1319. $this->thumbnail_image_height = $maxheight;
  1320. $this->thumbnail_image_width = round($this->thumbnailCropW * $this->thumbnail_image_height / $this->thumbnailCropH);
  1321. }
  1322. }
  1323. }
  1324. $this->thumbnail_width = $this->thumbnail_image_width;
  1325. $this->thumbnail_height = $this->thumbnail_image_height;
  1326. if (!empty($this->w) && !empty($this->h) && isset($this->far)) {
  1327. $this->thumbnail_width = $this->w;
  1328. $this->thumbnail_height = $this->h;
  1329. }
  1330. $this->FixedAspectRatio();
  1331. }
  1332. return true;
  1333. }
  1334. function CreateGDoutput() {
  1335. $this->CalculateThumbnailDimensions();
  1336. $this->thumbnail_width = max(1, $this->thumbnail_width);
  1337. $this->thumbnail_height = max(1, $this->thumbnail_height);
  1338. // Create the GD image (either true-color or 256-color, depending on GD version)
  1339. $this->gdimg_output = phpthumb_functions::ImageCreateFunction($this->thumbnail_width, $this->thumbnail_height);
  1340. // Images that have transparency must have the background filled with the configured 'bg' color
  1341. // otherwise the transparent color will appear as black
  1342. if (phpthumb_functions::version_compare_replacement(phpversion(), '4.3.2', '>=')) {
  1343. ImageSaveAlpha($this->gdimg_output, true);
  1344. }
  1345. if ($this->is_alpha && phpthumb_functions::gd_version() >= 2) {
  1346. ImageAlphaBlending($this->gdimg_output, false);
  1347. $output_full_alpha = phpthumb_functions::ImageColorAllocateAlphaSafe($this->gdimg_output, 255, 255, 255, 127);
  1348. ImageFilledRectangle($this->gdimg_output, 0, 0, $this->thumbnail_width, $this->thumbnail_height, $output_full_alpha);
  1349. } else {
  1350. $current_transparent_color = ImageColorTransparent($this->gdimg_source);
  1351. if ($this->bg || (@$current_transparent_color >= 0)) {
  1352. $this->config_background_hexcolor = ($this->bg ? $this->bg : $this->config_background_hexcolor);
  1353. if (!phpthumb_functions::IsHexColor($this->config_background_hexcolor)) {
  1354. return $this->ErrorImage('Invalid hex color string "'.$this->config_background_hexcolor.'" for parameter "bg"');
  1355. }
  1356. $background_color = phpthumb_functions::ImageHexColorAllocate($this->gdimg_output, $this->config_background_hexcolor);
  1357. ImageFilledRectangle($this->gdimg_output, 0, 0, $this->thumbnail_width, $this->thumbnail_height, $background_color);
  1358. }
  1359. }
  1360. return true;
  1361. }
  1362. function ExtractEXIFgetImageSize() {
  1363. if (is_resource($this->gdimg_source)) {
  1364. $this->source_width = ImageSX($this->gdimg_source);
  1365. $this->source_height = ImageSY($this->gdimg_source);
  1366. } elseif ($this->rawImageData && !$this->sourceFilename) {
  1367. $this->DebugMessage('bypassing EXIF and GetImageSize sections because $this->rawImageData is set and $this->sourceFilename is not', __FILE__, __LINE__);
  1368. } elseif ($this->getimagesizeinfo = @GetImageSize($this->sourceFilename)) {
  1369. $this->source_width = $this->getimagesizeinfo[0];
  1370. $this->source_height = $this->getimagesizeinfo[1];
  1371. if (function_exists('exif_thumbnail') && ($this->getimagesizeinfo[2] == 2)) {
  1372. // Extract EXIF info from JPEGs
  1373. $this->exif_thumbnail_width = '';
  1374. $this->exif_thumbnail_height = '';
  1375. $this->exif_thumbnail_type = '';
  1376. // The parameters width, height and imagetype are available since PHP v4.3.0
  1377. if (phpthumb_functions::version_compare_replacement(phpversion(), '4.3.0', '>=')) {
  1378. $this->exif_thumbnail_data = @exif_thumbnail($this->sourceFilename, $this->exif_thumbnail_width, $this->exif_thumbnail_height, $this->exif_thumbnail_type);
  1379. } else {
  1380. // older versions of exif_thumbnail output an error message but NOT return false on failure
  1381. ob_start();
  1382. $this->exif_thumbnail_data = exif_thumbnail($this->sourceFilename);
  1383. $exit_thumbnail_error = ob_get_contents();
  1384. ob_end_clean();
  1385. if (empty($exit_thumbnail_error) && !empty($this->exif_thumbnail_data)) {
  1386. if ($gdimg_exif_temp = $this->ImageCreateFromStringReplacement($this->exif_thumbnail_data, false)) {
  1387. $this->exif_thumbnail_width = ImageSX($gdimg_exif_temp);
  1388. $this->exif_thumbnail_height = ImageSY($gdimg_exif_temp);
  1389. $this->exif_thumbnail_type = 2; // (2 == JPEG) before PHP v4.3.0 only JPEG format EXIF thumbnails are returned
  1390. unset($gdimg_exif_temp);
  1391. } else {
  1392. return $this->ErrorImage('Failed - $this->ImageCreateFromStringReplacement($this->exif_thumbnail_data) in '.__FILE__.' on line '.__LINE__);
  1393. }
  1394. }
  1395. }
  1396. } elseif (!function_exists('exif_thumbnail')) {
  1397. $this->DebugMessage('exif_thumbnail() does not exist, cannot extract EXIF thumbnail', __FILE__, __LINE__);
  1398. }
  1399. // see if EXIF thumbnail can be used directly with no processing
  1400. if ($this->config_use_exif_thumbnail_for_speed && !empty($this->exif_thumbnail_data)) {
  1401. while (true) {
  1402. if (!$this->xto) {
  1403. if ($this->w && ($this->w != $this->exif_thumbnail_width)) {
  1404. break;
  1405. }
  1406. if ($this->h && ($this->h != $this->exif_thumbnail_height)) {
  1407. break;
  1408. }
  1409. $CannotBeSetParameters = array('sx', 'sy', 'sh', 'sw', 'far', 'bg', 'bc', 'fltr', 'phpthumbDebug');
  1410. foreach ($CannotBeSetParameters as $parameter) {
  1411. if (!empty($this->$parameter)) {
  1412. break 2;
  1413. }
  1414. }
  1415. }
  1416. $this->DebugMessage('setting $this->gdimg_source = $this->ImageCreateFromStringReplacement($this->exif_thumbnail_data)', __FILE__, __LINE__);
  1417. $this->gdimg_source = $this->ImageCreateFromStringReplacement($this->exif_thumbnail_data);
  1418. $this->source_width = ImageSX($this->gdimg_source);
  1419. $this->source_height = ImageSY($this->gdimg_source);
  1420. break;
  1421. }
  1422. }
  1423. if (($this->config_max_source_pixels > 0) && (($this->source_width * $this->source_height) > $this->config_max_source_pixels)) {
  1424. // Source image is larger than would fit in available PHP memory.
  1425. // If ImageMagick is installed, use it to generate the thumbnail.
  1426. // Else, if an EXIF thumbnail is available, use that as the source image.
  1427. // Otherwise, no choice but to fail with an error message
  1428. $this->DebugMessage('image is '.$this->source_width.'x'.$this->source_height.' and therefore contains more pixels ('.($this->source_width * $this->source_height).') than $this->config_max_source_pixels setting ('.$this->config_max_source_pixels.')', __FILE__, __LINE__);
  1429. if ($this->ImageMagickThumbnailToGD()) {
  1430. // excellent, we have a thumbnailed source image
  1431. } elseif (!empty($this->exif_thumbnail_data)) {
  1432. $this->DebugMessage('ImageMagickThumbnailToGD() failed, but $this->exif_thumbnail_data is usable', __FILE__, __LINE__);
  1433. // EXIF thumbnail exists, and will be use as source image
  1434. $this->gdimg_source = $this->ImageCreateFromStringReplacement($this->exif_thumbnail_data);
  1435. $this->source_width = $this->exif_thumbnail_width;
  1436. $this->source_height = $this->exif_thumbnail_height;
  1437. // override allow-enlarging setting if EXIF thumbnail is the only source available
  1438. // otherwise thumbnails larger than the EXIF thumbnail will be created at EXIF size
  1439. $this->config_output_allow_enlarging = true;
  1440. } else {
  1441. return $this->ErrorImage('Source image is ('.$this->source_width.'x'.$this->source_height.') which equals '.sprintf('%1.1f', $this->source_width * $this->source_height / 1000000).' megapixels, which is more than the allowed '.sprintf('%1.1f', ($this->config_max_source_pixels / 1000000)).' megapixels -- insufficient memory.'."\n".'EXIF thumbnail unavailable.');
  1442. }
  1443. }
  1444. } else {
  1445. $this->DebugMessage('GetImageSize("'.$this->sourceFilename.'") failed', __FILE__, __LINE__);
  1446. }
  1447. return true;
  1448. }
  1449. function SetCacheFilename() {
  1450. if (!is_null($this->cache_filename)) {
  1451. // $this->cache_filename already set, no need to re-set it
  1452. return true;
  1453. }
  1454. $this->setOutputFormat();
  1455. $this->setCacheDirectory();
  1456. if (empty($this->config_cache_directory)) {
  1457. $this->DebugMessage('SetCacheFilename() failed because $this->config_cache_directory is empty', __FILE__, __LINE__);
  1458. return false;
  1459. }
  1460. if (empty($this->sourceFilename) && empty($this->rawImageData) && !empty($this->src)) {
  1461. $this->sourceFilename = $this->ResolveFilenameToAbsolute($this->src);
  1462. }
  1463. $this->cache_filename = $this->config_cache_directory.'/phpthumb_cache';
  1464. if ($this->new) {
  1465. $this->cache_filename .= '_new'.urlencode($this->new);
  1466. } elseif ($this->md5s) {
  1467. // source image MD5 hash provided
  1468. $this->cache_filename .= '_'.$this->md5s;
  1469. } elseif (!$this->src && $this->rawImageData) {
  1470. $this->cache_filename .= '_'.strtolower(md5($this->rawImageData));
  1471. } else {
  1472. $this->cache_filename .= '_'.urlencode($this->src);
  1473. }
  1474. if (!empty($_SERVER['HTTP_REFERER'])) {
  1475. $parsed_url1 = @parse_url(@$_SERVER['HTTP_REFERER']);
  1476. $parsed_url2 = @parse_url('http://'.@$_SERVER['HTTP_HOST']);
  1477. if (@$parsed_url1['host'] && @$parsed_url2['host'] && ($parsed_url1['host'] != $parsed_url2['host'])) {
  1478. // include refering domain only if it doesn't match the domain of the current server
  1479. $this->cache_filename .= '_httpreferer'.urlencode(@$parsed_url2['host']);
  1480. }
  1481. }
  1482. if (!empty($_REQUEST['fltr']) && is_array($_REQUEST['fltr'])) {
  1483. $this->cache_filename .= '_fltr'.urlencode(implode('_fltr', $_REQUEST['fltr']));
  1484. }
  1485. $FilenameParameters1 = array('ar', 'bg', 'bc');
  1486. foreach ($FilenameParameters1 as $key) {
  1487. if (isset($this->$key)) {
  1488. $this->cache_filename .= '_'.$key.$this->$key;
  1489. }
  1490. }
  1491. $FilenameParameters2 = array('h', 'w', 'sx', 'sy', 'sw', 'sh', 'far', 'xto', 'ra', 'iar', 'maxb');
  1492. foreach ($FilenameParameters2 as $key) {
  1493. if (isset($this->$key)) {
  1494. $this->cache_filename .= '_'.$key.intval($this->$key);
  1495. }
  1496. }
  1497. if ($this->md5s) {
  1498. // source image MD5 hash provided
  1499. // do not source image modification date --
  1500. // cached image will be used even if file was modified or removed
  1501. } elseif (!$this->config_cache_source_filemtime_ignore_remote && eregi('^(f|ht)tp[s]?://', $this->src)) {
  1502. $this->cache_filename .= '_'.intval(phpthumb_functions::filedate_remote($this->src));
  1503. } elseif (!$this->config_cache_source_filemtime_ignore_local && $this->src && !$this->rawImageData) {
  1504. $this->cache_filename .= '_'.intval(@filemtime($this->sourceFilename));
  1505. }
  1506. if ($this->thumbnailFormat == 'jpeg') {
  1507. // only JPEG output has variable quality option
  1508. $this->cache_filename .= '_q'.intval($this->thumbnailQuality);
  1509. }
  1510. $this->cache_filename .= '.'.strtolower($this->thumbnailFormat);
  1511. return true;
  1512. }
  1513. function SourceImageToGD() {
  1514. if (is_resource($this->gdimg_source)) {
  1515. $this->DebugMessage('skipping SourceImageToGD() because $this->gdimg_source is already a resource', __FILE__, __LINE__);
  1516. return true;
  1517. }
  1518. $this->DebugMessage('starting SourceImageToGD()', __FILE__, __LINE__);
  1519. while (true) {
  1520. if (!$this->config_use_exif_thumbnail_for_speed) {
  1521. $this->DebugMessage('Not using EXIF thumbnail data because $this->config_use_exif_thumbnail_for_speed is FALSE', __FILE__, __LINE__);
  1522. break;
  1523. }
  1524. if (!$this->exif_thumbnail_data) {
  1525. $this->DebugMessage('Not using EXIF thumbnail data because $this->exif_thumbnail_data is empty', __FILE__, __LINE__);
  1526. break;
  1527. }
  1528. if (($this->thumbnailCropX != 0) || ($this->thumbnailCropY != 0)) {
  1529. $this->DebugMessage('Not using EXIF thumbnail data because source cropping is enabled ('.$this->thumbnailCropX.','.$this->thumbnailCropY.')', __FILE__, __LINE__);
  1530. break;
  1531. }
  1532. if (($this->w > $this->exif_thumbnail_width) || ($this->h > $this->exif_thumbnail_height)) {
  1533. $this->DebugMessage('Not using EXIF thumbnail data because EXIF thumbnail is too small ('.$this->exif_thumbnail_width.'x'.$this->exif_thumbnail_height.' vs '.$this->w.'x'.$this->h.')', __FILE__, __LINE__);
  1534. break;
  1535. }
  1536. // EXIF thumbnail exists, and is equal to or larger than destination thumbnail, and will be use as source image
  1537. // Only benefit here is greater speed, not lower memory usage
  1538. $this->DebugMessage('Trying to use EXIF thumbnail as source image', __FILE__, __LINE__);
  1539. if ($gdimg_exif_temp = $this->ImageCreateFromStringReplacement($this->exif_thumbnail_data, false)) {
  1540. $this->DebugMessage('Successfully using EXIF thumbnail as source image', __FILE__, __LINE__);
  1541. $this->gdimg_source = $gdimg_exif_temp;
  1542. $this->source_width = $this->exif_thumbnail_width;
  1543. $this->source_height = $this->exif_thumbnail_height;
  1544. $this->thumbnailCropW = $this->source_width;
  1545. $this->thumbnailCropH = $this->source_height;
  1546. return true;
  1547. } else {
  1548. $this->DebugMessage('$this->ImageCreateFromStringReplacement($this->exif_thumbnail_data, false) failed', __FILE__, __LINE__);
  1549. }
  1550. break;
  1551. }
  1552. if (empty($this->gdimg_source)) {
  1553. // try to create GD image source directly via GD, if possible,
  1554. // rather than buffering to memory and creating with ImageCreateFromString
  1555. $ImageCreateWasAttempted = false;
  1556. if (!empty($this->rawImageData)) {
  1557. // fine
  1558. } elseif ($this->iswindows && ((substr($this->sourceFilename, 0, 2) == '//') || (substr($this->sourceFilename, 0, 2) == '\\\\'))) {
  1559. // Windows \\share\filename.ext
  1560. } elseif (eregi('^(f|ht)tp[s]?://', $this->sourceFilename)) {
  1561. // URL
  1562. } elseif (!file_exists($this->sourceFilename)) {
  1563. return $this->ErrorImage('"'.$this->sourceFilename.'" does not exist');
  1564. } elseif (!is_file($this->sourceFilename)) {
  1565. return $this->ErrorImage('"'.$this->sourceFilename.'" is not a file');
  1566. }
  1567. $ImageCreateFromFunction = array(
  1568. 1 => 'ImageCreateFromGIF',
  1569. 2 => 'ImageCreateFromJPEG',
  1570. 3 => 'ImageCreateFromPNG',
  1571. 15 => 'ImageCreateFromWBMP',
  1572. );
  1573. switch (@$this->getimagesizeinfo[2]) {
  1574. case 1: // GIF
  1575. case 2: // JPEG
  1576. case 3: // PNG
  1577. case 15: // WBMP
  1578. if ($this->md5s && ($this->md5s != phpthumb_functions::md5_file_safe($this->sourceFilename))) {
  1579. return $this->ErrorImage('$this->md5s != md5($this->rawImageData)'."\n".'"'.$this->md5s.'" != '."\n".'"'.phpthumb_functions::md5_file_safe($this->sourceFilename).'"');
  1580. }
  1581. $ImageCreateFromFunctionName = $ImageCreateFromFunction[$this->getimagesizeinfo[2]];
  1582. if (function_exists($ImageCreateFromFunctionName)) {
  1583. $this->DebugMessage('Calling '.$ImageCreateFromFunctionName.'('.$this->sourceFilename.')', __FILE__, __LINE__);
  1584. $ImageCreateWasAttempted = true;
  1585. $this->gdimg_source = @$ImageCreateFromFunctionName($this->sourceFilename);
  1586. switch ($this->getimagesizeinfo[2]) {
  1587. case 1:
  1588. case 3:
  1589. // GIF or PNG input file may have transparency
  1590. $this->is_alpha = true;
  1591. break;
  1592. }
  1593. } else {
  1594. $this->DebugMessage('NOT calling '.$ImageCreateFromFunctionName.'('.$this->sourceFilename.') because !function_exists('.$ImageCreateFromFunctionName.')', __FILE__, __LINE__);
  1595. }
  1596. break;
  1597. case 4: // SWF
  1598. case 5: // PSD
  1599. case 6: // BMP
  1600. case 7: // TIFF (LE)
  1601. case 8: // TIFF (BE)
  1602. case 9: // JPC
  1603. case 10: // JP2
  1604. case 11: // JPX
  1605. case 12: // JB2
  1606. case 13: // SWC
  1607. case 14: // IFF
  1608. case 16: // XBM
  1609. $this->DebugMessage('No built-in image creation function for image type "'.@$this->getimagesizeinfo[2].'" ($this->getimagesizeinfo[2])', __FILE__, __LINE__);
  1610. break;
  1611. case '':
  1612. // no source file, source image was probably set by setSourceData()
  1613. break;
  1614. default:
  1615. $this->DebugMessage('Unknown value for $this->getimagesizeinfo[2]: "'.@$this->getimagesizeinfo[2].'"', __FILE__, __LINE__);
  1616. break;
  1617. }
  1618. if (empty($this->gdimg_source)) {
  1619. // cannot create from filename, attempt to create source image with ImageCreateFromString, if possible
  1620. if ($ImageCreateWasAttempted) {
  1621. $this->DebugMessage(@$ImageCreateFromFunctionName.'() was attempted but FAILED', __FILE__, __LINE__);
  1622. }
  1623. if (empty($this->rawImageData)) {
  1624. $this->DebugMessage('Populating $this->rawImageData and attempting ImageCreateFromStringReplacement()', __FILE__, __LINE__);
  1625. if ($fp = @fopen($this->sourceFilename, 'rb')) {
  1626. $this->rawImageData = '';
  1627. $filesize = filesize($this->sourceFilename);
  1628. $blocksize = 16384;
  1629. $blockreads = ceil($filesize / $blocksize);
  1630. for ($i = 0; $i < $blockreads; $i++) {
  1631. $this->rawImageData .= fread($fp, $blocksize);
  1632. }
  1633. fclose($fp);
  1634. } else {
  1635. return $this->ErrorImage('cannot fopen("'.$this->sourceFilename.'") on line '.__LINE__.' of '.__FILE__);
  1636. }
  1637. }
  1638. if ($this->md5s && ($this->md5s != md5($this->rawImageData))) {
  1639. return $this->ErrorImage('$this->md5s != md5($this->rawImageData)'."\n".'"'.$this->md5s.'" != '."\n".'"'.md5($this->rawImageData).'"');
  1640. }
  1641. $this->gdimg_source = $this->ImageCreateFromStringReplacement($this->rawImageData, true);
  1642. }
  1643. if (empty($this->gdimg_source)) {
  1644. $this->DebugMessage('$this->gdimg_source is still empty', __FILE__, __LINE__);
  1645. if ($this->ImageMagickThumbnailToGD()) {
  1646. // excellent, we have a thumbnailed source image
  1647. $this->DebugMessage('ImageMagickThumbnailToGD() succeeded', __FILE__, __LINE__);
  1648. } else {
  1649. $this->DebugMessage('ImageMagickThumbnailToGD() failed', __FILE__, __LINE__);
  1650. $imageHeader = '';
  1651. $gd_info = phpthumb_functions::gd_info();
  1652. $GDreadSupport = false;
  1653. switch (substr($this->rawImageData, 0, 3)) {
  1654. case 'GIF':
  1655. $imageHeader = 'Content-Type: image/gif';
  1656. $GDreadSupport = (bool) @$gd_info['GIF Read Support'];
  1657. break;
  1658. case "\xFF\xD8\xFF":
  1659. $imageHeader = 'Content-Type: image/jpeg';
  1660. $GDreadSupport = (bool) @$gd_info['JPG Support'];
  1661. break;
  1662. case "\x89".'PN':
  1663. $imageHeader = 'Content-Type: image/png';
  1664. $GDreadSupport = (bool) @$gd_info['PNG Support'];
  1665. break;
  1666. }
  1667. if ($imageHeader) {
  1668. // cannot create image for whatever reason (maybe ImageCreateFromJPEG et al are not available?)
  1669. // and ImageMagick is not available either, no choice but to output original (not resized/modified) data and exit
  1670. if ($this->config_error_die_on_source_failure && !$this->phpthumbDebug) {
  1671. $this->ErrorImage('All attempts to create GD image source failed ('.($GDreadSupport ? 'source image probably corrupt' : 'GD does not have read support for "'.$imageHeader.'"').'), cannot generate thumbnail');
  1672. } else {
  1673. //$this->DebugMessage('All attempts to create GD image source failed ('.($GDreadSupport ? 'source image probably corrupt' : 'GD does not have read support for "'.$imageHeader.'"').'), outputing raw image', __FILE__, __LINE__);
  1674. //if (!$this->phpthumbDebug) {
  1675. // header($imageHeader);
  1676. // echo $this->rawImageData;
  1677. // exit;
  1678. //}
  1679. return false;
  1680. }
  1681. }
  1682. switch (substr($this->rawImageData, 0, 2)) {
  1683. case 'BM':
  1684. ob_start();
  1685. if (!@include_once(dirname(__FILE__).'/phpthumb.bmp.php')) {
  1686. ob_end_clean();
  1687. if ($this->phpthumbDebug) {
  1688. $this->DebugMessage('include_once('.dirname(__FILE__).'/phpthumb.bmp.php) failed', __FILE__, __LINE__);
  1689. return false;
  1690. }
  1691. return $this->ErrorImage('include_once('.dirname(__FILE__).'/phpthumb.bmp.php) failed');
  1692. }
  1693. ob_end_clean();
  1694. $phpthumb_bmp = new phpthumb_bmp();
  1695. if ($this->gdimg_source = $phpthumb_bmp->phpthumb_bmp2gd($this->rawImageData, (phpthumb_functions::gd_version() >= 2.0))) {
  1696. $this->DebugMessage('$phpthumb_bmp->phpthumb_bmp2gd() succeeded', __FILE__, __LINE__);
  1697. break;
  1698. } elseif ($this->phpthumbDebug) {
  1699. $this->DebugMessage('phpthumb_bmp2db failed', __FILE__, __LINE__);
  1700. return false;
  1701. }
  1702. return $this->ErrorImage('ImageMagick is unavailable and phpthumb() does not support BMP source images without it');
  1703. break;
  1704. }
  1705. switch (substr($this->rawImageData, 0, 4)) {
  1706. case 'II'."\x2A\x00":
  1707. case 'MM'."\x00\x2A":
  1708. if ($this->phpthumbDebug) {
  1709. $this->DebugMessage('ImageMagick is unavailable and phpthumb() does not support TIFF source images without it', __FILE__, __LINE__);
  1710. return false;
  1711. }
  1712. return $this->ErrorImage('ImageMagick is unavailable and phpthumb() does not support TIFF source images without it');
  1713. break;
  1714. case "\xD7\xCD\xC6\x9A":
  1715. if ($this->phpthumbDebug) {
  1716. $this->DebugMessage('ImageMagick is unavailable and phpthumb() does not support WMF source images without it', __FILE__, __LINE__);
  1717. return false;
  1718. }
  1719. return $this->ErrorImage('ImageMagick is unavailable and phpthumb() does not support WMF source images without it');
  1720. break;
  1721. }
  1722. if (empty($this->gdimg_source)) {
  1723. if ($this->phpthumbDebug) {
  1724. $this->DebugMessage('Unknown image type identified by "'.substr($this->rawImageData, 0, 4).'" ('.phpthumb_functions::HexCharDisplay(substr($this->rawImageData, 0, 4)).') in SourceImageToGD()', __FILE__, __LINE__);
  1725. return false;
  1726. }
  1727. return $this->ErrorImage('Unknown image type identified by "'.substr($this->rawImageData, 0, 4).'" ('.phpthumb_functions::HexCharDisplay(substr($this->rawImageData, 0, 4)).') in SourceImageToGD()');
  1728. }
  1729. }
  1730. }
  1731. }
  1732. $this->source_width = ImageSX($this->gdimg_source);
  1733. $this->source_height = ImageSY($this->gdimg_source);
  1734. return true;
  1735. }
  1736. function phpthumbDebugVarDump($var) {
  1737. if (is_null($var)) {
  1738. return 'null';
  1739. } elseif (is_bool($var)) {
  1740. return ($var ? 'TRUE' : 'FALSE');
  1741. } elseif (is_string($var)) {
  1742. return 'string('.strlen($var).')'.str_repeat(' ', max(0, 3 - strlen(strlen($var)))).' "'.$var.'"';
  1743. } elseif (is_int($var)) {
  1744. return 'integer '.$var;
  1745. } elseif (is_float($var)) {
  1746. return 'float '.$var;
  1747. } elseif (is_array($var)) {
  1748. ob_start();
  1749. var_dump($var);
  1750. $vardumpoutput = ob_get_contents();
  1751. ob_end_clean();
  1752. return strtr($vardumpoutput, "\n\r\t", ' ');
  1753. }
  1754. return gettype($var);
  1755. }
  1756. function phpthumbDebug() {
  1757. if ($this->config_disable_debug) {
  1758. return $this->ErrorImage('phpthumbDebug disabled');
  1759. }
  1760. $FunctionsExistance = array('exif_thumbnail', 'gd_info', 'image_type_to_mime_type', 'ImageCopyResampled', 'ImageCopyResized', 'ImageCreate', 'ImageCreateFromString', 'ImageCreateTrueColor', 'ImageIsTrueColor', 'ImageRotate', 'ImageTypes', 'version_compare', 'ImageCreateFromGIF', 'ImageCreateFromJPEG', 'ImageCreateFromPNG', 'ImageCreateFromWBMP', 'ImageCreateFromXBM', 'ImageCreateFromXPM', 'ImageCreateFromString', 'ImageCreateFromGD', 'ImageCreateFromGD2', 'ImageCreateFromGD2Part', 'ImageJPEG', 'ImageGIF', 'ImagePNG', 'ImageWBMP');
  1761. $ParameterNames = array('src', 'new', 'w', 'h', 'f', 'q', 'sx', 'sy', 'sw', 'sh', 'far', 'bg', 'bc', 'file', 'goto', 'err', 'xto', 'ra', 'ar', 'aoe', 'iar', 'maxb');
  1762. $OtherVariableNames = array('phpthumbDebug', 'thumbnailQuality', 'thumbnailFormat', 'gdimg_output', 'gdimg_source', 'sourceFilename', 'source_width', 'source_height', 'thumbnailCropX', 'thumbnailCropY', 'thumbnailCropW', 'thumbnailCropH', 'exif_thumbnail_width', 'exif_thumbnail_height', 'exif_thumbnail_type', 'thumbnail_width', 'thumbnail_height', 'thumbnail_image_width', 'thumbnail_image_height');
  1763. $DebugOutput = array();
  1764. $DebugOutput[] = 'phpthumb() version = '.$this->phpthumb_version;
  1765. $DebugOutput[] = 'phpversion() = '.@phpversion();
  1766. $DebugOutput[] = 'PHP_OS = '.PHP_OS;
  1767. $DebugOutput[] = '$_SERVER[PHP_SELF] = '.@$_SERVER['PHP_SELF'];
  1768. $DebugOutput[] = '$_SERVER[DOCUMENT_ROOT] = '.@$_SERVER['DOCUMENT_ROOT'];
  1769. $DebugOutput[] = '$_SERVER[HTTP_REFERER] = '.@$_SERVER['HTTP_REFERER'];
  1770. $DebugOutput[] = '$_SERVER[QUERY_STRING] = '.@$_SERVER['QUERY_STRING'];
  1771. $DebugOutput[] = 'realpath(.) = '.@realpath('.');
  1772. $DebugOutput[] = '';
  1773. $DebugOutput[] = 'get_magic_quotes_gpc() = '.$this->phpthumbDebugVarDump(@get_magic_quotes_gpc());
  1774. $DebugOutput[] = 'get_magic_quotes_runtime() = '.$this->phpthumbDebugVarDump(@get_magic_quotes_runtime());
  1775. $DebugOutput[] = 'error_reporting() = '.$this->phpthumbDebugVarDump(error_reporting());
  1776. $DebugOutput[] = 'ini_get(error_reporting) = '.$this->phpthumbDebugVarDump(@ini_get('error_reporting'));
  1777. $DebugOutput[] = 'ini_get(display_errors) = '.$this->phpthumbDebugVarDump(@ini_get('display_errors'));
  1778. $DebugOutput[] = 'ini_get(allow_url_fopen) = '.$this->phpthumbDebugVarDump(@ini_get('allow_url_fopen'));
  1779. $DebugOutput[] = 'ini_get(disable_functions) = '.$this->phpthumbDebugVarDump(@ini_get('disable_functions'));
  1780. $DebugOutput[] = 'ini_get(safe_mode) = '.$this->phpthumbDebugVarDump(@ini_get('safe_mode'));
  1781. $DebugOutput[] = 'ini_get(open_basedir) = '.$this->phpthumbDebugVarDump(@ini_get('open_basedir'));
  1782. $DebugOutput[] = 'ini_get(memory_limit) = '.$this->phpthumbDebugVarDump(@ini_get('memory_limit'));
  1783. $DebugOutput[] = 'ini_get(max_execution_time) = '.$this->phpthumbDebugVarDump(@ini_get('max_execution_time'));
  1784. $DebugOutput[] = 'get_cfg_var(memory_limit) = '.$this->phpthumbDebugVarDump(@get_cfg_var('memory_limit'));
  1785. $DebugOutput[] = 'memory_get_usage() = '.(function_exists('memory_get_usage') ? $this->phpthumbDebugVarDump(@memory_get_usage()) : 'n/a');
  1786. $DebugOutput[] = '';
  1787. $DebugOutput[] = '$this->config_imagemagick_path = '.$this->phpthumbDebugVarDump($this->config_imagemagick_path);
  1788. $DebugOutput[] = 'SafeBackTick(which convert) = '.trim(phpthumb_functions::SafeBackTick('which convert'));
  1789. $IMpathUsed = ($this->config_imagemagick_path ? $this->config_imagemagick_path : trim(phpthumb_functions::SafeBackTick('which convert')));
  1790. $DebugOutput[] = '[actual ImageMagick path used] = '.$this->phpthumbDebugVarDump($IMpathUsed);
  1791. $DebugOutput[] = 'file_exists([actual ImageMagick path used]) = '.$this->phpthumbDebugVarDump(file_exists($IMpathUsed));
  1792. $DebugOutput[] = 'ImageMagickVersion() = '.$this->ImageMagickVersion();
  1793. $DebugOutput[] = '';
  1794. $DebugOutput[] = '$this->config_cache_directory = '.$this->phpthumbDebugVarDump($this->config_cache_directory);
  1795. $DebugOutput[] = '$this->config_cache_disable_warning = '.$this->phpthumbDebugVarDump($this->config_cache_disable_warning);
  1796. $DebugOutput[] = '$this->config_cache_maxage = '.$this->phpthumbDebugVarDump($this->config_cache_maxage);
  1797. $DebugOutput[] = '$this->config_cache_maxsize = '.$this->phpthumbDebugVarDump($this->config_cache_maxsize);
  1798. $DebugOutput[] = '$this->config_cache_maxfiles = '.$this->phpthumbDebugVarDump($this->config_cache_maxfiles);
  1799. $DebugOutput[] = '$this->cache_filename = '.$this->phpthumbDebugVarDump($this->cache_filename);
  1800. $DebugOutput[] = 'is_readable($this->config_cache_directory) = '.$this->phpthumbDebugVarDump(is_readable($this->config_cache_directory));
  1801. $DebugOutput[] = 'is_writable($this->config_cache_directory) = '.$this->phpthumbDebugVarDump(is_writable($this->config_cache_directory));
  1802. $DebugOutput[] = 'is_readable($this->cache_filename) = '.$this->phpthumbDebugVarDump(is_readable($this->cache_filename));
  1803. $DebugOutput[] = 'is_writable($this->cache_filename) = '.(file_exists($this->cache_filename) ? $this->phpthumbDebugVarDump(is_writable($this->cache_filename)) : 'n/a');
  1804. $DebugOutput[] = '';
  1805. $DebugOutput[] = '$this->config_document_root = '.$this->phpthumbDebugVarDump($this->config_document_root);
  1806. $DebugOutput[] = '$this->config_temp_directory = '.$this->phpthumbDebugVarDump($this->config_temp_directory);
  1807. $DebugOutput[] = '';
  1808. $DebugOutput[] = '$this->config_output_format = '.$this->phpthumbDebugVarDump($this->config_output_format);
  1809. $DebugOutput[] = '$this->config_output_maxwidth = '.$this->phpthumbDebugVarDump($this->config_output_maxwidth);
  1810. $DebugOutput[] = '$this->config_output_maxheight = '.$this->phpthumbDebugVarDump($this->config_output_maxheight);
  1811. $DebugOutput[] = '';
  1812. $DebugOutput[] = '$this->config_error_message_image_default = '.$this->phpthumbDebugVarDump($this->config_error_message_image_default);
  1813. $DebugOutput[] = '$this->config_error_bgcolor = '.$this->phpthumbDebugVarDump($this->config_error_bgcolor);
  1814. $DebugOutput[] = '$this->config_error_textcolor = '.$this->phpthumbDebugVarDump($this->config_error_textcolor);
  1815. $DebugOutput[] = '$this->config_error_fontsize = '.$this->phpthumbDebugVarDump($this->config_error_fontsize);
  1816. $DebugOutput[] = '$this->config_error_die_on_error = '.$this->phpthumbDebugVarDump($this->config_error_die_on_error);
  1817. $DebugOutput[] = '$this->config_error_die_on_error = '.$this->phpthumbDebugVarDump($this->config_error_die_on_error);
  1818. $DebugOutput[] = '$this->config_error_silent_die_on_error = '.$this->phpthumbDebugVarDump($this->config_error_silent_die_on_error);
  1819. $DebugOutput[] = '$this->config_error_die_on_source_failure = '.$this->phpthumbDebugVarDump($this->config_error_die_on_source_failure);
  1820. $DebugOutput[] = '';
  1821. $DebugOutput[] = '$this->config_nohotlink_enabled = '.$this->phpthumbDebugVarDump($this->config_nohotlink_enabled);
  1822. $DebugOutput[] = '$this->config_nohotlink_valid_domains = '.$this->phpthumbDebugVarDump($this->config_nohotlink_valid_domains);
  1823. $DebugOutput[] = '$this->config_nohotlink_erase_image = '.$this->phpthumbDebugVarDump($this->config_nohotlink_erase_image);
  1824. $DebugOutput[] = '$this->config_nohotlink_text_message = '.$this->phpthumbDebugVarDump($this->config_nohotlink_text_message);
  1825. $DebugOutput[] = '';
  1826. $DebugOutput[] = '$this->config_nooffsitelink_enabled = '.$this->phpthumbDebugVarDump($this->config_nooffsitelink_enabled);
  1827. $DebugOutput[] = '$this->config_nooffsitelink_valid_domains = '.$this->phpthumbDebugVarDump($this->config_nooffsitelink_valid_domains);
  1828. $DebugOutput[] = '$this->config_nooffsitelink_require_refer = '.$this->phpthumbDebugVarDump($this->config_nooffsitelink_require_refer);
  1829. $DebugOutput[] = '$this->config_nooffsitelink_erase_image = '.$this->phpthumbDebugVarDump($this->config_nooffsitelink_erase_image);
  1830. $DebugOutput[] = '$this->config_nooffsitelink_text_message = '.$this->phpthumbDebugVarDump($this->config_nooffsitelink_text_message);
  1831. $DebugOutput[] = '';
  1832. $DebugOutput[] = '$this->config_max_source_pixels = '.$this->phpthumbDebugVarDump($this->config_max_source_pixels);
  1833. $DebugOutput[] = '$this->config_use_exif_thumbnail_for_speed = '.$this->phpthumbDebugVarDump($this->config_use_exif_thumbnail_for_speed);
  1834. $DebugOutput[] = '$this->config_output_allow_enlarging = '.$this->phpthumbDebugVarDump($this->config_output_allow_enlarging);
  1835. $DebugOutput[] = '$this->config_border_hexcolor = '.$this->phpthumbDebugVarDump($this->config_border_hexcolor);
  1836. $DebugOutput[] = '$this->config_background_hexcolor = '.$this->phpthumbDebugVarDump($this->config_background_hexcolor);
  1837. $DebugOutput[] = '$this->config_ttf_directory = '.$this->phpthumbDebugVarDump($this->config_ttf_directory);
  1838. $DebugOutput[] = '';
  1839. foreach ($OtherVariableNames as $varname) {
  1840. $value = $this->$varname;
  1841. $DebugOutput[] = '$this->'.str_pad($varname, 27, ' ', STR_PAD_RIGHT).' = '.$this->phpthumbDebugVarDump($value);
  1842. }
  1843. $DebugOutput[] = 'strlen($this->rawImageData) = '.strlen(@$this->rawImageData);
  1844. $DebugOutput[] = 'strlen($this->exif_thumbnail_data) = '.strlen(@$this->exif_thumbnail_data);
  1845. $DebugOutput[] = '';
  1846. foreach ($ParameterNames as $varname) {
  1847. $value = $this->$varname;
  1848. $DebugOutput[] = '$this->'.str_pad($varname, 4, ' ', STR_PAD_RIGHT).' = '.$this->phpthumbDebugVarDump($value);
  1849. }
  1850. $DebugOutput[] = '';
  1851. foreach ($FunctionsExistance as $functionname) {
  1852. $DebugOutput[] = 'builtin_function_exists('.$functionname.')'.str_repeat(' ', 23 - strlen($functionname)).' = '.$this->phpthumbDebugVarDump(phpthumb_functions::builtin_function_exists($functionname));
  1853. }
  1854. $DebugOutput[] = '';
  1855. $gd_info = phpthumb_functions::gd_info();
  1856. foreach ($gd_info as $key => $value) {
  1857. $DebugOutput[] = 'gd_info.'.str_pad($key, 34, ' ', STR_PAD_RIGHT).' = '.$this->phpthumbDebugVarDump($value);
  1858. }
  1859. $DebugOutput[] = '';
  1860. $exif_info = phpthumb_functions::exif_info();
  1861. foreach ($exif_info as $key => $value) {
  1862. $DebugOutput[] = 'exif_info.'.str_pad($key, 26, ' ', STR_PAD_RIGHT).' = '.$this->phpthumbDebugVarDump($value);
  1863. }
  1864. $DebugOutput[] = '';
  1865. if ($ApacheLookupURIarray = phpthumb_functions::ApacheLookupURIarray(dirname(@$_SERVER['PHP_SELF']))) {
  1866. foreach ($ApacheLookupURIarray as $key => $value) {
  1867. $DebugOutput[] = 'ApacheLookupURIarray.'.str_pad($key, 15, ' ', STR_PAD_RIGHT).' = '.$this->phpthumbDebugVarDump($value);
  1868. }
  1869. } else {
  1870. $DebugOutput[] = 'ApacheLookupURIarray() -- FAILED';
  1871. }
  1872. $DebugOutput[] = '';
  1873. if (isset($_GET) && is_array($_GET)) {
  1874. foreach ($_GET as $key => $value) {
  1875. $DebugOutput[] = '$_GET['.$key.']'.str_repeat(' ', 30 - strlen($key)).'= '.$this->phpthumbDebugVarDump($value);
  1876. }
  1877. }
  1878. if (isset($_POST) && is_array($_POST)) {
  1879. foreach ($_POST as $key => $value) {
  1880. $DebugOutput[] = '$_POST['.$key.']'.str_repeat(' ', 29 - strlen($key)).'= '.$this->phpthumbDebugVarDump($value);
  1881. }
  1882. }
  1883. $DebugOutput[] = '';
  1884. $DebugOutput[] = '$this->debugmessages:';
  1885. foreach ($this->debugmessages as $errorstring) {
  1886. $DebugOutput[] = ' * '.$errorstring;
  1887. }
  1888. return $this->ErrorImage(implode("\n", $DebugOutput), 700, 500);
  1889. }
  1890. function ErrorImage($text, $width=0, $height=0) {
  1891. $width = ($width ? $width : $this->config_error_image_width);
  1892. $height = ($height ? $height : $this->config_error_image_height);
  1893. if ($this->config_disable_debug) {
  1894. $text = 'Error messages disabled';
  1895. }
  1896. $this->DebugMessage($text);
  1897. if (!$this->config_error_die_on_error) {
  1898. $this->fatalerror = $text;
  1899. return false;
  1900. }
  1901. if ($this->config_error_silent_die_on_error) {
  1902. exit;
  1903. }
  1904. if ($this->err || $this->config_error_message_image_default) {
  1905. // Show generic custom error image instead of error message
  1906. // for use on production sites where you don't want debug messages
  1907. if ($this->err == 'showerror') {
  1908. // fall through and actually show error message even if default error image is set
  1909. } else {
  1910. header('Location: '.($this->err ? $this->err : $this->config_error_message_image_default));
  1911. exit;
  1912. }
  1913. }
  1914. if (@$this->f == 'text') {
  1915. // bypass all GD functions and output text error message
  1916. die('<pre>'.$text.'</pre>');
  1917. }
  1918. $FontWidth = ImageFontWidth($this->config_error_fontsize);
  1919. $FontHeight = ImageFontHeight($this->config_error_fontsize);
  1920. $LinesOfText = explode("\n", @wordwrap($text, floor($width / $FontWidth), "\n", true));
  1921. $height = max($height, count($LinesOfText) * $FontHeight);
  1922. $headers_file = '';
  1923. $headers_line = '';
  1924. if (phpthumb_functions::version_compare_replacement(phpversion(), '4.3.0', '>=') && headers_sent($headers_file, $headers_line)) {
  1925. echo "\n".'**Headers already sent in file "'.$headers_file.'" on line "'.$headers_line.'", dumping error message as text:**<br><pre>'."\n\n".$text."\n".'</pre>';
  1926. } elseif (headers_sent()) {
  1927. echo "\n".'**Headers already sent, dumping error message as text:**<br><pre>'."\n\n".$text."\n".'</pre>';
  1928. } elseif ($gdimg_error = ImageCreate($width, $height)) {
  1929. $background_color = phpthumb_functions::ImageHexColorAllocate($gdimg_error, $this->config_error_bgcolor, true);
  1930. $text_color = phpthumb_functions::ImageHexColorAllocate($gdimg_error, $this->config_error_textcolor, true);
  1931. ImageFilledRectangle($gdimg_error, 0, 0, $width, $height, $background_color);
  1932. $lineYoffset = 0;
  1933. foreach ($LinesOfText as $line) {
  1934. ImageString($gdimg_error, $this->config_error_fontsize, 2, $lineYoffset, $line, $text_color);
  1935. $lineYoffset += $FontHeight;
  1936. }
  1937. if (function_exists('ImageTypes')) {
  1938. $imagetypes = ImageTypes();
  1939. if ($imagetypes & IMG_PNG) {
  1940. header('Content-Type: image/png');
  1941. ImagePNG($gdimg_error);
  1942. } elseif ($imagetypes & IMG_GIF) {
  1943. header('Content-Type: image/gif');
  1944. ImageGIF($gdimg_error);
  1945. } elseif ($imagetypes & IMG_JPG) {
  1946. header('Content-Type: image/jpeg');
  1947. ImageJPEG($gdimg_error);
  1948. } elseif ($imagetypes & IMG_WBMP) {
  1949. header('Content-Type: image/wbmp');
  1950. ImageWBMP($gdimg_error);
  1951. }
  1952. }
  1953. ImageDestroy($gdimg_error);
  1954. }
  1955. if (!headers_sent()) {
  1956. echo "\n".'**Failed to send graphical error image, dumping error message as text:**<br>'."\n\n".$text;
  1957. }
  1958. exit;
  1959. return true;
  1960. }
  1961. function ImageCreateFromStringReplacement(&$RawImageData, $DieOnErrors=false) {
  1962. // there are serious bugs in the non-bundled versions of GD which may cause
  1963. // PHP to segfault when calling ImageCreateFromString() - avoid if at all possible
  1964. // when not using a bundled version of GD2
  1965. $gd_info = phpthumb_functions::gd_info();
  1966. if (strpos($gd_info['GD Version'], 'bundled') !== false) {
  1967. return @ImageCreateFromString($RawImageData);
  1968. }
  1969. switch (substr($RawImageData, 0, 3)) {
  1970. case 'GIF':
  1971. $ICFSreplacementFunctionName = 'ImageCreateFromGIF';
  1972. break;
  1973. case "\xFF\xD8\xFF":
  1974. $ICFSreplacementFunctionName = 'ImageCreateFromJPEG';
  1975. break;
  1976. case "\x89".'PN':
  1977. $ICFSreplacementFunctionName = 'ImageCreateFromPNG';
  1978. break;
  1979. default:
  1980. return false;
  1981. break;
  1982. }
  1983. if ($tempnam = $this->phpthumb_tempnam()) {
  1984. if ($fp_tempnam = @fopen($tempnam, 'wb')) {
  1985. fwrite($fp_tempnam, $RawImageData);
  1986. fclose($fp_tempnam);
  1987. if (($ICFSreplacementFunctionName == 'ImageCreateFromGIF') && !function_exists($ICFSreplacementFunctionName)) {
  1988. // Need to create from GIF file, but ImageCreateFromGIF does not exist
  1989. ob_start();
  1990. if (!@include_once(dirname(__FILE__).'/phpthumb.gif.php')) {
  1991. $ErrorMessage = 'Failed to include required file "'.dirname(__FILE__).'/phpthumb.gif.php" in '.__FILE__.' on line '.__LINE__;
  1992. }
  1993. ob_end_clean();
  1994. // gif_loadFileToGDimageResource() cannot read from raw data, write to file first
  1995. if ($tempfilename = $this->phpthumb_tempnam()) {
  1996. if ($fp_tempfile = @fopen($tempfilename, 'wb')) {
  1997. fwrite($fp_tempfile, $RawImageData);
  1998. fclose($fp_tempfile);
  1999. $gdimg_source = gif_loadFileToGDimageResource($tempfilename);
  2000. unlink($tempfilename);
  2001. return $gdimg_source;
  2002. break;
  2003. } else {
  2004. $ErrorMessage = 'Failed to open tempfile in '.__FILE__.' on line '.__LINE__;
  2005. }
  2006. } else {
  2007. $ErrorMessage = 'Failed to open generate tempfile name in '.__FILE__.' on line '.__LINE__;
  2008. }
  2009. } elseif (function_exists($ICFSreplacementFunctionName) && ($gdimg_source = $ICFSreplacementFunctionName($tempnam))) {
  2010. // great
  2011. unlink($tempnam);
  2012. return $gdimg_source;
  2013. } else { // GD functions not available
  2014. // base64-encoded error image in GIF format
  2015. header('Content-Type: image/gif');
  2016. echo base64_decode('R0lGODlhIAAgALMAAAAAABQUFCQkJDY2NkZGRldXV2ZmZnJycoaGhpSUlKWlpbe3t8XFxdXV1eTk5P7+/iwAAAAAIAAgAAAE/vDJSau9WILtTAACUinDNijZtAHfCojS4W5H+qxD8xibIDE9h0OwWaRWDIljJSkUJYsN4bihMB8th3IToAKs1VtYM75cyV8sZ8vygtOE5yMKmGbO4jRdICQCjHdlZzwzNW4qZSQmKDaNjhUMBX4BBAlmMywFSRWEmAI6b5gAlhNxokGhooAIK5o/pi9vEw4Lfj4OLTAUpj6IabMtCwlSFw0DCKBoFqwAB04AjI54PyZ+yY3TD0ss2YcVmN/gvpcu4TOyFivWqYJlbAHPpOntvxNAACcmGHjZzAZqzSzcq5fNjxFmAFw9iFRunD1epU6tsIPmFCAJnWYE0FURk7wJDA0MTKpEzoWAAskiAAA7');
  2017. exit;
  2018. }
  2019. } else {
  2020. $ErrorMessage = 'Failed to fopen('.$tempnam.', "wb") in '.__FILE__.' on line '.__LINE__."\n".'You may need to set $PHPTHUMB_CONFIG[temp_directory] in phpthumb.config.php';
  2021. }
  2022. unlink($tempnam);
  2023. } else {
  2024. $ErrorMessage = 'Failed to generate phpthumb_tempnam() in '.__FILE__.' on line '.__LINE__."\n".'You may need to set $PHPTHUMB_CONFIG[temp_directory] in phpthumb.config.php';
  2025. }
  2026. if ($DieOnErrors && !empty($ErrorMessage)) {
  2027. return $this->ErrorImage($ErrorMessage);
  2028. }
  2029. return false;
  2030. }
  2031. function phpthumb_tempnam() {
  2032. return tempnam($this->config_temp_directory, 'pThumb');
  2033. }
  2034. function DebugMessage($message, $file='', $line='') {
  2035. $this->debugmessages[] = $message.($file ? ' in file "'.(basename($file) ? basename($file) : $file).'"' : '').($line ? ' on line '.$line : '');
  2036. return true;
  2037. }
  2038. }
  2039. ?>