Explicitly use PNG decoder in viewer

This also updates other uses of the PNG decoder to use either
libpng or rust.

Change-Id: I9799e7b1da3b0186d18e7433148f47bee46987e4
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/1140757
Auto-Submit: Kaylee Lubick <kjlubick@google.com>
Reviewed-by: Greg Daniel <egdaniel@google.com>
Commit-Queue: Greg Daniel <egdaniel@google.com>
diff --git a/bench/nanobench.cpp b/bench/nanobench.cpp
index bb13d73..d2cbc08 100644
--- a/bench/nanobench.cpp
+++ b/bench/nanobench.cpp
@@ -24,7 +24,6 @@
 #include "include/codec/SkAndroidCodec.h"
 #include "include/codec/SkCodec.h"
 #include "include/codec/SkJpegDecoder.h"
-#include "include/codec/SkPngDecoder.h"
 #include "include/core/SkBBHFactory.h"
 #include "include/core/SkCanvas.h"
 #include "include/core/SkData.h"
@@ -81,6 +80,12 @@
 #include "tools/graphite/GraphiteToolUtils.h"
 #endif
 
+#if defined(SK_CODEC_DECODES_PNG_WITH_RUST)
+#include "include/codec/SkPngRustDecoder.h"
+#else
+#include "include/codec/SkPngDecoder.h"
+#endif
+
 #include <cinttypes>
 #include <memory>
 #include <optional>
@@ -856,12 +861,14 @@
             return nullptr;
         }
         SkDeserialProcs procs;
-        procs.fImageDataProc = [](sk_sp<SkData> data, std::optional<SkAlphaType>, void* ctx) -> sk_sp<SkImage> {
-            if (!SkPngDecoder::IsPng(data->data(), data->size())) {
-                SkDebugf("non-png image serialized in skp\n");
-                return nullptr;
-            }
-            auto codec = SkPngDecoder::Decode(data, nullptr);
+        procs.fImageDataProc =
+                [](sk_sp<SkData> data, std::optional<SkAlphaType>, void* ctx) -> sk_sp<SkImage> {
+#if defined(SK_CODEC_DECODES_PNG_WITH_RUST)
+            std::unique_ptr<SkStream> stream = SkMemoryStream::Make(data);
+            auto codec = SkPngRustDecoder::Decode(std::move(stream), nullptr, nullptr);
+#else
+            auto codec = SkPngDecoder::Decode(data, nullptr, nullptr);
+#endif
             if (!codec) {
                 SkDebugf("Invalid png data detected\n");
                 return nullptr;
@@ -1385,7 +1392,11 @@
     }
 
     // Our benchmarks only currently decode .png or .jpg files
+#if defined(SK_CODEC_DECODES_PNG_WITH_RUST)
+    SkCodecs::Register(SkPngRustDecoder::Decoder());
+#else
     SkCodecs::Register(SkPngDecoder::Decoder());
+#endif
     SkCodecs::Register(SkJpegDecoder::Decoder());
 
     SkTaskGroup::Enabler enabled(FLAGS_threads);
diff --git a/tools/skpbench/skpbench.cpp b/tools/skpbench/skpbench.cpp
index 1368a3a..f80dd0d 100644
--- a/tools/skpbench/skpbench.cpp
+++ b/tools/skpbench/skpbench.cpp
@@ -8,7 +8,6 @@
 #include "bench/BigPath.h"
 #include "include/codec/SkCodec.h"
 #include "include/codec/SkJpegDecoder.h"
-#include "include/codec/SkPngDecoder.h"
 #include "include/core/SkCanvas.h"
 #include "include/core/SkGraphics.h"
 #include "include/core/SkPicture.h"
@@ -47,6 +46,12 @@
 #include "src/xml/SkDOM.h"
 #endif
 
+#if defined(SK_CODEC_DECODES_PNG_WITH_RUST)
+#include "include/codec/SkPngRustDecoder.h"
+#else
+#include "include/codec/SkPngDecoder.h"
+#endif
+
 #include <stdlib.h>
 #include <algorithm>
 #include <array>
@@ -525,7 +530,11 @@
     }
 
     SkGraphics::Init();
+#if defined(SK_CODEC_DECODES_PNG_WITH_RUST)
+    SkCodecs::Register(SkPngRustDecoder::Decoder());
+#else
     SkCodecs::Register(SkPngDecoder::Decoder());
+#endif
     SkCodecs::Register(SkJpegDecoder::Decoder());
 
     sk_sp<SkPicture> skp;
diff --git a/tools/viewer/SKPSlide.cpp b/tools/viewer/SKPSlide.cpp
index 55b80e8..a03088d 100644
--- a/tools/viewer/SKPSlide.cpp
+++ b/tools/viewer/SKPSlide.cpp
@@ -7,13 +7,23 @@
 
 #include "tools/viewer/SKPSlide.h"
 
+#include "include/codec/SkCodec.h"
 #include "include/core/SkCanvas.h"
+#include "include/core/SkImage.h"
 #include "include/core/SkPicture.h"
+#include "include/core/SkSerialProcs.h"
 #include "include/core/SkStream.h"
 #include "include/core/SkString.h"
 #include "include/private/base/SkDebug.h"
 #include "include/private/base/SkTo.h"
 
+#if defined(SK_CODEC_DECODES_PNG_WITH_RUST)
+#include "include/codec/SkPngRustDecoder.h"
+#else
+#include "include/codec/SkPngDecoder.h"
+#endif
+
+#include <memory>
 #include <utility>
 
 SKPSlide::SKPSlide(const SkString& name, const SkString& path)
@@ -49,7 +59,23 @@
         return;
     }
     fStream->rewind();
