// 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/cfx_codec_memory.h"
#include "third_party/base/stl_util.h"

namespace fxcodec {

namespace {

constexpr int32_t kGifInterlaceStep[4] = {8, 8, 4, 2};

}  // namespace

CFX_GifContext::CFX_GifContext(GifDecoder::Delegate* delegate)
    : delegate_(delegate) {}

CFX_GifContext::~CFX_GifContext() = default;

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

GifDecoder::Status CFX_GifContext::ReadHeader() {
  GifDecoder::Status status = ReadGifSignature();
  if (status != GifDecoder::Status::kSuccess)
    return status;
  return ReadLogicalScreenDescriptor();
}

GifDecoder::Status CFX_GifContext::GetFrame() {
  GifDecoder::Status ret = GifDecoder::Status::kSuccess;
  while (true) {
    switch (decode_status_) {
      case GIF_D_STATUS_TAIL:
        return GifDecoder::Status::kSuccess;
      case GIF_D_STATUS_SIG: {
        uint8_t signature;
        if (!ReadAllOrNone(&signature, sizeof(signature)))
          return GifDecoder::Status::kUnfinished;

        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 GifDecoder::Status::kSuccess;
          default:
            if (!input_buffer_->IsEOF()) {
              // The Gif File has non_standard Tag!
              SaveDecodingStatus(GIF_D_STATUS_SIG);
              continue;
            }
            // The Gif File Doesn't have Trailer Tag!
            return GifDecoder::Status::kSuccess;
        }
      }
      case GIF_D_STATUS_EXT: {
        uint8_t extension;
        if (!ReadAllOrNone(&extension, sizeof(extension)))
          return GifDecoder::Status::kUnfinished;

        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 != GifDecoder::Status::kSuccess)
          return ret;

        continue;
      }
      case GIF_D_STATUS_IMG_DATA: {
        uint8_t img_data_size;
        size_t read_marker = input_buffer_->GetPosition();

        if (!ReadAllOrNone(&img_data_size, sizeof(img_data_size)))
          return GifDecoder::Status::kUnfinished;

        while (img_data_size != GIF_BLOCK_TERMINAL) {
          if (!input_buffer_->Seek(input_buffer_->GetPosition() +
                                   img_data_size)) {
            input_buffer_->Seek(read_marker);
            return GifDecoder::Status::kUnfinished;
          }

          // This saving of the scan state on partial reads is why
          // ScanForTerminalMarker() cannot be used here.
          SaveDecodingStatus(GIF_D_STATUS_IMG_DATA);
          read_marker = input_buffer_->GetPosition();
          if (!ReadAllOrNone(&img_data_size, sizeof(img_data_size)))
            return GifDecoder::Status::kUnfinished;
        }

        SaveDecodingStatus(GIF_D_STATUS_SIG);
        continue;
      }
      default: {
        ret = DecodeExtension();
        if (ret != GifDecoder::Status::kSuccess)
          return ret;
        break;
      }
    }
  }
  return GifDecoder::Status::kSuccess;
}

GifDecoder::Status CFX_GifContext::LoadFrame(int32_t frame_num) {
  if (!pdfium::IndexInBounds(images_, frame_num))
    return GifDecoder::Status::kError;

  CFX_GifImage* gif_image = images_[static_cast<size_t>(frame_num)].get();
  if (gif_image->image_info.height == 0)
    return GifDecoder::Status::kError;

  uint32_t gif_img_row_bytes = gif_image->image_info.width;
  if (gif_img_row_bytes == 0)
    return GifDecoder::Status::kError;

  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;
    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 GifDecoder::Status::kError;
      }
    } 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 GifDecoder::Status::kError;
      }
    }

    if (gif_image->code_exp > GIF_MAX_LZW_EXP) {
      gif_image->row_buffer.clear();
      return GifDecoder::Status::kError;
    }

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

  uint8_t img_data_size;
  std::vector<uint8_t, FxAllocAllocator<uint8_t>> img_data;
  size_t read_marker = input_buffer_->GetPosition();

  if (decode_status_ == GIF_D_STATUS_IMG_DATA) {
    if (!ReadAllOrNone(&img_data_size, sizeof(img_data_size)))
      return GifDecoder::Status::kUnfinished;

    if (img_data_size != GIF_BLOCK_TERMINAL) {
      img_data.resize(img_data_size);
      if (!ReadAllOrNone(img_data.data(), img_data_size)) {
        input_buffer_->Seek(read_marker);
        return GifDecoder::Status::kUnfinished;
      }

      if (!lzw_decompressor_.get()) {
        lzw_decompressor_ = CFX_LZWDecompressor::Create(
            GetPaletteExp(gif_image), 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_;
      GifDecoder::Status ret =
          lzw_decompressor_.get()
              ? lzw_decompressor_->Decode(
                    img_data.data(), img_data_size,
                    gif_image->row_buffer.data() + img_row_offset_,
                    &img_row_avail_size_)
              : GifDecoder::Status::kError;
      if (ret == GifDecoder::Status::kError) {
        DecodingFailureAtTailCleanup(gif_image);
        return GifDecoder::Status::kError;
      }

      while (ret != GifDecoder::Status::kError) {
        if (ret == GifDecoder::Status::kSuccess) {
          ReadScanline(gif_image->row_num, gif_image->row_buffer.data());
          gif_image->row_buffer.clear();
          SaveDecodingStatus(GIF_D_STATUS_TAIL);
          return GifDecoder::Status::kSuccess;
        }

        if (ret == GifDecoder::Status::kUnfinished) {
          read_marker = input_buffer_->GetPosition();
          if (!ReadAllOrNone(&img_data_size, sizeof(img_data_size)))
            return GifDecoder::Status::kUnfinished;

          if (img_data_size != GIF_BLOCK_TERMINAL) {
            img_data.resize(img_data_size);
            if (!ReadAllOrNone(img_data.data(), img_data_size)) {
              input_buffer_->Seek(read_marker);
              return GifDecoder::Status::kUnfinished;
            }

            if (!lzw_decompressor_.get()) {
              lzw_decompressor_ = CFX_LZWDecompressor::Create(
                  GetPaletteExp(gif_image), 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.data(), img_data_size,
                            gif_image->row_buffer.data() + img_row_offset_,
                            &img_row_avail_size_)
                      : GifDecoder::Status::kError;
          }
        }

        if (ret == GifDecoder::Status::kInsufficientDestSize) {
          if (gif_image->image_info.local_flags.interlace) {
            ReadScanline(gif_image->row_num, gif_image->row_buffer.data());
            gif_image->row_num += kGifInterlaceStep[img_pass_num_];
            if (gif_image->row_num >=
                static_cast<int32_t>(gif_image->image_info.height)) {
              img_pass_num_++;
              if (img_pass_num_ == pdfium::size(kGifInterlaceStep)) {
                DecodingFailureAtTailCleanup(gif_image);
                return GifDecoder::Status::kError;
              }
              gif_image->row_num = kGifInterlaceStep[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.data(), img_data_size,
                          gif_image->row_buffer.data() + img_row_offset_,
                          &img_row_avail_size_)
                    : GifDecoder::Status::kError;
        }

        if (ret == GifDecoder::Status::kInsufficientDestSize ||
            ret == GifDecoder::Status::kError) {
          DecodingFailureAtTailCleanup(gif_image);
          return GifDecoder::Status::kError;
        }
      }
    }
    SaveDecodingStatus(GIF_D_STATUS_TAIL);
  }
  return GifDecoder::Status::kError;
}

void CFX_GifContext::SetInputBuffer(RetainPtr<CFX_CodecMemory> codec_memory) {
  input_buffer_ = std::move(codec_memory);
}

uint32_t CFX_GifContext::GetAvailInput() const {
  if (!input_buffer_)
    return 0;

  return input_buffer_->GetSize() - input_buffer_->GetPosition();
}

bool CFX_GifContext::ReadAllOrNone(uint8_t* dest, uint32_t size) {
  if (!input_buffer_ || !dest)
    return false;

  size_t read_marker = input_buffer_->GetPosition();
  size_t read = input_buffer_->ReadBlock(dest, size);
  if (read < size) {
    input_buffer_->Seek(read_marker);
    return false;
  }

  return true;
}

GifDecoder::Status CFX_GifContext::ReadGifSignature() {
  CFX_GifHeader header;
  if (!ReadAllOrNone(reinterpret_cast<uint8_t*>(&header), 6))
    return GifDecoder::Status::kUnfinished;

  if (strncmp(header.signature, kGifSignature87, 6) != 0 &&
      strncmp(header.signature, kGifSignature89, 6) != 0) {
    return GifDecoder::Status::kError;
  }

  return GifDecoder::Status::kSuccess;
}

GifDecoder::Status CFX_GifContext::ReadLogicalScreenDescriptor() {
  CFX_GifLocalScreenDescriptor lsd;
  size_t read_marker = input_buffer_->GetPosition();

  if (!ReadAllOrNone(reinterpret_cast<uint8_t*>(&lsd), sizeof(lsd)))
    return GifDecoder::Status::kUnfinished;

  if (lsd.global_flags.global_pal) {
    uint32_t palette_count = unsigned(2 << lsd.global_flags.pal_bits);
    if (lsd.bc_index >= palette_count)
      return GifDecoder::Status::kError;
    bc_index_ = lsd.bc_index;

    uint32_t palette_size = palette_count * sizeof(CFX_GifPalette);
    std::vector<CFX_GifPalette> palette(palette_count);
    if (!ReadAllOrNone(reinterpret_cast<uint8_t*>(palette.data()),
                       palette_size)) {
      // Roll back the read for the LSD
      input_buffer_->Seek(read_marker);
      return GifDecoder::Status::kUnfinished;
    }

    global_palette_exp_ = lsd.global_flags.pal_bits;
    global_sort_flag_ = lsd.global_flags.sort_flag;
    global_color_resolution_ = lsd.global_flags.color_resolution;
    std::swap(global_palette_, palette);
  }

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

  return GifDecoder::Status::kSuccess;
}

void CFX_GifContext::SaveDecodingStatus(int32_t status) {
  decode_status_ = status;
}

GifDecoder::Status CFX_GifContext::DecodeExtension() {
  size_t read_marker = input_buffer_->GetPosition();

  switch (decode_status_) {
    case GIF_D_STATUS_EXT_CE: {
      if (!ScanForTerminalMarker()) {
        input_buffer_->Seek(read_marker);
        return GifDecoder::Status::kUnfinished;
      }
      break;
    }
    case GIF_D_STATUS_EXT_PTE: {
      CFX_GifPlainTextExtension gif_pte;
      if (!ReadAllOrNone(reinterpret_cast<uint8_t*>(&gif_pte), sizeof(gif_pte)))
        return GifDecoder::Status::kUnfinished;

      graphic_control_extension_ = nullptr;
      if (!ScanForTerminalMarker()) {
        input_buffer_->Seek(read_marker);
        return GifDecoder::Status::kUnfinished;
      }
      break;
    }
    case GIF_D_STATUS_EXT_GCE: {
      CFX_GifGraphicControlExtension gif_gce;
      if (!ReadAllOrNone(reinterpret_cast<uint8_t*>(&gif_gce), sizeof(gif_gce)))
        return GifDecoder::Status::kUnfinished;

      if (!graphic_control_extension_.get())
        graphic_control_extension_ =
            std::make_unique<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 (!ScanForTerminalMarker()) {
        input_buffer_->Seek(read_marker);
        return GifDecoder::Status::kUnfinished;
      }
    }
  }

  SaveDecodingStatus(GIF_D_STATUS_SIG);
  return GifDecoder::Status::kSuccess;
}

GifDecoder::Status CFX_GifContext::DecodeImageInfo() {
  if (width_ <= 0 || height_ <= 0)
    return GifDecoder::Status::kError;

  size_t read_marker = input_buffer_->GetPosition();
  CFX_GifImageInfo img_info;
  if (!ReadAllOrNone(reinterpret_cast<uint8_t*>(&img_info), sizeof(img_info)))
    return GifDecoder::Status::kUnfinished;

  auto gif_image = std::make_unique<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 GifDecoder::Status::kError;

  CFX_GifLocalFlags* gif_img_info_lf = &img_info.local_flags;
  if (gif_img_info_lf->local_pal) {
    gif_image->local_palette_exp = gif_img_info_lf->pal_bits;
    uint32_t loc_pal_count = unsigned(2 << gif_img_info_lf->pal_bits);
    std::vector<CFX_GifPalette> loc_pal(loc_pal_count);
    if (!ReadAllOrNone(reinterpret_cast<uint8_t*>(loc_pal.data()),
                       loc_pal_count * sizeof(CFX_GifPalette))) {
      input_buffer_->Seek(read_marker);
      return GifDecoder::Status::kUnfinished;
    }

    gif_image->local_palettes = std::move(loc_pal);
  }

  uint8_t code_size;
  if (!ReadAllOrNone(&code_size, sizeof(code_size))) {
    input_buffer_->Seek(read_marker);
    return GifDecoder::Status::kUnfinished;
  }

  gif_image->code_exp = code_size;
  RecordCurrentPosition(&gif_image->data_pos);
  gif_image->data_pos += input_buffer_->GetPosition();
  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 << GetPaletteExp(gif_image.get()))) {
        return GifDecoder::Status::kError;
      }
    }
    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 GifDecoder::Status::kSuccess;
}

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

bool CFX_GifContext::ScanForTerminalMarker() {
  uint8_t data_size;

  if (!ReadAllOrNone(&data_size, sizeof(data_size)))
    return false;

  while (data_size != GIF_BLOCK_TERMINAL) {
    if (!input_buffer_->Seek(input_buffer_->GetPosition() + data_size) ||
        !ReadAllOrNone(&data_size, sizeof(data_size))) {
      return false;
    }
  }

  return true;
}

uint8_t CFX_GifContext::GetPaletteExp(CFX_GifImage* gif_image) const {
  return !gif_image->local_palettes.empty() ? gif_image->local_palette_exp
                                            : global_palette_exp_;
}

}  // namespace fxcodec
