You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@cocoon.apache.org by fe...@apache.org on 2007/07/22 16:51:30 UTC

svn commit: r558490 [17/33] - in /cocoon/trunk/blocks/cocoon-forms/cocoon-forms-impl/src/main/resources/org/apache/cocoon/forms/resources/xinha: ./ images/ images/de/ images/fr/ lang/ modules/ modules/ColorPicker/ modules/CreateLink/ modules/Dialogs/ m...

Added: cocoon/trunk/blocks/cocoon-forms/cocoon-forms-impl/src/main/resources/org/apache/cocoon/forms/resources/xinha/plugins/ImageManager/Classes/Files.php
URL: http://svn.apache.org/viewvc/cocoon/trunk/blocks/cocoon-forms/cocoon-forms-impl/src/main/resources/org/apache/cocoon/forms/resources/xinha/plugins/ImageManager/Classes/Files.php?view=auto&rev=558490
==============================================================================
--- cocoon/trunk/blocks/cocoon-forms/cocoon-forms-impl/src/main/resources/org/apache/cocoon/forms/resources/xinha/plugins/ImageManager/Classes/Files.php (added)
+++ cocoon/trunk/blocks/cocoon-forms/cocoon-forms-impl/src/main/resources/org/apache/cocoon/forms/resources/xinha/plugins/ImageManager/Classes/Files.php Sun Jul 22 07:50:10 2007
@@ -0,0 +1,333 @@
+<?php
+/**
+ * File Utilities.
+ * @author $Author: ray $
+ * @version $Id: Files.php 709 2007-01-30 23:22:04Z ray $
+ * @package ImageManager
+ */
+
+define('FILE_ERROR_NO_SOURCE', 100);
+define('FILE_ERROR_COPY_FAILED', 101);
+define('FILE_ERROR_DST_DIR_FAILED', 102);
+define('FILE_COPY_OK', 103);
+define('FILE_ERROR_DST_DIR_EXIST', 104);
+
+/**
+ * File Utilities
+ * @author $Author: ray $
+ * @version $Id: Files.php 709 2007-01-30 23:22:04Z ray $
+ * @package ImageManager
+ * @subpackage files
+ */
+class Files 
+{
+	
+	/**
+	 * Copy a file from source to destination. If unique == true, then if
+	 * the destination exists, it will be renamed by appending an increamenting 
+	 * counting number.
+	 * @param string $source where the file is from, full path to the files required
+	 * @param string $destination_file name of the new file, just the filename
+	 * @param string $destination_dir where the files, just the destination dir,
+	 * e.g., /www/html/gallery/
+	 * @param boolean $unique create unique destination file if true.
+	 * @return string the new copied filename, else error if anything goes bad.
+	 */
+	function copyFile($source, $destination_dir, $destination_file, $unique=true) 
+	{
+		if(!(file_exists($source) && is_file($source))) 
+			return FILE_ERROR_NO_SOURCE;
+
+		$destination_dir = Files::fixPath($destination_dir);
+
+		if(!is_dir($destination_dir)) 
+			Return FILE_ERROR_DST_DIR_FAILED;
+
+		$filename = Files::escape($destination_file);
+
+		if($unique) 
+		{
+			$dotIndex = strrpos($destination_file, '.');
+			$ext = '';
+			if(is_int($dotIndex)) 
+			{
+				$ext = substr($destination_file, $dotIndex);
+				$base = substr($destination_file, 0, $dotIndex);
+			}
+			$counter = 0;
+			while(is_file($destination_dir.$filename)) 
+			{
+				$counter++;
+				$filename = $base.'_'.$counter.$ext;
+			}
+		}
+
+		if (!copy($source, $destination_dir.$filename))
+			return FILE_ERROR_COPY_FAILED;
+		
+		//verify that it copied, new file must exists
+		if (is_file($destination_dir.$filename))
+			Return $filename;
+		else
+			return FILE_ERROR_COPY_FAILED;
+	}
+
+	/**
+	 * Create a new folder.
+	 * @param string $newFolder specifiy the full path of the new folder.
+	 * @return boolean true if the new folder is created, false otherwise.
+	 */
+	function createFolder($newFolder) 
+	{
+		mkdir ($newFolder, 0777);
+		return chmod($newFolder, 0777);
+	}
+
+
+	/**
+	 * Escape the filenames, any non-word characters will be
+	 * replaced by an underscore.
+	 * @param string $filename the orginal filename
+	 * @return string the escaped safe filename
+	 */
+	function escape($filename)
+	{
+		Return preg_replace('/[^\w\._]/', '_', $filename);
+	}
+
+	/**
+	 * Delete a file.
+	 * @param string $file file to be deleted
+	 * @return boolean true if deleted, false otherwise.
+	 */
+	function delFile($file) 
+	{
+		if(is_file($file)) 
+			Return unlink($file);
+		else
+			Return false;
+	}
+
+	/**
+	 * Delete folder(s), can delete recursively.
+	 * @param string $folder the folder to be deleted.
+	 * @param boolean $recursive if true, all files and sub-directories
+	 * are delete. If false, tries to delete the folder, can throw
+	 * error if the directory is not empty.
+	 * @return boolean true if deleted.
+	 */
+	function delFolder($folder, $recursive=false) 
+	{
+		$deleted = true;
+		if($recursive) 
+		{
+			$d = dir($folder);
+			while (false !== ($entry = $d->read())) 
+			{
+				if ($entry != '.' && $entry != '..')
+				{
+					$obj = Files::fixPath($folder).$entry;
+					//var_dump($obj);
+					if (is_file($obj))
+					{
+						$deleted &= Files::delFile($obj);					
+					}
+					else if(is_dir($obj))
+					{
+						$deleted &= Files::delFolder($obj, $recursive);
+					}
+					
+				}
+			}
+			$d->close();
+
+		}
+
+		//$folder= $folder.'/thumbs';
+		//var_dump($folder);
+		if(is_dir($folder)) 
+			$deleted &= rmdir($folder);
+		else
+			$deleted &= false;
+
+		Return $deleted;
+	}
+
+	/**
+	 * Append a / to the path if required.
+	 * @param string $path the path
+	 * @return string path with trailing /
+	 */
+	function fixPath($path) 
+	{
+		//append a slash to the path if it doesn't exists.
+		if(!(substr($path,-1) == '/'))
+			$path .= '/';
+		Return $path;
+	}
+
+	/**
+	 * Concat two paths together. Basically $pathA+$pathB
+	 * @param string $pathA path one
+	 * @param string $pathB path two
+	 * @return string a trailing slash combinded path.
+	 */
+	function makePath($pathA, $pathB) 
+	{
+		$pathA = Files::fixPath($pathA);
+		if(substr($pathB,0,1)=='/')
+			$pathB = substr($pathB,1);
+		Return Files::fixPath($pathA.$pathB);
+	}
+
+	/**
+	 * Similar to makePath, but the second parameter
+	 * is not only a path, it may contain say a file ending.
+	 * @param string $pathA the leading path
+	 * @param string $pathB the ending path with file
+	 * @return string combined file path.
+	 */
+	function makeFile($pathA, $pathB) 
+	{		
+		$pathA = Files::fixPath($pathA);
+		if(substr($pathB,0,1)=='/')
+			$pathB = substr($pathB,1);
+		
+		Return $pathA.$pathB;
+	}
+
+	
+	/**
+	 * Format the file size, limits to Mb.
+	 * @param int $size the raw filesize
+	 * @return string formated file size.
+	 */
+	function formatSize($size) 
+	{
+		if($size < 1024) 
+			return $size.' bytes';	
+		else if($size >= 1024 && $size < 1024*1024) 
+			return sprintf('%01.2f',$size/1024.0).' KB';
+		else
+			return sprintf('%01.2f',$size/(1024.0*1024)).' MB';
+	}
+
+	/**
+	 * Returns size of a directory, with all file & subdirectory
+	 * sizes added up
+	 * @param string dir path
+	 * @return int
+	 */
+	function dirSize($dirName = '.')
+	{
+		$dir  = dir($dirName);
+		$size = 0;
+
+		while ($file = $dir->read()) {
+			if ($file != '.' && $file != '..')
+			{
+				if (is_dir("$dirName$file"))
+				{
+					$size += Files::dirSize($dirName . '/' . $file);
+				}
+				else
+				{
+					$size += filesize($dirName . '/' . $file);
+				}
+			}
+		}
+		$dir->close();
+		return $size;
+	}
+	
+	/**
+	 * Renames file, preserving its directory and extension
+	 * @param string $oldPath path to the old existing file
+	 * @param string new filename (just the name, without path or extension)
+	 * @author Krzysztof Kotowicz <ko...@webworkers.pl>
+	 */
+	function renameFile($oldPath, $newName) {
+
+		if(!(file_exists($oldPath) && is_file($oldPath)))
+			return FILE_ERROR_NO_SOURCE;
+
+		$oldFileParts = pathinfo($oldPath);
+
+		$newPath = $oldFileParts['dirname'] . '/'
+				   . $newName
+				   . (!empty($oldFileParts['extension']) ? '.' . $oldFileParts['extension'] : '');
+
+		if (file_exists($newPath))
+			return false;
+
+		if (!rename($oldPath, $newPath))
+			return FILE_ERROR_COPY_FAILED;
+
+	}
+	
+	function rename ($oldPath,$newPath)
+	{
+		if(!(is_dir($oldPath) || is_file($oldPath)))
+			return FILE_ERROR_NO_SOURCE;
+		
+		if (file_exists($newPath))
+			return FILE_ERROR_DST_DIR_EXIST;
+
+		$ret = rename($oldPath, $newPath);
+		if (!$ret)
+			return FILE_ERROR_COPY_FAILED;
+		else return FILE_COPY_OK;
+	}
+	
+		/**
+	 * copy a directory and all subdirectories and files (recursive)
+	 * @author SBoisvert at Don'tSpamMe dot Bryxal dot ca (adapted from php.net)
+	 * @author Raimund Meyer
+	 * @param string base path
+	 * @param string source directory
+	 * @param string destination directory
+	 * @param bool   overwrite existing files
+	 *  
+	 * @return mixed bool true on pass, number on fail
+	 */
+  	function copyDir($basePath, $source, $dest, $overwrite = false)
+	{
+		if(!is_dir($basePath . $dest))
+		{
+			if (!@mkdir($basePath . $dest)) return FILE_ERROR_DST_DIR_FAILED;	
+		}
+		if($handle = opendir($basePath . $source))
+		{        // if the folder exploration is sucsessful, continue
+			while( ($file = readdir($handle)) !== false)
+			{ // as long as storing the next file to $file is successful, continue
+				if($file != '.' && $file != '..')
+				{
+					$path = $source . '/' . $file;
+					if(is_file($basePath . $path))
+					{
+						/*if(!is_file($basePath . $dest . '/' . $file) || $overwrite)
+						{
+							if(!@copy($basePath . $path, $basePath . $dest . '/' . $file))
+							{
+							  return FILE_ERROR_COPY_FAILED;
+							}
+						}*/
+						Files::copyFile($basePath . $path, $basePath . $dest . '/', $file, true);
+					} 
+					elseif(is_dir($basePath . $path))
+					{
+						if(!is_dir($basePath . $dest . '/' . $file))
+						{
+							mkdir($basePath . $dest . '/' . $file); // make subdirectory before subdirectory is copied
+							Files::copyDir($basePath, $path, $dest . '/' . $file, $overwrite); //recurse!
+						}
+					}
+				}
+			}
+			closedir($handle);
+		}
+		return true;
+	}
+}
+
+?>

