/*
 * Copyright (C) 2016 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

//#define LOG_NDEBUG 0
#define LOG_TAG "ColorUtils"

#include <inttypes.h>
#include <arpa/inet.h>
#include <media/stagefright/foundation/ABuffer.h>
#include <media/stagefright/foundation/ADebug.h>
#include <media/stagefright/foundation/ALookup.h>
#include <media/stagefright/foundation/ColorUtils.h>

namespace android {

// shortcut names for brevity in the following tables
typedef ColorAspects CA;
typedef ColorUtils CU;

#define HI_UINT16(a) (((a) >> 8) & 0xFF)
#define LO_UINT16(a) ((a) & 0xFF)

const static
ALookup<CU::ColorRange, CA::Range> sRanges{
    {
        { CU::kColorRangeLimited, CA::RangeLimited },
        { CU::kColorRangeFull, CA::RangeFull },
        { CU::kColorRangeUnspecified, CA::RangeUnspecified },
    }
};

const static
ALookup<CU::ColorStandard, std::pair<CA::Primaries, CA::MatrixCoeffs>> sStandards {
    {
        { CU::kColorStandardUnspecified,    { CA::PrimariesUnspecified, CA::MatrixUnspecified } },
        { CU::kColorStandardBT709,          { CA::PrimariesBT709_5, CA::MatrixBT709_5 } },
        { CU::kColorStandardBT601_625,      { CA::PrimariesBT601_6_625, CA::MatrixBT601_6 } },
        { CU::kColorStandardBT601_625_Unadjusted,
                                            // this is a really close match
                                            { CA::PrimariesBT601_6_625, CA::MatrixBT709_5 } },
        { CU::kColorStandardBT601_525,      { CA::PrimariesBT601_6_525, CA::MatrixBT601_6 } },
        { CU::kColorStandardBT601_525_Unadjusted,
                                            { CA::PrimariesBT601_6_525, CA::MatrixSMPTE240M } },
        { CU::kColorStandardBT2020,         { CA::PrimariesBT2020, CA::MatrixBT2020 } },
        { CU::kColorStandardBT2020Constant, { CA::PrimariesBT2020, CA::MatrixBT2020Constant } },
        { CU::kColorStandardBT470M,         { CA::PrimariesBT470_6M, CA::MatrixBT470_6M } },
        // NOTE: there is no close match to the matrix used by standard film, chose closest
        { CU::kColorStandardFilm,           { CA::PrimariesGenericFilm, CA::MatrixBT2020 } },
    }
};

const static
ALookup<CU::ColorTransfer, CA::Transfer> sTransfers{
    {
        { CU::kColorTransferUnspecified,    CA::TransferUnspecified },
        { CU::kColorTransferLinear,         CA::TransferLinear },
        { CU::kColorTransferSRGB,           CA::TransferSRGB },
        { CU::kColorTransferSMPTE_170M,     CA::TransferSMPTE170M },
        { CU::kColorTransferGamma22,        CA::TransferGamma22 },
        { CU::kColorTransferGamma28,        CA::TransferGamma28 },
        { CU::kColorTransferST2084,         CA::TransferST2084 },
        { CU::kColorTransferHLG,            CA::TransferHLG },
    }
};

static bool isValid(ColorAspects::Primaries p) {
    return p <= ColorAspects::PrimariesOther;
}

static bool isDefined(ColorAspects::Primaries p) {
    return p <= ColorAspects::PrimariesBT2020;
}

static bool isValid(ColorAspects::MatrixCoeffs c) {
    return c <= ColorAspects::MatrixOther;
}

static bool isDefined(ColorAspects::MatrixCoeffs c) {
    return c <= ColorAspects::MatrixBT2020Constant;
}

//static
int32_t ColorUtils::wrapColorAspectsIntoColorStandard(
        ColorAspects::Primaries primaries, ColorAspects::MatrixCoeffs coeffs) {
    ColorStandard res;
    if (sStandards.map(std::make_pair(primaries, coeffs), &res)) {
        return res;
    } else if (!isValid(primaries) || !isValid(coeffs)) {
        return kColorStandardUnspecified;
    }

    // check platform media limits
    uint32_t numPrimaries = ColorAspects::PrimariesBT2020 + 1;
    if (isDefined(primaries) && isDefined(coeffs)) {
        return kColorStandardExtendedStart + primaries + coeffs * numPrimaries;
    } else {
        return kColorStandardVendorStart + primaries + coeffs * 0x100;
    }
}

//static
status_t ColorUtils::unwrapColorAspectsFromColorStandard(
        int32_t standard,
        ColorAspects::Primaries *primaries, ColorAspects::MatrixCoeffs *coeffs) {
    std::pair<ColorAspects::Primaries, ColorAspects::MatrixCoeffs> res;
    if (sStandards.map((ColorStandard)standard, &res)) {
        *primaries = res.first;
        *coeffs = res.second;
        return OK;
    }

    int32_t start = kColorStandardExtendedStart;
    int32_t numPrimaries = ColorAspects::PrimariesBT2020 + 1;
    int32_t numCoeffs = ColorAspects::MatrixBT2020Constant + 1;
    if (standard >= (int32_t)kColorStandardVendorStart) {
        start = kColorStandardVendorStart;
        numPrimaries = ColorAspects::PrimariesOther + 1; // 0x100
        numCoeffs = ColorAspects::MatrixOther + 1; // 0x100;
    }
    if (standard >= start && standard < start + numPrimaries * numCoeffs) {
        int32_t product = standard - start;
        *primaries = (ColorAspects::Primaries)(product % numPrimaries);
        *coeffs = (ColorAspects::MatrixCoeffs)(product / numPrimaries);
        return OK;
    }
    *primaries = ColorAspects::PrimariesOther;
    *coeffs = ColorAspects::MatrixOther;
    return BAD_VALUE;
}

static bool isValid(ColorAspects::Range r) {
    return r <= ColorAspects::RangeOther;
}

static bool isDefined(ColorAspects::Range r) {
    return r <= ColorAspects::RangeLimited;
}

//  static
int32_t ColorUtils::wrapColorAspectsIntoColorRange(ColorAspects::Range range) {
    ColorRange res;
    if (sRanges.map(range, &res)) {
        return res;
    } else if (!isValid(range)) {
        return kColorRangeUnspecified;
    } else {
        CHECK(!isDefined(range));
        // all platform values are in sRanges
        return kColorRangeVendorStart + range;
    }
}

//static
status_t ColorUtils::unwrapColorAspectsFromColorRange(
        int32_t range, ColorAspects::Range *aspect) {
    if (sRanges.map((ColorRange)range, aspect)) {
        return OK;
    }

    int32_t start = kColorRangeVendorStart;
    int32_t numRanges = ColorAspects::RangeOther + 1; // 0x100
    if (range >= start && range < start + numRanges) {
        *aspect = (ColorAspects::Range)(range - start);
        return OK;
    }
    *aspect = ColorAspects::RangeOther;
    return BAD_VALUE;
}

static bool isValid(ColorAspects::Transfer t) {
    return t <= ColorAspects::TransferOther;
}

static bool isDefined(ColorAspects::Transfer t) {
    return t <= ColorAspects::TransferHLG
            || (t >= ColorAspects::TransferSMPTE240M && t <= ColorAspects::TransferST428);
}

//  static
int32_t ColorUtils::wrapColorAspectsIntoColorTransfer(
        ColorAspects::Transfer transfer) {
    ColorTransfer res;
    if (sTransfers.map(transfer, &res)) {
        return res;
    } else if (!isValid(transfer)) {
        return kColorTransferUnspecified;
    } else if (isDefined(transfer)) {
        return kColorTransferExtendedStart + transfer;
    } else {
        // all platform values are in sRanges
        return kColorTransferVendorStart + transfer;
    }
}

//static
status_t ColorUtils::unwrapColorAspectsFromColorTransfer(
        int32_t transfer, ColorAspects::Transfer *aspect) {
    if (sTransfers.map((ColorTransfer)transfer, aspect)) {
        return OK;
    }

    int32_t start = kColorTransferExtendedStart;
    int32_t numTransfers = ColorAspects::TransferST428 + 1;
    if (transfer >= (int32_t)kColorTransferVendorStart) {
        start = kColorTransferVendorStart;
        numTransfers = ColorAspects::TransferOther + 1; // 0x100
    }
    if (transfer >= start && transfer < start + numTransfers) {
        *aspect = (ColorAspects::Transfer)(transfer - start);
        return OK;
    }
    *aspect = ColorAspects::TransferOther;
    return BAD_VALUE;
}

// static
status_t ColorUtils::convertPlatformColorAspectsToCodecAspects(
    int32_t range, int32_t standard, int32_t transfer, ColorAspects &aspects) {
    status_t res1 = unwrapColorAspectsFromColorRange(range, &aspects.mRange);
    status_t res2 = unwrapColorAspectsFromColorStandard(
            standard, &aspects.mPrimaries, &aspects.mMatrixCoeffs);
    status_t res3 = unwrapColorAspectsFromColorTransfer(transfer, &aspects.mTransfer);
    return res1 != OK ? res1 : (res2 != OK ? res2 : res3);
}

// static
status_t ColorUtils::convertCodecColorAspectsToPlatformAspects(
    const ColorAspects &aspects, int32_t *range, int32_t *standard, int32_t *transfer) {
    *range = wrapColorAspectsIntoColorRange(aspects.mRange);
    *standard = wrapColorAspectsIntoColorStandard(aspects.mPrimaries, aspects.mMatrixCoeffs);
    *transfer = wrapColorAspectsIntoColorTransfer(aspects.mTransfer);
    if (isValid(aspects.mRange) && isValid(aspects.mPrimaries)
            && isValid(aspects.mMatrixCoeffs) && isValid(aspects.mTransfer)) {
        return OK;
    } else {
        return BAD_VALUE;
    }
}

const static
ALookup<int32_t, ColorAspects::Primaries> sIsoPrimaries {
    {
        { 1, ColorAspects::PrimariesBT709_5 },
        { 2, ColorAspects::PrimariesUnspecified },
        { 4, ColorAspects::PrimariesBT470_6M },
        { 5, ColorAspects::PrimariesBT601_6_625 },
        { 6, ColorAspects::PrimariesBT601_6_525 /* main */},
        { 7, ColorAspects::PrimariesBT601_6_525 },
        // -- ITU T.832 201201 ends here
        { 8, ColorAspects::PrimariesGenericFilm },
        { 9, ColorAspects::PrimariesBT2020 },
        { 10, ColorAspects::PrimariesOther /* XYZ */ },
    }
};

