/*
 * Copyright (C) Texas Instruments - http://www.ti.com/
 *
 * 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 Encoder_libjpeg.cpp
*
* This file encodes a YUV422I buffer to a jpeg
* TODO(XXX): Need to support formats other than yuv422i
*            Change interface to pre/post-proc algo framework
*
*/

#define LOG_TAG "CameraHAL"

#include "CameraHal.h"
#include "Encoder_libjpeg.h"
#include "NV12_resize.h"

#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <errno.h>
#include <math.h>

extern "C" {
    #include "jpeglib.h"
    #include "jerror.h"
}

#define ARRAY_SIZE(array) (sizeof((array)) / sizeof((array)[0]))
#define MIN(x,y) ((x < y) ? x : y)

namespace android {
struct string_pair {
    const char* string1;
    const char* string2;
};

static string_pair degress_to_exif_lut [] = {
    // degrees, exif_orientation
    {"0",   "1"},
    {"90",  "6"},
    {"180", "3"},
    {"270", "8"},
};
struct libjpeg_destination_mgr : jpeg_destination_mgr {
    libjpeg_destination_mgr(uint8_t* input, int size);

    uint8_t* buf;
    int bufsize;
    size_t jpegsize;
};

static void libjpeg_init_destination (j_compress_ptr cinfo) {
    libjpeg_destination_mgr* dest = (libjpeg_destination_mgr*)cinfo->dest;

    dest->next_output_byte = dest->buf;
    dest->free_in_buffer = dest->bufsize;
    dest->jpegsize = 0;
}

static boolean libjpeg_empty_output_buffer(j_compress_ptr cinfo) {
    libjpeg_destination_mgr* dest = (libjpeg_destination_mgr*)cinfo->dest;

    dest->next_output_byte = dest->buf;
    dest->free_in_buffer = dest->bufsize;
    return TRUE; // ?
}

static void libjpeg_term_destination (j_compress_ptr cinfo) {
    libjpeg_destination_mgr* dest = (libjpeg_destination_mgr*)cinfo->dest;
    dest->jpegsize = dest->bufsize - dest->free_in_buffer;
}

libjpeg_destination_mgr::libjpeg_destination_mgr(uint8_t* input, int size) {
    this->init_destination = libjpeg_init_destination;
    this->empty_output_buffer = libjpeg_empty_output_buffer;
    this->term_destination = libjpeg_term_destination;

    this->buf = input;
    this->bufsize = size;

    jpegsize = 0;
}

/* private static functions */
static void nv21_to_yuv(uint8_t* dst, uint8_t* y, uint8_t* uv, int width) {
    if (!dst || !y || !uv) {
        return;
    }

    while ((width--) > 0) {
        uint8_t y0 = y[0];
        uint8_t v0 = uv[0];
        uint8_t u0 = *(uv+1);
        dst[0] = y0;
        dst[1] = u0;
        dst[2] = v0;
        dst += 3;
        y++;
        if(!(width % 2)) uv+=2;
    }
}

static void uyvy_to_yuv(uint8_t* dst, uint32_t* src, int width) {
    if (!dst || !src) {
        return;
    }

    if (width % 2) {
        return; // not supporting odd widths
    }

    // currently, neon routine only supports multiple of 16 width
    if (width % 16) {
        while ((width-=2) >= 0) {
            uint8_t u0 = (src[0] >> 0) & 0xFF;
            uint8_t y0 = (src[0] >> 8) & 0xFF;
            uint8_t v0 = (src[0] >> 16) & 0xFF;
            uint8_t y1 = (src[0] >> 24) & 0xFF;
            dst[0] = y0;
            dst[1] = u0;
            dst[2] = v0;
            dst[3] = y1;
            dst[4] = u0;
            dst[5] = v0;
            dst += 6;
            src++;
        }
    } else {
        int n = width;
        asm volatile (
        "   pld [%[src], %[src_stride], lsl #2]                         \n\t"
        "   cmp %[n], #16                                               \n\t"
        "   blt 5f                                                      \n\t"
        "0: @ 16 pixel swap                                             \n\t"
        "   vld2.8  {q0, q1} , [%[src]]! @ q0 = uv q1 = y               \n\t"
        "   vuzp.8 q0, q2                @ d1 = u d5 = v                \n\t"
        "   vmov d1, d0                  @ q0 = u0u1u2..u0u1u2...       \n\t"
        "   vmov d5, d4                  @ q2 = v0v1v2..v0v1v2...       \n\t"
        "   vzip.8 d0, d1                @ q0 = u0u0u1u1u2u2...         \n\t"
        "   vzip.8 d4, d5                @ q2 = v0v0v1v1v2v2...         \n\t"
        "   vswp q0, q1                  @ now q0 = y q1 = u q2 = v     \n\t"
        "   vst3.8  {d0,d2,d4},[%[dst]]!                                \n\t"
        "   vst3.8  {d1,d3,d5},[%[dst]]!                                \n\t"
        "   sub %[n], %[n], #16                                         \n\t"
        "   cmp %[n], #16                                               \n\t"
        "   bge 0b                                                      \n\t"
        "5: @ end                                                       \n\t"
#ifdef NEEDS_ARM_ERRATA_754319_754320
        "   vmov s0,s0  @ add noop for errata item                      \n\t"
#endif
        : [dst] "+r" (dst), [src] "+r" (src), [n] "+r" (n)
        : [src_stride] "r" (width)
        : "cc", "memory", "q0", "q1", "q2"
        );
    }
}

static void resize_nv12(Encoder_libjpeg::params* params, uint8_t* dst_buffer) {
    structConvImage o_img_ptr, i_img_ptr;

    if (!params || !dst_buffer) {
        return;
    }

    //input
    i_img_ptr.uWidth =  params->in_width;
    i_img_ptr.uStride =  i_img_ptr.uWidth;
    i_img_ptr.uHeight =  params->in_height;
    i_img_ptr.eFormat = IC_FORMAT_YCbCr420_lp;
    i_img_ptr.imgPtr = (uint8_t*) params->src;
    i_img_ptr.clrPtr = i_img_ptr.imgPtr + (i_img_ptr.uWidth * i_img_ptr.uHeight);

    //ouput
    o_img_ptr.uWidth = params->out_width;
    o_img_ptr.uStride = o_img_ptr.uWidth;
    o_img_ptr.uHeight = params->out_height;
    o_img_ptr.eFormat = IC_FORMAT_YCbCr420_lp;
    o_img_ptr.imgPtr = dst_buffer;
    o_img_ptr.clrPtr = o_img_ptr.imgPtr + (o_img_ptr.uWidth * o_img_ptr.uHeight);

    VT_resizeFrame_Video_opt2_lp(&i_img_ptr, &o_img_ptr, NULL, 0);
}

/* public static functions */
const char* ExifElementsTable::degreesToExifOrientation(const char* degrees) {
    for (unsigned int i = 0; i < ARRAY_SIZE(degress_to_exif_lut); i++) {
        if (!strcmp(degrees, degress_to_exif_lut[i].string1)) {
            return degress_to_exif_lut[i].string2;
        }
    }
    return NULL;
}

void ExifElementsTable::stringToRational(const char* str, unsigned int* num, unsigned int* den) {
    int len;
    char * tempVal = NULL;

    if (str != NULL) {
        len = strlen(str);
        tempVal = (char*) malloc( sizeof(char) * (len + 1));
    }

    if (tempVal != NULL) {
        // convert the decimal string into a rational
        size_t den_len;
        char *ctx;
        unsigned int numerator = 0;
        unsigned int denominator = 0;
        char* temp = NULL;

        memset(tempVal, '\0', len + 1);
        strncpy(tempVal, str, len);
        temp = strtok_r(tempVal, ".", &ctx);

        if (temp != NULL)
            numerator = atoi(temp);

        if (!numerator)
            numerator = 1;

        temp = strtok_r(NULL, ".", &ctx);
        if (temp != NULL) {
            den_len = strlen(temp);
            if(HUGE_VAL == den_len ) {
                den_len = 0;
            }

            denominator = static_cast<unsigned int>(pow(10, den_len));
            numerator = numerator * denominator + atoi(temp);
        } else {
            denominator = 1;
        }

        free(tempVal);

        *num = numerator;
        *den = denominator;
    }
}

bool ExifElementsTable::isAsciiTag(const char* tag) {
    // TODO(XXX): Add tags as necessary
    return (strcmp(tag, TAG_GPS_PROCESSING_METHOD) == 0);
}

void ExifElementsTable::insertExifToJpeg(unsigned char* jpeg, size_t jpeg_size) {
    ReadMode_t read_mode = (ReadMode_t)(READ_METADATA | READ_IMAGE);

    ResetJpgfile();
    if (ReadJpegSectionsFromBuffer(jpeg, jpeg_size, read_mode)) {
        jpeg_opened = true;
        create_EXIF(table, exif_tag_count, gps_tag_count, has_datetime_tag);
    }
}

status_t ExifElementsTable::insertExifThumbnailImage(const char* thumb, int len) {
    status_t ret = NO_ERROR;

    if ((len > 0) && jpeg_opened) {
        ret = ReplaceThumbnailFromBuffer(thumb, len);
        CAMHAL_LOGDB("insertExifThumbnailImage. ReplaceThumbnail(). ret=%d", ret);
    }

    return ret;
}

void ExifElementsTable::saveJpeg(unsigned char* jpeg, size_t jpeg_size) {
    if (jpeg_opened) {
       WriteJpegToBuffer(jpeg, jpeg_size);
       DiscardData();
       jpeg_opened = false;
    }
}

/* public functions */
ExifElementsTable::~ExifElementsTable() {
    int num_elements = gps_tag_count + exif_tag_count;

    for (int i = 0; i < num_elements; i++) {
        if (table[i].Value) {
            free(table[i].Value);
        }
    }

    if (jpeg_opened) {
        DiscardData();
    }
}

status_t ExifElementsTable::insertElement(const char* tag, const char* value) {
    unsigned int value_length = 0;
    status_t ret = NO_ERROR;

    if (!value || !tag) {
        return -EINVAL;
    }

    if (position >= MAX_EXIF_TAGS_SUPPORTED) {
        CAMHAL_LOGEA("Max number of EXIF elements already inserted");
        return NO_MEMORY;
    }

    if (isAsciiTag(tag)) {
        value_length = sizeof(ExifAsciiPrefix) + strlen(value + sizeof(ExifAsciiPrefix));
    } else {
        value_length = strlen(value);
    }

    if (IsGpsTag(tag)) {
        table[position].GpsTag = TRUE;
        table[position].Tag = GpsTagNameToValue(tag);
        gps_tag_count++;
    } else {
        table[position].GpsTag = FALSE;
        table[position].Tag = TagNameToValue(tag);
        exif_tag_count++;

        if (strcmp(tag, TAG_DATETIME) == 0) {
            has_datetime_tag = true;
        }
    }

    table[position].DataLength = 0;
    table[position].Value = (char*) malloc(sizeof(char) * (value_length + 1));

    if (table[position].Value) {
        memcpy(table[position].Value, value, value_length + 1);
        table[position].DataLength = value_length + 1;
    }

    position++;
    return ret;
}

/* private member functions */
size_t Encoder_libjpeg::encode(params* input) {
    jpeg_compress_struct    cinfo;
    jpeg_error_mgr jerr;
    jpeg_destination_mgr jdest;
    uint8_t* src = NULL, *resize_src = NULL;
    uint8_t* row_tmp = NULL;
    uint8_t* row_src = NULL;
    uint8_t* row_uv = NULL; // used only for NV12
    int out_width = 0, in_width = 0;
    int out_height = 0, in_height = 0;
    int bpp = 2; // for uyvy
    int right_crop = 0, start_offset = 0;

    if (!input) {
        return 0;
    }

    out_width = input->out_width;
    in_width = input->in_width;
    out_height = input->out_height;
    in_height = input->in_height;
    right_crop = input->right_crop;
    start_offset = input->start_offset;
    src = input->src;
    input->jpeg_size = 0;

    libjpeg_destination_mgr dest_mgr(input->dst, input->dst_size);

    // param check...
    if ((in_width < 2) || (out_width < 2) || (in_height < 2) || (out_height < 2) ||
         (src == NULL) || (input->dst == NULL) || (input->quality < 1) || (input->src_size < 1) ||
         (input->dst_size < 1) || (input->format == NULL)) {
        goto exit;
    }

    if (strcmp(input->format, CameraParameters::PIXEL_FORMAT_YUV420SP) == 0) {
        bpp = 1;
        if ((in_width != out_width) || (in_height != out_height)) {
            resize_src = (uint8_t*) malloc(input->dst_size);
            resize_nv12(input, resize_src);
            if (resize_src) src = resize_src;
        }
    } else if ((in_width != out_width) || (in_height != out_height)) {
        CAMHAL_LOGEB("Encoder: resizing is not supported for this format: %s", input->format);
        goto exit;
    } else if (strcmp(input->format, CameraParameters::PIXEL_FORMAT_YUV422I)) {
        // we currently only support yuv422i and yuv420sp
        CAMHAL_LOGEB("Encoder: format not supported: %s", input->format);
        goto exit;
    }

    cinfo.err = jpeg_std_error(&jerr);

    jpeg_create_compress(&cinfo);

    CAMHAL_LOGDB("encoding...  \n\t"
                 "width: %d    \n\t"
                 "height:%d    \n\t"
                 "dest %p      \n\t"
                 "dest size:%d \n\t"
                 "mSrc %p",
                 out_width, out_height, input->dst,
                 input->dst_size, src);

    cinfo.dest = &dest_mgr;
    cinfo.image_width = out_width - right_crop;
    cinfo.image_height = out_height;
    cinfo.input_components = 3;
    cinfo.in_color_space = JCS_YCbCr;
    cinfo.input_gamma = 1;

    jpeg_set_defaults(&cinfo);
    jpeg_set_quality(&cinfo, input->quality, TRUE);
    cinfo.dct_method = JDCT_IFAST;

    jpeg_start_compress(&cinfo, TRUE);

    row_tmp = (uint8_t*)malloc(out_width * 3);
    row_src = src + start_offset;
    row_uv = src + out_width * out_height * bpp;

    while ((cinfo.next_scanline < cinfo.image_height) && !mCancelEncoding) {
        JSAMPROW row[1];    /* pointer to JSAMPLE row[s] */

        // convert input yuv format to yuv444
        if (strcmp(input->format, CameraParameters::PIXEL_FORMAT_YUV420SP) == 0) {
            nv21_to_yuv(row_tmp, row_src, row_uv, out_width - right_crop);
        } else {
            uyvy_to_yuv(row_tmp, (uint32_t*)row_src, out_width - right_crop);
        }

        row[0] = row_tmp;
        jpeg_write_scanlines(&cinfo, row, 1);
        row_src = row_src + out_width*bpp;

        // move uv row if input format needs it
        if (strcmp(input->format, CameraParameters::PIXEL_FORMAT_YUV420SP) == 0) {
            if (!(cinfo.next_scanline % 2))
                row_uv = row_uv +  out_width * bpp;
        }
    }

    // no need to finish encoding routine if we are prematurely stopping
    // we will end up crashing in dest_mgr since data is incomplete
    if (!mCancelEncoding)
        jpeg_finish_compress(&cinfo);
    jpeg_destroy_compress(&cinfo);

    if (resize_src) free(resize_src);
    if (row_tmp) free(row_tmp);

 exit:
    input->jpeg_size = dest_mgr.jpegsize;
    return dest_mgr.jpegsize;
}

} // namespace android
