/*
+-------------------------------------------------------------------+
| T H U M B S - U P (v2.0) |
| |
| Copyright Gerd Tentler www.gerd-tentler.de/tools |
| Created: Jan. 27, 2005 Last modified: Jan. 5, 2008 |
+-------------------------------------------------------------------+
| This program may be used and hosted free of charge by anyone for |
| personal purpose as long as this copyright notice remains intact. |
| |
| Obtain permission before selling the code for this program or |
| hosting this software on a commercial website or redistributing |
| this software over the Internet or in any other medium. In all |
| cases copyright must remain intact. |
+-------------------------------------------------------------------+
*/
//========================================================================================================
// Arguments: $image OR ($database, $table, $field, $key, $id), optional: $width, $height, $cache_dir
//
// Example #1:
// Example #2:
// Example #3:
//
// NOTE: $cache_dir must be readable + writable by PHP!
//========================================================================================================
error_reporting(E_WARNING);
//========================================================================================================
// Set variables, if they are not registered globally; needs PHP 4.1.0 or higher
//========================================================================================================
//security patch for LightNEasy:
if(isset($_REQUEST['image'])) $image = sanitize($_REQUEST['image']);
if(isset($_REQUEST['width'])) {
if(!is_intval($_REQUEST['width'])) die ("Aha! Clever!");
else $width = $_REQUEST['width'];
}
if(isset($_REQUEST['height'])) {
if(!is_intval($_REQUEST['height'])) die ("Aha! Clever!");
else $height = $_REQUEST['height'];
}
$cache_dir = "../data";
// not used by LightNEasy
/* if(isset($_REQUEST['cache_dir'])) $cache_dir = $_REQUEST['cache_dir'];
if(isset($_REQUEST['database'])) $database = $_REQUEST['database'];
if(isset($_REQUEST['table'])) $table = $_REQUEST['table'];
if(isset($_REQUEST['field'])) $field = $_REQUEST['field'];
if(isset($_REQUEST['key'])) $key = $_REQUEST['key'];
if(isset($_REQUEST['id'])) $id = $_REQUEST['id']; */
//========================================================================================================
// Configuration
//========================================================================================================
if(!$width) $width = 100; // max. thumbnail width
if(!$height) $height = 100; // max. thumbnail height
if(!$cache_dir) $cache_dir = "cache"; // path to cache
$autodelete = 7; // delete files from cache after .. days (0 = never delete)
$IM_path = ""; // path to ImageMagick's convert function, e.g. "/usr/bin"
// (leave empty to use the GD library instead)
// only needed if used with MySQL:
$db_host = "localhost"; // MySQL server
$db_user = "root"; // user name
$db_pass = ""; // password
//========================================================================================================
// Functions
//========================================================================================================
// sanitizes a input. It's probably an overkill in this case
function sanitize($text) {
// Convert problematic ascii characters to their true values
$search = array("40","41","58","65","66","67","68","69","70",
"71","72","73","74","75","76","77","78","79","80","81",
"82","83","84","85","86","87","88","89","90","97","98",
"99","100","101","102","103","104","105","106","107",
"108","109","110","111","112","113","114","115","116",
"117","118","119","120","121","122"
);
$replace = array("(",")",":","a","b","c","d","e","f","g","h",
"i","j","k","l","m","n","o","p","q","r","s","t","u",
"v","w","x","y","z","a","b","c","d","e","f","g","h",
"i","j","k","l","m","n","o","p","q","r","s","t","u",
"v","w","x","y","z"
);
$entities = count($search);
for ($i=0;$i < $entities;$i++) $text = preg_replace("#(&\#)(0*".$search[$i]."+);*#si", $replace[$i], $text);
// the following is based on code from bitflux (http://blog.bitflux.ch/wiki/)
// Kill hexadecimal characters completely
$text = preg_replace('#(&\#x)([0-9A-F]+);*#si', "", $text);
// remove any attribute starting with "on" or xmlns
$text = preg_replace('#(<[^>]+[\\"\'\s])(onmouseover|onmousedown|onmouseup|onmouseout|onmousemove|onclick|ondblclick|onload|xmlns)[^>]*>#iU', ">", $text);
do {
$oldtext = $text;
preg_replace('#*(applet|meta|xml|blink|link|style|script|embed|object|iframe|frame|frameset|ilayer|layer|bgsound|title|base)[^>]*>#i', "", $text);
// remove javascript: and vbscript: protocol
} while ($oldtext != $text);
$text = preg_replace('#([a-z]*)=([\`\'\"]*)script:#iU', '$1=$2nojscript...', $text);
$text = preg_replace('#([a-z]*)=([\`\'\"]*)javascript:#iU', '$1=$2nojavascript...', $text);
$text = preg_replace('#([a-z]*)=([\'\"]*)vbscript:#iU', '$1=$2novbscript...', $text);
$text = preg_replace('#(<[^>]+)style=([\`\'\"]*).*expression\([^>]*>#iU', "$1>", $text);
$text = preg_replace('#(<[^>]+)style=([\`\'\"]*).*behaviour\([^>]*>#iU', "$1>", $text);
return $text;
}
//returns true only if the string is composed only of digits or "+-"
function is_intval($value) {
return 1 === preg_match('/^[+-]?[0-9]+$/', $value);
}
//--------------------------------------------------------------------------------------------------------
// Delete files older than .. days from cache
//--------------------------------------------------------------------------------------------------------
// Arguments: path to cache, number of days
//--------------------------------------------------------------------------------------------------------
function clearCache($cache_dir, $days) {
if($dp = @opendir($cache_dir)) {
while($file = readdir($dp)) {
if(preg_match('/^img_/', $file)) {
$mtime = @filemtime("$cache_dir/$file");
if($mtime < time() - 3600 * 24 * $days) @unlink("$cache_dir/$file");
}
}
closedir($dp);
}
}
//--------------------------------------------------------------------------------------------------------
// If gd_info() doesn't exist it must be simulated
//--------------------------------------------------------------------------------------------------------
function gdInfo() {
$gd = array('GD Version' => '',
'FreeType Support' => 0,
'FreeType Linkage' => '',
'T1Lib Support' => 0,
'GIF Read Support' => 0,
'GIF Create Support' => 0,
'GIF Support' => 0,
'JPG Support' => 0,
'PNG Support' => 0,
'WBMP Support' => 0,
'XBM Support' => 0);
if(function_exists('ob_start')) {
ob_start();
phpinfo();
$info = explode("\n", ob_get_contents());
ob_end_clean();
for($i = 0; $i < count($info); $i++) {
while(list($str, $v) = each($gd)) {
if(strstr($info[$i], $str)) {
$val = trim(str_replace($str, '', strip_tags($info[$i])));
$gd[$str] = ($val == 'enabled') ? 1 : $val;
}
}
reset($gd);
}
if($gd['GIF Support']) $gd['GIF Read Support'] = $gd['GIF Create Support'] = 1;
else if($gd['GIF Read Support'] && $gd['GIF Create Support']) $gd['GIF Support'] = 1;
}
return $gd;
}
//--------------------------------------------------------------------------------------------------------
// If getImageSize() doesn't return proper values
//--------------------------------------------------------------------------------------------------------
// Arguments: image data (binary)
// Returns: image type (gif, jpeg, png, swf)
//--------------------------------------------------------------------------------------------------------
function getImgType($data) {
$header = substr($data, 0, 20);
if(strstr($header, 'GIF')) $type = 'gif';
else if(strstr($header, 'JFIF') || strstr($header, 'Exif')) $type = 'jpeg';
else if(strstr($header, 'PNG')) $type = 'png';
else if(strstr($header, 'FWS') || strstr($header, 'CWS')) $type = 'swf';
else $type = '';
return $type;
}
//--------------------------------------------------------------------------------------------------------
// Calculate thumbnail size
//--------------------------------------------------------------------------------------------------------
// Arguments: source width, source height
// Globals: max. thumbnail width, max. thumbnail height
// Returns: dest. width, dest. height
//--------------------------------------------------------------------------------------------------------
function getNewSize($src_w, $src_h) {
global $width, $height;
$perc_w = $width * 100 / $src_w;
$perc_h = $height * 100 / $src_h;
$div = ($perc_w < $perc_h) ? 100 / $perc_w : 100 / $perc_h;
$dst_w = round($src_w / $div);
$dst_h = round($src_h / $div);
return array($dst_w, $dst_h);
}
//--------------------------------------------------------------------------------------------------------
// View image with headers
//--------------------------------------------------------------------------------------------------------
// Arguments: filename, image type
//--------------------------------------------------------------------------------------------------------
function viewImage($file, $type) {
$last_modified = gmdate('D, d M Y H:i:s', filemtime($file)) . ' GMT';
$now = gmdate('D, d M Y H:i:s', time()) . ' GMT';
header("Content-Type: image/$type");
header("Last-Modified: $last_modified");
header('Cache-control: private, no-cache, must-revalidate');
header('Expires: Sat, 01 Jan 2000 00:00:00 GMT');
header("Date: $now");
header('Pragma: no-cache');
readfile($file);
exit;
}
//--------------------------------------------------------------------------------------------------------
// Read thumbnail from cache
//--------------------------------------------------------------------------------------------------------
// Arguments: original name, thumbnail name, [ view image (true or false) ]
//--------------------------------------------------------------------------------------------------------
function readCachedThumb($original, $thumbname, $view = true) {
if(file_exists($original)) {
if(file_exists("$thumbname.gif")) $type = 'gif';
else if(file_exists("$thumbname.jpeg")) $type = 'jpeg';
else if(file_exists("$thumbname.png")) $type = 'png';
else $type = '';
if($type) {
$thumbnail = "$thumbname.$type";
clearstatcache();
$last_modified = gmdate('D, d M Y H:i:s', filemtime($thumbnail)) . ' GMT';
if(isset($_SERVER['HTTP_IF_MODIFIED_SINCE'])) {
$if_modified_since = preg_replace('/;.*$/', '', $_SERVER['HTTP_IF_MODIFIED_SINCE']);
if($if_modified_since == $last_modified) {
if($view) {
header('HTTP/1.0 304 Not Modified');
exit;
}
else return true;
}
}
if($view) viewImage($thumbnail, $type);
else return true;
}
}
return false;
}
//--------------------------------------------------------------------------------------------------------
// Copy palette and set transparency
//--------------------------------------------------------------------------------------------------------
// Arguments: destination image, source image, color index
//--------------------------------------------------------------------------------------------------------
function setTransparency($dst_img, $src_img, $trans_col) {
if(function_exists('ImagePaletteCopy')) ImagePaletteCopy($dst_img, $src_img);
if($trans_col == -1) $trans_col = 0;
ImageFill($dst_img, 0, 0, $trans_col);
ImageColorTransparent($dst_img, $trans_col);
}
//--------------------------------------------------------------------------------------------------------
// Create thumbnail with ImageMagick
//--------------------------------------------------------------------------------------------------------
// Arguments: original name, thumbnail name, type (jpeg/gif/png), [ view image (true or false) ]
// Globals: path to ImageMagick's convert function
//--------------------------------------------------------------------------------------------------------
function createThumbIM($original, $thumbname, $type, $view = true) {
global $IM_path;
if($IM_path) {
$imgsize = @getImageSize($original);
list($dst_w, $dst_h) = getNewSize($imgsize[0], $imgsize[1]);
$format = $dst_w . 'x' . $dst_h;
$type2 = ($type == 'gif') ? 'png' : $type;
$thumbnail = $thumbname . '.' . $type2;
@exec("$IM_path/convert -sample $format $type:$original $type2:$thumbnail");
if(file_exists("$thumbnail.0")) {
@rename("$thumbnail.0", $thumbnail);
for($cnt = 1; file_exists("$thumbnail.$cnt"); $cnt++) @unlink("$thumbnail.$cnt");
}
if(file_exists($thumbnail)) {
if(filesize($thumbnail) == 0) @unlink($thumbnail);
else if($view) viewImage($thumbnail, $type2);
else return true;
}
}
return false;
}
//--------------------------------------------------------------------------------------------------------
// Create thumbnail with GD
//--------------------------------------------------------------------------------------------------------
// Arguments: path to original, thumbnail name, type (jpeg/gif/png), [ view image (true or false) ]
//--------------------------------------------------------------------------------------------------------
function createThumbGD($original, $thumbname, $type, $view = true) {
$error = '';
$gd = function_exists('gd_info') ? gd_info() : gdInfo();
$gd_ver = ereg_replace('[^0-9.]+', '', $gd['GD Version']);
switch($type) {
case 'gif': if(!$gd['GIF Read Support'] && !$gd['GIF Support']) $error = "GD $gd_ver: No GIF support"; break;
case 'png': if(!$gd['PNG Support']) $error = "GD $gd_ver: No PNG support"; break;
case 'jpeg': if(!$gd['JPG Support']) $error = "GD $gd_ver: No JPG support"; break;
default: $error = 'No ' . strtoupper($type) . ' support'; break;
}
if(!$error) {
if($fp = @fopen($original, 'rb')) {
$data = fread($fp, filesize($original));
fclose($fp);
if($data) {
if(function_exists('ImageCreateFromString')) {
$src_img = @ImageCreateFromString($data);
}
if(!$src_img) {
$php_ver = phpversion();
if($type == 'jpeg') {
if(function_exists('ImageCreateFromJPEG')) {
$src_img = @ImageCreateFromJPEG($original);
}
if(!$src_img) $error = "PHP $php_ver: No JPG support";
}
else if($type == 'gif') {
if(function_exists('ImageCreateFromGIF')) {
$src_img = @ImageCreateFromGIF($original);
}
if(!$src_img) $error = "PHP $php_ver: No GIF support";
}
else if($type == 'png') {
if(function_exists('ImageCreateFromPNG')) {
$src_img = @ImageCreateFromPNG($original);
}
if(!$src_img) $error = "PHP $php_ver: No PNG support";
}
else $error = 'Unknown type';
}
if(!$error) {
$src_w = ImageSX($src_img);
$src_h = ImageSY($src_img);
list($dst_w, $dst_h) = getNewSize($src_w, $src_h);
if($type == 'gif' || $type == 'png')
$trans_col = ImageColorTransparent($src_img);
else $trans_col = -1;
if($type == 'png' && $trans_col == -1)
if(ImageColorsTotal($src_img) <= 256) $trans_col = 0;
if($gd_ver >= 2.0) {
if($trans_col == -1 && function_exists('ImageCreateTrueColor'))
$dst_img = ImageCreateTrueColor($dst_w, $dst_h);
else {
$dst_img = ImageCreate($dst_w, $dst_h);
setTransparency($dst_img, $src_img, $trans_col);
}
if(function_exists('ImageCopyResampled'))
ImageCopyResampled($dst_img, $src_img, 0, 0, 0, 0, $dst_w, $dst_h, $src_w, $src_h);
else ImageCopyResized($dst_img, $src_img, 0, 0, 0, 0, $dst_w, $dst_h, $src_w, $src_h);
}
else {
$dst_img = ImageCreate($dst_w, $dst_h);
if($trans_col != -1) setTransparency($dst_img, $src_img, $trans_col);
ImageCopyResized($dst_img, $src_img, 0, 0, 0, 0, $dst_w, $dst_h, $src_w, $src_h);
}
if($type == 'jpeg') {
if(function_exists('ImageJPEG')) @ImageJPEG($dst_img, "$thumbname.$type");
else $error = "PHP $php_ver: No JPG preview";
}
else if($type == 'gif') {
if(function_exists('ImageGIF')) @ImageGIF($dst_img, "$thumbname.$type");
else if(function_exists('ImagePNG')) @ImagePNG($dst_img, "$thumbname.png");
else $error = "PHP $php_ver: No GIF preview";
}
else if($type == 'png') {
if(function_exists('ImagePNG')) @ImagePNG($dst_img, "$thumbname.$type");
else $error = "PHP $php_ver: No PNG preview";
}
ImageDestroy($src_img);
ImageDestroy($dst_img);
if($view) readCachedThumb($original, $thumbname);
}
}
else $error = 'No data';
}
else $error = 'Could not open';
}
return $error;
}
//--------------------------------------------------------------------------------------------------------
// View message as image with GD
//--------------------------------------------------------------------------------------------------------
// Arguments: text, width, height, [ font (1 - 5) ]
//--------------------------------------------------------------------------------------------------------
function showMessage($text, $width, $height, $font = 2) {
if($img = @ImageCreate($width, $height)) {
$red = ImageColorAllocate($img, 255, 0, 0);
$white = ImageColorAllocate($img, 255, 255, 255);
ImageFill($img, 0, 0, $white);
ImageColorTransparent($img, $white);
$hcenter = $width / 2;
$vcenter = $height / 2;
$x = round($hcenter - ImageFontWidth($font) * strlen($text) / 2);
$y = round($vcenter - ImageFontHeight($font) / 2);
ImageString($img, $font, $x, $y, $text, $red);
if(function_exists('ImagePNG')) {
header('Content-Type: image/png');
@ImagePNG($img);
}
else if(function_exists('ImageGIF')) {
header('Content-Type: image/gif');
@ImageGIF($img);
}
else if(function_exists('ImageJPEG')) {
header('Content-Type: image/jpeg');
@ImageJPEG($img);
}
ImageDestroy($img);
}
}
//========================================================================================================
// Main
//========================================================================================================
$blankImg = 'R0lGODlhCgAKAIAAAMDAwAAAACH5BAEAAAAALAAAAAAKAAoAAAIIhI+py+0PYysAOw==';
$error = '';
if($autodelete) clearCache($cache_dir, $autodelete);
if(($table && $field && $key && $id) || $image) {
$data = '';
if(strstr($table, '.')) {
$arr = explode('.', $table);
$database = $arr[0];
$table = $arr[1];
}
if($image) {
if($fp = @fopen($image, 'rb')) {
while(!feof($fp)) $data .= fread($fp, 4096);
fclose($fp);
}
else $error = 'Could not open';
}
else if($database) {
if(@mysql_connect($db_host, $db_user, $db_pass)) {
$sql = "SELECT $field FROM $database.$table WHERE $key='$id'";
if($result = mysql_query($sql)) {
if(mysql_num_rows($result)) $data = mysql_result($result, $field);
else $error = 'Not found';
}
else $error = 'Bad SQL query';
mysql_close();
}
else $error = 'No connection';
}
else $error = 'Database?';
if(!$error) {
if(!$data) {
header("Content-Type: image/gif");
echo base64_decode($blankImg);
exit;
}
else {
$original = "$cache_dir/img_" . md5($data);
$thumbname = $original . '_' . $width . 'x' . $height;
$cached = readCachedThumb($original, $thumbname);
if(!$cached) {
@unlink("$thumbname.gif");
@unlink("$thumbname.jpeg");
@unlink("$thumbname.png");
if(!file_exists($original)) {
if($fp = @fopen($original, 'wb')) {
fwrite($fp, $data, strlen($data));
fclose($fp);
}
else $error = 'Could not save';
}
if(!$error) {
$imgsize = @getImageSize($original);
switch($imgsize[2]) {
case 1: $type = 'gif'; break;
case 2: $type = 'jpeg'; break;
case 3: $type = 'png'; break;
case 4: $type = 'swf'; break;
default: $type = getImgType($data);
}
if($type == 'swf') $error = 'No SWF preview';
else if($type) {
if($imgsize[0] <= $width && $imgsize[1] <= $height) {
viewImage($original, $type);
}
else {
if($imgsize[0] < $width) $width = $imgsize[0];
if($imgsize[1] < $height) $height = $imgsize[1];
if(!createThumbIM($original, $thumbname, $type)) {
$error = createThumbGD($original, $thumbname, $type);
}
}
}
else $error = 'Unknown type';
}
}
}
}
}
else $error = 'Arguments?';
if($error) showMessage($error, ($width < 200) ? 200 : $width, $height);
?>