// Copyright 2017 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/gif/cfx_gifcontext.h"

#include <algorithm>
#include <utility>

#include "core/fxcodec/codec/ccodec_gifmodule.h"
#include "core/fxcodec/gif/cfx_gif.h"
#include "third_party/base/ptr_util.h"
#include "third_party/base/stl_util.h"

namespace {

const int32_t s_gif_interlace_step[4] = {8, 8, 4, 2};

}  // namespace

CFX_GifContext::CFX_GifContext(CCodec_GifModule* gif_module,
                               CCodec_GifModule::Delegate* delegate)
    : gif_module_(gif_module),
      delegate_(delegate),
      global_pal_exp_(0),
      img_row_offset_(0),
      img_row_avail_size_(0),
      avail_in_(0),
      decode_status_(GIF_D_STATUS_SIG),
      skip_size_(0),
      next_in_(nullptr),
      width_(0),
      height_(0),
      bc_index_(0),
      pixel_aspect_(0),
      global_sort_flag_(0),
      global_color_resolution_(0),
      img_pass_num_(0) {}

CFX_GifContext::~CFX_GifContext() {}

void CFX_GifContext::RecordCurrentPosition(uint32_t* cur_pos) {
  delegate_->GifRecordCurrentPosition(*cur_pos);
}

void CFX_GifContext::ReadScanline(int32_t row_num, uint8_t* row_buf) {
  delegate_->GifReadScanline(row_num, row_buf);
}

bool CFX_GifContext::GetRecordPosition(uint32_t cur_pos,
                                       int32_t left,
                                       int32_t top,
                                       int32_t width,
                                       int32_t height,
                                       int32_t pal_num,
                                       CFX_GifPalette* pal,
                                       int32_t delay_time,
                                       bool user_input,
                                       int32_t trans_index,
                                       int32_t disposal_method,
                                       bool interlace) {
  return delegate_->GifInputRecordPositionBuf(
      cur_pos, FX_RECT(left, top, left + width, top + height), pal_num, pal,
      delay_time, user_input, trans_index, disposal_method, interlace);
}

CFX_GifDecodeStatus CFX_GifContext::ReadHeader() {
  uint32_t skip_size_org = skip_size_;
  CFX_GifHeader* gif_header = nullptr;
  if (!ReadData(reinterpret_cast<uint8_t**>(&gif_header), 6))
    return CFX_GifDecodeStatus::Unfinished;

  if (strncmp(gif_header->signature, GIF_SIGNATURE, 3) != 0 ||
      gif_header->version[0] != '8' || gif_header->version[2] != 'a')
    return CFX_GifDecodeStatus::Error;

  CFX_GifLocalScreenDescriptor* gif_lsd = nullptr;
  if (!ReadData(reinterpret_cast<uint8_t**>(&gif_lsd), 7)) {
    skip_size_ = skip_size_org;
    return CFX_GifDecodeStatus::Unfinished;
  }

  if (gif_lsd->global_flags.global_pal) {
    global_pal_exp_ = gif_lsd->global_flags.pal_bits;
    uint32_t global_pal_size = unsigned(2 << global_pal_exp_) * 3u;
    uint8_t* global_pal = nullptr;
    if (!ReadData(&global_pal, global_pal_size)) {
      skip_size_ = skip_size_org;
      return CFX_GifDecodeStatus::Unfinished;
    }

    global_sort_flag_ = gif_lsd->global_flags.sort_flag;
    global_color_resolution_ = gif_lsd->global_flags.color_resolution;
    global_palette_.resize(global_pal_size / 3);
    memcpy(global_palette_.data(), global_pal, global_pal_size);
  }

  width_ = static_cast<int>(
      FXWORD_GET_LSBFIRST(reinterpret_cast<uint8_t*>(&gif_lsd->width)));
  height_ = static_cast<int>(
      FXWORD_GET_LSBFIRST(reinterpret_cast<uint8_t*>(&gif_lsd->height)));
  bc_index_ = gif_lsd->bc_index;
  pixel_aspect_ = gif_lsd->pixel_aspect;
  return CFX_GifDecodeStatus::Success;
}

