Cleanup: Updated copyright notices
[Packages/TYPO3.CMS.git] / t3lib / thumbs.php
1 <?php
2 /***************************************************************
3 * Copyright notice
4 *
5 * (c) 1999-2009 Kasper Skaarhoj (kasperYYYY@typo3.com)
6 * All rights reserved
7 *
8 * This script is part of the TYPO3 project. The TYPO3 project is
9 * free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * The GNU General Public License can be found at
15 * http://www.gnu.org/copyleft/gpl.html.
16 * A copy is found in the textfile GPL.txt and important notices to the license
17 * from the author is found in LICENSE.txt distributed with these scripts.
18 *
19 *
20 * This script is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * This copyright notice MUST APPEAR in all copies of the script!
26 ***************************************************************/
27 /**
28 * Generates a thumbnail and returns an image stream, either GIF/PNG or JPG
29 *
30 * $Id$
31 * Revised for TYPO3 3.6 July/2003 by Kasper Skaarhoj
32 *
33 * @author Kasper Skaarhoj <kasperYYYY@typo3.com>
34 */
35 /**
36 * [CLASS/FUNCTION INDEX of SCRIPT]
37 *
38 *
39 *
40 * 113: class SC_t3lib_thumbs
41 * 134: function init()
42 * 164: function main()
43 *
44 * SECTION: OTHER FUNCTIONS:
45 * 267: function errorGif($l1,$l2,$l3)
46 * 319: function fontGif($font)
47 * 366: function wrapFileName($inputName)
48 *
49 * TOTAL FUNCTIONS: 5
50 * (This index is automatically created/updated by the extension "extdeveval")
51 *
52 */
53
54
55 // *******************************
56 // Set error reporting
57 // *******************************
58 error_reporting (E_ALL ^ E_NOTICE);
59
60
61
62 // ******************
63 // Constants defined
64 // ******************
65 define('TYPO3_OS', stristr(PHP_OS,'win')&&!stristr(PHP_OS,'darwin')?'WIN':'');
66 define('TYPO3_MODE','BE');
67 if(!defined('PATH_thisScript')) define('PATH_thisScript',str_replace('//','/', str_replace('\\','/', (php_sapi_name()=='cgi'||php_sapi_name()=='isapi' ||php_sapi_name()=='cgi-fcgi')&&($_SERVER['ORIG_PATH_TRANSLATED']?$_SERVER['ORIG_PATH_TRANSLATED']:$_SERVER['PATH_TRANSLATED'])? ($_SERVER['ORIG_PATH_TRANSLATED']?$_SERVER['ORIG_PATH_TRANSLATED']:$_SERVER['PATH_TRANSLATED']):($_SERVER['ORIG_SCRIPT_FILENAME']?$_SERVER['ORIG_SCRIPT_FILENAME']:$_SERVER['SCRIPT_FILENAME']))));
68 if(!defined('PATH_site')) define('PATH_site', ereg_replace('[^/]*.[^/]*$','',PATH_thisScript)); // the path to the website folder (see init.php)
69 if(!defined('PATH_t3lib')) define('PATH_t3lib', PATH_site.'t3lib/');
70 define('PATH_typo3conf', PATH_site.'typo3conf/');
71 define('TYPO3_mainDir', 'typo3/'); // This is the directory of the backend administration for the sites of this TYPO3 installation.
72 define('PATH_typo3', PATH_site.TYPO3_mainDir);
73
74
75 // ******************
76 // Including config
77 // ******************
78 require_once(PATH_t3lib.'class.t3lib_div.php');
79 require_once(PATH_t3lib.'class.t3lib_extmgm.php');
80
81 require(PATH_t3lib.'config_default.php');
82 if (!defined ('TYPO3_db')) die ('The configuration file was not included.');
83 if (!$TYPO3_CONF_VARS['GFX']['image_processing']) die ('ImageProcessing was disabled!');
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101 /**
102 * Class for generating a thumbnail from the input parameters given to the script
103 *
104 * Input GET var, &file: relative or absolute reference to an imagefile. WILL be validated against PATH_site / lockRootPath
105 * Input GET var, &size: integer-values defining size of thumbnail, format '[int]' or '[int]x[int]'
106 *
107 * Relative paths MUST BE the first two characters ONLY: eg: '../dir/file.gif', otherwise it is expect to be absolute
108 *
109 * @author Kasper Skaarhoj <kasperYYYY@typo3.com>
110 * @package TYPO3
111 * @subpackage t3lib
112 */
113 class SC_t3lib_thumbs {
114 var $include_once = array();
115
116 var $outdir = 'typo3temp/'; // The output directory of temporary files in PATH_site
117 var $output = '';
118 var $sizeDefault='56x56';
119
120 var $imageList; // Coming from $TYPO3_CONF_VARS['GFX']['imagefile_ext']
121 var $input; // Contains the absolute path to the file for which to make a thumbnail (after init())
122
123 // Internal, static: GPvar:
124 var $file; // Holds the input filename (GET: file)
125 var $size; // Holds the input size (GET: size)
126 var $mtime = 0; // Last modification time of the supplied file
127
128
129 /**
130 * Initialize; reading parameters with GPvar and checking file path
131 * Results in internal var, $this->input, being set to the absolute path of the file for which to make the thumbnail.
132 *
133 * @return void
134 */
135 function init() {
136 global $TYPO3_CONF_VARS;
137
138 // Setting GPvars:
139 $file = t3lib_div::_GP('file');
140 $size = t3lib_div::_GP('size');
141 $md5sum = t3lib_div::_GP('md5sum');
142
143 // Image extension list is set:
144 $this->imageList = $TYPO3_CONF_VARS['GFX']['imagefile_ext']; // valid extensions. OBS: No spaces in the list, all lowercase...
145
146 // If the filereference $this->file is relative, we correct the path
147 if (substr($file,0,3)=='../') {
148 $file = PATH_site.substr($file,3);
149 }
150
151 // Now the path is absolute.
152 // Checking for backpath and double slashes + the thumbnail can be made from files which are in the PATH_site OR the lockRootPath only!
153 if (t3lib_div::isAllowedAbsPath($file)) {
154 $mtime = filemtime($file);
155 }
156
157 // Do an MD5 check to prevent viewing of images without permission
158 $OK = FALSE;
159 if ($mtime) {
160 // Always use the absolute path for this check!
161 $check = basename($file).':'.$mtime.':'.$GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey'];
162 $md5_real = t3lib_div::shortMD5($check);
163 if (!strcmp($md5_real,$md5sum)) {
164 $OK = TRUE;
165 }
166 }
167
168 if ($OK) {
169 $this->input = $file;
170 $this->size = $size;
171 $this->mtime = $mtime;
172 } else {
173 die('Error: Image does not exist and/or MD5 checksum did not match.');
174 }
175 }
176
177 /**
178 * Create the thumbnail
179 * Will exit before return if all is well.
180 *
181 * @return void
182 */
183 function main() {
184 global $TYPO3_CONF_VARS;
185
186 // If file exists, we make a thumbsnail of the file.
187 if ($this->input && file_exists($this->input)) {
188
189 // Check file extension:
190 $reg = array();
191 if (ereg('(.*)\.([^\.]*$)',$this->input,$reg)) {
192 $ext=strtolower($reg[2]);
193 $ext=($ext=='jpeg')?'jpg':$ext;
194 if ($ext=='ttf') {
195 $this->fontGif($this->input); // Make font preview... (will not return)
196 } elseif (!t3lib_div::inList($this->imageList, $ext)) {
197 $this->errorGif('Not imagefile!',$ext,basename($this->input));
198 }
199 } else {
200 $this->errorGif('Not imagefile!','No ext!',basename($this->input));
201 }
202
203 // ... so we passed the extension test meaning that we are going to make a thumbnail here:
204 if (!$this->size) $this->size = $this->sizeDefault; // default
205
206 // I added extra check, so that the size input option could not be fooled to pass other values. That means the value is exploded, evaluated to an integer and the imploded to [value]x[value]. Furthermore you can specify: size=340 and it'll be translated to 340x340.
207 $sizeParts = explode('x', $this->size.'x'.$this->size); // explodes the input size (and if no "x" is found this will add size again so it is the same for both dimensions)
208 $sizeParts = array(t3lib_div::intInRange($sizeParts[0],1,1000),t3lib_div::intInRange($sizeParts[1],1,1000)); // Cleaning it up, only two parameters now.
209 $this->size = implode('x',$sizeParts); // Imploding the cleaned size-value back to the internal variable
210 $sizeMax = max($sizeParts); // Getting max value
211
212 // Init
213 $outpath = PATH_site.$this->outdir;
214
215 // Should be - ? 'png' : 'gif' - , but doesn't work (ImageMagick prob.?)
216 // René: png work for me
217 $thmMode = t3lib_div::intInRange($TYPO3_CONF_VARS['GFX']['thumbnails_png'],0);
218 $outext = ($ext!='jpg' || ($thmMode & 2)) ? ($thmMode & 1 ? 'png' : 'gif') : 'jpg';
219
220 $outfile = 'tmb_'.substr(md5($this->input.$this->mtime.$this->size),0,10).'.'.$outext;
221 $this->output = $outpath.$outfile;
222
223 if ($TYPO3_CONF_VARS['GFX']['im']) {
224 // If thumbnail does not exist, we generate it
225 if (!file_exists($this->output)) {
226 /* if (strstr($this->input,' ') || strstr($this->output,' ')) {
227 $this->errorGif('Spaces in','filepath',basename($this->input));
228 }
229 */ // 16 colors for small (56) thumbs, 64 for bigger and all for jpegs
230 if ($outext=='jpg') {
231 $colors = '';
232 } else {
233 $colors = ($sizeMax>56)?'-colors 64':'-colors 16';
234 }
235 $parameters = '-sample '.$this->size.' '.$colors.' '.$this->wrapFileName($this->input.'[0]').' '.$this->wrapFileName($this->output);
236 $cmd = t3lib_div::imageMagickCommand('convert', $parameters);
237 exec($cmd);
238 if (!file_exists($this->output)) {
239 $this->errorGif('No thumb','generated!',basename($this->input));
240 }
241 }
242 // The thumbnail is read and output to the browser
243 if($fd = @fopen($this->output,'rb')) {
244 header('Content-type: image/'.$outext);
245 fpassthru($fd);
246 fclose($fd);
247 } else {
248 $this->errorGif('Read problem!','',$this->output);
249 }
250 } else exit;
251 } else {
252 $this->errorGif('No valid','inputfile!',basename($this->input));
253 }
254 }
255
256
257
258
259
260
261
262
263
264
265
266 /***************************
267 *
268 * OTHER FUNCTIONS:
269 *
270 ***************************/
271
272 /**
273 * Creates error image based on gfx/notfound_thumb.png
274 * Requires GD lib enabled, otherwise it will exit with the three textstrings outputted as text.
275 * Outputs the image stream to browser and exits!
276 *
277 * @param string Text line 1
278 * @param string Text line 2
279 * @param string Text line 3
280 * @return void
281 */
282 function errorGif($l1,$l2,$l3) {
283 global $TYPO3_CONF_VARS;
284
285 if (!$TYPO3_CONF_VARS['GFX']['gdlib']) die($l1.' '.$l2.' '.$l3);
286
287 // Creates the basis for the error image
288 if ($TYPO3_CONF_VARS['GFX']['gdlib_png']) {
289 header('Content-type: image/png');
290 $im = imagecreatefrompng(PATH_typo3.'gfx/notfound_thumb.png');
291 } else {
292 header('Content-type: image/gif');
293 $im = imagecreatefromgif(PATH_typo3.'gfx/notfound_thumb.gif');
294 }
295 // Sets background color and print color.
296 $white = imageColorAllocate($im, 0,0,0);
297 $black = imageColorAllocate($im, 255,255,0);
298
299 // Prints the text strings with the build-in font functions of GD
300 $x=0;
301 $font=0;
302 if ($l1) {
303 imagefilledrectangle($im, $x, 9, 56, 16, $black);
304 imageString($im,$font,$x,9,$l1,$white);
305 }
306 if ($l2) {
307 imagefilledrectangle($im, $x, 19, 56, 26, $black);
308 imageString($im,$font,$x,19,$l2,$white);
309 }
310 if ($l3) {
311 imagefilledrectangle($im, $x, 29, 56, 36, $black);
312 imageString($im,$font,$x,29,substr($l3,-14),$white);
313 }
314
315 // Outputting the image stream and exit
316 if ($TYPO3_CONF_VARS['GFX']['gdlib_png']) {
317 imagePng($im);
318 } else {
319 imageGif($im);
320 }
321 imagedestroy($im);
322 exit;
323 }
324
325 /**
326 * Creates a font-preview thumbnail.
327 * This means a PNG/GIF file with the text "AaBbCc...." set with the font-file given as input and in various sizes to show how the font looks
328 * Requires GD lib enabled.
329 * Outputs the image stream to browser and exits!
330 *
331 * @param string The filepath to the font file (absolute, probably)
332 * @return void
333 */
334 function fontGif($font) {
335 global $TYPO3_CONF_VARS;
336
337 if (!$TYPO3_CONF_VARS['GFX']['gdlib']) die('');
338
339 // Create image and set background color to white.
340 $im = imageCreate(250,76);
341 $white = imageColorAllocate($im, 255,255,255);
342 $col = imageColorAllocate($im, 0,0,0);
343
344 // The test string and offset in x-axis.
345 $string = 'AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZzÆæØøÅåÄäÖöÜüß';
346 $x=13;
347
348 // Print (with non-ttf font) the size displayed
349 imagestring ($im, 1, 0, 2, '10', $col);
350 imagestring ($im, 1, 0, 15, '12', $col);
351 imagestring ($im, 1, 0, 30, '14', $col);
352 imagestring ($im, 1, 0, 47, '18', $col);
353 imagestring ($im, 1, 0, 68, '24', $col);
354
355 // Print with ttf-font the test string
356 imagettftext ($im, t3lib_div::freetypeDpiComp(10), 0, $x, 8, $col, $font, $string);
357 imagettftext ($im, t3lib_div::freetypeDpiComp(12), 0, $x, 21, $col, $font, $string);
358 imagettftext ($im, t3lib_div::freetypeDpiComp(14), 0, $x, 36, $col, $font, $string);
359 imagettftext ($im, t3lib_div::freetypeDpiComp(18), 0, $x, 53, $col, $font, $string);
360 imagettftext ($im, t3lib_div::freetypeDpiComp(24), 0, $x, 74, $col, $font, $string);
361
362 // Output PNG or GIF based on $TYPO3_CONF_VARS['GFX']['gdlib_png']
363 if ($TYPO3_CONF_VARS['GFX']['gdlib_png']) {
364 header('Content-type: image/png');
365 imagePng($im);
366 } else {
367 header('Content-type: image/gif');
368 imageGif($im);
369 }
370 imagedestroy($im);
371 exit;
372 }
373
374 /**
375 * Wrapping the input filename in double-quotes
376 *
377 * @param string Input filename
378 * @return string The output wrapped in "" (if there are spaces in the filepath)
379 * @access private
380 */
381 function wrapFileName($inputName) {
382 if (strstr($inputName,' ')) {
383 $inputName='"'.$inputName.'"';
384 }
385 return $inputName;
386 }
387 }
388
389 if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['t3lib/thumbs.php']) {
390 include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['t3lib/thumbs.php']);
391 }
392
393
394
395
396 // Make instance:
397 $SOBE = t3lib_div::makeInstance('SC_t3lib_thumbs');
398 $SOBE->init();
399 $SOBE->main();
400
401 ?>