A few miscellaneous fixes including modifying WebServer to write data in chunks (improved performance and reliability on a slow connection)
<?php
/**
* Greyhound - real web management for Amarok
* Copyright (C) 2008 Dan Fuhry
*
* This program is Free Software; you can redistribute and/or modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for details.
*/
/**
* Determines an image's filetype based on its signature.
* @param string Path to image file
* @return string One of gif, png, or jpg, or false if none of these.
*/
function get_image_filetype($filename)
{
$filecontents = @file_get_contents($filename);
if ( empty($filecontents) )
return false;
if ( substr($filecontents, 0, 8) == "\x89\x50\x4e\x47\x0d\x0a\x1a\x0a" )
return 'png';
if ( substr($filecontents, 0, 6) == 'GIF87a' || substr($filecontents, 0, 6) == 'GIF89a' )
return 'gif';
if ( substr($filecontents, 0, 2) == "\xFF\xD8" )
return 'jpg';
return false;
}
/**
* 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, unless $preserve_ratio is set to false.
*
* Ported from Enano CMS (which is also my project)
*
* @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
* @param bool If true, preserves the image's aspect ratio (default)
* @return bool True on success, false on failure
*/
function scale_image($in_file, $out_file, $width = 225, $height = 225, $unlink = false, $preserve_ratio = true)
{
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) )
return false;
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;
}
// try to find convert in the PATH
// FIXME: unix specific (won't work on windows)
$path = ( isset($_ENV['PATH']) ) ? $_ENV['PATH'] : ( isset($_SERVER['PATH']) ? $_SERVER['PATH'] : '/usr/local/bin:/usr/bin:/bin' );
$path = explode(':', $path);
foreach ( $path as $dir )
{
if ( file_exists("$dir/convert") && is_executable("$dir/convert") )
{
$magick_path = "$dir/convert";
}
}
$can_use_magick = isset($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) )
{
// ImageMagick path seems screwy
return false;
}
$op = ( $preserve_ratio ) ? '>' : '!';
$cmdline = "\"$magick_path\" \"$in_file\" -resize '{$width}x{$height}$op' \"$out_file\"";
exec($cmdline, $output, $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
if ( $preserve_ratio )
{
$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;
}
}
else
{
$new_width = $width;
$new_height = $height;
}
$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;
}
if ( file_exists($out_file) )
return true;
return false;
}