1: <?php
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12: ob_start();
13: if (!include_once(dirname(__FILE__).'/phpthumb.functions.php')) {
14: ob_end_flush();
15: die('failed to include_once("'.dirname(__FILE__).'/phpthumb.functions.php")');
16: }
17: ob_end_clean();
18:
19: class phpthumb {
20:
21:
22:
23:
24: var $src = null;
25: var $new = null;
26: var $w = null;
27: var $h = null;
28: var $wp = null;
29: var $hp = null;
30: var $wl = null;
31: var $hl = null;
32: var $ws = null;
33: var $hs = null;
34: var $f = null;
35: var $q = 75;
36: var $sx = null;
37: var $sy = null;
38: var $sw = null;
39: var $sh = null;
40: var $zc = null;
41: var $bc = null;
42: var $bg = null;
43: var $fltr = array();
44: var $goto = null;
45: var $err = null;
46: var $xto = null;
47: var $ra = null;
48: var $ar = null;
49: var $aoe = null;
50: var $far = null;
51: var $iar = null;
52: var $maxb = null;
53: var $down = null;
54: var $md5s = null;
55: var $sfn = 0;
56: var $dpi = 150;
57: var $sia = null;
58:
59: var $file = null;
60:
61: var $phpThumbDebug = null;
62:
63:
64:
65:
66:
67:
68:
69:
70: var $config_cache_directory = null;
71: var $config_cache_directory_depth = 0;
72: var $config_cache_disable_warning = true;
73: var $config_cache_source_enabled = false;
74: var $config_cache_source_directory = null;
75: var $config_temp_directory = null;
76: var $config_document_root = null;
77:
78:
79: var $config_output_format = 'jpeg';
80: var $config_output_maxwidth = 0;
81: var $config_output_maxheight = 0;
82: var $config_output_interlace = true;
83:
84:
85: var $config_error_image_width = 400;
86: var $config_error_image_height = 100;
87: var $config_error_message_image_default = '';
88: var $config_error_bgcolor = 'CCCCFF';
89: var $config_error_textcolor = 'FF0000';
90: var $config_error_fontsize = 1;
91: var $config_error_die_on_error = false;
92: var $config_error_silent_die_on_error = false;
93: var $config_error_die_on_source_failure = true;
94:
95:
96: var $config_nohotlink_enabled = true;
97: var $config_nohotlink_valid_domains = array();
98: var $config_nohotlink_erase_image = true;
99: var $config_nohotlink_text_message = 'Off-server thumbnailing is not allowed';
100:
101: var $config_nooffsitelink_enabled = false;
102: var $config_nooffsitelink_valid_domains = array();
103: var $config_nooffsitelink_require_refer = false;
104: var $config_nooffsitelink_erase_image = true;
105: var $config_nooffsitelink_watermark_src = '';
106: var $config_nooffsitelink_text_message = 'Off-server linking is not allowed';
107:
108:
109: var $config_border_hexcolor = '000000';
110: var $config_background_hexcolor = 'FFFFFF';
111:
112:
113: var $config_ttf_directory = './fonts';
114:
115: var $config_max_source_pixels = null;
116: var $config_use_exif_thumbnail_for_speed = false;
117: var $allow_local_http_src = false;
118:
119: var $config_imagemagick_path = null;
120: var $config_prefer_imagemagick = true;
121: var $config_imagemagick_use_thumbnail = true;
122:
123: var $config_cache_maxage = null;
124: var $config_cache_maxsize = null;
125: var $config_cache_maxfiles = null;
126: var $config_cache_source_filemtime_ignore_local = false;
127: var $config_cache_source_filemtime_ignore_remote = true;
128: var $config_cache_default_only_suffix = false;
129: var $config_cache_force_passthru = true;
130: var $config_cache_prefix = '';
131:
132:
133: var $config_mysql_extension = null;
134: var $config_mysql_query = null;
135: var $config_mysql_hostname = null;
136: var $config_mysql_username = null;
137: var $config_mysql_password = null;
138: var $config_mysql_database = null;
139:
140:
141: var $config_high_security_enabled = true;
142: var $config_high_security_password = null;
143: var $config_high_security_url_separator = '&';
144: var $config_disable_debug = true;
145: var $config_allow_src_above_docroot = false;
146: var $config_allow_src_above_phpthumb = true;
147: var $config_auto_allow_symlinks = true;
148: var $config_additional_allowed_dirs = array();
149: var $config_file_create_mask = 0755;
150: var $config_dir_create_mask = 0755;
151:
152:
153: var $config_http_fopen_timeout = 10;
154: var $config_http_follow_redirect = true;
155:
156:
157: var $config_disable_pathinfo_parsing = false;
158: var $config_disable_imagecopyresampled = false;
159: var $config_disable_onlycreateable_passthru = false;
160: var $config_disable_realpath = false;
161:
162: var $config_http_user_agent = 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.12) Gecko/20050915 Firefox/1.0.7';
163:
164:
165:
166:
167:
168: var $debugmessages = array();
169: var $debugtiming = array();
170: var $fatalerror = null;
171:
172:
173:
174: var $thumbnailQuality = 75;
175: var $thumbnailFormat = null;
176:
177: var $sourceFilename = null;
178: var $rawImageData = null;
179: var $IMresizedData = null;
180: var $outputImageData = null;
181:
182: var $useRawIMoutput = false;
183:
184: var $gdimg_output = null;
185: var $gdimg_source = null;
186:
187: var $getimagesizeinfo = null;
188:
189: var $source_width = null;
190: var $source_height = null;
191:
192: var $thumbnailCropX = null;
193: var $thumbnailCropY = null;
194: var $thumbnailCropW = null;
195: var $thumbnailCropH = null;
196:
197: var $exif_thumbnail_width = null;
198: var $exif_thumbnail_height = null;
199: var $exif_thumbnail_type = null;
200: var $exif_thumbnail_data = null;
201: var $exif_raw_data = null;
202:
203: var $thumbnail_width = null;
204: var $thumbnail_height = null;
205: var $thumbnail_image_width = null;
206: var $thumbnail_image_height = null;
207:
208: var $tempFilesToDelete = array();
209: var $cache_filename = null;
210:
211: var $AlphaCapableFormats = array('png', 'ico', 'gif');
212: var $is_alpha = false;
213:
214: var $iswindows = null;
215: var $issafemode = null;
216: var $php_memory_limit = null;
217:
218: var $phpthumb_version = '1.7.14-201608101311';
219:
220:
221:
222:
223: function __construct() {
224: $this->phpThumb();
225: }
226:
227: function phpThumb() {
228: $this->DebugTimingMessage('phpThumb() constructor', __FILE__, __LINE__);
229: $this->DebugMessage('phpThumb() v'.$this->phpthumb_version, __FILE__, __LINE__);
230:
231: foreach (array(ini_get('memory_limit'), get_cfg_var('memory_limit')) as $php_config_memory_limit) {
232: if (strlen($php_config_memory_limit)) {
233: if (substr($php_config_memory_limit, -1, 1) == 'G') {
234: $php_config_memory_limit = intval(substr($php_config_memory_limit, 0, -1)) * 1073741824;
235: } elseif (substr($php_config_memory_limit, -1, 1) == 'M') {
236: $php_config_memory_limit = intval(substr($php_config_memory_limit, 0, -1)) * 1048576;
237: }
238: $this->php_memory_limit = max($this->php_memory_limit, $php_config_memory_limit);
239: }
240: }
241: if ($this->php_memory_limit > 0) {
242: $this->config_max_source_pixels = round($this->php_memory_limit * 0.20);
243: }
244:
245: $this->iswindows = (bool) (strtoupper(substr(PHP_OS, 0, 3)) == 'WIN');
246: $this->issafemode = (bool) preg_match('#(1|ON)#i', ini_get('safe_mode'));
247: $this->config_document_root = (!empty($_SERVER['DOCUMENT_ROOT']) ? $_SERVER['DOCUMENT_ROOT'] : $this->config_document_root);
248: $this->config_cache_prefix = ( isset($_SERVER['SERVER_NAME']) ? $_SERVER['SERVER_NAME'].'_' : '');
249:
250: $this->purgeTempFiles();
251:
252: $php_sapi_name = strtolower(function_exists('php_sapi_name') ? php_sapi_name() : '');
253: if ($php_sapi_name == 'cli') {
254: $this->config_allow_src_above_docroot = true;
255: }
256:
257: if (!$this->config_disable_debug) {
258:
259: $this->phpThumbDebug = (is_null($this->phpThumbDebug) ? 9 : max(1, intval($this->phpThumbDebug)));
260: }
261: }
262:
263: function __destruct() {
264: $this->purgeTempFiles();
265: }
266:
267:
268: function purgeTempFiles() {
269: foreach ($this->tempFilesToDelete as $tempFileToDelete) {
270: if (file_exists($tempFileToDelete)) {
271: $this->DebugMessage('Deleting temp file "'.$tempFileToDelete.'"', __FILE__, __LINE__);
272: @unlink($tempFileToDelete);
273: }
274: }
275: $this->tempFilesToDelete = array();
276: return true;
277: }
278:
279:
280: function setSourceFilename($sourceFilename) {
281:
282:
283: $this->sourceFilename = $sourceFilename;
284: $this->src = $sourceFilename;
285: if (is_null($this->config_output_format)) {
286: $sourceFileExtension = strtolower(substr(strrchr($sourceFilename, '.'), 1));
287: if (preg_match('#^[a-z]{3,4}$#', $sourceFileExtension)) {
288: $this->config_output_format = $sourceFileExtension;
289: $this->DebugMessage('setSourceFilename('.$sourceFilename.') set $this->config_output_format to "'.$sourceFileExtension.'"', __FILE__, __LINE__);
290: } else {
291: $this->DebugMessage('setSourceFilename('.$sourceFilename.') did NOT set $this->config_output_format to "'.$sourceFileExtension.'" because it did not seem like an appropriate image format', __FILE__, __LINE__);
292: }
293: }
294: $this->DebugMessage('setSourceFilename('.$sourceFilename.') set $this->sourceFilename to "'.$this->sourceFilename.'"', __FILE__, __LINE__);
295: return true;
296: }
297:
298:
299: function setSourceData($rawImageData, $sourceFilename='') {
300:
301:
302: $this->rawImageData = $rawImageData;
303: $this->DebugMessage('setSourceData() setting $this->rawImageData ('.strlen($this->rawImageData).' bytes; magic="'.substr($this->rawImageData, 0, 4).'" ('.phpthumb_functions::HexCharDisplay(substr($this->rawImageData, 0, 4)).'))', __FILE__, __LINE__);
304: if ($this->config_cache_source_enabled) {
305: $sourceFilename = ($sourceFilename ? $sourceFilename : md5($rawImageData));
306: if (!is_dir($this->config_cache_source_directory)) {
307: $this->ErrorImage('$this->config_cache_source_directory ('.$this->config_cache_source_directory.') is not a directory');
308: } elseif (!@is_writable($this->config_cache_source_directory)) {
309: $this->ErrorImage('$this->config_cache_source_directory ('.$this->config_cache_source_directory.') is not writable');
310: }
311: $this->DebugMessage('setSourceData() attempting to save source image to "'.$this->config_cache_source_directory.DIRECTORY_SEPARATOR.urlencode($sourceFilename).'"', __FILE__, __LINE__);
312: if ($fp = @fopen($this->config_cache_source_directory.DIRECTORY_SEPARATOR.urlencode($sourceFilename), 'wb')) {
313: fwrite($fp, $rawImageData);
314: fclose($fp);
315: } elseif (!$this->phpThumbDebug) {
316: $this->ErrorImage('setSourceData() failed to write to source cache ('.$this->config_cache_source_directory.DIRECTORY_SEPARATOR.urlencode($sourceFilename).')');
317: }
318: }
319: return true;
320: }
321:
322:
323: function setSourceImageResource($gdimg) {
324:
325: $this->gdimg_source = $gdimg;
326: return true;
327: }
328:
329:
330: function setParameter($param, $value) {
331: if ($param == 'src') {
332: $this->setSourceFilename($this->ResolveFilenameToAbsolute($value));
333: } elseif (@is_array($this->$param)) {
334: if (is_array($value)) {
335: foreach ($value as $arraykey => $arrayvalue) {
336: array_push($this->$param, $arrayvalue);
337: }
338: } else {
339: array_push($this->$param, $value);
340: }
341: } else {
342: $this->$param = $value;
343: }
344: return true;
345: }
346:
347:
348: function getParameter($param) {
349:
350: return $this->$param;
351:
352:
353:
354: }
355:
356:
357:
358: function GenerateThumbnail() {
359:
360: $this->setOutputFormat();
361: $this->phpThumbDebug('8a');
362: $this->ResolveSource();
363: $this->phpThumbDebug('8b');
364: $this->SetCacheFilename();
365: $this->phpThumbDebug('8c');
366: $this->ExtractEXIFgetImageSize();
367: $this->phpThumbDebug('8d');
368: if ($this->useRawIMoutput) {
369: $this->DebugMessage('Skipping rest of GenerateThumbnail() because ($this->useRawIMoutput == true)', __FILE__, __LINE__);
370: return true;
371: }
372: $this->phpThumbDebug('8e');
373: if (!$this->SourceImageToGD()) {
374: $this->DebugMessage('SourceImageToGD() failed', __FILE__, __LINE__);
375: return false;
376: }
377: $this->phpThumbDebug('8f');
378: $this->Rotate();
379: $this->phpThumbDebug('8g');
380: $this->CreateGDoutput();
381: $this->phpThumbDebug('8h');
382:
383:
384: $destination_offset_x = round(($this->thumbnail_width - $this->thumbnail_image_width) / 2);
385: $destination_offset_y = round(($this->thumbnail_height - $this->thumbnail_image_height) / 2);
386: if (($this->far == 'L') || ($this->far == 'TL') || ($this->far == 'BL')) {
387: $destination_offset_x = 0;
388: }
389: if (($this->far == 'R') || ($this->far == 'TR') || ($this->far == 'BR')) {
390: $destination_offset_x = round($this->thumbnail_width - $this->thumbnail_image_width);
391: }
392: if (($this->far == 'T') || ($this->far == 'TL') || ($this->far == 'TR')) {
393: $destination_offset_y = 0;
394: }
395: if (($this->far == 'B') || ($this->far == 'BL') || ($this->far == 'BR')) {
396: $destination_offset_y = round($this->thumbnail_height - $this->thumbnail_image_height);
397: }
398:
399:
400:
401:
402:
403:
404:
405:
406:
407:
408:
409:
410:
411:
412:
413: $this->ImageResizeFunction(
414: $this->gdimg_output,
415: $this->gdimg_source,
416: $destination_offset_x,
417: $destination_offset_y,
418: $this->thumbnailCropX,
419: $this->thumbnailCropY,
420: $this->thumbnail_image_width,
421: $this->thumbnail_image_height,
422: $this->thumbnailCropW,
423: $this->thumbnailCropH
424: );
425:
426: $this->DebugMessage('memory_get_usage() after copy-resize = '.(function_exists('memory_get_usage') ? @memory_get_usage() : 'n/a'), __FILE__, __LINE__);
427: imagedestroy($this->gdimg_source);
428: $this->DebugMessage('memory_get_usage() after imagedestroy = '.(function_exists('memory_get_usage') ? @memory_get_usage() : 'n/a'), __FILE__, __LINE__);
429:
430: $this->phpThumbDebug('8i');
431: $this->AntiOffsiteLinking();
432: $this->phpThumbDebug('8j');
433: $this->ApplyFilters();
434: $this->phpThumbDebug('8k');
435: $this->AlphaChannelFlatten();
436: $this->phpThumbDebug('8l');
437: $this->MaxFileSize();
438: $this->phpThumbDebug('8m');
439:
440: $this->DebugMessage('GenerateThumbnail() completed successfully', __FILE__, __LINE__);
441: return true;
442: }
443:
444:
445:
446: function RenderOutput() {
447: if (!$this->useRawIMoutput && !is_resource($this->gdimg_output)) {
448: $this->DebugMessage('RenderOutput() failed because !is_resource($this->gdimg_output)', __FILE__, __LINE__);
449: return false;
450: }
451: if (!$this->thumbnailFormat) {
452: $this->DebugMessage('RenderOutput() failed because $this->thumbnailFormat is empty', __FILE__, __LINE__);
453: return false;
454: }
455: if ($this->useRawIMoutput) {
456: $this->DebugMessage('RenderOutput copying $this->IMresizedData ('.strlen($this->IMresizedData).' bytes) to $this->outputImage', __FILE__, __LINE__);
457: $this->outputImageData = $this->IMresizedData;
458: return true;
459: }
460:
461: $builtin_formats = array();
462: if (function_exists('imagetypes')) {
463: $imagetypes = imagetypes();
464: $builtin_formats['wbmp'] = (bool) ($imagetypes & IMG_WBMP);
465: $builtin_formats['jpg'] = (bool) ($imagetypes & IMG_JPG);
466: $builtin_formats['gif'] = (bool) ($imagetypes & IMG_GIF);
467: $builtin_formats['png'] = (bool) ($imagetypes & IMG_PNG);
468: }
469:
470: $this->DebugMessage('imageinterlace($this->gdimg_output, '.intval($this->config_output_interlace).')', __FILE__, __LINE__);
471: imageinterlace($this->gdimg_output, intval($this->config_output_interlace));
472:
473: $this->DebugMessage('RenderOutput() attempting image'.strtolower(@$this->thumbnailFormat).'($this->gdimg_output)', __FILE__, __LINE__);
474: ob_start();
475: switch ($this->thumbnailFormat) {
476: case 'wbmp':
477: if (empty($builtin_formats['wbmp'])) {
478: $this->DebugMessage('GD does not have required built-in support for WBMP output', __FILE__, __LINE__);
479: ob_end_clean();
480: return false;
481: }
482: imagejpeg($this->gdimg_output, null, $this->thumbnailQuality);
483: $this->outputImageData = ob_get_contents();
484: break;
485:
486: case 'jpeg':
487: case 'jpg':
488: if (empty($builtin_formats['jpg'])) {
489: $this->DebugMessage('GD does not have required built-in support for JPEG output', __FILE__, __LINE__);
490: ob_end_clean();
491: return false;
492: }
493: imagejpeg($this->gdimg_output, null, $this->thumbnailQuality);
494: $this->outputImageData = ob_get_contents();
495: break;
496:
497: case 'png':
498: if (empty($builtin_formats['png'])) {
499: $this->DebugMessage('GD does not have required built-in support for PNG output', __FILE__, __LINE__);
500: ob_end_clean();
501: return false;
502: }
503: if (phpthumb_functions::version_compare_replacement(phpversion(), '5.1.2', '>=')) {
504:
505:
506: 507: 508: 509: 510: 511: 512: 513:
514: if (($this->thumbnailQuality >= -1) && ($this->thumbnailQuality <= 9)) {
515: $PNGquality = $this->thumbnailQuality;
516: } else {
517: $this->DebugMessage('Specified thumbnailQuality "'.$this->thumbnailQuality.'" is outside the accepted range (0-9, or -1). Using 6 as default value.', __FILE__, __LINE__);
518: $PNGquality = 6;
519: }
520: imagepng($this->gdimg_output, null, $PNGquality);
521: } else {
522: imagepng($this->gdimg_output);
523: }
524: $this->outputImageData = ob_get_contents();
525: break;
526:
527: case 'gif':
528: if (empty($builtin_formats['gif'])) {
529: $this->DebugMessage('GD does not have required built-in support for GIF output', __FILE__, __LINE__);
530: ob_end_clean();
531: return false;
532: }
533: imagegif($this->gdimg_output);
534: $this->outputImageData = ob_get_contents();
535: break;
536:
537: case 'bmp':
538: if (!@include_once(dirname(__FILE__).'/phpthumb.bmp.php')) {
539: $this->DebugMessage('Error including "'.dirname(__FILE__).'/phpthumb.bmp.php" which is required for BMP format output', __FILE__, __LINE__);
540: ob_end_clean();
541: return false;
542: }
543: $phpthumb_bmp = new phpthumb_bmp();
544: $this->outputImageData = $phpthumb_bmp->GD2BMPstring($this->gdimg_output);
545: unset($phpthumb_bmp);
546: break;
547:
548: case 'ico':
549: if (!@include_once(dirname(__FILE__).'/phpthumb.ico.php')) {
550: $this->DebugMessage('Error including "'.dirname(__FILE__).'/phpthumb.ico.php" which is required for ICO format output', __FILE__, __LINE__);
551: ob_end_clean();
552: return false;
553: }
554: $phpthumb_ico = new phpthumb_ico();
555: $arrayOfOutputImages = array($this->gdimg_output);
556: $this->outputImageData = $phpthumb_ico->GD2ICOstring($arrayOfOutputImages);
557: unset($phpthumb_ico);
558: break;
559:
560: default:
561: $this->DebugMessage('RenderOutput failed because $this->thumbnailFormat "'.$this->thumbnailFormat.'" is not valid', __FILE__, __LINE__);
562: ob_end_clean();
563: return false;
564: }
565: ob_end_clean();
566: if (!$this->outputImageData) {
567: $this->DebugMessage('RenderOutput() for "'.$this->thumbnailFormat.'" failed', __FILE__, __LINE__);
568: ob_end_clean();
569: return false;
570: }
571: $this->DebugMessage('RenderOutput() completing with $this->outputImageData = '.strlen($this->outputImageData).' bytes', __FILE__, __LINE__);
572: return true;
573: }
574:
575:
576:
577: function RenderToFile($filename) {
578: if (preg_match('#^[a-z0-9]+://#i', $filename)) {
579: $this->DebugMessage('RenderToFile() failed because $filename ('.$filename.') is a URL', __FILE__, __LINE__);
580: return false;
581: }
582:
583:
584: $renderfilename = $filename;
585: if (($filename{0} != '/') && ($filename{0} != '\\') && ($filename{1} != ':')) {
586: $renderfilename = $this->ResolveFilenameToAbsolute($renderfilename);
587: }
588: if (!@is_writable(dirname($renderfilename))) {
589: $this->DebugMessage('RenderToFile() failed because "'.dirname($renderfilename).'/" is not writable', __FILE__, __LINE__);
590: return false;
591: }
592: if (@is_file($renderfilename) && !@is_writable($renderfilename)) {
593: $this->DebugMessage('RenderToFile() failed because "'.$renderfilename.'" is not writable', __FILE__, __LINE__);
594: return false;
595: }
596:
597: if ($this->RenderOutput()) {
598: if (file_put_contents($renderfilename, $this->outputImageData)) {
599: @chmod($renderfilename, $this->getParameter('config_file_create_mask'));
600: $this->DebugMessage('RenderToFile('.$renderfilename.') succeeded', __FILE__, __LINE__);
601: return true;
602: }
603: if (!@file_exists($renderfilename)) {
604: $this->DebugMessage('RenderOutput ['.$this->thumbnailFormat.'('.$renderfilename.')] did not appear to fail, but the output image does not exist either...', __FILE__, __LINE__);
605: }
606: } else {
607: $this->DebugMessage('RenderOutput ['.$this->thumbnailFormat.'('.$renderfilename.')] failed', __FILE__, __LINE__);
608: }
609: return false;
610: }
611:
612:
613:
614: function OutputThumbnail() {
615: $this->purgeTempFiles();
616:
617: if (!$this->useRawIMoutput && !is_resource($this->gdimg_output)) {
618: $this->DebugMessage('OutputThumbnail() failed because !is_resource($this->gdimg_output)', __FILE__, __LINE__);
619: return false;
620: }
621: if (headers_sent()) {
622: return $this->ErrorImage('OutputThumbnail() failed - headers already sent');
623: }
624:
625: $downloadfilename = phpthumb_functions::SanitizeFilename(is_string($this->sia) ? $this->sia : ($this->down ? $this->down : 'phpThumb_generated_thumbnail'.'.'.$this->thumbnailFormat));
626: $this->DebugMessage('Content-Disposition header filename set to "'.$downloadfilename.'"', __FILE__, __LINE__);
627: if ($downloadfilename) {
628: header('Content-Disposition: '.($this->down ? 'attachment' : 'inline').'; filename="'.$downloadfilename.'"');
629: } else {
630: $this->DebugMessage('failed to send Content-Disposition header because $downloadfilename is empty', __FILE__, __LINE__);
631: }
632:
633: if ($this->useRawIMoutput) {
634:
635: header('Content-Type: '.phpthumb_functions::ImageTypeToMIMEtype($this->thumbnailFormat));
636: echo $this->IMresizedData;
637:
638: } else {
639:
640: $this->DebugMessage('imageinterlace($this->gdimg_output, '.intval($this->config_output_interlace).')', __FILE__, __LINE__);
641: imageinterlace($this->gdimg_output, intval($this->config_output_interlace));
642: switch ($this->thumbnailFormat) {
643: case 'jpeg':
644: header('Content-Type: '.phpthumb_functions::ImageTypeToMIMEtype($this->thumbnailFormat));
645: $ImageOutFunction = 'image'.$this->thumbnailFormat;
646: @$ImageOutFunction($this->gdimg_output, null, $this->thumbnailQuality);
647: break;
648:
649: case 'png':
650: case 'gif':
651: header('Content-Type: '.phpthumb_functions::ImageTypeToMIMEtype($this->thumbnailFormat));
652: $ImageOutFunction = 'image'.$this->thumbnailFormat;
653: @$ImageOutFunction($this->gdimg_output);
654: break;
655:
656: case 'bmp':
657: if (!@include_once(dirname(__FILE__).'/phpthumb.bmp.php')) {
658: $this->DebugMessage('Error including "'.dirname(__FILE__).'/phpthumb.bmp.php" which is required for BMP format output', __FILE__, __LINE__);
659: return false;
660: }
661: $phpthumb_bmp = new phpthumb_bmp();
662: if (is_object($phpthumb_bmp)) {
663: $bmp_data = $phpthumb_bmp->GD2BMPstring($this->gdimg_output);
664: unset($phpthumb_bmp);
665: if (!$bmp_data) {
666: $this->DebugMessage('$phpthumb_bmp->GD2BMPstring() failed', __FILE__, __LINE__);
667: return false;
668: }
669: header('Content-Type: '.phpthumb_functions::ImageTypeToMIMEtype($this->thumbnailFormat));
670: echo $bmp_data;
671: } else {
672: $this->DebugMessage('new phpthumb_bmp() failed', __FILE__, __LINE__);
673: return false;
674: }
675: break;
676:
677: case 'ico':
678: if (!@include_once(dirname(__FILE__).'/phpthumb.ico.php')) {
679: $this->DebugMessage('Error including "'.dirname(__FILE__).'/phpthumb.ico.php" which is required for ICO format output', __FILE__, __LINE__);
680: return false;
681: }
682: $phpthumb_ico = new phpthumb_ico();
683: if (is_object($phpthumb_ico)) {
684: $arrayOfOutputImages = array($this->gdimg_output);
685: $ico_data = $phpthumb_ico->GD2ICOstring($arrayOfOutputImages);
686: unset($phpthumb_ico);
687: if (!$ico_data) {
688: $this->DebugMessage('$phpthumb_ico->GD2ICOstring() failed', __FILE__, __LINE__);
689: return false;
690: }
691: header('Content-Type: '.phpthumb_functions::ImageTypeToMIMEtype($this->thumbnailFormat));
692: echo $ico_data;
693: } else {
694: $this->DebugMessage('new phpthumb_ico() failed', __FILE__, __LINE__);
695: return false;
696: }
697: break;
698:
699: default:
700: $this->DebugMessage('OutputThumbnail failed because $this->thumbnailFormat "'.$this->thumbnailFormat.'" is not valid', __FILE__, __LINE__);
701: return false;
702: break;
703: }
704:
705: }
706: return true;
707: }
708:
709:
710:
711: function CleanUpCacheDirectory() {
712: $this->DebugMessage('CleanUpCacheDirectory() set to purge ('.(is_null($this->config_cache_maxage) ? 'NULL' : number_format($this->config_cache_maxage / 86400, 1)).' days; '.(is_null($this->config_cache_maxsize) ? 'NULL' : number_format($this->config_cache_maxsize / 1048576, 2)).' MB; '.(is_null($this->config_cache_maxfiles) ? 'NULL' : number_format($this->config_cache_maxfiles)).' files)', __FILE__, __LINE__);
713:
714: if (!is_writable($this->config_cache_directory)) {
715: $this->DebugMessage('CleanUpCacheDirectory() skipped because "'.$this->config_cache_directory.'" is not writable', __FILE__, __LINE__);
716: return true;
717: }
718:
719:
720: $phpThumbCacheStats_filename = $this->config_cache_directory.DIRECTORY_SEPARATOR.'phpThumbCacheStats.txt';
721: if (file_exists($phpThumbCacheStats_filename) && is_readable($phpThumbCacheStats_filename) && (filemtime($phpThumbCacheStats_filename) >= (time() - 3600))) {
722: $this->DebugMessage('CleanUpCacheDirectory() skipped because "'.$phpThumbCacheStats_filename.'" is recently modified', __FILE__, __LINE__);
723: return true;
724: }
725: if (!@touch($phpThumbCacheStats_filename)) {
726: $this->DebugMessage('touch('.$phpThumbCacheStats_filename.') failed', __FILE__, __LINE__);
727: }
728:
729: $DeletedKeys = array();
730: $AllFilesInCacheDirectory = array();
731: if (($this->config_cache_maxage > 0) || ($this->config_cache_maxsize > 0) || ($this->config_cache_maxfiles > 0)) {
732: $CacheDirOldFilesAge = array();
733: $CacheDirOldFilesSize = array();
734: $AllFilesInCacheDirectory = phpthumb_functions::GetAllFilesInSubfolders($this->config_cache_directory);
735: foreach ($AllFilesInCacheDirectory as $fullfilename) {
736: if (preg_match('#'.preg_quote($this->config_cache_prefix).'#i', $fullfilename) && file_exists($fullfilename)) {
737: $CacheDirOldFilesAge[$fullfilename] = @fileatime($fullfilename);
738: if ($CacheDirOldFilesAge[$fullfilename] == 0) {
739: $CacheDirOldFilesAge[$fullfilename] = @filemtime($fullfilename);
740: }
741: $CacheDirOldFilesSize[$fullfilename] = @filesize($fullfilename);
742: }
743: }
744: if (empty($CacheDirOldFilesSize)) {
745: $this->DebugMessage('CleanUpCacheDirectory() skipped because $CacheDirOldFilesSize is empty (phpthumb_functions::GetAllFilesInSubfolders('.$this->config_cache_directory.') found no files)', __FILE__, __LINE__);
746: return true;
747: }
748: $DeletedKeys['zerobyte'] = array();
749: foreach ($CacheDirOldFilesSize as $fullfilename => $filesize) {
750:
751: $cutofftime = time() - 3600;
752: if (($filesize == 0) && ($CacheDirOldFilesAge[$fullfilename] < $cutofftime)) {
753: $this->DebugMessage('deleting "'.$fullfilename.'"', __FILE__, __LINE__);
754: if (@unlink($fullfilename)) {
755: $DeletedKeys['zerobyte'][] = $fullfilename;
756: unset($CacheDirOldFilesSize[$fullfilename]);
757: unset($CacheDirOldFilesAge[$fullfilename]);
758: }
759: }
760: }
761: $this->DebugMessage('CleanUpCacheDirectory() purged '.count($DeletedKeys['zerobyte']).' zero-byte files', __FILE__, __LINE__);
762: asort($CacheDirOldFilesAge);
763:
764: if ($this->config_cache_maxfiles > 0) {
765: $TotalCachedFiles = count($CacheDirOldFilesAge);
766: $DeletedKeys['maxfiles'] = array();
767: foreach ($CacheDirOldFilesAge as $fullfilename => $filedate) {
768: if ($TotalCachedFiles > $this->config_cache_maxfiles) {
769: $this->DebugMessage('deleting "'.$fullfilename.'"', __FILE__, __LINE__);
770: if (@unlink($fullfilename)) {
771: $TotalCachedFiles--;
772: $DeletedKeys['maxfiles'][] = $fullfilename;
773: }
774: } else {
775:
776: break;
777: }
778: }
779: $this->DebugMessage('CleanUpCacheDirectory() purged '.count($DeletedKeys['maxfiles']).' files based on (config_cache_maxfiles='.$this->config_cache_maxfiles.')', __FILE__, __LINE__);
780: foreach ($DeletedKeys['maxfiles'] as $fullfilename) {
781: unset($CacheDirOldFilesAge[$fullfilename]);
782: unset($CacheDirOldFilesSize[$fullfilename]);
783: }
784: }
785:
786: if ($this->config_cache_maxage > 0) {
787: $mindate = time() - $this->config_cache_maxage;
788: $DeletedKeys['maxage'] = array();
789: foreach ($CacheDirOldFilesAge as $fullfilename => $filedate) {
790: if ($filedate > 0) {
791: if ($filedate < $mindate) {
792: $this->DebugMessage('deleting "'.$fullfilename.'"', __FILE__, __LINE__);
793: if (@unlink($fullfilename)) {
794: $DeletedKeys['maxage'][] = $fullfilename;
795: }
796: } else {
797:
798: break;
799: }
800: }
801: }
802: $this->DebugMessage('CleanUpCacheDirectory() purged '.count($DeletedKeys['maxage']).' files based on (config_cache_maxage='.$this->config_cache_maxage.')', __FILE__, __LINE__);
803: foreach ($DeletedKeys['maxage'] as $fullfilename) {
804: unset($CacheDirOldFilesAge[$fullfilename]);
805: unset($CacheDirOldFilesSize[$fullfilename]);
806: }
807: }
808:
809: if ($this->config_cache_maxsize > 0) {
810: $TotalCachedFileSize = array_sum($CacheDirOldFilesSize);
811: $DeletedKeys['maxsize'] = array();
812: foreach ($CacheDirOldFilesAge as $fullfilename => $filedate) {
813: if ($TotalCachedFileSize > $this->config_cache_maxsize) {
814: $this->DebugMessage('deleting "'.$fullfilename.'"', __FILE__, __LINE__);
815: if (@unlink($fullfilename)) {
816: $TotalCachedFileSize -= $CacheDirOldFilesSize[$fullfilename];
817: $DeletedKeys['maxsize'][] = $fullfilename;
818: }
819: } else {
820:
821: break;
822: }
823: }
824: $this->DebugMessage('CleanUpCacheDirectory() purged '.count($DeletedKeys['maxsize']).' files based on (config_cache_maxsize='.$this->config_cache_maxsize.')', __FILE__, __LINE__);
825: foreach ($DeletedKeys['maxsize'] as $fullfilename) {
826: unset($CacheDirOldFilesAge[$fullfilename]);
827: unset($CacheDirOldFilesSize[$fullfilename]);
828: }
829: }
830:
831: } else {
832: $this->DebugMessage('skipping CleanUpCacheDirectory() because config set to not use it', __FILE__, __LINE__);
833: }
834: $totalpurged = 0;
835: foreach ($DeletedKeys as $key => $value) {
836: $totalpurged += count($value);
837: }
838: $this->DebugMessage('CleanUpCacheDirectory() purged '.$totalpurged.' files (from '.count($AllFilesInCacheDirectory).') based on config settings', __FILE__, __LINE__);
839: if ($totalpurged > 0) {
840: $empty_dirs = array();
841: foreach ($AllFilesInCacheDirectory as $fullfilename) {
842: if (is_dir($fullfilename)) {
843: $empty_dirs[$this->realPathSafe($fullfilename)] = 1;
844: } else {
845: unset($empty_dirs[$this->realPathSafe(dirname($fullfilename))]);
846: }
847: }
848: krsort($empty_dirs);
849: $totalpurgeddirs = 0;
850: foreach ($empty_dirs as $empty_dir => $dummy) {
851: if ($empty_dir == $this->config_cache_directory) {
852:
853: continue;
854: } elseif (@rmdir($empty_dir)) {
855: $totalpurgeddirs++;
856: } else {
857: $this->DebugMessage('failed to rmdir('.$empty_dir.')', __FILE__, __LINE__);
858: }
859: }
860: $this->DebugMessage('purged '.$totalpurgeddirs.' empty directories', __FILE__, __LINE__);
861: }
862: return true;
863: }
864:
865:
866:
867:
868: function resetObject() {
869: $class_vars = get_class_vars(get_class($this));
870: foreach ($class_vars as $key => $value) {
871:
872: if (!preg_match('#^(config_|debug|fatalerror)#i', $key)) {
873: $this->$key = $value;
874: }
875: }
876: $this->phpThumb();
877: return true;
878: }
879:
880:
881:
882: function ResolveSource() {
883: if (is_resource($this->gdimg_source)) {
884: $this->DebugMessage('ResolveSource() exiting because is_resource($this->gdimg_source)', __FILE__, __LINE__);
885: return true;
886: }
887: if ($this->rawImageData) {
888: $this->sourceFilename = null;
889: $this->DebugMessage('ResolveSource() exiting because $this->rawImageData is set ('.number_format(strlen($this->rawImageData)).' bytes)', __FILE__, __LINE__);
890: return true;
891: }
892: if ($this->sourceFilename) {
893: $this->sourceFilename = $this->ResolveFilenameToAbsolute($this->sourceFilename);
894: $this->DebugMessage('$this->sourceFilename set to "'.$this->sourceFilename.'"', __FILE__, __LINE__);
895: } elseif ($this->src) {
896: $this->sourceFilename = $this->ResolveFilenameToAbsolute($this->src);
897: $this->DebugMessage('$this->sourceFilename set to "'.$this->sourceFilename.'" from $this->src ('.$this->src.')', __FILE__, __LINE__);
898: } else {
899: return $this->ErrorImage('$this->sourceFilename and $this->src are both empty');
900: }
901: if ($this->iswindows && ((substr($this->sourceFilename, 0, 2) == '//') || (substr($this->sourceFilename, 0, 2) == '\\\\'))) {
902:
903: } elseif (preg_match('#^[a-z0-9]+://#i', $this->sourceFilename, $protocol_matches)) {
904: if (preg_match('#^(f|ht)tps?\://#i', $this->sourceFilename)) {
905:
906: if ($this->config_http_user_agent) {
907: ini_set('user_agent', $this->config_http_user_agent);
908: }
909: } else {
910: return $this->ErrorImage('only FTP and HTTP/HTTPS protocols are allowed, "'.$protocol_matches[1].'" is not');
911: }
912: } elseif (!@file_exists($this->sourceFilename)) {
913: return $this->ErrorImage('"'.$this->sourceFilename.'" does not exist');
914: } elseif (!@is_file($this->sourceFilename)) {
915: return $this->ErrorImage('"'.$this->sourceFilename.'" is not a file');
916: }
917: return true;
918: }
919:
920:
921: function setOutputFormat() {
922: static $alreadyCalled = false;
923: if ($this->thumbnailFormat && $alreadyCalled) {
924: return true;
925: }
926: $alreadyCalled = true;
927:
928: $AvailableImageOutputFormats = array();
929: $AvailableImageOutputFormats[] = 'text';
930: if (@is_readable(dirname(__FILE__).'/phpthumb.ico.php')) {
931: $AvailableImageOutputFormats[] = 'ico';
932: }
933: if (@is_readable(dirname(__FILE__).'/phpthumb.bmp.php')) {
934: $AvailableImageOutputFormats[] = 'bmp';
935: }
936:
937: $this->thumbnailFormat = 'ico';
938:
939:
940: if (function_exists('imagetypes')) {
941: $imagetypes = imagetypes();
942: if ($imagetypes & IMG_WBMP) {
943: $this->thumbnailFormat = 'wbmp';
944: $AvailableImageOutputFormats[] = 'wbmp';
945: }
946: if ($imagetypes & IMG_GIF) {
947: $this->thumbnailFormat = 'gif';
948: $AvailableImageOutputFormats[] = 'gif';
949: }
950: if ($imagetypes & IMG_PNG) {
951: $this->thumbnailFormat = 'png';
952: $AvailableImageOutputFormats[] = 'png';
953: }
954: if ($imagetypes & IMG_JPG) {
955: $this->thumbnailFormat = 'jpeg';
956: $AvailableImageOutputFormats[] = 'jpeg';
957: }
958: } else {
959: $this->DebugMessage('imagetypes() does not exist - GD support might not be enabled?', __FILE__, __LINE__);
960: }
961: if ($this->ImageMagickVersion()) {
962: $IMformats = array('jpeg', 'png', 'gif', 'bmp', 'ico', 'wbmp');
963: $this->DebugMessage('Addding ImageMagick formats to $AvailableImageOutputFormats ('.implode(';', $AvailableImageOutputFormats).')', __FILE__, __LINE__);
964: foreach ($IMformats as $key => $format) {
965: $AvailableImageOutputFormats[] = $format;
966: }
967: }
968: $AvailableImageOutputFormats = array_unique($AvailableImageOutputFormats);
969: $this->DebugMessage('$AvailableImageOutputFormats = array('.implode(';', $AvailableImageOutputFormats).')', __FILE__, __LINE__);
970:
971: $this->f = preg_replace('#[^a-z]#', '', strtolower($this->f));
972: if (strtolower($this->config_output_format) == 'jpg') {
973: $this->config_output_format = 'jpeg';
974: }
975: if (strtolower($this->f) == 'jpg') {
976: $this->f = 'jpeg';
977: }
978: if (phpthumb_functions::CaseInsensitiveInArray($this->config_output_format, $AvailableImageOutputFormats)) {
979:
980: $this->DebugMessage('$this->thumbnailFormat set to $this->config_output_format "'.strtolower($this->config_output_format).'"', __FILE__, __LINE__);
981: $this->thumbnailFormat = strtolower($this->config_output_format);
982: } elseif ($this->config_output_format) {
983: $this->DebugMessage('$this->thumbnailFormat staying as "'.$this->thumbnailFormat.'" because $this->config_output_format ('.strtolower($this->config_output_format).') is not in $AvailableImageOutputFormats', __FILE__, __LINE__);
984: }
985: if ($this->f && (phpthumb_functions::CaseInsensitiveInArray($this->f, $AvailableImageOutputFormats))) {
986:
987: $this->DebugMessage('$this->thumbnailFormat set to $this->f "'.strtolower($this->f).'"', __FILE__, __LINE__);
988: $this->thumbnailFormat = strtolower($this->f);
989: } elseif ($this->f) {
990: $this->DebugMessage('$this->thumbnailFormat staying as "'.$this->thumbnailFormat.'" because $this->f ('.strtolower($this->f).') is not in $AvailableImageOutputFormats', __FILE__, __LINE__);
991: }
992:
993:
994:
995:
996: $this->thumbnailQuality = max(1, min(99, ($this->q ? intval($this->q) : 75)));
997: $this->DebugMessage('$this->thumbnailQuality set to "'.$this->thumbnailQuality.'"', __FILE__, __LINE__);
998:
999: return true;
1000: }
1001:
1002:
1003: function setCacheDirectory() {
1004:
1005: $this->DebugMessage('setCacheDirectory() starting with config_cache_directory = "'.$this->config_cache_directory.'"', __FILE__, __LINE__);
1006: if (substr($this->config_cache_directory, 0, 1) == '.') {
1007: if (preg_match('#^(f|ht)tps?\://#i', $this->src)) {
1008: if (!$this->config_cache_disable_warning) {
1009: $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');
1010: }
1011: } elseif ($this->src) {
1012:
1013: $this->config_cache_directory = dirname($this->ResolveFilenameToAbsolute($this->src)).DIRECTORY_SEPARATOR.$this->config_cache_directory;
1014: } else {
1015:
1016: }
1017: }
1018: if (substr($this->config_cache_directory, -1) == '/') {
1019: $this->config_cache_directory = substr($this->config_cache_directory, 0, -1);
1020: }
1021: if ($this->iswindows) {
1022: $this->config_cache_directory = str_replace('/', DIRECTORY_SEPARATOR, $this->config_cache_directory);
1023: }
1024: if ($this->config_cache_directory) {
1025: $real_cache_path = $this->realPathSafe($this->config_cache_directory);
1026: if (!$real_cache_path) {
1027: $this->DebugMessage('$this->realPathSafe($this->config_cache_directory) failed for "'.$this->config_cache_directory.'"', __FILE__, __LINE__);
1028: if (!is_dir($this->config_cache_directory)) {
1029: $this->DebugMessage('!is_dir('.$this->config_cache_directory.')', __FILE__, __LINE__);
1030: }
1031: }
1032: if ($real_cache_path) {
1033: $this->DebugMessage('setting config_cache_directory to $this->realPathSafe('.$this->config_cache_directory.') = "'.$real_cache_path.'"', __FILE__, __LINE__);
1034: $this->config_cache_directory = $real_cache_path;
1035: }
1036: }
1037: if (!is_dir($this->config_cache_directory)) {
1038: if (!$this->config_cache_disable_warning) {
1039: $this->ErrorImage('$this->config_cache_directory ('.$this->config_cache_directory.') does not exist. Adjust "cache_directory" or "cache_disable_warning" in phpThumb.config.php');
1040: }
1041: $this->DebugMessage('$this->config_cache_directory ('.$this->config_cache_directory.') is not a directory', __FILE__, __LINE__);
1042: $this->config_cache_directory = null;
1043: } elseif (!@is_writable($this->config_cache_directory)) {
1044: $this->DebugMessage('$this->config_cache_directory is not writable ('.$this->config_cache_directory.')', __FILE__, __LINE__);
1045: }
1046:
1047: $this->InitializeTempDirSetting();
1048: if (!@is_dir($this->config_temp_directory) && !@is_writable($this->config_temp_directory) && @is_dir($this->config_cache_directory) && @is_writable($this->config_cache_directory)) {
1049: $this->DebugMessage('setting $this->config_temp_directory = $this->config_cache_directory ('.$this->config_cache_directory.')', __FILE__, __LINE__);
1050: $this->config_temp_directory = $this->config_cache_directory;
1051: }
1052: return true;
1053: }
1054:
1055: 1056:
1057:
1058: function applyPathSegment(&$segments, $segment) {
1059: if ($segment == '.') {
1060: return;
1061: }
1062: if ($segment == '') {
1063: $test = array_pop($segments);
1064: if (is_null($test)) {
1065: $segments[] = $segment;
1066: } elseif ($test == '') {
1067: $test = array_pop($segments);
1068: if (is_null($test)) {
1069: $segments[] = $test;
1070: $segments[] = $segment;
1071: } else {
1072: $segments[] = $test;
1073: $segments[] = $test;
1074: }
1075: } else {
1076: $segments[] = $test;
1077: }
1078: } else {
1079: if ($segment == '..') {
1080: $test = array_pop($segments);
1081: if (is_null($test)) {
1082: $segments[] = $segment;
1083: } elseif ($test == '..') {
1084: $segments[] = $test;
1085: $segments[] = $segment;
1086: } else {
1087: if ($test == '') {
1088: $segments[] = $test;
1089: }
1090: }
1091: } else {
1092: $segments[] = $segment;
1093: }
1094: }
1095: }
1096:
1097:
1098:
1099: function normalizePath($segments) {
1100: $parts = array();
1101: foreach ($segments as $segment) {
1102: $this->applyPathSegment($parts, $segment);
1103: }
1104: return $parts;
1105: }
1106:
1107:
1108:
1109: function matchPath($path, $allowed_dirs) {
1110: if (!empty($allowed_dirs)) {
1111: foreach ($allowed_dirs as $one_dir) {
1112: if (preg_match('#^'.preg_quote(str_replace(DIRECTORY_SEPARATOR, '/', $this->realPathSafe($one_dir))).'#', $path)) {
1113: return true;
1114: }
1115: }
1116: }
1117: return false;
1118: }
1119:
1120:
1121:
1122: function isInOpenBasedir($path) {
1123: static $open_basedirs = null;
1124: if (is_null($open_basedirs)) {
1125: $ini_text = ini_get('open_basedir');
1126: $this->DebugMessage('open_basedir: "'.$ini_text.'"', __FILE__, __LINE__);
1127: $open_basedirs = array();
1128: if (strlen($ini_text) > 0) {
1129: foreach (preg_split('#[;:]#', $ini_text) as $key => $value) {
1130: $open_basedirs[$key] = $this->realPathSafe($value);
1131: }
1132: }
1133: }
1134: return (empty($open_basedirs) || $this->matchPath($path, $open_basedirs));
1135: }
1136:
1137:
1138:
1139: function resolvePath($path, $allowed_dirs) {
1140: $this->DebugMessage('resolvePath: '.$path.' (allowed_dirs: '.print_r($allowed_dirs, true).')', __FILE__, __LINE__);
1141:
1142:
1143: if (!$this->config_allow_src_above_docroot) {
1144: array_unshift($allowed_dirs, $this->realPathSafe($this->config_document_root));
1145: } else {
1146: if (!$this->config_allow_src_above_phpthumb) {
1147: array_unshift($allowed_dirs, $this->realPathSafe(dirname(__FILE__)));
1148: } else {
1149:
1150: $this->DebugMessage('resolvePath: checks disabled, returning '.$this->realPathSafe($path), __FILE__, __LINE__);
1151: return $this->realPathSafe($path);
1152: }
1153: }
1154: if ($path == '') {
1155: return null;
1156: }
1157:
1158: do {
1159: $this->DebugMessage('resolvePath: iteration, path='.$path.', base path = '.$allowed_dirs[0], __FILE__, __LINE__);
1160:
1161: $parts = array();
1162:
1163:
1164: $segments = explode(DIRECTORY_SEPARATOR, $path);
1165: for ($i = 0; $i < count($segments); $i++) {
1166: $this->applyPathSegment($parts, $segments[$i]);
1167: $thispart = implode(DIRECTORY_SEPARATOR, $parts);
1168: if ($this->isInOpenBasedir($thispart)) {
1169: if (is_link($thispart)) {
1170: break;
1171: }
1172: }
1173: }
1174:
1175: $this->DebugMessage('resolvePath: stop at component '.$i, __FILE__, __LINE__);
1176:
1177: $path = implode(DIRECTORY_SEPARATOR, $parts);
1178: $this->DebugMessage('resolvePath: stop at path='.$path, __FILE__, __LINE__);
1179: if (!$this->matchPath($path, $allowed_dirs)) {
1180: $this->DebugMessage('resolvePath: no match, returning null', __FILE__, __LINE__);
1181: return null;
1182: }
1183: if ($i >= count($segments)) {
1184: $this->DebugMessage('resolvePath: path parsed, over', __FILE__, __LINE__);
1185: break;
1186: }
1187:
1188: $path = readlink($path);
1189: $this->DebugMessage('resolvePath: symlink matched, target='.$path, __FILE__, __LINE__);
1190:
1191: 1192: 1193: 1194: 1195: 1196: 1197: 1198: 1199: 1200:
1201: if ($this->config_auto_allow_symlinks) {
1202: $allowed_dirs[0] = $path;
1203: }
1204: $path = $path.DIRECTORY_SEPARATOR.implode(DIRECTORY_SEPARATOR, array_slice($segments,$i + 1));
1205: } while (true);
1206: return $path;
1207: }
1208:
1209:
1210: function realPathSafe($filename) {
1211:
1212:
1213: if (!$this->config_disable_realpath) {
1214: return realpath($filename);
1215: }
1216:
1217:
1218: $newfilename = preg_replace('#[\\/]+#', DIRECTORY_SEPARATOR, $filename);
1219: if (!preg_match('#^'.DIRECTORY_SEPARATOR.'#', $newfilename)) {
1220: $newfilename = dirname(__FILE__).DIRECTORY_SEPARATOR.$newfilename;
1221: }
1222: do {
1223: $beforeloop = $newfilename;
1224:
1225:
1226: $newfilename = preg_replace('#'.DIRECTORY_SEPARATOR.'+#', DIRECTORY_SEPARATOR, $newfilename);
1227:
1228:
1229: $newfilename = preg_replace('#'.DIRECTORY_SEPARATOR.'\\.'.DIRECTORY_SEPARATOR.'#', DIRECTORY_SEPARATOR, $newfilename);
1230:
1231:
1232: $newfilename = preg_replace('#^\\.'.DIRECTORY_SEPARATOR.'#', '', $newfilename);
1233:
1234:
1235: $newfilename = preg_replace('#'.DIRECTORY_SEPARATOR.'\\.$#', '', $newfilename);
1236:
1237:
1238: $newfilename = preg_replace('#'.DIRECTORY_SEPARATOR.'[^'.DIRECTORY_SEPARATOR.']+'.DIRECTORY_SEPARATOR.'\\.\\.'.DIRECTORY_SEPARATOR.'#', DIRECTORY_SEPARATOR, $newfilename);
1239:
1240:
1241: $newfilename = preg_replace('#'.DIRECTORY_SEPARATOR.'[^'.DIRECTORY_SEPARATOR.']+'.DIRECTORY_SEPARATOR.'\\.\\.$#', '', $newfilename);
1242:
1243: } while ($newfilename != $beforeloop);
1244: return $newfilename;
1245: }
1246:
1247:
1248: function ResolveFilenameToAbsolute($filename) {
1249: if (empty($filename)) {
1250: return false;
1251: }
1252:
1253: if (preg_match('#^[a-z0-9]+\:/{1,2}#i', $filename)) {
1254:
1255:
1256:
1257:
1258:
1259: return $filename;
1260:
1261: } elseif ($this->iswindows && isset($filename{1}) && ($filename{1} == ':')) {
1262:
1263:
1264: $AbsoluteFilename = $filename;
1265:
1266: } elseif ($this->iswindows && ((substr($filename, 0, 2) == '//') || (substr($filename, 0, 2) == '\\\\'))) {
1267:
1268:
1269: $AbsoluteFilename = $filename;
1270:
1271: } elseif ($filename{0} == '/') {
1272:
1273: if (@is_readable($filename) && !@is_readable($this->config_document_root.$filename)) {
1274:
1275:
1276: $AbsoluteFilename = $filename;
1277:
1278: } elseif (isset($filename{1}) && ($filename{1} == '~')) {
1279:
1280:
1281: if ($ApacheLookupURIarray = phpthumb_functions::ApacheLookupURIarray($filename)) {
1282: $AbsoluteFilename = $ApacheLookupURIarray['filename'];
1283: } else {
1284: $AbsoluteFilename = $this->realPathSafe($filename);
1285: if (@is_readable($AbsoluteFilename)) {
1286: $this->DebugMessage('phpthumb_functions::ApacheLookupURIarray() failed for "'.$filename.'", but the correct filename ('.$AbsoluteFilename.') seems to have been resolved with $this->realPathSafe($filename)', __FILE__, __LINE__);
1287: } elseif (is_dir(dirname($AbsoluteFilename))) {
1288: $this->DebugMessage('phpthumb_functions::ApacheLookupURIarray() failed for "'.dirname($filename).'", but the correct directory ('.dirname($AbsoluteFilename).') seems to have been resolved with $this->realPathSafe(.)', __FILE__, __LINE__);
1289: } else {
1290: 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 (ex: "/home/user/httpdocs/image.jpg" instead of "/~user/image.jpg")');
1291: }
1292: }
1293:
1294: } else {
1295:
1296:
1297: if (preg_match('#^'.preg_quote($this->config_document_root).'#', $filename)) {
1298: $AbsoluteFilename = $filename;
1299: $this->DebugMessage('ResolveFilenameToAbsolute() NOT prepending $this->config_document_root ('.$this->config_document_root.') to $filename ('.$filename.') resulting in ($AbsoluteFilename = "'.$AbsoluteFilename.'")', __FILE__, __LINE__);
1300: } else {
1301: $AbsoluteFilename = $this->config_document_root.$filename;
1302: $this->DebugMessage('ResolveFilenameToAbsolute() prepending $this->config_document_root ('.$this->config_document_root.') to $filename ('.$filename.') resulting in ($AbsoluteFilename = "'.$AbsoluteFilename.'")', __FILE__, __LINE__);
1303: }
1304:
1305: }
1306:
1307: } else {
1308:
1309:
1310: $AbsoluteFilename = dirname(__FILE__).DIRECTORY_SEPARATOR.preg_replace('#[/\\\\]#', DIRECTORY_SEPARATOR, $filename);
1311:
1312: if (substr(dirname(@$_SERVER['PHP_SELF']), 0, 2) == '/~') {
1313: if ($ApacheLookupURIarray = phpthumb_functions::ApacheLookupURIarray(dirname(@$_SERVER['PHP_SELF']))) {
1314: $AbsoluteFilename = $ApacheLookupURIarray['filename'].DIRECTORY_SEPARATOR.$filename;
1315: } else {
1316: $AbsoluteFilename = $this->realPathSafe('.').DIRECTORY_SEPARATOR.$filename;
1317: if (@is_readable($AbsoluteFilename)) {
1318: $this->DebugMessage('phpthumb_functions::ApacheLookupURIarray() failed for "'.dirname(@$_SERVER['PHP_SELF']).'", but the correct filename ('.$AbsoluteFilename.') seems to have been resolved with $this->realPathSafe(.)/$filename', __FILE__, __LINE__);
1319: } elseif (is_dir(dirname($AbsoluteFilename))) {
1320: $this->DebugMessage('phpthumb_functions::ApacheLookupURIarray() failed for "'.dirname(@$_SERVER['PHP_SELF']).'", but the correct directory ('.dirname($AbsoluteFilename).') seems to have been resolved with $this->realPathSafe(.)', __FILE__, __LINE__);
1321: } else {
1322: 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');
1323: }
1324: }
1325: }
1326:
1327: }
1328: 1329: 1330: 1331: 1332: 1333: 1334: 1335: 1336: 1337:
1338: if ($this->iswindows) {
1339: $AbsoluteFilename = preg_replace('#^'.preg_quote($this->realPathSafe($this->config_document_root)).'#i', str_replace('\\', '\\\\', $this->realPathSafe($this->config_document_root)), $AbsoluteFilename);
1340: $AbsoluteFilename = str_replace(DIRECTORY_SEPARATOR, '/', $AbsoluteFilename);
1341: }
1342: $AbsoluteFilename = $this->resolvePath($AbsoluteFilename, $this->config_additional_allowed_dirs);
1343: if (!$this->config_allow_src_above_docroot && !preg_match('#^'.preg_quote(str_replace(DIRECTORY_SEPARATOR, '/', $this->realPathSafe($this->config_document_root))).'#', $AbsoluteFilename)) {
1344: $this->DebugMessage('!$this->config_allow_src_above_docroot therefore setting "'.$AbsoluteFilename.'" (outside "'.$this->realPathSafe($this->config_document_root).'") to null', __FILE__, __LINE__);
1345: return false;
1346: }
1347: if (!$this->config_allow_src_above_phpthumb && !preg_match('#^'.preg_quote(str_replace(DIRECTORY_SEPARATOR, '/', dirname(__FILE__))).'#', $AbsoluteFilename)) {
1348: $this->DebugMessage('!$this->config_allow_src_above_phpthumb therefore setting "'.$AbsoluteFilename.'" (outside "'.dirname(__FILE__).'") to null', __FILE__, __LINE__);
1349: return false;
1350: }
1351: return $AbsoluteFilename;
1352: }
1353:
1354:
1355: function file_exists_ignoreopenbasedir($filename, $cached=true) {
1356: static $open_basedirs = null;
1357: static $file_exists_cache = array();
1358: if (!$cached || !isset($file_exists_cache[$filename])) {
1359: if (is_null($open_basedirs)) {
1360: $open_basedirs = preg_split('#[;:]#', ini_get('open_basedir'));
1361: }
1362: if (empty($open_basedirs) || in_array(dirname($filename), $open_basedirs)) {
1363: $file_exists_cache[$filename] = file_exists($filename);
1364: } elseif ($this->iswindows) {
1365: $ls_filename = trim(phpthumb_functions::SafeExec('dir /b '.phpthumb_functions::escapeshellarg_replacement($filename)));
1366: $file_exists_cache[$filename] = ($ls_filename == basename($filename));
1367: } else {
1368: $ls_filename = trim(phpthumb_functions::SafeExec('ls '.phpthumb_functions::escapeshellarg_replacement($filename)));
1369: $file_exists_cache[$filename] = ($ls_filename == $filename);
1370: }
1371: }
1372: return $file_exists_cache[$filename];
1373: }
1374:
1375:
1376: function ImageMagickWhichConvert() {
1377: static $WhichConvert = null;
1378: if (is_null($WhichConvert)) {
1379: if ($this->iswindows) {
1380: $WhichConvert = false;
1381: } else {
1382: $IMwhichConvertCacheFilename = $this->config_cache_directory.DIRECTORY_SEPARATOR.'phpThumbCacheIMwhichConvert.txt';
1383: if (($cachedwhichconvertstring = @file_get_contents($IMwhichConvertCacheFilename)) !== false) {
1384: $WhichConvert = $cachedwhichconvertstring;
1385: } else {
1386: $WhichConvert = trim(phpthumb_functions::SafeExec('which convert'));
1387: @file_put_contents($IMwhichConvertCacheFilename, $WhichConvert);
1388: @chmod($IMwhichConvertCacheFilename, $this->getParameter('config_file_create_mask'));
1389: }
1390: }
1391: }
1392: return $WhichConvert;
1393: }
1394:
1395:
1396: function ImageMagickCommandlineBase() {
1397: static $commandline = null;
1398: if (is_null($commandline)) {
1399: if ($this->issafemode) {
1400: $commandline = '';
1401: return $commandline;
1402: }
1403:
1404: $IMcommandlineBaseCacheFilename = $this->config_cache_directory.DIRECTORY_SEPARATOR.'phpThumbCacheIMcommandlineBase.txt';
1405: if (($commandline = @file_get_contents($IMcommandlineBaseCacheFilename)) !== false) {
1406: return $commandline;
1407: }
1408:
1409: $commandline = (!is_null($this->config_imagemagick_path) ? $this->config_imagemagick_path : '');
1410:
1411: if ($this->config_imagemagick_path && ($this->config_imagemagick_path != $this->realPathSafe($this->config_imagemagick_path))) {
1412: if (@is_executable($this->realPathSafe($this->config_imagemagick_path))) {
1413: $this->DebugMessage('Changing $this->config_imagemagick_path ('.$this->config_imagemagick_path.') to $this->realPathSafe($this->config_imagemagick_path) ('.$this->realPathSafe($this->config_imagemagick_path).')', __FILE__, __LINE__);
1414: $this->config_imagemagick_path = $this->realPathSafe($this->config_imagemagick_path);
1415: } else {
1416: $this->DebugMessage('Leaving $this->config_imagemagick_path as ('.$this->config_imagemagick_path.') because !is_execuatable($this->realPathSafe($this->config_imagemagick_path)) ('.$this->realPathSafe($this->config_imagemagick_path).')', __FILE__, __LINE__);
1417: }
1418: }
1419: $this->DebugMessage(' file_exists('.$this->config_imagemagick_path.') = '.intval( @file_exists($this->config_imagemagick_path)), __FILE__, __LINE__);
1420: $this->DebugMessage('file_exists_ignoreopenbasedir('.$this->config_imagemagick_path.') = '.intval($this->file_exists_ignoreopenbasedir($this->config_imagemagick_path)), __FILE__, __LINE__);
1421: $this->DebugMessage(' is_file('.$this->config_imagemagick_path.') = '.intval( @is_file($this->config_imagemagick_path)), __FILE__, __LINE__);
1422: $this->DebugMessage(' is_executable('.$this->config_imagemagick_path.') = '.intval( @is_executable($this->config_imagemagick_path)), __FILE__, __LINE__);
1423:
1424: if ($this->file_exists_ignoreopenbasedir($this->config_imagemagick_path)) {
1425:
1426: $this->DebugMessage('using ImageMagick path from $this->config_imagemagick_path ('.$this->config_imagemagick_path.')', __FILE__, __LINE__);
1427: if ($this->iswindows) {
1428: $commandline = substr($this->config_imagemagick_path, 0, 2).' && cd '.phpthumb_functions::escapeshellarg_replacement(str_replace('/', DIRECTORY_SEPARATOR, substr(dirname($this->config_imagemagick_path), 2))).' && '.phpthumb_functions::escapeshellarg_replacement(basename($this->config_imagemagick_path));
1429: } else {
1430: $commandline = phpthumb_functions::escapeshellarg_replacement($this->config_imagemagick_path);
1431: }
1432:
1433: } else {
1434:
1435: $which_convert = $this->ImageMagickWhichConvert();
1436: $IMversion = $this->ImageMagickVersion();
1437:
1438: if ($which_convert && ($which_convert{0} == '/') && $this->file_exists_ignoreopenbasedir($which_convert)) {
1439:
1440:
1441:
1442:
1443: $this->DebugMessage('using ImageMagick path from `which convert` ('.$which_convert.')', __FILE__, __LINE__);
1444: $commandline = 'convert';
1445:
1446: } elseif ($IMversion) {
1447:
1448: $this->DebugMessage('setting ImageMagick path to $this->config_imagemagick_path ('.$this->config_imagemagick_path.') ['.$IMversion.']', __FILE__, __LINE__);
1449: $commandline = $this->config_imagemagick_path;
1450:
1451: } else {
1452:
1453: $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__);
1454: $commandline = '';
1455:
1456: }
1457:
1458: }
1459:
1460: @file_put_contents($IMcommandlineBaseCacheFilename, $commandline);
1461: @chmod($IMcommandlineBaseCacheFilename, $this->getParameter('config_file_create_mask'));
1462: }
1463: return $commandline;
1464: }
1465:
1466:
1467: function ImageMagickVersion($returnRAW=false) {
1468: static $versionstring = null;
1469: if (is_null($versionstring)) {
1470: $versionstring = array(0=>false, 1=>false);
1471:
1472: $IMversionCacheFilename = $this->config_cache_directory.DIRECTORY_SEPARATOR.'phpThumbCacheIMversion.txt';
1473: if ($cachedversionstring = @file_get_contents($IMversionCacheFilename)) {
1474:
1475: $versionstring = explode("\n", $cachedversionstring, 2);
1476: $versionstring[0] = ($versionstring[0] ? $versionstring[0] : false);
1477: $versionstring[1] = ($versionstring[1] ? $versionstring[1] : false);
1478:
1479: } else {
1480:
1481: $commandline = $this->ImageMagickCommandlineBase();
1482: $commandline = (!is_null($commandline) ? $commandline : '');
1483: if ($commandline) {
1484: $commandline .= ' --version';
1485: $this->DebugMessage('ImageMagick version checked with "'.$commandline.'"', __FILE__, __LINE__);
1486: $versionstring[1] = trim(phpthumb_functions::SafeExec($commandline));
1487: if (preg_match('#^Version: [^0-9]*([ 0-9\\.\\:Q/\\-]+)#i', $versionstring[1], $matches)) {
1488: $versionstring[0] = trim($matches[1]);
1489: } else {
1490: $versionstring[0] = false;
1491: $this->DebugMessage('ImageMagick did not return recognized version string ('.$versionstring[1].')', __FILE__, __LINE__);
1492: }
1493: $this->DebugMessage('ImageMagick convert --version says "'.@$matches[0].'"', __FILE__, __LINE__);
1494: }
1495:
1496: @file_put_contents($IMversionCacheFilename, $versionstring[0]."\n".$versionstring[1]);
1497: @chmod($IMversionCacheFilename, $this->getParameter('config_file_create_mask'));
1498:
1499: }
1500: }
1501: return $versionstring[intval($returnRAW)];
1502: }
1503:
1504:
1505: function ImageMagickSwitchAvailable($switchname) {
1506: static $IMoptions = null;
1507: if (is_null($IMoptions)) {
1508: $IMoptions = array();
1509: $commandline = $this->ImageMagickCommandlineBase();
1510: if (!is_null($commandline)) {
1511: $commandline .= ' -help';
1512: $IMhelp_lines = explode("\n", phpthumb_functions::SafeExec($commandline));
1513: foreach ($IMhelp_lines as $line) {
1514: if (preg_match('#^[\\+\\-]([a-z\\-]+) #', trim($line), $matches)) {
1515: $IMoptions[$matches[1]] = true;
1516: }
1517: }
1518: }
1519: }
1520: if (is_array($switchname)) {
1521: $allOK = true;
1522: foreach ($switchname as $key => $value) {
1523: if (!isset($IMoptions[$value])) {
1524: $allOK = false;
1525: break;
1526: }
1527: }
1528: $this->DebugMessage('ImageMagickSwitchAvailable('.implode(';', $switchname).') = '.intval($allOK).'', __FILE__, __LINE__);
1529: } else {
1530: $allOK = isset($IMoptions[$switchname]);
1531: $this->DebugMessage('ImageMagickSwitchAvailable('.$switchname.') = '.intval($allOK).'', __FILE__, __LINE__);
1532: }
1533: return $allOK;
1534: }
1535:
1536:
1537: function ImageMagickFormatsList() {
1538: static $IMformatsList = null;
1539: if (is_null($IMformatsList)) {
1540: $IMformatsList = '';
1541: $commandline = $this->ImageMagickCommandlineBase();
1542: if (!is_null($commandline)) {
1543: $commandline = dirname($commandline).DIRECTORY_SEPARATOR.str_replace('convert', 'identify', basename($commandline));
1544: $commandline .= ' -list format';
1545: $IMformatsList = phpthumb_functions::SafeExec($commandline);
1546: }
1547: }
1548: return $IMformatsList;
1549: }
1550:
1551:
1552: function SourceDataToTempFile() {
1553: if ($IMtempSourceFilename = $this->phpThumb_tempnam()) {
1554: $IMtempSourceFilename = $this->realPathSafe($IMtempSourceFilename);
1555: ob_start();
1556: $fp_tempfile = fopen($IMtempSourceFilename, 'wb');
1557: $tempfile_open_error = ob_get_contents();
1558: ob_end_clean();
1559: if ($fp_tempfile) {
1560: fwrite($fp_tempfile, $this->rawImageData);
1561: fclose($fp_tempfile);
1562: @chmod($IMtempSourceFilename, $this->getParameter('config_file_create_mask'));
1563: $this->sourceFilename = $IMtempSourceFilename;
1564: $this->DebugMessage('ImageMagickThumbnailToGD() setting $this->sourceFilename to "'.$IMtempSourceFilename.'" from $this->rawImageData ('.strlen($this->rawImageData).' bytes)', __FILE__, __LINE__);
1565: } else {
1566: $this->DebugMessage('ImageMagickThumbnailToGD() FAILED setting $this->sourceFilename to "'.$IMtempSourceFilename.'" (failed to open for writing: "'.$tempfile_open_error.'")', __FILE__, __LINE__);
1567: }
1568: unset($tempfile_open_error, $IMtempSourceFilename);
1569: return true;
1570: }
1571: $this->DebugMessage('SourceDataToTempFile() FAILED because $this->phpThumb_tempnam() failed', __FILE__, __LINE__);
1572: return false;
1573: }
1574:
1575:
1576: function ImageMagickThumbnailToGD() {
1577:
1578:
1579: $this->useRawIMoutput = true;
1580: if (phpthumb_functions::gd_version()) {
1581:
1582:
1583:
1584:
1585: $UnAllowedParameters = array('xto', 'ar', 'bg', 'bc');
1586:
1587: foreach ($UnAllowedParameters as $parameter) {
1588: if (isset($this->$parameter)) {
1589: $this->DebugMessage('$this->useRawIMoutput=false because "'.$parameter.'" is set', __FILE__, __LINE__);
1590: $this->useRawIMoutput = false;
1591: break;
1592: }
1593: }
1594: }
1595: $this->DebugMessage('$this->useRawIMoutput='.($this->useRawIMoutput ? 'true' : 'false').' after checking $UnAllowedParameters', __FILE__, __LINE__);
1596: $ImageCreateFunction = '';
1597: $outputFormat = $this->thumbnailFormat;
1598: if (phpthumb_functions::gd_version()) {
1599: if ($this->useRawIMoutput) {
1600: switch ($this->thumbnailFormat) {
1601: case 'gif':
1602: $ImageCreateFunction = 'imagecreatefromgif';
1603: $this->is_alpha = true;
1604: break;
1605: case 'png':
1606: $ImageCreateFunction = 'imagecreatefrompng';
1607: $this->is_alpha = true;
1608: break;
1609: case 'jpg':
1610: case 'jpeg':
1611: $ImageCreateFunction = 'imagecreatefromjpeg';
1612: break;
1613: default:
1614: $this->DebugMessage('Forcing output to PNG because $this->thumbnailFormat ('.$this->thumbnailFormat.' is not a GD-supported format)', __FILE__, __LINE__);
1615: $outputFormat = 'png';
1616: $ImageCreateFunction = 'imagecreatefrompng';
1617: $this->is_alpha = true;
1618: $this->useRawIMoutput = false;
1619: break;
1620: }
1621: if (!function_exists(@$ImageCreateFunction)) {
1622:
1623:
1624: $this->useRawIMoutput = true;
1625:
1626: }
1627: } else {
1628: $outputFormat = 'png';
1629: $ImageCreateFunction = 'imagecreatefrompng';
1630: $this->is_alpha = true;
1631: $this->useRawIMoutput = false;
1632: }
1633: }
1634:
1635:
1636: if (!$this->sourceFilename && $this->rawImageData) {
1637: $this->SourceDataToTempFile();
1638: }
1639: if (!$this->sourceFilename) {
1640: $this->DebugMessage('ImageMagickThumbnailToGD() aborting because $this->sourceFilename is empty', __FILE__, __LINE__);
1641: $this->useRawIMoutput = false;
1642: return false;
1643: }
1644: if ($this->issafemode) {
1645: $this->DebugMessage('ImageMagickThumbnailToGD() aborting because safe_mode is enabled', __FILE__, __LINE__);
1646: $this->useRawIMoutput = false;
1647: return false;
1648: }
1649:
1650:
1651:
1652:
1653:
1654:
1655:
1656: $commandline = $this->ImageMagickCommandlineBase();
1657: if ($commandline) {
1658: if ($IMtempfilename = $this->phpThumb_tempnam()) {
1659: $IMtempfilename = $this->realPathSafe($IMtempfilename);
1660:
1661: $IMuseExplicitImageOutputDimensions = false;
1662: if ($this->ImageMagickSwitchAvailable('thumbnail') && $this->config_imagemagick_use_thumbnail) {
1663: $IMresizeParameter = 'thumbnail';
1664: } else {
1665: $IMresizeParameter = 'resize';
1666:
1667:
1668: $commandline_test = $this->ImageMagickCommandlineBase().' logo: -resize 1x '.phpthumb_functions::escapeshellarg_replacement($IMtempfilename).' 2>&1';
1669: $IMresult_test = phpthumb_functions::SafeExec($commandline_test);
1670: $IMuseExplicitImageOutputDimensions = preg_match('#image dimensions are zero#i', $IMresult_test);
1671: $this->DebugMessage('IMuseExplicitImageOutputDimensions = '.intval($IMuseExplicitImageOutputDimensions), __FILE__, __LINE__);
1672: if ($fp_im_temp = @fopen($IMtempfilename, 'wb')) {
1673:
1674: fclose($fp_im_temp);
1675: @chmod($IMtempfilename, $this->getParameter('config_file_create_mask'));
1676: }
1677: }
1678:
1679:
1680: if (!is_null($this->dpi) && $this->ImageMagickSwitchAvailable('density')) {
1681:
1682: $commandline .= ' -flatten';
1683: $commandline .= ' -density '.phpthumb_functions::escapeshellarg_replacement($this->dpi);
1684: }
1685: ob_start();
1686: $getimagesize = getimagesize($this->sourceFilename);
1687: $GetImageSizeError = ob_get_contents();
1688: ob_end_clean();
1689: if (is_array($getimagesize)) {
1690: $this->DebugMessage('getimagesize('.$this->sourceFilename.') SUCCEEDED: '.print_r($getimagesize, true), __FILE__, __LINE__);
1691: } else {
1692: $this->DebugMessage('getimagesize('.$this->sourceFilename.') FAILED with error "'.$GetImageSizeError.'"', __FILE__, __LINE__);
1693: }
1694: if (is_array($getimagesize)) {
1695: $this->DebugMessage('getimagesize('.$this->sourceFilename.') returned [w='.$getimagesize[0].';h='.$getimagesize[1].';f='.$getimagesize[2].']', __FILE__, __LINE__);
1696: $this->source_width = $getimagesize[0];
1697: $this->source_height = $getimagesize[1];
1698: $this->DebugMessage('source dimensions set to '.$this->source_width.'x'.$this->source_height, __FILE__, __LINE__);
1699: $this->SetOrientationDependantWidthHeight();
1700:
1701: if (!preg_match('#('.implode('|', $this->AlphaCapableFormats).')#i', $outputFormat)) {
1702:
1703: $commandline .= ' -background '.phpthumb_functions::escapeshellarg_replacement('#'.($this->bg ? $this->bg : 'FFFFFF'));
1704: if ($getimagesize[2] == IMAGETYPE_GIF) {
1705: $commandline .= ' -flatten';
1706: }
1707: }
1708: if ($getimagesize[2] == IMAGETYPE_GIF) {
1709: $commandline .= ' -coalesce';
1710: }
1711: if ($this->source_width || $this->source_height) {
1712: if ($this->zc) {
1713:
1714: $borderThickness = 0;
1715: if (!empty($this->fltr)) {
1716: foreach ($this->fltr as $key => $value) {
1717: if (preg_match('#^bord\|([0-9]+)#', $value, $matches)) {
1718: $borderThickness = $matches[1];
1719: break;
1720: }
1721: }
1722: }
1723: $wAll = intval(max($this->w, $this->wp, $this->wl, $this->ws)) - (2 * $borderThickness);
1724: $hAll = intval(max($this->h, $this->hp, $this->hl, $this->hs)) - (2 * $borderThickness);
1725: $imAR = $this->source_width / $this->source_height;
1726: $zcAR = (($wAll && $hAll) ? $wAll / $hAll : 1);
1727: $side = phpthumb_functions::nonempty_min($this->source_width, $this->source_height, max($wAll, $hAll));
1728: $sideX = phpthumb_functions::nonempty_min($this->source_width, $wAll, round($hAll * $zcAR));
1729: $sideY = phpthumb_functions::nonempty_min( $this->source_height, $hAll, round($wAll / $zcAR));
1730:
1731: $thumbnailH = round(max($sideY, ($sideY * $zcAR) / $imAR));
1732: $commandline .= ' -'.$IMresizeParameter.' '.phpthumb_functions::escapeshellarg_replacement(($IMuseExplicitImageOutputDimensions ? $thumbnailH : '').'x'.$thumbnailH);
1733:
1734: switch (strtoupper($this->zc)) {
1735: case 'T':
1736: $commandline .= ' -gravity north';
1737: break;
1738: case 'B':
1739: $commandline .= ' -gravity south';
1740: break;
1741: case 'L':
1742: $commandline .= ' -gravity west';
1743: break;
1744: case 'R':
1745: $commandline .= ' -gravity east';
1746: break;
1747: case 'TL':
1748: $commandline .= ' -gravity northwest';
1749: break;
1750: case 'TR':
1751: $commandline .= ' -gravity northeast';
1752: break;
1753: case 'BL':
1754: $commandline .= ' -gravity southwest';
1755: break;
1756: case 'BR':
1757: $commandline .= ' -gravity southeast';
1758: break;
1759: case '1':
1760: case 'C':
1761: default:
1762: $commandline .= ' -gravity center';
1763: break;
1764: }
1765:
1766: if (($wAll > 0) && ($hAll > 0)) {
1767: $commandline .= ' -crop '.phpthumb_functions::escapeshellarg_replacement($wAll.'x'.$hAll.'+0+0');
1768: } else {
1769: $commandline .= ' -crop '.phpthumb_functions::escapeshellarg_replacement($side.'x'.$side.'+0+0');
1770: }
1771: if ($this->ImageMagickSwitchAvailable('repage')) {
1772: $commandline .= ' +repage';
1773: } else {
1774: $this->DebugMessage('Skipping "+repage" because ImageMagick (v'.$this->ImageMagickVersion().') does not support it', __FILE__, __LINE__);
1775: }
1776:
1777: } elseif ($this->sw || $this->sh || $this->sx || $this->sy) {
1778:
1779: $crop_param = '';
1780: $crop_param .= ($this->sw ? (($this->sw < 2) ? round($this->sw * $this->source_width) : $this->sw) : $this->source_width);
1781: $crop_param .= 'x'.($this->sh ? (($this->sh < 2) ? round($this->sh * $this->source_height) : $this->sh) : $this->source_height);
1782: $crop_param .= '+'.(($this->sx < 2) ? round($this->sx * $this->source_width) : $this->sx);
1783: $crop_param .= '+'.(($this->sy < 2) ? round($this->sy * $this->source_height) : $this->sy);
1784:
1785:
1786:
1787:
1788: $commandline .= ' -crop '.phpthumb_functions::escapeshellarg_replacement($crop_param);
1789:
1790:
1791: if ($this->w || $this->h) {
1792:
1793: if (false) {
1794:
1795:
1796: $commandline .= ' -repage';
1797: } else {
1798: $this->DebugMessage('Skipping "-repage" because ImageMagick (v'.$this->ImageMagickVersion().') does not support it', __FILE__, __LINE__);
1799: }
1800: if ($IMuseExplicitImageOutputDimensions) {
1801: if ($this->w && !$this->h) {
1802: $this->h = ceil($this->w / ($this->source_width / $this->source_height));
1803: } elseif ($this->h && !$this->w) {
1804: $this->w = ceil($this->h * ($this->source_width / $this->source_height));
1805: }
1806: }
1807: $commandline .= ' -'.$IMresizeParameter.' '.phpthumb_functions::escapeshellarg_replacement($this->w.'x'.$this->h);
1808: }
1809:
1810: } else {
1811:
1812: if ($this->iar && (intval($this->w) > 0) && (intval($this->h) > 0)) {
1813: list($nw, $nh) = phpthumb_functions::TranslateWHbyAngle($this->w, $this->h, $this->ra);
1814: $nw = ((round($nw) != 0) ? round($nw) : '');
1815: $nh = ((round($nh) != 0) ? round($nh) : '');
1816: $commandline .= ' -'.$IMresizeParameter.' '.phpthumb_functions::escapeshellarg_replacement($nw.'x'.$nh.'!');
1817: } else {
1818: $this->w = ((($this->aoe || $this->far) && $this->w) ? $this->w : ($this->w ? phpthumb_functions::nonempty_min($this->w, $getimagesize[0]) : ''));
1819: $this->h = ((($this->aoe || $this->far) && $this->h) ? $this->h : ($this->h ? phpthumb_functions::nonempty_min($this->h, $getimagesize[1]) : ''));
1820: if ($this->w || $this->h) {
1821: if ($IMuseExplicitImageOutputDimensions) {
1822: if ($this->w && !$this->h) {
1823: $this->h = ceil($this->w / ($this->source_width / $this->source_height));
1824: } elseif ($this->h && !$this->w) {
1825: $this->w = ceil($this->h * ($this->source_width / $this->source_height));
1826: }
1827: }
1828: list($nw, $nh) = phpthumb_functions::TranslateWHbyAngle($this->w, $this->h, $this->ra);
1829: $nw = ((round($nw) != 0) ? round($nw) : '');
1830: $nh = ((round($nh) != 0) ? round($nh) : '');
1831: $commandline .= ' -'.$IMresizeParameter.' '.phpthumb_functions::escapeshellarg_replacement($nw.'x'.$nh);
1832: }
1833: }
1834: }
1835: }
1836:
1837: } else {
1838:
1839: $this->DebugMessage('getimagesize('.$this->sourceFilename.') failed', __FILE__, __LINE__);
1840: if ($this->w || $this->h) {
1841: $exactDimensionsBang = (($this->iar && (intval($this->w) > 0) && (intval($this->h) > 0)) ? '!' : '');
1842: if ($IMuseExplicitImageOutputDimensions) {
1843:
1844: $commandline .= ' -'.$IMresizeParameter.' '.phpthumb_functions::escapeshellarg_replacement(($this->w ? $this->w : '9999').'x'.($this->h ? $this->h : '9999').$exactDimensionsBang);
1845: } else {
1846: $commandline .= ' -'.$IMresizeParameter.' '.phpthumb_functions::escapeshellarg_replacement($this->w.'x'.$this->h.$exactDimensionsBang);
1847: }
1848: }
1849:
1850: }
1851:
1852: if ($this->ra) {
1853: $this->ra = intval($this->ra);
1854: if ($this->ImageMagickSwitchAvailable('rotate')) {
1855: if (!preg_match('#('.implode('|', $this->AlphaCapableFormats).')#i', $outputFormat) || phpthumb_functions::version_compare_replacement($this->ImageMagickVersion(), '6.3.7', '>=')) {
1856: $this->DebugMessage('Using ImageMagick rotate', __FILE__, __LINE__);
1857: $commandline .= ' -rotate '.phpthumb_functions::escapeshellarg_replacement($this->ra);
1858: if (($this->ra % 90) != 0) {
1859: if (preg_match('#('.implode('|', $this->AlphaCapableFormats).')#i', $outputFormat)) {
1860:
1861: $commandline .= ' -background rgba(255,255,255,0)';
1862: } else {
1863: $commandline .= ' -background '.phpthumb_functions::escapeshellarg_replacement('#'.($this->bg ? $this->bg : 'FFFFFF'));
1864: }
1865: }
1866: $this->ra = 0;
1867: } else {
1868: $this->DebugMessage('Not using ImageMagick rotate because alpha background buggy before v6.3.7', __FILE__, __LINE__);
1869: }
1870: } else {
1871: $this->DebugMessage('Not using ImageMagick rotate because not supported', __FILE__, __LINE__);
1872: }
1873: }
1874:
1875: $successfullyProcessedFilters = array();
1876: foreach ($this->fltr as $filterkey => $filtercommand) {
1877: @list($command, $parameter) = explode('|', $filtercommand, 2);
1878: switch ($command) {
1879: case 'brit':
1880: if ($this->ImageMagickSwitchAvailable('modulate')) {
1881: $commandline .= ' -modulate '.phpthumb_functions::escapeshellarg_replacement((100 + intval($parameter)).',100,100');
1882: $successfullyProcessedFilters[] = $filterkey;
1883: }
1884: break;
1885:
1886: case 'cont':
1887: if ($this->ImageMagickSwitchAvailable('contrast')) {
1888: $contDiv10 = round(intval($parameter) / 10);
1889: if ($contDiv10 > 0) {
1890: $contDiv10 = min($contDiv10, 100);
1891: for ($i = 0; $i < $contDiv10; $i++) {
1892: $commandline .= ' -contrast';
1893: }
1894: } elseif ($contDiv10 < 0) {
1895: $contDiv10 = max($contDiv10, -100);
1896: for ($i = $contDiv10; $i < 0; $i++) {
1897: $commandline .= ' +contrast';
1898: }
1899: } else {
1900:
1901: }
1902: $successfullyProcessedFilters[] = $filterkey;
1903: }
1904: break;
1905:
1906: case 'ds':
1907: if ($this->ImageMagickSwitchAvailable(array('colorspace', 'modulate'))) {
1908: if ($parameter == 100) {
1909: $commandline .= ' -colorspace GRAY';
1910: $commandline .= ' -modulate 100,0,100';
1911: } else {
1912: $commandline .= ' -modulate '.phpthumb_functions::escapeshellarg_replacement('100,'.(100 - intval($parameter)).',100');
1913: }
1914: $successfullyProcessedFilters[] = $filterkey;
1915: }
1916: break;
1917:
1918: case 'sat':
1919: if ($this->ImageMagickSwitchAvailable(array('colorspace', 'modulate'))) {
1920: if ($parameter == -100) {
1921: $commandline .= ' -colorspace GRAY';
1922: $commandline .= ' -modulate 100,0,100';
1923: } else {
1924: $commandline .= ' -modulate '.phpthumb_functions::escapeshellarg_replacement('100,'.(100 + intval($parameter)).',100');
1925: }
1926: $successfullyProcessedFilters[] = $filterkey;
1927: }
1928: break;
1929:
1930: case 'gray':
1931: if ($this->ImageMagickSwitchAvailable(array('colorspace', 'modulate'))) {
1932: $commandline .= ' -colorspace GRAY';
1933: $commandline .= ' -modulate 100,0,100';
1934: $successfullyProcessedFilters[] = $filterkey;
1935: }
1936: break;
1937:
1938: case 'clr':
1939: if ($this->ImageMagickSwitchAvailable(array('fill', 'colorize'))) {
1940: @list($amount, $color) = explode('|', $parameter);
1941: $commandline .= ' -fill '.phpthumb_functions::escapeshellarg_replacement('#'.preg_replace('#[^0-9A-F]#i', '', $color));
1942: $commandline .= ' -colorize '.phpthumb_functions::escapeshellarg_replacement(min(max(intval($amount), 0), 100));
1943: }
1944: break;
1945:
1946: case 'sep':
1947: if ($this->ImageMagickSwitchAvailable('sepia-tone')) {
1948: @list($amount, $color) = explode('|', $parameter);
1949: $amount = ($amount ? $amount : 80);
1950: if (!$color) {
1951: $commandline .= ' -sepia-tone '.phpthumb_functions::escapeshellarg_replacement(min(max(intval($amount), 0), 100).'%');
1952: $successfullyProcessedFilters[] = $filterkey;
1953: }
1954: }
1955: break;
1956:
1957: case 'gam':
1958: @list($amount) = explode('|', $parameter);
1959: $amount = min(max(floatval($amount), 0.001), 10);
1960: if (number_format($amount, 3) != '1.000') {
1961: if ($this->ImageMagickSwitchAvailable('gamma')) {
1962: $commandline .= ' -gamma '.phpthumb_functions::escapeshellarg_replacement($amount);
1963: $successfullyProcessedFilters[] = $filterkey;
1964: }
1965: }
1966: break;
1967:
1968: case 'neg':
1969: if ($this->ImageMagickSwitchAvailable('negate')) {
1970: $commandline .= ' -negate';
1971: $successfullyProcessedFilters[] = $filterkey;
1972: }
1973: break;
1974:
1975: case 'th':
1976: @list($amount) = explode('|', $parameter);
1977: if ($this->ImageMagickSwitchAvailable(array('threshold', 'dither', 'monochrome'))) {
1978: $commandline .= ' -threshold '.phpthumb_functions::escapeshellarg_replacement(round(min(max(intval($amount), 0), 255) / 2.55).'%');
1979: $commandline .= ' -dither';
1980: $commandline .= ' -monochrome';
1981: $successfullyProcessedFilters[] = $filterkey;
1982: }
1983: break;
1984:
1985: case 'rcd':
1986: if ($this->ImageMagickSwitchAvailable(array('colors', 'dither'))) {
1987: @list($colors, $dither) = explode('|', $parameter);
1988: $colors = ($colors ? (int) $colors : 256);
1989: $dither = ((strlen($dither) > 0) ? (bool) $dither : true);
1990: $commandline .= ' -colors '.phpthumb_functions::escapeshellarg_replacement(max($colors, 8));
1991: $commandline .= ($dither ? ' -dither' : ' +dither');
1992: $successfullyProcessedFilters[] = $filterkey;
1993: }
1994: break;
1995:
1996: case 'flip':
1997: if ($this->ImageMagickSwitchAvailable(array('flip', 'flop'))) {
1998: if (strpos(strtolower($parameter), 'x') !== false) {
1999: $commandline .= ' -flop';
2000: }
2001: if (strpos(strtolower($parameter), 'y') !== false) {
2002: $commandline .= ' -flip';
2003: }
2004: $successfullyProcessedFilters[] = $filterkey;
2005: }
2006: break;
2007:
2008: case 'edge':
2009: if ($this->ImageMagickSwitchAvailable('edge')) {
2010: $parameter = (!empty($parameter) ? $parameter : 2);
2011: $commandline .= ' -edge '.phpthumb_functions::escapeshellarg_replacement(!empty($parameter) ? intval($parameter) : 1);
2012: $successfullyProcessedFilters[] = $filterkey;
2013: }
2014: break;
2015:
2016: case 'emb':
2017: if ($this->ImageMagickSwitchAvailable(array('emboss', 'negate'))) {
2018: $parameter = (!empty($parameter) ? $parameter : 2);
2019: $commandline .= ' -emboss '.phpthumb_functions::escapeshellarg_replacement(intval($parameter));
2020: if ($parameter < 2) {
2021: $commandline .= ' -negate';
2022: }
2023: $successfullyProcessedFilters[] = $filterkey;
2024: }
2025: break;
2026:
2027: case 'lvl':
2028: @list($band, $method, $threshold) = explode('|', $parameter);
2029: $band = ($band ? preg_replace('#[^RGBA\\*]#', '', strtoupper($band)) : '*');
2030: $method = ((strlen($method) > 0) ? intval($method) : 2);
2031: $threshold = ((strlen($threshold) > 0) ? min(max(floatval($threshold), 0), 100) : 0.1);
2032:
2033: $band = preg_replace('#[^RGBA\\*]#', '', strtoupper($band));
2034:
2035: if (($method > 1) && !$this->ImageMagickSwitchAvailable(array('channel', 'contrast-stretch'))) {
2036:
2037:
2038:
2039:
2040: foreach ($this->fltr as $fltr_key => $fltr_value) {
2041: list($fltr_cmd) = explode('|', $fltr_value);
2042: if ($fltr_cmd == 'wb') {
2043: $this->DebugMessage('Setting "lvl" filter method to "0" (from "'.$method.'") because white-balance filter also enabled', __FILE__, __LINE__);
2044: $method = 0;
2045: }
2046: }
2047: }
2048:
2049: switch ($method) {
2050: case 0:
2051: case 1:
2052: break;
2053: case 2:
2054: if ($this->ImageMagickSwitchAvailable('contrast-stretch')) {
2055: if ($band != '*') {
2056: $commandline .= ' -channel '.phpthumb_functions::escapeshellarg_replacement(strtoupper($band));
2057: }
2058: $threshold = preg_replace('#[^0-9\\.]#', '', $threshold);
2059:
2060: $commandline .= ' -contrast-stretch \''.$threshold.'%\'';
2061: if ($band != '*') {
2062: $commandline .= ' +channel';
2063: }
2064: $successfullyProcessedFilters[] = $filterkey;
2065: }
2066: break;
2067: case 3:
2068: if ($this->ImageMagickSwitchAvailable('normalize')) {
2069: if ($band != '*') {
2070: $commandline .= ' -channel '.phpthumb_functions::escapeshellarg_replacement(strtoupper($band));
2071: }
2072: $commandline .= ' -normalize';
2073: if ($band != '*') {
2074: $commandline .= ' +channel';
2075: }
2076: $successfullyProcessedFilters[] = $filterkey;
2077: }
2078: break;
2079: default:
2080: $this->DebugMessage('unsupported method ('.$method.') for "lvl" filter', __FILE__, __LINE__);
2081: break;
2082: }
2083: if (isset($this->fltr[$filterkey]) && ($method > 1)) {
2084: $this->fltr[$filterkey] = $command.'|'.$band.'|0|'.$threshold;
2085: $this->DebugMessage('filter "lvl" remapped from method "'.$method.'" to method "0" because ImageMagick support is missing', __FILE__, __LINE__);
2086: }
2087: break;
2088:
2089: case 'wb':
2090: if ($this->ImageMagickSwitchAvailable(array('channel', 'contrast-stretch'))) {
2091: @list($threshold) = explode('|', $parameter);
2092: $threshold = (!empty($threshold) ? min(max(floatval($threshold), 0), 100) : 0.1);
2093: $threshold = preg_replace('#[^0-9\\.]#', '', $threshold);
2094:
2095:
2096:
2097: $commandline .= ' -channel R -contrast-stretch \''.$threshold.'%\'';
2098: $commandline .= ' -channel G -contrast-stretch \''.$threshold.'%\'';
2099: $commandline .= ' -channel B -contrast-stretch \''.$threshold.'%\'';
2100: $commandline .= ' +channel';
2101: $successfullyProcessedFilters[] = $filterkey;
2102: }
2103: break;
2104:
2105: case 'blur':
2106: if ($this->ImageMagickSwitchAvailable('blur')) {
2107: @list($radius) = explode('|', $parameter);
2108: $radius = (!empty($radius) ? min(max(intval($radius), 0), 25) : 1);
2109: $commandline .= ' -blur '.phpthumb_functions::escapeshellarg_replacement($radius);
2110: $successfullyProcessedFilters[] = $filterkey;
2111: }
2112: break;
2113:
2114: case 'gblr':
2115: @list($radius) = explode('|', $parameter);
2116: $radius = (!empty($radius) ? min(max(intval($radius), 0), 25) : 1);
2117:
2118: if ($this->ImageMagickSwitchAvailable('gaussian-blur')) {
2119: $commandline .= ' -gaussian-blur '.phpthumb_functions::escapeshellarg_replacement($radius);
2120: $successfullyProcessedFilters[] = $filterkey;
2121: } elseif ($this->ImageMagickSwitchAvailable('gaussian')) {
2122: $commandline .= ' -gaussian '.phpthumb_functions::escapeshellarg_replacement($radius);
2123: $successfullyProcessedFilters[] = $filterkey;
2124: }
2125: break;
2126:
2127: case 'usm':
2128: if ($this->ImageMagickSwitchAvailable('unsharp')) {
2129: @list($amount, $radius, $threshold) = explode('|', $parameter);
2130: $amount = ($amount ? min(max(intval($radius), 0), 255) : 80);
2131: $radius = ($radius ? min(max(intval($radius), 0), 10) : 0.5);
2132: $threshold = (strlen($threshold) ? min(max(intval($radius), 0), 50) : 3);
2133: $commandline .= ' -unsharp '.phpthumb_functions::escapeshellarg_replacement(number_format(($radius * 2) - 1, 2, '.', '').'x1+'.number_format($amount / 100, 2, '.', '').'+'.number_format($threshold / 100, 2, '.', ''));
2134: $successfullyProcessedFilters[] = $filterkey;
2135: }
2136: break;
2137:
2138: case 'bord':
2139: if ($this->ImageMagickSwitchAvailable(array('border', 'bordercolor', 'thumbnail', 'crop'))) {
2140: if (!$this->zc) {
2141: @list($width, $rX, $rY, $color) = explode('|', $parameter);
2142: $width = intval($width);
2143: $rX = intval($rX);
2144: $rY = intval($rY);
2145: if ($width && !$rX && !$rY) {
2146: if (!phpthumb_functions::IsHexColor($color)) {
2147: $color = ((!empty($this->bc) && phpthumb_functions::IsHexColor($this->bc)) ? $this->bc : '000000');
2148: }
2149: $commandline .= ' -border '.phpthumb_functions::escapeshellarg_replacement(intval($width));
2150: $commandline .= ' -bordercolor '.phpthumb_functions::escapeshellarg_replacement('#'.$color);
2151:
2152: if (preg_match('# \\-crop "([0-9]+)x([0-9]+)\\+0\\+0" #', $commandline, $matches)) {
2153: $commandline = str_replace(' -crop "'.$matches[1].'x'.$matches[2].'+0+0" ', ' -crop '.phpthumb_functions::escapeshellarg_replacement(($matches[1] - (2 * $width)).'x'.($matches[2] - (2 * $width)).'+0+0').' ', $commandline);
2154: } elseif (preg_match('# \\-'.$IMresizeParameter.' "([0-9]+)x([0-9]+)" #', $commandline, $matches)) {
2155: $commandline = str_replace(' -'.$IMresizeParameter.' "'.$matches[1].'x'.$matches[2].'" ', ' -'.$IMresizeParameter.' '.phpthumb_functions::escapeshellarg_replacement(($matches[1] - (2 * $width)).'x'.($matches[2] - (2 * $width))).' ', $commandline);
2156: }
2157: $successfullyProcessedFilters[] = $filterkey;
2158: }
2159: }
2160: }
2161: break;
2162:
2163: case 'crop':
2164: break;
2165:
2166: case 'sblr':
2167: break;
2168:
2169: case 'mean':
2170: break;
2171:
2172: case 'smth':
2173: break;
2174:
2175: case 'bvl':
2176: break;
2177:
2178: case 'wmi':
2179: break;
2180:
2181: case 'wmt':
2182: break;
2183:
2184: case 'over':
2185: break;
2186:
2187: case 'hist':
2188: break;
2189:
2190: case 'fram':
2191: break;
2192:
2193: case 'drop':
2194: break;
2195:
2196: case 'mask':
2197: break;
2198:
2199: case 'elip':
2200: break;
2201:
2202: case 'ric':
2203: break;
2204:
2205: case 'stc':
2206: break;
2207:
2208: case 'size':
2209: break;
2210:
2211: default:
2212: $this->DebugMessage('Unknown $this->fltr['.$filterkey.'] ('.$filtercommand.') -- deleting filter command', __FILE__, __LINE__);
2213: $successfullyProcessedFilters[] = $filterkey;
2214: break;
2215: }
2216: if (!isset($this->fltr[$filterkey])) {
2217: $this->DebugMessage('Processed $this->fltr['.$filterkey.'] ('.$filtercommand.') with ImageMagick', __FILE__, __LINE__);
2218: } else {
2219: $this->DebugMessage('Skipping $this->fltr['.$filterkey.'] ('.$filtercommand.') with ImageMagick', __FILE__, __LINE__);
2220: }
2221: }
2222: $this->DebugMessage('Remaining $this->fltr after ImageMagick: ('.$this->phpThumbDebugVarDump($this->fltr).')', __FILE__, __LINE__);
2223: if (count($this->fltr) > 0) {
2224: $this->useRawIMoutput = false;
2225: }
2226:
2227: if (preg_match('#jpe?g#i', $outputFormat) && $this->q) {
2228: if ($this->ImageMagickSwitchAvailable(array('quality', 'interlace'))) {
2229: $commandline .= ' -quality '.phpthumb_functions::escapeshellarg_replacement($this->thumbnailQuality);
2230: if ($this->config_output_interlace) {
2231:
2232: $commandline .= ' -interlace line ';
2233: }
2234: }
2235: }
2236: $commandline .= ' '.phpthumb_functions::escapeshellarg_replacement(preg_replace('#[/\\\\]#', DIRECTORY_SEPARATOR, $this->sourceFilename).(($outputFormat == 'gif') ? '' : '['.intval($this->sfn).']'));
2237: $commandline .= ' '.$outputFormat.':'.phpthumb_functions::escapeshellarg_replacement($IMtempfilename);
2238: if (!$this->iswindows) {
2239: $commandline .= ' 2>&1';
2240: }
2241: $this->DebugMessage('ImageMagick called as ('.$commandline.')', __FILE__, __LINE__);
2242: $IMresult = phpthumb_functions::SafeExec($commandline);
2243: clearstatcache();
2244: if (!@file_exists($IMtempfilename) || !@filesize($IMtempfilename)) {
2245: $this->FatalError('ImageMagick failed with message ('.trim($IMresult).')');
2246: $this->DebugMessage('ImageMagick failed with message ('.trim($IMresult).')', __FILE__, __LINE__);
2247: if ($this->iswindows && !$IMresult) {
2248: $this->DebugMessage('Check to make sure that PHP has read+write permissions to "'.dirname($IMtempfilename).'"', __FILE__, __LINE__);
2249: }
2250:
2251: } else {
2252:
2253: foreach ($successfullyProcessedFilters as $dummy => $filterkey) {
2254: unset($this->fltr[$filterkey]);
2255: }
2256: $this->IMresizedData = file_get_contents($IMtempfilename);
2257: $getimagesize_imresized = @getimagesize($IMtempfilename);
2258: $this->DebugMessage('getimagesize('.$IMtempfilename.') returned [w='.$getimagesize_imresized[0].';h='.$getimagesize_imresized[1].';f='.$getimagesize_imresized[2].']', __FILE__, __LINE__);
2259: if (($this->config_max_source_pixels > 0) && (($getimagesize_imresized[0] * $getimagesize_imresized[1]) > $this->config_max_source_pixels)) {
2260: $this->DebugMessage('skipping ImageMagickThumbnailToGD::'.$ImageCreateFunction.'() because IM output is too large ('.$getimagesize_imresized[0].'x'.$getimagesize_imresized[0].' = '.($getimagesize_imresized[0] * $getimagesize_imresized[1]).' > '.$this->config_max_source_pixels.')', __FILE__, __LINE__);
2261: } elseif (function_exists(@$ImageCreateFunction) && ($this->gdimg_source = @$ImageCreateFunction($IMtempfilename))) {
2262: $this->source_width = imagesx($this->gdimg_source);
2263: $this->source_height = imagesy($this->gdimg_source);
2264: $this->DebugMessage('ImageMagickThumbnailToGD::'.$ImageCreateFunction.'() succeeded, $this->gdimg_source is now ('.$this->source_width.'x'.$this->source_height.')', __FILE__, __LINE__);
2265: $this->DebugMessage('ImageMagickThumbnailToGD() returning $this->IMresizedData ('.strlen($this->IMresizedData).' bytes)', __FILE__, __LINE__);
2266: } else {
2267: $this->useRawIMoutput = true;
2268: $this->DebugMessage('$this->useRawIMoutput set to TRUE because '.@$ImageCreateFunction.'('.$IMtempfilename.') failed', __FILE__, __LINE__);
2269: }
2270: if (file_exists($IMtempfilename)) {
2271: $this->DebugMessage('deleting "'.$IMtempfilename.'"', __FILE__, __LINE__);
2272: @unlink($IMtempfilename);
2273: }
2274: return true;
2275:
2276: }
2277: if (file_exists($IMtempfilename)) {
2278: $this->DebugMessage('deleting "'.$IMtempfilename.'"', __FILE__, __LINE__);
2279: @unlink($IMtempfilename);
2280: }
2281:
2282: } elseif ($this->issafemode) {
2283: $this->DebugMessage('ImageMagickThumbnailToGD() aborting because PHP safe_mode is enabled and phpThumb_tempnam() failed', __FILE__, __LINE__);
2284: $this->useRawIMoutput = false;
2285: } else {
2286: if (file_exists($IMtempfilename)) {
2287: $this->DebugMessage('deleting "'.$IMtempfilename.'"', __FILE__, __LINE__);
2288: @unlink($IMtempfilename);
2289: }
2290: $this->DebugMessage('ImageMagickThumbnailToGD() aborting, phpThumb_tempnam() failed', __FILE__, __LINE__);
2291: }
2292: } else {
2293: $this->DebugMessage('ImageMagickThumbnailToGD() aborting because ImageMagickCommandlineBase() failed', __FILE__, __LINE__);
2294: }
2295: $this->useRawIMoutput = false;
2296: return false;
2297: }
2298:
2299:
2300: function Rotate() {
2301: if ($this->ra || $this->ar) {
2302: if (!function_exists('imagerotate')) {
2303: $this->DebugMessage('!function_exists(imagerotate)', __FILE__, __LINE__);
2304: return false;
2305: }
2306: if (!include_once(dirname(__FILE__).'/phpthumb.filters.php')) {
2307: $this->DebugMessage('Error including "'.dirname(__FILE__).'/phpthumb.filters.php" which is required for applying filters ('.implode(';', $this->fltr).')', __FILE__, __LINE__);
2308: return false;
2309: }
2310:
2311: $this->config_background_hexcolor = ($this->bg ? $this->bg : $this->config_background_hexcolor);
2312: if (!phpthumb_functions::IsHexColor($this->config_background_hexcolor)) {
2313: return $this->ErrorImage('Invalid hex color string "'.$this->config_background_hexcolor.'" for parameter "bg"');
2314: }
2315:
2316: $rotate_angle = 0;
2317: if ($this->ra) {
2318:
2319: $rotate_angle = floatval($this->ra);
2320:
2321: } else {
2322:
2323: if ($this->ar == 'x') {
2324: if (phpthumb_functions::version_compare_replacement(phpversion(), '4.2.0', '>=')) {
2325: if ($this->sourceFilename) {
2326: if (function_exists('exif_read_data')) {
2327: if ($exif_data = @exif_read_data($this->sourceFilename, 'IFD0')) {
2328:
2329: switch (@$exif_data['Orientation']) {
2330: case 1:
2331: $rotate_angle = 0;
2332: break;
2333: case 3:
2334: $rotate_angle = 180;
2335: break;
2336: case 6:
2337: $rotate_angle = 270;
2338: break;
2339: case 8:
2340: $rotate_angle = 90;
2341: break;
2342:
2343: default:
2344: $this->DebugMessage('EXIF auto-rotate failed because unknown $exif_data[Orientation] "'.@$exif_data['Orientation'].'"', __FILE__, __LINE__);
2345: return false;
2346: break;
2347: }
2348: $this->DebugMessage('EXIF auto-rotate set to '.$rotate_angle.' degrees ($exif_data[Orientation] = "'.@$exif_data['Orientation'].'")', __FILE__, __LINE__);
2349: } else {
2350: $this->DebugMessage('failed: exif_read_data('.$this->sourceFilename.')', __FILE__, __LINE__);
2351: return false;
2352: }
2353: } else {
2354: $this->DebugMessage('!function_exists(exif_read_data)', __FILE__, __LINE__);
2355: return false;
2356: }
2357: } else {
2358: $this->DebugMessage('Cannot auto-rotate from EXIF data because $this->sourceFilename is empty', __FILE__, __LINE__);
2359: return false;
2360: }
2361: } else {
2362: $this->DebugMessage('Cannot auto-rotate from EXIF data because PHP is less than v4.2.0 ('.phpversion().')', __FILE__, __LINE__);
2363: return false;
2364: }
2365: } elseif (($this->ar == 'l') && ($this->source_height > $this->source_width)) {
2366: $rotate_angle = 270;
2367: } elseif (($this->ar == 'L') && ($this->source_height > $this->source_width)) {
2368: $rotate_angle = 90;
2369: } elseif (($this->ar == 'p') && ($this->source_width > $this->source_height)) {
2370: $rotate_angle = 90;
2371: } elseif (($this->ar == 'P') && ($this->source_width > $this->source_height)) {
2372: $rotate_angle = 270;
2373: }
2374:
2375: }
2376: if ($rotate_angle % 90) {
2377: $this->is_alpha = true;
2378: }
2379: phpthumb_filters::ImprovedImageRotate($this->gdimg_source, $rotate_angle, $this->config_background_hexcolor, $this->bg, $this);
2380: $this->source_width = imagesx($this->gdimg_source);
2381: $this->source_height = imagesy($this->gdimg_source);
2382: }
2383: return true;
2384: }
2385:
2386:
2387: function FixedAspectRatio() {
2388:
2389:
2390: if (!$this->far) {
2391:
2392: return true;
2393: }
2394:
2395: if (!$this->w || !$this->h) {
2396: return false;
2397: }
2398: $this->thumbnail_width = $this->w;
2399: $this->thumbnail_height = $this->h;
2400: $this->is_alpha = true;
2401: if ($this->thumbnail_image_width >= $this->thumbnail_width) {
2402:
2403: $aspectratio = $this->thumbnail_image_height / $this->thumbnail_image_width;
2404: if ($this->w) {
2405: $this->thumbnail_image_height = round($this->thumbnail_image_width * $aspectratio);
2406: $this->thumbnail_height = ($this->h ? $this->h : $this->thumbnail_image_height);
2407: } elseif ($this->thumbnail_image_height < $this->thumbnail_height) {
2408: $this->thumbnail_image_height = $this->thumbnail_height;
2409: $this->thumbnail_image_width = round($this->thumbnail_image_height / $aspectratio);
2410: }
2411:
2412: } else {
2413:
2414: $aspectratio = $this->thumbnail_image_width / $this->thumbnail_image_height;
2415: if ($this->h) {
2416: $this->thumbnail_image_width = round($this->thumbnail_image_height * $aspectratio);
2417: } elseif ($this->thumbnail_image_width < $this->thumbnail_width) {
2418: $this->thumbnail_image_width = $this->thumbnail_width;
2419: $this->thumbnail_image_height = round($this->thumbnail_image_width / $aspectratio);
2420: }
2421:
2422: }
2423: return true;
2424: }
2425:
2426:
2427: function OffsiteDomainIsAllowed($hostname, $allowed_domains) {
2428: static $domain_is_allowed = array();
2429: $hostname = strtolower($hostname);
2430: if (!isset($domain_is_allowed[$hostname])) {
2431: $domain_is_allowed[$hostname] = false;
2432: foreach ($allowed_domains as $valid_domain) {
2433: $starpos = strpos($valid_domain, '*');
2434: if ($starpos !== false) {
2435: $valid_domain = substr($valid_domain, $starpos + 1);
2436: if (preg_match('#'.preg_quote($valid_domain).'$#', $hostname)) {
2437: $domain_is_allowed[$hostname] = true;
2438: break;
2439: }
2440: } else {
2441: if (strtolower($valid_domain) === $hostname) {
2442: $domain_is_allowed[$hostname] = true;
2443: break;
2444: }
2445: }
2446: }
2447: }
2448: return $domain_is_allowed[$hostname];
2449: }
2450:
2451:
2452: function AntiOffsiteLinking() {
2453:
2454: $allow = true;
2455: if ($allow && $this->config_nooffsitelink_enabled && (@$_SERVER['HTTP_REFERER'] || $this->config_nooffsitelink_require_refer)) {
2456: $this->DebugMessage('AntiOffsiteLinking() checking $_SERVER[HTTP_REFERER] "'.@$_SERVER['HTTP_REFERER'].'"', __FILE__, __LINE__);
2457: foreach ($this->config_nooffsitelink_valid_domains as $key => $valid_domain) {
2458:
2459: list($clean_domain) = explode(':', $valid_domain);
2460: $this->config_nooffsitelink_valid_domains[$key] = $clean_domain;
2461: }
2462: $parsed_url = phpthumb_functions::ParseURLbetter(@$_SERVER['HTTP_REFERER']);
2463: if (!$this->OffsiteDomainIsAllowed(@$parsed_url['host'], $this->config_nooffsitelink_valid_domains)) {
2464: $allow = false;
2465:
2466: $this->ErrorImage('AntiOffsiteLinking() - "'.@$parsed_url['host'].'" is NOT in $this->config_nooffsitelink_valid_domains ('.implode(';', $this->config_nooffsitelink_valid_domains).')');
2467: } else {
2468: $this->DebugMessage('AntiOffsiteLinking() - "'.@$parsed_url['host'].'" is in $this->config_nooffsitelink_valid_domains ('.implode(';', $this->config_nooffsitelink_valid_domains).')', __FILE__, __LINE__);
2469: }
2470: }
2471:
2472: if ($allow && $this->config_nohotlink_enabled && preg_match('#^(f|ht)tps?\://#i', $this->src)) {
2473: $parsed_url = phpthumb_functions::ParseURLbetter($this->src);
2474:
2475: if (!$this->OffsiteDomainIsAllowed(@$parsed_url['host'], $this->config_nohotlink_valid_domains)) {
2476:
2477: $allow = false;
2478: $this->DebugMessage('AntiOffsiteLinking() - "'.$parsed_url['host'].'" is NOT in $this->config_nohotlink_valid_domains ('.implode(';', $this->config_nohotlink_valid_domains).')', __FILE__, __LINE__);
2479: } else {
2480: $this->DebugMessage('AntiOffsiteLinking() - "'.$parsed_url['host'].'" is in $this->config_nohotlink_valid_domains ('.implode(';', $this->config_nohotlink_valid_domains).')', __FILE__, __LINE__);
2481: }
2482: }
2483:
2484: if ($allow) {
2485: $this->DebugMessage('AntiOffsiteLinking() says this is allowed', __FILE__, __LINE__);
2486: return true;
2487: }
2488:
2489: if (!phpthumb_functions::IsHexColor($this->config_error_bgcolor)) {
2490: return $this->ErrorImage('Invalid hex color string "'.$this->config_error_bgcolor.'" for $this->config_error_bgcolor');
2491: }
2492: if (!phpthumb_functions::IsHexColor($this->config_error_textcolor)) {
2493: return $this->ErrorImage('Invalid hex color string "'.$this->config_error_textcolor.'" for $this->config_error_textcolor');
2494: }
2495: if ($this->config_nooffsitelink_erase_image) {
2496:
2497: return $this->ErrorImage($this->config_nooffsitelink_text_message, $this->thumbnail_width, $this->thumbnail_height);
2498:
2499: } else {
2500:
2501: $this->config_nooffsitelink_watermark_src = $this->ResolveFilenameToAbsolute($this->config_nooffsitelink_watermark_src);
2502: if (is_file($this->config_nooffsitelink_watermark_src)) {
2503:
2504: if (!include_once(dirname(__FILE__).'/phpthumb.filters.php')) {
2505: $this->DebugMessage('Error including "'.dirname(__FILE__).'/phpthumb.filters.php" which is required for applying watermark', __FILE__, __LINE__);
2506: return false;
2507: }
2508: $watermark_img = $this->ImageCreateFromStringReplacement(file_get_contents($this->config_nooffsitelink_watermark_src));
2509: $phpthumbFilters = new phpthumb_filters();
2510: $phpthumbFilters->phpThumbObject = &$this;
2511: $opacity = 50;
2512: $margin = 5;
2513: $phpthumbFilters->WatermarkOverlay($this->gdimg_output, $watermark_img, '*', $opacity, $margin);
2514: imagedestroy($watermark_img);
2515: unset($phpthumbFilters);
2516:
2517: } else {
2518:
2519: $nohotlink_text_array = explode("\n", wordwrap($this->config_nooffsitelink_text_message, floor($this->thumbnail_width / imagefontwidth($this->config_error_fontsize)), "\n"));
2520: $nohotlink_text_color = phpthumb_functions::ImageHexColorAllocate($this->gdimg_output, $this->config_error_textcolor);
2521:
2522: $topoffset = round(($this->thumbnail_height - (count($nohotlink_text_array) * imagefontheight($this->config_error_fontsize))) / 2);
2523:
2524: $rowcounter = 0;
2525: $this->DebugMessage('AntiOffsiteLinking() writing '.count($nohotlink_text_array).' lines of text "'.$this->config_nooffsitelink_text_message.'" (in #'.$this->config_error_textcolor.') on top of image', __FILE__, __LINE__);
2526: foreach ($nohotlink_text_array as $textline) {
2527: $leftoffset = max(0, round(($this->thumbnail_width - (strlen($textline) * imagefontwidth($this->config_error_fontsize))) / 2));
2528: imagestring($this->gdimg_output, $this->config_error_fontsize, $leftoffset, $topoffset + ($rowcounter++ * imagefontheight($this->config_error_fontsize)), $textline, $nohotlink_text_color);
2529: }
2530:
2531: }
2532:
2533: }
2534: return true;
2535: }
2536:
2537:
2538: function AlphaChannelFlatten() {
2539: if (!$this->is_alpha) {
2540:
2541: $this->DebugMessage('skipping AlphaChannelFlatten() because !$this->is_alpha', __FILE__, __LINE__);
2542: return false;
2543: }
2544: switch ($this->thumbnailFormat) {
2545: case 'png':
2546: case 'ico':
2547:
2548: $this->DebugMessage('skipping AlphaChannelFlatten() because ($this->thumbnailFormat == "'.$this->thumbnailFormat.'")', __FILE__, __LINE__);
2549: return false;
2550: break;
2551:
2552: case 'gif':
2553:
2554: $CurrentImageColorTransparent = imagecolortransparent($this->gdimg_output);
2555: if ($CurrentImageColorTransparent == -1) {
2556:
2557:
2558: if (phpthumb_functions::gd_version() < 2.0) {
2559: $this->DebugMessage('AlphaChannelFlatten() failed because GD version is "'.phpthumb_functions::gd_version().'"', __FILE__, __LINE__);
2560: return false;
2561: }
2562:
2563: if ($img_alpha_mixdown_dither = @imagecreatetruecolor(imagesx($this->gdimg_output), imagesy($this->gdimg_output))) {
2564:
2565: $dither_color = array();
2566: for ($i = 0; $i <= 255; $i++) {
2567: $dither_color[$i] = imagecolorallocate($img_alpha_mixdown_dither, $i, $i, $i);
2568: }
2569:
2570:
2571: for ($x = 0; $x < $this->thumbnail_width; $x++) {
2572: for ($y = 0; $y < $this->thumbnail_height; $y++) {
2573: $PixelColor = phpthumb_functions::GetPixelColor($this->gdimg_output, $x, $y);
2574: imagesetpixel($img_alpha_mixdown_dither, $x, $y, $dither_color[($PixelColor['alpha'] * 2)]);
2575: }
2576: }
2577:
2578:
2579: imagetruecolortopalette($img_alpha_mixdown_dither, true, 2);
2580:
2581:
2582: imagetruecolortopalette($this->gdimg_output, true, 255);
2583:
2584:
2585: $TransparentColor = imagecolorallocate($this->gdimg_output, 1, 254, 253);
2586: imagecolortransparent($this->gdimg_output, $TransparentColor);
2587:
2588:
2589: for ($x = 0; $x < $this->thumbnail_width; $x++) {
2590: for ($y = 0; $y < $this->thumbnail_height; $y++) {
2591: $AlphaChannelPixel = phpthumb_functions::GetPixelColor($img_alpha_mixdown_dither, $x, $y);
2592: if ($AlphaChannelPixel['red'] > 127) {
2593: imagesetpixel($this->gdimg_output, $x, $y, $TransparentColor);
2594: }
2595: }
2596: }
2597: imagedestroy($img_alpha_mixdown_dither);
2598:
2599: $this->DebugMessage('AlphaChannelFlatten() set image to 255+1 colors with transparency for GIF output', __FILE__, __LINE__);
2600: return true;
2601:
2602: } else {
2603: $this->DebugMessage('AlphaChannelFlatten() failed imagecreate('.imagesx($this->gdimg_output).', '.imagesy($this->gdimg_output).')', __FILE__, __LINE__);
2604: return false;
2605: }
2606:
2607: } else {
2608:
2609: $this->DebugMessage('skipping AlphaChannelFlatten() because ($this->thumbnailFormat == "'.$this->thumbnailFormat.'") and imagecolortransparent() returned "'.$CurrentImageColorTransparent.'"', __FILE__, __LINE__);
2610: return true;
2611: }
2612: break;
2613: }
2614: $this->DebugMessage('continuing AlphaChannelFlatten() for output format "'.$this->thumbnailFormat.'"', __FILE__, __LINE__);
2615:
2616: if ($gdimg_flatten_temp = phpthumb_functions::ImageCreateFunction($this->thumbnail_width, $this->thumbnail_height)) {
2617:
2618: $this->config_background_hexcolor = ($this->bg ? $this->bg : $this->config_background_hexcolor);
2619: if (!phpthumb_functions::IsHexColor($this->config_background_hexcolor)) {
2620: return $this->ErrorImage('Invalid hex color string "'.$this->config_background_hexcolor.'" for parameter "bg"');
2621: }
2622: $background_color = phpthumb_functions::ImageHexColorAllocate($this->gdimg_output, $this->config_background_hexcolor);
2623: imagefilledrectangle($gdimg_flatten_temp, 0, 0, $this->thumbnail_width, $this->thumbnail_height, $background_color);
2624: imagecopy($gdimg_flatten_temp, $this->gdimg_output, 0, 0, 0, 0, $this->thumbnail_width, $this->thumbnail_height);
2625:
2626: imagealphablending($this->gdimg_output, true);
2627: imagesavealpha($this->gdimg_output, false);
2628: imagecolortransparent($this->gdimg_output, -1);
2629: imagecopy($this->gdimg_output, $gdimg_flatten_temp, 0, 0, 0, 0, $this->thumbnail_width, $this->thumbnail_height);
2630:
2631: imagedestroy($gdimg_flatten_temp);
2632: return true;
2633:
2634: } else {
2635: $this->DebugMessage('ImageCreateFunction() failed', __FILE__, __LINE__);
2636: }
2637: return false;
2638: }
2639:
2640:
2641: function ApplyFilters() {
2642: if ($this->fltr && is_array($this->fltr)) {
2643: if (!include_once(dirname(__FILE__).'/phpthumb.filters.php')) {
2644: $this->DebugMessage('Error including "'.dirname(__FILE__).'/phpthumb.filters.php" which is required for applying filters ('.implode(';', $this->fltr).')', __FILE__, __LINE__);
2645: return false;
2646: }
2647: $phpthumbFilters = new phpthumb_filters();
2648: $phpthumbFilters->phpThumbObject = &$this;
2649: foreach ($this->fltr as $filtercommand) {
2650: @list($command, $parameter) = explode('|', $filtercommand, 2);
2651: $this->DebugMessage('Attempting to process filter command "'.$command.'('.$parameter.')"', __FILE__, __LINE__);
2652: switch ($command) {
2653: case 'brit':
2654: $phpthumbFilters->Brightness($this->gdimg_output, $parameter);
2655: break;
2656:
2657: case 'cont':
2658: $phpthumbFilters->Contrast($this->gdimg_output, $parameter);
2659: break;
2660:
2661: case 'ds':
2662: $phpthumbFilters->Desaturate($this->gdimg_output, $parameter, '');
2663: break;
2664:
2665: case 'sat':
2666: $phpthumbFilters->Saturation($this->gdimg_output, $parameter, '');
2667: break;
2668:
2669: case 'gray':
2670: $phpthumbFilters->Grayscale($this->gdimg_output);
2671: break;
2672:
2673: case 'clr':
2674: if (phpthumb_functions::gd_version() < 2) {
2675: $this->DebugMessage('Skipping Colorize() because gd_version is "'.phpthumb_functions::gd_version().'"', __FILE__, __LINE__);
2676: break;
2677: }
2678: @list($amount, $color) = explode('|', $parameter, 2);
2679: $phpthumbFilters->Colorize($this->gdimg_output, $amount, $color);
2680: break;
2681:
2682: case 'sep':
2683: if (phpthumb_functions::gd_version() < 2) {
2684: $this->DebugMessage('Skipping Sepia() because gd_version is "'.phpthumb_functions::gd_version().'"', __FILE__, __LINE__);
2685: break;
2686: }
2687: @list($amount, $color) = explode('|', $parameter, 2);
2688: $phpthumbFilters->Sepia($this->gdimg_output, $amount, $color);
2689: break;
2690:
2691: case 'gam':
2692: $phpthumbFilters->Gamma($this->gdimg_output, $parameter);
2693: break;
2694:
2695: case 'neg':
2696: $phpthumbFilters->Negative($this->gdimg_output);
2697: break;
2698:
2699: case 'th':
2700: $phpthumbFilters->Threshold($this->gdimg_output, $parameter);
2701: break;
2702:
2703: case 'rcd':
2704: if (phpthumb_functions::gd_version() < 2) {
2705: $this->DebugMessage('Skipping ReduceColorDepth() because gd_version is "'.phpthumb_functions::gd_version().'"', __FILE__, __LINE__);
2706: break;
2707: }
2708: @list($colors, $dither) = explode('|', $parameter, 2);
2709: $colors = ($colors ? (int) $colors : 256);
2710: $dither = ((strlen($dither) > 0) ? (bool) $dither : true);
2711: $phpthumbFilters->ReduceColorDepth($this->gdimg_output, $colors, $dither);
2712: break;
2713:
2714: case 'flip':
2715: $phpthumbFilters->Flip($this->gdimg_output, (strpos(strtolower($parameter), 'x') !== false), (strpos(strtolower($parameter), 'y') !== false));
2716: break;
2717:
2718: case 'edge':
2719: $phpthumbFilters->EdgeDetect($this->gdimg_output);
2720: break;
2721:
2722: case 'emb':
2723: $phpthumbFilters->Emboss($this->gdimg_output);
2724: break;
2725:
2726: case 'bvl':
2727: @list($width, $color1, $color2) = explode('|', $parameter, 3);
2728: $phpthumbFilters->Bevel($this->gdimg_output, $width, $color1, $color2);
2729: break;
2730:
2731: case 'lvl':
2732: @list($band, $method, $threshold) = explode('|', $parameter, 3);
2733: $band = ($band ? preg_replace('#[^RGBA\\*]#', '', strtoupper($band)) : '*');
2734: $method = ((strlen($method) > 0) ? intval($method) : 2);
2735: $threshold = ((strlen($threshold) > 0) ? floatval($threshold) : 0.1);
2736:
2737: $phpthumbFilters->HistogramStretch($this->gdimg_output, $band, $method, $threshold);
2738: break;
2739:
2740: case 'wb':
2741: $phpthumbFilters->WhiteBalance($this->gdimg_output, $parameter);
2742: break;
2743:
2744: case 'hist':
2745: if (phpthumb_functions::gd_version() < 2) {
2746: $this->DebugMessage('Skipping HistogramOverlay() because gd_version is "'.phpthumb_functions::gd_version().'"', __FILE__, __LINE__);
2747: break;
2748: }
2749: @list($bands, $colors, $width, $height, $alignment, $opacity, $margin_x, $margin_y) = explode('|', $parameter, 8);
2750: $bands = ($bands ? $bands : '*');
2751: $colors = ($colors ? $colors : '');
2752: $width = ($width ? $width : 0.25);
2753: $height = ($height ? $height : 0.25);
2754: $alignment = ($alignment ? $alignment : 'BR');
2755: $opacity = ($opacity ? $opacity : 50);
2756: $margin_x = ($margin_x ? $margin_x : 5);
2757:
2758: $phpthumbFilters->HistogramOverlay($this->gdimg_output, $bands, $colors, $width, $height, $alignment, $opacity, $margin_x, $margin_y);
2759: break;
2760:
2761: case 'fram':
2762: @list($frame_width, $edge_width, $color_frame, $color1, $color2) = explode('|', $parameter, 5);
2763: $phpthumbFilters->Frame($this->gdimg_output, $frame_width, $edge_width, $color_frame, $color1, $color2);
2764: break;
2765:
2766: case 'drop':
2767: if (phpthumb_functions::gd_version() < 2) {
2768: $this->DebugMessage('Skipping DropShadow() because gd_version is "'.phpthumb_functions::gd_version().'"', __FILE__, __LINE__);
2769: return false;
2770: }
2771: $this->is_alpha = true;
2772: @list($distance, $width, $color, $angle, $fade) = explode('|', $parameter, 5);
2773: $phpthumbFilters->DropShadow($this->gdimg_output, $distance, $width, $color, $angle, $fade);
2774: break;
2775:
2776: case 'mask':
2777: if (phpthumb_functions::gd_version() < 2) {
2778: $this->DebugMessage('Skipping Mask() because gd_version is "'.phpthumb_functions::gd_version().'"', __FILE__, __LINE__);
2779: return false;
2780: }
2781: @list($mask_filename, $invert) = explode('|', $parameter, 2);
2782: $mask_filename = $this->ResolveFilenameToAbsolute($mask_filename);
2783: if (@is_readable($mask_filename) && ($fp_mask = @fopen($mask_filename, 'rb'))) {
2784: $MaskImageData = '';
2785: do {
2786: $buffer = fread($fp_mask, 8192);
2787: $MaskImageData .= $buffer;
2788: } while (strlen($buffer) > 0);
2789: fclose($fp_mask);
2790: if ($gdimg_mask = $this->ImageCreateFromStringReplacement($MaskImageData)) {
2791: if ($invert && phpthumb_functions::version_compare_replacement(phpversion(), '5.0.0', '>=') && phpthumb_functions::gd_is_bundled()) {
2792: imagefilter($gdimg_mask, IMG_FILTER_NEGATE);
2793: }
2794: $this->is_alpha = true;
2795: $phpthumbFilters->ApplyMask($gdimg_mask, $this->gdimg_output);
2796: imagedestroy($gdimg_mask);
2797: } else {
2798: $this->DebugMessage('ImageCreateFromStringReplacement() failed for "'.$mask_filename.'"', __FILE__, __LINE__);
2799: }
2800: } else {
2801: $this->DebugMessage('Cannot open mask file "'.$mask_filename.'"', __FILE__, __LINE__);
2802: }
2803: break;
2804:
2805: case 'elip':
2806: if (phpthumb_functions::gd_version() < 2) {
2807: $this->DebugMessage('Skipping Ellipse() because gd_version is "'.phpthumb_functions::gd_version().'"', __FILE__, __LINE__);
2808: return false;
2809: }
2810: $this->is_alpha = true;
2811: $phpthumbFilters->Ellipse($this->gdimg_output);
2812: break;
2813:
2814: case 'ric':
2815: if (phpthumb_functions::gd_version() < 2) {
2816: $this->DebugMessage('Skipping RoundedImageCorners() because gd_version is "'.phpthumb_functions::gd_version().'"', __FILE__, __LINE__);
2817: return false;
2818: }
2819: @list($radius_x, $radius_y) = explode('|', $parameter, 2);
2820: if (($radius_x < 1) || ($radius_y < 1)) {
2821: $this->DebugMessage('Skipping RoundedImageCorners('.$radius_x.', '.$radius_y.') because x/y radius is less than 1', __FILE__, __LINE__);
2822: break;
2823: }
2824: $this->is_alpha = true;
2825: $phpthumbFilters->RoundedImageCorners($this->gdimg_output, $radius_x, $radius_y);
2826: break;
2827:
2828: case 'crop':
2829: @list($left, $right, $top, $bottom) = explode('|', $parameter, 4);
2830: $phpthumbFilters->Crop($this->gdimg_output, $left, $right, $top, $bottom);
2831: break;
2832:
2833: case 'bord':
2834: @list($border_width, $radius_x, $radius_y, $hexcolor_border) = explode('|', $parameter, 4);
2835: $this->is_alpha = true;
2836: $phpthumbFilters->ImageBorder($this->gdimg_output, $border_width, $radius_x, $radius_y, $hexcolor_border);
2837: break;
2838:
2839: case 'over':
2840: @list($filename, $underlay, $margin, $opacity) = explode('|', $parameter, 4);
2841: $underlay = (bool) ($underlay ? $underlay : false);
2842: $margin = ((strlen($margin) > 0) ? $margin : ($underlay ? 0.1 : 0.0));
2843: $opacity = ((strlen($opacity) > 0) ? $opacity : 100);
2844: if (($margin > 0) && ($margin < 1)) {
2845: $margin = min(0.499, $margin);
2846: } elseif (($margin > -1) && ($margin < 0)) {
2847: $margin = max(-0.499, $margin);
2848: }
2849:
2850: $filename = $this->ResolveFilenameToAbsolute($filename);
2851: if (@is_readable($filename) && ($fp_watermark = @fopen($filename, 'rb'))) {
2852: $WatermarkImageData = '';
2853: do {
2854: $buffer = fread($fp_watermark, 8192);
2855: $WatermarkImageData .= $buffer;
2856: } while (strlen($buffer) > 0);
2857: fclose($fp_watermark);
2858: if ($img_watermark = $this->ImageCreateFromStringReplacement($WatermarkImageData)) {
2859: if (($margin > 0) && ($margin < 1)) {
2860: $resized_x = max(1, imagesx($this->gdimg_output) - round(2 * (imagesx($this->gdimg_output) * $margin)));
2861: $resized_y = max(1, imagesy($this->gdimg_output) - round(2 * (imagesy($this->gdimg_output) * $margin)));
2862: } else {
2863: $resized_x = max(1, imagesx($this->gdimg_output) - round(2 * $margin));
2864: $resized_y = max(1, imagesy($this->gdimg_output) - round(2 * $margin));
2865: }
2866:
2867: if ($underlay) {
2868:
2869: if ($img_watermark_resized = phpthumb_functions::ImageCreateFunction(imagesx($this->gdimg_output), imagesy($this->gdimg_output))) {
2870: imagealphablending($img_watermark_resized, false);
2871: imagesavealpha($img_watermark_resized, true);
2872: $this->ImageResizeFunction($img_watermark_resized, $img_watermark, 0, 0, 0, 0, imagesx($img_watermark_resized), imagesy($img_watermark_resized), imagesx($img_watermark), imagesy($img_watermark));
2873: if ($img_source_resized = phpthumb_functions::ImageCreateFunction($resized_x, $resized_y)) {
2874: imagealphablending($img_source_resized, false);
2875: imagesavealpha($img_source_resized, true);
2876: $this->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));
2877: $phpthumbFilters->WatermarkOverlay($img_watermark_resized, $img_source_resized, 'C', $opacity, $margin);
2878: imagecopy($this->gdimg_output, $img_watermark_resized, 0, 0, 0, 0, imagesx($this->gdimg_output), imagesy($this->gdimg_output));
2879: } else {
2880: $this->DebugMessage('phpthumb_functions::ImageCreateFunction('.$resized_x.', '.$resized_y.')', __FILE__, __LINE__);
2881: }
2882: imagedestroy($img_watermark_resized);
2883: } else {
2884: $this->DebugMessage('phpthumb_functions::ImageCreateFunction('.imagesx($this->gdimg_output).', '.imagesy($this->gdimg_output).')', __FILE__, __LINE__);
2885: }
2886:
2887: } else {
2888:
2889: if ($img_watermark_resized = phpthumb_functions::ImageCreateFunction($resized_x, $resized_y)) {
2890: imagealphablending($img_watermark_resized, false);
2891: imagesavealpha($img_watermark_resized, true);
2892: $this->ImageResizeFunction($img_watermark_resized, $img_watermark, 0, 0, 0, 0, imagesx($img_watermark_resized), imagesy($img_watermark_resized), imagesx($img_watermark), imagesy($img_watermark));
2893: $phpthumbFilters->WatermarkOverlay($this->gdimg_output, $img_watermark_resized, 'C', $opacity, $margin);
2894: imagedestroy($img_watermark_resized);
2895: } else {
2896: $this->DebugMessage('phpthumb_functions::ImageCreateFunction('.$resized_x.', '.$resized_y.')', __FILE__, __LINE__);
2897: }
2898:
2899: }
2900: imagedestroy($img_watermark);
2901:
2902: } else {
2903: $this->DebugMessage('ImageCreateFromStringReplacement() failed for "'.$filename.'"', __FILE__, __LINE__);
2904: }
2905: } else {
2906: $this->DebugMessage('Cannot open overlay file "'.$filename.'"', __FILE__, __LINE__);
2907: }
2908: break;
2909:
2910: case 'wmi':
2911: @list($filename, $alignment, $opacity, $margin['x'], $margin['y'], $rotate_angle) = explode('|', $parameter, 6);
2912:
2913: $alignment = ($alignment ? $alignment : 'BR');
2914: $opacity = (strlen($opacity) ? intval($opacity) : 50);
2915: $rotate_angle = (strlen($rotate_angle) ? intval($rotate_angle) : 0);
2916: if (!preg_match('#^([0-9\\.\\-]*)x([0-9\\.\\-]*)$#i', $alignment, $matches)) {
2917: $margins = array('x', 'y');
2918: foreach ($margins as $xy) {
2919: $margin[$xy] = (strlen($margin[$xy]) ? $margin[$xy] : 5);
2920: if (($margin[$xy] > 0) && ($margin[$xy] < 1)) {
2921: $margin[$xy] = min(0.499, $margin[$xy]);
2922: } elseif (($margin[$xy] > -1) && ($margin[$xy] < 0)) {
2923: $margin[$xy] = max(-0.499, $margin[$xy]);
2924: }
2925: }
2926: }
2927:
2928: $filename = $this->ResolveFilenameToAbsolute($filename);
2929: if (@is_readable($filename)) {
2930: if ($img_watermark = $this->ImageCreateFromFilename($filename)) {
2931: if ($rotate_angle !== 0) {
2932: $phpthumbFilters->ImprovedImageRotate($img_watermark, $rotate_angle, 'FFFFFF', null, $this);
2933: }
2934: if (preg_match('#^([0-9\\.\\-]*)x([0-9\\.\\-]*)$#i', $alignment, $matches)) {
2935: $watermark_max_width = intval($margin['x'] ? $margin['x'] : imagesx($img_watermark));
2936: $watermark_max_height = intval($margin['y'] ? $margin['y'] : imagesy($img_watermark));
2937: $scale = phpthumb_functions::ScaleToFitInBox(imagesx($img_watermark), imagesy($img_watermark), $watermark_max_width, $watermark_max_height, true, true);
2938: $this->DebugMessage('Scaling watermark by a factor of '.number_format($scale, 4), __FILE__, __LINE__);
2939: if (($scale > 1) || ($scale < 1)) {
2940: if ($img_watermark2 = phpthumb_functions::ImageCreateFunction($scale * imagesx($img_watermark), $scale * imagesy($img_watermark))) {
2941: imagealphablending($img_watermark2, false);
2942: imagesavealpha($img_watermark2, true);
2943: $this->ImageResizeFunction($img_watermark2, $img_watermark, 0, 0, 0, 0, imagesx($img_watermark2), imagesy($img_watermark2), imagesx($img_watermark), imagesy($img_watermark));
2944: $img_watermark = $img_watermark2;
2945: } else {
2946: $this->DebugMessage('ImageCreateFunction('.($scale * imagesx($img_watermark)).', '.($scale * imagesx($img_watermark)).') failed', __FILE__, __LINE__);
2947: }
2948: }
2949: $watermark_dest_x = round($matches[1] - (imagesx($img_watermark) / 2));
2950: $watermark_dest_y = round($matches[2] - (imagesy($img_watermark) / 2));
2951: $alignment = $watermark_dest_x.'x'.$watermark_dest_y;
2952: }
2953: $phpthumbFilters->WatermarkOverlay($this->gdimg_output, $img_watermark, $alignment, $opacity, $margin['x'], $margin['y']);
2954: imagedestroy($img_watermark);
2955: if (isset($img_watermark2) && is_resource($img_watermark2)) {
2956: imagedestroy($img_watermark2);
2957: }
2958: } else {
2959: $this->DebugMessage('ImageCreateFromFilename() failed for "'.$filename.'"', __FILE__, __LINE__);
2960: }
2961: } else {
2962: $this->DebugMessage('!is_readable('.$filename.')', __FILE__, __LINE__);
2963: }
2964: break;
2965:
2966: case 'wmt':
2967: @list($text, $size, $alignment, $hex_color, $ttffont, $opacity, $margin, $angle, $bg_color, $bg_opacity, $fillextend) = explode('|', $parameter, 11);
2968: $text = ($text ? $text : '');
2969: $size = ($size ? $size : 3);
2970: $alignment = ($alignment ? $alignment : 'BR');
2971: $hex_color = ($hex_color ? $hex_color : '000000');
2972: $ttffont = ($ttffont ? $ttffont : '');
2973: $opacity = (strlen($opacity) ? $opacity : 50);
2974: $margin = (strlen($margin) ? $margin : 5);
2975: $angle = (strlen($angle) ? $angle : 0);
2976: $bg_color = ($bg_color ? $bg_color : false);
2977: $bg_opacity = ($bg_opacity ? $bg_opacity : 0);
2978: $fillextend = ($fillextend ? $fillextend : '');
2979:
2980: if (basename($ttffont) == $ttffont) {
2981: $ttffont = $this->realPathSafe($this->config_ttf_directory.DIRECTORY_SEPARATOR.$ttffont);
2982: } else {
2983: $ttffont = $this->ResolveFilenameToAbsolute($ttffont);
2984: }
2985: $phpthumbFilters->WatermarkText($this->gdimg_output, $text, $size, $alignment, $hex_color, $ttffont, $opacity, $margin, $angle, $bg_color, $bg_opacity, $fillextend);
2986: break;
2987:
2988: case 'blur':
2989: @list($radius) = explode('|', $parameter, 1);
2990: $radius = ($radius ? $radius : 1);
2991: if (phpthumb_functions::gd_version() >= 2) {
2992: $phpthumbFilters->Blur($this->gdimg_output, $radius);
2993: } else {
2994: $this->DebugMessage('Skipping Blur() because gd_version is "'.phpthumb_functions::gd_version().'"', __FILE__, __LINE__);
2995: }
2996: break;
2997:
2998: case 'gblr':
2999: $phpthumbFilters->BlurGaussian($this->gdimg_output);
3000: break;
3001:
3002: case 'sblr':
3003: $phpthumbFilters->BlurSelective($this->gdimg_output);
3004: break;
3005:
3006: case 'mean':
3007: $phpthumbFilters->MeanRemoval($this->gdimg_output);
3008: break;
3009:
3010: case 'smth':
3011: $phpthumbFilters->Smooth($this->gdimg_output, $parameter);
3012: break;
3013:
3014: case 'usm':
3015: @list($amount, $radius, $threshold) = explode('|', $parameter, 3);
3016: $amount = ($amount ? $amount : 80);
3017: $radius = ($radius ? $radius : 0.5);
3018: $threshold = (strlen($threshold) ? $threshold : 3);
3019: if (phpthumb_functions::gd_version() >= 2.0) {
3020: ob_start();
3021: if (!@include_once(dirname(__FILE__).'/phpthumb.unsharp.php')) {
3022: $include_error = ob_get_contents();
3023: if ($include_error) {
3024: $this->DebugMessage('include_once("'.dirname(__FILE__).'/phpthumb.unsharp.php") generated message: "'.$include_error.'"', __FILE__, __LINE__);
3025: }
3026: $this->DebugMessage('Error including "'.dirname(__FILE__).'/phpthumb.unsharp.php" which is required for unsharp masking', __FILE__, __LINE__);
3027: ob_end_clean();
3028: return false;
3029: }
3030: ob_end_clean();
3031: phpUnsharpMask::applyUnsharpMask($this->gdimg_output, $amount, $radius, $threshold);
3032: } else {
3033: $this->DebugMessage('Skipping unsharp mask because gd_version is "'.phpthumb_functions::gd_version().'"', __FILE__, __LINE__);
3034: return false;
3035: }
3036: break;
3037:
3038: case 'size':
3039: @list($newwidth, $newheight, $stretch) = explode('|', $parameter);
3040: $newwidth = (!$newwidth ? imagesx($this->gdimg_output) : ((($newwidth > 0) && ($newwidth < 1)) ? round($newwidth * imagesx($this->gdimg_output)) : round($newwidth)));
3041: $newheight = (!$newheight ? imagesy($this->gdimg_output) : ((($newheight > 0) && ($newheight < 1)) ? round($newheight * imagesy($this->gdimg_output)) : round($newheight)));
3042: $stretch = ($stretch ? true : false);
3043: if ($stretch) {
3044: $scale_x = phpthumb_functions::ScaleToFitInBox(imagesx($this->gdimg_output), imagesx($this->gdimg_output), $newwidth, $newwidth, true, true);
3045: $scale_y = phpthumb_functions::ScaleToFitInBox(imagesy($this->gdimg_output), imagesy($this->gdimg_output), $newheight, $newheight, true, true);
3046: } else {
3047: $scale_x = phpthumb_functions::ScaleToFitInBox(imagesx($this->gdimg_output), imagesy($this->gdimg_output), $newwidth, $newheight, true, true);
3048: $scale_y = $scale_x;
3049: }
3050: $this->DebugMessage('Scaling watermark ('.($stretch ? 'with' : 'without').' stretch) by a factor of "'.number_format($scale_x, 4).' x '.number_format($scale_y, 4).'"', __FILE__, __LINE__);
3051: if (($scale_x > 1) || ($scale_x < 1) || ($scale_y > 1) || ($scale_y < 1)) {
3052: if ($img_temp = phpthumb_functions::ImageCreateFunction(imagesx($this->gdimg_output), imagesy($this->gdimg_output))) {
3053: imagecopy($img_temp, $this->gdimg_output, 0, 0, 0, 0, imagesx($this->gdimg_output), imagesy($this->gdimg_output));
3054: if ($this->gdimg_output = phpthumb_functions::ImageCreateFunction($scale_x * imagesx($img_temp), $scale_y * imagesy($img_temp))) {
3055: imagealphablending($this->gdimg_output, false);
3056: imagesavealpha($this->gdimg_output, true);
3057: $this->ImageResizeFunction($this->gdimg_output, $img_temp, 0, 0, 0, 0, imagesx($this->gdimg_output), imagesy($this->gdimg_output), imagesx($img_temp), imagesy($img_temp));
3058: } else {
3059: $this->DebugMessage('ImageCreateFunction('.($scale_x * imagesx($img_temp)).', '.($scale_y * imagesy($img_temp)).') failed', __FILE__, __LINE__);
3060: }
3061: imagedestroy($img_temp);
3062: } else {
3063: $this->DebugMessage('ImageCreateFunction('.imagesx($this->gdimg_output).', '.imagesy($this->gdimg_output).') failed', __FILE__, __LINE__);
3064: }
3065: }
3066: break;
3067:
3068: case 'rot':
3069: @list($angle, $bgcolor) = explode('|', $parameter, 2);
3070: $phpthumbFilters->ImprovedImageRotate($this->gdimg_output, $angle, $bgcolor, null, $this);
3071: break;
3072:
3073: case 'stc':
3074: @list($hexcolor, $min_limit, $max_limit) = explode('|', $parameter, 3);
3075: if (!phpthumb_functions::IsHexColor($hexcolor)) {
3076: $this->DebugMessage('Skipping SourceTransparentColor hex color is invalid ('.$hexcolor.')', __FILE__, __LINE__);
3077: return false;
3078: }
3079: $min_limit = (strlen($min_limit) ? $min_limit : 5);
3080: $max_limit = (strlen($max_limit) ? $max_limit : 10);
3081: if ($gdimg_mask = $phpthumbFilters->SourceTransparentColorMask($this->gdimg_output, $hexcolor, $min_limit, $max_limit)) {
3082: $this->is_alpha = true;
3083: $phpthumbFilters->ApplyMask($gdimg_mask, $this->gdimg_output);
3084: imagedestroy($gdimg_mask);
3085: } else {
3086: $this->DebugMessage('SourceTransparentColorMask() failed for "'.$hexcolor.','.$min_limit.','.$max_limit.'"', __FILE__, __LINE__);
3087: }
3088: break;
3089: }
3090: $this->DebugMessage('Finished processing filter command "'.$command.'('.$parameter.')"', __FILE__, __LINE__);
3091: }
3092: }
3093: return true;
3094: }
3095:
3096:
3097: function MaxFileSize() {
3098: if (phpthumb_functions::gd_version() < 2) {
3099: $this->DebugMessage('Skipping MaxFileSize() because gd_version is "'.phpthumb_functions::gd_version().'"', __FILE__, __LINE__);
3100: return false;
3101: }
3102: if ($this->maxb > 0) {
3103: switch ($this->thumbnailFormat) {
3104: case 'png':
3105: case 'gif':
3106: $imgRenderFunction = 'image'.$this->thumbnailFormat;
3107:
3108: ob_start();
3109: $imgRenderFunction($this->gdimg_output);
3110: $imgdata = ob_get_contents();
3111: ob_end_clean();
3112:
3113: if (strlen($imgdata) > $this->maxb) {
3114: for ($i = 8; $i >= 1; $i--) {
3115: $tempIMG = imagecreatetruecolor(imagesx($this->gdimg_output), imagesy($this->gdimg_output));
3116: imagecopy($tempIMG, $this->gdimg_output, 0, 0, 0, 0, imagesx($this->gdimg_output), imagesy($this->gdimg_output));
3117: imagetruecolortopalette($tempIMG, true, pow(2, $i));
3118: ob_start();
3119: $imgRenderFunction($tempIMG);
3120: $imgdata = ob_get_contents();
3121: ob_end_clean();
3122:
3123: if (strlen($imgdata) <= $this->maxb) {
3124: imagetruecolortopalette($this->gdimg_output, true, pow(2, $i));
3125: break;
3126: }
3127: }
3128: }
3129: break;
3130:
3131: case 'jpeg':
3132: ob_start();
3133: imagejpeg($this->gdimg_output);
3134: $imgdata = ob_get_contents();
3135: ob_end_clean();
3136:
3137: if (strlen($imgdata) > $this->maxb) {
3138: for ($i = 3; $i < 20; $i++) {
3139: $q = round(100 * (1 - log10($i / 2)));
3140: ob_start();
3141: imagejpeg($this->gdimg_output, null, $q);
3142: $imgdata = ob_get_contents();
3143: ob_end_clean();
3144:
3145: $this->thumbnailQuality = $q;
3146: if (strlen($imgdata) <= $this->maxb) {
3147: break;
3148: }
3149: }
3150: }
3151: if (strlen($imgdata) > $this->maxb) {
3152: return false;
3153: }
3154: break;
3155:
3156: default:
3157: return false;
3158: }
3159: }
3160: return true;
3161: }
3162:
3163:
3164: function CalculateThumbnailDimensions() {
3165: $this->DebugMessage('CalculateThumbnailDimensions() starting with [W,H,sx,sy,sw,sh] initially set to ['.$this->source_width.','.$this->source_height.','.$this->sx.','.$this->sy.','.$this->sw.','.$this->sh.']', __FILE__, __LINE__);
3166:
3167: $this->thumbnailCropX = ($this->sx ? (($this->sx >= 2) ? $this->sx : round($this->sx * $this->source_width)) : 0);
3168:
3169: $this->thumbnailCropY = ($this->sy ? (($this->sy >= 2) ? $this->sy : round($this->sy * $this->source_height)) : 0);
3170:
3171: $this->thumbnailCropW = ($this->sw ? (($this->sw >= 2) ? $this->sw : round($this->sw * $this->source_width)) : $this->source_width);
3172:
3173: $this->thumbnailCropH = ($this->sh ? (($this->sh >= 2) ? $this->sh : round($this->sh * $this->source_height)) : $this->source_height);
3174:
3175:
3176:
3177: $this->thumbnailCropW = max(1, min($this->thumbnailCropW, $this->source_width - $this->thumbnailCropX));
3178: $this->thumbnailCropH = max(1, min($this->thumbnailCropH, $this->source_height - $this->thumbnailCropY));
3179:
3180: $this->DebugMessage('CalculateThumbnailDimensions() starting with [x,y,w,h] initially set to ['.$this->thumbnailCropX.','.$this->thumbnailCropY.','.$this->thumbnailCropW.','.$this->thumbnailCropH.']', __FILE__, __LINE__);
3181:
3182:
3183: if ($this->zc && $this->w && $this->h) {
3184:
3185:
3186:
3187:
3188: $scaling_X = $this->source_width / $this->w;
3189: $scaling_Y = $this->source_height / $this->h;
3190: if ($scaling_X > $scaling_Y) {
3191:
3192: $allowable_width = $this->source_width / $scaling_X * $scaling_Y;
3193: $this->thumbnailCropW = round($allowable_width);
3194: $this->thumbnailCropX = round(($this->source_width - $allowable_width) / 2);
3195:
3196: } elseif ($scaling_Y > $scaling_X) {
3197:
3198: $allowable_height = $this->source_height / $scaling_Y * $scaling_X;
3199: $this->thumbnailCropH = round($allowable_height);
3200: $this->thumbnailCropY = round(($this->source_height - $allowable_height) / 2);
3201:
3202: } else {
3203:
3204: }
3205: $this->thumbnail_width = $this->w;
3206: $this->thumbnail_height = $this->h;
3207: $this->thumbnail_image_width = $this->thumbnail_width;
3208: $this->thumbnail_image_height = $this->thumbnail_height;
3209:
3210: } elseif ($this->iar && $this->w && $this->h) {
3211:
3212:
3213:
3214: $this->thumbnail_width = $this->w;
3215: $this->thumbnail_height = $this->h;
3216: $this->thumbnail_image_width = $this->thumbnail_width;
3217: $this->thumbnail_image_height = $this->thumbnail_height;
3218:
3219: } else {
3220:
3221: $original_aspect_ratio = $this->thumbnailCropW / $this->thumbnailCropH;
3222: if ($this->aoe) {
3223: if ($this->w && $this->h) {
3224: $maxwidth = min($this->w, $this->h * $original_aspect_ratio);
3225: $maxheight = min($this->h, $this->w / $original_aspect_ratio);
3226: } elseif ($this->w) {
3227: $maxwidth = $this->w;
3228: $maxheight = $this->w / $original_aspect_ratio;
3229: } elseif ($this->h) {
3230: $maxwidth = $this->h * $original_aspect_ratio;
3231: $maxheight = $this->h;
3232: } else {
3233: $maxwidth = $this->thumbnailCropW;
3234: $maxheight = $this->thumbnailCropH;
3235: }
3236: } else {
3237: $maxwidth = phpthumb_functions::nonempty_min($this->w, $this->thumbnailCropW, $this->config_output_maxwidth);
3238: $maxheight = phpthumb_functions::nonempty_min($this->h, $this->thumbnailCropH, $this->config_output_maxheight);
3239:
3240: $maxwidth = min($maxwidth, $maxheight * $original_aspect_ratio);
3241: $maxheight = min($maxheight, $maxwidth / $original_aspect_ratio);
3242:
3243: }
3244:
3245: $this->thumbnail_image_width = $maxwidth;
3246: $this->thumbnail_image_height = $maxheight;
3247: $this->thumbnail_width = $maxwidth;
3248: $this->thumbnail_height = $maxheight;
3249:
3250: $this->FixedAspectRatio();
3251: }
3252:
3253: $this->thumbnail_width = max(1, floor($this->thumbnail_width));
3254: $this->thumbnail_height = max(1, floor($this->thumbnail_height));
3255: return true;
3256: }
3257:
3258:
3259: function CreateGDoutput() {
3260: $this->CalculateThumbnailDimensions();
3261:
3262:
3263: $this->gdimg_output = phpthumb_functions::ImageCreateFunction($this->thumbnail_width, $this->thumbnail_height);
3264:
3265:
3266: imagesavealpha($this->gdimg_output, true);
3267: if ($this->is_alpha && phpthumb_functions::gd_version() >= 2) {
3268:
3269: imagealphablending($this->gdimg_output, false);
3270: $output_full_alpha = phpthumb_functions::ImageColorAllocateAlphaSafe($this->gdimg_output, 255, 255, 255, 127);
3271: imagefilledrectangle($this->gdimg_output, 0, 0, $this->thumbnail_width, $this->thumbnail_height, $output_full_alpha);
3272:
3273: } else {
3274:
3275: $current_transparent_color = imagecolortransparent($this->gdimg_source);
3276: if ($this->bg || (@$current_transparent_color >= 0)) {
3277:
3278: $this->config_background_hexcolor = ($this->bg ? $this->bg : $this->config_background_hexcolor);
3279: if (!phpthumb_functions::IsHexColor($this->config_background_hexcolor)) {
3280: return $this->ErrorImage('Invalid hex color string "'.$this->config_background_hexcolor.'" for parameter "bg"');
3281: }
3282: $background_color = phpthumb_functions::ImageHexColorAllocate($this->gdimg_output, $this->config_background_hexcolor);
3283: imagefilledrectangle($this->gdimg_output, 0, 0, $this->thumbnail_width, $this->thumbnail_height, $background_color);
3284:
3285: }
3286:
3287: }
3288: $this->DebugMessage('CreateGDoutput() returning canvas "'.$this->thumbnail_width.'x'.$this->thumbnail_height.'"', __FILE__, __LINE__);
3289: return true;
3290: }
3291:
3292: function SetOrientationDependantWidthHeight() {
3293: $this->DebugMessage('SetOrientationDependantWidthHeight() starting with "'.$this->source_width.'"x"'.$this->source_height.'"', __FILE__, __LINE__);
3294: if ($this->source_height > $this->source_width) {
3295:
3296: $this->w = phpthumb_functions::OneOfThese($this->wp, $this->w, $this->ws, $this->wl);
3297: $this->h = phpthumb_functions::OneOfThese($this->hp, $this->h, $this->hs, $this->hl);
3298: } elseif ($this->source_height < $this->source_width) {
3299:
3300: $this->w = phpthumb_functions::OneOfThese($this->wl, $this->w, $this->ws, $this->wp);
3301: $this->h = phpthumb_functions::OneOfThese($this->hl, $this->h, $this->hs, $this->hp);
3302: } else {
3303:
3304: $this->w = phpthumb_functions::OneOfThese($this->ws, $this->w, $this->wl, $this->wp);
3305: $this->h = phpthumb_functions::OneOfThese($this->hs, $this->h, $this->hl, $this->hp);
3306: }
3307:
3308:
3309: $this->DebugMessage('SetOrientationDependantWidthHeight() setting w="'.intval($this->w).'", h="'.intval($this->h).'"', __FILE__, __LINE__);
3310: return true;
3311: }
3312:
3313: function ExtractEXIFgetImageSize() {
3314: $this->DebugMessage('starting ExtractEXIFgetImageSize()', __FILE__, __LINE__);
3315:
3316: if (preg_match('#^http:#i', $this->src) && !$this->sourceFilename && $this->rawImageData) {
3317: $this->SourceDataToTempFile();
3318: }
3319: if (is_null($this->getimagesizeinfo)) {
3320: if ($this->sourceFilename) {
3321: $this->getimagesizeinfo = @getimagesize($this->sourceFilename);
3322: $this->source_width = $this->getimagesizeinfo[0];
3323: $this->source_height = $this->getimagesizeinfo[1];
3324: $this->DebugMessage('getimagesize('.$this->sourceFilename.') says image is '.$this->source_width.'x'.$this->source_height, __FILE__, __LINE__);
3325: } else {
3326: $this->DebugMessage('skipping getimagesize() because $this->sourceFilename is empty', __FILE__, __LINE__);
3327: }
3328: } else {
3329: $this->DebugMessage('skipping getimagesize() because !is_null($this->getimagesizeinfo)', __FILE__, __LINE__);
3330: }
3331:
3332: if (is_resource($this->gdimg_source)) {
3333:
3334: $this->source_width = imagesx($this->gdimg_source);
3335: $this->source_height = imagesy($this->gdimg_source);
3336:
3337: $this->SetOrientationDependantWidthHeight();
3338:
3339: } elseif ($this->rawImageData && !$this->sourceFilename) {
3340:
3341: if ($this->SourceImageIsTooLarge($this->source_width, $this->source_height)) {
3342: $this->DebugMessage('NOT bypassing EXIF and getimagesize sections because source image is too large for GD ('.$this->source_width.'x'.$this->source_width.'='.($this->source_width * $this->source_height * 5).'MB)', __FILE__, __LINE__);
3343: } else {
3344: $this->DebugMessage('bypassing EXIF and getimagesize sections because $this->rawImageData is set, and $this->sourceFilename is not set, and source image is not too large for GD ('.$this->source_width.'x'.$this->source_width.'='.($this->source_width * $this->source_height * 5).'MB)', __FILE__, __LINE__);
3345: }
3346:
3347: }
3348:
3349: if (is_null($this->getimagesizeinfo)) {
3350: $this->getimagesizeinfo = @getimagesize($this->sourceFilename);
3351: }
3352:
3353: if (!empty($this->getimagesizeinfo)) {
3354:
3355: $this->getimagesizeinfo['filesize'] = @filesize($this->sourceFilename);
3356: } elseif (!$this->rawImageData) {
3357: $this->DebugMessage('getimagesize("'.$this->sourceFilename.'") failed', __FILE__, __LINE__);
3358: }
3359:
3360: if ($this->config_prefer_imagemagick) {
3361: if ($this->ImageMagickThumbnailToGD()) {
3362: return true;
3363: }
3364: $this->DebugMessage('ImageMagickThumbnailToGD() failed', __FILE__, __LINE__);
3365: }
3366:
3367: $this->source_width = $this->getimagesizeinfo[0];
3368: $this->source_height = $this->getimagesizeinfo[1];
3369:
3370: $this->SetOrientationDependantWidthHeight();
3371:
3372: if (phpthumb_functions::version_compare_replacement(phpversion(), '4.2.0', '>=') && function_exists('exif_read_data')) {
3373: switch ($this->getimagesizeinfo[2]) {
3374: case IMAGETYPE_JPEG:
3375: case IMAGETYPE_TIFF_II:
3376: case IMAGETYPE_TIFF_MM:
3377: $this->exif_raw_data = @exif_read_data($this->sourceFilename, 0, true);
3378: break;
3379: }
3380: }
3381: if (function_exists('exif_thumbnail') && ($this->getimagesizeinfo[2] == IMAGETYPE_JPEG)) {
3382:
3383:
3384: $this->exif_thumbnail_width = '';
3385: $this->exif_thumbnail_height = '';
3386: $this->exif_thumbnail_type = '';
3387:
3388:
3389: if (phpthumb_functions::version_compare_replacement(phpversion(), '4.3.0', '>=')) {
3390:
3391: $this->exif_thumbnail_data = @exif_thumbnail($this->sourceFilename, $this->exif_thumbnail_width, $this->exif_thumbnail_height, $this->exif_thumbnail_type);
3392:
3393: } else {
3394:
3395:
3396: ob_start();
3397: $this->exif_thumbnail_data = exif_thumbnail($this->sourceFilename);
3398: $exit_thumbnail_error = ob_get_contents();
3399: ob_end_clean();
3400: if (!$exit_thumbnail_error && $this->exif_thumbnail_data) {
3401:
3402: if ($gdimg_exif_temp = $this->ImageCreateFromStringReplacement($this->exif_thumbnail_data, false)) {
3403: $this->exif_thumbnail_width = imagesx($gdimg_exif_temp);
3404: $this->exif_thumbnail_height = imagesy($gdimg_exif_temp);
3405: $this->exif_thumbnail_type = 2;
3406: unset($gdimg_exif_temp);
3407: } else {
3408: return $this->ErrorImage('Failed - $this->ImageCreateFromStringReplacement($this->exif_thumbnail_data) in '.__FILE__.' on line '.__LINE__);
3409: }
3410:
3411: }
3412:
3413: }
3414:
3415: } elseif (!function_exists('exif_thumbnail')) {
3416:
3417: $this->DebugMessage('exif_thumbnail() does not exist, cannot extract EXIF thumbnail', __FILE__, __LINE__);
3418:
3419: }
3420:
3421: $this->DebugMessage('EXIF thumbnail extraction: (size='.strlen($this->exif_thumbnail_data).'; type="'.$this->exif_thumbnail_type.'"; '.intval($this->exif_thumbnail_width).'x'.intval($this->exif_thumbnail_height).')', __FILE__, __LINE__);
3422:
3423:
3424: if ($this->config_use_exif_thumbnail_for_speed && $this->exif_thumbnail_data) {
3425: while (true) {
3426: if (!$this->xto) {
3427: $source_ar = $this->source_width / $this->source_height;
3428: $exif_ar = $this->exif_thumbnail_width / $this->exif_thumbnail_height;
3429: if (number_format($source_ar, 2) != number_format($exif_ar, 2)) {
3430: $this->DebugMessage('not using EXIF thumbnail because $source_ar != $exif_ar ('.$source_ar.' != '.$exif_ar.')', __FILE__, __LINE__);
3431: break;
3432: }
3433: if ($this->w && ($this->w != $this->exif_thumbnail_width)) {
3434: $this->DebugMessage('not using EXIF thumbnail because $this->w != $this->exif_thumbnail_width ('.$this->w.' != '.$this->exif_thumbnail_width.')', __FILE__, __LINE__);
3435: break;
3436: }
3437: if ($this->h && ($this->h != $this->exif_thumbnail_height)) {
3438: $this->DebugMessage('not using EXIF thumbnail because $this->h != $this->exif_thumbnail_height ('.$this->h.' != '.$this->exif_thumbnail_height.')', __FILE__, __LINE__);
3439: break;
3440: }
3441: $CannotBeSetParameters = array('sx', 'sy', 'sh', 'sw', 'far', 'bg', 'bc', 'fltr', 'phpThumbDebug');
3442: foreach ($CannotBeSetParameters as $parameter) {
3443: if ($this->$parameter) {
3444: break 2;
3445: }
3446: }
3447: }
3448:
3449: $this->DebugMessage('setting $this->gdimg_source = $this->ImageCreateFromStringReplacement($this->exif_thumbnail_data)', __FILE__, __LINE__);
3450: $this->gdimg_source = $this->ImageCreateFromStringReplacement($this->exif_thumbnail_data);
3451: $this->source_width = imagesx($this->gdimg_source);
3452: $this->source_height = imagesy($this->gdimg_source);
3453: return true;
3454: }
3455: }
3456:
3457: if (($this->config_max_source_pixels > 0) && (($this->source_width * $this->source_height) > $this->config_max_source_pixels)) {
3458:
3459:
3460:
3461:
3462:
3463: $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__);
3464: if (!$this->config_prefer_imagemagick && $this->ImageMagickThumbnailToGD()) {
3465:
3466: return true;
3467: }
3468:
3469: }
3470: return true;
3471: }
3472:
3473:
3474: function SetCacheFilename() {
3475: if (!is_null($this->cache_filename)) {
3476: $this->DebugMessage('$this->cache_filename already set, skipping SetCacheFilename()', __FILE__, __LINE__);
3477: return true;
3478: }
3479: if (is_null($this->config_cache_directory)) {
3480: $this->setCacheDirectory();
3481: if (!$this->config_cache_directory) {
3482: $this->DebugMessage('SetCacheFilename() failed because $this->config_cache_directory is empty', __FILE__, __LINE__);
3483: return false;
3484: }
3485: }
3486: $this->setOutputFormat();
3487:
3488: if (!$this->sourceFilename && !$this->rawImageData && $this->src) {
3489: $this->sourceFilename = $this->ResolveFilenameToAbsolute($this->src);
3490: }
3491:
3492: if ($this->config_cache_default_only_suffix && $this->sourceFilename) {
3493:
3494:
3495:
3496:
3497: if (strpos($this->config_cache_default_only_suffix, '*') === false) {
3498: $this->DebugMessage('aborting simplified caching filename because no * in "'.$this->config_cache_default_only_suffix.'"', __FILE__, __LINE__);
3499: } else {
3500: preg_match('#(.+)(\\.[a-z0-9]+)?$#i', basename($this->sourceFilename), $matches);
3501: $this->cache_filename = $this->config_cache_directory.DIRECTORY_SEPARATOR.rawurlencode(str_replace('*', @$matches[1], $this->config_cache_default_only_suffix)).'.'.strtolower($this->thumbnailFormat);
3502: return true;
3503: }
3504: }
3505:
3506: $this->cache_filename = '';
3507: if ($this->new) {
3508: $broad_directory_name = strtolower(md5($this->new));
3509: $this->cache_filename .= '_new'.$broad_directory_name;
3510: } elseif ($this->md5s) {
3511:
3512: $this->DebugMessage('SetCacheFilename() _raw set from $this->md5s = "'.$this->md5s.'"', __FILE__, __LINE__);
3513: $broad_directory_name = $this->md5s;
3514: $this->cache_filename .= '_raw'.$this->md5s;
3515: } elseif (!$this->src && $this->rawImageData) {
3516: $this->DebugMessage('SetCacheFilename() _raw set from md5($this->rawImageData) = "'.md5($this->rawImageData).'"', __FILE__, __LINE__);
3517: $broad_directory_name = strtolower(md5($this->rawImageData));
3518: $this->cache_filename .= '_raw'.$broad_directory_name;
3519: } else {
3520: $this->DebugMessage('SetCacheFilename() _src set from md5($this->sourceFilename) "'.$this->sourceFilename.'" = "'.md5($this->sourceFilename).'"', __FILE__, __LINE__);
3521: $broad_directory_name = strtolower(md5($this->sourceFilename));
3522: $this->cache_filename .= '_src'.$broad_directory_name;
3523: }
3524: if (!empty($_SERVER['HTTP_REFERER']) && $this->config_nooffsitelink_enabled) {
3525: $parsed_url1 = @phpthumb_functions::ParseURLbetter(@$_SERVER['HTTP_REFERER']);
3526: $parsed_url2 = @phpthumb_functions::ParseURLbetter('http://'.@$_SERVER['HTTP_HOST']);
3527: if (@$parsed_url1['host'] && @$parsed_url2['host'] && ($parsed_url1['host'] != $parsed_url2['host'])) {
3528:
3529: $this->cache_filename .= '_offsite';
3530: }
3531: }
3532:
3533: $ParametersString = '';
3534: if ($this->fltr && is_array($this->fltr)) {
3535: $ParametersString .= '_fltr'.implode('_fltr', $this->fltr);
3536: }
3537: $FilenameParameters1 = array('ar', 'bg', 'bc', 'far', 'sx', 'sy', 'sw', 'sh', 'zc');
3538: foreach ($FilenameParameters1 as $key) {
3539: if ($this->$key) {
3540: $ParametersString .= '_'.$key.$this->$key;
3541: }
3542: }
3543: $FilenameParameters2 = array('h', 'w', 'wl', 'wp', 'ws', 'hp', 'hs', 'xto', 'ra', 'iar', 'aoe', 'maxb', 'sfn', 'dpi');
3544: foreach ($FilenameParameters2 as $key) {
3545: if ($this->$key) {
3546: $ParametersString .= '_'.$key.intval($this->$key);
3547: }
3548: }
3549: if ($this->thumbnailFormat == 'jpeg') {
3550:
3551: $ParametersString .= '_q'.intval($this->thumbnailQuality);
3552: }
3553: $this->DebugMessage('SetCacheFilename() _par set from md5('.$ParametersString.')', __FILE__, __LINE__);
3554: $this->cache_filename .= '_par'.strtolower(md5($ParametersString));
3555:
3556: if ($this->md5s) {
3557:
3558:
3559:
3560: } elseif (!$this->config_cache_source_filemtime_ignore_remote && preg_match('#^(f|ht)tps?\://#i', $this->src)) {
3561: $this->cache_filename .= '_dat'.intval(phpthumb_functions::filedate_remote($this->src));
3562: } elseif (!$this->config_cache_source_filemtime_ignore_local && $this->src && !$this->rawImageData) {
3563: $this->cache_filename .= '_dat'.intval(@filemtime($this->sourceFilename));
3564: }
3565:
3566: $this->cache_filename .= '.'.strtolower($this->thumbnailFormat);
3567: $broad_directories = '';
3568: for ($i = 0; $i < $this->config_cache_directory_depth; $i++) {
3569: $broad_directories .= DIRECTORY_SEPARATOR.substr($broad_directory_name, 0, $i + 1);
3570: }
3571:
3572: $this->cache_filename = $this->config_cache_directory.$broad_directories.DIRECTORY_SEPARATOR.$this->config_cache_prefix.rawurlencode($this->cache_filename);
3573: return true;
3574: }
3575:
3576:
3577: function SourceImageIsTooLarge($width, $height) {
3578: if (!$this->config_max_source_pixels) {
3579: return false;
3580: }
3581: if ($this->php_memory_limit && function_exists('memory_get_usage')) {
3582: $available_memory = $this->php_memory_limit - memory_get_usage();
3583: return (bool) (($width * $height * 5) > $available_memory);
3584: }
3585: return (bool) (($width * $height) > $this->config_max_source_pixels);
3586: }
3587:
3588: function ImageCreateFromFilename($filename) {
3589:
3590:
3591: $ImageCreateWasAttempted = false;
3592: $gd_image = false;
3593:
3594: $this->DebugMessage('starting ImageCreateFromFilename('.$filename.')', __FILE__, __LINE__);
3595: if ($filename && ($getimagesizeinfo = @getimagesize($filename))) {
3596: if (!$this->SourceImageIsTooLarge($getimagesizeinfo[0], $getimagesizeinfo[1])) {
3597: $ImageCreateFromFunction = array(
3598: 1 => 'imagecreatefromgif',
3599: 2 => 'imagecreatefromjpeg',
3600: 3 => 'imagecreatefrompng',
3601: 15 => 'imagecreatefromwbmp',
3602: );
3603: $this->DebugMessage('ImageCreateFromFilename found ($getimagesizeinfo[2]=='.@$getimagesizeinfo[2].')', __FILE__, __LINE__);
3604: switch (@$getimagesizeinfo[2]) {
3605: case 1:
3606: case 2:
3607: case 3:
3608: case 15:
3609: $ImageCreateFromFunctionName = $ImageCreateFromFunction[$getimagesizeinfo[2]];
3610: if (function_exists($ImageCreateFromFunctionName)) {
3611: $this->DebugMessage('Calling '.$ImageCreateFromFunctionName.'('.$filename.')', __FILE__, __LINE__);
3612: $ImageCreateWasAttempted = true;
3613: $gd_image = $ImageCreateFromFunctionName($filename);
3614: } else {
3615: $this->DebugMessage('NOT calling '.$ImageCreateFromFunctionName.'('.$filename.') because !function_exists('.$ImageCreateFromFunctionName.')', __FILE__, __LINE__);
3616: }
3617: break;
3618:
3619: case 4:
3620: case 5:
3621: case 6:
3622: case 7:
3623: case 8:
3624: case 9:
3625: case 10:
3626: case 11:
3627: case 12:
3628: case 13:
3629: case 14:
3630: case 16:
3631: $this->DebugMessage('No built-in image creation function for image type "'.@$getimagesizeinfo[2].'" ($getimagesizeinfo[2])', __FILE__, __LINE__);
3632: break;
3633:
3634: default:
3635: $this->DebugMessage('Unknown value for $getimagesizeinfo[2]: "'.@$getimagesizeinfo[2].'"', __FILE__, __LINE__);
3636: break;
3637: }
3638: } else {
3639: $this->DebugMessage('image is '.$getimagesizeinfo[0].'x'.$getimagesizeinfo[1].' and therefore contains more pixels ('.($getimagesizeinfo[0] * $getimagesizeinfo[1]).') than $this->config_max_source_pixels setting ('.$this->config_max_source_pixels.')', __FILE__, __LINE__);
3640: return false;
3641: }
3642: } else {
3643: $this->DebugMessage('empty $filename or getimagesize('.$filename.') failed', __FILE__, __LINE__);
3644: }
3645:
3646: if (!$gd_image) {
3647:
3648: if ($ImageCreateWasAttempted) {
3649: $this->DebugMessage($ImageCreateFromFunctionName.'() was attempted but FAILED', __FILE__, __LINE__);
3650: }
3651: $this->DebugMessage('Populating $rawimagedata', __FILE__, __LINE__);
3652: $rawimagedata = '';
3653: if ($fp = @fopen($filename, 'rb')) {
3654: $filesize = filesize($filename);
3655: $blocksize = 8192;
3656: $blockreads = ceil($filesize / $blocksize);
3657: for ($i = 0; $i < $blockreads; $i++) {
3658: $rawimagedata .= fread($fp, $blocksize);
3659: }
3660: fclose($fp);
3661: } else {
3662: $this->DebugMessage('cannot fopen('.$filename.')', __FILE__, __LINE__);
3663: }
3664: if ($rawimagedata) {
3665: $this->DebugMessage('attempting ImageCreateFromStringReplacement($rawimagedata ('.strlen($rawimagedata).' bytes), true)', __FILE__, __LINE__);
3666: $gd_image = $this->ImageCreateFromStringReplacement($rawimagedata, true);
3667: }
3668: }
3669: return $gd_image;
3670: }
3671:
3672: function SourceImageToGD() {
3673: if (is_resource($this->gdimg_source)) {
3674: $this->source_width = imagesx($this->gdimg_source);
3675: $this->source_height = imagesy($this->gdimg_source);
3676: $this->DebugMessage('skipping SourceImageToGD() because $this->gdimg_source is already a resource ('.$this->source_width.'x'.$this->source_height.')', __FILE__, __LINE__);
3677: return true;
3678: }
3679: $this->DebugMessage('starting SourceImageToGD()', __FILE__, __LINE__);
3680:
3681: if ($this->config_prefer_imagemagick) {
3682: if (empty($this->sourceFilename) && !empty($this->rawImageData)) {
3683: $this->DebugMessage('Copying raw image data to temp file and trying again with ImageMagick', __FILE__, __LINE__);
3684: if ($tempnam = $this->phpThumb_tempnam()) {
3685: if (file_put_contents($tempnam, $this->rawImageData)) {
3686: $this->sourceFilename = $tempnam;
3687: if ($this->ImageMagickThumbnailToGD()) {
3688:
3689: $this->DebugMessage('ImageMagickThumbnailToGD() succeeded', __FILE__, __LINE__);
3690: } else {
3691: $this->DebugMessage('ImageMagickThumbnailToGD() failed', __FILE__, __LINE__);
3692: }
3693: @chmod($tempnam, $this->getParameter('config_file_create_mask'));
3694: } else {
3695: $this->DebugMessage('failed to put $this->rawImageData into temp file "'.$tempnam.'"', __FILE__, __LINE__);
3696: }
3697: } else {
3698: $this->DebugMessage('failed to generate temp file name', __FILE__, __LINE__);
3699: }
3700: }
3701: }
3702: if (!$this->gdimg_source && $this->rawImageData) {
3703:
3704: if ($this->SourceImageIsTooLarge($this->source_width, $this->source_height)) {
3705: $memory_get_usage = (function_exists('memory_get_usage') ? memory_get_usage() : 0);
3706: return $this->ErrorImage('Source image is too large ('.$this->source_width.'x'.$this->source_height.' = '.number_format($this->source_width * $this->source_height / 1000000, 1).'Mpx, max='.number_format($this->config_max_source_pixels / 1000000, 1).'Mpx) for GD creation (either install ImageMagick or increase PHP memory_limit to at least '.ceil(($memory_get_usage + (5 * $this->source_width * $this->source_height)) / 1048576).'M).');
3707: }
3708: if ($this->md5s && ($this->md5s != md5($this->rawImageData))) {
3709: return $this->ErrorImage('$this->md5s != md5($this->rawImageData)'."\n".'"'.$this->md5s.'" != '."\n".'"'.md5($this->rawImageData).'"');
3710: }
3711:
3712:
3713:
3714: $this->gdimg_source = $this->ImageCreateFromStringReplacement($this->rawImageData);
3715: if (!$this->gdimg_source) {
3716: if (substr($this->rawImageData, 0, 2) === 'BM') {
3717: $this->getimagesizeinfo[2] = 6;
3718: } elseif (substr($this->rawImageData, 0, 4) === 'II'."\x2A\x00") {
3719: $this->getimagesizeinfo[2] = 7;
3720: } elseif (substr($this->rawImageData, 0, 4) === 'MM'."\x00\x2A") {
3721: $this->getimagesizeinfo[2] = 8;
3722: }
3723: $this->DebugMessage('SourceImageToGD.ImageCreateFromStringReplacement() failed with unknown image type "'.substr($this->rawImageData, 0, 4).'" ('.phpthumb_functions::HexCharDisplay(substr($this->rawImageData, 0, 4)).')', __FILE__, __LINE__);
3724:
3725: }
3726:
3727: } elseif (!$this->gdimg_source && $this->sourceFilename) {
3728:
3729: if ($this->md5s && ($this->md5s != phpthumb_functions::md5_file_safe($this->sourceFilename))) {
3730: return $this->ErrorImage('$this->md5s != md5(sourceFilename)'."\n".'"'.$this->md5s.'" != '."\n".'"'.phpthumb_functions::md5_file_safe($this->sourceFilename).'"');
3731: }
3732: switch (@$this->getimagesizeinfo[2]) {
3733: case 1:
3734: case 3:
3735:
3736: $this->is_alpha = true;
3737: break;
3738: }
3739: if (!$this->SourceImageIsTooLarge($this->source_width, $this->source_height)) {
3740: $this->gdimg_source = $this->ImageCreateFromFilename($this->sourceFilename);
3741: }
3742:
3743: }
3744:
3745: while (true) {
3746: if ($this->gdimg_source) {
3747: $this->DebugMessage('Not using EXIF thumbnail data because $this->gdimg_source is already set', __FILE__, __LINE__);
3748: break;
3749: }
3750: if (!$this->exif_thumbnail_data) {
3751: $this->DebugMessage('Not using EXIF thumbnail data because $this->exif_thumbnail_data is empty', __FILE__, __LINE__);
3752: break;
3753: }
3754: if (ini_get('safe_mode')) {
3755: if (!$this->SourceImageIsTooLarge($this->source_width, $this->source_height)) {
3756: $this->DebugMessage('Using EXIF thumbnail data because source image too large and safe_mode enabled', __FILE__, __LINE__);
3757: $this->aoe = true;
3758: } else {
3759: break;
3760: }
3761: } else {
3762: if (!$this->config_use_exif_thumbnail_for_speed) {
3763: $this->DebugMessage('Not using EXIF thumbnail data because $this->config_use_exif_thumbnail_for_speed is FALSE', __FILE__, __LINE__);
3764: break;
3765: }
3766: if (($this->thumbnailCropX != 0) || ($this->thumbnailCropY != 0)) {
3767: $this->DebugMessage('Not using EXIF thumbnail data because source cropping is enabled ('.$this->thumbnailCropX.','.$this->thumbnailCropY.')', __FILE__, __LINE__);
3768: break;
3769: }
3770: if (($this->w > $this->exif_thumbnail_width) || ($this->h > $this->exif_thumbnail_height)) {
3771: $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__);
3772: break;
3773: }
3774: $source_ar = $this->source_width / $this->source_height;
3775: $exif_ar = $this->exif_thumbnail_width / $this->exif_thumbnail_height;
3776: if (number_format($source_ar, 2) != number_format($exif_ar, 2)) {
3777: $this->DebugMessage('not using EXIF thumbnail because $source_ar != $exif_ar ('.$source_ar.' != '.$exif_ar.')', __FILE__, __LINE__);
3778: break;
3779: }
3780: }
3781:
3782:
3783: $this->DebugMessage('Trying to use EXIF thumbnail as source image', __FILE__, __LINE__);
3784:
3785: if ($gdimg_exif_temp = $this->ImageCreateFromStringReplacement($this->exif_thumbnail_data, false)) {
3786:
3787: $this->DebugMessage('Successfully using EXIF thumbnail as source image', __FILE__, __LINE__);
3788: $this->gdimg_source = $gdimg_exif_temp;
3789: $this->source_width = $this->exif_thumbnail_width;
3790: $this->source_height = $this->exif_thumbnail_height;
3791: $this->thumbnailCropW = $this->source_width;
3792: $this->thumbnailCropH = $this->source_height;
3793: return true;
3794:
3795: } else {
3796: $this->DebugMessage('$this->ImageCreateFromStringReplacement($this->exif_thumbnail_data, false) failed', __FILE__, __LINE__);
3797: }
3798:
3799: break;
3800: }
3801:
3802: if (!$this->gdimg_source) {
3803: $this->DebugMessage('$this->gdimg_source is still empty', __FILE__, __LINE__);
3804:
3805: $this->DebugMessage('ImageMagickThumbnailToGD() failed', __FILE__, __LINE__);
3806:
3807: $imageHeader = '';
3808: $gd_info = gd_info();
3809: $GDreadSupport = false;
3810: switch (@$this->getimagesizeinfo[2]) {
3811: case 1:
3812: $imageHeader = 'Content-Type: image/gif';
3813: $GDreadSupport = (bool) @$gd_info['GIF Read Support'];
3814: break;
3815: case 2:
3816: $imageHeader = 'Content-Type: image/jpeg';
3817: $GDreadSupport = (bool) @$gd_info['JPEG Support'] || (bool) @$gd_info['JPG Support'];
3818: break;
3819: case 3:
3820: $imageHeader = 'Content-Type: image/png';
3821: $GDreadSupport = (bool) @$gd_info['PNG Support'];
3822: break;
3823: }
3824: if ($imageHeader) {
3825:
3826:
3827: if ($this->config_error_die_on_source_failure) {
3828: $errormessages = array();
3829: $errormessages[] = 'All attempts to create GD image source failed.';
3830: if ($this->fatalerror) {
3831: $errormessages[] = $this->fatalerror;
3832: }
3833: if ($this->issafemode) {
3834: $errormessages[] = 'Safe Mode enabled, therefore ImageMagick is unavailable. (disable Safe Mode if possible)';
3835: } elseif (!$this->ImageMagickVersion()) {
3836: $errormessages[] = 'ImageMagick is not installed (it is highly recommended that you install it).';
3837: }
3838: if ($this->SourceImageIsTooLarge($this->getimagesizeinfo[0], $this->getimagesizeinfo[1])) {
3839: $memory_get_usage = (function_exists('memory_get_usage') ? memory_get_usage() : 0);
3840: $errormessages[] = 'Source image is too large ('.$this->getimagesizeinfo[0].'x'.$this->getimagesizeinfo[1].' = '.number_format($this->getimagesizeinfo[0] * $this->getimagesizeinfo[1] / 1000000, 1).'Mpx, max='.number_format($this->config_max_source_pixels / 1000000, 1).'Mpx) for GD creation (either install ImageMagick or increase PHP memory_limit to at least '.ceil(($memory_get_usage + (5 * $this->getimagesizeinfo[0] * $this->getimagesizeinfo[1])) / 1048576).'M).';
3841: } elseif (!$GDreadSupport) {
3842: $errormessages[] = 'GD does not have read support for "'.$imageHeader.'".';
3843: } else {
3844: $errormessages[] = 'Source image probably corrupt.';
3845: }
3846: $this->ErrorImage(implode("\n", $errormessages));
3847:
3848: } else {
3849: $this->DebugMessage('All attempts to create GD image source failed ('.(ini_get('safe_mode') ? 'Safe Mode enabled, ImageMagick unavailable and source image probably too large for GD': ($GDreadSupport ? 'source image probably corrupt' : 'GD does not have read support for "'.$imageHeader.'"')).'), cannot generate thumbnail');
3850:
3851:
3852:
3853:
3854:
3855:
3856: return false;
3857: }
3858: }
3859:
3860:
3861:
3862: switch (@$this->getimagesizeinfo[2]) {
3863: case 6:
3864: ob_start();
3865: if (!@include_once(dirname(__FILE__).'/phpthumb.bmp.php')) {
3866: ob_end_clean();
3867: return $this->ErrorImage('include_once('.dirname(__FILE__).'/phpthumb.bmp.php) failed');
3868: }
3869: ob_end_clean();
3870: if ($fp = @fopen($this->sourceFilename, 'rb')) {
3871: $this->rawImageData = '';
3872: while (!feof($fp)) {
3873: $this->rawImageData .= fread($fp, 32768);
3874: }
3875: fclose($fp);
3876: }
3877: $phpthumb_bmp = new phpthumb_bmp();
3878: $this->gdimg_source = $phpthumb_bmp->phpthumb_bmp2gd($this->rawImageData, (phpthumb_functions::gd_version() >= 2.0));
3879: unset($phpthumb_bmp);
3880: if ($this->gdimg_source) {
3881: $this->DebugMessage('$phpthumb_bmp->phpthumb_bmp2gd() succeeded', __FILE__, __LINE__);
3882: } else {
3883: return $this->ErrorImage($this->ImageMagickVersion() ? 'ImageMagick failed on BMP source conversion' : 'phpthumb_bmp2gd() failed');
3884: }
3885: break;
3886:
3887:
3888:
3889:
3890: case 7:
3891: case 8:
3892: return $this->ErrorImage($this->ImageMagickVersion() ? 'ImageMagick failed on TIFF source conversion' : 'ImageMagick is unavailable and phpThumb() does not support TIFF source images without it');
3893: break;
3894:
3895:
3896:
3897:
3898: }
3899:
3900: if (!$this->gdimg_source) {
3901: if ($this->rawImageData) {
3902: $HeaderFourBytes = substr($this->rawImageData, 0, 4);
3903: } elseif ($this->sourceFilename) {
3904: if ($fp = @fopen($this->sourceFilename, 'rb')) {
3905: $HeaderFourBytes = fread($fp, 4);
3906: fclose($fp);
3907: } else {
3908: return $this->ErrorImage('failed to open "'.$this->sourceFilename.'" SourceImageToGD() ['.__LINE__.']');
3909: }
3910: } else {
3911: return $this->ErrorImage('Unable to create image, neither filename nor image data suppplied in SourceImageToGD() ['.__LINE__.']');
3912: }
3913: if (!$this->ImageMagickVersion() && !phpthumb_functions::gd_version()) {
3914: return $this->ErrorImage('Neither GD nor ImageMagick seem to be installed on this server. At least one (preferably GD), or better both, MUST be installed for phpThumb to work.');
3915: } elseif ($HeaderFourBytes == "\xD7\xCD\xC6\x9A") {
3916: return $this->ErrorImage($this->ImageMagickVersion() ? 'ImageMagick failed on WMF source conversion' : 'ImageMagick is unavailable and phpThumb() does not support WMF source images without it');
3917: } elseif ($HeaderFourBytes == '%PDF') {
3918: return $this->ErrorImage($this->ImageMagickVersion() ? 'ImageMagick and GhostScript are both required for PDF source images; GhostScript may not be properly configured' : 'ImageMagick and/or GhostScript are unavailable and phpThumb() does not support PDF source images without them');
3919: } elseif (substr($HeaderFourBytes, 0, 3) == "\xFF\xD8\xFF") {
3920: return $this->ErrorImage('Image (JPEG) is too large for PHP-GD memory_limit, please install ImageMagick or increase php.ini memory_limit setting');
3921: } elseif ($HeaderFourBytes == '%PNG') {
3922: return $this->ErrorImage('Image (PNG) is too large for PHP-GD memory_limit, please install ImageMagick or increase php.ini memory_limit setting');
3923: } elseif (substr($HeaderFourBytes, 0, 3) == 'GIF') {
3924: return $this->ErrorImage('Image (GIF) is too large for PHP-GD memory_limit, please install ImageMagick or increase php.ini memory_limit setting');
3925: }
3926: return $this->ErrorImage('Unknown image type identified by "'.$HeaderFourBytes.'" ('.phpthumb_functions::HexCharDisplay($HeaderFourBytes).') in SourceImageToGD() ['.__LINE__.']');
3927: }
3928: }
3929:
3930: if (!$this->gdimg_source) {
3931: if ($gdimg_exif_temp = $this->ImageCreateFromStringReplacement($this->exif_thumbnail_data, false)) {
3932: $this->DebugMessage('All other attempts failed, but successfully using EXIF thumbnail as source image', __FILE__, __LINE__);
3933: $this->gdimg_source = $gdimg_exif_temp;
3934:
3935:
3936: $this->aoe = true;
3937: return true;
3938: }
3939: return false;
3940: }
3941:
3942: $this->source_width = imagesx($this->gdimg_source);
3943: $this->source_height = imagesy($this->gdimg_source);
3944: return true;
3945: }
3946:
3947:
3948: function phpThumbDebugVarDump($var) {
3949: if (is_null($var)) {
3950: return 'NULL';
3951: } elseif (is_bool($var)) {
3952: return ($var ? 'TRUE' : 'FALSE');
3953: } elseif (is_string($var)) {
3954: return 'string('.strlen($var).')'.str_repeat(' ', max(0, 3 - strlen(strlen($var)))).' "'.$var.'"';
3955: } elseif (is_int($var)) {
3956: return 'integer '.$var;
3957: } elseif (is_float($var)) {
3958: return 'float '.$var;
3959: } elseif (is_array($var)) {
3960: ob_start();
3961: var_dump($var);
3962: $vardumpoutput = ob_get_contents();
3963: ob_end_clean();
3964: return strtr($vardumpoutput, "\n\r\t", ' ');
3965: }
3966: return gettype($var);
3967: }
3968:
3969: function phpThumbDebug($level='') {
3970: if ($level && ($this->phpThumbDebug !== $level)) {
3971: return true;
3972: }
3973: if ($this->config_disable_debug) {
3974: return $this->ErrorImage('phpThumbDebug disabled');
3975: }
3976:
3977: $FunctionsExistance = array('exif_thumbnail', 'gd_info', 'image_type_to_mime_type', 'getimagesize', 'imagecopyresampled', 'imagecopyresized', 'imagecreate', 'imagecreatefromstring', 'imagecreatetruecolor', 'imageistruecolor', 'imagerotate', 'imagetypes', 'version_compare', 'imagecreatefromgif', 'imagecreatefromjpeg', 'imagecreatefrompng', 'imagecreatefromwbmp', 'imagecreatefromxbm', 'imagecreatefromxpm', 'imagecreatefromstring', 'imagecreatefromgd', 'imagecreatefromgd2', 'imagecreatefromgd2part', 'imagejpeg', 'imagegif', 'imagepng', 'imagewbmp');
3978: $ParameterNames = array('src', 'new', 'w', 'h', 'f', 'q', 'sx', 'sy', 'sw', 'sh', 'far', 'bg', 'bc', 'file', 'goto', 'err', 'xto', 'ra', 'ar', 'aoe', 'iar', 'maxb');
3979: $ConfigVariableNames = array('document_root', 'temp_directory', 'output_format', 'output_maxwidth', 'output_maxheight', 'error_message_image_default', 'error_bgcolor', 'error_textcolor', 'error_fontsize', 'error_die_on_error', 'error_silent_die_on_error', 'error_die_on_source_failure', 'nohotlink_enabled', 'nohotlink_valid_domains', 'nohotlink_erase_image', 'nohotlink_text_message', 'nooffsitelink_enabled', 'nooffsitelink_valid_domains', 'nooffsitelink_require_refer', 'nooffsitelink_erase_image', 'nooffsitelink_text_message', 'high_security_enabled', 'allow_src_above_docroot', 'allow_src_above_phpthumb', 'max_source_pixels', 'use_exif_thumbnail_for_speed', 'border_hexcolor', 'background_hexcolor', 'ttf_directory', 'disable_pathinfo_parsing', 'disable_imagecopyresampled');
3980: $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');
3981:
3982: $DebugOutput = array();
3983: $DebugOutput[] = 'phpThumb() version = '.$this->phpthumb_version;
3984: $DebugOutput[] = 'phpversion() = '.@phpversion();
3985: $DebugOutput[] = 'PHP_OS = '.PHP_OS;
3986: $DebugOutput[] = '$_SERVER[SERVER_SOFTWARE] = '.@$_SERVER['SERVER_SOFTWARE'];
3987: $DebugOutput[] = '__FILE__ = '.__FILE__;
3988: $DebugOutput[] = 'realpath(.) = '.@realpath('.');
3989: $DebugOutput[] = '$_SERVER[PHP_SELF] = '.@$_SERVER['PHP_SELF'];
3990: $DebugOutput[] = '$_SERVER[HOST_NAME] = '.@$_SERVER['HOST_NAME'];
3991: $DebugOutput[] = '$_SERVER[HTTP_REFERER] = '.@$_SERVER['HTTP_REFERER'];
3992: $DebugOutput[] = '$_SERVER[QUERY_STRING] = '.@$_SERVER['QUERY_STRING'];
3993: $DebugOutput[] = '$_SERVER[PATH_INFO] = '.@$_SERVER['PATH_INFO'];
3994: $DebugOutput[] = '$_SERVER[DOCUMENT_ROOT] = '.@$_SERVER['DOCUMENT_ROOT'];
3995: $DebugOutput[] = 'getenv(DOCUMENT_ROOT) = '.@getenv('DOCUMENT_ROOT');
3996: $DebugOutput[] = '';
3997:
3998: $DebugOutput[] = 'get_magic_quotes_gpc() = '.$this->phpThumbDebugVarDump(@get_magic_quotes_gpc());
3999: $DebugOutput[] = 'get_magic_quotes_runtime() = '.$this->phpThumbDebugVarDump(@get_magic_quotes_runtime());
4000: $DebugOutput[] = 'error_reporting() = '.$this->phpThumbDebugVarDump(error_reporting());
4001: $DebugOutput[] = 'ini_get(error_reporting) = '.$this->phpThumbDebugVarDump(@ini_get('error_reporting'));
4002: $DebugOutput[] = 'ini_get(display_errors) = '.$this->phpThumbDebugVarDump(@ini_get('display_errors'));
4003: $DebugOutput[] = 'ini_get(allow_url_fopen) = '.$this->phpThumbDebugVarDump(@ini_get('allow_url_fopen'));
4004: $DebugOutput[] = 'ini_get(disable_functions) = '.$this->phpThumbDebugVarDump(@ini_get('disable_functions'));
4005: $DebugOutput[] = 'get_cfg_var(disable_functions) = '.$this->phpThumbDebugVarDump(@get_cfg_var('disable_functions'));
4006: $DebugOutput[] = 'ini_get(safe_mode) = '.$this->phpThumbDebugVarDump(@ini_get('safe_mode'));
4007: $DebugOutput[] = 'ini_get(open_basedir) = '.$this->phpThumbDebugVarDump(@ini_get('open_basedir'));
4008: $DebugOutput[] = 'ini_get(max_execution_time) = '.$this->phpThumbDebugVarDump(@ini_get('max_execution_time'));
4009: $DebugOutput[] = 'ini_get(memory_limit) = '.$this->phpThumbDebugVarDump(@ini_get('memory_limit'));
4010: $DebugOutput[] = 'get_cfg_var(memory_limit) = '.$this->phpThumbDebugVarDump(@get_cfg_var('memory_limit'));
4011: $DebugOutput[] = 'memory_get_usage() = '.(function_exists('memory_get_usage') ? $this->phpThumbDebugVarDump(@memory_get_usage()) : 'n/a');
4012: $DebugOutput[] = '';
4013:
4014: $DebugOutput[] = '$this->config_prefer_imagemagick = '.$this->phpThumbDebugVarDump($this->config_prefer_imagemagick);
4015: $DebugOutput[] = '$this->config_imagemagick_path = '.$this->phpThumbDebugVarDump($this->config_imagemagick_path);
4016: $DebugOutput[] = '$this->ImageMagickWhichConvert() = '.$this->ImageMagickWhichConvert();
4017: $IMpathUsed = ($this->config_imagemagick_path ? $this->config_imagemagick_path : $this->ImageMagickWhichConvert());
4018: $DebugOutput[] = '[actual ImageMagick path used] = '.$this->phpThumbDebugVarDump($IMpathUsed);
4019: $DebugOutput[] = 'file_exists([actual ImageMagick path used]) = '.$this->phpThumbDebugVarDump(@file_exists($IMpathUsed));
4020: $DebugOutput[] = 'ImageMagickVersion(false) = '.$this->ImageMagickVersion(false);
4021: $DebugOutput[] = 'ImageMagickVersion(true) = '.$this->ImageMagickVersion(true);
4022: $DebugOutput[] = '';
4023:
4024: $DebugOutput[] = '$this->config_cache_directory = '.$this->phpThumbDebugVarDump($this->config_cache_directory);
4025: $DebugOutput[] = '$this->config_cache_directory_depth = '.$this->phpThumbDebugVarDump($this->config_cache_directory_depth);
4026: $DebugOutput[] = '$this->config_cache_disable_warning = '.$this->phpThumbDebugVarDump($this->config_cache_disable_warning);
4027: $DebugOutput[] = '$this->config_cache_maxage = '.$this->phpThumbDebugVarDump($this->config_cache_maxage);
4028: $DebugOutput[] = '$this->config_cache_maxsize = '.$this->phpThumbDebugVarDump($this->config_cache_maxsize);
4029: $DebugOutput[] = '$this->config_cache_maxfiles = '.$this->phpThumbDebugVarDump($this->config_cache_maxfiles);
4030: $DebugOutput[] = '$this->config_cache_force_passthru = '.$this->phpThumbDebugVarDump($this->config_cache_force_passthru);
4031: $DebugOutput[] = '$this->cache_filename = '.$this->phpThumbDebugVarDump($this->cache_filename);
4032: $DebugOutput[] = 'is_readable($this->config_cache_directory) = '.$this->phpThumbDebugVarDump(@is_readable($this->config_cache_directory));
4033: $DebugOutput[] = 'is_writable($this->config_cache_directory) = '.$this->phpThumbDebugVarDump(@is_writable($this->config_cache_directory));
4034: $DebugOutput[] = 'is_readable($this->cache_filename) = '.$this->phpThumbDebugVarDump(@is_readable($this->cache_filename));
4035: $DebugOutput[] = 'is_writable($this->cache_filename) = '.(@file_exists($this->cache_filename) ? $this->phpThumbDebugVarDump(@is_writable($this->cache_filename)) : 'n/a');
4036: $DebugOutput[] = '';
4037:
4038: foreach ($ConfigVariableNames as $varname) {
4039: $varname = 'config_'.$varname;
4040: $value = $this->$varname;
4041: $DebugOutput[] = '$this->'.str_pad($varname, 37, ' ', STR_PAD_RIGHT).' = '.$this->phpThumbDebugVarDump($value);
4042: }
4043: $DebugOutput[] = '';
4044: foreach ($OtherVariableNames as $varname) {
4045: $value = $this->$varname;
4046: $DebugOutput[] = '$this->'.str_pad($varname, 27, ' ', STR_PAD_RIGHT).' = '.$this->phpThumbDebugVarDump($value);
4047: }
4048: $DebugOutput[] = 'strlen($this->rawImageData) = '.strlen(@$this->rawImageData);
4049: $DebugOutput[] = 'strlen($this->exif_thumbnail_data) = '.strlen(@$this->exif_thumbnail_data);
4050: $DebugOutput[] = '';
4051:
4052: foreach ($ParameterNames as $varname) {
4053: $value = $this->$varname;
4054: $DebugOutput[] = '$this->'.str_pad($varname, 4, ' ', STR_PAD_RIGHT).' = '.$this->phpThumbDebugVarDump($value);
4055: }
4056: $DebugOutput[] = '';
4057:
4058: foreach ($FunctionsExistance as $functionname) {
4059: $DebugOutput[] = 'builtin_function_exists('.$functionname.')'.str_repeat(' ', 23 - strlen($functionname)).' = '.$this->phpThumbDebugVarDump(phpthumb_functions::builtin_function_exists($functionname));
4060: }
4061: $DebugOutput[] = '';
4062:
4063: $gd_info = gd_info();
4064: foreach ($gd_info as $key => $value) {
4065: $DebugOutput[] = 'gd_info.'.str_pad($key, 34, ' ', STR_PAD_RIGHT).' = '.$this->phpThumbDebugVarDump($value);
4066: }
4067: $DebugOutput[] = '';
4068:
4069: $exif_info = phpthumb_functions::exif_info();
4070: foreach ($exif_info as $key => $value) {
4071: $DebugOutput[] = 'exif_info.'.str_pad($key, 26, ' ', STR_PAD_RIGHT).' = '.$this->phpThumbDebugVarDump($value);
4072: }
4073: $DebugOutput[] = '';
4074:
4075: if ($ApacheLookupURIarray = phpthumb_functions::ApacheLookupURIarray(dirname(@$_SERVER['PHP_SELF']))) {
4076: foreach ($ApacheLookupURIarray as $key => $value) {
4077: $DebugOutput[] = 'ApacheLookupURIarray.'.str_pad($key, 15, ' ', STR_PAD_RIGHT).' = '.$this->phpThumbDebugVarDump($value);
4078: }
4079: } else {
4080: $DebugOutput[] = 'ApacheLookupURIarray() -- FAILED';
4081: }
4082: $DebugOutput[] = '';
4083:
4084: if (isset($_GET) && is_array($_GET)) {
4085: foreach ($_GET as $key => $value) {
4086: $DebugOutput[] = '$_GET['.$key.']'.str_repeat(' ', 30 - strlen($key)).'= '.$this->phpThumbDebugVarDump($value);
4087: }
4088: }
4089: if (isset($_POST) && is_array($_POST)) {
4090: foreach ($_POST as $key => $value) {
4091: $DebugOutput[] = '$_POST['.$key.']'.str_repeat(' ', 29 - strlen($key)).'= '.$this->phpThumbDebugVarDump($value);
4092: }
4093: }
4094: $DebugOutput[] = '';
4095:
4096: $DebugOutput[] = '$this->debugmessages:';
4097: foreach ($this->debugmessages as $errorstring) {
4098: $DebugOutput[] = ' * '.$errorstring;
4099: }
4100: $DebugOutput[] = '';
4101:
4102: $DebugOutput[] = '$this->debugtiming:';
4103: foreach ($this->debugtiming as $timestamp => $timingstring) {
4104: $DebugOutput[] = ' * '.$timestamp.' '.$timingstring;
4105: }
4106: $DebugOutput[] = ' * Total processing time: '.number_format(max(array_keys($this->debugtiming)) - min(array_keys($this->debugtiming)), 6);
4107:
4108: $this->f = (isset($_GET['f']) ? $_GET['f'] : $this->f);
4109: return $this->ErrorImage(implode("\n", $DebugOutput), 700, 500, true);
4110: }
4111:
4112: function FatalError($text) {
4113: if (is_null($this->fatalerror)) {
4114: $this->fatalerror = $text;
4115: }
4116: return true;
4117: }
4118:
4119: function ErrorImage($text, $width=0, $height=0, $forcedisplay=false) {
4120: $width = ($width ? $width : $this->config_error_image_width);
4121: $height = ($height ? $height : $this->config_error_image_height);
4122:
4123: $text = 'phpThumb() v'.$this->phpthumb_version."\n".'http://phpthumb.sourceforge.net'."\n\n".($this->config_disable_debug ? 'Error messages disabled.'."\n\n".'edit phpThumb.config.php and (temporarily) set'."\n".'$PHPTHUMB_CONFIG[\'disable_debug\'] = false;'."\n".'to view the details of this error' : $text);
4124:
4125: $this->FatalError($text);
4126: $this->DebugMessage($text, __FILE__, __LINE__);
4127: $this->purgeTempFiles();
4128: if ($this->config_error_silent_die_on_error) {
4129: exit;
4130: }
4131: if ($this->phpThumbDebug && !$forcedisplay) {
4132: return false;
4133: }
4134: if (!$this->config_error_die_on_error && !$forcedisplay) {
4135: return false;
4136: }
4137: if ($this->err || $this->config_error_message_image_default) {
4138:
4139:
4140: if (($this->err == 'showerror') || $this->phpThumbDebug) {
4141:
4142: } else {
4143: header('Location: '.($this->err ? $this->err : $this->config_error_message_image_default));
4144: exit;
4145: }
4146: }
4147: $this->setOutputFormat();
4148: if (!$this->thumbnailFormat || !$this->config_disable_debug || (phpthumb_functions::gd_version() < 1)) {
4149: $this->thumbnailFormat = 'text';
4150: }
4151: if (@$this->thumbnailFormat == 'text') {
4152:
4153: if (!headers_sent()) {
4154: header('Content-type: text/plain');
4155: echo $text;
4156: } else {
4157: echo '<pre>'.htmlspecialchars($text).'</pre>';
4158: }
4159: exit;
4160: }
4161:
4162: $FontWidth = imagefontwidth($this->config_error_fontsize);
4163: $FontHeight = imagefontheight($this->config_error_fontsize);
4164:
4165: $LinesOfText = explode("\n", @wordwrap($text, floor($width / $FontWidth), "\n", true));
4166: $height = max($height, count($LinesOfText) * $FontHeight);
4167:
4168: $headers_file = '';
4169: $headers_line = '';
4170: if (phpthumb_functions::version_compare_replacement(phpversion(), '4.3.0', '>=') && headers_sent($headers_file, $headers_line)) {
4171:
4172: 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>';
4173:
4174: } elseif (headers_sent()) {
4175:
4176: echo "\n".'**Headers already sent, dumping error message as text:**<br><pre>'."\n\n".$text."\n".'</pre>';
4177:
4178: } elseif ($gdimg_error = imagecreate($width, $height)) {
4179:
4180: $background_color = phpthumb_functions::ImageHexColorAllocate($gdimg_error, $this->config_error_bgcolor, true);
4181: $text_color = phpthumb_functions::ImageHexColorAllocate($gdimg_error, $this->config_error_textcolor, true);
4182: imagefilledrectangle($gdimg_error, 0, 0, $width, $height, $background_color);
4183: $lineYoffset = 0;
4184: foreach ($LinesOfText as $line) {
4185: imagestring($gdimg_error, $this->config_error_fontsize, 2, $lineYoffset, $line, $text_color);
4186: $lineYoffset += $FontHeight;
4187: }
4188: if (function_exists('imagetypes')) {
4189: $imagetypes = imagetypes();
4190: if ($imagetypes & IMG_PNG) {
4191: header('Content-Type: image/png');
4192: imagepng($gdimg_error);
4193: } elseif ($imagetypes & IMG_GIF) {
4194: header('Content-Type: image/gif');
4195: imagegif($gdimg_error);
4196: } elseif ($imagetypes & IMG_JPG) {
4197: header('Content-Type: image/jpeg');
4198: imagejpeg($gdimg_error);
4199: } elseif ($imagetypes & IMG_WBMP) {
4200: header('Content-Type: image/vnd.wap.wbmp');
4201: imagewbmp($gdimg_error);
4202: }
4203: }
4204: imagedestroy($gdimg_error);
4205:
4206: }
4207: if (!headers_sent()) {
4208: echo "\n".'**Failed to send graphical error image, dumping error message as text:**<br>'."\n\n".$text;
4209: }
4210: exit;
4211: }
4212:
4213: function ImageCreateFromStringReplacement(&$RawImageData, $DieOnErrors=false) {
4214:
4215:
4216:
4217: if (!phpthumb_functions::gd_version()) {
4218: if ($DieOnErrors) {
4219: if (!headers_sent()) {
4220:
4221: $ERROR_NOGD = 'R0lGODlhIAAgALMAAAAAABQUFCQkJDY2NkZGRldXV2ZmZnJycoaGhpSUlKWlpbe3t8XFxdXV1eTk5P7+/iwAAAAAIAAgAAAE/vDJSau9WILtTAACUinDNijZtAHfCojS4W5H+qxD8xibIDE9h0OwWaRWDIljJSkUJYsN4bihMB8th3IToAKs1VtYM75cyV8sZ8vygtOE5yMKmGbO4jRdICQCjHdlZzwzNW4qZSQmKDaNjhUMBX4BBAlmMywFSRWEmAI6b5gAlhNxokGhooAIK5o/pi9vEw4Lfj4OLTAUpj6IabMtCwlSFw0DCKBoFqwAB04AjI54PyZ+yY3TD0ss2YcVmN/gvpcu4TOyFivWqYJlbAHPpOntvxNAACcmGHjZzAZqzSzcq5fNjxFmAFw9iFRunD1epU6tsIPmFCAJnWYE0FURk7wJDA0MTKpEzoWAAskiAAA7';
4222: header('Content-Type: image/gif');
4223: echo base64_decode($ERROR_NOGD);
4224: } else {
4225: echo '*** ERROR: No PHP-GD support available ***';
4226: }
4227: exit;
4228: } else {
4229: $this->DebugMessage('ImageCreateFromStringReplacement() failed: gd_version says "'.phpthumb_functions::gd_version().'"', __FILE__, __LINE__);
4230: return false;
4231: }
4232: }
4233: if (phpthumb_functions::gd_is_bundled()) {
4234: $this->DebugMessage('ImageCreateFromStringReplacement() calling built-in imagecreatefromstring()', __FILE__, __LINE__);
4235: return @imagecreatefromstring($RawImageData);
4236: }
4237: if ($this->issafemode) {
4238: $this->DebugMessage('ImageCreateFromStringReplacement() failed: cannot create temp file in SAFE_MODE', __FILE__, __LINE__);
4239: return false;
4240: }
4241:
4242: switch (substr($RawImageData, 0, 3)) {
4243: case 'GIF':
4244: $ICFSreplacementFunctionName = 'imagecreatefromgif';
4245: break;
4246: case "\xFF\xD8\xFF":
4247: $ICFSreplacementFunctionName = 'imagecreatefromjpeg';
4248: break;
4249: case "\x89".'PN':
4250: $ICFSreplacementFunctionName = 'imagecreatefrompng';
4251: break;
4252: default:
4253: $this->DebugMessage('ImageCreateFromStringReplacement() failed: unknown fileformat signature "'.phpthumb_functions::HexCharDisplay(substr($RawImageData, 0, 3)).'"', __FILE__, __LINE__);
4254: return false;
4255: break;
4256: }
4257: $ErrorMessage = '';
4258: if ($tempnam = $this->phpThumb_tempnam()) {
4259: if ($fp_tempnam = @fopen($tempnam, 'wb')) {
4260: fwrite($fp_tempnam, $RawImageData);
4261: fclose($fp_tempnam);
4262: @chmod($tempnam, $this->getParameter('config_file_create_mask'));
4263: if (($ICFSreplacementFunctionName == 'imagecreatefromgif') && !function_exists($ICFSreplacementFunctionName)) {
4264:
4265:
4266: ob_start();
4267: if (!@include_once(dirname(__FILE__).'/phpthumb.gif.php')) {
4268: $ErrorMessage = 'Failed to include required file "'.dirname(__FILE__).'/phpthumb.gif.php" in '.__FILE__.' on line '.__LINE__;
4269: $this->DebugMessage($ErrorMessage, __FILE__, __LINE__);
4270: }
4271: ob_end_clean();
4272:
4273: if ($tempfilename = $this->phpThumb_tempnam()) {
4274: if ($fp_tempfile = @fopen($tempfilename, 'wb')) {
4275: fwrite($fp_tempfile, $RawImageData);
4276: fclose($fp_tempfile);
4277: $gdimg_source = gif_loadFileToGDimageResource($tempfilename);
4278: $this->DebugMessage('gif_loadFileToGDimageResource('.$tempfilename.') completed', __FILE__, __LINE__);
4279: $this->DebugMessage('deleting "'.$tempfilename.'"', __FILE__, __LINE__);
4280: unlink($tempfilename);
4281: return $gdimg_source;
4282: } else {
4283: $ErrorMessage = 'Failed to open tempfile in '.__FILE__.' on line '.__LINE__;
4284: $this->DebugMessage($ErrorMessage, __FILE__, __LINE__);
4285: }
4286: } else {
4287: $ErrorMessage = 'Failed to open generate tempfile name in '.__FILE__.' on line '.__LINE__;
4288: $this->DebugMessage($ErrorMessage, __FILE__, __LINE__);
4289: }
4290:
4291: } elseif (function_exists($ICFSreplacementFunctionName) && ($gdimg_source = @$ICFSreplacementFunctionName($tempnam))) {
4292:
4293:
4294: $this->DebugMessage($ICFSreplacementFunctionName.'('.$tempnam.') succeeded', __FILE__, __LINE__);
4295: $this->DebugMessage('deleting "'.$tempnam.'"', __FILE__, __LINE__);
4296: unlink($tempnam);
4297: return $gdimg_source;
4298:
4299: } else {
4300:
4301:
4302: $this->DebugMessage($ICFSreplacementFunctionName.'('.$tempnam.') '.(function_exists($ICFSreplacementFunctionName) ? 'failed' : 'does not exist'), __FILE__, __LINE__);
4303: if (isset($_GET['phpThumbDebug'])) {
4304: $this->phpThumbDebug();
4305: }
4306:
4307: }
4308: } else {
4309: $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';
4310: if ($this->issafemode) {
4311: $ErrorMessage = 'ImageCreateFromStringReplacement() failed in '.__FILE__.' on line '.__LINE__.': cannot create temp file in SAFE_MODE';
4312: }
4313: $this->DebugMessage($ErrorMessage, __FILE__, __LINE__);
4314: }
4315: $this->DebugMessage('deleting "'.$tempnam.'"', __FILE__, __LINE__);
4316: @unlink($tempnam);
4317: } else {
4318: $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';
4319: if ($this->issafemode) {
4320: $ErrorMessage = 'ImageCreateFromStringReplacement() failed in '.__FILE__.' on line '.__LINE__.': cannot create temp file in SAFE_MODE';
4321: }
4322: }
4323: if ($DieOnErrors && $ErrorMessage) {
4324: return $this->ErrorImage($ErrorMessage);
4325: }
4326: return false;
4327: }
4328:
4329: function ImageResizeFunction(&$dst_im, &$src_im, $dstX, $dstY, $srcX, $srcY, $dstW, $dstH, $srcW, $srcH) {
4330: $this->DebugMessage('ImageResizeFunction($o, $s, '.$dstX.', '.$dstY.', '.$srcX.', '.$srcY.', '.$dstW.', '.$dstH.', '.$srcW.', '.$srcH.')', __FILE__, __LINE__);
4331: if (($dstW == $srcW) && ($dstH == $srcH)) {
4332: return imagecopy($dst_im, $src_im, $dstX, $dstY, $srcX, $srcY, $srcW, $srcH);
4333: }
4334: if (phpthumb_functions::gd_version() >= 2.0) {
4335: if ($this->config_disable_imagecopyresampled) {
4336: return phpthumb_functions::ImageCopyResampleBicubic($dst_im, $src_im, $dstX, $dstY, $srcX, $srcY, $dstW, $dstH, $srcW, $srcH);
4337: }
4338: return imagecopyresampled($dst_im, $src_im, $dstX, $dstY, $srcX, $srcY, $dstW, $dstH, $srcW, $srcH);
4339: }
4340: return imagecopyresized($dst_im, $src_im, $dstX, $dstY, $srcX, $srcY, $dstW, $dstH, $srcW, $srcH);
4341: }
4342:
4343: function InitializeTempDirSetting() {
4344: $this->config_temp_directory = ($this->config_temp_directory ? $this->config_temp_directory : (function_exists('sys_get_temp_dir') ? sys_get_temp_dir() : ''));
4345: $this->config_temp_directory = ($this->config_temp_directory ? $this->config_temp_directory : getenv('TMPDIR'));
4346: $this->config_temp_directory = ($this->config_temp_directory ? $this->config_temp_directory : getenv('TMP'));
4347: $this->config_temp_directory = ($this->config_temp_directory ? $this->config_temp_directory : ini_get('upload_tmp_dir'));
4348: $this->config_temp_directory = $this->realPathSafe($this->config_temp_directory);
4349: return true;
4350: }
4351:
4352: function phpThumb_tempnam() {
4353: $this->InitializeTempDirSetting();
4354: $tempnam = $this->realPathSafe(tempnam($this->config_temp_directory, 'pThumb'));
4355: $this->tempFilesToDelete[$tempnam] = $tempnam;
4356: $this->DebugMessage('phpThumb_tempnam() returning "'.$tempnam.'"', __FILE__, __LINE__);
4357: return $tempnam;
4358: }
4359:
4360: function DebugMessage($message, $file='', $line='') {
4361: $this->debugmessages[] = $message.($file ? ' in file "'.(basename($file) ? basename($file) : $file).'"' : '').($line ? ' on line '.$line : '');
4362: return true;
4363: }
4364:
4365: function DebugTimingMessage($message, $file='', $line='', $timestamp=0) {
4366: if (!$timestamp) {
4367: $timestamp = array_sum(explode(' ', microtime()));
4368: }
4369: $this->debugtiming[number_format($timestamp, 6, '.', '')] = ': '.$message.($file ? ' in file "'.(basename($file) ? basename($file) : $file).'"' : '').($line ? ' on line '.$line : '');
4370: return true;
4371: }
4372:
4373: }
4374: