// 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() {
  CFX_GifDecodeStatus status = ReadGifSignature();
  if (status != CFX_GifDecodeStatus::Success)
    return status;
  return ReadLogicalScreenDescriptor();
}

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();
  if (gif_image->image_info.height == 0)
    return CFX_GifDecodeStatus::Error;

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

uint8_t* CFX_GifContext::ReadData(uint8_t** des_buf_pp, uint32_t data_size) {
  if (!next_in_)
    return nullptr;
  if (avail_in_ <= skip_size_)
    return nullptr;
  if (!des_buf_pp)
    return nullptr;
  if (data_size == 0)
    return nullptr;
  if (avail_in_ - skip_size_ < data_size)
    return nullptr;

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

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

  if (strncmp(header->signature, kGifSignature87, 6) != 0 &&
      strncmp(header->signature, kGifSignature89, 6) != 0)
    return CFX_GifDecodeStatus::Error;

  return CFX_GifDecodeStatus::Success;
}

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

  if (lsd->global_flags.global_pal) {
    uint32_t palette_count = unsigned(2 << lsd->global_flags.pal_bits);
    if (lsd->bc_index >= palette_count)
      return CFX_GifDecodeStatus::Error;
    bc_index_ = lsd->bc_index;

    uint32_t palette_size = palette_count * 3u;
    uint8_t* palette = nullptr;
    if (!ReadData(&palette, palette_size)) {
      skip_size_ = skip_size_org;
      return CFX_GifDecodeStatus::Unfinished;
    }

    global_pal_exp_ = lsd->global_flags.pal_bits;
    global_sort_flag_ = lsd->global_flags.sort_flag;
    global_color_resolution_ = lsd->global_flags.color_resolution;
    global_palette_.resize(palette_count);
    memcpy(global_palette_.data(), palette, palette_size);
  }

  width_ = static_cast<int>(
      FXWORD_GET_LSBFIRST(reinterpret_cast<uint8_t*>(&lsd->width)));
  height_ = static_cast<int>(
      FXWORD_GET_LSBFIRST(reinterpret_cast<uint8_t*>(&lsd->height)));

  pixel_aspect_ = lsd->pixel_aspect;
  return CFX_GifDecodeStatus::Success;
}

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()) {
    if (graphic_control_extension_->gce_flags.transparency) {
      // Need to test that the color that is going to be transparent is actually
      // in the palette being used.
      if (graphic_control_extension_->trans_index >=
          2 << (gif_image->local_palettes.empty()
                    ? global_pal_exp_
                    : gif_image->local_pallette_exp))
        return CFX_GifDecodeStatus::Error;
    }
    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);
}
