Add the lazy decoder from PictureFlags to SkImageDecoder

R=caryclark@google.com, scroggo@google.com

Author: sglez@google.com

Review URL: https://chromiumcodereview.appspot.com/19109002

git-svn-id: http://skia.googlecode.com/svn/trunk@10111 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/tools/LazyDecodeBitmap.cpp b/tools/LazyDecodeBitmap.cpp
new file mode 100644
index 0000000..2367154
--- /dev/null
+++ b/tools/LazyDecodeBitmap.cpp
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2013 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "LazyDecodeBitmap.h"
+
+#include "PictureRenderingFlags.h"  // --deferImageDecoding is defined here.
+#include "SkBitmap.h"
+#include "SkData.h"
+#include "SkImageDecoder.h"
+#include "SkForceLinking.h"
+#include "SkLruImageCache.h"
+#include "SkPurgeableImageCache.h"
+#include "SkCommandLineFlags.h"
+
+__SK_FORCE_IMAGE_DECODER_LINKING;
+
+DEFINE_bool(useVolatileCache, false, "Use a volatile cache for deferred image decoding pixels. "
+            "Only meaningful if --deferImageDecoding is set to true and the platform has an "
+            "implementation.");
+
+SkLruImageCache gLruImageCache(1024 * 1024);
+
+namespace sk_tools {
+
+// Simple cache selector to choose between a purgeable cache for large images and the standard one
+// for smaller images.
+//
+class CacheSelector : public SkBitmapFactory::CacheSelector {
+
+public:
+    CacheSelector() {
+        fPurgeableImageCache = SkPurgeableImageCache::Create();
+    }
+
+    ~CacheSelector() {
+        SkSafeUnref(fPurgeableImageCache);
+    }
+
+    virtual SkImageCache* selectCache(const SkImage::Info& info) SK_OVERRIDE {
+        if (info.fWidth * info.fHeight > 32 * 1024 && fPurgeableImageCache != NULL) {
+            return fPurgeableImageCache;
+        }
+        return &gLruImageCache;
+    }
+private:
+    SkImageCache* fPurgeableImageCache;
+};
+
+static CacheSelector gCacheSelector;
+static SkBitmapFactory gFactory(&SkImageDecoder::DecodeMemoryToTarget);
+
+bool LazyDecodeBitmap(const void* buffer, size_t size, SkBitmap* bitmap) {
+    void* copiedBuffer = sk_malloc_throw(size);
+    memcpy(copiedBuffer, buffer, size);
+    SkAutoDataUnref data(SkData::NewFromMalloc(copiedBuffer, size));
+
+    static bool gOnce;
+    if (!gOnce) {
+        // Only use the cache selector if there is a purgeable image cache to use for large
+        // images.
+        if (FLAGS_useVolatileCache && SkAutoTUnref<SkImageCache>(
+                SkPurgeableImageCache::Create()).get() != NULL) {
+            gFactory.setCacheSelector(&gCacheSelector);
+        } else {
+            gFactory.setImageCache(&gLruImageCache);
+        }
+        gOnce = true;
+    }
+    return gFactory.installPixelRef(data, bitmap);
+}
+
+}  // namespace sk_tools
diff --git a/tools/LazyDecodeBitmap.h b/tools/LazyDecodeBitmap.h
new file mode 100644
index 0000000..ecceb94
--- /dev/null
+++ b/tools/LazyDecodeBitmap.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright 2013 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef LazyDecodeBitmap_DEFINED
+#define LazyDecodeBitmap_DEFINED
+
+#include "SkTypes.h"
+
+class SkBitmap;
+
+namespace sk_tools {
+
+/**
+ * Decode the image with DecodeMemoryToTarget but defer the process until it is needed.
+ */
+bool LazyDecodeBitmap(const void* buffer, size_t size, SkBitmap* bitmap);
+
+}
+
+#endif  // LazyDecodeBitmap_DEFINED
diff --git a/tools/PictureRenderingFlags.cpp b/tools/PictureRenderingFlags.cpp
index 4255773..dfa28a0 100644
--- a/tools/PictureRenderingFlags.cpp
+++ b/tools/PictureRenderingFlags.cpp
@@ -10,14 +10,11 @@
 #include "CopyTilesRenderer.h"
 #include "PictureRenderer.h"
 #include "picture_utils.h"
-
 #include "SkBitmapFactory.h"
 #include "SkCommandLineFlags.h"
 #include "SkData.h"
 #include "SkImage.h"
 #include "SkImageDecoder.h"
-#include "SkLruImageCache.h"
-#include "SkPurgeableImageCache.h"
 #include "SkString.h"
 
 // Alphabetized list of flags used by this file or bench_ and render_pictures.
@@ -64,9 +61,6 @@
 DEFINE_double(scale, 1, "Set the scale factor.");
 DEFINE_string(tiles, "", "Used with --mode copyTile to specify number of tiles per larger tile "
               "in the x and y directions.");
