/*
 * Copyright 2023 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/SkAndroidCodec.h"
#include "include/codec/SkCodec.h"
#include "include/core/SkBitmap.h"
#include "include/core/SkCanvas.h"
#include "include/core/SkColor.h"
#include "include/core/SkImage.h"
#include "include/core/SkShader.h"
#include "include/core/SkSize.h"
#include "include/core/SkStream.h"
#include "include/core/SkTypes.h"
#include "include/encode/SkJpegEncoder.h"
#include "include/private/SkGainmapInfo.h"
#include "include/private/SkGainmapShader.h"
#include "include/private/SkJpegGainmapEncoder.h"
#include "src/codec/SkJpegCodec.h"
#include "src/codec/SkJpegConstants.h"
#include "src/codec/SkJpegMultiPicture.h"
#include "src/codec/SkJpegSegmentScan.h"
#include "src/codec/SkJpegSourceMgr.h"
#include "src/codec/SkTiffUtility.h"
#include "tests/GainmapTestCommon.h"
#include "tests/Test.h"
#include "tools/Resources.h"

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

namespace {


// A test stream to stress the different SkJpegSourceMgr sub-classes.
class TestStream : public SkStream {
public:
    enum class Type {
        kUnseekable,    // SkJpegUnseekableSourceMgr
        kSeekable,      // SkJpegBufferedSourceMgr
        kMemoryMapped,  // SkJpegMemorySourceMgr
    };
    TestStream(Type type, SkStream* stream)
            : fStream(stream)
            , fSeekable(type != Type::kUnseekable)
            , fMemoryMapped(type == Type::kMemoryMapped) {}
    ~TestStream() override {}

    size_t read(void* buffer, size_t size) override { return fStream->read(buffer, size); }
    size_t peek(void* buffer, size_t size) const override { return fStream->peek(buffer, size); }
    bool isAtEnd() const override { return fStream->isAtEnd(); }
    bool rewind() override {
        if (!fSeekable) {
            return false;
        }
        return fStream->rewind();
    }
    bool hasPosition() const override {
        if (!fSeekable) {
            return false;
        }
        return fStream->hasPosition();
    }
    size_t getPosition() const override {
        if (!fSeekable) {
            return 0;
        }
        return fStream->hasPosition();
    }
    bool seek(size_t position) override {
        if (!fSeekable) {
            return 0;
        }
        return fStream->seek(position);
    }
    bool move(long offset) override {
        if (!fSeekable) {
            return 0;
        }
        return fStream->move(offset);
    }
    bool hasLength() const override {
        if (!fMemoryMapped) {
            return false;
        }
        return fStream->hasLength();
    }
    size_t getLength() const override {
        if (!fMemoryMapped) {
            return 0;
        }
        return fStream->getLength();
    }
    const void* getMemoryBase() override {
        if (!fMemoryMapped) {
            return nullptr;
        }
        return fStream->getMemoryBase();
    }

private:
    SkStream* const fStream;
    bool fSeekable = false;
    bool fMemoryMapped = false;
};

}  // namespace

DEF_TEST(Codec_jpegSegmentScan, r) {
    const struct Rec {
        const char* path;
        size_t sosSegmentCount;
        size_t eoiSegmentCount;
        size_t testSegmentIndex;
        uint8_t testSegmentMarker;
        size_t testSegmentOffset;
        uint16_t testSegmentParameterLength;
    } recs[] = {
            {"images/wide_gamut_yellow_224_224_64.jpeg", 11, 15, 10, 0xda, 9768, 12},
            {"images/CMYK.jpg", 7, 8, 1, 0xee, 2, 14},
            {"images/b78329453.jpeg", 10, 23, 3, 0xe2, 154, 540},
            {"images/brickwork-texture.jpg", 8, 28, 12, 0xc4, 34183, 42},
            {"images/brickwork_normal-map.jpg", 8, 28, 27, 0xd9, 180612, 0},
            {"images/cmyk_yellow_224_224_32.jpg", 19, 23, 2, 0xed, 854, 2828},
            {"images/color_wheel.jpg", 10, 11, 2, 0xdb, 20, 67},
            {"images/cropped_mandrill.jpg", 10, 11, 4, 0xc0, 158, 17},
            {"images/dog.jpg", 10, 11, 5, 0xc4, 177, 28},
            {"images/ducky.jpg", 12, 13, 10, 0xc4, 3718, 181},
            {"images/exif-orientation-2-ur.jpg", 11, 12, 2, 0xe1, 20, 130},
            {"images/flutter_logo.jpg", 9, 27, 21, 0xda, 5731, 8},
            {"images/grayscale.jpg", 6, 16, 9, 0xda, 327, 8},
            {"images/icc-v2-gbr.jpg", 12, 25, 24, 0xd9, 43832, 0},
            {"images/mandrill_512_q075.jpg", 10, 11, 7, 0xc4, 393, 31},
            {"images/mandrill_cmyk.jpg", 19, 35, 16, 0xdd, 574336, 4},
            {"images/mandrill_h1v1.jpg", 10, 11, 1, 0xe0, 2, 16},
            {"images/mandrill_h2v1.jpg", 10, 11, 0, 0xd8, 0, 0},
            {"images/randPixels.jpg", 10, 11, 6, 0xc4, 200, 30},
            {"images/wide_gamut_yellow_224_224_64.jpeg", 11, 15, 10, 0xda, 9768, 12},
    };

    for (const auto& rec : recs) {
        auto stream = GetResourceAsStream(rec.path);
        if (!stream) {
            continue;
        }

        // Scan all the way to EndOfImage.
        auto sourceMgr = SkJpegSourceMgr::Make(stream.get());
        const auto& segments = sourceMgr->getAllSegments();

        // Verify we got the expected number of segments at EndOfImage
        REPORTER_ASSERT(r, rec.eoiSegmentCount == segments.size());

        // Verify we got the expected number of segments before StartOfScan
        for (size_t i = 0; i < segments.size(); ++i) {
            if (segments[i].marker == kJpegMarkerStartOfScan) {
                REPORTER_ASSERT(r, rec.sosSegmentCount == i + 1);
                break;
            }
        }

        // Verify the values for a randomly pre-selected segment index.
        const auto& segment = segments[rec.testSegmentIndex];
        REPORTER_ASSERT(r, rec.testSegmentMarker == segment.marker);
        REPORTER_ASSERT(r, rec.testSegmentOffset == segment.offset);
        REPORTER_ASSERT(r, rec.testSegmentParameterLength == segment.parameterLength);
    }
}

static bool find_mp_params_segment(SkStream* stream,
                                   std::unique_ptr<SkJpegMultiPictureParameters>* outMpParams,
                                   SkJpegSegment* outMpParamsSegment) {
    auto sourceMgr = SkJpegSourceMgr::Make(stream);
    for (const auto& segment : sourceMgr->getAllSegments()) {
        if (segment.marker != kMpfMarker) {
            continue;
        }
        auto parameterData = sourceMgr->getSegmentParameters(segment);
        if (!parameterData) {
            continue;
        }
        *outMpParams = SkJpegMultiPictureParameters::Make(parameterData);
        if (*outMpParams) {
            *outMpParamsSegment = segment;
            return true;
        }
    }
    return false;
}

DEF_TEST(Codec_multiPictureParams, r) {
    // Little-endian test.
    {
        const uint8_t bytes[] = {
                0x4d, 0x50, 0x46, 0x00, 0x49, 0x49, 0x2a, 0x00, 0x08, 0x00, 0x00, 0x00, 0x03,
                0x00, 0x00, 0xb0, 0x07, 0x00, 0x04, 0x00, 0x00, 0x00, 0x30, 0x31, 0x30, 0x30,
                0x01, 0xb0, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02,
                0xb0, 0x07, 0x00, 0x20, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00,
                0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x20, 0xcf, 0x49, 0x00, 0x00, 0x00, 0x00,
                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xee, 0x28, 0x01, 0x00,
                0xf9, 0xb7, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00,
        };
        auto mpParams =
                SkJpegMultiPictureParameters::Make(SkData::MakeWithoutCopy(bytes, sizeof(bytes)));
        REPORTER_ASSERT(r, mpParams);
        REPORTER_ASSERT(r, mpParams->images.size() == 2);
        REPORTER_ASSERT(r, mpParams->images[0].dataOffset == 0);
        REPORTER_ASSERT(r, mpParams->images[0].size == 4837152);
        REPORTER_ASSERT(r, mpParams->images[1].dataOffset == 3979257);
        REPORTER_ASSERT(r, mpParams->images[1].size == 76014);
    }

    // Big-endian test.
    {
        const uint8_t bytes[] = {
                0x4d, 0x50, 0x46, 0x00, 0x4d, 0x4d, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x08, 0x00,
                0x03, 0xb0, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x04, 0x30, 0x31, 0x30, 0x30,
                0xb0, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0xb0,
                0x02, 0x00, 0x07, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00,
                0x00, 0x00, 0x20, 0x03, 0x00, 0x00, 0x00, 0x56, 0xda, 0x2f, 0x00, 0x00, 0x00,
                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0xc6, 0x01,
                0x00, 0x55, 0x7c, 0x1f, 0x00, 0x00, 0x00, 0x00,
        };
        auto mpParams =
                SkJpegMultiPictureParameters::Make(SkData::MakeWithoutCopy(bytes, sizeof(bytes)));
        REPORTER_ASSERT(r, mpParams);
        REPORTER_ASSERT(r, mpParams->images.size() == 2);
        REPORTER_ASSERT(r, mpParams->images[0].dataOffset == 0);
        REPORTER_ASSERT(r, mpParams->images[0].size == 5691951);
        REPORTER_ASSERT(r, mpParams->images[1].dataOffset == 5602335);
        REPORTER_ASSERT(r, mpParams->images[1].size == 1361409);
    }

    // Three entry test.
    {
        const uint8_t bytes[] = {
                0x4d, 0x50, 0x46, 0x00, 0x4d, 0x4d, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x08, 0x00,
                0x03, 0xb0, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x04, 0x30, 0x31, 0x30, 0x30,
                0xb0, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0xb0,
                0x02, 0x00, 0x07, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00,
                0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x1f, 0x1c, 0xc2, 0x00, 0x00, 0x00,
                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x05, 0xb0,
                0x00, 0x1f, 0x12, 0xec, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                0x00, 0x96, 0x6b, 0x00, 0x22, 0x18, 0x9c, 0x00, 0x00, 0x00, 0x00,
        };
        auto mpParams =
                SkJpegMultiPictureParameters::Make(SkData::MakeWithoutCopy(bytes, sizeof(bytes)));
        REPORTER_ASSERT(r, mpParams);
        REPORTER_ASSERT(r, mpParams->images.size() == 3);
        REPORTER_ASSERT(r, mpParams->images[0].dataOffset == 0);
        REPORTER_ASSERT(r, mpParams->images[0].size == 2038978);
        REPORTER_ASSERT(r, mpParams->images[1].dataOffset == 2036460);
        REPORTER_ASSERT(r, mpParams->images[1].size == 198064);
        REPORTER_ASSERT(r, mpParams->images[2].dataOffset == 2234524);
        REPORTER_ASSERT(r, mpParams->images[2].size == 38507);
    }

    // Inserting various corrupt values.
    {
        const uint8_t bytes[] = {
                0x4d, 0x50, 0x46, 0x00,  // 0: {'M', 'P', 'F',   0} signature
                0x4d, 0x4d, 0x00, 0x2a,  // 4: {'M', 'M',   0, '*'} big-endian
                0x00, 0x00, 0x00, 0x08,  // 8: Index IFD offset
                0x00, 0x03,              // 12: Number of tags
                0xb0, 0x00,              // 14: Version tag
                0x00, 0x07,              // 16: Undefined type
                0x00, 0x00, 0x00, 0x04,  // 18: Size
                0x30, 0x31, 0x30, 0x30,  // 22: Value
                0xb0, 0x01,              // 26: Number of images
                0x00, 0x04,              // 28: Unsigned long type
                0x00, 0x00, 0x00, 0x01,  // 30: Count
                0x00, 0x00, 0x00, 0x02,  // 34: Value
                0xb0, 0x02,              // 38: MP entry tag
                0x00, 0x07,              // 40: Undefined type
                0x00, 0x00, 0x00, 0x20,  // 42: Size
                0x00, 0x00, 0x00, 0x32,  // 46: Value (offset)
                0x00, 0x00, 0x00, 0x00,  // 50: Next IFD offset (null)
                0x20, 0x03, 0x00, 0x00,  // 54: MP Entry 0 attributes
                0x00, 0x56, 0xda, 0x2f,  // 58: MP Entry 0 size (5691951)
                0x00, 0x00, 0x00, 0x00,  // 62: MP Entry 0 offset (0)
                0x00, 0x00, 0x00, 0x00,  // 66: MP Entry 0 dependencies
                0x00, 0x00, 0x00, 0x00,  // 70: MP Entry 1 attributes.
                0x00, 0x14, 0xc6, 0x01,  // 74: MP Entry 1 size (1361409)
                0x00, 0x55, 0x7c, 0x1f,  // 78: MP Entry 1 offset (5602335)
                0x00, 0x00, 0x00, 0x00,  // 82: MP Entry 1 dependencies
        };

        // Verify the offsets labeled above.
        REPORTER_ASSERT(r, bytes[22] == 0x30);
        REPORTER_ASSERT(r, bytes[26] == 0xb0);
        REPORTER_ASSERT(r, bytes[38] == 0xb0);
        REPORTER_ASSERT(r, bytes[54] == 0x20);
        REPORTER_ASSERT(r, bytes[81] == 0x1f);

        {
            // Change the version to {'0', '1', '0', '1'}.
            auto bytesInvalid = SkData::MakeWithCopy(bytes, sizeof(bytes));
            REPORTER_ASSERT(r, bytes[25] == '0');
            reinterpret_cast<uint8_t*>(bytesInvalid->writable_data())[25] = '1';
            REPORTER_ASSERT(r, SkJpegMultiPictureParameters::Make(bytesInvalid) == nullptr);
        }

        {
            // Change the number of images to be undefined type instead of unsigned long type.
            auto bytesInvalid = SkData::MakeWithCopy(bytes, sizeof(bytes));
            REPORTER_ASSERT(r, bytes[29] == 0x04);
            reinterpret_cast<uint8_t*>(bytesInvalid->writable_data())[29] = 0x07;
            REPORTER_ASSERT(r, SkJpegMultiPictureParameters::Make(bytesInvalid) == nullptr);
        }

        {
            // Make the MP entries point off of the end of the buffer.
            auto bytesInvalid = SkData::MakeWithCopy(bytes, sizeof(bytes));
            REPORTER_ASSERT(r, bytes[49] == 0x32);
            reinterpret_cast<uint8_t*>(bytesInvalid->writable_data())[49] = 0xFE;
            REPORTER_ASSERT(r, SkJpegMultiPictureParameters::Make(bytesInvalid) == nullptr);
        }

        {
            // Make the MP entries too small.
            auto bytesInvalid = SkData::MakeWithCopy(bytes, sizeof(bytes));
            REPORTER_ASSERT(r, bytes[45] == 0x20);
            reinterpret_cast<uint8_t*>(bytesInvalid->writable_data())[45] = 0x1F;
            REPORTER_ASSERT(r, SkJpegMultiPictureParameters::Make(bytesInvalid) == nullptr);
        }
    }
}

DEF_TEST(Codec_jpegMultiPicture, r) {
    const char* path = "images/iphone_13_pro.jpeg";
    auto stream = GetResourceAsStream(path);
    REPORTER_ASSERT(r, stream);

    // Search and parse the MPF header.
    std::unique_ptr<SkJpegMultiPictureParameters> mpParams;
    SkJpegSegment mpParamsSegment;
    REPORTER_ASSERT(r, find_mp_params_segment(stream.get(), &mpParams, &mpParamsSegment));

    // Verify that we get the same parameters when we re-serialize and de-serialize them
    {
        auto mpParamsSerialized = mpParams->serialize(0);
        REPORTER_ASSERT(r, mpParamsSerialized);
        auto mpParamsRoundTripped = SkJpegMultiPictureParameters::Make(mpParamsSerialized);
        REPORTER_ASSERT(r, mpParamsRoundTripped);
        REPORTER_ASSERT(r, mpParamsRoundTripped->images.size() == mpParams->images.size());
        for (size_t i = 0; i < mpParamsRoundTripped->images.size(); ++i) {
            REPORTER_ASSERT(r, mpParamsRoundTripped->images[i].size == mpParams->images[i].size);
            REPORTER_ASSERT(
                    r,
                    mpParamsRoundTripped->images[i].dataOffset == mpParams->images[i].dataOffset);
        }
    }

    const struct Rec {
        const TestStream::Type streamType;
        const bool skipFirstImage;
        const size_t bufferSize;
    } recs[] = {
            {TestStream::Type::kMemoryMapped, false, 1024},
            {TestStream::Type::kMemoryMapped, true, 1024},
            {TestStream::Type::kSeekable, false, 1024},
            {TestStream::Type::kSeekable, true, 1024},
            {TestStream::Type::kSeekable, false, 7},
            {TestStream::Type::kSeekable, true, 13},
            {TestStream::Type::kSeekable, true, 1024 * 1024 * 16},
            {TestStream::Type::kUnseekable, false, 1024},
            {TestStream::Type::kUnseekable, true, 1024},
            {TestStream::Type::kUnseekable, false, 1},
            {TestStream::Type::kUnseekable, true, 1},
            {TestStream::Type::kUnseekable, false, 7},
            {TestStream::Type::kUnseekable, true, 13},
            {TestStream::Type::kUnseekable, false, 1024 * 1024 * 16},
            {TestStream::Type::kUnseekable, true, 1024 * 1024 * 16},
    };
    for (const auto& rec : recs) {
        stream->rewind();
        TestStream testStream(rec.streamType, stream.get());
        auto sourceMgr = SkJpegSourceMgr::Make(&testStream, rec.bufferSize);

        // Decode the images into bitmaps.
        size_t numberOfImages = mpParams->images.size();
        std::vector<SkBitmap> bitmaps(numberOfImages);
        for (size_t i = 0; i < numberOfImages; ++i) {
            if (i == 0) {
                REPORTER_ASSERT(r, mpParams->images[i].dataOffset == 0);
                continue;
            }
            if (i == 1 && rec.skipFirstImage) {
                continue;
            }
            auto imageData = sourceMgr->getSubsetData(
                    SkJpegMultiPictureParameters::GetImageAbsoluteOffset(
                            mpParams->images[i].dataOffset, mpParamsSegment.offset),
                    mpParams->images[i].size);
            REPORTER_ASSERT(r, imageData);

            std::unique_ptr<SkCodec> codec =
                    SkCodec::MakeFromStream(SkMemoryStream::Make(imageData));
            REPORTER_ASSERT(r, codec);

            SkBitmap bm;
            bm.allocPixels(codec->getInfo());
            REPORTER_ASSERT(r,
                            SkCodec::kSuccess ==
                                    codec->getPixels(bm.info(), bm.getPixels(), bm.rowBytes()));
            bitmaps[i] = bm;
        }

        // Spot-check the image size and pixels.
        if (!rec.skipFirstImage) {
            REPORTER_ASSERT(r, bitmaps[1].dimensions() == SkISize::Make(1512, 2016));
            REPORTER_ASSERT(r, bitmaps[1].getColor(0, 0) == 0xFF3B3B3B);
            REPORTER_ASSERT(r, bitmaps[1].getColor(1511, 2015) == 0xFF101010);
        }
        REPORTER_ASSERT(r, bitmaps[2].dimensions() == SkISize::Make(576, 768));
        REPORTER_ASSERT(r, bitmaps[2].getColor(0, 0) == 0xFF010101);
        REPORTER_ASSERT(r, bitmaps[2].getColor(575, 767) == 0xFFB5B5B5);
    }
}

// Decode an image and its gainmap.
template <typename Reporter>
void decode_all(Reporter& r,
                std::unique_ptr<SkStream> stream,
                SkBitmap& baseBitmap,
                SkBitmap& gainmapBitmap,
                SkGainmapInfo& gainmapInfo) {
    // Decode the base bitmap.
    SkCodec::Result result = SkCodec::kSuccess;
    std::unique_ptr<SkCodec> baseCodec = SkJpegCodec::MakeFromStream(std::move(stream), &result);
    REPORTER_ASSERT(r, baseCodec);
    baseBitmap.allocPixels(baseCodec->getInfo());
    REPORTER_ASSERT(r,
                    SkCodec::kSuccess == baseCodec->getPixels(baseBitmap.info(),
                                                              baseBitmap.getPixels(),
                                                              baseBitmap.rowBytes()));
    std::unique_ptr<SkAndroidCodec> androidCodec =
            SkAndroidCodec::MakeFromCodec(std::move(baseCodec));
    REPORTER_ASSERT(r, androidCodec);

    // Extract the gainmap info and codec.
    std::unique_ptr<SkAndroidCodec> gainmapCodec;
    REPORTER_ASSERT(r, androidCodec->getGainmapAndroidCodec(&gainmapInfo, &gainmapCodec));
    REPORTER_ASSERT(r, gainmapCodec);

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

DEF_TEST(AndroidCodec_jpegGainmapDecode, r) {
    const struct Rec {
        const char* path;
        SkISize dimensions;
        SkColor originColor;
        SkColor farCornerColor;
        SkGainmapInfo info;
    } recs[] = {
            {"images/iphone_13_pro.jpeg",
             SkISize::Make(1512, 2016),
             0xFF3B3B3B,
             0xFF101010,
             {{1.f, 1.f, 1.f, 1.f},
              {3.482202f, 3.482202f, 3.482202f, 1.f},
              {1.f, 1.f, 1.f, 1.f},
              {0.f, 0.f, 0.f, 1.f},
              {0.f, 0.f, 0.f, 1.f},
              1.f,
              3.482202f,
              SkGainmapInfo::BaseImageType::kSDR,
              SkGainmapInfo::Type::kApple,
              nullptr}},
            {"images/iphone_15.jpeg",
             SkISize::Make(2016, 1512),
             0xFF5C5C5C,
             0xFF656565,
             {{1.f, 1.f, 1.f, 1.f},
              {3.755272f, 3.755272f, 3.755272f, 1.f},
              {1.f, 1.f, 1.f, 1.f},
              {0.f, 0.f, 0.f, 1.f},
              {0.f, 0.f, 0.f, 1.f},
              1.f,
              3.755272f,
              SkGainmapInfo::BaseImageType::kSDR,
              SkGainmapInfo::Type::kApple,
              nullptr}},
            {"images/gainmap_gcontainer_only.jpg",
             SkISize::Make(32, 32),
             0xffffffff,
             0xffffffff,
             {{25.f, 0.5f, 1.f, 1.f},
              {2.f, 4.f, 8.f, 1.f},
              {0.5, 1.f, 2.f, 1.f},
              {0.01f, 0.001f, 0.0001f, 1.f},
              {0.0001f, 0.001f, 0.01f, 1.f},
              2.f,
              4.f,
              SkGainmapInfo::BaseImageType::kSDR,
              SkGainmapInfo::Type::kDefault,
              nullptr}},
            {"images/gainmap_iso21496_1_adobe_gcontainer.jpg",
             SkISize::Make(32, 32),
             0xffffffff,
             0xff000000,
             {{25.f, 0.5f, 1.f, 1.f},
              {2.f, 4.f, 8.f, 1.f},
              {0.5, 1.f, 2.f, 1.f},
              {0.01f, 0.001f, 0.0001f, 1.f},
              {0.0001f, 0.001f, 0.01f, 1.f},
              2.f,
              4.f,
              SkGainmapInfo::BaseImageType::kSDR,
              SkGainmapInfo::Type::kDefault,
              nullptr}},
            {"images/gainmap_iso21496_1.jpg",
             SkISize::Make(32, 32),
             0xffffffff,
             0xff000000,
             {{25.f, 0.5f, 1.f, 1.f},
              {2.f, 4.f, 8.f, 1.f},
              {0.5, 1.f, 2.f, 1.f},
              {0.01f, 0.001f, 0.0001f, 1.f},
              {0.0001f, 0.001f, 0.01f, 1.f},
              2.f,
              4.f,
              SkGainmapInfo::BaseImageType::kHDR,
              SkGainmapInfo::Type::kDefault,
              SkColorSpace::MakeRGB(SkNamedTransferFn::kSRGB, SkNamedGamut::kRec2020)}},
    };

    TestStream::Type kStreamTypes[] = {
            TestStream::Type::kUnseekable,
            TestStream::Type::kSeekable,
            TestStream::Type::kMemoryMapped,
    };
    for (const auto& streamType : kStreamTypes) {
        bool useFileStream = streamType != TestStream::Type::kMemoryMapped;
        for (const auto& rec : recs) {
            auto stream = GetResourceAsStream(rec.path, useFileStream);
            REPORTER_ASSERT(r, stream);
            auto testStream = std::make_unique<TestStream>(streamType, stream.get());

            SkBitmap baseBitmap;
            SkBitmap gainmapBitmap;
            SkGainmapInfo gainmapInfo;
            decode_all(r, std::move(testStream), baseBitmap, gainmapBitmap, gainmapInfo);

            // Spot-check the image size and pixels.
            REPORTER_ASSERT(r, gainmapBitmap.dimensions() == rec.dimensions);
            REPORTER_ASSERT(r, gainmapBitmap.getColor(0, 0) == rec.originColor);
            REPORTER_ASSERT(
                    r,
                    gainmapBitmap.getColor(rec.dimensions.fWidth - 1, rec.dimensions.fHeight - 1) ==
                            rec.farCornerColor);

            // Verify the gainmap rendering parameters.
            skiatest::ExpectApproxEqInfo(r, rec.info, gainmapInfo);
        }
    }
}

DEF_TEST(AndroidCodec_jpegNoGainmap, r) {
    // This test image has a large APP16 segment that will stress the various SkJpegSourceMgrs'
    // data skipping paths.
    const char* path = "images/icc-v2-gbr.jpg";

    TestStream::Type kStreamTypes[] = {
            TestStream::Type::kUnseekable,
            TestStream::Type::kSeekable,
            TestStream::Type::kMemoryMapped,
    };
    for (const auto& streamType : kStreamTypes) {
        bool useFileStream = streamType != TestStream::Type::kMemoryMapped;
        auto stream = GetResourceAsStream(path, useFileStream);
        REPORTER_ASSERT(r, stream);
        auto testStream = std::make_unique<TestStream>(streamType, stream.get());

        // Decode the base bitmap.
        SkCodec::Result result = SkCodec::kSuccess;
        std::unique_ptr<SkCodec> baseCodec =
                SkJpegCodec::MakeFromStream(std::move(testStream), &result);
        REPORTER_ASSERT(r, baseCodec);
        SkBitmap baseBitmap;
        baseBitmap.allocPixels(baseCodec->getInfo());
        REPORTER_ASSERT(r,
                        SkCodec::kSuccess == baseCodec->getPixels(baseBitmap.info(),
                                                                  baseBitmap.getPixels(),
                                                                  baseBitmap.rowBytes()));

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

        // Try to extract the gainmap info and stream. It should fail.
        SkGainmapInfo gainmapInfo;
        std::unique_ptr<SkStream> gainmapStream;
        REPORTER_ASSERT(r, !androidCodec->getAndroidGainmap(&gainmapInfo, &gainmapStream));
    }
}

#if !defined(SK_ENABLE_NDK_IMAGES)

DEF_TEST(AndroidCodec_gainmapInfoEncode, r) {
    SkDynamicMemoryWStream encodeStream;

    constexpr size_t kNumTests = 4;

    SkBitmap baseBitmap;
    baseBitmap.allocPixels(SkImageInfo::MakeN32Premul(16, 16));

    SkBitmap gainmapBitmaps[kNumTests];
    gainmapBitmaps[0].allocPixels(SkImageInfo::MakeN32Premul(16, 16));
    gainmapBitmaps[1].allocPixels(SkImageInfo::MakeN32Premul(8, 8));
    gainmapBitmaps[2].allocPixels(
            SkImageInfo::Make(4, 4, kAlpha_8_SkColorType, kPremul_SkAlphaType));
    gainmapBitmaps[3].allocPixels(
            SkImageInfo::Make(8, 8, kGray_8_SkColorType, kPremul_SkAlphaType));

    SkGainmapInfo infos[kNumTests] = {
            // Multi-channel, UltraHDR-compatible.
            {{1.f, 2.f, 4.f, 1.f},
             {8.f, 16.f, 32.f, 1.f},
             {64.f, 128.f, 256.f, 1.f},
             {1 / 10.f, 1 / 11.f, 1 / 12.f, 1.f},
             {1 / 13.f, 1 / 14.f, 1 / 15.f, 1.f},
             4.f,
             32.f,
             SkGainmapInfo::BaseImageType::kSDR,
             SkGainmapInfo::Type::kDefault,
             nullptr},
            // Multi-channel, not UltraHDR-compatible.
            {{1.f, 2.f, 4.f, 1.f},
             {8.f, 16.f, 32.f, 1.f},
             {64.f, 128.f, 256.f, 1.f},
             {1 / 10.f, 1 / 11.f, 1 / 12.f, 1.f},
             {1 / 13.f, 1 / 14.f, 1 / 15.f, 1.f},
             4.f,
             32.f,
             SkGainmapInfo::BaseImageType::kSDR,
             SkGainmapInfo::Type::kDefault,
             SkColorSpace::MakeRGB(SkNamedTransferFn::kSRGB, SkNamedGamut::kDisplayP3)},
            // Single-channel, UltraHDR-compatible.
            {{1.f, 1.f, 1.f, 1.f},
             {8.f, 8.f, 8.f, 1.f},
             {64.f, 64.f, 64.f, 1.f},
             {1 / 128.f, 1 / 128.f, 1 / 128.f, 1.f},
             {1 / 256.f, 1 / 256.f, 1 / 256.f, 1.f},
             4.f,
             32.f,
             SkGainmapInfo::BaseImageType::kSDR,
             SkGainmapInfo::Type::kDefault,
             nullptr},
            // Single-channel, not UltraHDR-compatible.
            {{1.f, 1.f, 1.f, 1.f},
             {8.f, 8.f, 8.f, 1.f},
             {64.f, 64.f, 64.f, 1.f},
             {1 / 128.f, 1 / 128.f, 1 / 128.f, 1.f},
             {1 / 256.f, 1 / 256.f, 1 / 256.f, 1.f},
             4.f,
             32.f,
             SkGainmapInfo::BaseImageType::kHDR,
             SkGainmapInfo::Type::kDefault,
             SkColorSpace::MakeRGB(SkNamedTransferFn::kSRGB, SkNamedGamut::kDisplayP3)},
    };

    for (size_t i = 0; i < kNumTests; ++i) {
        // Encode |gainmapInfo|.
        bool encodeResult = SkJpegGainmapEncoder::EncodeHDRGM(&encodeStream,
                                                              baseBitmap.pixmap(),
                                                              SkJpegEncoder::Options(),
                                                              gainmapBitmaps[i].pixmap(),
                                                              SkJpegEncoder::Options(),
                                                              infos[i]);
        REPORTER_ASSERT(r, encodeResult);

        // Decode into |decodedGainmapInfo|.
        SkGainmapInfo decodedGainmapInfo;
        SkBitmap decodedBaseBitmap;
        SkBitmap decodedGainmapBitmap;
        auto decodeStream = std::make_unique<SkMemoryStream>(encodeStream.detachAsData());
        decode_all(r,
                   std::move(decodeStream),
                   decodedBaseBitmap,
                   decodedGainmapBitmap,
                   decodedGainmapInfo);

        // Verify that the decode reproducd the input.
        skiatest::ExpectApproxEqInfo(r, infos[i], decodedGainmapInfo);
    }
}

// Render an applied gainmap.
static SkBitmap render_gainmap(const SkImageInfo& renderInfo,
                               float renderHdrRatio,
                               const SkBitmap& baseBitmap,
                               const SkBitmap& gainmapBitmap,
                               const SkGainmapInfo& gainmapInfo,
                               int x,
                               int y) {
    SkRect baseRect = SkRect::MakeXYWH(x, y, renderInfo.width(), renderInfo.height());

    float scaleX = gainmapBitmap.width() / static_cast<float>(baseBitmap.width());
    float scaleY = gainmapBitmap.height() / static_cast<float>(baseBitmap.height());
    SkRect gainmapRect = SkRect::MakeXYWH(baseRect.x() * scaleX,
                                          baseRect.y() * scaleY,
                                          baseRect.width() * scaleX,
                                          baseRect.height() * scaleY);

    SkRect dstRect = SkRect::Make(renderInfo.dimensions());

    sk_sp<SkImage> baseImage = SkImages::RasterFromBitmap(baseBitmap);
    sk_sp<SkImage> gainmapImage = SkImages::RasterFromBitmap(gainmapBitmap);
    sk_sp<SkShader> shader = SkGainmapShader::Make(baseImage,
                                                   baseRect,
                                                   SkSamplingOptions(),
                                                   gainmapImage,
                                                   gainmapRect,
                                                   SkSamplingOptions(),
                                                   gainmapInfo,
                                                   dstRect,
                                                   renderHdrRatio);

    SkBitmap result;
    result.allocPixels(renderInfo);
    result.eraseColor(SK_ColorTRANSPARENT);
    SkCanvas canvas(result);

    SkPaint paint;
    paint.setShader(shader);
    canvas.drawRect(dstRect, paint);

    return result;
}

// Render a single pixel of an applied gainmap and return it.
static SkColor4f render_gainmap_pixel(float renderHdrRatio,
                                      const SkBitmap& baseBitmap,
                                      const SkBitmap& gainmapBitmap,
                                      const SkGainmapInfo& gainmapInfo,
                                      int x,
                                      int y) {
    SkImageInfo testPixelInfo = SkImageInfo::Make(
            /*width=*/1,
            /*height=*/1,
            kRGBA_F16_SkColorType,
            kPremul_SkAlphaType,
            SkColorSpace::MakeSRGB());
    SkBitmap testPixelBitmap = render_gainmap(
            testPixelInfo, renderHdrRatio, baseBitmap, gainmapBitmap, gainmapInfo, x, y);
    return testPixelBitmap.getColor4f(0, 0);
}