Added: cocoon/trunk/blocks/cocoon-forms/cocoon-forms-impl/src/main/resources/org/apache/cocoon/forms/resources/xinha/plugins/ImageManager/Classes/GD.php
URL: http://svn.apache.org/viewvc/cocoon/trunk/blocks/cocoon-forms/cocoon-forms-impl/src/main/resources/org/apache/cocoon/forms/resources/xinha/plugins/ImageManager/Classes/GD.php?view=auto&rev=558490
==============================================================================
--- cocoon/trunk/blocks/cocoon-forms/cocoon-forms-impl/src/main/resources/org/apache/cocoon/forms/resources/xinha/plugins/ImageManager/Classes/GD.php (added)
+++ cocoon/trunk/blocks/cocoon-forms/cocoon-forms-impl/src/main/resources/org/apache/cocoon/forms/resources/xinha/plugins/ImageManager/Classes/GD.php Sun Jul 22 07:50:10 2007
@@ -0,0 +1,503 @@
+<?php
+/***********************************************************************
+** Title.........:  GD Driver
+** Version.......:  1.0
+** Author........:  Xiang Wei ZHUO <we...@zhuo.org>
+** Filename......:  GD.php
+** Last changed..:  30 Aug 2003 
+** Notes.........:  Orginal is from PEAR
+**/
+// +----------------------------------------------------------------------+
+// | PHP Version 4                                                        |
+// +----------------------------------------------------------------------+
+// | Copyright (c) 1997-2002 The PHP Group                                |
+// +----------------------------------------------------------------------+
+// | This source file is subject to version 2.02 of the PHP license,      |
+// | that is bundled with this package in the file LICENSE, and is        |
+// | available at through the world-wide-web at                           |
+// | http://www.php.net/license/2_02.txt.                                 |
+// | If you did not receive a copy of the PHP license and are unable to   |
+// | obtain it through the world-wide-web, please send a note to          |
+// | license@php.net so we can mail you a copy immediately.               |
+// +----------------------------------------------------------------------+
+// | Authors: Peter Bowyer <pe...@mapledesign.co.uk>                      |
+// |          Alan Knowles <al...@akbkhome.com>                            |
+// +----------------------------------------------------------------------+
+//
+//    Usage :
+//    $img    = new Image_Transform_GD();
+//    $angle  = -78;
+//    $img->load('magick.png');
+//
+//    if($img->rotate($angle,array('autoresize'=>true,'color_mask'=>array(255,0,0)))){
+//        $img->addText(array('text'=>"Rotation $angle",'x'=>0,'y'=>100,'font'=>'/usr/share/fonts/default/TrueType/cogb____.ttf'));
+//        $img->display();
+//    } else {
+//        echo "Error";
+//    }
+//
+//
+// $Id: GD.php 709 2007-01-30 23:22:04Z ray $
+//
+// Image Transformation interface using the GD library
+//
+
+require_once "../ImageManager/Classes/Transform.php";
+
+Class Image_Transform_Driver_GD extends Image_Transform
+{
+    /**
+     * Holds the image file for manipulation
+     */
+    var $imageHandle = '';
+
+    /**
+     * Holds the original image file
+     */
+    var $old_image = '';
+
+    /**
+     * Check settings
+     *
+     * @return mixed true or  or a PEAR error object on error
+     *
+     * @see PEAR::isError()
+     */
+    function Image_Transform_GD()
+    {
+        return;
+    } // End function Image
+
+    /**
+     * Load image
+     *
+     * @param string filename
+     *
+     * @return mixed none or a PEAR error object on error
+     * @see PEAR::isError()
+     */
+    function load($image)
+    {
+        $this->uid = md5($_SERVER['REMOTE_ADDR']);
+        $this->image = $image;
+        $this->_get_image_details($image);
+        $functionName = 'ImageCreateFrom' . $this->type;
+		if(function_exists($functionName))
+		{
+			$this->imageHandle = $functionName($this->image);
+		}
+    } // End load
+
+    /**
+     * addText
+     *
+     * @param   array   options     Array contains options
+     *                              array(
+     *                                  'text'  The string to draw
+     *                                  'x'     Horizontal position
+     *                                  'y'     Vertical Position
+     *                                  'Color' Font color
+     *                                  'font'  Font to be used
+     *                                  'size'  Size of the fonts in pixel
+     *                                  'resize_first'  Tell if the image has to be resized
+     *                                                  before drawing the text
+     *                              )
+     *
+     * @return none
+     * @see PEAR::isError()
+     */
+    function addText($params)
+    {
+        $default_params = array(
+                                'text' => 'This is Text',
+                                'x' => 10,
+                                'y' => 20,
+                                'color' => array(255,0,0),
+                                'font' => 'Arial.ttf',
+                                'size' => '12',
+                                'angle' => 0,
+                                'resize_first' => false // Carry out the scaling of the image before annotation?  Not used for GD
+                                );
+        $params = array_merge($default_params, $params);
+        extract($params);
+
+        if( !is_array($color) ){
+            if ($color[0]=='#'){
+                $this->colorhex2colorarray( $color );
+            } else {
+                include_once('Image/Transform/Driver/ColorsDefs.php');
+                $color = isset($colornames[$color])?$colornames[$color]:false;
+            }
+        }
+
+        $c = imagecolorresolve ($this->imageHandle, $color[0], $color[1], $color[2]);
+
+        if ('ttf' == substr($font, -3)) {
+            ImageTTFText($this->imageHandle, $size, $angle, $x, $y, $c, $font, $text);
+        } else {
+            ImagePSText($this->imageHandle, $size, $angle, $x, $y, $c, $font, $text);
+        }
+        return true;
+    } // End addText
+
+
+    /**
+     * Rotate image by the given angle
+     * Uses a fast rotation algorythm for custom angles
+     * or lines copy for multiple of 90 degrees
+     *
+     * @param int       $angle      Rotation angle
+     * @param array     $options    array(  'autoresize'=>true|false,
+     *                                      'color_mask'=>array(r,g,b), named color or #rrggbb
+     *                                   )
+     * @author Pierre-Alain Joye
+     * @return mixed none or a PEAR error object on error
+     * @see PEAR::isError()
+     */
+    function rotate($angle, $options=null)
+    {
+        if(function_exists('imagerotate')) {
+            $white = imagecolorallocate ($this->imageHandle, 255, 255, 255);
+			$this->imageHandle = imagerotate($this->imageHandle, $angle, $white);
+            return true;
+        }
+
+        if ( $options==null ){
+            $autoresize = true;
+            $color_mask = array(255,255,0);
+        } else {
+            extract( $options );
+        }
+
+        while ($angle <= -45) {
+            $angle  += 360;
+        }
+        while ($angle > 270) {
+            $angle  -= 360;
+        }
+
+        $t      = deg2rad($angle);
+
+        if( !is_array($color_mask) ){
+            if ($color[0]=='#'){
+                $this->colorhex2colorarray( $color_mask );
+            } else {
+                include_once('Image/Transform/Driver/ColorDefs.php');
+                $color = isset($colornames[$color_mask])?$colornames[$color_mask]:false;
+            }
+        }
+
+        // Do not round it, too much lost of quality
+        $cosT   = cos($t);
+        $sinT   = sin($t);
+
+        $img    =& $this->imageHandle;
+
+        $width  = $max_x  = $this->img_x;
+        $height = $max_y  = $this->img_y;
+        $min_y  = 0;
+        $min_x  = 0;
+
+        $x1     = round($max_x/2,0);
+        $y1     = round($max_y/2,0);
+
+        if ( $autoresize ){
+            $t      = abs($t);
+            $a      = round($angle,0);
+            switch((int)($angle)){
+                case 0:
+                        $width2     = $width;
+                        $height2    = $height;
+                    break;
+                case 90:
+                        $width2     = $height;
+                        $height2    = $width;
+                    break;
+                case 180:
+                        $width2     = $width;
+                        $height2    = $height;
+                    break;
+                case 270:
+                        $width2     = $height;
+                        $height2    = $width;
+                    break;
+                default:
+                    $width2     = (int)(abs(sin($t) * $height + cos($t) * $width));
+                    $height2    = (int)(abs(cos($t) * $height+sin($t) * $width));
+            }
+
+            $width2     -= $width2%2;
+            $height2    -= $height2%2;
+
+            $d_width    = abs($width - $width2);
+            $d_height   = abs($height - $height2);
+            $x_offset   = $d_width/2;
+            $y_offset   = $d_height/2;
+            $min_x2     = -abs($x_offset);
+            $min_y2     = -abs($y_offset);
+            $max_x2     = $width2;
+            $max_y2     = $height2;
+        }
+
+        $img2   = @imagecreate($width2,$height2);
+
+        if ( !is_resource($img2) ){
+            return false;/*PEAR::raiseError('Cannot create buffer for the rotataion.',
+                                null, PEAR_ERROR_TRIGGER, E_USER_NOTICE);*/
+        }
+
+        $this->img_x = $width2;
+        $this->img_y = $height2;
+
+
+        imagepalettecopy($img2,$img);
+
+        $mask   = imagecolorresolve($img2,$color_mask[0],$color_mask[1],$color_mask[2]);
+
+        // use simple lines copy for axes angles
+        switch((int)($angle)){
+            case 0:
+                imagefill ($img2, 0, 0,$mask);
+                for ($y=0; $y < $max_y; $y++) {
+                    for ($x = $min_x; $x < $max_x; $x++){
+                        $c  = @imagecolorat ( $img, $x, $y);
+                        imagesetpixel($img2,$x+$x_offset,$y+$y_offset,$c);
+                    }
+                }
+                break;
+            case 90:
+                imagefill ($img2, 0, 0,$mask);
+                for ($x = $min_x; $x < $max_x; $x++){
+                    for ($y=$min_y; $y < $max_y; $y++) {
+                        $c  = imagecolorat ( $img, $x, $y);
+                        imagesetpixel($img2,$max_y-$y-1,$x,$c);
+                    }
+                }
+                break;
+            case 180:
+                imagefill ($img2, 0, 0,$mask);
+                for ($y=0; $y < $max_y; $y++) {
+                    for ($x = $min_x; $x < $max_x; $x++){
+                        $c  = @imagecolorat ( $img, $x, $y);
+                        imagesetpixel($img2, $max_x2-$x-1, $max_y2-$y-1, $c);
+                    }
+                }
+                break;
+            case 270:
+                imagefill ($img2, 0, 0,$mask);
+                for ($y=0; $y < $max_y; $y++) {
+                    for ($x = $max_x; $x >= $min_x; $x--){
+                        $c  = @imagecolorat ( $img, $x, $y);
+                        imagesetpixel($img2,$y,$max_x-$x-1,$c);
+                    }
+                }
+                break;
+            // simple reverse rotation algo
+            default:
+                $i=0;
+                for ($y = $min_y2; $y < $max_y2; $y++){
+
+                    // Algebra :)
+                    $x2 = round((($min_x2-$x1) * $cosT) + (($y-$y1) * $sinT + $x1),0);
+                    $y2 = round((($y-$y1) * $cosT - ($min_x2-$x1) * $sinT + $y1),0);
+
+                    for ($x = $min_x2; $x < $max_x2; $x++){
+
+                        // Check if we are out of original bounces, if we are
+                        // use the default color mask
+                        if ( $x2>=0 && $x2<$max_x && $y2>=0 && $y2<$max_y ){
+                            $c  = imagecolorat ( $img, $x2, $y2);
+                        } else {
+                            $c  = $mask;
+                        }
+                        imagesetpixel($img2,$x+$x_offset,$y+$y_offset,$c);
+
+                        // round verboten!
+                        $x2  += $cosT;
+                        $y2  -= $sinT;
+                    }
+                }
+                break;
+        }
+        $this->old_image    = $this->imageHandle;
+        $this->imageHandle  =  $img2;
+        return true;
+    }
+
+
+   /**
+    * Resize Action
+    *
+    * For GD 2.01+ the new copyresampled function is used
+    * It uses a bicubic interpolation algorithm to get far
+    * better result.
+    *
+    * @param int  $new_x new width
+    * @param int  $new_y new height
+    *
+    * @return true on success or pear error
+    * @see PEAR::isError()
+    */
+    function _resize($new_x, $new_y) {
+        if ($this->resized === true) {
+            return false; /*PEAR::raiseError('You have already resized the image without saving it.  Your previous resizing will be overwritten', null, PEAR_ERROR_TRIGGER, E_USER_NOTICE);*/
+        }
+        if(function_exists('ImageCreateTrueColor')){
+            $new_img =ImageCreateTrueColor($new_x,$new_y);
+        } else {
+            $new_img =ImageCreate($new_x,$new_y);
+        }
+        if(function_exists('ImageCopyResampled')){
+            ImageCopyResampled($new_img, $this->imageHandle, 0, 0, 0, 0, $new_x, $new_y, $this->img_x, $this->img_y);
+        } else {
+            ImageCopyResized($new_img, $this->imageHandle, 0, 0, 0, 0, $new_x, $new_y, $this->img_x, $this->img_y);
+        }
+        $this->old_image = $this->imageHandle;
+        $this->imageHandle = $new_img;
+        $this->resized = true;
+
+        $this->new_x = $new_x;
+        $this->new_y = $new_y;
+        return true;
+    }
+
+    /**
+     * Crop the image
+     *
+     * @param int $crop_x left column of the image
+     * @param int $crop_y top row of the image
+     * @param int $crop_width new cropped image width
+     * @param int $crop_height new cropped image height
+     */
+    function crop($new_x, $new_y, $new_width, $new_height) 
+    {
+        if(function_exists('ImageCreateTrueColor')){
+            $new_img =ImageCreateTrueColor($new_width,$new_height);
+        } else {
+            $new_img =ImageCreate($new_width,$new_height);
+        }
+        if(function_exists('ImageCopyResampled')){
+            ImageCopyResampled($new_img, $this->imageHandle, 0, 0, $new_x, $new_y,$new_width,$new_height,$new_width,$new_height);
+        } else {
+            ImageCopyResized($new_img, $this->imageHandle, 0, 0, $new_x, $new_y, $new_width,$new_height,$new_width,$new_height);
+        }
+        $this->old_image = $this->imageHandle;
+        $this->imageHandle = $new_img;
+        $this->resized = true;
+
+        $this->new_x = $new_x;
+        $this->new_y = $new_y;
+        return true;
+    }
+   
+    /**
+     * Flip the image horizontally or vertically
+     *
+     * @param boolean $horizontal true if horizontal flip, vertical otherwise
+     */
+    function flip($horizontal)
+    {
+        if(!$horizontal) {
+            $this->rotate(180);
+        }
+
+        $width = imagesx($this->imageHandle); 
+        $height = imagesy($this->imageHandle); 
+
+        for ($j = 0; $j < $height; $j++) { 
+                $left = 0; 
+                $right = $width-1; 
+
+
+                while ($left < $right) { 
+                    //echo " j:".$j." l:".$left." r:".$right."\n<br>";
+                    $t = imagecolorat($this->imageHandle, $left, $j); 
+                    imagesetpixel($this->imageHandle, $left, $j, imagecolorat($this->imageHandle, $right, $j)); 
+                    imagesetpixel($this->imageHandle, $right, $j, $t); 
+                    $left++; $right--; 
+                } 
+            
+        }
+
+        return true;
+    }
+
+
+    /**
+     * Adjust the image gamma
+     *
+     * @param float $outputgamma
+     *
+     * @return none
+     */
+    function gamma($outputgamma=1.0) {
+        ImageGammaCorrect($this->imageHandle, 1.0, $outputgamma);
+    }
+
+    /**
+     * Save the image file
+     *
+     * @param string  $filename the name of the file to write to
+     * @param int     $quality  output DPI, default is 85
+     * @param string  $types    define the output format, default
+     *                          is the current used format
+     *
+     * @return none
+     */
+    function save($filename, $type = '', $quality = 85)
+    {
+		$type           = $type==''? $this->type : $type;
+		$functionName   = 'image' . $type;
+
+		if(function_exists($functionName))
+		{
+			$this->old_image = $this->imageHandle;
+			if($type=='jpeg')
+				$functionName($this->imageHandle, $filename, $quality);
+			else
+				$functionName($this->imageHandle, $filename);
+			$this->imageHandle = $this->old_image;
+			$this->resized = false;
+		}
+    } // End save
+
+
+    /**
+     * Display image without saving and lose changes
+     *
+     * @param string type (JPG,PNG...);
+     * @param int quality 75
+     *
+     * @return none
+     */
+    function display($type = '', $quality = 75)
+    {
+        if ($type != '') {
+            $this->type = $type;
+        }
+        $functionName = 'Image' . $this->type;
+		if(function_exists($functionName))
+		{
+			header('Content-type: image/' . strtolower($this->type));
+			$functionName($this->imageHandle, '', $quality);
+			$this->imageHandle = $this->old_image;
+			$this->resized = false;
+			ImageDestroy($this->old_image);
+			$this->free();
+		}
+    }
+
+    /**
+     * Destroy image handle
+     *
+     * @return none
+     */
+    function free()
+    {
+        if ($this->imageHandle){
+            ImageDestroy($this->imageHandle);
+        }
+    }
+
+} // End class ImageGD
+?>

Added: cocoon/trunk/blocks/cocoon-forms/cocoon-forms-impl/src/main/resources/org/apache/cocoon/forms/resources/xinha/plugins/ImageManager/Classes/IM.php
URL: http://svn.apache.org/viewvc/cocoon/trunk/blocks/cocoon-forms/cocoon-forms-impl/src/main/resources/org/apache/cocoon/forms/resources/xinha/plugins/ImageManager/Classes/IM.php?view=auto&rev=558490
==============================================================================
--- cocoon/trunk/blocks/cocoon-forms/cocoon-forms-impl/src/main/resources/org/apache/cocoon/forms/resources/xinha/plugins/ImageManager/Classes/IM.php (added)
+++ cocoon/trunk/blocks/cocoon-forms/cocoon-forms-impl/src/main/resources/org/apache/cocoon/forms/resources/xinha/plugins/ImageManager/Classes/IM.php Sun Jul 22 07:50:10 2007
@@ -0,0 +1,235 @@
+<?php
+
+/***********************************************************************
+** Title.........:  ImageMagick Driver
+** Version.......:  1.0
+** Author........:  Xiang Wei ZHUO <we...@zhuo.org>
+** Filename......:  IM.php
+** Last changed..:  30 Aug 2003 
+** Notes.........:  Orginal is from PEAR
+**/
+
+// +----------------------------------------------------------------------+
+// | PHP Version 4                                                        |
+// +----------------------------------------------------------------------+
+// | Copyright (c) 1997-2002 The PHP Group                                |
+// +----------------------------------------------------------------------+
+// | This source file is subject to version 2.02 of the PHP license,      |
+// | that is bundled with this package in the file LICENSE, and is        |
+// | available at through the world-wide-web at                           |
+// | http://www.php.net/license/2_02.txt.                                 |
+// | If you did not receive a copy of the PHP license and are unable to   |
+// | obtain it through the world-wide-web, please send a note to          |
+// | license@php.net so we can mail you a copy immediately.               |
+// +----------------------------------------------------------------------+
+// | Authors: Peter Bowyer <pe...@mapledesign.co.uk>                      |
+// +----------------------------------------------------------------------+
+//
+// $Id: IM.php 709 2007-01-30 23:22:04Z ray $
+//
+// Image Transformation interface using command line ImageMagick
+//
+
+require_once "../ImageManager/Classes/Transform.php";
+
+Class Image_Transform_Driver_IM extends Image_Transform
+{
+    /**
+     * associative array commands to be executed
+     * @var array
+     */
+    var $command = array();
+
+    /**
+     *
+     *
+     */
+    function Image_Transform_Driver_IM()
+    {
+        return true;
+    } // End Image_IM
+
+    /**
+     * Load image
+     *
+     * @param string filename
+     *
+     * @return mixed none or a PEAR error object on error
+     * @see PEAR::isError()
+     */
+    function load($image)
+    {
+
+        $this->uid = md5($_SERVER['REMOTE_ADDR']);
+        /*if (!file_exists($image)) {
+            return PEAR::raiseError('The image file ' . $image . ' does\'t exist', true);
+        }*/
+        $this->image = $image;
+        $this->_get_image_details($image);
+    } // End load
+
+    /**
+     * Resize Action
+     *
+     * @param int   new_x   new width
+     * @param int   new_y   new height
+     *
+     * @return none
+     * @see PEAR::isError()
+     */
+    function _resize($new_x, $new_y)
+    {
+        /*if (isset($this->command['resize'])) {
+            return PEAR::raiseError("You cannot scale or resize an image more than once without calling save or display", true);
+        }*/
+        $this->command['resize'] = "-geometry ${new_x}x${new_y}!";
+
+        $this->new_x = $new_x;
+        $this->new_y = $new_y;
+    } // End resize
+
+    /**
+     * Crop the image
+     *
+     * @param int $crop_x left column of the image
+     * @param int $crop_y top row of the image
+     * @param int $crop_width new cropped image width
+     * @param int $crop_height new cropped image height
+     */
+    function crop($crop_x, $crop_y, $crop_width, $crop_height) 
+    {
+        $this->command['crop'] = "-crop {$crop_width}x{$crop_height}+{$crop_x}+{$crop_y}";
+    }
+
+    /**
+     * Flip the image horizontally or vertically
+     *
+     * @param boolean $horizontal true if horizontal flip, vertical otherwise
+     */
+    function flip($horizontal) 
+    {
+        if($horizontal)
+            $this->command['flop'] = "-flop";
+        else
+            $this->command['flip'] = "-flip";
+    }
+    /**
+     * rotate
+     *
+     * @param   int     angle   rotation angle
+     * @param   array   options no option allowed
+     *
+     */
+    function rotate($angle, $options=null)
+    {
+        if ('-' == $angle{0}) {
+            $angle = 360 - substr($angle, 1);
+        }
+         $this->command['rotate'] = "-rotate $angle";
+    } // End rotate
+
+    /**
+     * addText
+     *
+     * @param   array   options     Array contains options
+     *                              array(
+     *                                  'text'  The string to draw
+     *                                  'x'     Horizontal position
+     *                                  'y'     Vertical Position
+     *                                  'Color' Font color
+     *                                  'font'  Font to be used
+     *                                  'size'  Size of the fonts in pixel
+     *                                  'resize_first'  Tell if the image has to be resized
+     *                                                  before drawing the text
+     *                              )
+     *
+     * @return none
+     * @see PEAR::isError()
+     */
+    function addText($params)
+    {
+        $default_params = array(
+                                'text' => 'This is Text',
+                                'x' => 10,
+                                'y' => 20,
+                                'color' => 'red',
+                                'font' => 'Arial.ttf',
+                                'resize_first' => false // Carry out the scaling of the image before annotation?
+                                );
+         $params = array_merge($default_params, $params);
+         extract($params);
+         if (true === $resize_first) {
+             // Set the key so that this will be the last item in the array
+            $key = 'ztext';
+         } else {
+            $key = 'text';
+         }
+         $this->command[$key] = "-font $font -fill $color -draw 'text $x,$y \"$text\"'";
+         // Producing error: gs: not found gs: not found convert: Postscript delegate failed [No such file or directory].
+    } // End addText
+
+    /**
+     * Adjust the image gamma
+     *
+     * @param float $outputgamma
+     *
+     * @return none
+     */
+    function gamma($outputgamma=1.0) {
+        $this->command['gamma'] = "-gamma $outputgamma";
+    }
+
+    /**
+     * Save the image file
+     *
+     * @param string  $filename the name of the file to write to
+     * @param quality $quality  image dpi, default=75
+     * @param string  $type     (JPG,PNG...)
+     *
+     * @return none
+     */
+    function save($filename, $type='', $quality = 85)
+    {
+        $type == '' ? $this->type : $type;
+        $cmd = '' . IMAGE_TRANSFORM_LIB_PATH . 'convert ';
+		$cmd .= implode(' ', $this->command) . " -quality $quality ";
+		$cmd .= '"'.($this->image) . '" "' . ($filename) . '"';
+        
+        //$cmd = str_replace('/', '\\', $cmd);
+		//echo($cmd.'<br>');
+        exec($cmd,$retval);
+		//error_log('IM '.print_r($retval,true));
+    } // End save
+
+    /**
+     * Display image without saving and lose changes
+     *
+     * @param string type (JPG,PNG...);
+     * @param int quality 75
+     *
+     * @return none
+     */
+    function display($type = '', $quality = 75)
+    {
+        if ($type == '') {
+            header('Content-type: image/' . $this->type);
+            passthru(IMAGE_TRANSFORM_LIB_PATH . 'convert ' . implode(' ', $this->command) . " -quality $quality "  . escapeshellarg($this->image) . ' ' . strtoupper($this->type) . ":-");
+        } else {
+            header('Content-type: image/' . $type);
+            passthru(IMAGE_TRANSFORM_LIB_PATH . 'convert ' . implode(' ', $this->command) . " -quality $quality "  . escapeshellarg($this->image) . ' ' . strtoupper($type) . ":-");
+        }
+    }
+
+
+    /**
+     * Destroy image handle
+     *
+     * @return none
+     */
+    function free()
+    {
+        return true;
+    }
+
+} // End class ImageIM
+?>

