// Copyright 2014 The PDFium Authors
// 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/progressive_decoder.h"

#include <algorithm>
#include <memory>
#include <utility>

#include "build/build_config.h"
#include "core/fxcodec/cfx_codec_memory.h"
#include "core/fxcodec/gif/cfx_gifcontext.h"
#include "core/fxcodec/jpeg/libjpeg_jpeg_context.h"
#include "core/fxcodec/progressive_decoder_context.h"
#include "core/fxcodec/tiff/libtiff_tiff_context.h"
#include "core/fxcrt/check.h"
#include "core/fxcrt/check_op.h"
#include "core/fxcrt/compiler_specific.h"
#include "core/fxcrt/fx_2d_size.h"
#include "core/fxcrt/fx_memcpy_wrappers.h"
#include "core/fxcrt/fx_safe_types.h"
#include "core/fxcrt/fx_stream.h"
#include "core/fxcrt/fx_system.h"
#include "core/fxcrt/notreached.h"
#include "core/fxcrt/numerics/safe_conversions.h"
#include "core/fxcrt/span_util.h"
#include "core/fxcrt/stl_util.h"
#include "core/fxcrt/to_underlying.h"
#include "core/fxge/dib/cfx_cmyk_to_srgb.h"
#include "core/fxge/dib/cfx_dibitmap.h"
#include "core/fxge/dib/fx_dib.h"

#ifndef PDF_ENABLE_XFA
#error "XFA only"
#endif

#if defined(PDF_ENABLE_RUST_BMP)
#include "core/fxcodec/bmp/skia_bmp_context.h"
#else
#include "core/fxcodec/bmp/cfx_bmpcontext.h"
#endif
// TODO(https://crbug.com/444045690): Remove `pdf_enable_rust_png` from the
// condition below once this build mode has been tested and stabilized.
// (Chromium already sets `pdf_use_skia_override = true` so having an extra
// condition avoids affecting the Chromium behavior.)
#if defined(PDF_USE_SKIA) && defined(PDF_ENABLE_RUST_PNG)
#include "core/fxcodec/png/skia_png_context.h"
#else
#include "core/fxcodec/png/libpng_png_context.h"
#endif

