Fix to prevent auto-thumbnailer to run on images whose decoding has failed (causing CPU cycles being wasted resulting in sometimes affecting performance of CPU intensive applications such as the video player)
diff --git a/src/com/cooliris/cache/BootReceiver.java b/src/com/cooliris/cache/BootReceiver.java
index 35fc3c3..2ca5455 100644
--- a/src/com/cooliris/cache/BootReceiver.java
+++ b/src/com/cooliris/cache/BootReceiver.java
@@ -58,6 +58,7 @@
             PicasaDataSource.sThumbnailCache.close();
             CacheService.sAlbumCache.close();
             CacheService.sMetaAlbumCache.close();
+            CacheService.sSkipThumbnailIds.flush();
         }
     }
 }
diff --git a/src/com/cooliris/cache/CacheService.java b/src/com/cooliris/cache/CacheService.java
index 602e207..6b8f9f0 100644
--- a/src/com/cooliris/cache/CacheService.java
+++ b/src/com/cooliris/cache/CacheService.java
@@ -57,6 +57,7 @@
     public static final String ACTION_CACHE = "com.cooliris.cache.action.CACHE";
     public static final DiskCache sAlbumCache = new DiskCache("local-album-cache");
     public static final DiskCache sMetaAlbumCache = new DiskCache("local-meta-cache");
+    public static final DiskCache sSkipThumbnailIds = new DiskCache("local-skip-cache");
 
     private static final String TAG = "CacheService";
     private static ImageList sList = null;
@@ -603,14 +604,36 @@
             final long id = ids[i];
             final long timeModifiedInSec = timestamp[i];
             final long thumbnailId = thumbnailIds[i];
-            if (!thumbnailCache.isDataAvailable(thumbnailId, timeModifiedInSec * 1000)) {
-                buildThumbnailForId(context, thumbnailCache, thumbnailId, id, false, DEFAULT_THUMBNAIL_WIDTH,
-                        DEFAULT_THUMBNAIL_HEIGHT, timeModifiedInSec * 1000);
+            if (!isInThumbnailerSkipList(thumbnailId)) {
+                if (!thumbnailCache.isDataAvailable(thumbnailId, timeModifiedInSec * 1000)) {
+                    byte[] retVal = buildThumbnailForId(context, thumbnailCache, thumbnailId, id, false, DEFAULT_THUMBNAIL_WIDTH,
+                            DEFAULT_THUMBNAIL_HEIGHT, timeModifiedInSec * 1000);
+                    if (retVal == null || retVal.length == 0) {
+                        // There was an error in building the thumbnail.
+                        // We record this thumbnail id
+                        addToThumbnailerSkipList(thumbnailId);
+                    }
+                }
             }
         }
         Log.i(TAG, "DiskCache ready for all thumbnails.");
     }
 
+    private static void addToThumbnailerSkipList(long thumbnailId) {
+        sSkipThumbnailIds.put(thumbnailId, sDummyData, 0);
+        sSkipThumbnailIds.flush();
+    }
+
+    private static boolean isInThumbnailerSkipList(long thumbnailId) {
+        if (sSkipThumbnailIds.isDataAvailable(thumbnailId, 0)) {
+            byte[] data = sSkipThumbnailIds.get(thumbnailId, 0);
+            if (data.length > 0) {
+                return true;
+            }
+        }
+        return false;
+    }
+
     private static final byte[] buildThumbnailForId(final Context context, final DiskCache thumbnailCache, final long thumbId,
             final long origId, final boolean isVideo, final int thumbnailWidth, final int thumbnailHeight, final long timestamp) {
         if (origId == Shared.INVALID) {
@@ -650,7 +673,8 @@
             if (bitmap == null) {
                 return null;
             }
-            final byte[] retVal = writeBitmapToCache(thumbnailCache, thumbId, origId, bitmap, thumbnailWidth, thumbnailHeight, timestamp);
+            final byte[] retVal = writeBitmapToCache(thumbnailCache, thumbId, origId, bitmap, thumbnailWidth, thumbnailHeight,
+                    timestamp);
             return retVal;
         } catch (InterruptedException e) {
             return null;