diff options
-rw-r--r-- | inc/common.php | 30 | ||||
-rw-r--r-- | inc/media.php | 305 | ||||
-rw-r--r-- | lib/exe/fetch.php | 342 |
3 files changed, 339 insertions, 338 deletions
diff --git a/inc/common.php b/inc/common.php index 9b284617b..faee93623 100644 --- a/inc/common.php +++ b/inc/common.php @@ -1424,4 +1424,34 @@ function license_img($type){ return ''; } +/** + * Checks if the given amount of memory is available + * + * If the memory_get_usage() function is not available the + * function just assumes $bytes of already allocated memory + * + * @param int $mem Size of memory you want to allocate in bytes + * @param int $used already allocated memory (see above) + * @author Filip Oscadal <webmaster@illusionsoftworks.cz> + * @author Andreas Gohr <andi@splitbrain.org> + */ +function is_mem_available($mem,$bytes=1048576){ + $limit = trim(ini_get('memory_limit')); + if(empty($limit)) return true; // no limit set! + + // parse limit to bytes + $limit = php_to_byte($limit); + + // get used memory if possible + if(function_exists('memory_get_usage')){ + $used = memory_get_usage(); + } + + if($used+$mem > $limit){ + return false; + } + + return true; +} + //Setup VIM: ex: et ts=2 enc=utf-8 : diff --git a/inc/media.php b/inc/media.php index 0da8a8578..3e54db512 100644 --- a/inc/media.php +++ b/inc/media.php @@ -721,3 +721,308 @@ function media_nstree_li($item){ return '<li class="'.$class.'">'. '<img src="'.$img.'" alt="'.$alt.'" />'; } + +/** + * Resizes the given image to the given size + * + * @author Andreas Gohr <andi@splitbrain.org> + */ +function media_resize_image($file, $ext, $w, $h=0){ + global $conf; + + $info = @getimagesize($file); //get original size + if($info == false) return $file; // that's no image - it's a spaceship! + + if(!$h) $h = round(($w * $info[1]) / $info[0]); + + // we wont scale up to infinity + if($w > 2000 || $h > 2000) return $file; + + //cache + $local = getCacheName($file,'.media.'.$w.'x'.$h.'.'.$ext); + $mtime = @filemtime($local); // 0 if not exists + + if( $mtime > filemtime($file) || + media_resize_imageIM($ext,$file,$info[0],$info[1],$local,$w,$h) || + media_resize_imageGD($ext,$file,$info[0],$info[1],$local,$w,$h) ){ + if($conf['fperm']) chmod($local, $conf['fperm']); + return $local; + } + //still here? resizing failed + return $file; +} + +/** + * Crops the given image to the wanted ratio, then calls media_resize_image to scale it + * to the wanted size + * + * Crops are centered horizontally but prefer the upper third of an vertical + * image because most pics are more interesting in that area (rule of thirds) + * + * @author Andreas Gohr <andi@splitbrain.org> + */ +function media_crop_image($file, $ext, $w, $h=0){ + global $conf; + + if(!$h) $h = $w; + $info = @getimagesize($file); //get original size + if($info == false) return $file; // that's no image - it's a spaceship! + + // calculate crop size + $fr = $info[0]/$info[1]; + $tr = $w/$h; + if($tr >= 1){ + if($tr > $fr){ + $cw = $info[0]; + $ch = (int) $info[0]/$tr; + }else{ + $cw = (int) $info[1]*$tr; + $ch = $info[1]; + } + }else{ + if($tr < $fr){ + $cw = (int) $info[1]*$tr; + $ch = $info[1]; + }else{ + $cw = $info[0]; + $ch = (int) $info[0]/$tr; + } + } + // calculate crop offset + $cx = (int) ($info[0]-$cw)/2; + $cy = (int) ($info[1]-$ch)/3; + + //cache + $local = getCacheName($file,'.media.'.$cw.'x'.$ch.'.crop.'.$ext); + $mtime = @filemtime($local); // 0 if not exists + + if( $mtime > filemtime($file) || + media_crop_imageIM($ext,$file,$info[0],$info[1],$local,$cw,$ch,$cx,$cy) || + media_resize_imageGD($ext,$file,$cw,$ch,$local,$cw,$ch,$cx,$cy) ){ + if($conf['fperm']) chmod($local, $conf['fperm']); + return media_resize_image($local,$ext, $w, $h); + } + + //still here? cropping failed + return media_resize_image($file,$ext, $w, $h); +} + +/** + * Download a remote file and return local filename + * + * returns false if download fails. Uses cached file if available and + * wanted + * + * @author Andreas Gohr <andi@splitbrain.org> + * @author Pavel Vitis <Pavel.Vitis@seznam.cz> + */ +function media_get_from_URL($url,$ext,$cache){ + global $conf; + + // if no cache or fetchsize just redirect + if ($cache==0) return false; + if (!$conf['fetchsize']) return false; + + $local = getCacheName(strtolower($url),".media.$ext"); + $mtime = @filemtime($local); // 0 if not exists + + //decide if download needed: + if( ($mtime == 0) || // cache does not exist + ($cache != -1 && $mtime < time()-$cache) // 'recache' and cache has expired + ){ + if(media_image_download($url,$local)){ + return $local; + }else{ + return false; + } + } + + //if cache exists use it else + if($mtime) return $local; + + //else return false + return false; +} + +/** + * Download image files + * + * @author Andreas Gohr <andi@splitbrain.org> + */ +function media_image_download($url,$file){ + global $conf; + $http = new DokuHTTPClient(); + $http->max_bodysize = $conf['fetchsize']; + $http->timeout = 25; //max. 25 sec + $http->header_regexp = '!\r\nContent-Type: image/(jpe?g|gif|png)!i'; + + $data = $http->get($url); + if(!$data) return false; + + $fileexists = @file_exists($file); + $fp = @fopen($file,"w"); + if(!$fp) return false; + fwrite($fp,$data); + fclose($fp); + if(!$fileexists and $conf['fperm']) chmod($file, $conf['fperm']); + + // check if it is really an image + $info = @getimagesize($file); + if(!$info){ + @unlink($file); + return false; + } + + return true; +} + +/** + * resize images using external ImageMagick convert program + * + * @author Pavel Vitis <Pavel.Vitis@seznam.cz> + * @author Andreas Gohr <andi@splitbrain.org> + */ +function media_resize_imageIM($ext,$from,$from_w,$from_h,$to,$to_w,$to_h){ + global $conf; + + // check if convert is configured + if(!$conf['im_convert']) return false; + + // prepare command + $cmd = $conf['im_convert']; + $cmd .= ' -resize '.$to_w.'x'.$to_h.'!'; + if ($ext == 'jpg' || $ext == 'jpeg') { + $cmd .= ' -quality '.$conf['jpg_quality']; + } + $cmd .= " $from $to"; + + @exec($cmd,$out,$retval); + if ($retval == 0) return true; + return false; +} + +/** + * crop images using external ImageMagick convert program + * + * @author Andreas Gohr <andi@splitbrain.org> + */ +function media_crop_imageIM($ext,$from,$from_w,$from_h,$to,$to_w,$to_h,$ofs_x,$ofs_y){ + global $conf; + + // check if convert is configured + if(!$conf['im_convert']) return false; + + // prepare command + $cmd = $conf['im_convert']; + $cmd .= ' -crop '.$to_w.'x'.$to_h.'+'.$ofs_x.'+'.$ofs_y; + if ($ext == 'jpg' || $ext == 'jpeg') { + $cmd .= ' -quality '.$conf['jpg_quality']; + } + $cmd .= " $from $to"; + + @exec($cmd,$out,$retval); + if ($retval == 0) return true; + return false; +} + +/** + * resize or crop images using PHP's libGD support + * + * @author Andreas Gohr <andi@splitbrain.org> + * @author Sebastian Wienecke <s_wienecke@web.de> + */ +function media_resize_imageGD($ext,$from,$from_w,$from_h,$to,$to_w,$to_h,$ofs_x=0,$ofs_y=0){ + global $conf; + + if($conf['gdlib'] < 1) return false; //no GDlib available or wanted + + // check available memory + if(!is_mem_available(($from_w * $from_h * 4) + ($to_w * $to_h * 4))){ + return false; + } + + // create an image of the given filetype + if ($ext == 'jpg' || $ext == 'jpeg'){ + if(!function_exists("imagecreatefromjpeg")) return false; + $image = @imagecreatefromjpeg($from); + }elseif($ext == 'png') { + if(!function_exists("imagecreatefrompng")) return false; + $image = @imagecreatefrompng($from); + + }elseif($ext == 'gif') { + if(!function_exists("imagecreatefromgif")) return false; + $image = @imagecreatefromgif($from); + } + if(!$image) return false; + + if(($conf['gdlib']>1) && function_exists("imagecreatetruecolor") && $ext != 'gif'){ + $newimg = @imagecreatetruecolor ($to_w, $to_h); + } + if(!$newimg) $newimg = @imagecreate($to_w, $to_h); + if(!$newimg){ + imagedestroy($image); + return false; + } + + //keep png alpha channel if possible + if($ext == 'png' && $conf['gdlib']>1 && function_exists('imagesavealpha')){ + imagealphablending($newimg, false); + imagesavealpha($newimg,true); + } + + //keep gif transparent color if possible + if($ext == 'gif' && function_exists('imagefill') && function_exists('imagecolorallocate')) { + if(function_exists('imagecolorsforindex') && function_exists('imagecolortransparent')) { + $transcolorindex = @imagecolortransparent($image); + if($transcolorindex >= 0 ) { //transparent color exists + $transcolor = @imagecolorsforindex($image, $transcolorindex); + $transcolorindex = @imagecolorallocate($newimg, $transcolor['red'], $transcolor['green'], $transcolor['blue']); + @imagefill($newimg, 0, 0, $transcolorindex); + @imagecolortransparent($newimg, $transcolorindex); + }else{ //filling with white + $whitecolorindex = @imagecolorallocate($newimg, 255, 255, 255); + @imagefill($newimg, 0, 0, $whitecolorindex); + } + }else{ //filling with white + $whitecolorindex = @imagecolorallocate($newimg, 255, 255, 255); + @imagefill($newimg, 0, 0, $whitecolorindex); + } + } + + //try resampling first + if(function_exists("imagecopyresampled")){ + if(!@imagecopyresampled($newimg, $image, 0, 0, $ofs_x, $ofs_y, $to_w, $to_h, $from_w, $from_h)) { + imagecopyresized($newimg, $image, 0, 0, $ofs_x, $ofs_y, $to_w, $to_h, $from_w, $from_h); + } + }else{ + imagecopyresized($newimg, $image, 0, 0, $ofs_x, $ofs_y, $to_w, $to_h, $from_w, $from_h); + } + + $okay = false; + if ($ext == 'jpg' || $ext == 'jpeg'){ + if(!function_exists('imagejpeg')){ + $okay = false; + }else{ + $okay = imagejpeg($newimg, $to, $conf['jpg_quality']); + } + }elseif($ext == 'png') { + if(!function_exists('imagepng')){ + $okay = false; + }else{ + $okay = imagepng($newimg, $to); + } + }elseif($ext == 'gif') { + if(!function_exists('imagegif')){ + $okay = false; + }else{ + $okay = imagegif($newimg, $to); + } + } + + // destroy GD image ressources + if($image) imagedestroy($image); + if($newimg) imagedestroy($newimg); + + return $okay; +} + diff --git a/lib/exe/fetch.php b/lib/exe/fetch.php index 091fd501b..becb60b64 100644 --- a/lib/exe/fetch.php +++ b/lib/exe/fetch.php @@ -10,6 +10,7 @@ define('DOKU_DISABLE_GZIP_OUTPUT', 1); require_once(DOKU_INC.'inc/init.php'); require_once(DOKU_INC.'inc/common.php'); + require_once(DOKU_INC.'inc/media.php'); require_once(DOKU_INC.'inc/pageutils.php'); require_once(DOKU_INC.'inc/confutils.php'); require_once(DOKU_INC.'inc/auth.php'); @@ -33,7 +34,7 @@ //media to local file if(preg_match('#^(https?)://#i',$MEDIA)){ //handle external images - if(strncmp($MIME,'image/',6) == 0) $FILE = get_from_URL($MEDIA,$EXT,$CACHE); + if(strncmp($MIME,'image/',6) == 0) $FILE = media_get_from_URL($MEDIA,$EXT,$CACHE); if(!$FILE){ //download failed - redirect to original URL header('Location: '.$MEDIA); @@ -70,9 +71,9 @@ //handle image resizing/cropping if((substr($MIME,0,5) == 'image') && $WIDTH){ if($HEIGHT){ - $FILE = get_cropped($FILE,$EXT,$WIDTH,$HEIGHT); + $FILE = media_crop_image($FILE,$EXT,$WIDTH,$HEIGHT); }else{ - $FILE = get_resized($FILE,$EXT,$WIDTH,$HEIGHT); + $FILE = media_resize_image($FILE,$EXT,$WIDTH,$HEIGHT); } } @@ -205,92 +206,6 @@ function http_rangeRequest($size){ } /** - * Resizes the given image to the given size - * - * @author Andreas Gohr <andi@splitbrain.org> - */ -function get_resized($file, $ext, $w, $h=0){ - global $conf; - - $info = @getimagesize($file); //get original size - if($info == false) return $file; // that's no image - it's a spaceship! - - if(!$h) $h = round(($w * $info[1]) / $info[0]); - - // we wont scale up to infinity - if($w > 2000 || $h > 2000) return $file; - - //cache - $local = getCacheName($file,'.media.'.$w.'x'.$h.'.'.$ext); - $mtime = @filemtime($local); // 0 if not exists - - if( $mtime > filemtime($file) || - resize_imageIM($ext,$file,$info[0],$info[1],$local,$w,$h) || - resize_imageGD($ext,$file,$info[0],$info[1],$local,$w,$h) ){ - if($conf['fperm']) chmod($local, $conf['fperm']); - return $local; - } - //still here? resizing failed - return $file; -} - -/** - * Crops the given image to the wanted ratio, then calls get_resized to scale it - * to the wanted size - * - * Crops are centered horizontally but prefer the upper third of an vertical - * image because most pics are more interesting in that area (rule of thirds) - * - * @author Andreas Gohr <andi@splitbrain.org> - */ -function get_cropped($file, $ext, $w, $h=0){ - global $conf; - - if(!$h) $h = $w; - $info = @getimagesize($file); //get original size - if($info == false) return $file; // that's no image - it's a spaceship! - - // calculate crop size - $fr = $info[0]/$info[1]; - $tr = $w/$h; - if($tr >= 1){ - if($tr > $fr){ - $cw = $info[0]; - $ch = (int) $info[0]/$tr; - }else{ - $cw = (int) $info[1]*$tr; - $ch = $info[1]; - } - }else{ - if($tr < $fr){ - $cw = (int) $info[1]*$tr; - $ch = $info[1]; - }else{ - $cw = $info[0]; - $ch = (int) $info[0]/$tr; - } - } - // calculate crop offset - $cx = (int) ($info[0]-$cw)/2; - $cy = (int) ($info[1]-$ch)/3; - - //cache - $local = getCacheName($file,'.media.'.$cw.'x'.$ch.'.crop.'.$ext); - $mtime = @filemtime($local); // 0 if not exists - - if( $mtime > filemtime($file) || - crop_imageIM($ext,$file,$info[0],$info[1],$local,$cw,$ch,$cx,$cy) || - resize_imageGD($ext,$file,$cw,$ch,$local,$cw,$ch,$cx,$cy) ){ - if($conf['fperm']) chmod($local, $conf['fperm']); - return get_resized($local,$ext, $w, $h); - } - - //still here? cropping failed - return get_resized($file,$ext, $w, $h); -} - - -/** * Returns the wanted cachetime in seconds * * Resolves named constants @@ -305,254 +220,5 @@ function calc_cache($cache){ return -1; //cache endless } -/** - * Download a remote file and return local filename - * - * returns false if download fails. Uses cached file if available and - * wanted - * - * @author Andreas Gohr <andi@splitbrain.org> - * @author Pavel Vitis <Pavel.Vitis@seznam.cz> - */ -function get_from_URL($url,$ext,$cache){ - global $conf; - - // if no cache or fetchsize just redirect - if ($cache==0) return false; - if (!$conf['fetchsize']) return false; - - $local = getCacheName(strtolower($url),".media.$ext"); - $mtime = @filemtime($local); // 0 if not exists - - //decide if download needed: - if( ($mtime == 0) || // cache does not exist - ($cache != -1 && $mtime < time()-$cache) // 'recache' and cache has expired - ){ - if(image_download($url,$local)){ - return $local; - }else{ - return false; - } - } - - //if cache exists use it else - if($mtime) return $local; - - //else return false - return false; -} - -/** - * Download image files - * - * @author Andreas Gohr <andi@splitbrain.org> - */ -function image_download($url,$file){ - global $conf; - $http = new DokuHTTPClient(); - $http->max_bodysize = $conf['fetchsize']; - $http->timeout = 25; //max. 25 sec - $http->header_regexp = '!\r\nContent-Type: image/(jpe?g|gif|png)!i'; - - $data = $http->get($url); - if(!$data) return false; - - $fileexists = @file_exists($file); - $fp = @fopen($file,"w"); - if(!$fp) return false; - fwrite($fp,$data); - fclose($fp); - if(!$fileexists and $conf['fperm']) chmod($file, $conf['fperm']); - - // check if it is really an image - $info = @getimagesize($file); - if(!$info){ - @unlink($file); - return false; - } - - return true; -} - -/** - * resize images using external ImageMagick convert program - * - * @author Pavel Vitis <Pavel.Vitis@seznam.cz> - * @author Andreas Gohr <andi@splitbrain.org> - */ -function resize_imageIM($ext,$from,$from_w,$from_h,$to,$to_w,$to_h){ - global $conf; - - // check if convert is configured - if(!$conf['im_convert']) return false; - - // prepare command - $cmd = $conf['im_convert']; - $cmd .= ' -resize '.$to_w.'x'.$to_h.'!'; - if ($ext == 'jpg' || $ext == 'jpeg') { - $cmd .= ' -quality '.$conf['jpg_quality']; - } - $cmd .= " $from $to"; - - @exec($cmd,$out,$retval); - if ($retval == 0) return true; - return false; -} - -/** - * crop images using external ImageMagick convert program - * - * @author Andreas Gohr <andi@splitbrain.org> - */ -function crop_imageIM($ext,$from,$from_w,$from_h,$to,$to_w,$to_h,$ofs_x,$ofs_y){ - global $conf; - - // check if convert is configured - if(!$conf['im_convert']) return false; - - // prepare command - $cmd = $conf['im_convert']; - $cmd .= ' -crop '.$to_w.'x'.$to_h.'+'.$ofs_x.'+'.$ofs_y; - if ($ext == 'jpg' || $ext == 'jpeg') { - $cmd .= ' -quality '.$conf['jpg_quality']; - } - $cmd .= " $from $to"; - - @exec($cmd,$out,$retval); - if ($retval == 0) return true; - return false; -} - -/** - * resize or crop images using PHP's libGD support - * - * @author Andreas Gohr <andi@splitbrain.org> - * @author Sebastian Wienecke <s_wienecke@web.de> - */ -function resize_imageGD($ext,$from,$from_w,$from_h,$to,$to_w,$to_h,$ofs_x=0,$ofs_y=0){ - global $conf; - - if($conf['gdlib'] < 1) return false; //no GDlib available or wanted - - // check available memory - if(!is_mem_available(($from_w * $from_h * 4) + ($to_w * $to_h * 4))){ - return false; - } - - // create an image of the given filetype - if ($ext == 'jpg' || $ext == 'jpeg'){ - if(!function_exists("imagecreatefromjpeg")) return false; - $image = @imagecreatefromjpeg($from); - }elseif($ext == 'png') { - if(!function_exists("imagecreatefrompng")) return false; - $image = @imagecreatefrompng($from); - - }elseif($ext == 'gif') { - if(!function_exists("imagecreatefromgif")) return false; - $image = @imagecreatefromgif($from); - } - if(!$image) return false; - - if(($conf['gdlib']>1) && function_exists("imagecreatetruecolor") && $ext != 'gif'){ - $newimg = @imagecreatetruecolor ($to_w, $to_h); - } - if(!$newimg) $newimg = @imagecreate($to_w, $to_h); - if(!$newimg){ - imagedestroy($image); - return false; - } - - //keep png alpha channel if possible - if($ext == 'png' && $conf['gdlib']>1 && function_exists('imagesavealpha')){ - imagealphablending($newimg, false); - imagesavealpha($newimg,true); - } - - //keep gif transparent color if possible - if($ext == 'gif' && function_exists('imagefill') && function_exists('imagecolorallocate')) { - if(function_exists('imagecolorsforindex') && function_exists('imagecolortransparent')) { - $transcolorindex = @imagecolortransparent($image); - if($transcolorindex >= 0 ) { //transparent color exists - $transcolor = @imagecolorsforindex($image, $transcolorindex); - $transcolorindex = @imagecolorallocate($newimg, $transcolor['red'], $transcolor['green'], $transcolor['blue']); - @imagefill($newimg, 0, 0, $transcolorindex); - @imagecolortransparent($newimg, $transcolorindex); - }else{ //filling with white - $whitecolorindex = @imagecolorallocate($newimg, 255, 255, 255); - @imagefill($newimg, 0, 0, $whitecolorindex); - } - }else{ //filling with white - $whitecolorindex = @imagecolorallocate($newimg, 255, 255, 255); - @imagefill($newimg, 0, 0, $whitecolorindex); - } - } - - //try resampling first - if(function_exists("imagecopyresampled")){ - if(!@imagecopyresampled($newimg, $image, 0, 0, $ofs_x, $ofs_y, $to_w, $to_h, $from_w, $from_h)) { - imagecopyresized($newimg, $image, 0, 0, $ofs_x, $ofs_y, $to_w, $to_h, $from_w, $from_h); - } - }else{ - imagecopyresized($newimg, $image, 0, 0, $ofs_x, $ofs_y, $to_w, $to_h, $from_w, $from_h); - } - - $okay = false; - if ($ext == 'jpg' || $ext == 'jpeg'){ - if(!function_exists('imagejpeg')){ - $okay = false; - }else{ - $okay = imagejpeg($newimg, $to, $conf['jpg_quality']); - } - }elseif($ext == 'png') { - if(!function_exists('imagepng')){ - $okay = false; - }else{ - $okay = imagepng($newimg, $to); - } - }elseif($ext == 'gif') { - if(!function_exists('imagegif')){ - $okay = false; - }else{ - $okay = imagegif($newimg, $to); - } - } - - // destroy GD image ressources - if($image) imagedestroy($image); - if($newimg) imagedestroy($newimg); - - return $okay; -} - -/** - * Checks if the given amount of memory is available - * - * If the memory_get_usage() function is not available the - * function just assumes $bytes of already allocated memory - * - * @param int $mem Size of memory you want to allocate in bytes - * @param int $used already allocated memory (see above) - * @author Filip Oscadal <webmaster@illusionsoftworks.cz> - * @author Andreas Gohr <andi@splitbrain.org> - */ -function is_mem_available($mem,$bytes=1048576){ - $limit = trim(ini_get('memory_limit')); - if(empty($limit)) return true; // no limit set! - - // parse limit to bytes - $limit = php_to_byte($limit); - - // get used memory if possible - if(function_exists('memory_get_usage')){ - $used = memory_get_usage(); - } - - if($used+$mem > $limit){ - return false; - } - - return true; -} - //Setup VIM: ex: et ts=2 enc=utf-8 : ?> |