/* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above
 *       copyright notice, this list of conditions and the following
 *       disclaimer in the documentation and/or other materials provided
 *       with the distribution.
 *     * Neither the name of The Linux Foundation nor the names of its
 *       contributors may be used to endorse or promote products derived
 *       from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 */

#define ATRACE_TAG ATRACE_TAG_CAMERA

// System dependencies
#include <pthread.h>

// JPEG dependencies
#include "mm_jpeg_dbg.h"
#include "mm_jpeg_mpo.h"

#define M_APP0    0xe0
#define M_APP1    0xe1
#define M_APP2    0xe2
#define M_EOI     0xd9
#define M_SOI     0xd8

/** READ_LONG:
 *  @b: Buffer start addr
 *  @o: Buffer offset to start reading
 *
 *  Read long value from the specified buff addr at given offset
 **/
#define READ_LONG(b, o)  \
  (uint32_t)(((uint32_t)b[o] << 24) + \
  ((uint32_t)b[o+1] << 16) + \
  ((uint32_t)b[o+2] << 8) + \
  ((uint32_t)b[o+3]))

/** READ_LONG_LITTLE:
 *  @b: Buffer start addr
 *  @o: Buffer offset to start reading
 *
 *  Read long value from the specified buff addr at given offset
 *  in Little Endian
 **/
#define READ_LONG_LITTLE(b, o)  \
  (uint32_t)(((uint32_t)b[o + 3] << 24) + \
  ((uint32_t) b[o + 2] << 16) + \
  ((uint32_t) b[o + 1] << 8) + \
  (uint32_t) b[o]);

/** READ_LONG:
 *  @b: Buffer start addr
 *  @o: Buffer offset to start reading
 *
 *  Read short value from the specified buff addr at given
 *  offset
 **/
#define READ_SHORT(b, o)  \
  (uint16_t) (((uint16_t)b[o] << 8) + \
  (uint16_t) b[o + 1]);

/*Mutex to serializa MPO composition*/
static pthread_mutex_t g_mpo_lock = PTHREAD_MUTEX_INITIALIZER;

/** mm_jpeg_mpo_write_long_little_endian
 *
 *  Arguments:
 *    @buffer_addr: image start addr
 *    @buff_offset: offset in the buffer
 *    @buffer_size: Size of the buffer
 *    @value: Value to write
 *    @overflow : Overflow flag
 *
 *  Return:
 *       None
 *
 *  Description:
 *       Write value at the given offset
 *
 **/
void mm_jpeg_mpo_write_long_little_endian(uint8_t *buff_addr, uint32_t buff_offset,
  uint32_t buffer_size, int value, uint8_t *overflow)
{
  if (buff_offset + 3 >= buffer_size) {
    *overflow = TRUE;
  }

  if (!(*overflow)) {
    buff_addr[buff_offset + 3] = (uint8_t)((value >> 24) & 0xFF);
    buff_addr[buff_offset + 2] = (uint8_t)((value >> 16) & 0xFF);
    buff_addr[buff_offset + 1] = (uint8_t)((value >> 8) & 0xFF);
    buff_addr[buff_offset] = (uint8_t)(value & 0xFF);
  }
}

/** mm_jpeg_mpo_write_long
 *
 *  Arguments:
 *    @buffer_addr: image start addr
 *    @buff_offset: offset in the buffer
 *    @buffer_size: Size of the buffer
 *    @value: Value to write
 *    @overflow : Overflow flag
 *
 *  Return:
 *       None
 *
 *  Description:
 *       Write value at the given offset
 *
 **/
void mm_jpeg_mpo_write_long(uint8_t *buff_addr, uint32_t buff_offset,
  uint32_t buffer_size, int value, uint8_t *overflow)
{
  if ((buff_offset + 3) >= buffer_size) {
    *overflow = TRUE;
  }

  if (!(*overflow)) {
    buff_addr[buff_offset] = (uint8_t)((value >> 24) & 0xFF);
    buff_addr[buff_offset+1] = (uint8_t)((value >> 16) & 0xFF);
    buff_addr[buff_offset+2] = (uint8_t)((value >> 8) & 0xFF);
    buff_addr[buff_offset+3] = (uint8_t)(value & 0xFF);
  }
}

/** mm_jpeg_mpo_get_app_marker
 *
 *  Arguments:
 *    @buffer_addr: Jpeg image start addr
 *    @buffer_size: Size of the Buffer
 *    @app_marker: app_marker to find
 *
 *  Return:
 *       Start offset of the specified app marker
 *
 *  Description:
 *       Gets the start offset of the given app marker
 *
 **/
