00001 <?php
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00147 class t3lib_stdGraphic {
00148
00149
00150 var $combineScript = 'combine';
00151 var $noFramePrepended=0;
00152 var $GD2=0;
00153 var $imagecopyresized_fix=0;
00154 var $gifExtension = 'gif';
00155 var $TTFLocaleConv = '';
00156 var $enable_typo3temp_db_tracking = 0;
00157 var $imageMagickPath = '';
00158 var $imageFileExt = 'gif,jpg,jpeg,png,tif,bmp,tga,pcx,ai,pdf';
00159 var $webImageExt = 'gif,jpg,jpeg,png';
00160 var $maskNegate = '';
00161 var $NO_IM_EFFECTS = '';
00162 var $cmds = Array (
00163 'jpg' => '',
00164 'jpeg' => '',
00165 'gif' => '-colors 64',
00166 'png' => '-colors 64'
00167 );
00168 var $NO_IMAGE_MAGICK = '';
00169 var $V5_EFFECTS = 0;
00170 var $mayScaleUp = 1;
00171
00172
00173 var $filenamePrefix='';
00174 var $imageMagickConvert_forceFileNameBody='';
00175 var $dontCheckForExistingTempFile = 0;
00176 var $dontCompress=0;
00177 var $dontUnlinkTempFiles=0;
00178 var $alternativeOutputKey='';
00179
00180
00181 var $IM_commands = Array();
00182 var $workArea = Array();
00183
00184
00185 var $tempPath = 'typo3temp/';
00186 var $absPrefix = '';
00187 var $scalecmd = '-geometry';
00188 var $im5fx_blurSteps='1x2,2x2,3x2,4x3,5x3,5x4,6x4,7x5,8x5,9x5';
00189 var $im5fx_sharpenSteps='1x2,2x2,3x2,2x3,3x3,4x3,3x4,4x4,4x5,5x5';
00190 var $pixelLimitGif = 10000;
00191 var $colMap = Array (
00192 'aqua' => Array(0,255,255),
00193 'black' => Array(0,0,0),
00194 'blue' => Array(0,0,255),
00195 'fuchsia' => Array(255,0,255),
00196 'gray' => Array(128,128,128),
00197 'green' => Array(0,128,0),
00198 'lime' => Array(0,255,0),
00199 'maroon' => Array(128,0,0),
00200 'navy' => Array(0,0,128),
00201 'olive' => Array(128,128,0),
00202 'purple' => Array(128,0,128),
00203 'red' => Array(255,0,0),
00204 'silver' => Array(192,192,192),
00205 'teal' => Array(0,128,128),
00206 'yellow' => Array(255,255,0),
00207 'white' => Array(255,255,255)
00208 );
00209
00210
00211 var $csConvObj;
00212 var $nativeCharset='';
00213
00214
00215
00216
00217
00224 function init() {
00225 $gfxConf = $GLOBALS['TYPO3_CONF_VARS']['GFX'];
00226
00227
00228 $this->cmds['jpg'] = $this->cmds['jpeg'] = '-colorspace RGB -sharpen 50 -quality '.intval($gfxConf['im_jpg_quality']);
00229
00230 if ($gfxConf['im_combine_filename']) $this->combineScript=$gfxConf['im_combine_filename'];
00231 if ($gfxConf['im_noFramePrepended']) $this->noFramePrepended=1;
00232
00233 if ($gfxConf['gdlib_2']) {
00234 $this->GD2 = 1;
00235 $this->imagecopyresized_fix = $gfxConf['gdlib_2']==='no_imagecopyresized_fix' ? 0 : 1;
00236 }
00237 if ($gfxConf['gdlib_png']) {
00238 $this->gifExtension='png';
00239 }
00240 if ($gfxConf['TTFLocaleConv']) {
00241 $this->TTFLocaleConv = $gfxConf['TTFLocaleConv'];
00242 }
00243 if ($gfxConf['enable_typo3temp_db_tracking']) {
00244 $this->enable_typo3temp_db_tracking = $gfxConf['enable_typo3temp_db_tracking'];
00245 }
00246
00247 $this->imageMagickPath = $gfxConf['im_path'];
00248 $this->imageFileExt = $gfxConf['imagefile_ext'];
00249
00250
00251 if ($gfxConf['im_negate_mask']) {
00252
00253
00254
00255
00256 $this->maskNegate = ' -negate';
00257 }
00258 if ($gfxConf['im_no_effects']) {
00259
00260
00261
00262
00263 $this->NO_IM_EFFECTS = 1;
00264
00265 $this->cmds['jpg'] = $this->cmds['jpeg'] = '-colorspace RGB -quality '.intval($gfxConf['im_jpg_quality']);
00266 }
00267
00268 if ($gfxConf['im_v5effects']) {
00269 $this->NO_IM_EFFECTS = 0;
00270 $this->V5_EFFECTS = 1;
00271
00272 if ($gfxConf['im_v5effects']>0) {
00273 $this->cmds['jpg'] = $this->cmds['jpeg'] = '-colorspace RGB -quality '.intval($gfxConf['im_jpg_quality']).$this->v5_sharpen(10);
00274 }
00275 }
00276
00277 if (!$gfxConf['im']) {
00278 $this->NO_IMAGE_MAGICK = 1;
00279 }
00280
00281 if ($gfxConf['im_noScaleUp']) {
00282 $this->mayScaleUp=0;
00283 }
00284
00285 if (TYPO3_MODE=='FE') {
00286 $this->csConvObj = &$GLOBALS['TSFE']->csConvObj;
00287 } else {
00288 $this->csConvObj = &$GLOBALS['LANG']->csConvObj;
00289 }
00290 $this->nativeCharset = $GLOBALS['TYPO3_CONF_VARS']['BE']['forceCharset'];
00291 }
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00325 function maskImageOntoImage(&$im,$conf,$workArea) {
00326 if ($conf['file'] && $conf['mask']) {
00327 $BBimage = $this->imageMagickConvert($conf['file'],$this->gifExtension,'','','','','');
00328 $BBmask = $this->imageMagickConvert($conf['mask'],$this->gifExtension,'','','','','');
00329 if ($BBimage && $BBmask) {
00330 $w = imagesx($im);
00331 $h = imagesy($im);
00332 $tmpStr = $this->randomName();
00333 $theImage = $tmpStr.'_img.'.$this->gifExtension;
00334 $theDest = $tmpStr.'_dest.'.$this->gifExtension;
00335 $theMask = $tmpStr.'_mask.'.$this->gifExtension;
00336 $theMask2 = $tmpStr.'_mask2.'.trim($GLOBALS['TYPO3_CONF_VARS']['GFX']['im_mask_temp_ext_noloss']);
00337
00338 $cpImg = $this->imageCreateFromGif($BBimage[3]);
00339 $destImg = imagecreate($w,$h);
00340 ImageColorAllocate($destImg, 0,0,0);
00341 $this->copyGifOntoGif($destImg,$cpImg,$conf,$workArea);
00342 $this->ImageGif($destImg, $theImage);
00343 imageDestroy($cpImg);
00344 imageDestroy($destImg);
00345
00346 $cpImg = $this->imageCreateFromGif($BBmask[3]);
00347 $destImg = imagecreate($w,$h);
00348 ImageColorAllocate($destImg, 0,0,0);
00349 $this->copyGifOntoGif($destImg,$cpImg,$conf,$workArea);
00350 $this->ImageGif($destImg, $theMask);
00351 imageDestroy($cpImg);
00352 imageDestroy($destImg);
00353
00354 $this->imageMagickExec($theMask,$theMask2,'-colorspace GRAY'.$this->maskNegate);
00355
00356 $this->ImageGif($im, $theDest);
00357
00358 $this->combineExec($theDest,$theImage,$theMask2,$theDest);
00359
00360 $backIm = $this->imageCreateFromGif($theDest);
00361 if ($backIm) {
00362 ImageColorTransparent($backIm,-1);
00363 $im = $backIm;
00364 }
00365
00366 if (!$this->dontUnlinkTempFiles) {
00367 unlink($theDest);
00368 unlink($theImage);
00369 unlink($theMask);
00370 unlink($theMask2);
00371 }
00372 }
00373 }
00374 }
00375
00385 function copyImageOntoImage(&$im,$conf,$workArea) {
00386 if ($conf['file']) {
00387 if ($conf['BBOX'][2]!=$this->gifExtension) {
00388 $conf['BBOX']=$this->imageMagickConvert($conf['BBOX'][3],$this->gifExtension,'','','','','');
00389 $conf['file']=$conf['BBOX'][3];
00390 }
00391 $cpImg = $this->imageCreateFromGif($conf['file']);
00392 $this->copyGifOntoGif($im,$cpImg,$conf,$workArea);
00393 imageDestroy($cpImg);
00394 }
00395 }
00396
00407 function copyGifOntoGif(&$im,$cpImg,$conf,$workArea) {
00408 $cpW = imagesx($cpImg);
00409 $cpH = imagesy($cpImg);
00410 $tile = t3lib_div::intExplode(',',$conf['tile']);
00411 $tile[0] = t3lib_div::intInRange($tile[0],1,20);
00412 $tile[1] = t3lib_div::intInRange($tile[1],1,20);
00413 $cpOff = $this->objPosition($conf,$workArea,Array($cpW*$tile[0],$cpH*$tile[1]));
00414
00415 for ($xt=0;$xt<$tile[0];$xt++) {
00416 $Xstart=$cpOff[0]+$cpW*$xt;
00417 if ($Xstart+$cpW > $workArea[0]) {
00418
00419 if ($Xstart < $workArea[0]) {
00420 $cpImgCutX = $workArea[0]-$Xstart;
00421 $Xstart = $workArea[0];
00422 } else {
00423 $cpImgCutX = 0;
00424 }
00425 $w = $cpW-$cpImgCutX;
00426 if ($Xstart > $workArea[0]+$workArea[2]-$w) {
00427 $w = $workArea[0]+$workArea[2]-$Xstart;
00428 }
00429 if ($Xstart < $workArea[0]+$workArea[2]) {
00430
00431 for ($yt=0;$yt<$tile[1];$yt++) {
00432 $Ystart=$cpOff[1]+$cpH*$yt;
00433 if ($Ystart+$cpH > $workArea[1]) {
00434 if ($Ystart < $workArea[1]) {
00435 $cpImgCutY = $workArea[1]-$Ystart;
00436 $Ystart = $workArea[1];
00437 } else {
00438 $cpImgCutY = 0;
00439 }
00440 $h = $cpH-$cpImgCutY;
00441 if ($Ystart > $workArea[1]+$workArea[3]-$h) {
00442 $h = $workArea[1]+$workArea[3]-$Ystart;
00443 }
00444 if ($Ystart < $workArea[1]+$workArea[3]) {
00445 $this->imagecopyresized($im, $cpImg, $Xstart, $Ystart, $cpImgCutX, $cpImgCutY, $w, $h, $w, $h);
00446 }
00447 }
00448 }
00449 }
00450 }
00451 }
00452 }
00453
00486 function imagecopyresized(&$im, $cpImg, $Xstart, $Ystart, $cpImgCutX, $cpImgCutY, $w, $h, $w, $h) {
00487 if ($this->imagecopyresized_fix) {
00488 $im_base = imagecreatetruecolor(imagesx($im), imagesy($im));
00489 imagecopyresized($im_base, $im, 0,0,0,0, imagesx($im),imagesy($im),imagesx($im),imagesy($im));
00490 imagecopyresized($im_base, $cpImg, $Xstart, $Ystart, $cpImgCutX, $cpImgCutY, $w, $h, $w, $h);
00491 $im = $im_base;
00492 $this->makeEffect($im, Array('value'=>'colors=256'));
00493 } else {
00494 imagecopyresized($im, $cpImg, $Xstart, $Ystart, $cpImgCutX, $cpImgCutY, $w, $h, $w, $h);
00495 }
00496 }
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525
00535 function makeText(&$im,$conf,$workArea) {
00536
00537 $spacing = intval($conf['spacing']);
00538 $wordSpacing = intval($conf['wordSpacing']);
00539 $wordSpacing = $wordSpacing?$wordSpacing:$spacing*2;
00540
00541 $txtPos = $this->txtPosition($conf,$workArea,$conf['BBOX']);
00542 $theText = $this->recodeString($conf['text']);
00543
00544 if ($conf['imgMap'] && is_array($conf['imgMap.'])) {
00545 $this->addToMap($this->calcTextCordsForMap($conf['BBOX'][2],$txtPos, $conf['imgMap.']), $conf['imgMap.']);
00546 }
00547 if (!$conf['hideButCreateMap']) {
00548
00549 $cols=$this->convertColor($conf['fontColor']);
00550
00551 if (!$conf['niceText']) {
00552
00553 $this->reduceColors($im,256, 200);
00554 $Fcolor = ImageColorAllocate($im, $cols[0],$cols[1],$cols[2]);
00555
00556 $Fcolor = ($conf['antiAlias']) ? $Fcolor : -$Fcolor;
00557
00558 for ($a=0; $a<$conf['iterations']; $a++) {
00559 if ($spacing || $wordSpacing) {
00560 $this->SpacedImageTTFText($im, $conf['fontSize'], $conf['angle'], $txtPos[0], $txtPos[1], $Fcolor, t3lib_stdGraphic::prependAbsolutePath($conf['fontFile']), $theText, $spacing, $wordSpacing, $conf['splitRendering.']);
00561 } else {
00562 $this->ImageTTFTextWrapper($im, $conf['fontSize'], $conf['angle'], $txtPos[0], $txtPos[1], $Fcolor, $conf['fontFile'], $theText, $conf['splitRendering.']);
00563 }
00564 }
00565 } else {
00566
00567 $w = imagesx($im);
00568 $h = imagesy($im);
00569 $tmpStr = $this->randomName();
00570
00571 $fileMenu = $tmpStr.'_menuNT.'.$this->gifExtension;
00572 $fileColor = $tmpStr.'_colorNT.'.$this->gifExtension;
00573 $fileMask = $tmpStr.'_maskNT.'.$this->gifExtension;
00574
00575 $sF = t3lib_div::intInRange($conf['niceText.']['scaleFactor'],2,5);
00576 $newW = ceil($sF*imagesx($im));
00577 $newH = ceil($sF*imagesy($im));
00578
00579
00580 $maskImg = imagecreate($newW, $newH);
00581 ImageColorAllocate($maskImg, 255,255,255);
00582 $Fcolor = ImageColorAllocate($maskImg, 0,0,0);
00583 if ($spacing || $wordSpacing) {
00584 $this->SpacedImageTTFText($maskImg, $conf['fontSize'], $conf['angle'], $txtPos[0], $txtPos[1], $Fcolor, t3lib_stdGraphic::prependAbsolutePath($conf['fontFile']), $theText, $spacing, $wordSpacing, $conf['splitRendering.'],$sF);
00585 } else {
00586 $this->ImageTTFTextWrapper($maskImg, $conf['fontSize'], $conf['angle'], $txtPos[0], $txtPos[1], $Fcolor, $conf['fontFile'], $theText, $conf['splitRendering.'],$sF);
00587 }
00588 $this->ImageGif($maskImg, $fileMask);
00589 ImageDestroy($maskImg);
00590
00591
00592 if ($this->NO_IM_EFFECTS) {
00593 if ($this->maskNegate) {
00594 $command = trim($this->scalecmd.' '.$w.'x'.$h.'!');
00595 } else {
00596 $command = trim($this->scalecmd.' '.$w.'x'.$h.'! -negate');
00597 }
00598 } else {
00599 if ($this->maskNegate) {
00600 $command = trim($conf['niceText.']['before'].' '.$this->scalecmd.' '.$w.'x'.$h.'! '.$conf['niceText.']['after']);
00601 } else {
00602 $command = trim($conf['niceText.']['before'].' '.$this->scalecmd.' '.$w.'x'.$h.'! '.$conf['niceText.']['after'].' -negate');
00603 }
00604 if ($conf['niceText.']['sharpen']) {
00605 if ($this->V5_EFFECTS) {
00606 $command.=$this->v5_sharpen($conf['niceText.']['sharpen']);
00607 } else {
00608 $command.=' -sharpen '.t3lib_div::intInRange($conf['niceText.']['sharpen'],1,99);
00609 }
00610 }
00611 }
00612 $this->imageMagickExec($fileMask,$fileMask,$command);
00613
00614
00615 $colorImg = imagecreate($w,$h);
00616 ImageColorAllocate($colorImg, $cols[0],$cols[1],$cols[2]);
00617 $this->ImageGif($colorImg, $fileColor);
00618 ImageDestroy($colorImg);
00619
00620
00621 $this->ImageGif($im, $fileMenu);
00622
00623 $this->combineExec($fileMenu,$fileColor,$fileMask,$fileMenu);
00624
00625 $backIm = $this->imageCreateFromGif($fileMenu);
00626 if ($backIm) {
00627 ImageColorTransparent($backIm,-1);
00628 $im = $backIm;
00629 }
00630
00631
00632 if (!$this->dontUnlinkTempFiles) {
00633 unlink($fileMenu);
00634 unlink($fileColor);
00635 unlink($fileMask);
00636 }
00637 }
00638 }
00639 }
00640
00651 function txtPosition($conf,$workArea,$BB) {
00652 $bbox = $BB[2];
00653 $angle=intval($conf['angle'])/180*pi();
00654 $conf['angle']=0;
00655 $straightBB = $this->calcBBox($conf);
00656
00657
00658 $result=Array();
00659 $result[2] = $BB[0];
00660 $result[3] = $BB[1];
00661 $w=$workArea[2];
00662 $h=$workArea[3];
00663
00664 switch($conf['align']) {
00665 case 'right':
00666 case 'center':
00667 $factor=abs(cos($angle));
00668 $sign=(cos($angle)<0)?-1:1;
00669 $len1 = $sign*$factor*$straightBB[0];
00670 $len2= $sign*$BB[0];
00671 $result[0] = $w-ceil($len2*$factor+(1-$factor)*$len1);
00672
00673 $factor=abs(sin($angle));
00674 $sign=(sin($angle)<0)?-1:1;
00675 $len1= $sign*$factor*$straightBB[0];
00676 $len2= $sign*$BB[1];
00677 $result[1]=ceil($len2*$factor+(1-$factor)*$len1);
00678 break;
00679 }
00680 switch($conf['align']) {
00681 case 'right':
00682 break;
00683 case 'center':
00684 $result[0] = round(($result[0])/2);
00685 $result[1] = round(($result[1])/2);
00686 break;
00687 default:
00688 $result[0]=0;
00689 $result[1]=0;
00690 break;
00691 }
00692 $result = $this->applyOffset($result,t3lib_div::intExplode(',',$conf['offset']));
00693 $result = $this->applyOffset($result,$workArea);
00694 return $result;
00695 }
00696
00705 function calcBBox($conf) {
00706 if (!$conf['niceText']) {
00707 $sF = 1;
00708 } else {
00709 $sF = t3lib_div::intInRange($conf['niceText.']['scaleFactor'],2,5);
00710 }
00711
00712 $spacing = intval($conf['spacing']);
00713 $wordSpacing = intval($conf['wordSpacing']);
00714 $wordSpacing = $wordSpacing?$wordSpacing:$spacing*2;
00715
00716 $spacing*=$sF;
00717 $wordSpacing*=$sF;
00718 $theText = $this->recodeString($conf['text']);
00719
00720 $charInf = $this->ImageTTFBBoxWrapper($conf['fontSize'], $conf['angle'], $conf['fontFile'], $theText, $conf['splitRendering.'],$sF);
00721 $theBBoxInfo = $charInf;
00722 if ($conf['angle']) {
00723 $xArr = Array($charInf[0],$charInf[2],$charInf[4],$charInf[6]);
00724 $yArr = Array($charInf[1],$charInf[3],$charInf[5],$charInf[7]);
00725 $x=max($xArr)-min($xArr);
00726 $y=max($yArr)-min($yArr);
00727 } else {
00728 $x = ($charInf[2]-$charInf[0]);
00729 $y = ($charInf[1]-$charInf[7]);
00730 }
00731 if ($spacing || $wordSpacing) {
00732 $x=0;
00733 if (!$spacing && $wordSpacing) {
00734 $bits = explode(' ',$theText);
00735 while(list(,$word)=each($bits)) {
00736 $word.=' ';
00737 $wordInf = $this->ImageTTFBBoxWrapper($conf['fontSize'], $conf['angle'], $conf['fontFile'], $word, $conf['splitRendering.'],$sF);
00738 $wordW = ($wordInf[2]-$wordInf[0]);
00739 $x+=$wordW+$wordSpacing;
00740 }
00741 } else {
00742 $utf8Chars = $this->singleChars($theText);
00743
00744 foreach($utf8Chars as $char) {
00745 $charInf = $this->ImageTTFBBoxWrapper($conf['fontSize'], $conf['angle'], $conf['fontFile'], $char, $conf['splitRendering.'],$sF);
00746 $charW = ($charInf[2]-$charInf[0]);
00747 $x+=$charW+(($char==' ')?$wordSpacing:$spacing);
00748 }
00749 }
00750 }
00751
00752 if ($sF>1) {
00753 $x = ceil($x/$sF);
00754 $y = ceil($y/$sF);
00755 if (is_array($theBBoxInfo)) {
00756 reset($theBBoxInfo);
00757 while(list($key,$val)=each($theBBoxInfo)) {
00758 $theBBoxInfo[$key]=ceil($theBBoxInfo[$key]/$sF);
00759 }
00760 }
00761 }
00762 return Array($x,$y,$theBBoxInfo);
00763 }
00764
00774 function addToMap($cords,$conf) {
00775 $JS = $conf['noBlur'] ? '' : ' onfocus="blurLink(this);"';
00776
00777 $this->map.='<area'.
00778 ' shape="poly"'.
00779 ' coords="'.implode(',',$cords).'"'.
00780 ' href="'.htmlspecialchars($conf['url']).'"'.
00781 ($conf['target'] ? ' target="'.htmlspecialchars($conf['target']).'"' : '').
00782 $JS.
00783 (strlen($conf['titleText']) ? ' title="'.htmlspecialchars($conf['titleText']).'"' : '').
00784 ' alt="'.htmlspecialchars($conf['altText']).'" />';
00785 }
00786
00797 function calcTextCordsForMap($cords,$offset, $conf) {
00798 $pars = t3lib_div::intExplode(',',$conf['explode'].',');
00799
00800 $newCords[0] = $cords[0]+$offset[0]-$pars[0];
00801 $newCords[1] = $cords[1]+$offset[1]+$pars[1];
00802 $newCords[2] = $cords[2]+$offset[0]+$pars[0];
00803 $newCords[3] = $cords[3]+$offset[1]+$pars[1];
00804 $newCords[4] = $cords[4]+$offset[0]+$pars[0];
00805 $newCords[5] = $cords[5]+$offset[1]-$pars[1];
00806 $newCords[6] = $cords[6]+$offset[0]-$pars[0];
00807 $newCords[7] = $cords[7]+$offset[1]-$pars[1];
00808
00809 return $newCords;
00810 }
00811
00832 function SpacedImageTTFText(&$im, $fontSize, $angle, $x, $y, $Fcolor, $fontFile, $text, $spacing, $wordSpacing, $splitRenderingConf, $sF=1) {
00833
00834 $spacing*=$sF;
00835 $wordSpacing*=$sF;
00836
00837 if (!$spacing && $wordSpacing) {
00838 $bits = explode(' ',$text);
00839 reset($bits);
00840 while(list(,$word)=each($bits)) {
00841 $word.=' ';
00842 $word = $word;
00843 $wordInf = $this->ImageTTFBBoxWrapper($fontSize, $angle, $fontFile, $word, $splitRenderingConf ,$sF);
00844 $wordW = ($wordInf[2]-$wordInf[0]);
00845 $this->ImageTTFTextWrapper($im, $fontSize, $angle, $x, $y, $Fcolor, $fontFile, $word, $splitRenderingConf, $sF);
00846 $x+=$wordW+$wordSpacing;
00847 }
00848 } else {
00849 $utf8Chars = $this->singleChars($text);
00850
00851 foreach($utf8Chars as $char) {
00852 $charInf = $this->ImageTTFBBoxWrapper($fontSize, $angle, $fontFile, $char, $splitRenderingConf, $sF);
00853 $charW = ($charInf[2]-$charInf[0]);
00854 $this->ImageTTFTextWrapper($im, $fontSize, $angle, $x, $y, $Fcolor, $fontFile, $char, $splitRenderingConf, $sF);
00855 $x+=$charW+(($char==' ')?$wordSpacing:$spacing);
00856 }
00857 }
00858 }
00859
00869 function fontResize($conf) {
00870
00871 $maxWidth = intval($conf['maxWidth']);
00872 if ($maxWidth) {
00873 if ($spacing || $wordSpacing) {
00874 return $conf['fontSize'];
00875
00876 } else {
00877 do {
00878
00879 $bounds = $this->ImageTTFBBoxWrapper($conf['fontSize'], $conf['angle'], $conf['fontFile'], $this->recodeString($conf['text']), $conf['splitRendering.']);
00880 if ($conf['angle']< 0) {
00881 $pixelWidth = abs($bounds[4]-$bounds[0]);
00882 } elseif ($conf['angle'] > 0) {
00883 $pixelWidth = abs($bounds[2]-$bounds[6]);
00884 } else {
00885 $pixelWidth = abs($bounds[4]-$bounds[6]);
00886 }
00887
00888
00889 if ($pixelWidth <= $maxWidth) {
00890 break;
00891 } else {
00892 $conf['fontSize']--;
00893 }
00894 } while ($conf['fontSize']>1);
00895 }
00896 }
00897 return $conf['fontSize'];
00898 }
00899
00911 function ImageTTFBBoxWrapper($fontSize, $angle, $fontFile, $string, $splitRendering, $sF=1) {
00912
00913
00914 $offsetInfo = array();
00915 $stringParts = $this->splitString($string,$splitRendering,$fontSize,$fontFile);
00916
00917
00918 foreach($stringParts as $strCfg) {
00919
00920
00921 $calc = ImageTTFBBox(t3lib_div::freetypeDpiComp($sF*$strCfg['fontSize']), $angle, t3lib_stdGraphic::prependAbsolutePath($strCfg['fontFile']), $strCfg['str']);
00922
00923
00924 if (!count($offsetInfo)) {
00925 $offsetInfo = $calc;
00926 } else {
00927 $offsetInfo[2]+=$calc[2]-$calc[0]+intval($splitRendering['compX'])+intval($strCfg['xSpaceBefore'])+intval($strCfg['xSpaceAfter']);
00928 $offsetInfo[3]+=$calc[3]-$calc[1]-intval($splitRendering['compY'])-intval($strCfg['ySpaceBefore'])-intval($strCfg['ySpaceAfter']);
00929 $offsetInfo[4]+=$calc[4]-$calc[6]+intval($splitRendering['compX'])+intval($strCfg['xSpaceBefore'])+intval($strCfg['xSpaceAfter']);
00930 $offsetInfo[5]+=$calc[5]-$calc[7]-intval($splitRendering['compY'])-intval($strCfg['ySpaceBefore'])-intval($strCfg['ySpaceAfter']);
00931 }
00932 }
00933
00934 return $offsetInfo;
00935 }
00936
00952 function ImageTTFTextWrapper($im, $fontSize, $angle, $x, $y, $color, $fontFile, $string, $splitRendering,$sF=1) {
00953
00954
00955 $stringParts = $this->splitString($string,$splitRendering,$fontSize,$fontFile);
00956 $x = ceil($sF*$x);
00957 $y = ceil($sF*$y);
00958
00959
00960 foreach($stringParts as $i => $strCfg) {
00961
00962
00963 $colorIndex = $color;
00964
00965
00966 if ($strCfg['color'] && $sF==1) {
00967 $cols = $this->convertColor($strCfg['color']);
00968 $colorIndex = ImageColorAllocate($im, $cols[0],$cols[1],$cols[2]);
00969 $colorIndex = $color >= 0 ? $colorIndex : -$colorIndex;
00970 }
00971
00972
00973 if ($i) {
00974 $x+= intval($strCfg['xSpaceBefore']);
00975 $y-= intval($strCfg['ySpaceBefore']);
00976 }
00977
00978
00979 ImageTTFText($im, t3lib_div::freetypeDpiComp($sF*$strCfg['fontSize']), $angle, $x, $y, $colorIndex, t3lib_stdGraphic::prependAbsolutePath($strCfg['fontFile']), $strCfg['str']);
00980
00981
00982 $wordInf = ImageTTFBBox(t3lib_div::freetypeDpiComp($sF*$strCfg['fontSize']), $angle, t3lib_stdGraphic::prependAbsolutePath($strCfg['fontFile']), $strCfg['str']);
00983 $x+= $wordInf[2]-$wordInf[0]+intval($splitRendering['compX'])+intval($strCfg['xSpaceAfter']);
00984 $y+= $wordInf[5]-$wordInf[7]-intval($splitRendering['compY'])-intval($strCfg['ySpaceAfter']);
00985 }
00986 }
00987
00997 function splitString($string,$splitRendering,$fontSize,$fontFile) {
00998
00999
01000 $result = array();
01001 $result[] = array(
01002 'str' => $string,
01003 'fontSize' => $fontSize,
01004 'fontFile' => $fontFile
01005 );
01006
01007
01008
01009 if (is_array($splitRendering)) {
01010 $sKeyArray = t3lib_TStemplate::sortedKeyList($splitRendering);
01011
01012
01013 foreach($sKeyArray as $key) {
01014 $cfg = $splitRendering[$key.'.'];
01015
01016
01017 switch((string)$splitRendering[$key]) {
01018 case 'highlightWord':
01019 if (strlen($cfg['value'])) {
01020 $newResult = array();
01021
01022
01023 foreach($result as $part) {
01024
01025 $explodedParts = explode($cfg['value'],$part['str']);
01026 foreach($explodedParts as $c => $expValue) {
01027 if (strlen($expValue)) {
01028 $newResult[] = array_merge($part,array('str' => $expValue));
01029 }
01030 if ($c+1 < count($explodedParts)) {
01031 $newResult[] = array(
01032 'str' => $cfg['value'],
01033 'fontSize' => $cfg['fontSize'] ? $cfg['fontSize'] : $part['fontSize'],
01034 'fontFile' => $cfg['fontFile'] ? $cfg['fontFile'] : $part['fontFile'],
01035 'color' => $cfg['color'],
01036 'xSpaceBefore' => $cfg['xSpaceBefore'],
01037 'xSpaceAfter' => $cfg['xSpaceAfter'],
01038 'ySpaceBefore' => $cfg['ySpaceBefore'],
01039 'ySpaceAfter' => $cfg['ySpaceAfter'],
01040 );
01041 }
01042 }
01043 }
01044
01045
01046 if (count($newResult)) {
01047 $result = $newResult;
01048 }
01049 }
01050 break;
01051 case 'charRange':
01052 if (strlen($cfg['value'])) {
01053
01054
01055 $ranges = t3lib_div::trimExplode(',',$cfg['value'],1);
01056 foreach($ranges as $i => $rangeDef) {
01057 $ranges[$i] = t3lib_div::intExplode('-',$ranges[$i]);
01058 if (!isset($ranges[$i][1])) $ranges[$i][1] = $ranges[$i][0];
01059 }
01060 $newResult = array();
01061
01062
01063 foreach($result as $part) {
01064
01065
01066 $currentState = -1;
01067 $bankAccum = '';
01068
01069
01070 $utf8Chars = $this->singleChars($part['str']);
01071 foreach($utf8Chars as $utfChar) {
01072
01073
01074 $uNumber = $this->csConvObj->utf8CharToUnumber($utfChar);
01075 $inRange = 0;
01076 foreach($ranges as $rangeDef) {
01077 if ($uNumber >= $rangeDef[0] && (!$rangeDef[1] || $uNumber <= $rangeDef[1])) {
01078 $inRange = 1;
01079 break;
01080 }
01081 }
01082 if ($currentState==-1) $currentState = $inRange;
01083
01084
01085 if ($inRange != $currentState && !t3lib_div::inList('32,10,13,9',$uNumber)) {
01086
01087
01088 if (strlen($bankAccum)) {
01089 $newResult[] = array(
01090 'str' => $bankAccum,
01091 'fontSize' => $currentState && $cfg['fontSize'] ? $cfg['fontSize'] : $part['fontSize'],
01092 'fontFile' => $currentState && $cfg['fontFile'] ? $cfg['fontFile'] : $part['fontFile'],
01093 'color' => $currentState ? $cfg['color'] : '',
01094 'xSpaceBefore' => $currentState ? $cfg['xSpaceBefore'] : '',
01095 'xSpaceAfter' => $currentState ? $cfg['xSpaceAfter'] : '',
01096 'ySpaceBefore' => $currentState ? $cfg['ySpaceBefore'] : '',
01097 'ySpaceAfter' => $currentState ? $cfg['ySpaceAfter'] : '',
01098 );
01099 }
01100
01101
01102 $currentState = $inRange;
01103 $bankAccum = '';
01104 }
01105
01106
01107 $bankAccum.=$utfChar;
01108 }
01109
01110
01111 if (strlen($bankAccum)) {
01112 $newResult[] = array(
01113 'str' => $bankAccum,
01114 'fontSize' => $currentState && $cfg['fontSize'] ? $cfg['fontSize'] : $part['fontSize'],
01115 'fontFile' => $currentState && $cfg['fontFile'] ? $cfg['fontFile'] : $part['fontFile'],
01116 'color' => $currentState ? $cfg['color'] : '',
01117 'xSpaceBefore' => $currentState ? $cfg['xSpaceBefore'] : '',
01118 'xSpaceAfter' => $currentState ? $cfg['xSpaceAfter'] : '',
01119 'ySpaceBefore' => $currentState ? $cfg['ySpaceBefore'] : '',
01120 'ySpaceAfter' => $currentState ? $cfg['ySpaceAfter'] : '',
01121 );
01122 }
01123 }
01124
01125
01126 if (count($newResult)) {
01127 $result = $newResult;
01128 }
01129 }
01130 break;
01131 }
01132 }
01133 }
01134
01135 return $result;
01136 }
01137
01138
01139
01140
01141
01142
01143
01144
01145
01146
01147
01148
01149
01150
01151
01152
01153
01154
01155
01156
01157
01168 function makeOutline(&$im,$conf,$workArea,$txtConf) {
01169 $thickness = intval($conf['thickness']);
01170 if ($thickness) {
01171 $txtConf['fontColor'] = $conf['color'];
01172 $outLineDist = t3lib_div::intInRange($thickness,1,2);
01173 for ($b=1;$b<=$outLineDist;$b++) {
01174 if ($b==1) {
01175 $it = 8;
01176 } else {
01177 $it = 16;
01178 }
01179 $outL = $this->circleOffset($b, $it);
01180 for ($a=0;$a<$it;$a++) {
01181 $this->makeText($im,$txtConf,$this->applyOffset($workArea,$outL[$a]));
01182 }
01183 }
01184 }
01185 }
01186
01197 function circleOffset($distance, $iterations) {
01198 $res = Array();
01199 if ($distance && $iterations) {
01200 for ($a=0;$a<$iterations;$a++) {
01201 $yOff = round(sin(2*pi()/$iterations*($a+1))*100*$distance);
01202 if ($yOff) {$yOff = intval(ceil(abs($yOff/100))*($yOff/abs($yOff)));}
01203 $xOff = round(cos(2*pi()/$iterations*($a+1))*100*$distance);
01204 if ($xOff) {$xOff = intval(ceil(abs($xOff/100))*($xOff/abs($xOff)));}
01205 $res[$a] = Array($xOff,$yOff);
01206 }
01207 }
01208 return $res;
01209 }
01210
01221 function makeEmboss(&$im,$conf,$workArea,$txtConf) {
01222 $conf['color']=$conf['highColor'];
01223 $this->makeShadow($im,$conf,$workArea,$txtConf);
01224 $newOffset = t3lib_div::intExplode(',',$conf['offset']);
01225 $newOffset[0]*=-1;
01226 $newOffset[1]*=-1;
01227 $conf['offset']=implode(',',$newOffset);
01228 $conf['color']=$conf['lowColor'];
01229 $this->makeShadow($im,$conf,$workArea,$txtConf);
01230 }
01231
01243 function makeShadow(&$im,$conf,$workArea,$txtConf) {
01244 $workArea = $this->applyOffset($workArea,t3lib_div::intExplode(',',$conf['offset']));
01245 $blurRate = t3lib_div::intInRange(intval($conf['blur']),0,99);
01246
01247 if (!$blurRate || $this->NO_IM_EFFECTS) {
01248 $txtConf['fontColor'] = $conf['color'];
01249 $this->makeText($im,$txtConf,$workArea);
01250 } else {
01251 $w = imagesx($im);
01252 $h = imagesy($im);
01253 $blurBorder= 3;
01254 $tmpStr = $this->randomName();
01255 $fileMenu = $tmpStr.'_menu.'.$this->gifExtension;
01256 $fileColor = $tmpStr.'_color.'.$this->gifExtension;
01257 $fileMask = $tmpStr.'_mask.'.$this->gifExtension;
01258
01259
01260 $blurColImg = imagecreate($w,$h);
01261 $bcols=$this->convertColor($conf['color']);
01262 ImageColorAllocate($blurColImg, $bcols[0],$bcols[1],$bcols[2]);
01263 $this->ImageGif($blurColImg, $fileColor);
01264 ImageDestroy($blurColImg);
01265
01266
01267 $blurTextImg = imagecreate($w+$blurBorder*2,$h+$blurBorder*2);
01268 ImageColorAllocate($blurTextImg, 0,0,0);
01269 $txtConf['fontColor'] = 'white';
01270 $blurBordArr = Array($blurBorder,$blurBorder);
01271 $this->makeText($blurTextImg,$txtConf, $this->applyOffset($workArea,$blurBordArr));
01272 $this->ImageGif($blurTextImg, $fileMask);
01273 ImageDestroy($blurTextImg);
01274
01275
01276 $command='';
01277 $command.=$this->maskNegate;
01278
01279 if ($this->V5_EFFECTS) {
01280 $command.=$this->v5_blur($blurRate+1);
01281 } else {
01282
01283 $times = ceil($blurRate/10);
01284 $newBlurRate = $blurRate*4;
01285 $newBlurRate = t3lib_div::intInRange($newBlurRate,1,99);
01286 for ($a=0;$a<$times;$a++) {
01287 $command.=' -blur '.$blurRate;
01288 }
01289 }
01290
01291 $this->imageMagickExec($fileMask,$fileMask,$command);
01292
01293 $blurTextImg_tmp = $this->imageCreateFromGif($fileMask);
01294 if ($blurTextImg_tmp) {
01295
01296
01297 $blurTextImg = imagecreate($w,$h);
01298 $this->imagecopyresized($blurTextImg, $blurTextImg_tmp, 0, 0, $blurBorder, $blurBorder, $w, $h, $w, $h);
01299 ImageDestroy($blurTextImg_tmp);
01300
01301
01302 $intensity = 40;
01303 if ($conf['intensity']) {
01304 $intensity = t3lib_div::intInRange($conf['intensity'],0,100);
01305 }
01306 $intensity = ceil(255-($intensity/100*255));
01307 $this->inputLevels($blurTextImg,0,$intensity,$this->maskNegate);
01308
01309 $opacity = t3lib_div::intInRange(intval($conf['opacity']),0,100);
01310 if ($opacity && $opacity<100) {
01311 $high = ceil(255*$opacity/100);
01312 $this->outputLevels($blurTextImg,0,$high,$this->maskNegate);
01313 }
01314
01315 $this->ImageGif($blurTextImg, $fileMask);
01316 ImageDestroy($blurTextImg);
01317
01318
01319 $this->ImageGif($im, $fileMenu);
01320
01321 $this->combineExec($fileMenu,$fileColor,$fileMask,$fileMenu);
01322
01323 $backIm = $this->imageCreateFromGif($fileMenu);
01324 if ($backIm) {
01325 ImageColorTransparent($backIm,-1);
01326 $im = $backIm;
01327 }
01328 }
01329
01330 if (!$this->dontUnlinkTempFiles) {
01331 unlink($fileMenu);
01332 unlink($fileColor);
01333 unlink($fileMask);
01334 }
01335 }
01336 }
01337
01338
01339
01340
01341
01342
01343
01344
01345
01346
01347
01348
01349
01350
01351
01352
01353
01354
01355
01356
01357
01358
01359
01360
01361
01362
01363
01373 function makeBox(&$im,$conf,$workArea) {
01374 $cords = t3lib_div::intExplode(',',$conf['dimensions'].',,,');
01375 $conf['offset']=$cords[0].','.$cords[1];
01376 $cords = $this->objPosition($conf,$workArea,Array($cords[2],$cords[3]));
01377 $cols=$this->convertColor($conf['color']);
01378 $this->reduceColors($im,256, 255);
01379 $tmpColor = ImageColorAllocate($im, $cols[0],$cols[1],$cols[2]);
01380 imagefilledrectangle($im, $cords[0], $cords[1], $cords[0]+$cords[2]-1, $cords[1]+$cords[3]-1, $tmpColor);
01381 }
01382
01392 function makeEffect(&$im, $conf) {
01393 $commands = $this->IMparams($conf['value']);
01394 if ($commands) {
01395 $this->applyImageMagickToPHPGif($im, $commands);
01396 }
01397 }
01398
01407 function IMparams($setup) {
01408 if (!trim($setup)){return '';}
01409 $effects = explode('|', $setup);
01410 $commands = '';
01411 while(list(,$val)=each($effects)) {
01412 $pairs=explode('=',$val,2);
01413 $value = trim($pairs[1]);
01414 $effect = strtolower(trim($pairs[0]));
01415 switch($effect) {
01416 case 'gamma':
01417 $commands.=' -gamma '.doubleval($value);
01418 break;
01419 case 'blur':
01420 if (!$this->NO_IM_EFFECTS) {
01421 if ($this->V5_EFFECTS) {
01422 $commands.=$this->v5_blur($value);
01423 } else {
01424 $commands.=' -blur '.t3lib_div::intInRange($value,1,99);
01425 }
01426 }
01427 break;
01428 case 'sharpen':
01429 if (!$this->NO_IM_EFFECTS) {
01430 if ($this->V5_EFFECTS) {
01431 $commands.=$this->v5_sharpen($value);
01432 } else {
01433 $commands.=' -sharpen '.t3lib_div::intInRange($value,1,99);
01434 }
01435 }
01436 break;
01437 case 'rotate':
01438 $commands.=' -rotate '.t3lib_div::intInRange($value,0,360);
01439 break;
01440 case 'solarize':
01441 $commands.=' -solarize '.t3lib_div::intInRange($value,0,99);
01442 break;
01443 case 'swirl':
01444 $commands.=' -swirl '.t3lib_div::intInRange($value,0,1000);
01445 break;
01446 case 'wave':
01447 $params = t3lib_div::intExplode(',',$value);
01448 $commands.=' -wave '.t3lib_div::intInRange($params[0],0,99).'x'.t3lib_div::intInRange($params[1],0,99);
01449 break;
01450 case 'charcoal':
01451 $commands.=' -charcoal '.t3lib_div::intInRange($value,0,100);
01452 break;
01453 case 'gray':
01454 $commands.=' -colorspace GRAY';
01455 break;
01456 case 'edge':
01457 $commands.=' -edge '.t3lib_div::intInRange($value,0,99);
01458 break;
01459 case 'emboss':
01460 $commands.=' -emboss';
01461 break;
01462 case 'flip':
01463 $commands.=' -flip';
01464 break;
01465 case 'flop':
01466 $commands.=' -flop';
01467 break;
01468 case 'colors':
01469 $commands.=' -colors '.t3lib_div::intInRange($value,2,255);
01470 break;
01471 case 'shear':
01472 $commands.=' -shear '.t3lib_div::intInRange($value,-90,90);
01473 break;
01474 case 'invert':
01475 $commands.=' -negate';
01476 break;
01477 }
01478 }
01479 return $commands;
01480 }
01481
01490 function adjust(&$im, $conf) {
01491 $setup = $conf['value'];
01492 if (!trim($setup)){return '';}
01493 $effects = explode('|', $setup);
01494 while(list(,$val)=each($effects)) {
01495 $pairs=explode('=',$val,2);
01496 $value = trim($pairs[1]);
01497 $effect = strtolower(trim($pairs[0]));
01498 switch($effect) {
01499 case 'inputlevels':
01500 $params = t3lib_div::intExplode(',',$value);
01501 $this->inputLevels($im,$params[0],$params[1]);
01502 break;
01503 case 'outputlevels':
01504 $params = t3lib_div::intExplode(',',$value);
01505 $this->outputLevels($im,$params[0],$params[1]);
01506 break;
01507 case 'autolevels':
01508 $this->autoLevels($im);
01509 break;
01510 }
01511 }
01512 }
01513
01522 function crop(&$im,$conf) {
01523 $this->setWorkArea('');
01524 $cords = t3lib_div::intExplode(',',$conf['crop'].',,,');
01525 $conf['offset']=$cords[0].','.$cords[1];
01526 $cords = $this->objPosition($conf,$this->workArea,Array($cords[2],$cords[3]));
01527
01528 $newIm = imagecreate($cords[2],$cords[3]);
01529 $cols=$this->convertColor($conf['backColor']?$conf['backColor']:$this->setup['backColor']);
01530 ImageColorAllocate($newIm, $cols[0],$cols[1],$cols[2]);
01531
01532 $newConf = Array();
01533 $workArea = Array(0,0,$cords[2],$cords[3]);
01534 if ($cords[0]<0) {$workArea[0]=abs($cords[0]);} else {$newConf['offset']=-$cords[0];}
01535 if ($cords[1]<0) {$workArea[1]=abs($cords[1]);} else {$newConf['offset'].=','.-$cords[1];}
01536
01537 $this->copyGifOntoGif($newIm,$im,$newConf,$workArea);
01538 $im = $newIm;
01539 $this->w = imagesx($im);
01540 $this->h = imagesy($im);
01541 $this->setWorkArea('');
01542 }
01543
01552 function scale(&$im,$conf) {
01553 if ($conf['width'] || $conf['height'] || $conf['params']) {
01554 $tmpStr = $this->randomName();
01555 $theFile = $tmpStr.'.'.$this->gifExtension;
01556 $this->ImageGif($im, $theFile);
01557 $theNewFile = $this->imageMagickConvert($theFile,$this->gifExtension,$conf['width'],$conf['height'],$conf['params'],'','');
01558 $tmpImg = $this->imageCreateFromGif($theNewFile[3]);
01559 if ($tmpImg) {
01560 ImageDestroy($im);
01561 $im = $tmpImg;
01562 $this->w = imagesx($im);
01563 $this->h = imagesy($im);
01564 $this->setWorkArea('');
01565 }
01566 if (!$this->dontUnlinkTempFiles) {
01567 unlink($theFile);
01568 if ($theNewFile[3] && $theNewFile[3]!=$theFile) {
01569 unlink($theNewFile[3]);
01570 }
01571 }
01572 }
01573 }
01574
01584 function setWorkArea($workArea) {
01585 $this->workArea = t3lib_div::intExplode(',',$workArea);
01586 $this->workArea = $this->applyOffset($this->workArea,$this->OFFSET);
01587 if (!$this->workArea[2]) {$this->workArea[2]=$this->w;}
01588 if (!$this->workArea[3]) {$this->workArea[3]=$this->h;}
01589 }
01590
01591
01592
01593
01594
01595
01596
01597
01598
01599
01600
01601
01602
01603
01604
01605
01606
01607
01608
01609
01610
01611
01612
01613
01614
01615
01616
01617
01618
01625 function autolevels(&$im) {
01626 $totalCols = ImageColorsTotal($im);
01627 $min=255;
01628 $max=0;
01629 for ($c=0; $c<$totalCols; $c++) {
01630 $cols = ImageColorsForIndex($im,$c);
01631 $grayArr[] = round(($cols['red']+$cols['green']+$cols['blue'])/3);
01632 }
01633 $min=min($grayArr);
01634 $max=max($grayArr);
01635 $delta = $max-$min;
01636 if ($delta) {
01637 for ($c=0; $c<$totalCols; $c++) {
01638 $cols = ImageColorsForIndex($im,$c);
01639 $cols['red'] = floor(($cols['red']-$min)/$delta*255);
01640 $cols['green'] = floor(($cols['green']-$min)/$delta*255);
01641 $cols['blue'] = floor(($cols['blue']-$min)/$delta*255);
01642 ImageColorSet($im,$c,$cols['red'],$cols['green'],$cols['blue']);
01643 }
01644 }
01645 }
01646
01656 function outputLevels(&$im,$low,$high,$swap='') {
01657 if ($low<$high){
01658 $low = t3lib_div::intInRange($low,0,255);
01659 $high = t3lib_div::intInRange($high,0,255);
01660
01661 if ($swap) {
01662 $temp = $low;
01663 $low = 255-$high;
01664 $high = 255-$temp;
01665 }
01666
01667 $delta = $high-$low;
01668 $totalCols = ImageColorsTotal($im);
01669 for ($c=0; $c<$totalCols; $c++) {
01670 $cols = ImageColorsForIndex($im,$c);
01671 $cols['red'] = $low+floor($cols['red']/255*$delta);
01672 $cols['green'] = $low+floor($cols['green']/255*$delta);
01673 $cols['blue'] = $low+floor($cols['blue']/255*$delta);
01674 ImageColorSet($im,$c,$cols['red'],$cols['green'],$cols['blue']);
01675 }
01676 }
01677 }
01678
01688 function inputLevels(&$im,$low,$high,$swap='') {
01689 if ($low<$high){
01690 $low = t3lib_div::intInRange($low,0,255);
01691 $high = t3lib_div::intInRange($high,0,255);
01692
01693 if ($swap) {
01694 $temp = $low;
01695 $low = 255-$high;
01696 $high = 255-$temp;
01697 }
01698
01699 $delta = $high-$low;
01700 $totalCols = ImageColorsTotal($im);
01701 for ($c=0; $c<$totalCols; $c++) {
01702 $cols = ImageColorsForIndex($im,$c);
01703 $cols['red'] = t3lib_div::intInRange(($cols['red']-$low)/$delta*255, 0,255);
01704 $cols['green'] = t3lib_div::intInRange(($cols['green']-$low)/$delta*255, 0,255);
01705 $cols['blue'] = t3lib_div::intInRange(($cols['blue']-$low)/$delta*255, 0,255);
01706 ImageColorSet($im,$c,$cols['red'],$cols['green'],$cols['blue']);
01707 }
01708 }
01709 }
01710
01719 function reduceColors(&$im,$limit, $cols) {
01720 if (ImageColorsTotal($im)>=$limit) {
01721 $this->makeEffect($im, Array('value'=>'colors='.$cols) );
01722 }
01723 }
01724
01725
01726
01727
01728
01729
01730
01731
01732
01733
01734
01735
01736
01737
01738
01739
01740
01741
01742
01743
01744
01745
01746
01747
01748
01757 function prependAbsolutePath($fontFile) {
01758 $absPath = defined('PATH_typo3') ? dirname(PATH_thisScript).'/' :PATH_site;
01759 $fontFile = t3lib_div::isAbsPath($fontFile) ? $fontFile : $absPath.$fontFile;
01760 return $fontFile;
01761 }
01762
01771 function v5_sharpen($factor) {
01772 $factor = t3lib_div::intInRange(ceil($factor/10),0,10);
01773
01774 $sharpenArr=explode(',',','.$this->im5fx_sharpenSteps);
01775 $sharpenF= trim($sharpenArr[$factor]);
01776 if ($sharpenF) {
01777 $cmd = ' -sharpen '.$sharpenF;
01778 return $cmd;
01779 }
01780 }
01781
01790 function v5_blur($factor) {
01791 $factor = t3lib_div::intInRange(ceil($factor/10),0,10);
01792
01793 $blurArr=explode(',',','.$this->im5fx_blurSteps);
01794 $blurF= trim($blurArr[$factor]);
01795 if ($blurF) {
01796 $cmd=' -blur '.$blurF;
01797 return $cmd;
01798 }
01799 }
01800
01807 function randomName() {
01808 $this->createTempSubDir('temp/');
01809 return $this->tempPath.'temp/'.md5(uniqid(''));
01810 }
01811
01820 function applyOffset($cords,$OFFSET) {
01821 $cords[0] = intval($cords[0])+intval($OFFSET[0]);
01822 $cords[1] = intval($cords[1])+intval($OFFSET[1]);
01823 return $cords;
01824 }
01825
01833 function convertColor($string) {
01834 $col=array();
01835 $cParts = explode(':',$string,2);
01836
01837
01838 $string=$cParts[0];
01839 if (strstr($string,'#')) {
01840 $string = ereg_replace('[^A-Fa-f0-9]*','',$string);
01841 $col[]=HexDec(substr($string,0,2));
01842 $col[]=HexDec(substr($string,2,2));
01843 $col[]=HexDec(substr($string,4,2));
01844 } elseif (strstr($string,',')) {
01845 $string = ereg_replace('[^,0-9]*','',$string);
01846 $strArr = explode(',',$string);
01847 $col[]=intval($strArr[0]);
01848 $col[]=intval($strArr[1]);
01849 $col[]=intval($strArr[2]);
01850 } else {
01851 $string = strtolower(trim($string));
01852 if ($this->colMap[$string]) {
01853 $col = $this->colMap[$string];
01854 } else {
01855 $col = Array(0,0,0);
01856 }
01857 }
01858
01859 if (trim($cParts[1])) {
01860 $cParts[1]=trim($cParts[1]);
01861 if (substr($cParts[1],0,1)=='*') {
01862 $val=doubleval(substr($cParts[1],1));
01863 $col[0]=t3lib_div::intInRange($col[0]*$val,0,255);
01864 $col[1]=t3lib_div::intInRange($col[1]*$val,0,255);
01865 $col[2]=t3lib_div::intInRange($col[2]*$val,0,255);
01866 } else {
01867 $val=intval($cParts[1]);
01868 $col[0]=t3lib_div::intInRange($col[0]+$val,0,255);
01869 $col[1]=t3lib_div::intInRange($col[1]+$val,0,255);
01870 $col[2]=t3lib_div::intInRange($col[2]+$val,0,255);
01871 }
01872 }
01873 return $col;
01874 }
01875
01883 function recodeString($string) {
01884
01885 if ($this->nativeCharset && $this->nativeCharset!='utf-8') {
01886 $string = $this->csConvObj->utf8_encode($string,$this->nativeCharset);
01887 }
01888
01889
01890 if ($this->TTFLocaleConv) {
01891 $string = recode_string($this->TTFLocaleConv,$string);
01892 }
01893
01894 return $string;
01895 }
01896
01905 function singleChars($theText,$returnUnicodeNumber=FALSE) {
01906 if ($this->nativeCharset) {
01907 return $this->csConvObj->utf8_to_numberarray($theText,1,$returnUnicodeNumber ? 0 : 1);
01908 } else {
01909 $output=array();
01910 $c=strlen($theText);
01911 for($a=0;$a<$c;$a++) {
01912 $output[]=substr($theText,$a,1);
01913 }
01914 return $output;
01915 }
01916 }
01917
01928 function objPosition($conf,$workArea,$BB) {
01929
01930 $result=Array();
01931 $result[2] = $BB[0];
01932 $result[3] = $BB[1];
01933 $w=$workArea[2];
01934 $h=$workArea[3];
01935
01936 $align = explode(',',$conf['align']);
01937 $align[0] = strtolower(substr(trim($align[0]),0,1));
01938 $align[1] = strtolower(substr(trim($align[1]),0,1));
01939
01940 switch($align[0]) {
01941 case 'r':
01942 $result[0]=$w-$result[2];
01943 break;
01944 case 'c':
01945 $result[0] = round(($w-$result[2])/2);
01946 break;
01947 default:
01948 $result[0] = 0;
01949 break;
01950 }
01951 switch($align[1]) {
01952 case 'b':
01953 $result[1] = $h-$result[3];
01954 break;
01955 case 'c':
01956 $result[1] = round(($h-$result[3])/2);
01957 break;
01958 default:
01959 $result[1]=0;
01960 break;
01961 }
01962 $result = $this->applyOffset($result,t3lib_div::intExplode(',',$conf['offset']));
01963 $result = $this->applyOffset($result,$workArea);
01964 return $result;
01965 }
01966
01967
01968
01969
01970
01971
01972
01973
01974
01975
01976
01977
01978
01979
01980
01981
01982
01983
01984
01985
01986
01987
01988
01989
01990
01991
01992
02007 function imageMagickConvert($imagefile,$newExt='',$w='',$h='',$params='',$frame='',$options='',$mustCreate=0) {
02008 if ($this->NO_IMAGE_MAGICK) {
02009
02010 return $this->getImageDimensions($imagefile);
02011 }
02012
02013 if($info=$this->getImageDimensions($imagefile)) {
02014 $newExt=strtolower(trim($newExt));
02015 if (!$newExt) {
02016 $newExt = $info[2];
02017 }
02018 if ($newExt=='web') {
02019 if (t3lib_div::inList($this->webImageExt,$info[2])) {
02020 $newExt = $info[2];
02021 } else {
02022 $newExt = $this->gif_or_jpg($info[2],$info[0],$info[1]);
02023 if (!$params) {
02024 $params = $this->cmds[$newExt];
02025 }
02026 }
02027 }
02028 if (t3lib_div::inList($this->imageFileExt,$newExt)) {
02029 if (strstr($w.$h, 'm')) {$max=1;} else {$max=0;}
02030
02031 $data = $this->getImageScale($info,$w,$h,$options);
02032 $w=$data['origW'];
02033 $h=$data['origH'];
02034
02035
02036 $wh_noscale = (!$w && !$h) || ($data[0]==$info[0] && $data[1]==$info[1]);
02037
02038 if ($wh_noscale && !$params && !$frame && $newExt==$info[2] && !$mustCreate) {
02039 $info[3] = $imagefile;
02040 return $info;
02041 }
02042 $info[0]=$data[0];
02043 $info[1]=$data[1];
02044
02045 $frame = $this->noFramePrepended ? '' : '['.intval($frame).']';
02046
02047 if (!$params) {
02048 $params = $this->cmds[$newExt];
02049 }
02050
02051 $command = $this->scalecmd.' '.$info[0].'x'.$info[1].'! '.$params.' ';
02052
02053 if ($this->alternativeOutputKey) {
02054 $theOutputName = t3lib_div::shortMD5($command.basename($imagefile).$this->alternativeOutputKey.$frame);
02055 } else {
02056 $theOutputName = t3lib_div::shortMD5($command.$imagefile.filemtime($imagefile).$frame);
02057 }
02058 if ($this->imageMagickConvert_forceFileNameBody) {
02059 $theOutputName = $this->imageMagickConvert_forceFileNameBody;
02060 $this->imageMagickConvert_forceFileNameBody='';
02061 }
02062
02063
02064 $this->createTempSubDir('pics/');
02065 $output = $this->absPrefix.$this->tempPath.'pics/'.$this->filenamePrefix.$theOutputName.'.'.$newExt;
02066
02067
02068 $GLOBALS['TEMP_IMAGES_ON_PAGE'][] = $output;
02069
02070 if (!$this->file_exists_typo3temp_file($output,$imagefile) || $this->dontCheckForExistingTempFile) {
02071 $this->imageMagickExec($imagefile.$frame,$output,$command);
02072 }
02073 if (@file_exists($output)) {
02074 $info[3] = $output;
02075 $info[2] = $newExt;
02076 if ($params) {
02077 $info=$this->getImageDimensions($info[3]);
02078 }
02079 if ($info[2]==$this->gifExtension && !$this->dontCompress) {
02080 t3lib_div::gif_compress($info[3],'');
02081 }
02082 return $info;
02083 }
02084 }
02085 }
02086 }
02087
02095 function getImageDimensions($imageFile) {
02096 ereg('([^\.]*)$',$imageFile,$reg);
02097 if (@file_exists($imageFile) && t3lib_div::inList($this->imageFileExt,strtolower($reg[0]))) {
02098 if ($returnArr = $this->getCachedImageDimensions($imageFile)) {
02099 return $returnArr;
02100 } else {
02101 if ($temp = @getImageSize($imageFile)) {
02102 $returnArr = Array($temp[0], $temp[1], strtolower($reg[0]), $imageFile);
02103 } else {
02104 $returnArr = $this->imageMagickIdentify($imageFile);
02105 }
02106 if ($returnArr) {
02107 $this->cacheImageDimensions($returnArr);
02108 return $returnArr;
02109 }
02110 }
02111 }
02112 return false;
02113 }
02114
02123 function cacheImageDimensions($identifyResult) {
02124 global $TYPO3_DB;
02125
02126 if (function_exists('md5_file')) {
02127 $md5Hash = md5_file($identifyResult[3]);
02128 } else {
02129 $md5Hash = md5 (t3lib_div::getURL($identifyResult[3]));
02130 }
02131 if ($md5Hash) {
02132 $fieldArr = array (
02133 'md5hash' => $md5Hash,
02134 'md5filename' => md5($identifyResult[3]),
02135 'tstamp' => time(),
02136 'filename' => $identifyResult[3],
02137 'imagewidth' => $identifyResult[0],
02138 'imageheight' => $identifyResult[1],
02139 );
02140 $TYPO3_DB->exec_INSERTquery('cache_imagesizes', $fieldArr);
02141 if (!$err = $TYPO3_DB->sql_error()) {
02142 return true;
02143 }
02144 }
02145 return false;
02146 }
02147
02155 function getCachedImageDimensions($imageFile) {
02156 global $TYPO3_DB;
02157
02158 if(function_exists('md5_file')) {
02159 $md5Hash = md5_file($imageFile);
02160 } else {
02161 $md5Hash = md5(t3lib_div::getURL ($imageFile));
02162 }
02163 ereg('([^\.]*)$',$imageFile,$reg);
02164 $res = $TYPO3_DB->exec_SELECTquery ('md5hash, imagewidth, imageheight', 'cache_imagesizes', 'md5filename="'.md5($imageFile).'"');
02165 if ($res) {
02166 if ($row = $TYPO3_DB->sql_fetch_assoc($res)) {
02167 if ($row['md5hash']!=$md5Hash) {
02168
02169 $TYPO3_DB->exec_DELETEquery ('cache_imagesizes', 'md5hash="'.$TYPO3_DB->quoteStr($row['md5hash'], 'cache_imagesizes').'"');
02170 } else {
02171 return (array($row['imagewidth'], $row['imageheight'], strtolower($reg[0]), $imageFile));
02172 }
02173 }
02174 }
02175 return false;
02176 }
02177
02189 function getImageScale($info,$w,$h,$options) {
02190 if (strstr($w.$h, 'm')) {$max=1;} else {$max=0;}
02191 $w=intval($w);
02192 $h=intval($h);
02193
02194 if ($options['maxW']) {
02195 if ($w) {
02196 if ($w>$options['maxW']) {
02197 $w=$options['maxW'];
02198 $max=1;
02199 }
02200 } else {
02201 if ($info[0]>$options['maxW']) {
02202 $w=$options['maxW'];
02203 $max=1;
02204 }
02205 }
02206 }
02207 if ($options['maxH']) {
02208 if ($h) {
02209 if ($h>$options['maxH']) {
02210 $h=$options['maxH'];
02211 $max=1;
02212 }
02213 } else {
02214 if ($info[1]>$options['maxH']) {
02215 $h=$options['maxH'];
02216 $max=1;
02217 }
02218 }
02219 }
02220 $out['origW']=$w;
02221 $out['origH']=$h;
02222 $out['max'] = $max;
02223
02224 if (!$this->mayScaleUp) {
02225 if ($w>$info[0]){$w=$info[0];}
02226 if ($h>$info[1]){$h=$info[1];}
02227 }
02228 if ($w || $h) {
02229 if ($w && !$h) {
02230 $info[1] = ceil($info[1]*($w/$info[0]));
02231 $info[0] = $w;
02232 }
02233 if (!$w && $h) {
02234 $info[0] = ceil($info[0]*($h/$info[1]));
02235 $info[1] = $h;
02236 }
02237 if ($w && $h) {
02238 if ($max) {
02239 $ratio = $info[0]/$info[1];
02240 if ($h*$ratio > $w) {
02241 $h = round($w/$ratio);
02242 } else {
02243 $w = round($h*$ratio);
02244 }
02245 }
02246 $info[0] = $w;
02247 $info[1] = $h;
02248 }
02249 }
02250 $out[0]=$info[0];
02251 $out[1]=$info[1];
02252
02253 if ($options['minW'] && $out[0]<$options['minW']) {
02254 if ($max && $out[0]) {
02255 $out[1]= round($out[1]*$options['minW']/$out[0]);
02256 }
02257 $out[0]=$options['minW'];
02258 }
02259 if ($options['minH'] && $out[1]<$options['minH']) {
02260 if ($max && $out[1]) {
02261 $out[0]= round($out[0]*$options['minH']/$out[1]);
02262 }
02263 $out[1]=$options['minH'];
02264 }
02265
02266 return $out;
02267 }
02268
02277 function file_exists_typo3temp_file($output,$orig='') {
02278 if ($this->enable_typo3temp_db_tracking) {
02279 if (@file_exists($output)) {
02280 return 1;
02281 } else {
02282 $md5Hash=md5($output);
02283 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('md5hash', 'cache_typo3temp_log', 'md5hash="'.$GLOBALS['TYPO3_DB']->quoteStr($md5Hash, 'cache_typo3temp_log').'" AND tstamp>'.(time()-30));
02284 if ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
02285 if (is_object($GLOBALS['TSFE'])) $GLOBALS['TSFE']->set_no_cache();
02286 if (is_object($GLOBALS['TT'])) $GLOBALS['TT']->setTSlogMessage('typo3temp_log: Assume this file is being rendered now: '.$output);
02287 return 2;
02288 } else {
02289
02290 $insertFields = array(
02291 'md5hash' => $md5Hash,
02292 'tstamp' => time(),
02293 'filename' => $output,
02294 'orig_filename' => $orig
02295 );
02296 $GLOBALS['TYPO3_DB']->exec_DELETEquery('cache_typo3temp_log', 'md5hash="'.$GLOBALS['TYPO3_DB']->quoteStr($md5Hash, 'cache_typo3temp_log').'"');
02297 $GLOBALS['TYPO3_DB']->exec_INSERTquery('cache_typo3temp_log', $insertFields);
02298
02299 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);
02300 return 0;
02301 }
02302 }
02303 } else {
02304 return @file_exists($output);
02305 }
02306 }
02307
02308
02309
02310
02311
02312
02313
02314
02315
02316
02317
02318
02319
02320
02321
02322
02323
02324
02325
02326
02327
02328
02329
02330
02338 function imageMagickIdentify($imagefile) {
02339 if (!$this->NO_IMAGE_MAGICK) {
02340 $frame = $this->noFramePrepended?'':'[0]';
02341 $cmd = $this->imageMagickPath.'identify '.$this->wrapFileName($imagefile).$frame;
02342 exec($cmd, $returnVal);
02343 $splitstring=$returnVal[0];
02344 $this->IM_commands[] = Array ('identify',$cmd,$returnVal[0]);
02345 if ($splitstring) {
02346 ereg('([^\.]*)$',$imagefile,$reg);
02347 $splitinfo = explode(' ', $splitstring);
02348 while (list($key,$val) = each($splitinfo)) {
02349 $temp = '';
02350 if ($val) {$temp = explode('x', $val);}
02351 if (intval($temp[0]) && intval($temp[1])) {
02352 $dim=$temp;
02353 break;
02354 }
02355 }
02356 if ($dim[0] && $dim[1]) {
02357 return Array($dim[0], $dim[1], strtolower($reg[0]), $imagefile);
02358 }
02359 }
02360 }
02361 }
02362
02372 function imageMagickExec($input,$output,$params) {
02373 if (!$this->NO_IMAGE_MAGICK) {
02374 $cmd = $this->imageMagickPath.'convert '.$params.' '.$this->wrapFileName($input).' '.$this->wrapFileName($output);
02375 $this->IM_commands[] = Array ($output,$cmd);
02376 return exec($cmd);
02377 }
02378 }
02379
02390 function combineExec($input,$overlay,$mask,$output) {
02391 if (!$this->NO_IMAGE_MAGICK) {
02392 $cmd = $this->imageMagickPath.$this->combineScript.' -compose over '.$this->wrapFileName($input).' '.$this->wrapFileName($overlay).' '.$this->wrapFileName($mask).' '.$this->wrapFileName($output);
02393 $this->IM_commands[] = Array ($output,$cmd);
02394 exec($cmd);
02395 }
02396 }
02397
02405 function wrapFileName($inputName) {
02406 if (strstr($inputName,' ')) {
02407 $inputName='"'.$inputName.'"';
02408 }
02409 return $inputName;
02410 }
02411
02412
02413
02414
02415
02416
02417
02418
02419
02420
02421
02422
02423
02424
02425
02426
02427
02428
02429
02430
02431
02432
02433
02434
02435
02436
02437
02438
02439
02446 function checkFile($file) {
02447 if (@is_file($file)) {
02448 return $file;
02449 } else {
02450 return '';
02451 }
02452 }
02453
02460 function createTempSubDir($dirName) {
02461
02462
02463 if (t3lib_div::isFirstPartOfStr($this->tempPath,PATH_site)) {
02464 $tmpPath = $this->tempPath;
02465 } else {
02466 $tmpPath = PATH_site.$this->tempPath;
02467 }
02468
02469
02470 if (!@is_dir($tmpPath.$dirName)) {
02471 return t3lib_div::mkdir($tmpPath.$dirName);
02472 }
02473 }
02474
02482 function applyImageMagickToPHPGif(&$im, $command) {
02483 $tmpStr = $this->randomName();
02484 $theFile = $tmpStr.'.'.$this->gifExtension;
02485 $this->ImageGif($im, $theFile);
02486 $this->imageMagickExec($theFile,$theFile,$command);
02487 $tmpImg = $this->imageCreateFromGif($theFile);
02488 if ($tmpImg) {
02489 ImageDestroy($im);
02490 $im = $tmpImg;
02491 $this->w = imagesx($im);
02492 $this->h = imagesy($im);
02493 }
02494 if (!$this->dontUnlinkTempFiles) {
02495 unlink($theFile);
02496 }
02497 }
02498
02508 function gif_or_jpg($type,$w,$h) {
02509 if ($type=='ai' || $w*$h < $this->pixelLimitGif) {
02510 return $this->gifExtension;
02511 } else {
02512 return 'jpg';
02513 }
02514 }
02515
02525 function output($file) {
02526 if ($file) {
02527 ereg('([^\.]*)$',$file,$reg);
02528 $ext=strtolower($reg[0]);
02529 switch($ext) {
02530 case $this->gifExtension:
02531 if ($this->ImageGif($this->im, $file)) {
02532
02533 if($this->setup['reduceColors']) {
02534 $this->imageMagickExec($file,$file,' -colors '.t3lib_div::intInRange($this->setup['reduceColors'],2,255));
02535 t3lib_div::gif_compress($file,'');
02536 } else {
02537 t3lib_div::gif_compress($file, 'IM');
02538 }
02539 }
02540 break;
02541 case 'jpg':
02542 case 'jpeg':
02543 $tmpStr = $this->randomName();
02544 $theFile = $tmpStr.'.'.$this->gifExtension;
02545 if ($this->ImageGif($this->im, $theFile)) {
02546
02547 $operations='';
02548 if($this->setup['quality']) {
02549 $operations.=' -quality '.t3lib_div::intInRange($this->setup['quality'],10,100);
02550 }
02551 $this->imageMagickExec($theFile,$file,$operations);
02552 if (!$this->dontUnlinkTempFiles) {
02553 unlink($theFile);
02554 }
02555 }
02556 break;
02557 }
02558 $GLOBALS['TEMP_IMAGES_ON_PAGE'][]=$file;
02559 }
02560 return $file;
02561 }
02562
02569 function destroy() {
02570 ImageDestroy($this->im);
02571 }
02572
02579 function imgTag ($imgInfo) {
02580 return '<img src="'.$imgInfo[3].'" width="'.$imgInfo[0].'" height="'.$imgInfo[1].'" border="0" alt="" />';
02581 }
02582
02591 function ImageGif($destImg, $theImage) {
02592 imageinterlace ($destImg,0);
02593 if ($this->gifExtension=='gif') {
02594 return ImageGif($destImg, $theImage);
02595 }
02596 if ($this->gifExtension=='png') {
02597 return ImagePng($destImg, $theImage);
02598 }
02599 }
02600
02608 function imageCreateFromGif($sourceImg) {
02609 $imgInf = pathinfo($sourceImg);
02610 $ext = strtolower($imgInf['extension']);
02611
02612
02613 if ($ext=='gif' && function_exists('imagecreatefromgif')) {
02614 return imageCreateFromGif($sourceImg);
02615 }
02616
02617 if ($ext=='png' && function_exists('imagecreatefrompng')) {
02618 return imageCreateFromPng($sourceImg);
02619 }
02620
02621 if (($ext=='jpg' || $ext=='jpeg') && function_exists('imagecreatefromjpeg')) {
02622 return imageCreateFromJpeg($sourceImg);
02623 }
02624
02625
02626 $i = @getimagesize($sourceImg);
02627 $im = imagecreate($i[0],$i[1]);
02628 ImageColorAllocate($im, 128,128,128);
02629 return $im;
02630 }
02631 }
02632
02633
02634 if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_stdgraphic.php']) {
02635 include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_stdgraphic.php']);
02636 }
02637 ?>