public function save($thumbnail, $thumbDest, $targetMime = null)
 {
     $command = '';
     $width = $this->sourceWidth;
     $height = $this->sourceHeight;
     $x = $y = 0;
     // @kuba: quick fix to accept crop options
     if (isset($this->options['crop']) && $this->options['crop'] == true) {
         $cropWidth = isset($this->options['crop_width']) ? $this->options['crop_width'] : 0;
         $cropHeight = isset($this->options['crop_height']) ? $this->options['crop_height'] : 0;
         if ($cropWidth == 0 && $cropHeight != 0) {
             $cropWidth = $thumbnail->getThumbWidth() * ($cropHeight / $thumbnail->getThumbHeight());
         }
         if ($cropHeight == 0 && $cropWidth != 0) {
             $cropHeight = $thumbnail->getThumbHeight() * ($cropWidth / $thumbnail->getThumbWidth());
         }
         if ($cropWidth == 0 && $cropHeight == 0) {
             $cropWidth = $thumbnail->getThumbWidth();
             $cropHeight = $thumbnail->getThumbHeight();
         }
         $changeThumbDimensions = false;
         if ($thumbnail->getThumbWidth() == $width && $thumbnail->getThumbHeight() == $height) {
             $changeThumbDimensions = true;
         }
         $cropX = isset($this->options['crop_x']) ? $this->options['crop_x'] : (int) ($width / 2 - $cropWidth / 2);
         $cropY = isset($this->options['crop_y']) ? $this->options['crop_y'] : (int) ($height / 2 - $cropHeight / 2);
         if (!in_array(substr($cropX, 0, 1), array('+', '-'))) {
             $cropX = '+' . $cropX;
         }
         if (!in_array(substr($cropY, 0, 1), array('+', '-'))) {
             $cropY = '+' . $cropY;
         }
         $command .= sprintf(' -crop %dx%d%s%s %s - | %s -', $cropWidth, $cropHeight, $cropX, $cropY, escapeshellarg($this->image), $this->magickCommands['convert']);
         $this->image = '-';
         $command .= ' -thumbnail ';
         $command .= $changeThumbDimensions ? $cropWidth . 'x' . $cropHeight : $thumbnail->getThumbWidth() . 'x' . $thumbnail->getThumbHeight();
     } else {
         switch (@$this->options['method']) {
             case "shave_all":
                 if ($width > $height) {
                     $x = ceil(($width - $height) / 2);
                     $width = $height;
                 } elseif ($height > $width) {
                     $y = ceil(($height - $width) / 2);
                     $height = $width;
                 }
                 $command = sprintf(" -shave %dx%d", $x, $y);
                 break;
             case "shave_bottom":
                 if ($width > $height) {
                     $x = ceil(($width - $height) / 2);
                     $width = $height;
                 } elseif ($height > $width) {
                     $y = 0;
                     $height = $width;
                 }
                 if (is_null($thumbDest)) {
                     $command = sprintf(" -crop %dx%d+%d+%d %s '-' | %s", $width, $height, $x, $y, escapeshellarg($this->image), $this->magickCommands['convert']);
                     $this->image = '-';
                 } else {
                     $command = sprintf(" -crop %dx%d+%d+%d %s %s && %s", $width, $height, $x, $y, escapeshellarg($this->image), escapeshellarg($thumbDest), $this->magickCommands['convert']);
                     $this->image = $thumbDest;
                 }
                 break;
         }
         // end switch
         $command .= ' -thumbnail ';
         $command .= $thumbnail->getThumbWidth() . 'x' . $thumbnail->getThumbHeight();
     }
     // absolute sizing
     if (!$this->scale) {
         $command .= '!';
     }
     if ($this->quality && $thumbnail->getMime() == 'image/jpeg') {
         $command .= ' -quality ' . $this->quality . '% ';
     }
     // extract images such as pages from a pdf doc
     $extract = '';
     if (isset($this->options['extract']) && is_int($this->options['extract'])) {
         if ($this->options['extract'] > 0) {
             $this->options['extract']--;
         }
         $extract = '[' . escapeshellarg($this->options['extract']) . '] ';
     }
     $output = is_null($thumbDest) ? '-' : $thumbDest;
     $output = (($mime = array_search($targetMime, $this->mimeMap)) ? $mime . ':' : '') . $output;
     $cmd = $this->magickCommands['convert'] . ' ' . $command . ' ' . escapeshellarg($this->image) . $extract . ' ' . escapeshellarg($output);
     is_null($thumbDest) ? passthru($cmd) : exec($cmd);
     //WATERMARKING
     if (isset($this->options['watermark_path'])) {
         $waterMarkFileName = $this->options['watermark_path'];
         if ($cropWidth) {
             $thumbWidth = $cropWidth;
         } else {
             $thumbWidth = $thumbnail->getThumbWidth();
         }
         if ($thumbWitdh * 0.25 > 200) {
             $watermarkWidth = 200;
         } else {
             $watermarkWidth = (int) ($thumbWidth * 0.25);
         }
         if (!isset($this->options['watermark_min_width']) || $this->options['watermark_min_width'] <= $thumbWidth || !isset($this->options['watermark_min_height']) || $this->options['watermark_min_height'] <= $thumbHeight) {
             $watermarkThumbnail = new gyThumbnailCache($waterMarkFileName, (int) $watermarkWidth, null, true);
             $waterMarkPath = $watermarkThumbnail->getPath();
             $watermarkCmd = 'composite -gravity NorthWest ' . $waterMarkPath . ' ' . $thumbDest . ' ' . $thumbDest;
             exec($watermarkCmd, $s);
         }
     }
 }
 /**
  * This function takes a file and returns a path to it's thumb
  * 
  */
 public static function gy_thumbnail_cache_path($photo, $w = null, $h = null, $options = null)
 {
     $w = $w ? $w : 0;
     $h = $h ? $h : 0;
     $thumb = gyThumbnailCache::getNewInstance($photo, $w, $h);
     return $thumb->getPath();
 }