const static
ALookup<int32_t, ColorAspects::Transfer> sIsoTransfers {
    {
        { 1, ColorAspects::TransferSMPTE170M /* main */},
        { 2, ColorAspects::TransferUnspecified },
        { 4, ColorAspects::TransferGamma22 },
        { 5, ColorAspects::TransferGamma28 },
        { 6, ColorAspects::TransferSMPTE170M },
        { 7, ColorAspects::TransferSMPTE240M },
        { 8, ColorAspects::TransferLinear },
        { 9, ColorAspects::TransferOther /* log 100:1 */ },
        { 10, ColorAspects::TransferOther /* log 316:1 */ },
        { 11, ColorAspects::TransferXvYCC },
        { 12, ColorAspects::TransferBT1361 },
        { 13, ColorAspects::TransferSRGB },
        // -- ITU T.832 201201 ends here
        { 14, ColorAspects::TransferSMPTE170M },
        { 15, ColorAspects::TransferSMPTE170M },
        { 16, ColorAspects::TransferST2084 },
        { 17, ColorAspects::TransferST428 },
        { 18, ColorAspects::TransferHLG },
    }
};

const static
ALookup<int32_t, ColorAspects::MatrixCoeffs> sIsoMatrixCoeffs {
    {
        { 0, ColorAspects::MatrixOther },
        { 1, ColorAspects::MatrixBT709_5 },
        { 2, ColorAspects::MatrixUnspecified },
        { 4, ColorAspects::MatrixBT470_6M },
        { 6, ColorAspects::MatrixBT601_6 /* main */ },
        { 5, ColorAspects::MatrixBT601_6 },
        { 7, ColorAspects::MatrixSMPTE240M },
        { 8, ColorAspects::MatrixOther /* YCgCo */ },
        // -- ITU T.832 201201 ends here
        { 9, ColorAspects::MatrixBT2020 },
        { 10, ColorAspects::MatrixBT2020Constant },
    }
};

