/*
 * Copyright Samsung Electronics Co.,LTD.
 * 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.
 */

#include <utils/Log.h>

#include "ExynosJpegEncoderForCamera.h"

static const char ExifAsciiPrefix[] = { 0x41, 0x53, 0x43, 0x49, 0x49, 0x0, 0x0, 0x0 };

#define JPEG_ERROR_LOG ALOGE
#define LOG_TAG "ExynosJpegForCamera"

#define JPEG_THUMBNAIL_QUALITY (60)
#define EXIF_LIMIT_SIZE (64*1024)
#define THUMBNAIL_IMAGE_PIXEL_SIZE (4)
#define MAX_JPG_WIDTH (8192)
#define MAX_JPG_HEIGHT (8192)

#define MAX_INPUT_BUFFER_PLANE_NUM (1)
#define MAX_OUTPUT_BUFFER_PLANE_NUM (1)

ExynosJpegEncoderForCamera::ExynosJpegEncoderForCamera()
{
    m_flagCreate = false;
    m_jpegMain = NULL;
    m_jpegThumb = NULL;
    m_thumbnailW = 0;
    m_thumbnailH = 0;
    m_thumbnailQuality = JPEG_THUMBNAIL_QUALITY;
    m_ionJpegClient = 0;
    initJpegMemory(&m_stThumbInBuf, MAX_IMAGE_PLANE_NUM);
    initJpegMemory(&m_stThumbOutBuf, MAX_IMAGE_PLANE_NUM);
    initJpegMemory(&m_stMainInBuf, MAX_IMAGE_PLANE_NUM);
    initJpegMemory(&m_stMainOutBuf, MAX_IMAGE_PLANE_NUM);
}

ExynosJpegEncoderForCamera::~ExynosJpegEncoderForCamera()
{
    if (m_flagCreate == true) {
        this->destroy();
    }
}

bool ExynosJpegEncoderForCamera::flagCreate(void)
{
    return m_flagCreate;
}

int ExynosJpegEncoderForCamera::create(void)
{
    int ret = ERROR_NONE;
    if (m_flagCreate == true) {
        return ERROR_ALREADY_CREATE;
    }

    if (m_jpegMain == NULL) {
        m_jpegMain = new ExynosJpegEncoder;

        if (m_jpegMain == NULL) {
            JPEG_ERROR_LOG("ERR(%s):Cannot create ExynosJpegEncoder class\n", __func__);
            return ERROR_CANNOT_CREATE_EXYNOS_JPEG_ENC_HAL;
        }

        ret = m_jpegMain->create();
        if (ret) {
            return ret;
        }

        ret = m_jpegMain->setCache(JPEG_CACHE_ON);

        if (ret) {
            m_jpegMain->destroy();
            return ret;
        }
    }

    m_ionJpegClient = createIonClient(m_ionJpegClient);
    if(m_ionJpegClient == 0) {
        return ERROR_CANNOT_CREATE_EXYNOS_JPEG_ENC_HAL;
    }
    m_stMainOutBuf.ionClient = m_stMainInBuf.ionClient = m_stThumbInBuf.ionClient = m_stThumbOutBuf.ionClient = m_ionJpegClient;

    m_flagCreate = true;

    return ERROR_NONE;
}

int ExynosJpegEncoderForCamera::destroy(void)
{
    if (m_flagCreate == false) {
        return ERROR_ALREADY_DESTROY;
    }

    if (m_jpegMain != NULL) {
        m_jpegMain->destroy();
        delete m_jpegMain;
        m_jpegMain = NULL;
    }

    if (m_jpegThumb != NULL) {
        int iSize = sizeof(char)*m_thumbnailW*m_thumbnailH*4;

        freeJpegMemory(&m_stThumbInBuf, MAX_IMAGE_PLANE_NUM);
        freeJpegMemory(&m_stThumbOutBuf, MAX_IMAGE_PLANE_NUM);
        initJpegMemory(&m_stMainInBuf, MAX_IMAGE_PLANE_NUM);
        initJpegMemory(&m_stMainOutBuf, MAX_IMAGE_PLANE_NUM);
        m_ionJpegClient = deleteIonClient(m_ionJpegClient);
        m_stMainOutBuf.ionClient = m_stMainInBuf.ionClient = m_stThumbInBuf.ionClient = m_stThumbOutBuf.ionClient = m_ionJpegClient;
        m_jpegThumb->destroy();
        delete m_jpegThumb;
        m_jpegThumb = NULL;
    }

    m_flagCreate = false;
    m_thumbnailW = 0;
    m_thumbnailH = 0;
    m_thumbnailQuality = JPEG_THUMBNAIL_QUALITY;
    return ERROR_NONE;
}

int ExynosJpegEncoderForCamera::setSize(int w, int h)
{
    if (m_flagCreate == false) {
        return ERROR_NOT_YET_CREATED;
    }

    return m_jpegMain->setSize(w, h);
}


int ExynosJpegEncoderForCamera::setQuality(int quality)
{
    if (m_flagCreate == false) {
        return ERROR_NOT_YET_CREATED;
    }

    return m_jpegMain->setQuality(quality);
}

int ExynosJpegEncoderForCamera::setColorFormat(int colorFormat)
{
    if (m_flagCreate == false) {
        return ERROR_NOT_YET_CREATED;
    }

    return m_jpegMain->setColorFormat(colorFormat);
}