uint8_t *mm_jpeg_mpo_get_app_marker(uint8_t *buffer_addr, int buffer_size,
  int app_marker)
{
  int32_t byte;
  uint8_t *p_current_addr = NULL, *p_start_offset = NULL;
  uint16_t app_marker_size = 0;

  p_current_addr = buffer_addr;
  do {
    do {
      byte = *(p_current_addr);
      p_current_addr++;
    }
    while ((byte != 0xFF) &&
      (p_current_addr < (buffer_addr + (buffer_size - 1))));

    //If 0xFF is not found at all, break
    if (byte != 0xFF) {
      LOGD("0xFF not found");
      break;
    }

    //Read the next byte after 0xFF
    byte = *(p_current_addr);
    LOGD("Byte %x", byte);
    if (byte == app_marker) {
      LOGD("Byte %x", byte);
      p_start_offset = ++p_current_addr;
      break;
    } else if (byte != M_SOI) {
      app_marker_size = READ_SHORT(p_current_addr, 1);
      LOGD("size %d", app_marker_size);
      p_current_addr += app_marker_size;
    }
  }
  while ((byte != M_EOI) &&
    (p_current_addr < (buffer_addr + (buffer_size - 1))));

  return p_start_offset;
}

/** mm_jpeg_mpo_get_mp_header
 *
 *  Arguments:
 *    @app2_marker: app2_marker start offset
 *
 *  Return:
 *       Start offset of the MP header
 *
 *  Description:
 *       Get the start offset of the MP header (before the MP
 *       Endian field). All offsets in the MP header need to be
 *       specified wrt this start offset.
 *
 **/
uint8_t *mm_jpeg_mpo_get_mp_header(uint8_t *app2_start_offset)
{
  uint8_t *mp_headr_start_offset = NULL;

  if (app2_start_offset != NULL) {
    mp_headr_start_offset = app2_start_offset + MP_APP2_FIELD_LENGTH_BYTES +
      MP_FORMAT_IDENTIFIER_BYTES;
  }

  return mp_headr_start_offset;
}

/** mm_jpeg_mpo_update_header
 *
 *  Arguments:
 *    @mpo_info: MPO Info
 *
 *  Return:
 *       0 - Success
 *       -1 - otherwise
 *
 *  Description:
 *      Update the MP Index IFD of the first image with info
 *      about about all other images.
 *
 **/
int mm_jpeg_mpo_update_header(mm_jpeg_mpo_info_t *mpo_info)
{
  uint8_t *app2_start_off_addr = NULL, *mp_headr_start_off_addr = NULL;
  uint32_t mp_index_ifd_offset = 0, current_offset = 0, mp_entry_val_offset = 0;
  uint8_t *aux_start_addr = NULL;
  uint8_t overflow_flag = 0;
  int i = 0, rc = -1;
  uint32_t endianess = MPO_LITTLE_ENDIAN, offset_to_nxt_ifd = 8;
  uint16_t ifd_tag_count = 0;

  //Get the addr of the App Marker
  app2_start_off_addr = mm_jpeg_mpo_get_app_marker(
    mpo_info->output_buff.buf_vaddr, mpo_info->primary_image.buf_filled_len, M_APP2);
  if (!app2_start_off_addr) {
    LOGE("Cannot find App2 marker. MPO composition failed" );
    return rc;
  }
  LOGD("app2_start_off_addr %p = %x",
    app2_start_off_addr, *app2_start_off_addr);

  //Get the addr of the MP Headr start offset.
  //All offsets in the MP header are wrt to this addr
  mp_headr_start_off_addr = mm_jpeg_mpo_get_mp_header(app2_start_off_addr);
  if (!mp_headr_start_off_addr) {
    LOGE("mp headr start offset is NULL. MPO composition failed" );
    return rc;
  }
  LOGD("mp_headr_start_off_addr %x",
    *mp_headr_start_off_addr);

  current_offset = mp_headr_start_off_addr - mpo_info->output_buff.buf_vaddr;

  endianess = READ_LONG(mpo_info->output_buff.buf_vaddr, current_offset);
  LOGD("Endianess %d", endianess);

  //Add offset to first ifd
  current_offset += MP_ENDIAN_BYTES;

  //Read the value to get MP Index IFD.
  if (endianess == MPO_LITTLE_ENDIAN) {
    offset_to_nxt_ifd = READ_LONG_LITTLE(mpo_info->output_buff.buf_vaddr,
      current_offset);
  } else {
    offset_to_nxt_ifd = READ_LONG(mpo_info->output_buff.buf_vaddr,
      current_offset);
  }
  LOGD("offset_to_nxt_ifd %d", offset_to_nxt_ifd);

  current_offset = ((mp_headr_start_off_addr + offset_to_nxt_ifd) -
    mpo_info->output_buff.buf_vaddr);
  mp_index_ifd_offset = current_offset;
  LOGD("mp_index_ifd_offset %d",
    mp_index_ifd_offset);

  //Traverse to MP Entry value
  ifd_tag_count = READ_SHORT(mpo_info->output_buff.buf_vaddr, current_offset);
  LOGD("Tag count in MP entry %d", ifd_tag_count);
  current_offset += MP_INDEX_COUNT_BYTES;

  /* Get MP Entry Value offset - Count * 12 (Each tag is 12 bytes)*/
  current_offset += (ifd_tag_count * 12);
  /*Add Offset to next IFD*/
  current_offset += MP_INDEX_OFFSET_OF_NEXT_IFD_BYTES;

  mp_entry_val_offset = current_offset;
  LOGD("MP Entry value offset %d",
    mp_entry_val_offset);

  //Update image size for primary image
  current_offset += MP_INDEX_ENTRY_INDIVIDUAL_IMAGE_ATTRIBUTE_BYTES;
  if (endianess == MPO_LITTLE_ENDIAN) {
    mm_jpeg_mpo_write_long_little_endian(mpo_info->output_buff.buf_vaddr,
      current_offset, mpo_info->output_buff_size,
      mpo_info->primary_image.buf_filled_len, &overflow_flag);
  } else {
    mm_jpeg_mpo_write_long(mpo_info->output_buff.buf_vaddr,
      current_offset, mpo_info->output_buff_size,
      mpo_info->primary_image.buf_filled_len, &overflow_flag);
  }

  aux_start_addr = mpo_info->output_buff.buf_vaddr +
    mpo_info->primary_image.buf_filled_len;

  for (i = 0; i < mpo_info->num_of_images - 1; i++) {
    //Go to MP Entry val for each image
    mp_entry_val_offset += MP_INDEX_ENTRY_VALUE_BYTES;
    current_offset = mp_entry_val_offset;

    //Update image size
    current_offset += MP_INDEX_ENTRY_INDIVIDUAL_IMAGE_ATTRIBUTE_BYTES;
    if (endianess == MPO_LITTLE_ENDIAN) {
      mm_jpeg_mpo_write_long_little_endian(mpo_info->output_buff.buf_vaddr,
        current_offset, mpo_info->output_buff_size,
        mpo_info->aux_images[i].buf_filled_len, &overflow_flag);
    } else {
      mm_jpeg_mpo_write_long(mpo_info->output_buff.buf_vaddr,
        current_offset, mpo_info->output_buff_size,
        mpo_info->aux_images[i].buf_filled_len, &overflow_flag);
    }
    LOGD("aux[start_addr %x", *aux_start_addr);
    //Update the offset
    current_offset += MP_INDEX_ENTRY_INDIVIDUAL_IMAGE_SIZE_BYTES;
    if (endianess == MPO_LITTLE_ENDIAN) {
      mm_jpeg_mpo_write_long_little_endian(mpo_info->output_buff.buf_vaddr,
        current_offset, mpo_info->output_buff_size,
        aux_start_addr - mp_headr_start_off_addr, &overflow_flag);
    } else {
      mm_jpeg_mpo_write_long(mpo_info->output_buff.buf_vaddr,
        current_offset, mpo_info->output_buff_size,
        aux_start_addr - mp_headr_start_off_addr, &overflow_flag);
    }
    aux_start_addr += mpo_info->aux_images[i].buf_filled_len;
  }
  if (!overflow_flag) {
    rc = 0;
  }
  return rc;
}

