Fixed bug #10629: class and title parameters of typolinks get broken
[Packages/TYPO3.CMS.git] / t3lib / class.t3lib_stdgraphic.php
index f67a1e3..eb248e6 100644 (file)
@@ -2,7 +2,7 @@
 /***************************************************************
 *  Copyright notice
 *
-*  (c) 1999-2004 Kasper Skaarhoj (kasper@typo3.com)
+*  (c) 1999-2009 Kasper Skaarhoj (kasperYYYY@typo3.com)
 *  All rights reserved
 *
 *  This script is part of the TYPO3 project. The TYPO3 project is
  * $Id$
  * Revised for TYPO3 3.6 July/2003 by Kasper Skaarhoj
  *
- * @author     Kasper Skaarhoj <kasper@typo3.com>
+ * @author     Kasper Skaarhoj <kasperYYYY@typo3.com>
  */
 /**
  * [CLASS/FUNCTION INDEX of SCRIPT]
  *
  *
  *
- *  143: class t3lib_stdGraphic
- *  218:     function init()
+ *  155: class t3lib_stdGraphic
+ *  236:     function init()
  *
  *              SECTION: Layering images / "IMAGE" GIFBUILDER object
- *  317:     function maskImageOntoImage(&$im,$conf,$workArea)
- *  377:     function copyImageOntoImage(&$im,$conf,$workArea)
- *  399:     function copyGifOntoGif(&$im,$cpImg,$conf,$workArea)
- *  478:     function imagecopyresized(&$im, $cpImg, $Xstart, $Ystart, $cpImgCutX, $cpImgCutY, $w, $h, $w, $h)
+ *  366:     function maskImageOntoImage(&$im,$conf,$workArea)
+ *  436:     function copyImageOntoImage(&$im,$conf,$workArea)
+ *  458:     function copyGifOntoGif(&$im,$cpImg,$conf,$workArea)
+ *  537:     function imagecopyresized(&$im, $cpImg, $Xstart, $Ystart, $cpImgCutX, $cpImgCutY, $w, $h, $w, $h)
  *
  *              SECTION: Text / "TEXT" GIFBUILDER object
- *  527:     function makeText(&$im,$conf,$workArea)
- *  643:     function txtPosition($conf,$workArea,$BB)
- *  697:     function calcBBox($conf)
- *  766:     function addToMap($cords,$conf)
- *  787:     function calcTextCordsForMap($cords,$offset, $conf)
- *  820:     function SpacedImageTTFText(&$im, $fontSize, $angle, $x, $y, $Fcolor, $fontFile, $text, $spacing, $wordSpacing)
- *  853:     function fontResize($conf)
+ *  587:     function makeText(&$im,$conf,$workArea)
+ *  707:     function txtPosition($conf,$workArea,$BB)
+ *  761:     function calcBBox($conf)
+ *  820:     function addToMap($cords,$conf)
+ *  843:     function calcTextCordsForMap($cords,$offset, $conf)
+ *  878:     function SpacedImageTTFText(&$im, $fontSize, $angle, $x, $y, $Fcolor, $fontFile, $text, $spacing, $wordSpacing, $splitRenderingConf, $sF=1)
+ *  915:     function fontResize($conf)
+ *  958:     function ImageTTFBBoxWrapper($fontSize, $angle, $fontFile, $string, $splitRendering, $sF=1)
+ * 1005:     function ImageTTFTextWrapper($im, $fontSize, $angle, $x, $y, $color, $fontFile, $string, $splitRendering,$sF=1)
+ * 1058:     function splitString($string,$splitRendering,$fontSize,$fontFile)
+ * 1208:     function calcWordSpacing($conf, $scaleFactor=1)
+ * 1227:     function getTextScalFactor($conf)
  *
  *              SECTION: Other GIFBUILDER objects related to TEXT
- *  915:     function makeOutline(&$im,$conf,$workArea,$txtConf)
- *  944:     function circleOffset($distance, $iterations)
- *  968:     function makeEmboss(&$im,$conf,$workArea,$txtConf)
- *  990:     function makeShadow(&$im,$conf,$workArea,$txtConf)
+ * 1262:     function makeOutline(&$im,$conf,$workArea,$txtConf)
+ * 1291:     function circleOffset($distance, $iterations)
+ * 1315:     function makeEmboss(&$im,$conf,$workArea,$txtConf)
+ * 1337:     function makeShadow(&$im,$conf,$workArea,$txtConf)
  *
  *              SECTION: Other GIFBUILDER objects
- * 1120:     function makeBox(&$im,$conf,$workArea)
- * 1139:     function makeEffect(&$im, $conf)
- * 1154:     function IMparams($setup)
- * 1237:     function adjust(&$im, $conf)
- * 1269:     function crop(&$im,$conf)
- * 1299:     function scale(&$im,$conf)
- * 1331:     function setWorkArea($workArea)
+ * 1469:     function makeBox(&$im,$conf,$workArea)
+ * 1491:     function makeEffect(&$im, $conf)
+ * 1506:     function IMparams($setup)
+ * 1589:     function adjust(&$im, $conf)
+ * 1621:     function crop(&$im,$conf)
+ * 1652:     function scale(&$im,$conf)
+ * 1684:     function setWorkArea($workArea)
  *
  *              SECTION: Adjustment functions
- * 1372:     function autolevels(&$im)
- * 1403:     function outputLevels(&$im,$low,$high,$swap='')
- * 1435:     function inputLevels(&$im,$low,$high,$swap='')
- * 1466:     function reduceColors(&$im,$limit, $cols)
+ * 1725:     function autolevels(&$im)
+ * 1756:     function outputLevels(&$im,$low,$high,$swap='')
+ * 1788:     function inputLevels(&$im,$low,$high,$swap='')
+ * 1819:     function reduceColors(&$im,$limit, $cols)
+ * 1832:     function IMreduceColors($file, $cols)
  *
  *              SECTION: GIFBUILDER Helper functions
- * 1504:     function prependAbsolutePath($fontFile)
- * 1518:     function v5_sharpen($factor)
- * 1537:     function v5_blur($factor)
- * 1554:     function randomName()
- * 1566:     function applyOffset($cords,$OFFSET)
- * 1579:     function convertColor($string)
- * 1629:     function recodeString($string)
- * 1650:     function singleChars($theText)
- * 1673:     function objPosition($conf,$workArea,$BB)
+ * 1875:     function prependAbsolutePath($fontFile)
+ * 1889:     function v5_sharpen($factor)
+ * 1908:     function v5_blur($factor)
+ * 1925:     function randomName()
+ * 1938:     function applyOffset($cords,$OFFSET)
+ * 1951:     function convertColor($string)
+ * 2001:     function recodeString($string)
+ * 2023:     function singleChars($theText,$returnUnicodeNumber=FALSE)
+ * 2046:     function objPosition($conf,$workArea,$BB)
  *
  *              SECTION: Scaling, Dimensions of images
- * 1752:     function imageMagickConvert($imagefile,$newExt='',$w='',$h='',$params='',$frame='',$options='',$mustCreate=0)
- * 1835:     function getImageDimensions($imageFile)
- * 1863:     function cacheImageDimensions($identifyResult)
- * 1895:     function getCachedImageDimensions($imageFile)
- * 1930:     function getImageScale($info,$w,$h,$options)
- * 2018:     function file_exists_typo3temp_file($output,$orig='')
+ * 2125:     function imageMagickConvert($imagefile,$newExt='',$w='',$h='',$params='',$frame='',$options='',$mustCreate=0)
+ * 2238:     function getImageDimensions($imageFile)
+ * 2266:     function cacheImageDimensions($identifyResult)
+ * 2298:     function getCachedImageDimensions($imageFile)
+ * 2332:     function getImageScale($info,$w,$h,$options)
+ * 2438:     function file_exists_typo3temp_file($output,$orig='')
  *
  *              SECTION: ImageMagick API functions
- * 2079:     function imageMagickIdentify($imagefile)
- * 2112:     function imageMagickExec($input,$output,$params)
- * 2130:     function combineExec($input,$overlay,$mask,$output)
- * 2145:     function wrapFileName($inputName)
+ * 2499:     function imageMagickIdentify($imagefile)
+ * 2534:     function imageMagickExec($input,$output,$params)
+ * 2557:     function combineExec($input,$overlay,$mask,$output, $handleNegation = false)
+ * 2588:     function wrapFileName($inputName)
  *
  *              SECTION: Various IO functions
- * 2186:     function checkFile($file)
- * 2201:     function applyImageMagickToPHPGif(&$im, $command)
- * 2227:     function gif_or_jpg($type,$w,$h)
- * 2244:     function output($file)
- * 2288:     function destroy()
- * 2298:     function imgTag ($imgInfo)
- * 2310:     function ImageGif($destImg, $theImage)
- * 2327:     function imageCreateFromGif($sourceImg)
+ * 2629:     function checkFile($file)
+ * 2643:     function createTempSubDir($dirName)
+ * 2665:     function applyImageMagickToPHPGif(&$im, $command)
+ * 2691:     function gif_or_jpg($type,$w,$h)
+ * 2708:     function output($file)
+ * 2748:     function destroy()
+ * 2758:     function imgTag ($imgInfo)
+ * 2770:     function ImageWrite($destImg, $theImage)
+ * 2808:     function imageGif($destImg, $theImage)
+ * 2820:     function imageCreateFromGif($sourceImg)
+ * 2831:     function imageCreateFromFile($sourceImg)
+ * 2870:     function imagecreate($w, $h)
+ * 2885:     function hexColor($col)
+ * 2903:     function unifyColors(&$img, $colArr, $closest = false)
  *
- * TOTAL FUNCTIONS: 54
+ * TOTAL FUNCTIONS: 66
  * (This index is automatically created/updated by the extension "extdeveval")
  *
  */
  * Class contains a bunch of cool functions for manipulating graphics with GDlib/Freetype and ImageMagick
  * VERY OFTEN used with gifbuilder that extends this class and provides a TypoScript API to using these functions
  *
- * @author     Kasper Skaarhoj <kasper@typo3.com>
+ * @author     Kasper Skaarhoj <kasperYYYY@typo3.com>
  * @package TYPO3
  * @subpackage t3lib
  * @see tslib_gifBuilder
