/*
 * Copyright 2025 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/SkBmpRustDecoder.h"

#include <cstring>
#include <memory>
#include <utility>
#include <vector>

#include "include/codec/SkBmpDecoder.h"
#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 "modules/skcms/skcms.h"
#include "tests/ComparePixels.h"
#include "tests/FakeStreams.h"
#include "tests/Test.h"
#include "tools/Resources.h"

// Helper to verify pixel color at a specific location.
static void assert_pixel_color(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);

    skiatest::ReporterContext ctx(r, 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)",
                    actualColor, expectedColor, x, y);
}
#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 `SkBmpRustDecoder::Decode`.
static std::unique_ptr<SkCodec> decode_bmp(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 =
            SkBmpRustDecoder::Decode(SkMemoryStream::Make(std::move(data)), &result);
    REPORTER_ASSERT_SUCCESSFUL_CODEC_RESULT(r, result);

    return codec;
}

static void write_u16_le(std::vector<uint8_t>& bytes, size_t offset, uint16_t value) {
    bytes[offset] = value & 0xFF;
    bytes[offset + 1] = value >> 8;
}

static void write_u32_le(std::vector<uint8_t>& bytes, size_t offset, uint32_t value) {
    bytes[offset] = value & 0xFF;
    bytes[offset + 1] = (value >> 8) & 0xFF;
    bytes[offset + 2] = (value >> 16) & 0xFF;
    bytes[offset + 3] = value >> 24;
}

static sk_sp<SkData> make_bmp_with_icc_profile(const SkData& profile) {
    constexpr size_t kFileHeaderSize = 14;
    constexpr size_t kDibHeaderSize = 124;
    constexpr size_t kPixelDataOffset = kFileHeaderSize + kDibHeaderSize;
    constexpr size_t kPixelDataSize = 8;
    constexpr size_t kProfileOffset = kPixelDataOffset + kPixelDataSize;

    std::vector<uint8_t> bmp(kProfileOffset + profile.size(), 0);
    bmp[0] = 'B';
    bmp[1] = 'M';
    write_u32_le(bmp, 2, bmp.size());
    write_u32_le(bmp, 10, kPixelDataOffset);
    write_u32_le(bmp, 14, kDibHeaderSize);
    write_u32_le(bmp, 18, 2);  // Width.
    write_u32_le(bmp, 22, 1);  // Height.
    write_u16_le(bmp, 26, 1);  // Planes.
    write_u16_le(bmp, 28, 24);
    write_u32_le(bmp, 34, kPixelDataSize);
    write_u32_le(bmp, 70, 0x4D424544);  // PROFILE_EMBEDDED ("MBED").
    write_u32_le(bmp, 126, kProfileOffset - kFileHeaderSize);
    write_u32_le(bmp, 130, profile.size());

    // Two BGR pixels followed by row padding: red, then green.
    const uint8_t pixels[kPixelDataSize] = {0, 0, 255, 0, 255, 0, 0, 0};
    std::memcpy(bmp.data() + kPixelDataOffset, pixels, sizeof(pixels));
    std::memcpy(bmp.data() + kProfileOffset, profile.data(), profile.size());
    return SkData::MakeWithCopy(bmp.data(), bmp.size());
}

// Table-based test for decoding valid BMP files.
DEF_TEST(RustBmpCodec_decode_valid_bmp, r) {
    auto test = [&r](const char* description, const char* file, SkISize expectedSize,
                     SkColorType expectedColorType,
                     SkCodec::SkScanlineOrder expectedScanlineOrder) {
        skiatest::ReporterContext ctx(r, description);
        std::unique_ptr<SkCodec> codec = decode_bmp(r, file);
        if (!codec) {
            return;
        }
        REPORTER_ASSERT(r, codec->dimensions() == expectedSize,
                        "dimensions=%dx%d != expected=%dx%d",
                        codec->dimensions().width(), codec->dimensions().height(),
                        expectedSize.width(), expectedSize.height());

        // Verify color type
        SkImageInfo info = codec->getInfo();
        REPORTER_ASSERT(r, info.colorType() == expectedColorType,
                        "colorType=%d != expected=%d",
                        info.colorType(), expectedColorType);

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

    test("basic 24-bit", "images/randPixels.bmp", {8, 8}, kN32_SkColorType,
        SkCodec::kBottomUp_SkScanlineOrder);
    test("rle compression", "images/rle.bmp", {320, 240}, kN32_SkColorType,
        SkCodec::kBottomUp_SkScanlineOrder);
    test("8 bit indexed", "images/bmp-size-32x32-8bpp.bmp", {32, 32}, kN32_SkColorType,
        SkCodec::kBottomUp_SkScanlineOrder);
    test("32 bit top-down", "images/32bpp-topdown-320x240.bmp", {320, 240}, kN32_SkColorType,
        SkCodec::kTopDown_SkScanlineOrder);
}

// Test that Decode handles nullptr for the Result parameter.
DEF_TEST(RustBmpCodec_nullptr_result, r) {
    sk_sp<SkData> data = GetResourceAsData("images/randPixels.bmp");
    REPORTER_ASSERT(r, data);

    // This should not crash even when result is nullptr
    std::unique_ptr<SkCodec> codec =
            SkBmpRustDecoder::Decode(SkMemoryStream::Make(std::move(data)), nullptr);
    REPORTER_ASSERT(r, codec);
    REPORTER_ASSERT(r, codec->dimensions() == SkISize::Make(8, 8));
}

// Test that SkBmpRustDecoder correctly rejects non-BMP data.
DEF_TEST(RustBmpCodec_reject_non_bmp, 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 =
            SkBmpRustDecoder::Decode(SkMemoryStream::Make(std::move(data)), &result);

    // Should fail to decode PNG data as BMP
    REPORTER_ASSERT(r, !codec, "SkBmpRustDecoder should reject PNG data");
}

// Test codec reuse functionality.
DEF_TEST(RustBmpCodec_rewind, r) {
    std::unique_ptr<SkCodec> codec = decode_bmp(r, "images/randPixels.bmp");
    if (!codec) {
        return;
    }

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

    // Decode again using the same codec (tests reuse)
    auto [image2, result2] = codec->getImage();
    REPORTER_ASSERT_SUCCESSFUL_CODEC_RESULT(r, result2);
    REPORTER_ASSERT(r, image2);

    // Both images should have the same dimensions
    REPORTER_ASSERT(r,
                    image1->dimensions() == image2->dimensions(),
                    "Images after rewind should have same dimensions");

    // Verify pixel data is identical
    SkBitmap bm1, bm2;
    REPORTER_ASSERT(r, bm1.tryAllocPixels(image1->imageInfo()));
    REPORTER_ASSERT(r, bm2.tryAllocPixels(image2->imageInfo()));
    REPORTER_ASSERT(r, image1->readPixels(nullptr, bm1.pixmap(), 0, 0));
    REPORTER_ASSERT(r, image2->readPixels(nullptr, bm2.pixmap(), 0, 0));

    // Use zero tolerance for exact pixel match
    const float tols[4] = {0, 0, 0, 0};
    auto error = std::function<ComparePixmapsErrorReporter>(
            [&](int x, int y, const float diffs[4]) {
        ERRORF(r, "Pixels differ at (%d, %d) after rewind. Diffs: (%f, %f, %f, %f)",
               x, y, diffs[0], diffs[1], diffs[2], diffs[3]);
    });
    ComparePixels(bm1.pixmap(), bm2.pixmap(), tols, error);
}

// Test getPixels with a pre-allocated bitmap.
DEF_TEST(RustBmpCodec_getPixels, r) {
    std::unique_ptr<SkCodec> codec = decode_bmp(r, "images/randPixels.bmp");
    if (!codec) {
        return;
    }

    SkImageInfo info = codec->getInfo().makeColorType(kN32_SkColorType);
    SkBitmap bitmap;
    bitmap.allocPixels(info);

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

    // Verify bitmap dimensions
    REPORTER_ASSERT(r, bitmap.width() == 8);
    REPORTER_ASSERT(r, bitmap.height() == 8);

    // Spot check pixel values to verify correct decoding
    SkPixmap pixmap = bitmap.pixmap();
    assert_pixel_color(r, pixmap, 0, 0, SkColorSetARGB(0xFF, 0xBB, 0xA5, 0x70), "pixel (0,0)");
    assert_pixel_color(r, pixmap, 1, 0, SkColorSetARGB(0xFF, 0x39, 0x5F, 0x5D), "pixel (1,0)");
    assert_pixel_color(r, pixmap, 0, 1, SkColorSetARGB(0xFF, 0xBD, 0xA6, 0x0E), "pixel (0,1)");
    assert_pixel_color(r, pixmap, 1, 1, SkColorSetARGB(0xFF, 0xC0, 0x1D, 0xB6), "pixel (1,1)");
}

// Test that IsBmp correctly identifies BMP data.
DEF_TEST(RustBmpCodec_IsBmp_positive, r) {
    sk_sp<SkData> data = GetResourceAsData("images/randPixels.bmp");
    if (!data) {
        ERRORF(r, "Missing resource: images/randPixels.bmp");
        return;
    }

    bool isBmp = SkBmpRustDecoder::IsBmp(data->data(), data->size());
    REPORTER_ASSERT(r, isBmp, "IsBmp should return true for BMP data");
}

// Test that IsBmp correctly rejects non-BMP data.
DEF_TEST(RustBmpCodec_IsBmp_negative, r) {
    sk_sp<SkData> data = GetResourceAsData("images/color_wheel.png");
    if (!data) {
        ERRORF(r, "Missing resource: images/color_wheel.png");
        return;
    }

    bool isBmp = SkBmpRustDecoder::IsBmp(data->data(), data->size());
    REPORTER_ASSERT(r, !isBmp, "IsBmp should return false for PNG data");
}

// Test IsBmp with insufficient data.
DEF_TEST(RustBmpCodec_IsBmp_insufficient_data, r) {
    // BMP signature is "BM" (2 bytes), but header is larger
    const uint8_t shortData[] = {'B'};
    bool isBmp = SkBmpRustDecoder::IsBmp(shortData, sizeof(shortData));
    REPORTER_ASSERT(r, !isBmp, "IsBmp should return false for insufficient data");
}

// Table-based test for handling invalid/corrupted BMP files.
DEF_TEST(RustBmpCodec_invalid_bmp_handling, r) {
    auto test = [&r](const char* description, const char* file) {
        skiatest::ReporterContext ctx(r, description);
        sk_sp<SkData> data = GetResourceAsData(file);
        if (!data) {
            ERRORF(r, "Missing resource: %s", file);
            return;
        }

        SkCodec::Result result;
        std::unique_ptr<SkCodec> codec =
                SkBmpRustDecoder::Decode(SkMemoryStream::Make(std::move(data)), &result);

        // If we got a codec, try to decode to ensure we don't crash
        if (codec) {
            auto [image, decodeResult] = codec->getImage();
            // Any result is acceptable as long as we don't crash
            (void)image;
            (void)decodeResult;
        }
    };

    test("zero width", "empty_images/zero-width.bmp");
    test("zero height", "empty_images/zero-height.bmp");
    test("corrupted incomplete", "invalid_images/b33251605.bmp");
    test("invalid header", "invalid_images/b33651913.bmp");
    test("extreme dimensions", "invalid_images/b34778578.bmp");
    test("os2 fuzz", "invalid_images/osfuzz6288.bmp");
}

// Test explicit rewind through multiple getPixels calls.
DEF_TEST(RustBmpCodec_explicit_rewind, r) {
    std::unique_ptr<SkCodec> codec = decode_bmp(r, "images/randPixels.bmp");
    if (!codec) {
        return;
    }

    // First decode
    SkBitmap bitmap1;
    bitmap1.allocPixels(codec->getInfo());
    SkCodec::Result result1 = codec->getPixels(bitmap1.pixmap());
    REPORTER_ASSERT_SUCCESSFUL_CODEC_RESULT(r, result1);

    // Second decode (implicitly rewinds internally)
    SkBitmap bitmap2;
    bitmap2.allocPixels(codec->getInfo());
    SkCodec::Result result2 = codec->getPixels(bitmap2.pixmap());
    REPORTER_ASSERT_SUCCESSFUL_CODEC_RESULT(r, result2);

    // Verify dimensions match
    REPORTER_ASSERT(r, bitmap1.dimensions() == bitmap2.dimensions(),
                    "Dimensions should match after rewind");

    // Verify pixel data matches
    REPORTER_ASSERT(r, bitmap1.computeByteSize() == bitmap2.computeByteSize(),
                    "Byte sizes should match");
    REPORTER_ASSERT(r,
                    memcmp(bitmap1.getPixels(), bitmap2.getPixels(),
                           bitmap1.computeByteSize()) == 0,
                    "Pixel data should match after rewind");
}


// Test incremental decoding
DEF_TEST(RustBmpCodec_IncrementalDecode, r) {
    const char* path = "images/randPixels.bmp";
    sk_sp<SkData> data = GetResourceAsData(path);
    REPORTER_ASSERT(r, data, "Missing test image: %s", path);
    if (!data) {
        return;
    }

    // Decode with standard BMP decoder for reference
    std::unique_ptr<SkCodec> stdCodec = SkBmpDecoder::Decode(SkMemoryStream::Make(data), nullptr);
    REPORTER_ASSERT(r, stdCodec, "Failed to create standard BMP codec for %s", path);
    if (!stdCodec) {
        return;
    }

    SkBitmap reference;
    reference.allocPixels(stdCodec->getInfo());
    SkCodec::Result result = stdCodec->getPixels(reference.pixmap());
    REPORTER_ASSERT_SUCCESSFUL_CODEC_RESULT(r, result);

    // Now decode using Rust BMP decoder with incremental decode
    std::unique_ptr<SkCodec> rustCodec =
            SkBmpRustDecoder::Decode(SkMemoryStream::Make(data), nullptr);
    REPORTER_ASSERT(r, rustCodec, "Failed to create Rust BMP codec for %s", path);
    if (!rustCodec) {
        return;
    }

    // Verify dimensions match before decoding
    REPORTER_ASSERT(r, rustCodec->dimensions() == stdCodec->dimensions(),
                    "Rust codec dimensions should match standard codec");

    SkBitmap incremental;
    incremental.allocPixels(rustCodec->getInfo());

    result = rustCodec->startIncrementalDecode(incremental.info(),
                                               incremental.getPixels(),
                                               incremental.rowBytes());
    REPORTER_ASSERT_SUCCESSFUL_CODEC_RESULT(r, result);

    // Decode all rows incrementally
    // For BMP with all data available, this should complete in one call
    result = rustCodec->incrementalDecode();
    REPORTER_ASSERT_SUCCESSFUL_CODEC_RESULT(r, result);

    // Verify that Rust incremental decode produces the same output as standard BMP decoder
    REPORTER_ASSERT(r, reference.dimensions() == incremental.dimensions(),
                    "Dimensions should match");
    REPORTER_ASSERT(r, reference.computeByteSize() == incremental.computeByteSize(),
                    "Byte sizes should match");

    // Compare pixel data
    const uint8_t* refPixels = static_cast<const uint8_t*>(reference.getPixels());
    const uint8_t* incPixels = static_cast<const uint8_t*>(incremental.getPixels());
    size_t byteSize = reference.computeByteSize();

    bool pixelsMatch = memcmp(refPixels, incPixels, byteSize) == 0;
    REPORTER_ASSERT(r, pixelsMatch,
                    "Rust incremental decode should produce identical output to standard BMP "
                    "decoder");
}

// Test incremental decode with progressively available data.
// Simulates a streaming scenario where data arrives in chunks (like over a network).
// This tests true resumability: starting with partial data, getting kIncompleteInput,
// adding more data, and resuming until complete. Tests both top-down and bottom-up
// BMP images to ensure correct row ordering in both cases.
DEF_TEST(RustBmpCodec_IncrementalDecode_PartialStreaming, r) {
    struct TestCase {
        const char* path;
        const char* description;
        int expectedIterations;
        bool isTopDown;             // Used for intermediate row verification
        int expectedFirstRowsDecoded;  // Expected rows after first 8KB chunk
    };

    // Test both top-down and bottom-up BMP files.
    // expectedFirstRowsDecoded is calculated as:
    //   (kInitialBytes + kChunkSize - headerSize) / srcRowBytes
    // where srcRowBytes is the row size in the source BMP file.
    constexpr TestCase testCases[] = {
        // Top-down 32bpp: 307254 bytes, 54-byte header, row=320*4=1280 bytes
        // After first chunk: (256 + 8192 - 54) / 1280 = 6 rows
        {"images/32bpp-topdown-320x240.bmp", "top-down 320x240 32-bit", 39, true, 6},
        // Bottom-up 24bpp with ICC: 138-byte header, row=127*3 padded to 384 bytes
        // After first chunk: (256 + 8192 - 138) / 384 = 21 rows
        {"images/rgb24prof.bmp", "bottom-up 127x64 24-bit with ICC", 4, false, 21},
    };

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

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

        // Create a HaltingStream that starts with enough data for the BMP header.
        // Use 256 bytes to accommodate various BMP header sizes (including ICC).
        constexpr size_t kInitialBytes = 256;
        constexpr size_t kChunkSize = 8 * 1024;  // Add 8KB at a time
        const size_t fullSize = data->size();
        const size_t initialBytes = std::min(kInitialBytes, fullSize);

        // Create stream and retain raw pointer before moving to codec
        auto haltingStream = std::make_unique<HaltingStream>(data, initialBytes);
        HaltingStream* streamPtr = haltingStream.get();

        // Create codec with Rust BMP decoder
        SkCodec::Result result;
        std::unique_ptr<SkCodec> codec =
                SkBmpRustDecoder::Decode(std::move(haltingStream), &result);

        REPORTER_ASSERT(r, codec, "Failed to create codec with %zu bytes, result: %s",
                        initialBytes, SkCodec::ResultToString(result));
        if (!codec) {
            continue;
        }

        // Get the image info from the streaming codec
        const SkImageInfo streamingInfo = codec->getInfo();

        // Decode the full image for comparison using standard BMP decoder,
        // requesting the same image info for valid comparison.
        std::unique_ptr<SkCodec> stdCodec =
                SkBmpDecoder::Decode(SkMemoryStream::Make(data), nullptr);
        REPORTER_ASSERT(r, stdCodec, "Failed to create standard BMP codec");
        if (!stdCodec) {
            continue;
        }

        // Verify dimensions match
        REPORTER_ASSERT(r, codec->dimensions() == stdCodec->dimensions(),
                        "Streaming codec dimensions should match standard codec");

        SkBitmap reference;
        reference.allocPixels(streamingInfo);  // Use streaming codec's info
        SkCodec::Result refResult = stdCodec->getPixels(reference.pixmap());
        REPORTER_ASSERT_SUCCESSFUL_CODEC_RESULT(r, refResult);

        SkBitmap bitmap;
        bitmap.allocPixels(streamingInfo);
        // Fill with non-zero pattern to verify decoder properly writes all pixels
        memset(bitmap.getPixels(), 0xAB, bitmap.computeByteSize());

        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);

        // Resumable decode loop
        int totalRowsDecoded = 0;
        int iterations = 0;
        constexpr int kMaxIterations = 1000;
        bool sawProgressiveRows = false;   // Track if we saw partial row decoding
        bool verifiedDecodedRows = false;  // Track if we verified decoded rows

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

            if (result == SkCodec::kSuccess) {
                totalRowsDecoded = rowsDecoded;
                break;
            } else if (result == SkCodec::kIncompleteInput) {
                // Track if we got partial rows (progressive rendering)
                if (rowsDecoded > 0 && rowsDecoded < codec->getInfo().height()) {
                    sawProgressiveRows = true;

                    // Verify decoded rows match reference image (not garbage 0xAB).
                    // Only check once to avoid slowing down the test.
                    if (!verifiedDecodedRows) {
                        verifiedDecodedRows = true;

                        // Verify rowsDecoded matches our expected value based on
                        // chunk size, header size, and row bytes.
                        REPORTER_ASSERT(r, rowsDecoded == testCase.expectedFirstRowsDecoded,
                                        "Expected %d rows decoded after first chunk, got %d",
                                        testCase.expectedFirstRowsDecoded, rowsDecoded);

                        const int height = codec->getInfo().height();
                        const size_t rowBytes = bitmap.rowBytes();
                        const uint8_t* bitmapPixels =
                                static_cast<const uint8_t*>(bitmap.getPixels());
                        const uint8_t* refPixels =
                                static_cast<const uint8_t*>(reference.getPixels());

                        // For top-down images: decoded rows are at positions 0 to
                        // rowsDecoded-1.
                        // For bottom-up images: decoded rows are placed at the bottom
                        // of the buffer, positions (height - rowsDecoded) to (height - 1).
                        int startRow = testCase.isTopDown ? 0 : (height - rowsDecoded);

                        bool decodedRowsMatch = true;
                        for (int i = 0; i < rowsDecoded && decodedRowsMatch; ++i) {
                            int y = startRow + i;
                            if (memcmp(bitmapPixels + y * rowBytes,
                                       refPixels + y * rowBytes,
                                       rowBytes) != 0) {
                                decodedRowsMatch = false;
                                ERRORF(r, "Decoded row %d doesn't match reference", y);
                            }
                        }
                        REPORTER_ASSERT(r, decodedRowsMatch,
                                        "Decoded rows should match reference, not garbage");
                    }
                }
                totalRowsDecoded = rowsDecoded;

                if (streamPtr->isAllDataReceived()) {
                    ERRORF(r, "Got kIncompleteInput with all data available");
                    break;
                }
                streamPtr->addNewData(kChunkSize);
            } else {
                ERRORF(r, "Unexpected result: %s", SkCodec::ResultToString(result));
                break;
            }
        }

        REPORTER_ASSERT(r, iterations < kMaxIterations,
                        "Decode loop exceeded max iterations");

        // Verify the exact iteration count for deterministic behavior
        REPORTER_ASSERT(r, iterations == testCase.expectedIterations,
                        "Expected exactly %d iterations, got %d",
                        testCase.expectedIterations, iterations);

        REPORTER_ASSERT(r, result == SkCodec::kSuccess,
                        "Should complete successfully, got %s",
                        SkCodec::ResultToString(result));
        REPORTER_ASSERT(r, totalRowsDecoded == codec->getInfo().height(),
                        "Should decode all %d rows, decoded %d",
                        codec->getInfo().height(), totalRowsDecoded);

        // Verify progressive rendering occurred
        REPORTER_ASSERT(r, sawProgressiveRows,
                        "Should see progressive row decoding with small chunk sizes");

        // Verify we checked decoded rows during partial decode
        REPORTER_ASSERT(r, verifiedDecodedRows,
                        "Should have verified decoded rows during partial decode");

        // Verify final image matches standard decoder output
        REPORTER_ASSERT(r, bitmap.dimensions() == reference.dimensions(),
                        "Dimensions should match reference");

        // Compare row by row for detailed error reporting.
        // Both decoders output rows in logical (top-down) order.
        const size_t rowBytes = bitmap.rowBytes();
        const uint8_t* bitmapPixels = static_cast<const uint8_t*>(bitmap.getPixels());
        const uint8_t* refPixels = static_cast<const uint8_t*>(reference.getPixels());
        const int height = codec->getInfo().height();

        bool allRowsMatch = true;
        for (int y = 0; y < height; ++y) {
            if (memcmp(bitmapPixels + y * rowBytes,
                       refPixels + y * rowBytes, rowBytes) != 0) {
                allRowsMatch = false;
                ERRORF(r, "Row %d doesn't match between Rust streaming and "
                          "standard decoder", y);
            }
        }
        REPORTER_ASSERT(r, allRowsMatch,
                        "Streaming decode should match standard BMP decoder output");
    }
}

// Test incomplete metadata - stream with partial BMP header
DEF_TEST(RustBmpCodec_IncompleteMetadata_PartialHeader, r) {
    // Load a valid BMP
    sk_sp<SkData> data = GetResourceAsData("images/randPixels.bmp");
    if (!data) {
        ERRORF(r, "Failed to load test image");
        return;
    }

    // Create stream with only partial header (30 bytes of 54-byte header)
    constexpr size_t kPartialSize = 30;
    sk_sp<SkData> partialData = SkData::MakeSubset(data.get(), 0, kPartialSize);
    std::unique_ptr<SkStream> partialStream = SkMemoryStream::Make(partialData);

    SkCodec::Result result;
    std::unique_ptr<SkCodec> codec =
        SkBmpRustDecoder::Decode(std::move(partialStream), &result);

    // Should fail with incomplete input (not enough for metadata)
    REPORTER_ASSERT(r, codec == nullptr,
                   "Should not create codec with incomplete metadata");
    REPORTER_ASSERT(r, result == SkCodec::kIncompleteInput,
                   "Should return kIncompleteInput, got %d", result);
}

// Test incomplete row data - stream with partial pixel data
DEF_TEST(RustBmpCodec_IncompleteRowData, r) {
    // Load a valid BMP
    sk_sp<SkData> data = GetResourceAsData("images/randPixels.bmp");
    if (!data) {
        ERRORF(r, "Failed to load test image");
        return;
    }

    // Get codec to determine dimensions
    std::unique_ptr<SkCodec> fullCodec =
        SkBmpRustDecoder::Decode(SkMemoryStream::Make(data), nullptr);
    if (!fullCodec) {
        ERRORF(r, "Failed to create codec from full data");
        return;
    }

    SkImageInfo info = fullCodec->getInfo();

    // BMP header is 54 bytes, calculate size for header + half of first row
    constexpr size_t kHeaderSize = 54;
    size_t rowBytes = info.width() * 3; // Assuming 24-bit RGB
    rowBytes = ((rowBytes + 3) / 4) * 4; // Row padding to 4-byte boundary
    size_t partialSize = kHeaderSize + (rowBytes / 2);

    // Ensure we don't exceed data size
    if (partialSize >= data->size()) {
        ERRORF(r, "Image too small for this test");
        return;
    }

    sk_sp<SkData> partialData = SkData::MakeSubset(data.get(), 0, partialSize);
    std::unique_ptr<SkStream> partialStream = SkMemoryStream::Make(partialData);

    SkCodec::Result result;
    std::unique_ptr<SkCodec> codec =
        SkBmpRustDecoder::Decode(std::move(partialStream), &result);

    // With header data available, codec creation should succeed
    REPORTER_ASSERT(r, codec, "Codec should be created with header data available");
    REPORTER_ASSERT(r, result == SkCodec::kSuccess,
                    "Expected kSuccess for codec creation, got %s",
                    SkCodec::ResultToString(result));
    if (!codec) {
        return;
    }

    // Try to decode - should fail with kIncompleteInput since we don't have all pixel data
    SkBitmap bitmap;
    bitmap.allocPixels(info);
    SkCodec::Result decodeResult = codec->getPixels(info, bitmap.getPixels(),
                                                    bitmap.rowBytes());

    REPORTER_ASSERT(r, decodeResult == SkCodec::kIncompleteInput,
                    "Expected kIncompleteInput with partial pixel data, got %s",
                    SkCodec::ResultToString(decodeResult));
}

// Test that embedded ICC profiles in BMP V5 headers are correctly extracted and applied.
// This uses rgb24prof.bmp from the image-rs test suite, which contains an embedded ICC profile.
DEF_TEST(RustBmpCodec_ICCProfile, r) {
    const char* path = "images/rgb24prof.bmp";
    sk_sp<SkData> data = GetResourceAsData(path);
    REPORTER_ASSERT(r, data, "Missing test image: %s", path);
    if (!data) {
        return;
    }

    std::unique_ptr<SkCodec> codec =
            SkBmpRustDecoder::Decode(SkMemoryStream::Make(data), nullptr);
    REPORTER_ASSERT(r, codec, "Failed to create Rust BMP codec");
    if (!codec) {
        return;
    }

    // Verify that the codec extracted an ICC profile
    const skcms_ICCProfile* profile = codec->getICCProfile();
    REPORTER_ASSERT(r, profile,
                    "BMP with embedded ICC profile should have getICCProfile() != null");
    if (!profile) {
        return;
    }

    // Verify the profile can be used to create a color space
    sk_sp<SkColorSpace> colorSpace = SkColorSpace::Make(*profile);
    REPORTER_ASSERT(r, colorSpace, "ICC profile should be valid and create a color space");
    if (!colorSpace) {
        return;
    }

    // Verify the color space from getInfo() matches
    SkImageInfo info = codec->getInfo();
    REPORTER_ASSERT(r, info.colorSpace(), "getInfo() should have a color space");
    if (info.colorSpace()) {
        REPORTER_ASSERT(r, SkColorSpace::Equals(info.colorSpace(), colorSpace.get()),
                        "Color space from getInfo() should match ICC profile");
    }

    // Verify decoding works with the ICC profile
    auto [image, result] = codec->getImage();
    REPORTER_ASSERT_SUCCESSFUL_CODEC_RESULT(r, result);
    REPORTER_ASSERT(r, image, "Should be able to decode BMP with ICC profile");
}

DEF_TEST(RustBmpCodec_ICCProfileTransform, r) {
    sk_sp<SkData> profile = GetResourceAsData("icc_profiles/AdobeRGB1998.icc");
    REPORTER_ASSERT(r, profile, "Missing Adobe RGB ICC profile");
    if (!profile) {
        return;
    }

    sk_sp<SkData> data = make_bmp_with_icc_profile(*profile);
    std::unique_ptr<SkCodec> codec =
            SkBmpRustDecoder::Decode(SkMemoryStream::Make(data), nullptr);
    std::unique_ptr<SkCodec> referenceCodec =
            SkBmpDecoder::Decode(SkMemoryStream::Make(data), nullptr);
    REPORTER_ASSERT(r, codec && referenceCodec, "Failed to create BMP codecs");
    if (!codec || !referenceCodec) {
        return;
    }

    SkImageInfo dstInfo = codec->getInfo()
                                  .makeColorType(kN32_SkColorType)
                                  .makeAlphaType(kPremul_SkAlphaType)
                                  .makeColorSpace(SkColorSpace::MakeSRGB());
    SkBitmap actual;
    SkBitmap expected;
    REPORTER_ASSERT(r, actual.tryAllocPixels(dstInfo));
    REPORTER_ASSERT(r, expected.tryAllocPixels(dstInfo));
    REPORTER_ASSERT_SUCCESSFUL_CODEC_RESULT(r, codec->getPixels(actual.pixmap()));
    REPORTER_ASSERT_SUCCESSFUL_CODEC_RESULT(r, referenceCodec->getPixels(expected.pixmap()));

    const float tolerances[4] = {0, 0, 0, 0};
    auto reportError = std::function<ComparePixmapsErrorReporter>(
            [&](int x, int y, const float differences[4]) {
                ERRORF(r,
                       "ICC-transformed pixels differ at (%d, %d): (%f, %f, %f, %f)",
                       x, y, differences[0], differences[1], differences[2], differences[3]);
            });
    ComparePixels(expected.pixmap(), actual.pixmap(), tolerances, reportError);
}

#undef REPORTER_ASSERT_SUCCESSFUL_CODEC_RESULT
