Thumbnail sharp tool timthumb.php detailed comments on source code

Blog News five thousand three hundred and sixty-four

Timthumb.php is a very popular tool for cutting pictures to generate thumbnails. This thumbnail tool only has a file named timthumb.php, and this file only has a timthumb class, but it is very powerful, and is widely used in php websites as a thumbnail plug-in. Many people know that timthumb.php also knows how to use it, but many people may not know the source code of this file, so the blog has reprinted an article about the detailed source code of timthumb.php from OSChina to share with you for reference.

Tutorial for WordPress using timthumb.php: https://www.boke8.net/wordpress-timthumb-php-thumbnail.html

The commented file code is as follows:

There are many codes (more than 2000 lines), so they are divided into several parts:

 one two three four five six seven eight nine ten eleven twelve thirteen fourteen fifteen sixteen seventeen eighteen nineteen twenty twenty-one twenty-two twenty-three twenty-four twenty-five twenty-six twenty-seven twenty-eight twenty-nine thirty thirty-one thirty-two thirty-three thirty-four thirty-five thirty-six thirty-seven thirty-eight thirty-nine forty forty-one forty-two forty-three forty-four forty-five forty-six forty-seven forty-eight forty-nine fifty fifty-one fifty-two fifty-three fifty-four fifty-five fifty-six fifty-seven fifty-eight fifty-nine sixty sixty-one sixty-two sixty-three sixty-four sixty-five sixty-six sixty-seven sixty-eight sixty-nine seventy seventy-one seventy-two seventy-three seventy-four seventy-five seventy-six seventy-seven seventy-eight seventy-nine eighty eighty-one eighty-two eighty-three eighty-four eighty-five eighty-six eighty-seven eighty-eight eighty-nine ninety ninety-one ninety-two ninety-three ninety-four ninety-five ninety-six ninety-seven ninety-eight ninety-nine one hundred one hundred and one one hundred and two one hundred and three one hundred and four one hundred and five one hundred and six one hundred and seven one hundred and eight one hundred and nine one hundred and ten one hundred and eleven one hundred and twelve one hundred and thirteen one hundred and fourteen one hundred and fifteen one hundred and sixteen one hundred and seventeen one hundred and eighteen one hundred and nineteen one hundred and twenty one hundred and twenty-one one hundred and twenty-two one hundred and twenty-three one hundred and twenty-four one hundred and twenty-five one hundred and twenty-six one hundred and twenty-seven one hundred and twenty-eight one hundred and twenty-nine one hundred and thirty one hundred and thirty-one one hundred and thirty-two one hundred and thirty-three one hundred and thirty-four one hundred and thirty-five one hundred and thirty-six one hundred and thirty-seven one hundred and thirty-eight one hundred and thirty-nine one hundred and forty one hundred and forty-one one hundred and forty-two one hundred and forty-three one hundred and forty-four one hundred and forty-five one hundred and forty-six one hundred and forty-seven one hundred and forty-eight one hundred and forty-nine one hundred and fifty one hundred and fifty-one one hundred and fifty-two one hundred and fifty-three one hundred and fifty-four one hundred and fifty-five one hundred and fifty-six one hundred and fifty-seven one hundred and fifty-eight one hundred and fifty-nine one hundred and sixty one hundred and sixty-one one hundred and sixty-two one hundred and sixty-three one hundred and sixty-four one hundred and sixty-five one hundred and sixty-six one hundred and sixty-seven one hundred and sixty-eight one hundred and sixty-nine one hundred and seventy one hundred and seventy-one one hundred and seventy-two one hundred and seventy-three one hundred and seventy-four one hundred and seventy-five one hundred and seventy-six one hundred and seventy-seven one hundred and seventy-eight one hundred and seventy-nine one hundred and eighty one hundred and eighty-one one hundred and eighty-two one hundred and eighty-three one hundred and eighty-four one hundred and eighty-five one hundred and eighty-six one hundred and eighty-seven one hundred and eighty-eight one hundred and eighty-nine one hundred and ninety one hundred and ninety-one one hundred and ninety-two one hundred and ninety-three one hundred and ninety-four one hundred and ninety-five one hundred and ninety-six one hundred and ninety-seven one hundred and ninety-eight one hundred and ninety-nine two hundred two hundred and one two hundred and two two hundred and three two hundred and four two hundred and five two hundred and six two hundred and seven two hundred and eight two hundred and nine two hundred and ten two hundred and eleven two hundred and twelve two hundred and thirteen two hundred and fourteen two hundred and fifteen two hundred and sixteen two hundred and seventeen two hundred and eighteen two hundred and nineteen two hundred and twenty two hundred and twenty-one two hundred and twenty-two two hundred and twenty-three two hundred and twenty-four two hundred and twenty-five two hundred and twenty-six two hundred and twenty-seven two hundred and twenty-eight two hundred and twenty-nine two hundred and thirty two hundred and thirty-one two hundred and thirty-two two hundred and thirty-three two hundred and thirty-four two hundred and thirty-five two hundred and thirty-six two hundred and thirty-seven two hundred and thirty-eight two hundred and thirty-nine two hundred and forty two hundred and forty-one two hundred and forty-two two hundred and forty-three two hundred and forty-four two hundred and forty-five two hundred and forty-six two hundred and forty-seven two hundred and forty-eight two hundred and forty-nine two hundred and fifty two hundred and fifty-one two hundred and fifty-two two hundred and fifty-three two hundred and fifty-four two hundred and fifty-five two hundred and fifty-six two hundred and fifty-seven two hundred and fifty-eight two hundred and fifty-nine two hundred and sixty two hundred and sixty-one two hundred and sixty-two two hundred and sixty-three two hundred and sixty-four two hundred and sixty-five two hundred and sixty-six two hundred and sixty-seven two hundred and sixty-eight two hundred and sixty-nine two hundred and seventy two hundred and seventy-one two hundred and seventy-two two hundred and seventy-three two hundred and seventy-four two hundred and seventy-five two hundred and seventy-six two hundred and seventy-seven two hundred and seventy-eight two hundred and seventy-nine two hundred and eighty two hundred and eighty-one two hundred and eighty-two
 <? php
 //Define version information
 define  ( 'VERSION' ,  '2.8.10' ) ;
 //If there is a configuration file, load timthumb-config.php. If not, use the following values
 if (  file_exists ( dirname ( __FILE__ )  .  '/timthumb-config.php' ) ) {
   require_once ( 'timthumb-config.php' ) ;
 }
 //Debug logs are recorded in web server logs
 if ( !  defined ( 'DEBUG_ON' )  ) {
   define  ( 'DEBUG_ON' ,  false ) ;
 }
 //Debugging level. Levels higher than this value will not be recorded. 1 is the lowest and 3 is the highest
 if ( !  defined ( 'DEBUG_LEVEL' )  ) {
   define  ( 'DEBUG_LEVEL' ,  one ) ;
 }
 //Maximum memory limit 30M
 if ( !  defined ( 'MEMORY_LIMIT' )  ) {
   define  ( 'MEMORY_LIMIT' ,  '30M' ) ;
 }
 //Close the pirate chain
 if ( !  defined ( 'BLOCK_EXTERNAL_LEECHERS' )  ) {
   define  ( 'BLOCK_EXTERNAL_LEECHERS' ,  false ) ;
 } 					
 //Allow getting pictures from outside
 if ( !  defined ( 'ALLOW_EXTERNAL' )  ) {
   define  ( 'ALLOW_EXTERNAL' ,  TRUE ) ;
 }
 //Allow getting all external site urls
 if ( !  defined ( 'ALLOW_ALL_EXTERNAL_SITES' )  ) {
   define  ( 'ALLOW_ALL_EXTERNAL_SITES' ,  false ) ;
 }
 //Enable file caching
 if ( !  defined ( 'FILE_CACHE_ENABLED' )  ) {
   define  ( 'FILE_CACHE_ENABLED' ,  TRUE ) ;
 }
 //File cache update time, s
 if ( !  defined ( 'FILE_CACHE_TIME_BETWEEN_CLEANS' ) ) {
   define  ( 'FILE_CACHE_TIME_BETWEEN_CLEANS' ,  eighty-six thousand and four hundred ) ;
 }
 //File cache lifetime, s, after which the cache file will be deleted
 if ( !  defined ( 'FILE_CACHE_MAX_FILE_AGE' )  ) {
   define  ( 'FILE_CACHE_MAX_FILE_AGE' ,  eighty-six thousand and four hundred ) ;
 }
 //Cache File Suffix
 if ( !  defined ( 'FILE_CACHE_SUFFIX' )  ) {
   define  ( 'FILE_CACHE_SUFFIX' ,  '.timthumb.txt' ) ;
 }
 //Cache file prefix
 if ( !  defined ( 'FILE_CACHE_PREFIX' )  ) {
   define  ( 'FILE_CACHE_PREFIX' ,  'timthumb' ) ;
 }
 //Cache file directory. If left blank, use the system temporary directory (recommended)
 if ( !  defined ( 'FILE_CACHE_DIRECTORY' )  ) {
   define  ( 'FILE_CACHE_DIRECTORY' ,  './ cache' ) ;
 }
 //The maximum size of an image. This script can process 10485760 bytes of images at most, that is, 10M
 if ( !  defined ( 'MAX_FILE_SIZE' )  ) {
   define  ( 'MAX_FILE_SIZE' ,  ten million four hundred and eighty-five thousand seven hundred and sixty ) ;
 }  
 //Timeout of CURL
 if ( !  defined ( 'CURL_TIMEOUT' )  ) {
   define  ( 'CURL_TIMEOUT' ,  twenty ) ;
 }
 //Time to clean the error cache
 if ( !  defined ( 'WAIT_BETWEEN_FETCH_ERRORS' )  ) {
   define  ( 'WAIT_BETWEEN_FETCH_ERRORS' ,  three thousand and six hundred ) ;
 }
 //Browser cache time
 if ( !  defined ( 'BROWSER_CACHE_MAX_AGE' )  ) {
   define  ( 'BROWSER_CACHE_MAX_AGE' ,  eight hundred and sixty-four thousand ) ;
 }
 //Turn off all browser caches
 if ( !  defined ( 'BROWSER_CACHE_DISABLE' )  ) {
   define  ( 'BROWSER_CACHE_DISABLE' ,  false ) ;
 }
 //Maximum image width
 if ( !  defined ( 'MAX_WIDTH' )  ) {
   define  ( 'MAX_WIDTH' ,  one thousand and five hundred ) ;
 }
 //Maximum image height
 if ( !  defined ( 'MAX_HEIGHT' )  ) {
   define  ( 'MAX_HEIGHT' ,  one thousand and five hundred ) ;
 }
 //404 The address of the prompt picture displayed in case of error. Setting the measured value will not display specific error information
 if ( !  defined ( 'NOT_FOUND_IMAGE' )  ) {
   define  ( 'NOT_FOUND_IMAGE' ,  '' ) ;
 }
 //Address of prompt picture displayed in case of other errors. Setting the measured value will not display specific error information
 if ( !  defined ( 'ERROR_IMAGE' )  ) {
   define  ( 'ERROR_IMAGE' ,  '' ) ;
 }
 //PNG picture background color, use false to represent transparency
 if ( !  defined ( 'PNG_IS_TRANSPARENT' )  ) {
   define  ( 'PNG_IS_TRANSPARENT' ,  FALSE ) ;
 }
 //Default picture quality
 if ( !  defined ( 'DEFAULT_Q' )  ) {
   define  ( 'DEFAULT_Q' ,  ninety ) ;
 }
 //Default zoom/clipping mode: 0: scale according to the incoming value (no clipping), 1: clip and resize at the most appropriate scale (clipping), 2: resize proportionally and add a border (clipping), 2: resize proportionally and do not add a border (clipping)
 if ( !  defined ( 'DEFAULT_ZC' )  ) {
   define  ( 'DEFAULT_ZC' ,  one ) ;
 }
 //By default, the image processing operation is required. For optional values and parameter formats, please refer to the notes of $filters and $imageFilters in the processImageAndWriteToCache function
 if ( !  defined ( 'DEFAULT_F' )  ) {
   define  ( 'DEFAULT_F' ,  '' ) ;
 }
 //Whether to sharpen the picture
 if ( !  defined ( 'DEFAULT_S' )  ) {
   define  ( 'DEFAULT_S' ,  zero ) ;
 }
 //Default Canvas Color
 if ( !  defined ( 'DEFAULT_CC' )  ) {
   define  ( 'DEFAULT_CC' ,  'ffffff' ) ;
 }
 //The following is the image compression settings, provided that your host has two tools, optimpng or pngcrush. Otherwise, this function will not be enabled
 //This function is only valid for png pictures
 if ( !  defined ( 'OPTIPNG_ENABLED' )  ) {
   define  ( 'OPTIPNG_ENABLED' ,  false ) ;
 }  
 if ( !  defined ( 'OPTIPNG_PATH' )  ) {
   define  ( 'OPTIPNG_PATH' ,  '/usr/bin/optipng' ) ;
 }  //Optipng is preferred because of better compression ratio
 if ( !  defined ( 'PNGCRUSH_ENABLED' )  ) {
   define  ( 'PNGCRUSH_ENABLED' ,  false ) ;
 } 
 if ( !  defined ( 'PNGCRUSH_PATH' )  ) {
   define  ( 'PNGCRUSH_PATH' ,  '/usr/bin/pngcrush' ) ;
 }  //If optipng does not exist, use pngcrush
 //End of picture compression setting     /*  ** The following is the website screenshot configuration *First, the website screenshot requires root permission *Steps for using website screenshots on Ubuntu: *1. Use this command to install Xvfb sudo apt-get install subversion libqt4-webkit libqt4-dev g++ xvfb *2. Create a new folder and download the following source code *3. Use this command to download the latest CutyCap svn co https://cutycapt.svn.sourceforge.net/svnroot/cutycapt *4. Enter the CutyCap folder *5. Compile and install CutyCap *6. Try running the following command: xvfb run -- server args="- screen 0, 1024x768x24" CutyCap -- url=“ http://markmaunder.com/ " --out=test.png *7. If a test.php image is generated, it proves that everything is normal. Now try using the browser to access the following address: http://yoursite.com/path/to/timthumb.php?src=http://markmaunder.com/&webshot=1 * *Attention: *1. When the webshot is loaded for the first time, it takes several seconds, and then it will load quickly * *Advanced users: *1. If you want to speed up by about 25% and you know Linux, you can run the following command: *   nohup Xvfb :100 -ac -nolisten tcp -screen 0, 1024x768x24 > /dev/null 2>&1 & *And set WEBSHOT_XVFB_RUNNING to true * * */
 //Test function. If this value is set to true and webshot=1 is added to the query string, the script will return the screenshot of the browser instead of acquiring the image
 if ( !  defined ( 'WEBSHOT_ENABLED' )  ) {
   define  ( 'WEBSHOT_ENABLED' ,  false ) ;
 }
 //Define CutyCap address
 if ( !  defined ( 'WEBSHOT_CUTYCAPT' )  ) {
   define  ( 'WEBSHOT_CUTYCAPT' ,  '/usr/local/bin/CutyCapt' ) ;
 }
 //Xvfb address
 if ( !  defined ( 'WEBSHOT_XVFB' )  ) {
   define  ( 'WEBSHOT_XVFB' ,  '/usr/bin/xvfb-run' ) ;
 }
 //Screenshot width 1024
 if ( !  defined ( 'WEBSHOT_SCREEN_X' )  ) {
   define  ( 'WEBSHOT_SCREEN_X' ,  '1024' ) ;
 }
 //Screenshot screen height 768
 if ( !  defined ( 'WEBSHOT_SCREEN_Y' )  ) {
   define  ( 'WEBSHOT_SCREEN_Y' ,  '768' ) ;
 }
 //Color deep, the author said he only tested 24
 if ( !  defined ( 'WEBSHOT_COLOR_DEPTH' )  ) {
   define  ( 'WEBSHOT_COLOR_DEPTH' ,  '24' ) ;	
 }
 //Screenshot format
 if ( !  defined ( 'WEBSHOT_IMAGE_FORMAT' )  ) {
   define  ( 'WEBSHOT_IMAGE_FORMAT' ,  'png' ) ;
 }
 //Screenshot timeout, unit s
 if ( !  defined ( 'WEBSHOT_TIMEOUT' )  ) {
   define  ( 'WEBSHOT_TIMEOUT' ,  '20' ) ;
 }
 //User_agent header
 if ( !  defined ( 'WEBSHOT_USER_AGENT' )  ) {
   define  ( 'WEBSHOT_USER_AGENT' ,  "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-GB; rv:1.9.2.18) Gecko/20110614 Firefox/3.6.18" ) ;
 }
 //Enable JS
 if ( !  defined ( 'WEBSHOT_JAVASCRIPT_ON' )  ) {
   define  ( 'WEBSHOT_JAVASCRIPT_ON' ,  true ) ;
 }
 //Enable java
 if ( !  defined ( 'WEBSHOT_JAVA_ON' )  ) {
   define  ( 'WEBSHOT_JAVA_ON' ,  false ) ;
 }
 //Open flash and other plug-ins
 if ( !  defined ( 'WEBSHOT_PLUGINS_ON' )  ) {
   define  ( 'WEBSHOT_PLUGINS_ON' ,  true ) ;
 }
 //Proxy server
 if ( !  defined ( 'WEBSHOT_PROXY' )  ) {
   define  ( 'WEBSHOT_PROXY' ,  '' ) ;	
 }
 //If XVFB is run, set this to true
 if ( !  defined ( 'WEBSHOT_XVFB_RUNNING' )  ) {
   define  ( 'WEBSHOT_XVFB_RUNNING' ,  false ) ;
 }
 //If the value of ALLOW_EXTERNAL is true and the value of ALLOW_ALL_EXTERNAL_SITES is false, the screenshots can only be taken from the fields and sub fields in the following arrays
 if ( !  isset ( $ALLOWED_SITES ) ) {
   $ALLOWED_SITES  =  array  (
     'flickr.com' ,
     'staticflickr.com' ,
     'picasa.com' ,
     'img.youtube.com' ,
     'upload.wikimedia.org' ,
     'photobucket.com' ,
     'imgur.com' ,
     'imageshack.us' ,
     'tinypic.com' ,
   ) ;
 }
 /*End of screenshot configuration*/   // -------------------------------------------------------------
 //------------------------ End of configuration------------------------
 // -------------------------------------------------------------   timthumb :: start ( ) ;   class timthumb {
	 protected  $src  =  "" ;   //The image url to be obtained
	 protected  $is404  =  false ;   //404 error code
	 protected  $docRoot  =  "" ;   //Server Document Root
	 protected  $lastURLError  =  false ;  //Error information of the last request for external url
	 protected  $localImage  =  "" ;  //If the requested url is a local image, it is the address of the local image
	 protected  $localImageMTime  =  zero ;   //Modification time of local picture
	 protected  $url  =  false ;   //Parse the src array with parse_url
         protected  $myHost  =  "" ;   //Local domain name
	 protected  $isURL  =  false ;   //Whether it is an external picture address
	 protected  $cachefile  =  '' ;  //Cache file address
	 protected  $errors  =  array ( ) ;   //Error Message List
	 protected  $toDeletes  =  array ( ) ;  //List of resources to be deleted in the destructor
	 protected  $cacheDirectory  =  '' ;  //Cache address
	 protected  $startTime  =  zero ;   //Start time
	 protected  $lastBenchTime  =  zero ;  //Time of last debug completion
	 protected  $cropTop  =  false ;   //Enable Cropping
	 protected  $salt  =  "" ;   //File modification time and salt value of inode connected string
	 protected  $fileCacheVersion  =  one ;  //File cache version. When this class is upgraded or changed, this value should be changed to regenerate the cache
	 protected  $filePrependSecurityBlock  =  "<?php die('Execution denied!'); // " ;  //Cache file security header to prevent direct access
	 protected static $curlDataWritten  =  zero ;   //The length of writing the data obtained by curl to the cache file
	 protected static $curlFH  =  false ;   //After the curl request succeeds, the obtained data should be written to this file
	 /*External call interface*/
	 public static function start ( ) {
	  	 //Instantiated model
	  	 $tim  =  new timthumb ( ) ;
		 //Check whether there are errors when instantiating the model
		 $tim -> handleErrors ( ) ;
		 //This function is empty and is used for user-defined data verification
		 $tim -> securityChecks ( ) ;
		 //Attempt to read browser cache
		 if ( $tim -> tryBrowserCache ( ) ) {
		  	 //Output cache if successful
			 exit ( zero ) ;
		 }
		 //Detection error
		 $tim -> handleErrors ( ) ;
		 //If file caching is enabled and the server cache is read
		 if ( FILE_CACHE_ENABLED &&  $tim -> tryServerCache ( ) ) {
		  	 //Output cache if successful
			 exit ( zero ) ;
		 }
		 //Detect the error when reading the server cache
		 $tim -> handleErrors ( ) ;
		 //Generate and Process Picture Main Functions
		 $tim -> run ( ) ;
		 //Detect errors in image generation and processing
		 $tim -> handleErrors ( ) ;
		 //Run the destructor and exit after the program finishes executing
		 exit ( zero ) ;
	 }
 one two three four five six seven eight nine ten eleven twelve thirteen fourteen fifteen sixteen seventeen eighteen nineteen twenty twenty-one twenty-two twenty-three twenty-four twenty-five twenty-six twenty-seven twenty-eight twenty-nine thirty thirty-one thirty-two thirty-three thirty-four thirty-five thirty-six thirty-seven thirty-eight thirty-nine forty forty-one forty-two forty-three forty-four forty-five forty-six forty-seven forty-eight forty-nine fifty fifty-one fifty-two fifty-three fifty-four fifty-five fifty-six fifty-seven fifty-eight fifty-nine sixty sixty-one sixty-two sixty-three sixty-four sixty-five sixty-six sixty-seven sixty-eight sixty-nine seventy seventy-one seventy-two seventy-three seventy-four seventy-five seventy-six seventy-seven seventy-eight seventy-nine eighty eighty-one eighty-two eighty-three eighty-four eighty-five eighty-six eighty-seven eighty-eight eighty-nine ninety ninety-one ninety-two ninety-three ninety-four ninety-five ninety-six ninety-seven ninety-eight ninety-nine one hundred one hundred and one one hundred and two one hundred and three one hundred and four one hundred and five one hundred and six one hundred and seven one hundred and eight one hundred and nine one hundred and ten one hundred and eleven one hundred and twelve one hundred and thirteen one hundred and fourteen one hundred and fifteen one hundred and sixteen one hundred and seventeen one hundred and eighteen one hundred and nineteen one hundred and twenty one hundred and twenty-one one hundred and twenty-two one hundred and twenty-three one hundred and twenty-four one hundred and twenty-five one hundred and twenty-six one hundred and twenty-seven one hundred and twenty-eight one hundred and twenty-nine one hundred and thirty one hundred and thirty-one one hundred and thirty-two one hundred and thirty-three one hundred and thirty-four one hundred and thirty-five one hundred and thirty-six one hundred and thirty-seven one hundred and thirty-eight one hundred and thirty-nine one hundred and forty one hundred and forty-one one hundred and forty-two one hundred and forty-three one hundred and forty-four one hundred and forty-five one hundred and forty-six one hundred and forty-seven one hundred and forty-eight one hundred and forty-nine one hundred and fifty one hundred and fifty-one one hundred and fifty-two one hundred and fifty-three one hundred and fifty-four one hundred and fifty-five one hundred and fifty-six one hundred and fifty-seven one hundred and fifty-eight one hundred and fifty-nine one hundred and sixty one hundred and sixty-one one hundred and sixty-two one hundred and sixty-three one hundred and sixty-four one hundred and sixty-five one hundred and sixty-six one hundred and sixty-seven one hundred and sixty-eight one hundred and sixty-nine one hundred and seventy one hundred and seventy-one one hundred and seventy-two one hundred and seventy-three one hundred and seventy-four one hundred and seventy-five one hundred and seventy-six one hundred and seventy-seven one hundred and seventy-eight one hundred and seventy-nine one hundred and eighty one hundred and eighty-one one hundred and eighty-two one hundred and eighty-three one hundred and eighty-four one hundred and eighty-five one hundred and eighty-six one hundred and eighty-seven one hundred and eighty-eight one hundred and eighty-nine one hundred and ninety one hundred and ninety-one one hundred and ninety-two one hundred and ninety-three one hundred and ninety-four one hundred and ninety-five one hundred and ninety-six one hundred and ninety-seven one hundred and ninety-eight one hundred and ninety-nine two hundred two hundred and one two hundred and two two hundred and three two hundred and four two hundred and five two hundred and six two hundred and seven two hundred and eight two hundred and nine two hundred and ten two hundred and eleven two hundred and twelve two hundred and thirteen two hundred and fourteen two hundred and fifteen two hundred and sixteen two hundred and seventeen two hundred and eighteen two hundred and nineteen two hundred and twenty two hundred and twenty-one two hundred and twenty-two two hundred and twenty-three two hundred and twenty-four two hundred and twenty-five two hundred and twenty-six two hundred and twenty-seven two hundred and twenty-eight two hundred and twenty-nine two hundred and thirty two hundred and thirty-one two hundred and thirty-two two hundred and thirty-three two hundred and thirty-four two hundred and thirty-five two hundred and thirty-six two hundred and thirty-seven two hundred and thirty-eight two hundred and thirty-nine two hundred and forty two hundred and forty-one two hundred and forty-two two hundred and forty-three two hundred and forty-four two hundred and forty-five two hundred and forty-six two hundred and forty-seven two hundred and forty-eight two hundred and forty-nine two hundred and fifty two hundred and fifty-one two hundred and fifty-two two hundred and fifty-three two hundred and fifty-four two hundred and fifty-five two hundred and fifty-six two hundred and fifty-seven two hundred and fifty-eight two hundred and fifty-nine two hundred and sixty two hundred and sixty-one two hundred and sixty-two two hundred and sixty-three two hundred and sixty-four two hundred and sixty-five two hundred and sixty-six two hundred and sixty-seven two hundred and sixty-eight two hundred and sixty-nine two hundred and seventy two hundred and seventy-one two hundred and seventy-two two hundred and seventy-three two hundred and seventy-four two hundred and seventy-five two hundred and seventy-six two hundred and seventy-seven two hundred and seventy-eight two hundred and seventy-nine two hundred and eighty two hundred and eighty-one two hundred and eighty-two two hundred and eighty-three two hundred and eighty-four two hundred and eighty-five two hundred and eighty-six two hundred and eighty-seven two hundred and eighty-eight two hundred and eighty-nine two hundred and ninety two hundred and ninety-one two hundred and ninety-two two hundred and ninety-three two hundred and ninety-four two hundred and ninety-five two hundred and ninety-six two hundred and ninety-seven two hundred and ninety-eight two hundred and ninety-nine three hundred three hundred and one three hundred and two three hundred and three three hundred and four three hundred and five three hundred and six three hundred and seven three hundred and eight three hundred and nine three hundred and ten three hundred and eleven three hundred and twelve three hundred and thirteen three hundred and fourteen three hundred and fifteen three hundred and sixteen three hundred and seventeen three hundred and eighteen three hundred and nineteen three hundred and twenty three hundred and twenty-one three hundred and twenty-two three hundred and twenty-three three hundred and twenty-four three hundred and twenty-five three hundred and twenty-six three hundred and twenty-seven three hundred and twenty-eight three hundred and twenty-nine three hundred and thirty three hundred and thirty-one three hundred and thirty-two three hundred and thirty-three three hundred and thirty-four three hundred and thirty-five three hundred and thirty-six three hundred and thirty-seven three hundred and thirty-eight three hundred and thirty-nine three hundred and forty three hundred and forty-one three hundred and forty-two three hundred and forty-three three hundred and forty-four three hundred and forty-five three hundred and forty-six three hundred and forty-seven three hundred and forty-eight three hundred and forty-nine three hundred and fifty three hundred and fifty-one three hundred and fifty-two three hundred and fifty-three three hundred and fifty-four three hundred and fifty-five three hundred and fifty-six three hundred and fifty-seven three hundred and fifty-eight three hundred and fifty-nine three hundred and sixty three hundred and sixty-one three hundred and sixty-two three hundred and sixty-three three hundred and sixty-four three hundred and sixty-five three hundred and sixty-six three hundred and sixty-seven
 /*Construction method, used to obtain and set some basic properties*/
	 public  function __construct ( ) {
	  	 //Set allowed fields as global variables
	  	 global  $ALLOWED_SITES ;
		 //Record start time
		 $this -> startTime  =  microtime ( true ) ;
		 //Set Time Zone
		 date_default_timezone_set ( 'UTC' ) ;
		 //Write a log to record the request IP and request URL
		 $this -> debug ( one ,  "Starting new request from "  .  $this -> getIP ( )  .  " to "  .  $_SERVER [ 'REQUEST_URI' ] ) ;
		 //Get server document root directory
		 $this -> calcDocRoot ( ) ;
		 //Get the file modification time and inode. The inode is only valid in the Linux system
		 $this -> salt  =  @ filemtime ( __FILE__ )  .  '-'  .  @ fileinode ( __FILE__ ) ;
		 //Record salt information, level 3
		 $this -> debug ( three ,  "Salt is: "  .  $this -> salt ) ;
		 //If the cache file address is defined
		 if ( FILE_CACHE_DIRECTORY ) {
		  	 //If this address does not exist or is not a directory
		  	 if ( !  is_dir ( FILE_CACHE_DIRECTORY ) ) {
		    		 //Create this directory
			  	 @ mkdir ( FILE_CACHE_DIRECTORY ) ;
				 //If the establishment fails
				 if ( !  is_dir ( FILE_CACHE_DIRECTORY ) ) {
				  	 //Record error information and stop execution
					 $this -> error ( "Could not create the file cache directory." ) ;
					 return  false ;
				 }
			 }
			 //Write cache address to member property
			 $this -> cacheDirectory  = FILE_CACHE_DIRECTORY ;
			 //Create an index.html file in the cache directory to prevent directories from being listed
			 if  ( ! touch ( $this -> cacheDirectory  .  '/index.html' ) )  {
			  	 //If an error occurs, record the error message
				 $this -> error ( "Could not create the index.html file - to fix this create an empty file named index.html file in the cache directory." ) ;
			 }
		 //If the cache file address is not defined, use the temporary file directory of the system as the cache file directory
		 }  else  {
			 $this -> cacheDirectory  =  sys_get_temp_dir ( ) ;
		 }
		 //Check the cache and clear the expired cache
		 $this -> cleanCache ( ) ;
		 //Record local domain name
		 $this -> myHost  =  preg_replace ( '/^www\./ i' ,  '' ,  $_SERVER [ 'HTTP_HOST' ] ) ;
		 //Get the image address, which should be passed by the src parameter in $_GET
		 $this -> src  =  $this -> param ( 'src' ) ;
		 //This array is the result of parsing src, including one or more values of scheme, host, port, user, pass, path, query, and fragment
		 $this -> url  =  parse_url ( $this -> src ) ;
		 //If the image address is local, delete the local domain name in the image url
		 $this -> src  =  preg_replace ( '/https?:\/\/ (?:www\.)?'  .  $this -> myHost  .  '/i' ,  '' ,  $this -> src ) ;
		 //If the length of the picture address is less than 3, it is an invalid address
		 if ( strlen ( $this -> src )  <=  three ) {
		  	 //Add error message
			 $this -> error ( "No image specified" ) ;
			 return  false ;
		 }
		 //If the anti-theft chain is enabled and there is a source address, that is, the HTTP_REFERER header, and the source address is not the local machine, then the anti-theft chain processing is performed
		 if ( BLOCK_EXTERNAL_LEECHERS &&  array_key_exists ( 'HTTP_REFERER' ,  $_SERVER )  &&  ( !  preg_match ( '/^https?:\/\/ (?:www\.)?'  .  $this -> myHost  .  '(?:$|\/)/i' ,  $_SERVER [ 'HTTP_REFERER' ] ) ) ) {
			 //This base64 encoded content is a picture showing No Hotlinking
		  	 $imgData  =  base64_decode ( "R0lGODlhUAAMAIAAAP8AAP///yH5BAAHAP8ALAAAAABQAAwAAAJpjI+py+0Po5y0OgAMjjv01YUZ \n OGplhWXfNa6JCLnWkXplrcBmW+spbwvaVr/cDyg7IoFC2KbYVC2NQ5MQ4ZNao9Ynzjl9ScNYpneb \n DULB3RP6JuPuaGfuuV4fumf8PuvqFyhYtjdoeFgAADs=" ) ;
			 //Display content is gif image
			 header ( 'Content-Type: image/gif' ) ;
			 //Content length
			 header ( 'Content-Length: '  .  sizeof ( $imgData ) ) ;
			 //No web cache
			 header ( 'Cache-Control: no-store,  no-cache, must-revalidate, max-age=0' ) ;
			 //Compatible with http1.0 and https
			 header ( "Pragma: no-cache" ) ;
			 //Content expires immediately
			 header ( 'Expires: '  .  gmdate  ( 'D, d M Y H:i:s' ,  time ( ) ) ) ;
			 //Output Picture
			 echo  $imgData ;
			 return  false ;
			 //Exit Script
			 exit ( zero ) ;
		 }
		 //If the src attribute at this time contains http and other characters, it indicates an external link
		 if ( preg_match ( '/^https?:\/\/ [^\/]+/i' ,  $this -> src ) ) {
		  	 //Write a log, indicating that the link is external, level 2
		  	 $this -> debug ( two ,  "Is a request for an external URL: "  .  $this -> src ) ;
			 //Set isURL to true, indicating external url
			 $this -> isURL  =  true ;
		 //If not, it means internal link
		 }  else  {
			 $this -> debug ( two ,  "Is a request for an internal file: "  .  $this -> src ) ;
		 }
		 //If the src of the image is an external website, and the configuration file does not allow obtaining the image from outside, exit
		 if ( $this -> isURL  &&  ( ! ALLOW_EXTERNAL ) ) {
			 $this -> error ( "You are not allowed to fetch images from an external website." ) ;
			 return  false ;
		 }
		 //If you are allowed to get pictures from external websites
		 if ( $this -> isURL ) {
		  	 //And the configuration file allows you to get pictures from all external websites
		  	 if ( ALLOW_ALL_EXTERNAL_SITES ) {
				 //Write a log, allow to retrieve pictures from external websites, level 2
			  	 $this -> debug ( two ,  "Fetching from all external sites is enabled." ) ;
			 //If the configuration file does not allow getting pictures from all external websites
			 }  else  {
			  	 //Write a log. You can only get pictures from the specified external website. Level 2
			  	 $this -> debug ( two ,  "Fetching only from selected external sites is enabled." ) ;
				 //This is the verification bit, and the default is false
				 $allowed  =  false ;
				 //Traverse the list of allowed sites in the configuration file
				 foreach ( $ALLOWED_SITES  as  $site ) {
				  	 //Here we verify the URL of the image and the list of sites allowed to access. The preceding conditions correspond to those with a host name, and the following contents correspond to those without a host name, which is very ingenious
				  	 if  ( ( strtolower ( substr ( $this -> url [ 'host' ] ,- strlen ( $site ) - one ) )  ===  strtolower ( ". $site " ) )  ||  ( strtolower ( $this -> url [ 'host' ] ) === strtolower ( $site ) ) )  {
						 //Write a log if the verification is passed. The verification is successful. Level 3
					  	 $this -> debug ( three ,  "URL hostname {$this->url['host']} matches $site so allowing." ) ;
						 //The verification bit is true
						 $allowed  =  true ;
					 }
				 }
				 //If the verification fails, write an error message and exit
				 if ( !  $allowed ) {
					 return  $this -> error ( "You may not fetch images from that site. To enable this site in timthumb,  you can either add it to \$ ALLOWED_SITES and set ALLOW_EXTERNAL=true. Or you can set ALLOW_ALL_EXTERNAL_SITES=true, depending on your security needs." ) ;
				 }
			 }
		 }
		 //The prefix of the cache file. If it is an internal image, use _int_, and if it is an external image, use _ext_
		 $cachePrefix  =  ( $this -> isURL ? '_ext_'  :  '_int_' ) ;
		 //If it is an external picture address
		 if ( $this -> isURL ) {
		  	 //Get an array of GET strings
		  	 $arr  =  explode ( '&' ,  $_SERVER  [ 'QUERY_STRING' ] ) ;
			 //Sort array elements alphabetically
			 asort ( $arr ) ;
			 //Generate cache file address cache directory+/+cache prefix+$cachePrefix+unique hash value+cache suffix
			 $this -> cachefile  =  $this -> cacheDirectory  .  '/'  . FILE_CACHE_PREFIX .  $cachePrefix  .  md5 ( $this -> salt  .  implode ( '' ,  $arr )  .  $this -> fileCacheVersion )  . FILE_CACHE_SUFFIX ;
		 //If it is a local picture
		 }  else  {
		  	 //Get local picture address
		  	 $this -> localImage  =  $this -> getLocalImagePath ( $this -> src ) ;
			 //If the address cannot be obtained
			 if ( !  $this -> localImage ) {
			  	 //Write log. This file is not found. Level 1
			  	 $this -> debug ( one ,  "Could not find the local image: {$this->localImage} " ) ;
				 //Log error messages
				 $this -> error ( "Could not find the internal image you specified." ) ;
				 //Set 404 error message
				 $this -> set404 ( ) ;
				 //Terminate execution program
				 return  false ;
			 }
			 //Write a log to record local image information, level 1
			 $this -> debug ( one ,  "Local image path is {$this->localImage} " ) ;
			 //Get file modification time
			 $this -> localImageMTime  =  @ filemtime ( $this -> localImage ) ;
			 //Generate cache file address, cache directory+/+cache prefix+$cachePrefix+unique hash value+cache suffix
			 $this -> cachefile  =  $this -> cacheDirectory  .  '/'  . FILE_CACHE_PREFIX .  $cachePrefix  .  md5 ( $this -> salt  .  $this -> localImageMTime  .  $_SERVER  [ 'QUERY_STRING' ]  .  $this -> fileCacheVersion )  . FILE_CACHE_SUFFIX ;
		 }
		 //Record cache file address
		 $this -> debug ( two ,  "Cache file is: "  .  $this -> cachefile ) ;
		 //Constructor complete
		 return  true ;
	 }
	 /*Destruct method to delete every file in the toDeletes array*/
	 public  function __destruct ( ) {
		 foreach ( $this -> toDeletes  as  $del ) {
			 $this -> debug ( two ,  "Deleting temp file $del " ) ;
			 @ unlink ( $del ) ;
		 }
	 }
	 /*Main function, calling different image processing functions through different parameters*/
	 public  function run ( ) {
	  	 //If it is an external picture link
	  	 if ( $this -> isURL ) {
			 //But the configuration file does not allow getting links from outside
		  	 if ( ! ALLOW_EXTERNAL ) {
				 //Write a log indicating that the configuration file is prohibited from accessing external pictures, level 1
			  	 $this -> debug ( one ,  "Got a request for an external image but ALLOW_EXTERNAL is disabled so returning error msg." ) ;
				 //Write error record
				 $this -> error ( "You are not allowed to fetch images from an external website." ) ;
				 //Exit execution
				 return  false ;
			 }
			 //If the configuration file allows obtaining links from outside, write logs and then run, level 3
			 $this -> debug ( three ,  "Got request for external image. Starting serveExternalImage." ) ;
			 //If the webshot parameter is obtained and true, the screenshot operation will be performed
			 if ( $this -> param ( 'webshot' ) ) {
			  	 //If the configuration file allows screenshots
			  	 if ( WEBSHOT_ENABLED ) {
			    		 //Write a log, indicating the screenshot operation, level 3
				  	 $this -> debug ( three ,  "webshot param is set, so we're going to take a webshot." ) ;
					 //Screenshot operation
					 $this -> serveWebshot ( ) ;
				 //If the configuration file does not allow screenshots
				 }  else  {
				  	 //Log the error message and exit
					 $this -> error ( "You added the webshot parameter but webshots are disabled on this server. You need to set WEBSHOT_ENABLED == true to enable webshots." ) ;
				 }
			 //If the sebshot parameter does not exist or is false
			 }  else  {
			  	 //Log writing, no screenshot operation, level 3
			  	 $this -> debug ( three ,  "webshot is NOT set so we're going to try to fetch a regular image." ) ;
				 //Get pictures from external URLs and process them
				 $this -> serveExternalImage ( ) ;   }
		 //Otherwise, it's an internal picture
		 }  else  {
		  	 //Write a log. The record is an internal picture. Level 3
		  	 $this -> debug ( three ,  "Got request for internal image. Starting serveInternalImage()" ) ;
			 //Get internal pictures and process them
			 $this -> serveInternalImage ( ) ;
		 }
		 //Program execution completed
		 return  true ;
	 }
	 /*This function is used to handle errors*/
	 protected  function handleErrors ( ) {
	  	 //If there is something in the error list
	  	 if ( $this -> haveErrors ( ) ) {
			 //First, detect the 404 error. If the 404 image address is set and there is a 404 error
		  	 if ( NOT_FOUND_IMAGE &&  $this -> is404 ( ) ) {
				 //Then output the error image and exit the script
				 if ( $this -> serveImg ( NOT_FOUND_IMAGE ) ) {
				  	 exit ( zero ) ;
				 //Record error information if output fails
				 }  else  {
					 $this -> error ( "Additionally, the 404 image that is configured could not be found or there was an error serving it." ) ;
				 }
			 }
			 //If there is no 404 error and an error image is defined, the image will be output
			 if ( ERROR_IMAGE ) {
			  	 //Output other error prompt pictures and exit the script
				 if ( $this -> serveImg ( ERROR_IMAGE ) ) {
				  	 exit ( zero ) ;
				 //Record error information if output fails
				 }  else  {
					 $this -> error ( "Additionally, the error image that is configured could not be found or there was an error serving it." ) ;
				 }
			 }
			 //If the above two constants are not defined, detailed error information will be output according to the template
			 $this -> serveErrors ( ) ; 
			 exit ( zero ) ; 
		 }
		 //Return false if there is no error
		 return  false ;
	 }
	 /*This function is used to read the browser cache file, provided that the browser cache file is valid. Please refer to the function for specific implementation*/
	 protected  function tryBrowserCache ( ) {
	  	 //If all browser caches are turned off in the configuration file, write logs and return false
	  	 if ( BROWSER_CACHE_DISABLE ) { 
		  	 $this -> debug ( three ,  "Browser caching is disabled" ) ;  return  false ; 
		 }
		 //If the browser records the time when the page was last modified
		 if ( ! empty ( $_SERVER [ 'HTTP_IF_MODIFIED_SINCE' ] )  ) {
		  	 //Write log, record, level 3
		  	 $this -> debug ( three ,  "Got a conditional get" ) ;
			 //Last modification time of cache file
			 $mtime  =  false ;
			 //If the cache address is invalid
			 if ( !  is_file ( $this -> cachefile ) ) {
				 //Description No cache, return false
				 return  false ;
			 }
			 //If there is a local image modification time, that is, the requested image is local
			 if ( $this -> localImageMTime ) {
			  	 //Set the cache file modification time to the local picture modification time
			  	 $mtime  =  $this -> localImageMTime ;
				 //Write a log to record the actual file modification time, level 3
				 $this -> debug ( three ,  "Local real file's modification time is $mtime " ) ;
			 //If the requested image is not local
			 }  else  if ( is_file ( $this -> cachefile ) ) {
			  	 //Get cache file modification time
			  	 $mtime  =  @ filemtime ( $this -> cachefile ) ;
				 //Write a log to record the cache file modification time, level 3
				 $this -> debug ( three ,  "Cached file's modification time is $mtime " ) ;
			 }
			 //If the last modification time of the cache file is not obtained, it means that there is no cache and exit
			 if ( !  $mtime ) {  return  false ;  }
			 //Convert the last modification time stored in the browser to a timestamp
			 $iftime  =  strtotime ( $_SERVER [ 'HTTP_IF_MODIFIED_SINCE' ] ) ;
			 //Log writing, UNIX timestamp recording, level 3
			 $this -> debug ( three ,  "The conditional get's if-modified-since unixtime is $iftime " ) ;
			 //If the time is less than 1 second, the value is invalid, exit
			 if ( $iftime  <  one ) {
			  	 //Write a log. This value is invalid
				 $this -> debug ( three ,  "Got an invalid conditional get modified since time. Returning false." ) ;
				 return  false ;
			 }
			 //If the time stored by the browser is less than the last modification time of the actual cache file, that is, the file has been changed since the last access, the page should be requested again
			 if ( $iftime  <  $mtime ) {
			  	 //Write log, record file has been changed, level 3
				 $this -> debug ( three ,  "File has been modified since last fetch." ) ;
				 return  false ;
			 //Otherwise, you don't need to re request the page and read the cache directly
			 }  else  {
			  	 //Write logs, record cache is valid, read cache directly, level 3
			  	 $this -> debug ( three ,  "File has not been modified since last get, so serving a 304." ) ;
				 //Set the HTTP header response code to 304
				 header  ( $_SERVER [ 'SERVER_PROTOCOL' ]  .  ' 304 Not Modified' ) ;
				 //Record this operation, level 1
				 $this -> debug ( one ,  "Returning 304 not modified" ) ;
				 //Return true after reading successfully
				 return  true ;
			 }
		 }
		 //No cache read, return false
		 return  false ;
	 }
	 /*This function is used to run the GC of the cache file and read the cache file on the server*/
	 protected  function tryServerCache ( ) {
	  	 //Write a log that will read the server cache, level 3
	  	 $this -> debug ( three ,  "Trying server cache" ) ;
	  	 //If the cache file exists
		 if ( file_exists ( $this -> cachefile ) ) {
		  	 //Write logs to record the existence of cache files
		  	 $this -> debug ( three ,  "Cachefile {$this->cachefile} exists" ) ;
			 //If the request is for an external picture address
			 if ( $this -> isURL ) {
			  	 //Write a log to record that this is an external request, level 3
			  	 $this -> debug ( three ,  "This is an external request, so checking if the cachefile is empty which means the request failed previously." ) ;
				 //If the size of the cache file is less than 1, it is an invalid cache file
				 if ( filesize ( $this -> cachefile )  <  one ) {
				  	 //Write a log to record that this is an empty cache file, level 3
					 $this -> debug ( three ,  "Found an empty cachefile indicating a failed earlier request. Checking how old it is." ) ;
					 //If it is time to clear the invalid cache in the configuration file
					 if ( time ( )  -  @ filemtime ( $this -> cachefile )  > WAIT_BETWEEN_FETCH_ERRORS ) {
					  	 //Write a log to record the deletion operation. Level 3
					  	 $this -> debug ( three ,  "File is older than "  . WAIT_BETWEEN_FETCH_ERRORS .  " seconds. Deleting and returning false so app can try and load file." ) ;
						 //Delete this cache file
						 @ unlink ( $this -> cachefile ) ;
						 //Returns false, indicating that the server cache is not read
						 return  false ;
					 //Otherwise, an empty cache file indicates that the last request failed, so an error record should be written
					 }  else  {
					  	 //Write logs to record empty cache files. Level 3 is still valid
					  	 $this -> debug ( three ,  "Empty cachefile is still fresh so returning message saying we had an error fetching this image from remote host." ) ;
						 //Setting 404 error
						 $this -> set404 ( ) ;
						 //Set error message
						 $this -> error ( "An error occured fetching image." ) ;
						 //If false is returned, it means that the cache is not available
						 return  false ; 
					 }
				 }
			 //Otherwise, it is the correct cache file
			 }  else  {
			  	 //Write logs to record that cache files will be read directly, level 3
				 $this -> debug ( three ,  "Trying to serve cachefile {$this->cachefile} " ) ;
			 }
			 //If the output image cache is successful
			 if ( $this -> serveCacheFile ( ) ) {
			  	 //Write logs, record cache file information, level 3
				 $this -> debug ( three ,  "Succesfully served cachefile {$this->cachefile} " ) ;
				 return  true ;
			 //If unsuccessful
			 }  else  {
			  	 //Write log, record error information, level 3
				 $this -> debug ( three ,  "Failed to serve cachefile {$this->cachefile} - Deleting it from cache. " ) ;
				 //Delete this invalid cache so that the next request can be recreated
				 @ unlink ( $this -> cachefile ) ;
				 //Also returns true, because the error information has been recorded in the serverCacheFile
				 return  true ;
			 }
		 }
	 }
	 /*This function is used to record error information*/
	 protected  function error ( $err ) {
	  	 //Write record, record error information, level 3
	  	 $this -> debug ( three ,  "Adding error message: $err " ) ;
		 //Log to error information array
		 $this -> errors [ ]  =  $err ;
		 return  false ;
	 }
 one two three four five six seven eight nine ten eleven twelve thirteen fourteen fifteen sixteen seventeen eighteen nineteen twenty twenty-one twenty-two twenty-three twenty-four twenty-five twenty-six twenty-seven twenty-eight twenty-nine thirty thirty-one thirty-two thirty-three thirty-four thirty-five thirty-six thirty-seven thirty-eight thirty-nine forty forty-one forty-two forty-three forty-four forty-five forty-six forty-seven forty-eight forty-nine fifty fifty-one fifty-two fifty-three fifty-four fifty-five fifty-six fifty-seven fifty-eight fifty-nine sixty sixty-one sixty-two sixty-three sixty-four sixty-five sixty-six sixty-seven sixty-eight sixty-nine seventy seventy-one seventy-two seventy-three seventy-four seventy-five seventy-six seventy-seven seventy-eight seventy-nine eighty eighty-one eighty-two eighty-three eighty-four eighty-five eighty-six eighty-seven eighty-eight eighty-nine ninety ninety-one ninety-two ninety-three ninety-four ninety-five ninety-six ninety-seven ninety-eight ninety-nine one hundred one hundred and one one hundred and two one hundred and three one hundred and four one hundred and five one hundred and six one hundred and seven one hundred and eight one hundred and nine one hundred and ten one hundred and eleven one hundred and twelve one hundred and thirteen one hundred and fourteen one hundred and fifteen one hundred and sixteen one hundred and seventeen one hundred and eighteen one hundred and nineteen one hundred and twenty one hundred and twenty-one one hundred and twenty-two one hundred and twenty-three one hundred and twenty-four one hundred and twenty-five one hundred and twenty-six one hundred and twenty-seven one hundred and twenty-eight one hundred and twenty-nine one hundred and thirty one hundred and thirty-one one hundred and thirty-two one hundred and thirty-three one hundred and thirty-four one hundred and thirty-five one hundred and thirty-six one hundred and thirty-seven one hundred and thirty-eight one hundred and thirty-nine one hundred and forty one hundred and forty-one one hundred and forty-two one hundred and forty-three one hundred and forty-four one hundred and forty-five one hundred and forty-six one hundred and forty-seven one hundred and forty-eight one hundred and forty-nine one hundred and fifty one hundred and fifty-one one hundred and fifty-two one hundred and fifty-three one hundred and fifty-four one hundred and fifty-five one hundred and fifty-six one hundred and fifty-seven one hundred and fifty-eight one hundred and fifty-nine one hundred and sixty one hundred and sixty-one one hundred and sixty-two one hundred and sixty-three one hundred and sixty-four one hundred and sixty-five one hundred and sixty-six one hundred and sixty-seven one hundred and sixty-eight one hundred and sixty-nine one hundred and seventy one hundred and seventy-one one hundred and seventy-two one hundred and seventy-three one hundred and seventy-four one hundred and seventy-five one hundred and seventy-six one hundred and seventy-seven one hundred and seventy-eight one hundred and seventy-nine one hundred and eighty one hundred and eighty-one one hundred and eighty-two one hundred and eighty-three one hundred and eighty-four one hundred and eighty-five one hundred and eighty-six one hundred and eighty-seven one hundred and eighty-eight one hundred and eighty-nine one hundred and ninety one hundred and ninety-one one hundred and ninety-two one hundred and ninety-three one hundred and ninety-four one hundred and ninety-five one hundred and ninety-six one hundred and ninety-seven one hundred and ninety-eight one hundred and ninety-nine two hundred two hundred and one two hundred and two two hundred and three two hundred and four two hundred and five two hundred and six two hundred and seven two hundred and eight two hundred and nine two hundred and ten two hundred and eleven two hundred and twelve two hundred and thirteen two hundred and fourteen two hundred and fifteen two hundred and sixteen two hundred and seventeen two hundred and eighteen two hundred and nineteen two hundred and twenty two hundred and twenty-one two hundred and twenty-two two hundred and twenty-three two hundred and twenty-four two hundred and twenty-five two hundred and twenty-six two hundred and twenty-seven two hundred and twenty-eight two hundred and twenty-nine two hundred and thirty two hundred and thirty-one two hundred and thirty-two two hundred and thirty-three two hundred and thirty-four two hundred and thirty-five two hundred and thirty-six two hundred and thirty-seven two hundred and thirty-eight two hundred and thirty-nine two hundred and forty two hundred and forty-one two hundred and forty-two two hundred and forty-three two hundred and forty-four two hundred and forty-five two hundred and forty-six two hundred and forty-seven two hundred and forty-eight two hundred and forty-nine two hundred and fifty two hundred and fifty-one two hundred and fifty-two two hundred and fifty-three two hundred and fifty-four two hundred and fifty-five two hundred and fifty-six two hundred and fifty-seven two hundred and fifty-eight two hundred and fifty-nine two hundred and sixty two hundred and sixty-one two hundred and sixty-two two hundred and sixty-three two hundred and sixty-four two hundred and sixty-five two hundred and sixty-six two hundred and sixty-seven two hundred and sixty-eight two hundred and sixty-nine two hundred and seventy two hundred and seventy-one two hundred and seventy-two two hundred and seventy-three two hundred and seventy-four two hundred and seventy-five two hundred and seventy-six two hundred and seventy-seven two hundred and seventy-eight two hundred and seventy-nine two hundred and eighty two hundred and eighty-one two hundred and eighty-two two hundred and eighty-three two hundred and eighty-four two hundred and eighty-five two hundred and eighty-six two hundred and eighty-seven two hundred and eighty-eight two hundred and eighty-nine two hundred and ninety two hundred and ninety-one two hundred and ninety-two two hundred and ninety-three two hundred and ninety-four two hundred and ninety-five two hundred and ninety-six two hundred and ninety-seven two hundred and ninety-eight two hundred and ninety-nine three hundred three hundred and one three hundred and two three hundred and three three hundred and four three hundred and five three hundred and six three hundred and seven three hundred and eight three hundred and nine three hundred and ten three hundred and eleven three hundred and twelve three hundred and thirteen three hundred and fourteen three hundred and fifteen three hundred and sixteen three hundred and seventeen three hundred and eighteen three hundred and nineteen three hundred and twenty three hundred and twenty-one three hundred and twenty-two three hundred and twenty-three three hundred and twenty-four three hundred and twenty-five three hundred and twenty-six three hundred and twenty-seven three hundred and twenty-eight three hundred and twenty-nine three hundred and thirty three hundred and thirty-one three hundred and thirty-two three hundred and thirty-three three hundred and thirty-four three hundred and thirty-five three hundred and thirty-six three hundred and thirty-seven three hundred and thirty-eight three hundred and thirty-nine three hundred and forty three hundred and forty-one three hundred and forty-two three hundred and forty-three three hundred and forty-four three hundred and forty-five three hundred and forty-six three hundred and forty-seven three hundred and forty-eight three hundred and forty-nine three hundred and fifty three hundred and fifty-one three hundred and fifty-two three hundred and fifty-three three hundred and fifty-four three hundred and fifty-five three hundred and fifty-six three hundred and fifty-seven three hundred and fifty-eight three hundred and fifty-nine three hundred and sixty three hundred and sixty-one three hundred and sixty-two three hundred and sixty-three three hundred and sixty-four three hundred and sixty-five three hundred and sixty-six three hundred and sixty-seven three hundred and sixty-eight three hundred and sixty-nine three hundred and seventy three hundred and seventy-one three hundred and seventy-two three hundred and seventy-three three hundred and seventy-four three hundred and seventy-five three hundred and seventy-six three hundred and seventy-seven three hundred and seventy-eight three hundred and seventy-nine three hundred and eighty three hundred and eighty-one three hundred and eighty-two three hundred and eighty-three three hundred and eighty-four three hundred and eighty-five three hundred and eighty-six three hundred and eighty-seven three hundred and eighty-eight three hundred and eighty-nine three hundred and ninety three hundred and ninety-one three hundred and ninety-two three hundred and ninety-three three hundred and ninety-four three hundred and ninety-five three hundred and ninety-six three hundred and ninety-seven three hundred and ninety-eight three hundred and ninety-nine four hundred four hundred and one four hundred and two four hundred and three four hundred and four four hundred and five four hundred and six four hundred and seven four hundred and eight four hundred and nine four hundred and ten four hundred and eleven four hundred and twelve four hundred and thirteen four hundred and fourteen four hundred and fifteen four hundred and sixteen four hundred and seventeen four hundred and eighteen four hundred and nineteen four hundred and twenty four hundred and twenty-one four hundred and twenty-two four hundred and twenty-three four hundred and twenty-four four hundred and twenty-five four hundred and twenty-six four hundred and twenty-seven four hundred and twenty-eight four hundred and twenty-nine four hundred and thirty four hundred and thirty-one four hundred and thirty-two four hundred and thirty-three four hundred and thirty-four four hundred and thirty-five four hundred and thirty-six four hundred and thirty-seven four hundred and thirty-eight four hundred and thirty-nine four hundred and forty four hundred and forty-one four hundred and forty-two four hundred and forty-three four hundred and forty-four four hundred and forty-five four hundred and forty-six four hundred and forty-seven four hundred and forty-eight four hundred and forty-nine four hundred and fifty four hundred and fifty-one four hundred and fifty-two four hundred and fifty-three four hundred and fifty-four four hundred and fifty-five four hundred and fifty-six four hundred and fifty-seven four hundred and fifty-eight four hundred and fifty-nine four hundred and sixty four hundred and sixty-one four hundred and sixty-two four hundred and sixty-three four hundred and sixty-four four hundred and sixty-five four hundred and sixty-six four hundred and sixty-seven four hundred and sixty-eight four hundred and sixty-nine four hundred and seventy four hundred and seventy-one four hundred and seventy-two four hundred and seventy-three four hundred and seventy-four four hundred and seventy-five four hundred and seventy-six four hundred and seventy-seven four hundred and seventy-eight four hundred and seventy-nine four hundred and eighty four hundred and eighty-one four hundred and eighty-two four hundred and eighty-three four hundred and eighty-four four hundred and eighty-five four hundred and eighty-six four hundred and eighty-seven four hundred and eighty-eight four hundred and eighty-nine four hundred and ninety four hundred and ninety-one four hundred and ninety-two four hundred and ninety-three four hundred and ninety-four four hundred and ninety-five four hundred and ninety-six four hundred and ninety-seven four hundred and ninety-eight four hundred and ninety-nine five hundred five hundred and one five hundred and two five hundred and three five hundred and four five hundred and five five hundred and six five hundred and seven five hundred and eight five hundred and nine five hundred and ten five hundred and eleven five hundred and twelve five hundred and thirteen five hundred and fourteen five hundred and fifteen five hundred and sixteen five hundred and seventeen five hundred and eighteen five hundred and nineteen five hundred and twenty five hundred and twenty-one five hundred and twenty-two five hundred and twenty-three five hundred and twenty-four five hundred and twenty-five five hundred and twenty-six five hundred and twenty-seven five hundred and twenty-eight
 /*The measurement function is used to detect whether there is any content in the array storing error information, that is, whether there is any error in the last operation*/
	 protected  function haveErrors ( ) {
		 if ( sizeof ( $this -> errors )  >  zero ) {
			 return  true ;
		 }
		 return  false ;
	 }
	 /*This function outputs the stored error information*/
	 protected  function serveErrors ( ) {
	  	 //Set http header
	   header  ( $_SERVER [ 'SERVER_PROTOCOL' ]  .  ' 400 Bad Request' ) ;
	  	 //Circular output error list information
		 $html  =  '<ul>' ;
		 foreach ( $this -> errors  as  $err ) {
			 $html  .=  '<li>'  .  htmlentities ( $err )  .  '</li>' ;
		 }
		 $html  .=  '</ul>' ;
		 //Output other error messages
		 echo  '<h1>A TimThumb error has occured</h1>The following error(s) occured:<br />'  .  $html  .  '<br />' ;
		 echo  '<br />Query String : '  .  htmlentities  ( $_SERVER [ 'QUERY_STRING' ] ) ;
		 echo  '<br />TimThumb version : '  . VERSION ;
	 }
	 /*This function is used to read the local image*/
	 protected  function serveInternalImage ( ) {
	  	 //Write a log to record the local image address
	  	 $this -> debug ( three ,  "Local image path is $this->localImage " ) ;
	  	 //If the address is invalid
		 if ( !  $this -> localImage ) {
		  	 //Log this error and exit execution
			 $this -> sanityFail ( "localImage not set after verifying it earlier in the code." ) ;
			 return  false ;
		 }
		 //Get local picture size
		 $fileSize  =  filesize ( $this -> localImage ) ;
		 //If the size of the local picture exceeds the relevant settings of the configuration file
		 if ( $fileSize  > MAX_FILE_SIZE ) {
		  	 //Record the error reason and exit
			 $this -> error ( "The file you specified is greater than the maximum allowed file size." ) ;
			 return  false ;
		 }
		 //If the acquired image size is invalid
		 if ( $fileSize  <=  zero ) {
		  	 //Log errors and exit
			 $this -> error ( "The file you specified is <= 0 bytes." ) ;
			 return  false ;
		 }
		 //If the above verification is passed, a log will be written to record that the local image will be processed with the processImageAndWriteToCache function
		 $this -> debug ( three ,  "Calling processImageAndWriteToCache() for local image." ) ;
		 //If the processing is successful, the image will be returned from the cache
		 if ( $this -> processImageAndWriteToCache ( $this -> localImage ) ) {
			 $this -> serveCacheFile ( ) ;
			 return  true ;
		 //Return false if failed
		 }  else  { 
			 return  false ;
		 }
	 }
	 /*This function is used to clean the cache*/
	 protected  function cleanCache ( ) {
		 //If the defined cache time is less than 0, exit
		 if  ( FILE_CACHE_TIME_BETWEEN_CLEANS <  zero )  {
			 return ;
		 }
		 //Write logs, record cache clearing operations, level 3
		 $this -> debug ( three ,  "cleanCache() called" ) ;
		 //This file is a timestamp file that records the last cache clearing operation
		 $lastCleanFile  =  $this -> cacheDirectory  .  '/timthumb_cacheLastCleanTime.touch' ;   //If the file defined above does not exist, it means that this is the first time to clear the cache. Create this file and return null
		 if ( !  is_file ( $lastCleanFile ) ) {
		  	 //Write log, record creation file, level 1
		  	 $this -> debug ( one ,  "File tracking last clean doesn't exist. Creating $lastCleanFile " ) ;
			 //Create this file
			 if  ( ! touch ( $lastCleanFile ) )  {
			  	 //If it fails, report an error and exit
				 $this -> error ( "Could not create cache clean timestamp file." ) ;
			 }
			 return ;
		 }
		 //If the cache time has exceeded
		 if ( @ filemtime ( $lastCleanFile )  <  ( time ( )  - FILE_CACHE_TIME_BETWEEN_CLEANS )  ) {
		  	 //Write a log to record the following cache clearing operations
			 $this -> debug ( one ,  "Cache was last cleaned more than "  . FILE_CACHE_TIME_BETWEEN_CLEANS .  " seconds ago. Cleaning now." ) ;
			 //Create a new purge cache timestamp file
			 if  ( ! touch ( $lastCleanFile ) )  {
			  	 //Record the error message in case of failure
				 $this -> error ( "Could not create cache clean timestamp file." ) ;
			 }
			 //This array stores all cache files according to the cache file directory and cache file suffix defined previously
			 $files  =  glob ( $this -> cacheDirectory  .  '/*'  . FILE_CACHE_SUFFIX ) ;
			 //If there are cache files
			 if  ( $files )  {
			  	 //Calculate the difference between the current time and the maximum lifetime of the cache to determine whether the cache file is deleted
			  	 $timeAgo  =  time ( )  - FILE_CACHE_MAX_FILE_AGE ;
				 //Traversal cache file array
				 foreach ( $files  as  $file ) {
				  	 //If the file creation time is less than the value calculated above, that is to say, the cache file will be deleted when its expiration date is reached
				  	 if ( @ filemtime ( $file )  <  $timeAgo ) {
				    		 //Record deletion cache file, level 3
						 $this -> debug ( three ,  "Deleting cache file $file older than max age: "  . FILE_CACHE_MAX_FILE_AGE .  " seconds" ) ;
						 @ unlink ( $file ) ;
					 }
				 }
			 }
			 return  true ;
		 //Do not clear if the cache time is not exceeded
		 }  else  {
		  	 //Write logs without clearing cache
			 $this -> debug ( three ,  "Cache was cleaned less than "  . FILE_CACHE_TIME_BETWEEN_CLEANS .  " seconds ago so no cleaning needed." ) ;
		 }
		 return  false ;
	 }
	 /*Core function, processing pictures and writing to cache*/
	 protected  function processImageAndWriteToCache ( $localImage ) {
	  	 //Get picture information
	  	 $sData  =  getimagesize ( $localImage ) ;
		 //Image type marker
		 $origType  =  $sData [ two ] ;
		 //Mime type
		 $mimeType  =  $sData [ 'mime' ] ;
		 //Write a log to record the mime type of the incoming image
		 $this -> debug ( three ,  "Mime type of image is $mimeType " ) ;
		 //Perform image mime type verification. Only gif, jpg and png are allowed
		 if ( !  preg_match ( '/^image\/(?:gif|jpg|jpeg|png)$/i' ,  $mimeType ) ) {
		  	 //If not, record the error message and exit the script
			 return  $this -> error ( "The image being resized is not a valid gif, jpg or png." ) ;
		 }
		 //Image processing requires GD library support. Check whether GD library is installed
		 if  ( ! function_exists  ( 'imagecreatetruecolor' ) )  {
		     //If not installed, the script will be launched
		     return  $this -> error ( 'GD Library Error: imagecreatetruecolor does not exist - please contact your webhost and ask them to install the GD library' ) ;
		 }
		 //If the GD library is installed, the image filter function imagefilter is supported, and the IMG_FILTER_NEGATE constant is supported
		 if  ( function_exists  ( 'imagefilter' )  &&  defined  ( 'IMG_FILTER_NEGATE' ) )  {
		  	 //Define a filter effect array, and the numbers after it represent the parameters that need to be passed in additionally
		  	 $imageFilters  =  array  (
		    		 //Negative film
			  	 one  =>  array  ( IMG_FILTER_NEGATE ,  zero ) ,
				 //Black-and-white
				 two  =>  array  ( IMG_FILTER_GRAYSCALE ,  zero ) ,
				 //Brightness level
				 three  =>  array  ( IMG_FILTER_BRIGHTNESS ,  one ) ,
				 //Contrast Level
				 four  =>  array  ( IMG_FILTER_CONTRAST ,  one ) ,
				 //Image conversion to specified color
				 five  =>  array  ( IMG_FILTER_COLORIZE ,  four ) ,
				 //Protruding edge
				 six  =>  array  ( IMG_FILTER_EDGEDETECT ,  zero ) ,
				 //Relief
				 seven  =>  array  ( IMG_FILTER_EMBOSS ,  zero ) ,
				 //Blur image with Gaussian algorithm
				 eight  =>  array  ( IMG_FILTER_GAUSSIAN_BLUR ,  zero ) ,
				 //Blurred image
				 nine  =>  array  ( IMG_FILTER_SELECTIVE_BLUR ,  zero ) ,
				 //Average removal method to achieve contour effect
				 ten  =>  array  ( IMG_FILTER_MEAN_REMOVAL ,  zero ) ,
				 //Smoothing
				 eleven  =>  array  ( IMG_FILTER_SMOOTH ,  zero ) ,
			 ) ;
		 }   //The width of the generated picture, specified by the w parameter in get, is 0 by default
		 $new_width  =   ( int )  abs  ( $this -> param ( 'w' ,  zero ) ) ;
		 //The height of the generated image, specified by the h parameter in get, is 0 by default
		 $new_height  =  ( int )  abs  ( $this -> param ( 'h' ,  zero ) ) ;
		 //Generate the image scaling mode, which is specified by the zc parameter in get. The default value is DEFAULT_ZC in the configuration file
		 $zoom_crop  =  ( int )  $this -> param ( 'zc' , DEFAULT_ZC ) ;
		 //The quality of the generated image, specified by the q parameter in get, defaults to the value of DEFAULT_Q in the configuration file
		 $quality  =  ( int )  abs  ( $this -> param ( 'q' , DEFAULT_Q ) ) ;
		 //Cropped position
		 $align  =  $this -> cropTop ? 't'  :  $this -> param ( 'a' ,  'c' ) ;
		 //For image processing operations to be performed, multiple filters are separated by "|". For optional parameters, see the note at $imageFilters. Because different filters require different parameters, for example, one filter requires multiple parameters, multiple parameters are separated by. For example, 1,2 | 3,1,1 means to apply 1 and 3 filtering effects to the image respectively. The corresponding filtering effects of 1 and 3 are determined by the $imageFilters array. Filter 1 requires an additional parameter. Here, filter 1 and filter 3 require two additional parameters. Here, filter 1 and filter 1 are passed
		 $filters  =  $this -> param ( 'f' , DEFAULT_F ) ;
		 //Whether to sharpen the picture is specified by the s parameter in get. The default value is DEFAULT_S in the configuration file
		 $sharpen  =  ( bool )  $this -> param ( 's' , DEFAULT_S ) ;
		 //The default background canvas color of the generated picture, specified by the cc parameter in get, is the value of DEFAULT_CC in the configuration file by default
		 $canvas_color  =  $this -> param ( 'cc' , DEFAULT_CC ) ;
		 //Whether the background of the generated png image is transparent
		 $canvas_trans  =  ( bool )  $this -> param ( 'ct' ,  '1' ) ;   //If the height and width are not specified, set them to 100 * 100
		 if  ( $new_width  ==  zero  &&  $new_height  ==  zero )  {
		     $new_width  =  one hundred ;
		     $new_height  =  one hundred ;
		 }   //Limit maximum height and width
		 $new_width  =  min  ( $new_width , MAX_WIDTH ) ;
		 $new_height  =  min  ( $new_height , MAX_HEIGHT ) ;   //Detect and set the maximum memory occupied by php operation
		 $this -> setMemoryLimit ( ) ;   //Open Image Resources
		 $image  =  $this -> openImage  ( $mimeType ,  $localImage ) ;
		 //If the opening fails, record the information and exit the script
		 if  ( $image  ===  false )  {
			 return  $this -> error ( 'Unable to open image.' ) ;
		 }   //Get the original image, that is, the width and height of the image opened above
		 $width  =  imagesx  ( $image ) ;
		 $height  =  imagesy  ( $image ) ;
		 $origin_x  =  zero ;
		 $origin_y  =  zero ;   //If the width or height of the newly generated picture is not specified, use this proportional algorithm to calculate the height or width value
		 if  ( $new_width  &&  ! $new_height )  {
			 $new_height  =  floor  ( $height  *  ( $new_width  /  $width ) ) ;
		 }  else  if  ( $new_height  &&  ! $new_width )  {
			 $new_width  =  floor  ( $width  *  ( $new_height  /  $height ) ) ;
		 }   //If 3 is selected as the zoom mode, that is, zc=3 in get or DEFAULT_ZC=3 in the configuration file, then perform proportional scaling without clipping
		 if  ( $zoom_crop  ==  three )  {   $final_height  =  $height  *  ( $new_width  /  $width ) ;
			 //Set the width or height after proportional calculation according to the proportional algorithm
			 if  ( $final_height  >  $new_height )  {
				 $new_width  =  $width  *  ( $new_height  /  $height ) ;
			 }  else  {
				 $new_height  =  $final_height ;
			 }   }   //Create a new canvas with the processed length and width,
		 $canvas  =  imagecreatetruecolor  ( $new_width ,  $new_height ) ;
		 //Turn off the color mixing mode, that is, save the alpha value of PNG to make the background transparent
		 imagealphablending  ( $canvas ,  false ) ;
		 //Detect and convert the default canvas color. If a color value of 3 characters is given
		 if  ( strlen ( $canvas_color )  ==  three )  {  //if is 3-char notation,  edit string into 6-char notation
		  	 //Convert to the color value represented by 6 characters
		  	 $canvas_color  =   str_repeat ( substr ( $canvas_color ,  zero ,  one ) ,  two )  .  str_repeat ( substr ( $canvas_color ,  one ,  one ) ,  two )  .  str_repeat ( substr ( $canvas_color ,  two ,  one ) ,  two ) ; 
		 //If it is not a string of 3 or 6 lengths, it is illegal and set as the default value
		 }  else  if  ( strlen ( $canvas_color )  !=  six )  {
			 $canvas_color  = DEFAULT_CC ;
 		 }
		 //Convert the three color values of R, G and B obtained above to decimal representation
		 $canvas_color_R  =  hexdec  ( substr  ( $canvas_color ,  zero ,  two ) ) ;
		 $canvas_color_G  =  hexdec  ( substr  ( $canvas_color ,  two ,  two ) ) ;
		 $canvas_color_B  =  hexdec  ( substr  ( $canvas_color ,  four ,  two ) ) ;   //If the format of the incoming picture is png, and the configuration file sets the png background color to transparent, and the value of the incoming ct in get is true, then set the background color to transparent
		 if ( preg_match ( '/^image\/png$/i' ,  $mimeType )  &&  ! PNG_IS_TRANSPARENT &&  $canvas_trans ) { 
		  	 $color  =  imagecolorallocatealpha  ( $canvas ,  $canvas_color_R ,  $canvas_color_G ,  $canvas_color_B ,  one hundred and twenty-seven ) ;
		 //Otherwise, set it to opaque
		 } else {
			 $color  =  imagecolorallocatealpha  ( $canvas ,  $canvas_color_R ,  $canvas_color_G ,  $canvas_color_B ,  zero ) ;
		 }   //Fill background with assigned color
		 imagefill  ( $canvas ,  zero ,  zero ,  $color ) ;     //If 2 is selected as the zoom mode, the volume of the canvas is created according to the incoming value, and the width of the border is calculated
		 if  ( $zoom_crop  ==  two )  {
		  	 //Proportionally scaled height
			 $final_height  =  $height  *  ( $new_width  /  $width ) ;
			 //If the calculated equal height is greater than the incoming height
			 if  ( $final_height  >  $new_height )  {
				 //Origin_x is equal to half of the new height passed in
			  	 $origin_x  =  $new_width  /  two ;
			  	 //Set the new width to the value calculated proportionally
				 $new_width  =  $width  *  ( $new_height  /  $height ) ;
				 //Calculate the difference between two origin_x
				 $origin_x  =  round  ( $origin_x  -  ( $new_width  /  two ) ) ;
			 //Otherwise, calculate the difference between two origin_y values
			 }  else  {
				 $origin_y  =  $new_height  /  two ;
				 $new_height  =  $final_height ;
				 $origin_y  =  round  ( $origin_y  -  ( $new_height  /  two ) ) ;   }   }   //Save the complete alpha information when saving the image
		 imagesavealpha  ( $canvas ,  true ) ;   //If zoom mode is 1 or 2 or 3
		 if  ( $zoom_crop  >  zero )  {   $src_x  =  $src_y  =  zero ;
			 //Original width of picture
			 $src_w  =  $width ;
			 //Original height of picture
			 $src_h  =  $height ;   //Picture aspect ratio
			 $cmp_x  =  $width  /  $new_width ;
			 $cmp_y  =  $height  /  $new_height ;   //Clipping algorithm
			 if  ( $cmp_x  >  $cmp_y )  {
				 $src_w  =  round  ( $width  /  $cmp_x  *  $cmp_y ) ;
				 $src_x  =  round  ( ( $width  -  ( $width  /  $cmp_x  *  $cmp_y ) )  /  two ) ;   }  else  if  ( $cmp_y  >  $cmp_x )  {   $src_h  =  round  ( $height  /  $cmp_y  *  $cmp_x ) ;
				 $src_y  =  round  ( ( $height  -  ( $height  /  $cmp_y  *  $cmp_x ) )  /  two ) ;   }   //Calculate the clipping position according to the incoming parameters
			 if  ( $align )  {
				 if  ( strpos  ( $align ,  't' )  !==  false )  {
					 $src_y  =  zero ;
				 }
				 if  ( strpos  ( $align ,  'b' )  !==  false )  {
					 $src_y  =  $height  -  $src_h ;
				 }
				 if  ( strpos  ( $align ,  'l' )  !==  false )  {
					 $src_x  =  zero ;
				 }
				 if  ( strpos  ( $align ,  'r' )  !==  false )  {
					 $src_x  =  $width  -  $src_w ;
				 }
			 }   //Crop the image according to the algorithm and copy it to the background image
			 imagecopyresampled  ( $canvas ,  $image ,  $origin_x ,  $origin_y ,  $src_x ,  $src_y ,  $new_width ,  $new_height ,  $src_w ,  $src_h ) ;   }  else  {   //If 0 is selected as the clipping mode, no clipping will be performed and an image will be generated
			 imagecopyresampled  ( $canvas ,  $image ,  zero ,  zero ,  zero ,  zero ,  $new_width ,  $new_height ,  $width ,  $height ) ;   }
		 //If image processing operations are defined and image processing functions are supported
		 if  ( $filters  !=  ''  &&  function_exists  ( 'imagefilter' )  &&  defined  ( 'IMG_FILTER_NEGATE' ) )  {
			 //Split each filter process
			 $filterList  =  explode  ( '|' ,  $filters ) ;
			 foreach  ( $filterList  as  $fl )  {
			  	 //Split parameters in a filtering operation
			  	 $filterSettings  =  explode  ( ',' ,  $fl ) ;
				 //If the selected filtering operation exists
				 if  ( isset  ( $imageFilters [ $filterSettings [ zero ] ] ) )  {
					 //Convert all parameters to int type
					 for  ( $i  =  zero ;  $i  <  four ;  $i  ++ )  {
						 if  ( ! isset  ( $filterSettings [ $i ] ) )  {
							 $filterSettings [ $i ]  =  null ;
						 }  else  {
							 $filterSettings [ $i ]  =  ( int )  $filterSettings [ $i ] ;
						 }
					 }
					 //Apply filter effects to images according to the different parameters required for each filter effect defined in $imageFilters
					 switch  ( $imageFilters [ $filterSettings [ zero ] ] [ one ] )  {   case  one :   imagefilter  ( $canvas ,  $imageFilters [ $filterSettings [ zero ] ] [ zero ] ,  $filterSettings [ one ] ) ;
							 break ;   case  two :   imagefilter  ( $canvas ,  $imageFilters [ $filterSettings [ zero ] ] [ zero ] ,  $filterSettings [ one ] ,  $filterSettings [ two ] ) ;
							 break ;   case  three :   imagefilter  ( $canvas ,  $imageFilters [ $filterSettings [ zero ] ] [ zero ] ,  $filterSettings [ one ] ,  $filterSettings [ two ] ,  $filterSettings [ three ] ) ;
							 break ;   case  four :   imagefilter  ( $canvas ,  $imageFilters [ $filterSettings [ zero ] ] [ zero ] ,  $filterSettings [ one ] ,  $filterSettings [ two ] ,  $filterSettings [ three ] ,  $filterSettings [ four ] ) ;
							 break ;   default :   imagefilter  ( $canvas ,  $imageFilters [ $filterSettings [ zero ] ] [ zero ] ) ;
							 break ;   }
				 }
			 }
		 }   //If the sharpening value is set and the system supports the sharpening function, the sharpening operation is performed
		 if  ( $sharpen  &&  function_exists  ( 'imageconvolution' ) )  {   $sharpenMatrix  =  array  (
					 array  ( - one ,- one ,- one ) ,
					 array  ( - one , sixteen ,- one ) ,
					 array  ( - one ,- one ,- one ) ,
					 ) ;   $divisor  =  eight ;
			 $offset  =  zero ;   imageconvolution  ( $canvas ,  $sharpenMatrix ,  $divisor ,  $offset ) ;   }
		 //If the image is PNG or GIF, use imageruecolortopalette to reduce their size
		 if  (  ( IMAGETYPE_PNG ==  $origType  || IMAGETYPE_GIF ==  $origType )  &&  function_exists ( 'imageistruecolor' )  &&  ! imageistruecolor (  $image  )  &&  imagecolortransparent (  $image  )  >  zero  ) {
			 imagetruecolortopalette (  $canvas ,  false ,  imagecolorstotal (  $image  )  ) ;
		 }
		 //Generate image cache according to different image types generated, and the value of $imgType is used to generate security header
		 $imgType  =  "" ;
		 $tempfile  =  tempnam ( $this -> cacheDirectory ,  'timthumb_tmpimg_' ) ;
		 if ( preg_match ( '/^image\/(?:jpg|jpeg)$/i' ,  $mimeType ) ) { 
			 $imgType  =  'jpg' ;
			 imagejpeg ( $canvas ,  $tempfile ,  $quality ) ; 
		 }  else  if ( preg_match ( '/^image\/png$/i' ,  $mimeType ) ) { 
			 $imgType  =  'png' ;
			 imagepng ( $canvas ,  $tempfile ,  floor ( $quality  *  zero point zero nine ) ) ;
		 }  else  if ( preg_match ( '/^image\/gif$/i' ,  $mimeType ) ) {
			 $imgType  =  'gif' ;
			 imagegif ( $canvas ,  $tempfile ) ;
		 }  else  {
		  	 //If not, record this error and exit
			 return  $this -> sanityFail ( "Could not match mime type after verifying it previously." ) ;
		 }
		 //Give priority to using optimpng tool to compress png images, provided that you have installed the tool
		 if ( $imgType  ==  'png'  && OPTIPNG_ENABLED && OPTIPNG_PATH &&  @ is_file ( OPTIPNG_PATH ) ) {
		  	 //Record the address of optipng
		  	 $exec  = OPTIPNG_PATH ;
			 //Write logs to record that optipng will run, level 3
			 $this -> debug ( three ,  "optipng'ing $tempfile " ) ;
			 //Get Picture Size
			 $presize  =  filesize ( $tempfile ) ;
			 //Perform image compression operation
			 $out  = ` $exec  - o1 $tempfile ` ;
		       	 //Clear file status cache
			 clearstatcache ( ) ;
			 //Get the compressed file size
			 $aftersize  =  filesize ( $tempfile ) ;
			 //Calculate how much compression
			 $sizeDrop  =  $presize  -  $aftersize ;
			 //Write logs according to different calculated values, level 1
			 if ( $sizeDrop  >  zero ) {
				 $this -> debug ( one ,  "optipng reduced size by $sizeDrop " ) ;
			 }  else  if ( $sizeDrop  <  zero ) {
				 $this -> debug ( one ,  "optipng increased size! Difference was: $sizeDrop " ) ;
			 }  else  {
				 $this -> debug ( one ,  "optipng did not change image size." ) ;
			 }
		 //Optipng does not exist. Try pngcrush
		 }  else  if ( $imgType  ==  'png'  && PNGCRUSH_ENABLED && PNGCRUSH_PATH &&  @ is_file ( PNGCRUSH_PATH ) ) {
		  	 $exec  = PNGCRUSH_PATH ;
			 //Different from optimpng, pngcrush will generate a new file from the processed file, so create a new file here
			 $tempfile2  =  tempnam ( $this -> cacheDirectory ,  'timthumb_tmpimg_' ) ;
			 //Write logs and record file names
			 $this -> debug ( three ,  "pngcrush'ing $tempfile to $tempfile2 " ) ;
			 //Run pngcrush
			 $out  = ` $exec  $tempfile  $tempfile2 ` ;
			 $todel  =  "" ;
			 //If the file is generated successfully
			 if ( is_file ( $tempfile2 ) ) {
			  	 //Calculate the difference of the compressed file size
			  	 $sizeDrop  =  filesize ( $tempfile )  -  filesize ( $tempfile2 ) ;
				 //If it is a valid compression, the compressed file will be used as the cache file
				 if ( $sizeDrop  >  zero ) {
					 $this -> debug ( one ,  "pngcrush was succesful and gave a $sizeDrop byte size reduction" ) ;
					 $todel  =  $tempfile ;
					 $tempfile  =  $tempfile2 ;
				 //Otherwise, this file is unnecessary
				 }  else  {
					 $this -> debug ( one ,  "pngcrush did not reduce file size. Difference was $sizeDrop bytes." ) ;
					 $todel  =  $tempfile2 ;
				 }
			 //You need to delete this file if it does not run successfully
			 }  else  {
				 $this -> debug ( three ,  "pngcrush failed with output: $out " ) ;
				 $todel  =  $tempfile2 ;
			 }
			 //Delete invalid files or large files before compression
			 @ unlink ( $todel ) ;
		 }
		 //Write the security header on the cached image
		 $this -> debug ( three ,  "Rewriting image with security header." ) ;
		 //Create a new cache file
		 $tempfile4  =  tempnam ( $this -> cacheDirectory ,  'timthumb_tmpimg_' ) ;
		 //
		 $context  =  stream_context_create  ( ) ;
		 //Read the generated image cache content
		 $fp  =  fopen ( $tempfile , 'r' , zero , $context ) ;
		 //Write the security header to the new cache file. The length of the security header should always be $this ->filePrependSecurityBlock+6
		 file_put_contents ( $tempfile4 ,  $this -> filePrependSecurityBlock  .  $imgType  .  ' ?'  .  '>' ) ;
		 //Write the read cache image content to a new cache file
		 file_put_contents ( $tempfile4 ,  $fp , FILE_APPEND ) ;
		 //Close File Resources
		 fclose ( $fp ) ;
		 //Delete previously unsafe picture cache files
		 @ unlink ( $tempfile ) ;
		 //Write logs and lock cache files ~ ~
		 $this -> debug ( three ,  "Locking and replacing cache file." ) ;
		 //Create lock file file name
		 $lockFile  =  $this -> cachefile  .  '.lock' ;
		 //Create or open lock file
		 $fh  =  fopen ( $lockFile ,  'w' ) ;
		 //Fail to create and exit directly
		 if ( !  $fh ) {
			 return  $this -> error ( "Could not open the lockfile for writing an image." ) ;
		 }
		 //If the write lock is successfully added to the lock file
		 if ( flock ( $fh , LOCK_EX ) ) {
		  	 //Delete the original cache file
		  	 @ unlink ( $this -> cachefile ) ; 
			 //Rename the overwrite and use the secure cache file as the cache file
			 rename ( $tempfile4 ,  $this -> cachefile ) ;
			 //Release the write lock
			 flock ( $fh , LOCK_UN ) ;
			 //Free resources
			 fclose ( $fh ) ;
			 //Delete lock file
			 @ unlink ( $lockFile ) ;
		 //Otherwise
		 }  else  {
		  	 //Close Resources
		  	 fclose ( $fh ) ;
			 //Delete lock file
			 @ unlink ( $lockFile ) ;
			 //Delete a secure cache file
			 @ unlink ( $tempfile4 ) ;
			 //Log errors and exit
			 return  $this -> error ( "Could not get a lock for writing." ) ;
		 }
		 //Write the log and record the completion of the operation
		 $this -> debug ( three ,  "Done image replace with security header. Cleaning up and running cleanCache()" ) ;
		 //Free picture resources
		 imagedestroy ( $canvas ) ;
		 imagedestroy ( $image ) ;
		 //Successfully generated cache returns true
		 return  true ;
	 }
 one two three four five six seven eight nine ten eleven twelve thirteen fourteen fifteen sixteen seventeen eighteen nineteen twenty twenty-one twenty-two twenty-three twenty-four twenty-five twenty-six twenty-seven twenty-eight twenty-nine thirty thirty-one thirty-two thirty-three thirty-four thirty-five thirty-six thirty-seven thirty-eight thirty-nine forty forty-one forty-two forty-three forty-four forty-five forty-six forty-seven forty-eight forty-nine fifty fifty-one fifty-two fifty-three fifty-four fifty-five fifty-six fifty-seven fifty-eight fifty-nine sixty sixty-one sixty-two sixty-three sixty-four sixty-five sixty-six sixty-seven sixty-eight sixty-nine seventy seventy-one seventy-two seventy-three seventy-four seventy-five seventy-six seventy-seven seventy-eight seventy-nine eighty eighty-one eighty-two eighty-three eighty-four eighty-five eighty-six eighty-seven eighty-eight eighty-nine ninety ninety-one ninety-two ninety-three ninety-four ninety-five ninety-six ninety-seven ninety-eight ninety-nine one hundred one hundred and one one hundred and two one hundred and three one hundred and four one hundred and five one hundred and six one hundred and seven one hundred and eight one hundred and nine one hundred and ten one hundred and eleven one hundred and twelve one hundred and thirteen one hundred and fourteen one hundred and fifteen one hundred and sixteen one hundred and seventeen one hundred and eighteen one hundred and nineteen one hundred and twenty one hundred and twenty-one one hundred and twenty-two one hundred and twenty-three one hundred and twenty-four one hundred and twenty-five one hundred and twenty-six one hundred and twenty-seven one hundred and twenty-eight one hundred and twenty-nine one hundred and thirty one hundred and thirty-one one hundred and thirty-two one hundred and thirty-three one hundred and thirty-four one hundred and thirty-five one hundred and thirty-six one hundred and thirty-seven one hundred and thirty-eight one hundred and thirty-nine one hundred and forty one hundred and forty-one one hundred and forty-two one hundred and forty-three one hundred and forty-four one hundred and forty-five one hundred and forty-six one hundred and forty-seven one hundred and forty-eight one hundred and forty-nine one hundred and fifty one hundred and fifty-one one hundred and fifty-two one hundred and fifty-three one hundred and fifty-four one hundred and fifty-five one hundred and fifty-six one hundred and fifty-seven one hundred and fifty-eight one hundred and fifty-nine one hundred and sixty one hundred and sixty-one one hundred and sixty-two one hundred and sixty-three one hundred and sixty-four one hundred and sixty-five one hundred and sixty-six one hundred and sixty-seven one hundred and sixty-eight one hundred and sixty-nine one hundred and seventy one hundred and seventy-one one hundred and seventy-two one hundred and seventy-three one hundred and seventy-four one hundred and seventy-five one hundred and seventy-six one hundred and seventy-seven one hundred and seventy-eight one hundred and seventy-nine one hundred and eighty one hundred and eighty-one one hundred and eighty-two one hundred and eighty-three one hundred and eighty-four one hundred and eighty-five one hundred and eighty-six one hundred and eighty-seven one hundred and eighty-eight one hundred and eighty-nine one hundred and ninety one hundred and ninety-one one hundred and ninety-two one hundred and ninety-three one hundred and ninety-four one hundred and ninety-five one hundred and ninety-six one hundred and ninety-seven one hundred and ninety-eight one hundred and ninety-nine two hundred two hundred and one two hundred and two two hundred and three two hundred and four two hundred and five two hundred and six two hundred and seven two hundred and eight two hundred and nine two hundred and ten two hundred and eleven two hundred and twelve two hundred and thirteen two hundred and fourteen two hundred and fifteen two hundred and sixteen two hundred and seventeen two hundred and eighteen two hundred and nineteen two hundred and twenty two hundred and twenty-one two hundred and twenty-two two hundred and twenty-three two hundred and twenty-four two hundred and twenty-five two hundred and twenty-six two hundred and twenty-seven two hundred and twenty-eight two hundred and twenty-nine two hundred and thirty two hundred and thirty-one two hundred and thirty-two two hundred and thirty-three two hundred and thirty-four two hundred and thirty-five two hundred and thirty-six two hundred and thirty-seven two hundred and thirty-eight two hundred and thirty-nine two hundred and forty two hundred and forty-one two hundred and forty-two two hundred and forty-three two hundred and forty-four two hundred and forty-five two hundred and forty-six two hundred and forty-seven two hundred and forty-eight two hundred and forty-nine two hundred and fifty two hundred and fifty-one two hundred and fifty-two two hundred and fifty-three two hundred and fifty-four two hundred and fifty-five two hundred and fifty-six two hundred and fifty-seven two hundred and fifty-eight two hundred and fifty-nine two hundred and sixty two hundred and sixty-one two hundred and sixty-two two hundred and sixty-three two hundred and sixty-four two hundred and sixty-five two hundred and sixty-six two hundred and sixty-seven two hundred and sixty-eight two hundred and sixty-nine two hundred and seventy two hundred and seventy-one two hundred and seventy-two two hundred and seventy-three two hundred and seventy-four two hundred and seventy-five two hundred and seventy-six two hundred and seventy-seven two hundred and seventy-eight two hundred and seventy-nine two hundred and eighty two hundred and eighty-one two hundred and eighty-two two hundred and eighty-three two hundred and eighty-four two hundred and eighty-five two hundred and eighty-six two hundred and eighty-seven two hundred and eighty-eight two hundred and eighty-nine two hundred and ninety two hundred and ninety-one two hundred and ninety-two two hundred and ninety-three two hundred and ninety-four two hundred and ninety-five two hundred and ninety-six two hundred and ninety-seven two hundred and ninety-eight two hundred and ninety-nine three hundred three hundred and one three hundred and two three hundred and three three hundred and four three hundred and five three hundred and six three hundred and seven three hundred and eight three hundred and nine three hundred and ten three hundred and eleven three hundred and twelve three hundred and thirteen three hundred and fourteen three hundred and fifteen three hundred and sixteen three hundred and seventeen three hundred and eighteen three hundred and nineteen three hundred and twenty three hundred and twenty-one three hundred and twenty-two three hundred and twenty-three three hundred and twenty-four three hundred and twenty-five three hundred and twenty-six three hundred and twenty-seven three hundred and twenty-eight three hundred and twenty-nine three hundred and thirty three hundred and thirty-one three hundred and thirty-two three hundred and thirty-three three hundred and thirty-four three hundred and thirty-five three hundred and thirty-six three hundred and thirty-seven three hundred and thirty-eight three hundred and thirty-nine three hundred and forty three hundred and forty-one three hundred and forty-two three hundred and forty-three three hundred and forty-four three hundred and forty-five three hundred and forty-six three hundred and forty-seven three hundred and forty-eight three hundred and forty-nine three hundred and fifty three hundred and fifty-one three hundred and fifty-two three hundred and fifty-three three hundred and fifty-four three hundred and fifty-five three hundred and fifty-six three hundred and fifty-seven three hundred and fifty-eight three hundred and fifty-nine three hundred and sixty three hundred and sixty-one three hundred and sixty-two three hundred and sixty-three three hundred and sixty-four three hundred and sixty-five three hundred and sixty-six three hundred and sixty-seven three hundred and sixty-eight three hundred and sixty-nine three hundred and seventy three hundred and seventy-one three hundred and seventy-two three hundred and seventy-three three hundred and seventy-four three hundred and seventy-five three hundred and seventy-six three hundred and seventy-seven three hundred and seventy-eight three hundred and seventy-nine three hundred and eighty three hundred and eighty-one three hundred and eighty-two three hundred and eighty-three three hundred and eighty-four three hundred and eighty-five three hundred and eighty-six three hundred and eighty-seven three hundred and eighty-eight three hundred and eighty-nine three hundred and ninety three hundred and ninety-one three hundred and ninety-two three hundred and ninety-three three hundred and ninety-four three hundred and ninety-five three hundred and ninety-six three hundred and ninety-seven three hundred and ninety-eight three hundred and ninety-nine four hundred four hundred and one four hundred and two four hundred and three four hundred and four four hundred and five four hundred and six four hundred and seven four hundred and eight four hundred and nine four hundred and ten four hundred and eleven four hundred and twelve four hundred and thirteen four hundred and fourteen four hundred and fifteen four hundred and sixteen four hundred and seventeen
 /*This function is used to get the server document root directory*/
	 protected  function calcDocRoot ( ) {
	  	 //Get the document root directory directly
	  	 $docRoot  =  @ $_SERVER [ 'DOCUMENT_ROOT' ] ;
		 //Use this value if LOCAL_FILE_BASE_DIRECTORY is defined
		 if  ( defined ( 'LOCAL_FILE_BASE_DIRECTORY' ) )  {
			 $docRoot  = LOCAL_FILE_BASE_DIRECTORY ;   
		 }
		 //If the document root directory is not obtained, that is, the value of DOCUMENT_ROOT
		 if ( ! isset ( $docRoot ) ) {
		  	 //Write a record indicating that DOCUMENT_ROOT is not found. Note that the level is 3
		  	 $this -> debug ( three ,  "DOCUMENT_ROOT is not set. This is probably windows. Starting search 1." ) ;
			 //Use SCRIPT_FILENAME and PHP_SELF to get the document root directory
			 if ( isset ( $_SERVER [ 'SCRIPT_FILENAME' ] ) ) {
			  	 $docRoot  =  str_replace (  '\\' ,  '/' ,  substr ( $_SERVER [ 'SCRIPT_FILENAME' ] ,  zero ,  zero - strlen ( $_SERVER [ 'PHP_SELF' ] ) ) ) ;
				 //Write a record indicating that the value of DOCUMENT_ROOT is obtained through SCRIPT_FILENAME and PHP_SELF, level 3
				 $this -> debug ( three ,  "Generated docRoot using SCRIPT_FILENAME and PHP_SELF as: $docRoot " ) ;
			 } 
		 }
		 //If the document root directory is still not obtained
		 if ( ! isset ( $docRoot ) ) {
		  	 //Write a record first, indicating that the DOCUMENT_ROOT, level 3, has not been obtained
		  	 $this -> debug ( three ,  "DOCUMENT_ROOT still is not set. Starting search 2." ) ;
			 //The document root directory is obtained through PATH_TRANSLATED and PHP_SELF. For the description of PATH_TRANSLATED, see here: http://blogs.msdn.com/b/david.wang/archive/2005/08/04/what-is-path-translated.aspx
			 if ( isset ( $_SERVER [ 'PATH_TRANSLATED' ] ) ) {
			  	 $docRoot  =  str_replace (  '\\' ,  '/' ,  substr ( str_replace ( '\\\\' ,  '\\' ,  $_SERVER [ 'PATH_TRANSLATED' ] ) ,  zero ,  zero - strlen ( $_SERVER [ 'PHP_SELF' ] ) ) ) ;
				 //Write a record, indicating that the value of DOCUMENT_ROOT is obtained through PATH_TRANSLATED and PHP_SELF, level 3
				 $this -> debug ( three ,  "Generated docRoot using PATH_TRANSLATED and PHP_SELF as: $docRoot " ) ;
			 } 
		 }
		 //If the document root is not the server root, remove the last '/'
		 if ( $docRoot  &&  $_SERVER [ 'DOCUMENT_ROOT' ]  !=  '/' ) {  $docRoot  =  preg_replace ( '/\/$/' ,  '' ,  $docRoot ) ;  }
		 //Write a record indicating the value of the document root directory, level 3
		 $this -> debug ( three ,  "Doc root is: "  .  $docRoot ) ;
		 //Assign value to member property
		 $this -> docRoot  =  $docRoot ;   }   /*This function is used to obtain the local image address. The parameter src is the address relative to the document root directory*/
	 protected  function getLocalImagePath ( $src ) {
	  	 //Remove the beginning/
	 	  $src  =  ltrim ( $src ,  '/' ) ;
		  //If the document root directory has not been obtained previously, for security reasons, only the images in the directory where timthumbs.php is located can be operated here
		  if ( !  $this -> docRoot ) {
		   	 //Write a log, level 3, indicating that the image address is checked below
			 $this -> debug ( three ,  "We have no document root set, so as a last resort, lets check if the image is in the current dir and serve that." ) ;
			 //Get the file name with all path information removed
			 $file  =  preg_replace ( '/^.*? ([^\/\\\\]+)$/' ,  '$1' ,  $src ) ; 
			 //If the image file and timthumb.php are in the same directory
			 if ( is_file ( $file ) ) {
			  	 //Return the path of this picture
				 return  $this -> realpath ( $file ) ;
			 }
			 //If the image file and timthumb.php are not in the same directory, write an error message. For security reasons, a file without a document root directory and outside the directory where timthumbs.php is located will not be allowed
			 return  $this -> error ( "Could not find your website document root and the file specified doesn't exist in timthumbs directory. We don't support serving files outside timthumb's directory without a document root for security reasons." ) ;
		 }   //Try to find this picture, if the picture address exists
		  if ( file_exists  ( $this -> docRoot  .  '/'  .  $src ) )  {
		   	 //Write log, record file address, level 3
		   	 $this -> debug ( three ,  "Found file as "  .  $this -> docRoot  .  '/'  .  $src ) ;
			 //Return image path
			 $real  =  $this -> realpath ( $this -> docRoot  .  '/'  .  $src ) ;
			 //Verify that the image path is on the local computer
			 if ( stripos ( $real ,  $this -> docRoot )  ===  zero ) {
			  	 //If yes, return the image address
				 return  $real ;
			 }  else  {
			  	 //Otherwise, write the log. The specified file is not found. Level 1
				 $this -> debug ( one ,  "Security block: The file specified occurs outside the document root." ) ;
			 }
		 }   //Then look for...
		  $absolute  =  $this -> realpath ( '/'  .  $src ) ;
		  //If it is determined that the address exists
		  if ( $absolute  &&  file_exists ( $absolute ) ) {
		  	 //Write a log, record the absolute address of the picture, level 3
		   	 $this -> debug ( three ,  "Found absolute path: $absolute " ) ;
			 //If the document root directory is not defined, record this error message
			 if ( !  $this -> docRoot ) {  $this -> sanityFail ( "docRoot not set when checking absolute path." ) ;  }
			 //Verify that the image path is on the local computer
			 if ( stripos ( $absolute ,  $this -> docRoot )  ===  zero ) {
				 //Return the image address if you are in
				 return  $absolute ;
			 }  else  {
			  	 //Otherwise, write the log. The specified file is not found. Level 1
				 $this -> debug ( one ,  "Security block: The file specified occurs outside the document root." ) ;
			 }
		 }   //If the specified file has not been found, search up level by level
		 $base  =  $this -> docRoot ;   //Get the list of query subdirectories
		 if  ( strstr ( $_SERVER [ 'SCRIPT_FILENAME' ] , ':' ) )  {
			 $sub_directories  =  explode ( '\\' ,  str_replace ( $this -> docRoot ,  '' ,  $_SERVER [ 'SCRIPT_FILENAME' ] ) ) ;
		 }  else  {
			 $sub_directories  =  explode ( '/' ,  str_replace ( $this -> docRoot ,  '' ,  $_SERVER [ 'SCRIPT_FILENAME' ] ) ) ;
		 }
		 //Traverse subdirectory array
		 foreach  ( $sub_directories  as  $sub ) {
		  	 //Recombine request addresses
		  	 $base  .=  $sub  .  '/' ;
			 //Write log, record search record, level 3
			 $this -> debug ( three ,  "Trying file as: "  .  $base  .  $src ) ;
			 //If this file is found
			 if ( file_exists ( $base  .  $src ) ) {
			  	 //Write log, record file address, level 3
			  	 $this -> debug ( three ,  "Found file as: "  .  $base  .  $src ) ;
				 //Get the actual address
				 $real  =  $this -> realpath ( $base  .  $src ) ;
				 //If the actual address is in the local machine, return this address
				 if ( stripos ( $real ,  $this -> realpath ( $this -> docRoot ) )  ===  zero ) {
					 return  $real ;
				 }  else  {
				  	 //Write log if not found, level 1
					 $this -> debug ( one ,  "Security block: The file specified occurs outside the document root." ) ;
				 }
			 }
		 }
		 //If it cannot be found, false is returned;
		 return  false ;
	 }
	 /*This function is used to obtain the real path of the passed in file parameters*/
	 protected  function  realpath ( $path ) {
		 //Removal path with Relative path of
		 $remove_relatives  =  '/\w+\/\.\.\//' ;
		 while ( preg_match ( $remove_relatives , $path ) ) {
		     $path  =  preg_replace ( $remove_relatives ,  '' ,  $path ) ;
		 }
		 //If there is still To return the path, use the realpath function to return the path, otherwise, return directly
		 return  preg_match ( '#^\.\./|/\.\./#' ,  $path ) ? realpath ( $path )  :  $path ;
	 }
	 /*This function is used to record the list of resources to be deleted in the destructor*/
	 protected  function toDelete ( $name ) {
	  	 //Write a log to record the file information to be deleted
	  	 $this -> debug ( three ,  "Scheduling file $name to delete on destruct." ) ;
		 //Add to array to be deleted
		 $this -> toDeletes [ ]  =  $name ;
	 }
	 /*This function is the specific implementation of screenshot operation*/
	 protected  function serveWebshot ( ) {
	  	 //Write a log to record the starting screenshot operation, level 3
	  	 $this -> debug ( three ,  "Starting serveWebshot" ) ;
		 //A prompt text, you can go to http://code.google.com/p/timthumb/ Follow the tutorial to set the website screenshot on
		 $instr  =  "Please follow the instructions at  http://code.google.com/p/timthumb/  to set your server up for taking website screenshots." ;
		 //If CutyCap does not exist
		 if ( !  is_file ( WEBSHOT_CUTYCAPT ) ) {
		  	 //Exit execution and record that CutyCap is not installed
			 return  $this -> error ( "CutyCapt is not installed. $instr " ) ;
		 }
		 //If xvfb does not exist
		 if ( !  is_file ( WEBSHOT_XVFB ) ) {
		  	 //Exit execution and record that xvfb is not installed
			 return  $this -> Error ( "Xvfb is not installed. $instr " ) ;
		 }
		 //CUTYCAPT address
		 $cuty  = WEBSHOT_CUTYCAPT ;
		 //Xvfb address
		 $xv  = WEBSHOT_XVFB ;
		 //Screenshot screen width
		 $screenX  = WEBSHOT_SCREEN_X ;
		 //Screenshot screen height
		 $screenY  = WEBSHOT_SCREEN_Y ;
		 //Screenshot color depth
		 $colDepth  = WEBSHOT_COLOR_DEPTH ;
		 //Screenshot saving format
		 $format  = WEBSHOT_IMAGE_FORMAT ;
		 //Screenshot timeout, in ms
		 $timeout  = WEBSHOT_TIMEOUT *  one thousand ;
		 //USER_AGENT header
		 $ua  = WEBSHOT_USER_AGENT ;
		 //Enable js
		 $jsOn  = WEBSHOT_JAVASCRIPT_ON ? 'on'  :  'off' ;
		 //Enable java
		 $javaOn  = WEBSHOT_JAVA_ON ? 'on'  :  'off' ;
		 //Whether to enable other plug-ins
		 $pluginsOn  = WEBSHOT_PLUGINS_ON ? 'on'  :  'off' ;
		 //Enable Agent
		 $proxy  = WEBSHOT_PROXY ? ' --http-proxy='  . WEBSHOT_PROXY :  '' ;
		 //In the cache file directory, create a file with a unique file name prefixed with timthumb_webshot. The user stores the image after the screenshot
		 $tempfile  =  tempnam ( $this -> cacheDirectory ,  'timthumb_webshot' ) ;
		 //Destination website address
		 $url  =  $this -> src ;
		 //Verify the validity of the url
		 if ( !  preg_match ( '/^https?:\/\/ [a-zA-Z0-9\.\-]+/i' ,  $url ) ) {
		  	 //Illegal withdrawal from execution
			 return  $this -> error ( "Invalid URL supplied." ) ;
		 }
		 //Filter out illegal characters
		 $url  =  preg_replace ( '/[^A-Za-z0-9\-\.\_\~:\/\?\#\[\]\@\!\$\&\'\ (\)\*\+\,\;\=]+/' ,  '' ,  $url ) ;
		 //CUTYCAPT is preferred
		 if ( WEBSHOT_XVFB_RUNNING ) {
		  	 //Set the system variable to configure the graphic output display.
		  	 putenv ( 'DISPLAY=:100.0' ) ;
			 //Assemble shell commands
			 $command  =  " $cuty  $proxy --max-wait= $timeout --user-agent= \" $ua \" --javascript= $jsOn --java= $javaOn --plugins= $pluginsOn --js-can-open-windows=off --url= \" $url \" --out-format= $format --out= $tempfile " ;
		 //Otherwise, use XVFB
		 }  else  {
			 $command  =  " $xv --server-args= \" -screen 0, {$screenX} x {$screenY} x {$colDepth} \"  $cuty  $proxy --max-wait= $timeout --user-agent= \" $ua \" --javascript= $jsOn --java= $javaOn --plugins= $pluginsOn --js-can-open-windows=off --url= \" $url \" --out-format= $format --out= $tempfile " ;
		 }
		 //Write log, record the command executed, level 3
		 $this -> debug ( three ,  "Executing command: $command " ) ;
		 //Execute commands and capture output
		 $out  = ` $command ` ;
		 //Write log, record output, level 3
		 $this -> debug ( three ,  "Received output: $out " ) ;
		 //If the file with the unique file name just created fails
		 if ( !  is_file ( $tempfile ) ) {
		  	 //Setting 404 error
		  	 $this -> set404 ( ) ;
		  	 //Roll out script
			 return  $this -> error ( "The command to create a thumbnail failed." ) ;
		 }
		 //Enable Cropping
		 $this -> cropTop  =  true ;
		 //Process the captured image file and generate a cache
		 if ( $this -> processImageAndWriteToCache ( $tempfile ) ) {
		  	 //If successful, write the log and read the image from the cache
		  	 $this -> debug ( three ,  "Image processed succesfully. Serving from cache" ) ;
			 //Returns the contents of the file read from the cache
			 return  $this -> serveCacheFile ( ) ;
		 //If it doesn't succeed, it will return to false
		 }  else  {
			 return  false ;
		 }
	 }
	 /*This function is used to obtain an image from an external url*/
	 protected  function serveExternalImage ( ) {
	  	 //Verify the validity of the url
		 if ( !  preg_match ( '/^https?:\/\/ [a-zA-Z0-9\-\.]+/i' ,  $this -> src ) ) {
			 $this -> error ( "Invalid URL supplied." ) ;
			 return  false ;
		 }
		 //Generate temporary cache file
		 $tempfile  =  tempnam ( $this -> cacheDirectory ,  'timthumb' ) ;
		 //Write log, record reading external image to temporary file, level 3
		 $this -> debug ( three ,  "Fetching external image into temporary file $tempfile " ) ;
		 //Add temporary cache files to the list to be deleted
		 $this -> toDelete ( $tempfile ) ;
		 //Request the url and write the result to the temporary cache file. If it fails
		 if ( !  $this -> getURL ( $this -> src ,  $tempfile ) ) {
		  	 //Delete this cache file
		  	 @ unlink ( $this -> cachefile ) ;
			 //Create a new cache file
			 touch ( $this -> cachefile ) ;
			 //Write log, record error information, level 3
			 $this -> debug ( three ,  "Error fetching URL: "  .  $this -> lastURLError ) ;
			 //Write an error message and exit
			 $this -> error ( "Error reading the URL you specified from remote host."  .  $this -> lastURLError ) ;
			 return  false ;
		 }
		 //Get the MIME type of the obtained picture
		 $mimeType  =  $this -> getMimeType ( $tempfile ) ;
		 //If not in the three types
		 if ( !  preg_match ( "/^image\/(?:jpg|jpeg|gif|png)$/i" ,  $mimeType ) ) {
		  	 //Write log, record error information, level 3
		  	 $this -> debug ( three ,  "Remote file has invalid mime type: $mimeType " ) ;
			 //Delete existing cache file
			 @ unlink ( $this -> cachefile ) ;
			 //Create a new cache file
			 touch ( $this -> cachefile ) ;
			 //Write error message and exit
			 $this -> error ( "The remote file is not a valid image." ) ;
			 return  false ;
		 }
		 //Process image and cache
		 if ( $this -> processImageAndWriteToCache ( $tempfile ) ) {
		  	 $this -> debug ( three ,  "Image processed succesfully. Serving from cache" ) ;
		  	 //Return cache information if successful
			 return  $this -> serveCacheFile ( ) ;
		 }  else  {
		  	 //Failure returns false
			 return  false ;
		 }
	 }
	 /*This function is used to write the data obtained by curl to the corresponding file*/
	 public static function curlWrite ( $h ,  $d ) {
	  	 //Write data to file
	  	 fwrite ( self :: $curlFH ,  $d ) ;
		 //Record data length
		 self :: $curlDataWritten  +=  strlen ( $d ) ;
		 //If the image size exceeds the limit of the configuration file, 0 is returned
		 if ( self :: $curlDataWritten  > MAX_FILE_SIZE ) {
		  	 return  zero ;
		 //Otherwise, return to the image size
		 }  else  {
			 return  strlen ( $d ) ;
		 }
	 }
	 /*This function is used to read and output the server cache*/
	 protected  function serveCacheFile ( ) {
	  	 //Write a log to record the address of the read cache
	  	 $this -> debug ( three ,  "Serving {$this->cachefile} " ) ;
		 //If the cache address is invalid
		 if ( !  is_file ( $this -> cachefile ) ) {
		  	 //Add to error record
		  	 $this -> error ( "serveCacheFile called in timthumb but we couldn't find the cached file." ) ;
			 //Stop executing script
			 return  false ;
		 }
		 //If the cache address is valid, the file has been opened in read-only mode
		 $fp  =  fopen ( $this -> cachefile ,  'rb' ) ;
		 //If the opening fails, exit the script directly and record the error message
		 if ( !  $fp ) {  return  $this -> error ( "Could not open cachefile." ) ;  }
		 //Set the file pointer to skip the filePrependSecurityBlock value, that is, start reading after skipping the security header
		 fseek ( $fp ,  strlen ( $this -> filePrependSecurityBlock ) , SEEK_SET ) ;
		 //Read the mime type of the file
		 $imgType  =  fread ( $fp ,  three ) ;
		 //Skip the mime value again
		 fseek ( $fp ,  three , SEEK_CUR ) ;
		 //If the current file pointer is not 6 characters after the security header, the cache file may be damaged
		 if ( ftell ( $fp )  !=  strlen ( $this -> filePrependSecurityBlock )  +  six ) {
		  	 //Delete this cache file
		  	 @ unlink ( $this -> cachefile ) ;
			 //Log errors and exit execution
			 return  $this -> error ( "The cached image file seems to be corrupt." ) ;
		 }
		 //The actual size of the cached image should be the file size - security header size
		 $imageDataSize  =  filesize ( $this -> cachefile )  -  ( strlen ( $this -> filePrependSecurityBlock )  +  six ) ;
		 //Set the necessary HTTP headers for output
		 $this -> sendImageHeaders ( $imgType ,  $imageDataSize ) ;
		 //All remaining data at the output file pointer
		 $bytesSent  =  @ fpassthru ( $fp ) ;
		 //Close File Resources
		 fclose ( $fp ) ;
		 //Returns true if the method executes successfully
		 if ( $bytesSent  >  zero ) {
			 return  true ;
		 }
		 //If fpassthru fails, use file_get_contents to read and output
		 $content  =  file_get_contents  ( $this -> cachefile ) ;
		 //If the read is successful
		 if  ( $content  !=  FALSE )  {
		  	 //Intercept the safety head
		  	 $content  =  substr ( $content ,  strlen ( $this -> filePrependSecurityBlock )  +  six ) ;
			 //Output Image
			 echo  $content ;
			 //Write a log to record the way to read the cache
			 $this -> debug ( three ,  "Served using file_get_contents and echo" ) ;
			 return  true ;
		 //If reading fails, record the error message and exit the execution
		 }  else  {
			 $this -> error ( "Cache file could not be loaded." ) ;
			 return  false ;
		 }
	 }
	 /*This function sets the http header necessary for image output*/
	 protected  function sendImageHeaders ( $mimeType ,  $dataSize ) {
	  	 //Complete the mime information of the picture
		 if ( !  preg_match ( '/^image\//i' ,  $mimeType ) ) {
			 $mimeType  =  'image/'  .  $mimeType ;
		 }
		 //Write the mime type of jpg as standard. The reason why it is not standard here is that it pursues convenience when verifying the file security header
		 if ( strtolower ( $mimeType )  ==  'image/jpg' ) {
			 $mimeType  =  'image/jpeg' ;
		 }
		 //Browser cache expiration time
		 $gmdate_expires  =  gmdate  ( 'D, d M Y H:i:s' ,  strtotime  ( 'now +10 days' ) )  .  ' GMT' ;
		 //The last modification time of the document is used to let the browser judge whether to request the page again
		 $gmdate_modified  =  gmdate  ( 'D, d M Y H:i:s' )  .  ' GMT' ;
		 //Set HTTP header
		 header  ( 'Content-Type: '  .  $mimeType ) ;
		 header  ( 'Accept-Ranges: none' ) ; 
		 header  ( 'Last-Modified: '  .  $gmdate_modified ) ;
		 header  ( 'Content-Length: '  .  $dataSize ) ;
		 //If the configuration file prohibits browser caching, set the corresponding HTTP header information
		 if ( BROWSER_CACHE_DISABLE ) {
			 $this -> debug ( three ,  "Browser cache is disabled so setting non-caching headers." ) ;
			 header ( 'Cache-Control: no-store,  no-cache, must-revalidate, max-age=0' ) ;
			 header ( "Pragma: no-cache" ) ;
			 header ( 'Expires: '  .  gmdate  ( 'D, d M Y H:i:s' ,  time ( ) ) ) ;
		 //Otherwise, set the cache time according to the configuration file
		 }  else  {
			 $this -> debug ( three ,  "Browser caching is enabled" ) ;
			 header ( 'Cache-Control: max-age='  . BROWSER_CACHE_MAX_AGE .  ', must-revalidate' ) ;
			 header ( 'Expires: '  .  $gmdate_expires ) ;
		 }
		 //Return to true after running successfully
		 return  true ;
	 }
	 /*Custom validation function*/
	 protected  function securityChecks ( ) {
	 }
	 /*This function is used to obtain the parameters in the $_GET array and allow setting default values*/
	 protected  function param ( $property ,  $default  =  '' ) {
	  	 //This parameter is returned if it exists
		 if  ( isset  ( $_GET [ $property ] ) )  {
		  	 return  $_GET [ $property ] ;
		 //If it does not exist, return the default value
		 }  else  {
			 return  $default ;
		 }
	 }
	 /*This function opens the image resource according to the incoming mime type*/
	 protected  function openImage ( $mimeType ,  $src ) {
		 switch  ( $mimeType )  {
			 case  'image/jpeg' :
				 $image  =  imagecreatefromjpeg  ( $src ) ;
				 break ;   case  'image/png' :
				 $image  =  imagecreatefrompng  ( $src ) ;
				 break ;   case  'image/gif' :
				 $image  =  imagecreatefromgif  ( $src ) ;
				 break ;
			 //If not, the script will exit
			 default :
				 $this -> error ( "Unrecognised mimeType" ) ;
		 }
		 //Return to image resources
		 return  $image ;
	 }
 one two three four five six seven eight nine ten eleven twelve thirteen fourteen fifteen sixteen seventeen eighteen nineteen twenty twenty-one twenty-two twenty-three twenty-four twenty-five twenty-six twenty-seven twenty-eight twenty-nine thirty thirty-one thirty-two thirty-three thirty-four thirty-five thirty-six thirty-seven thirty-eight thirty-nine forty forty-one forty-two forty-three forty-four forty-five forty-six forty-seven forty-eight forty-nine fifty fifty-one fifty-two fifty-three fifty-four fifty-five fifty-six fifty-seven fifty-eight fifty-nine sixty sixty-one sixty-two sixty-three sixty-four sixty-five sixty-six sixty-seven sixty-eight sixty-nine seventy seventy-one seventy-two seventy-three seventy-four seventy-five seventy-six seventy-seven seventy-eight seventy-nine eighty eighty-one eighty-two eighty-three eighty-four eighty-five eighty-six eighty-seven eighty-eight eighty-nine ninety ninety-one ninety-two ninety-three ninety-four ninety-five ninety-six ninety-seven ninety-eight ninety-nine one hundred one hundred and one one hundred and two one hundred and three one hundred and four one hundred and five one hundred and six one hundred and seven one hundred and eight one hundred and nine one hundred and ten one hundred and eleven one hundred and twelve one hundred and thirteen one hundred and fourteen one hundred and fifteen one hundred and sixteen one hundred and seventeen one hundred and eighteen one hundred and nineteen one hundred and twenty one hundred and twenty-one one hundred and twenty-two one hundred and twenty-three one hundred and twenty-four one hundred and twenty-five one hundred and twenty-six one hundred and twenty-seven one hundred and twenty-eight one hundred and twenty-nine one hundred and thirty one hundred and thirty-one one hundred and thirty-two one hundred and thirty-three one hundred and thirty-four one hundred and thirty-five one hundred and thirty-six one hundred and thirty-seven one hundred and thirty-eight one hundred and thirty-nine one hundred and forty one hundred and forty-one one hundred and forty-two one hundred and forty-three one hundred and forty-four one hundred and forty-five one hundred and forty-six one hundred and forty-seven one hundred and forty-eight one hundred and forty-nine one hundred and fifty one hundred and fifty-one one hundred and fifty-two one hundred and fifty-three one hundred and fifty-four one hundred and fifty-five one hundred and fifty-six one hundred and fifty-seven one hundred and fifty-eight one hundred and fifty-nine one hundred and sixty one hundred and sixty-one one hundred and sixty-two one hundred and sixty-three one hundred and sixty-four one hundred and sixty-five one hundred and sixty-six one hundred and sixty-seven one hundred and sixty-eight one hundred and sixty-nine one hundred and seventy one hundred and seventy-one one hundred and seventy-two one hundred and seventy-three one hundred and seventy-four one hundred and seventy-five one hundred and seventy-six one hundred and seventy-seven one hundred and seventy-eight one hundred and seventy-nine one hundred and eighty one hundred and eighty-one one hundred and eighty-two one hundred and eighty-three one hundred and eighty-four one hundred and eighty-five one hundred and eighty-six one hundred and eighty-seven one hundred and eighty-eight one hundred and eighty-nine one hundred and ninety one hundred and ninety-one one hundred and ninety-two one hundred and ninety-three one hundred and ninety-four one hundred and ninety-five one hundred and ninety-six one hundred and ninety-seven one hundred and ninety-eight one hundred and ninety-nine two hundred two hundred and one two hundred and two two hundred and three two hundred and four two hundred and five two hundred and six two hundred and seven two hundred and eight two hundred and nine
	 /*Nothing to say, get the client IP*/
	 protected  function getIP ( ) {
		 $rem  =  @ $_SERVER [ "REMOTE_ADDR" ] ;
		 $ff  =  @ $_SERVER [ "HTTP_X_FORWARDED_FOR" ] ;
		 $ci  =  @ $_SERVER [ "HTTP_CLIENT_IP" ] ;
		 if ( preg_match ( '/^(?:192\.168|172\.16|10\.|127\.)/' ,  $rem ) ) { 
			 if ( $ff ) {  return  $ff ;  }
			 if ( $ci ) {  return  $ci ;  }
			 return  $rem ;
		 }  else  {
			 if ( $rem ) {  return  $rem ;  }
			 if ( $ff ) {  return  $ff ;  }
			 if ( $ci ) {  return  $ci ;  }
			 return  "UNKNOWN" ;
		 }
	 }
	 /*The debug run log function is used to record operation information to the system log*/
	 protected  function debug ( $level ,  $msg ) {
	  	 //If debug is enabled, and $level, that is, the debug level is less than or equal to the value in the configuration file, start recording
	  	 if ( DEBUG_ON &&  $level  <= DEBUG_LEVEL ) {
			 //Format and record the start time, with 6 decimal places reserved. This time represents the time from the instantiation of the class to the execution of this debug
		  	 $execTime  =  sprintf ( '%.6f' ,  microtime ( true )  -  $this -> startTime ) ;
			 //This value represents the time from the end of the last debug to this one
			 $tick  =  sprintf ( '%.6f' ,  zero ) ;
			 //If the last debug time exists, subtract the last debug time from the current time to get the difference
			 if ( $this -> lastBenchTime  >  zero ) {
				 $tick  =  sprintf ( '%.6f' ,  microtime ( true )  -  $this -> lastBenchTime ) ;
			 }
			 //Update time
			 $this -> lastBenchTime  =  microtime ( true ) ;
			 //Write the debug information to the system log
			 error_log ( "TimThumb Debug line "  .  __LINE__  .  " [ $execTime : $tick ]: $msg " ) ;
		 }
	 }
	 /*This function is used to record unknown BUGs*/
	 protected  function sanityFail ( $msg ) {
	  	 //Record BUG information
		 return  $this -> error ( "There is a problem in the timthumb code. Message: Please report this error at <a href=' http://code.google.com/p/timthumb/issues/list '>timthumb's bug tracking page</a>: $msg " ) ;
	 }
	 /*This function is used to return the MIME information of the picture file*/
	 protected  function getMimeType ( $file ) {
	  	 //Get information about picture files
	  	 $info  =  getimagesize ( $file ) ;
		 //If successful, MIME information will be returned
		 if ( is_array ( $info )  &&  $info [ 'mime' ] ) {
			 return  $info [ 'mime' ] ;
		 }
		 //Failed to return null
		 return  '' ;
	 }
	 /*This function is used to detect and set the maximum memory occupied by php runtime*/
	 protected  function setMemoryLimit ( ) {
	  	 //Get the maximum memory usage value in php.ini
	  	 $inimem  =  ini_get ( 'memory_limit' ) ;
		 //Convert the above value to a value in bytes
		 $inibytes  = timthumb :: returnBytes ( $inimem ) ;
		 //Calculate the value of the memory limit in the configuration file
		 $ourbytes  = timthumb :: returnBytes ( MEMORY_LIMIT ) ;
		 //If the value in the php configuration file is less than the value you set
		 if ( $inibytes  <  $ourbytes ) {
		  	 //Set the maximum memory value in the php.ini configuration to the value you set
		  	 ini_set  ( 'memory_limit' , MEMORY_LIMIT ) ;
		  	 //Write logs to record memory changes, level 3
			 $this -> debug ( three ,  "Increased memory from $inimem to "  . MEMORY_LIMIT ) ;
		 //If the value you set is less than the value in php.ini
		 }  else  {
		  	 //Then no operation will be performed, just write the log to record this information, level 3
			 $this -> debug ( three ,  "Not adjusting memory size because the current setting is "  .  $inimem  .  " and our size of "  . MEMORY_LIMIT .  " is smaller." ) ;
		 }
	 }
	 /*This function converts G, KB, MB to B (bytes)*/
	 protected static function returnBytes ( $size_str ) {
	  	 //Take the last unit value, perform conversion, and return the converted value
		 switch  ( substr  ( $size_str ,  - one ) )
		 {
			 case  'M' :  case  'm' :  return  ( int ) $size_str  *  one million forty-eight thousand five hundred and seventy-six ;
			 case  'K' :  case  'k' :  return  ( int ) $size_str  *  one thousand and twenty-four ;
			 case  'G' :  case  'g' :  return  ( int ) $size_str  *  one billion seventy-three million seven hundred and forty-one thousand eight hundred and twenty-four ;
			 default :  return  $size_str ;
		 }
	 }
	 /*This function is used to read the resources in the url into the tempfile file*/
	 protected  function getURL ( $url ,  $tempfile ) {
	  	 //Reset the last url request error message
	  	 $this -> lastURLError  =  false ;
	  	 //URL encoding
		 $url  =  preg_replace ( '/ /' ,  '%20' ,  $url ) ;
		 //Prefer curl extension
		 if ( function_exists ( 'curl_init' ) ) {
		  	 //Write logs to record that the url will be accessed using the curl extension, level 3
		  	 $this -> debug ( three ,  "Curl is installed so using it to fetch URL." ) ;
			 //Open File
			 self :: $curlFH  =  fopen ( $tempfile ,  'w' ) ;
			 //If the opening fails, record the error message and exit
			 if ( !  self :: $curlFH ) {
				 $this -> error ( "Could not open $tempfile for writing." ) ;
				 return  false ;
			 }
			 //Reset Write Length
			 self :: $curlDataWritten  =  zero ;
			 //Write logs to record the URL information accessed, level 3
			 $this -> debug ( three ,  "Fetching url with curl: $url " ) ;
			 //Initialize curl
			 $curl  =  curl_init ( $url ) ;
			 //Curl option setting
			 curl_setopt  ( $curl , CURLOPT_TIMEOUT , CURL_TIMEOUT ) ;
			 curl_setopt  ( $curl , CURLOPT_USERAGENT ,  "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/534.30 (KHTML, like Gecko) Chrome/12.0.742.122 Safari/534.30" ) ;
			 curl_setopt  ( $curl , CURLOPT_RETURNTRANSFER ,  TRUE ) ;
			 curl_setopt  ( $curl , CURLOPT_HEADER ,  zero ) ;
			 curl_setopt  ( $curl , CURLOPT_SSL_VERIFYPEER ,  FALSE ) ;
			 //Execute curlWrite when closing a session
			 curl_setopt  ( $curl , CURLOPT_WRITEFUNCTION ,  'timthumb::curlWrite' ) ;
			 @ curl_setopt  ( $curl , CURLOPT_FOLLOWLOCATION ,  true ) ;
			 @ curl_setopt  ( $curl , CURLOPT_MAXREDIRS ,  ten ) ;
			 //Execute this request and assign the result to $curlResult
			 $curlResult  =  curl_exec ( $curl ) ;
			 //Free file resources
			 fclose ( self :: $curlFH ) ;
			 //Get the last received HTTP code
			 $httpStatus  =  curl_getinfo ( $curl , CURLINFO_HTTP_CODE ) ;
			 //If it is 404, set 404 error and exit
			 if ( $httpStatus  ==  four hundred and four ) {
				 $this -> set404 ( ) ;
			 }
			 //If the request is successful
			 if ( $curlResult ) {
			  	 //Close curl and execute curlWrite to write data to the file
			  	 curl_close ( $curl ) ;
			  	 //Return to true, request completed
				 return  true ;
			 //If the request is unsuccessful
			 }  else  {
			  	 //Log error messages
			  	 $this -> lastURLError  =  curl_error ( $curl ) ;
				 //Close Resources
				 curl_close ( $curl ) ;
				 //Unsuccessful execution
				 return  false ;
			 }
		 //If curl is not supported, use file_get_contents to obtain data
		 }  else  {
		  	 //Get Data
		  	 $img  =  @ file_get_contents  ( $url ) ;
			 //If the acquisition fails
			 if ( $img  ===  false ) {
			  	 //Array of error information returned by the record
			  	 $err  =  error_get_last ( ) ;
			  	 //If yes, and there is an error message
				 if ( is_array ( $err )  &&  $err [ 'message' ] ) {
				  	 //This error message will be recorded
				  	 $this -> lastURLError  =  $err [ 'message' ] ;
				 //Otherwise, record the entire error message
				 }  else  {
					 $this -> lastURLError  =  $err ;
				 }
				 //If there is 404 in the error message, it is set as 404 error
				 if ( preg_match ( '/404/' ,  $this -> lastURLError ) ) {
					 $this -> set404 ( ) ;
				 }
				 //Return false
				 return  false ;
			 }
			 //If the read picture fails to be written to the file
			 if ( !  file_put_contents ( $tempfile ,  $img ) ) {
			  	 //Write error message and exit execution
				 $this -> error ( "Could not write to $tempfile ." ) ;
				 return  false ;
			 }
			 //If there is no problem, the execution is successful
			 return  true ;
		 }   }
 /*This function outputs the specified picture, which is used to output the error message*/
	 protected  function serveImg ( $file ) {
	  	 //Get image information
	  	 $s  =  getimagesize ( $file ) ;
		 //If image information is not available, push
		 if ( !  ( $s  &&  $s [ 'mime' ] ) ) {
			 return  false ;
		 }
		 //Set http header and output pictures
		 header  ( 'Content-Type: '  .  $s [ 'mime' ] ) ;
		 header  ( 'Content-Length: '  .  filesize ( $file )  ) ;
		 header  ( 'Cache-Control: no-store,  no-cache, must-revalidate, max-age=0' ) ;
		 header  ( "Pragma: no-cache" ) ;
		 //Use readfile to output pictures
		 $bytes  =  @ readfile ( $file ) ;
		 if ( $bytes  >  zero ) {
			 return  true ;
		 }
		 //If it fails, use file_get_contents and echo to output the image
		 $content  =  @ file_get_contents  ( $file ) ;
		 if  ( $content  !=  FALSE ) {
			 echo  $content ;
			 return  true ;
		 }
		 //If it still fails, return false
		 return  false ;
	 }
	 /*This function sets the 404 error code*/
	 protected  function set404 ( ) {
		 $this -> is404  =  true ;
	 }
	 /*This function returns 404 error code*/
	 protected  function is404 ( ) {
		 return  $this -> is404 ;
	 }
 }

