// Copyright 2014 PDFium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com

#include "core/fxcodec/codec/codec_int.h"
#include "core/fxcodec/include/fx_codec.h"
#include "core/fxcodec/lgif/fx_gif.h"
#include "core/fxge/include/fx_dib.h"
struct FXGIF_Context {
  gif_decompress_struct_p gif_ptr;
  void* parent_ptr;
  void* child_ptr;

  void* (*m_AllocFunc)(unsigned int);
  void (*m_FreeFunc)(void*);
};
extern "C" {
static void* gif_alloc_func(unsigned int size) {
  return FX_Alloc(char, size);
}
static void gif_free_func(void* p) {
  FX_Free(p);
}
};
static void gif_error_data(gif_decompress_struct_p gif_ptr,
                           const FX_CHAR* err_msg) {
  FXSYS_strncpy((char*)gif_ptr->err_ptr, err_msg, GIF_MAX_ERROR_SIZE - 1);
  longjmp(gif_ptr->jmpbuf, 1);
}
static uint8_t* gif_ask_buf_for_pal(gif_decompress_struct_p gif_ptr,
                                    int32_t pal_size) {
  FXGIF_Context* p = (FXGIF_Context*)gif_ptr->context_ptr;
  CCodec_GifModule* pModule = (CCodec_GifModule*)p->parent_ptr;
  return pModule->AskLocalPaletteBufCallback(
      p->child_ptr, gif_get_frame_num(gif_ptr), pal_size);
}
static void gif_record_current_position(gif_decompress_struct_p gif_ptr,
                                        uint32_t* cur_pos_ptr) {
  FXGIF_Context* p = (FXGIF_Context*)gif_ptr->context_ptr;
  CCodec_GifModule* pModule = (CCodec_GifModule*)p->parent_ptr;
  pModule->RecordCurrentPositionCallback(p->child_ptr, *cur_pos_ptr);
}
static void gif_read_scanline(gif_decompress_struct_p gif_ptr,
                              int32_t row_num,
                              uint8_t* row_buf) {
  FXGIF_Context* p = (FXGIF_Context*)gif_ptr->context_ptr;
  CCodec_GifModule* pModule = (CCodec_GifModule*)p->parent_ptr;
  pModule->ReadScanlineCallback(p->child_ptr, row_num, row_buf);
}
static FX_BOOL gif_get_record_position(gif_decompress_struct_p gif_ptr,
                                       uint32_t cur_pos,
                                       int32_t left,
                                       int32_t top,
                                       int32_t width,
                                       int32_t height,
                                       int32_t pal_num,
                                       void* pal_ptr,
                                       int32_t delay_time,
                                       FX_BOOL user_input,
                                       int32_t trans_index,
                                       int32_t disposal_method,
                                       FX_BOOL interlace) {
  FXGIF_Context* p = (FXGIF_Context*)gif_ptr->context_ptr;
  CCodec_GifModule* pModule = (CCodec_GifModule*)p->parent_ptr;
  return pModule->InputRecordPositionBufCallback(
      p->child_ptr, cur_pos, FX_RECT(left, top, left + width, top + height),
      pal_num, pal_ptr, delay_time, user_input, trans_index, disposal_method,
      interlace);
}

FXGIF_Context* CCodec_GifModule::Start(void* pModule) {
  FXGIF_Context* p = FX_Alloc(FXGIF_Context, 1);
  if (!p)
    return nullptr;

  FXSYS_memset(p, 0, sizeof(FXGIF_Context));
  p->m_AllocFunc = gif_alloc_func;
  p->m_FreeFunc = gif_free_func;
  p->gif_ptr = nullptr;
  p->parent_ptr = (void*)this;
  p->child_ptr = pModule;
  p->gif_ptr = gif_create_decompress();
  if (!p->gif_ptr) {
    FX_Free(p);
    return nullptr;
  }
  p->gif_ptr->context_ptr = (void*)p;
  p->gif_ptr->err_ptr = m_szLastError;
  p->gif_ptr->gif_error_fn = gif_error_data;
  p->gif_ptr->gif_ask_buf_for_pal_fn = gif_ask_buf_for_pal;
  p->gif_ptr->gif_record_current_position_fn = gif_record_current_position;
  p->gif_ptr->gif_get_row_fn = gif_read_scanline;
  p->gif_ptr->gif_get_record_position_fn = gif_get_record_position;
  return p;
}