// static
void ColorUtils::convertCodecColorAspectsToIsoAspects(
        const ColorAspects &aspects,
        int32_t *primaries, int32_t *transfer, int32_t *coeffs, bool *fullRange) {
    if (aspects.mPrimaries == ColorAspects::PrimariesOther ||
            !sIsoPrimaries.map(aspects.mPrimaries, primaries)) {
        CHECK(sIsoPrimaries.map(ColorAspects::PrimariesUnspecified, primaries));
    }
    if (aspects.mTransfer == ColorAspects::TransferOther ||
            !sIsoTransfers.map(aspects.mTransfer, transfer)) {
        CHECK(sIsoTransfers.map(ColorAspects::TransferUnspecified, transfer));
    }
    if (aspects.mMatrixCoeffs == ColorAspects::MatrixOther ||
            !sIsoMatrixCoeffs.map(aspects.mMatrixCoeffs, coeffs)) {
        CHECK(sIsoMatrixCoeffs.map(ColorAspects::MatrixUnspecified, coeffs));
    }
    *fullRange = aspects.mRange == ColorAspects::RangeFull;
}

// static
void ColorUtils::convertIsoColorAspectsToCodecAspects(
        int32_t primaries, int32_t transfer, int32_t coeffs, bool fullRange,
        ColorAspects &aspects) {
    if (!sIsoPrimaries.map(primaries, &aspects.mPrimaries)) {
        aspects.mPrimaries = ColorAspects::PrimariesUnspecified;
    }
    if (!sIsoTransfers.map(transfer, &aspects.mTransfer)) {
        aspects.mTransfer = ColorAspects::TransferUnspecified;
    }
    if (!sIsoMatrixCoeffs.map(coeffs, &aspects.mMatrixCoeffs)) {
        aspects.mMatrixCoeffs = ColorAspects::MatrixUnspecified;
    }
    aspects.mRange = fullRange ? ColorAspects::RangeFull : ColorAspects::RangeLimited;
}