int ExynosJpegEncoderForCamera::setJpegFormat(int jpegFormat)
{
    if (m_flagCreate == false) {
        return ERROR_NOT_YET_CREATED;
    }

    return m_jpegMain->setJpegFormat(jpegFormat);
}

int ExynosJpegEncoderForCamera::updateConfig(void)
{
    if (m_flagCreate == false) {
        return ERROR_NOT_YET_CREATED;
    }

    return m_jpegMain->updateConfig();
}

int  ExynosJpegEncoderForCamera::setInBuf(int *buf, char** vBuf, int *size)
{
    if (m_flagCreate == false) {
        return ERROR_NOT_YET_CREATED;
    }

    if (buf == NULL) {
        return ERROR_BUFFR_IS_NULL;
    }

    if (size == NULL) {
        return ERROR_BUFFR_IS_NULL;
    }

    int ret = ERROR_NONE;

    ret = m_jpegMain->setInBuf(buf, size);
    if (ret) {
        JPEG_ERROR_LOG("%s::Fail to JPEG input buffer!!\n", __func__);
        return ret;
    }
    m_stMainInBuf.ionBuffer[0] = buf[0];
    m_stMainInBuf.iSize[0] = size[0];
    m_stMainInBuf.pcBuf[0] = vBuf[0];

    return ERROR_NONE;
}

int  ExynosJpegEncoderForCamera::setOutBuf(int buf, char* vBuf, int size)
{
    if (m_flagCreate == false) {
        return ERROR_NOT_YET_CREATED;
    }

    if (buf == NULL) {
        return ERROR_BUFFR_IS_NULL;
    }

    if (size<=0) {
        return ERROR_BUFFER_TOO_SMALL;
    }

    int ret = ERROR_NONE;
    ret = m_jpegMain->setOutBuf(buf, size);
    if (ret) {
        JPEG_ERROR_LOG("%s::Fail to JPEG output buffer!!\n", __func__);
        return ret;
    }
    m_stMainOutBuf.ionBuffer[0] = buf;
    m_stMainOutBuf.iSize[0] = size;
    m_stMainOutBuf.pcBuf[0] = vBuf;

    return ERROR_NONE;
}

int ExynosJpegEncoderForCamera::encode(int *size, exif_attribute_t *exifInfo)
{
    int ret = ERROR_NONE;
    unsigned char *exifOut = NULL;

    if (m_flagCreate == false) {
        return ERROR_NOT_YET_CREATED;
    }


    ret = m_jpegMain->encode();
    if (ret) {
        JPEG_ERROR_LOG("encode failed\n");
        return ret;
    }

    int iJpegSize = m_jpegMain->getJpegSize();

    if (iJpegSize<=0) {
        JPEG_ERROR_LOG("%s:: output_size is too small(%d)!!\n", __func__, iJpegSize);
        return ERROR_OUT_BUFFER_SIZE_TOO_SMALL;
    }

    int iOutputSize = m_stMainOutBuf.iSize[0];
    int iJpegBuffer = m_stMainOutBuf.ionBuffer[0];
    char *pcJpegBuffer = m_stMainOutBuf.pcBuf[0];

    if (pcJpegBuffer[0] == NULL) {
        JPEG_ERROR_LOG("%s::pcJpegBuffer[0] is null!!\n", __func__);
        return ERROR_OUT_BUFFER_CREATE_FAIL;
    }

    if (exifInfo != NULL) {
        unsigned int thumbLen, exifLen;

        unsigned int bufSize = 0;
        if (exifInfo->enableThumb) {
            if (encodeThumbnail(&thumbLen)) {
                bufSize = EXIF_FILE_SIZE;
                exifInfo->enableThumb = false;
            } else {
                if (thumbLen > EXIF_LIMIT_SIZE) {
                    bufSize = EXIF_FILE_SIZE;
                    exifInfo->enableThumb = false;
                }
                else {
                    bufSize = EXIF_FILE_SIZE + thumbLen;
                }
            }
        } else {
            bufSize = EXIF_FILE_SIZE;
            exifInfo->enableThumb = false;
        }

        exifOut = new unsigned char[bufSize];
        if (exifOut == NULL) {
            JPEG_ERROR_LOG("%s::Failed to allocate for exifOut\n", __func__);
            delete[] exifOut;
            return ERROR_EXIFOUT_ALLOC_FAIL;
        }
        memset(exifOut, 0, bufSize);

        if (makeExif (exifOut, exifInfo, &exifLen)) {
            JPEG_ERROR_LOG("%s::Failed to make EXIF\n", __func__);
            delete[] exifOut;
            return ERROR_MAKE_EXIF_FAIL;
        }

        if (exifLen <= EXIF_LIMIT_SIZE) {
            memmove(pcJpegBuffer+exifLen+2, pcJpegBuffer+2, iJpegSize - 2);
            memcpy(pcJpegBuffer+2, exifOut, exifLen);
            iJpegSize += exifLen;
        }

        delete[] exifOut;
    }

    *size = iJpegSize;

    return ERROR_NONE;
}