-    fPic = SkPicture::MakeFromStream(fStream.get());
+
+    SkDeserialProcs procs;
+    procs.fImageDataProc =
+            [](sk_sp<SkData> data, std::optional<SkAlphaType>, void*) -> sk_sp<SkImage> {
+#if defined(SK_CODEC_DECODES_PNG_WITH_RUST)
+        std::unique_ptr<SkStream> stream = SkMemoryStream::Make(data);
+        auto codec = SkPngRustDecoder::Decode(std::move(stream), nullptr, nullptr);
+#else
+        auto codec = SkPngDecoder::Decode(data, nullptr, nullptr);
+#endif
+        if (!codec) {
+            SkDebugf("Invalid png data detected\n");
+            return nullptr;
+        }
+        return std::get<0>(codec->getImage());
+    };
+    fPic = SkPicture::MakeFromStream(fStream.get(), &procs);
     if (!fPic) {
         SkDebugf("Could not parse SkPicture from skp stream for slide %s.\n", fName.c_str());
         return;
diff --git a/tools/viewer/Viewer.cpp b/tools/viewer/Viewer.cpp
index f92413a..06c421d7 100644
--- a/tools/viewer/Viewer.cpp
+++ b/tools/viewer/Viewer.cpp
@@ -9,6 +9,7 @@
 
 #include "bench/GpuTools.h"
 #include "gm/gm.h"
+#include "include/codec/SkCodec.h"
 #include "include/core/SkAlphaType.h"
 #include "include/core/SkBitmap.h"
 #include "include/core/SkBlendMode.h"
@@ -29,7 +30,6 @@
 #include "include/core/SkSurface.h"
 #include "include/core/SkSurfaceProps.h"
 #include "include/core/SkTextBlob.h"
-#include "include/encode/SkPngEncoder.h"
 #include "include/private/base/SkDebug.h"
 #include "include/private/base/SkTPin.h"
 #include "include/private/base/SkTo.h"
@@ -136,16 +136,16 @@
 #include "tools/viewer/SvgSlide.h"
 #endif
 
-#ifdef SK_CODEC_DECODES_AVIF
-#include "include/codec/SkAvifDecoder.h"
+#if defined(SK_CODEC_DECODES_PNG_WITH_RUST)
+#include "include/codec/SkPngRustDecoder.h"
+#else
+#include "include/codec/SkPngDecoder.h"
 #endif
 
-#ifdef SK_CODEC_DECODES_JPEGXL
-#include "include/codec/SkJpegxlDecoder.h"
-#endif
-
-#ifdef SK_CODEC_DECODES_RAW
-#include "include/codec/SkRawDecoder.h"
+#if defined(SK_CODEC_ENCODES_PNG_WITH_RUST)
+#include "include/encode/SkPngRustEncoder.h"
+#else
+#include "include/encode/SkPngEncoder.h"
 #endif
 
 using namespace skia_private;
@@ -1869,11 +1869,35 @@
 static SkSerialProcs serial_procs_using_png() {
     SkSerialProcs sProcs;
     sProcs.fImageProc = [](SkImage* img, void*) -> SkSerialReturnType {
+#if defined(SK_CODEC_ENCODES_PNG_WITH_RUST)
+        return SkPngRustEncoder::Encode(
+                as_IB(img)->directContext(), img, SkPngRustEncoder::Options{});
+#else
         return SkPngEncoder::Encode(as_IB(img)->directContext(), img, SkPngEncoder::Options{});
+#endif
     };
     return sProcs;
 }
 
+static SkDeserialProcs deserial_procs_using_png() {
+    SkDeserialProcs dProcs;
+    dProcs.fImageDataProc =
+            [](sk_sp<SkData> data, std::optional<SkAlphaType>, void*) -> sk_sp<SkImage> {
+#if defined(SK_CODEC_DECODES_PNG_WITH_RUST)
+        std::unique_ptr<SkStream> stream = SkMemoryStream::Make(data);
+        auto codec = SkPngRustDecoder::Decode(std::move(stream), nullptr, nullptr);
+#else
+        auto codec = SkPngDecoder::Decode(data, nullptr, nullptr);
+#endif
+        if (!codec) {
+            SkDebugf("Invalid png data detected\n");
+            return nullptr;
+        }
+        return std::get<0>(codec->getImage());
+    };
+    return dProcs;
+}
+
 void Viewer::drawSlide(SkSurface* surface) {
     if (fCurrentSlide < 0) {
         return;
@@ -2022,7 +2046,8 @@
         SkSerialProcs sProcs = serial_procs_using_png();
         auto data = picture->serialize(&sProcs);
         slideCanvas = recorderRestoreCanvas;
-        slideCanvas->drawPicture(SkPicture::MakeFromData(data.get()));
+        SkDeserialProcs dProcs = deserial_procs_using_png();
+        slideCanvas->drawPicture(SkPicture::MakeFromData(data.get(), &dProcs));
     }
 
     // Force a flush so we can time that and add a gpu timer.