// static
void ColorUtils::setDefaultCodecColorAspectsIfNeeded(
        ColorAspects &aspects, int32_t width, int32_t height) {
    ColorAspects::MatrixCoeffs coeffs;
    ColorAspects::Primaries primaries;

    // Default to BT2020, BT709 or BT601 based on size. Allow 2.35:1 aspect ratio. Limit BT601
    // to PAL or smaller, BT2020 to 4K or larger, leaving BT709 for all resolutions in between.
    if (width >= 3840 || height >= 3840 || width * (int64_t)height >= 3840 * 1634) {
        primaries = ColorAspects::PrimariesBT2020;
        coeffs = ColorAspects::MatrixBT2020;
    } else if ((width <= 720 && height > 480 && height <= 576)
            || (height <= 720 && width > 480 && width <= 576)) {
        primaries = ColorAspects::PrimariesBT601_6_625;
        coeffs = ColorAspects::MatrixBT601_6;
    } else if ((width <= 720 && height <= 480) || (height <= 720 && width <= 480)) {
        primaries = ColorAspects::PrimariesBT601_6_525;
        coeffs = ColorAspects::MatrixBT601_6;
    } else {
        primaries = ColorAspects::PrimariesBT709_5;
        coeffs = ColorAspects::MatrixBT709_5;
    }

    if (aspects.mRange == ColorAspects::RangeUnspecified) {
        aspects.mRange = ColorAspects::RangeLimited;
    }

    if (aspects.mPrimaries == ColorAspects::PrimariesUnspecified) {
        aspects.mPrimaries = primaries;
    }
    if (aspects.mMatrixCoeffs == ColorAspects::MatrixUnspecified) {
        aspects.mMatrixCoeffs = coeffs;
    }
    if (aspects.mTransfer == ColorAspects::TransferUnspecified) {
        aspects.mTransfer = ColorAspects::TransferSMPTE170M;
    }
}

