/*
 * Copyright 2024 Google LLC
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "include/codec/SkPngRustDecoder.h"

#include <algorithm>
#include <cstdint>
#include <functional>
#include <memory>
#include <optional>
#include <utility>
#include <vector>

#include "include/codec/SkAndroidCodec.h"
#include "include/codec/SkCodec.h"
#include "include/codec/SkCodecAnimation.h"
#include "include/codec/SkPngChunkReader.h"
#if defined(SK_CODEC_DECODES_PNG_WITH_LIBPNG)
#include "include/codec/SkPngDecoder.h"
#endif
#include "include/core/SkBitmap.h"
#include "include/core/SkColor.h"
#include "include/core/SkColorSpace.h"
#include "include/core/SkColorType.h"
#include "include/core/SkData.h"
#include "include/core/SkImage.h"
#include "include/core/SkImageInfo.h"
#include "include/core/SkPixmap.h"
#include "include/core/SkRect.h"
#include "include/core/SkRefCnt.h"
#include "include/core/SkSize.h"
#include "include/core/SkStream.h"
#include "include/private/SkGainmapInfo.h"
#include "src/codec/SkCodecPriv.h"
#include "tests/FakeStreams.h"
#include "tests/Test.h"
#include "tools/Resources.h"

#define REPORTER_ASSERT_SUCCESSFUL_CODEC_RESULT(r, actualResult) \
    REPORTER_ASSERT(r,                                           \
                    actualResult == SkCodec::kSuccess,           \
                    "actualResult=\"%s\" != kSuccess",           \
                    SkCodec::ResultToString(actualResult))

namespace {
// This class wraps another SkStream. It does not own the underlying stream, so
// that the underlying stream can be reused starting from where the first
// client left off. This mimics Android's JavaInputStreamAdaptor.
// Replicated from tests/CodecExactReadTest.cpp.
class UnowningStream : public SkStream {
public:
    explicit UnowningStream(SkStream* stream) : fStream(stream) {}

    size_t read(void* buf, size_t bytes) override { return fStream->read(buf, bytes); }

    bool rewind() override { return fStream->rewind(); }

    bool isAtEnd() const override { return fStream->isAtEnd(); }

private:
    SkStream* fStream;  // Unowned.
};

}  // namespace

// Helper wrapping a call to `SkPngRustDecoder::Decode`.
std::unique_ptr<SkCodec> SkPngRustDecoderDecode(skiatest::Reporter* r, const char* path) {
    sk_sp<SkData> data = GetResourceAsData(path);
    if (!data) {
        ERRORF(r, "Missing resource: %s", path);
        return nullptr;
    }

    SkCodec::Result result;
    std::unique_ptr<SkCodec> codec =
            SkPngRustDecoder::Decode(std::make_unique<SkMemoryStream>(std::move(data)), &result);
    REPORTER_ASSERT_SUCCESSFUL_CODEC_RESULT(r, result);

    return codec;
}

void AssertPixelColor(skiatest::Reporter* r,
                      const SkPixmap& pixmap,
                      int x,
                      int y,
                      SkColor expectedColor,
                      const char* description) {
    SkASSERT(r);
    SkASSERT(x >= 0);
    SkASSERT(y >= 0);
    SkASSERT(description);

    REPORTER_ASSERT(r, x < pixmap.width(), "x=%d >= width=%d", x, pixmap.width());
    REPORTER_ASSERT(r, y < pixmap.height(), "y=%d >= height=%d", y, pixmap.height());
    REPORTER_ASSERT(r,
                    kN32_SkColorType == pixmap.colorType(),
                    "kN32_SkColorType != pixmap.ColorType()=%d",
                    pixmap.colorType());

    SkColor actualColor = pixmap.getColor(x, y);
    REPORTER_ASSERT(r,
                    actualColor == expectedColor,
                    "actualColor=0x%08X != expectedColor==0x%08X at (%d,%d) (%s)",
                    actualColor,
                    expectedColor,
                    x,
                    y,
                    description);
}

void AssertGreenPixel(skiatest::Reporter* r,
                      const SkPixmap& pixmap,
                      int x,
                      int y,
                      const char* description = "Expecting a green pixel") {
    AssertPixelColor(r, pixmap, x, y, SkColorSetRGB(0x00, 0xFF, 0x00), description);
}

void AssertRedPixel(skiatest::Reporter* r,
                    const SkPixmap& pixmap,
                    int x,
                    int y,
                    const char* description = "Expecting a red pixel") {
    AssertPixelColor(r, pixmap, x, y, SkColorSetRGB(0xFF, 0x00, 0x00), description);
}

void AssertBluePixel(skiatest::Reporter* r,
                     const SkPixmap& pixmap,
                     int x,
                     int y,
                     const char* description = "Expecting a blue pixel") {
    AssertPixelColor(r, pixmap, x, y, SkColorSetRGB(0x00, 0x00, 0xFF), description);
}

void AssertSingleGreenFrame(skiatest::Reporter* r,
                            int expectedWidth,
                            int expectedHeight,
                            const char* resourcePath) {
    std::unique_ptr<SkCodec> codec = SkPngRustDecoderDecode(r, resourcePath);
    if (!codec) {
        return;
    }

    REPORTER_ASSERT(r, codec->getFrameCount() == 1);
    REPORTER_ASSERT(r, codec->getRepetitionCount() == 0);

    SkCodec::FrameInfo info;
    REPORTER_ASSERT(r, codec->getFrameInfo(0, &info));
    REPORTER_ASSERT(r, info.fBlend == SkCodecAnimation::Blend::kSrc);
    REPORTER_ASSERT(r, info.fDisposalMethod == SkCodecAnimation::DisposalMethod::kKeep);
    REPORTER_ASSERT(r, info.fFrameRect == SkIRect::MakeWH(expectedWidth, expectedHeight));
    REPORTER_ASSERT(r, info.fRequiredFrame == SkCodec::kNoFrame);

    auto [image, result] = codec->getImage();
    REPORTER_ASSERT_SUCCESSFUL_CODEC_RESULT(r, result);

    REPORTER_ASSERT(r, image);
    REPORTER_ASSERT(r,
                    image->width() == expectedWidth,
                    "actualWidth=%d != expectedWidth=%d",
                    image->width(),
                    expectedWidth);
    REPORTER_ASSERT(r,
                    image->height() == expectedHeight,
                    "actualHeight=%d != expectedHeight=%d",
                    image->height(),
                    expectedHeight);

    SkPixmap pixmap;
    REPORTER_ASSERT(r, image->peekPixels(&pixmap));

    AssertGreenPixel(r, pixmap, 0, 0);
    AssertGreenPixel(r, pixmap, expectedWidth / 2, expectedHeight / 2);
}

static std::unique_ptr<SkCodec> StartIncrementalDecodeSubset(skiatest::Reporter* r,
                                                             std::unique_ptr<SkStream> stream,
                                                             const SkIRect& subset,
                                                             SkBitmap* dstBitmap) {
    SkCodec::Result result;
    std::unique_ptr<SkCodec> codec = SkPngRustDecoder::Decode(std::move(stream), &result);
    if (!codec) {
        ERRORF(r, "Failed to create Rust codec");
        return nullptr;
    }

    SkImageInfo subsetInfo =
            codec->getInfo().makeDimensions(subset.size()).makeColorType(kN32_SkColorType);
    dstBitmap->allocPixels(subsetInfo);

    SkImageInfo fullInfo = codec->getInfo().makeColorType(kN32_SkColorType);
    SkCodec::Options options;
    options.fSubset = &subset;

    result = codec->startIncrementalDecode(
            fullInfo, dstBitmap->getPixels(), dstBitmap->rowBytes(), &options);
    if (result != SkCodec::kSuccess) {
        ERRORF(r, "startIncrementalDecode failed with %i", (int)result);
        return nullptr;
    }

    return codec;
}

static bool DecodeSubsetOneShot(skiatest::Reporter* r,
                                sk_sp<SkData> data,
                                const SkIRect& subset,
                                SkBitmap* dstBitmap) {
    auto codec = StartIncrementalDecodeSubset(r, SkMemoryStream::Make(data), subset, dstBitmap);
    if (!codec) {
        return false;
    }
    int rowsDecoded = 0;
    SkCodec::Result result = codec->incrementalDecode(&rowsDecoded);
    if (result != SkCodec::kSuccess) {
        ERRORF(r, "incrementalDecode failed: %d", (int)result);
        return false;
    }
    return true;
}

static bool DecodeSubsetHalting(skiatest::Reporter* r,
                                sk_sp<SkData> data,
                                const SkIRect& subset,
                                SkBitmap* dstBitmap) {
    size_t initialLimit = data->size() / 2;
    auto haltingStream = std::make_unique<HaltingStream>(data, initialLimit);
    HaltingStream* retainedStream = haltingStream.get();

    auto codec = StartIncrementalDecodeSubset(r, std::move(haltingStream), subset, dstBitmap);
    if (!codec) {
        return false;
    }

    int rowsDecoded = 0;
    SkCodec::Result result = codec->incrementalDecode(&rowsDecoded);
    if (result != SkCodec::kIncompleteInput) {
        ERRORF(r, "Expected kIncompleteInput, got %d", (int)result);
        return false;
    }

    retainedStream->addNewData(data->size() - initialLimit);
    result = codec->incrementalDecode(&rowsDecoded);
    if (result != SkCodec::kSuccess) {
        ERRORF(r, "incrementalDecode resume failed: %d", (int)result);
        return false;
    }
    return true;
}

static void CompareBitmaps(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;
    }
    const size_t rowBytes = info.minRowBytes();
    for (int i = 0; i < info.height(); i++) {
        if (0 != memcmp(bm1.getAddr(0, i), bm2.getAddr(0, i), rowBytes)) {
            ERRORF(r, "Bitmaps have different pixels, starting on line %i!", i);
            return;
        }
    }
}

// A valid `IEND` chunk has an empty payload: 4-byte length (0), 4-byte type ("IEND"), 4-byte CRC.
static constexpr size_t kIendChunkSize = 12;

static bool HasTrailingIendChunk(const SkData* data) {
    return data->size() > kIendChunkSize &&
           memcmp(data->bytes() + data->size() - kIendChunkSize, "\0\0\0\0IEND", 8) == 0;
}

// Returns a copy of `data` with the last byte of the trailing `IEND` CRC flipped.
static sk_sp<SkData> WithCorruptIendCrc(const SkData* data) {
    SkASSERT(HasTrailingIendChunk(data));
    sk_sp<SkData> copy = SkData::MakeWithCopy(data->data(), data->size());
    static_cast<uint8_t*>(copy->writable_data())[copy->size() - 1] ^= 0xFF;
    return copy;
}

// Returns `data` without the trailing 4-byte `IEND` CRC (the 8-byte chunk header is kept).
static sk_sp<SkData> WithoutIendCrc(const SkData* data) {
    SkASSERT(HasTrailingIendChunk(data));
    return SkData::MakeSubset(data, 0, data->size() - 4);
}

// Returns `data` without the entire 12-byte trailing `IEND` chunk.
static sk_sp<SkData> WithoutIendChunk(const SkData* data) {
    SkASSERT(HasTrailingIendChunk(data));
    return SkData::MakeSubset(data, 0, data->size() - kIendChunkSize);
}

// Returns a copy of `data` with the last byte of the CRC of its `idatIndex`-th (0-based) `IDAT`
// chunk flipped, or nullptr if there is no such chunk. Decoding then fails with `kErrorInInput`
// once that chunk has been read, after the rows from the preceding `IDAT` chunks.
static sk_sp<SkData> WithCorruptIdatCrc(const SkData* data, int idatIndex) {
    constexpr size_t kSignatureSize = 8;
    constexpr size_t kChunkHeaderSize = 8;  // 4-byte length + 4-byte type.
    constexpr size_t kCrcSize = 4;

    sk_sp<SkData> copy = SkData::MakeWithCopy(data->data(), data->size());
    uint8_t* bytes = static_cast<uint8_t*>(copy->writable_data());
    size_t offset = kSignatureSize;
    while (offset + kChunkHeaderSize <= copy->size()) {
        const size_t length = (size_t{bytes[offset]} << 24) | (size_t{bytes[offset + 1]} << 16) |
                              (size_t{bytes[offset + 2]} << 8) | size_t{bytes[offset + 3]};
        const size_t crcEnd = offset + kChunkHeaderSize + length + kCrcSize;
        if (crcEnd > copy->size()) {
            break;
        }
        if (memcmp(bytes + offset + 4, "IDAT", 4) == 0 && idatIndex-- == 0) {
            bytes[crcEnd - 1] ^= 0xFF;
            return copy;
        }
        offset = crcEnd;
    }
    return nullptr;
}

static std::optional<SkBitmap> DecodeToBitmap(skiatest::Reporter* r,
                                              const SkImageInfo& dstInfo,
                                              SkCodec::Result expectedResult,
                                              std::function<SkCodec::Result(SkBitmap&)> decode) {
    SkBitmap bm;
    REPORTER_ASSERT(r, bm.tryAllocPixels(dstInfo));
    SkCodec::Result result = decode(bm);
    REPORTER_ASSERT(r,
                    result == expectedResult,
                    "Expected %s, got %s",
                    SkCodec::ResultToString(expectedResult),
                    SkCodec::ResultToString(result));
    if (result != SkCodec::kSuccess) {
        return std::nullopt;
    }
    return bm;
}

static std::optional<SkBitmap> DecodeAndroidPixels(
        skiatest::Reporter* r,
        std::unique_ptr<SkCodec> codec,
        int sampleSize,
        std::function<SkIRect(const SkImageInfo&)> getSubset = nullptr,
        size_t maxDecodeMemory = 0,
        SkCodec::Result expectedResult = SkCodec::kSuccess) {
    REPORTER_ASSERT(r, codec);
    if (!codec) {
        return std::nullopt;
    }

    auto androidCodec = SkAndroidCodec::MakeFromCodec(std::move(codec));
    REPORTER_ASSERT(r, androidCodec);
    if (!androidCodec) {
        return std::nullopt;
    }

    SkISize sampledDims = androidCodec->getSampledDimensions(sampleSize);
    SkImageInfo info =
            androidCodec->getInfo().makeDimensions(sampledDims).makeColorType(kN32_SkColorType);
    SkIRect subset;
    if (getSubset) {
        subset = getSubset(androidCodec->getInfo());
        int subsetWidth = SkCodecPriv::GetSampledDimension(subset.width(), sampleSize);
        int subsetHeight = SkCodecPriv::GetSampledDimension(subset.height(), sampleSize);
        info = info.makeWH(subsetWidth, subsetHeight);
    }

    return DecodeToBitmap(r, info, expectedResult, [&](SkBitmap& bm) {
        SkAndroidCodec::AndroidOptions opts;
        opts.fSampleSize = sampleSize;
        if (getSubset) {
            opts.fSubset = &subset;
        }
        opts.fMaxDecodeMemory = maxDecodeMemory;
        return androidCodec->getAndroidPixels(bm.info(), bm.getPixels(), bm.rowBytes(), &opts);
    });
}

// Decodes `codec` with `SkCodec::getPixels`. The plain-`SkCodec` counterpart of
// `DecodeAndroidPixels`.
//
// The destination is zeroed for `kYes_ZeroInitialized` (as that option requires), and otherwise
// pre-filled with magenta so that pixels left unwritten by the codec are detectable.
static std::optional<SkBitmap> DecodePixels(
        skiatest::Reporter* r,
        std::unique_ptr<SkCodec> codec,
        std::function<SkImageInfo(const SkImageInfo&)> makeDstInfo = nullptr,
        const SkCodec::Options& options = {},
        SkCodec::Result expectedResult = SkCodec::kSuccess) {
    REPORTER_ASSERT(r, codec);
    if (!codec) {
        return std::nullopt;
    }

    SkImageInfo info = makeDstInfo ? makeDstInfo(codec->getInfo()) : codec->getInfo();
    return DecodeToBitmap(r, info, expectedResult, [&](SkBitmap& bm) {
        bm.eraseColor(options.fZeroInitialized == SkCodec::kYes_ZeroInitialized
                              ? SK_ColorTRANSPARENT
                              : SK_ColorMAGENTA);
        return codec->getPixels(bm.info(), bm.getPixels(), bm.rowBytes(), &options);
    });
}

// Returns default `SkCodec::Options` with `fMaxDecodeMemory` set to `maxDecodeMemory`.
static SkCodec::Options MakeBudgetOptions(size_t maxDecodeMemory) {
    SkCodec::Options options;
    options.fMaxDecodeMemory = maxDecodeMemory;
    return options;
}

// Verifies that decoding `path` with `expectedBudgetBytes - 1` fails with `kOutOfMemory` and
// decoding with `expectedBudgetBytes` succeeds.
static void AssertDecodeBudget(
        skiatest::Reporter* r,
        const char* path,
        size_t expectedBudgetBytes,
        std::function<std::optional<SkBitmap>(std::unique_ptr<SkCodec>, size_t, SkCodec::Result)>
                decode) {
    REPORTER_ASSERT(
            r,
            !decode(SkPngRustDecoderDecode(r, path), expectedBudgetBytes - 1, SkCodec::kOutOfMemory)
                     .has_value());
    REPORTER_ASSERT(r,
                    decode(SkPngRustDecoderDecode(r, path), expectedBudgetBytes, SkCodec::kSuccess)
                            .has_value());
}

static void AssertAndroidDecodeSampling(
        skiatest::Reporter* r,
        const char* path,
        int sampleSize,
        std::function<SkIRect(const SkImageInfo&)> getSubset = nullptr) {
    sk_sp<SkData> data = GetResourceAsData(path);
    if (!data) {
        ERRORF(r, "Missing resource: %s", path);
        return;
    }

    std::optional<SkBitmap> rustBm = DecodeAndroidPixels(
            r,
            SkPngRustDecoder::Decode(std::make_unique<SkMemoryStream>(data), nullptr),
            sampleSize,
            getSubset);

#if defined(SK_CODEC_DECODES_PNG_WITH_LIBPNG)
    std::optional<SkBitmap> libpngBm = DecodeAndroidPixels(
            r,
            SkPngDecoder::Decode(std::make_unique<SkMemoryStream>(data), nullptr),
            sampleSize,
            getSubset);

    if (!rustBm || !libpngBm) {
        return;
    }

    CompareBitmaps(r, *rustBm, *libpngBm);
#else
    REPORTER_ASSERT(r, rustBm.has_value());
#endif
}

#if defined(SK_CODEC_USES_PNG_WITH_RUST_FOR_ANDROID)
static void AssertAndroidStaticApng(skiatest::Reporter* r,
                                    const char* path,
                                    std::optional<SkColor> expectedTopLeftColor = std::nullopt) {
    std::unique_ptr<SkCodec> codec = SkPngRustDecoderDecode(r, path);
    if (!codec) {
        return;
    }

    REPORTER_ASSERT(r, codec->isAnimated() == SkCodec::IsAnimated::kNo);
    REPORTER_ASSERT(r, codec->getFrameCount() == 1);
    REPORTER_ASSERT(r, codec->getRepetitionCount() == 0);

    SkCodec::FrameInfo info;
    REPORTER_ASSERT(r, codec->getFrameInfo(0, &info));
    REPORTER_ASSERT(r, info.fRequiredFrame == SkCodec::kNoFrame);

    if (expectedTopLeftColor.has_value()) {
        auto [image, result] = codec->getImage();
        REPORTER_ASSERT_SUCCESSFUL_CODEC_RESULT(r, result);
        if (image) {
            SkPixmap pixmap;
            REPORTER_ASSERT(r, image->peekPixels(&pixmap));
            AssertPixelColor(r, pixmap, 0, 0, *expectedTopLeftColor, "IDAT top-left pixel");
        }
    }

    // Verify full, downsampled, and subset+downsampled decodes succeed and match `libpng`.
    AssertAndroidDecodeSampling(r, path, /*sampleSize=*/1);
    AssertAndroidDecodeSampling(r, path, /*sampleSize=*/2);
    AssertAndroidDecodeSampling(r, path, /*sampleSize=*/2, [](const SkImageInfo& imgInfo) {
        return SkIRect::MakeXYWH(0, 0, imgInfo.width() / 2, imgInfo.height() / 2);
    });
}
#endif