Added: cocoon/trunk/blocks/cocoon-forms/cocoon-forms-impl/src/main/resources/org/apache/cocoon/forms/resources/xinha/plugins/ImageManager/Classes/ImageEditor.php
URL: http://svn.apache.org/viewvc/cocoon/trunk/blocks/cocoon-forms/cocoon-forms-impl/src/main/resources/org/apache/cocoon/forms/resources/xinha/plugins/ImageManager/Classes/ImageEditor.php?view=auto&rev=558490
==============================================================================
--- cocoon/trunk/blocks/cocoon-forms/cocoon-forms-impl/src/main/resources/org/apache/cocoon/forms/resources/xinha/plugins/ImageManager/Classes/ImageEditor.php (added)
+++ cocoon/trunk/blocks/cocoon-forms/cocoon-forms-impl/src/main/resources/org/apache/cocoon/forms/resources/xinha/plugins/ImageManager/Classes/ImageEditor.php Sun Jul 22 07:50:10 2007
@@ -0,0 +1,449 @@
+<?php
+/**
+ * Image Editor. Editing tools, crop, rotate, scale and save.
+ * @author $Author: ray $
+ * @version $Id: ImageEditor.php 709 2007-01-30 23:22:04Z ray $
+ * @package ImageManager
+ */
+
+require_once('../ImageManager/Classes/Transform.php');
+
+/**
+ * Handles the basic image editing capbabilities.
+ * @author $Author: ray $
+ * @version $Id: ImageEditor.php 709 2007-01-30 23:22:04Z ray $
+ * @package ImageManager
+ * @subpackage Editor
+ */
+class ImageEditor 
+{
+	/**
+	 * ImageManager instance.
+	 */
+	var $manager;
+
+	/**
+	 * user based on IP address
+	 */
+	var $_uid;
+
+	/**
+	 * tmp file storage time.
+	 */
+	var $lapse_time =900; //15 mins
+
+	var $filesaved = 0;
+
+	/**
+	 * Create a new ImageEditor instance. Editing requires a 
+	 * tmp file, which is saved in the current directory where the
+	 * image is edited. The tmp file is assigned by md5 hash of the
+	 * user IP address. This hashed is used as an ID for cleaning up
+	 * the tmp files. In addition, any tmp files older than the
+	 * the specified period will be deleted.
+	 * @param ImageManager $manager the image manager, we need this
+	 * for some file and path handling functions.
+	 */
+	function ImageEditor($manager) 
+	{
+		$this->manager = $manager;
+		$this->_uid = md5($_SERVER['REMOTE_ADDR']);
+	}
+	
+	/**
+	 * Did we save a file?
+	 * @return int 1 if the file was saved sucessfully, 
+	 * 0 no save operation, -1 file save error.
+	 */
+	function isFileSaved() 
+	{
+		Return $this->filesaved;
+	}
+
+	/**
+	 * Process the image, if not action, just display the image.
+	 * @return array with image information, empty array if not an image.
+	 * <code>array('src'=>'url of the image', 'dimensions'=>'width="xx" height="yy"',
+	 * 'file'=>'image file, relative', 'fullpath'=>'full path to the image');</code>
+	 */
+	function processImage() 
+	{
+		if(isset($_GET['img']))
+			$relative = rawurldecode($_GET['img']);
+		else
+			Return array();
+		
+		//$relative = '/Series2004NoteFront.jpg';
+
+		$imgURL = $this->manager->getFileURL($relative);
+		$fullpath = $this->manager->getFullPath($relative);
+		
+		$imgInfo = @getImageSize($fullpath);
+		if(!is_array($imgInfo))
+			Return array();
+
+		$action = $this->getAction();
+
+		if(!is_null($action))
+		{
+			$image = $this->processAction($action, $relative, $fullpath);
+		}
+		else
+		{
+			$image['src'] = $imgURL;
+			$image['dimensions'] = $imgInfo[3];
+			$image['file'] = $relative;
+			$image['fullpath'] = $fullpath;
+		}
+
+		Return $image;
+	}
+
+	/**
+	 * Process the actions, crop, scale(resize), rotate, flip, and save.
+	 * When ever an action is performed, the result is save into a
+	 * temporary image file, see createUnique on the filename specs.
+	 * It does not return the saved file, alway returning the tmp file.
+	 * @param string $action, should be 'crop', 'scale', 'rotate','flip', or 'save'
+	 * @param string $relative the relative image filename
+	 * @param string $fullpath the fullpath to the image file
+	 * @return array with image information
+	 * <code>array('src'=>'url of the image', 'dimensions'=>'width="xx" height="yy"',
+	 * 'file'=>'image file, relative', 'fullpath'=>'full path to the image');</code>
+	 */
+	function processAction($action, $relative, $fullpath) 
+	{
+		$params = '';
+		
+		if(isset($_GET['params']))
+			$params = $_GET['params'];
+
+		$values =  explode(',',$params,4);
+		$saveFile = $this->getSaveFileName($values[0]);
+
+		$img = Image_Transform::factory(IMAGE_CLASS);
+		$img->load($fullpath);
+
+		switch ($action) 
+		{
+			case 'crop':
+				$img->crop(intval($values[0]),intval($values[1]),
+							intval($values[2]),intval($values[3]));
+			break;
+			case 'scale':
+				$img->resize(intval($values[0]),intval($values[1]));
+				break;
+			case 'rotate':
+				$img->rotate(floatval($values[0]));
+				break;
+			case 'flip':
+				if ($values[0] == 'hoz')
+					$img->flip(true);
+				else if($values[0] == 'ver') 
+					$img->flip(false);
+				break;
+			case 'save':
+				if(!is_null($saveFile))
+				{
+					$quality = intval($values[1]);
+		            if($quality <0) $quality = 85;
+					$newSaveFile = $this->makeRelative($relative, $saveFile);
+					$newSaveFile = $this->getUniqueFilename($newSaveFile);
+					
+					//get unique filename just returns the filename, so
+					//we need to make the relative path once more.
+					$newSaveFile = $this->makeRelative($relative, $newSaveFile);
+          $image['saveFile'] = $newSaveFile;
+					$newSaveFullpath = $this->manager->getFullPath($newSaveFile);
+					$img->save($newSaveFullpath, $values[0], $quality);
+					if(is_file($newSaveFullpath))
+						$this->filesaved = 1;
+					else
+						$this->filesaved = -1;
+				}
+				break;
+		}
+		
+		//create the tmp image file
+		$filename = $this->createUnique($fullpath);
+		$newRelative = $this->makeRelative($relative, $filename);
+		$newFullpath = $this->manager->getFullPath($newRelative);
+		$newURL = $this->manager->getFileURL($newRelative);
+		
+		//save the file.
+		$img->save($newFullpath);
+		$img->free();
+
+		//get the image information
+		$imgInfo = @getimagesize($newFullpath);
+
+		$image['src'] = $newURL;
+    $image['width'] = $imgInfo[0];
+    $image['height'] = $imgInfo[1];
+		$image['dimensions'] = $imgInfo[3];
+		$image['file'] = $newRelative;
+		$image['fullpath'] = $newFullpath;
+
+		Return $image;
+	
+	}
+
+	/**
+	 * Get the file name base on the save name
+	 * and the save type.
+	 * @param string $type image type, 'jpeg', 'png', or 'gif'
+	 * @return string the filename according to save type
+	 */
+	function getSaveFileName($type) 
+	{
+		if(!isset($_GET['file']))
+			Return null;
+
+		$filename = Files::escape(rawurldecode($_GET['file']));
+		$index = strrpos($filename,'.');
+		$base = substr($filename,0,$index);
+		$ext = strtolower(substr($filename,$index+1,strlen($filename)));
+
+		if($type == 'jpeg' && !($ext=='jpeg' || $ext=='jpg'))
+		{
+			Return $base.'.jpeg';
+		}
+		if($type=='png' && $ext != 'png')
+			Return $base.'.png';
+		if($type=='gif' && $ext != 'gif')
+			Return $base.'.gif';
+
+		Return $filename;
+	}
+
+	/**
+	 * Get the default save file name, used by editor.php.
+	 * @return string a suggestive filename, this should be unique
+	 */
+	function getDefaultSaveFile() 
+	{
+		if(isset($_GET['img']))
+			$relative = rawurldecode($_GET['img']);
+		else
+			Return null;
+
+		Return $this->getUniqueFilename($relative);
+	}
+
+	/**
+	 * Get a unique filename. If the file exists, the filename
+	 * base is appended with an increasing integer.
+	 * @param string $relative the relative filename to the base_dir
+	 * @return string a unique filename in the current path
+	 */
+	function getUniqueFilename($relative) 
+	{
+		$fullpath = $this->manager->getFullPath($relative);
+		
+		$pathinfo = pathinfo($fullpath);
+
+		$path = Files::fixPath($pathinfo['dirname']);
+		$file = Files::escape($pathinfo['basename']);
+		
+		$filename = $file;
+
+		$dotIndex = strrpos($file, '.');
+		$ext = '';
+
+		if(is_int($dotIndex)) 
+		{
+			$ext = substr($file, $dotIndex);
+			$base = substr($file, 0, $dotIndex);
+		}
+
+		$counter = 0;
+		while(is_file($path.$filename)) 
+		{
+			$counter++;
+			$filename = $base.'_'.$counter.$ext;
+		}
+		
+		Return $filename;
+		
+	}
+
+	/**
+	 * Specifiy the original relative path, a new filename
+	 * and return the new filename with relative path.
+	 * i.e. $pathA (-filename) + $file
+	 * @param string $pathA the relative file
+	 * @param string $file the new filename
+	 * @return string relative path with the new filename
+	 */
+	function makeRelative($pathA, $file) 
+	{
+		$index = strrpos($pathA,'/');
+		if(!is_int($index))
+			Return $file;
+
+		$path = substr($pathA, 0, $index);
+		Return Files::fixPath($path).$file;
+	}
+
+	/**
+	 * Get the action GET parameter
+	 * @return string action parameter
+	 */
+	function getAction() 
+	{
+		$action = null;
+		if(isset($_GET['action']))
+			$action = $_GET['action'];
+		Return $action;
+	}
+
+	/**
+	 * Generate a unique string based on md5(microtime()).
+	 * Well not so uniqe, as it is limited to 6 characters
+	 * @return string unique string.
+	 */
+    function uniqueStr()
+    {
+      return substr(md5(microtime()),0,6);
+    }
+
+	/**
+	 * Create unique tmp image file name.
+	 * The filename is based on the tmp file prefix
+	 * specified in config.inc.php plus 
+	 * the UID (basically a md5 of the remote IP)
+	 * and some random 6 character string.
+	 * This function also calls to clean up the tmp files.
+	 * @param string $file the fullpath to a file
+	 * @return string a unique filename for that path
+	 * NOTE: it only returns the filename, path no included.
+	 */
+	function createUnique($file) 
+	{
+		$pathinfo = pathinfo($file);
+		$path = Files::fixPath($pathinfo['dirname']);
+		$imgType = $this->getImageType($file);
+
+		$unique_str = $this->manager->getTmpPrefix().$this->_uid.'_'.$this->uniqueStr().".".$imgType;
+
+	   //make sure the the unique temp file does not exists
+        while (file_exists($path.$unique_str))
+        {
+            $unique_str = $this->manager->getTmpPrefix().$this->_uid.'_'.$this->uniqueStr().".".$imgType;
+        }
+
+		$this->cleanUp($path,$pathinfo['basename']);
+
+		Return $unique_str;
+	}
+
+	/**
+	 * Delete any tmp image files.
+	 * @param string $path the full path 
+	 * where the clean should take place.
+	 */
+	function cleanUp($path,$file) 
+	{
+		$path = Files::fixPath($path);
+
+		if(!is_dir($path))
+			Return false;
+
+		$d = @dir($path);
+		
+		$tmp = $this->manager->getTmpPrefix();
+		$tmpLen = strlen($tmp);
+
+		$prefix = $tmp.$this->_uid;
+		$len = strlen($prefix);
+
+		while (false !== ($entry = $d->read())) 
+		{
+			//echo $entry."<br>";
+			if(is_file($path.$entry) && $this->manager->isTmpFile($entry))
+			{
+				if(substr($entry,0,$len)==$prefix && $entry != $file)
+					Files::delFile($path.$entry);
+				else if(substr($entry,0,$tmpLen)==$tmp && $entry != $file)
+				{
+					if(filemtime($path.$entry)+$this->lapse_time < time())
+						Files::delFile($path.$entry);
+				}
+			}
+		}
+		$d->close();
+	}
+
+	/**
+	 * Get the image type base on an image file.
+	 * @param string $file the full path to the image file.
+	 * @return string of either 'gif', 'jpeg', 'png' or 'bmp'
+	 * otherwise it will return null.
+	 */
+	function getImageType($file) 
+	{
+		$imageInfo = @getImageSize($file);
+
+		if(!is_array($imageInfo))
+			Return null;
+
+		switch($imageInfo[2]) 
+		{
+			case 1:
+				Return 'gif';
+			case 2:
+				Return 'jpeg';
+			case 3:
+				Return 'png';
+			case 6:
+				Return 'bmp';
+		}
+
+		Return null;
+	}
+
+	/**
+	 * Check if the specified image can be edit by GD
+	 * mainly to check that GD can read and save GIFs
+	 * @return int 0 if it is not a GIF file, 1 is GIF is editable, -1 if not editable.
+	 */
+	function isGDEditable() 
+	{
+		if(isset($_GET['img']))
+			$relative = rawurldecode($_GET['img']);
+		else
+			Return 0;
+		if(IMAGE_CLASS != 'GD')
+			Return 0;
+
+		$fullpath = $this->manager->getFullPath($relative);
+
+		$type = $this->getImageType($fullpath);
+		if($type != 'gif')
+			Return 0;
+
+		if(function_exists('ImageCreateFrom'+$type)
+			&& function_exists('image'+$type))
+			Return 1;
+		else
+			Return -1;
+	}
+
+	/**
+	 * Check if GIF can be edit by GD.
+	 * @return int 0 if it is not using the GD library, 1 is GIF is editable, -1 if not editable.
+	 */
+	function isGDGIFAble() 
+	{
+		if(IMAGE_CLASS != 'GD')
+			Return 0;
+
+		if(function_exists('ImageCreateFromGif')
+			&& function_exists('imagegif'))
+			Return 1;
+		else
+			Return -1;
+	}
+}
+
+?>