/** mm_jpeg_mpo_compose
 *
 *  Arguments:
 *    @mpo_info: MPO Info
 *
 *  Return:
 *       0 - Success
 *      -1 - otherwise
 *
 *  Description:
 *      Compose MPO image from multiple JPEG images
 *
 **/
int mm_jpeg_mpo_compose(mm_jpeg_mpo_info_t *mpo_info)
{
  uint8_t *aux_write_offset = NULL;
  int i = 0, rc = -1;

  pthread_mutex_lock(&g_mpo_lock);

  //Primary image needs to be copied to the o/p buffer if its not already
  if (mpo_info->output_buff.buf_filled_len == 0) {
    if (mpo_info->primary_image.buf_filled_len < mpo_info->output_buff_size) {
      memcpy(mpo_info->output_buff.buf_vaddr, mpo_info->primary_image.buf_vaddr,
        mpo_info->primary_image.buf_filled_len);
      mpo_info->output_buff.buf_filled_len +=
        mpo_info->primary_image.buf_filled_len;
    } else {
      LOGE("O/P buffer not large enough. MPO composition failed");
      pthread_mutex_unlock(&g_mpo_lock);
      return rc;
    }
  }
  //Append each Aux image to the buffer
  for (i = 0; i < mpo_info->num_of_images - 1; i++) {
    if ((mpo_info->output_buff.buf_filled_len +
      mpo_info->aux_images[i].buf_filled_len) <= mpo_info->output_buff_size) {
      aux_write_offset = mpo_info->output_buff.buf_vaddr +
        mpo_info->output_buff.buf_filled_len;
      memcpy(aux_write_offset, mpo_info->aux_images[i].buf_vaddr,
        mpo_info->aux_images[i].buf_filled_len);
      mpo_info->output_buff.buf_filled_len +=
        mpo_info->aux_images[i].buf_filled_len;
    } else {
      LOGE("O/P buffer not large enough. MPO composition failed");
      pthread_mutex_unlock(&g_mpo_lock);
      return rc;
    }
  }

  rc = mm_jpeg_mpo_update_header(mpo_info);
  pthread_mutex_unlock(&g_mpo_lock);

  return rc;
}