#if !defined(SK_CODEC_USES_PNG_WITH_RUST_FOR_ANDROID)
// Decodes into a buffer surrounded by guard bytes to detect out-of-bounds writes
// even in builds without ASAN, and asserts that the decode is refused with
// `SkCodec::kUnimplemented`.
static void AssertAndroidDecodeRefused(skiatest::Reporter* r,
                                       const sk_sp<SkData>& data,
                                       int sampleSize,
                                       bool useSubset,
                                       size_t customRowBytes = 0) {
    constexpr size_t kGuardBytes = 64 * 1024;
    constexpr uint8_t kGuardValue = 0x5A;

    auto codec = SkPngRustDecoder::Decode(std::make_unique<SkMemoryStream>(data), nullptr);
    REPORTER_ASSERT(r, codec);
    if (!codec) {
        return;
    }

    auto androidCodec = SkAndroidCodec::MakeFromCodec(std::move(codec));
    REPORTER_ASSERT(r, androidCodec);
    if (!androidCodec) {
        return;
    }

    const SkISize fullDims = androidCodec->getInfo().dimensions();
    SkIRect subset = SkIRect::MakeWH(fullDims.width(), std::max(1, fullDims.height() / 2));
    if (useSubset) {
        REPORTER_ASSERT(r, androidCodec->getSupportedSubset(&subset));
    }

    const SkISize dims =
            useSubset ? SkISize::Make(SkCodecPriv::GetSampledDimension(subset.width(), sampleSize),
                                      SkCodecPriv::GetSampledDimension(subset.height(), sampleSize))
                      : androidCodec->getSampledDimensions(sampleSize);

    const SkImageInfo info = androidCodec->getInfo()
                                     .makeDimensions(dims)
                                     .makeColorType(kN32_SkColorType)
                                     .makeAlphaType(kPremul_SkAlphaType);
    const size_t rowBytes = customRowBytes ? customRowBytes : info.minRowBytes();
    const size_t pixelBytes = info.computeByteSize(rowBytes);
    std::vector<uint8_t> buffer(kGuardBytes + pixelBytes + kGuardBytes, kGuardValue);

    SkAndroidCodec::AndroidOptions options;
    options.fSampleSize = sampleSize;
    if (useSubset) {
        options.fSubset = &subset;
    }

    SkCodec::Result result =
            androidCodec->getAndroidPixels(info, buffer.data() + kGuardBytes, rowBytes, &options);
    REPORTER_ASSERT(r,
                    result == SkCodec::kUnimplemented,
                    "Expected the decode to be refused with kUnimplemented, got %s "
                    "(sampleSize=%d, useSubset=%d, rowBytes=%zu)",
                    SkCodec::ResultToString(result),
                    sampleSize,
                    (int)useSubset,
                    rowBytes);

    const bool guardBytesIntact = std::all_of(buffer.begin(),
                                              buffer.begin() + kGuardBytes,
                                              [](uint8_t b) { return b == kGuardValue; }) &&
                                  std::all_of(buffer.begin() + kGuardBytes + pixelBytes,
                                              buffer.end(),
                                              [](uint8_t b) { return b == kGuardValue; });
    REPORTER_ASSERT(r,
                    guardBytesIntact,
                    "The decode wrote outside of the destination buffer "
                    "(sampleSize=%d, useSubset=%d, rowBytes=%zu)",
                    sampleSize,
                    (int)useSubset,
                    rowBytes);
}
#endif

// Asserts that `decode` produces the same pixels for `path` as for copies of it with a corrupt
// and with a truncated trailing `IEND` CRC. Both variants leave all of `IDAT` intact.
static void AssertBrokenIendTailMatchesIntact(
        skiatest::Reporter* r,
        const char* path,
        std::function<std::optional<SkBitmap>(sk_sp<SkData>)> decode) {
    sk_sp<SkData> fullData = GetResourceAsData(path);
    if (!fullData) {
        ERRORF(r, "Missing resource: %s", path);
        return;
    }

    std::optional<SkBitmap> refBm = decode(fullData);
    REPORTER_ASSERT(r, refBm.has_value());
    if (!refBm) {
        return;
    }

    const struct {
        const char* fLabel;
        sk_sp<SkData> fData;
    } variants[] = {
            {"corrupt IEND CRC", WithCorruptIendCrc(fullData.get())},
            {"truncated IEND CRC", WithoutIendCrc(fullData.get())},
    };
    for (const auto& [label, variant] : variants) {
        std::optional<SkBitmap> bm = decode(variant);
        REPORTER_ASSERT(
                r, bm.has_value(), "%s: decode failed for variant '%s'", path, label);
        if (bm) {
            CompareBitmaps(r, *refBm, *bm);
        }
    }
}

// Full decodes, in the color configurations that cover both decode paths.
static void AssertDecodesWithBrokenIendTail(skiatest::Reporter* r, const char* path) {
    // kRGBA_8888 + kUnpremul on an RGBA8 source with an `iCCP` chunk is the only combination that
    // satisfies `canReadRow()`, i.e. the only one decoded by `incrementalDecode` (`read_row`).
    // The others go through `incrementalDecodeXForm`.
    static constexpr struct {
        SkColorType fColorType;
        SkAlphaType fAlphaType;
    } kConfigs[] = {
            {kN32_SkColorType, kUnpremul_SkAlphaType},
            {kN32_SkColorType, kPremul_SkAlphaType},
            {kRGBA_8888_SkColorType, kUnpremul_SkAlphaType},
    };

    for (const auto& config : kConfigs) {
        AssertBrokenIendTailMatchesIntact(r, path, [&](sk_sp<SkData> data) {
            return DecodePixels(r,
                                SkPngRustDecoder::Decode(
                                        std::make_unique<SkMemoryStream>(std::move(data)), nullptr),
                                [&](const SkImageInfo& info) {
                                    return info.makeColorType(config.fColorType)
                                            .makeAlphaType(config.fAlphaType);
                                });
        });
    }
}

