root/devel/lib/phpthumb/phpthumb.functions.php

Revision 421, 23.3 kB (checked in by sven, 3 years ago)

icons: upgrade phpthumb to 1.7.2 and move it to lib/
change icons to be output through a function rather than the bundled phpThumb.php, to allow greater control over security

  • Property svn:eol-style set to native
Line 
1 <?php
2 //////////////////////////////////////////////////////////////
3 ///  phpThumb() by James Heinrich <info@silisoftware.com>   //
4 //        available at http://phpthumb.sourceforge.net     ///
5 //////////////////////////////////////////////////////////////
6 ///                                                         //
7 // phpthumb.functions.php - general support functions       //
8 //                                                         ///
9 //////////////////////////////////////////////////////////////
10
11 class phpthumb_functions {
12
13     function user_function_exists($functionname) {
14         if (function_exists('get_defined_functions')) {
15             static $get_defined_functions = array();
16             if (empty($get_defined_functions)) {
17                 $get_defined_functions = get_defined_functions();
18             }
19             return in_array(strtolower($functionname), $get_defined_functions['user']);
20         }
21         return function_exists($functionname);
22     }
23
24
25     function builtin_function_exists($functionname) {
26         if (function_exists('get_defined_functions')) {
27             static $get_defined_functions = array();
28             if (empty($get_defined_functions)) {
29                 $get_defined_functions = get_defined_functions();
30             }
31             return in_array(strtolower($functionname), $get_defined_functions['internal']);
32         }
33         return function_exists($functionname);
34     }
35
36
37     function version_compare_replacement_sub($version1, $version2, $operator='') {
38         // If you specify the third optional operator argument, you can test for a particular relationship.
39         // The possible operators are: <, lt, <=, le, >, gt, >=, ge, ==, =, eq, !=, <>, ne respectively.
40         // Using this argument, the function will return 1 if the relationship is the one specified by the operator, 0 otherwise.
41
42         // If a part contains special version strings these are handled in the following order: dev < (alpha = a) < (beta = b) < RC < pl
43         static $versiontype_lookup = array();
44         if (empty($versiontype_lookup)) {
45             $versiontype_lookup['dev']   = 10001;
46             $versiontype_lookup['a']     = 10002;
47             $versiontype_lookup['alpha'] = 10002;
48             $versiontype_lookup['b']     = 10003;
49             $versiontype_lookup['beta']  = 10003;
50             $versiontype_lookup['RC']    = 10004;
51             $versiontype_lookup['pl']    = 10005;
52         }
53         if (isset($versiontype_lookup[$version1])) {
54             $version1 = $versiontype_lookup[$version1];
55         }
56         if (isset($versiontype_lookup[$version2])) {
57             $version2 = $versiontype_lookup[$version2];
58         }
59
60         switch ($operator) {
61             case '<':
62             case 'lt':
63                 return intval($version1 < $version2);
64                 break;
65             case '<=':
66             case 'le':
67                 return intval($version1 <= $version2);
68                 break;
69             case '>':
70             case 'gt':
71                 return intval($version1 > $version2);
72                 break;
73             case '>=':
74             case 'ge':
75                 return intval($version1 >= $version2);
76                 break;
77             case '==':
78             case '=':
79             case 'eq':
80                 return intval($version1 == $version2);
81                 break;
82             case '!=':
83             case '<>':
84             case 'ne':
85                 return intval($version1 != $version2);
86                 break;
87         }
88         if ($version1 == $version2) {
89             return 0;
90         } elseif ($version1 < $version2) {
91             return -1;
92         }
93         return 1;
94     }
95
96
97     function version_compare_replacement($version1, $version2, $operator='') {
98         if (function_exists('version_compare')) {
99             // built into PHP v4.1.0+
100             return version_compare($version1, $version2, $operator);
101         }
102
103         // The function first replaces _, - and + with a dot . in the version strings
104         $version1 = strtr($version1, '_-+', '...');
105         $version2 = strtr($version2, '_-+', '...');
106
107         // and also inserts dots . before and after any non number so that for example '4.3.2RC1' becomes '4.3.2.RC.1'.
108         // Then it splits the results like if you were using explode('.',$ver). Then it compares the parts starting from left to right.
109         $version1 = eregi_replace('([0-9]+)([A-Z]+)([0-9]+)', '\\1.\\2.\\3', $version1);
110         $version2 = eregi_replace('([0-9]+)([A-Z]+)([0-9]+)', '\\1.\\2.\\3', $version2);
111
112         $parts1 = explode('.', $version1);
113         $parts2 = explode('.', $version1);
114         $parts_count = max(count($parts1), count($parts2));
115         for ($i = 0; $i < $parts_count; $i++) {
116             $comparison = phpthumb_functions::version_compare_replacement_sub($version1, $version2, $operator);
117             if ($comparison != 0) {
118                 return $comparison;
119             }
120         }
121         return 0;
122     }
123
124
125     function phpinfo_array() {
126         static $phpinfo_array = array();
127         if (empty($phpinfo_array)) {
128             ob_start();
129             phpinfo();
130             $phpinfo = ob_get_contents();
131             ob_end_clean();
132             $phpinfo_array = explode("\n", $phpinfo);
133         }
134         return $phpinfo_array;
135     }
136
137
138     function exif_info() {
139         static $exif_info = array();
140         if (empty($exif_info)) {
141             // based on code by johnschaefer at gmx dot de
142             // from PHP help on gd_info()
143             $exif_info = array(
144                 'EXIF Support'           => '',
145                 'EXIF Version'           => '',
146                 'Supported EXIF Version' => '',
147                 'Supported filetypes'    => ''
148             );
149             $phpinfo_array = phpthumb_functions::phpinfo_array();
150             foreach ($phpinfo_array as $dummy => $line) {
151                 $line = trim(strip_tags($line));
152                 foreach ($exif_info as $key => $value) {
153                     if (strpos($line, $key) === 0) {
154                         $newvalue = trim(str_replace($key, '', $line));
155                         $exif_info[$key] = $newvalue;
156                     }
157                 }
158             }
159         }
160         return $exif_info;
161     }
162
163
164     function ImageTypeToMIMEtype($imagetype) {
165         if (function_exists('image_type_to_mime_type') && ($imagetype >= 1) && ($imagetype <= 16)) {
166             // PHP v4.3.0+
167             return image_type_to_mime_type($imagetype);
168         }
169         static $image_type_to_mime_type = array(
170             => 'image/gif',                     // IMAGETYPE_GIF
171             => 'image/jpeg',                    // IMAGETYPE_JPEG
172             => 'image/png',                     // IMAGETYPE_PNG
173             => 'application/x-shockwave-flash', // IMAGETYPE_SWF
174             => 'image/psd',                     // IMAGETYPE_PSD
175             => 'image/bmp',                     // IMAGETYPE_BMP
176             => 'image/tiff',                    // IMAGETYPE_TIFF_II (intel byte order)
177             => 'image/tiff',                    // IMAGETYPE_TIFF_MM (motorola byte order)
178             => 'application/octet-stream',      // IMAGETYPE_JPC
179             10 => 'image/jp2',                     // IMAGETYPE_JP2
180             11 => 'application/octet-stream',      // IMAGETYPE_JPX
181             12 => 'application/octet-stream',      // IMAGETYPE_JB2
182             13 => 'application/x-shockwave-flash', // IMAGETYPE_SWC
183             14 => 'image/iff',                     // IMAGETYPE_IFF
184             15 => 'image/vnd.wap.wbmp',            // IMAGETYPE_WBMP
185             16 => 'image/xbm',                     // IMAGETYPE_XBM
186
187             'gif'  => 'image/gif',                 // IMAGETYPE_GIF
188             'jpg'  => 'image/jpeg',                // IMAGETYPE_JPEG
189             'jpeg' => 'image/jpeg',                // IMAGETYPE_JPEG
190             'png'  => 'image/png',                 // IMAGETYPE_PNG
191             'bmp'  => 'image/bmp',                 // IMAGETYPE_BMP
192             'ico'  => 'image/x-icon',
193         );
194
195         return (isset($image_type_to_mime_type[$imagetype]) ? $image_type_to_mime_type[$imagetype] : false);
196     }
197
198
199     function HexCharDisplay($string) {
200         $len = strlen($string);
201         $output = '';
202         for ($i = 0; $i < $len; $i++) {
203             $output .= ' 0x'.str_pad(dechex(ord($string{$i})), 2, '0', STR_PAD_LEFT);
204         }
205         return $output;
206     }
207
208
209     function IsHexColor($HexColorString) {
210         return eregi('^[0-9A-F]{6}$', $HexColorString);
211     }
212
213
214     function ImageColorAllocateAlphaSafe(&$gdimg_hexcolorallocate, $R, $G, $B, $alpha=false) {
215         if (phpthumb_functions::version_compare_replacement(phpversion(), '4.3.2', '>=') && ($alpha !== false)) {
216             return ImageColorAllocateAlpha($gdimg_hexcolorallocate, $R, $G, $B, intval($alpha));
217         } else {
218             return ImageColorAllocate($gdimg_hexcolorallocate, $R, $G, $B);
219         }
220     }
221
222     function ImageHexColorAllocate(&$gdimg_hexcolorallocate, $HexColorString, $dieOnInvalid=false, $alpha=false) {
223         if (!is_resource($gdimg_hexcolorallocate)) {
224             die('$gdimg_hexcolorallocate is not a GD resource in ImageHexColorAllocate()');
225         }
226         if (phpthumb_functions::IsHexColor($HexColorString)) {
227             $R = hexdec(substr($HexColorString, 0, 2));
228             $G = hexdec(substr($HexColorString, 2, 2));
229             $B = hexdec(substr($HexColorString, 4, 2));
230             return phpthumb_functions::ImageColorAllocateAlphaSafe($gdimg_hexcolorallocate, $R, $G, $B, $alpha);
231         }
232         if ($dieOnInvalid) {
233             die('Invalid hex color string: "'.$HexColorString.'"');
234         }
235         return ImageColorAllocate($gdimg_hexcolorallocate, 0x00, 0x00, 0x00);
236     }
237
238
239     function HexColorXOR($hexcolor) {
240         return strtoupper(str_pad(dechex(~hexdec($hexcolor) & 0xFFFFFF), 6, '0', STR_PAD_LEFT));
241     }
242
243
244     function GetPixelColor(&$img, $x, $y) {
245         if (!is_resource($img)) {
246             return false;
247         }
248         return @ImageColorsForIndex($img, @ImageColorAt($img, $x, $y));
249     }
250
251
252     function GrayscaleValue($r, $g, $b) {
253         return round(($r * 0.30) + ($g * 0.59) + ($b * 0.11));
254     }
255
256
257     function GrayscalePixel($OriginalPixel) {
258         $gray = phpthumb_functions::GrayscaleValue($OriginalPixel['red'], $OriginalPixel['green'], $OriginalPixel['blue']);
259         return array('red'=>$gray, 'green'=>$gray, 'blue'=>$gray);
260     }
261
262
263     function GrayscalePixelRGB($rgb) {
264         $r = ($rgb >> 16) & 0xFF;
265         $g = ($rgb >>  8) & 0xFF;
266         $b $rgb        & 0xFF;
267         return ($r * 0.299) + ($g * 0.587) + ($b * 0.114);
268     }
269
270
271     function ImageCopyResampleBicubic($dst_img, $src_img, $dst_x, $dst_y, $src_x, $src_y, $dst_w, $dst_h, $src_w, $src_h) {
272         // ron at korving dot demon dot nl
273         // http://www.php.net/imagecopyresampled
274
275         $scaleX = ($src_w - 1) / $dst_w;
276         $scaleY = ($src_h - 1) / $dst_h;
277
278         $scaleX2 = $scaleX / 2.0;
279         $scaleY2 = $scaleY / 2.0;
280
281         $isTrueColor = ImageIsTrueColor($src_img);
282
283         for ($y = $src_y; $y < $src_y + $dst_h; $y++) {
284             $sY   = $y * $scaleY;
285             $siY  = (int) $sY;
286             $siY2 = (int) $sY + $scaleY2;
287
288             for ($x = $src_x; $x < $src_x + $dst_w; $x++) {
289                 $sX   = $x * $scaleX;
290                 $siX  = (int) $sX;
291                 $siX2 = (int) $sX + $scaleX2;
292
293                 if ($isTrueColor) {
294
295                     $c1 = ImageColorAt($src_img, $siX, $siY2);
296                     $c2 = ImageColorAt($src_img, $siX, $siY);
297                     $c3 = ImageColorAt($src_img, $siX2, $siY2);
298                     $c4 = ImageColorAt($src_img, $siX2, $siY);
299
300                     $r = (( $c1             $c2             $c3             $c4            ) >> 2) & 0xFF0000;
301                     $g = ((($c1 & 0x00FF00) + ($c2 & 0x00FF00) + ($c3 & 0x00FF00) + ($c4 & 0x00FF00)) >> 2) & 0x00FF00;
302                     $b = ((($c1 & 0x0000FF) + ($c2 & 0x0000FF) + ($c3 & 0x0000FF) + ($c4 & 0x0000FF)) >> 2);
303
304                 } else {
305
306                     $c1 = ImageColorsForIndex($src_img, ImageColorAt($src_img, $siX, $siY2));
307                     $c2 = ImageColorsForIndex($src_img, ImageColorAt($src_img, $siX, $siY));
308                     $c3 = ImageColorsForIndex($src_img, ImageColorAt($src_img, $siX2, $siY2));
309                     $c4 = ImageColorsForIndex($src_img, ImageColorAt($src_img, $siX2, $siY));
310
311                     $r = ($c1['red']   + $c2['red']   + $c3['red']   + $c4['red'] )  << 14;
312                     $g = ($c1['green'] + $c2['green'] + $c3['green'] + $c4['green']) <<  6;
313                     $b = ($c1['blue']  + $c2['blue']  + $c3['blue']  + $c4['blue'] ) >>  2;
314
315                 }
316                 ImageSetPixel($dst_img, $dst_x + $x - $src_x, $dst_y + $y - $src_y, $r+$g+$b);
317             }
318         }
319         return true;
320     }
321
322
323     function ImageCreateFunction($x_size, $y_size) {
324         $ImageCreateFunction = 'ImageCreate';
325         if (phpthumb_functions::gd_version() >= 2.0) {
326             $ImageCreateFunction = 'ImageCreateTrueColor';
327         }
328         if (!function_exists($ImageCreateFunction)) {
329             return phpthumb::ErrorImage($ImageCreateFunction.'() does not exist - no GD support?');
330         }
331         if (($x_size <= 0) || ($y_size <= 0)) {
332             return phpthumb::ErrorImage('Invalid image dimensions: '.$ImageCreateFunction.'('.$x_size.', '.$y_size.')');
333         }
334         return $ImageCreateFunction($x_size, $y_size);
335     }
336
337
338     function ImageCopyRespectAlpha(&$dst_im, &$src_im, $dst_x, $dst_y, $src_x, $src_y, $src_w, $src_h, $pct=100) {
339         for ($x = $src_x; $x < $src_w; $x++) {
340             for ($y = $src_y; $y < $src_h; $y++) {
341                 $RealPixel    = phpthumb_functions::GetPixelColor($dst_im, $dst_x + $x, $dst_y + $y);
342                 $OverlayPixel = phpthumb_functions::GetPixelColor($src_im, $x, $y);
343                 $alphapct = $OverlayPixel['alpha'] / 127;
344                 $opacipct = $pct / 100;
345                 $overlaypct = (1 - $alphapct) * $opacipct;
346
347                 $newcolor = phpthumb_functions::ImageColorAllocateAlphaSafe(
348                     $dst_im,
349                     round($RealPixel['red']   * (1 - $overlaypct)) + ($OverlayPixel['red']   * $overlaypct),
350                     round($RealPixel['green'] * (1 - $overlaypct)) + ($OverlayPixel['green'] * $overlaypct),
351                     round($RealPixel['blue']  * (1 - $overlaypct)) + ($OverlayPixel['blue']  * $overlaypct),
352                     //$RealPixel['alpha']);
353                     0);
354
355                 ImageSetPixel($dst_im, $dst_x + $x, $dst_y + $y, $newcolor);
356             }
357         }
358         return true;
359     }
360
361
362     function ProportionalResize($old_width, $old_height, $new_width=false, $new_height=false) {
363         $old_aspect_ratio = $old_width / $old_height;
364         if (($new_width === false) && ($new_height === false)) {
365             return false;
366         } elseif ($new_width === false) {
367             $new_width = $new_height * $old_aspect_ratio;
368         } elseif ($new_height === false) {
369             $new_height = $new_width / $old_aspect_ratio;
370         }
371         $new_aspect_ratio = $new_width / $new_height;
372         if ($new_aspect_ratio == $old_aspect_ratio) {
373             // great, done
374         } elseif ($new_aspect_ratio < $old_aspect_ratio) {
375             // limited by width
376             $new_height = $new_width / $old_aspect_ratio;
377         } elseif ($new_aspect_ratio > $old_aspect_ratio) {
378             // limited by height
379             $new_width = $new_height * $old_aspect_ratio;
380         }
381         return array(round($new_width), round($new_height));
382     }
383
384
385     function SafeExec($command) {
386         static $AllowedExecFunctions = array();
387         if (empty($AllowedExecFunctions)) {
388             $AllowedExecFunctions = array('shell_exec'=>true, 'passthru'=>true, 'system'=>true, 'exec'=>true);
389             if (@ini_get('safe_mode')) {
390                 $AllowedExecFunctions['shell_exec'] = false;
391             }
392             $disable_functions = explode(',', @ini_get('disable_functions'));
393             foreach ($AllowedExecFunctions as $key => $value) {
394                 if (in_array($key, $disable_functions)) {
395                     $AllowedExecFunctions[$key] = false;
396                 }
397             }
398         }
399         foreach ($AllowedExecFunctions as $execfunction => $is_allowed) {
400             if (!$is_allowed) {
401                 continue;
402             }
403             switch ($execfunction) {
404                 case 'passthru':
405                     ob_start();
406                     $execfunction($command);
407                     $returnvalue = ob_get_contents();
408                     ob_end_clean();
409                     break;
410
411                 case 'shell_exec':
412                 case 'system':
413                 case 'exec':
414                 default:
415                     $returnvalue = @$execfunction($command);
416                     break;
417             }
418             return $returnvalue;
419         }
420         return false;