DEF_TEST(AndroidCodec_jpegGainmapTranscode, r) {
    const char* path = "images/iphone_13_pro.jpeg";
    SkBitmap baseBitmap[2];
    SkBitmap gainmapBitmap[2];
    SkGainmapInfo gainmapInfo[2];

    // Decode an MPF-based gainmap image.
    decode_all(r, GetResourceAsStream(path), baseBitmap[0], gainmapBitmap[0], gainmapInfo[0]);

    // This test was written before SkGainmapShader added support for kApple type. Strip the
    // type out.
    gainmapInfo[0].fType = SkGainmapInfo::Type::kDefault;

    constexpr float kEpsilon = 1e-2f;
    {
        SkDynamicMemoryWStream encodeStream;

        // Transcode to UltraHDR.
        bool encodeResult = SkJpegGainmapEncoder::EncodeHDRGM(&encodeStream,
                                                              baseBitmap[0].pixmap(),
                                                              SkJpegEncoder::Options(),
                                                              gainmapBitmap[0].pixmap(),
                                                              SkJpegEncoder::Options(),
                                                              gainmapInfo[0]);
        REPORTER_ASSERT(r, encodeResult);
        auto encodeData = encodeStream.detachAsData();

        // Decode the just-encoded image.
        auto decodeStream = std::make_unique<SkMemoryStream>(encodeData);
        decode_all(r, std::move(decodeStream), baseBitmap[1], gainmapBitmap[1], gainmapInfo[1]);

        // HDRGM will have the same rendering parameters.
        skiatest::ExpectApproxEqInfo(r, gainmapInfo[0], gainmapInfo[1]);

        // Render a few pixels and verify that they come out the same. Rendering requires SkSL.
        const struct Rec {
            int x;
            int y;
            float hdrRatio;
            SkColor4f expectedColor;
            SkColorType forcedColorType;
        } recs[] = {
                {1446, 1603, 1.05f, {0.984375f, 1.004883f, 1.008789f, 1.f}, kUnknown_SkColorType},
                {1446, 1603, 100.f, {1.147461f, 1.170898f, 1.174805f, 1.f}, kUnknown_SkColorType},
                {1446, 1603, 100.f, {1.147461f, 1.170898f, 1.174805f, 1.f}, kGray_8_SkColorType},
                {1446, 1603, 100.f, {1.147461f, 1.170898f, 1.174805f, 1.f}, kAlpha_8_SkColorType},
                {1446, 1603, 100.f, {1.147461f, 1.170898f, 1.174805f, 1.f}, kR8_unorm_SkColorType},
        };

        for (const auto& rec : recs) {
            SkBitmap gainmapBitmap0;
            SkASSERT(gainmapBitmap[0].colorType() == kGray_8_SkColorType);

            // Force various different single-channel formats, to ensure that they all work. Note
            // that when the color type is forced to kAlpha_8_SkColorType, the shader will always
            // read (0,0,0,1) if the alpha type is kOpaque_SkAlphaType.
            if (rec.forcedColorType == kUnknown_SkColorType) {
                gainmapBitmap0 = gainmapBitmap[0];
            } else {
                gainmapBitmap0.installPixels(gainmapBitmap[0]
                                                     .info()
                                                     .makeColorType(rec.forcedColorType)
                                                     .makeAlphaType(kPremul_SkAlphaType),
                                             gainmapBitmap[0].getPixels(),
                                             gainmapBitmap[0].rowBytes());
            }
            SkColor4f p0 = render_gainmap_pixel(
                    rec.hdrRatio, baseBitmap[0], gainmapBitmap0, gainmapInfo[0], rec.x, rec.y);
            SkColor4f p1 = render_gainmap_pixel(
                    rec.hdrRatio, baseBitmap[1], gainmapBitmap[1], gainmapInfo[1], rec.x, rec.y);

            REPORTER_ASSERT(r, skiatest::ApproxEq(p0, p1, kEpsilon));
        }
    }
}

