Fix uninitialized bug in SkWuffsCodec for incomplete images

Bug: skia:8579

Zero-initialize the pixel buffer that wuffs uses inside the frame rect.
If the encoded image is incomplete, we will swizzle this memory into the
destination, so this prevents swizzling uninitialized memory.

In addition, zero-initialize the client's memory if the above buffer
will not fill it, and if the frame is independent.

Move decodeFrameConfig into onStartIncrementalDecode. This makes it
clear that we haven't begun decoding the pixels so rowsDecoded is
irrelevant. Update the documentation for onStartIncrementalDecode to
make it clear that it can be called more than once (and when to do so).

If a frame is incomplete and depends on prior frames, do not blend it.
This will overwrite pixels from the prior frames without a way to undo.
Current clients only want to show incomplete images for the first frame
anyway.

Add some debugging information to Codec_partialAnim test, including
writing out pngs when failing the test.

TBR=djsollen@google.com for documentation change in SkCodec.h

Change-Id: I85c8ca4075301306f4738ddfc2f5992a5745108b
Reviewed-on: https://skia-review.googlesource.com/c/174310
Commit-Queue: Leon Scroggins <scroggo@google.com>
Reviewed-by: Nigel Tao <nigeltao@google.com>
diff --git a/tests/CodecPartialTest.cpp b/tests/CodecPartialTest.cpp
index 452ba85..e07432a 100644
--- a/tests/CodecPartialTest.cpp
+++ b/tests/CodecPartialTest.cpp
@@ -5,6 +5,7 @@
  * found in the LICENSE file.
  */
 
+#include "CodecPriv.h"
 #include "FakeStreams.h"
 #include "Resources.h"
 #include "SkBitmap.h"
@@ -40,19 +41,21 @@
     return SkCodec::kSuccess == codec->getPixels(info, dst->getPixels(), dst->rowBytes());
 }
 
-static void compare_bitmaps(skiatest::Reporter* r, const SkBitmap& bm1, const SkBitmap& bm2) {
+static bool compare_bitmaps(skiatest::Reporter* r, const SkBitmap& bm1, const SkBitmap& bm2) {
     const SkImageInfo& info = bm1.info();
     if (info != bm2.info()) {
         ERRORF(r, "Bitmaps have different image infos!");
-        return;
+        return false;
     }
     const size_t rowBytes = info.minRowBytes();
     for (int i = 0; i < info.height(); i++) {
         if (memcmp(bm1.getAddr(0, i), bm2.getAddr(0, i), rowBytes)) {
             ERRORF(r, "Bitmaps have different pixels, starting on line %i!", i);
-            return;
+            return false;
         }
     }
+
+    return true;
 }
 
 static void test_partial(skiatest::Reporter* r, const char* name, size_t minBytes = 0) {
@@ -289,7 +292,14 @@
         frameInfo = partialCodec->getFrameInfo();
         REPORTER_ASSERT(r, frameInfo.size() == i + 1);
         REPORTER_ASSERT(r, frameInfo[i].fFullyReceived);
-        compare_bitmaps(r, frames[i], frame);
+        if (!compare_bitmaps(r, frames[i], frame)) {
+            ERRORF(r, "\tfailure was on frame %i", i);
+            SkString name = SkStringPrintf("expected_%i", i);
+            write_bm(name.c_str(), frames[i]);
+
+            name = SkStringPrintf("actual_%i", i);
+            write_bm(name.c_str(), frame);
+        }
     }
 }