namespace fxcodec {

namespace {

constexpr size_t kBlockSize = 4096;

std::unique_ptr<ProgressiveDecoderContext> CreateDecoderContext(
    FXCODEC_IMAGE_TYPE type,
    ProgressiveDecoder* delegate) {
  switch (type) {
    case FXCODEC_IMAGE_BMP:
#if defined(PDF_ENABLE_RUST_BMP)
      return std::make_unique<SkiaBmpContext>(delegate);
#else
      return std::make_unique<CFX_BmpContext>(delegate);
#endif
    case FXCODEC_IMAGE_GIF:
      return std::make_unique<CFX_GifContext>(delegate);
    case FXCODEC_IMAGE_JPG: {
      auto context = std::make_unique<LibjpegJpegContext>(delegate);
      if (!context->create_ok_) {
        return nullptr;
      }
      return context;
    }
    case FXCODEC_IMAGE_PNG:
#if defined(PDF_USE_SKIA) && defined(PDF_ENABLE_RUST_PNG)
      return std::make_unique<SkiaPngContext>(delegate);
#else
    {
      auto context = std::make_unique<LibpngPngContext>(delegate);
      if (!context->png_ || !context->info_) {
        return nullptr;
      }
      return context;
    }
#endif
    default:
      return nullptr;
  }
}

}  // namespace

ProgressiveDecoder::ProgressiveDecoder() = default;

ProgressiveDecoder::~ProgressiveDecoder() = default;

bool ProgressiveDecoder::ReadMoreData(std::optional<uint32_t> rcd_pos,
                                      FXCODEC_STATUS* err_status) {
  if (rcd_pos.has_value()) {
    offset_ = rcd_pos.value();
    codec_memory_->Seek(codec_memory_->GetSize());
  }
  size_t unconsumed_bytes = codec_memory_->GetUnconsumedSpan().size();
  if (!ReadMoreDataInternal(unconsumed_bytes, err_status)) {
    return false;
  }
  if (context_) {
    context_->Input(codec_memory_);
  }
  return true;
}

uint32_t ProgressiveDecoder::GetCurrentInputPosition() const {
  uint32_t remain_size =
      context_ ? pdfium::checked_cast<uint32_t>(context_->GetAvailInput()) : 0;
  return offset_ - remain_size;
}

bool ProgressiveDecoder::PrepareScanlineResampling(
    int src_width,
    int src_height,
    Format src_format,
    pdfium::span<const FX_ARGB> palette,
    std::optional<FX_ARGB> fill_argb) {
  if (!device_bitmap_) {
    return false;
  }
  src_width_ = src_width;
  src_height_ = src_height;
  src_format_ = src_format;
  SetTransMethod();
  decode_buf_.resize(GetScanlineSize());
  FXDIB_ResampleOptions options;
  options.bInterpolateBilinear = true;
  weight_horz_.CalculateWeights(src_width_, 0, src_width_, src_width_, 0,
                                src_width_, options);
  if (!palette.empty()) {
    device_bitmap_->SetPalette(palette);
    src_palette_ = DataVector<FX_ARGB>(palette.begin(), palette.end());
  }
  if (fill_argb.has_value()) {
    device_bitmap_->Clear(fill_argb.value());
  }
  return true;
}

void ProgressiveDecoder::ResampleScanline(
    int line,
    pdfium::span<const uint8_t> src_span) {
  CHECK(device_bitmap_);
  if (line < 0 || line >= src_height_) {
    return;
  }
  int scanline_size = GetScanlineSize();
  fxcrt::Copy(src_span.first(static_cast<size_t>(scanline_size)), decode_buf_);
  ResampleScanline(device_bitmap_, line, decode_buf_, src_format_);
}

bool ProgressiveDecoder::PrepareDirectOutput(int src_width,
                                             int src_height,
                                             Format src_format) {
  if (src_width <= 0 || src_height <= 0 || src_format != Format::kArgb) {
    return false;
  }
  src_width_ = src_width;
  src_height_ = src_height;
  src_format_ = src_format;
  src_bits_per_component_ = 8;
  src_components_count_ = 4;
  return true;
}

pdfium::span<uint8_t> ProgressiveDecoder::AskScanlineBuf(int line) {
  CHECK_GE(line, 0);
  CHECK_LT(line, src_height_);
  CHECK_EQ(device_bitmap_->GetFormat(), FXDIB_Format::kBgra);
  CHECK_EQ(src_format_, Format::kArgb);
  return device_bitmap_->GetWritableScanline(line);
}

pdfium::span<uint8_t> ProgressiveDecoder::AskImageBuf() {
  CHECK_EQ(device_bitmap_->GetFormat(), FXDIB_Format::kBgra);
  CHECK_EQ(src_format_, Format::kArgb);
  return device_bitmap_->GetWritableBuffer();
}

bool ProgressiveDecoder::BmpDetectImageTypeInBuffer(
    CFX_DIBAttribute* pAttribute) {
  std::unique_ptr<ProgressiveDecoderContext> pBmcontext =
      CreateDecoderContext(FXCODEC_IMAGE_BMP, this);
  pBmcontext->Input(codec_memory_);

#if defined(PDF_ENABLE_RUST_BMP)
  auto* ctx = static_cast<SkiaBmpContext*>(pBmcontext.get());
#else
  auto* ctx = static_cast<CFX_BmpContext*>(pBmcontext.get());
#endif

  pdfium::span<const FX_ARGB> palette;
  ProgressiveDecoderContext::Status read_result = ctx->ReadHeader(
      &src_width_, &src_height_, &src_components_count_, &palette, pAttribute);
  while (read_result == ProgressiveDecoderContext::Status::kContinue) {
    FXCODEC_STATUS error_status = FXCODEC_STATUS::kError;
    if (!BmpReadMoreData(pBmcontext.get(), &error_status)) {
      status_ = error_status;
      return false;
    }
    read_result = ctx->ReadHeader(&src_width_, &src_height_,
                                  &src_components_count_, &palette, pAttribute);
  }

  if (read_result != ProgressiveDecoderContext::Status::kSuccess) {
    status_ = FXCODEC_STATUS::kError;
    return false;
  }

  FXDIB_Format format = FXDIB_Format::kInvalid;
  switch (src_components_count_) {
    case 1:
      src_format_ = Format::k8bppRgb;
      format = FXDIB_Format::k8bppRgb;
      break;
    case 3:
      src_format_ = Format::kRgb;
      format = FXDIB_Format::kBgr;
      break;
    case 4:
      src_format_ = Format::kRgb32;
      format = FXDIB_Format::kBgrx;
      break;
    default:
      status_ = FXCODEC_STATUS::kError;
      return false;
  }

  // Set to 0 to make CalculatePitchAndSize() calculate it.
  static constexpr uint32_t kNoPitch = 0;
  std::optional<CFX_DIBitmap::PitchAndSize> needed_data =
      CFX_DIBitmap::CalculatePitchAndSize(src_width_, src_height_, format,
                                          kNoPitch);
  if (!needed_data.has_value()) {
    status_ = FXCODEC_STATUS::kError;
    return false;
  }

  uint32_t available_data = pdfium::checked_cast<uint32_t>(
      file_->GetSize() - offset_ + pBmcontext->GetAvailInput());
  if (needed_data.value().size / src_components_count_ > available_data) {
    status_ = FXCODEC_STATUS::kError;
    return false;
  }

  src_bits_per_component_ = 8;
  context_ = std::move(pBmcontext);
  if (!palette.empty()) {
    src_palette_.resize(palette.size());
    fxcrt::Copy(palette, src_palette_);
  } else {
    src_palette_.clear();
  }
  return true;
}

bool ProgressiveDecoder::BmpReadMoreData(ProgressiveDecoderContext* bmp_context,
                                         FXCODEC_STATUS* err_status) {
  // TODO(lukasza): Can this just use
  // `codec_memory_->GetUnconsumedSpan().size()`? (IIUC this is what
  // `GetAvailInput` uses in the end, but I haven't investigated that this is
  // the same instance of `CFX_CodecMemory`.)
  FX_SAFE_SIZE_T avail_input = bmp_context->GetAvailInput();
  if (!avail_input.IsValid()) {
    return false;
  }
  if (!ReadMoreDataInternal(avail_input.ValueOrDie(), err_status)) {
    return false;
  }
  bmp_context->Input(codec_memory_);
  return true;
}

FXCODEC_STATUS ProgressiveDecoder::BmpStartDecode() {
  SetTransMethod();
  decode_buf_.resize(GetScanlineSize());
  FXDIB_ResampleOptions options;
  options.bInterpolateBilinear = true;
  weight_horz_.CalculateWeights(src_width_, 0, src_width_, src_width_, 0,
                                src_width_, options);
  status_ = FXCODEC_STATUS::kDecodeToBeContinued;
  return status_;
}

FXCODEC_STATUS ProgressiveDecoder::BmpContinueDecode() {
  ProgressiveDecoderContext::Status read_res = context_->DecodeImage();
  while (read_res == ProgressiveDecoderContext::Status::kContinue) {
    FXCODEC_STATUS error_status = FXCODEC_STATUS::kDecodeFinished;
    if (!BmpReadMoreData(context_.get(), &error_status)) {
      device_bitmap_ = nullptr;
      file_ = nullptr;
      status_ = error_status;
      return status_;
    }
    read_res = context_->DecodeImage();
  }

  device_bitmap_ = nullptr;
  file_ = nullptr;
  status_ = read_res == ProgressiveDecoderContext::Status::kSuccess
                ? FXCODEC_STATUS::kDecodeFinished
                : FXCODEC_STATUS::kError;
  return status_;
}

bool ProgressiveDecoder::GifReadMoreData(FXCODEC_STATUS* err_status) {
  // TODO(lukasza): Can this just use
  // `codec_memory_->GetUnconsumedSpan().size()`? (IIUC this is what
  // `GetAvailInput` uses in the end, but I haven't investigated that this is
  // the same instance of `CFX_CodecMemory`.)
  FX_SAFE_SIZE_T avail_input = context_->GetAvailInput();
  if (!avail_input.IsValid()) {
    return false;
  }
  if (!ReadMoreDataInternal(avail_input.ValueOrDie(), err_status)) {
    return false;
  }

  context_->Input(codec_memory_);
  return true;
}

bool ProgressiveDecoder::GifDetectImageTypeInBuffer() {
  context_ = CreateDecoderContext(FXCODEC_IMAGE_GIF, this);
  context_->Input(codec_memory_);
  src_components_count_ = 1;
  auto* ctx = static_cast<CFX_GifContext*>(context_.get());
  ProgressiveDecoderContext::Status readResult =
      ctx->ReadHeader(&src_width_, &src_height_);
  while (readResult == ProgressiveDecoderContext::Status::kContinue) {
    FXCODEC_STATUS error_status = FXCODEC_STATUS::kError;
    if (!GifReadMoreData(&error_status)) {
      context_ = nullptr;
      status_ = error_status;
      return false;
    }
    readResult = ctx->ReadHeader(&src_width_, &src_height_);
  }
  if (readResult == ProgressiveDecoderContext::Status::kSuccess) {
    src_bits_per_component_ = 8;
    return true;
  }
  context_ = nullptr;
  status_ = FXCODEC_STATUS::kError;
  return false;
}

FXCODEC_STATUS ProgressiveDecoder::GifStartDecode() {
  src_format_ = Format::k8bppRgb;
  SetTransMethod();
  decode_buf_.resize(GetScanlineSize());
  FXDIB_ResampleOptions options;
  options.bInterpolateBilinear = true;
  weight_horz_.CalculateWeights(src_width_, 0, src_width_, src_width_, 0,
                                src_width_, options);
  auto* ctx = static_cast<CFX_GifContext*>(context_.get());
  status_ = ctx->StartDecode(device_bitmap_);
  return status_;
}

FXCODEC_STATUS ProgressiveDecoder::GifContinueDecode() {
  auto* ctx = static_cast<CFX_GifContext*>(context_.get());
  status_ = ctx->ContinueDecode();  // Success or error, never continue.
  device_bitmap_ = nullptr;
  file_ = nullptr;
  return status_;
}

bool ProgressiveDecoder::JpegReadMoreData(FXCODEC_STATUS* err_status) {
  FX_SAFE_SIZE_T avail_input = context_->GetAvailInput();
  if (!avail_input.IsValid()) {
    return false;
  }
  if (!ReadMoreDataInternal(avail_input.ValueOrDie(), err_status)) {
    return false;
  }
  context_->Input(codec_memory_);
  return true;
}

bool ProgressiveDecoder::JpegDetectImageTypeInBuffer(
    CFX_DIBAttribute* pAttribute) {
  context_ = CreateDecoderContext(FXCODEC_IMAGE_JPG, this);
  if (!context_) {
    status_ = FXCODEC_STATUS::kError;
    return false;
  }
  context_->Input(codec_memory_);

  auto* ctx = static_cast<LibjpegJpegContext*>(context_.get());
  while (1) {
    int read_result = ctx->ReadHeader(&src_width_, &src_height_,
                                      &src_components_count_, pAttribute);
    switch (read_result) {
      case LibjpegJpegContext::kFatal:
      case LibjpegJpegContext::kError:
        status_ = FXCODEC_STATUS::kError;
        return false;
      case LibjpegJpegContext::kOk:
        src_bits_per_component_ = 8;
        return true;
      case LibjpegJpegContext::kNeedsMoreInput: {
        FXCODEC_STATUS error_status = FXCODEC_STATUS::kError;
        if (!JpegReadMoreData(&error_status)) {
          status_ = error_status;
          return false;
        }
        break;
      }
      default:
        NOTREACHED();
    }
  }
}

FXCODEC_STATUS ProgressiveDecoder::JpegStartDecode() {
  status_ = static_cast<LibjpegJpegContext*>(context_.get())->StartDecode();
  if (status_ == FXCODEC_STATUS::kError) {
    device_bitmap_ = nullptr;
    file_ = nullptr;
    context_.reset();
  }
  return status_;
}

FXCODEC_STATUS ProgressiveDecoder::JpegContinueDecode() {
  status_ = static_cast<LibjpegJpegContext*>(context_.get())->ContinueDecode();
  if (status_ == FXCODEC_STATUS::kError) {
    context_.reset();
  }
  if (status_ != FXCODEC_STATUS::kDecodeToBeContinued) {
    device_bitmap_ = nullptr;
    file_ = nullptr;
  }
  return status_;
}

bool ProgressiveDecoder::PngDetectImageTypeInBuffer() {
  context_ = CreateDecoderContext(FXCODEC_IMAGE_PNG, this);
  if (!context_) {
    status_ = FXCODEC_STATUS::kError;
    return false;
  }

#if defined(PDF_USE_SKIA) && defined(PDF_ENABLE_RUST_PNG)
  auto* ctx = static_cast<SkiaPngContext*>(context_.get());
#else
  auto* ctx = static_cast<LibpngPngContext*>(context_.get());
#endif

  src_width_ = 0;
  src_height_ = 0;
  if (ctx->ReadHeader(codec_memory_)) {
    FXCODEC_STATUS status = FXCODEC_STATUS::kError;
    while (src_width_ == 0 && ReadMoreData(std::nullopt, &status)) {
      if (!ctx->ReadHeader(codec_memory_)) {
        break;
      }
    }
  }

  bool got_metadata = (src_width_ > 0 && src_height_ > 0);
  context_.reset();
  return got_metadata;
}

FXCODEC_STATUS ProgressiveDecoder::PngStartDecode() {
  context_ = CreateDecoderContext(FXCODEC_IMAGE_PNG, this);
  if (!context_) {
    device_bitmap_ = nullptr;
    file_ = nullptr;
    status_ = FXCODEC_STATUS::kError;
    return status_;
  }
  context_->Input(codec_memory_);
#if defined(PDF_USE_SKIA) && defined(PDF_ENABLE_RUST_PNG)
  auto* ctx = static_cast<SkiaPngContext*>(context_.get());
#else
  auto* ctx = static_cast<LibpngPngContext*>(context_.get());
#endif
  status_ = ctx->StartDecode(device_bitmap_);
  return status_;
}

FXCODEC_STATUS ProgressiveDecoder::PngContinueDecode() {
#if defined(PDF_USE_SKIA) && defined(PDF_ENABLE_RUST_PNG)
  auto* ctx = static_cast<SkiaPngContext*>(context_.get());
#else
  auto* ctx = static_cast<LibpngPngContext*>(context_.get());
#endif
  status_ = ctx->ContinueDecode();
  if (status_ != FXCODEC_STATUS::kDecodeToBeContinued) {
    device_bitmap_ = nullptr;
    file_ = nullptr;
  }
  return status_;
}

bool ProgressiveDecoder::TiffDetectImageTypeFromFile(
    CFX_DIBAttribute* pAttribute) {
  auto ctx = std::make_unique<LibtiffTiffContext>();
  if (!ctx->InitDecoder(file_)) {
    status_ = FXCODEC_STATUS::kError;
    return false;
  }
  int32_t dummy_bpc;
  bool ret = ctx->LoadFrameInfo(0, &src_width_, &src_height_,
                                &src_components_count_, &dummy_bpc, pAttribute);
  src_components_count_ = 4;
  if (!ret) {
    status_ = FXCODEC_STATUS::kError;
    return false;
  }
  context_ = std::move(ctx);
  return true;
}

FXCODEC_STATUS ProgressiveDecoder::TiffContinueDecode() {
  // TODO(crbug.com/355630556): Consider adding support for
  // `FXDIB_Format::kBgraPremul`
  CHECK_EQ(device_bitmap_->GetFormat(), FXDIB_Format::kBgra);
  auto* ctx = static_cast<LibtiffTiffContext*>(context_.get());
  status_ = ctx->Decode(std::move(device_bitmap_))
                ? FXCODEC_STATUS::kDecodeFinished
                : FXCODEC_STATUS::kError;
  file_ = nullptr;
  return status_;
}

bool ProgressiveDecoder::DetectImageType(FXCODEC_IMAGE_TYPE imageType,
                                         CFX_DIBAttribute* pAttribute) {
  if (imageType == FXCODEC_IMAGE_TIFF) {
    return TiffDetectImageTypeFromFile(pAttribute);
  }

  size_t size = pdfium::checked_cast<size_t>(
      std::min<FX_FILESIZE>(file_->GetSize(), kBlockSize));
  codec_memory_ = pdfium::MakeRetain<CFX_CodecMemory>(size);
  offset_ = 0;
  if (!file_->ReadBlockAtOffset(codec_memory_->GetBufferSpan().first(size),
                                offset_)) {
    status_ = FXCODEC_STATUS::kError;
    return false;
  }
  offset_ += size;

  if (imageType == FXCODEC_IMAGE_JPG) {
    return JpegDetectImageTypeInBuffer(pAttribute);
  }

  if (imageType == FXCODEC_IMAGE_BMP) {
    return BmpDetectImageTypeInBuffer(pAttribute);
  }
  if (imageType == FXCODEC_IMAGE_GIF) {
    return GifDetectImageTypeInBuffer();
  }
  if (imageType == FXCODEC_IMAGE_PNG) {
    return PngDetectImageTypeInBuffer();
  }

  status_ = FXCODEC_STATUS::kError;
  return false;
}

bool ProgressiveDecoder::ReadMoreDataInternal(size_t unconsumed_bytes,
                                              FXCODEC_STATUS* err_status) {
  // Check for EOF.
  if (offset_ >= static_cast<uint32_t>(file_->GetSize())) {
    return false;
  }

  // Try to get whatever remains.
  uint32_t bytes_to_fetch_from_file =
      pdfium::checked_cast<uint32_t>(file_->GetSize() - offset_);

  if (unconsumed_bytes == codec_memory_->GetSize()) {
    // Codec couldn't make any progress against the bytes in the buffer.
    // Increase the buffer size so that there might be enough contiguous
    // bytes to allow whatever operation is having difficulty to succeed.
    bytes_to_fetch_from_file =
        std::min<uint32_t>(bytes_to_fetch_from_file, kBlockSize);
    size_t new_size = codec_memory_->GetSize() + bytes_to_fetch_from_file;
    if (!codec_memory_->TryResize(new_size)) {
      *err_status = FXCODEC_STATUS::kError;
      return false;
    }
  } else {
    // TODO(crbug.com/42270919): Simplify the `CFX_CodecMemory` API so we
    // don't need to do this awkward dance to free up exactly enough buffer
    // space for the next read.
    size_t already_read_bytes = codec_memory_->GetSize() - unconsumed_bytes;
    bytes_to_fetch_from_file = pdfium::checked_cast<uint32_t>(
        std::min<size_t>(bytes_to_fetch_from_file, already_read_bytes));
    codec_memory_->Consume(bytes_to_fetch_from_file);
    codec_memory_->Seek(already_read_bytes - bytes_to_fetch_from_file);
    unconsumed_bytes += codec_memory_->GetPosition();
  }

  // Append new data past the bytes not yet processed by the codec.
  if (!file_->ReadBlockAtOffset(codec_memory_->GetBufferSpan().subspan(
                                    unconsumed_bytes, bytes_to_fetch_from_file),
                                offset_)) {
    *err_status = FXCODEC_STATUS::kError;
    return false;
  }
  offset_ += bytes_to_fetch_from_file;
  return true;
}

FXCODEC_STATUS ProgressiveDecoder::LoadImageInfo(
    RetainPtr<IFX_SeekableReadStream> pFile,
    FXCODEC_IMAGE_TYPE imageType,
    CFX_DIBAttribute* pAttribute,
    bool bSkipImageTypeCheck) {
  DCHECK(pAttribute);

  switch (status_) {
    case FXCODEC_STATUS::kFrameReady:
    case FXCODEC_STATUS::kFrameToBeContinued:
    case FXCODEC_STATUS::kDecodeReady:
    case FXCODEC_STATUS::kDecodeToBeContinued:
      return FXCODEC_STATUS::kError;
    case FXCODEC_STATUS::kError:
    case FXCODEC_STATUS::kDecodeFinished:
      break;
  }
  file_ = std::move(pFile);
  if (!file_) {
    status_ = FXCODEC_STATUS::kError;
    return status_;
  }
  offset_ = 0;
  src_width_ = 0;
  src_height_ = 0;
  src_components_count_ = 0;
  src_bits_per_component_ = 0;
  if (imageType != FXCODEC_IMAGE_UNKNOWN &&
      DetectImageType(imageType, pAttribute)) {
    image_type_ = imageType;
    status_ = FXCODEC_STATUS::kFrameReady;
    return status_;
  }
  // If we got here then the image data does not match the requested decoder.
  // If we're skipping the type check then bail out at this point and return
  // the failed status.
  if (bSkipImageTypeCheck) {
    return status_;
  }

  for (int type = FXCODEC_IMAGE_UNKNOWN + 1; type < FXCODEC_IMAGE_MAX; type++) {
    if (DetectImageType(static_cast<FXCODEC_IMAGE_TYPE>(type), pAttribute)) {
      image_type_ = static_cast<FXCODEC_IMAGE_TYPE>(type);
      status_ = FXCODEC_STATUS::kFrameReady;
      return status_;
    }
  }
  status_ = FXCODEC_STATUS::kError;
  file_ = nullptr;
  return status_;
}

void ProgressiveDecoder::SetTransMethod() {
  switch (device_bitmap_->GetFormat()) {
    case FXDIB_Format::kInvalid:
    case FXDIB_Format::k1bppMask:
    case FXDIB_Format::k1bppRgb:
    case FXDIB_Format::k8bppMask:
    case FXDIB_Format::k8bppRgb:
      NOTREACHED();
    case FXDIB_Format::kBgr: {
      switch (src_format_) {
        case Format::kInvalid:
          trans_method_ = TransformMethod::kInvalid;
          break;
        case Format::k8bppGray:
          trans_method_ = TransformMethod::k8BppGrayToRgbMaybeAlpha;
          break;
        case Format::k8bppRgb:
          trans_method_ = TransformMethod::k8BppRgbToRgbNoAlpha;
          break;
        case Format::kRgb:
        case Format::kRgb32:
        case Format::kArgb:
          trans_method_ = TransformMethod::kRgbMaybeAlphaToRgbMaybeAlpha;
          break;
        case Format::kCmyk:
          trans_method_ = TransformMethod::kCmykToRgbMaybeAlpha;
          break;
      }
      break;
    }
    case FXDIB_Format::kBgrx:
    case FXDIB_Format::kBgra: {
      switch (src_format_) {
        case Format::kInvalid:
          trans_method_ = TransformMethod::kInvalid;
          break;
        case Format::k8bppGray:
          trans_method_ = TransformMethod::k8BppGrayToRgbMaybeAlpha;
          break;
        case Format::k8bppRgb:
          if (device_bitmap_->GetFormat() == FXDIB_Format::kBgra) {
            trans_method_ = TransformMethod::k8BppRgbToArgb;
          } else {
            trans_method_ = TransformMethod::k8BppRgbToRgbNoAlpha;
          }
          break;
        case Format::kRgb:
        case Format::kRgb32:
          trans_method_ = TransformMethod::kRgbMaybeAlphaToRgbMaybeAlpha;
          break;
        case Format::kCmyk:
          trans_method_ = TransformMethod::kCmykToRgbMaybeAlpha;
          break;
        case Format::kArgb:
          trans_method_ = TransformMethod::kArgbToArgb;
          break;
      }
      break;
    }
#if defined(PDF_USE_SKIA)
    case FXDIB_Format::kBgraPremul:
      // TODO(crbug.com/355630556): Consider adding support for
      // `FXDIB_Format::kBgraPremul`
      NOTREACHED();
#endif
  }
}

void ProgressiveDecoder::ResampleScanline(
    const RetainPtr<CFX_DIBitmap>& pDeviceBitmap,
    int dest_line,
    pdfium::span<uint8_t> src_span,
    Format src_format) {
  uint8_t* src_scan = src_span.data();
  uint8_t* dest_scan = pDeviceBitmap->GetWritableScanline(dest_line).data();
  const auto src_bytes_per_pixel =
      (fxcrt::to_underlying(src_format) & 0xff) / 8;
  const int dest_bytes_per_pixel = pDeviceBitmap->GetBPP() / 8;
  for (int dest_col = 0; dest_col < src_width_; dest_col++) {
    CStretchEngine::PixelWeight* pPixelWeights =
        weight_horz_.GetPixelWeight(dest_col);
    switch (trans_method_) {
      case TransformMethod::kInvalid:
        return;
      case TransformMethod::k8BppGrayToRgbMaybeAlpha: {
        UNSAFE_TODO({
          uint32_t dest_g = 0;
          for (int j = pPixelWeights->src_start_; j <= pPixelWeights->src_end_;
               j++) {
            uint32_t pixel_weight =
                pPixelWeights->weights_[j - pPixelWeights->src_start_];
            dest_g += pixel_weight * src_scan[j];
          }
          FXSYS_memset(dest_scan, CStretchEngine::PixelFromFixed(dest_g), 3);
          dest_scan += dest_bytes_per_pixel;
          break;
        });
      }
      case TransformMethod::k8BppRgbToRgbNoAlpha: {
        UNSAFE_TODO({
          uint32_t dest_r = 0;
          uint32_t dest_g = 0;
          uint32_t dest_b = 0;
          for (int j = pPixelWeights->src_start_; j <= pPixelWeights->src_end_;
               j++) {
            uint32_t pixel_weight =
                pPixelWeights->weights_[j - pPixelWeights->src_start_];
            uint32_t argb = src_palette_[src_scan[j]];
            dest_r += pixel_weight * FXARGB_R(argb);
            dest_g += pixel_weight * FXARGB_G(argb);
            dest_b += pixel_weight * FXARGB_B(argb);
          }
          *dest_scan++ = CStretchEngine::PixelFromFixed(dest_b);
          *dest_scan++ = CStretchEngine::PixelFromFixed(dest_g);
          *dest_scan++ = CStretchEngine::PixelFromFixed(dest_r);
          dest_scan += dest_bytes_per_pixel - 3;
          break;
        });
      }
      case TransformMethod::k8BppRgbToArgb: {
        UNSAFE_TODO({
          uint32_t dest_a = 0;
          uint32_t dest_r = 0;
          uint32_t dest_g = 0;
          uint32_t dest_b = 0;
          for (int j = pPixelWeights->src_start_; j <= pPixelWeights->src_end_;
               j++) {
            uint32_t pixel_weight =
                pPixelWeights->weights_[j - pPixelWeights->src_start_];
            FX_ARGB argb = src_palette_[src_scan[j]];
            dest_a += pixel_weight * FXARGB_A(argb);
            dest_r += pixel_weight * FXARGB_R(argb);
            dest_g += pixel_weight * FXARGB_G(argb);
            dest_b += pixel_weight * FXARGB_B(argb);
          }
          *dest_scan++ = CStretchEngine::PixelFromFixed(dest_b);
          *dest_scan++ = CStretchEngine::PixelFromFixed(dest_g);
          *dest_scan++ = CStretchEngine::PixelFromFixed(dest_r);
          *dest_scan++ = CStretchEngine::PixelFromFixed(dest_a);
          break;
        });
      }
      case TransformMethod::kRgbMaybeAlphaToRgbMaybeAlpha: {
        UNSAFE_TODO({
          uint32_t dest_b = 0;
          uint32_t dest_g = 0;
          uint32_t dest_r = 0;
          for (int j = pPixelWeights->src_start_; j <= pPixelWeights->src_end_;
               j++) {
            uint32_t pixel_weight =
                pPixelWeights->weights_[j - pPixelWeights->src_start_];
            const uint8_t* src_pixel = src_scan + j * src_bytes_per_pixel;
            dest_b += pixel_weight * (*src_pixel++);
            dest_g += pixel_weight * (*src_pixel++);
            dest_r += pixel_weight * (*src_pixel);
          }
          *dest_scan++ = CStretchEngine::PixelFromFixed(dest_b);
          *dest_scan++ = CStretchEngine::PixelFromFixed(dest_g);
          *dest_scan++ = CStretchEngine::PixelFromFixed(dest_r);
          dest_scan += dest_bytes_per_pixel - 3;
          break;
        });
      }
      case TransformMethod::kCmykToRgbMaybeAlpha: {
        UNSAFE_TODO({
          uint32_t dest_b = 0;
          uint32_t dest_g = 0;
          uint32_t dest_r = 0;
          for (int j = pPixelWeights->src_start_; j <= pPixelWeights->src_end_;
               j++) {
            uint32_t pixel_weight =
                pPixelWeights->weights_[j - pPixelWeights->src_start_];
            const uint8_t* src_pixel = src_scan + j * src_bytes_per_pixel;
            FX_RGB_STRUCT<uint8_t> src_rgb =
                AdobeCmykToStandardRgb(255 - src_pixel[0], 255 - src_pixel[1],
                                       255 - src_pixel[2], 255 - src_pixel[3]);
            dest_b += pixel_weight * src_rgb.blue;
            dest_g += pixel_weight * src_rgb.green;
            dest_r += pixel_weight * src_rgb.red;
          }
          *dest_scan++ = CStretchEngine::PixelFromFixed(dest_b);
          *dest_scan++ = CStretchEngine::PixelFromFixed(dest_g);
          *dest_scan++ = CStretchEngine::PixelFromFixed(dest_r);
          dest_scan += dest_bytes_per_pixel - 3;
          break;
        });
      }
      case TransformMethod::kArgbToArgb: {
        UNSAFE_TODO({
          uint32_t dest_alpha = 0;
          uint32_t dest_r = 0;
          uint32_t dest_g = 0;
          uint32_t dest_b = 0;
          for (int j = pPixelWeights->src_start_; j <= pPixelWeights->src_end_;
               j++) {
            uint32_t pixel_weight =
                pPixelWeights->weights_[j - pPixelWeights->src_start_];
            const uint8_t* src_pixel = src_scan + j * src_bytes_per_pixel;
            pixel_weight = pixel_weight * src_pixel[3] / 255;
            dest_b += pixel_weight * (*src_pixel++);
            dest_g += pixel_weight * (*src_pixel++);
            dest_r += pixel_weight * (*src_pixel);
            dest_alpha += pixel_weight;
          }
          *dest_scan++ = CStretchEngine::PixelFromFixed(dest_b);
          *dest_scan++ = CStretchEngine::PixelFromFixed(dest_g);
          *dest_scan++ = CStretchEngine::PixelFromFixed(dest_r);
          *dest_scan++ = CStretchEngine::PixelFromFixed(dest_alpha * 255);
          break;
        });
      }
    }
  }
}

void ProgressiveDecoder::Resample(const RetainPtr<CFX_DIBitmap>& pDeviceBitmap,
                                  int32_t src_line,
                                  uint8_t* src_scan,
                                  Format src_format) {
  if (src_line < 0 || src_line >= src_height_) {
    return;
  }

  ResampleScanline(pDeviceBitmap, src_line, decode_buf_, src_format);
}

FXDIB_Format ProgressiveDecoder::GetBitmapFormat() const {
  switch (image_type_) {
    case FXCODEC_IMAGE_JPG:
    case FXCODEC_IMAGE_BMP:
      return GetBitsPerPixel() <= 24 ? FXDIB_Format::kBgr : FXDIB_Format::kBgrx;
    case FXCODEC_IMAGE_PNG:
    case FXCODEC_IMAGE_TIFF:
    default:
      // TODO(crbug.com/355630556): Consider adding support for
      // `FXDIB_Format::kBgraPremul`
      return FXDIB_Format::kBgra;
  }
}

std::pair<FXCODEC_STATUS, size_t> ProgressiveDecoder::GetFrames() {
  if (!(status_ == FXCODEC_STATUS::kFrameReady ||
        status_ == FXCODEC_STATUS::kFrameToBeContinued)) {
    return {FXCODEC_STATUS::kError, 0};
  }

  switch (image_type_) {
    case FXCODEC_IMAGE_JPG:
    case FXCODEC_IMAGE_BMP:
    case FXCODEC_IMAGE_PNG:
    case FXCODEC_IMAGE_TIFF:
      frame_number_ = 1;
      status_ = FXCODEC_STATUS::kDecodeReady;
      return {status_, 1};
    case FXCODEC_IMAGE_GIF: {
      auto* ctx = static_cast<CFX_GifContext*>(context_.get());
      while (true) {
        ProgressiveDecoderContext::Status readResult = ctx->GetFrame();
        frame_number_ =
            readResult == ProgressiveDecoderContext::Status::kSuccess
                ? ctx->GetFrameNum()
                : 0;
        while (readResult == ProgressiveDecoderContext::Status::kContinue) {
          FXCODEC_STATUS error_status = FXCODEC_STATUS::kError;
          if (!GifReadMoreData(&error_status)) {
            return {error_status, 0};
          }

          readResult = ctx->GetFrame();
          frame_number_ =
              readResult == ProgressiveDecoderContext::Status::kSuccess
                  ? ctx->GetFrameNum()
                  : 0;
        }
        if (readResult == ProgressiveDecoderContext::Status::kSuccess) {
          status_ = FXCODEC_STATUS::kDecodeReady;
          return {status_, frame_number_};
        }
        context_ = nullptr;
        status_ = FXCODEC_STATUS::kError;
        return {status_, 0};
      }
    }
    default:
      return {FXCODEC_STATUS::kError, 0};
  }
}

FXCODEC_STATUS ProgressiveDecoder::StartDecode(RetainPtr<CFX_DIBitmap> bitmap) {
  CHECK(bitmap);
  CHECK_EQ(bitmap->GetWidth(), src_width_);
  CHECK_EQ(bitmap->GetHeight(), src_height_);
  CHECK_GT(src_width_, 0);
  CHECK_GT(src_height_, 0);

  const FXDIB_Format format = bitmap->GetFormat();
  CHECK(format == FXDIB_Format::kBgra || format == FXDIB_Format::kBgr ||
        format == FXDIB_Format::kBgrx);

  if (status_ != FXCODEC_STATUS::kDecodeReady) {
    return FXCODEC_STATUS::kError;
  }

  if (frame_number_ == 0) {
    return FXCODEC_STATUS::kError;
  }

  if (bitmap->GetWidth() > 65535 || bitmap->GetHeight() > 65535) {
    return FXCODEC_STATUS::kError;
  }

  device_bitmap_ = std::move(bitmap);
  switch (image_type_) {
    case FXCODEC_IMAGE_JPG:
      return JpegStartDecode();
    case FXCODEC_IMAGE_BMP:
      return BmpStartDecode();
    case FXCODEC_IMAGE_GIF:
      return GifStartDecode();
    case FXCODEC_IMAGE_PNG:
      return PngStartDecode();
    case FXCODEC_IMAGE_TIFF:
      status_ = FXCODEC_STATUS::kDecodeToBeContinued;
      return status_;
    default:
      return FXCODEC_STATUS::kError;
  }
}

FXCODEC_STATUS ProgressiveDecoder::ContinueDecode() {
  if (status_ != FXCODEC_STATUS::kDecodeToBeContinued) {
    return FXCODEC_STATUS::kError;
  }

  switch (image_type_) {
    case FXCODEC_IMAGE_JPG:
      return JpegContinueDecode();
    case FXCODEC_IMAGE_BMP:
      return BmpContinueDecode();
    case FXCODEC_IMAGE_GIF:
      return GifContinueDecode();
    case FXCODEC_IMAGE_PNG:
      return PngContinueDecode();
    case FXCODEC_IMAGE_TIFF:
      return TiffContinueDecode();
    default:
      return FXCODEC_STATUS::kError;
  }
}

int ProgressiveDecoder::GetScanlineSize() const {
  // Can't be called before basic image metadata is decoded.
  CHECK_NE(src_components_count_, 0);
  CHECK_NE(src_width_, 0);

  FX_SAFE_INT32 result = src_width_;
  result *= src_components_count_;

  return FxAlignToBoundary<4>(result).ValueOrDie();
}

}  // namespace fxcodec
