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

#include "experimental/rust_jpeg/decoder/SkJpegRustDecoder.h"
#include "experimental/rust_jpeg/decoder/impl/SkJpegRustCodec.h"

#include <algorithm>
#include <array>
#include <cmath>
#include <cstring>
#include <functional>
#include <memory>
#include <utility>
#include <vector>

#include "include/codec/SkCodec.h"
#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/SkRefCnt.h"
#include "include/core/SkStream.h"
#include "include/core/SkYUVAInfo.h"
#include "include/core/SkYUVAPixmaps.h"
#include "include/private/SkFeatures.h"
#include "rust/common/SkStreamAdapter.h"
#include "tests/ComparePixels.h"
#include "tests/FakeStreams.h"
#include "tests/Test.h"
#include "tools/DecodeUtils.h"
#include "tools/Resources.h"

#if defined(SK_CODEC_ENCODES_JPEG_WITH_RUST)
#include "experimental/rust_jpeg/encoder/SkJpegRustEncoder.h"
#include "include/encode/SkJpegEncoder.h"
#include "tools/ToolUtils.h"
#endif

#if defined(SK_CODEC_DECODES_JPEG_GAINMAPS)
#include "include/codec/SkAndroidCodec.h"
#include "include/private/SkGainmapInfo.h"
#endif

#if defined(SK_CODEC_DECODES_JPEG)
#include "include/codec/SkEncodedOrigin.h"
#include "include/codec/SkJpegDecoder.h"
#include "modules/skcms/skcms.h"
#endif

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

