// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "lib/image-format/image_format.h"

#include <fbl/algorithm.h>
#include <zircon/assert.h>

#include <map>
#include <set>

namespace {

// There are two aspects of the ColorSpace and PixelFormat that we care about:
//   * bits-per-sample - bits per primary sample (R, G, B, or Y)
//   * RGB vs. YUV - whether the system supports the ColorSpace or PixelFormat
//     representing RGB data or YUV data.  Any given ColorSpace only supports
//     one or the other. Currently any given PixelFormat only supports one or
//     the other and this isn't likely to change.
// While we could just list all the ColorSpace(s) that each PixelFormat could
// plausibly support, expressing in terms of bits-per-sample and RGB vs. YUV is
// perhaps easier to grok.

enum ColorType {
    kColorType_NONE,
    kColorType_RGB,
    kColorType_YUV
};

struct SamplingInfo {
    std::set<uint32_t> possible_bits_per_sample;
    ColorType color_type;
};

const std::map<fuchsia_sysmem_ColorSpaceType, SamplingInfo> kColorSpaceSamplingInfo = {
    {fuchsia_sysmem_ColorSpaceType_SRGB, {{8, 10, 12, 16}, kColorType_RGB}},
    {fuchsia_sysmem_ColorSpaceType_REC601_NTSC, {{8, 10}, kColorType_YUV}},
    {fuchsia_sysmem_ColorSpaceType_REC601_NTSC_FULL_RANGE, {{8, 10}, kColorType_YUV}},
    {fuchsia_sysmem_ColorSpaceType_REC601_PAL, {{8, 10}, kColorType_YUV}},
    {fuchsia_sysmem_ColorSpaceType_REC601_PAL_FULL_RANGE, {{8, 10}, kColorType_YUV}},
    {fuchsia_sysmem_ColorSpaceType_REC709, {{8, 10}, kColorType_YUV}},
    {fuchsia_sysmem_ColorSpaceType_REC2020, {{10, 12}, kColorType_YUV}},
    {fuchsia_sysmem_ColorSpaceType_REC2100, {{10, 12}, kColorType_YUV}},
};
const std::map<fuchsia_sysmem_PixelFormatType, SamplingInfo> kPixelFormatSamplingInfo = {
    {fuchsia_sysmem_PixelFormatType_R8G8B8A8, {{8}, kColorType_RGB}},
    {fuchsia_sysmem_PixelFormatType_BGRA32, {{8}, kColorType_RGB}},
    {fuchsia_sysmem_PixelFormatType_I420, {{8}, kColorType_YUV}},
    {fuchsia_sysmem_PixelFormatType_M420, {{8}, kColorType_YUV}},
    {fuchsia_sysmem_PixelFormatType_NV12, {{8}, kColorType_YUV}},
    {fuchsia_sysmem_PixelFormatType_YUY2, {{8}, kColorType_YUV}},
    // 8 bits RGB when uncompressed - in this context, MJPEG is essentially
    // pretending to be uncompressed.
    {fuchsia_sysmem_PixelFormatType_MJPEG, {{8}, kColorType_RGB}},
    {fuchsia_sysmem_PixelFormatType_YV12, {{8}, kColorType_YUV}},
};

class ImageFormatSet {
public:
    virtual bool IsSupported(const fuchsia_sysmem_PixelFormat* pixel_format) const = 0;
    virtual uint64_t
    ImageFormatImageSize(const fuchsia_sysmem_ImageFormat_2* image_format) const = 0;
};

class IntelTiledFormats : public ImageFormatSet {
public:
    bool IsSupported(const fuchsia_sysmem_PixelFormat* pixel_format) const override {
        if (!pixel_format->has_format_modifier)
            return false;
        if (pixel_format->type != fuchsia_sysmem_PixelFormatType_R8G8B8A8 &&
            pixel_format->type != fuchsia_sysmem_PixelFormatType_BGRA32) {
            return false;
        }
        switch (pixel_format->format_modifier.value) {
        case fuchsia_sysmem_FORMAT_MODIFIER_INTEL_I915_X_TILED:
        case fuchsia_sysmem_FORMAT_MODIFIER_INTEL_I915_Y_TILED:
        case fuchsia_sysmem_FORMAT_MODIFIER_INTEL_I915_YF_TILED:
            return true;
        default:
            return false;
        }
    }
    uint64_t ImageFormatImageSize(const fuchsia_sysmem_ImageFormat_2* image_format) const override {
        // See
        // https://01.org/sites/default/files/documentation/intel-gfx-prm-osrc-skl-vol05-memory_views.pdf
        constexpr uint32_t kIntelTileByteSize = 4096;
        constexpr uint32_t kIntelYTilePixelWidth = 32;
        constexpr uint32_t kIntelYTileHeight = 4096 / (kIntelYTilePixelWidth * 4);
        constexpr uint32_t kIntelXTilePixelWidth = 128;
        constexpr uint32_t kIntelXTileHeight = 4096 / (kIntelXTilePixelWidth * 4);
        constexpr uint32_t kIntelYFTilePixelWidth = 32; // For a 4 byte per component format
        constexpr uint32_t kIntelYFTileHeight = 4096 / (kIntelYFTilePixelWidth * 4);
        ZX_DEBUG_ASSERT(IsSupported(&image_format->pixel_format));
        switch (image_format->pixel_format.format_modifier.value) {
        case fuchsia_sysmem_FORMAT_MODIFIER_INTEL_I915_X_TILED:
            return fbl::round_up(image_format->coded_width, kIntelXTilePixelWidth) /
                   kIntelXTilePixelWidth *
                   fbl::round_up(image_format->coded_height, kIntelXTileHeight) /
                   kIntelXTileHeight * kIntelTileByteSize;

        case fuchsia_sysmem_FORMAT_MODIFIER_INTEL_I915_Y_TILED:
            return fbl::round_up(image_format->coded_width, kIntelYTilePixelWidth) /
                   kIntelYTilePixelWidth *
                   fbl::round_up(image_format->coded_height, kIntelYTileHeight) /
                   kIntelYTileHeight * kIntelTileByteSize;

        case fuchsia_sysmem_FORMAT_MODIFIER_INTEL_I915_YF_TILED:
            return fbl::round_up(image_format->coded_width, kIntelYFTilePixelWidth) /
                   kIntelYFTilePixelWidth *
                   fbl::round_up(image_format->coded_height, kIntelYFTileHeight) /
                   kIntelYFTileHeight * kIntelTileByteSize;
        default:
            return 0u;
        }
    }
};

class AfbcFormats : public ImageFormatSet {
public:
    bool IsSupported(const fuchsia_sysmem_PixelFormat* pixel_format) const override {
        if (!pixel_format->has_format_modifier)
            return false;
        if (pixel_format->type != fuchsia_sysmem_PixelFormatType_R8G8B8A8 &&
            pixel_format->type != fuchsia_sysmem_PixelFormatType_BGRA32) {
            return false;
        }
        switch (pixel_format->format_modifier.value) {
        case fuchsia_sysmem_FORMAT_MODIFIER_ARM_AFBC_16x16:
        case fuchsia_sysmem_FORMAT_MODIFIER_ARM_AFBC_32x8:
            return true;
        default:
            return false;
        }
    }
    uint64_t ImageFormatImageSize(const fuchsia_sysmem_ImageFormat_2* image_format) const override {
        // See
        // https://android.googlesource.com/device/linaro/hikey/+/android-o-preview-3/gralloc960/alloc_device.cpp
        constexpr uint32_t kAfbcBodyAlignment = 1024u;

        ZX_DEBUG_ASSERT(IsSupported(&image_format->pixel_format));
        uint32_t block_width;
        uint32_t block_height;
        switch (image_format->pixel_format.format_modifier.value) {
        case fuchsia_sysmem_FORMAT_MODIFIER_ARM_AFBC_16x16:
            block_width = 16;
            block_height = 16;
            break;

        case fuchsia_sysmem_FORMAT_MODIFIER_ARM_AFBC_32x8:
            block_width = 32;
            block_height = 8;
            break;
        default:
            return 0;
        }

        ZX_DEBUG_ASSERT(image_format->pixel_format.type ==
                            fuchsia_sysmem_PixelFormatType_R8G8B8A8 ||
                        image_format->pixel_format.type == fuchsia_sysmem_PixelFormatType_BGRA32);
        constexpr uint32_t kBytesPerPixel = 4;
        constexpr uint32_t kBytesPerBlockHeader = 16;

        uint64_t block_count = fbl::round_up(image_format->coded_width, block_width) / block_width *
                               fbl::round_up(image_format->coded_height, block_height) /
                               block_height;
        return block_count * block_width * block_height * kBytesPerPixel +
               fbl::round_up(block_count * kBytesPerBlockHeader, kAfbcBodyAlignment);
    }
};

class LinearFormats : public ImageFormatSet {
    bool IsSupported(const fuchsia_sysmem_PixelFormat* pixel_format) const override {
        if (pixel_format->has_format_modifier)
            return false;
        switch (pixel_format->type) {
        case fuchsia_sysmem_PixelFormatType_INVALID:
        case fuchsia_sysmem_PixelFormatType_MJPEG:
            return false;
        case fuchsia_sysmem_PixelFormatType_R8G8B8A8:
        case fuchsia_sysmem_PixelFormatType_BGRA32:
        case fuchsia_sysmem_PixelFormatType_I420:
        case fuchsia_sysmem_PixelFormatType_M420:
        case fuchsia_sysmem_PixelFormatType_NV12:
        case fuchsia_sysmem_PixelFormatType_YUY2:
        case fuchsia_sysmem_PixelFormatType_YV12:
            return true;
        }
        return false;
    }
    uint64_t ImageFormatImageSize(const fuchsia_sysmem_ImageFormat_2* image_format) const override {
        ZX_DEBUG_ASSERT(IsSupported(&image_format->pixel_format));

        uint64_t coded_height = image_format->coded_height;
        uint64_t bytes_per_row = image_format->bytes_per_row;
        switch (image_format->pixel_format.type) {
        case fuchsia_sysmem_PixelFormatType_R8G8B8A8:
        case fuchsia_sysmem_PixelFormatType_BGRA32:
            return coded_height * bytes_per_row;
        case fuchsia_sysmem_PixelFormatType_I420:
            return coded_height * bytes_per_row * 3 / 2;
        case fuchsia_sysmem_PixelFormatType_M420:
            return coded_height * bytes_per_row * 3 / 2;
        case fuchsia_sysmem_PixelFormatType_NV12:
            return coded_height * bytes_per_row * 3 / 2;
        case fuchsia_sysmem_PixelFormatType_YUY2:
            return coded_height * bytes_per_row;
        case fuchsia_sysmem_PixelFormatType_YV12:
            return coded_height * bytes_per_row * 3 / 2;
        default:
            return 0u;
        }
    }
};

constexpr LinearFormats kLinearFormats;
constexpr IntelTiledFormats kIntelFormats;
constexpr AfbcFormats kAfbcFormats;

constexpr const ImageFormatSet* kImageFormats[] = {
    &kLinearFormats, &kIntelFormats, &kAfbcFormats,
};

}  // namespace