-DEFINE_bool(useVolatileCache, false, "Use a volatile cache for deferred image decoding pixels. "
-            "Only meaningful if --deferImageDecoding is set to true and the platform has an "
-            "implementation.");
 DEFINE_string(viewport, "", "width height: Set the viewport.");
 
 sk_tools::PictureRenderer* parseRenderer(SkString& error, PictureTool tool) {
@@ -341,51 +335,3 @@
     return renderer.detach();
 }
 
-SkLruImageCache gLruImageCache(1024*1024);
-
-// Simple cache selector to choose between a purgeable cache for large images and the standard one
-// for smaller images.
-class MyCacheSelector : public SkBitmapFactory::CacheSelector {
-
-public:
-    MyCacheSelector() {
-        fPurgeableImageCache = SkPurgeableImageCache::Create();
-    }
-
-    ~MyCacheSelector() {
-        SkSafeUnref(fPurgeableImageCache);
-    }
-
-    virtual SkImageCache* selectCache(const SkImage::Info& info) SK_OVERRIDE {
-        if (info.fWidth * info.fHeight > 32 * 1024 && fPurgeableImageCache != NULL) {
-            return fPurgeableImageCache;
-        }
-        return &gLruImageCache;
-    }
-private:
-    SkImageCache* fPurgeableImageCache;
-};
-
-static MyCacheSelector gCacheSelector;
-static SkBitmapFactory gFactory(&SkImageDecoder::DecodeMemoryToTarget);
-
-bool lazy_decode_bitmap(const void* buffer, size_t size, SkBitmap* bitmap);
-bool lazy_decode_bitmap(const void* buffer, size_t size, SkBitmap* bitmap) {
-    void* copiedBuffer = sk_malloc_throw(size);
-    memcpy(copiedBuffer, buffer, size);
-    SkAutoDataUnref data(SkData::NewFromMalloc(copiedBuffer, size));
-
-    static bool gOnce;
-    if (!gOnce) {
-        // Only use the cache selector if there is a purgeable image cache to use for large
-        // images.
-        if (FLAGS_useVolatileCache && SkAutoTUnref<SkImageCache>(
-                SkPurgeableImageCache::Create()).get() != NULL) {
-            gFactory.setCacheSelector(&gCacheSelector);
-        } else {
-            gFactory.setImageCache(&gLruImageCache);
-        }
-        gOnce = true;
-    }
-    return gFactory.installPixelRef(data, bitmap);
-}
diff --git a/tools/bench_pictures_main.cpp b/tools/bench_pictures_main.cpp
index 720621e..eea9644 100644
--- a/tools/bench_pictures_main.cpp
+++ b/tools/bench_pictures_main.cpp
@@ -7,11 +7,11 @@
 
 #include "BenchTimer.h"
 #include "CopyTilesRenderer.h"
+#include "LazyDecodeBitmap.h"
 #include "PictureBenchmark.h"
 #include "PictureRenderingFlags.h"
 #include "SkBenchLogger.h"
 #include "SkCommandLineFlags.h"
-#include "SkForceLinking.h"
 #include "SkGraphics.h"
 #include "SkImageDecoder.h"
 #if LAZY_CACHE_STATS
@@ -24,8 +24,6 @@
 #include "SkStream.h"
 #include "picture_utils.h"
 
-__SK_FORCE_IMAGE_DECODER_LINKING;
-
 SkBenchLogger gLogger;
 
 // Flags used by this file, in alphabetical order.
@@ -145,9 +143,8 @@
     return result;
 }
 
-// These are defined in PictureRenderingFlags.cpp
+// Defined in LazyDecodeBitmap.cpp
 extern SkLruImageCache gLruImageCache;
-extern bool lazy_decode_bitmap(const void* buffer, size_t size, SkBitmap* bitmap);
 
 #if LAZY_CACHE_STATS
 static int32_t gTotalCacheHits;
@@ -170,12 +167,12 @@
     SkASSERT(gLruImageCache.getImageCacheUsed() == 0);
     if (FLAGS_countRAM) {
         // Set the limit to zero, so all pixels will be kept
-        gLruImageCache.setImageCacheLimit(0);
+      gLruImageCache.setImageCacheLimit(0);
     }
 
     SkPicture::InstallPixelRefProc proc;
     if (FLAGS_deferImageDecoding) {
-        proc = &lazy_decode_bitmap;
+        proc = &sk_tools::LazyDecodeBitmap;
     } else {
         proc = &SkImageDecoder::DecodeMemory;
     }
diff --git a/tools/lua/lua_pictures.cpp b/tools/lua/lua_pictures.cpp
index f1bca28..355a823 100644
--- a/tools/lua/lua_pictures.cpp
+++ b/tools/lua/lua_pictures.cpp
@@ -5,6 +5,7 @@
  * found in the LICENSE file.
  */
 
