/*
 * Copyright 2008, The Android Open Source Project
 * Copyright 2013, Samsung Electronics Co. LTD
 *
 * 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.
 */

/*!
 * \file      Exif.cpp
 * \brief     source file for Android Camera Ext HAL
 * \author    teahyung kim (tkon.kim@samsung.com)
 * \date      2013/04/30
 *
 */

#define LOG_TAG "Exif"

#include <cutils/compiler.h>
#include <utils/Log.h>
#include <fcntl.h>

#include <camera/Camera.h>

#include "Exif.h"

namespace android {
#define CLEAR(x)    memset(&(x), 0, sizeof(x))

const char Exif::DEFAULT_MAKER[] = "SAMSUNG";
const char Exif::DEFAULT_MODEL[] = "Exynos";
const char Exif::DEFAULT_SOFTWARE[] = "Exif Software Version 1.0.2.0";
const char Exif::DEFAULT_EXIF_VERSION[] = "0220";
const char Exif::DEFAULT_USERCOMMENTS[] = "User comments";

const int Exif::DEFAULT_YCBCR_POSITIONING = 1;

const int Exif::DEFAULT_EXPOSURE_PROGRAM = 2;

const int Exif::DEFAULT_FLASH = 0;
const int Exif::DEFAULT_COLOR_SPACE = 1;
const int Exif::DEFAULT_EXPOSURE_MODE = EXIF_EXPOSURE_AUTO;
const int Exif::DEFAULT_APEX_DEN = 100;
const int Exif::DEFAULT_SENSING_METHOD = 2;

const int Exif::DEFAULT_COMPRESSION = 6;
const int Exif::DEFAULT_RESOLUTION_NUM = 72;
const int Exif::DEFAULT_RESOLUTION_DEN = 1;
const int Exif::DEFAULT_RESOLUTION_UNIT = 2;

const int Exif::DEFAULT_CONTINUOUS_SHOT_INFO = 0;
Exif::Exif(int cameraId, int CameraType)
{
    mCameraId = cameraId;
    mCameraType = CameraType;

    mNum0thIfdTiff = 10;

    if (cameraId == CAMERA_FACING_BACK) {
        if (mCameraType == CAMERA_TYPE_SOC)
            mNum0thIfdExif = 23;
        else
            mNum0thIfdExif = 27;
    } else {
        mNum0thIfdExif = 14;
    }

    mNum0thIfdGps = 10;
    mNum1thIfdTiff = 9;
}

Exif::~Exif()
{
}

uint32_t Exif::make(void *exifOutBuf,
            exif_attribute_t *exifInfo,
            unsigned int exifOutBufSize,
            unsigned char *thumbBuf,
            unsigned int thumbSize)
{
    ALOGV("makeExif E");

    unsigned char *pCur, *pApp1Start, *pIfdStart, *pGpsIfdPtr, *pNextIfdOffset;
    unsigned int tmp, LongerTagOffest = 0;
    pApp1Start = pCur = (unsigned char *)exifOutBuf;

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

    const char asciiPrefix[] = {0x41, 0x53, 0x43, 0x49, 0x49, 0x0, 0x0, 0x0};
    unsigned char tmpBuf[256] = {0, };
    size_t len;

    /* 0th IFD TIFF Tags */
    if (exifInfo->enableGps)
        tmp = mNum0thIfdTiff;
    else
        tmp = mNum0thIfdTiff - 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);

    if (CAMERA_TYPE_ISP == mCameraType) {
        writeExifIfd(&pCur, EXIF_TAG_SOFTWARE, EXIF_TYPE_ASCII,
            strlen((char *)exifInfo->software) + 1, exifInfo->software, &LongerTagOffest, pIfdStart);
    } else {
        writeExifIfd(&pCur, EXIF_TAG_SOFTWARE, EXIF_TYPE_ASCII,
            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;
        /* Skip a ifd size for gps IFD pointer */
        pCur += IFD_SIZE;
    }

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

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

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

    LongerTagOffest += NUM_SIZE + mNum0thIfdExif*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);

