/*
 * Copyright 2023 Google Inc.
 *
 * 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/Test.h"
#include "tools/Resources.h"

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

namespace {

// Return true if the relative difference between x and y is less than epsilon.
static bool approx_eq(float x, float y, float epsilon) {
    float numerator = std::abs(x - y);
    // To avoid being too sensitive around zero, set the minimum denominator to epsilon.
    float denominator = std::max(std::min(std::abs(x), std::abs(y)), epsilon);
    if (numerator / denominator > epsilon) {
        return false;
    }
    return true;
}

static bool approx_eq(const SkColor4f& x, const SkColor4f& y, float epsilon) {
    return approx_eq(x.fR, y.fR, epsilon) && approx_eq(x.fG, y.fG, epsilon) &&
           approx_eq(x.fB, y.fB, epsilon);
}

template <typename Reporter>
void expect_approx_eq_info(Reporter& r, const SkGainmapInfo& a, const SkGainmapInfo& b) {
    float kEpsilon = 1e-4f;
    REPORTER_ASSERT(r, approx_eq(a.fGainmapRatioMin, b.fGainmapRatioMin, kEpsilon));
    REPORTER_ASSERT(r, approx_eq(a.fGainmapRatioMin, b.fGainmapRatioMin, kEpsilon));
    REPORTER_ASSERT(r, approx_eq(a.fGainmapGamma, b.fGainmapGamma, kEpsilon));
    REPORTER_ASSERT(r, approx_eq(a.fEpsilonSdr, b.fEpsilonSdr, kEpsilon));
    REPORTER_ASSERT(r, approx_eq(a.fEpsilonHdr, b.fEpsilonHdr, kEpsilon));
    REPORTER_ASSERT(r, approx_eq(a.fDisplayRatioSdr, b.fDisplayRatioSdr, kEpsilon));
    REPORTER_ASSERT(r, approx_eq(a.fDisplayRatioHdr, b.fDisplayRatioHdr, kEpsilon));
    REPORTER_ASSERT(r, a.fType == b.fType);
    REPORTER_ASSERT(r, a.fBaseImageType == b.fBaseImageType);

    REPORTER_ASSERT(r, !!a.fGainmapMathColorSpace == !!b.fGainmapMathColorSpace);
    if (a.fGainmapMathColorSpace) {
        skcms_TransferFunction a_fn;
        skcms_Matrix3x3 a_m;
        a.fGainmapMathColorSpace->transferFn(&a_fn);
        a.fGainmapMathColorSpace->toXYZD50(&a_m);
        skcms_TransferFunction b_fn;
        skcms_Matrix3x3 b_m;
        b.fGainmapMathColorSpace->transferFn(&b_fn);
        b.fGainmapMathColorSpace->toXYZD50(&b_m);

        REPORTER_ASSERT(r, approx_eq(a_fn.g, b_fn.g, kEpsilon));
        REPORTER_ASSERT(r, approx_eq(a_fn.a, b_fn.a, kEpsilon));
        REPORTER_ASSERT(r, approx_eq(a_fn.b, b_fn.b, kEpsilon));
        REPORTER_ASSERT(r, approx_eq(a_fn.c, b_fn.c, kEpsilon));
        REPORTER_ASSERT(r, approx_eq(a_fn.d, b_fn.d, kEpsilon));
        REPORTER_ASSERT(r, approx_eq(a_fn.e, b_fn.e, kEpsilon));
        REPORTER_ASSERT(r, approx_eq(a_fn.f, b_fn.f, kEpsilon));

        // The round-trip of the color space through the ICC profile loses significant precision.
        // Use a larger epsilon for it.
        const float kMatrixEpsilon = 1e-2f;
        for (int i = 0; i < 3; ++i) {
            for (int j = 0; j < 3; ++j) {
                REPORTER_ASSERT(r, approx_eq(a_m.vals[i][j], b_m.vals[i][j], kMatrixEpsilon));
            }
        }
    }
}

// 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.
            expect_approx_eq_info(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.
        expect_approx_eq_info(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.
        expect_approx_eq_info(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, approx_eq(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.1234567e-4f, -0.1234567e-4f, -0.1234567e-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));
    expect_approx_eq_info(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));
    expect_approx_eq_info(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));
    expect_approx_eq_info(r, singleChannelInfoRoundTrip, kSingleChannelInfo);
}

#endif  // !defined(SK_ENABLE_NDK_IMAGES)
