/*
 * 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]))

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);
    }
}

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) {
    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++;
    }

    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