int ExynosJpegEncoderForCamera::makeExif (unsigned char *exifOut,
                              exif_attribute_t *exifInfo,
                              unsigned int *size,
                              bool useMainbufForThumb)
{
    unsigned char *pCur, *pApp1Start, *pIfdStart, *pGpsIfdPtr, *pNextIfdOffset;
    unsigned int tmp, LongerTagOffest = 0, exifSizeExceptThumb;
    pApp1Start = pCur = exifOut;

    //2 Exif Identifier Code & TIFF Header
    pCur += 4;  // Skip 4 Byte for APP1 marker and length
    unsigned char ExifIdentifierCode[6] = { 0x45, 0x78, 0x69, 0x66, 0x00, 0x00 };
    memcpy(pCur, ExifIdentifierCode, 6);
    pCur += 6;

    /* Byte Order - little endian, Offset of IFD - 0x00000008.H */
    unsigned char TiffHeader[8] = { 0x49, 0x49, 0x2A, 0x00, 0x08, 0x00, 0x00, 0x00 };
    memcpy(pCur, TiffHeader, 8);
    pIfdStart = pCur;
    pCur += 8;

    //2 0th IFD TIFF Tags
    if (exifInfo->enableGps)
        tmp = NUM_0TH_IFD_TIFF;
    else
        tmp = NUM_0TH_IFD_TIFF - 1;

    memcpy(pCur, &tmp, NUM_SIZE);
    pCur += NUM_SIZE;

    LongerTagOffest += 8 + NUM_SIZE + tmp*IFD_SIZE + OFFSET_SIZE;

    writeExifIfd(&pCur, EXIF_TAG_IMAGE_WIDTH, EXIF_TYPE_LONG,
                 1, exifInfo->width);
    writeExifIfd(&pCur, EXIF_TAG_IMAGE_HEIGHT, EXIF_TYPE_LONG,
                 1, exifInfo->height);
    writeExifIfd(&pCur, EXIF_TAG_MAKE, EXIF_TYPE_ASCII,
                 strlen((char *)exifInfo->maker) + 1, exifInfo->maker, &LongerTagOffest, pIfdStart);
    writeExifIfd(&pCur, EXIF_TAG_MODEL, EXIF_TYPE_ASCII,
                 strlen((char *)exifInfo->model) + 1, exifInfo->model, &LongerTagOffest, pIfdStart);
    writeExifIfd(&pCur, EXIF_TAG_ORIENTATION, EXIF_TYPE_SHORT,
                 1, exifInfo->orientation);
    writeExifIfd(&pCur, EXIF_TAG_SOFTWARE, EXIF_TYPE_ASCII,
                 strlen((char *)exifInfo->software) + 1, exifInfo->software, &LongerTagOffest, pIfdStart);
    writeExifIfd(&pCur, EXIF_TAG_DATE_TIME, EXIF_TYPE_ASCII,
                 20, exifInfo->date_time, &LongerTagOffest, pIfdStart);
    writeExifIfd(&pCur, EXIF_TAG_YCBCR_POSITIONING, EXIF_TYPE_SHORT,
                 1, exifInfo->ycbcr_positioning);
    writeExifIfd(&pCur, EXIF_TAG_EXIF_IFD_POINTER, EXIF_TYPE_LONG,
                 1, LongerTagOffest);
    if (exifInfo->enableGps) {
        pGpsIfdPtr = pCur;
        pCur += IFD_SIZE;   // Skip a ifd size for gps IFD pointer
    }

    pNextIfdOffset = pCur;  // Skip a offset size for next IFD offset
    pCur += OFFSET_SIZE;

    //2 0th IFD Exif Private Tags
    pCur = pIfdStart + LongerTagOffest;

    tmp = NUM_0TH_IFD_EXIF;
    memcpy(pCur, &tmp , NUM_SIZE);
    pCur += NUM_SIZE;

    LongerTagOffest += NUM_SIZE + NUM_0TH_IFD_EXIF*IFD_SIZE + OFFSET_SIZE;

    writeExifIfd(&pCur, EXIF_TAG_EXPOSURE_TIME, EXIF_TYPE_RATIONAL,
                 1, &exifInfo->exposure_time, &LongerTagOffest, pIfdStart);
    writeExifIfd(&pCur, EXIF_TAG_FNUMBER, EXIF_TYPE_RATIONAL,
                 1, &exifInfo->fnumber, &LongerTagOffest, pIfdStart);
    writeExifIfd(&pCur, EXIF_TAG_EXPOSURE_PROGRAM, EXIF_TYPE_SHORT,
                 1, exifInfo->exposure_program);
    writeExifIfd(&pCur, EXIF_TAG_ISO_SPEED_RATING, EXIF_TYPE_SHORT,
                 1, exifInfo->iso_speed_rating);
    writeExifIfd(&pCur, EXIF_TAG_EXIF_VERSION, EXIF_TYPE_UNDEFINED,
                 4, exifInfo->exif_version);
    writeExifIfd(&pCur, EXIF_TAG_DATE_TIME_ORG, EXIF_TYPE_ASCII,
                 20, exifInfo->date_time, &LongerTagOffest, pIfdStart);
    writeExifIfd(&pCur, EXIF_TAG_DATE_TIME_DIGITIZE, EXIF_TYPE_ASCII,
                 20, exifInfo->date_time, &LongerTagOffest, pIfdStart);
    writeExifIfd(&pCur, EXIF_TAG_SHUTTER_SPEED, EXIF_TYPE_SRATIONAL,
                 1, (rational_t *)&exifInfo->shutter_speed, &LongerTagOffest, pIfdStart);
    writeExifIfd(&pCur, EXIF_TAG_APERTURE, EXIF_TYPE_RATIONAL,
                 1, &exifInfo->aperture, &LongerTagOffest, pIfdStart);
    writeExifIfd(&pCur, EXIF_TAG_BRIGHTNESS, EXIF_TYPE_SRATIONAL,
                 1, (rational_t *)&exifInfo->brightness, &LongerTagOffest, pIfdStart);
    writeExifIfd(&pCur, EXIF_TAG_EXPOSURE_BIAS, EXIF_TYPE_SRATIONAL,
                 1, (rational_t *)&exifInfo->exposure_bias, &LongerTagOffest, pIfdStart);
    writeExifIfd(&pCur, EXIF_TAG_MAX_APERTURE, EXIF_TYPE_RATIONAL,
                 1, &exifInfo->max_aperture, &LongerTagOffest, pIfdStart);
    writeExifIfd(&pCur, EXIF_TAG_METERING_MODE, EXIF_TYPE_SHORT,
                 1, exifInfo->metering_mode);
    writeExifIfd(&pCur, EXIF_TAG_FLASH, EXIF_TYPE_SHORT,
                 1, exifInfo->flash);
    writeExifIfd(&pCur, EXIF_TAG_FOCAL_LENGTH, EXIF_TYPE_RATIONAL,
                 1, &exifInfo->focal_length, &LongerTagOffest, pIfdStart);
    char code[8] = { 0x00, 0x00, 0x00, 0x49, 0x49, 0x43, 0x53, 0x41 };
    int commentsLen = strlen((char *)exifInfo->user_comment) + 1;
    memmove(exifInfo->user_comment + sizeof(code), exifInfo->user_comment, commentsLen);
    memcpy(exifInfo->user_comment, code, sizeof(code));
    writeExifIfd(&pCur, EXIF_TAG_USER_COMMENT, EXIF_TYPE_UNDEFINED,
                 commentsLen + sizeof(code), exifInfo->user_comment, &LongerTagOffest, pIfdStart);
    writeExifIfd(&pCur, EXIF_TAG_COLOR_SPACE, EXIF_TYPE_SHORT,
                 1, exifInfo->color_space);
    writeExifIfd(&pCur, EXIF_TAG_PIXEL_X_DIMENSION, EXIF_TYPE_LONG,
                 1, exifInfo->width);
    writeExifIfd(&pCur, EXIF_TAG_PIXEL_Y_DIMENSION, EXIF_TYPE_LONG,
                 1, exifInfo->height);
    writeExifIfd(&pCur, EXIF_TAG_EXPOSURE_MODE, EXIF_TYPE_LONG,
                 1, exifInfo->exposure_mode);
    writeExifIfd(&pCur, EXIF_TAG_WHITE_BALANCE, EXIF_TYPE_LONG,
                 1, exifInfo->white_balance);
    writeExifIfd(&pCur, EXIF_TAG_SCENCE_CAPTURE_TYPE, EXIF_TYPE_LONG,
                 1, exifInfo->scene_capture_type);
    tmp = 0;
    memcpy(pCur, &tmp, OFFSET_SIZE); // next IFD offset
    pCur += OFFSET_SIZE;

    //2 0th IFD GPS Info Tags
    if (exifInfo->enableGps) {
        writeExifIfd(&pGpsIfdPtr, EXIF_TAG_GPS_IFD_POINTER, EXIF_TYPE_LONG,
                     1, LongerTagOffest); // GPS IFD pointer skipped on 0th IFD

        pCur = pIfdStart + LongerTagOffest;

        if (exifInfo->gps_processing_method[0] == 0) {
            // don't create GPS_PROCESSING_METHOD tag if there isn't any
            tmp = NUM_0TH_IFD_GPS - 1;
        } else {
            tmp = NUM_0TH_IFD_GPS;
        }
        memcpy(pCur, &tmp, NUM_SIZE);
        pCur += NUM_SIZE;

        LongerTagOffest += NUM_SIZE + tmp*IFD_SIZE + OFFSET_SIZE;

        writeExifIfd(&pCur, EXIF_TAG_GPS_VERSION_ID, EXIF_TYPE_BYTE,
                     4, exifInfo->gps_version_id);
        writeExifIfd(&pCur, EXIF_TAG_GPS_LATITUDE_REF, EXIF_TYPE_ASCII,
                     2, exifInfo->gps_latitude_ref);
        writeExifIfd(&pCur, EXIF_TAG_GPS_LATITUDE, EXIF_TYPE_RATIONAL,
                     3, exifInfo->gps_latitude, &LongerTagOffest, pIfdStart);
        writeExifIfd(&pCur, EXIF_TAG_GPS_LONGITUDE_REF, EXIF_TYPE_ASCII,
                     2, exifInfo->gps_longitude_ref);
        writeExifIfd(&pCur, EXIF_TAG_GPS_LONGITUDE, EXIF_TYPE_RATIONAL,
                     3, exifInfo->gps_longitude, &LongerTagOffest, pIfdStart);
        writeExifIfd(&pCur, EXIF_TAG_GPS_ALTITUDE_REF, EXIF_TYPE_BYTE,
                     1, exifInfo->gps_altitude_ref);
        writeExifIfd(&pCur, EXIF_TAG_GPS_ALTITUDE, EXIF_TYPE_RATIONAL,
                     1, &exifInfo->gps_altitude, &LongerTagOffest, pIfdStart);
        writeExifIfd(&pCur, EXIF_TAG_GPS_TIMESTAMP, EXIF_TYPE_RATIONAL,
                     3, exifInfo->gps_timestamp, &LongerTagOffest, pIfdStart);
        tmp = strlen((char*)exifInfo->gps_processing_method);
        if (tmp > 0) {
            if (tmp > 100) {
                tmp = 100;
            }
            unsigned char tmp_buf[100+sizeof(ExifAsciiPrefix)];
            memcpy(tmp_buf, ExifAsciiPrefix, sizeof(ExifAsciiPrefix));
            memcpy(&tmp_buf[sizeof(ExifAsciiPrefix)], exifInfo->gps_processing_method, tmp);
            writeExifIfd(&pCur, EXIF_TAG_GPS_PROCESSING_METHOD, EXIF_TYPE_UNDEFINED,
                         tmp+sizeof(ExifAsciiPrefix), tmp_buf, &LongerTagOffest, pIfdStart);
        }
        writeExifIfd(&pCur, EXIF_TAG_GPS_DATESTAMP, EXIF_TYPE_ASCII,
                     11, exifInfo->gps_datestamp, &LongerTagOffest, pIfdStart);
        tmp = 0;
        memcpy(pCur, &tmp, OFFSET_SIZE); // next IFD offset
        pCur += OFFSET_SIZE;
    }

    //2 1th IFD TIFF Tags
    int iThumbFd = 0;
    char *thumbBuf = NULL;
    unsigned int thumbSize = 0;
    int thumbBufSize = 0;
    int ret = ERROR_NONE;

    if (useMainbufForThumb) {
        if (m_jpegMain) {
            ret = m_jpegMain->getOutBuf((int *)&iThumbFd, (int *)&thumbBufSize);
            if (ret != ERROR_NONE) {
                iThumbFd = -1;
            }
            thumbSize = (unsigned int)m_jpegMain->getJpegSize();
            thumbBuf = m_stMainOutBuf.pcBuf[0];
        }
    } else {
        if (m_jpegThumb) {
            ret = m_jpegThumb->getOutBuf((int *)&iThumbFd, (int *)&thumbBufSize);
            if (ret != ERROR_NONE) {
                iThumbFd = -1;
            }
            thumbSize = (unsigned int)m_jpegThumb->getJpegSize();
            thumbBuf = m_stThumbOutBuf.pcBuf[0];
        }
    }

    if (exifInfo->enableThumb && (thumbBuf != NULL) && (thumbSize != 0)) {
        exifSizeExceptThumb = tmp = LongerTagOffest;
        memcpy(pNextIfdOffset, &tmp, OFFSET_SIZE);  // NEXT IFD offset skipped on 0th IFD

        pCur = pIfdStart + LongerTagOffest;

        tmp = NUM_1TH_IFD_TIFF;
        memcpy(pCur, &tmp, NUM_SIZE);
        pCur += NUM_SIZE;

        LongerTagOffest += NUM_SIZE + NUM_1TH_IFD_TIFF*IFD_SIZE + OFFSET_SIZE;

        writeExifIfd(&pCur, EXIF_TAG_IMAGE_WIDTH, EXIF_TYPE_LONG,
                     1, exifInfo->widthThumb);
        writeExifIfd(&pCur, EXIF_TAG_IMAGE_HEIGHT, EXIF_TYPE_LONG,
                     1, exifInfo->heightThumb);
        writeExifIfd(&pCur, EXIF_TAG_COMPRESSION_SCHEME, EXIF_TYPE_SHORT,
                     1, exifInfo->compression_scheme);
        writeExifIfd(&pCur, EXIF_TAG_ORIENTATION, EXIF_TYPE_SHORT,
                     1, exifInfo->orientation);
        writeExifIfd(&pCur, EXIF_TAG_X_RESOLUTION, EXIF_TYPE_RATIONAL,
                     1, &exifInfo->x_resolution, &LongerTagOffest, pIfdStart);
        writeExifIfd(&pCur, EXIF_TAG_Y_RESOLUTION, EXIF_TYPE_RATIONAL,
                     1, &exifInfo->y_resolution, &LongerTagOffest, pIfdStart);
        writeExifIfd(&pCur, EXIF_TAG_RESOLUTION_UNIT, EXIF_TYPE_SHORT,
                     1, exifInfo->resolution_unit);
        writeExifIfd(&pCur, EXIF_TAG_JPEG_INTERCHANGE_FORMAT, EXIF_TYPE_LONG,
                     1, LongerTagOffest);
        writeExifIfd(&pCur, EXIF_TAG_JPEG_INTERCHANGE_FORMAT_LEN, EXIF_TYPE_LONG,
                     1, thumbSize);

        tmp = 0;
        memcpy(pCur, &tmp, OFFSET_SIZE); // next IFD offset
        pCur += OFFSET_SIZE;

        memcpy(pIfdStart + LongerTagOffest,
               thumbBuf, thumbSize);
        LongerTagOffest += thumbSize;
        if (LongerTagOffest > EXIF_LIMIT_SIZE) {
            LongerTagOffest = exifSizeExceptThumb;
            tmp = 0;
            memcpy(pNextIfdOffset, &tmp, OFFSET_SIZE);  // NEXT IFD offset skipped on 0th IFD
        }
    } else {
        tmp = 0;
        memcpy(pNextIfdOffset, &tmp, OFFSET_SIZE);  // NEXT IFD offset skipped on 0th IFD
    }

    unsigned char App1Marker[2] = { 0xff, 0xe1 };
    memcpy(pApp1Start, App1Marker, 2);
    pApp1Start += 2;

    *size = 10 + LongerTagOffest;
    tmp = *size - 2;    // APP1 Maker isn't counted
    unsigned char size_mm[2] = {(tmp >> 8) & 0xFF, tmp & 0xFF};
    memcpy(pApp1Start, size_mm, 2);

    return ERROR_NONE;
}