Added: cocoon/trunk/blocks/cocoon-forms/cocoon-forms-impl/src/main/resources/org/apache/cocoon/forms/resources/xinha/plugins/ImageManager/Classes/ImageManager.php
URL: http://svn.apache.org/viewvc/cocoon/trunk/blocks/cocoon-forms/cocoon-forms-impl/src/main/resources/org/apache/cocoon/forms/resources/xinha/plugins/ImageManager/Classes/ImageManager.php?view=auto&rev=558490
==============================================================================
--- cocoon/trunk/blocks/cocoon-forms/cocoon-forms-impl/src/main/resources/org/apache/cocoon/forms/resources/xinha/plugins/ImageManager/Classes/ImageManager.php (added)
+++ cocoon/trunk/blocks/cocoon-forms/cocoon-forms-impl/src/main/resources/org/apache/cocoon/forms/resources/xinha/plugins/ImageManager/Classes/ImageManager.php Sun Jul 22 07:50:10 2007
@@ -0,0 +1,664 @@
+<?php
+/**
+ * ImageManager, list images, directories, and thumbnails.
+ * @author $Author: ray $
+ * @version $Id: ImageManager.php 709 2007-01-30 23:22:04Z ray $
+ * @package ImageManager
+ */
+
+require_once('../ImageManager/Classes/Files.php');
+
+// uncomment to turn on debugging
+
+// _ddtOn();
+
+/**
+ * ImageManager Class.
+ * @author $Author: ray $
+ * @version $Id: ImageManager.php 709 2007-01-30 23:22:04Z ray $
+ */
+class ImageManager 
+{
+	/**
+	 * Configuration array.
+	 */
+	var $config;
+
+	/**
+	 * Array of directory information.
+	 */
+	var $dirs;
+
+	/**
+	 * Constructor. Create a new Image Manager instance.
+	 * @param array $config configuration array, see config.inc.php
+	 */
+	function ImageManager($config) 
+	{
+		$this->config = $config;
+	}
+
+	/**
+	 * Get the images base directory.
+	 * @return string base dir, see config.inc.php
+	 */
+	function getImagesDir() 
+	{
+		Return $this->config['images_dir'];
+	}
+
+	/**
+	 * Get the images base URL.
+	 * @return string base url, see config.inc.php
+	 */
+	function getImagesURL() 
+	{
+		Return $this->config['images_url'];
+	}
+
+	function isValidBase()
+	{
+		return is_dir($this->getImagesDir());
+	}
+
+	/**
+	 * Get the tmp file prefix.
+	 * @return string tmp file prefix.
+	 */
+	function getTmpPrefix() 
+	{
+		Return $this->config['tmp_prefix'];
+	}
+
+	/**
+	 * Get the sub directories in the base dir.
+	 * Each array element contain
+	 * the relative path (relative to the base dir) as key and the 
+	 * full path as value.
+	 * @return array of sub directries
+	 * <code>array('path name' => 'full directory path', ...)</code>
+	 */
+	function getDirs() 
+	{
+		if(is_null($this->dirs))
+		{
+			$dirs = $this->_dirs($this->getImagesDir(),'/');
+			ksort($dirs);
+			$this->dirs = $dirs;
+		}
+		return $this->dirs;
+	}
+
+	/**
+	 * Recursively travese the directories to get a list
+	 * of accessable directories.
+	 * @param string $base the full path to the current directory
+	 * @param string $path the relative path name
+	 * @return array of accessiable sub-directories
+	 * <code>array('path name' => 'full directory path', ...)</code>
+	 */
+	function _dirs($base, $path) 
+	{
+		$base = Files::fixPath($base);
+		$dirs = array();
+
+		if($this->isValidBase() == false)
+			return $dirs;
+
+		$d = @dir($base);
+		
+		while (false !== ($entry = $d->read())) 
+		{
+			//If it is a directory, and it doesn't start with
+			// a dot, and if is it not the thumbnail directory
+			if(is_dir($base.$entry) 
+				&& substr($entry,0,1) != '.'
+				&& $this->isThumbDir($entry) == false) 
+			{
+				$relative = Files::fixPath($path.$entry);
+				$fullpath = Files::fixPath($base.$entry);
+				$dirs[$relative] = $fullpath;
+				$dirs = array_merge($dirs, $this->_dirs($fullpath, $relative));
+			}
+		}
+		$d->close();
+
+		Return $dirs;
+	}
+
+	/**
+	 * Get all the files and directories of a relative path.
+	 * @param string $path relative path to be base path.
+	 * @return array of file and path information.
+	 * <code>array(0=>array('relative'=>'fullpath',...), 1=>array('filename'=>fileinfo array(),...)</code>
+	 * fileinfo array: <code>array('url'=>'full url', 
+	 *                       'relative'=>'relative to base', 
+	 *                        'fullpath'=>'full file path', 
+	 *                        'image'=>imageInfo array() false if not image,
+	 *                        'stat' => filestat)</code>
+	 */
+	function getFiles($path) 
+	{
+		$files = array();
+		$dirs = array();
+
+		if($this->isValidBase() == false)
+			return array($files,$dirs);
+
+		$path = Files::fixPath($path);
+		$base = Files::fixPath($this->getImagesDir());
+		$fullpath = Files::makePath($base,$path);
+
+
+		$d = @dir($fullpath);
+		
+		while (false !== ($entry = $d->read())) 
+		{
+			//not a dot file or directory
+			if(substr($entry,0,1) != '.')
+			{
+				if(is_dir($fullpath.$entry)
+					&& $this->isThumbDir($entry) == false)
+				{
+					$relative = Files::fixPath($path.$entry);
+					$full = Files::fixPath($fullpath.$entry);
+					$count = $this->countFiles($full);
+					$dirs[$relative] = array('fullpath'=>$full,'entry'=>$entry,'count'=>$count);
+				}
+				else if(is_file($fullpath.$entry) && $this->isThumb($entry)==false && $this->isTmpFile($entry) == false) 
+				{
+					$img = $this->getImageInfo($fullpath.$entry);
+
+					if(!(!is_array($img)&&$this->config['validate_images']))
+					{
+						$file['url'] = Files::makePath($this->config['base_url'],$path).$entry;
+						$file['relative'] = $path.$entry;
+						$file['fullpath'] = $fullpath.$entry;
+						$file['image'] = $img;
+						$file['stat'] = stat($fullpath.$entry);
+						$files[$entry] = $file;
+					}
+				}
+			}
+		}
+		$d->close();
+		ksort($dirs);
+		ksort($files);
+		
+		Return array($dirs, $files);
+	}	
+
+	/**
+	 * Count the number of files and directories in a given folder
+	 * minus the thumbnail folders and thumbnails.
+	 */
+	function countFiles($path) 
+	{
+		$total = 0;
+
+		if(is_dir($path)) 
+		{
+			$d = @dir($path);
+
+			while (false !== ($entry = $d->read())) 
+			{
+				//echo $entry."<br>";
+				if(substr($entry,0,1) != '.'
+					&& $this->isThumbDir($entry) == false
+					&& $this->isTmpFile($entry) == false
+					&& $this->isThumb($entry) == false) 
+				{
+					$total++;
+				}
+			}
+			$d->close();
+		}
+		return $total;
+	}
+
+	/**
+	 * Get image size information.
+	 * @param string $file the image file
+	 * @return array of getImageSize information, 
+	 *  false if the file is not an image.
+	 */
+	function getImageInfo($file) 
+	{
+		Return @getImageSize($file);
+	}
+
+	/**
+	 * Check if the file contains the thumbnail prefix.
+	 * @param string $file filename to be checked
+	 * @return true if the file contains the thumbnail prefix, false otherwise.
+	 */
+	function isThumb($file) 
+	{
+		$len = strlen($this->config['thumbnail_prefix']);
+		if(substr($file,0,$len)==$this->config['thumbnail_prefix'])
+			Return true;
+		else
+			Return false;
+	}
+
+	/**
+	 * Check if the given directory is a thumbnail directory.
+	 * @param string $entry directory name
+	 * @return true if it is a thumbnail directory, false otherwise
+	 */
+	function isThumbDir($entry) 
+	{
+		if($this->config['thumbnail_dir'] == false
+			|| strlen(trim($this->config['thumbnail_dir'])) == 0)
+			Return false;		
+		else
+			Return ($entry == $this->config['thumbnail_dir']);
+	}
+
+	/**
+	 * Check if the given file is a tmp file.
+	 * @param string $file file name
+	 * @return boolean true if it is a tmp file, false otherwise
+	 */
+	function isTmpFile($file) 
+	{
+		$len = strlen($this->config['tmp_prefix']);
+		if(substr($file,0,$len)==$this->config['tmp_prefix'])
+			Return true;
+		else
+			Return false;	 	
+	}
+
+	/**
+	 * For a given image file, get the respective thumbnail filename
+	 * no file existence check is done.
+	 * @param string $fullpathfile the full path to the image file
+	 * @return string of the thumbnail file
+	 */
+	function getThumbName($fullpathfile) 
+	{
+		$path_parts = pathinfo($fullpathfile);
+		
+		$thumbnail = $this->config['thumbnail_prefix'].$path_parts['basename'];
+
+		if( strlen(trim($this->config['thumbnail_dir'])) == 0 || $this->config['safe_mode'] == true)
+		{
+			Return Files::makeFile($path_parts['dirname'],$thumbnail);
+		}
+		else
+		{
+				$path = Files::makePath($path_parts['dirname'],$this->config['thumbnail_dir']);
+				if(!is_dir($path))
+					Files::createFolder($path);
+				Return Files::makeFile($path,$thumbnail);
+		}
+	}
+	
+	/**
+	 * Similar to getThumbName, but returns the URL, base on the
+	 * given base_url in config.inc.php
+	 * @param string $relative the relative image file name, 
+	 * relative to the base_dir path
+	 * @return string the url of the thumbnail
+	 */
+	function getThumbURL($relative) 
+	{
+
+		_ddt( __FILE__, __LINE__, "getThumbURL(): relative is '$relative'" );
+
+		$path_parts = pathinfo($relative);
+		$thumbnail = $this->config['thumbnail_prefix'].$path_parts['basename'];
+		if($path_parts['dirname']=='\\') $path_parts['dirname']='/';
+
+		if($this->config['safe_mode'] == true
+			|| strlen(trim($this->config['thumbnail_dir'])) == 0)
+		{
+			Return Files::makeFile($this->getImagesURL(),$thumbnail);
+		}
+		else
+		{
+			if(strlen(trim($this->config['thumbnail_dir'])) > 0)
+			{
+				$path = Files::makePath($path_parts['dirname'],$this->config['thumbnail_dir']);
+				$url_path = Files::makePath($this->getImagesURL(), $path);
+
+				_ddt( __FILE__, __LINE__, "getThumbURL(): url_path is '$url_path'" );
+
+				Return Files::makeFile($url_path,$thumbnail);
+			}
+			else //should this ever happen?
+			{
+				//error_log('ImageManager: Error in creating thumbnail url');
+			}
+
+		}
+	}
+
+
+	/**
+	 * For a given image file, get the respective resized filename
+	 * no file existence check is done.
+	 * @param string $fullpathfile the full path to the image file
+	 * @param integer $width the intended width
+	 * @param integer $height the intended height
+	 * @param boolean $mkDir whether to attempt to make the resized_dir if it doesn't exist
+	 * @return string of the resized filename
+	 */
+	function getResizedName($fullpathfile, $width, $height, $mkDir = TRUE)
+	{
+		$path_parts = pathinfo($fullpathfile);
+
+		$thumbnail = $this->config['resized_prefix']."_{$width}x{$height}_{$path_parts['basename']}";
+
+		if( strlen(trim($this->config['resized_dir'])) == 0 || $this->config['safe_mode'] == true )
+		{
+			Return Files::makeFile($path_parts['dirname'],$thumbnail);
+		}
+		else
+		{
+			$path = Files::makePath($path_parts['dirname'],$this->config['resized_dir']);
+			if($mkDir && !is_dir($path))
+				Files::createFolder($path);
+			Return Files::makeFile($path,$thumbnail);
+		}
+	}
+
+	/**
+	 * Check if the given path is part of the subdirectories
+	 * under the base_dir.
+	 * @param string $path the relative path to be checked
+	 * @return boolean true if the path exists, false otherwise
+	 */
+	function validRelativePath($path) 
+	{
+		$dirs = $this->getDirs();
+		if($path == '/')
+			Return true;
+		//check the path given in the url against the 
+		//list of paths in the system.
+		for($i = 0; $i < count($dirs); $i++)
+		{
+			$key = key($dirs);
+			//we found the path
+			if($key == $path)
+				Return true;
+		
+			next($dirs);
+		}		
+		Return false;
+	}
+
+	/**
+	 * Process uploaded files, assumes the file is in 
+	 * $_FILES['upload'] and $_POST['dir'] is set.
+	 * The dir must be relative to the base_dir and exists.
+	 * If 'validate_images' is set to true, only file with
+	 * image dimensions will be accepted.
+	 * @return null
+	 */
+	function processUploads() 
+	{
+		if($this->isValidBase() == false)
+			return;
+
+		$relative = null;
+
+		if(isset($_POST['dir'])) 
+			$relative = rawurldecode($_POST['dir']);
+		else
+			return;
+
+		//check for the file, and must have valid relative path
+		if(isset($_FILES['upload']) && $this->validRelativePath($relative))
+		{
+			$this->_processFiles($relative, $_FILES['upload']);
+		}
+	}
+
+	/**
+	 * Process upload files. The file must be an 
+	 * uploaded file. If 'validate_images' is set to
+	 * true, only images will be processed. Any duplicate
+	 * file will be renamed. See Files::copyFile for details
+	 * on renaming.
+	 * @param string $relative the relative path where the file
+	 * should be copied to.
+	 * @param array $file the uploaded file from $_FILES
+	 * @return boolean true if the file was processed successfully, 
+	 * false otherwise
+	 */
+	function _processFiles($relative, $file)
+	{
+		
+		if($file['error']!=0)
+		{
+			Return false;
+		}
+
+		if(!is_file($file['tmp_name']))
+		{
+			Return false;
+		}
+
+		if(!is_uploaded_file($file['tmp_name']))
+		{
+			Files::delFile($file['tmp_name']);
+			Return false;
+		}
+		
+
+		if($this->config['validate_images'] == true)
+		{
+			$imgInfo = @getImageSize($file['tmp_name']);
+			if(!is_array($imgInfo))
+			{
+				Files::delFile($file['tmp_name']);
+				Return false;
+			}
+		}
+
+		//now copy the file
+		$path = Files::makePath($this->getImagesDir(),$relative);
+		$result = Files::copyFile($file['tmp_name'], $path, $file['name']);
+
+		//no copy error
+		if(!is_int($result))
+		{
+			Files::delFile($file['tmp_name']);
+			Return true;
+		}
+
+		//delete tmp files.
+		Files::delFile($file['tmp_name']);
+		Return false;
+	}
+
+	/**
+	 * Get the URL of the relative file.
+	 * basically appends the relative file to the 
+	 * base_url given in config.inc.php
+	 * @param string $relative a file the relative to the base_dir
+	 * @return string the URL of the relative file.
+	 */
+	function getFileURL($relative) 
+	{
+		Return Files::makeFile($this->getImagesURL(),$relative);
+	}
+
+	/**
+	 * Get the fullpath to a relative file.
+	 * @param string $relative the relative file.
+	 * @return string the full path, .ie. the base_dir + relative.
+	 */
+	function getFullPath($relative) 
+	{
+		Return Files::makeFile($this->getImagesDir(),$relative);;
+	}
+
+	/**
+	 * Get the default thumbnail.
+	 * @return string default thumbnail, empty string if 
+	 * the thumbnail doesn't exist.
+	 */
+	function getDefaultThumb() 
+	{
+
+		// FIXME: hack
+
+		Return $this->config['default_thumbnail'];
+
+		if(is_file($this->config['default_thumbnail']))
+			{
+			Return $this->config['default_thumbnail'];
+			}
+		else 
+			Return '';
+	}
+
+
+	/**
+	 * Get the thumbnail url to be displayed. 
+	 * If the thumbnail exists, and it is up-to-date
+	 * the thumbnail url will be returns. If the 
+	 * file is not an image, a default image will be returned.
+	 * If it is an image file, and no thumbnail exists or 
+	 * the thumbnail is out-of-date (i.e. the thumbnail 
+	 * modified time is less than the original file)
+	 * then a thumbs.php?img=filename.jpg is returned.
+	 * The thumbs.php url will generate a new thumbnail
+	 * on the fly. If the image is less than the dimensions
+	 * of the thumbnails, the image will be display instead.
+	 * @param string $relative the relative image file.
+	 * @return string the url of the thumbnail, be it
+	 * actually thumbnail or a script to generate the
+	 * thumbnail on the fly.
+	 */
+	function getThumbnail($relative) 
+	{
+
+		global $IMConfig;
+
+		_ddt( __FILE__, __LINE__, "getThumbnail(): top with '$relative'" );
+
+		$fullpath = Files::makeFile($this->getImagesDir(),$relative);
+
+		//not a file???
+		if(!is_file($fullpath))
+			Return $this->getDefaultThumb();
+
+		$imgInfo = @getImageSize($fullpath);
+		
+		//not an image
+		if(!is_array($imgInfo))
+			Return $this->getDefaultThumb();
+
+		//the original image is smaller than thumbnails,
+		//so just return the url to the original image.
+		if ($imgInfo[0] <= $this->config['thumbnail_width']
+		 && $imgInfo[1] <= $this->config['thumbnail_height'])
+			Return $this->getFileURL($relative);
+
+		$thumbnail = $this->getThumbName($fullpath);
+		
+		//check for thumbnails, if exists and
+		// it is up-to-date, return the thumbnail url
+		if(is_file($thumbnail))
+		{
+			if(filemtime($thumbnail) >= filemtime($fullpath))
+				{
+				_ddt( __FILE__, __LINE__, "getThumbnail(): returning url '" . $this->getThumbURL($relative) . "'" );
+
+				Return $this->getThumbURL($relative);
+				}
+		}
+
+		//well, no thumbnail was found, so ask the thumbs.php
+		//to generate the thumbnail on the fly.
+		Return $IMConfig['backend_url'] . '__function=thumbs&img='.rawurlencode($relative);
+	}
+
+	/**
+	 * Delete and specified files.
+	 * @return boolean true if delete, false otherwise
+	 */
+	function deleteFiles() 
+	{
+		if(isset($_GET['delf']))
+			$this->_delFile(rawurldecode($_GET['delf']));
+	}
+
+	/**
+	 * Delete and specified directories.
+	 * @return boolean true if delete, false otherwise
+	 */
+	function deleteDirs() 
+	{
+		 if(isset($_GET['deld']))
+			return $this->_delDir(rawurldecode($_GET['deld']));		
+		 else
+			 Return false;
+	}
+
+	/**
+	 * Delete the relative file, and any thumbnails.
+	 * @param string $relative the relative file.
+	 * @return boolean true if deleted, false otherwise.
+	 */
+	function _delFile($relative) 
+	{
+		$fullpath = Files::makeFile($this->getImagesDir(),$relative);
+		
+		//check that the file is an image
+		if($this->config['validate_images'] == true)
+		{
+			if(!is_array($this->getImageInfo($fullpath)))
+				return false; //hmmm not an Image!!???
+		}
+
+		$thumbnail = $this->getThumbName($fullpath);
+
+		if(Files::delFile($fullpath))
+			Return Files::delFile($thumbnail);
+		else
+			Return false;
+	}
+
+	/**
+	 * Delete directories recursively.
+	 * @param string $relative the relative path to be deleted.
+	 * @return boolean true if deleted, false otherwise.
+	 */
+	function _delDir($relative) 
+	{
+		$fullpath = Files::makePath($this->getImagesDir(),$relative);
+		if($this->countFiles($fullpath) <= 0)
+			return Files::delFolder($fullpath,true); //delete recursively.
+		else
+			Return false;
+	}
+
+	/**
+	 * Create new directories.
+	 * If in safe_mode, nothing happens.
+	 * @return boolean true if created, false otherwise.
+	 */
+	function processNewDir() 
+	{
+		if($this->config['safe_mode'] == true)
+			Return false;
+
+		if(isset($_GET['newDir']) && isset($_GET['dir']))
+		{
+			$newDir = rawurldecode($_GET['newDir']);
+			$dir = rawurldecode($_GET['dir']);
+			$path = Files::makePath($this->getImagesDir(),$dir);
+			$fullpath = Files::makePath($path, Files::escape($newDir));
+			if(is_dir($fullpath))
+				Return false;
+
+			Return Files::createFolder($fullpath);
+		}
+	}
+}
+
+?>