// Same, for a sampled decode. It goes through `SkAndroidCodec`, always decodes to `kN32`, and
// skips `finish_decoding()` altogether rather than ignoring its result.
static void AssertSampledDecodeWithBrokenIendTail(skiatest::Reporter* r,
                                                  const char* path,
                                                  int sampleSize) {
    auto decode = [&](sk_sp<SkData> data) {
        return DecodeAndroidPixels(
                r,
                SkPngRustDecoder::Decode(std::make_unique<SkMemoryStream>(std::move(data)),
                                         nullptr),
                sampleSize);
    };
    AssertBrokenIendTailMatchesIntact(r, path, decode);

    // Because a non-interlaced sampled decode stops after the last needed scanline without reading
    // the `IDAT` CRC or the 8-byte `IEND` chunk header (`stopsBeforeEndOfFrame`), it must also
    // succeed when the entire 12-byte `IEND` chunk is stripped.
    sk_sp<SkData> fullData = GetResourceAsData(path);
    std::optional<SkBitmap> refBm = decode(fullData);
    std::optional<SkBitmap> withoutIendBm = decode(WithoutIendChunk(fullData.get()));
    REPORTER_ASSERT(r, withoutIendBm.has_value());
    if (refBm && withoutIendBm) {
        CompareBitmaps(r, *refBm, *withoutIendBm);
    }
}

sk_sp<SkImage> DecodeLastFrame(skiatest::Reporter* r, SkCodec* codec) {
    int frameCount = codec->getFrameCount();
    sk_sp<SkImage> image;
    SkCodec::Result result = SkCodec::kSuccess;
    for (int i = 0; i < frameCount; i++) {
        SkCodec::FrameInfo info;
        REPORTER_ASSERT(r, codec->getFrameInfo(i, &info));

        // This test method only supports `kKeep` disposal method.
        SkASSERT(info.fDisposalMethod == SkCodecAnimation::DisposalMethod::kKeep);

        if (!image) {
            std::tie(image, result) = codec->getImage();
            REPORTER_ASSERT_SUCCESSFUL_CODEC_RESULT(r, result);
            if (result != SkCodec::kSuccess) {
                return nullptr;
            }
        } else {
            SkPixmap pixmap;
            REPORTER_ASSERT(r, image->peekPixels(&pixmap));

            SkCodec::Options options;
            options.fZeroInitialized = SkCodec::kNo_ZeroInitialized;
            options.fSubset = nullptr;
            options.fFrameIndex = i;
            options.fPriorFrame = i - 1;

            result = codec->getPixels(pixmap, &options);
            REPORTER_ASSERT_SUCCESSFUL_CODEC_RESULT(r, result);
            if (result != SkCodec::kSuccess) {
                return nullptr;
            }
        }
    }

    return image;
}

sk_sp<SkImage> DecodeLastFrame(skiatest::Reporter* r, const char* resourcePath) {
    std::unique_ptr<SkCodec> codec = SkPngRustDecoderDecode(r, resourcePath);
    if (!codec) {
        return nullptr;
    }

    return DecodeLastFrame(r, codec.get());
}

void AssertAnimationRepetitionCount(skiatest::Reporter* r,
                                    int expectedRepetitionCount,
                                    const char* resourcePath) {
    std::unique_ptr<SkCodec> codec = SkPngRustDecoderDecode(r, resourcePath);
    if (!codec) {
        return;
    }

    int actualRepetitionCount = codec->getRepetitionCount();
    REPORTER_ASSERT(r,
                    actualRepetitionCount == expectedRepetitionCount,
                    "actualRepetitionCount=%d != expectedRepetitionCount=%d",
                    actualRepetitionCount,
                    expectedRepetitionCount);
}

// Test based on
// https://philip.html5.org/tests/apng/tests.html#trivial-static-image
DEF_TEST(RustPngCodec_apng_basic_trivial_static_image, r) {
    AssertSingleGreenFrame(r, 128, 64, "images/apng-test-suite--basic--trivial-static-image.png");
}

// Test based on
// https://philip.html5.org/tests/apng/tests.html#trivial-animated-image-one-frame-using-default-image
DEF_TEST(RustPngCodec_apng_basic_using_default_image, r) {
    const char* kResource = "images/apng-test-suite--basic--using-default-image.png";
#if !defined(SK_CODEC_USES_PNG_WITH_RUST_FOR_ANDROID)
    AssertSingleGreenFrame(r, 128, 64, kResource);
#else
    AssertAndroidStaticApng(r, kResource, SK_ColorGREEN);
#endif
}

// Test based on
// https://philip.html5.org/tests/apng/tests.html#trivial-animated-image-one-frame-ignoring-default-image
//
// The input file contains the following PNG chunks: IHDR, acTL, IDAT, fcTL,
// fdAT, IEND.  Presence of acTL chunk + no fcTL chunk before IDAT means that
// the IDAT chunk is *not* part of the animation:
// * On non-Android (APNG-aware), `SkPngRustCodec` ignores the red `IDAT` default
//   image and decodes the green `fdAT` animation frame.
// * On Android (`SK_CODEC_USES_PNG_WITH_RUST_FOR_ANDROID`), `SkPngRustCodec`
//   ignores `acTL`/`fcTL` for `SkPngCodec` (libpng) parity and decodes the red
//   `IDAT` default image as a static single-frame PNG.
DEF_TEST(RustPngCodec_apng_basic_ignoring_default_image, r) {
    const char* kResource = "images/apng-test-suite--basic--ignoring-default-image.png";
#if !defined(SK_CODEC_USES_PNG_WITH_RUST_FOR_ANDROID)
    AssertSingleGreenFrame(r, 128, 64, kResource);
#else
    AssertAndroidStaticApng(r, kResource, SK_ColorRED);
#endif
}

// Regression test for b/562862995: When an APNG has no `fcTL` chunk before
// `IDAT` (`IDAT` is the fallback default image and Frame 0 starts at `fdAT`),
// callers that decode Frame 0 directly via `getImage()`, `getPixels()`,
// `startIncrementalDecode()`, or `SkAndroidCodec::getAndroidPixels()` without
// calling `getFrameCount()` first must still succeed rather than failing with
// `kInvalidParameters` (decoding the green `fdAT` frame on non-Android, or the
// red `IDAT` default image on Android where APNG chunks are ignored).
DEF_TEST(RustPngCodec_apng_ignoring_default_image_without_getFrameCount, r) {
    const char* kResource = "images/apng-test-suite--basic--ignoring-default-image.png";
#if !defined(SK_CODEC_USES_PNG_WITH_RUST_FOR_ANDROID)
    // 1. Direct `getImage()` / `getPixels()` without `getFrameCount()`.
    {
        std::unique_ptr<SkCodec> codec = SkPngRustDecoderDecode(r, kResource);
        REPORTER_ASSERT(r, codec);
        auto [image, result] = codec->getImage();
        REPORTER_ASSERT_SUCCESSFUL_CODEC_RESULT(r, result);
        if (image) {
            SkPixmap pixmap;
            REPORTER_ASSERT(r, image->peekPixels(&pixmap));
            AssertGreenPixel(r, pixmap, 0, 0);
        }
    }

    // 2. Direct `startIncrementalDecode()` + `incrementalDecode()` without `getFrameCount()`.
    {
        std::unique_ptr<SkCodec> codec = SkPngRustDecoderDecode(r, kResource);
        REPORTER_ASSERT(r, codec);
        SkBitmap bitmap;
        REPORTER_ASSERT(r, bitmap.tryAllocPixels(codec->getInfo()));
        SkCodec::Result result =
                codec->startIncrementalDecode(bitmap.info(), bitmap.getPixels(), bitmap.rowBytes());
        REPORTER_ASSERT_SUCCESSFUL_CODEC_RESULT(r, result);
        if (result == SkCodec::kSuccess) {
            result = codec->incrementalDecode();
            REPORTER_ASSERT_SUCCESSFUL_CODEC_RESULT(r, result);
            AssertGreenPixel(r, bitmap.pixmap(), 0, 0);
        }
    }

    // 3. Direct `SkAndroidCodec::getAndroidPixels()` (with downsampling) without `getFrameCount()`.
    {
        std::unique_ptr<SkCodec> codec = SkPngRustDecoderDecode(r, kResource);
        REPORTER_ASSERT(r, codec);
        std::unique_ptr<SkAndroidCodec> androidCodec =
                SkAndroidCodec::MakeFromCodec(std::move(codec));
        REPORTER_ASSERT(r, androidCodec);
        SkISize sampledDims = androidCodec->getSampledDimensions(2);
        SkImageInfo sampledInfo = androidCodec->getInfo().makeDimensions(sampledDims);
        SkBitmap bitmap;
        REPORTER_ASSERT(r, bitmap.tryAllocPixels(sampledInfo));
        SkAndroidCodec::AndroidOptions options;
        options.fSampleSize = 2;
        SkCodec::Result result = androidCodec->getAndroidPixels(
                sampledInfo, bitmap.getPixels(), bitmap.rowBytes(), &options);
        REPORTER_ASSERT_SUCCESSFUL_CODEC_RESULT(r, result);
        if (result == SkCodec::kSuccess) {
            AssertGreenPixel(r, bitmap.pixmap(), 0, 0);
        }
    }
#else
    AssertAndroidStaticApng(r, kResource, SK_ColorRED);
#endif
}

// Test based on
// https://philip.html5.org/tests/apng/tests.html#apng-dispose-op-none-basic
//
// This test covers two aspects of `SkPngRustCodec` implementation:
//
// * Blink expects that `onGetFrameCount` returns the total frame count when
//   the complete image resource is available (i.e. a lower frame count should
//   only happen upon `SkCodec::kIncompleteInput`).  Before http://review.skia.org/911038
//   `SkPngRustCodec::onGetFrameCount` would not discover additional frames if
//   previous frames haven't been decoded yet.
// * Skia client (e.g. Blink; or here the testcase) is expected to handle
//   `SkCodecAnimation::DisposalMethod` and populate the target buffer (and
//   `SkCodec::Options::fPriorFrame`) with the expected pixels.  OTOH,
//   `SkPngRustCodec` needs to handle `SkCodecAnimation::Blend` - without this
//   the final frame in this test will contain red pixels.
DEF_TEST(RustPngCodec_apng_dispose_op_none_basic, r) {
    const char* kResource = "images/apng-test-suite--dispose-ops--none-basic.png";
#if !defined(SK_CODEC_USES_PNG_WITH_RUST_FOR_ANDROID)
    std::unique_ptr<SkCodec> codec = SkPngRustDecoderDecode(r, kResource);
    if (!codec) {
        return;
    }

    REPORTER_ASSERT(r, codec->getFrameCount() == 3);
    REPORTER_ASSERT(r, codec->getRepetitionCount() == 0);

    // We should have `FrameInfo` for all 3 frames.
    SkCodec::FrameInfo info[3];
    REPORTER_ASSERT(r, codec->getFrameInfo(0, &info[0]));
    REPORTER_ASSERT(r, codec->getFrameInfo(1, &info[1]));
    REPORTER_ASSERT(r, codec->getFrameInfo(2, &info[2]));

    // The codec should realize that the `SkStream` contains all the data of the
    // first 2 frames.  Currently `SkPngRustCodec::onGetFrameCount` stops after
    // parsing the final, 3rd `fcTL` chunk and therefore it can't tell if the
    // subsequent `fdAT` chunk has been fully received or not.
    REPORTER_ASSERT(r, info[0].fFullyReceived);
    REPORTER_ASSERT(r, info[1].fFullyReceived);
    REPORTER_ASSERT(r, !info[2].fFullyReceived);

    // Spot-check frame metadata.
    REPORTER_ASSERT(r, info[1].fAlphaType == kUnpremul_SkAlphaType);
    REPORTER_ASSERT(r, info[1].fBlend == SkCodecAnimation::Blend::kSrcOver);
    REPORTER_ASSERT(r, info[1].fDisposalMethod == SkCodecAnimation::DisposalMethod::kKeep);
    REPORTER_ASSERT(r, info[1].fDuration == 100, "dur = %d", info[1].fDuration);
    REPORTER_ASSERT(r, info[1].fFrameRect == SkIRect::MakeWH(128, 64));
    REPORTER_ASSERT(r, info[1].fHasAlphaWithinBounds);
    REPORTER_ASSERT(r, info[1].fRequiredFrame == 0);

    // Validate contents of the first frame.
    auto [image, result] = codec->getImage();
    REPORTER_ASSERT_SUCCESSFUL_CODEC_RESULT(r, result);
    REPORTER_ASSERT(r, image);
    REPORTER_ASSERT(r, image->width() == 128, "width %d != 128", image->width());
    REPORTER_ASSERT(r, image->height() == 64, "height %d != 64", image->height());
    SkPixmap pixmap;
    REPORTER_ASSERT(r, image->peekPixels(&pixmap));
    AssertRedPixel(r, pixmap, 0, 0, "Frame #0 should be red");

    // Validate contents of the second frame.
    SkCodec::Options options;
    options.fZeroInitialized = SkCodec::kNo_ZeroInitialized;
    options.fSubset = nullptr;
    options.fFrameIndex = 1;  // We want to decode the second frame.
    options.fPriorFrame = 0;  // `pixmap` contains the first frame before `getPixels` call.
    REPORTER_ASSERT_SUCCESSFUL_CODEC_RESULT(r, codec->getPixels(pixmap, &options));
    AssertGreenPixel(r, pixmap, 0, 0, "Frame #1 should be green");

    // Validate contents of the third frame.
    options.fFrameIndex = 2;  // We want to decode the second frame.
    options.fPriorFrame = 1;  // `pixmap` contains the second frame before `getPixels` call.
    REPORTER_ASSERT_SUCCESSFUL_CODEC_RESULT(r, codec->getPixels(pixmap, &options));
    AssertGreenPixel(r, pixmap, 0, 0, "Frame #2 should be green");
#else
    AssertAndroidStaticApng(r, kResource, SK_ColorRED);
#endif
}