CFX_GifDecodeStatus CFX_GifContext::GetFrame() {
  CFX_GifDecodeStatus ret = CFX_GifDecodeStatus::Success;
  while (true) {
    switch (decode_status_) {
      case GIF_D_STATUS_TAIL:
        return CFX_GifDecodeStatus::Success;
      case GIF_D_STATUS_SIG: {
        uint8_t* signature = nullptr;
        if (!ReadData(&signature, 1))
          return CFX_GifDecodeStatus::Unfinished;

        switch (*signature) {
          case GIF_SIG_EXTENSION:
            SaveDecodingStatus(GIF_D_STATUS_EXT);
            continue;
          case GIF_SIG_IMAGE:
            SaveDecodingStatus(GIF_D_STATUS_IMG_INFO);
            continue;
          case GIF_SIG_TRAILER:
            SaveDecodingStatus(GIF_D_STATUS_TAIL);
            return CFX_GifDecodeStatus::Success;
          default:
            if (avail_in_) {
              // The Gif File has non_standard Tag!
              SaveDecodingStatus(GIF_D_STATUS_SIG);
              continue;
            }
            // The Gif File Doesn't have Trailer Tag!
            return CFX_GifDecodeStatus::Success;
        }
      }
      case GIF_D_STATUS_EXT: {
        uint8_t* extension = nullptr;
        if (!ReadData(&extension, 1))
          return CFX_GifDecodeStatus::Unfinished;

        switch (*extension) {
          case GIF_BLOCK_CE:
            SaveDecodingStatus(GIF_D_STATUS_EXT_CE);
            continue;
          case GIF_BLOCK_GCE:
            SaveDecodingStatus(GIF_D_STATUS_EXT_GCE);
            continue;
          case GIF_BLOCK_PTE:
            SaveDecodingStatus(GIF_D_STATUS_EXT_PTE);
            continue;
          default: {
            int32_t status = GIF_D_STATUS_EXT_UNE;
            if (*extension == GIF_BLOCK_PTE) {
              status = GIF_D_STATUS_EXT_PTE;
            }
            SaveDecodingStatus(status);
            continue;
          }
        }
      }
      case GIF_D_STATUS_IMG_INFO: {
        ret = DecodeImageInfo();
        if (ret != CFX_GifDecodeStatus::Success)
          return ret;

        continue;
      }
      case GIF_D_STATUS_IMG_DATA: {
        uint8_t* img_data_size = nullptr;
        uint8_t* img_data = nullptr;
        uint32_t skip_size_org = skip_size_;
        if (!ReadData(&img_data_size, 1))
          return CFX_GifDecodeStatus::Unfinished;

        while (*img_data_size != GIF_BLOCK_TERMINAL) {
          if (!ReadData(&img_data, *img_data_size)) {
            skip_size_ = skip_size_org;
            return CFX_GifDecodeStatus::Unfinished;
          }

          SaveDecodingStatus(GIF_D_STATUS_IMG_DATA);
          skip_size_org = skip_size_;
          if (!ReadData(&img_data_size, 1))
            return CFX_GifDecodeStatus::Unfinished;
        }
        SaveDecodingStatus(GIF_D_STATUS_SIG);
        continue;
      }
      default: {
        ret = DecodeExtension();
        if (ret != CFX_GifDecodeStatus::Success)
          return ret;
        break;
      }
    }
  }
  return CFX_GifDecodeStatus::Success;
}

