--- orig/image/image.module	2007-09-26 15:40:42.000000000 -0400
+++ patched/image/image.module	2007-09-30 19:03:19.000000000 -0400
@@ -628,27 +628,9 @@
   }
   $node->rebuild_images = FALSE;
 
-  // Figure out which sizes should have been generated.
-  $all_sizes = image_get_sizes();
-  unset($all_sizes[IMAGE_ORIGINAL]);
-  $needed_sizes = array_keys(image_get_derivative_sizes($original_path));
-  $unneeded_sizes = array_diff(array_keys($all_sizes), $needed_sizes);
-
-  // Derivative sizes that are larger than the original get set to the 
-  // original.
-  foreach ($unneeded_sizes as $key) {
-    if (empty($node->images[$key])) {
-      $node->images[$key] = $original_path;
-    } 
-    else {
-      // Need to remove an extra derivative image in the database.
-      drupal_set_message(t("%title's has an unneeded %key derivative images. The derivatives will be rebuilt to remove it.", array('%title' => $node->title, '%key' => $key)));
-      $node->rebuild_images = TRUE;
-    }
-  }
-
   // Check that the derivative images are present and current.
-  foreach ($needed_sizes as $key) {
+  foreach (image_get_sizes() as $key => $size) {
+    if ($key == '_original') continue;
     // If the file is missing or created after the last change to the sizes,
     // rebuild the derivatives.
     if (empty($node->images[$key]) || !file_exists($node->images[$key])) {
@@ -672,19 +654,8 @@
  * Implementation of hook_insert
  */
 function image_insert($node) {
-  // Derivative images that aren't needed are set to the original file. Make
-  // note of the current path before calling _image_insert() because if it's
-  // in the temp directory it'll be moved. We'll need it later to determine
-  // which derivative images need to be saved with _image_insert().
-  $original_path = $node->images[IMAGE_ORIGINAL];
-
-  // Save the original first so that it if it's moved the derivatives are
-  // placed in the correct directory.
-  _image_insert($node, IMAGE_ORIGINAL, $original_path);
-
-  $sizes = image_get_derivative_sizes($node->images[IMAGE_ORIGINAL]);
-  foreach ($sizes as $key => $size_info) {
-    if (!empty($node->images[$key]) && $node->images[$key] != $original_path) {
+  foreach (image_get_sizes() as $key => $size_info) {
+    if (!empty($node->images[$key])) {
       _image_insert($node, $key, $node->images[$key]);
     }
   }
@@ -748,8 +719,7 @@
       $node->rebuild_images = FALSE;
     }
 
-    $sizes = image_get_derivative_sizes($node->images[IMAGE_ORIGINAL]);
-    foreach ($sizes as $key => $size_info) {
+    foreach (image_get_sizes() as $key => $size_info) {
       if (!empty($node->images[$key]) && $node->images[$key] != $original_path) {
         _image_insert($node, $key, $node->images[$key]);
       }
@@ -892,40 +862,6 @@
 }
 
 /**
- * Determine which sizes of derivative images need to be built for this image.
- *
- * @param $image_path
- *   String file path to the image.
- * @return
- *   Returns a subset of image_get_sizes()'s results depending on what
- *   derivative images are needed.
- */
-function image_get_derivative_sizes($image_path) {
-  $sizes = array();
-
-  // Can't do much if we can't read the image.
-  if (!$image_info = image_get_info($image_path)) {
-    return $sizes;
-  }
-
-  $all_sizes = image_get_sizes(NULL, $image_info['height'] / $image_info['width']);
-  foreach ($all_sizes as $key => $size) {
-    // We don't want to include the original.
-    if ($key == IMAGE_ORIGINAL) {
-      continue;
-    }
-
-    // If the original isn't bigger than the requested size then there's no
-    // need to resize it.
-    if ($image_info['width'] > $size['width'] || $image_info['height'] > $size['height']) {
-      $sizes[$key] = $size;
-    }
-  }
-
-  return $sizes;
-}
-
-/**
  * Generate image derivatives.
  */
 function _image_build_derivatives(&$node, $temp = FALSE) {
@@ -935,23 +871,40 @@
   }
   $original_path = file_create_path($node->images[IMAGE_ORIGINAL]);
 
-  // Figure out which sizes we need to generate.
-  $all_sizes = image_get_sizes();
-  $needed_sizes = image_get_derivative_sizes($original_path);
-  $unneeded_sizes = array_diff(array_keys($all_sizes), array_keys($needed_sizes));
-
-  // Images that don't need a derivative image get set to the original.
-  foreach ($unneeded_sizes as $key) {
-    $node->images[$key] = $original_path;
-  }
-
   // Resize for the necessary sizes.
   $image_info = image_get_info($original_path);
-  foreach ($needed_sizes as $key => $size) {
+  foreach (image_get_sizes() as $key => $size) {
+    if ($key == '_original') continue;
     $destination = _image_filename($original_path, $key, $temp);
 
+    // If the original is already within size limits, just hardlink or copy it.
+    if ($image_info['width'] <= $size['width'] && $image_info['height'] <= $size['height']) {
+    	$size['operation'] = 'link';
+    }
     $status = FALSE;
     switch ($size['operation']) {
+      case 'link':
+        $drupalroot=$_SERVER['DOCUMENT_ROOT'].base_path();
+        $dst = $drupalroot . $destination;
+        $src = $drupalroot . $original_path;
+        if (file_exists($src)) {
+          if (file_exist($dst)) {
+            unlink($dst);
+          }
+          // Try a hardlink first
+	  if (function_exists('link')) {
+            link($src,$dst);
+          }
+	  // If the hardlink fails or is unavailable, try a copy
+          if (! file_exists($dst)) {
+            copy($src,$dst);
+          }
+          // Make sure the destination exists before declaring victory
+          if (file_exists($dst)) {
+            $status = TRUE;
+          }
+        }
+        break;
       // Depending on the operation, the image will be scaled or resized & cropped
       case 'scale':
         $status = image_scale($original_path, $destination, $size['width'], $size['height']);
