Index: includes/file.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/file.inc,v
retrieving revision 1.174
diff -u -r1.174 file.inc
--- includes/file.inc	10 Jul 2009 04:08:20 -0000	1.174
+++ includes/file.inc	12 Jul 2009 08:24:08 -0000
@@ -1164,32 +1164,48 @@
  *   A Drupal file object. This function may resize the file affecting its
  *   size.
  * @param $maximum_dimensions
- *   An optional string in the form WIDTHxHEIGHT e.g. '640x480' or '85x85'. If
+ *   (optional) A string in the form WIDTHxHEIGHT e.g. '640x480' or '85x85'. If
  *   an image toolkit is installed the image will be resized down to these
  *   dimensions. A value of 0 indicates no restriction on size, so resizing
  *   will be attempted.
  * @param $minimum_dimensions
- *   An optional string in the form WIDTHxHEIGHT. This will check that the
+ *   (optional) A string in the form WIDTHxHEIGHT. This will check that the
  *   image meets a minimum size. A value of 0 indicates no restriction.
+ * @param $scale
+ *   (optional) Boolean value to scale the image down to fit within the maximum
+ *   dimensions if it is too large. Note that this may be resource intensive
+ *   if the upload image is very large.
  * @return
  *   An array. If the file is an image and did not meet the requirements, it
  *   will contain an error message.
  *
  * @see hook_file_validate()
  */
-function file_validate_image_resolution($file, $maximum_dimensions = 0, $minimum_dimensions = 0) {
+function file_validate_image_resolution($file, $maximum_dimensions = 0, $minimum_dimensions = 0, $scale = TRUE) {
   $errors = array();
 
+  list($max_width, $max_height) = explode('x', $maximum_dimensions);
+  list($min_width, $min_height) = explode('x', $minimum_dimensions);
+
   // Check first that the file is an image.
   if ($info = image_get_info($file->filepath)) {
     if ($maximum_dimensions) {
       // Check that it is smaller than the given dimensions.
-      list($width, $height) = explode('x', $maximum_dimensions);
-      if ($info['width'] > $width || $info['height'] > $height) {
+      if ($info['width'] > $max_width || $info['height'] > $max_height) {
+        $ratio = min($max_width/$info['width'], $max_height/$info['height']);
+        // Check for exact dimension requirements (scaling allowed).
+        if (strcmp($minimum_dimensions, $maximum_dimensions) == 0 && $info['width']/$max_width != $info['height']/$max_height) {
+          $errors[] = t('The image must be exactly %dimensions pixels.', array('%dimensions' => $maximum_dimensions));
+        }
+        // Check that scaling won't drop the image below the minimum dimensions.
+        elseif (image_get_toolkit() && (($info['width'] * $ratio < $min_width) || ($info['height'] * $ratio < $min_height))) {
+          $errors[] = t('The image will not fit between the dimensions of %min_dimensions and %max_dimensions pixels.', array('%min_dimensions' => $minimum_dimensions, '%max_dimensions' => $maximum_dimensions));
+        }
         // Try to resize the image to fit the dimensions.
-        if ($image = image_load($file->filepath)) {
-          image_scale($image, $width, $height);
+        elseif ($scale && $image = image_load($file->filepath)) {
+          image_scale($image, $max_width, $max_height);
           image_save($image);
+          // Clear the cached filesize and refresh the image information.
           $file->filesize = $image->info['file_size'];
           drupal_set_message(t('The image was resized to fit within the maximum allowed dimensions of %dimensions pixels.', array('%dimensions' => $maximum_dimensions)));
         }
@@ -1199,10 +1215,9 @@
       }
     }
 
-    if ($minimum_dimensions) {
+    if ($minimum_dimensions && empty($errors)) {
       // Check that it is larger than the given dimensions.
-      list($width, $height) = explode('x', $minimum_dimensions);
-      if ($info['width'] < $width || $info['height'] < $height) {
+      if ($info['width'] < $min_width || $info['height'] < $min_height) {
         $errors[] = t('The image is too small; the minimum dimensions are %dimensions pixels.', array('%dimensions' => $minimum_dimensions));
       }
     }