// This test covers an incomplete input scenario:
//
// * Only half of 1st frame is available during `onGetFrameCount`.
//   In this situation `onGetFrameCount` may consume the whole input in a
//   (futile in this case) attempt to discover `fcTL` chunks for 2nd and 3rd
//   frame.  This will mean that the input stream is in the middle of the 1st
//   frame - no longer positioned correctly for decoding the 1st frame.
// * Full input is available when subsequently decoding 1st frame.
DEF_TEST(RustPngCodec_apng_dispose_op_none_basic_incomplete_input1, r) {
    const char* path = "images/apng-test-suite--dispose-ops--none-basic.png";
    sk_sp<SkData> data = GetResourceAsData(path);
    if (!data) {
        ERRORF(r, "Missing resource: %s", path);
        return;
    }
    size_t fullLength = data->size();

    // Initially expose roughly middle of `IDAT` chunk (in this image `fcTL` is
    // present before the `IDAT` chunk and therefore the `IDAT` chunk is part of
    // the animated image).
    constexpr size_t kInitialBytes = 0xAD;
    auto streamForCodec = std::make_unique<HaltingStream>(std::move(data), kInitialBytes);
    HaltingStream* retainedStream = streamForCodec.get();

    SkCodec::Result result;
    std::unique_ptr<SkCodec> codec = SkPngRustDecoder::Decode(std::move(streamForCodec), &result);
    REPORTER_ASSERT_SUCCESSFUL_CODEC_RESULT(r, result);
    if (!codec) {
        return;
    }

    SkBitmap bitmap;
    if (!bitmap.tryAllocN32Pixels(codec->dimensions().width(), codec->dimensions().height())) {
        ERRORF(r, "Failed to allocate SkBitmap");
        return;
    }

    // Try to provoke the codec to consume the currently-available part of the
    // input stream.
    //
    // At this point only the metadata for the first frame is available.
    int frameCount = codec->getFrameCount();
    REPORTER_ASSERT(r, frameCount == 1);

    // Make the rest of the input available to the codec.
    retainedStream->addNewData(fullLength);

    // Try to decode the first frame and check its contents.
    sk_sp<SkImage> image;
    std::tie(image, result) = codec->getImage();
    REPORTER_ASSERT_SUCCESSFUL_CODEC_RESULT(r, result);
    REPORTER_ASSERT(r, image);
    REPORTER_ASSERT(r, image->width() == 128, "width %d != 128", image->width());
    REPORTER_ASSERT(r, image->height() == 64, "height %d != 64", image->height());
    SkPixmap pixmap;
    REPORTER_ASSERT(r, image->peekPixels(&pixmap));
    AssertRedPixel(r, pixmap, 0, 0, "Frame #0 should be red");
}

// This test covers an incomplete input scenario:
//
// * Only half of 1st frame is available during the initial `incrementalDecode`.
// * Before retrying, `getFrameCount` is called.  This should *not* reposition
//   the stream while in the middle of an active incremental decode.
// * Then we retry `incrementalDecode`.
DEF_TEST(RustPngCodec_apng_dispose_op_none_basic_incomplete_input2, r) {
    const char* path = "images/apng-test-suite--dispose-ops--none-basic.png";
    sk_sp<SkData> data = GetResourceAsData(path);
    if (!data) {
        ERRORF(r, "Missing resource: %s", path);
        return;
    }
    size_t fullLength = data->size();

    constexpr size_t kInitialBytes = 0x8D;  // Roughly middle of IDAT chunk.
    auto streamForCodec = std::make_unique<HaltingStream>(std::move(data), kInitialBytes);
    HaltingStream* retainedStream = streamForCodec.get();

    SkCodec::Result result;
    std::unique_ptr<SkCodec> codec = SkPngRustDecoder::Decode(std::move(streamForCodec), &result);
    REPORTER_ASSERT_SUCCESSFUL_CODEC_RESULT(r, result);
    if (!codec) {
        return;
    }

    SkBitmap bitmap;
    if (!bitmap.tryAllocN32Pixels(codec->dimensions().width(), codec->dimensions().height())) {
        ERRORF(r, "Failed to allocate SkBitmap");
        return;
    }
    const SkPixmap& pixmap = bitmap.pixmap();

    // Fill the `bitmap` with blue pixels to detect which pixels have been filled
    // by the codec during a partially-successful `incrementalDecode`.
    //
    // (The first frame has all red pixels.)
    bitmap.erase(SkColorSetRGB(0, 0, 0xFF), bitmap.bounds());
    AssertBluePixel(r, pixmap, 0, 0);
    AssertBluePixel(r, pixmap, 40, 29);
    AssertBluePixel(r, pixmap, 80, 35);
    AssertBluePixel(r, pixmap, 127, 63);

    // Decode partially-available, incomplete image.
    SkCodec::Options options;
    options.fZeroInitialized = SkCodec::kNo_ZeroInitialized;
    options.fSubset = nullptr;
    options.fFrameIndex = 0;
    options.fPriorFrame = SkCodec::kNoFrame;
    result = codec->startIncrementalDecode(bitmap.pixmap().info(),
                                           bitmap.pixmap().writable_addr(),
                                           bitmap.pixmap().rowBytes(),
                                           &options);
    REPORTER_ASSERT(r, result == SkCodec::kSuccess);
    int rowsDecoded = -1;
    result = codec->incrementalDecode(&rowsDecoded);
    REPORTER_ASSERT(r, result == SkCodec::kIncompleteInput);
    REPORTER_ASSERT(r, rowsDecoded == 10, "actual rowsDecoded = %d", rowsDecoded);
    AssertRedPixel(r, pixmap, 0, 0);
    AssertBluePixel(r, pixmap, 40, 29);
    AssertBluePixel(r, pixmap, 80, 35);
    AssertBluePixel(r, pixmap, 127, 63);

    // Make the rest of the input available to the codec.
    retainedStream->addNewData(fullLength);

    // Try to provoke the codec to consume further into the input stream (doing
    // this would loose the position inside the currently active incremental
    // decode).
    //
    // At this point metadata of all the frames is available, but the codec
    // shouldn't read the other two `fcTL` chunks during an active incremental
    // decode.
    int frameCount = codec->getFrameCount();
    REPORTER_ASSERT(r, frameCount == 1);

    // Check that all the pixels of the first frame got decoded.
    rowsDecoded = -1;
    result = codec->incrementalDecode(&rowsDecoded);
    REPORTER_ASSERT(r, result == SkCodec::kSuccess);
    REPORTER_ASSERT(r, rowsDecoded == -1);  // Not set when `kSuccess`.
    AssertRedPixel(r, pixmap, 0, 0);
    AssertRedPixel(r, pixmap, 40, 29);
    AssertRedPixel(r, pixmap, 80, 35);
    AssertRedPixel(r, pixmap, 127, 63);
}

// Test based on
// https://philip.html5.org/tests/apng/tests.html#apng-blend-op-source-on-solid-colour
DEF_TEST(RustPngCodec_apng_blend_ops_source_on_solid, r) {
    const char* kResource = "images/apng-test-suite--blend-ops--source-on-solid.png";
#if !defined(SK_CODEC_USES_PNG_WITH_RUST_FOR_ANDROID)
    std::unique_ptr<SkCodec> codec = SkPngRustDecoderDecode(r, kResource);
    if (!codec) {
        return;
    }
    sk_sp<SkImage> image = DecodeLastFrame(r, codec.get());
    if (!image) {
        return;
    }

    SkPixmap pixmap;
    REPORTER_ASSERT(r, image->peekPixels(&pixmap));
    AssertGreenPixel(r, pixmap, 0, 0);

    SkCodec::FrameInfo info;
    REPORTER_ASSERT(r, codec->getFrameInfo(1, &info));
    REPORTER_ASSERT(r, info.fBlend == SkCodecAnimation::Blend::kSrc);
    REPORTER_ASSERT(r, info.fRequiredFrame == SkCodec::kNoFrame);
#else
    AssertAndroidStaticApng(r, kResource);
#endif
}

// Test based on
// https://philip.html5.org/tests/apng/tests.html#apng-blend-op-source-on-nearly-transparent-colour
DEF_TEST(RustPngCodec_apng_blend_ops_source_on_nearly_transparent, r) {
    const char* kResource = "images/apng-test-suite--blend-ops--source-on-nearly-transparent.png";
#if !defined(SK_CODEC_USES_PNG_WITH_RUST_FOR_ANDROID)
    sk_sp<SkImage> image = DecodeLastFrame(r, kResource);
    if (!image) {
        return;
    }

    SkPixmap pixmap;
    REPORTER_ASSERT(r, image->peekPixels(&pixmap));
    AssertPixelColor(r,
                     pixmap,
                     0,
                     0,
                     SkColorSetARGB(0x02, 0x00, 0xFF, 0x00),
                     "Expecting a nearly transparent pixel");
#else
    AssertAndroidStaticApng(r, kResource);
#endif
}

// Test based on
// https://philip.html5.org/tests/apng/tests.html#apng-blend-op-over-on-solid-and-transparent-colours
DEF_TEST(RustPngCodec_apng_blend_ops_over_on_solid_and_transparent, r) {
    const char* kResource = "images/apng-test-suite--blend-ops--over-on-solid-and-transparent.png";
#if !defined(SK_CODEC_USES_PNG_WITH_RUST_FOR_ANDROID)
    sk_sp<SkImage> image = DecodeLastFrame(r, kResource);
    if (!image) {
        return;
    }

    SkPixmap pixmap;
    REPORTER_ASSERT(r, image->peekPixels(&pixmap));
    AssertGreenPixel(r, pixmap, 0, 0);
#else
    AssertAndroidStaticApng(r, kResource);
#endif
}

// Test based on
// https://philip.html5.org/tests/apng/tests.html#apng-blend-op-over-repeatedly-with-nearly-transparent-colours
DEF_TEST(RustPngCodec_apng_blend_ops_over_repeatedly, r) {
    const char* kResource = "images/apng-test-suite--blend-ops--over-repeatedly.png";
#if !defined(SK_CODEC_USES_PNG_WITH_RUST_FOR_ANDROID)
    sk_sp<SkImage> image = DecodeLastFrame(r, kResource);
    if (!image) {
        return;
    }

    SkPixmap pixmap;
    REPORTER_ASSERT(r, image->peekPixels(&pixmap));
    AssertGreenPixel(r, pixmap, 0, 0);
#else
    AssertAndroidStaticApng(r, kResource);
#endif
}

// Test based on
// https://philip.html5.org/tests/apng/tests.html#apng-dispose-op-none-in-region
DEF_TEST(RustPngCodec_apng_regions_dispose_op_none, r) {
    const char* kResource = "images/apng-test-suite--regions--dispose-op-none.png";
#if !defined(SK_CODEC_USES_PNG_WITH_RUST_FOR_ANDROID)
    sk_sp<SkImage> image = DecodeLastFrame(r, kResource);
    if (!image) {
        return;
    }

    // Check all pixels.
    //
    // * The image (and the first frame) is 128x64
    // * The 2nd frame is 64x32 at offset (32,16)
    // * The 3rd frame is 1x1 at offset (0,0)
    SkPixmap pixmap;
    REPORTER_ASSERT(r, image->peekPixels(&pixmap));
    for (int y = 0; y < pixmap.height(); y++) {
        for (int x = 0; x < pixmap.width(); x++) {
            AssertGreenPixel(r, pixmap, x, y);
        }
    }
#else
    AssertAndroidStaticApng(r, kResource);
#endif
}

// Test based on
// https://philip.html5.org/tests/apng/tests.html#num-plays-0
DEF_TEST(RustPngCodec_apng_num_plays_0, r) {
    const char* kResource = "images/apng-test-suite--num-plays--0.png";
#if !defined(SK_CODEC_USES_PNG_WITH_RUST_FOR_ANDROID)
    AssertAnimationRepetitionCount(r, SkCodec::kRepetitionCountInfinite, kResource);
#else
    AssertAndroidStaticApng(r, kResource);
#endif
}

// Test based on
// https://philip.html5.org/tests/apng/tests.html#num-plays-1
DEF_TEST(RustPngCodec_apng_num_plays_1, r) {
    const char* kResource = "images/apng-test-suite--num-plays--1.png";
#if !defined(SK_CODEC_USES_PNG_WITH_RUST_FOR_ANDROID)
    AssertAnimationRepetitionCount(r, 0, kResource);
#else
    AssertAndroidStaticApng(r, kResource);
#endif
}