// TODO: move this into a Video HAL
ALookup<CU::ColorStandard, std::pair<CA::Primaries, CA::MatrixCoeffs>> sStandardFallbacks {
    {
        { CU::kColorStandardBT601_625, { CA::PrimariesBT709_5, CA::MatrixBT470_6M } },
        { CU::kColorStandardBT601_625, { CA::PrimariesBT709_5, CA::MatrixBT601_6 } },
        { CU::kColorStandardBT709,     { CA::PrimariesBT709_5, CA::MatrixSMPTE240M } },
        { CU::kColorStandardBT709,     { CA::PrimariesBT709_5, CA::MatrixBT2020 } },
        { CU::kColorStandardBT601_525, { CA::PrimariesBT709_5, CA::MatrixBT2020Constant } },

        { CU::kColorStandardBT2020Constant,
                                       { CA::PrimariesBT470_6M, CA::MatrixBT2020Constant } },

        { CU::kColorStandardBT601_625, { CA::PrimariesBT601_6_625, CA::MatrixBT470_6M } },
        { CU::kColorStandardBT601_525, { CA::PrimariesBT601_6_625, CA::MatrixBT2020Constant } },

        { CU::kColorStandardBT601_525, { CA::PrimariesBT601_6_525, CA::MatrixBT470_6M } },
        { CU::kColorStandardBT601_525, { CA::PrimariesBT601_6_525, CA::MatrixBT2020Constant } },

        { CU::kColorStandardBT2020Constant,
                                       { CA::PrimariesGenericFilm, CA::MatrixBT2020Constant } },
    }
};

ALookup<CU::ColorStandard, CA::Primaries> sStandardPrimariesFallbacks {
    {
        { CU::kColorStandardFilm,                 CA::PrimariesGenericFilm },
        { CU::kColorStandardBT470M,               CA::PrimariesBT470_6M },
        { CU::kColorStandardBT2020,               CA::PrimariesBT2020 },
        { CU::kColorStandardBT601_525_Unadjusted, CA::PrimariesBT601_6_525 },
        { CU::kColorStandardBT601_625_Unadjusted, CA::PrimariesBT601_6_625 },
    }
};

static ALookup<android_dataspace, android_dataspace> sLegacyDataSpaceToV0 {
    {
        { HAL_DATASPACE_SRGB, HAL_DATASPACE_V0_SRGB },
        { HAL_DATASPACE_BT709, HAL_DATASPACE_V0_BT709 },
        { HAL_DATASPACE_SRGB_LINEAR, HAL_DATASPACE_V0_SRGB_LINEAR },
        { HAL_DATASPACE_BT601_525, HAL_DATASPACE_V0_BT601_525 },
        { HAL_DATASPACE_BT601_625, HAL_DATASPACE_V0_BT601_625 },
        { HAL_DATASPACE_JFIF, HAL_DATASPACE_V0_JFIF },
    }
};

bool ColorUtils::convertDataSpaceToV0(android_dataspace &dataSpace) {
    (void)sLegacyDataSpaceToV0.lookup(dataSpace, &dataSpace);
    return (dataSpace & 0xC000FFFF) == 0;
}