/*
 * private member functions
*/
inline void ExynosJpegEncoderForCamera::writeExifIfd(unsigned char **pCur,
                                             unsigned short tag,
                                             unsigned short type,
                                             unsigned int count,
                                             unsigned int value)
{
    memcpy(*pCur, &tag, 2);
    *pCur += 2;
    memcpy(*pCur, &type, 2);
    *pCur += 2;
    memcpy(*pCur, &count, 4);
    *pCur += 4;
    memcpy(*pCur, &value, 4);
    *pCur += 4;
}

inline void ExynosJpegEncoderForCamera::writeExifIfd(unsigned char **pCur,
                                             unsigned short tag,
                                             unsigned short type,
                                             unsigned int count,
                                             unsigned char *pValue)
{
    char buf[4] = { 0,};

    memcpy(buf, pValue, count);
    memcpy(*pCur, &tag, 2);
    *pCur += 2;
    memcpy(*pCur, &type, 2);
    *pCur += 2;
    memcpy(*pCur, &count, 4);
    *pCur += 4;
    memcpy(*pCur, buf, 4);
    *pCur += 4;
}

inline void ExynosJpegEncoderForCamera::writeExifIfd(unsigned char **pCur,
                                             unsigned short tag,
                                             unsigned short type,
                                             unsigned int count,
                                             unsigned char *pValue,
                                             unsigned int *offset,
                                             unsigned char *start)
{
    memcpy(*pCur, &tag, 2);
    *pCur += 2;
    memcpy(*pCur, &type, 2);
    *pCur += 2;
    memcpy(*pCur, &count, 4);
    *pCur += 4;
    memcpy(*pCur, offset, 4);
    *pCur += 4;
    memcpy(start + *offset, pValue, count);
    *offset += count;
}

