Index: modules/image/image.module
===================================================================
RCS file: /cvs/drupal/contributions/modules/image/image.module,v
retrieving revision 1.197.2.6
diff -u -r1.197.2.6 image.module
--- modules/image/image.module	1 Mar 2007 04:05:48 -0000	1.197.2.6
+++ modules/image/image.module	23 Jul 2007 10:40:53 -0000
@@ -291,12 +291,87 @@
   while ($file = db_fetch_object($result)) {
     $node->images[$file->filename] = $file->filepath;
   }
-  // special images
-  if (empty($node->images['thumbnail'])) {
-    $node->images['thumbnail'] = $node->images['_original'];
+  // The $node->images array should now contains the original, plus
+  // any sizes that are smaller than the original.
+  // Image sizes that are not smaller than the original were not saved,
+  // so we now recreate them.
+  // For image derivatives already defined, check that they are up to date,
+  // i.e. that image module settings haven't changed since they were created.
+  
+  // First make sure we've actually got the original
+  if (empty($node->images['_original'])) {
+    // Failed to load _original filename
+    // TODO: error message to watchdog
+    return;
+  }
+  //assert($node->images['_original']);
+  $original = $node->images['_original'];
+  // Also make sure that the original image file exists and we can get its info
+  $info = image_get_info(file_create_path($original));
+  if (!$info) {
+    // Failed to find the file & get its size info
+    // TODO: error message to watchdog
+    return;
+  }
+  //assert($info);
+  // We've got an original image file, it exists, and we've got its size info.
+
+  // If the settings have changed since any image derivative was created,
+  // or any required (smaller) derivatives are missing,
+  // we need to (re)build the image derivatives.
+  $rebuild_required = FALSE;
+  $sizes = _image_get_sizes();  // NB: Does not include '_original'
+  $image_settings_updated = variable_get('image_updated', 0);
+
+  foreach ($sizes as $size) {
+    // Make sure label exists
+    if (empty($size['label'])) {
+      continue;
+    }
+    //assert($size['label']);
+    $label = $size['label'];
+    if (!empty($node->images[$label])) {
+      // We have a filename for this size label
+      $image = $node->images[$label];
+      if ($image != $original) {
+        // The image derivative filename is different from the original. So make sure the file exists,
+        // and that the image module settings were not updated since the file was last modified
+        $imagefile = file_create_path($node->images[$label]);
+        if (!file_exists($imagefile) || ($image_settings_updated > filemtime($imagefile))) {
+          $rebuild_required = TRUE;      
+          break;
+        }
+      }
+    }
+    elseif ((!empty($size['width']) && ($size['width'] < $info['width'])) || 
+            (!empty($size['height']) && ($size['height'] < $info['height']))) {
+      // The image derivative was not loaded, but is smaller than the original, 
+      // so a rebuild is required
+      $rebuild_required = TRUE;      
+      break;
+    }
+  }
+
+  // Rebuild derivatives if required
+  if ($rebuild_required) {
+    _image_build_derivatives($node);
+    // TODO: Check if this worked OK. 
+    // If it failed, we will keep trying to rebuild each time we load the image
+    // Preventing this would require the image node to save a failure flag somewhere
   }
-  if (empty($node->images['preview'])) {
-    $node->images['preview'] = $node->images['_original'];
+  else {
+    // No rebuild required, so for the remaining missing labels 
+    // with nonempty label and nonzero size we use the original
+    foreach ($sizes as $size) {
+      // Make sure label exists
+      if (empty($size['label'])) {
+        continue;
+      }
+      $label = $size['label'];
+      if (empty($node->images[$label]) && ($size['width'] || $size['height'])) {
+        $node->images[$label] = $original;
+      }
+    }
   }
 }
 
@@ -363,13 +438,6 @@
  * Create an <img> tag for an image.
  */
 function image_display(&$node, $label = 'preview', $attributes = array()) {
-  // regenerate images?
-  if ($node->images[$label] != $node->images['_original'] &&
-      (!file_exists(file_create_path($node->images[$label])) ||
-       filemtime(file_create_path($node->images[$label])) < variable_get('image_updated', 0))) {
-    _image_build_derivatives($node);
-  }
-
   if (empty($node->images[$label])) {
     return;
   }