bool ImageFormatIsPixelFormatEqual(const fuchsia_sysmem_PixelFormat& a, const fuchsia_sysmem_PixelFormat& b) {
    return
        a.type == b.type &&
        // !has_format_modifier is for consistency with making format_modifier
        // optional in future.
        a.has_format_modifier == b.has_format_modifier &&
        // Must be 0 if !has_format_modifier.
        a.format_modifier.value == b.format_modifier.value;
}

bool ImageFormatIsSupportedColorSpaceForPixelFormat(const fuchsia_sysmem_ColorSpace& color_space, const fuchsia_sysmem_PixelFormat& pixel_format) {
    // Ignore pixel format modifier - assume it has already been checked.
    auto color_space_sampling_info_iter = kColorSpaceSamplingInfo.find(color_space.type);
    if (color_space_sampling_info_iter == kColorSpaceSamplingInfo.end()) {
        return false;
    }
    auto pixel_format_sampling_info_iter = kPixelFormatSamplingInfo.find(pixel_format.type);
    if (pixel_format_sampling_info_iter == kPixelFormatSamplingInfo.end()) {
        return false;
    }
    const SamplingInfo& color_space_sampling_info = color_space_sampling_info_iter->second;
    const SamplingInfo& pixel_format_sampling_info = pixel_format_sampling_info_iter->second;
    if (color_space_sampling_info.color_type != pixel_format_sampling_info.color_type) {
        return false;
    }
    bool is_bits_per_sample_match_found = false;
    for (uint32_t bits_per_sample : color_space_sampling_info.possible_bits_per_sample) {
        auto pixel_format_bits_per_sample_iter = pixel_format_sampling_info.possible_bits_per_sample.find(bits_per_sample);
        if (pixel_format_bits_per_sample_iter != pixel_format_sampling_info.possible_bits_per_sample.end()) {
            is_bits_per_sample_match_found = true;
            break;
        }
    }
    if (!is_bits_per_sample_match_found) {
        return false;
    }
    return true;
}