CFX_GifDecodeStatus CFX_GifContext::LoadFrame(int32_t frame_num) {
  if (!pdfium::IndexInBounds(images_, frame_num))
    return CFX_GifDecodeStatus::Error;

  uint8_t* img_data_size = nullptr;
  uint8_t* img_data = nullptr;
  uint32_t skip_size_org = skip_size_;
  CFX_GifImage* gif_image = images_[static_cast<size_t>(frame_num)].get();
  uint32_t gif_img_row_bytes = gif_image->image_info.width;
  if (gif_img_row_bytes == 0)
    return CFX_GifDecodeStatus::Error;

  if (decode_status_ == GIF_D_STATUS_TAIL) {
    gif_image->row_buffer.resize(gif_img_row_bytes);
    CFX_GifGraphicControlExtension* gif_img_gce = gif_image->image_GCE.get();
    int32_t loc_pal_num =
        gif_image->image_info.local_flags.local_pal
            ? (2 << gif_image->image_info.local_flags.pal_bits)
            : 0;
    avail_in_ = 0;
    CFX_GifPalette* pLocalPalette = gif_image->local_palettes.empty()
                                        ? nullptr
                                        : gif_image->local_palettes.data();
    if (!gif_img_gce) {
      bool bRes = GetRecordPosition(
          gif_image->data_pos, gif_image->image_info.left,
          gif_image->image_info.top, gif_image->image_info.width,
          gif_image->image_info.height, loc_pal_num, pLocalPalette, 0, 0, -1, 0,
          gif_image->image_info.local_flags.interlace);
      if (!bRes) {
        gif_image->row_buffer.clear();
        return CFX_GifDecodeStatus::Error;
      }
    } else {
      bool bRes = GetRecordPosition(
          gif_image->data_pos, gif_image->image_info.left,
          gif_image->image_info.top, gif_image->image_info.width,
          gif_image->image_info.height, loc_pal_num, pLocalPalette,
          static_cast<int32_t>(gif_image->image_GCE->delay_time),
          gif_image->image_GCE->gce_flags.user_input,
          gif_image->image_GCE->gce_flags.transparency
              ? static_cast<int32_t>(gif_image->image_GCE->trans_index)
              : -1,
          static_cast<int32_t>(gif_image->image_GCE->gce_flags.disposal_method),
          gif_image->image_info.local_flags.interlace);
      if (!bRes) {
        gif_image->row_buffer.clear();
        return CFX_GifDecodeStatus::Error;
      }
    }

    if (gif_image->code_exp > GIF_MAX_LZW_EXP) {
      gif_image->row_buffer.clear();
      return CFX_GifDecodeStatus::Error;
    }

    img_row_offset_ = 0;
    img_row_avail_size_ = 0;
    img_pass_num_ = 0;
    gif_image->row_num = 0;
    SaveDecodingStatus(GIF_D_STATUS_IMG_DATA);
  }

  if (decode_status_ == GIF_D_STATUS_IMG_DATA) {
    if (!ReadData(&img_data_size, 1))
      return CFX_GifDecodeStatus::Unfinished;

    if (*img_data_size != GIF_BLOCK_TERMINAL) {
      if (!ReadData(&img_data, *img_data_size)) {
        skip_size_ = skip_size_org;
        return CFX_GifDecodeStatus::Unfinished;
      }

      if (!lzw_decompressor_.get())
        lzw_decompressor_ = CFX_LZWDecompressor::Create(
            !gif_image->local_palettes.empty() ? gif_image->local_pallette_exp
                                               : global_pal_exp_,
            gif_image->code_exp);
      SaveDecodingStatus(GIF_D_STATUS_IMG_DATA);
      img_row_offset_ += img_row_avail_size_;
      img_row_avail_size_ = gif_img_row_bytes - img_row_offset_;
      CFX_GifDecodeStatus ret =
          lzw_decompressor_.get()
              ? lzw_decompressor_->Decode(
                    img_data, *img_data_size,
                    gif_image->row_buffer.data() + img_row_offset_,
                    &img_row_avail_size_)
              : CFX_GifDecodeStatus::Error;
      if (ret == CFX_GifDecodeStatus::Error) {
        DecodingFailureAtTailCleanup(gif_image);
        return CFX_GifDecodeStatus::Error;
      }
      while (ret != CFX_GifDecodeStatus::Error) {
        if (ret == CFX_GifDecodeStatus::Success) {
          ReadScanline(gif_image->row_num, gif_image->row_buffer.data());
          gif_image->row_buffer.clear();
          SaveDecodingStatus(GIF_D_STATUS_TAIL);
          return CFX_GifDecodeStatus::Success;
        }
        if (ret == CFX_GifDecodeStatus::Unfinished) {
          skip_size_org = skip_size_;
          if (!ReadData(&img_data_size, 1))
            return CFX_GifDecodeStatus::Unfinished;

          if (*img_data_size != GIF_BLOCK_TERMINAL) {
            if (!ReadData(&img_data, *img_data_size)) {
              skip_size_ = skip_size_org;
              return CFX_GifDecodeStatus::Unfinished;
            }
            if (!lzw_decompressor_.get())
              lzw_decompressor_ = CFX_LZWDecompressor::Create(
                  !gif_image->local_palettes.empty()
                      ? gif_image->local_pallette_exp
                      : global_pal_exp_,
                  gif_image->code_exp);
            SaveDecodingStatus(GIF_D_STATUS_IMG_DATA);
            img_row_offset_ += img_row_avail_size_;
            img_row_avail_size_ = gif_img_row_bytes - img_row_offset_;
            ret = lzw_decompressor_.get()
                      ? lzw_decompressor_->Decode(
                            img_data, *img_data_size,
                            gif_image->row_buffer.data() + img_row_offset_,
                            &img_row_avail_size_)
                      : CFX_GifDecodeStatus::Error;
          }
        }
        if (ret == CFX_GifDecodeStatus::InsufficientDestSize) {
          if (gif_image->image_info.local_flags.interlace) {
            ReadScanline(gif_image->row_num, gif_image->row_buffer.data());
            gif_image->row_num += s_gif_interlace_step[img_pass_num_];
            if (gif_image->row_num >=
                static_cast<int32_t>(gif_image->image_info.height)) {
              img_pass_num_++;
              if (img_pass_num_ == FX_ArraySize(s_gif_interlace_step)) {
                DecodingFailureAtTailCleanup(gif_image);
                return CFX_GifDecodeStatus::Error;
              }
              gif_image->row_num = s_gif_interlace_step[img_pass_num_] / 2;
            }
          } else {
            ReadScanline(gif_image->row_num++, gif_image->row_buffer.data());
          }
          img_row_offset_ = 0;
          img_row_avail_size_ = gif_img_row_bytes;
          ret = lzw_decompressor_.get()
                    ? lzw_decompressor_->Decode(
                          img_data, *img_data_size,
                          gif_image->row_buffer.data() + img_row_offset_,
                          &img_row_avail_size_)
                    : CFX_GifDecodeStatus::Error;
        }
        if (ret == CFX_GifDecodeStatus::Error) {
          DecodingFailureAtTailCleanup(gif_image);
          return CFX_GifDecodeStatus::Error;
        }
      }
    }
    SaveDecodingStatus(GIF_D_STATUS_TAIL);
  }
  return CFX_GifDecodeStatus::Error;
}

