function copyFile(PhingFile $sourceFile, PhingFile $destFile, $overwrite = false, $preserveLastModified = true, &$filterChains = null, Project $project)
 {
     // writes to tmp file first, then rename it to avoid file locking race
     // conditions
     $parent = $destFile->getParentFile();
     $tmpFile = new PhingFile($parent, substr(md5(time()), 0, 8));
     parent::copyFile($sourceFile, $tmpFile, $overwrite, $preserveLastModified, $filterChains, $project);
     $tmpFile->renameTo($destFile);
 }
 private function resizeImage($source, $parameters, $preview = false, $custom_settings = null)
 {
     // TODO *******
     //
     // Leider bietet diese drecks GD-Lib keine M�glichkeit, einen "out of memory"-Fehler zu umgehen,
     // oder vorauszusehen, wann ein Bild zu gro� f�r den Speicher ist.
     //
     // Daher sollte hier noch ein Mechanismus geschaffen werden, um voraus zu berechnen, wieviel Speicher
     // es brauchen wird, das Bild zu laden und einen Fehlercode zur�ckzugeben, falls der Speicher nicht reicht!
     // gew�nschte JPEG-Kompression feststellen
     $source_path_info = pathinfo($source);
     $source_ext = UTF8String::strtolower($source_path_info['extension']);
     if ($source_ext == 'jpg' || $source_ext == 'jpg' || $source_ext == 'jpe') {
         if ($this->isParameterPositiveNumber($parameters, 'jpegQuality')) {
             $jpeqQuality = $parameters['jpegQuality'];
         } else {
             $jpeqQuality = Config::get()->jpegQuality;
         }
     } else {
         $jpeqQuality = null;
     }
     // Erstmal keine Gr��en�nderung annehmen
     $mode = 'copy';
     // Pr�fen, ob maximal-Werte angegeben sind
     $max_width = 0;
     $max_height = 0;
     if ($this->isParameterPositiveNumber($parameters, 'maxWidth')) {
         $max_width = $parameters['maxWidth'];
     }
     if ($this->isParameterPositiveNumber($parameters, 'maxHeight')) {
         $max_height = $parameters['maxHeight'];
     }
     // Wenn Maximal-Werte gesetzt sind, Einpassung annehmen
     if ($max_width > 0 || $max_height > 0) {
         $mode = 'fitIn';
     }
     // Pr�fen, ob genaue Abmessungen gefordert sind
     $force_width = 0;
     $force_height = 0;
     if ($this->isParameterPositiveNumber($parameters, 'forceWidth')) {
         $force_width = $parameters['forceWidth'];
     }
     if ($this->isParameterPositiveNumber($parameters, 'forceHeight')) {
         $force_height = $parameters['forceHeight'];
     }
     // ggf. Benutzereingaben auswerten
     if ($custom_settings !== null) {
         // der Benutzer hat selbst eine Gr��e festgelegt...
         // diese Werte �berschreiben forceWidth und forceHeight
         if ($this->sanitizeBoolean($custom_settings['customSize'])) {
             if ($this->sanitizeInteger($custom_settings['width']) > 0) {
                 $force_width = $this->sanitizeInteger($custom_settings['width']);
             } else {
                 $force_width = 0;
             }
             if ($this->sanitizeInteger($custom_settings['height']) > 0) {
                 $force_height = $this->sanitizeInteger($custom_settings['height']);
             } else {
                 $force_height = 0;
             }
         }
         // der Benutzer hat einen Ausschnitt festgelegt oder die s/w option gew�hlt...
         if ($this->sanitizeBoolean($custom_settings['customCrop']) || $this->sanitizeBoolean($custom_settings['convertToBlackAndWhite'])) {
             $tmp_file = APPLICATION_ROOT . 'user-data/tmp/images/' . $this->getRandomFilenameWithTimeStamp($source);
             $tmp_image = WideImage::load($source);
             if ($this->sanitizeBoolean($custom_settings['customCrop'])) {
                 $tmp_image = $tmp_image->crop($this->sanitizeInteger($custom_settings['cropX1']), $this->sanitizeInteger($custom_settings['cropY1']), $this->sanitizeInteger($custom_settings['cropX2']) - $this->sanitizeInteger($custom_settings['cropX1']), $this->sanitizeInteger($custom_settings['cropY2']) - $this->sanitizeInteger($custom_settings['cropY1']));
             }
             if ($this->sanitizeBoolean($custom_settings['convertToBlackAndWhite'])) {
                 $tmp_image = $tmp_image->asGrayscale();
             }
             $this->saveImage($tmp_image, $tmp_file, $jpeqQuality);
             $tmp_image->destroy();
             $source = $tmp_file;
         }
     }
     // Wenn genaue Abmessungen gefordert sind, entsprechenden Modus setzen...
     if ($force_width > 0 && $force_height > 0) {
         $mode = 'exact';
     } elseif ($force_width > 0) {
         $mode = 'forceWidth';
     } elseif ($force_height > 0) {
         $mode = 'forceHeight';
     }
     // Tempor�ren Dateinamen erstellen
     $temp_file_name = $this->getRandomFilenameWithTimeStamp($source);
     $relative_path_to_dest_file = 'user-data/tmp/images/' . $temp_file_name;
     $absolute_path_to_dest_file = APPLICATION_ROOT . $relative_path_to_dest_file;
     // Je nach Modus Bild kopieren / ge�nderte Version speichern
     $result = true;
     try {
         switch ($mode) {
             case 'copy':
                 // keine Gr��en�nderung erfoderlich
                 $result = FileUtils::copyFile($source, $absolute_path_to_dest_file);
                 break;
             case 'exact':
                 // Gr��e genau vorgegeben
                 $image = WideImage::load($source);
                 $image_dimensions = $this->getDimensions($image);
                 $resized_image = $image->resize($force_width, $force_height, 'outside', 'any');
                 $resized_image_dimensions = $this->getDimensions($resized_image);
                 $image->destroy();
                 if ($resized_image->getWidth() > $force_width || $resized_image->getHeight() > $force_height) {
                     $crop_x = 0;
                     if ($resized_image->getWidth() > $force_width) {
                         $crop_x = floor(($resized_image->getWidth() - $force_width) / 2);
                     }
                     $crop_y = 0;
                     if ($resized_image->getHeight() > $force_height) {
                         $crop_y = floor(($resized_image->getHeight() - $force_height) / 2);
                     }
                     $cropped_image = $resized_image->crop($crop_x, $crop_y, $force_width, $force_height);
                     $resized_image->destroy();
                     $this->saveImage($cropped_image, $absolute_path_to_dest_file, $jpeqQuality);
                     $cropped_image->destroy();
                 } else {
                     if ($this->equalDimensions($image_dimensions, $resized_image_dimensions)) {
                         FileUtils::copyFile($source, $absolute_path_to_dest_file);
                     } else {
                         $this->saveImage($resized_image, $absolute_path_to_dest_file, $jpeqQuality);
                     }
                     $resized_image->destroy();
                 }
                 break;
             case 'forceWidth':
                 // Breite vorgegeben
                 $image = WideImage::load($source);
                 $image_dimensions = $this->getDimensions($image);
                 $resized_image = $image->resize($force_width, null, 'outside', 'any');
                 $resized_image_dimensions = $this->getDimensions($resized_image);
                 $image->destroy();
                 if ($max_height > 0 && $resized_image->getHeight() > $max_height) {
                     $crop_y = 0;
                     if ($resized_image->getHeight() > $max_height) {
                         $crop_y = floor(($resized_image->getHeight() - $max_height) / 2);
                     }
                     $cropped_image = $resized_image->crop(0, $crop_y, $force_width, $max_height);
                     $resized_image->destroy();
                     $this->saveImage($cropped_image, $absolute_path_to_dest_file, $jpeqQuality);
                     $cropped_image->destroy();
                 } else {
                     if ($this->equalDimensions($image_dimensions, $resized_image_dimensions)) {
                         FileUtils::copyFile($source, $absolute_path_to_dest_file);
                     } else {
                         $this->saveImage($resized_image, $absolute_path_to_dest_file, $jpeqQuality);
                     }
                     $resized_image->destroy();
                 }
                 break;
             case 'forceHeight':
                 // H�he vorgegeben
                 $image = WideImage::load($source);
                 $image_dimensions = $this->getDimensions($image);
                 $resized_image = $image->resize(null, $force_height, 'outside', 'any');
                 $resized_image_dimensions = $this->getDimensions($resized_image);
                 $image->destroy();
                 if ($max_width > 0 && $resized_image->getWidth() > $max_width) {
                     $crop_x = 0;
                     if ($resized_image->getWidth() > $max_width) {
                         $crop_x = floor(($resized_image->getWidth() - $max_width) / 2);
                     }
                     $cropped_image = $resized_image->crop($crop_x, 0, $max_width, $force_height);
                     $resized_image->destroy();
                     $this->saveImage($cropped_image, $absolute_path_to_dest_file, $jpeqQuality);
                     $cropped_image->destroy();
                 } else {
                     if ($this->equalDimensions($image_dimensions, $resized_image_dimensions)) {
                         FileUtils::copyFile($source, $absolute_path_to_dest_file);
                     } else {
                         $this->saveImage($resized_image, $absolute_path_to_dest_file, $jpeqQuality);
                     }
                     $resized_image->destroy();
                 }
                 break;
             case 'fitIn':
                 // in angegebenes Rechteck einpassen
                 $image = WideImage::load($source);
                 $image_dimensions = $this->getDimensions($image);
                 if ($max_width == 0) {
                     $max_width = null;
                 }
                 if ($max_height == 0) {
                     $max_height = null;
                 }
                 $resized_image = $image->resize($max_width, $max_height, 'inside', 'down');
                 $resized_image_dimensions = $this->getDimensions($resized_image);
                 $image->destroy();
                 if ($this->equalDimensions($image_dimensions, $resized_image_dimensions)) {
                     FileUtils::copyFile($source, $absolute_path_to_dest_file);
                 } else {
                     $this->saveImage($resized_image, $absolute_path_to_dest_file, $jpeqQuality);
                 }
                 $resized_image->destroy();
                 break;
         }
     } catch (WideImage_Exception $e) {
         $result = false;
     }
     // im Erfolgsfall zum Stammverzeichnis relativen Pfad zur�ckgeben
     if ($result) {
         // M�glicherweise wird das Bild nochmal von einem geladenen Plugin bearbeitet
         $plugin_parameters = array('source' => $source, 'parameters' => $parameters, 'preview' => $preview, 'customSettings' => $custom_settings);
         Plugins::call(Plugins::AFTER_IMAGE_RESIZE, $plugin_parameters, $relative_path_to_dest_file);
         return $relative_path_to_dest_file;
     } else {
         return false;
     }
 }