pdfviewer: add --pages arg: render a certain page (all, all in desceding order, firsl, last and by page number)

Review URL: https://codereview.chromium.org/18584010

git-svn-id: http://skia.googlecode.com/svn/trunk@9999 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/experimental/PdfViewer/SkPdfRenderer.cpp b/experimental/PdfViewer/SkPdfRenderer.cpp
index 37867b4..f52d9a0 100644
--- a/experimental/PdfViewer/SkPdfRenderer.cpp
+++ b/experimental/PdfViewer/SkPdfRenderer.cpp
@@ -2013,7 +2013,7 @@
     return fPdfDoc->MediaBox(page);
 }
 
-size_t SkPdfRenderer::bytesUsed() {
+size_t SkPdfRenderer::bytesUsed() const {
     return fPdfDoc ? fPdfDoc->bytesUsed() : 0;
 }
 
diff --git a/experimental/PdfViewer/SkPdfRenderer.h b/experimental/PdfViewer/SkPdfRenderer.h
index ba556ff..d6d2c92 100644
--- a/experimental/PdfViewer/SkPdfRenderer.h
+++ b/experimental/PdfViewer/SkPdfRenderer.h
@@ -34,6 +34,7 @@
     int pages() const;
     void unload();
     SkRect MediaBox(int page) const;
+    size_t bytesUsed() const;
 };
 
 void reportPdfRenderStats();
diff --git a/experimental/PdfViewer/pdf_viewer_main.cpp b/experimental/PdfViewer/pdf_viewer_main.cpp
index 0b3b1aa..cc9c3ed 100644
--- a/experimental/PdfViewer/pdf_viewer_main.cpp
+++ b/experimental/PdfViewer/pdf_viewer_main.cpp
@@ -17,6 +17,14 @@
 DEFINE_string2(writePath, w, "", "Directory to write the rendered pages.");
 DEFINE_bool2(noExtensionForOnePagePdf, n, false, "No page extension if only one page.");
 DEFINE_bool2(showMemoryUsage, m, false, "Show Memory usage.");