Added: cocoon/trunk/blocks/cocoon-forms/cocoon-forms-impl/src/main/resources/org/apache/cocoon/forms/resources/xinha/plugins/ImageManager/Classes/NetPBM.php
URL: http://svn.apache.org/viewvc/cocoon/trunk/blocks/cocoon-forms/cocoon-forms-impl/src/main/resources/org/apache/cocoon/forms/resources/xinha/plugins/ImageManager/Classes/NetPBM.php?view=auto&rev=558490
==============================================================================
--- cocoon/trunk/blocks/cocoon-forms/cocoon-forms-impl/src/main/resources/org/apache/cocoon/forms/resources/xinha/plugins/ImageManager/Classes/NetPBM.php (added)
+++ cocoon/trunk/blocks/cocoon-forms/cocoon-forms-impl/src/main/resources/org/apache/cocoon/forms/resources/xinha/plugins/ImageManager/Classes/NetPBM.php Sun Jul 22 07:50:10 2007
@@ -0,0 +1,257 @@
+<?php
+/***********************************************************************
+** Title.........:  NetPBM Driver
+** Version.......:  1.0
+** Author........:  Xiang Wei ZHUO <we...@zhuo.org>
+** Filename......:  NetPBM.php
+** Last changed..:  30 Aug 2003 
+** Notes.........:  Orginal is from PEAR
+**/
+
+// +----------------------------------------------------------------------+
+// | PHP Version 4                                                        |
+// +----------------------------------------------------------------------+
+// | Copyright (c) 1997-2002 The PHP Group                                |
+// +----------------------------------------------------------------------+
+// | This source file is subject to version 2.02 of the PHP license,      |
+// | that is bundled with this package in the file LICENSE, and is        |
+// | available at through the world-wide-web at                           |
+// | http://www.php.net/license/2_02.txt.                                 |
+// | If you did not receive a copy of the PHP license and are unable to   |
+// | obtain it through the world-wide-web, please send a note to          |
+// | license@php.net so we can mail you a copy immediately.               |
+// +----------------------------------------------------------------------+
+// | Authors: Peter Bowyer <pe...@mapledesign.co.uk>                      |
+// +----------------------------------------------------------------------+
+//
+// $Id: NetPBM.php 709 2007-01-30 23:22:04Z ray $
+//
+// Image Transformation interface using command line NetPBM
+
+require_once "../ImageManager/Classes/Transform.php";
+
+Class Image_Transform_Driver_NetPBM extends Image_Transform
+{
+
+    /**
+     * associative array commands to be executed
+     * @var array
+     */
+    var $command = array();
+
+    /**
+     * Class Constructor
+     */
+    function Image_Transform_Driver_NetPBM()
+    {
+        $this->uid = md5($_SERVER['REMOTE_ADDR']);
+            
+        return true;
+    } // End function Image_NetPBM
+
+    /**
+     * Load image
+     *
+     * @param string filename
+     *
+     * @return mixed none or a PEAR error object on error
+     * @see PEAR::isError()
+     */
+    function load($image)
+    {
+        //echo $image;
+        $this->image = $image;
+        $this->_get_image_details($image);
+    } // End load
+
+    /**
+     * Resizes the image
+     *
+     * @return none
+     * @see PEAR::isError()
+     */
+    function _resize($new_x, $new_y)
+    {
+        // there's no technical reason why resize can't be called multiple
+        // times...it's just silly to do so
+
+        $this->command[] = IMAGE_TRANSFORM_LIB_PATH .
+                           "pnmscale -width $new_x -height $new_y";
+
+        $this->_set_new_x($new_x);
+        $this->_set_new_y($new_y);
+    } // End resize
+
+    /**
+     * Crop the image
+     *
+     * @param int $crop_x left column of the image
+     * @param int $crop_y top row of the image
+     * @param int $crop_width new cropped image width
+     * @param int $crop_height new cropped image height
+     */
+    function crop($crop_x, $crop_y, $crop_width, $crop_height) 
+    {
+        $this->command[] = IMAGE_TRANSFORM_LIB_PATH .
+                            "pnmcut -left $crop_x -top $crop_y -width $crop_width -height $crop_height";
+    }
+
+    /**
+     * Rotates the image
+     *
+     * @param int $angle The angle to rotate the image through
+     */
+    function rotate($angle)
+    {
+        $angle = -1*floatval($angle);
+
+        if($angle > 90)
+        {   
+            $this->command[] = IMAGE_TRANSFORM_LIB_PATH . "pnmrotate -noantialias 90";
+            $this->rotate(-1*($angle-90));
+        }
+        else if ($angle < -90)
+        {
+            $this->command[] = IMAGE_TRANSFORM_LIB_PATH . "pnmrotate -noantialias -90";
+            $this->rotate(-1*($angle+90));
+        }
+        else
+            $this->command[] = IMAGE_TRANSFORM_LIB_PATH . "pnmrotate -noantialias $angle";
+    } // End rotate
+
+    /**
+     * Flip the image horizontally or vertically
+     *
+     * @param boolean $horizontal true if horizontal flip, vertical otherwise
+     */
+    function flip($horizontal) 
+    {
+        if($horizontal) 
+            $this->command[] = IMAGE_TRANSFORM_LIB_PATH . "pnmflip -lr";
+        else
+            $this->command[] = IMAGE_TRANSFORM_LIB_PATH . "pnmflip -tb";
+    }
+
+    /**
+     * Adjust the image gamma
+     *
+     * @param float $outputgamma
+     *
+     * @return none
+     */
+    function gamma($outputgamma = 1.0) {
+        $this->command[13] = IMAGE_TRANSFORM_LIB_PATH . "pnmgamma $outputgamma";
+    }
+
+    /**
+     * adds text to an image
+     *
+     * @param   array   options     Array contains options
+     *             array(
+     *                  'text'          // The string to draw
+     *                  'x'             // Horizontal position
+     *                  'y'             // Vertical Position
+     *                  'Color'         // Font color
+     *                  'font'          // Font to be used
+     *                  'size'          // Size of the fonts in pixel
+     *                  'resize_first'  // Tell if the image has to be resized
+     *                                  // before drawing the text
+     *                   )
+     *
+     * @return none
+     */
+    function addText($params)
+    {
+        $default_params = array('text' => 'This is Text',
+                                'x' => 10,
+                                'y' => 20,
+                                'color' => 'red',
+                                'font' => 'Arial.ttf',
+                                'size' => '12',
+                                'angle' => 0,
+                                'resize_first' => false);
+        // we ignore 'resize_first' since the more logical approach would be
+        // for the user to just call $this->_resize() _first_ ;)
+        extract(array_merge($default_params, $params));
+        $this->command[] = "ppmlabel -angle $angle -colour $color -size "
+                           ."$size -x $x -y ".$y+$size." -text \"$text\"";
+    } // End addText
+
+    function _postProcess($type, $quality, $save_type)
+    {
+        $type = is_null($type) || $type==''? $this->type : $type;
+        $save_type = is_null($save_type) || $save_type==''? $this->type : $save_type;
+        //echo "TYPE:". $this->type;
+        array_unshift($this->command, IMAGE_TRANSFORM_LIB_PATH
+                      . $type.'topnm '. $this->image);
+        $arg = '';
+        switch(strtolower($save_type)){
+            case 'gif':
+                $this->command[] = IMAGE_TRANSFORM_LIB_PATH . "ppmquant 256";
+                $this->command[] = IMAGE_TRANSFORM_LIB_PATH . "ppmto$save_type";
+                break;
+            case 'jpg':
+            case 'jpeg':
+                $arg = "--quality=$quality";
+                $this->command[] = IMAGE_TRANSFORM_LIB_PATH . "ppmto$save_type $arg";
+                break;
+            default:
+                $this->command[] = IMAGE_TRANSFORM_LIB_PATH . "pnmto$save_type $arg";
+                break;
+        } // switch
+        return implode('|', $this->command);
+    } 
+
+    /**
+     * Save the image file
+     *
+     * @param string $filename the name of the file to write to
+     * @param string $type (jpeg,png...);
+     * @param int $quality 75
+     * @return none
+     */
+    function save($filename, $type=null, $quality = 85)
+    {
+        $cmd = $this->_postProcess('', $quality, $type) . ">$filename";
+            
+		//if we have windows server
+        if(isset($_ENV['OS']) && eregi('window',$_ENV['OS']))
+			$cmd = ereg_replace('/','\\',$cmd);
+        //echo $cmd."##";
+        $output = system($cmd);
+		error_log('NETPBM: '.$cmd);
+		//error_log($output);
+        $this->command = array();
+    } // End save
+
+
+    /**
+     * Display image without saving and lose changes
+     *
+     * @param string $type (jpeg,png...);
+     * @param int $quality 75
+     * @return none
+     */
+    function display($type = null, $quality = 75)
+    {
+        header('Content-type: image/' . $type);
+        $cmd = $this->_postProcess($type, $quality);
+        
+        passthru($cmd);
+        $this->command = array();
+    }
+
+    /**
+     * Destroy image handle
+     *
+     * @return none
+     */
+    function free()
+    {
+        // there is no image handle here
+        return true;
+    }
+
+
+} // End class NetPBM
+?>