static sk_sp<SkData> get_mp_image(sk_sp<SkData> imageData, size_t imageNumber) {
    SkMemoryStream stream(imageData);
    auto sourceMgr = SkJpegSourceMgr::Make(&stream);

    std::unique_ptr<SkJpegMultiPictureParameters> mpParams;
    SkJpegSegment mpParamsSegment;
    if (!find_mp_params_segment(&stream, &mpParams, &mpParamsSegment)) {
        return nullptr;
    }
    return SkData::MakeSubset(
            imageData.get(),
            SkJpegMultiPictureParameters::GetImageAbsoluteOffset(
                    mpParams->images[imageNumber].dataOffset, mpParamsSegment.offset),
            mpParams->images[imageNumber].size);
}

static std::unique_ptr<SkTiff::ImageFileDirectory> get_ifd(
        sk_sp<SkData> imageData, uint8_t marker, const void* sig, size_t sigSize, size_t pad) {
    SkMemoryStream stream(imageData);
    auto sourceMgr = SkJpegSourceMgr::Make(&stream);
    for (const auto& segment : sourceMgr->getAllSegments()) {
        if (segment.marker != marker) {
            continue;
        }
        auto parameterData = sourceMgr->getSegmentParameters(segment);
        if (!parameterData) {
            continue;
        }
        if (parameterData->size() < sigSize || memcmp(sig, parameterData->data(), sigSize) != 0) {
            continue;
        }
        auto ifdData = SkData::MakeSubset(
                parameterData.get(), sigSize + pad, parameterData->size() - (sigSize + pad));

        bool littleEndian = false;
        uint32_t ifdOffset = 0;
        if (!SkTiff::ImageFileDirectory::ParseHeader(ifdData.get(), &littleEndian, &ifdOffset)) {
            return nullptr;
        }
        return SkTiff::ImageFileDirectory::MakeFromOffset(ifdData, littleEndian, ifdOffset);
    }
    return nullptr;
}