@@ -146,22 +158,27 @@ class t3lib_stdGraphic    {
        var $combineScript = 'combine';                         // The ImageMagick filename used for combining two images. This name changed during the versions.
        var $noFramePrepended=0;                                        // If set, there is no frame pointer prepended to the filenames.
        var $GD2=0;                                                                     // Set, if the GDlib used is version 2.
+       var $imagecopyresized_fix=0;                            // If set, imagecopyresized will not be called directly. For GD2 (some PHP installs?)
        var $gifExtension = 'gif';                                      // This should be changed to 'png' if you want this class to read/make PNG-files instead!
+       var $gdlibExtensions = '';                      // File formats supported by gdlib. This variable get's filled in "init" method
+       var $truecolor = true;                                  // Internal variable which get's used to determine wheter GDlib should use function truecolor pendants
+       var $png_truecolor = false;                                     // Set to true if generated png's should be truecolor by default
+       var $truecolorColors = 0xffffff;                        // 16777216 Colors is the maximum value for PNG, JPEG truecolor images (24-bit, 8-bit / Channel)
        var $TTFLocaleConv = '';                                        // Used to recode input to TTF-functions for other charsets.
        var $enable_typo3temp_db_tracking = 0;          // If set, then all files in typo3temp will be logged in a database table. In addition to being a log of the files with original filenames, it also serves to secure that the same image is not rendered simultaneously by two different processes.
-       var $imageMagickPath = '';                                      // path to imageMagick, eg: /usr/lib/
        var $imageFileExt = 'gif,jpg,jpeg,png,tif,bmp,tga,pcx,ai,pdf';  // Commalist of file extensions perceived as images by TYPO3. List should be set to 'gif,png,jpeg,jpg' if IM is not available. Lowercase and no spaces between!
        var $webImageExt = 'gif,jpg,jpeg,png';          // Commalist of web image extensions (can be shown by a webbrowser)
        var $maskNegate = '';                                           // Will be ' -negate' if ImageMagick ver 5.2+. See init();
        var $NO_IM_EFFECTS = '';
        var $cmds = Array (
-               'jpg' => '-colorspace RGB -sharpen 50 -quality 60',
-               'jpeg' => '-colorspace RGB -sharpen 50 -quality 60',
+               'jpg' => '',
+               'jpeg' => '',
                'gif' => '-colors 64',
                'png' => '-colors 64'
        );
        var $NO_IMAGE_MAGICK = '';
        var $V5_EFFECTS = 0;
+       var $im_version_4 = 0;
        var $mayScaleUp = 1;
 
                // Variables for testing, alternative usage etc.
@@ -177,7 +194,8 @@ class t3lib_stdGraphic      {
        var $workArea = Array();
 
                // Constants:
-       var $tempPath = 'typo3temp/';                                           // The temp-directory where to store the files. Relative to PATH_site.
+       var $tempPath = 'typo3temp/';                                           // The temp-directory where to store the files. Normally relative to PATH_site but is allowed to be the absolute path AS LONG AS it is a subdir to PATH_site.
+       var $absPrefix = '';                                                            // Prefix for relative paths. Used in "show_item.php" script. Is prefixed the output file name IN imageMagickConvert()
        var $scalecmd = '-geometry';                                            // ImageMagick scaling command; "-geometry" eller "-sample". Used in makeText() and imageMagickConvert()
        var $im5fx_blurSteps='1x2,2x2,3x2,4x3,5x3,5x4,6x4,7x5,8x5,9x5';                 // Used by v5_blur() to simulate 10 continuous steps of blurring
        var $im5fx_sharpenSteps='1x2,2x2,3x2,2x3,3x3,4x3,3x4,4x4,4x5,5x5';              // Used by v5_sharpen() to simulate 10 continuous steps of sharpening.
@@ -201,7 +219,11 @@ class t3lib_stdGraphic     {
                'white' => Array(255,255,255)
        );
 
-               // Charset conversion object:
+       /**
+        * Charset conversion object:
+        *
+        * @var t3lib_cs
+        */
        var $csConvObj;
        var $nativeCharset='';          // Is set to the native character set of the input strings.
 
@@ -218,11 +240,43 @@ class t3lib_stdGraphic    {
        function init() {
                $gfxConf = $GLOBALS['TYPO3_CONF_VARS']['GFX'];
 
+               if (function_exists('imagecreatefromjpeg')&&function_exists('imagejpeg'))       {
+                       $this->gdlibExtensions .= ',jpg,jpeg';
+               }
+               if (function_exists('imagecreatefrompng')&&function_exists('imagepng')) {
+                       $this->gdlibExtensions .= ',png';
+               }
+               if (function_exists('imagecreatefromgif')&&function_exists('imagegif')) {
+                       $this->gdlibExtensions .= ',gif';
+               }
+               if ($GLOBALS['TYPO3_CONF_VARS']['GFX']['png_truecolor'])        {
+                       $this->png_truecolor = true;
+               }
+               if (!$gfxConf['gdlib_2'] || !function_exists('imagecreatetruecolor'))   {
+                       $this->truecolor = false;
+               }
+               if (!$gfxConf['im_version_5'])  {
+                       $this->im_version_4 = true;
+               }
+
+                       // When GIFBUILDER gets used in truecolor mode (GD2 required)
+               if ($this->truecolor)   {
+                       if ($this->png_truecolor)       {
+                               $this->cmds['png'] = '';        // No colors parameter if we generate truecolor images.
+                       }
+                       $this->cmds['gif'] = '';        // No colors parameter if we generate truecolor images.
+               }
+
+                       // Setting default JPG parameters:
+               $this->jpegQuality = t3lib_div::intInRange($gfxConf['jpg_quality'], 10, 100, 75);
+               $this->cmds['jpg'] = $this->cmds['jpeg'] = '-colorspace RGB -sharpen 50 -quality '.$this->jpegQuality;
+
                if ($gfxConf['im_combine_filename'])    $this->combineScript=$gfxConf['im_combine_filename'];
                if ($gfxConf['im_noFramePrepended'])    $this->noFramePrepended=1;
 
                if ($gfxConf['gdlib_2'])        {
-                       $this->GD2=1;
+                       $this->GD2 = 1;
+                       $this->imagecopyresized_fix = $gfxConf['gdlib_2']==='no_imagecopyresized_fix' ? 0 : 1;
                }
                if ($gfxConf['gdlib_png'])      {
                        $this->gifExtension='png';
@@ -234,7 +288,6 @@ class t3lib_stdGraphic      {
                        $this->enable_typo3temp_db_tracking = $gfxConf['enable_typo3temp_db_tracking'];
                }
 
-               $this->imageMagickPath = $gfxConf['im_path'];
                $this->imageFileExt = $gfxConf['imagefile_ext'];
 
                        // This should be set if ImageMagick ver. 5+ is used.
@@ -252,17 +305,15 @@ class t3lib_stdGraphic    {
                                // - therefore must be disabled in order not to perform sharpen, blurring and such.
                        $this->NO_IM_EFFECTS = 1;
 
-                       $this->cmds['jpg']  = '-colorspace RGB -quality 60';
-                       $this->cmds['jpeg'] = '-colorspace RGB -quality 60';
+                       $this->cmds['jpg'] = $this->cmds['jpeg'] = '-colorspace RGB -quality '.$this->jpegQuality;
                }
-                       // ... but if 'im_v5effects' is set, dont care about 'im_no_effects'
+                       // ... but if 'im_v5effects' is set, don't care about 'im_no_effects'
                if ($gfxConf['im_v5effects'])   {
                        $this->NO_IM_EFFECTS = 0;
                        $this->V5_EFFECTS = 1;
 
                        if ($gfxConf['im_v5effects']>0) {
-                               $this->cmds['jpg']  = '-colorspace RGB -quality 60'.$this->v5_sharpen(10);
-                               $this->cmds['jpeg'] = '-colorspace RGB -quality 60'.$this->v5_sharpen(10);
+                               $this->cmds['jpg'] = $this->cmds['jpeg'] = '-colorspace RGB -quality '.intval($gfxConf['jpg_quality']).$this->v5_sharpen(10);
                        }
                }
 
@@ -275,9 +326,11 @@ class t3lib_stdGraphic     {
                }
 
                if (TYPO3_MODE=='FE')   {
-                       $this->csConvObj = &$GLOBALS['TSFE']->csConvObj;
-               } else {        // BE assumed:
-                       $this->csConvObj = &$GLOBALS['LANG']->csConvObj;
+                       $this->csConvObj = $GLOBALS['TSFE']->csConvObj;
+               } elseif(is_object($GLOBALS['LANG']))   {       // BE assumed:
+                       $this->csConvObj = $GLOBALS['LANG']->csConvObj;
+               } else  {       // The object may not exist yet, so we need to create it now. Happens in the Install Tool for example.
+                       $this->csConvObj = t3lib_div::makeInstance('t3lib_cs');
                }
                $this->nativeCharset = $GLOBALS['TYPO3_CONF_VARS']['BE']['forceCharset'];
        }
@@ -316,8 +369,20 @@ class t3lib_stdGraphic     {
         */
        function maskImageOntoImage(&$im,$conf,$workArea)       {
                if ($conf['file'] && $conf['mask'])     {
-                       $BBimage = $this->imageMagickConvert($conf['file'],$this->gifExtension,'','','','','');
-                       $BBmask = $this->imageMagickConvert($conf['mask'],$this->gifExtension,'','','','','');
+                       $imgInf = pathinfo($conf['file']);
+                       $imgExt = strtolower($imgInf['extension']);
+                       if (!t3lib_div::inList($this->gdlibExtensions, $imgExt))        {
+                               $BBimage = $this->imageMagickConvert($conf['file'],$this->gifExtension,'','','','','');
+                       } else  {
+                               $BBimage = $this->getImageDimensions($conf['file']);
+                       }
+                       $maskInf = pathinfo($conf['mask']);
+                       $maskExt = strtolower($maskInf['extension']);
+                       if (!t3lib_div::inList($this->gdlibExtensions, $maskExt))       {
+                               $BBmask = $this->imageMagickConvert($conf['mask'],$this->gifExtension,'','','','','');
+                       } else  {
+                               $BBmask = $this->getImageDimensions($conf['mask']);
+                       }
                        if ($BBimage && $BBmask)        {
                                $w = imagesx($im);
                                $h = imagesy($im);
@@ -325,31 +390,30 @@ class t3lib_stdGraphic    {
                                $theImage = $tmpStr.'_img.'.$this->gifExtension;
                                $theDest = $tmpStr.'_dest.'.$this->gifExtension;
                                $theMask = $tmpStr.'_mask.'.$this->gifExtension;
-                               $theMask2 = $tmpStr.'_mask2.'.trim($GLOBALS['TYPO3_CONF_VARS']['GFX']['im_mask_temp_ext_noloss']);
                                                // prepare overlay image
-                               $cpImg = $this->imageCreateFromGif($BBimage[3]);
-                               $destImg = imagecreate($w,$h);
-                               ImageColorAllocate($destImg, 0,0,0);
+                               $cpImg = $this->imageCreateFromFile($BBimage[3]);
+                               $destImg = $this->imagecreate($w,$h);
+                               $Bcolor = ImageColorAllocate($destImg, 0,0,0);
+                               ImageFilledRectangle($destImg, 0, 0, $w, $h, $Bcolor);
                                $this->copyGifOntoGif($destImg,$cpImg,$conf,$workArea);
-                               $this->ImageGif($destImg, $theImage);
+                               $this->ImageWrite($destImg, $theImage);
                                imageDestroy($cpImg);
                                imageDestroy($destImg);
                                                // prepare mask image
-                               $cpImg = $this->imageCreateFromGif($BBmask[3]);
-                               $destImg = imagecreate($w,$h);
-                               ImageColorAllocate($destImg, 0,0,0);
+                               $cpImg = $this->imageCreateFromFile($BBmask[3]);
+                               $destImg = $this->imagecreate($w,$h);
+                               $Bcolor = ImageColorAllocate($destImg, 0, 0, 0);
+                               ImageFilledRectangle($destImg, 0, 0, $w, $h, $Bcolor);
                                $this->copyGifOntoGif($destImg,$cpImg,$conf,$workArea);
-                               $this->ImageGif($destImg, $theMask);
+                               $this->ImageWrite($destImg, $theMask);
                                imageDestroy($cpImg);
                                imageDestroy($destImg);
-                                       // treat the mask
-                               $this->imageMagickExec($theMask,$theMask2,'-colorspace GRAY'.$this->maskNegate);
                                        // mask the images
-                               $this->ImageGif($im, $theDest);
+                               $this->ImageWrite($im, $theDest);
 
-                               $this->combineExec($theDest,$theImage,$theMask2,$theDest);
+                               $this->combineExec($theDest,$theImage,$theMask,$theDest, true);         // Let combineExec handle maskNegation
 
-                               $backIm = $this->imageCreateFromGif($theDest);  // The main image is loaded again...
+                               $backIm = $this->imageCreateFromFile($theDest); // The main image is loaded again...
                                if ($backIm)    {       // ... and if nothing went wrong we load it onto the old one.
                                        ImageColorTransparent($backIm,-1);
                                        $im = $backIm;
@@ -359,7 +423,6 @@ class t3lib_stdGraphic      {
                                        unlink($theDest);
                                        unlink($theImage);
                                        unlink($theMask);
-                                       unlink($theMask2);
                                }
                        }
                }
@@ -376,11 +439,11 @@ class t3lib_stdGraphic    {
         */
        function copyImageOntoImage(&$im,$conf,$workArea)       {
                if ($conf['file'])      {
-                       if ($conf['BBOX'][2]!=$this->gifExtension)      {
+                       if (!t3lib_div::inList($this->gdlibExtensions, $conf['BBOX'][2]))       {
                                $conf['BBOX']=$this->imageMagickConvert($conf['BBOX'][3],$this->gifExtension,'','','','','');
                                $conf['file']=$conf['BBOX'][3];
                        }
-                       $cpImg = $this->imageCreateFromGif($conf['file']);
+                       $cpImg = $this->imageCreateFromFile($conf['file']);
                        $this->copyGifOntoGif($im,$cpImg,$conf,$workArea);
                        imageDestroy($cpImg);
                }
@@ -444,7 +507,7 @@ class t3lib_stdGraphic      {
        }
 
        /**
-        * Alternative function for using the similat PHP function imagecopyresized(). Used for GD2 only.
+        * Alternative function for using the similar PHP function imagecopyresized(). Used for GD2 only.
         *
         * OK, the reason for this stupid fix is the following story:
         * GD1.x was capable of copying two images together and combining their palettes! GD2 is apparently not.
@@ -476,12 +539,14 @@ class t3lib_stdGraphic    {
         * @see t3lib_iconWorks::imagecopyresized()
         */
        function imagecopyresized(&$im, $cpImg, $Xstart, $Ystart, $cpImgCutX, $cpImgCutY, $w, $h, $w, $h)       {
-               if ($this->GD2) {
-                       $im_base = imagecreatetruecolor(imagesx($im), imagesy($im));    // Make true color image
+               if ($this->imagecopyresized_fix)        {
+                       $im_base = $this->imagecreate(imagesx($im), imagesy($im));      // Make true color image
                        imagecopyresized($im_base, $im, 0,0,0,0, imagesx($im),imagesy($im),imagesx($im),imagesy($im));  // Copy the source image onto that
                        imagecopyresized($im_base, $cpImg, $Xstart, $Ystart, $cpImgCutX, $cpImgCutY, $w, $h, $w, $h);   // Then copy the $cpImg onto that (the actual operation!)
                        $im = $im_base; // Set pointer
-                       $this->makeEffect($im, Array('value'=>'colors=256'));   // Reduce colors to 256 - make SURE that IM is working then!
+                       if (!$this->truecolor)  {
+                               $this->makeEffect($im, Array('value'=>'colors='.t3lib_div::intInRange($this->setup['reduceColors'], 256, $this->truecolorColors, 256)));                // Reduce to "reduceColors" colors - make SURE that IM is working then!
+                       }
                } else {
                        imagecopyresized($im, $cpImg, $Xstart, $Ystart, $cpImgCutX, $cpImgCutY, $w, $h, $w, $h);
                }
@@ -508,7 +573,6 @@ class t3lib_stdGraphic      {
 
 
 
-
        /********************************
         *
         * Text / "TEXT" GIFBUILDER object
@@ -526,9 +590,7 @@ class t3lib_stdGraphic      {
         */
        function makeText(&$im,$conf,$workArea) {
                        // Spacing
-               $spacing = intval($conf['spacing']);
-               $wordSpacing = intval($conf['wordSpacing']);
-               $wordSpacing = $wordSpacing?$wordSpacing:$spacing*2;
+               list($spacing,$wordSpacing) = $this->calcWordSpacing($conf);
                        // Position
                $txtPos = $this->txtPosition($conf,$workArea,$conf['BBOX']);
                $theText = $this->recodeString($conf['text']);
@@ -542,16 +604,19 @@ class t3lib_stdGraphic    {
                                // NiceText is calculated
                        if (!$conf['niceText']) {
                                        // Font Color is reserved:
-                               $this->reduceColors($im,256, 200);
+                               if (!$this->truecolor)  {
+                                       $reduce = t3lib_div::intInRange($this->setup['reduceColors'], 256, $this->truecolorColors, 256);
+                                       $this->reduceColors($im, $reduce-49, $reduce-50);       // If "reduce-49" colors (or more) are used reduce them to "reduce-50"
+                               }
                                $Fcolor = ImageColorAllocate($im, $cols[0],$cols[1],$cols[2]);
                                        // antiAliasing is setup:
                                $Fcolor = ($conf['antiAlias']) ? $Fcolor : -$Fcolor;
 
                                for ($a=0; $a<$conf['iterations']; $a++)        {
                                        if ($spacing || $wordSpacing)   {               // If any kind of spacing applys, we use this function:
-                                               $this->SpacedImageTTFText($im, $conf['fontSize'], $conf['angle'], $txtPos[0], $txtPos[1], $Fcolor, t3lib_stdGraphic::prependAbsolutePath($conf['fontFile']), $theText, $spacing, $wordSpacing);
+                                               $this->SpacedImageTTFText($im, $conf['fontSize'], $conf['angle'], $txtPos[0], $txtPos[1], $Fcolor, t3lib_stdGraphic::prependAbsolutePath($conf['fontFile']), $theText, $spacing, $wordSpacing, $conf['splitRendering.']);
                                        } else {
-                                               ImageTTFText($im, t3lib_div::freetypeDpiComp($conf['fontSize']), $conf['angle'], $txtPos[0], $txtPos[1], $Fcolor, t3lib_stdGraphic::prependAbsolutePath($conf['fontFile']), $theText);
+                                               $this->renderTTFText($im, $conf['fontSize'], $conf['angle'], $txtPos[0], $txtPos[1], $Fcolor, $conf['fontFile'], $theText, $conf['splitRendering.'], $conf);
                                        }
                                }
                        } else {                // NICETEXT::
@@ -569,15 +634,16 @@ class t3lib_stdGraphic    {
                                $newH = ceil($sF*imagesy($im));
 
                                        // Make mask
-                               $maskImg = imagecreate($newW, $newH);
-                               ImageColorAllocate($maskImg, 255,255,255);
+                               $maskImg = $this->imagecreate($newW, $newH);
+                               $Bcolor = ImageColorAllocate($maskImg, 255,255,255);
+                               ImageFilledRectangle($maskImg, 0, 0, $newW, $newH, $Bcolor);
                                $Fcolor = ImageColorAllocate($maskImg, 0,0,0);
                                if ($spacing || $wordSpacing)   {               // If any kind of spacing applys, we use this function:
-                                       $this->SpacedImageTTFText($maskImg, ceil($sF*$conf['fontSize']), $conf['angle'], ceil($sF*$txtPos[0]), ceil($sF*$txtPos[1]), $Fcolor, t3lib_stdGraphic::prependAbsolutePath($conf['fontFile']), $theText, ceil($sF*$spacing), ceil($sF*$wordSpacing));
+                                       $this->SpacedImageTTFText($maskImg, $conf['fontSize'], $conf['angle'], $txtPos[0], $txtPos[1], $Fcolor, t3lib_stdGraphic::prependAbsolutePath($conf['fontFile']), $theText, $spacing, $wordSpacing, $conf['splitRendering.'],$sF);
                                } else {
-                                       ImageTTFText($maskImg, t3lib_div::freetypeDpiComp(ceil($sF*$conf['fontSize'])), $conf['angle'], ceil($sF*$txtPos[0]), ceil($sF*$txtPos[1]), $Fcolor, t3lib_stdGraphic::prependAbsolutePath($conf['fontFile']), $theText);
+                                       $this->renderTTFText($maskImg, $conf['fontSize'], $conf['angle'], $txtPos[0], $txtPos[1], $Fcolor, $conf['fontFile'], $theText, $conf['splitRendering.'], $conf, $sF);
                                }
-                               $this->ImageGif($maskImg, $fileMask);
+                               $this->ImageWrite($maskImg, $fileMask);
                                ImageDestroy($maskImg);
 
                                        // Downscales the mask
@@ -601,20 +667,22 @@ class t3lib_stdGraphic    {
                                                }
                                        }
                                }
+
                                $this->imageMagickExec($fileMask,$fileMask,$command);
 
                                        // Make the color-file
-                               $colorImg = imagecreate($w,$h);
-                               ImageColorAllocate($colorImg, $cols[0],$cols[1],$cols[2]);
-                               $this->ImageGif($colorImg, $fileColor);
+                               $colorImg = $this->imagecreate($w,$h);
+                               $Ccolor = ImageColorAllocate($colorImg, $cols[0],$cols[1],$cols[2]);
+                               ImageFilledRectangle($colorImg, 0, 0, $w, $h, $Ccolor);
+                               $this->ImageWrite($colorImg, $fileColor);
                                ImageDestroy($colorImg);
 
                                        // The mask is applied
-                               $this->ImageGif($im, $fileMenu);        // The main pictures is saved temporarily
+                               $this->ImageWrite($im, $fileMenu);      // The main pictures is saved temporarily
 
-                               $this->combineExec($fileMenu,$fileColor,$fileMask,$fileMenu);
+                               $this->combineExec($fileMenu,$fileColor,$fileMask, $fileMenu);
 
-                               $backIm = $this->imageCreateFromGif($fileMenu); // The main image is loaded again...
+                               $backIm = $this->imageCreateFromFile($fileMenu);        // The main image is loaded again...
                                if ($backIm)    {       // ... and if nothing went wrong we load it onto the old one.
                                        ImageColorTransparent($backIm,-1);
                                        $im = $backIm;
@@ -695,21 +763,11 @@ class t3lib_stdGraphic    {
         * @see txtPosition(), tslib_gifBuilder::start()
         */
        function calcBBox($conf)        {
-               if (!$conf['niceText']) {
-                       $sF = 1;
-               } else {                // NICETEXT::
-                       $sF = t3lib_div::intInRange($conf['niceText.']['scaleFactor'],2,5);
-               }
-
-               $spacing = intval($conf['spacing']);
-               $wordSpacing = intval($conf['wordSpacing']);
-               $wordSpacing = $wordSpacing?$wordSpacing:$spacing*2;
-
-               $spacing*=$sF;
-               $wordSpacing*=$sF;
+               $sF = $this->getTextScalFactor($conf);
+               list($spacing,$wordSpacing) = $this->calcWordSpacing($conf, $sF);
                $theText = $this->recodeString($conf['text']);
 
-               $charInf = ImageTTFBBox(t3lib_div::freetypeDpiComp($sF*$conf['fontSize']), $conf['angle'], t3lib_stdGraphic::prependAbsolutePath($conf['fontFile']), $theText);
+               $charInf = $this->ImageTTFBBoxWrapper($conf['fontSize'], $conf['angle'], $conf['fontFile'], $theText, $conf['splitRendering.'],$sF);
                $theBBoxInfo = $charInf;
                if ($conf['angle'])     {
                        $xArr = Array($charInf[0],$charInf[2],$charInf[4],$charInf[6]);
@@ -720,13 +778,16 @@ class t3lib_stdGraphic    {
                        $x = ($charInf[2]-$charInf[0]);
                        $y = ($charInf[1]-$charInf[7]);
                }
+                       // Set original lineHeight (used by line breaks):
+               $theBBoxInfo['lineHeight'] = $y;
+
                if ($spacing || $wordSpacing)   {               // If any kind of spacing applys, we use this function:
                        $x=0;
                        if (!$spacing && $wordSpacing)  {
                                $bits = explode(' ',$theText);
                                while(list(,$word)=each($bits)) {
                                        $word.=' ';
-                                       $wordInf = ImageTTFBBox(t3lib_div::freetypeDpiComp($sF*$conf['fontSize']), $conf['angle'], t3lib_stdGraphic::prependAbsolutePath($conf['fontFile']), $word);
+                                       $wordInf = $this->ImageTTFBBoxWrapper($conf['fontSize'], $conf['angle'], $conf['fontFile'], $word, $conf['splitRendering.'],$sF);
                                        $wordW = ($wordInf[2]-$wordInf[0]);
                                        $x+=$wordW+$wordSpacing;
                                }
@@ -734,24 +795,43 @@ class t3lib_stdGraphic    {
                                $utf8Chars = $this->singleChars($theText);
                                        // For each UTF-8 char, do:
                                foreach($utf8Chars as $char)    {
-                                       $charInf = ImageTTFBBox(t3lib_div::freetypeDpiComp($sF*$conf['fontSize']), $conf['angle'], t3lib_stdGraphic::prependAbsolutePath($conf['fontFile']), $char);
+                                       $charInf = $this->ImageTTFBBoxWrapper($conf['fontSize'], $conf['angle'], $conf['fontFile'], $char, $conf['splitRendering.'],$sF);
                                        $charW = ($charInf[2]-$charInf[0]);
                                        $x+=$charW+(($char==' ')?$wordSpacing:$spacing);
                                }
                        }
+               } elseif (isset($conf['breakWidth']) && $conf['breakWidth'] && $this->getRenderedTextWidth($conf['text'], $conf) > $conf['breakWidth']) {
+                       $maxWidth = 0;
+                       $currentWidth = 0;
+                       $breakWidth = $conf['breakWidth'];
+                       $breakSpace = $this->getBreakSpace($conf, $theBBoxInfo);
+
+                       $wordPairs = $this->getWordPairsForLineBreak($conf['text']);
+                               // Iterate through all word pairs:
+                       foreach ($wordPairs as $index => $wordPair) {
+                               $wordWidth = $this->getRenderedTextWidth($wordPair, $conf);
+                               if ($index == 0 || $currentWidth + $wordWidth <= $breakWidth) {
+                                       $currentWidth+= $wordWidth;
+                               } else {
+                                       $maxWidth = max($maxWidth, $currentWidth);
+                                       $y+= $breakSpace;
+                                               // Restart:
+                                       $currentWidth = $wordWidth;
+                               }
+                       }
+                       $x = max($maxWidth, $currentWidth) * $sF;
                }
 
-               if ($sF>1) {
-                       $x = ceil($x/$sF);
-                       $y = ceil($y/$sF);
+               if ($sF > 1) {
+                       $x = ceil($x / $sF);
+                       $y = ceil($y / $sF);
                        if (is_array($theBBoxInfo))     {
-                               reset($theBBoxInfo);
-                               while(list($key,$val)=each($theBBoxInfo))       {
-                                       $theBBoxInfo[$key]=ceil($theBBoxInfo[$key]/$sF);
+                               foreach ($theBBoxInfo as &$value) {
+                                       $value = ceil($value / $sF);
                                }
                        }
                }
-               return Array($x,$y,$theBBoxInfo);
+               return array($x, $y, $theBBoxInfo);
        }
 
        /**
@@ -765,13 +845,15 @@ class t3lib_stdGraphic    {
         */
        function addToMap($cords,$conf) {
                $JS = $conf['noBlur'] ? '' : ' onfocus="blurLink(this);"';
+
                $this->map.='<area'.
                                ' shape="poly"'.
-                               ' coords="'.implode($cords,',').'"'.
+                               ' coords="'.implode(',',$cords).'"'.
                                ' href="'.htmlspecialchars($conf['url']).'"'.
-                               ($conf['target'] ? ' target="'.$conf['target'].'"' : '').
+                               ($conf['target'] ? ' target="'.htmlspecialchars($conf['target']).'"' : '').
                                $JS.
-                               ' alt="" />';
+                               (strlen($conf['titleText']) ? ' title="'.htmlspecialchars($conf['titleText']).'"' : '').
+                               ' alt="'.htmlspecialchars($conf['altText']).'" />';
        }
 
        /**
@@ -814,28 +896,34 @@ class t3lib_stdGraphic    {
         * @param       string          (See argument for PHP function imageTTFtext()). UTF-8 string, possibly with entities in.
         * @param       integer         The spacing of letters in pixels
         * @param       integer         The spacing of words in pixels
+        * @param       array           $splitRenderingConf array
+        * @param       integer         Scale factor
         * @return      void
         * @access private
         */
-       function SpacedImageTTFText(&$im, $fontSize, $angle, $x, $y, $Fcolor, $fontFile, $text, $spacing, $wordSpacing) {
+       function SpacedImageTTFText(&$im, $fontSize, $angle, $x, $y, $Fcolor, $fontFile, $text, $spacing, $wordSpacing, $splitRenderingConf, $sF=1)     {
+
+               $spacing*=$sF;
+               $wordSpacing*=$sF;
+
                if (!$spacing && $wordSpacing)  {
                        $bits = explode(' ',$text);
                        reset($bits);
                        while(list(,$word)=each($bits)) {
                                $word.=' ';
                                $word = $word;
-                               $wordInf = ImageTTFBBox(t3lib_div::freetypeDpiComp($fontSize), $angle, t3lib_stdGraphic::prependAbsolutePath($fontFile), $word);
+                               $wordInf = $this->ImageTTFBBoxWrapper($fontSize, $angle, $fontFile, $word, $splitRenderingConf ,$sF);
                                $wordW = ($wordInf[2]-$wordInf[0]);
-                               ImageTTFText($im, t3lib_div::freetypeDpiComp($fontSize), $angle, $x, $y, $Fcolor, t3lib_stdGraphic::prependAbsolutePath($fontFile), $word);
+                               $this->ImageTTFTextWrapper($im, $fontSize, $angle, $x, $y, $Fcolor, $fontFile, $word, $splitRenderingConf, $sF);
                                $x+=$wordW+$wordSpacing;
                        }
                } else {
                        $utf8Chars = $this->singleChars($text);
                                // For each UTF-8 char, do:
                        foreach($utf8Chars as $char)    {
-                               $charInf = ImageTTFBBox(t3lib_div::freetypeDpiComp($fontSize), $angle, t3lib_stdGraphic::prependAbsolutePath($fontFile), $char);
+                               $charInf = $this->ImageTTFBBoxWrapper($fontSize, $angle, $fontFile, $char, $splitRenderingConf, $sF);
                                $charW = ($charInf[2]-$charInf[0]);
-                               ImageTTFText($im, t3lib_div::freetypeDpiComp($fontSize), $angle, $x, $y, $Fcolor, t3lib_stdGraphic::prependAbsolutePath($fontFile), $char);
+                               $this->ImageTTFTextWrapper($im, $fontSize, $angle, $x, $y, $Fcolor, $fontFile, $char, $splitRenderingConf, $sF);
                                $x+=$charW+(($char==' ')?$wordSpacing:$spacing);
                        }
                }
@@ -847,22 +935,21 @@ class t3lib_stdGraphic    {
         * @param       array           The TypoScript properties of the TEXT GIFBUILDER object
         * @return      integer         The new fontSize
         * @access private
-        * @author      Rene Fritz <r.fritz@colorcube.de>
+        * @author Rene Fritz <r.fritz@colorcube.de>
         * @see tslib_gifBuilder::start()
         */
        function fontResize($conf) {
                // you have to use +calc options like [10.h] in 'offset' to get the right position of your text-image, if you use +calc in XY height!!!!
                $maxWidth = intval($conf['maxWidth']);
+               list($spacing,$wordSpacing) = $this->calcWordSpacing($conf);
                if ($maxWidth)  {
                        if ($spacing || $wordSpacing)   {               // If any kind of spacing applys, we use this function:
                                return $conf['fontSize'];
                                //  ################ no calc for spacing yet !!!!!!
                        } else {
-                               $fontSize = $conf['fontSize'];
                                do {
-                                       $conf['fontSize'] = $fontSize;
                                                // determine bounding box.
-                                       $bounds = ImageTTFBBox(t3lib_div::freetypeDpiComp($conf['fontSize']), $conf['angle'], t3lib_stdGraphic::prependAbsolutePath($conf['fontFile']), $this->recodeString($conf['text']));
+                                       $bounds = $this->ImageTTFBBoxWrapper($conf['fontSize'], $conf['angle'], $conf['fontFile'], $this->recodeString($conf['text']), $conf['splitRendering.']);
                                        if ($conf['angle']< 0) {
                                                $pixelWidth = abs($bounds[4]-$bounds[0]);
                                        } elseif ($conf['angle'] > 0) {
@@ -870,21 +957,416 @@ class t3lib_stdGraphic   {
                                        } else {
                                                $pixelWidth = abs($bounds[4]-$bounds[6]);
                                        }
-                                               // This is a very raw calculation but it makes it in one step
-                                       $fontSize=(int)($maxWidth*$fontSize/$pixelWidth);
-                                       if ($fontSize >= $conf['fontSize'])     {
-                                               $fontSize = $conf['fontSize']-1;
+
+                                               // Size is fine, exit:
+                                       if ($pixelWidth <= $maxWidth)   {
+                                               break;
+                                       } else {
+                                               $conf['fontSize']--;
                                        }
-                               } while ($pixelWidth > $maxWidth);
+                               } while ($conf['fontSize']>1);
                        }//if spacing
                }
                return $conf['fontSize'];
        }
 
+       /**
+        * Wrapper for ImageTTFBBox
+        *
+        * @param       integer         (See argument for PHP function ImageTTFBBox())
+        * @param       integer         (See argument for PHP function ImageTTFBBox())
+        * @param       string          (See argument for PHP function ImageTTFBBox())
+        * @param       string          (See argument for PHP function ImageTTFBBox())
+        * @param       array           Split-rendering configuration
+        * @param       integer         Scale factor
+        * @return      array           Information array.
+        */
+       function ImageTTFBBoxWrapper($fontSize, $angle, $fontFile, $string, $splitRendering, $sF=1)     {
 
+                       // Initialize:
+               $offsetInfo = array();
+               $stringParts = $this->splitString($string,$splitRendering,$fontSize,$fontFile);
 
+                       // Traverse string parts:
+               foreach($stringParts as $strCfg)        {
+                       $fontFile = t3lib_stdGraphic::prependAbsolutePath($strCfg['fontFile']);
+                       if (is_readable($fontFile)) {
 
+                                       // Calculate Bounding Box for part:
+                               $calc = ImageTTFBBox(t3lib_div::freetypeDpiComp($sF*$strCfg['fontSize']), $angle, $fontFile, $strCfg['str']);
 
+                                       // Calculate offsets:
+                               if (!count($offsetInfo))        {
+                                       $offsetInfo = $calc;    // First run, just copy over.
+                               } else {
+                                       $offsetInfo[2]+=$calc[2]-$calc[0]+intval($splitRendering['compX'])+intval($strCfg['xSpaceBefore'])+intval($strCfg['xSpaceAfter']);
+                                       $offsetInfo[3]+=$calc[3]-$calc[1]-intval($splitRendering['compY'])-intval($strCfg['ySpaceBefore'])-intval($strCfg['ySpaceAfter']);
+                                       $offsetInfo[4]+=$calc[4]-$calc[6]+intval($splitRendering['compX'])+intval($strCfg['xSpaceBefore'])+intval($strCfg['xSpaceAfter']);
+                                       $offsetInfo[5]+=$calc[5]-$calc[7]-intval($splitRendering['compY'])-intval($strCfg['ySpaceBefore'])-intval($strCfg['ySpaceAfter']);
+                               }
+
+                       } else {
+                               debug('cannot read file: '.$fontFile, 't3lib_stdGraphic::ImageTTFBBoxWrapper()');
+                       }
+               }
+
+               return $offsetInfo;
+       }
+
+       /**
+        * Wrapper for ImageTTFText
+        *
+        * @param       pointer         (See argument for PHP function imageTTFtext())
+        * @param       integer         (See argument for PHP function imageTTFtext())
+        * @param       integer         (See argument for PHP function imageTTFtext())
+        * @param       integer         (See argument for PHP function imageTTFtext())
+        * @param       integer         (See argument for PHP function imageTTFtext())
+        * @param       integer         (See argument for PHP function imageTTFtext())
+        * @param       string          (See argument for PHP function imageTTFtext())
+        * @param       string          (See argument for PHP function imageTTFtext()). UTF-8 string, possibly with entities in.
+        * @param       array           Split-rendering configuration
+        * @param       integer         Scale factor
+        * @return      void
+        */
+       function ImageTTFTextWrapper($im, $fontSize, $angle, $x, $y, $color, $fontFile, $string, $splitRendering,$sF=1) {
+
+                       // Initialize:
+               $stringParts = $this->splitString($string,$splitRendering,$fontSize,$fontFile);
+               $x = ceil($sF*$x);
+               $y = ceil($sF*$y);
+
+                       // Traverse string parts:
+               foreach($stringParts as $i => $strCfg)  {
+
+                               // Initialize:
+                       $colorIndex = $color;
+
+                               // Set custom color if any (only when niceText is off):
+                       if ($strCfg['color'] && $sF==1) {
+                               $cols = $this->convertColor($strCfg['color']);
+                               $colorIndex = ImageColorAllocate($im, $cols[0],$cols[1],$cols[2]);
+                               $colorIndex = $color >= 0 ? $colorIndex : -$colorIndex;
+                       }
+
+                               // Setting xSpaceBefore
+                       if ($i) {
+                               $x+= intval($strCfg['xSpaceBefore']);
+                               $y-= intval($strCfg['ySpaceBefore']);
+                       }
+
+                       $fontFile = t3lib_stdGraphic::prependAbsolutePath($strCfg['fontFile']);
+                       if (is_readable($fontFile)) {
+
+                                       // Render part:
+                               ImageTTFText($im, t3lib_div::freetypeDpiComp($sF*$strCfg['fontSize']), $angle, $x, $y, $colorIndex, $fontFile, $strCfg['str']);
+
+                                       // Calculate offset to apply:
+                               $wordInf = ImageTTFBBox(t3lib_div::freetypeDpiComp($sF*$strCfg['fontSize']), $angle, t3lib_stdGraphic::prependAbsolutePath($strCfg['fontFile']), $strCfg['str']);
+                               $x+= $wordInf[2]-$wordInf[0]+intval($splitRendering['compX'])+intval($strCfg['xSpaceAfter']);
+                               $y+= $wordInf[5]-$wordInf[7]-intval($splitRendering['compY'])-intval($strCfg['ySpaceAfter']);
+
+                       } else {
+                               debug('cannot read file: '.$fontFile, 't3lib_stdGraphic::ImageTTFTextWrapper()');
+                       }
+
+               }
+       }
+
+       /**
+        * Splitting a string for ImageTTFBBox up into an array where each part has its own configuration options.
+        *
+        * @param       string          UTF-8 string
+        * @param       array           Split-rendering configuration from GIFBUILDER TEXT object.
+        * @param       integer         Current fontsize
+        * @param       string          Current font file
+        * @return      array           Array with input string splitted according to configuration
+        */
+       function splitString($string,$splitRendering,$fontSize,$fontFile)       {
+
+                       // Initialize by setting the whole string and default configuration as the first entry.
+               $result = array();
+               $result[] = array(
+                       'str' => $string,
+                       'fontSize' => $fontSize,
+                       'fontFile' => $fontFile
+               );
+
+                       // Traverse the split-rendering configuration:
+                       // Splitting will create more entries in $result with individual configurations.
+               if (is_array($splitRendering))  {
+                       $sKeyArray = t3lib_TStemplate::sortedKeyList($splitRendering);
+
+                               // Traverse configured options:
+                       foreach($sKeyArray as $key)     {
+                               $cfg = $splitRendering[$key.'.'];
+
+                                       // Process each type of split rendering keyword:
+                               switch((string)$splitRendering[$key])   {
+                                       case 'highlightWord':
+                                               if (strlen($cfg['value']))      {
+                                                       $newResult = array();
+
+                                                               // Traverse the current parts of the result array:
+                                                       foreach($result as $part)       {
+                                                                       // Explode the string value by the word value to highlight:
+                                                               $explodedParts = explode($cfg['value'],$part['str']);
+                                                               foreach($explodedParts as $c => $expValue)      {
+                                                                       if (strlen($expValue))  {
+                                                                               $newResult[] = array_merge($part,array('str' => $expValue));
+                                                                       }
+                                                                       if ($c+1 < count($explodedParts))       {
+                                                                               $newResult[] = array(
+                                                                                       'str' => $cfg['value'],
+                                                                                       'fontSize' => $cfg['fontSize'] ? $cfg['fontSize'] : $part['fontSize'],
+                                                                                       'fontFile' => $cfg['fontFile'] ? $cfg['fontFile'] : $part['fontFile'],
+                                                                                       'color' => $cfg['color'],
+                                                                                       'xSpaceBefore' => $cfg['xSpaceBefore'],
+                                                                                       'xSpaceAfter' => $cfg['xSpaceAfter'],
+                                                                                       'ySpaceBefore' => $cfg['ySpaceBefore'],
+                                                                                       'ySpaceAfter' => $cfg['ySpaceAfter'],
+                                                                               );
+                                                                       }
+                                                               }
+                                                       }
+
+                                                               // Set the new result as result array:
+                                                       if (count($newResult))  {
+                                                               $result = $newResult;
+                                                       }
+                                               }
+                                       break;
+                                       case 'charRange':
+                                               if (strlen($cfg['value']))      {
+
+                                                               // Initialize range:
+                                                       $ranges = t3lib_div::trimExplode(',',$cfg['value'],1);
+                                                       foreach($ranges as $i => $rangeDef)     {
+                                                               $ranges[$i] = t3lib_div::intExplode('-',$ranges[$i]);
+                                                               if (!isset($ranges[$i][1]))     $ranges[$i][1] = $ranges[$i][0];
+                                                       }
+                                                       $newResult = array();
+
+                                                               // Traverse the current parts of the result array:
+                                                       foreach($result as $part)       {
+
+                                                                       // Initialize:
+                                                               $currentState = -1;
+                                                               $bankAccum = '';
+
+                                                                       // Explode the string value by the word value to highlight:
+                                                               $utf8Chars = $this->singleChars($part['str']);
+                                                               foreach($utf8Chars as $utfChar) {
+
+                                                                               // Find number and evaluate position:
+                                                                       $uNumber = $this->csConvObj->utf8CharToUnumber($utfChar);
+                                                                       $inRange = 0;
+                                                                       foreach($ranges as $rangeDef)   {
+                                                                               if ($uNumber >= $rangeDef[0] && (!$rangeDef[1] || $uNumber <= $rangeDef[1])) {
+                                                                                       $inRange = 1;
+                                                                                       break;
+                                                                               }
+                                                                       }
+                                                                       if ($currentState==-1)  $currentState = $inRange;       // Initialize first char
+
+                                                                               // Switch bank:
+                                                                       if ($inRange != $currentState && !t3lib_div::inList('32,10,13,9',$uNumber))     {
+
+                                                                                       // Set result:
+                                                                               if (strlen($bankAccum)) {
+                                                                                       $newResult[] = array(
+                                                                                               'str' => $bankAccum,
+                                                                                               'fontSize' => $currentState && $cfg['fontSize'] ? $cfg['fontSize'] : $part['fontSize'],
+                                                                                               'fontFile' => $currentState && $cfg['fontFile'] ? $cfg['fontFile'] : $part['fontFile'],
+                                                                                               'color' => $currentState ? $cfg['color'] : '',
+                                                                                               'xSpaceBefore' => $currentState ? $cfg['xSpaceBefore'] : '',
+                                                                                               'xSpaceAfter' => $currentState ? $cfg['xSpaceAfter'] : '',
+                                                                                               'ySpaceBefore' => $currentState ? $cfg['ySpaceBefore'] : '',
+                                                                                               'ySpaceAfter' => $currentState ? $cfg['ySpaceAfter'] : '',
+                                                                                       );
+                                                                               }
+
+                                                                                       // Initialize new settings:
+                                                                               $currentState = $inRange;
+                                                                               $bankAccum = '';
+                                                                       }
+
+                                                                               // Add char to bank:
+                                                                       $bankAccum.=$utfChar;
+                                                               }
+
+                                                                       // Set result for FINAL part:
+                                                               if (strlen($bankAccum)) {
+                                                                       $newResult[] = array(
+                                                                               'str' => $bankAccum,
+                                                                               'fontSize' => $currentState && $cfg['fontSize'] ? $cfg['fontSize'] : $part['fontSize'],
+                                                                               'fontFile' => $currentState && $cfg['fontFile'] ? $cfg['fontFile'] : $part['fontFile'],
+                                                                               'color' => $currentState ? $cfg['color'] : '',
+                                                                               'xSpaceBefore' => $currentState ? $cfg['xSpaceBefore'] : '',
+                                                                               'xSpaceAfter' => $currentState ? $cfg['xSpaceAfter'] : '',
+                                                                               'ySpaceBefore' => $currentState ? $cfg['ySpaceBefore'] : '',
+                                                                               'ySpaceAfter' => $currentState ? $cfg['ySpaceAfter'] : '',
+                                                                       );
+                                                               }
+                                                       }
+
+                                                               // Set the new result as result array:
+                                                       if (count($newResult))  {
+                                                               $result = $newResult;
+                                                       }
+                                               }
+                                       break;
+                               }
+                       }
+               }
+
+               return $result;
+       }
+
+       /**
+        * Calculates the spacing and wordSpacing values
+        *
+        * @param       array           TypoScript array for the TEXT GIFBUILDER object
+        * @param       integer         TypoScript value from eg $conf['niceText.']['scaleFactor']
+        * @return      array           Array with two keys [0]/[1] being array($spacing,$wordSpacing)
+        * @access private
+        * @see calcBBox()
+        */
+       function calcWordSpacing($conf, $scaleFactor=1) {
+
+               $spacing = intval($conf['spacing']);
+               $wordSpacing = intval($conf['wordSpacing']);
+               $wordSpacing = $wordSpacing?$wordSpacing:$spacing*2;
+
+               $spacing*=$scaleFactor;
+               $wordSpacing*=$scaleFactor;
+
+               return array($spacing,$wordSpacing);
+       }
+
+       /**
+        * Calculates and returns the niceText.scaleFactor
+        *
+        * @param       array           TypoScript array for the TEXT GIFBUILDER object
+        * @return      integer         TypoScript value from eg $conf['niceText.']['scaleFactor']
+        * @access private
+        */
+       function getTextScalFactor($conf) {
+               if (!$conf['niceText']) {
+                       $sF = 1;
+               } else {                // NICETEXT::
+                       $sF = t3lib_div::intInRange($conf['niceText.']['scaleFactor'],2,5);
+               }
+               return $sF;
+       }
+
+       /**
+        * Renders a regular text and takes care of a possible line break automatically.
+        *
+        * @param       pointer         (See argument for PHP function imageTTFtext())
+        * @param       integer         (See argument for PHP function imageTTFtext())
+        * @param       integer         (See argument for PHP function imageTTFtext())
+        * @param       integer         (See argument for PHP function imageTTFtext())
+        * @param       integer         (See argument for PHP function imageTTFtext())
+        * @param       integer         (See argument for PHP function imageTTFtext())
+        * @param       string          (See argument for PHP function imageTTFtext())
+        * @param       string          (See argument for PHP function imageTTFtext()). UTF-8 string, possibly with entities in.
+        * @param       array           Split-rendering configuration
+        * @param       integer         Scale factor
+        * @param       array           $conf: The configuration
+        * @return      void
+        */
+       protected function renderTTFText(&$im, $fontSize, $angle, $x, $y, $color, $fontFile, $string, $splitRendering, $conf, $sF = 1) {
+               if (isset($conf['breakWidth']) && $conf['breakWidth'] && $this->getRenderedTextWidth($string, $conf) > $conf['breakWidth']) {
+                       $phrase = '';
+                       $currentWidth = 0;
+
+                       $breakWidth = $conf['breakWidth'];
+                       $breakSpace = $this->getBreakSpace($conf);
+
+                       $wordPairs = $this->getWordPairsForLineBreak($string);
+                               // Iterate through all word pairs:
+                       foreach ($wordPairs as $index => $wordPair) {
+                               $wordWidth = $this->getRenderedTextWidth($wordPair, $conf);
+                               if ($index == 0 || $currentWidth + $wordWidth <= $breakWidth) {
+                                       $currentWidth+= $wordWidth;
+                                       $phrase.= $wordPair;
+                               } else {
+                                               // Render the current phrase that is below breakWidth:
+                                       $this->ImageTTFTextWrapper($im, $fontSize, $angle, $x, $y, $color, $fontFile, $phrase, $splitRendering, $sF);
+                                               // Calculate the news height offset:
+                                       $y+= $breakSpace;
+                                               // Restart the phrase:
+                                       $currentWidth = $wordWidth;
+                                       $phrase = $wordPair;
+                               }
+                       }
+                               // Render the remaining phrase:
+                       if ($currentWidth) {
+                               $this->ImageTTFTextWrapper($im, $fontSize, $angle, $x, $y, $color, $fontFile, $phrase, $splitRendering, $sF);
+                       }
+               } else {
+                       $this->ImageTTFTextWrapper($im, $fontSize, $angle, $x, $y, $color, $fontFile, $string, $splitRendering, $sF);
+               }
+       }
+
+       /**
+        * Gets the word pairs used for automatic line breaks.
+        *
+        * @param       string          $string
+        * @return      array
+        */
+       protected function getWordPairsForLineBreak($string) {
+               $wordPairs = array();
+
+               $wordsArray = preg_split('#([ -.,!:]+)#', $string, -1,  PREG_SPLIT_DELIM_CAPTURE);
+               $wordsCount = count($wordsArray);
+               for ($index=0; $index < $wordsCount; $index+= 2) {
+                       $wordPairs[] = $wordsArray[$index] . $wordsArray[$index + 1];
+               }
+
+               return $wordPairs;
+       }
+
+       /**
+        * Gets the rendered text width.
+        *
+        * @param       string          $text
+        * @param       array           $conf
+        * @param       integer
+        */
+       protected function getRenderedTextWidth($text, $conf) {
+               $bounds = $this->ImageTTFBBoxWrapper($conf['fontSize'], $conf['angle'], $conf['fontFile'], $this->recodeString($text), $conf['splitRendering.']);
+               if ($conf['angle']< 0) {
+                       $pixelWidth = abs($bounds[4]-$bounds[0]);
+               } elseif ($conf['angle'] > 0) {
+                       $pixelWidth = abs($bounds[2]-$bounds[6]);
+               } else {
+                       $pixelWidth = abs($bounds[4]-$bounds[6]);
+               }
+               return $pixelWidth;
+       }
+
+       /**
+        * Gets the break space for each new line.
+        *
+        * @param       array           $conf: TypoScript configuration for the currently rendered object
+        * @param       array           $boundingBox: The bounding box the the currently rendered object
+        * @return      integer         The break space
+        */
+       protected function getBreakSpace($conf, array $boundingBox = NULL) {
+               if (!isset($boundingBox)) {
+                       $boundingBox = $this->calcBBox($conf);
+                       $boundingBox = $boundingBox[2];
+               }
+
+               if (isset($conf['breakSpace']) && $conf['breakSpace']) {
+                       $breakSpace = $boundingBox['lineHeight'] * $conf['breakSpace'];
+               } else {
+                       $breakSpace = $boundingBox['lineHeight'];
+               }
+
+               return $breakSpace;
+       }
 
 
 
@@ -971,7 +1453,7 @@ class t3lib_stdGraphic     {
                $newOffset = t3lib_div::intExplode(',',$conf['offset']);
                $newOffset[0]*=-1;
                $newOffset[1]*=-1;
-               $conf['offset']=implode($newOffset,',');
+               $conf['offset']=implode(',',$newOffset);
                $conf['color']=$conf['lowColor'];
                $this->makeShadow($im,$conf,$workArea,$txtConf);
        }
@@ -1004,19 +1486,21 @@ class t3lib_stdGraphic  {
                        $fileMask = $tmpStr.'_mask.'.$this->gifExtension;
 
                                // BlurColor Image laves
-                       $blurColImg = imagecreate($w,$h);
+                       $blurColImg = $this->imagecreate($w,$h);
                        $bcols=$this->convertColor($conf['color']);
-                       ImageColorAllocate($blurColImg, $bcols[0],$bcols[1],$bcols[2]);
-                       $this->ImageGif($blurColImg, $fileColor);
+                       $Bcolor = ImageColorAllocate($blurColImg, $bcols[0],$bcols[1],$bcols[2]);
+                       ImageFilledRectangle($blurColImg, 0, 0, $w, $h, $Bcolor);
+                       $this->ImageWrite($blurColImg, $fileColor);
                        ImageDestroy($blurColImg);
 
                                // The mask is made: BlurTextImage
-                       $blurTextImg = imagecreate($w+$blurBorder*2,$h+$blurBorder*2);
-                       ImageColorAllocate($blurTextImg, 0,0,0);                // black background
+                       $blurTextImg = $this->imagecreate($w+$blurBorder*2,$h+$blurBorder*2);
+                       $Bcolor = ImageColorAllocate($blurTextImg, 0,0,0);              // black background
+                       ImageFilledRectangle($blurTextImg, 0, 0, $w+$blurBorder*2, $h+$blurBorder*2, $Bcolor);
                        $txtConf['fontColor'] = 'white';
                        $blurBordArr = Array($blurBorder,$blurBorder);
                        $this->makeText($blurTextImg,$txtConf,  $this->applyOffset($workArea,$blurBordArr));
-                       $this->ImageGif($blurTextImg, $fileMask);       // dump to temporary file
+                       $this->ImageWrite($blurTextImg, $fileMask);     // dump to temporary file
                        ImageDestroy($blurTextImg);     // destroy
 
 
@@ -1028,20 +1512,20 @@ class t3lib_stdGraphic  {
                        } else {
                                        // Blurring of the mask
                                $times = ceil($blurRate/10);    // How many blur-commands that is executed. Min = 1;
-                               $newBlurRate = $blurRate*4;             // Her booster vi blur-rate, så at den allerede ved 25 er på 100. Resten op til 99 går på iterationer af blur-kommandoen
+                               $newBlurRate = $blurRate*4;             // Here I boost the blur-rate so that it is 100 already at 25. The rest is done by up to 99 iterations of the blur-command.
                                $newBlurRate = t3lib_div::intInRange($newBlurRate,1,99);
                                for ($a=0;$a<$times;$a++)       {               // Building blur-command
                                        $command.=' -blur '.$blurRate;
                                }
                        }
 
-                       $this->imageMagickExec($fileMask,$fileMask,$command);
+                       $this->imageMagickExec($fileMask,$fileMask,$command.' +matte');
 
-                       $blurTextImg_tmp = $this->imageCreateFromGif($fileMask);        // the mask is loaded again
+                       $blurTextImg_tmp = $this->imageCreateFromFile($fileMask);       // the mask is loaded again
                        if ($blurTextImg_tmp)   {       // if nothing went wrong we continue with the blurred mask
 
                                        // cropping the border from the mask
-                               $blurTextImg = imagecreate($w,$h);
+                               $blurTextImg = $this->imagecreate($w,$h);
                                $this->imagecopyresized($blurTextImg, $blurTextImg_tmp, 0, 0, $blurBorder, $blurBorder, $w, $h, $w, $h);
                                ImageDestroy($blurTextImg_tmp); // Destroy the temporary mask
 
@@ -1059,15 +1543,15 @@ class t3lib_stdGraphic  {
                                        $this->outputLevels($blurTextImg,0,$high,$this->maskNegate);    // reducing levels as the opacity demands
                                }
 
-                               $this->ImageGif($blurTextImg, $fileMask);       // Dump the mask again
+                               $this->ImageWrite($blurTextImg, $fileMask);     // Dump the mask again
                                ImageDestroy($blurTextImg);     // Destroy the mask
 
                                        // The pictures are combined
-                               $this->ImageGif($im, $fileMenu);        // The main pictures is saved temporarily
+                               $this->ImageWrite($im, $fileMenu);      // The main pictures is saved temporarily
 
                                $this->combineExec($fileMenu,$fileColor,$fileMask,$fileMenu);
 
-                               $backIm = $this->imageCreateFromGif($fileMenu); // The main image is loaded again...
+                               $backIm = $this->imageCreateFromFile($fileMenu);        // The main image is loaded again...
                                if ($backIm)    {       // ... and if nothing went wrong we load it onto the old one.
                                        ImageColorTransparent($backIm,-1);
                                        $im = $backIm;
@@ -1122,8 +1606,22 @@ class t3lib_stdGraphic   {
                $conf['offset']=$cords[0].','.$cords[1];
                $cords = $this->objPosition($conf,$workArea,Array($cords[2],$cords[3]));
                $cols=$this->convertColor($conf['color']);
-               $this->reduceColors($im,256, 255);
-               $tmpColor = ImageColorAllocate($im, $cols[0],$cols[1],$cols[2]);
+               if (!$this->truecolor)  {
+                       $reduce = t3lib_div::intInRange($this->setup['reduceColors'], 256, $this->truecolorColors, 256);
+                       $this->reduceColors($im, $reduce-1, $reduce-2); // If "reduce-1" colors (or more) are used reduce them to "reduce-2"
+               }
+
+               $opacity = 0;
+               if (isset($conf['opacity'])) {
+                               // conversion:
+                               // PHP 0 = opaque, 127 = transparent
+                               // TYPO3 100 = opaque, 0 = transparent
+                       $opacity = t3lib_div::intInRange(intval($conf['opacity']), 1, 100, 1);
+                       $opacity = abs($opacity - 100);
+                       $opacity = round((127 * $opacity) / 100);
+               }
+
+               $tmpColor = ImageColorAllocateAlpha($im, $cols[0],$cols[1],$cols[2], $opacity);
                imagefilledrectangle($im, $cords[0], $cords[1], $cords[0]+$cords[2]-1, $cords[1]+$cords[3]-1, $tmpColor);
        }
 
@@ -1272,9 +1770,10 @@ class t3lib_stdGraphic   {
                $conf['offset']=$cords[0].','.$cords[1];
                $cords = $this->objPosition($conf,$this->workArea,Array($cords[2],$cords[3]));
 
-               $newIm = imagecreate($cords[2],$cords[3]);
+               $newIm = $this->imagecreate($cords[2],$cords[3]);
                $cols=$this->convertColor($conf['backColor']?$conf['backColor']:$this->setup['backColor']);
-               ImageColorAllocate($newIm, $cols[0],$cols[1],$cols[2]);
+               $Bcolor = ImageColorAllocate($newIm, $cols[0],$cols[1],$cols[2]);
+               ImageFilledRectangle($newIm, 0, 0, $cords[2], $cords[3], $Bcolor);
 
                $newConf = Array();
                $workArea = Array(0,0,$cords[2],$cords[3]);
@@ -1300,9 +1799,9 @@ class t3lib_stdGraphic    {
                if ($conf['width'] || $conf['height'] || $conf['params'])       {
                        $tmpStr = $this->randomName();
                        $theFile = $tmpStr.'.'.$this->gifExtension;
-                       $this->ImageGif($im, $theFile);
+                       $this->ImageWrite($im, $theFile);
                        $theNewFile = $this->imageMagickConvert($theFile,$this->gifExtension,$conf['width'],$conf['height'],$conf['params'],'','');
-                       $tmpImg = $this->imageCreateFromGif($theNewFile[3]);
+                       $tmpImg = $this->imageCreateFromFile($theNewFile[3]);
                        if ($tmpImg)    {
                                ImageDestroy($im);
                                $im = $tmpImg;
@@ -1456,7 +1955,7 @@ class t3lib_stdGraphic    {
        }
 
        /**
-        * Reduce colors in image
+        * Reduce colors in image dependend on the actual amount of colors (Only works if we are not in truecolor mode)
         *
         * @param       integer         GDlib Image Pointer
         * @param       integer         The max number of colors in the image before a reduction will happen; basically this means that IF the GD image current has the same amount or more colors than $limit define, THEN a reduction is performed.
@@ -1464,18 +1963,36 @@ class t3lib_stdGraphic  {
         * @return      void
         */
        function reduceColors(&$im,$limit, $cols)       {
-               if (ImageColorsTotal($im)>=$limit)      {
+               if (!$this->truecolor && ImageColorsTotal($im)>=$limit) {
                        $this->makeEffect($im, Array('value'=>'colors='.$cols) );
                }
        }
 
-
-
-
-
-
-
-
+       /**
+        * Reduce colors in image using IM and create a palette based image if possible (<=256 colors)
+        *
+        * @param       string          Image file to reduce
+        * @param       integer         Number of colors to reduce the image to.
+        * @return      string          Reduced file
+        */
+       function IMreduceColors($file, $cols)   {
+               $fI = t3lib_div::split_fileref($file);
+               $ext = strtolower($fI['fileext']);
+               $result = $this->randomName().'.'.$ext;
+               if (($reduce = t3lib_div::intInRange($cols, 0, ($ext=='gif'?256:$this->truecolorColors), 0))>0) {
+                       $params = ' -colors '.$reduce;
+                       if (!$this->im_version_4)       {
+                                       // IM4 doesn't have this options but forces them automatically if applicaple (<256 colors in image)
+                               if ($reduce<=256)       { $params .= ' -type Palette'; }
+                               if ($ext=='png' && $reduce<=256)        { $prefix = 'png8:'; }
+                       }
+                       $this->imageMagickExec($file, $prefix.$result, $params);
+                       if ($result)    {
+                               return $result;
+                       }
+               }
+               return '';
+       }
 
 
 
@@ -1503,7 +2020,7 @@ class t3lib_stdGraphic    {
         */
        function prependAbsolutePath($fontFile) {
                $absPath = defined('PATH_typo3') ? dirname(PATH_thisScript).'/' :PATH_site;
-               $fontFile = t3lib_div::isAbsPath($fontFile) ? $fontFile : $absPath.$fontFile;
+               $fontFile = t3lib_div::isAbsPath($fontFile) ? $fontFile : t3lib_div::resolveBackPath($absPath.$fontFile);
                return $fontFile;
        }
 
@@ -1552,7 +2069,8 @@ class t3lib_stdGraphic    {
         * @return      string
         */
        function randomName()   {
-               return $this->tempPath.'temp_'.md5(uniqid(''));
+               $this->createTempSubDir('temp/');
+               return $this->tempPath.'temp/'.md5(uniqid(''));
        }
 
        /**
@@ -1583,12 +2101,12 @@ class t3lib_stdGraphic  {
                        // Finding the RGB definitions of the color:
                $string=$cParts[0];
                if (strstr($string,'#'))        {
-                       $string = ereg_replace('[^A-Fa-f0-9]*','',$string);
+                       $string = preg_replace('/[^A-Fa-f0-9]*/','',$string);
                        $col[]=HexDec(substr($string,0,2));
                        $col[]=HexDec(substr($string,2,2));
                        $col[]=HexDec(substr($string,4,2));
                } elseif (strstr($string,','))  {
-                       $string = ereg_replace('[^,0-9]*','',$string);
+                       $string = preg_replace('/[^,0-9]*/','',$string);
                        $strArr = explode(',',$string);
                        $col[]=intval($strArr[0]);
                        $col[]=intval($strArr[1]);
@@ -1632,9 +2150,10 @@ class t3lib_stdGraphic   {
                        $string = $this->csConvObj->utf8_encode($string,$this->nativeCharset);  // Convert to UTF-8
                }
 
-                       // Recode string accoding to TTFLocaleConv. Depreciated.
+                       // Recode string accoding to TTFLocaleConv. Deprecated.
                if ($this->TTFLocaleConv)       {
-                       $string = recode_string($this->TTFLocaleConv,$string);
+                       list($from, $to) = t3lib_div::trimExplode('..', $this->TTFLocaleConv, true);
+                       $string = $this->csConvObj->conv($string, $from, $to);
                }
 
                return $string;
@@ -1642,14 +2161,15 @@ class t3lib_stdGraphic  {
 
        /**
         * Split a string into an array of individual characters
-        * The function will look at  $this->nativeCharset and if that is set, the input string is expected to be UTF-8 encoded, possibly with entities in it. Otherwise the string is supposed to be a single-byte charset which is just splitted by a for-loop.
+        * The function will look at $this->nativeCharset and if that is set, the input string is expected to be UTF-8 encoded, possibly with entities in it. Otherwise the string is supposed to be a single-byte charset which is just splitted by a for-loop.
         *
-        * @param       string          The text string to spli
+        * @param       string          The text string to split
+        * @param       boolean         Return Unicode numbers instead of chars.
         * @return      array           Numerical array with a char as each value.
         */
-       function singleChars($theText)  {
+       function singleChars($theText,$returnUnicodeNumber=FALSE)       {
                if ($this->nativeCharset)       {
-                       return $this->csConvObj->utf8_to_numberarray($theText,1,1);     // Get an array of separated UTF-8 chars
+                       return $this->csConvObj->utf8_to_numberarray($theText,1,$returnUnicodeNumber ? 0 : 1);  // Get an array of separated UTF-8 chars
                } else {
                        $output=array();
                        $c=strlen($theText);
@@ -1780,40 +2300,55 @@ class t3lib_stdGraphic  {
                                        // if no convertion should be performed
                                $wh_noscale = (!$w && !$h) || ($data[0]==$info[0] && $data[1]==$info[1]);               // this flag is true if the width / height does NOT dictate the image to be scaled!! (that is if no w/h is given or if the destination w/h matches the original image-dimensions....
 
-                               if ($wh_noscale && !$params && !$frame && $newExt==$info[2] && !$mustCreate) {
+                               if ($wh_noscale && !$data['crs'] && !$params && !$frame && $newExt==$info[2] && !$mustCreate) {
                                        $info[3] = $imagefile;
                                        return $info;
                                }
                                $info[0]=$data[0];
                                $info[1]=$data[1];
 
-                               $frame = $this->noFramePrepended ? '' : '['.intval($frame).']';
+                               $frame = $this->noFramePrepended ? '' : intval($frame);
 
                                if (!$params)   {
                                        $params = $this->cmds[$newExt];
                                }
 
+                                       // Cropscaling:
+                               if ($data['crs']) {
+                                       if (!$data['origW']) { $data['origW'] = $data[0]; }
+                                       if (!$data['origH']) { $data['origH'] = $data[1]; }
+                                       $offsetX = intval(($data[0] - $data['origW']) * ($data['cropH']+100)/200);
+                                       $offsetY = intval(($data[1] - $data['origH']) * ($data['cropV']+100)/200);
+                                       $params .= ' -crop '.$data['origW'].'x'.$data['origH'].'+'.$offsetX.'+'.$offsetY.' ';
+                               }
+
                                $command = $this->scalecmd.' '.$info[0].'x'.$info[1].'! '.$params.' ';
+                               $cropscale = ($data['crs'] ? 'crs-V'.$data['cropV'].'H'.$data['cropH'] : '');
 
                                if ($this->alternativeOutputKey)        {
-                                       $theOutputName = t3lib_div::shortMD5($command.basename($imagefile).$this->alternativeOutputKey.$frame);
+                                       $theOutputName = t3lib_div::shortMD5($command.$cropscale.basename($imagefile).$this->alternativeOutputKey.'['.$frame.']');
                                } else {
-                                       $theOutputName = t3lib_div::shortMD5($command.$imagefile.filemtime($imagefile).$frame);
+                                       $theOutputName = t3lib_div::shortMD5($command.$cropscale.$imagefile.filemtime($imagefile).'['.$frame.']');
                                }
                                if ($this->imageMagickConvert_forceFileNameBody)        {
                                        $theOutputName = $this->imageMagickConvert_forceFileNameBody;
                                        $this->imageMagickConvert_forceFileNameBody='';
                                }
-                               $output = $this->tempPath.$this->filenamePrefix.$theOutputName.'.'.$newExt;
-                               $GLOBALS['TEMP_IMAGES_ON_PAGE'][]=$output;
 
-                               if (!$this->file_exists_typo3temp_file($output,$imagefile) || $this->dontCheckForExistingTempFile)      {
-                                       $this->imageMagickExec($imagefile.$frame,$output,$command);
+                                       // Making the temporary filename:
+                               $this->createTempSubDir('pics/');
+                               $output = $this->absPrefix.$this->tempPath.'pics/'.$this->filenamePrefix.$theOutputName.'.'.$newExt;
+
+                                       // Register temporary filename:
+                               $GLOBALS['TEMP_IMAGES_ON_PAGE'][] = $output;
+
+                               if ($this->dontCheckForExistingTempFile || !$this->file_exists_typo3temp_file($output, $imagefile))     {
+                                       $this->imageMagickExec($imagefile, $output, $command, $frame);
                                }
-                               if (@file_exists($output))      {
+                               if (file_exists($output))       {
                                        $info[3] = $output;
                                        $info[2] = $newExt;
-                                       if ($params)    {       // params could realisticly change som imagedata!
+                                       if ($params)    {       // params could realisticly change some imagedata!
                                                $info=$this->getImageDimensions($info[3]);
                                        }
                                        if ($info[2]==$this->gifExtension && !$this->dontCompress)      {
@@ -1833,8 +2368,8 @@ class t3lib_stdGraphic    {
         * @see imageMagickConvert(), tslib_cObj::getImgResource()
         */
        function getImageDimensions($imageFile) {
-               ereg('([^\.]*)$',$imageFile,$reg);
-               if (@file_exists($imageFile) && t3lib_div::inList($this->imageFileExt,strtolower($reg[0])))     {
+               preg_match('/([^\.]*)$/',$imageFile,$reg);
+               if (file_exists($imageFile) && t3lib_div::inList($this->imageFileExt,strtolower($reg[0])))      {
                        if ($returnArr = $this->getCachedImageDimensions($imageFile))   {
                                return $returnArr;
                        } else {
@@ -1843,7 +2378,7 @@ class t3lib_stdGraphic    {
                                } else {
                                        $returnArr = $this->imageMagickIdentify($imageFile);
                                }
-                               if($returnArr) {
+                               if ($returnArr) {
                                        $this->cacheImageDimensions($returnArr);
                                        return $returnArr;
                                }
@@ -1858,21 +2393,17 @@ class t3lib_stdGraphic  {
         *
         * @param       array           $identifyResult: Result of the getImageDimensions function
         * @return      boolean         True if operation was successful
-        * @author      Michael Stucki <mundaun@gmx.ch> / Robert Lemke <rl@robertlemke.de>
+        * @author      Michael Stucki <michael@typo3.org> / Robert Lemke <rl@robertlemke.de>
         */
        function cacheImageDimensions($identifyResult)  {
                global $TYPO3_DB;
                        // Create a md5 hash of the filename
-               if (function_exists('md5_file')) {
-                       $md5Hash = md5_file($identifyResult[3]);
-               } else {
-                       $md5Hash = md5 (t3lib_div::getURL($identifyResult[3]));
-               }
+               $md5Hash = md5_file($identifyResult[3]);
                if ($md5Hash) {
                        $fieldArr = array (
                                'md5hash' => $md5Hash,
                                'md5filename' => md5($identifyResult[3]),
-                               'tstamp' => time(),
+                               'tstamp' => $GLOBALS['EXEC_TIME'],
                                'filename' => $identifyResult[3],
                                'imagewidth' => $identifyResult[0],
                                'imageheight' => $identifyResult[1],
@@ -1890,25 +2421,21 @@ class t3lib_stdGraphic  {
         *
         * @param       string          The image filepath
         * @return      array           Returns an array where [0]/[1] is w/h, [2] is extension and [3] is the filename.
-        * @author      Michael Stucki <mundaun@gmx.ch> / Robert Lemke <rl@robertlemke.de>
+        * @author      Michael Stucki <michael@typo3.org> / Robert Lemke <rl@robertlemke.de>
         */
        function getCachedImageDimensions($imageFile)   {
                global $TYPO3_DB;
                        // Create a md5 hash of the filename
-               if(function_exists('md5_file')) {
-                       $md5Hash = md5_file($imageFile);
-               } else {
-                       $md5Hash = md5(t3lib_div::getURL ($imageFile));
-               }
-               ereg('([^\.]*)$',$imageFile,$reg);
-               $res = $TYPO3_DB->exec_SELECTquery ('md5hash, imagewidth, imageheight', 'cache_imagesizes', 'md5filename="'.md5($imageFile).'"');
+               $md5Hash = md5_file($imageFile);
+               preg_match('/([^\.]*)$/',$imageFile,$reg);
+               $res = $TYPO3_DB->exec_SELECTquery ('md5hash, imagewidth, imageheight', 'cache_imagesizes', 'md5filename='.$TYPO3_DB->fullQuoteStr(md5($imageFile),'cache_imagesizes'));
                if ($res) {
                        if ($row = $TYPO3_DB->sql_fetch_assoc($res)) {
                                if ($row['md5hash']!=$md5Hash) {
                                                // file has changed, delete the row
-                                       $TYPO3_DB->exec_DELETEquery ('cache_imagesizes', 'md5hash="'.$TYPO3_DB->quoteStr($row['md5hash']).'"');
+                                       $TYPO3_DB->exec_DELETEquery ('cache_imagesizes', 'md5hash='.$TYPO3_DB->fullQuoteStr($row['md5hash'],'cache_imagesizes'));
                                } else {
-                                       return (array($row['imagewidth'], $row['imageheight'], strtolower($reg[0]), $imageFile));
+                                       return (array((int) $row['imagewidth'], (int) $row['imageheight'], strtolower($reg[0]), $imageFile));
                                }
                        }
                }
@@ -1928,6 +2455,16 @@ class t3lib_stdGraphic   {
         */
        function getImageScale($info,$w,$h,$options) {
                if (strstr($w.$h, 'm')) {$max=1;} else {$max=0;}
+
+               if (strstr($w.$h, 'c')) {
+                       $out['cropH'] = intval(substr(strstr($w, 'c'), 1));
+                       $out['cropV'] = intval(substr(strstr($h, 'c'), 1));
+                       $crs = true;
+               } else {
+                       $crs = false;
+               }
+               $out['crs'] = $crs;
+
                $w=intval($w);
                $h=intval($h);
                        // if there are max-values...
@@ -1983,6 +2520,14 @@ class t3lib_stdGraphic   {
                                                $w = round($h*$ratio);
                                        }
                                }
+                               if ($crs)       {
+                                       $ratio = $info[0] / $info[1];
+                                       if ($h * $ratio < $w) {
+                                               $h = round($w / $ratio);
+                                       } else {
+                                               $w = round($h * $ratio);
+                                       }
+                               }
                                $info[0] = $w;
                                $info[1] = $h;
                        }
@@ -1991,13 +2536,13 @@ class t3lib_stdGraphic  {
                $out[1]=$info[1];
                        // Set minimum-measures!
                if ($options['minW'] && $out[0]<$options['minW'])       {
-                       if ($max && $out[0])    {
+                       if (($max || $crs) && $out[0])  {
                                $out[1]= round($out[1]*$options['minW']/$out[0]);
                        }
                        $out[0]=$options['minW'];
                }
                if ($options['minH'] && $out[1]<$options['minH'])       {
-                       if ($max && $out[1])    {
+                       if (($max || $crs) && $out[1])  {
                                $out[0]= round($out[0]*$options['minH']/$out[1]);
                        }
                        $out[1]=$options['minH'];
@@ -2016,11 +2561,15 @@ class t3lib_stdGraphic  {
         */
        function file_exists_typo3temp_file($output,$orig='')   {
                if ($this->enable_typo3temp_db_tracking)        {
-                       if (@file_exists($output))      {       // If file exists, then we return immediately
+                       if (file_exists($output))       {       // If file exists, then we return immediately
                                return 1;
                        } else {        // If not, we look up in the cache_typo3temp_log table to see if there is a image being rendered right now.
                                $md5Hash=md5($output);
-                               $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('md5hash', 'cache_typo3temp_log', 'md5hash="'.$GLOBALS['TYPO3_DB']->quoteStr($md5Hash, 'cache_typo3temp_log').'" AND tstamp>'.(time()-30));
+                               $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
+                                       'md5hash',
+                                       'cache_typo3temp_log',
+                                       'md5hash=' . $GLOBALS['TYPO3_DB']->fullQuoteStr($md5Hash, 'cache_typo3temp_log') . ' AND tstamp>' . ($GLOBALS['EXEC_TIME'] - 30)
+                               );
                                if ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {       // If there was a record, the image is being generated by another proces (we assume)
                                        if (is_object($GLOBALS['TSFE']))        $GLOBALS['TSFE']->set_no_cache();       // ...so we set no_cache, because we dont want this page (which will NOT display an image...!) to be cached! (Only a page with the correct image on...)
                                        if (is_object($GLOBALS['TT']))  $GLOBALS['TT']->setTSlogMessage('typo3temp_log: Assume this file is being rendered now: '.$output);
@@ -2029,11 +2578,11 @@ class t3lib_stdGraphic  {
 
                                        $insertFields = array(
                                                'md5hash' => $md5Hash,
-                                               'tstamp' => time(),
+                                               'tstamp' => $GLOBALS['EXEC_TIME'],
                                                'filename' => $output,
                                                'orig_filename' => $orig
                                        );
-                                       $GLOBALS['TYPO3_DB']->exec_DELETEquery('cache_typo3temp_log', 'md5hash="'.$GLOBALS['TYPO3_DB']->quoteStr($md5Hash, 'cache_typo3temp_log').'"');
+                                       $GLOBALS['TYPO3_DB']->exec_DELETEquery('cache_typo3temp_log', 'md5hash='.$GLOBALS['TYPO3_DB']->fullQuoteStr($md5Hash, 'cache_typo3temp_log'));
                                        $GLOBALS['TYPO3_DB']->exec_INSERTquery('cache_typo3temp_log', $insertFields);
 
                                        if (is_object($GLOBALS['TT']))  $GLOBALS['TT']->setTSlogMessage('typo3temp_log: The row did not exist, so a new is written and file is being processed: '.$output);
@@ -2041,7 +2590,7 @@ class t3lib_stdGraphic    {
                                }
                        }
                } else {
-                       return @file_exists($output);
+                       return file_exists($output);
                }
        }
 
@@ -2072,17 +2621,19 @@ class t3lib_stdGraphic  {
         * Returns an array where [0]/[1] is w/h, [2] is extension and [3] is the filename.
         * Using ImageMagick
         *
-        * @param       string          The absolute image filepath
+        * @param       string          The relative (to PATH_site) image filepath
         * @return      array
         */
        function imageMagickIdentify($imagefile)        {
                if (!$this->NO_IMAGE_MAGICK)    {
-                       $cmd = $this->imageMagickPath.'identify '.$this->wrapFileName($imagefile);
+                       $frame = $this->noFramePrepended?'':'[0]';
+                       $cmd = t3lib_div::imageMagickCommand('identify', $this->wrapFileName($imagefile).$frame);
+                       $returnVal = array();
                        exec($cmd, $returnVal);
                        $splitstring=$returnVal[0];
                        $this->IM_commands[] = Array ('identify',$cmd,$returnVal[0]);
                        if ($splitstring)       {
-                               ereg('([^\.]*)$',$imagefile,$reg);
+                               preg_match('/([^\.]*)$/',$imagefile,$reg);
                                $splitinfo = explode(' ', $splitstring);
                                while (list($key,$val) = each($splitinfo))      {
                                        $temp = '';
@@ -2103,16 +2654,31 @@ class t3lib_stdGraphic  {
         * Executes a ImageMagick "convert" on two filenames, $input and $output using $params before them.
         * Can be used for many things, mostly scaling and effects.
         *
-        * @param       string          The absolute image filepath, input file (read from)
-        * @param       string          The absolute image filepath, output filename (written to)
+        * @param       string          The relative (to PATH_site) image filepath, input file (read from)
+        * @param       string          The relative (to PATH_site) image filepath, output filename (written to)
         * @param       string          ImageMagick parameters
+        * @param       integer         Optional, refers to which frame-number to select in the image. '' or 0
+        *                              will select the first frame, 1 will select the next and so on...
         * @return      string          The result of a call to PHP function "exec()"
         */
-       function imageMagickExec($input,$output,$params)        {
-               if (!$this->NO_IMAGE_MAGICK)    {
-                       $cmd = $this->imageMagickPath.'convert '.$params.' '.$this->wrapFileName($input).' '.$this->wrapFileName($output);
-                       $this->IM_commands[] = Array ($output,$cmd);
-                       return exec($cmd);
+       function imageMagickExec($input, $output, $params, $frame = 0) {
+               if (!$this->NO_IMAGE_MAGICK) {
+
+                               // Unless noFramePrepended is set in the Install Tool, a frame number is added to
+                               // select a specific page of the image (by default this will be the first page)
+                       if (!$this->noFramePrepended) {
+                               $frame = '[' . intval($frame) . ']';
+                       } else {
+                               $frame = '';
+                       }
+
+                       $cmd = t3lib_div::imageMagickCommand('convert', $params . ' ' . $this->wrapFileName($input) . $frame . ' ' . $this->wrapFileName($output));
+                       $this->IM_commands[] = array($output,$cmd);
+
+                       $ret = exec($cmd);
+                       t3lib_div::fixPermissions($output);     // Change the permissions of the file
+
+                       return $ret;
                }
        }
 
@@ -2120,32 +2686,46 @@ class t3lib_stdGraphic  {
         * Executes a ImageMagick "combine" (or composite in newer times) on four filenames - $input, $overlay and $mask as input files and $output as the output filename (written to)
         * Can be used for many things, mostly scaling and effects.
         *
-        * @param       string          The absolute image filepath, bottom file
-        * @param       string          The absolute image filepath, overlay file (top)
-        * @param       string          The absolute image filepath, the mask file (grayscale)
-        * @param       string          The absolute image filepath, output filename (written to)
+        * @param       string          The relative (to PATH_site) image filepath, bottom file
+        * @param       string          The relative (to PATH_site) image filepath, overlay file (top)
+        * @param       string          The relative (to PATH_site) image filepath, the mask file (grayscale)
+        * @param       string          The relative (to PATH_site) image filepath, output filename (written to)
+        * @param       [type]          $handleNegation: ...
         * @return      void
         */
-       function combineExec($input,$overlay,$mask,$output    {
+       function combineExec($input,$overlay,$mask,$output, $handleNegation = false)    {
                if (!$this->NO_IMAGE_MAGICK)    {
-                       $cmd = $this->imageMagickPath.$this->combineScript.' -compose over '.$this->wrapFileName($input).' '.$this->wrapFileName($overlay).' '.$this->wrapFileName($mask).' '.$this->wrapFileName($output);
+                       $params = '-colorspace GRAY +matte';
+                       if ($handleNegation)    {
+                               if ($this->maskNegate)  {
+                                       $params .= ' '.$this->maskNegate;
+                               }
+                       }
+                       $theMask = $this->randomName().'.'.$this->gifExtension;
+                       $this->imageMagickExec($mask, $theMask, $params);
+                       $cmd = t3lib_div::imageMagickCommand('combine', '-compose over +matte '.$this->wrapFileName($input).' '.$this->wrapFileName($overlay).' '.$this->wrapFileName($theMask).' '.$this->wrapFileName($output));              // +matte = no alpha layer in output
                        $this->IM_commands[] = Array ($output,$cmd);
-                       exec($cmd);
+
+                       $ret = exec($cmd);
+                       t3lib_div::fixPermissions($output);     // Change the permissions of the file
+
+                       if (is_file($theMask))  {
+                               @unlink($theMask);
+                       }
+
+                       return $ret;
                }
        }
 
        /**
-        * Wrapping the input filename in double-quotes
+        * Escapes a file name so it can safely be used on the command line.
         *
-        * @param       string          Input filename
-        * @return      string          The output wrapped in "" (if there are spaces in the filepath)
-        * @access private
+        * @param string $inputName filename to safeguard, must not be empty
+        *
+        * @return string $inputName escaped as needed
         */
-       function wrapFileName($inputName)       {
-               if (strstr($inputName,' '))     {
-                       $inputName='"'.$inputName.'"';
-               }
-               return $inputName;
+       protected function wrapFileName($inputName) {
+               return escapeshellarg($inputName);
        }
 
 
@@ -2191,6 +2771,27 @@ class t3lib_stdGraphic   {
        }
 
        /**
+        * Creates subdirectory in typo3temp/ if not already found.
+        *
+        * @param       string          Name of sub directory
+        * @return      boolean         Result of t3lib_div::mkdir(), true if it went well.
+        */
+       function createTempSubDir($dirName)     {
+
+                       // Checking if the this->tempPath is already prefixed with PATH_site and if not, prefix it with that constant.
+               if (t3lib_div::isFirstPartOfStr($this->tempPath,PATH_site))     {
+                       $tmpPath = $this->tempPath;
+               } else {
+                       $tmpPath = PATH_site.$this->tempPath;
+               }
+
+                       // Making the temporary filename:
+               if (!@is_dir($tmpPath.$dirName))         {
+                       return t3lib_div::mkdir($tmpPath.$dirName);
+               }
+       }
+
+       /**
         * Applies an ImageMagick parameter to a GDlib image pointer resource by writing the resource to file, performing an IM operation upon it and reading back the result into the ImagePointer.
         *
         * @param       pointer         The image pointer (reference)
@@ -2200,9 +2801,9 @@ class t3lib_stdGraphic    {
        function applyImageMagickToPHPGif(&$im, $command)       {
                $tmpStr = $this->randomName();
                $theFile = $tmpStr.'.'.$this->gifExtension;
-               $this->ImageGif($im, $theFile);
+               $this->ImageWrite($im, $theFile);
                $this->imageMagickExec($theFile,$theFile,$command);
-               $tmpImg = $this->imageCreateFromGif($theFile);
+               $tmpImg = $this->imageCreateFromFile($theFile);
                if ($tmpImg)    {
                        ImageDestroy($im);
                        $im = $tmpImg;
@@ -2242,35 +2843,31 @@ class t3lib_stdGraphic  {
         */
        function output($file)  {
                if ($file)      {
-                       ereg('([^\.]*)$',$file,$reg);
+                       $reg = array();
+                       preg_match('/([^\.]*)$/',$file,$reg);
                        $ext=strtolower($reg[0]);
                        switch($ext)    {
-                               case $this->gifExtension:
-                                       if ($this->ImageGif($this->im, $file))  {
-                                               // ImageMagick operations
-                                               if($this->setup['reduceColors'])        {
-                                                       $this->imageMagickExec($file,$file,' -colors '.t3lib_div::intInRange($this->setup['reduceColors'],2,255));
-                                                       t3lib_div::gif_compress($file,'');      // Compress with IM (lzw) or GD (rle)      (Workaround for the absence of lzw-compression in GD)
-                                               } else {
-                                                       t3lib_div::gif_compress($file, 'IM');           // Compress with IM! (adds extra compression, LZW from ImageMagick)     (Workaround for the absence of lzw-compression in GD)
+                               case 'gif':
+                               case 'png':
+                                       if ($this->ImageWrite($this->im, $file))        {
+                                                       // ImageMagick operations
+                                               if ($this->setup['reduceColors'] || (!$this->png_truecolor && $this->truecolor))        {
+                                                       $reduced = $this->IMreduceColors($file, t3lib_div::intInRange($this->setup['reduceColors'], 256, $this->truecolorColors, 256));
+                                                       if ($reduced)   {
+                                                               @copy($reduced, $file);
+                                                               @unlink($reduced);
+                                                       }
                                                }
+                                               t3lib_div::gif_compress($file, 'IM');           // Compress with IM! (adds extra compression, LZW from ImageMagick)     (Workaround for the absence of lzw-compression in GD)
                                        }
                                break;
                                case 'jpg':
                                case 'jpeg':
-                                       $tmpStr = $this->randomName();
-                                       $theFile = $tmpStr.'.'.$this->gifExtension;
-                                       if ($this->ImageGif($this->im, $theFile))       {
-                                               // ImageMagick operations
-                                               $operations='';
-                                               if($this->setup['quality'])     {
-                                                       $operations.=' -quality '.t3lib_div::intInRange($this->setup['quality'],10,100);
-                                               }
-                                               $this->imageMagickExec($theFile,$file,$operations);
-                                               if (!$this->dontUnlinkTempFiles)        {
-                                                       unlink($theFile);
-                                               }
+                                       $quality = 0;   // Use the default
+                                       if($this->setup['quality'])     {
+                                               $quality = t3lib_div::intInRange($this->setup['quality'],10,100);
                                        }
+                                       if ($this->ImageWrite($this->im, $file, $quality));
                                break;
                        }
                        $GLOBALS['TEMP_IMAGES_ON_PAGE'][]=$file;
@@ -2303,17 +2900,73 @@ class t3lib_stdGraphic  {
         *
         * @param       pointer         The GDlib image resource pointer
         * @param       string          The filename to write to
-        * @return      mixed           The output of either imageGif or imagePng based on whether the $this->gifExtension was set to "gif" or "png"
+        * @param       integer         The image quality (for JPEGs)
+        * @return      boolean         The output of either imageGif, imagePng or imageJpeg based on the filename to write
         * @see maskImageOntoImage(), scale(), output()
         */
-       function ImageGif($destImg, $theImage)  {
+       function ImageWrite($destImg, $theImage, $quality=0)    {
                imageinterlace ($destImg,0);
-               if ($this->gifExtension=='gif') {
-                       return ImageGif($destImg, $theImage);
+               $ext = strtolower(substr($theImage, strrpos($theImage, '.')+1));
+               $result = FALSE;
+               switch ($ext)   {
+                       case 'jpg':
+                       case 'jpeg':
+                               if (function_exists('imageJpeg'))       {
+                                       if ($quality == 0)      {
+                                               $quality = $this->jpegQuality;
+                                       }
+                                       $result = imageJpeg($destImg, $theImage, $quality);
+                               }
+                       break;
+                       case 'gif':
+                               if (function_exists('imageGif'))        {
+                                       if ($this->truecolor)   {
+                                               imagetruecolortopalette($destImg, true, 256);
+                                       }
+                                       $result = imageGif($destImg, $theImage);
+                               }
+                       break;
+                       case 'png':
+                               if (function_exists('imagePng'))        {
+                                       $result = ImagePng($destImg, $theImage);
+                               }
+                       break;
                }
-               if ($this->gifExtension=='png') {
-                       return ImagePng($destImg, $theImage);
+               if ($result) {
+                       t3lib_div::fixPermissions($theImage);
                }
+               return $result;
+       }
+
+
+
+       /**
+        * Writes the input GDlib image pointer to file. Now just a wrapper to ImageWrite.
+        *
+        * @param       pointer         The GDlib image resource pointer
+        * @param       string          The filename to write to
+        * @return      mixed           The output of either imageGif, imagePng or imageJpeg based on the filename to write
+        * @see imageWrite()
+        * @deprecated since TYPO3 4.0, this function will be removed in TYPO3 4.5.
+        */
+       function imageGif($destImg, $theImage)  {
+               t3lib_div::logDeprecatedFunction();
+
+               return $this->imageWrite($destImg, $theImage);
+       }
+
+       /**
+        * This function has been renamed and only exists for providing backwards compatibility.
+        * Please use $this->imageCreateFromFile() instead.
+        *
+        * @param       string          Image filename
+        * @return      pointer         Image Resource pointer
+        * @deprecated since TYPO3 4.0, this function will be removed in TYPO3 4.5.
+        */
+       function imageCreateFromGif($sourceImg) {
+               t3lib_div::logDeprecatedFunction();
+
+               return $this->imageCreateFromFile($sourceImg);
        }
 
        /**
@@ -2323,33 +2976,128 @@ class t3lib_stdGraphic {
         * @param       string          Image filename
         * @return      pointer         Image Resource pointer
         */
-       function imageCreateFromGif($sourceImg) {
+       function imageCreateFromFile($sourceImg)        {
                $imgInf = pathinfo($sourceImg);
                $ext = strtolower($imgInf['extension']);
 
-//             if ($ext=='gif' && (ImageTypes() & IMG_GIF))    {
-               if ($ext=='gif' && function_exists('imagecreatefromgif'))       {
-                       return imageCreateFromGif($sourceImg);
-               }
-//             if ($ext=='png' && (ImageTypes() & IMG_PNG))    {
-               if ($ext=='png' && function_exists('imagecreatefrompng'))       {
-                       return imageCreateFromPng($sourceImg);
-               }
-//             if (($ext=='jpg' || $ext=='jpeg') && (ImageTypes() & IMG_JPG))  {
-               if (($ext=='jpg' || $ext=='jpeg') && function_exists('imagecreatefromjpeg'))    {
-                       return imageCreateFromJpeg($sourceImg);
+               switch ($ext)   {
+                       case 'gif':
+                               if (function_exists('imagecreatefromgif'))      {
+                                       return imageCreateFromGif($sourceImg);
+                               }
+                       break;
+                       case 'png':
+                               if (function_exists('imagecreatefrompng'))      {
+                                       return imageCreateFromPng($sourceImg);
+                               }
+                       break;
+                       case 'jpg':
+                       case 'jpeg':
+                               if (function_exists('imagecreatefromjpeg'))     {
+                                       return imageCreateFromJpeg($sourceImg);
+                               }
+                       break;
                }
 
                // If non of the above:
                $i = @getimagesize($sourceImg);
-               $im = imagecreate($i[0],$i[1]);
-               ImageColorAllocate($im, 128,128,128);
+               $im = $this->imagecreate($i[0],$i[1]);
+               $Bcolor = ImageColorAllocate($im, 128,128,128);
+               ImageFilledRectangle($im, 0, 0, $i[0], $i[1], $Bcolor);
                return $im;
        }
-}
 
 
+       /**
+        * Creates a new GD image resource. Wrapper for imagecreate(truecolor) depended if GD2 is used.
+        *
+        * @param       integer         Width of image
+        * @param       integer         Height of image
+        * @return      pointer         Image Resource pointer
+        */
+       function imagecreate($w, $h)    {
+               if($this->truecolor && function_exists('imagecreatetruecolor')) {
+                       return imagecreatetruecolor($w, $h);
+               } else  {
+                       return imagecreate($w, $h);
+               }
+
+       }
+
+       /**
+        * Returns the HEX color value for an RGB color array
+        *
+        * @param       array           RGB color array
+        * @return      string          HEX color value
+        */
+       function hexColor($col) {
+               $r = dechex($col[0]);
+               if (strlen($r)<2)       { $r = '0'.$r; }
+               $g = dechex($col[1]);
+               if (strlen($g)<2)       { $g = '0'.$g; }
+               $b = dechex($col[2]);
+               if (strlen($b)<2)       { $b = '0'.$b; }
+               return '#'.$r.$g.$b;
+       }
+
+       /**
+        * Unifies all colors given in the colArr color array to the first color in the array.
+        *
+        * @param       pointer         Image resource
+        * @param       array           Array containing RGB color arrays
+        * @param       [type]          $closest: ...
+        * @return      integer         The index of the unified color
+        */
+       function unifyColors(&$img, $colArr, $closest = false)  {
+               $retCol = -1;
+               if (is_array($colArr) && count($colArr) && function_exists('imagepng') && function_exists('imagecreatefrompng'))        {
+                       $firstCol = array_shift($colArr);
+                       $firstColArr = $this->convertColor($firstCol);
+                       if (count($colArr)>1)   {
+                               $origName = $preName = $this->randomName().'.png';
+                               $postName = $this->randomName().'.png';
+                               $this->imageWrite($img, $preName);
+                               $firstCol = $this->hexColor($firstColArr);
+                               foreach ($colArr as $transparentColor)  {
+                                       $transparentColor = $this->convertColor($transparentColor);
+                                       $transparentColor = $this->hexColor($transparentColor);
+                                       $cmd = '-fill "'.$firstCol.'" -opaque "'.$transparentColor.'"';
+                                       $this->imageMagickExec($preName, $postName, $cmd);
+                                       $preName = $postName;
+                               }
+                               $this->imageMagickExec($postName, $origName, '');
+                               if (@is_file($origName))        {
+                                       $tmpImg = $this->imageCreateFromFile($origName);
+                               }
+                       } else  {
+                               $tmpImg = $img;
+                       }
+                       if ($tmpImg)    {
+                               $img = $tmpImg;
+                               if ($closest)   {
+                                       $retCol = ImageColorClosest ($img, $firstColArr[0], $firstColArr[1], $firstColArr[2]);
+                               } else  {
+                                       $retCol = ImageColorExact ($img, $firstColArr[0], $firstColArr[1], $firstColArr[2]);
+                               }
+                       }
+                               // unlink files from process
+                       if (!$this->dontUnlinkTempFiles)        {
+                               if ($origName)  {
+                                       @unlink($origName);
+                               }
+                               if ($postName)  {
+                                       @unlink($postName);
+                               }
+                       }
+               }
+               return $retCol;
+       }
+
+
+}
+
 if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_stdgraphic.php'])       {
        include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_stdgraphic.php']);
 }
+
 ?>
\ No newline at end of file