bool ImageFormatIsSupported(const fuchsia_sysmem_PixelFormat* pixel_format) {
    for (auto& format_set : kImageFormats) {
        if (format_set->IsSupported(pixel_format))
            return true;
    }
    return false;
}

// Overall bits per pixel, across all pixel data in the whole image.
uint32_t ImageFormatBitsPerPixel(const fuchsia_sysmem_PixelFormat* pixel_format) {
    ZX_DEBUG_ASSERT(ImageFormatIsSupported(pixel_format));
    switch (pixel_format->type) {
        case fuchsia_sysmem_PixelFormatType_INVALID:
        case fuchsia_sysmem_PixelFormatType_MJPEG:
            // impossible; checked previously.
            ZX_DEBUG_ASSERT(false);
            return 0u;
        case fuchsia_sysmem_PixelFormatType_R8G8B8A8:
            return 4u * 8u;
        case fuchsia_sysmem_PixelFormatType_BGRA32:
            return 4u * 8u;
        case fuchsia_sysmem_PixelFormatType_I420:
            return 12u;
        case fuchsia_sysmem_PixelFormatType_M420:
            return 12u;
        case fuchsia_sysmem_PixelFormatType_NV12:
            return 12u;
        case fuchsia_sysmem_PixelFormatType_YUY2:
            return 2u * 8u;
        case fuchsia_sysmem_PixelFormatType_YV12:
            return 12u;
    }
    ZX_PANIC("Unknown Pixel Format: %d", static_cast<int>(pixel_format->type));
    return 0u;
}

uint32_t ImageFormatStrideBytesPerWidthPixel(
    const fuchsia_sysmem_PixelFormat* pixel_format) {
    ZX_DEBUG_ASSERT(ImageFormatIsSupported(pixel_format));
    switch (pixel_format->type) {
        case fuchsia_sysmem_PixelFormatType_INVALID:
        case fuchsia_sysmem_PixelFormatType_MJPEG:
            // impossible; checked previously.
            ZX_DEBUG_ASSERT(false);
            return 0u;
        case fuchsia_sysmem_PixelFormatType_R8G8B8A8:
            return 4u;
        case fuchsia_sysmem_PixelFormatType_BGRA32:
            return 4u;
        case fuchsia_sysmem_PixelFormatType_I420:
            return 1u;
        case fuchsia_sysmem_PixelFormatType_M420:
            return 1u;
        case fuchsia_sysmem_PixelFormatType_NV12:
            return 1u;
        case fuchsia_sysmem_PixelFormatType_YUY2:
            return 2u;
        case fuchsia_sysmem_PixelFormatType_YV12:
            return 1u;
    }
    ZX_PANIC("Unknown Pixel Format: %d", static_cast<int>(pixel_format->type));
    return 0u;
}

uint64_t ImageFormatImageSize(const fuchsia_sysmem_ImageFormat_2* image_format) {
    for (auto& format_set : kImageFormats) {
        if (format_set->IsSupported(&image_format->pixel_format))
            return format_set->ImageFormatImageSize(image_format);
    }
    ZX_PANIC("Unknown Pixel Format: %d", static_cast<int>(image_format->pixel_format.type));
    return 0;
}

uint32_t ImageFormatCodedWidthMinDivisor(
    const fuchsia_sysmem_PixelFormat* pixel_format) {
    ZX_DEBUG_ASSERT(ImageFormatIsSupported(pixel_format));
    switch (pixel_format->type) {
        case fuchsia_sysmem_PixelFormatType_INVALID:
        case fuchsia_sysmem_PixelFormatType_MJPEG:
            // impossible; checked previously.
            ZX_DEBUG_ASSERT(false);
            return 0u;
        case fuchsia_sysmem_PixelFormatType_R8G8B8A8:
            return 1u;
        case fuchsia_sysmem_PixelFormatType_BGRA32:
            return 1u;
        case fuchsia_sysmem_PixelFormatType_I420:
            return 2u;
        case fuchsia_sysmem_PixelFormatType_M420:
            return 2u;
        case fuchsia_sysmem_PixelFormatType_NV12:
            return 2u;
        case fuchsia_sysmem_PixelFormatType_YUY2:
            return 2u;
        case fuchsia_sysmem_PixelFormatType_YV12:
            return 2u;
    }
    ZX_PANIC("Unknown Pixel Format: %d", static_cast<int>(pixel_format->type));
    return 0u;
}

uint32_t ImageFormatCodedHeightMinDivisor(
    const fuchsia_sysmem_PixelFormat* pixel_format) {
    ZX_DEBUG_ASSERT(ImageFormatIsSupported(pixel_format));
    switch (pixel_format->type) {
        case fuchsia_sysmem_PixelFormatType_INVALID:
        case fuchsia_sysmem_PixelFormatType_MJPEG:
            // impossible; checked previously.
            ZX_DEBUG_ASSERT(false);
            return 0u;
        case fuchsia_sysmem_PixelFormatType_R8G8B8A8:
            return 1u;
        case fuchsia_sysmem_PixelFormatType_BGRA32:
            return 1u;
        case fuchsia_sysmem_PixelFormatType_I420:
            return 2u;
        case fuchsia_sysmem_PixelFormatType_M420:
            return 2u;
        case fuchsia_sysmem_PixelFormatType_NV12:
            return 2u;
        case fuchsia_sysmem_PixelFormatType_YUY2:
            return 2u;
        case fuchsia_sysmem_PixelFormatType_YV12:
            return 2u;
    }
    ZX_PANIC("Unknown Pixel Format: %d", static_cast<int>(pixel_format->type));
    return 0u;
}

uint32_t ImageFormatSampleAlignment(
    const fuchsia_sysmem_PixelFormat* pixel_format) {
    ZX_DEBUG_ASSERT(ImageFormatIsSupported(pixel_format));
    switch (pixel_format->type) {
        case fuchsia_sysmem_PixelFormatType_INVALID:
        case fuchsia_sysmem_PixelFormatType_MJPEG:
            // impossible; checked previously.
            ZX_DEBUG_ASSERT(false);
            return 0u;
        case fuchsia_sysmem_PixelFormatType_R8G8B8A8:
            return 4u;
        case fuchsia_sysmem_PixelFormatType_BGRA32:
            return 4u;
        case fuchsia_sysmem_PixelFormatType_I420:
            return 2u;
        case fuchsia_sysmem_PixelFormatType_M420:
            return 2u;
        case fuchsia_sysmem_PixelFormatType_NV12:
            return 2u;
        case fuchsia_sysmem_PixelFormatType_YUY2:
            return 2u;
        case fuchsia_sysmem_PixelFormatType_YV12:
            return 2u;
    }
    ZX_PANIC("Unknown Pixel Format: %d", static_cast<int>(pixel_format->type));
    return 0u;
}

bool ImageFormatMinimumRowBytes(const fuchsia_sysmem_ImageFormatConstraints* constraints,
                                uint32_t width, uint32_t* minimum_row_bytes_out) {
    // Bytes per row is not well-defined for tiled types.
    ZX_DEBUG_ASSERT(!constraints->pixel_format.has_format_modifier);
    if (width < constraints->min_coded_width || width > constraints->max_coded_width) {
        return false;
    }
    *minimum_row_bytes_out = fbl::round_up(
        fbl::max(ImageFormatStrideBytesPerWidthPixel(&constraints->pixel_format) * width,
                 constraints->min_bytes_per_row),
        constraints->bytes_per_row_divisor);
    ZX_ASSERT(*minimum_row_bytes_out <= constraints->max_bytes_per_row);
    return true;
}