bool ColorUtils::checkIfAspectsChangedAndUnspecifyThem(
        ColorAspects &aspects, const ColorAspects &orig, bool usePlatformAspects) {
    // remove changed aspects (change them to Unspecified)
    bool changed = false;
    if (aspects.mRange && aspects.mRange != orig.mRange) {
        aspects.mRange = ColorAspects::RangeUnspecified;
        changed = true;
    }
    if (aspects.mPrimaries && aspects.mPrimaries != orig.mPrimaries) {
        aspects.mPrimaries = ColorAspects::PrimariesUnspecified;
        if (usePlatformAspects) {
            aspects.mMatrixCoeffs = ColorAspects::MatrixUnspecified;
        }
        changed = true;
    }
    if (aspects.mMatrixCoeffs && aspects.mMatrixCoeffs != orig.mMatrixCoeffs) {
        aspects.mMatrixCoeffs = ColorAspects::MatrixUnspecified;
        if (usePlatformAspects) {
            aspects.mPrimaries = ColorAspects::PrimariesUnspecified;
        }
        changed = true;
    }
    if (aspects.mTransfer && aspects.mTransfer != orig.mTransfer) {
        aspects.mTransfer = ColorAspects::TransferUnspecified;
        changed = true;
    }
    return changed;
}

// static
android_dataspace ColorUtils::getDataSpaceForColorAspects(ColorAspects &aspects, bool mayExpand) {
    // This platform implementation never expands color space (e.g. returns an expanded
    // dataspace to use where the codec does in-the-background color space conversion)
    mayExpand = false;

    if (aspects.mRange == ColorAspects::RangeUnspecified
            || aspects.mPrimaries == ColorAspects::PrimariesUnspecified
            || aspects.mMatrixCoeffs == ColorAspects::MatrixUnspecified
            || aspects.mTransfer == ColorAspects::TransferUnspecified) {
        ALOGW("expected specified color aspects (%u:%u:%u:%u)",
                aspects.mRange, aspects.mPrimaries, aspects.mMatrixCoeffs, aspects.mTransfer);
    }

    // default to video range and transfer
    ColorRange range = kColorRangeLimited;
    ColorTransfer transfer = kColorTransferSMPTE_170M;
    (void)sRanges.map(aspects.mRange, &range);
    (void)sTransfers.map(aspects.mTransfer, &transfer);

    ColorStandard standard = kColorStandardBT709;
    auto pair = std::make_pair(aspects.mPrimaries, aspects.mMatrixCoeffs);
    if (!sStandards.map(pair, &standard)) {
        if (!sStandardFallbacks.map(pair, &standard)) {
            (void)sStandardPrimariesFallbacks.map(aspects.mPrimaries, &standard);

            if (aspects.mMatrixCoeffs == ColorAspects::MatrixBT2020Constant) {
                range = kColorRangeFull;
            }
        }
    }

    android_dataspace dataSpace = (android_dataspace)(
            (range << HAL_DATASPACE_RANGE_SHIFT) | (standard << HAL_DATASPACE_STANDARD_SHIFT) |
            (transfer << HAL_DATASPACE_TRANSFER_SHIFT));
    (void)sLegacyDataSpaceToV0.rlookup(dataSpace, &dataSpace);

    if (!mayExpand) {
        // update codec aspects based on dataspace
        convertPlatformColorAspectsToCodecAspects(range, standard, transfer, aspects);
    }
    return dataSpace;
}

// static
void ColorUtils::getColorConfigFromFormat(
        const sp<AMessage> &format, int32_t *range, int32_t *standard, int32_t *transfer) {
    if (!format->findInt32("color-range", range)) {
        *range = kColorRangeUnspecified;
    }
    if (!format->findInt32("color-standard", standard)) {
        *standard = kColorStandardUnspecified;
    }
    if (!format->findInt32("color-transfer", transfer)) {
        *transfer = kColorTransferUnspecified;
    }
}