static std::unique_ptr<SkTiff::ImageFileDirectory> get_mpf_ifd(sk_sp<SkData> imageData) {
    return get_ifd(std::move(imageData), kMpfMarker, kMpfSig, sizeof(kMpfSig), 0);
}

static std::unique_ptr<SkTiff::ImageFileDirectory> get_exif_ifd(sk_sp<SkData> imageData) {
    return get_ifd(std::move(imageData), kExifMarker, kExifSig, sizeof(kExifSig), 1);
}

DEF_TEST(AndroidCodec_mpfParse, r) {
    sk_sp<SkData> inputData = GetResourceAsData("images/iphone_13_pro.jpeg");

    {
        // The MPF in iPhone images has 3 entries: version, image count, and the MP entries.
        auto ifd = get_mpf_ifd(inputData);
        REPORTER_ASSERT(r, ifd);
        REPORTER_ASSERT(r, ifd->getNumEntries() == 3);
        REPORTER_ASSERT(r, ifd->getEntryTag(0) == 0xB000);
        REPORTER_ASSERT(r, ifd->getEntryTag(1) == 0xB001);
        REPORTER_ASSERT(r, ifd->getEntryTag(2) == 0xB002);

        // There is no attribute IFD.
        REPORTER_ASSERT(r, !ifd->nextIfdOffset());
    }

    {
        // The gainmap images have version and image count.
        auto ifd = get_mpf_ifd(get_mp_image(inputData, 1));
        REPORTER_ASSERT(r, ifd);

        REPORTER_ASSERT(r, ifd->getNumEntries() == 2);
        REPORTER_ASSERT(r, ifd->getEntryTag(0) == 0xB000);
        REPORTER_ASSERT(r, ifd->getEntryTag(1) == 0xB001);
        uint32_t value = 0;
        REPORTER_ASSERT(r, ifd->getEntryUnsignedLong(1, 1, &value));
        REPORTER_ASSERT(r, value == 3);

        // There is no further IFD.
        REPORTER_ASSERT(r, !ifd->nextIfdOffset());
    }

    // Replace |inputData| with its transcoded version.
    {
        SkBitmap baseBitmap;
        SkBitmap gainmapBitmap;
        SkGainmapInfo gainmapInfo;
        decode_all(r,
                   std::make_unique<SkMemoryStream>(inputData),
                   baseBitmap,
                   gainmapBitmap,
                   gainmapInfo);
        gainmapInfo.fType = SkGainmapInfo::Type::kDefault;
        SkDynamicMemoryWStream encodeStream;
        bool encodeResult = SkJpegGainmapEncoder::EncodeHDRGM(&encodeStream,
                                                              baseBitmap.pixmap(),
                                                              SkJpegEncoder::Options(),
                                                              gainmapBitmap.pixmap(),
                                                              SkJpegEncoder::Options(),
                                                              gainmapInfo);
        REPORTER_ASSERT(r, encodeResult);
        inputData = encodeStream.detachAsData();
    }

    {
        // Exif should be present and valid.
        auto ifd = get_exif_ifd(inputData);
        REPORTER_ASSERT(r, ifd);
        REPORTER_ASSERT(r, ifd->getNumEntries() == 1);
        constexpr uint16_t kSubIFDOffsetTag = 0x8769;
        REPORTER_ASSERT(r, ifd->getEntryTag(0) == kSubIFDOffsetTag);
    }

    {
        // The MPF in encoded images has 3 entries: version, image count, and the MP entries.
        auto ifd = get_mpf_ifd(inputData);
        REPORTER_ASSERT(r, ifd);
        REPORTER_ASSERT(r, ifd->getNumEntries() == 3);
        REPORTER_ASSERT(r, ifd->getEntryTag(0) == 0xB000);
        REPORTER_ASSERT(r, ifd->getEntryTag(1) == 0xB001);
        REPORTER_ASSERT(r, ifd->getEntryTag(2) == 0xB002);

        // There is no attribute IFD.
        REPORTER_ASSERT(r, !ifd->nextIfdOffset());
    }

    {
        // The MPF in encoded gainmap images has 2 entries: Version and number of images.
        auto ifd = get_mpf_ifd(get_mp_image(inputData, 1));
        REPORTER_ASSERT(r, ifd);

        REPORTER_ASSERT(r, ifd->getNumEntries() == 1);
        REPORTER_ASSERT(r, ifd->getEntryTag(0) == 0xB000);

        // Verify the version data (don't verify the version in the primary image, because if that
        // were broken all MPF images would be broken).
        sk_sp<SkData> versionData = ifd->getEntryUndefinedData(0);
        REPORTER_ASSERT(r, versionData);
        REPORTER_ASSERT(r, versionData->bytes()[0] == '0');
        REPORTER_ASSERT(r, versionData->bytes()[1] == '1');
        REPORTER_ASSERT(r, versionData->bytes()[2] == '0');
        REPORTER_ASSERT(r, versionData->bytes()[3] == '0');

        // There is no further IFD.
        REPORTER_ASSERT(r, !ifd->nextIfdOffset());
    }
}

