// 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 "core/fxcrt/stl_util.h"
#include "third_party/base/cxx17_backports.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;

uint32_t CFX_GifContext::CurrentPosition() const {
  return delegate_->GifCurrentPosition();
}

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 trans_index,
                                       bool interlace) {
  return delegate_->GifInputRecordPositionBuf(
      cur_pos, FX_RECT(left, top, left + width, top + height), pal_num, pal,
      trans_index, 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;
      }
    }
  }
}

GifDecoder::Status CFX_GifContext::LoadFrame(int32_t frame_num) {
  if (!fxcrt::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, -1,
          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,
          gif_image->image_GCE->gce_flags.transparency
              ? static_cast<int32_t>(gif_image->image_GCE->trans_index)
              : -1,
          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_ = 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_;
      LZWDecompressor::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_)
              : LZWDecompressor::Status::kError;
      if (ret == LZWDecompressor::Status::kError) {
        DecodingFailureAtTailCleanup(gif_image);
        return GifDecoder::Status::kError;
      }

      while (ret != LZWDecompressor::Status::kError) {
        if (ret == LZWDecompressor::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 == LZWDecompressor::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_ = 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_)
                      : LZWDecompressor::Status::kError;
          }
        }

        if (ret == LZWDecompressor::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_)
                    : LZWDecompressor::Status::kError;
        }

        if (ret == LZWDecompressor::Status::kInsufficientDestSize ||
            ret == LZWDecompressor::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>(
      FXSYS_UINT16_GET_LSBFIRST(reinterpret_cast<uint8_t*>(&lsd.width)));
  height_ = static_cast<int>(
      FXSYS_UINT16_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 = FXSYS_UINT16_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 =
      FXSYS_UINT16_GET_LSBFIRST(reinterpret_cast<uint8_t*>(&img_info.left));
  gif_image->image_info.top =
      FXSYS_UINT16_GET_LSBFIRST(reinterpret_cast<uint8_t*>(&img_info.top));
  gif_image->image_info.width =
      FXSYS_UINT16_GET_LSBFIRST(reinterpret_cast<uint8_t*>(&img_info.width));
  gif_image->image_info.height =
      FXSYS_UINT16_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;
  gif_image->data_pos = CurrentPosition();
  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