+DEFINE_string2(pages, p, "all", "What pages to render and how:\n"
+                                "\tall - all pages\n"
+                                "\treverse - all pages, in reverse order\n"
+                                "\tfirst - first page\n"
+                                "\tlast - last page\n"
+                                "\tnumber - a specific page number\n"
+               );
+
 
 /**
  * Given list of directories and files to use as input, expects to find .pdf
@@ -122,6 +130,10 @@
 
     SkImageEncoder::EncodeFile(outputPath.c_str(), bitmap, SkImageEncoder::kPNG_Type, 100);
 
+    if (FLAGS_showMemoryUsage) {
+        SkDebugf("Memory usage after page %i rendered: %u\n", page < 0 ? 0 : page, (unsigned int)renderer.bytesUsed());
+    }
+
     return true;
 }
 
@@ -131,7 +143,7 @@
  * @param renderer The object responsible to render the skp object into pdf.
  */
 static bool process_pdf(const SkString& inputPath, const SkString& outputDir,
-                        SkPdfRenderer& renderer, bool noPageExt, bool showMemoryUsage) {
+                        SkPdfRenderer& renderer) {
     SkDebugf("Loading PDF:  %s\n", inputPath.c_str());
 
     SkString inputFilename;
@@ -149,7 +161,7 @@
     success = renderer.load(inputPath);
 
     if (success) {
-        if (showMemoryUsage) {
+        if (FLAGS_showMemoryUsage) {
             SkDebugf("Memory usage after load: %u\n", (unsigned int)renderer.bytesUsed());
         }
         if (!renderer.pages())
@@ -157,9 +169,21 @@
             SkDebugf("ERROR: Empty PDF Document %s\n", inputPath.c_str());
             return false;
         } else {
-            for (int pn = 0; pn < renderer.pages(); ++pn) {
-                success = render_page(outputDir, inputFilename, renderer, noPageExt && renderer.pages() == 1 ? -1 : pn) && success;
-                SkDebugf("Memory usage after page %i rendered: %u\n", pn, (unsigned int)renderer.bytesUsed());
+            if (strcmp(FLAGS_pages[0], "all") == 0) {
+                for (int pn = 0; pn < renderer.pages(); ++pn) {
+                    success = render_page(outputDir, inputFilename, renderer, FLAGS_noExtensionForOnePagePdf && renderer.pages() == 1 ? -1 : pn) && success;
+                }
+            } else if (strcmp(FLAGS_pages[0], "reverse") == 0) {
+                for (int pn = renderer.pages() - 1; pn >= 0; --pn) {
+                    success = render_page(outputDir, inputFilename, renderer, FLAGS_noExtensionForOnePagePdf && renderer.pages() == 1 ? -1 : pn) && success;
+                }
+            } else if (strcmp(FLAGS_pages[0], "first") == 0) {
+                success = render_page(outputDir, inputFilename, renderer, FLAGS_noExtensionForOnePagePdf && renderer.pages() == 1 ? -1 : 0) && success;
+            } else if (strcmp(FLAGS_pages[0], "last") == 0) {
+                success = render_page(outputDir, inputFilename, renderer, FLAGS_noExtensionForOnePagePdf && renderer.pages() == 1 ? -1 : renderer.pages() - 1) && success;
+            } else {
+                int pn = atoi(FLAGS_pages[0]);
+                success = render_page(outputDir, inputFilename, renderer, FLAGS_noExtensionForOnePagePdf && renderer.pages() == 1 ? -1 : renderer.pages() - 1) && pn;
             }
         }
     }
@@ -174,7 +198,7 @@
  * @param renderer The object responsible to render the skp object into pdf.
  */
 static int process_input(const char* input, const SkString& outputDir,
-                         SkPdfRenderer& renderer, bool noPageExt, bool showMemoryUsage) {
+                         SkPdfRenderer& renderer) {
     int failures = 0;
     if (sk_isdir(input)) {
         SkOSFile::Iter iter(input, PDF_FILE_EXTENSION);
@@ -184,13 +208,13 @@
             SkString _input;
             _input.append(input);
             sk_tools::make_filepath(&inputPath, _input, inputFilename);
-            if (!process_pdf(inputPath, outputDir, renderer, noPageExt, showMemoryUsage)) {
+            if (!process_pdf(inputPath, outputDir, renderer)) {
                 ++failures;
             }
         }
     } else {
         SkString inputPath(input);
-        if (!process_pdf(inputPath, outputDir, renderer, noPageExt, showMemoryUsage)) {
+        if (!process_pdf(inputPath, outputDir, renderer)) {
             ++failures;
         }
     }
@@ -216,9 +240,7 @@
 
     int failures = 0;
     for (int i = 0; i < FLAGS_readPath.count(); i ++) {
-        failures += process_input(FLAGS_readPath[i], outputDir, renderer,
-                                  FLAGS_noExtensionForOnePagePdf,
-                                  FLAGS_showMemoryUsage);
+        failures += process_input(FLAGS_readPath[i], outputDir, renderer);
         renderer.unload();
     }
 
diff --git a/experimental/PdfViewer/pdfparser/native/SkNativeParsedPDF.cpp b/experimental/PdfViewer/pdfparser/native/SkNativeParsedPDF.cpp
index bd46577..dd8ec44 100644
--- a/experimental/PdfViewer/pdfparser/native/SkNativeParsedPDF.cpp
+++ b/experimental/PdfViewer/pdfparser/native/SkNativeParsedPDF.cpp
@@ -417,7 +417,7 @@
     return (SkPdfObject*)ref;
 }
 
-size_t SkNativeParsedPDF::bytesUsed() {
+size_t SkNativeParsedPDF::bytesUsed() const {
     return fAllocator->bytesUsed() +
            fContentLength +
            fObjects.count() * sizeof(PublicObjectEntry) +
diff --git a/experimental/PdfViewer/pdfparser/native/SkNativeParsedPDF.h b/experimental/PdfViewer/pdfparser/native/SkNativeParsedPDF.h
index 48442fd..b91d574 100644
--- a/experimental/PdfViewer/pdfparser/native/SkNativeParsedPDF.h
+++ b/experimental/PdfViewer/pdfparser/native/SkNativeParsedPDF.h
@@ -62,7 +62,7 @@
     SkPdfObject* resolveReference(const SkPdfObject* ref);
 
     // Reports an approximation of all the memory usage.
-    size_t bytesUsed();
+    size_t bytesUsed() const;
 
 private:
 
diff --git a/experimental/PdfViewer/pdfparser/native/SkPdfNativeTokenizer.h b/experimental/PdfViewer/pdfparser/native/SkPdfNativeTokenizer.h
index f544ff3..399fba9 100644
--- a/experimental/PdfViewer/pdfparser/native/SkPdfNativeTokenizer.h
+++ b/experimental/PdfViewer/pdfparser/native/SkPdfNativeTokenizer.h
@@ -104,7 +104,7 @@
         return data;
     }
 
-    size_t bytesUsed() {
+    size_t bytesUsed() const {
         return fSizeInBytes;
     }
 };