void CFX_GifContext::SetInputBuffer(uint8_t* src_buf, uint32_t src_size) {
  next_in_ = src_buf;
  avail_in_ = src_size;
  skip_size_ = 0;
}

uint32_t CFX_GifContext::GetAvailInput(uint8_t** avail_buf) const {
  if (avail_buf) {
    *avail_buf = nullptr;
    if (avail_in_ > 0)
      *avail_buf = next_in_;
  }
  return avail_in_;
}

int32_t CFX_GifContext::GetFrameNum() const {
  return pdfium::CollectionSize<int32_t>(images_);
}

uint8_t* CFX_GifContext::ReadData(uint8_t** des_buf_pp, uint32_t data_size) {
  if (avail_in_ < skip_size_ + data_size)
    return nullptr;

  *des_buf_pp = next_in_ + skip_size_;
  skip_size_ += data_size;
  return *des_buf_pp;
}

void CFX_GifContext::SaveDecodingStatus(int32_t status) {
  decode_status_ = status;
  next_in_ += skip_size_;
  avail_in_ -= skip_size_;
  skip_size_ = 0;
}

CFX_GifDecodeStatus CFX_GifContext::DecodeExtension() {
  uint8_t* data_size = nullptr;
  uint8_t* data_buf = nullptr;
  uint32_t skip_size_org = skip_size_;
  switch (decode_status_) {
    case GIF_D_STATUS_EXT_CE: {
      if (!ReadData(&data_size, 1)) {
        skip_size_ = skip_size_org;
        return CFX_GifDecodeStatus::Unfinished;
      }

      cmt_data_.clear();
      while (*data_size != GIF_BLOCK_TERMINAL) {
        uint8_t block_size = *data_size;
        if (!ReadData(&data_buf, *data_size) || !ReadData(&data_size, 1)) {
          skip_size_ = skip_size_org;
          return CFX_GifDecodeStatus::Unfinished;
        }

        cmt_data_ += ByteString(data_buf, block_size);
      }
      break;
    }
    case GIF_D_STATUS_EXT_PTE: {
      CFX_GifPlainTextExtension* gif_pte = nullptr;
      if (!ReadData(reinterpret_cast<uint8_t**>(&gif_pte), 13))
        return CFX_GifDecodeStatus::Unfinished;

      graphic_control_extension_ = nullptr;
      if (!ReadData(&data_size, 1)) {
        skip_size_ = skip_size_org;
        return CFX_GifDecodeStatus::Unfinished;
      }

      while (*data_size != GIF_BLOCK_TERMINAL) {
        if (!ReadData(&data_buf, *data_size) || !ReadData(&data_size, 1)) {
          skip_size_ = skip_size_org;
          return CFX_GifDecodeStatus::Unfinished;
        }
      }
      break;
    }
    case GIF_D_STATUS_EXT_GCE: {
      CFX_GifGraphicControlExtension* gif_gce = nullptr;
      if (!ReadData(reinterpret_cast<uint8_t**>(&gif_gce), 6))
        return CFX_GifDecodeStatus::Unfinished;

      if (!graphic_control_extension_.get())
        graphic_control_extension_ =
            pdfium::MakeUnique<CFX_GifGraphicControlExtension>();
      graphic_control_extension_->block_size = gif_gce->block_size;
      graphic_control_extension_->gce_flags = gif_gce->gce_flags;
      graphic_control_extension_->delay_time =
          FXWORD_GET_LSBFIRST(reinterpret_cast<uint8_t*>(&gif_gce->delay_time));
      graphic_control_extension_->trans_index = gif_gce->trans_index;
      break;
    }
    default: {
      if (decode_status_ == GIF_D_STATUS_EXT_PTE)
        graphic_control_extension_ = nullptr;
      if (!ReadData(&data_size, 1))
        return CFX_GifDecodeStatus::Unfinished;

      while (*data_size != GIF_BLOCK_TERMINAL) {
        if (!ReadData(&data_buf, *data_size) || !ReadData(&data_size, 1)) {
          skip_size_ = skip_size_org;
          return CFX_GifDecodeStatus::Unfinished;
        }
      }
    }
  }
  SaveDecodingStatus(GIF_D_STATUS_SIG);
  return CFX_GifDecodeStatus::Success;
}