inline void ExynosJpegEncoderForCamera::writeExifIfd(unsigned char **pCur,
                                             unsigned short tag,
                                             unsigned short type,
                                             unsigned int count,
                                             rational_t *pValue,
                                             unsigned int *offset,
                                             unsigned char *start)
{
    memcpy(*pCur, &tag, 2);
    *pCur += 2;
    memcpy(*pCur, &type, 2);
    *pCur += 2;
    memcpy(*pCur, &count, 4);
    *pCur += 4;
    memcpy(*pCur, offset, 4);
    *pCur += 4;
    memcpy(start + *offset, pValue, 8 * count);
    *offset += 8 * count;
}

int ExynosJpegEncoderForCamera::scaleDownYuv422(char **srcBuf, unsigned int srcW, unsigned int srcH,  char **dstBuf, unsigned int dstW, unsigned int dstH)
{
    int step_x, step_y;
    int src_y_start_pos, dst_pos, src_pos;
    char *src_buf = srcBuf[0];
    char *dst_buf = dstBuf[0];

    if (dstW & 0x01 || dstH & 0x01) {
        return ERROR_INVALID_SCALING_WIDTH_HEIGHT;
    }

    step_x = srcW / dstW;
    step_y = srcH / dstH;

    unsigned int srcWStride = srcW * 2;
    unsigned int stepXStride = step_x * 2;

    dst_pos = 0;
    for (unsigned int y = 0; y < dstH; y++) {
        src_y_start_pos = srcWStride * step_y * y;

        for (unsigned int x = 0; x < dstW; x += 2) {
            src_pos = src_y_start_pos + (stepXStride * x);

            dst_buf[dst_pos++] = src_buf[src_pos    ];
            dst_buf[dst_pos++] = src_buf[src_pos + 1];
            dst_buf[dst_pos++] = src_buf[src_pos + 2];
            dst_buf[dst_pos++] = src_buf[src_pos + 3];
        }
    }

    return ERROR_NONE;
}

