/*
 * Copyright 2014 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.
 */

#include <img_utils/DngUtils.h>

#include <inttypes.h>

#include <vector>
#include <math.h>

namespace android {
namespace img_utils {

OpcodeListBuilder::OpcodeListBuilder() : mCount(0), mOpList(), mEndianOut(&mOpList, BIG) {
    if(mEndianOut.open() != OK) {
        ALOGE("%s: Open failed.", __FUNCTION__);
    }
}

OpcodeListBuilder::~OpcodeListBuilder() {
    if(mEndianOut.close() != OK) {
        ALOGE("%s: Close failed.", __FUNCTION__);
    }
}

size_t OpcodeListBuilder::getSize() const {
    return mOpList.getSize() + sizeof(mCount);
}

uint32_t OpcodeListBuilder::getCount() const {
    return mCount;
}

status_t OpcodeListBuilder::buildOpList(uint8_t* buf) const {
    uint32_t count = convertToBigEndian(mCount);
    memcpy(buf, &count, sizeof(count));
    memcpy(buf + sizeof(count), mOpList.getArray(), mOpList.getSize());
    return OK;
}

status_t OpcodeListBuilder::addGainMapsForMetadata(uint32_t lsmWidth,
                                                   uint32_t lsmHeight,
                                                   uint32_t activeAreaTop,
                                                   uint32_t activeAreaLeft,
                                                   uint32_t activeAreaBottom,
                                                   uint32_t activeAreaRight,
                                                   CfaLayout cfa,
                                                   const float* lensShadingMap) {
    uint32_t activeAreaWidth = activeAreaRight - activeAreaLeft;
    uint32_t activeAreaHeight = activeAreaBottom - activeAreaTop;
    double spacingV = 1.0 / lsmHeight;
    double spacingH = 1.0 / lsmWidth;

    std::vector<float> redMapVector(lsmWidth * lsmHeight);
    float *redMap = redMapVector.data();

    std::vector<float> greenEvenMapVector(lsmWidth * lsmHeight);
    float *greenEvenMap = greenEvenMapVector.data();

    std::vector<float> greenOddMapVector(lsmWidth * lsmHeight);
    float *greenOddMap = greenOddMapVector.data();

    std::vector<float> blueMapVector(lsmWidth * lsmHeight);
    float *blueMap = blueMapVector.data();

    size_t lsmMapSize = lsmWidth * lsmHeight * 4;

    // Split lens shading map channels into separate arrays
    size_t j = 0;
    for (size_t i = 0; i < lsmMapSize; i += 4, ++j) {
        redMap[j] = lensShadingMap[i + LSM_R_IND];
        greenEvenMap[j] = lensShadingMap[i + LSM_GE_IND];
        greenOddMap[j] = lensShadingMap[i + LSM_GO_IND];
        blueMap[j] = lensShadingMap[i + LSM_B_IND];
    }

    uint32_t redTop = 0;
    uint32_t redLeft = 0;
    uint32_t greenEvenTop = 0;
    uint32_t greenEvenLeft = 1;
    uint32_t greenOddTop = 1;
    uint32_t greenOddLeft = 0;
    uint32_t blueTop = 1;
    uint32_t blueLeft = 1;

    switch(cfa) {
        case CFA_RGGB:
            redTop = 0;
            redLeft = 0;
            greenEvenTop = 0;
            greenEvenLeft = 1;
            greenOddTop = 1;
            greenOddLeft = 0;
            blueTop = 1;
            blueLeft = 1;
            break;
        case CFA_GRBG:
            redTop = 0;
            redLeft = 1;
            greenEvenTop = 0;
            greenEvenLeft = 0;
            greenOddTop = 1;
            greenOddLeft = 1;
            blueTop = 1;
            blueLeft = 0;
            break;
        case CFA_GBRG:
            redTop = 1;
            redLeft = 0;
            greenEvenTop = 0;
            greenEvenLeft = 0;
            greenOddTop = 1;
            greenOddLeft = 1;
            blueTop = 0;
            blueLeft = 1;
            break;
        case CFA_BGGR:
            redTop = 1;
            redLeft = 1;
            greenEvenTop = 0;
            greenEvenLeft = 1;
            greenOddTop = 1;
            greenOddLeft = 0;
            blueTop = 0;
            blueLeft = 0;
            break;
        default:
            ALOGE("%s: Unknown CFA layout %d", __FUNCTION__, cfa);
            return BAD_VALUE;
    }

    status_t err = addGainMap(/*top*/redTop,
                              /*left*/redLeft,
                              /*bottom*/activeAreaHeight - 1,
                              /*right*/activeAreaWidth - 1,
                              /*plane*/0,
                              /*planes*/1,
                              /*rowPitch*/2,
                              /*colPitch*/2,
                              /*mapPointsV*/lsmHeight,
                              /*mapPointsH*/lsmWidth,
                              /*mapSpacingV*/spacingV,
                              /*mapSpacingH*/spacingH,
                              /*mapOriginV*/0,
                              /*mapOriginH*/0,
                              /*mapPlanes*/1,
                              /*mapGains*/redMap);
    if (err != OK) return err;

    err = addGainMap(/*top*/greenEvenTop,
                     /*left*/greenEvenLeft,
                     /*bottom*/activeAreaHeight - 1,
                     /*right*/activeAreaWidth - 1,
                     /*plane*/0,
                     /*planes*/1,
                     /*rowPitch*/2,
                     /*colPitch*/2,
                     /*mapPointsV*/lsmHeight,
                     /*mapPointsH*/lsmWidth,
                     /*mapSpacingV*/spacingV,
                     /*mapSpacingH*/spacingH,
                     /*mapOriginV*/0,
                     /*mapOriginH*/0,
                     /*mapPlanes*/1,
                     /*mapGains*/greenEvenMap);
    if (err != OK) return err;

    err = addGainMap(/*top*/greenOddTop,
                     /*left*/greenOddLeft,
                     /*bottom*/activeAreaHeight - 1,
                     /*right*/activeAreaWidth - 1,
                     /*plane*/0,
                     /*planes*/1,
                     /*rowPitch*/2,
                     /*colPitch*/2,
                     /*mapPointsV*/lsmHeight,
                     /*mapPointsH*/lsmWidth,
                     /*mapSpacingV*/spacingV,
                     /*mapSpacingH*/spacingH,
                     /*mapOriginV*/0,
                     /*mapOriginH*/0,
                     /*mapPlanes*/1,
                     /*mapGains*/greenOddMap);
    if (err != OK) return err;

    err = addGainMap(/*top*/blueTop,
                     /*left*/blueLeft,
                     /*bottom*/activeAreaHeight - 1,
                     /*right*/activeAreaWidth - 1,
                     /*plane*/0,
                     /*planes*/1,
                     /*rowPitch*/2,
                     /*colPitch*/2,
                     /*mapPointsV*/lsmHeight,
                     /*mapPointsH*/lsmWidth,
                     /*mapSpacingV*/spacingV,
                     /*mapSpacingH*/spacingH,
                     /*mapOriginV*/0,
                     /*mapOriginH*/0,
                     /*mapPlanes*/1,
                     /*mapGains*/blueMap);
    return err;
}

status_t OpcodeListBuilder::addGainMap(uint32_t top,
                                       uint32_t left,
                                       uint32_t bottom,
                                       uint32_t right,
                                       uint32_t plane,
                                       uint32_t planes,
                                       uint32_t rowPitch,
                                       uint32_t colPitch,
                                       uint32_t mapPointsV,
                                       uint32_t mapPointsH,
                                       double mapSpacingV,
                                       double mapSpacingH,
                                       double mapOriginV,
                                       double mapOriginH,
                                       uint32_t mapPlanes,
                                       const float* mapGains) {

    status_t err = addOpcodePreamble(GAIN_MAP_ID);
    if (err != OK) return err;

    // Allow this opcode to be skipped if not supported
    uint32_t flags = FLAG_OPTIONAL;

    err = mEndianOut.write(&flags, 0, 1);
    if (err != OK) return err;

    const uint32_t NUMBER_INT_ARGS = 11;
    const uint32_t NUMBER_DOUBLE_ARGS = 4;

    uint32_t totalSize = NUMBER_INT_ARGS * sizeof(uint32_t) + NUMBER_DOUBLE_ARGS * sizeof(double) +
            mapPointsV * mapPointsH * mapPlanes * sizeof(float);

    err = mEndianOut.write(&totalSize, 0, 1);
    if (err != OK) return err;

    // Batch writes as much as possible
    uint32_t settings1[] = { top,
                            left,
                            bottom,
                            right,
                            plane,
                            planes,
                            rowPitch,
                            colPitch,
                            mapPointsV,
                            mapPointsH };

    err = mEndianOut.write(settings1, 0, NELEMS(settings1));
    if (err != OK) return err;

    double settings2[] = { mapSpacingV,
                          mapSpacingH,
                          mapOriginV,
                          mapOriginH };

    err = mEndianOut.write(settings2, 0, NELEMS(settings2));
    if (err != OK) return err;

    err = mEndianOut.write(&mapPlanes, 0, 1);
    if (err != OK) return err;

    err = mEndianOut.write(mapGains, 0, mapPointsV * mapPointsH * mapPlanes);
    if (err != OK) return err;

    mCount++;

    return OK;
}

status_t OpcodeListBuilder::addWarpRectilinearForMetadata(const float* kCoeffs,
                                                          uint32_t activeArrayWidth,
                                                          uint32_t activeArrayHeight,
                                                          float opticalCenterX,
                                                          float opticalCenterY) {
    if (activeArrayWidth <= 1 || activeArrayHeight <= 1) {
        ALOGE("%s: Cannot add opcode for active array with dimensions w=%" PRIu32 ", h=%" PRIu32,
                __FUNCTION__, activeArrayWidth, activeArrayHeight);
        return BAD_VALUE;
    }

    double normalizedOCX = opticalCenterX / static_cast<double>(activeArrayWidth - 1);
    double normalizedOCY = opticalCenterY / static_cast<double>(activeArrayHeight - 1);

    normalizedOCX = CLAMP(normalizedOCX, 0, 1);
    normalizedOCY = CLAMP(normalizedOCY, 0, 1);

    // Conversion factors from Camera2 K factors to DNG spec. K factors:
    //
    //      Note: these are necessary because our unit system assumes a
    //      normalized max radius of sqrt(2), whereas the DNG spec's
    //      WarpRectilinear opcode assumes a normalized max radius of 1.
    //      Thus, each K coefficient must include the domain scaling
    //      factor (the DNG domain is scaled by sqrt(2) to emulate the
    //      domain used by the Camera2 specification).

    const double c_0 = sqrt(2);
    const double c_1 = 2 * sqrt(2);
    const double c_2 = 4 * sqrt(2);
    const double c_3 = 8 * sqrt(2);
    const double c_4 = 2;
    const double c_5 = 2;

    const double coeffs[] = { c_0 * kCoeffs[0],
                              c_1 * kCoeffs[1],
                              c_2 * kCoeffs[2],
                              c_3 * kCoeffs[3],
                              c_4 * kCoeffs[4],
                              c_5 * kCoeffs[5] };


    return addWarpRectilinear(/*numPlanes*/1,
                              /*opticalCenterX*/normalizedOCX,
                              /*opticalCenterY*/normalizedOCY,
                              coeffs);
}

status_t OpcodeListBuilder::addWarpRectilinear(uint32_t numPlanes,
                                               double opticalCenterX,
                                               double opticalCenterY,
                                               const double* kCoeffs) {

    status_t err = addOpcodePreamble(WARP_RECTILINEAR_ID);
    if (err != OK) return err;

    // Allow this opcode to be skipped if not supported
    uint32_t flags = FLAG_OPTIONAL;

    err = mEndianOut.write(&flags, 0, 1);
    if (err != OK) return err;

    const uint32_t NUMBER_CENTER_ARGS = 2;
    const uint32_t NUMBER_COEFFS = numPlanes * 6;
    uint32_t totalSize = (NUMBER_CENTER_ARGS + NUMBER_COEFFS) * sizeof(double) + sizeof(uint32_t);

    err = mEndianOut.write(&totalSize, 0, 1);
    if (err != OK) return err;

    err = mEndianOut.write(&numPlanes, 0, 1);
    if (err != OK) return err;

    err = mEndianOut.write(kCoeffs, 0, NUMBER_COEFFS);
    if (err != OK) return err;

    err = mEndianOut.write(&opticalCenterX, 0, 1);
    if (err != OK) return err;

    err = mEndianOut.write(&opticalCenterY, 0, 1);
    if (err != OK) return err;

    mCount++;

    return OK;
}

status_t OpcodeListBuilder::addBadPixelListForMetadata(const uint32_t* hotPixels,
                                                       uint32_t xyPairCount,
                                                       uint32_t colorFilterArrangement) {
    if (colorFilterArrangement > 3) {
        ALOGE("%s:  Unknown color filter arrangement %" PRIu32, __FUNCTION__,
                colorFilterArrangement);
        return BAD_VALUE;
    }

    return addBadPixelList(colorFilterArrangement, xyPairCount, 0, hotPixels, nullptr);
}

status_t OpcodeListBuilder::addBadPixelList(uint32_t bayerPhase,
                                            uint32_t badPointCount,
                                            uint32_t badRectCount,
                                            const uint32_t* badPointRowColPairs,
                                            const uint32_t* badRectTopLeftBottomRightTuples) {

    status_t err = addOpcodePreamble(FIX_BAD_PIXELS_LIST);
    if (err != OK) return err;

    // Allow this opcode to be skipped if not supported
    uint32_t flags = FLAG_OPTIONAL;

    err = mEndianOut.write(&flags, 0, 1);
    if (err != OK) return err;

    const uint32_t NUM_NON_VARLEN_FIELDS = 3;
    const uint32_t SIZE_OF_POINT = 2;
    const uint32_t SIZE_OF_RECT = 4;

    uint32_t totalSize =  (NUM_NON_VARLEN_FIELDS  + badPointCount * SIZE_OF_POINT +
            badRectCount * SIZE_OF_RECT) * sizeof(uint32_t);
    err = mEndianOut.write(&totalSize, 0, 1);
    if (err != OK) return err;

    err = mEndianOut.write(&bayerPhase, 0, 1);
    if (err != OK) return err;

    err = mEndianOut.write(&badPointCount, 0, 1);
    if (err != OK) return err;

    err = mEndianOut.write(&badRectCount, 0, 1);
    if (err != OK) return err;

    if (badPointCount > 0) {
        err = mEndianOut.write(badPointRowColPairs, 0, SIZE_OF_POINT * badPointCount);
        if (err != OK) return err;
    }

    if (badRectCount > 0) {
        err = mEndianOut.write(badRectTopLeftBottomRightTuples, 0, SIZE_OF_RECT * badRectCount);
        if (err != OK) return err;
    }

    mCount++;
    return OK;
}

status_t OpcodeListBuilder::addOpcodePreamble(uint32_t opcodeId) {
    status_t err = mEndianOut.write(&opcodeId, 0, 1);
    if (err != OK) return err;

    uint8_t version[] = {1, 3, 0, 0};
    err = mEndianOut.write(version, 0, NELEMS(version));
    if (err != OK) return err;
    return OK;
}

} /*namespace img_utils*/
} /*namespace android*/