// Test based on
// https://philip.html5.org/tests/apng/tests.html#num-plays-2
DEF_TEST(RustPngCodec_apng_num_plays_2, r) {
    const char* kResource = "images/apng-test-suite--num-plays--2.png";
#if !defined(SK_CODEC_USES_PNG_WITH_RUST_FOR_ANDROID)
    AssertAnimationRepetitionCount(r, 1, kResource);
#else
    AssertAndroidStaticApng(r, kResource);
#endif
}

// Test based on
// https://philip.html5.org/tests/apng/tests.html#num-frames-outside-valid-range
//
// In this test the `acTL` chunk sets `num_frames` to `2147483649u` (or `0x80000001u`):
//
// * AFAICT version 1.0 of the APNG spec only says that "0 is not a valid value"
// * The test suite webpage says that at one point the APNG spec said that
//   `num_frames` shall be "limited to the range 0 to (2^31)-1"
DEF_TEST(RustPngCodec_apng_invalid_num_frames_outside_valid_range, r) {
    std::unique_ptr<SkCodec> codec = SkPngRustDecoderDecode(
            r, "images/apng-test-suite--invalid--num-frames-outside-valid-range.png");
    if (!codec) {
        return;
    }

    // Calling `codec->getFrameCount` exercises the code used to discover and
    // parse `fcTL` chunks on non-Android (where `onGetFrameCount` returns the
    // number of successfully parsed `fcTL` chunks, 1, rather than the raw
    // `acTL.num_frames`), and returns 1 immediately on Android where `acTL` is
    // ignored.
    REPORTER_ASSERT(r, codec->getFrameCount() == 1);
}

DEF_TEST(RustPngCodec_png_swizzling_target_unimplemented, r) {
    std::unique_ptr<SkCodec> codec =
            SkPngRustDecoderDecode(r, "images/apng-test-suite--basic--ignoring-default-image.png");
    if (!codec) {
        return;
    }
    REPORTER_ASSERT(r, codec->getFrameCount() == 1);

    // Ask to decode into an esoteric `SkColorType`:
    //
    // * Unsupported by `SkSwizzler`.
    // * Supported by `SkCodec::conversionSupported`.
    SkImageInfo dstInfo = SkImageInfo::Make(
            codec->dimensions(), kBGRA_10101010_XR_SkColorType, kPremul_SkAlphaType);

    auto [image, result] = codec->getImage(dstInfo);
    REPORTER_ASSERT(r, result == SkCodec::kUnimplemented);
    REPORTER_ASSERT(r, !image);
}

DEF_TEST(RustPngCodec_png_was_encoded_with_16_bits_or_more_per_component, r) {
    struct Test {
        const char* fFilename;
        bool fEncodedWith16bits;
    };
    const std::array<Test, 4> kTests = {
            Test{"images/pngsuite/basn0g04.png", false},  // 4 bit (16 level) grayscale
            Test{"images/pngsuite/basn2c08.png", false},  // 3x8 bits rgb color
            Test{"images/pngsuite/basn2c16.png", true},   // 3x16 bits rgb color
            Test{"images/pngsuite/basn3p01.png", false}   // 1 bit (2 color) paletted
    };
    for (const auto& test : kTests) {
        std::unique_ptr<SkCodec> codec = SkPngRustDecoderDecode(r, test.fFilename);
        if (codec) {
            REPORTER_ASSERT(r, codec->hasHighBitDepthEncodedData() == test.fEncodedWith16bits);
        }
    }
}

DEF_TEST(RustPngCodec_png_cicp, r) {
    std::unique_ptr<SkCodec> codec = SkPngRustDecoderDecode(r, "images/cicp_pq.png");
    if (!codec) {
        return;
    }

    const skcms_ICCProfile* profile = codec->getICCProfile();
    REPORTER_ASSERT(r, profile);
    if (!profile) {
        return;
    }
    auto cs = SkColorSpace::Make(*profile);
    skcms_TransferFunction tf;
    cs->transferFn(&tf);

    REPORTER_ASSERT(r, skcms_TransferFunction_isPQish(&tf) ||
                       skcms_TransferFunction_isPQ(&tf));
}

DEF_TEST(RustPngCodec_green15x15, r) {
    std::unique_ptr<SkCodec> codec = SkPngRustDecoderDecode(r, "images/green15x15.png");
    if (!codec) {
        return;
    }

    SkImageInfo dstInfo = codec->getInfo();
    dstInfo = dstInfo.makeColorSpace(SkColorSpace::MakeSRGB());
    auto [image, result] = codec->getImage(dstInfo);
    REPORTER_ASSERT_SUCCESSFUL_CODEC_RESULT(r, result);
    if (result != SkCodec::kSuccess) {
        return;
    }

    SkPixmap pixmap;
    REPORTER_ASSERT(r, image->peekPixels(&pixmap));
    const SkColor kExpectedColor = SkColorSetARGB(0xFF, 0x00, 0x80, 0x00);
    AssertPixelColor(r, pixmap, 0, 0, kExpectedColor, "Expecting a dark green pixel");
}

DEF_TEST(RustPngCodec_exif_orientation, r) {
    std::unique_ptr<SkCodec> codec = SkPngRustDecoderDecode(r, "images/F-exif-chunk-early.png");
    if (!codec) {
        return;
    }

    REPORTER_ASSERT(r, codec->getOrigin() == kRightTop_SkEncodedOrigin);
}

DEF_TEST(RustPngCodec_f16_trc_tables, r) {
    std::unique_ptr<SkCodec> codec = SkPngRustDecoderDecode(r, "images/f16-trc-tables.png");
    REPORTER_ASSERT(r, codec);

    const SkImageInfo info = codec->getInfo();
    REPORTER_ASSERT(r, info.colorSpace());

    // Decoding to F16 without color space conversion.
    const SkImageInfo dstInfo = info.makeColorType(kRGBA_F16_SkColorType)
                                    .makeColorSpace(nullptr);
    // This should not crash.
    auto [image, result] = codec->getImage(dstInfo);
    REPORTER_ASSERT_SUCCESSFUL_CODEC_RESULT(r, result);
}

DEF_TEST(RustPngCodec_crbug445556737, r) {
    const char* kResource = "images/crbug445556737.png";
#if !defined(SK_CODEC_USES_PNG_WITH_RUST_FOR_ANDROID)
    sk_sp<SkImage> image = DecodeLastFrame(r, kResource);
    if (!image) {
        return;
    }

    // The main test verification is that there are no assertion failures nor
    // other crashes.  Cursory verification below is supplementary/secondary.
    REPORTER_ASSERT(r, image->height() == 5);
    REPORTER_ASSERT(r, image->width() == 5);
#else
    AssertAndroidStaticApng(r, kResource);
#endif
}

DEF_TEST(RustPngCodec_invalid_profile, r) {
    // This image has an gamma value of 0. For parity with Blink, we want to disregard
    // the ICC profile in this case and create the codec without it. This is different
    // than libpng SkPngCodec behavior, which will default to an SRGB icc profile.
    std::unique_ptr<SkCodec> codec =
        SkPngRustDecoderDecode(r, "images/png-zero-gamma-color-profile.png");
    REPORTER_ASSERT(r, codec);

    // There should be no ICC profile.
    REPORTER_ASSERT(r, !codec->getICCProfile());

    // This should not crash.
    auto [image, result] = codec->getImage(codec->getInfo());
    REPORTER_ASSERT_SUCCESSFUL_CODEC_RESULT(r, result);
}

static bool bitmaps_equal(const SkBitmap& actual, const SkBitmap& expected) {
    for (int y = 0; y < actual.height(); ++y) {
        for (int x = 0; x < actual.width(); ++x) {
            SkColor c1 = actual.getColor(x, y);
            SkColor c2 = expected.getColor(x, y);
            SkPMColor actualPMColor = SkPreMultiplyColor(c1);
            SkPMColor expectedPMColor = SkPreMultiplyColor(c2);

            if (actualPMColor != expectedPMColor) {
                return false;
            }
        }
    }
    return true;
}

static void test_subset_decode(skiatest::Reporter* r, const char* resource) {
    skiatest::ReporterContext context(r, resource);
    std::unique_ptr<SkStream> stream(GetResourceAsStream(resource));
    REPORTER_ASSERT(r, stream);

    std::unique_ptr<SkCodec> codec = SkCodec::MakeFromStream(std::move(stream));
    REPORTER_ASSERT(r, codec);

    const SkImageInfo info = codec->getInfo();

    SkBitmap bm;
    bm.allocPixels(info);
    codec->getPixels(info, bm.getPixels(), bm.rowBytes());

    SkBitmap tiledBM;
    tiledBM.allocPixels(info);

    const int height = info.height();
    const int width = info.width();
    // Note that if numStripes does not evenly divide height there will be an extra
    // stripe.
    const int numStripes = 4;
    const int numVerticalStripes = 2;

    if (numStripes > height || numVerticalStripes > width) {
        // Image is too small.
        return;
    }

    const int stripeHeight = height / numStripes;
    const int stripeWidth = width / numVerticalStripes;

    // Iterate through the image twice. Once to decode odd stripes, and once for even.
    for (int oddEven = 1; oddEven >= 0; oddEven--) {
        for (int y = oddEven * stripeHeight; y < height; y += 2 * stripeHeight) {
            for (int xStripe = 0; xStripe < numVerticalStripes; xStripe++) {
                // Calculate all four bounds for the grid section
                const int top = y;
                const int bottom = std::min(y + stripeHeight, height);
                const int left = xStripe * stripeWidth;
                const int right = std::min((xStripe + 1) * stripeWidth, width);

                SkIRect subset = SkIRect::MakeLTRB(left, top, right, bottom);
                SkCodec::Options options;
                options.fSubset = &subset;

                // Decode each subset tile into a tightly allocated temporary bitmap
                // (sized exactly to the subset). This is a valid use case that
                // replicates how clients (like Android) perform subset decodes.
                // Doing so explicitly exercises the tight-allocation path where the
                // stride is exactly the subset row size (lacking full-image stride
                // padding), ensuring fDstRowBytes is calculated correctly.
                SkBitmap subsetBM;
                subsetBM.allocPixels(info.makeDimensions(subset.size()));

                REPORTER_ASSERT(
                        r,
                        SkCodec::kSuccess ==
                                codec->startIncrementalDecode(
                                        info, subsetBM.getPixels(), subsetBM.rowBytes(), &options));
                REPORTER_ASSERT(r, SkCodec::kSuccess == codec->incrementalDecode());

                // Copy the decoded subset into the full tiled bitmap
                REPORTER_ASSERT(r, tiledBM.writePixels(subsetBM.pixmap(), left, top));
            }
        }
    }

    REPORTER_ASSERT(r, bitmaps_equal(bm, tiledBM));
}

DEF_TEST(RustPngCodec_subset, r) {
    // Tests subsets by splitting the image into 8 or 10 different tiles and decoding
    // those each separately, then comparing to the full image decoded.
    test_subset_decode(r, "images/baby_tux.png");
    test_subset_decode(r, "images/plane_interlaced.png");
    test_subset_decode(r, "images/basi3p01.png");
}

// An interlaced image that has only been partially received should still cover
// every pixel of the image - pixels that have not been decoded yet are
// approximated by the closest already-decoded Adam7 sample.  Otherwise a
// partially received image is mostly untouched (i.e. fully transparent for
// clients that hand a zero-initialized buffer to the codec) and therefore
// invisible.
DEF_TEST(RustPngCodec_interlaced_partial_decode_covers_all_pixels, r) {
    const char* path = "images/plane_interlaced.png";
    sk_sp<SkData> data = GetResourceAsData(path);
    if (!data) {
        ERRORF(r, "Missing resource: %s", path);
        return;
    }
    const size_t fullLength = data->size();

    // Enough bytes to cover the initial Adam7 passes, but not the whole image.
    const size_t initialBytes = fullLength / 4;
    auto streamForCodec = std::make_unique<HaltingStream>(std::move(data), initialBytes);
    HaltingStream* retainedStream = streamForCodec.get();

    SkCodec::Result result;
    std::unique_ptr<SkCodec> codec = SkPngRustDecoder::Decode(std::move(streamForCodec), &result);
    REPORTER_ASSERT_SUCCESSFUL_CODEC_RESULT(r, result);
    if (!codec) {
        return;
    }

    SkBitmap bitmap;
    if (!bitmap.tryAllocN32Pixels(codec->dimensions().width(), codec->dimensions().height())) {
        ERRORF(r, "Failed to allocate SkBitmap");
        return;
    }

    // Fill `bitmap` with a sentinel color, so that pixels that the codec never
    // wrote to can be detected below.
    constexpr SkColor kSentinel = SkColorSetARGB(0xFF, 0x12, 0x34, 0x56);
    bitmap.eraseColor(kSentinel);

    SkCodec::Options options;
    options.fZeroInitialized = SkCodec::kNo_ZeroInitialized;
    result = codec->startIncrementalDecode(
            bitmap.info(), bitmap.getPixels(), bitmap.rowBytes(), &options);
    REPORTER_ASSERT_SUCCESSFUL_CODEC_RESULT(r, result);
    result = codec->incrementalDecode();
    REPORTER_ASSERT(r, result == SkCodec::kIncompleteInput, "result = %d", (int)result);

    int untouchedPixels = 0;
    for (int y = 0; y < bitmap.height(); ++y) {
        for (int x = 0; x < bitmap.width(); ++x) {
            if (bitmap.getColor(x, y) == kSentinel) {
                ++untouchedPixels;
            }
        }
    }
    REPORTER_ASSERT(r, untouchedPixels == 0, "untouchedPixels = %d", untouchedPixels);

    // Finishing the decode has to produce exactly the same pixels as a decode
    // that had all the input available from the start.
    retainedStream->addNewData(fullLength);
    result = codec->incrementalDecode();
    REPORTER_ASSERT_SUCCESSFUL_CODEC_RESULT(r, result);

    std::unique_ptr<SkCodec> referenceCodec = SkPngRustDecoderDecode(r, path);
    if (!referenceCodec) {
        return;
    }
    SkBitmap referenceBitmap;
    referenceBitmap.allocPixels(bitmap.info());
    result = referenceCodec->getPixels(referenceBitmap.pixmap());
    REPORTER_ASSERT_SUCCESSFUL_CODEC_RESULT(r, result);
    REPORTER_ASSERT(r, bitmaps_equal(bitmap, referenceBitmap));
}

DEF_TEST(RustPngCodec_interlaced_animated_blending, r) {
    const char* kResource = "images/interlaced-multiframe-with-blending.png";
#if !defined(SK_CODEC_USES_PNG_WITH_RUST_FOR_ANDROID)
    std::unique_ptr<SkCodec> codec = SkPngRustDecoderDecode(r, kResource);
    REPORTER_ASSERT(r, codec);

    // Use incrementalDecode for each frame of this image. This should not crash.
    SkBitmap bm;
    SkImageInfo info = codec->getInfo();
    bm.allocPixels(info);
    REPORTER_ASSERT(r, codec->getFrameCount() == 4);
    for (int i = 0; i < codec->getFrameCount(); ++i) {
        SkCodec::Options options;
        options.fFrameIndex = i;
        options.fPriorFrame = i - 1;
        SkCodec::Result result;
        result = codec->startIncrementalDecode(info, bm.getPixels(), bm.rowBytes(), &options);
        REPORTER_ASSERT_SUCCESSFUL_CODEC_RESULT(r, result);
        std::ignore = codec->incrementalDecode();
    }
#else
    AssertAndroidStaticApng(r, kResource);
#endif
}

DEF_TEST(RustPngCodec_sbit565_ihdr16bits, r) {
    std::unique_ptr<SkCodec> codec = SkPngRustDecoderDecode(r, "images/basn2c16-sbit565.png");
    REPORTER_ASSERT(r, codec);

    SkBitmap bm;
    SkImageInfo info = codec->getInfo();
    bm.allocPixels(info);
    REPORTER_ASSERT(r, codec->getFrameCount() == 1);
    SkCodec::Result result;
    result = codec->startIncrementalDecode(info, bm.getPixels(), bm.rowBytes());
    REPORTER_ASSERT_SUCCESSFUL_CODEC_RESULT(r, result);
    result = codec->incrementalDecode();
    REPORTER_ASSERT_SUCCESSFUL_CODEC_RESULT(r, result);
}

#ifdef SK_CODEC_USES_PNG_WITH_RUST_FOR_ANDROID
class MockChunkReader : public SkPngChunkReader {
public:
    bool readChunk(const char tag[], const void* data, size_t length) override {
        fChunks.push_back({tag, std::string((const char*)data, length)});
        return true;
    }

    std::vector<std::pair<std::string, std::string>> fChunks;
};

DEF_TEST(RustPngCodec_gainmapDecode, r) {
    auto stream = GetResourceAsStream("images/gainmap.png", false);
    REPORTER_ASSERT(r, stream);

    SkCodec::Result result = SkCodec::kSuccess;
    std::unique_ptr<SkCodec> baseCodec = SkPngRustDecoder::Decode(std::move(stream), &result);
    REPORTER_ASSERT(r, baseCodec);

    std::unique_ptr<SkAndroidCodec> androidCodec =
            SkAndroidCodec::MakeFromCodec(std::move(baseCodec));
    REPORTER_ASSERT(r, androidCodec);

    SkGainmapInfo gainmapInfo;
    std::unique_ptr<SkAndroidCodec> gainmapCodec;
    bool hasGainmap = androidCodec->getGainmapAndroidCodec(&gainmapInfo, &gainmapCodec);

    REPORTER_ASSERT(r, hasGainmap);
    REPORTER_ASSERT(r, gainmapCodec);

    // Decode the gainmap bitmap.
    SkBitmap gainmapBitmap;
    gainmapBitmap.allocPixels(gainmapCodec->getInfo());
    REPORTER_ASSERT(r,
                    SkCodec::kSuccess == gainmapCodec->getAndroidPixels(gainmapBitmap.info(),
                                                                        gainmapBitmap.getPixels(),
                                                                        gainmapBitmap.rowBytes()));

    // Spot-check the image size and pixels (dimensions should be 32x32 for gainmap.png)
    REPORTER_ASSERT(r, gainmapBitmap.dimensions() == SkISize::Make(32, 32));
    REPORTER_ASSERT(r, gainmapBitmap.getColor(0, 0) == 0xffffffff);
    REPORTER_ASSERT(r, gainmapBitmap.getColor(31, 31) == 0xff000000);

    // Verify some gainmap info values (matching recs in PngGainmapTest.cpp)
    REPORTER_ASSERT(r, gainmapInfo.fType == SkGainmapInfo::Type::kDefault);
    REPORTER_ASSERT(r, gainmapInfo.fBaseImageType == SkGainmapInfo::BaseImageType::kHDR);
    REPORTER_ASSERT(r, gainmapInfo.fDisplayRatioSdr == 2.f);
    REPORTER_ASSERT(r, gainmapInfo.fDisplayRatioHdr == 4.f);
}

DEF_TEST(RustPngCodec_gainmapRewind, r) {
    auto stream = GetResourceAsStream("images/gainmap.png", false);
    REPORTER_ASSERT(r, stream);

    MockChunkReader chunkReader;
    SkCodec::Result result = SkCodec::kSuccess;
    std::unique_ptr<SkCodec> baseCodec =
            SkPngRustDecoder::Decode(std::move(stream), &result, &chunkReader);
    REPORTER_ASSERT(r, baseCodec);
    REPORTER_ASSERT(r, chunkReader.fChunks.size() == 2);

    // Decode pixels the first time.
    SkImageInfo info = baseCodec->getInfo();
    SkBitmap bm;
    bm.allocPixels(info);
    result = baseCodec->getPixels(info, bm.getPixels(), bm.rowBytes());
    REPORTER_ASSERT_SUCCESSFUL_CODEC_RESULT(r, result);
    // Should still be 2 (no rewind was needed for first decode).
    REPORTER_ASSERT(r, chunkReader.fChunks.size() == 2);

    // Decode pixels again (forces rewind).
    result = baseCodec->getPixels(info, bm.getPixels(), bm.rowBytes());
    REPORTER_ASSERT_SUCCESSFUL_CODEC_RESULT(r, result);
    // Should be 4 now because rewind recreated the reader and processed chunks again.
    REPORTER_ASSERT(r, chunkReader.fChunks.size() == 4);
}

DEF_TEST(RustPngCodec_ninepatchPngChunkReader, r) {
    auto stream = GetResourceAsStream("images/ninepatch.png", false);
    REPORTER_ASSERT(r, stream);

    MockChunkReader chunkReader;

    SkCodec::Result result;
    std::unique_ptr<SkCodec> codec(
            SkPngRustDecoder::Decode(std::move(stream), &result, &chunkReader));
    REPORTER_ASSERT(r, codec);
    if (!codec) {
        return;
    }

    // Now compare to the original.
    SkBitmap decodedBm;
    decodedBm.setInfo(codec->getInfo());
    decodedBm.allocPixels();
    result = codec->getPixels(codec->getInfo(), decodedBm.getPixels(), decodedBm.rowBytes());
    REPORTER_ASSERT(r, SkCodec::kSuccess == result);
    REPORTER_ASSERT(r, decodedBm.getColor(0, 0) == SK_ColorBLUE);
    REPORTER_ASSERT(r, chunkReader.fChunks.size() == 3);
    REPORTER_ASSERT(r,
                    chunkReader.fChunks[0] ==
                            std::make_pair(std::string("npOl"), std::string("outline", 8)));
    REPORTER_ASSERT(r,
                    chunkReader.fChunks[1] ==
                            std::make_pair(std::string("npLb"), std::string("layoutBounds", 13)));
    REPORTER_ASSERT(r,
                    chunkReader.fChunks[2] ==
                            std::make_pair(std::string("npTc"), std::string("ninePatchData", 14)));
}

DEF_TEST(RustPngCodec_exactRead, r) {
    // Replicates the Codec_end test from CodecExactReadTest.cpp.
    // Verifies that with the limit reader enabled, we don't overshoot
    // and can decode subsequent images from the same stream.
    for (const char* path : {
                 "images/plane.png",
                 "images/yellow_rose.png",
                 "images/plane_interlaced.png",
         }) {
        sk_sp<SkData> data = GetResourceAsData(path);
        if (!data) {
            continue;
        }

        const int kNumImages = 2;
        const size_t size = data->size();
        sk_sp<SkData> multiData = SkData::MakeUninitialized(size * kNumImages);
        void* dst = multiData->writable_data();
        for (int i = 0; i < kNumImages; i++) {
            memcpy(SkTAddOffset<void>(dst, size * i), data->data(), size);
        }
        data.reset();

        SkMemoryStream stream(std::move(multiData));

        for (int i = 0; i < kNumImages; ++i) {
            SkCodec::Result result;
            std::unique_ptr<SkCodec> codec =
                    SkPngRustDecoder::Decode(std::make_unique<UnowningStream>(&stream), &result);
            if (!codec) {
                ERRORF(r, "Failed to create a codec from %s, iteration %i", path, i);
                continue;
            }

            auto info = codec->getInfo().makeColorType(kN32_SkColorType);
            SkBitmap bm;
            bm.allocPixels(info);

            result = codec->getPixels(bm.info(), bm.getPixels(), bm.rowBytes());
            if (result != SkCodec::kSuccess) {
                ERRORF(r, "Failed to getPixels from %s, iteration %i error %i", path, i, result);
                continue;
            }

            // A full decode must drain the stream through `IEND`, leaving it exactly at the start
            // of the next image.
            REPORTER_ASSERT(r,
                            stream.getPosition() == size * (i + 1),
                            "%s: decode %i left the stream at %zu, expected %zu",
                            path,
                            i,
                            stream.getPosition(),
                            size * (i + 1));
        }
    }
}
#else
DEF_TEST(RustPngCodec_gainmapNoOp, r) {
    auto stream = GetResourceAsStream("images/gainmap.png", false);
    REPORTER_ASSERT(r, stream);

    SkCodec::Result result = SkCodec::kSuccess;
    std::unique_ptr<SkCodec> baseCodec = SkPngRustDecoder::Decode(std::move(stream), &result);
    REPORTER_ASSERT(r, baseCodec);

    std::unique_ptr<SkAndroidCodec> androidCodec =
            SkAndroidCodec::MakeFromCodec(std::move(baseCodec));
    REPORTER_ASSERT(r, androidCodec);

    SkGainmapInfo gainmapInfo;
    std::unique_ptr<SkAndroidCodec> gainmapCodec;
    bool hasGainmap = androidCodec->getGainmapAndroidCodec(&gainmapInfo, &gainmapCodec);

    // When the build flag is off, it should return false (no gainmap).
    REPORTER_ASSERT(r, !hasGainmap);
    REPORTER_ASSERT(r, !gainmapCodec);
}

DEF_TEST(RustPngCodec_exactRead_overshoot, r) {
    // Replicates the Codec_end test from CodecExactReadTest.cpp.
    // Verifies that without the limit reader, the decoder overshoots
    // and fails to decode the second image because the stream is misaligned.
    const char* path = "images/plane.png";
    sk_sp<SkData> data = GetResourceAsData(path);
    if (!data) {
        return;
    }

    const int kNumImages = 2;
    const size_t size = data->size();
    sk_sp<SkData> multiData = SkData::MakeUninitialized(size * kNumImages);
    void* dst = multiData->writable_data();
    for (int i = 0; i < kNumImages; i++) {
        memcpy(SkTAddOffset<void>(dst, size * i), data->data(), size);
    }
    data.reset();

    SkMemoryStream stream(std::move(multiData));

    for (int i = 0; i < kNumImages; ++i) {
        SkCodec::Result result;
        std::unique_ptr<SkCodec> codec =
                SkPngRustDecoder::Decode(std::make_unique<UnowningStream>(&stream), &result);
        if (i == 0) {
            if (!codec) {
                ERRORF(r, "Failed to create a codec from %s, iteration %i", path, i);
                return;
            }
            auto info = codec->getInfo().makeColorType(kN32_SkColorType);
            SkBitmap bm;
            bm.allocPixels(info);
            result = codec->getPixels(bm.info(), bm.getPixels(), bm.rowBytes());
            if (result != SkCodec::kSuccess) {
                ERRORF(r, "Failed to getPixels from %s, iteration %i error %i", path, i, result);
                return;
            }
        } else {
            // We expect failure on the second iteration because the first decode overshot.
            REPORTER_ASSERT(r, !codec);
        }
    }
}
#endif

DEF_TEST(RustPngCodec_subset_halting, r) {
    sk_sp<SkData> data = GetResourceAsData("images/mandrill_128.png");
    if (!data) {
        ERRORF(r, "Missing resource: images/mandrill_128.png");
        return;
    }

    // Mandrill is 128x128. We target a center 64x64 subset.
    SkIRect subset = SkIRect::MakeXYWH(32, 32, 64, 64);

    SkBitmap bmOneShot;
    if (!DecodeSubsetOneShot(r, data, subset, &bmOneShot)) {
        return;
    }

    SkBitmap bmHalting;
    if (!DecodeSubsetHalting(r, data, subset, &bmHalting)) {
        return;
    }

    CompareBitmaps(r, bmOneShot, bmHalting);
}

DEF_TEST(RustPngCodec_subsampling, r) {
    for (int sampleSize : {2, 3, 5, 8, 100, 1000}) {
        AssertAndroidDecodeSampling(r, "images/plane.png", sampleSize);
    }
}

DEF_TEST(RustPngCodec_subsampling_interlaced, r) {
    for (int sampleSize : {2, 3, 5, 8, 100, 1000}) {
        AssertAndroidDecodeSampling(r, "images/plane_interlaced.png", sampleSize);
    }
}

DEF_TEST(RustPngCodec_subsampling_subset, r) {
    for (int sampleSize : {2, 3, 5, 8, 100, 1000}) {
        AssertAndroidDecodeSampling(r, "images/plane.png", sampleSize, [](const SkImageInfo& info) {
            return SkIRect::MakeXYWH(info.width() / 2, 0, info.width() / 2, info.height());
        });
    }
}

DEF_TEST(RustPngCodec_subsampling_subset_interlaced, r) {
    for (int sampleSize : {2, 3, 5, 8, 100, 1000}) {
        AssertAndroidDecodeSampling(
                r, "images/plane_interlaced.png", sampleSize, [](const SkImageInfo& info) {
                    return SkIRect::MakeXYWH(0, 1, info.width(), info.height() - 1);
                });
    }
}

// Regression test for a heap buffer overflow.
//
// In `apng-single-frame-with-offset.png`, `IDAT` is a full-canvas 64x64 default
// image, followed by a single `fcTL`/`fdAT` animation frame of size 64x32 at
// y-origin 32:
// * On non-Android (`!SK_CODEC_USES_PNG_WITH_RUST_FOR_ANDROID`), `onIsAnimated`
//   reports `kNo` for a 1-frame APNG, while Frame 0 uses the `fcTL` sub-rect
//   `(0, 32, 64, 64)`. Since that origin is only valid in a full-canvas
//   destination, the codec must refuse sampled or subset decodes (`kUnimplemented`)
//   rather than writing outside the caller's buffer.
// * On Android (`SK_CODEC_USES_PNG_WITH_RUST_FOR_ANDROID`), `acTL`/`fcTL` are
//   ignored for `libpng` parity, so the full-canvas 64x64 `IDAT` default image
//   is decoded and sampled/subset decodes succeed.
DEF_TEST(RustPngCodec_apng_offset_frame_does_not_overflow_dst, r) {
    // 64x64 canvas.  The single frame covers the bottom half: y-origin of 32.
    const char* path = "images/apng-single-frame-with-offset.png";
#if !defined(SK_CODEC_USES_PNG_WITH_RUST_FOR_ANDROID)
    sk_sp<SkData> data = GetResourceAsData(path);
    if (!data) {
        ERRORF(r, "Missing resource: %s", path);
        return;
    }

    struct Case {
        int fSampleSize;
        bool fUseSubset;
        // `0` means `info.minRowBytes()`.  A larger value gives the destination
        // buffer row padding, which makes `rowBytes >= dstInfo.minRowBytes()`
        // even though the buffer holds fewer rows than the full canvas.
        size_t fRowBytes;
    };
    static constexpr Case kCases[] = {
            // Sampling only.  `sampleSize` of 2 halves both dimensions, while a
            // `sampleSize` of 64 makes the destination a single pixel.
            {2, false, 0},
            {64, false, 0},
            {2, false, 256},

            // Subset only.
            {1, true, 0},

            // Subset and sampling.
            {2, true, 0},
    };

    for (const Case& testCase : kCases) {
        AssertAndroidDecodeRefused(
                r, data, testCase.fSampleSize, testCase.fUseSubset, testCase.fRowBytes);
    }
#else
    AssertAndroidStaticApng(r, path);
#endif
}

// A caller that drives `SkCodec` directly (rather than through
// `SkAndroidCodec`) can pass a `rowBytes` that is too small for a full-canvas
// destination.  `SkSampledCodec` does this and then narrows the destination
// with a sampler, but a caller that never asks for a sampler must get a clean
// error instead of a decode into an undersized buffer.
DEF_TEST(RustPngCodec_apng_offset_frame_small_row_bytes, r) {
    const char* path = "images/apng-single-frame-with-offset.png";
    sk_sp<SkData> data = GetResourceAsData(path);
    if (!data) {
        ERRORF(r, "Missing resource: %s", path);
        return;
    }

    auto codec = SkPngRustDecoder::Decode(std::make_unique<SkMemoryStream>(data), nullptr);
    REPORTER_ASSERT(r, codec);
    if (!codec) {
        return;
    }

    const SkImageInfo info = codec->getInfo().makeColorType(kN32_SkColorType);
    std::vector<uint8_t> buffer(info.computeMinByteSize(), 0x00);
    SkCodec::Result result =
            codec->startIncrementalDecode(info, buffer.data(), info.minRowBytes() / 2);
    REPORTER_ASSERT_SUCCESSFUL_CODEC_RESULT(r, result);

    result = codec->incrementalDecode();
    REPORTER_ASSERT(r,
                    result == SkCodec::kInvalidParameters,
                    "expected kInvalidParameters, got %s",
                    SkCodec::ResultToString(result));
}

// On non-Android (`!SK_CODEC_USES_PNG_WITH_RUST_FOR_ANDROID`), the refusal above
// must not change a full-canvas decode: the `fdAT` frame still goes to its
// y=32 origin.  On Android (`SK_CODEC_USES_PNG_WITH_RUST_FOR_ANDROID`), the
// 64x64 `IDAT` default image is decoded instead, matching `libpng`.
DEF_TEST(RustPngCodec_apng_offset_frame_full_canvas_placement, r) {
    const char* path = "images/apng-single-frame-with-offset.png";
#if !defined(SK_CODEC_USES_PNG_WITH_RUST_FOR_ANDROID)
    sk_sp<SkData> data = GetResourceAsData(path);
    if (!data) {
        ERRORF(r, "Missing resource: %s", path);
        return;
    }

    auto codec = SkPngRustDecoder::Decode(std::make_unique<SkMemoryStream>(data), nullptr);
    if (!codec) {
        ERRORF(r, "Failed to create a codec for %s", path);
        return;
    }

    for (SkAlphaType alphaType : {kUnpremul_SkAlphaType, kPremul_SkAlphaType}) {
        SkBitmap bm;
        bm.allocPixels(codec->getInfo().makeColorType(kN32_SkColorType).makeAlphaType(alphaType));
        // The APNG spec says the output buffer starts as transparent black.
        bm.eraseColor(SK_ColorTRANSPARENT);

        SkCodec::Result result = codec->getPixels(bm.pixmap());
        REPORTER_ASSERT_SUCCESSFUL_CODEC_RESULT(r, result);

        // Rows above the frame stay transparent.  The frame fills rows 32..63.
        REPORTER_ASSERT(r, bm.getColor(0, 0) == SK_ColorTRANSPARENT);
        REPORTER_ASSERT(r, bm.getColor(63, 31) == SK_ColorTRANSPARENT);
        REPORTER_ASSERT(r, bm.getColor(0, 32) == SK_ColorMAGENTA);
        REPORTER_ASSERT(r, bm.getColor(63, 63) == SK_ColorMAGENTA);
    }
#else
    AssertAndroidStaticApng(r, path);
#endif
}

#ifdef SK_CODEC_USES_PNG_WITH_RUST_FOR_ANDROID
// Decodes a top subset of `path` and asserts that the decode stopped short of the end of the
// stream, i.e. that `finish_decoding()` was not called. libpng stops early the same way: its row
// callbacks longjmp out once the requested rows have been written, and only a whole-image decode
// reads through `IEND` (`SkPngCodec.cpp`).
// A non-interlaced decode stops inside `IDAT`. An interlaced one has to read every Adam7 pass, and
// the `png` crate consumes `IEND`'s 8-byte length+type header while detecting the end of the
// frame, so it stops with only the 4-byte CRC left.
// Only `for_android` builds limit reads to chunk boundaries; elsewhere the `BufReader` inside the
// `png` crate may have buffered the rest of the file, so the position says nothing.
static void AssertPartialDecodeStopsBeforeIend(
        skiatest::Reporter* r,
        const char* path,
        bool interlaced,
        int sampleSize,
        std::function<SkIRect(const SkImageInfo&)> getSubset = nullptr) {
    sk_sp<SkData> data = GetResourceAsData(path);
    if (!data) {
        ERRORF(r, "Missing resource: %s", path);
        return;
    }

    SkMemoryStream memStream(data);
    std::optional<SkBitmap> bm = DecodeAndroidPixels(
            r,
            SkPngRustDecoder::Decode(std::make_unique<UnowningStream>(&memStream), nullptr),
            sampleSize,
            std::move(getSubset));
    REPORTER_ASSERT(r, bm.has_value());

    // A non-interlaced subset/sampled decode never reads into `IEND` (at most the end of `IDAT`,
    // i.e. `<= data->size() - kIendChunkSize`). An interlaced one reads the 8-byte `IEND` header
    // while detecting end-of-frame, but stops before the 4-byte `IEND` CRC (`< data->size()`).
    const size_t limit = interlaced ? data->size() : data->size() - kIendChunkSize + 1;
    REPORTER_ASSERT(r,
                    memStream.getPosition() < limit,
                    "%s: decode read too far, pos=%zu (expected < %zu, file is %zu, IEND at %zu)",
                    path,
                    memStream.getPosition(),
                    limit,
                    data->size(),
                    data->size() - kIendChunkSize);
}

// Regression tests for b/562939096:
// A subset or subsampled decode must stop after the last row it needs, rather than reading and
// CRC-checking the rest of the PNG stream through `IEND` via `finish_decoding()`.
DEF_TEST(RustPngCodec_subsetDoesNotReadToIend, r) {
    AssertPartialDecodeStopsBeforeIend(
            r,
            "images/mandrill_128.png",
            /*interlaced=*/false,
            /*sampleSize=*/1,
            [](const SkImageInfo& info) { return SkIRect::MakeWH(info.width(), 16); });
}

DEF_TEST(RustPngCodec_subsetDoesNotReadToIend_interlaced, r) {
    AssertPartialDecodeStopsBeforeIend(
            r,
            "images/plane_interlaced.png",
            /*interlaced=*/true,
            /*sampleSize=*/1,
            [](const SkImageInfo& info) { return SkIRect::MakeWH(info.width(), 16); });
}

DEF_TEST(RustPngCodec_subsamplingDoesNotReadToIend, r) {
    AssertPartialDecodeStopsBeforeIend(
            r, "images/mandrill_128.png", /*interlaced=*/false, /*sampleSize=*/2);
}

DEF_TEST(RustPngCodec_subsamplingDoesNotReadToIend_interlaced, r) {
    AssertPartialDecodeStopsBeforeIend(
            r, "images/plane_interlaced.png", /*interlaced=*/true, /*sampleSize=*/2);
}
#endif

// A top subset must decode even if everything after the rows it needs is missing.
DEF_TEST(RustPngCodec_subsetOfTruncatedFile, r) {
    static constexpr char kPath[] = "images/mandrill_128.png";
    sk_sp<SkData> data = GetResourceAsData(kPath);
    if (!data) {
        ERRORF(r, "Missing resource: %s", kPath);
        return;
    }

    auto topSubset = [](const SkImageInfo& info) { return SkIRect::MakeWH(info.width(), 16); };
    std::optional<SkBitmap> refBm = DecodeAndroidPixels(
            r,
            SkPngRustDecoder::Decode(std::make_unique<SkMemoryStream>(data), nullptr),
            /*sampleSize=*/1,
            topSubset);
    REPORTER_ASSERT(r, refBm.has_value());

    sk_sp<SkData> truncatedHalf = SkData::MakeSubset(data.get(), 0, data->size() / 2);
    std::optional<SkBitmap> bm = DecodeAndroidPixels(
            r,
            SkPngRustDecoder::Decode(std::make_unique<SkMemoryStream>(truncatedHalf), nullptr),
            /*sampleSize=*/1,
            topSubset);
    REPORTER_ASSERT(r, bm.has_value());
    if (refBm && bm) {
        CompareBitmaps(r, *refBm, *bm);
    }
}

// Regression tests for b/562802947:
// When all scanlines and the IDAT chunk have been decoded, a corrupt or truncated trailing `IEND`
// CRC in `finish_decoding()` must not cause the decode to fail or zero-fill the output bitmap
// (matching `SkPngCodec` / libpng `png_read_end` behavior and Chrome's `SkPngRustCodec`).
DEF_TEST(RustPngCodec_missingOrCorruptIendSucceeds, r) {
    AssertDecodesWithBrokenIendTail(r, "images/mandrill_128.png");
}

