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

#include "include/private/SkGainmapInfo.h"

#include "include/core/SkColor.h"
#include "include/core/SkData.h"
#include "include/core/SkRefCnt.h"
#include "include/core/SkStream.h"
#include "src/base/SkEndian.h"
#include "src/codec/SkCodecPriv.h"
#include "src/core/SkStreamPriv.h"

#include <cmath>
#include <cstdint>
#include <memory>

namespace {
constexpr uint8_t kIsMultiChannelMask = (1u << 7);
constexpr uint8_t kUseBaseColourSpaceMask = (1u << 6);
}  // namespace

static void write_rational_be(SkDynamicMemoryWStream& s, float x) {
    // TODO(b/338342146): Select denominator to get maximum precision and robustness.
    uint32_t denominator = 0x10000000;
    if (std::abs(x) > 1.f) {
        denominator = 0x1000;
    }
    int32_t numerator = static_cast<int32_t>(std::llround(static_cast<double>(x) * denominator));
    SkStreamPriv::WriteS32BE(&s, numerator);
    SkStreamPriv::WriteU32BE(&s, denominator);
}

static void write_positive_rational_be(SkDynamicMemoryWStream& s, float x) {
    // TODO(b/338342146): Select denominator to get maximum precision and robustness.
    uint32_t denominator = 0x10000000;
    if (x > 1.f) {
        denominator = 0x1000;
    }
    uint32_t numerator = static_cast<uint32_t>(std::llround(static_cast<double>(x) * denominator));
    SkStreamPriv::WriteU32BE(&s, numerator);
    SkStreamPriv::WriteU32BE(&s, denominator);
}

static bool read_rational_be(SkStream* s, float* value) {
    int32_t numerator = 0;
    uint32_t denominator = 0;
    if (!SkStreamPriv::ReadS32BE(s, &numerator)) {
        return false;
    }
    if (!SkStreamPriv::ReadU32BE(s, &denominator)) {
        return false;
    }
    *value = static_cast<float>(static_cast<double>(numerator) / static_cast<double>(denominator));
    return true;
}

static bool read_positive_rational_be(SkStream* s, float* value) {
    uint32_t numerator = 0;
    uint32_t denominator = 0;
    if (!SkStreamPriv::ReadU32BE(s, &numerator)) {
        return false;
    }
    if (!SkStreamPriv::ReadU32BE(s, &denominator)) {
        return false;
    }
    *value = static_cast<float>(static_cast<double>(numerator) / static_cast<double>(denominator));
    return true;
}

static bool read_iso_gainmap_version(SkStream* s) {
    // Ensure minimum version is 0.
    uint16_t minimum_version = 0;
    if (!SkStreamPriv::ReadU16BE(s, &minimum_version)) {
        SkCodecPrintf("Failed to read ISO 21496-1 minimum version.\n");
        return false;
    }
    if (minimum_version != 0) {
        SkCodecPrintf("Unsupported ISO 21496-1 minimum version.\n");
        return false;
    }

    // Ensure writer version is present. No value is invalid.
    uint16_t writer_version = 0;
    if (!SkStreamPriv::ReadU16BE(s, &writer_version)) {
        SkCodecPrintf("Failed to read ISO 21496-1 version.\n");
        return false;
    }

    return true;
}

static bool read_iso_gainmap_info(SkStream* s, SkGainmapInfo& info) {
    if (!read_iso_gainmap_version(s)) {
        SkCodecPrintf("Failed to read ISO 21496-1 version.\n");
        return false;
    }

    uint8_t flags = 0;
    if (!s->readU8(&flags)) {
        SkCodecPrintf("Failed to read ISO 21496-1 flags.\n");
        return false;
    }
    bool isMultiChannel = (flags & kIsMultiChannelMask) != 0;
    bool useBaseColourSpace = (flags & kUseBaseColourSpaceMask) != 0;

    float baseHdrHeadroom = 0.f;
    if (!read_positive_rational_be(s, &baseHdrHeadroom)) {
        SkCodecPrintf("Failed to read ISO 21496-1 base HDR headroom.\n");
        return false;
    }
    float altrHdrHeadroom = 0.f;
    if (!read_positive_rational_be(s, &altrHdrHeadroom)) {
        SkCodecPrintf("Failed to read ISO 21496-1 altr HDR headroom.\n");
        return false;
    }

    float gainMapMin[3] = {0.f};
    float gainMapMax[3] = {0.f};
    float gamma[3] = {0.f};
    float baseOffset[3] = {0.f};
    float altrOffset[3] = {0.f};

    int channelCount = isMultiChannel ? 3 : 1;
    for (int i = 0; i < channelCount; ++i) {
        if (!read_rational_be(s, gainMapMin + i)) {
            SkCodecPrintf("Failed to read ISO 21496-1 gainmap minimum.\n");
            return false;
        }
        if (!read_rational_be(s, gainMapMax + i)) {
            SkCodecPrintf("Failed to read ISO 21496-1 gainmap maximum.\n");
            return false;
        }
        if (!read_positive_rational_be(s, gamma + i)) {
            SkCodecPrintf("Failed to read ISO 21496-1 gamma.\n");
            return false;
        }
        if (!read_rational_be(s, baseOffset + i)) {
            SkCodecPrintf("Failed to read ISO 21496-1 base offset.\n");
            return false;
        }
        if (!read_rational_be(s, altrOffset + i)) {
            SkCodecPrintf("Failed to read ISO 21496-1 altr offset.\n");
            return false;
        }
    }

    info = SkGainmapInfo();
    if (!useBaseColourSpace) {
        info.fGainmapMathColorSpace = SkColorSpace::MakeSRGB();
    }
    if (baseHdrHeadroom < altrHdrHeadroom) {
        info.fBaseImageType = SkGainmapInfo::BaseImageType::kSDR;
        info.fDisplayRatioSdr = std::exp2(baseHdrHeadroom);
        info.fDisplayRatioHdr = std::exp2(altrHdrHeadroom);
    } else {
        info.fBaseImageType = SkGainmapInfo::BaseImageType::kHDR;
        info.fDisplayRatioHdr = std::exp2(baseHdrHeadroom);
        info.fDisplayRatioSdr = std::exp2(altrHdrHeadroom);
    }
    for (int i = 0; i < 3; ++i) {
        int j = i >= channelCount ? 0 : i;
        info.fGainmapRatioMin[i] = std::exp2(gainMapMin[j]);
        info.fGainmapRatioMax[i] = std::exp2(gainMapMax[j]);
        info.fGainmapGamma[i] = 1.f / gamma[j];
        switch (info.fBaseImageType) {
            case SkGainmapInfo::BaseImageType::kSDR:
                info.fEpsilonSdr[i] = baseOffset[j];
                info.fEpsilonHdr[i] = altrOffset[j];
                break;
            case SkGainmapInfo::BaseImageType::kHDR:
                info.fEpsilonHdr[i] = baseOffset[j];
                info.fEpsilonSdr[i] = altrOffset[j];
                break;
        }
    }
    return true;
}

bool SkGainmapInfo::isUltraHDRv1Compatible() const {
    // UltraHDR v1 supports having the base image be HDR in theory, but it is largely
    // untested.
    if (fBaseImageType == BaseImageType::kHDR) {
        return false;
    }
    // UltraHDR v1 doesn't support a non-base gainmap math color space.
    if (fGainmapMathColorSpace) {
        return false;
    }
    return true;
}

bool SkGainmapInfo::ParseVersion(const SkData* data) {
    if (!data) {
        return false;
    }
    auto s = SkMemoryStream::MakeDirect(data->data(), data->size());
    return read_iso_gainmap_version(s.get());
}

bool SkGainmapInfo::Parse(const SkData* data, SkGainmapInfo& info) {
    if (!data) {
        return false;
    }
    auto s = SkMemoryStream::MakeDirect(data->data(), data->size());
    return read_iso_gainmap_info(s.get(), info);
}

sk_sp<SkData> SkGainmapInfo::SerializeVersion() {
    SkDynamicMemoryWStream s;
    SkStreamPriv::WriteU16BE(&s, 0);  // Minimum reader version
    SkStreamPriv::WriteU16BE(&s, 0);  // Writer version
    return s.detachAsData();
}

static bool is_single_channel(SkColor4f c) { return c.fR == c.fG && c.fG == c.fB; }

sk_sp<SkData> SkGainmapInfo::serialize() const {
    SkDynamicMemoryWStream s;
    // Version.
    SkStreamPriv::WriteU16BE(&s, 0);  // Minimum reader version
    SkStreamPriv::WriteU16BE(&s, 0);  // Writer version

    // Flags.
    bool all_single_channel = is_single_channel(fGainmapRatioMin) &&
                              is_single_channel(fGainmapRatioMax) &&
                              is_single_channel(fGainmapGamma) && is_single_channel(fEpsilonSdr) &&
                              is_single_channel(fEpsilonHdr);
    uint8_t flags = 0;
    if (!fGainmapMathColorSpace) {
        flags |= kUseBaseColourSpaceMask;
    }
    if (!all_single_channel) {
        flags |= kIsMultiChannelMask;
    }
    s.write8(flags);

    // Base and altr headroom.
    switch (fBaseImageType) {
        case SkGainmapInfo::BaseImageType::kSDR:
            write_positive_rational_be(s, std::log2(fDisplayRatioSdr));
            write_positive_rational_be(s, std::log2(fDisplayRatioHdr));
            break;
        case SkGainmapInfo::BaseImageType::kHDR:
            write_positive_rational_be(s, std::log2(fDisplayRatioHdr));
            write_positive_rational_be(s, std::log2(fDisplayRatioSdr));
            break;
    }

    // Per-channel information.
    for (int i = 0; i < (all_single_channel ? 1 : 3); ++i) {
        write_rational_be(s, std::log2(fGainmapRatioMin[i]));
        write_rational_be(s, std::log2(fGainmapRatioMax[i]));
        write_positive_rational_be(s, 1.f / fGainmapGamma[i]);
        switch (fBaseImageType) {
            case SkGainmapInfo::BaseImageType::kSDR:
                write_rational_be(s, fEpsilonSdr[i]);
                write_rational_be(s, fEpsilonHdr[i]);
                break;
            case SkGainmapInfo::BaseImageType::kHDR:
                write_rational_be(s, fEpsilonHdr[i]);
                write_rational_be(s, fEpsilonSdr[i]);
                break;
        }
    }
    return s.detachAsData();
}