    if (mCameraId == CAMERA_FACING_BACK) {
        if (CAMERA_TYPE_ISP == mCameraType) {
            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_DIGITAL_ZOOM_RATIO, EXIF_TYPE_RATIONAL,
                     1, &exifInfo->digital_zoom_ratio, &LongerTagOffest, pIfdStart);
        writeExifIfd(&pCur, EXIF_TAG_METERING_MODE, EXIF_TYPE_SHORT,
                     1, exifInfo->metering_mode);
        writeExifIfd(&pCur, EXIF_TAG_LIGHT_SOURCE, EXIF_TYPE_SHORT,
                     1, exifInfo->light_source);
        writeExifIfd(&pCur, EXIF_TAG_FLASH, EXIF_TYPE_SHORT,
                     1, exifInfo->flash);
		writeExifIfd(&pCur, EXIF_TAG_FOCAL_35mm_LENGTH, EXIF_TYPE_SHORT,
				1, exifInfo->focal_35mm_length);
    }

    writeExifIfd(&pCur, EXIF_TAG_FOCAL_LENGTH, EXIF_TYPE_RATIONAL,
                 1, &exifInfo->focal_length, &LongerTagOffest, pIfdStart);
    CLEAR(tmpBuf);
    len = strlen((char *)exifInfo->user_comment) + 1;
    memcpy(tmpBuf, asciiPrefix, sizeof(asciiPrefix));
    memcpy(tmpBuf + sizeof(asciiPrefix), exifInfo->user_comment, len);
    writeExifIfd(&pCur, EXIF_TAG_USER_COMMENT, EXIF_TYPE_UNDEFINED,
                 len + sizeof(asciiPrefix), tmpBuf, &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);
    if (mCameraId == CAMERA_FACING_BACK) {
        writeExifIfd(&pCur, EXIF_TAG_SCENCE_CAPTURE_TYPE, EXIF_TYPE_LONG,
                     1, exifInfo->scene_capture_type);
        writeExifIfd(&pCur, EXIF_TAG_IMAGE_UNIQUE_ID, EXIF_TYPE_ASCII,
                     12, exifInfo->unique_id, &LongerTagOffest, pIfdStart);
		writeExifIfd(&pCur, EXIF_TAG_SENSING_METHOD, EXIF_TYPE_SHORT,
				1, exifInfo->sensing_method);
    }

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

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

        pCur = pIfdStart + LongerTagOffest;

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

        LongerTagOffest += NUM_SIZE + mNum0thIfdGps * 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);
        CLEAR(tmpBuf);
        len = strlen((char *)exifInfo->gps_processing_method);
        memcpy(tmpBuf, asciiPrefix, sizeof(asciiPrefix));
        memcpy(tmpBuf + sizeof(asciiPrefix), exifInfo->gps_processing_method, len);
        writeExifIfd(&pCur, EXIF_TAG_GPS_PROCESSING_METHOD, EXIF_TYPE_UNDEFINED,
                     len + sizeof(asciiPrefix), tmpBuf, &LongerTagOffest, pIfdStart);
        writeExifIfd(&pCur, EXIF_TAG_GPS_DATESTAMP, EXIF_TYPE_ASCII,
                     11, exifInfo->gps_datestamp, &LongerTagOffest, pIfdStart);
        tmp = 0;
        /* next IFD offset */
        memcpy(pCur, &tmp, OFFSET_SIZE);
        pCur += OFFSET_SIZE;
    }

    /* 1th IFD TIFF Tags */
    if ((thumbBuf != NULL) && (thumbSize > 0)) {
        if (CC_UNLIKELY(!exifOutBufSize)) {
            ALOGE("makeExif: error, exifOutBufSize is zero");
            return 0;
        }

        tmp = LongerTagOffest;
        /* NEXT IFD offset skipped on 0th IFD */
        memcpy(pNextIfdOffset, &tmp, OFFSET_SIZE);

        pCur = pIfdStart + LongerTagOffest;

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

        LongerTagOffest += NUM_SIZE + mNum1thIfdTiff * 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;
        /* next IFD offset */
        memcpy(pCur, &tmp, OFFSET_SIZE);
        pCur += OFFSET_SIZE;

        if (CC_UNLIKELY(pIfdStart + LongerTagOffest + thumbSize >= (void *)((uint32_t)exifOutBuf + exifOutBufSize))) {
            ALOGE("makeExif: error, thumbnail size(%d bytes) is too big ", thumbSize);
            return 0;
        }

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

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

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

    ALOGV("makeExif X: size %d byte", size);
    return size;
}

inline void Exif::writeExifIfd(unsigned char **pCur,
                                 unsigned short tag,
                                 unsigned short type,
                                 unsigned int count,
                                 uint32_t 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 Exif::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 Exif::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 Exif::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;
}

};

