/*
 * 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 },
    }
};

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