// static
void ColorUtils::copyColorConfig(const sp<AMessage> &source, sp<AMessage> &target) {
    // 0 values are unspecified
    int32_t value;
    if (source->findInt32("color-range", &value)) {
        target->setInt32("color-range", value);
    }
    if (source->findInt32("color-standard", &value)) {
        target->setInt32("color-standard", value);
    }
    if (source->findInt32("color-transfer", &value)) {
        target->setInt32("color-transfer", value);
    }
}

// static
void ColorUtils::getColorAspectsFromFormat(const sp<AMessage> &format, ColorAspects &aspects) {
    int32_t range, standard, transfer;
    getColorConfigFromFormat(format, &range, &standard, &transfer);

    if (convertPlatformColorAspectsToCodecAspects(
            range, standard, transfer, aspects) != OK) {
        ALOGW("Ignoring illegal color aspects(R:%d(%s), S:%d(%s), T:%d(%s))",
                range, asString((ColorRange)range),
                standard, asString((ColorStandard)standard),
                transfer, asString((ColorTransfer)transfer));
        // Invalid values were converted to unspecified !params!, but otherwise were not changed
        // For encoders, we leave these as is. For decoders, we will use default values.
    }
    ALOGV("Got color aspects (R:%d(%s), P:%d(%s), M:%d(%s), T:%d(%s)) "
          "from format (out:R:%d(%s), S:%d(%s), T:%d(%s))",
            aspects.mRange, asString(aspects.mRange),
            aspects.mPrimaries, asString(aspects.mPrimaries),
            aspects.mMatrixCoeffs, asString(aspects.mMatrixCoeffs),
            aspects.mTransfer, asString(aspects.mTransfer),
            range, asString((ColorRange)range),
            standard, asString((ColorStandard)standard),
            transfer, asString((ColorTransfer)transfer));
}

// static
void ColorUtils::setColorAspectsIntoFormat(
        const ColorAspects &aspects, sp<AMessage> &format, bool force) {
    int32_t range = 0, standard = 0, transfer = 0;
    convertCodecColorAspectsToPlatformAspects(aspects, &range, &standard, &transfer);
    // save set values to base output format
    // (encoder input format will read back actually supported values by the codec)
    if (range != 0 || force) {
        format->setInt32("color-range", range);
    }
    if (standard != 0 || force) {
        format->setInt32("color-standard", standard);
    }
    if (transfer != 0 || force) {
        format->setInt32("color-transfer", transfer);
    }
    ALOGV("Setting color aspects (R:%d(%s), P:%d(%s), M:%d(%s), T:%d(%s)) "
          "into format (out:R:%d(%s), S:%d(%s), T:%d(%s))",
            aspects.mRange, asString(aspects.mRange),
            aspects.mPrimaries, asString(aspects.mPrimaries),
            aspects.mMatrixCoeffs, asString(aspects.mMatrixCoeffs),
            aspects.mTransfer, asString(aspects.mTransfer),
            range, asString((ColorRange)range),
            standard, asString((ColorStandard)standard),
            transfer, asString((ColorTransfer)transfer));
}