Attachment:

Timthumb.php thumbnail access address structure:
 one
 http://localhost/timthumb.php?src=http://localhost/200.jpg &amp; w=200 &amp; h=300 &amp; q=100 &amp; f=3,9|4,2 &amp; s=1 &amp; ct=1
The parameters are all submitted by get. Parameter description:
  • Src: the address of the source image that needs to be scaled, or the address of the web page that needs to be screenshot
  • Webshot: If this value is true, take a screenshot
  • W: Generates the width of the picture. If only one value is set for the width or height, it will be scaled proportionally according to one of the values
  • H: The height of the generated image. If the height and width are not specified, the default is 100 * 100
  • Zc: The zoom mode of the generated image. The optional values are 0, 1, 2, and 3. The default value is 1. The difference of each value can be seen in the comment on line 100 of the following file
  • Q: quality of the generated picture, 90 by default
  • A: The clipping position of the excess part is related to the zoom mode. The optional values are t, b, l, r, and the default is to clip from the top
  • F: If you need to use some filters on the generated image, you can transfer the codes and values of different filters here. For specific operation methods, see the notes on line 821 of the following file
  • S: Whether to sharpen the produced pictures
  • Cc: Generate the background canvas color of the picture
  • Ct: Whether the background is transparent when generating a png picture

Relevant code transferred from: https://my.oschina.net/whrlmc/blog/81739

Highlight: