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

#ifndef SkYUVAInfo_DEFINED
#define SkYUVAInfo_DEFINED

#include "include/codec/SkEncodedOrigin.h"
#include "include/core/SkImageInfo.h"
#include "include/core/SkSize.h"
#include "include/core/SkYUVAIndex.h"

#include <tuple>

/**
 * Specifies the structure of planes for a YUV image with optional alpha. The actual planar data
 * is not part of this structure and depending on usage is in external textures or pixmaps.
 */
class SK_API SkYUVAInfo {
public:
    /**
     * Specifies how YUV (and optionally A) are divided among planes. Planes are separated by
     * underscores in the enum value names. Within each plane the pixmap/texture channels are
     * mapped to the YUVA channels in the order specified, e.g. for kY_UV Y is in channel 0 of plane
     * 0, U is in channel 0 of plane 1, and V is in channel 1 of plane 1. Channel ordering
     * within a pixmap/texture given the channels it contains:
     * A:               0:A
     * Luminance/Gray:  0:Gray
     * RG               0:R,    1:G
     * RGB              0:R,    1:G, 2:B
     * RGBA             0:R,    1:G, 2:B, 3:A
     */
    enum class PlaneConfig {
        kUnknown,

        kY_U_V,    ///< Plane 0: Y, Plane 1: U,  Plane 2: V
        kY_V_U,    ///< Plane 0: Y, Plane 1: V,  Plane 2: U
        kY_UV,     ///< Plane 0: Y, Plane 1: UV
        kY_VU,     ///< Plane 0: Y, Plane 1: VU
        kYUV,      ///< Plane 0: YUV
        kUYV,      ///< Plane 0: UYV

        kY_U_V_A,  ///< Plane 0: Y, Plane 1: U,  Plane 2: V, Plane 3: A
        kY_V_U_A,  ///< Plane 0: Y, Plane 1: V,  Plane 2: U, Plane 3: A
        kY_UV_A,   ///< Plane 0: Y, Plane 1: UV, Plane 2: A
        kY_VU_A,   ///< Plane 0: Y, Plane 1: VU, Plane 2: A
        kYUVA,     ///< Plane 0: YUVA
        kUYVA,     ///< Plane 0: UYVA

        kLast = kUYVA
    };

    /**
     * UV subsampling is also specified in the enum value names using J:a:b notation (e.g. 4:2:0 is
     * 1/2 horizontal and 1/2 vertical resolution for U and V). If alpha is present it is not sub-
     * sampled. Note that Subsampling values other than k444 are only valid with PlaneConfig values
     * that have U and V in different planes than Y (and A, if present).
     */
    enum class Subsampling {
        kUnknown,

        k444,    ///< No subsampling. UV values for each Y.
        k422,    ///< 1 set of UV values for each 2x1 block of Y values.
        k420,    ///< 1 set of UV values for each 2x2 block of Y values.
        k440,    ///< 1 set of UV values for each 1x2 block of Y values.
        k411,    ///< 1 set of UV values for each 4x1 block of Y values.
        k410,    ///< 1 set of UV values for each 4x2 block of Y values.

        kLast = k410
    };

    /**
     * Describes how subsampled chroma values are sited relative to luma values.
     *
     * Currently only centered siting is supported but will expand to support additional sitings.
     */
    enum class Siting {
        /**
         * Subsampled chroma value is sited at the center of the block of corresponding luma values.
         */
        kCentered,
    };

    static constexpr int kMaxPlanes = 4;

    /**
     * Given image dimensions, a planer configuration, subsampling, and origin, determine the
     * expected size of each plane. Returns the number of expected planes. planeDimensions[0]
     * through planeDimensions[<ret>] are written. The input image dimensions are as displayed
     * (after the planes have been transformed to the intended display orientation). The plane
     * dimensions are output as the planes are stored in memory (may be rotated from image
     * dimensions).
     */
    static int PlaneDimensions(SkISize imageDimensions,
                               PlaneConfig,
                               Subsampling,
                               SkEncodedOrigin,
                               SkISize planeDimensions[kMaxPlanes]);

    /** Number of planes for a given PlaneConfig. */
    static constexpr int NumPlanes(PlaneConfig);

    /**
     * Number of Y, U, V, A channels in the ith plane for a given PlaneConfig (or 0 if i is
     * invalid).
     */
    static constexpr int NumChannelsInPlane(PlaneConfig, int i);

    /**
     * Given a PlaneConfig and a set of channel flags for each plane, convert to SkYUVAIndex
     * representation. Fails if channel flags aren't valid for the PlaneConfig (i.e. don't have
     * enough channels in a plane).
     */
    static bool GetYUVAIndices(PlaneConfig,
                               const uint32_t planeChannelFlags[kMaxPlanes],
                               SkYUVAIndex indices[SkYUVAIndex::kIndexCount]);

    /** Does the PlaneConfig have alpha values? */
    static bool HasAlpha(PlaneConfig);

    SkYUVAInfo() = default;
    SkYUVAInfo(const SkYUVAInfo&) = default;

    /**
     * 'dimensions' should specify the size of the full resolution image (after planes have been
     * oriented to how the image is displayed as indicated by 'origin').
     */
    SkYUVAInfo(SkISize dimensions,
               PlaneConfig,
               Subsampling,
               SkYUVColorSpace,
               SkEncodedOrigin origin = kTopLeft_SkEncodedOrigin,
               Siting sitingX = Siting::kCentered,
               Siting sitingY = Siting::kCentered);

    SkYUVAInfo& operator=(const SkYUVAInfo& that) = default;

    PlaneConfig planeConfig() const { return fPlaneConfig; }
    Subsampling subsampling() const { return fSubsampling; }

    /**
     * Dimensions of the full resolution image (after planes have been oriented to how the image
     * is displayed as indicated by fOrigin).
     */
    SkISize dimensions() const { return fDimensions; }
    int width() const { return fDimensions.width(); }
    int height() const { return fDimensions.height(); }

    SkYUVColorSpace yuvColorSpace() const { return fYUVColorSpace; }
    Siting sitingX() const { return fSitingX; }
    Siting sitingY() const { return fSitingY; }

    SkEncodedOrigin origin() const { return fOrigin; }

    bool hasAlpha() const { return HasAlpha(fPlaneConfig); }

    /**
     * Returns the number of planes and initializes planeDimensions[0]..planeDimensions[<ret>] to
     * the expected dimensions for each plane. Dimensions are as stored in memory, before
     * transformation to image display space as indicated by origin().
     */
    int planeDimensions(SkISize planeDimensions[kMaxPlanes]) const {
        return PlaneDimensions(fDimensions, fPlaneConfig, fSubsampling, fOrigin, planeDimensions);
    }

    /**
     * Given a per-plane row bytes, determine size to allocate for all planes. Optionally retrieves
     * the per-plane byte sizes in planeSizes if not null. If total size overflows will return
     * SIZE_MAX and set all planeSizes to SIZE_MAX.
     */
    size_t computeTotalBytes(const size_t rowBytes[kMaxPlanes],
                             size_t planeSizes[kMaxPlanes] = nullptr) const;

    int numPlanes() const { return NumPlanes(fPlaneConfig); }

    int numChannelsInPlane(int i) const { return NumChannelsInPlane(fPlaneConfig, i); }

    /**
     * Given a set of channel flags for each plane, converts this->planeConfig() to SkYUVAIndex
     * representation. Fails if the channel flags aren't valid for the PlaneConfig (i.e. don't have
     * enough channels in a plane).
     */
    bool toYUVAIndices(const uint32_t channelFlags[4], SkYUVAIndex indices[4]) const {
        return GetYUVAIndices(fPlaneConfig, channelFlags, indices);
    }

    /**
     * Makes a SkYUVAInfo that is identical to this one but with the passed Subsampling. If the
     * passed Subsampling is not k444 and this info's PlaneConfig is not compatible with chroma
     * subsampling (because Y is in the same plane as UV) then the result will be an invalid
     * SkYUVAInfo.
     */
    SkYUVAInfo makeSubsampling(SkYUVAInfo::Subsampling) const;

    bool operator==(const SkYUVAInfo& that) const;
    bool operator!=(const SkYUVAInfo& that) const { return !(*this == that); }

    bool isValid() const { return fPlaneConfig != PlaneConfig::kUnknown; }

private:
    SkISize fDimensions = {0, 0};

    PlaneConfig fPlaneConfig = PlaneConfig::kUnknown;
    Subsampling fSubsampling = Subsampling::kUnknown;

    SkYUVColorSpace fYUVColorSpace = SkYUVColorSpace::kIdentity_SkYUVColorSpace;

    /**
     * YUVA data often comes from formats like JPEG that support EXIF orientation.
     * Code that operates on the raw YUV data often needs to know that orientation.
     */
    SkEncodedOrigin fOrigin = kTopLeft_SkEncodedOrigin;

    Siting fSitingX = Siting::kCentered;
    Siting fSitingY = Siting::kCentered;
};

constexpr int SkYUVAInfo::NumPlanes(PlaneConfig planeConfig) {
    switch (planeConfig) {
        case PlaneConfig::kUnknown: return 0;
        case PlaneConfig::kY_U_V:   return 3;
        case PlaneConfig::kY_V_U:   return 3;
        case PlaneConfig::kY_UV:    return 2;
        case PlaneConfig::kY_VU:    return 2;
        case PlaneConfig::kYUV:     return 1;
        case PlaneConfig::kUYV:     return 1;
        case PlaneConfig::kY_U_V_A: return 4;
        case PlaneConfig::kY_V_U_A: return 4;
        case PlaneConfig::kY_UV_A:  return 3;
        case PlaneConfig::kY_VU_A:  return 3;
        case PlaneConfig::kYUVA:    return 1;
        case PlaneConfig::kUYVA:    return 1;
    }
    SkUNREACHABLE;
}

constexpr int SkYUVAInfo::NumChannelsInPlane(PlaneConfig config, int i) {
    switch (config) {
        case PlaneConfig::kUnknown:
            return 0;

        case SkYUVAInfo::PlaneConfig::kY_U_V:
        case SkYUVAInfo::PlaneConfig::kY_V_U:
            return i >= 0 && i < 3 ? 1 : 0;
        case SkYUVAInfo::PlaneConfig::kY_UV:
        case SkYUVAInfo::PlaneConfig::kY_VU:
            switch (i) {
                case 0:  return 1;
                case 1:  return 2;
                default: return 0;
            }
        case SkYUVAInfo::PlaneConfig::kYUV:
        case SkYUVAInfo::PlaneConfig::kUYV:
            return i == 0 ? 3 : 0;
        case SkYUVAInfo::PlaneConfig::kY_U_V_A:
        case SkYUVAInfo::PlaneConfig::kY_V_U_A:
            return i >= 0 && i < 4 ? 1 : 0;
        case SkYUVAInfo::PlaneConfig::kY_UV_A:
        case SkYUVAInfo::PlaneConfig::kY_VU_A:
            switch (i) {
                case 0:  return 1;
                case 1:  return 2;
                case 2:  return 1;
                default: return 0;
            }
        case SkYUVAInfo::PlaneConfig::kYUVA:
        case SkYUVAInfo::PlaneConfig::kUYVA:
            return i == 0 ? 4 : 0;
    }
    return 0;
}

#endif