DEF_TEST(RustPngCodec_missingOrCorruptIendSucceeds_interlaced, r) {
    AssertDecodesWithBrokenIendTail(r, "images/plane_interlaced.png");
}

// `images/color_wheel_with_profile.png` is RGBA8 with an `iCCP` chunk, so this covers the
// `read_row` decode path (see `AssertDecodesWithBrokenIendTail`).
DEF_TEST(RustPngCodec_missingOrCorruptIendSucceeds_readRow, r) {
    AssertDecodesWithBrokenIendTail(r, "images/color_wheel_with_profile.png");
}

DEF_TEST(RustPngCodec_missingOrCorruptIendSucceeds_sampled, r) {
    AssertSampledDecodeWithBrokenIendTail(r, "images/mandrill_128.png", /*sampleSize=*/2);
}

// Regression tests for b/565484678 on `images/plane_interlaced.png` (250x126, 8-bit RGB with
// `tRNS`, expanded to RGBA8 -> 4 bytes per encoded pixel = 1000 bytes/row).
//
// First two tests verify that `fPreblendBuffer` in `SkPngRustCodec` is charged against
// `fMaxDecodeMemory` (`allocateFromBudget`) for interlaced sampled/subset decodes, which buffer
// all 126 rows in `fPreblendBuffer`.
DEF_TEST(RustPngCodec_interlacedPreblendBufferBudget_sampled, r) {
    constexpr size_t kEncodedRowBytes = 250 * 4;
    constexpr size_t kFullBufferBytes = 126 * kEncodedRowBytes;

    AssertDecodeBudget(r,
                       "images/plane_interlaced.png",
                       kFullBufferBytes,
                       [&](std::unique_ptr<SkCodec> codec,
                           size_t maxDecodeMemory,
                           SkCodec::Result expectedResult) {
                           return DecodeAndroidPixels(r,
                                                      std::move(codec),
                                                      /*sampleSize=*/2,
                                                      /*getSubset=*/nullptr,
                                                      maxDecodeMemory,
                                                      expectedResult);
                       });
}

DEF_TEST(RustPngCodec_interlacedPreblendBufferBudget_subset, r) {
    constexpr size_t kEncodedRowBytes = 250 * 4;
    constexpr size_t kFullBufferBytes = 126 * kEncodedRowBytes;

    AssertDecodeBudget(r,
                       "images/plane_interlaced.png",
                       kFullBufferBytes,
                       [&](std::unique_ptr<SkCodec> codec,
                           size_t maxDecodeMemory,
                           SkCodec::Result expectedResult) {
                           return DecodeAndroidPixels(
                                   r,
                                   std::move(codec),
                                   /*sampleSize=*/1,
                                   [](const SkImageInfo& info) {
                                       return SkIRect::MakeXYWH(
                                               0, 1, info.width(), info.height() - 1);
                                   },
                                   maxDecodeMemory,
                                   expectedResult);
                       });
}

// Next tests verify that the single-row interlaced scratch buffers
// (`fDecodedInterlacedFullWidthRow`, `fXformedInterlacedRow`, and `SkPngCodecBase::fStorage`) are
// charged against `fMaxDecodeMemory` even when `fPreblendBuffer` is empty (full-image decode of a
// non-blended interlaced PNG).
//
// Note: `plane_interlaced.png` has no embedded ICC profile (`getEncodedInfo().profile() ==
// nullptr`), so `makeColorSpace(nullptr)` is required for `canReadRow()` to match when
// `alphaType == kUnpremul_SkAlphaType`.
DEF_TEST(RustPngCodec_interlacedRowBufferBudget_readRow, r) {
    // `kUnpremul_SkAlphaType` + `kRGBA_8888_SkColorType` + `nullptr` colorSpace takes the
    // `canReadRow()` path, which only allocates `fDecodedInterlacedFullWidthRow`
    // (250 * 4 = 1000 bytes).
    constexpr size_t kEncodedRowBytes = 250 * 4;

    AssertDecodeBudget(r,
                       "images/plane_interlaced.png",
                       kEncodedRowBytes,
                       [&](std::unique_ptr<SkCodec> codec,
                           size_t maxDecodeMemory,
                           SkCodec::Result expectedResult) {
                           return DecodePixels(
                                   r,
                                   std::move(codec),
                                   [](const SkImageInfo& info) {
                                       return info.makeColorType(kRGBA_8888_SkColorType)
                                               .makeAlphaType(kUnpremul_SkAlphaType)
                                               .makeColorSpace(nullptr);
                                   },
                                   MakeBudgetOptions(maxDecodeMemory),
                                   expectedResult);
                       });
}

DEF_TEST(RustPngCodec_interlacedRowBufferBudget_xform, r) {
    // `kPremul_SkAlphaType` + `nullptr` colorSpace takes the `!canReadRow()`
    // (`incrementalDecodeXForm`) path with `kSwizzleOnly_XformMode`, which allocates both
    // `fDecodedInterlacedFullWidthRow` (1000 bytes) and `fXformedInterlacedRow` (1000 bytes).
    constexpr size_t kEncodedRowBytes = 250 * 4;
    constexpr size_t kDstRowBytes = 250 * 4;

    AssertDecodeBudget(r,
                       "images/plane_interlaced.png",
                       kEncodedRowBytes + kDstRowBytes,
                       [&](std::unique_ptr<SkCodec> codec,
                           size_t maxDecodeMemory,
                           SkCodec::Result expectedResult) {
                           return DecodePixels(
                                   r,
                                   std::move(codec),
                                   [](const SkImageInfo& info) {
                                       return info.makeColorType(kRGBA_8888_SkColorType)
                                               .makeAlphaType(kPremul_SkAlphaType)
                                               .makeColorSpace(nullptr);
                                   },
                                   MakeBudgetOptions(maxDecodeMemory),
                                   expectedResult);
                       });
}

// With `kYes_ZeroInitialized`, `fSwizzler` skips writing leading transparent pixels, so
// `fXformedInterlacedRow` must be re-zeroed before each row, or pixels from the previous row
// leak into them. `plane_interlaced.png` has `tRNS` transparency, and `kPremul_SkAlphaType`
// takes the `incrementalDecodeXForm` path.
DEF_TEST(RustPngCodec_interlacedXformZeroInitialized, r) {
    auto decode = [&](SkCodec::ZeroInitialized zeroInit) {
        SkCodec::Options options;
        options.fZeroInitialized = zeroInit;
        return DecodePixels(
                r,
                SkPngRustDecoderDecode(r, "images/plane_interlaced.png"),
                [](const SkImageInfo& info) {
                    return info.makeColorType(kRGBA_8888_SkColorType)
                            .makeAlphaType(kPremul_SkAlphaType)
                            .makeColorSpace(nullptr);
                },
                options);
    };

    std::optional<SkBitmap> zeroInitBm = decode(SkCodec::kYes_ZeroInitialized);
    std::optional<SkBitmap> noZeroInitBm = decode(SkCodec::kNo_ZeroInitialized);
    if (zeroInitBm && noZeroInitBm) {
        CompareBitmaps(r, *noZeroInitBm, *zeroInitBm);
    }
}

DEF_TEST(RustPngCodec_interlacedRowBufferBudget_colorXform, r) {
    // Decoding into a non-sRGB color space (`SkColorSpace::MakeSRGBLinear()`) activates
    // `SkPngCodecBase::allocateStorage` (`fStorage`, 1000 bytes) in addition to
    // `fDecodedInterlacedFullWidthRow` (1000 bytes) and `fXformedInterlacedRow` (1000 bytes).
    constexpr size_t kEncodedRowBytes = 250 * 4;
    constexpr size_t kDstRowBytes = 250 * 4;
    constexpr size_t kColorXformBytes = 250 * 4;

    AssertDecodeBudget(r,
                       "images/plane_interlaced.png",
                       kEncodedRowBytes + kDstRowBytes + kColorXformBytes,
                       [&](std::unique_ptr<SkCodec> codec,
                           size_t maxDecodeMemory,
                           SkCodec::Result expectedResult) {
                           return DecodePixels(
                                   r,
                                   std::move(codec),
                                   [](const SkImageInfo& info) {
                                       return info.makeColorType(kRGBA_8888_SkColorType)
                                               .makeAlphaType(kPremul_SkAlphaType)
                                               .makeColorSpace(SkColorSpace::MakeSRGBLinear());
                                   },
                                   MakeBudgetOptions(maxDecodeMemory),
                                   expectedResult);
                       });
}

// Regression test helper for b/562804783: like `SkPngCodec`, `SkPngRustCodec` must report
// `rowsDecoded` for `kErrorInInput` (not just `kIncompleteInput`), so that callers such as
// `SkCodec::getPixels` keep the rows decoded before the error instead of filling the whole image.
static void AssertRowsDecodedReportedOnErrorInInput(skiatest::Reporter* r,
                                                    SkColorType colorType,
                                                    SkAlphaType alphaType,
                                                    sk_sp<SkColorSpace> colorSpace) {
    // Non-interlaced RGBA8 image whose image data is split across 12 `IDAT` chunks.
    static constexpr char kPath[] = "images/text.png";
    sk_sp<SkData> data = GetResourceAsData(kPath);
    if (!data) {
        ERRORF(r, "Missing resource: %s", kPath);
        return;
    }
    sk_sp<SkData> corruptData = WithCorruptIdatCrc(data.get(), /*idatIndex=*/5);
    if (!corruptData) {
        ERRORF(r, "Failed to corrupt IDAT CRC in %s", kPath);
        return;
    }

    std::unique_ptr<SkCodec> refCodec =
            SkPngRustDecoder::Decode(std::make_unique<SkMemoryStream>(data), nullptr);
    std::unique_ptr<SkCodec> codec =
            SkPngRustDecoder::Decode(std::make_unique<SkMemoryStream>(corruptData), nullptr);
    if (!refCodec || !codec) {
        ERRORF(r, "Failed to create Rust codec");
        return;
    }
    const SkImageInfo info =
            codec->getInfo().makeColorType(colorType).makeAlphaType(alphaType).makeColorSpace(
                    std::move(colorSpace));
    SkBitmap refBitmap;
    refBitmap.allocPixels(info);
    SkCodec::Result result = refCodec->getPixels(info, refBitmap.getPixels(), refBitmap.rowBytes());
    REPORTER_ASSERT_SUCCESSFUL_CODEC_RESULT(r, result);

    SkBitmap bitmap;
    bitmap.allocPixels(info);
    result = codec->startIncrementalDecode(info, bitmap.getPixels(), bitmap.rowBytes());
    REPORTER_ASSERT_SUCCESSFUL_CODEC_RESULT(r, result);
    int rowsDecoded = -1;
    result = codec->incrementalDecode(&rowsDecoded);
    REPORTER_ASSERT(r,
                    result == SkCodec::kErrorInInput,
                    "actualResult=\"%s\" != kErrorInInput",
                    SkCodec::ResultToString(result));
    REPORTER_ASSERT(r,
                    rowsDecoded > 0 && rowsDecoded < info.height(),
                    "rowsDecoded=%d, height=%d",
                    rowsDecoded,
                    info.height());
    if (rowsDecoded <= 0 || rowsDecoded >= info.height()) {
        return;
    }

    // `getPixels` keeps the decoded rows, and only fills the rows after them.
    bitmap.eraseColor(SK_ColorMAGENTA);
    SkCodec::Options options;
    options.fZeroInitialized = SkCodec::kNo_ZeroInitialized;
    result = codec->getPixels(info, bitmap.getPixels(), bitmap.rowBytes(), &options);
    REPORTER_ASSERT(r,
                    result == SkCodec::kErrorInInput,
                    "actualResult=\"%s\" != kErrorInInput",
                    SkCodec::ResultToString(result));
    const size_t rowBytes = info.minRowBytes();
    for (int y = 0; y < rowsDecoded; ++y) {
        if (memcmp(bitmap.getAddr(0, y), refBitmap.getAddr(0, y), rowBytes) != 0) {
            ERRORF(r, "Decoded row %d differs from the intact image", y);
            return;
        }
    }
    for (int y = rowsDecoded; y < info.height(); ++y) {
        if (bitmap.getColor(0, y) == SK_ColorMAGENTA) {
            ERRORF(r, "Row %d after rowsDecoded (%d) was not filled", y, rowsDecoded);
            return;
        }
    }
}

// kRGBA_8888 + kUnpremul without a color space on an RGBA8 source without `iCCP` satisfies
// `canReadRow()`, i.e. goes through `incrementalDecode` (`read_row`).
DEF_TEST(RustPngCodec_rowsDecodedReportedOnErrorInInput_readRow, r) {
    AssertRowsDecodedReportedOnErrorInInput(
            r, kRGBA_8888_SkColorType, kUnpremul_SkAlphaType, /*colorSpace=*/nullptr);
}

DEF_TEST(RustPngCodec_rowsDecodedReportedOnErrorInInput_xform, r) {
    AssertRowsDecodedReportedOnErrorInInput(
            r, kN32_SkColorType, kPremul_SkAlphaType, SkColorSpace::MakeSRGB());
}