int ExynosJpegEncoderForCamera::scaleDownYuv422_2p(char **srcBuf, unsigned int srcW, unsigned int srcH, char **dstBuf, unsigned int dstW, unsigned int dstH)
{
    int32_t step_x, step_y;
    int32_t src_y_start_pos, dst_pos, src_pos;
    int32_t src_Y_offset;
    char *src_buf;
    char *dst_buf;

    if (dstW % 2 != 0 || dstH % 2 != 0) {
        return ERROR_INVALID_SCALING_WIDTH_HEIGHT;
    }

    step_x = srcW / dstW;
    step_y = srcH / dstH;

    // Y scale down
    src_buf = srcBuf[0];
    dst_buf = dstBuf[0];
    dst_pos = 0;
    for (uint32_t y = 0; y < dstH; y++) {
        src_y_start_pos = y * step_y * srcW;

        for (uint32_t x = 0; x < dstW; x++) {
            src_pos = src_y_start_pos + (x * step_x);

            dst_buf[dst_pos++] = src_buf[src_pos];
        }
    }

    // UV scale down
    for (uint32_t i = 0; i < dstH; i++) {
        src_y_start_pos = i * step_y * srcW + (srcW*srcH);

        for (uint32_t j = 0; j < dstW; j += 2) {
            src_pos = src_y_start_pos + (j * step_x);

            dst_buf[dst_pos++] = src_buf[src_pos    ];
            dst_buf[dst_pos++] = src_buf[src_pos + 1];
        }
    }

    return ERROR_NONE;
}