// static
void ColorUtils::setHDRStaticInfoIntoFormat(
        const HDRStaticInfo &info, sp<AMessage> &format) {
    sp<ABuffer> infoBuffer = new ABuffer(25);

    // Convert the data in infoBuffer to little endian format as defined by CTA-861-3
    uint8_t *data = infoBuffer->data();
    // Static_Metadata_Descriptor_ID
    data[0] = info.mID;

    // display primary 0
    data[1] = LO_UINT16(info.sType1.mR.x);
    data[2] = HI_UINT16(info.sType1.mR.x);
    data[3] = LO_UINT16(info.sType1.mR.y);
    data[4] = HI_UINT16(info.sType1.mR.y);

    // display primary 1
    data[5] = LO_UINT16(info.sType1.mG.x);
    data[6] = HI_UINT16(info.sType1.mG.x);
    data[7] = LO_UINT16(info.sType1.mG.y);
    data[8] = HI_UINT16(info.sType1.mG.y);

    // display primary 2
    data[9] = LO_UINT16(info.sType1.mB.x);
    data[10] = HI_UINT16(info.sType1.mB.x);
    data[11] = LO_UINT16(info.sType1.mB.y);
    data[12] = HI_UINT16(info.sType1.mB.y);

    // white point
    data[13] = LO_UINT16(info.sType1.mW.x);
    data[14] = HI_UINT16(info.sType1.mW.x);
    data[15] = LO_UINT16(info.sType1.mW.y);
    data[16] = HI_UINT16(info.sType1.mW.y);

    // MaxDisplayLuminance
    data[17] = LO_UINT16(info.sType1.mMaxDisplayLuminance);
    data[18] = HI_UINT16(info.sType1.mMaxDisplayLuminance);

    // MinDisplayLuminance
    data[19] = LO_UINT16(info.sType1.mMinDisplayLuminance);
    data[20] = HI_UINT16(info.sType1.mMinDisplayLuminance);

    // MaxContentLightLevel
    data[21] = LO_UINT16(info.sType1.mMaxContentLightLevel);
    data[22] = HI_UINT16(info.sType1.mMaxContentLightLevel);

    // MaxFrameAverageLightLevel
    data[23] = LO_UINT16(info.sType1.mMaxFrameAverageLightLevel);
    data[24] = HI_UINT16(info.sType1.mMaxFrameAverageLightLevel);

    format->setBuffer("hdr-static-info", infoBuffer);
}

// a simple method copied from Utils.cpp
static uint16_t U16LE_AT(const uint8_t *ptr) {
    return ptr[0] | (ptr[1] << 8);
}

// static
bool ColorUtils::getHDRStaticInfoFromFormat(const sp<AMessage> &format, HDRStaticInfo *info) {
    sp<ABuffer> buf;
    if (!format->findBuffer("hdr-static-info", &buf)) {
        return false;
    }

    // TODO: Make this more flexible when adding more members to HDRStaticInfo
    if (buf->size() != 25 /* static Metadata Type 1 size */) {
        ALOGW("Ignore invalid HDRStaticInfo with size: %zu", buf->size());
        return false;
    }

    const uint8_t *data = buf->data();
    if (*data != HDRStaticInfo::kType1) {
        ALOGW("Unsupported static Metadata Type %u", *data);
        return false;
    }

    info->mID = HDRStaticInfo::kType1;
    info->sType1.mR.x = U16LE_AT(&data[1]);
    info->sType1.mR.y = U16LE_AT(&data[3]);
    info->sType1.mG.x = U16LE_AT(&data[5]);
    info->sType1.mG.y = U16LE_AT(&data[7]);
    info->sType1.mB.x = U16LE_AT(&data[9]);
    info->sType1.mB.y = U16LE_AT(&data[11]);
    info->sType1.mW.x = U16LE_AT(&data[13]);
    info->sType1.mW.y = U16LE_AT(&data[15]);
    info->sType1.mMaxDisplayLuminance = U16LE_AT(&data[17]);
    info->sType1.mMinDisplayLuminance = U16LE_AT(&data[19]);
    info->sType1.mMaxContentLightLevel = U16LE_AT(&data[21]);
    info->sType1.mMaxFrameAverageLightLevel = U16LE_AT(&data[23]);

    ALOGV("Got HDRStaticInfo from config (R: %u %u, G: %u %u, B: %u, %u, W: %u, %u, "
            "MaxDispL: %u, MinDispL: %u, MaxContentL: %u, MaxFrameAvgL: %u)",
            info->sType1.mR.x, info->sType1.mR.y, info->sType1.mG.x, info->sType1.mG.y,
            info->sType1.mB.x, info->sType1.mB.y, info->sType1.mW.x, info->sType1.mW.y,
            info->sType1.mMaxDisplayLuminance, info->sType1.mMinDisplayLuminance,
            info->sType1.mMaxContentLightLevel, info->sType1.mMaxFrameAverageLightLevel);
    return true;
}

}  // namespace android

