/**
  * Resize to $width x $height but keep the image proportion
  *
  * @param integer $width Max width
  * @param integer $height Max height
  * @param string $boundary Limit the scale action: drecrease or increase 
  *   only. If $boundary is NULL than don't limit
  * @param boolean $mutate Save the transformation in internal resource or
  *   create new image and keep internal as is?
  * @return SimpleGdImage
  */
 function scale($width, $height, $boundary = null, $mutate = true)
 {
     if (!is_resource($this->resource) || get_resource_type($this->resource) != 'gd') {
         return false;
     }
     $width = (int) $width > 0 ? (int) $width : 1;
     $height = (int) $height > 0 ? (int) $height : 1;
     $scale = min($width / $this->getWidth(), $height / $this->getHeight());
     if ($boundary == self::BOUNDARY_DECREASE_ONLY) {
         if ($scale > 1) {
             if ($mutate) {
                 return;
             } else {
                 $new_image = new SimpleGdImage();
                 $new_image->createFromResource($this->resource);
                 return $new_image;
             }
             // if
         }
         // if
     } elseif ($boundary == self::BOUNDARY_INCREASE_ONLY) {
         if ($scale < 1) {
             if ($mutate) {
                 return;
             } else {
                 $new_image = new SimpleGdImage();
                 $new_image->createFromResource($this->resource);
                 return $new_image;
             }
             // if
         }
         // if
     }
     // if
     $new_width = floor($scale * $this->getWidth());
     $new_height = floor($scale * $this->getHeight());
     if ($this->getImageType() == IMAGETYPE_GIF) {
         $new_resource = imagecreate($new_width, $new_height);
         $originaltransparentcolor = imagecolortransparent($this->resource);
         if ($originaltransparentcolor >= 0 && $originaltransparentcolor < imagecolorstotal($this->resource)) {
             // for animated GIF, imagecolortransparent will return a color index larger
             // than total colors, in this case the image is treated as opaque ( actually
             // it is opaque )
             $transparentcolor = imagecolorsforindex($this->resource, $originaltransparentcolor);
             $newtransparentcolor = imagecolorallocate($new_resource, $transparentcolor['red'], $transparentcolor['green'], $transparentcolor['blue']);
             // for true color image, we must fill the background manually
             imagefill($new_resource, 0, 0, $newtransparentcolor);
             // assign the transparent color in the thumbnail image
             imagecolortransparent($new_resource, $newtransparentcolor);
         }
     } else {
         $new_resource = imagecreatetruecolor($new_width, $new_height);
         imagealphablending($new_resource, false);
         imagesavealpha($new_resource, true);
     }
     // if
     imagecopyresampled($new_resource, $this->resource, 0, 0, 0, 0, $new_width, $new_height, $this->getWidth(), $this->getHeight());
     if ($mutate) {
         imagedestroy($this->resource);
         $this->resource = $new_resource;
         $this->width = $new_width;
         $this->height = $new_height;
         return true;
     } else {
         $new_image = new SimpleGdImage();
         $new_image->createFromResource($new_resource);
         return $new_image;
     }
     // if
 }
 /**
  * Resize to $width x $height but keep the image proportion
  *
  * @param integer $width Max width
  * @param integer $height Max height
  * @param string $boundary Limit the scale action: drecrease or increase 
  *   only. If $boundary is NULL than don't limit
  * @param boolean $mutate Save the transformation in internal resource or
  *   create new image and keep internal as is?
  * @return SimpleGdImage
  */
 function scale($width, $height, $boundary = null, $mutate = true)
 {
     if (!is_resource($this->resource) || get_resource_type($this->resource) != 'gd') {
         if (is_null($this->source)) {
             return false;
         }
     }
     $width = (int) $width > 0 ? (int) $width : 1;
     $height = (int) $height > 0 ? (int) $height : 1;
     $mem_allowed = 1024 * 1024 * 6;
     // 6 MB
     $image_mem_usage = $this->getWidth() * $this->getHeight() * 4;
     // 4 bytes per pixel (RGBA)
     if ($image_mem_usage > $mem_allowed) {
         $im = imagecreatetruecolor($width, $height);
         $white = imagecolorallocate($im, 0xff, 0xff, 0xff);
         $black = imagecolorallocate($im, 0x0, 0x0, 0xff);
         @imagefill($im, 0, 0, $white);
         $s = $this->getWidth() . "x" . $this->getHeight();
         @imagestring($im, 6, 10, 30, $s, $black);
         $this->resource = $im;
         $scale = 1;
     } else {
         $this->load();
         $scale = min($width / $this->getWidth(), $height / $this->getHeight());
     }
     if ($boundary == self::BOUNDARY_DECREASE_ONLY) {
         if ($scale >= 1) {
             if ($mutate) {
                 return;
             } else {
                 $new_image = new SimpleGdImage();
                 $new_image->createFromResource($this->resource);
                 return $new_image;
             }
             // if
         }
         // if
     } elseif ($boundary == self::BOUNDARY_INCREASE_ONLY) {
         if ($scale <= 1) {
             if ($mutate) {
                 return;
             } else {
                 $new_image = new SimpleGdImage();
                 $new_image->createFromResource($this->resource);
                 return $new_image;
             }
             // if
         }
         // if
     }
     // if
     $new_width = floor($scale * $this->getWidth());
     $new_height = floor($scale * $this->getHeight());
     switch ($this->getImageType()) {
         case IMAGETYPE_GIF:
             $new_resource = imagecreatetruecolor($new_width, $new_height);
             $colorcount = imagecolorstotal($this->resource);
             imagetruecolortopalette($new_resource, true, $colorcount);
             imagepalettecopy($new_resource, $this->resource);
             $transparentcolor = imagecolortransparent($this->resource);
             imagefill($new_resource, 0, 0, $transparentcolor);
             imagecolortransparent($new_resource, $transparentcolor);
             break;
         case IMAGETYPE_PNG:
             $new_resource = imagecreatetruecolor($new_width, $new_height);
             $transparent_color_index = imagecolortransparent($this->resource);
             if ($transparent_color_index >= 0) {
                 $transparent_color = imagecolorsforindex($this->resource, $transparent_color_index);
                 ${$transparent_color_index} = imagecolorallocate($new_resource, $transparent_color['red'], $transparent_color['green'], $transparent_color['blue']);
                 imagefill($new_resource, 0, 0, $transparent_color_index);
                 imagecolortransparent($new_resource, $transparent_color_index);
             } else {
                 imagealphablending($new_resource, false);
                 $color = imagecolorallocatealpha($new_resource, 0, 0, 0, 127);
                 imagefill($new_resource, 0, 0, $color);
                 imagesavealpha($new_resource, true);
             }
             break;
         default:
             $new_resource = imagecreatetruecolor($new_width, $new_height);
             break;
     }
     // switch
     imagecopyresampled($new_resource, $this->resource, 0, 0, 0, 0, $new_width, $new_height, $this->getWidth(), $this->getHeight());
     if ($mutate) {
         imagedestroy($this->resource);
         $this->resource = $new_resource;
         $this->width = $new_width;
         $this->height = $new_height;
         return true;
     } else {
         $new_image = new SimpleGdImage();
         $new_image->createFromResource($new_resource);
         return $new_image;
     }
     // if
 }
 /**
  * Resize to $width x $height but keep the image proportion
  *
  * @param integer $width Max width
  * @param integer $height Max height
  * @param string $boundary Limit the scale action: drecrease or increase 
  *   only. If $boundary is NULL than don't limit
  * @param boolean $mutate Save the transformation in internal resource or
  *   create new image and keep internal as is?
  * @return SimpleGdImage
  */
 function scale($width, $height, $boundary = null, $mutate = true)
 {
     if (!is_resource($this->resource) || get_resource_type($this->resource) != 'gd') {
         return false;
     }
     $width = (int) $width > 0 ? (int) $width : 1;
     $height = (int) $height > 0 ? (int) $height : 1;
     $scale = min($width / $this->getWidth(), $height / $this->getHeight());
     if ($boundary == self::BOUNDARY_DECREASE_ONLY) {
         if ($scale > 1) {
             if ($mutate) {
                 return;
             } else {
                 $new_image = new SimpleGdImage();
                 $new_image->createFromResource($this->resource);
                 return $new_image;
             }
             // if
         }
         // if
     } elseif ($boundary == self::BOUNDARY_INCREASE_ONLY) {
         if ($scale < 1) {
             if ($mutate) {
                 return;
             } else {
                 $new_image = new SimpleGdImage();
                 $new_image->createFromResource($this->resource);
                 return $new_image;
             }
             // if
         }
         // if
     }
     // if
     $new_width = floor($scale * $this->getWidth());
     $new_height = floor($scale * $this->getHeight());
     if ($this->getImageType() == IMAGETYPE_GIF) {
         $new_resource = imagecreate($new_width, $new_height);
     } else {
         $new_resource = imagecreatetruecolor($new_width, $new_height);
     }
     // if
     imagecopyresampled($new_resource, $this->resource, 0, 0, 0, 0, $new_width, $new_height, $this->getWidth(), $this->getHeight());
     if ($mutate) {
         imagedestroy($this->resource);
         $this->resource = $new_resource;
         $this->width = $new_width;
         $this->height = $new_height;
         return true;
     } else {
         $new_image = new SimpleGdImage();
         $new_image->createFromResource($new_resource);
         return $new_image;
     }
     // if
 }