/*
 * Copyright (C) 2010 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 "YUVImage"

#include <media/stagefright/foundation/ADebug.h>
#include <media/stagefright/YUVImage.h>
#include <ui/Rect.h>

namespace android {

YUVImage::YUVImage(YUVFormat yuvFormat, int32_t width, int32_t height) {
    mYUVFormat = yuvFormat;
    mWidth = width;
    mHeight = height;

    size_t numberOfBytes = bufferSize(yuvFormat, width, height);
    uint8_t *buffer = new uint8_t[numberOfBytes];
    mBuffer = buffer;
    mOwnBuffer = true;

    initializeYUVPointers();
}

YUVImage::YUVImage(YUVFormat yuvFormat, int32_t width, int32_t height, uint8_t *buffer) {
    mYUVFormat = yuvFormat;
    mWidth = width;
    mHeight = height;
    mBuffer = buffer;
    mOwnBuffer = false;

    initializeYUVPointers();
}

//static
size_t YUVImage::bufferSize(YUVFormat yuvFormat, int32_t width, int32_t height) {
    int32_t numberOfPixels = width*height;
    size_t numberOfBytes = 0;
    if (yuvFormat == YUV420Planar || yuvFormat == YUV420SemiPlanar) {
        // Y takes numberOfPixels bytes and U/V take numberOfPixels/4 bytes each.
        numberOfBytes = (size_t)(numberOfPixels + (numberOfPixels >> 1));
    } else {
        ALOGE("Format not supported");
    }
    return numberOfBytes;
}

bool YUVImage::initializeYUVPointers() {
    int32_t numberOfPixels = mWidth * mHeight;

    if (mYUVFormat == YUV420Planar) {
        mYdata = (uint8_t *)mBuffer;
        mUdata = mYdata + numberOfPixels;
        mVdata = mUdata + (numberOfPixels >> 2);
    } else if (mYUVFormat == YUV420SemiPlanar) {
        // U and V channels are interleaved as VUVUVU.
        // So V data starts at the end of Y channel and
        // U data starts right after V's start.
        mYdata = (uint8_t *)mBuffer;
        mVdata = mYdata + numberOfPixels;
        mUdata = mVdata + 1;
    } else {
        ALOGE("Format not supported");
        return false;
    }
    return true;
}

YUVImage::~YUVImage() {
    if (mOwnBuffer) delete[] mBuffer;
}

bool YUVImage::getOffsets(int32_t x, int32_t y,
        int32_t *yOffset, int32_t *uOffset, int32_t *vOffset) const {
    *yOffset = y*mWidth + x;

    int32_t uvOffset = (y >> 1) * (mWidth >> 1) + (x >> 1);
    if (mYUVFormat == YUV420Planar) {
        *uOffset = uvOffset;
        *vOffset = uvOffset;
    } else if (mYUVFormat == YUV420SemiPlanar) {
        // Since U and V channels are interleaved, offsets need
        // to be doubled.
        *uOffset = 2*uvOffset;
        *vOffset = 2*uvOffset;
    } else {
        ALOGE("Format not supported");
        return false;
    }

    return true;
}

bool YUVImage::getOffsetIncrementsPerDataRow(
        int32_t *yDataOffsetIncrement,
        int32_t *uDataOffsetIncrement,
        int32_t *vDataOffsetIncrement) const {
    *yDataOffsetIncrement = mWidth;

    int32_t uvDataOffsetIncrement = mWidth >> 1;

    if (mYUVFormat == YUV420Planar) {
        *uDataOffsetIncrement = uvDataOffsetIncrement;
        *vDataOffsetIncrement = uvDataOffsetIncrement;
    } else if (mYUVFormat == YUV420SemiPlanar) {
        // Since U and V channels are interleaved, offsets need
        // to be doubled.
        *uDataOffsetIncrement = 2*uvDataOffsetIncrement;
        *vDataOffsetIncrement = 2*uvDataOffsetIncrement;
    } else {
        ALOGE("Format not supported");
        return false;
    }

    return true;
}

uint8_t* YUVImage::getYAddress(int32_t offset) const {
    return mYdata + offset;
}

uint8_t* YUVImage::getUAddress(int32_t offset) const {
    return mUdata + offset;
}

uint8_t* YUVImage::getVAddress(int32_t offset) const {
    return mVdata + offset;
}

bool YUVImage::getYUVAddresses(int32_t x, int32_t y,
        uint8_t **yAddr, uint8_t **uAddr, uint8_t **vAddr) const {
    int32_t yOffset;
    int32_t uOffset;
    int32_t vOffset;
    if (!getOffsets(x, y, &yOffset, &uOffset, &vOffset)) return false;

    *yAddr = getYAddress(yOffset);
    *uAddr = getUAddress(uOffset);
    *vAddr = getVAddress(vOffset);

    return true;
}

bool YUVImage::validPixel(int32_t x, int32_t y) const {
    return (x >= 0 && x < mWidth &&
            y >= 0 && y < mHeight);
}

bool YUVImage::getPixelValue(int32_t x, int32_t y,
        uint8_t *yPtr, uint8_t *uPtr, uint8_t *vPtr) const {
    CHECK(validPixel(x, y));

    uint8_t *yAddr;
    uint8_t *uAddr;
    uint8_t *vAddr;
    if (!getYUVAddresses(x, y, &yAddr, &uAddr, &vAddr)) return false;

    *yPtr = *yAddr;
    *uPtr = *uAddr;
    *vPtr = *vAddr;

    return true;
}

bool YUVImage::setPixelValue(int32_t x, int32_t y,
        uint8_t yValue, uint8_t uValue, uint8_t vValue) {
    CHECK(validPixel(x, y));

    uint8_t *yAddr;
    uint8_t *uAddr;
    uint8_t *vAddr;
    if (!getYUVAddresses(x, y, &yAddr, &uAddr, &vAddr)) return false;

    *yAddr = yValue;
    *uAddr = uValue;
    *vAddr = vValue;

    return true;
}

void YUVImage::fastCopyRectangle420Planar(
        const Rect& srcRect,
        int32_t destStartX, int32_t destStartY,
        const YUVImage &srcImage, YUVImage &destImage) {
    CHECK(srcImage.mYUVFormat == YUV420Planar);
    CHECK(destImage.mYUVFormat == YUV420Planar);

    int32_t srcStartX = srcRect.left;
    int32_t srcStartY = srcRect.top;
    int32_t width = srcRect.width();
    int32_t height = srcRect.height();

    // Get source and destination start addresses
    uint8_t *ySrcAddrBase;
    uint8_t *uSrcAddrBase;
    uint8_t *vSrcAddrBase;
    srcImage.getYUVAddresses(srcStartX, srcStartY,
            &ySrcAddrBase, &uSrcAddrBase, &vSrcAddrBase);

    uint8_t *yDestAddrBase;
    uint8_t *uDestAddrBase;
    uint8_t *vDestAddrBase;
    destImage.getYUVAddresses(destStartX, destStartY,
            &yDestAddrBase, &uDestAddrBase, &vDestAddrBase);

    // Get source and destination offset increments incurred in going
    // from one data row to next.
    int32_t ySrcOffsetIncrement;
    int32_t uSrcOffsetIncrement;
    int32_t vSrcOffsetIncrement;
    srcImage.getOffsetIncrementsPerDataRow(
            &ySrcOffsetIncrement, &uSrcOffsetIncrement, &vSrcOffsetIncrement);

    int32_t yDestOffsetIncrement;
    int32_t uDestOffsetIncrement;
    int32_t vDestOffsetIncrement;
    destImage.getOffsetIncrementsPerDataRow(
            &yDestOffsetIncrement, &uDestOffsetIncrement, &vDestOffsetIncrement);

    // Copy Y
    {
        size_t numberOfYBytesPerRow = (size_t) width;
        uint8_t *ySrcAddr = ySrcAddrBase;
        uint8_t *yDestAddr = yDestAddrBase;
        for (int32_t offsetY = 0; offsetY < height; ++offsetY) {
            memcpy(yDestAddr, ySrcAddr, numberOfYBytesPerRow);

            ySrcAddr += ySrcOffsetIncrement;
            yDestAddr += yDestOffsetIncrement;
        }
    }

    // Copy U
    {
        size_t numberOfUBytesPerRow = (size_t) (width >> 1);
        uint8_t *uSrcAddr = uSrcAddrBase;
        uint8_t *uDestAddr = uDestAddrBase;
        // Every other row has an entry for U/V channel values. Hence only
        // go half the height.
        for (int32_t offsetY = 0; offsetY < (height >> 1); ++offsetY) {
            memcpy(uDestAddr, uSrcAddr, numberOfUBytesPerRow);

            uSrcAddr += uSrcOffsetIncrement;
            uDestAddr += uDestOffsetIncrement;
        }
    }

    // Copy V
    {
        size_t numberOfVBytesPerRow = (size_t) (width >> 1);
        uint8_t *vSrcAddr = vSrcAddrBase;
        uint8_t *vDestAddr = vDestAddrBase;
        // Every other pixel row has a U/V data row. Hence only go half the height.
        for (int32_t offsetY = 0; offsetY < (height >> 1); ++offsetY) {
            memcpy(vDestAddr, vSrcAddr, numberOfVBytesPerRow);

            vSrcAddr += vSrcOffsetIncrement;
            vDestAddr += vDestOffsetIncrement;
        }
    }
}

void YUVImage::fastCopyRectangle420SemiPlanar(
        const Rect& srcRect,
        int32_t destStartX, int32_t destStartY,
        const YUVImage &srcImage, YUVImage &destImage) {
    CHECK(srcImage.mYUVFormat == YUV420SemiPlanar);
    CHECK(destImage.mYUVFormat == YUV420SemiPlanar);

    int32_t srcStartX = srcRect.left;
    int32_t srcStartY = srcRect.top;
    int32_t width = srcRect.width();
    int32_t height = srcRect.height();

    // Get source and destination start addresses
    uint8_t *ySrcAddrBase;
    uint8_t *uSrcAddrBase;
    uint8_t *vSrcAddrBase;
    srcImage.getYUVAddresses(srcStartX, srcStartY,
            &ySrcAddrBase, &uSrcAddrBase, &vSrcAddrBase);

    uint8_t *yDestAddrBase;
    uint8_t *uDestAddrBase;
    uint8_t *vDestAddrBase;
    destImage.getYUVAddresses(destStartX, destStartY,
            &yDestAddrBase, &uDestAddrBase, &vDestAddrBase);

    // Get source and destination offset increments incurred in going
    // from one data row to next.
    int32_t ySrcOffsetIncrement;
    int32_t uSrcOffsetIncrement;
    int32_t vSrcOffsetIncrement;
    srcImage.getOffsetIncrementsPerDataRow(
            &ySrcOffsetIncrement, &uSrcOffsetIncrement, &vSrcOffsetIncrement);

    int32_t yDestOffsetIncrement;
    int32_t uDestOffsetIncrement;
    int32_t vDestOffsetIncrement;
    destImage.getOffsetIncrementsPerDataRow(
            &yDestOffsetIncrement, &uDestOffsetIncrement, &vDestOffsetIncrement);

    // Copy Y
    {
        size_t numberOfYBytesPerRow = (size_t) width;
        uint8_t *ySrcAddr = ySrcAddrBase;
        uint8_t *yDestAddr = yDestAddrBase;
        for (int32_t offsetY = 0; offsetY < height; ++offsetY) {
            memcpy(yDestAddr, ySrcAddr, numberOfYBytesPerRow);

            ySrcAddr = ySrcAddr + ySrcOffsetIncrement;
            yDestAddr = yDestAddr + yDestOffsetIncrement;
        }
    }

    // Copy UV
    {
        // UV are interleaved. So number of UV bytes per row is 2*(width/2).
        size_t numberOfUVBytesPerRow = (size_t) width;
        uint8_t *vSrcAddr = vSrcAddrBase;
        uint8_t *vDestAddr = vDestAddrBase;
        // Every other pixel row has a U/V data row. Hence only go half the height.
        for (int32_t offsetY = 0; offsetY < (height >> 1); ++offsetY) {
            memcpy(vDestAddr, vSrcAddr, numberOfUVBytesPerRow);

            vSrcAddr += vSrcOffsetIncrement;
            vDestAddr += vDestOffsetIncrement;
        }
    }
}

// static
bool YUVImage::fastCopyRectangle(
        const Rect& srcRect,
        int32_t destStartX, int32_t destStartY,
        const YUVImage &srcImage, YUVImage &destImage) {
    if (srcImage.mYUVFormat == destImage.mYUVFormat) {
        if (srcImage.mYUVFormat == YUV420Planar) {
            fastCopyRectangle420Planar(
                    srcRect,
                    destStartX, destStartY,
                    srcImage, destImage);
        } else if (srcImage.mYUVFormat == YUV420SemiPlanar) {
            fastCopyRectangle420SemiPlanar(
                    srcRect,
                    destStartX, destStartY,
                    srcImage, destImage);
        }
        return true;
    }
    return false;
}

uint8_t clamp(uint8_t v, uint8_t minValue, uint8_t maxValue) {
    CHECK(maxValue >= minValue);

    if (v < minValue) return minValue;
    else if (v > maxValue) return maxValue;
    else return v;
}

void YUVImage::yuv2rgb(uint8_t yValue, uint8_t uValue, uint8_t vValue,
        uint8_t *r, uint8_t *g, uint8_t *b) const {
    *r = yValue + (1.370705 * (vValue-128));
    *g = yValue - (0.698001 * (vValue-128)) - (0.337633 * (uValue-128));
    *b = yValue + (1.732446 * (uValue-128));

    *r = clamp(*r, 0, 255);
    *g = clamp(*g, 0, 255);
    *b = clamp(*b, 0, 255);
}

bool YUVImage::writeToPPM(const char *filename) const {
    FILE *fp = fopen(filename, "w");
    if (fp == NULL) {
        return false;
    }
    fprintf(fp, "P3\n");
    fprintf(fp, "%d %d\n", mWidth, mHeight);
    fprintf(fp, "255\n");
    for (int32_t y = 0; y < mHeight; ++y) {
        for (int32_t x = 0; x < mWidth; ++x) {
            uint8_t yValue;
            uint8_t uValue;
            uint8_t vValue;
            getPixelValue(x, y, &yValue, &uValue, & vValue);

            uint8_t rValue;
            uint8_t gValue;
            uint8_t bValue;
            yuv2rgb(yValue, uValue, vValue, &rValue, &gValue, &bValue);

            fprintf(fp, "%d %d %d\n", (int32_t)rValue, (int32_t)gValue, (int32_t)bValue);
        }
    }
    fclose(fp);
    return true;
}

}  // namespace android