// thumbnail
int ExynosJpegEncoderForCamera::setThumbnailSize(int w, int h)
{
    if (m_flagCreate == false) {
        return ERROR_CANNOT_CREATE_EXYNOS_JPEG_ENC_HAL;
    }

    if (w < 0 || MAX_JPG_WIDTH < w) {
        return false;
    }

    if (h < 0 || MAX_JPG_HEIGHT < h) {
        return false;
    }

    m_thumbnailW = w;
    m_thumbnailH = h;
    return ERROR_NONE;
}

int ExynosJpegEncoderForCamera::setThumbnailQuality(int quality)
{
    if (m_flagCreate == false) {
        return ERROR_CANNOT_CREATE_EXYNOS_JPEG_ENC_HAL;
    }

    if (quality < 1 || 100 < quality) {
        return false;
    }

    m_thumbnailQuality = quality;
    return ERROR_NONE;
}

int ExynosJpegEncoderForCamera::encodeThumbnail(unsigned int *size, bool useMain)
{
    int ret = ERROR_NONE;

    if (m_flagCreate == false) {
        return ERROR_CANNOT_CREATE_EXYNOS_JPEG_ENC_HAL;
    }

    // create jpeg thumbnail class
    if (m_jpegThumb == NULL) {
        m_jpegThumb = new ExynosJpegEncoder;

        if (m_jpegThumb == NULL) {
            JPEG_ERROR_LOG("ERR(%s):Cannot open a jpeg device file\n", __func__);
            return ERROR_CANNOT_CREATE_SEC_THUMB;
        }
    }

    ret = m_jpegThumb->create();
    if (ret) {
        JPEG_ERROR_LOG("ERR(%s):Fail create\n", __func__);
        return ret;
    }

        ret = m_jpegThumb->setCache(JPEG_CACHE_ON);
    if (ret) {
        JPEG_ERROR_LOG("ERR(%s):Fail cache set\n", __func__);
        return ret;
    }

    void *pConfig = m_jpegMain->getJpegConfig();
    if (pConfig == NULL) {
        JPEG_ERROR_LOG("ERR(%s):Fail getJpegConfig\n", __func__);
        return ERROR_BUFFR_IS_NULL;
    }

    ret = m_jpegThumb->setJpegConfig(pConfig);
    if (ret) {
        JPEG_ERROR_LOG("ERR(%s):Fail setJpegConfig\n", __func__);
        return ret;
    }

    /* TODO: Currently we fix the thumbnail quality */
    ret = m_jpegThumb->setQuality(JPEG_THUMBNAIL_QUALITY);
    if (ret) {
        JPEG_ERROR_LOG("ERR(%s):Fail setQuality\n", __func__);
        return ret;
    }

    ret = m_jpegThumb->setSize(m_thumbnailW, m_thumbnailH);
    if (ret) {
        JPEG_ERROR_LOG("ERR(%s):Fail setSize\n", __func__);
        return ret;
    }

    freeJpegMemory(&m_stThumbInBuf, MAX_IMAGE_PLANE_NUM);
    freeJpegMemory(&m_stThumbOutBuf, MAX_IMAGE_PLANE_NUM);

    if (m_jpegThumb->setColorBufSize(m_stThumbInBuf.iSize, MAX_IMAGE_PLANE_NUM) != ERROR_NONE) {
        return ERROR_INVALID_COLOR_FORMAT;
    }
    m_stThumbOutBuf.iSize[0] = sizeof(char)*m_thumbnailW*m_thumbnailH*THUMBNAIL_IMAGE_PIXEL_SIZE;


    if (allocJpegMemory(&m_stThumbInBuf, MAX_IMAGE_PLANE_NUM) != ERROR_NONE) {
        return ERROR_MEM_ALLOC_FAIL;
    }

    if (allocJpegMemory(&m_stThumbOutBuf, MAX_IMAGE_PLANE_NUM) != ERROR_NONE) {
        return ERROR_MEM_ALLOC_FAIL;
    }

    ret = m_jpegThumb->setInBuf(m_stThumbInBuf.ionBuffer, m_stThumbInBuf.iSize);
    if (ret) {
        JPEG_ERROR_LOG("ERR(%s):Fail setInBuf\n", __func__);
        return ret;
    }

    ret = m_jpegThumb->setOutBuf(m_stThumbOutBuf.ionBuffer[0], m_stThumbOutBuf.iSize[0]);
    if (ret) {
        JPEG_ERROR_LOG("ERR(%s):Fail setOutBuf\n", __func__);
        return ret;
    }

    ret = m_jpegThumb->updateConfig();
    if (ret) {
        JPEG_ERROR_LOG("update config failed\n");
        return ret;
    }

    if (useMain) {
        int iTempWidth=0;
        int iTempHeight=0;
        int iTempColorformat = 0;

        iTempColorformat = m_jpegMain->getColorFormat();

        ret = m_jpegMain->getSize(&iTempWidth, &iTempHeight);
        if (ret) {
            JPEG_ERROR_LOG("ERR(%s):Fail getSize\n", __func__);
            return ret;
        }

        switch (iTempColorformat) {
        case V4L2_PIX_FMT_YUYV:
            ret = scaleDownYuv422(m_stMainInBuf.pcBuf,
                              iTempWidth,
                              iTempHeight,
                              m_stThumbInBuf.pcBuf,
                              m_thumbnailW,
                              m_thumbnailH);
            break;
        case V4L2_PIX_FMT_NV16:
            ret = scaleDownYuv422_2p(m_stMainInBuf.pcBuf,
                              iTempWidth,
                              iTempHeight,
                              m_stThumbInBuf.pcBuf,
                              m_thumbnailW,
                              m_thumbnailH);
            break;
        default:
            return ERROR_INVALID_COLOR_FORMAT;
            break;
        }

        if (ret) {
            JPEG_ERROR_LOG("%s::scaleDown(%d, %d, %d, %d) fail", __func__, iTempWidth, iTempHeight, m_thumbnailW, m_thumbnailH);
            return ret;
        }
    }
    else {
        return ERROR_IMPLEMENT_NOT_YET;
    }

    int iOutSizeThumb;

    ret = m_jpegThumb->encode();
    if (ret) {
        JPEG_ERROR_LOG("encode failed\n");
        return ret;
    }

    iOutSizeThumb = m_jpegThumb->getJpegSize();
    if (iOutSizeThumb<=0) {
        JPEG_ERROR_LOG("jpeg size is too small\n");
        return ERROR_THUMB_JPEG_SIZE_TOO_SMALL;
    }

    *size = (unsigned int)iOutSizeThumb;

    return ERROR_NONE;

}

