Added ability to extract SkBitmaps to filter tool

https://codereview.appspot.com/6748043/



git-svn-id: http://skia.googlecode.com/svn/trunk@6021 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/src/core/SkPictureRecord.h b/src/core/SkPictureRecord.h
index c36c24a..77e0114 100644
--- a/src/core/SkPictureRecord.h
+++ b/src/core/SkPictureRecord.h
@@ -174,8 +174,10 @@
     SkBBoxHierarchy* fBoundingHierarchy;
     SkPictureStateTree* fStateTree;
 
-private:
+    // Allocated in the constructor and managed by this class.
     SkBitmapHeap* fBitmapHeap;
+
+private:
     SkChunkFlatController fFlattenableHeap;
 
     SkMatrixDictionary fMatrices;
diff --git a/tools/filtermain.cpp b/tools/filtermain.cpp
index a804c4c..b415219 100644
--- a/tools/filtermain.cpp
+++ b/tools/filtermain.cpp
@@ -5,30 +5,67 @@
  * found in the LICENSE file.
  */
 
+#include "SkDevice.h"
 #include "SkGraphics.h"
+#include "SkImageEncoder.h"
 #include "SkPicture.h"
+#include "SkPicturePlayback.h"
+#include "SkPictureRecord.h"
 #include "SkStream.h"
 
 static void usage() {
-    SkDebugf("Usage: filter -i inFile -o outFile [-h|--help]");
+    SkDebugf("Usage: filter -i inFile [-o outFile] [-t textureDir] [-h|--help]");
     SkDebugf("\n\n");
     SkDebugf("    -i inFile  : file to file.\n");
     SkDebugf("    -o outFile : result of filtering.\n");
+    SkDebugf("    -t textureDir : directory in which to place textures.\n");
     SkDebugf("    -h|--help  : Show this help message.\n");
 }
 
+// SkFilterRecord allows the filter to manipulate the read in SkPicture
+class SkFilterRecord : public SkPictureRecord {
+public:
+    SkFilterRecord(uint32_t recordFlags, SkDevice* device)
+        : INHERITED(recordFlags, device) {
+    }
+
+    void saveImages(const SkString& path) {
+        SkTRefArray<SkBitmap>* bitmaps = fBitmapHeap->extractBitmaps();
+
+        if (NULL != bitmaps) {
+            for (int i = 0; i < bitmaps->count(); ++i) {
+                SkString filename(path);
+                if (!path.endsWith("\\")) {
+                    filename.append("\\");
+                }
+                filename.append("image");
+                filename.appendS32(i);
+                filename.append(".png");
+
+                SkImageEncoder::EncodeFile(filename.c_str(), (*bitmaps)[i],
+                                           SkImageEncoder::kPNG_Type, 0);
+            }
+        }
+
+        bitmaps->unref();
+    }
+
+private:
+    typedef SkPictureRecord INHERITED;
+};
+
 // This function is not marked as 'static' so it can be referenced externally
 // in the iOS build.
 int tool_main(int argc, char** argv) {
     SkGraphics::Init();
 
-    SkString inFile, outFile;
-
-    if (argc < 5) {
+    if (argc < 3) {
         usage();
         return -1;
     }
 
+    SkString inFile, outFile, textureDir;
+
     char* const* stop = argv + argc;
     for (++argv; argv < stop; ++argv) {
         if (strcmp(*argv, "-i") == 0) {
@@ -36,7 +73,7 @@
             if (argv < stop && **argv) {
                 inFile.set(*argv);
             } else {
-                SkDebugf("missing arg for --i\n");
+                SkDebugf("missing arg for -i\n");
                 usage();
                 return -1;
             }
@@ -45,7 +82,16 @@
             if (argv < stop && **argv) {
                 outFile.set(*argv);
             } else {
-                SkDebugf("missing arg for --o\n");
+                SkDebugf("missing arg for -o\n");
+                usage();
+                return -1;
+            }
+        } else if (strcmp(*argv, "-t") == 0) {
+            argv++;
+            if (argv < stop && **argv) {
+                textureDir.set(*argv);
+            } else {
+                SkDebugf("missing arg for -t\n");
                 usage();
                 return -1;
             }
@@ -59,6 +105,11 @@
         }
     }
 
+    if (inFile.isEmpty()) {
+        usage();
+        return -1;
+    }
+
     SkPicture* inPicture = NULL;
 
     SkFILEStream inStream(inFile.c_str());
@@ -71,12 +122,30 @@
         return -1;
     }
 
-    SkPicture outPicture;
-    inPicture->draw(outPicture.beginRecording(inPicture->width(), inPicture->height()));
-    outPicture.endRecording();
+    if (!outFile.isEmpty()) {
+        // Playback the read in picture to another picture to allow whatever
+        // translation occurs inside Skia to occur
+        SkPicture outPicture;
+        inPicture->draw(outPicture.beginRecording(inPicture->width(), inPicture->height()));
+        outPicture.endRecording();
 
-    SkFILEWStream outStream(outFile.c_str());
-    outPicture.serialize(&outStream);
+        SkFILEWStream outStream(outFile.c_str());
+        outPicture.serialize(&outStream);
+    }
+
+    if (!textureDir.isEmpty()) {
+        SkBitmap bm;
+        bm.setConfig(SkBitmap::kNo_Config, inPicture->width(), inPicture->height());
+        SkAutoTUnref<SkDevice> dev(SkNEW_ARGS(SkDevice, (bm)));
+
+        SkFilterRecord filterRecord(0, dev);
+
+        filterRecord.beginRecording();
+        inPicture->draw(&filterRecord);
+        filterRecord.endRecording();
+
+        filterRecord.saveImages(textureDir);
+    }
 
     SkGraphics::Term();