// Helper wrapping a call to `SkJpegRustDecoder::Decode`.
static std::unique_ptr<SkCodec> decode_rust_jpeg(skiatest::Reporter* r, const char* path) {
    skiatest::ReporterContext ctx(r, 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 =
            SkJpegRustDecoder::Decode(SkMemoryStream::Make(std::move(data)), &result);
    REPORTER_ASSERT_SUCCESSFUL_CODEC_RESULT(r, result);
    return codec;
}

static std::unique_ptr<SkCodec> decode_rust_jpeg_data(sk_sp<SkData> data,
                                                      SkCodec::Result* result = nullptr) {
    return SkJpegRustDecoder::Decode(SkMemoryStream::Make(std::move(data)), result);
}

static rust::Box<rust_jpeg::Reader> make_rust_jpeg_reader_for_test(SkStream* stream,
                                                                   uint64_t streamLength) {
    auto reader = rust_jpeg::new_reader(std::make_unique<rust::stream::SkStreamAdapter>(stream),
                                        streamLength);
    SkASSERT_RELEASE(reader->initialization_result() == rust_jpeg::DecodingResult::Success);
    return reader;
}

struct RustJpegReaderForTest {
    explicit RustJpegReaderForTest(std::unique_ptr<SkStream> stream, uint64_t streamLength)
            : fStream(std::move(stream))
            , fReader(make_rust_jpeg_reader_for_test(fStream.get(), streamLength)) {}

    std::unique_ptr<SkStream> fStream;
    rust::Box<rust_jpeg::Reader> fReader;
};

// ========== Decoder Tests ==========

DEF_TEST(RustJpegCodec_IsJpeg, r) {
    sk_sp<SkData> jpegData = GetResourceAsData("images/color_wheel.jpg");
    if (!jpegData) {
        ERRORF(r, "Missing resource: images/color_wheel.jpg");
        return;
    }
    REPORTER_ASSERT(r, SkJpegRustDecoder::IsJpeg(jpegData->data(), jpegData->size()));

    sk_sp<SkData> pngData = GetResourceAsData("images/color_wheel.png");
    if (!pngData) {
        ERRORF(r, "Missing resource: images/color_wheel.png");
        return;
    }
    REPORTER_ASSERT(r, !SkJpegRustDecoder::IsJpeg(pngData->data(), pngData->size()));
}

// Decode a variety of JPEG images covering baseline, progressive, grayscale,
// different subsampling modes, ICC profiles, and other edge cases.
DEF_TEST(RustJpegCodec_decode_valid_jpgs, r) {
    struct TestCase {
        const char* path;
        SkISize expectedDimensions;
    };

    static const TestCase kTestCases[] = {
            {"images/color_wheel.jpg", SkISize::Make(128, 128)},
            {"images/grayscale.jpg", SkISize::Make(128, 128)},
            {"images/dog.jpg", SkISize::Make(180, 180)},
            {"images/b78329453.jpeg", SkISize::Make(635, 760)},
            {"images/mandrill_512_q075.jpg", SkISize::Make(512, 512)},
            {"images/ducky.jpg", SkISize::Make(489, 537)},
            {"images/mandrill_h1v1.jpg", SkISize::Make(512, 512)},
            {"images/mandrill_h2v1.jpg", SkISize::Make(512, 512)},
            {"images/cropped_mandrill.jpg", SkISize::Make(439, 154)},
            {"images/flutter_logo.jpg", SkISize::Make(400, 400)},
            {"images/icc-v2-gbr.jpg", SkISize::Make(275, 207)},
            {"images/randPixels.jpg", SkISize::Make(8, 8)},
            {"images/crbug999986.jpeg", SkISize::Make(2000, 1500)},
            {"images/CMYK.jpg", SkISize::Make(642, 516)},
    };

    for (const auto& tc : kTestCases) {
        skiatest::ReporterContext ctx(r, tc.path);

        std::unique_ptr<SkCodec> codec = decode_rust_jpeg(r, tc.path);
        if (!codec) {
            continue;
        }

        REPORTER_ASSERT(r, codec->getFrameCount() == 1);
        REPORTER_ASSERT(r,
                        codec->dimensions() == tc.expectedDimensions,
                        "dimensions=%dx%d != expected=%dx%d",
                        codec->dimensions().width(),
                        codec->dimensions().height(),
                        tc.expectedDimensions.width(),
                        tc.expectedDimensions.height());

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

// Verify true incremental resumption with a HaltingStream: start decoding with
// incomplete input, observe kIncompleteInput, progressively expose more of the
// same stream, and complete without restarting the decoder.
DEF_TEST(RustJpeg_IncrementalDecode_PartialStreaming, r) {
    struct TestCase {
        const char* path;
        const char* description;
        bool expectProgressivePreview;
    };

    static const TestCase kTestCases[] = {
            {"images/color_wheel.jpg", "baseline RGB 128x128", false},
            {"images/dog.jpg", "RGB 180x180", false},
            {"images/mandrill_512_q075.jpg", "RGB 512x512", false},
            {"images/b78329453.jpeg", "progressive RGB 635x760", true},
    };

    // JPEG headers (SOS, DQT, DHT tables...) can exceed 1 KB. This leaves
    // enough bytes to construct the codec while withholding image data.
    constexpr size_t kInitialBytes = 4 * 1024;
    constexpr size_t kChunkSize = 4 * 1024;
    constexpr int kMaxIterations = 1000;

    for (const auto& testCase : kTestCases) {
        skiatest::ReporterContext ctx(r, testCase.description);

        sk_sp<SkData> data = GetResourceAsData(testCase.path);
        if (!data) {
            ERRORF(r, "Missing resource: %s", testCase.path);
            continue;
        }

        // Decode the full image first so we can verify the incremental result.
        std::unique_ptr<SkCodec> refCodec =
                SkJpegRustDecoder::Decode(SkMemoryStream::Make(data), nullptr);
        if (!refCodec) {
            ERRORF(r, "Failed to create reference codec for %s", testCase.path);
            continue;
        }
        SkBitmap reference;
        reference.allocPixels(refCodec->getInfo().makeColorType(kN32_SkColorType));
        {
            SkCodec::Result refResult = refCodec->getPixels(reference.pixmap());
            REPORTER_ASSERT_SUCCESSFUL_CODEC_RESULT(r, refResult);
            if (refResult != SkCodec::kSuccess) {
                continue;
            }
        }

        REPORTER_ASSERT(r,
                        data->size() > kInitialBytes,
                        "%s: test image must exceed the initial stream window",
                        testCase.description);
        if (data->size() <= kInitialBytes) {
            continue;
        }

        // Create a HaltingStream that starts with the headers and partial image data.
        const size_t initialBytes = kInitialBytes;
        auto haltingStream = std::make_unique<HaltingStream>(data, initialBytes);
        HaltingStream* streamPtr = haltingStream.get();

        SkCodec::Result result;
        std::unique_ptr<SkCodec> codec =
                SkJpegRustDecoder::Decode(std::move(haltingStream), &result);
        if (!codec) {
            ERRORF(r,
                   "%s: failed to create streaming codec with %zu bytes: %s",
                   testCase.description,
                   initialBytes,
                   SkCodec::ResultToString(result));
            continue;
        }

        const SkImageInfo info = codec->getInfo().makeColorType(kN32_SkColorType);
        SkBitmap bitmap;
        if (!bitmap.tryAllocPixels(info)) {
            ERRORF(r, "%s: failed to allocate bitmap", testCase.description);
            continue;
        }
        memset(bitmap.getPixels(), 0xAB, bitmap.computeByteSize());

        result = codec->startIncrementalDecode(info, bitmap.getPixels(), bitmap.rowBytes());
        REPORTER_ASSERT_SUCCESSFUL_CODEC_RESULT(r, result);
        if (result != SkCodec::kSuccess) {
            continue;
        }

        int rowsDecoded = 0;
        int previousRowsDecoded = 0;
        int iterations = 0;
        bool sawIncompleteInput = false;
        bool sawPartialOutput = false;
        bool checkedNoNewDataRetry = false;
        int progressivePreviewCount = 0;
        std::vector<uint8_t> previousPixels(bitmap.computeByteSize(), 0xAB);

        while (iterations++ < kMaxIterations) {
            result = codec->incrementalDecode(&rowsDecoded);

            REPORTER_ASSERT(r,
                            rowsDecoded >= previousRowsDecoded,
                            "%s: decoded row count regressed from %d to %d",
                            testCase.description,
                            previousRowsDecoded,
                            rowsDecoded);

            const uint8_t* pixels = static_cast<const uint8_t*>(bitmap.getPixels());
            if (!testCase.expectProgressivePreview && previousRowsDecoded > 0) {
                const size_t stableBytes =
                        static_cast<size_t>(previousRowsDecoded) * bitmap.rowBytes();
                REPORTER_ASSERT(r,
                                memcmp(pixels, previousPixels.data(), stableBytes) == 0,
                                "%s: previously reported stable rows changed",
                                testCase.description);
            }

            if (result == SkCodec::kSuccess) {
                break;
            }

            REPORTER_ASSERT(r,
                            result == SkCodec::kIncompleteInput,
                            "%s: partial input should return kIncompleteInput, got %s",
                            testCase.description,
                            SkCodec::ResultToString(result));
            if (result != SkCodec::kIncompleteInput) {
                break;
            }
            sawIncompleteInput = true;

            const bool pixelsChanged = std::any_of(pixels,
                                                   pixels + bitmap.computeByteSize(),
                                                   [](uint8_t value) { return value != 0xAB; });
            if (testCase.expectProgressivePreview) {
                if (memcmp(pixels, previousPixels.data(), bitmap.computeByteSize()) != 0) {
                    progressivePreviewCount++;
                    sawPartialOutput = true;
                    REPORTER_ASSERT(r,
                                    rowsDecoded > 0,
                                    "%s: preview pixels were not reported as initialized",
                                    testCase.description);
                }
            } else if (rowsDecoded > 0) {
                sawPartialOutput = true;
                REPORTER_ASSERT(r,
                                pixelsChanged,
                                "%s: reported stable rows were not written",
                                testCase.description);
            }

            for (int y = 0; y < rowsDecoded; ++y) {
                for (int x = 0; x < info.width(); ++x) {
                    REPORTER_ASSERT(r,
                                    SkColorGetA(bitmap.getColor(x, y)) == SK_AlphaOPAQUE,
                                    "%s: initialized pixel (%d,%d) is not opaque",
                                    testCase.description,
                                    x,
                                    y);
                }
            }

            previousRowsDecoded = rowsDecoded;
            memcpy(previousPixels.data(), pixels, bitmap.computeByteSize());

            if (!checkedNoNewDataRetry && sawPartialOutput) {
                int retryRowsDecoded = -1;
                const SkCodec::Result retryResult = codec->incrementalDecode(&retryRowsDecoded);
                REPORTER_ASSERT(r,
                                retryResult == SkCodec::kIncompleteInput,
                                "%s: retry without new data returned %s",
                                testCase.description,
                                SkCodec::ResultToString(retryResult));
                REPORTER_ASSERT(r,
                                retryRowsDecoded == rowsDecoded,
                                "%s: retry changed initialized rows from %d to %d",
                                testCase.description,
                                rowsDecoded,
                                retryRowsDecoded);
                REPORTER_ASSERT(
                        r,
                        memcmp(pixels, previousPixels.data(), bitmap.computeByteSize()) == 0,
                        "%s: retry without new data changed output",
                        testCase.description);
                checkedNoNewDataRetry = true;
            }

            if (streamPtr->isAllDataReceived()) {
                ERRORF(r,
                       "%s: still incomplete after all data was available",
                       testCase.description);
                break;
            }

            // Do not call startIncrementalDecode() again. Each subsequent call
            // must resume the existing Rust/zune decoder after one more chunk
            // becomes available.
            streamPtr->addNewData(kChunkSize);
        }

        REPORTER_ASSERT(r,
                        iterations < kMaxIterations,
                        "%s: decode loop exceeded max iterations",
                        testCase.description);
        REPORTER_ASSERT(r,
                        sawIncompleteInput,
                        "%s: decode never observed incomplete input",
                        testCase.description);
        REPORTER_ASSERT(r,
                        sawPartialOutput,
                        "%s: no partial output was exposed before all input arrived",
                        testCase.description);
        REPORTER_ASSERT(r,
                        checkedNoNewDataRetry,
                        "%s: retry without new input was not exercised",
                        testCase.description);
        if (testCase.expectProgressivePreview) {
            REPORTER_ASSERT(r,
                            progressivePreviewCount >= 2,
                            "%s: expected multiple progressive preview replacements, got %d",
                            testCase.description,
                            progressivePreviewCount);
        }
        REPORTER_ASSERT(r,
                        result == SkCodec::kSuccess,
                        "%s: resumed decode expected kSuccess, got %s",
                        testCase.description,
                        SkCodec::ResultToString(result));
        REPORTER_ASSERT(r,
                        rowsDecoded == info.height(),
                        "%s: resumed decode reported %d of %d rows",
                        testCase.description,
                        rowsDecoded,
                        info.height());

        // Verify dimensions match the reference.
        REPORTER_ASSERT(r,
                        bitmap.dimensions() == reference.dimensions(),
                        "%s: incremental dims %dx%d != reference %dx%d",
                        testCase.description,
                        bitmap.width(),
                        bitmap.height(),
                        reference.width(),
                        reference.height());

        // Both paths used the same Rust decoder, so pixel output should be
        // identical (zero tolerance).
        if (bitmap.dimensions() == reference.dimensions()) {
            const float tols[4] = {0, 0, 0, 0};
            auto error = std::function<ComparePixmapsErrorReporter>(
                    [&](int x, int y, const float diffs[4]) {
                        ERRORF(r,
                               "%s: pixel differs at (%d,%d): diffs=(%f,%f,%f,%f)",
                               testCase.description,
                               x,
                               y,
                               diffs[0],
                               diffs[1],
                               diffs[2],
                               diffs[3]);
                    });
            ComparePixels(bitmap.pixmap(), reference.pixmap(), tols, error);
        }
    }
}

DEF_TEST(RustJpeg_IncrementalDecode_RejectsSubset, r) {
    std::unique_ptr<SkCodec> codec = decode_rust_jpeg(r, "images/color_wheel.jpg");
    if (!codec) {
        return;
    }

    const SkImageInfo info = codec->getInfo().makeColorType(kN32_SkColorType);
    const SkIRect subset = SkIRect::MakeXYWH(0, 1, info.width(), info.height() - 1);
    SkBitmap bitmap;
    bitmap.allocPixels(info.makeWH(subset.width(), subset.height()));

    SkCodec::Options options;
    options.fSubset = &subset;
    const SkCodec::Result result =
            codec->startIncrementalDecode(info, bitmap.getPixels(), bitmap.rowBytes(), &options);
    REPORTER_ASSERT(r,
                    result == SkCodec::kInvalidParameters,
                    "incremental subset decode returned %s",
                    SkCodec::ResultToString(result));
}

DEF_TEST(RustJpeg_IncrementalDecode_RejectsShortRowBytes, r) {
    std::unique_ptr<SkCodec> codec = decode_rust_jpeg(r, "images/color_wheel.jpg");
    if (!codec) {
        return;
    }

    const SkImageInfo info = codec->getInfo().makeColorType(kN32_SkColorType);
    SkBitmap bitmap;
    bitmap.allocPixels(info);
    const SkCodec::Result result =
            codec->startIncrementalDecode(info, bitmap.getPixels(), info.minRowBytes() - 1);
    REPORTER_ASSERT(r,
                    result == SkCodec::kInvalidParameters,
                    "short incremental row bytes returned %s",
                    SkCodec::ResultToString(result));
}

DEF_TEST(RustJpeg_IncrementalDecode_AfterRewind, r) {
    std::unique_ptr<SkCodec> codec = decode_rust_jpeg(r, "images/color_wheel.jpg");
    if (!codec) {
        return;
    }

    const SkImageInfo info = codec->getInfo().makeColorType(kN32_SkColorType);
    SkBitmap firstIncremental;
    firstIncremental.allocPixels(info);
    REPORTER_ASSERT_SUCCESSFUL_CODEC_RESULT(
            r,
            codec->startIncrementalDecode(
                    info, firstIncremental.getPixels(), firstIncremental.rowBytes()));
    int rowsDecoded = 0;
    REPORTER_ASSERT_SUCCESSFUL_CODEC_RESULT(r, codec->incrementalDecode(&rowsDecoded));
    REPORTER_ASSERT(r, rowsDecoded == info.height());

    auto [fullImage, fullResult] = codec->getImage();
    REPORTER_ASSERT_SUCCESSFUL_CODEC_RESULT(r, fullResult);
    REPORTER_ASSERT(r, fullImage);

    SkBitmap secondIncremental;
    secondIncremental.allocPixels(info);
    REPORTER_ASSERT_SUCCESSFUL_CODEC_RESULT(
            r,
            codec->startIncrementalDecode(
                    info, secondIncremental.getPixels(), secondIncremental.rowBytes()));
    rowsDecoded = 0;
    REPORTER_ASSERT_SUCCESSFUL_CODEC_RESULT(r, codec->incrementalDecode(&rowsDecoded));
    REPORTER_ASSERT(r, rowsDecoded == info.height());

    REPORTER_ASSERT(r, firstIncremental.computeByteSize() == secondIncremental.computeByteSize());
    REPORTER_ASSERT(r,
                    memcmp(firstIncremental.getPixels(),
                           secondIncremental.getPixels(),
                           firstIncremental.computeByteSize()) == 0);
}

DEF_TEST(RustJpeg_IncrementalDecode_ColorTransformPaddedStride, r) {
    // This file has more than 32 KiB of metadata before its decodable scan data.
    constexpr size_t kInitialBytes = 34 * 1024;
    constexpr size_t kChunkSize = 4 * 1024;
    constexpr int kMaxIterations = 1000;

    sk_sp<SkData> data = GetResourceAsData("images/icc-v2-gbr.jpg");
    if (!data) {
        ERRORF(r, "Missing resource: images/icc-v2-gbr.jpg");
        return;
    }

    std::unique_ptr<SkCodec> referenceCodec =
            SkJpegRustDecoder::Decode(SkMemoryStream::Make(data), nullptr);
    REPORTER_ASSERT(r, referenceCodec);
    if (!referenceCodec) {
        return;
    }

    const SkImageInfo dstInfo = referenceCodec->getInfo()
                                        .makeColorType(kRGBA_8888_SkColorType)
                                        .makeColorSpace(SkColorSpace::MakeSRGB());
    SkBitmap reference;
    reference.allocPixels(dstInfo);
    REPORTER_ASSERT_SUCCESSFUL_CODEC_RESULT(
            r, referenceCodec->getPixels(dstInfo, reference.getPixels(), reference.rowBytes()));

    auto haltingStream = std::make_unique<HaltingStream>(data, kInitialBytes);
    HaltingStream* streamPtr = haltingStream.get();
    SkCodec::Result result;
    std::unique_ptr<SkCodec> codec = SkJpegRustDecoder::Decode(std::move(haltingStream), &result);
    REPORTER_ASSERT_SUCCESSFUL_CODEC_RESULT(r, result);
    REPORTER_ASSERT(r, codec);
    if (!codec) {
        return;
    }

    const size_t paddedRowBytes = dstInfo.minRowBytes() + 32;
    SkBitmap incremental;
    incremental.allocPixels(dstInfo, paddedRowBytes);
    memset(incremental.getPixels(), 0xAB, incremental.computeByteSize());

    REPORTER_ASSERT_SUCCESSFUL_CODEC_RESULT(
            r,
            codec->startIncrementalDecode(
                    dstInfo, incremental.getPixels(), incremental.rowBytes()));

    int rowsDecoded = 0;
    int iterations = 0;
    bool sawIncompleteInput = false;
    do {
        result = codec->incrementalDecode(&rowsDecoded);
        if (result == SkCodec::kIncompleteInput) {
            sawIncompleteInput = true;
            REPORTER_ASSERT(r, !streamPtr->isAllDataReceived());
            streamPtr->addNewData(kChunkSize);
        }
    } while (result == SkCodec::kIncompleteInput && iterations++ < kMaxIterations);

    REPORTER_ASSERT(r, sawIncompleteInput);
    REPORTER_ASSERT(r, iterations < kMaxIterations);
    REPORTER_ASSERT_SUCCESSFUL_CODEC_RESULT(r, result);
    REPORTER_ASSERT(r, rowsDecoded == dstInfo.height());

    const float tolerances[4] = {0, 0, 0, 0};
    auto reportError =
            std::function<ComparePixmapsErrorReporter>([&](int x, int y, const float diffs[4]) {
                ERRORF(r,
                       "incremental transformed pixel differs at (%d,%d): "
                       "diffs=(%f,%f,%f,%f)",
                       x,
                       y,
                       diffs[0],
                       diffs[1],
                       diffs[2],
                       diffs[3]);
            });
    ComparePixels(reference.pixmap(), incremental.pixmap(), tolerances, reportError);

    const size_t pixelBytes = dstInfo.minRowBytes();
    for (int y = 0; y + 1 < dstInfo.height(); ++y) {
        const uint8_t* row = static_cast<const uint8_t*>(incremental.getAddr(0, y));
        REPORTER_ASSERT(r,
                        std::all_of(row + pixelBytes,
                                    row + paddedRowBytes,
                                    [](uint8_t value) { return value == 0xAB; }),
                        "incremental decode modified row %d padding",
                        y);
    }
}

DEF_TEST(RustJpegCodec_rewind, r) {
    std::unique_ptr<SkCodec> codec = decode_rust_jpeg(r, "images/color_wheel.jpg");
    if (!codec) {
        return;
    }

    auto [image1, result1] = codec->getImage();
    REPORTER_ASSERT_SUCCESSFUL_CODEC_RESULT(r, result1);
    REPORTER_ASSERT(r, image1);

    auto [image2, result2] = codec->getImage();
    REPORTER_ASSERT_SUCCESSFUL_CODEC_RESULT(r, result2);
    REPORTER_ASSERT(r, image2);

    REPORTER_ASSERT(r, image1->dimensions() == image2->dimensions());
}

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

    // Keep only the first third of the data.
    sk_sp<SkData> truncated = SkData::MakeSubset(data.get(), 0, data->size() / 3);

    SkCodec::Result result;
    std::unique_ptr<SkCodec> codec =
            SkJpegRustDecoder::Decode(SkMemoryStream::Make(std::move(truncated)), &result);
    if (!codec) {
        // Acceptable: codec construction failed.
        REPORTER_ASSERT(r, result != SkCodec::kSuccess);
        return;
    }

    // If codec constructed, decoding may succeed (Rust decoder is lenient with
    // truncated data) or fail - either outcome is acceptable.
    auto [image, decodeResult] = codec->getImage();
    (void)decodeResult;
}

DEF_TEST(RustJpegCodec_short_input_classification, r) {
    const auto decode = [](sk_sp<SkData> data, SkCodec::Result* result) {
        return SkJpegRustDecoder::Decode(SkMemoryStream::Make(std::move(data)), result);
    };

    SkCodec::Result result;
    std::unique_ptr<SkCodec> codec = decode(SkData::MakeEmpty(), &result);
    REPORTER_ASSERT(r, !codec);
    REPORTER_ASSERT(r, result == SkCodec::kIncompleteInput);

    constexpr uint8_t kPartialSignature[] = {0xFF};
    codec = decode(SkData::MakeWithCopy(kPartialSignature, sizeof(kPartialSignature)), &result);
    REPORTER_ASSERT(r, !codec);
    REPORTER_ASSERT(r, result == SkCodec::kIncompleteInput);

    constexpr uint8_t kInvalidSignature[] = {0x00};
    codec = decode(SkData::MakeWithCopy(kInvalidSignature, sizeof(kInvalidSignature)), &result);
    REPORTER_ASSERT(r, !codec);
    REPORTER_ASSERT(r, result == SkCodec::kErrorInInput);

    constexpr uint8_t kStartOfImage[] = {0xFF, 0xD8};
    codec = decode(SkData::MakeWithCopy(kStartOfImage, sizeof(kStartOfImage)), &result);
    REPORTER_ASSERT(r, !codec);
    REPORTER_ASSERT(r, result == SkCodec::kIncompleteInput);

    sk_sp<SkData> data = GetResourceAsData("images/color_wheel.jpg");
    REPORTER_ASSERT(r, data);
    if (!data) {
        return;
    }

    codec = decode(std::move(data), &result);
    REPORTER_ASSERT_SUCCESSFUL_CODEC_RESULT(r, result);
    REPORTER_ASSERT(r, codec);
}

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

    SkCodec::Result result;
    std::unique_ptr<SkCodec> codec =
            SkJpegRustDecoder::Decode(SkMemoryStream::Make(std::move(data)), &result);
    REPORTER_ASSERT(r, !codec, "Should reject PNG data as JPEG");
}

// Decode an ICC-profiled JPEG into an explicit sRGB color space, exercising the
// applyColorXform() path (xformOnDecode == true).
DEF_TEST(RustJpegCodec_decode_with_color_transform, r) {
    std::unique_ptr<SkCodec> codec = decode_rust_jpeg(r, "images/icc-v2-gbr.jpg");
    if (!codec) {
        return;
    }

    // The image has a non-sRGB ICC profile. Requesting sRGB forces a color transform.
    SkImageInfo dstInfo = codec->getInfo()
                                  .makeColorType(kRGBA_8888_SkColorType)
                                  .makeColorSpace(SkColorSpace::MakeSRGB());
    SkBitmap bitmap;
    bitmap.allocPixels(dstInfo);
    SkCodec::Result result = codec->getPixels(dstInfo, bitmap.getPixels(), bitmap.rowBytes());
    REPORTER_ASSERT_SUCCESSFUL_CODEC_RESULT(r, result);

    // Sanity: the decoded pixels should not be all zero (would indicate garbled output).
    bool allZero = true;
    const uint32_t* pixels = static_cast<const uint32_t*>(bitmap.getPixels());
    for (int i = 0; i < bitmap.width() * bitmap.height() && allZero; ++i) {
        if (pixels[i] != 0) {
            allZero = false;
        }
    }
    REPORTER_ASSERT(r, !allZero, "Color-transformed decode produced all-zero pixels");
}

#if defined(SK_CODEC_DECODES_JPEG)

DEF_TEST(RustJpegCodec_RawYUVAParity, r) {
    struct TestCase {
        const char* path;
        SkYUVAInfo::Subsampling subsampling;
    };
    const TestCase testCases[] = {
            {"images/orientation/1_444.jpg", SkYUVAInfo::Subsampling::k444},
            {"images/orientation/1_422.jpg", SkYUVAInfo::Subsampling::k422},
            {"images/orientation/1_420.jpg", SkYUVAInfo::Subsampling::k420},
            {"images/orientation/1_440.jpg", SkYUVAInfo::Subsampling::k440},
            {"images/orientation/1_411.jpg", SkYUVAInfo::Subsampling::k411},
            {"images/orientation/1_410.jpg", SkYUVAInfo::Subsampling::k410},
            {"images/cropped_mandrill.jpg", SkYUVAInfo::Subsampling::k420},
            {"images/brickwork-texture.jpg", SkYUVAInfo::Subsampling::k444},
            {"images/non_interleaved_420_64x64.jpg", SkYUVAInfo::Subsampling::k420},
            {"images/four-colors-limited-range-420-8bpc.jpg", SkYUVAInfo::Subsampling::k420},
            {"images/b78329453.jpeg", SkYUVAInfo::Subsampling::k420},
    };
    constexpr auto kAllTypes = SkYUVAPixmapInfo::SupportedDataTypes::All();
    int maximumDeviation = 0;

    for (const TestCase& testCase : testCases) {
        skiatest::ReporterContext context(r, testCase.path);
        sk_sp<SkData> data = GetResourceAsData(testCase.path);
        REPORTER_ASSERT(r, data);
        if (!data) {
            continue;
        }

        std::unique_ptr<SkCodec> rustCodec = decode_rust_jpeg_data(data);
        std::unique_ptr<SkCodec> jpegCodec =
                SkJpegDecoder::Decode(SkMemoryStream::Make(data), nullptr);
        REPORTER_ASSERT(r, rustCodec && jpegCodec);
        if (!rustCodec || !jpegCodec) {
            continue;
        }

        SkYUVAPixmapInfo rustInfo;
        SkYUVAPixmapInfo jpegInfo;
        REPORTER_ASSERT(r, rustCodec->queryYUVAInfo(kAllTypes, &rustInfo));
        REPORTER_ASSERT(r, jpegCodec->queryYUVAInfo(kAllTypes, &jpegInfo));
        if (!rustInfo.isValid() || !jpegInfo.isValid()) {
            continue;
        }
        REPORTER_ASSERT(r, rustInfo.yuvaInfo() == jpegInfo.yuvaInfo());
        REPORTER_ASSERT(r, rustInfo.yuvaInfo().subsampling() == testCase.subsampling);
        REPORTER_ASSERT(r, rustInfo.yuvaInfo().yuvColorSpace() == kJPEG_Full_SkYUVColorSpace);
        REPORTER_ASSERT(r, rustInfo.yuvaInfo().origin() == rustCodec->getOrigin());

        std::array<std::vector<uint8_t>, SkYUVAPixmaps::kMaxPlanes> storage;
        std::array<SkPixmap, SkYUVAPixmaps::kMaxPlanes> pixmaps;
        for (int plane = 0; plane < rustInfo.numPlanes(); ++plane) {
            const SkImageInfo& info = rustInfo.planeInfo(plane);
            const size_t rowBytes = static_cast<size_t>(info.width()) + 13;
            const size_t exactSize = (static_cast<size_t>(info.height()) - 1) * rowBytes +
                                     static_cast<size_t>(info.width());
            storage[plane].assign(exactSize, 0xCD);
            pixmaps[plane] = SkPixmap(info, storage[plane].data(), rowBytes);
        }
        SkYUVAPixmaps rustPlanes =
                SkYUVAPixmaps::FromExternalPixmaps(rustInfo.yuvaInfo(), pixmaps.data());
        SkYUVAPixmaps jpegPlanes = SkYUVAPixmaps::Allocate(jpegInfo);
        REPORTER_ASSERT(r, rustPlanes.isValid() && jpegPlanes.isValid());
        REPORTER_ASSERT_SUCCESSFUL_CODEC_RESULT(r, rustCodec->getYUVAPlanes(rustPlanes));
        REPORTER_ASSERT_SUCCESSFUL_CODEC_RESULT(r, jpegCodec->getYUVAPlanes(jpegPlanes));

        if (&testCase == &testCases[0] ||
            !strcmp(testCase.path, "images/four-colors-limited-range-420-8bpc.jpg")) {
            SkYUVAPixmaps replay = SkYUVAPixmaps::Allocate(rustInfo);
            REPORTER_ASSERT_SUCCESSFUL_CODEC_RESULT(r, rustCodec->getYUVAPlanes(replay));
            for (int plane = 0; plane < rustPlanes.numPlanes(); ++plane) {
                for (int y = 0; y < rustPlanes.plane(plane).height(); ++y) {
                    REPORTER_ASSERT(
                            r,
                            memcmp(rustPlanes.plane(plane).addr(0, y),
                                   replay.plane(plane).addr(0, y),
                                   static_cast<size_t>(rustPlanes.plane(plane).width())) == 0);
                }
            }
        }

        for (int plane = 0; plane < rustPlanes.numPlanes(); ++plane) {
            const SkPixmap& actual = rustPlanes.plane(plane);
            const SkPixmap& expected = jpegPlanes.plane(plane);
            REPORTER_ASSERT(r, actual.dimensions() == expected.dimensions());
            for (int y = 0; y < actual.height(); ++y) {
                const auto* actualRow = static_cast<const uint8_t*>(actual.addr(0, y));
                const auto* expectedRow = static_cast<const uint8_t*>(expected.addr(0, y));
                for (int x = 0; x < actual.width(); ++x) {
                    const int deviation = std::abs(static_cast<int>(actualRow[x]) -
                                                   static_cast<int>(expectedRow[x]));
                    maximumDeviation = std::max(maximumDeviation, deviation);
                    REPORTER_ASSERT(r,
                                    deviation <= 2,
                                    "%s plane %d sample (%d,%d) deviation %d exceeds 2",
                                    testCase.path,
                                    plane,
                                    x,
                                    y,
                                    deviation);
                }
                if (y + 1 < actual.height()) {
                    REPORTER_ASSERT(r,
                                    std::all_of(actualRow + actual.width(),
                                                actualRow + actual.rowBytes(),
                                                [](uint8_t value) { return value == 0xCD; }),
                                    "%s plane %d row %d padding was modified",
                                    testCase.path,
                                    plane,
                                    y);
                }
            }
        }
    }
    INFOF(r, "Rust JPEG raw-plane maximum libjpeg-turbo deviation: %d", maximumDeviation);

    for (const char* path : {"images/grayscale.jpg", "images/CMYK.jpg"}) {
        std::unique_ptr<SkCodec> codec = decode_rust_jpeg(r, path);
        SkYUVAPixmapInfo info;
        REPORTER_ASSERT(r, codec && !codec->queryYUVAInfo(kAllTypes, &info));
    }

    sk_sp<SkData> source = GetResourceAsData("images/orientation/1_444.jpg");
    REPORTER_ASSERT(r, source);
    if (source) {
        auto makeMutatedSOF = [&](size_t componentOffset, uint8_t value) {
            sk_sp<SkData> mutated = SkData::MakeUninitialized(source->size());
            memcpy(mutated->writable_data(), source->data(), source->size());
            auto* bytes = static_cast<uint8_t*>(mutated->writable_data());
            for (size_t index = 0; index + 16 < mutated->size(); ++index) {
                if (bytes[index] == 0xFF && bytes[index + 1] == 0xC0) {
                    bytes[index + componentOffset] = value;
                    break;
                }
            }
            if (componentOffset == 10) {
                for (size_t index = 0; index + 6 < mutated->size(); ++index) {
                    if (bytes[index] == 0xFF && bytes[index + 1] == 0xDA) {
                        bytes[index + 5] = value;
                        break;
                    }
                }
            }
            return mutated;
        };
        struct Mutation {
            const char* description;
            sk_sp<SkData> data;
        };
        Mutation mutations[] = {{"component ID", makeMutatedSOF(10, 4)},
                                {"chroma sampling", makeMutatedSOF(14, 0x21)}};
        for (Mutation& mutation : mutations) {
            skiatest::ReporterContext context(r, mutation.description);
            std::unique_ptr<SkCodec> codec = decode_rust_jpeg_data(std::move(mutation.data));
            SkYUVAPixmapInfo info;
            REPORTER_ASSERT(r, codec && !codec->queryYUVAInfo(kAllTypes, &info));
        }
    }
}

#endif

DEF_TEST(RustJpegCodec_ProgressiveRawYUVRetry, r) {
    sk_sp<SkData> data = GetResourceAsData("images/four-colors-limited-range-420-8bpc.jpg");
    REPORTER_ASSERT(r, data);
    if (!data) {
        return;
    }

    auto stream = std::make_unique<HaltingStream>(data, data->size() / 2);
    HaltingStream* streamPtr = stream.get();
    SkCodec::Result result;
    std::unique_ptr<SkCodec> codec = SkJpegRustDecoder::Decode(std::move(stream), &result);
    REPORTER_ASSERT_SUCCESSFUL_CODEC_RESULT(r, result);
    REPORTER_ASSERT(r, codec);
    if (!codec) {
        return;
    }

    constexpr auto kAllTypes = SkYUVAPixmapInfo::SupportedDataTypes::All();
    SkYUVAPixmapInfo info;
    REPORTER_ASSERT(r, codec->queryYUVAInfo(kAllTypes, &info));
    REPORTER_ASSERT(r, info.yuvaInfo().planeConfig() == SkYUVAInfo::PlaneConfig::kY_U_V);
    REPORTER_ASSERT(r, info.yuvaInfo().subsampling() == SkYUVAInfo::Subsampling::k420);

    std::array<std::vector<uint8_t>, SkYUVAPixmaps::kMaxPlanes> storage;
    std::array<SkPixmap, SkYUVAPixmaps::kMaxPlanes> pixmaps;
    for (int plane = 0; plane < info.numPlanes(); ++plane) {
        const SkImageInfo& planeInfo = info.planeInfo(plane);
        const size_t rowBytes = static_cast<size_t>(planeInfo.width()) + 13;
        storage[plane].assign(rowBytes * static_cast<size_t>(planeInfo.height()), 0xCD);
        pixmaps[plane] = SkPixmap(planeInfo, storage[plane].data(), rowBytes);
    }
    SkYUVAPixmaps planes = SkYUVAPixmaps::FromExternalPixmaps(info.yuvaInfo(), pixmaps.data());
    REPORTER_ASSERT(r, planes.isValid());

    REPORTER_ASSERT(r, codec->getYUVAPlanes(planes) == SkCodec::kIncompleteInput);
    for (int plane = 0; plane < planes.numPlanes(); ++plane) {
        REPORTER_ASSERT(
                r, std::all_of(storage[plane].begin(), storage[plane].end(), [](uint8_t value) {
                    return value == 0xCD;
                }));
    }

    streamPtr->addNewData(data->size());
    REPORTER_ASSERT_SUCCESSFUL_CODEC_RESULT(r, codec->getYUVAPlanes(planes));
    for (int plane = 0; plane < planes.numPlanes(); ++plane) {
        REPORTER_ASSERT(
                r, std::any_of(storage[plane].begin(), storage[plane].end(), [](uint8_t value) {
                    return value != 0xCD;
                }));
    }
}

DEF_TEST(RustJpegCodec_RawDirectPlaneContracts, r) {
    constexpr uint8_t kSentinel = 0xCD;
    sk_sp<SkData> data = GetResourceAsData("images/color_wheel.jpg");
    REPORTER_ASSERT(r, data);
    if (!data) {
        return;
    }

    auto makeReader = [&]() {
        return RustJpegReaderForTest(SkMemoryStream::Make(data), data->size());
    };
    auto reader = makeReader();
    REPORTER_ASSERT(r, reader.fReader->read_metadata() == rust_jpeg::DecodingResult::Success);
    REPORTER_ASSERT(r, reader.fReader->raw_component_count() == 3);

    std::array<rust_jpeg::RawPlaneInfo, 3> infos = {
            reader.fReader->raw_plane_info(0),
            reader.fReader->raw_plane_info(1),
            reader.fReader->raw_plane_info(2),
    };
    std::array<size_t, 3> strides;
    std::array<size_t, 3> rows;
    std::array<size_t, 3> required;
    for (int plane = 0; plane < 3; ++plane) {
        strides[plane] = static_cast<size_t>(infos[plane].width) + 7 + plane * 3;
        rows[plane] = std::min(static_cast<size_t>(infos[plane].height),
                               static_cast<size_t>(infos[plane].vertical_sampling_factor) * 8);
        required[plane] =
                rows[plane] == 0 ? 0 : (rows[plane] - 1) * strides[plane] + infos[plane].width;
    }

    std::array<std::vector<uint8_t>, 3> expected;
    for (int plane = 0; plane < 3; ++plane) {
        expected[plane].assign(required[plane], kSentinel);
    }
    rust_jpeg::RawOutputResult expectedResult = reader.fReader->read_raw_imcu_row(
            rust::Slice<uint8_t>(expected[0].data(), expected[0].size()),
            static_cast<uint32_t>(strides[0]),
            rust::Slice<uint8_t>(expected[1].data(), expected[1].size()),
            static_cast<uint32_t>(strides[1]),
            rust::Slice<uint8_t>(expected[2].data(), expected[2].size()),
            static_cast<uint32_t>(strides[2]));
    REPORTER_ASSERT(r, expectedResult.status == rust_jpeg::OutputStatus::Ready);
    const std::array<uint32_t, 3> expectedRows = {
            expectedResult.y_rows, expectedResult.u_rows, expectedResult.v_rows};
    for (int plane = 0; plane < 3; ++plane) {
        REPORTER_ASSERT(r, expectedRows[plane] == rows[plane]);
        for (size_t row = 0; row + 1 < rows[plane]; ++row) {
            REPORTER_ASSERT(
                    r,
                    std::all_of(expected[plane].begin() + row * strides[plane] + infos[plane].width,
                                expected[plane].begin() + (row + 1) * strides[plane],
                                [](uint8_t value) { return value == kSentinel; }));
        }
    }

    for (int shortPlane = 0; shortPlane < 3; ++shortPlane) {
        auto shortReader = makeReader();
        REPORTER_ASSERT(r,
                        shortReader.fReader->read_metadata() == rust_jpeg::DecodingResult::Success);
        std::array<std::vector<uint8_t>, 3> storage;
        for (int plane = 0; plane < 3; ++plane) {
            storage[plane].assign(required[plane] - (plane == shortPlane), kSentinel);
        }
        rust_jpeg::RawOutputResult result = shortReader.fReader->read_raw_imcu_row(
                rust::Slice<uint8_t>(storage[0].data(), storage[0].size()),
                static_cast<uint32_t>(strides[0]),
                rust::Slice<uint8_t>(storage[1].data(), storage[1].size()),
                static_cast<uint32_t>(strides[1]),
                rust::Slice<uint8_t>(storage[2].data(), storage[2].size()),
                static_cast<uint32_t>(strides[2]));
        REPORTER_ASSERT(r, result.status == rust_jpeg::OutputStatus::Error);
        for (const auto& plane : storage) {
            REPORTER_ASSERT(r, std::all_of(plane.begin(), plane.end(), [](uint8_t value) {
                                return value == kSentinel;
                            }));
        }
    }

    size_t entropyStart = 0;
    const uint8_t* bytes = data->bytes();
    for (size_t offset = 0; offset + 4 < data->size(); ++offset) {
        if (bytes[offset] == 0xFF && bytes[offset + 1] == 0xDA) {
            const size_t markerLength = static_cast<size_t>(bytes[offset + 2]) << 8 |
                                        static_cast<size_t>(bytes[offset + 3]);
            entropyStart = offset + 2 + markerLength;
            break;
        }
    }
    REPORTER_ASSERT(r, entropyStart > 0 && entropyStart < data->size());

    int suspensionsTested = 0;
    for (size_t visible = entropyStart;
         visible < std::min(data->size(), entropyStart + 128) && suspensionsTested < 3;
         ++visible) {
        auto stream = std::make_unique<HaltingStream>(data, visible);
        HaltingStream* streamPtr = stream.get();
        RustJpegReaderForTest partialReader(std::move(stream), 0);
        REPORTER_ASSERT(
                r, partialReader.fReader->read_metadata() == rust_jpeg::DecodingResult::Success);
        std::array<std::vector<uint8_t>, 3> storage;
        for (int plane = 0; plane < 3; ++plane) {
            storage[plane].assign(required[plane], kSentinel);
        }
        rust_jpeg::RawOutputResult result = partialReader.fReader->read_raw_imcu_row(
                rust::Slice<uint8_t>(storage[0].data(), storage[0].size()),
                static_cast<uint32_t>(strides[0]),
                rust::Slice<uint8_t>(storage[1].data(), storage[1].size()),
                static_cast<uint32_t>(strides[1]),
                rust::Slice<uint8_t>(storage[2].data(), storage[2].size()),
                static_cast<uint32_t>(strides[2]));
        if (result.status != rust_jpeg::OutputStatus::NeedMoreInput) {
            continue;
        }
        ++suspensionsTested;
        for (const auto& plane : storage) {
            REPORTER_ASSERT(r, std::all_of(plane.begin(), plane.end(), [](uint8_t value) {
                                return value == kSentinel;
                            }));
        }

        streamPtr->addNewData(data->size());
        result = partialReader.fReader->read_raw_imcu_row(
                rust::Slice<uint8_t>(storage[0].data(), storage[0].size()),
                static_cast<uint32_t>(strides[0]),
                rust::Slice<uint8_t>(storage[1].data(), storage[1].size()),
                static_cast<uint32_t>(strides[1]),
                rust::Slice<uint8_t>(storage[2].data(), storage[2].size()),
                static_cast<uint32_t>(strides[2]));
        REPORTER_ASSERT(r, result.status == rust_jpeg::OutputStatus::Ready);
        REPORTER_ASSERT(r, result.y_rows == expectedRows[0]);
        REPORTER_ASSERT(r, result.u_rows == expectedRows[1]);
        REPORTER_ASSERT(r, result.v_rows == expectedRows[2]);
        REPORTER_ASSERT(r, storage == expected);
    }
    REPORTER_ASSERT(r, suspensionsTested == 3);
}

// ========== Encoder Tests ==========

#if defined(SK_CODEC_ENCODES_JPEG_WITH_RUST)

// Encode smoke test: decode a JPEG, re-encode it, verify the output is
// non-empty, re-decodable, and preserves dimensions.
DEF_TEST(RustJpegEncode_smoke_test, r) {
    struct TestCase {
        const char* path;
        int expectedWidth;
        int expectedHeight;
        int quality;
    };

    static const TestCase kTestCases[] = {
            {"images/mandrill_512_q075.jpg", 512, 512, 85},
            {"images/dog.jpg", 180, 180, 90},
    };

    for (const auto& tc : kTestCases) {
        skiatest::ReporterContext ctx(r, tc.path);

        sk_sp<SkData> data = GetResourceAsData(tc.path);
        if (!data) {
            ERRORF(r, "Missing resource: %s", tc.path);
            continue;
        }

        SkCodec::Result result;
        std::unique_ptr<SkCodec> codec =
                SkJpegRustDecoder::Decode(SkMemoryStream::Make(data), &result);
        REPORTER_ASSERT_SUCCESSFUL_CODEC_RESULT(r, result);
        if (!codec) continue;

        auto [image, decodeResult] = codec->getImage();
        REPORTER_ASSERT_SUCCESSFUL_CODEC_RESULT(r, decodeResult);
        REPORTER_ASSERT(r, image);
        if (!image) continue;

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

        SkDynamicMemoryWStream dst;
        SkJpegEncoder::Options options;
        options.fQuality = tc.quality;
        REPORTER_ASSERT(r, SkJpegRustEncoder::Encode(&dst, src, options));
        REPORTER_ASSERT(r, dst.bytesWritten() > 0);

        sk_sp<SkData> encoded = dst.detachAsData();
        REPORTER_ASSERT(r, SkJpegRustDecoder::IsJpeg(encoded->data(), encoded->size()));

        SkCodec::Result reDecodeResult;
        std::unique_ptr<SkCodec> reCodec =
                SkJpegRustDecoder::Decode(SkMemoryStream::Make(encoded), &reDecodeResult);
        REPORTER_ASSERT_SUCCESSFUL_CODEC_RESULT(r, reDecodeResult);
        REPORTER_ASSERT(r, reCodec);
        if (!reCodec) continue;

        auto [reImage, reImageResult] = reCodec->getImage();
        REPORTER_ASSERT_SUCCESSFUL_CODEC_RESULT(r, reImageResult);
        REPORTER_ASSERT(r, reImage);
        if (!reImage) continue;
        REPORTER_ASSERT(r, reImage->width() == tc.expectedWidth);
        REPORTER_ASSERT(r, reImage->height() == tc.expectedHeight);
    }
}

DEF_TEST(RustJpegEncode_quality_affects_size, r) {
    SkBitmap bitmap;
    if (!ToolUtils::GetResourceAsBitmap("images/mandrill_512_q075.jpg", &bitmap)) {
        ERRORF(r, "Failed to decode images/mandrill_512_q075.jpg");
        return;
    }

    SkPixmap src;
    REPORTER_ASSERT(r, bitmap.peekPixels(&src));

    SkDynamicMemoryWStream dstLow, dstHigh;
    SkJpegEncoder::Options lowOptions, highOptions;
    lowOptions.fQuality = 10;
    highOptions.fQuality = 95;

    REPORTER_ASSERT(r, SkJpegRustEncoder::Encode(&dstLow, src, lowOptions));
    REPORTER_ASSERT(r, SkJpegRustEncoder::Encode(&dstHigh, src, highOptions));

    REPORTER_ASSERT(r,
                    dstLow.bytesWritten() < dstHigh.bytesWritten(),
                    "Low quality (%zu bytes) should be smaller than high quality (%zu bytes)",
                    dstLow.bytesWritten(),
                    dstHigh.bytesWritten());
}

// Table-based test for encoding different pixel formats. Verifies that RGB,
// RGBA (alpha stripped or blended), BGRA, and grayscale all round-trip through
// the encoder without crashing and produce non-empty output.
DEF_TEST(RustJpegEncode_color_formats, r) {
    struct TestCase {
        const char* description;
        SkColorType colorType;
        SkAlphaType alphaType;
        SkColor fillColor;
        SkJpegEncoder::AlphaOption alphaOption;
    };

    static const TestCase kTestCases[] = {
            {"grayscale",
             kGray_8_SkColorType,
             kOpaque_SkAlphaType,
             SK_ColorGRAY,
             SkJpegEncoder::AlphaOption::kIgnore},
            {"RGBA ignore alpha",
             kRGBA_8888_SkColorType,
             kUnpremul_SkAlphaType,
             0x80FF0000,
             SkJpegEncoder::AlphaOption::kIgnore},
            {"RGBA blend on black",
             kRGBA_8888_SkColorType,
             kUnpremul_SkAlphaType,
             0x8000FF00,
             SkJpegEncoder::AlphaOption::kBlendOnBlack},
            {"BGRA",
             kBGRA_8888_SkColorType,
             kUnpremul_SkAlphaType,
             SK_ColorBLUE,
             SkJpegEncoder::AlphaOption::kIgnore},
            {"RGB_888x (4-byte opaque)",
             kRGB_888x_SkColorType,
             kOpaque_SkAlphaType,
             SK_ColorRED,
             SkJpegEncoder::AlphaOption::kIgnore},
    };

    for (const auto& tc : kTestCases) {
        skiatest::ReporterContext ctx(r, tc.description);

        SkImageInfo info = SkImageInfo::Make(64, 64, tc.colorType, tc.alphaType);
        SkBitmap bitmap;
        REPORTER_ASSERT(r, bitmap.tryAllocPixels(info));
        bitmap.eraseColor(tc.fillColor);

        SkPixmap src;
        REPORTER_ASSERT(r, bitmap.peekPixels(&src));

        SkDynamicMemoryWStream dst;
        SkJpegEncoder::Options options;
        options.fQuality = 85;
        options.fAlphaOption = tc.alphaOption;
        REPORTER_ASSERT(r, SkJpegRustEncoder::Encode(&dst, src, options));
        REPORTER_ASSERT(r, dst.bytesWritten() > 0);
    }
}

#endif  // defined(SK_CODEC_ENCODES_JPEG_WITH_RUST)

// ========== Gainmap / MPF Tests ==========

#if defined(SK_CODEC_DECODES_JPEG_GAINMAPS)

// Verify the Rust codec's gainmap pipeline: Rust segment scanning → MPF parsing
// → C++ metadata interpretation → gainmap codec extraction.  This exercises the
// ~190-line onGetGainmapInfo code path that is otherwise untested.
DEF_TEST(RustJpeg_gainmap_extraction, r) {
    // gainmap_iso21496_1.jpg is a synthetic test image with an ISO 21496-1
    // gainmap embedded via MPF.  The C++ codec's JpegGainmapTest suite already
    // validates the detailed SkGainmapInfo fields, so here we only verify that
    // the Rust codec successfully extracts the gainmap and can decode it.
    static const char* kGainmapImages[] = {
            "images/gainmap_iso21496_1.jpg",
            "images/gainmap_iso21496_1_adobe_gcontainer.jpg",
    };

    for (const char* path : kGainmapImages) {
        skiatest::ReporterContext ctx(r, path);
        sk_sp<SkData> data = GetResourceAsData(path);
        if (!data) {
            ERRORF(r, "Missing resource: %s", path);
            continue;
        }

        SkCodec::Result result;
        std::unique_ptr<SkCodec> codec =
                SkJpegRustDecoder::Decode(SkMemoryStream::Make(data), &result);
        REPORTER_ASSERT(r, codec);
        if (!codec) continue;

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

        SkGainmapInfo gainmapInfo;
        std::unique_ptr<SkAndroidCodec> gainmapCodec;
        bool hasGainmap = androidCodec->getGainmapAndroidCodec(&gainmapInfo, &gainmapCodec);
        REPORTER_ASSERT(r, hasGainmap, "Expected gainmap in %s", path);
        if (!hasGainmap) continue;

        REPORTER_ASSERT(r, gainmapCodec);
        // The gainmap image should have valid non-zero dimensions.
        REPORTER_ASSERT(r, gainmapCodec->getInfo().width() > 0);
        REPORTER_ASSERT(r, gainmapCodec->getInfo().height() > 0);

        // Actually decode the gainmap to verify the full pipeline.
        SkBitmap gainmapBitmap;
        gainmapBitmap.allocPixels(gainmapCodec->getInfo());
        REPORTER_ASSERT(
                r,
                SkCodec::kSuccess == gainmapCodec->getAndroidPixels(gainmapBitmap.info(),
                                                                    gainmapBitmap.getPixels(),
                                                                    gainmapBitmap.rowBytes()));
    }
}

#endif  // defined(SK_CODEC_DECODES_JPEG_GAINMAPS)

// ========== Rust vs C++ JPEG Comparison Tests ==========

#if defined(SK_CODEC_DECODES_JPEG)

// Decode the same JPEG with both the Rust decoder and the C++ libjpeg-turbo
// decoder, then compare the outputs pixel-by-pixel within a tolerance.
// JPEG decoding is inherently lossy and different DCT implementations may
// produce slightly different values; a tolerance of ~8/255 per channel covers
// the typical inter-implementation variance.
static void compare_rust_vs_cpp_jpeg(skiatest::Reporter* r,
                                     const char* path,
                                     float tolerancePerChannel = 8.0f / 255.0f) {
    skiatest::ReporterContext ctx(r, path);
    sk_sp<SkData> data = GetResourceAsData(path);
    if (!data) {
        ERRORF(r, "Missing resource: %s", path);
        return;
    }

    SkCodec::Result rustResult;
    std::unique_ptr<SkCodec> rustCodec =
            SkJpegRustDecoder::Decode(SkMemoryStream::Make(data), &rustResult);
    if (!rustCodec) {
        // Some images may not be supported by the Rust decoder.
        return;
    }
    REPORTER_ASSERT_SUCCESSFUL_CODEC_RESULT(r, rustResult);

    SkCodec::Result cppResult;
    std::unique_ptr<SkCodec> cppCodec =
            SkJpegDecoder::Decode(SkMemoryStream::Make(data), &cppResult);
    if (!cppCodec) {
        return;
    }
    REPORTER_ASSERT_SUCCESSFUL_CODEC_RESULT(r, cppResult);

    auto [rustImage, rustDecodeResult] = rustCodec->getImage();
    REPORTER_ASSERT_SUCCESSFUL_CODEC_RESULT(r, rustDecodeResult);
    REPORTER_ASSERT(r, rustImage);

    auto [cppImage, cppDecodeResult] = cppCodec->getImage();
    REPORTER_ASSERT_SUCCESSFUL_CODEC_RESULT(r, cppDecodeResult);
    REPORTER_ASSERT(r, cppImage);

    if (!rustImage || !cppImage) {
        return;
    }

    REPORTER_ASSERT(r,
                    rustImage->dimensions() == cppImage->dimensions(),
                    "Rust dims %dx%d != C++ dims %dx%d",
                    rustImage->width(),
                    rustImage->height(),
                    cppImage->width(),
                    cppImage->height());
    if (rustImage->dimensions() != cppImage->dimensions()) {
        return;
    }

    SkBitmap rustBitmap, cppBitmap;
    REPORTER_ASSERT(r, rustBitmap.tryAllocPixels(rustImage->imageInfo()));
    REPORTER_ASSERT(r, cppBitmap.tryAllocPixels(cppImage->imageInfo()));
    REPORTER_ASSERT(r, rustImage->readPixels(nullptr, rustBitmap.pixmap(), 0, 0));
    REPORTER_ASSERT(r, cppImage->readPixels(nullptr, cppBitmap.pixmap(), 0, 0));

    const float tols[4] = {tolerancePerChannel, tolerancePerChannel, tolerancePerChannel, 0.0f};
    auto error =
            std::function<ComparePixmapsErrorReporter>([&](int x, int y, const float diffs[4]) {
                ERRORF(r,
                       "%s: pixel differs at (%d, %d): diffs=(%f, %f, %f, %f)",
                       path,
                       x,
                       y,
                       diffs[0],
                       diffs[1],
                       diffs[2],
                       diffs[3]);
            });
    ComparePixels(rustBitmap.pixmap(), cppBitmap.pixmap(), tols, error);
}

// Table-based test comparing Rust and C++ JPEG decoders across many images.
// Each entry specifies a description, path, and optional per-channel tolerance
// (default 8/255). Unsupported formats are gracefully skipped when the Rust
// decoder returns nullptr.
DEF_TEST(RustJpeg_vs_CppJpeg, r) {
    struct TestCase {
        const char* description;
        const char* path;
        float tolerance;
    };

    static constexpr float kDefaultTol = 8.0f / 255.0f;

    static const TestCase kTestCases[] = {
            {"color wheel (baseline RGB)", "images/color_wheel.jpg", kDefaultTol},
            {"dog (180x180, RGB)", "images/dog.jpg", kDefaultTol},
            {"ducky", "images/ducky.jpg", kDefaultTol},
            {"mandrill 512 q075", "images/mandrill_512_q075.jpg", kDefaultTol},
            {"mandrill h1v1 subsampling", "images/mandrill_h1v1.jpg", kDefaultTol},
            {"mandrill h2v1 subsampling", "images/mandrill_h2v1.jpg", kDefaultTol},
            {"grayscale", "images/grayscale.jpg", kDefaultTol},
            {"progressive (b78329453)", "images/b78329453.jpeg", kDefaultTol},
            // Progressive JPEGs can have slightly larger inter-implementation diffs.
            {"progressive (crbug999986)", "images/crbug999986.jpeg", 10.0f / 255.0f},
            {"cropped mandrill", "images/cropped_mandrill.jpg", kDefaultTol},
            {"flutter logo", "images/flutter_logo.jpg", kDefaultTol},
            {"ICC v2 GBR profile", "images/icc-v2-gbr.jpg", kDefaultTol},
            // randPixels has small DCT rounding differences between implementations.
            {"random pixels", "images/randPixels.jpg", 16.0f / 255.0f},
            // CMYK: different CMYK→RGB conversion paths (zune-jpeg vs libjpeg-turbo)
            // may produce slightly larger per-channel differences.
            {"CMYK", "images/CMYK.jpg", 16.0f / 255.0f},
    };

    for (const TestCase& tc : kTestCases) {
        compare_rust_vs_cpp_jpeg(r, tc.path, tc.tolerance);
    }
}

// Compare EXIF orientation reported by Rust and C++ JPEG decoders for the same
// image.  Both codecs ultimately use SkExif::Parse, so the values must match
// exactly.
DEF_TEST(RustJpeg_vs_CppJpeg_Orientation, r) {
    static const char* kImages[] = {
            "images/orientation/1_444.jpg",
            "images/orientation/2_444.jpg",
            "images/orientation/3_444.jpg",
            "images/orientation/4_444.jpg",
            "images/orientation/5_444.jpg",
            "images/orientation/6_444.jpg",
            "images/orientation/7_444.jpg",
            "images/orientation/8_444.jpg",
            "images/exif-orientation-2-ur.jpg",
            "images/orientation/exif.jpg",    // large EXIF block
            "images/orientation/subifd.jpg",  // EXIF with sub-IFD structure
            "images/ducky.jpg",
            "images/color_wheel.jpg",  // no EXIF → default orientation
    };

    for (const char* path : kImages) {
        skiatest::ReporterContext ctx(r, path);
        sk_sp<SkData> data = GetResourceAsData(path);
        if (!data) {
            ERRORF(r, "Missing resource: %s", path);
            continue;
        }

        SkCodec::Result rustResult;
        auto rustCodec = SkJpegRustDecoder::Decode(SkMemoryStream::Make(data), &rustResult);
        if (!rustCodec) continue;

        SkCodec::Result cppResult;
        auto cppCodec = SkJpegDecoder::Decode(SkMemoryStream::Make(data), &cppResult);
        if (!cppCodec) continue;

        REPORTER_ASSERT(r,
                        rustCodec->getOrigin() == cppCodec->getOrigin(),
                        "%s: Rust orientation %d != C++ orientation %d",
                        path,
                        static_cast<int>(rustCodec->getOrigin()),
                        static_cast<int>(cppCodec->getOrigin()));
    }
}

// Compare ICC profile data reported by Rust and C++ JPEG decoders.  Both
// profiles should round-trip to the same parsed representation.
DEF_TEST(RustJpeg_vs_CppJpeg_ICCProfile, r) {
    static const char* kImages[] = {
            "images/icc-v2-gbr.jpg",   // ICC v2 with GBR channel order
            "images/ducky.jpg",        // large ICC profile
            "images/color_wheel.jpg",  // no ICC → both should be nullptr
            "images/grayscale.jpg",    // no ICC
    };

    for (const char* path : kImages) {
        skiatest::ReporterContext ctx(r, path);
        sk_sp<SkData> data = GetResourceAsData(path);
        if (!data) {
            ERRORF(r, "Missing resource: %s", path);
            continue;
        }

        SkCodec::Result rustResult;
        auto rustCodec = SkJpegRustDecoder::Decode(SkMemoryStream::Make(data), &rustResult);
        if (!rustCodec) continue;

        SkCodec::Result cppResult;
        auto cppCodec = SkJpegDecoder::Decode(SkMemoryStream::Make(data), &cppResult);
        if (!cppCodec) continue;

        const skcms_ICCProfile* rustICC = rustCodec->getICCProfile();
        const skcms_ICCProfile* cppICC = cppCodec->getICCProfile();

        // Both should agree on presence.
        if (!rustICC && !cppICC) {
            continue;  // both null — OK
        }
        if (!rustICC || !cppICC) {
            ERRORF(r,
                   "%s: ICC presence mismatch (Rust %s, C++ %s)",
                   path,
                   rustICC ? "present" : "absent",
                   cppICC ? "present" : "absent");
            continue;
        }

        // Compare data class and color space.
        REPORTER_ASSERT(r,
                        rustICC->data_color_space == cppICC->data_color_space,
                        "%s: ICC data_color_space mismatch",
                        path);

        // Compare the TRC (transfer function) for each channel.
        for (int ch = 0; ch < 3; ++ch) {
            REPORTER_ASSERT(r,
                            skcms_TransferFunction_isSRGBish(&rustICC->trc[ch].parametric) ==
                                    skcms_TransferFunction_isSRGBish(&cppICC->trc[ch].parametric),
                            "%s: ICC TRC[%d] sRGB-ish mismatch",
                            path,
                            ch);
        }

        // Compare the 3x3 toXYZD50 matrix.
        for (int row = 0; row < 3; ++row) {
            for (int col = 0; col < 3; ++col) {
                float rustVal = rustICC->toXYZD50.vals[row][col];
                float cppVal = cppICC->toXYZD50.vals[row][col];
                float diff = std::abs(rustVal - cppVal);
                REPORTER_ASSERT(r,
                                diff < 1e-5f,
                                "%s: ICC toXYZD50[%d][%d] differs: Rust=%f C++=%f",
                                path,
                                row,
                                col,
                                rustVal,
                                cppVal);
            }
        }
    }
}

#endif  // defined(SK_CODEC_DECODES_JPEG)
