--- a/includes/functions.php Sat Nov 03 07:43:35 2007 -0400
+++ b/includes/functions.php Sat Nov 03 14:30:53 2007 -0400
@@ -3223,6 +3223,169 @@
return true;
}
+/**
+ * Scales an image to the specified width and height, and writes the output to the specified
+ * file. Will use ImageMagick if present, but if not will attempt to scale with GD. This will
+ * always scale images proportionally.
+ * @param string Path to image file
+ * @param string Path to output file
+ * @param int Image width, in pixels
+ * @param int Image height, in pixels
+ * @param bool If true, the output file will be deleted if it exists before it is written
+ * @return bool True on success, false on failure
+ */
+
+function scale_image($in_file, $out_file, $width = 225, $height = 225, $unlink = false)
+{
+ global $db, $session, $paths, $template, $plugins; // Common objects
+
+ if ( !is_int($width) || !is_int($height) )
+ return false;
+
+ if ( !file_exists($in_file) )
+ return false;
+
+ if ( preg_match('/["\'\/\\]/', $in_file) || preg_match('/["\'\/\\]/', $out_file) )
+ die('SECURITY: scale_image(): infile or outfile path is screwy');
+
+ if ( file_exists($out_file) && !$unlink )
+ return false;
+ else if ( file_exists($out_file) && $unlink )
+ @unlink($out_file);
+ if ( file_exists($out_file) )
+ // couldn't unlink (delete) the output file
+ return false;
+
+ $file_ext = substr($in_file, ( strrpos($in_file, '.') + 1));
+ switch($file_ext)
+ {
+ case 'png':
+ $func = 'imagecreatefrompng';
+ break;
+ case 'jpg':
+ case 'jpeg':
+ $func = 'imagecreatefromjpeg';
+ break;
+ case 'gif':
+ $func = 'imagecreatefromgif';
+ break;
+ case 'xpm':
+ $func = 'imagecreatefromxpm';
+ break;
+ default:
+ return false;
+ }
+
+ $magick_path = getConfig('imagemagick_path');
+ $can_use_magick = (
+ getConfig('enable_imagemagick') == '1' &&
+ file_exists($magick_path) &&
+ is_executable($magick_path)
+ );
+ $can_use_gd = (
+ function_exists('getimagesize') &&
+ function_exists('imagecreatetruecolor') &&
+ function_exists('imagecopyresampled') &&
+ function_exists($func)
+ );
+ if ( $can_use_magick )
+ {
+ if ( !preg_match('/^([\/A-z0-9_-]+)$/', $magick_path) )
+ {
+ die('SECURITY: ImageMagick path is screwy');
+ }
+ $cmdline = "$magick_path \"$in_file\" -resize \"{$width}x{$height}>\" \"$out_file\"";
+ system($cmdline, $return);
+ if ( !file_exists($out_file) )
+ return false;
+ return true;
+ }
+ else if ( $can_use_gd )
+ {
+ @list($width_orig, $height_orig) = @getimagesize($in_file);
+ if ( !$width_orig || !$height_orig )
+ return false;
+ // calculate new width and height
+
+ $ratio = $width_orig / $height_orig;
+ if ( $ratio > 1 )
+ {
+ // orig. width is greater that height
+ $new_width = $width;
+ $new_height = round( $width / $ratio );
+ }
+ else if ( $ratio < 1 )
+ {
+ // orig. height is greater than width
+ $new_width = round( $height / $ratio );
+ $new_height = $height;
+ }
+ else if ( $ratio == 1 )
+ {
+ $new_width = $width;
+ $new_height = $width;
+ }
+ if ( $new_width > $width_orig || $new_height > $height_orig )
+ {
+ // Too big for our britches here; set it to only convert the file
+ $new_width = $width_orig;
+ $new_height = $height_orig;
+ }
+
+ $newimage = @imagecreatetruecolor($new_width, $new_height);
+ if ( !$newimage )
+ return false;
+ $oldimage = @$func($in_file);
+ if ( !$oldimage )
+ return false;
+
+ // Perform scaling
+ imagecopyresampled($newimage, $oldimage, 0, 0, 0, 0, $new_width, $new_height, $width_orig, $height_orig);
+
+ // Get output format
+ $out_ext = substr($out_file, ( strrpos($out_file, '.') + 1));
+ switch($out_ext)
+ {
+ case 'png':
+ $outfunc = 'imagepng';
+ break;
+ case 'jpg':
+ case 'jpeg':
+ $outfunc = 'imagejpeg';
+ break;
+ case 'gif':
+ $outfunc = 'imagegif';
+ break;
+ case 'xpm':
+ $outfunc = 'imagexpm';
+ break;
+ default:
+ imagedestroy($newimage);
+ imagedestroy($oldimage);
+ return false;
+ }
+
+ // Write output
+ $outfunc($newimage, $out_file);
+
+ // clean up
+ imagedestroy($newimage);
+ imagedestroy($oldimage);
+
+ // done!
+ return true;
+ }
+ // Neither scaling method worked; we'll let plugins try to scale it, and then if the file still doesn't exist, die
+ $code = $plugins->setHook('scale_image_failure');
+ foreach ( $code as $cmd )
+ {
+ eval($cmd);
+ }
+ if ( file_exists($out_file) )
+ return true;
+ return false;
+}
+
//die('<pre>Original: 01010101010100101010100101010101011010'."\nProcessed: ".uncompress_bitfield(compress_bitfield('01010101010100101010100101010101011010')).'</pre>');
?>
--- a/plugins/SpecialUpdownload.php Sat Nov 03 07:43:35 2007 -0400
+++ b/plugins/SpecialUpdownload.php Sat Nov 03 14:30:53 2007 -0400
@@ -235,45 +235,73 @@
}
$fname = ENANO_ROOT . '/files/' . $row['file_key'] . '_' . $row['time_id'] . $row['file_extension'];
- $data = file_get_contents($fname);
- if(isset($_GET['preview']) && getConfig('enable_imagemagick')=='1' && file_exists(getConfig('imagemagick_path')) && substr($row['mimetype'], 0, 6) == 'image/')
+
+ if ( isset($_GET['preview']) && substr($row['mimetype'], 0, 6) == 'image/' )
{
- $nam = tempnam('/tmp', $filename);
- $h = @fopen($nam, 'w');
- if(!$h) die('Error opening '.$nam.' for writing');
- fwrite($h, $data);
- fclose($h);
- /* Make sure the request doesn't contain commandline injection - yow! */
- if(!isset($_GET['width' ]) || (isset($_GET['width'] ) && !preg_match('#^([0-9]+)$#', $_GET['width'] ))) $width = '320'; else $width = $_GET['width' ];
- if(!isset($_GET['height']) || (isset($_GET['height']) && !preg_match('#^([0-9]+)$#', $_GET['height'] ))) $height = '240'; else $height = $_GET['height'];
- $cache_filename=ENANO_ROOT.'/cache/'.$filename.'-'.$row['time_id'].'-'.$width.'x'.$height.$row['file_extension'];
- if(getConfig('cache_thumbs')=='1' && file_exists($cache_filename) && is_writable(ENANO_ROOT.'/cache')) {
- $data = file_get_contents($cache_filename);
- } elseif(getConfig('enable_imagemagick')=='1' && file_exists(getConfig('imagemagick_path'))) {
- // Use ImageMagick to convert the image
- //unlink($nam);
- error_reporting(E_ALL);
- $cmd = ''.getConfig('imagemagick_path').' "'.$nam.'" -resize "'.$width.'x'.$height.'>" "'.$nam.'.scaled'.$row['file_extension'].'"';
- system($cmd, $stat);
- if(!file_exists($nam.'.scaled'.$row['file_extension'])) die('Failed to call ImageMagick (return value '.$stat.'), command line was:<br />'.$cmd);
- $data = file_get_contents($nam.'.scaled'.$row['file_extension']);
- // Be stingy about it - better to re-generate the image hundreds of times than to fail completely
- if(getConfig('cache_thumbs')=='1' && !file_exists($cache_filename)) {
- // Write the generated thumbnail to the cache directory
- $h = @fopen($cache_filename, 'w');
- if(!$h) die('Error opening cache file "'.$cache_filename.'" for writing.');
- fwrite($h, $data);
- fclose($h);
+ // Determine appropriate width and height
+ $width = ( isset($_GET['width']) ) ? intval($_GET['width'] ) : 320;
+ $height = ( isset($_GET['height']) ) ? intval($_GET['height']) : 320;
+ $cache_filename = ENANO_ROOT . "/cache/{$filename}-{$row['time_id']}-{$width}x{$height}{$row['file_extension']}";
+ if ( file_exists($cache_filename) )
+ {
+ $fname = $cache_filename;
+ }
+ else
+ {
+ $allow_scale = false;
+ $orig_fname = $fname;
+ // is caching enabled?
+ if ( getConfig('cache_thumbs') == '1' )
+ {
+ $fname = $cache_filename;
+ if ( is_writeable(dirname($fname)) )
+ {
+ $allow_scale = true;
+ }
+ }
+ else
+ {
+ // Get a temporary file
+ // In this case, the file will not be cached and will be scaled each time it's requested
+ $temp_dir = ( is_dir('/tmp') ) ? '/tmp' : ( isset($_ENV['TEMP']) ) ? $_ENV['TEMP'] : 'SOME RANDOM NAME';
+ // if tempnam() cannot use the specified directory name, it will fall back on the system default
+ $tempname = tempnam($temp_dir, $filename);
+ if ( $tempname && is_writeable($tempname) )
+ {
+ $allow_scale = true;
+ }
+ }
+ if ( $allow_scale )
+ {
+ $result = scale_image($orig_fname, $fname, $width, $height);
+ if ( !$result )
+ $fname = $orig_fname;
+ }
+ else
+ {
+ $fname = $orig_fname;
}
}
- unlink($nam);
}
- $len = strlen($data);
+ $handle = @fopen($fname, 'r');
+ if ( !$handle )
+ die('Can\'t open output file for reading');
+
+ $len = filesize($fname);
header('Content-type: '.$row['mimetype']);
- if(isset($_GET['download'])) header('Content-disposition: attachment, filename="'.$filename.'";');
+ if ( isset($_GET['download']) )
+ {
+ header('Content-disposition: attachment, filename="' . $filename . '";');
+ }
header('Content-length: '.$len);
header('Last-Modified: '.date('r', $row['time_id']));
- echo($data);
+
+ // using this method limits RAM consumption
+ while ( !feof($handle) )
+ {
+ echo fread($handle, 512000);
+ }
+ fclose($handle);
gzip_output();