DEF_TEST(AndroidCodec_gainmapInfoParse, r) {
    const uint8_t versionData[] = {
            0x00,  // Minimum version
            0x00,
            0x00,  // Writer version
            0x00,
    };
    const uint8_t data[] = {
            0x00, 0x00,                                      // Minimum version
            0x00, 0x00,                                      // Writer version
            0xc0,                                            // Flags
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,  // Base HDR headroom
            0x00, 0x01, 0x45, 0x3e, 0x00, 0x00, 0x80, 0x00,  // Altr HDR headroom
            0xfc, 0x23, 0x05, 0x14, 0x40, 0x00, 0x00, 0x00,  // Red: Gainmap min
            0x00, 0x01, 0x1f, 0xe1, 0x00, 0x00, 0x80, 0x00,  // Red: Gainmap max
            0x10, 0x4b, 0x9f, 0x0a, 0x40, 0x00, 0x00, 0x00,  // Red: Gamma
            0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,  // Red: Base offset
            0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,  // Red: Altr offset
            0xfd, 0xdb, 0x68, 0x04, 0x40, 0x00, 0x00, 0x00,  // Green: Gainmap min
            0x00, 0x01, 0x11, 0x68, 0x00, 0x00, 0x80, 0x00,  // Green: Gainmap max
            0x10, 0x28, 0xf9, 0x53, 0x40, 0x00, 0x00, 0x00,  // Green: Gamma
            0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,  // Green: Base offset
            0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,  // Green: Altr offset
            0xf7, 0x16, 0x7b, 0x90, 0x40, 0x00, 0x00, 0x00,  // Blue: Gainmap min
            0x00, 0x01, 0x0f, 0x9a, 0x00, 0x00, 0x80, 0x00,  // Blue: Gainmap max
            0x12, 0x95, 0xa8, 0x3f, 0x40, 0x00, 0x00, 0x00,  // Blue: Gamma
            0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,  // Blue: Base offset
            0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,  // Blue: Altr offset
    };
    SkGainmapInfo kExpectedInfo = {{0.959023f, 0.977058f, 0.907989f, 1.f},
                                   {4.753710f, 4.395375f, 4.352630f, 1.f},
                                   {3.927490f, 3.960382f, 3.443712f, 1.f},
                                   {0.015625f, 0.015625f, 0.015625f, 1.f},
                                   {0.015625f, 0.015625f, 0.015625f, 1.f},
                                   1.000000f,
                                   5.819739f,
                                   SkGainmapInfo::BaseImageType::kSDR,
                                   SkGainmapInfo::Type::kDefault,
                                   nullptr};
    SkGainmapInfo kSingleChannelInfo = {{0.1234567e-4f, 0.1234567e-4f, 0.1234567e-4f, 1.f},
                                        {0.2345678e-4f, 0.2345678e-4f, 0.2345678e-4f, 1.f},
                                        {0.1234567e+0f, 0.1234567e+0f, 0.1234567e+0f, 1.f},
                                        {0.1234567e+4f, 0.1234567e+4f, 0.1234567e+4f, 1.f},
                                        {0.1234567e+4f, 0.1234567e+4f, 0.1234567e+4f, 1.f},
                                        1.,
                                        4.f,
                                        SkGainmapInfo::BaseImageType::kHDR,
                                        SkGainmapInfo::Type::kDefault,
                                        SkColorSpace::MakeSRGB()};

    // Verify the version from data.
    REPORTER_ASSERT(r,
                    SkGainmapInfo::ParseVersion(
                            SkData::MakeWithoutCopy(versionData, sizeof(versionData)).get()));

    // Verify the SkGainmapInfo from data.
    SkGainmapInfo info;
    REPORTER_ASSERT(r,
                    SkGainmapInfo::Parse(SkData::MakeWithoutCopy(data, sizeof(data)).get(), info));
    skiatest::ExpectApproxEqInfo(r, info, kExpectedInfo);

    // Verify the parsed version.
    REPORTER_ASSERT(r, SkGainmapInfo::ParseVersion(SkGainmapInfo::SerializeVersion().get()));

    // Verify the round-trip SkGainmapInfo.
    auto dataInfo = info.serialize();
    SkGainmapInfo infoRoundTrip;
    REPORTER_ASSERT(r, SkGainmapInfo::Parse(dataInfo.get(), infoRoundTrip));
    skiatest::ExpectApproxEqInfo(r, info, infoRoundTrip);

    // Serialize a single-channel SkGainmapInfo. The serialized data should be smaller.
    auto dataSingleChannelInfo = kSingleChannelInfo.serialize();
    REPORTER_ASSERT(r, dataSingleChannelInfo->size() < dataInfo->size());
    SkGainmapInfo singleChannelInfoRoundTrip;
    REPORTER_ASSERT(r,
                    SkGainmapInfo::Parse(dataSingleChannelInfo.get(), singleChannelInfoRoundTrip));
    skiatest::ExpectApproxEqInfo(r, singleChannelInfoRoundTrip, kSingleChannelInfo);
}

#endif  // !defined(SK_ENABLE_NDK_IMAGES)