CFX_GifDecodeStatus CFX_GifContext::DecodeImageInfo() {
  if (width_ <= 0 || height_ <= 0)
    return CFX_GifDecodeStatus::Error;

  uint32_t skip_size_org = skip_size_;
  CFX_CFX_GifImageInfo* img_info = nullptr;
  if (!ReadData(reinterpret_cast<uint8_t**>(&img_info), 9))
    return CFX_GifDecodeStatus::Unfinished;

  auto gif_image = pdfium::MakeUnique<CFX_GifImage>();
  gif_image->image_info.left =
      FXWORD_GET_LSBFIRST(reinterpret_cast<uint8_t*>(&img_info->left));
  gif_image->image_info.top =
      FXWORD_GET_LSBFIRST(reinterpret_cast<uint8_t*>(&img_info->top));
  gif_image->image_info.width =
      FXWORD_GET_LSBFIRST(reinterpret_cast<uint8_t*>(&img_info->width));
  gif_image->image_info.height =
      FXWORD_GET_LSBFIRST(reinterpret_cast<uint8_t*>(&img_info->height));
  gif_image->image_info.local_flags = img_info->local_flags;
  if (gif_image->image_info.left + gif_image->image_info.width > width_ ||
      gif_image->image_info.top + gif_image->image_info.height > height_)
    return CFX_GifDecodeStatus::Error;

  CFX_GifLocalFlags* gif_img_info_lf = &img_info->local_flags;
  if (gif_img_info_lf->local_pal) {
    gif_image->local_pallette_exp = gif_img_info_lf->pal_bits;
    uint32_t loc_pal_size = unsigned(2 << gif_img_info_lf->pal_bits) * 3u;
    uint8_t* loc_pal = nullptr;
    if (!ReadData(&loc_pal, loc_pal_size)) {
      skip_size_ = skip_size_org;
      return CFX_GifDecodeStatus::Unfinished;
    }

    gif_image->local_palettes = std::vector<CFX_GifPalette>(loc_pal_size / 3);
    std::copy(loc_pal, loc_pal + loc_pal_size,
              reinterpret_cast<uint8_t*>(gif_image->local_palettes.data()));
  }

  uint8_t* code_size = nullptr;
  if (!ReadData(&code_size, 1)) {
    skip_size_ = skip_size_org;
    return CFX_GifDecodeStatus::Unfinished;
  }

  gif_image->code_exp = *code_size;
  RecordCurrentPosition(&gif_image->data_pos);
  gif_image->data_pos += skip_size_;
  gif_image->image_GCE = nullptr;
  if (graphic_control_extension_.get()) {
    gif_image->image_GCE = std::move(graphic_control_extension_);
    graphic_control_extension_ = nullptr;
  }
  images_.push_back(std::move(gif_image));
  SaveDecodingStatus(GIF_D_STATUS_IMG_DATA);
  return CFX_GifDecodeStatus::Success;
}

void CFX_GifContext::DecodingFailureAtTailCleanup(CFX_GifImage* gif_image) {
  gif_image->row_buffer.clear();
  SaveDecodingStatus(GIF_D_STATUS_TAIL);
}