Added: cocoon/trunk/blocks/cocoon-forms/cocoon-forms-impl/src/main/resources/org/apache/cocoon/forms/resources/xinha/plugins/ImageManager/Classes/Thumbnail.php
URL: http://svn.apache.org/viewvc/cocoon/trunk/blocks/cocoon-forms/cocoon-forms-impl/src/main/resources/org/apache/cocoon/forms/resources/xinha/plugins/ImageManager/Classes/Thumbnail.php?view=auto&rev=558490
==============================================================================
--- cocoon/trunk/blocks/cocoon-forms/cocoon-forms-impl/src/main/resources/org/apache/cocoon/forms/resources/xinha/plugins/ImageManager/Classes/Thumbnail.php (added)
+++ cocoon/trunk/blocks/cocoon-forms/cocoon-forms-impl/src/main/resources/org/apache/cocoon/forms/resources/xinha/plugins/ImageManager/Classes/Thumbnail.php Sun Jul 22 07:50:10 2007
@@ -0,0 +1,125 @@
+<?php
+/**
+ * Create thumbnails.
+ * @author $Author: ray $
+ * @version $Id: Thumbnail.php 709 2007-01-30 23:22:04Z ray $
+ * @package ImageManager
+ */
+
+
+require_once('../ImageManager/Classes/Transform.php');
+
+/**
+ * Thumbnail creation
+ * @author $Author: ray $
+ * @version $Id: Thumbnail.php 709 2007-01-30 23:22:04Z ray $
+ * @package ImageManager
+ * @subpackage Images
+ */
+class Thumbnail 
+{
+	/**
+	 * Graphics driver, GD, NetPBM or ImageMagick.
+	 */
+	var $driver;
+
+	/**
+	 * Thumbnail default width.
+	 */
+	var $width = 96;
+
+	/**
+	 * Thumbnail default height.
+	 */
+	var $height = 96;
+
+	/**
+	 * Thumbnail default JPEG quality.
+	 */
+	var $quality = 85;
+
+	/**
+	 * Thumbnail is proportional
+	 */
+	var $proportional = true;
+
+	/**
+	 * Default image type is JPEG.
+	 */
+	var $type = 'jpeg';
+
+	/**
+	 * Create a new Thumbnail instance.
+	 * @param int $width thumbnail width
+	 * @param int $height thumbnail height
+	 */
+	function Thumbnail($width=96, $height=96) 
+	{
+		$this->driver = Image_Transform::factory(IMAGE_CLASS);
+		$this->width = $width;
+		$this->height = $height;
+	}
+
+	/**
+	 * Create a thumbnail.
+	 * @param string $file the image for the thumbnail
+	 * @param string $thumbnail if not null, the thumbnail will be saved
+	 * as this parameter value.
+	 * @return boolean true if thumbnail is created, false otherwise
+	 */
+	function createThumbnail($file, $thumbnail=null) 
+	{
+		if(!is_file($file)) 
+			Return false;
+
+		//error_log('Creating Thumbs: '.$file);
+
+		$this->driver->load($file);
+
+		if($this->proportional) 
+		{
+			$width = $this->driver->img_x;
+			$height = $this->driver->img_y;
+
+			if ($width > $height)
+				$this->height = intval($this->width/$width*$height);
+			else if ($height > $width)
+				$this->width = intval($this->height/$height*$width);
+		}
+
+		$this->driver->resize($this->width, $this->height);
+
+		if(is_null($thumbnail)) 
+			$this->save($file);
+		else
+			$this->save($thumbnail);
+
+
+		$this->free();
+
+		if(is_file($thumbnail)) 
+			Return true;
+		else
+			Return false;
+	}
+
+	/**
+	 * Save the thumbnail file.
+	 * @param string $file file name to be saved as.
+	 */
+	function save($file) 
+	{
+		$this->driver->save($file);
+	}
+
+	/**
+	 * Free up the graphic driver resources.
+	 */
+	function free() 
+	{
+		$this->driver->free();
+	}
+}
+
+
+?>
\ No newline at end of file