/*
 * 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 stream.
    std::unique_ptr<SkStream> gainmapStream;
    REPORTER_ASSERT(r, androidCodec->getAndroidGainmap(&gainmapInfo, &gainmapStream));
    REPORTER_ASSERT(r, gainmapStream);

    // Decode the gainmap bitmap.
    std::unique_ptr<SkCodec> gainmapCodec = SkCodec::MakeFromStream(std::move(gainmapStream));
    REPORTER_ASSERT(r, gainmapCodec);
    SkBitmap bm;
    bm.allocPixels(gainmapCodec->getInfo());
    gainmapBitmap.allocPixels(gainmapCodec->getInfo());
    REPORTER_ASSERT(r,
                    SkCodec::kSuccess == gainmapCodec->getPixels(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,
                                                   renderInfo.refColorSpace());

    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)