void CCodec_GifModule::Finish(FXGIF_Context* ctx) {
  if (ctx) {
    gif_destroy_decompress(&ctx->gif_ptr);
    ctx->m_FreeFunc(ctx);
  }
}

int32_t CCodec_GifModule::ReadHeader(FXGIF_Context* ctx,
                                     int* width,
                                     int* height,
                                     int* pal_num,
                                     void** pal_pp,
                                     int* bg_index,
                                     CFX_DIBAttribute* pAttribute) {
  if (setjmp(ctx->gif_ptr->jmpbuf))
    return 0;

  int32_t ret = gif_read_header(ctx->gif_ptr);
  if (ret != 1)
    return ret;

  *width = ctx->gif_ptr->width;
  *height = ctx->gif_ptr->height;
  *pal_num = ctx->gif_ptr->global_pal_num;
  *pal_pp = ctx->gif_ptr->global_pal_ptr;
  *bg_index = ctx->gif_ptr->bc_index;
  return 1;
}

int32_t CCodec_GifModule::LoadFrameInfo(FXGIF_Context* ctx, int* frame_num) {
  if (setjmp(ctx->gif_ptr->jmpbuf))
    return 0;

  int32_t ret = gif_get_frame(ctx->gif_ptr);
  if (ret != 1)
    return ret;

  *frame_num = gif_get_frame_num(ctx->gif_ptr);
  return 1;
}

int32_t CCodec_GifModule::LoadFrame(FXGIF_Context* ctx,
                                    int frame_num,
                                    CFX_DIBAttribute* pAttribute) {
  if (setjmp(ctx->gif_ptr->jmpbuf))
    return 0;

  int32_t ret = gif_load_frame(ctx->gif_ptr, frame_num);
  if (ret == 1) {
    if (pAttribute) {
      pAttribute->m_nGifLeft =
          ctx->gif_ptr->img_ptr_arr_ptr->GetAt(frame_num)->image_info_ptr->left;
      pAttribute->m_nGifTop =
          ctx->gif_ptr->img_ptr_arr_ptr->GetAt(frame_num)->image_info_ptr->top;
      pAttribute->m_fAspectRatio = ctx->gif_ptr->pixel_aspect;
      if (ctx->gif_ptr->cmt_data_ptr) {
        const uint8_t* buf =
            (const uint8_t*)ctx->gif_ptr->cmt_data_ptr->GetBuffer(0);
        uint32_t len = ctx->gif_ptr->cmt_data_ptr->GetLength();
        if (len > 21) {
          uint8_t size = *buf++;
          if (size) {
            pAttribute->m_strAuthor = CFX_ByteString(buf, size);
          } else {
            pAttribute->m_strAuthor.clear();
          }
          buf += size;
          size = *buf++;
          if (size == 20) {
            FXSYS_memcpy(pAttribute->m_strTime, buf, size);
          }
        }
      }
    }
  }
  return ret;
}

uint32_t CCodec_GifModule::GetAvailInput(FXGIF_Context* ctx,
                                         uint8_t** avail_buf_ptr) {
  return gif_get_avail_input(ctx->gif_ptr, avail_buf_ptr);
}

void CCodec_GifModule::Input(FXGIF_Context* ctx,
                             const uint8_t* src_buf,
                             uint32_t src_size) {
  gif_input_buffer(ctx->gif_ptr, (uint8_t*)src_buf, src_size);
}