+#include "LazyDecodeBitmap.h"
 #include "SkLua.h"
 #include "SkLuaCanvas.h"
 #include "SkPicture.h"
@@ -15,9 +16,6 @@
 #include "picture_utils.h"
 #include "SkOSFile.h"
 #include "SkImageDecoder.h"
-#include "SkForceLinking.h"
-
-__SK_FORCE_IMAGE_DECODER_LINKING;
 
 extern "C" {
     #include "lua.h"
@@ -30,9 +28,6 @@
 static const char gAccumulateFunc[] = "sk_scrape_accumulate";
 static const char gSummarizeFunc[] = "sk_scrape_summarize";
 
-// PictureRenderingFlags.cpp
-extern bool lazy_decode_bitmap(const void* buffer, size_t size, SkBitmap*);
-
 // Example usage for the modulo flag:
 // for i in {0..5}; do lua_pictures --skpPath SKP_PATH -l YOUR_SCRIPT --modulo $i 6 &; done
 DEFINE_string(modulo, "", "[--modulo <remainder> <divisor>]: only run tests for which "
@@ -46,7 +41,7 @@
     SkAutoTUnref<SkStream> stream(SkStream::NewFromFile(path));
     SkPicture* pic = NULL;
     if (stream.get()) {
-        pic = SkPicture::CreateFromStream(stream.get(), &lazy_decode_bitmap);
+        pic = SkPicture::CreateFromStream(stream.get(), &sk_tools::LazyDecodeBitmap);
     }
     return pic;
 }
diff --git a/tools/pinspect.cpp b/tools/pinspect.cpp
index 969d87c..306bf6f 100644
--- a/tools/pinspect.cpp
+++ b/tools/pinspect.cpp
@@ -5,6 +5,7 @@
  * found in the LICENSE file.
  */
 
+#include "LazyDecodeBitmap.h"
 #include "SkBitmap.h"
 #include "SkCanvas.h"
 #include "SkGraphics.h"
@@ -14,12 +15,6 @@
 #include "SkStream.h"
 #include "SkString.h"
 #include "SkDumpCanvas.h"
-#include "SkForceLinking.h"
-
-__SK_FORCE_IMAGE_DECODER_LINKING;
-
-// Defined in PictureRenderingFlags.cpp
-extern bool lazy_decode_bitmap(const void* buffer, size_t size, SkBitmap* bitmap);
 
 static SkPicture* inspect(const char path[]) {
     SkFILEStream stream(path);
@@ -40,7 +35,7 @@
     }
 
     stream.rewind();
-    SkPicture* pic = SkPicture::CreateFromStream(&stream, &lazy_decode_bitmap);
+    SkPicture* pic = SkPicture::CreateFromStream(&stream, &sk_tools::LazyDecodeBitmap);
     if (NULL == pic) {
         SkDebugf("Could not create SkPicture: %s\n", path);
         return NULL;
diff --git a/tools/render_pictures_main.cpp b/tools/render_pictures_main.cpp
index de477d3..a2dff67 100644
--- a/tools/render_pictures_main.cpp
+++ b/tools/render_pictures_main.cpp
@@ -5,11 +5,11 @@
  * found in the LICENSE file.
  */
 
+#include "LazyDecodeBitmap.h"
 #include "CopyTilesRenderer.h"
 #include "SkBitmap.h"
 #include "SkDevice.h"
 #include "SkCommandLineFlags.h"
-#include "SkForceLinking.h"
 #include "SkGraphics.h"
 #include "SkImageDecoder.h"
 #include "SkImageEncoder.h"
@@ -22,9 +22,6 @@
 #include "PictureRenderingFlags.h"
 #include "picture_utils.h"
 
-// Required to ensure that image decoders get linked correctly.
-__SK_FORCE_IMAGE_DECODER_LINKING;
-
 // Flags used by this file, alphabetically:
 DEFINE_int32(clone, 0, "Clone the picture n times before rendering.");
 DECLARE_bool(deferImageDecoding);
@@ -49,9 +46,6 @@
     path->remove(path->size() - 4, 4);
 }
 
-// Defined in PictureRenderingFlags.cpp
-extern bool lazy_decode_bitmap(const void* buffer, size_t size, SkBitmap* bitmap);
-
 ////////////////////////////////////////////////////////////////////////////////////////////////////
 
 /**
@@ -151,7 +145,7 @@
 
     SkPicture::InstallPixelRefProc proc;
     if (FLAGS_deferImageDecoding) {
-        proc = &lazy_decode_bitmap;
+        proc = &sk_tools::LazyDecodeBitmap;
     } else if (FLAGS_writeEncodedImages) {
         SkASSERT(!FLAGS_writePath.isEmpty());
         reset_image_file_base_name(inputFilename);