int ExynosJpegEncoderForCamera::createIonClient(ion_client ionClient)
{
    if (ionClient == 0) {
        ionClient = ion_client_create();
        if (ionClient < 0) {
            JPEG_ERROR_LOG("[%s]src ion client create failed, value = %d\n", __func__, ionClient);
            return 0;
        }
    }

    return ionClient;
}

int ExynosJpegEncoderForCamera::deleteIonClient(ion_client ionClient)
{
    if (ionClient != 0) {
        if (ionClient > 0) {
            ion_client_destroy(ionClient);
        }
        ionClient = 0;
    }

    return ionClient;
}

int ExynosJpegEncoderForCamera::allocJpegMemory(struct stJpegMem *pstMem, int iMemoryNum)
{
    int ret = ERROR_NONE;
    int i = 0;

    if (pstMem->ionClient == 0) {
        JPEG_ERROR_LOG("[%s] i = %d , ionClient is zero (%d)\n", __func__, i, pstMem->ionClient);
        return ERROR_BUFFR_IS_NULL;
    }

    for (i=0;i<iMemoryNum;i++) {
        if (pstMem->iSize[i] == 0) {
            break;
        }

        pstMem->ionBuffer[i] = ion_alloc(pstMem->ionClient, \
                                                        pstMem->iSize[i], 0, ION_HEAP_SYSTEM_MASK, 0);
        if ((pstMem->ionBuffer[i] == -1) ||(pstMem->ionBuffer[i] == 0)) {
            JPEG_ERROR_LOG("[%s]ion_alloc(%d) failed\n", __func__, pstMem->iSize[i]);
            pstMem->ionBuffer[i] = -1;
            freeJpegMemory(pstMem, iMemoryNum);
            return ERROR_MEM_ALLOC_FAIL;
        }

        pstMem->pcBuf[i] = (char *)ion_map(pstMem->ionBuffer[i], \
                                                            pstMem->iSize[i], 0);
        if ((pstMem->pcBuf[i] == (char *)MAP_FAILED) || (pstMem->pcBuf[i] == NULL)) {
            JPEG_ERROR_LOG("[%s]src ion map failed(%d)\n", __func__, pstMem->iSize[i]);
            pstMem->pcBuf[i] = (char *)MAP_FAILED;
            freeJpegMemory(pstMem, iMemoryNum);
            return ERROR_MEM_ALLOC_FAIL;
        }
    }

    return ERROR_NONE;
}

void ExynosJpegEncoderForCamera::freeJpegMemory(struct stJpegMem *pstMem, int iMemoryNum)
{
    int i =0 ;
    if (pstMem->ionClient == 0) {
        return;
    }


    for (i=0;i<iMemoryNum;i++) {
        if (pstMem->ionBuffer[i] != -1) {
            if (pstMem->pcBuf[i] != (char *)MAP_FAILED) {
                ion_unmap(pstMem->pcBuf[i], pstMem->iSize[i]);
            }
            ion_free(pstMem->ionBuffer[i]);
        }
        pstMem->ionBuffer[i] = -1;
        pstMem->pcBuf[i] = (char *)MAP_FAILED;
        pstMem->iSize[i] = 0;
    }
}

void ExynosJpegEncoderForCamera::initJpegMemory(struct stJpegMem *pstMem, int iMemoryNum)
{
    int i =0 ;
    for (i=0;i<iMemoryNum;i++) {
        pstMem->pcBuf[i] = (char *)MAP_FAILED;
        pstMem->ionBuffer[i] = -1;
        pstMem->iSize[i] = 0;
    }
    pstMem->ionClient = 0;
}

