// Copyright 2014 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/progressivedecoder.h"

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

#include "build/build_config.h"
#include "core/fxcodec/cfx_codec_memory.h"
#include "core/fxcodec/fx_codec.h"
#include "core/fxcrt/fx_safe_types.h"
#include "core/fxcrt/fx_stream.h"
#include "core/fxge/dib/cfx_cmyk_to_srgb.h"
#include "core/fxge/dib/cfx_dibitmap.h"
#include "core/fxge/fx_dib.h"
#include "third_party/base/logging.h"
#include "third_party/base/numerics/safe_math.h"
#include "third_party/base/ptr_util.h"

#define FXCODEC_BLOCK_SIZE 4096

namespace fxcodec {

namespace {

#ifdef PDF_ENABLE_XFA_PNG
#if defined(OS_MACOSX)
const double kPngGamma = 1.7;
#else
const double kPngGamma = 2.2;
#endif  // defined(OS_MACOSX)
#endif  // PDF_ENABLE_XFA_PNG

void RGB2BGR(uint8_t* buffer, int width = 1) {
  if (buffer && width > 0) {
    uint8_t temp;
    int i = 0;
    int j = 0;
    for (; i < width; i++, j += 3) {
      temp = buffer[j];
      buffer[j] = buffer[j + 2];
      buffer[j + 2] = temp;
    }
  }
}

}  // namespace

ProgressiveDecoder::CFXCODEC_WeightTable::CFXCODEC_WeightTable() = default;

ProgressiveDecoder::CFXCODEC_WeightTable::~CFXCODEC_WeightTable() = default;

void ProgressiveDecoder::CFXCODEC_WeightTable::Calc(int dest_len,
                                                    int dest_min,
                                                    int dest_max,
                                                    int src_len,
                                                    int src_min,
                                                    int src_max) {
  double scale, base;
  scale = (float)src_len / (float)dest_len;
  if (dest_len < 0) {
    base = (float)(src_len);
  } else {
    base = 0.0f;
  }
  m_ItemSize =
      (int)(sizeof(int) * 2 + sizeof(int) * (ceil(fabs((float)scale)) + 1));
  m_DestMin = dest_min;
  m_pWeightTables.resize((dest_max - dest_min) * m_ItemSize + 4);
  if (fabs((float)scale) < 1.0f) {
    for (int dest_pixel = dest_min; dest_pixel < dest_max; dest_pixel++) {
      PixelWeight& pixel_weights = *GetPixelWeight(dest_pixel);
      double src_pos = dest_pixel * scale + scale / 2 + base;
      pixel_weights.m_SrcStart = (int)floor((float)src_pos - 1.0f / 2);
      pixel_weights.m_SrcEnd = (int)floor((float)src_pos + 1.0f / 2);
      if (pixel_weights.m_SrcStart < src_min) {
        pixel_weights.m_SrcStart = src_min;
      }
      if (pixel_weights.m_SrcEnd >= src_max) {
        pixel_weights.m_SrcEnd = src_max - 1;
      }
      if (pixel_weights.m_SrcStart == pixel_weights.m_SrcEnd) {
        pixel_weights.m_Weights[0] = 65536;
      } else {
        pixel_weights.m_Weights[1] = FXSYS_round(
            (float)(src_pos - pixel_weights.m_SrcStart - 1.0f / 2) * 65536);
        pixel_weights.m_Weights[0] = 65536 - pixel_weights.m_Weights[1];
      }
    }
    return;
  }
  for (int dest_pixel = dest_min; dest_pixel < dest_max; dest_pixel++) {
    PixelWeight& pixel_weights = *GetPixelWeight(dest_pixel);
    double src_start = dest_pixel * scale + base;
    double src_end = src_start + scale;
    int start_i, end_i;
    if (src_start < src_end) {
      start_i = (int)floor((float)src_start);
      end_i = (int)ceil((float)src_end);
    } else {
      start_i = (int)floor((float)src_end);
      end_i = (int)ceil((float)src_start);
    }
    if (start_i < src_min) {
      start_i = src_min;
    }
    if (end_i >= src_max) {
      end_i = src_max - 1;
    }
    if (start_i > end_i) {
      pixel_weights.m_SrcStart = start_i;
      pixel_weights.m_SrcEnd = start_i;
      continue;
    }
    pixel_weights.m_SrcStart = start_i;
    pixel_weights.m_SrcEnd = end_i;
    for (int j = start_i; j <= end_i; j++) {
      double dest_start = ((float)j - base) / scale;
      double dest_end = ((float)(j + 1) - base) / scale;
      if (dest_start > dest_end) {
        double temp = dest_start;
        dest_start = dest_end;
        dest_end = temp;
      }
      double area_start =
          dest_start > (float)(dest_pixel) ? dest_start : (float)(dest_pixel);
      double area_end = dest_end > (float)(dest_pixel + 1)
                            ? (float)(dest_pixel + 1)
                            : dest_end;
      double weight = area_start >= area_end ? 0.0f : area_end - area_start;
      if (weight == 0 && j == end_i) {
        pixel_weights.m_SrcEnd--;
        break;
      }
      pixel_weights.m_Weights[j - start_i] =
          FXSYS_round((float)(weight * 65536));
    }
  }
}

ProgressiveDecoder::CFXCODEC_HorzTable::CFXCODEC_HorzTable() = default;

ProgressiveDecoder::CFXCODEC_HorzTable::~CFXCODEC_HorzTable() = default;

void ProgressiveDecoder::CFXCODEC_HorzTable::Calc(int dest_len, int src_len) {
  double scale = (double)dest_len / (double)src_len;
  m_ItemSize = sizeof(int) * 4;
  int size = dest_len * m_ItemSize + 4;
  m_pWeightTables.resize(size, 0);
  if (scale > 1) {
    int pre_dest_col = 0;
    for (int src_col = 0; src_col < src_len; src_col++) {
      double dest_col_f = src_col * scale;
      int dest_col = FXSYS_round((float)dest_col_f);
      PixelWeight* pWeight = GetPixelWeight(dest_col);
      pWeight->m_SrcStart = pWeight->m_SrcEnd = src_col;
      pWeight->m_Weights[0] = 65536;
      pWeight->m_Weights[1] = 0;
      if (src_col == src_len - 1 && dest_col < dest_len - 1) {
        for (int dest_col_index = pre_dest_col + 1; dest_col_index < dest_len;
             dest_col_index++) {
          pWeight = GetPixelWeight(dest_col_index);
          pWeight->m_SrcStart = pWeight->m_SrcEnd = src_col;
          pWeight->m_Weights[0] = 65536;
          pWeight->m_Weights[1] = 0;
        }
        return;
      }
      int dest_col_len = dest_col - pre_dest_col;
      for (int dest_col_index = pre_dest_col + 1; dest_col_index < dest_col;
           dest_col_index++) {
        pWeight = GetPixelWeight(dest_col_index);
        pWeight->m_SrcStart = src_col - 1;
        pWeight->m_SrcEnd = src_col;
        pWeight->m_Weights[0] =
            FXSYS_round((float)(((float)dest_col - (float)dest_col_index) /
                                (float)dest_col_len * 65536));
        pWeight->m_Weights[1] = 65536 - pWeight->m_Weights[0];
      }
      pre_dest_col = dest_col;
    }
    return;
  }
  for (int dest_col = 0; dest_col < dest_len; dest_col++) {
    double src_col_f = dest_col / scale;
    int src_col = FXSYS_round((float)src_col_f);
    PixelWeight* pWeight = GetPixelWeight(dest_col);
    pWeight->m_SrcStart = pWeight->m_SrcEnd = src_col;
    pWeight->m_Weights[0] = 65536;
    pWeight->m_Weights[1] = 0;
  }
}

ProgressiveDecoder::CFXCODEC_VertTable::CFXCODEC_VertTable() = default;

ProgressiveDecoder::CFXCODEC_VertTable::~CFXCODEC_VertTable() = default;

void ProgressiveDecoder::CFXCODEC_VertTable::Calc(int dest_len, int src_len) {
  double scale = (double)dest_len / (double)src_len;
  m_ItemSize = sizeof(int) * 4;
  int size = dest_len * m_ItemSize + 4;
  m_pWeightTables.resize(size, 0);
  if (scale <= 1) {
    for (int dest_row = 0; dest_row < dest_len; dest_row++) {
      PixelWeight* pWeight = GetPixelWeight(dest_row);
      pWeight->m_SrcStart = dest_row;
      pWeight->m_SrcEnd = dest_row;
      pWeight->m_Weights[0] = 65536;
      pWeight->m_Weights[1] = 0;
    }
    return;
  }

  double step = 0.0;
  int src_row = 0;
  while (step < (double)dest_len) {
    int start_step = (int)step;
    step = scale * (++src_row);
    int end_step = (int)step;
    if (end_step >= dest_len) {
      end_step = dest_len;
      for (int dest_row = start_step; dest_row < end_step; dest_row++) {
        PixelWeight* pWeight = GetPixelWeight(dest_row);
        pWeight->m_SrcStart = start_step;
        pWeight->m_SrcEnd = start_step;
        pWeight->m_Weights[0] = 65536;
        pWeight->m_Weights[1] = 0;
      }
      return;
    }
    int length = end_step - start_step;
    {
      PixelWeight* pWeight = GetPixelWeight(start_step);
      pWeight->m_SrcStart = start_step;
      pWeight->m_SrcEnd = start_step;
      pWeight->m_Weights[0] = 65536;
      pWeight->m_Weights[1] = 0;
    }
    for (int dest_row = start_step + 1; dest_row < end_step; dest_row++) {
      PixelWeight* pWeight = GetPixelWeight(dest_row);
      pWeight->m_SrcStart = start_step;
      pWeight->m_SrcEnd = end_step;
      pWeight->m_Weights[0] =
          FXSYS_round((float)(end_step - dest_row) / (float)length * 65536);
      pWeight->m_Weights[1] = 65536 - pWeight->m_Weights[0];
    }
  }
}

ProgressiveDecoder::ProgressiveDecoder(ModuleMgr* pCodecMgr)
    : m_pCodecMgr(pCodecMgr) {}

ProgressiveDecoder::~ProgressiveDecoder() = default;

#ifdef PDF_ENABLE_XFA_PNG
bool ProgressiveDecoder::PngReadHeader(int width,
                                       int height,
                                       int bpc,
                                       int pass,
                                       int* color_type,
                                       double* gamma) {
  if (!m_pDeviceBitmap) {
    m_SrcWidth = width;
    m_SrcHeight = height;
    m_SrcBPC = bpc;
    m_SrcPassNumber = pass;
    switch (*color_type) {
      case 0:
        m_SrcComponents = 1;
        break;
      case 4:
        m_SrcComponents = 2;
        break;
      case 2:
        m_SrcComponents = 3;
        break;
      case 3:
      case 6:
        m_SrcComponents = 4;
        break;
      default:
        m_SrcComponents = 0;
        break;
    }
    m_clipBox = FX_RECT(0, 0, width, height);
    return false;
  }
  FXDIB_Format format = m_pDeviceBitmap->GetFormat();
  switch (format) {
    case FXDIB_1bppMask:
    case FXDIB_1bppRgb:
      NOTREACHED();
      return false;
    case FXDIB_8bppMask:
    case FXDIB_8bppRgb:
      *color_type = 0;
      break;
    case FXDIB_Rgb:
      *color_type = 2;
      break;
    case FXDIB_Rgb32:
    case FXDIB_Argb:
      *color_type = 6;
      break;
    default:
      NOTREACHED();
      return false;
  }
  *gamma = kPngGamma;
  return true;
}

bool ProgressiveDecoder::PngAskScanlineBuf(int line, uint8_t** pSrcBuf) {
  RetainPtr<CFX_DIBitmap> pDIBitmap = m_pDeviceBitmap;
  if (!pDIBitmap) {
    NOTREACHED();
    return false;
  }
  if (line >= m_clipBox.top && line < m_clipBox.bottom) {
    double scale_y = static_cast<double>(m_sizeY) / m_clipBox.Height();
    int32_t row = (int32_t)((line - m_clipBox.top) * scale_y) + m_startY;
    const uint8_t* src_scan = pDIBitmap->GetScanline(row);
    uint8_t* dest_scan = m_pDecodeBuf.get();
    *pSrcBuf = m_pDecodeBuf.get();
    int32_t src_Bpp = pDIBitmap->GetBPP() >> 3;
    int32_t dest_Bpp = (m_SrcFormat & 0xff) >> 3;
    int32_t src_left = m_startX;
    int32_t dest_left = m_clipBox.left;
    src_scan += src_left * src_Bpp;
    dest_scan += dest_left * dest_Bpp;
    for (int32_t src_col = 0; src_col < m_sizeX; src_col++) {
      PixelWeight* pPixelWeights = m_WeightHorzOO.GetPixelWeight(src_col);
      if (pPixelWeights->m_SrcStart != pPixelWeights->m_SrcEnd) {
        continue;
      }
      switch (pDIBitmap->GetFormat()) {
        case FXDIB_1bppMask:
        case FXDIB_1bppRgb:
          NOTREACHED();
          return false;
        case FXDIB_8bppMask:
        case FXDIB_8bppRgb: {
          if (pDIBitmap->GetPalette()) {
            return false;
          }
          uint32_t dest_g = 0;
          dest_g += pPixelWeights->m_Weights[0] * src_scan[src_col];
          dest_scan[pPixelWeights->m_SrcStart] = (uint8_t)(dest_g >> 16);
        } break;
        case FXDIB_Rgb:
        case FXDIB_Rgb32: {
          uint32_t dest_b = 0;
          uint32_t dest_g = 0;
          uint32_t dest_r = 0;
          const uint8_t* p = src_scan + src_col * src_Bpp;
          dest_b += pPixelWeights->m_Weights[0] * (*p++);
          dest_g += pPixelWeights->m_Weights[0] * (*p++);
          dest_r += pPixelWeights->m_Weights[0] * (*p);
          uint8_t* pDes = &dest_scan[pPixelWeights->m_SrcStart * dest_Bpp];
          *pDes++ = (uint8_t)((dest_b) >> 16);
          *pDes++ = (uint8_t)((dest_g) >> 16);
          *pDes = (uint8_t)((dest_r) >> 16);
        } break;
        case FXDIB_Argb: {
          uint32_t dest_r = 0;
          uint32_t dest_g = 0;
          uint32_t dest_b = 0;
          const uint8_t* p = src_scan + src_col * src_Bpp;
          dest_b += pPixelWeights->m_Weights[0] * (*p++);
          dest_g += pPixelWeights->m_Weights[0] * (*p++);
          dest_r += pPixelWeights->m_Weights[0] * (*p++);
          uint8_t* pDes = &dest_scan[pPixelWeights->m_SrcStart * dest_Bpp];
          *pDes++ = (uint8_t)((dest_b) >> 16);
          *pDes++ = (uint8_t)((dest_g) >> 16);
          *pDes++ = (uint8_t)((dest_r) >> 16);
          *pDes = *p;
        } break;
        default:
          return false;
      }
    }
  }
  return true;
}

void ProgressiveDecoder::PngFillScanlineBufCompleted(int pass, int line) {
  RetainPtr<CFX_DIBitmap> pDIBitmap = m_pDeviceBitmap;
  ASSERT(pDIBitmap);
  int src_top = m_clipBox.top;
  int src_bottom = m_clipBox.bottom;
  int dest_top = m_startY;
  int src_height = m_clipBox.Height();
  int dest_height = m_sizeY;
  if (line >= src_top && line < src_bottom) {
    double scale_y = static_cast<double>(dest_height) / src_height;
    int src_row = line - src_top;
    int dest_row = (int)(src_row * scale_y) + dest_top;
    if (dest_row >= dest_top + dest_height) {
      return;
    }
    PngOneOneMapResampleHorz(pDIBitmap, dest_row, m_pDecodeBuf.get(),
                             m_SrcFormat);
    if (m_SrcPassNumber == 1 && scale_y > 1.0) {
      ResampleVert(pDIBitmap, scale_y, dest_row);
      return;
    }
    if (pass == 6 && scale_y > 1.0) {
      ResampleVert(pDIBitmap, scale_y, dest_row);
    }
  }
}
#endif  // PDF_ENABLE_XFA_PNG

#ifdef PDF_ENABLE_XFA_GIF
void ProgressiveDecoder::GifRecordCurrentPosition(uint32_t& cur_pos) {
  uint32_t remain_size =
      m_pCodecMgr->GetGifModule()->GetAvailInput(m_pGifContext.get());
  cur_pos = m_offSet - remain_size;
}

bool ProgressiveDecoder::GifInputRecordPositionBuf(uint32_t rcd_pos,
                                                   const FX_RECT& img_rc,
                                                   int32_t pal_num,
                                                   CFX_GifPalette* pal_ptr,
                                                   int32_t delay_time,
                                                   bool user_input,
                                                   int32_t trans_index,
                                                   int32_t disposal_method,
                                                   bool interlace) {
  m_offSet = rcd_pos;
  m_InvalidateGifBuffer = true;

  FXCODEC_STATUS error_status = FXCODEC_STATUS_ERROR;
  if (!GifReadMoreData(m_pCodecMgr->GetGifModule(), error_status)) {
    return false;
  }
  CFX_GifPalette* pPalette = nullptr;
  if (pal_num != 0 && pal_ptr) {
    pPalette = pal_ptr;
  } else {
    if (!m_pGifPalette)
      return false;
    pal_num = m_GifPltNumber;
    pPalette = m_pGifPalette;
  }
  if (!m_pSrcPalette)
    m_pSrcPalette.reset(FX_Alloc(FX_ARGB, pal_num));
  else if (pal_num > m_SrcPaletteNumber)
    m_pSrcPalette.reset(FX_Realloc(FX_ARGB, m_pSrcPalette.release(), pal_num));
  if (!m_pSrcPalette)
    return false;

  m_SrcPaletteNumber = pal_num;
  for (int i = 0; i < pal_num; i++) {
    m_pSrcPalette.get()[i] =
        ArgbEncode(0xff, pPalette[i].r, pPalette[i].g, pPalette[i].b);
  }
  m_GifTransIndex = trans_index;
  m_GifFrameRect = img_rc;
  m_SrcPassNumber = interlace ? 4 : 1;
  int32_t pal_index = m_GifBgIndex;
  RetainPtr<CFX_DIBitmap> pDevice = m_pDeviceBitmap;
  if (trans_index >= pal_num)
    trans_index = -1;
  if (trans_index != -1) {
    m_pSrcPalette.get()[trans_index] &= 0x00ffffff;
    if (pDevice->HasAlpha())
      pal_index = trans_index;
  }
  if (pal_index >= pal_num)
    return false;

  int startX = m_startX;
  int startY = m_startY;
  int sizeX = m_sizeX;
  int sizeY = m_sizeY;
  int Bpp = pDevice->GetBPP() / 8;
  FX_ARGB argb = m_pSrcPalette.get()[pal_index];
  for (int row = 0; row < sizeY; row++) {
    uint8_t* pScanline =
        pDevice->GetWritableScanline(row + startY) + startX * Bpp;
    switch (m_TransMethod) {
      case 3: {
        uint8_t gray =
            FXRGB2GRAY(FXARGB_R(argb), FXARGB_G(argb), FXARGB_B(argb));
        memset(pScanline, gray, sizeX);
        break;
      }
      case 8: {
        for (int col = 0; col < sizeX; col++) {
          *pScanline++ = FXARGB_B(argb);
          *pScanline++ = FXARGB_G(argb);
          *pScanline++ = FXARGB_R(argb);
          pScanline += Bpp - 3;
        }
        break;
      }
      case 12: {
        for (int col = 0; col < sizeX; col++) {
          FXARGB_SETDIB(pScanline, argb);
          pScanline += 4;
        }
        break;
      }
    }
  }
  return true;
}

void ProgressiveDecoder::GifReadScanline(int32_t row_num, uint8_t* row_buf) {
  RetainPtr<CFX_DIBitmap> pDIBitmap = m_pDeviceBitmap;
  ASSERT(pDIBitmap);
  int32_t img_width = m_GifFrameRect.Width();
  if (!pDIBitmap->HasAlpha()) {
    uint8_t* byte_ptr = row_buf;
    for (int i = 0; i < img_width; i++) {
      if (*byte_ptr == m_GifTransIndex) {
        *byte_ptr = m_GifBgIndex;
      }
      byte_ptr++;
    }
  }
  int32_t pal_index = m_GifBgIndex;
  if (m_GifTransIndex != -1 && m_pDeviceBitmap->HasAlpha()) {
    pal_index = m_GifTransIndex;
  }
  memset(m_pDecodeBuf.get(), pal_index, m_SrcWidth);
  bool bLastPass = (row_num % 2) == 1;
  int32_t line = row_num + m_GifFrameRect.top;
  int32_t left = m_GifFrameRect.left;
  memcpy(m_pDecodeBuf.get() + left, row_buf, img_width);
  int src_top = m_clipBox.top;
  int src_bottom = m_clipBox.bottom;
  int dest_top = m_startY;
  int src_height = m_clipBox.Height();
  int dest_height = m_sizeY;
  if (line < src_top || line >= src_bottom)
    return;

  double scale_y = static_cast<double>(dest_height) / src_height;
  int src_row = line - src_top;
  int dest_row = (int)(src_row * scale_y) + dest_top;
  if (dest_row >= dest_top + dest_height)
    return;

  ReSampleScanline(pDIBitmap, dest_row, m_pDecodeBuf.get(), m_SrcFormat);
  if (scale_y > 1.0 && m_SrcPassNumber == 1) {
    ResampleVert(pDIBitmap, scale_y, dest_row);
    return;
  }
  if (scale_y <= 1.0)
    return;

  int dest_bottom = dest_top + m_sizeY;
  int dest_Bpp = pDIBitmap->GetBPP() >> 3;
  uint32_t dest_ScanOffet = m_startX * dest_Bpp;
  if (dest_row + (int)scale_y >= dest_bottom - 1) {
    const uint8_t* scan_src = pDIBitmap->GetScanline(dest_row) + dest_ScanOffet;
    int cur_row = dest_row;
    while (++cur_row < dest_bottom) {
      uint8_t* scan_des =
          pDIBitmap->GetWritableScanline(cur_row) + dest_ScanOffet;
      uint32_t size = m_sizeX * dest_Bpp;
      memmove(scan_des, scan_src, size);
    }
  }
  if (bLastPass)
    GifDoubleLineResampleVert(pDIBitmap, scale_y, dest_row);
}
#endif  // PDF_ENABLE_XFA_GIF

#ifdef PDF_ENABLE_XFA_BMP
bool ProgressiveDecoder::BmpInputImagePositionBuf(uint32_t rcd_pos) {
  m_offSet = rcd_pos;
  FXCODEC_STATUS error_status = FXCODEC_STATUS_ERROR;
  return BmpReadMoreData(m_pCodecMgr->GetBmpModule(), m_pBmpContext.get(),
                         error_status);
}

void ProgressiveDecoder::BmpReadScanline(uint32_t row_num,
                                         const std::vector<uint8_t>& row_buf) {
  RetainPtr<CFX_DIBitmap> pDIBitmap = m_pDeviceBitmap;
  ASSERT(pDIBitmap);
  std::copy(row_buf.begin(), row_buf.begin() + m_ScanlineSize,
            m_pDecodeBuf.get());
  int src_top = m_clipBox.top;
  int src_bottom = m_clipBox.bottom;
  int dest_top = m_startY;
  int src_height = m_clipBox.Height();
  int dest_height = m_sizeY;
  if ((src_top >= 0 && row_num < static_cast<uint32_t>(src_top)) ||
      src_bottom < 0 || row_num >= static_cast<uint32_t>(src_bottom)) {
    return;
  }

  double scale_y = static_cast<double>(dest_height) / src_height;
  int src_row = row_num - src_top;
  int dest_row = (int)(src_row * scale_y) + dest_top;
  if (dest_row >= dest_top + dest_height)
    return;

  ReSampleScanline(pDIBitmap, dest_row, m_pDecodeBuf.get(), m_SrcFormat);
  if (scale_y <= 1.0)
    return;

  if (m_BmpIsTopBottom) {
    ResampleVert(pDIBitmap, scale_y, dest_row);
    return;
  }
  ResampleVertBT(pDIBitmap, scale_y, dest_row);
}

void ProgressiveDecoder::ResampleVertBT(
    const RetainPtr<CFX_DIBitmap>& pDeviceBitmap,
    double scale_y,
    int dest_row) {
  int dest_Bpp = pDeviceBitmap->GetBPP() >> 3;
  uint32_t dest_ScanOffet = m_startX * dest_Bpp;
  int dest_top = m_startY;
  int dest_bottom = m_startY + m_sizeY;
  pdfium::base::CheckedNumeric<int> check_dest_row_1 = dest_row;
  check_dest_row_1 += pdfium::base::checked_cast<int>(scale_y);
  int dest_row_1 = check_dest_row_1.ValueOrDie();
  if (dest_row_1 >= dest_bottom - 1) {
    const uint8_t* scan_src =
        pDeviceBitmap->GetScanline(dest_row) + dest_ScanOffet;
    while (++dest_row < dest_bottom) {
      uint8_t* scan_des =
          pDeviceBitmap->GetWritableScanline(dest_row) + dest_ScanOffet;
      uint32_t size = m_sizeX * dest_Bpp;
      memmove(scan_des, scan_src, size);
    }
    return;
  }
  for (; dest_row_1 > dest_row; dest_row_1--) {
    uint8_t* scan_des =
        pDeviceBitmap->GetWritableScanline(dest_row_1) + dest_ScanOffet;
    PixelWeight* pWeight = m_WeightVert.GetPixelWeight(dest_row_1 - dest_top);
    const uint8_t* scan_src1 =
        pDeviceBitmap->GetScanline(pWeight->m_SrcStart + dest_top) +
        dest_ScanOffet;
    const uint8_t* scan_src2 =
        pDeviceBitmap->GetScanline(pWeight->m_SrcEnd + dest_top) +
        dest_ScanOffet;
    for (int dest_col = 0; dest_col < m_sizeX; dest_col++) {
      switch (pDeviceBitmap->GetFormat()) {
        case FXDIB_Invalid:
        case FXDIB_1bppMask:
        case FXDIB_1bppRgb:
          return;
        case FXDIB_8bppMask:
        case FXDIB_8bppRgb: {
          if (pDeviceBitmap->GetPalette()) {
            return;
          }
          int dest_g = 0;
          dest_g += pWeight->m_Weights[0] * (*scan_src1++);
          dest_g += pWeight->m_Weights[1] * (*scan_src2++);
          *scan_des++ = (uint8_t)(dest_g >> 16);
        } break;
        case FXDIB_Rgb:
        case FXDIB_Rgb32: {
          uint32_t dest_b = 0;
          uint32_t dest_g = 0;
          uint32_t dest_r = 0;
          dest_b += pWeight->m_Weights[0] * (*scan_src1++);
          dest_g += pWeight->m_Weights[0] * (*scan_src1++);
          dest_r += pWeight->m_Weights[0] * (*scan_src1++);
          scan_src1 += dest_Bpp - 3;
          dest_b += pWeight->m_Weights[1] * (*scan_src2++);
          dest_g += pWeight->m_Weights[1] * (*scan_src2++);
          dest_r += pWeight->m_Weights[1] * (*scan_src2++);
          scan_src2 += dest_Bpp - 3;
          *scan_des++ = (uint8_t)((dest_b) >> 16);
          *scan_des++ = (uint8_t)((dest_g) >> 16);
          *scan_des++ = (uint8_t)((dest_r) >> 16);
          scan_des += dest_Bpp - 3;
        } break;
        case FXDIB_Argb: {
          uint32_t dest_a = 0;
          uint32_t dest_b = 0;
          uint32_t dest_g = 0;
          uint32_t dest_r = 0;
          dest_b += pWeight->m_Weights[0] * (*scan_src1++);
          dest_g += pWeight->m_Weights[0] * (*scan_src1++);
          dest_r += pWeight->m_Weights[0] * (*scan_src1++);
          dest_a += pWeight->m_Weights[0] * (*scan_src1++);
          dest_b += pWeight->m_Weights[1] * (*scan_src2++);
          dest_g += pWeight->m_Weights[1] * (*scan_src2++);
          dest_r += pWeight->m_Weights[1] * (*scan_src2++);
          dest_a += pWeight->m_Weights[1] * (*scan_src2++);
          *scan_des++ = (uint8_t)((dest_b) >> 16);
          *scan_des++ = (uint8_t)((dest_g) >> 16);
          *scan_des++ = (uint8_t)((dest_r) >> 16);
          *scan_des++ = (uint8_t)((dest_a) >> 16);
        } break;
        default:
          return;
      }
    }
  }
}

bool ProgressiveDecoder::BmpDetectImageTypeInBuffer(
    CFX_DIBAttribute* pAttribute) {
  BmpModule* pBmpModule = m_pCodecMgr->GetBmpModule();
  if (!pBmpModule) {
    m_status = FXCODEC_STATUS_ERR_MEMORY;
    return false;
  }

  std::unique_ptr<ModuleIface::Context> pBmpContext = pBmpModule->Start(this);
  pBmpModule->Input(pBmpContext.get(), m_pCodecMemory, nullptr);

  const std::vector<uint32_t>* palette;
  BmpModule::Status read_result = pBmpModule->ReadHeader(
      pBmpContext.get(), &m_SrcWidth, &m_SrcHeight, &m_BmpIsTopBottom,
      &m_SrcComponents, &m_SrcPaletteNumber, &palette, pAttribute);
  while (read_result == BmpModule::Status::kContinue) {
    FXCODEC_STATUS error_status = FXCODEC_STATUS_ERR_FORMAT;
    if (!BmpReadMoreData(pBmpModule, pBmpContext.get(), error_status)) {
      m_status = error_status;
      return false;
    }
    read_result = pBmpModule->ReadHeader(
        pBmpContext.get(), &m_SrcWidth, &m_SrcHeight, &m_BmpIsTopBottom,
        &m_SrcComponents, &m_SrcPaletteNumber, &palette, pAttribute);
  }

  if (read_result != BmpModule::Status::kSuccess) {
    m_status = FXCODEC_STATUS_ERR_FORMAT;
    return false;
  }

  FXDIB_Format format = FXDIB_Invalid;
  switch (m_SrcComponents) {
    case 1:
      m_SrcFormat = FXCodec_8bppRgb;
      format = FXDIB_8bppRgb;
      break;
    case 3:
      m_SrcFormat = FXCodec_Rgb;
      format = FXDIB_Rgb;
      break;
    case 4:
      m_SrcFormat = FXCodec_Rgb32;
      format = FXDIB_Rgb32;
      break;
    default:
      m_status = FXCODEC_STATUS_ERR_FORMAT;
      return false;
  }

  uint32_t pitch = 0;
  uint32_t neededData = 0;
  if (!CFX_DIBitmap::CalculatePitchAndSize(m_SrcWidth, m_SrcHeight, format,
                                           &pitch, &neededData)) {
    m_status = FXCODEC_STATUS_ERR_FORMAT;
    return false;
  }

  uint32_t availableData = m_pCodecMemory->GetSize() > m_offSet
                               ? m_pCodecMemory->GetSize() - m_offSet
                               : 0;
  if (neededData > availableData) {
    m_status = FXCODEC_STATUS_ERR_FORMAT;
    return false;
  }

  m_SrcBPC = 8;
  m_clipBox = FX_RECT(0, 0, m_SrcWidth, m_SrcHeight);
  m_pBmpContext = std::move(pBmpContext);
  if (m_SrcPaletteNumber) {
    m_pSrcPalette.reset(FX_Alloc(FX_ARGB, m_SrcPaletteNumber));
    memcpy(m_pSrcPalette.get(), palette->data(),
           m_SrcPaletteNumber * sizeof(FX_ARGB));
  } else {
    m_pSrcPalette.reset();
  }
  return true;
}

bool ProgressiveDecoder::BmpReadMoreData(BmpModule* pBmpModule,
                                         ModuleIface::Context* pContext,
                                         FXCODEC_STATUS& err_status) {
  return ReadMoreData(pBmpModule, pContext, false, err_status);
}

FXCODEC_STATUS ProgressiveDecoder::BmpStartDecode(
    const RetainPtr<CFX_DIBitmap>& pDIBitmap) {
  BmpModule* pBmpModule = m_pCodecMgr->GetBmpModule();
  if (!pBmpModule) {
    m_pDeviceBitmap = nullptr;
    m_pFile = nullptr;
    m_status = FXCODEC_STATUS_ERR_MEMORY;
    return m_status;
  }
  GetTransMethod(m_pDeviceBitmap->GetFormat(), m_SrcFormat);
  m_ScanlineSize = FxAlignToBoundary<4>(m_SrcWidth * m_SrcComponents);
  m_pDecodeBuf.reset(FX_Alloc(uint8_t, m_ScanlineSize));
  m_WeightHorz.Calc(m_sizeX, 0, m_sizeX, m_clipBox.Width(), 0,
                    m_clipBox.Width());
  m_WeightVert.Calc(m_sizeY, m_clipBox.Height());
  m_status = FXCODEC_STATUS_DECODE_TOBECONTINUE;
  return m_status;
}

FXCODEC_STATUS ProgressiveDecoder::BmpContinueDecode() {
  BmpModule* pBmpModule = m_pCodecMgr->GetBmpModule();
  if (!pBmpModule) {
    m_status = FXCODEC_STATUS_ERR_MEMORY;
    return m_status;
  }
  while (true) {
    BmpModule::Status read_res = pBmpModule->LoadImage(m_pBmpContext.get());
    while (read_res == BmpModule::Status::kContinue) {
      FXCODEC_STATUS error_status = FXCODEC_STATUS_DECODE_FINISH;
      if (!BmpReadMoreData(pBmpModule, m_pBmpContext.get(), error_status)) {
        m_pDeviceBitmap = nullptr;
        m_pFile = nullptr;
        m_status = error_status;
        return m_status;
      }
      read_res = pBmpModule->LoadImage(m_pBmpContext.get());
    }
    if (read_res == BmpModule::Status::kSuccess) {
      m_pDeviceBitmap = nullptr;
      m_pFile = nullptr;
      m_status = FXCODEC_STATUS_DECODE_FINISH;
      return m_status;
    }
    m_pDeviceBitmap = nullptr;
    m_pFile = nullptr;
    m_status = FXCODEC_STATUS_ERROR;
    return m_status;
  }
}
#endif  // PDF_ENABLE_XFA_BMP

#ifdef PDF_ENABLE_XFA_GIF
bool ProgressiveDecoder::GifReadMoreData(GifModule* pGifModule,
                                         FXCODEC_STATUS& err_status) {
  if (!ReadMoreData(pGifModule, m_pGifContext.get(), m_InvalidateGifBuffer,
                    err_status)) {
    return false;
  }
  m_InvalidateGifBuffer = false;
  return true;
}

bool ProgressiveDecoder::GifDetectImageTypeInBuffer() {
  GifModule* pGifModule = m_pCodecMgr->GetGifModule();
  if (!pGifModule) {
    m_status = FXCODEC_STATUS_ERR_MEMORY;
    return false;
  }
  m_pGifContext = pGifModule->Start(this);
  pGifModule->Input(m_pGifContext.get(), m_pCodecMemory, nullptr);
  m_SrcComponents = 1;
  CFX_GifDecodeStatus readResult =
      pGifModule->ReadHeader(m_pGifContext.get(), &m_SrcWidth, &m_SrcHeight,
                             &m_GifPltNumber, &m_pGifPalette, &m_GifBgIndex);
  while (readResult == CFX_GifDecodeStatus::Unfinished) {
    FXCODEC_STATUS error_status = FXCODEC_STATUS_ERR_FORMAT;
    if (!GifReadMoreData(pGifModule, error_status)) {
      m_pGifContext = nullptr;
      m_status = error_status;
      return false;
    }
    readResult =
        pGifModule->ReadHeader(m_pGifContext.get(), &m_SrcWidth, &m_SrcHeight,
                               &m_GifPltNumber, &m_pGifPalette, &m_GifBgIndex);
  }
  if (readResult == CFX_GifDecodeStatus::Success) {
    m_SrcBPC = 8;
    m_clipBox = FX_RECT(0, 0, m_SrcWidth, m_SrcHeight);
    return true;
  }
  m_pGifContext = nullptr;
  m_status = FXCODEC_STATUS_ERR_FORMAT;
  return false;
}

FXCODEC_STATUS ProgressiveDecoder::GifStartDecode(
    const RetainPtr<CFX_DIBitmap>& pDIBitmap) {
  GifModule* pGifModule = m_pCodecMgr->GetGifModule();
  if (!pGifModule) {
    m_pDeviceBitmap = nullptr;
    m_pFile = nullptr;
    m_status = FXCODEC_STATUS_ERR_MEMORY;
    return m_status;
  }
  m_SrcFormat = FXCodec_8bppRgb;
  GetTransMethod(m_pDeviceBitmap->GetFormat(), m_SrcFormat);
  int scanline_size = FxAlignToBoundary<4>(m_SrcWidth);
  m_pDecodeBuf.reset(FX_Alloc(uint8_t, scanline_size));
  m_WeightHorz.Calc(m_sizeX, 0, m_sizeX, m_clipBox.Width(), 0,
                    m_clipBox.Width());
  m_WeightVert.Calc(m_sizeY, m_clipBox.Height());
  m_FrameCur = 0;
  m_status = FXCODEC_STATUS_DECODE_TOBECONTINUE;
  return m_status;
}

FXCODEC_STATUS ProgressiveDecoder::GifContinueDecode() {
  GifModule* pGifModule = m_pCodecMgr->GetGifModule();
  if (!pGifModule) {
    m_pDeviceBitmap = nullptr;
    m_pFile = nullptr;
    m_status = FXCODEC_STATUS_ERR_MEMORY;
    return m_status;
  }

  CFX_GifDecodeStatus readRes =
      pGifModule->LoadFrame(m_pGifContext.get(), m_FrameCur);
  while (readRes == CFX_GifDecodeStatus::Unfinished) {
    FXCODEC_STATUS error_status = FXCODEC_STATUS_DECODE_FINISH;
    if (!GifReadMoreData(pGifModule, error_status)) {
      m_pDeviceBitmap = nullptr;
      m_pFile = nullptr;
      m_status = error_status;
      return m_status;
    }
    readRes = pGifModule->LoadFrame(m_pGifContext.get(), m_FrameCur);
  }

  if (readRes == CFX_GifDecodeStatus::Success) {
    m_pDeviceBitmap = nullptr;
    m_pFile = nullptr;
    m_status = FXCODEC_STATUS_DECODE_FINISH;
    return m_status;
  }

  m_pDeviceBitmap = nullptr;
  m_pFile = nullptr;
  m_status = FXCODEC_STATUS_ERROR;
  return m_status;
}

void ProgressiveDecoder::GifDoubleLineResampleVert(
    const RetainPtr<CFX_DIBitmap>& pDeviceBitmap,
    double scale_y,
    int dest_row) {
  int dest_Bpp = pDeviceBitmap->GetBPP() >> 3;
  uint32_t dest_ScanOffet = m_startX * dest_Bpp;
  int dest_top = m_startY;
  pdfium::base::CheckedNumeric<double> scale_y2 = scale_y;
  scale_y2 *= 2;
  pdfium::base::CheckedNumeric<int> check_dest_row_1 = dest_row;
  check_dest_row_1 -= scale_y2.ValueOrDie();
  int dest_row_1 = check_dest_row_1.ValueOrDie();
  dest_row_1 = std::max(dest_row_1, dest_top);
  for (; dest_row_1 < dest_row; dest_row_1++) {
    uint8_t* scan_des =
        pDeviceBitmap->GetWritableScanline(dest_row_1) + dest_ScanOffet;
    PixelWeight* pWeight = m_WeightVert.GetPixelWeight(dest_row_1 - dest_top);
    const uint8_t* scan_src1 =
        pDeviceBitmap->GetScanline(pWeight->m_SrcStart + dest_top) +
        dest_ScanOffet;
    const uint8_t* scan_src2 =
        pDeviceBitmap->GetScanline(pWeight->m_SrcEnd + dest_top) +
        dest_ScanOffet;
    for (int dest_col = 0; dest_col < m_sizeX; dest_col++) {
      switch (pDeviceBitmap->GetFormat()) {
        case FXDIB_Invalid:
        case FXDIB_1bppMask:
        case FXDIB_1bppRgb:
          return;
        case FXDIB_8bppMask:
        case FXDIB_8bppRgb: {
          if (pDeviceBitmap->GetPalette()) {
            return;
          }
          int dest_g = 0;
          dest_g += pWeight->m_Weights[0] * (*scan_src1++);
          dest_g += pWeight->m_Weights[1] * (*scan_src2++);
          *scan_des++ = (uint8_t)(dest_g >> 16);
        } break;
        case FXDIB_Rgb:
        case FXDIB_Rgb32: {
          uint32_t dest_b = 0;
          uint32_t dest_g = 0;
          uint32_t dest_r = 0;
          dest_b += pWeight->m_Weights[0] * (*scan_src1++);
          dest_g += pWeight->m_Weights[0] * (*scan_src1++);
          dest_r += pWeight->m_Weights[0] * (*scan_src1++);
          scan_src1 += dest_Bpp - 3;
          dest_b += pWeight->m_Weights[1] * (*scan_src2++);
          dest_g += pWeight->m_Weights[1] * (*scan_src2++);
          dest_r += pWeight->m_Weights[1] * (*scan_src2++);
          scan_src2 += dest_Bpp - 3;
          *scan_des++ = (uint8_t)((dest_b) >> 16);
          *scan_des++ = (uint8_t)((dest_g) >> 16);
          *scan_des++ = (uint8_t)((dest_r) >> 16);
          scan_des += dest_Bpp - 3;
        } break;
        case FXDIB_Argb: {
          uint32_t dest_a = 0;
          uint32_t dest_b = 0;
          uint32_t dest_g = 0;
          uint32_t dest_r = 0;
          dest_b += pWeight->m_Weights[0] * (*scan_src1++);
          dest_g += pWeight->m_Weights[0] * (*scan_src1++);
          dest_r += pWeight->m_Weights[0] * (*scan_src1++);
          dest_a += pWeight->m_Weights[0] * (*scan_src1++);
          dest_b += pWeight->m_Weights[1] * (*scan_src2++);
          dest_g += pWeight->m_Weights[1] * (*scan_src2++);
          dest_r += pWeight->m_Weights[1] * (*scan_src2++);
          dest_a += pWeight->m_Weights[1] * (*scan_src2++);
          *scan_des++ = (uint8_t)((dest_b) >> 16);
          *scan_des++ = (uint8_t)((dest_g) >> 16);
          *scan_des++ = (uint8_t)((dest_r) >> 16);
          *scan_des++ = (uint8_t)((dest_a) >> 16);
        } break;
        default:
          return;
      }
    }
  }
  int dest_bottom = dest_top + m_sizeY - 1;
  if (dest_row + (int)(2 * scale_y) >= dest_bottom &&
      dest_row + (int)scale_y < dest_bottom) {
    GifDoubleLineResampleVert(pDeviceBitmap, scale_y, dest_row + (int)scale_y);
  }
}
#endif  // PDF_ENABLE_XFA_GIF

bool ProgressiveDecoder::JpegReadMoreData(JpegModule* pJpegModule,
                                          FXCODEC_STATUS& err_status) {
  return ReadMoreData(pJpegModule, m_pJpegContext.get(), false, err_status);
}

bool ProgressiveDecoder::JpegDetectImageTypeInBuffer(
    CFX_DIBAttribute* pAttribute) {
  JpegModule* pJpegModule = m_pCodecMgr->GetJpegModule();
  m_pJpegContext = pJpegModule->Start();
  if (!m_pJpegContext) {
    m_status = FXCODEC_STATUS_ERR_MEMORY;
    return false;
  }
  pJpegModule->Input(m_pJpegContext.get(), m_pCodecMemory, nullptr);

  // Setting jump marker before calling ReadHeader, since a longjmp to
  // the marker indicates a fatal error.
  if (setjmp(*pJpegModule->GetJumpMark(m_pJpegContext.get())) == -1) {
    m_pJpegContext.reset();
    m_status = FXCODEC_STATUS_ERR_FORMAT;
    return false;
  }

  int32_t readResult =
      pJpegModule->ReadHeader(m_pJpegContext.get(), &m_SrcWidth, &m_SrcHeight,
                              &m_SrcComponents, pAttribute);
  while (readResult == 2) {
    FXCODEC_STATUS error_status = FXCODEC_STATUS_ERR_FORMAT;
    if (!JpegReadMoreData(pJpegModule, error_status)) {
      m_status = error_status;
      return false;
    }
    readResult =
        pJpegModule->ReadHeader(m_pJpegContext.get(), &m_SrcWidth, &m_SrcHeight,
                                &m_SrcComponents, pAttribute);
  }
  if (!readResult) {
    m_SrcBPC = 8;
    m_clipBox = FX_RECT(0, 0, m_SrcWidth, m_SrcHeight);
    return true;
  }
  m_pJpegContext.reset();
  m_status = FXCODEC_STATUS_ERR_FORMAT;
  return false;
}

FXCODEC_STATUS ProgressiveDecoder::JpegStartDecode(
    const RetainPtr<CFX_DIBitmap>& pDIBitmap) {
  JpegModule* pJpegModule = m_pCodecMgr->GetJpegModule();
  int down_scale = 1;
  GetDownScale(down_scale);
  // Setting jump marker before calling StartScanLine, since a longjmp to
  // the marker indicates a fatal error.
  if (setjmp(*pJpegModule->GetJumpMark(m_pJpegContext.get())) == -1) {
    m_pJpegContext.reset();
    m_status = FXCODEC_STATUS_ERROR;
    return FXCODEC_STATUS_ERROR;
  }

  bool startStatus =
      pJpegModule->StartScanline(m_pJpegContext.get(), down_scale);
  while (!startStatus) {
    FXCODEC_STATUS error_status = FXCODEC_STATUS_ERROR;
    if (!JpegReadMoreData(pJpegModule, error_status)) {
      m_pDeviceBitmap = nullptr;
      m_pFile = nullptr;
      m_status = error_status;
      return m_status;
    }

    startStatus = pJpegModule->StartScanline(m_pJpegContext.get(), down_scale);
  }
  int scanline_size = (m_SrcWidth + down_scale - 1) / down_scale;
  scanline_size = FxAlignToBoundary<4>(scanline_size * m_SrcComponents);
  m_pDecodeBuf.reset(FX_Alloc(uint8_t, scanline_size));
  m_WeightHorz.Calc(m_sizeX, 0, m_sizeX, m_clipBox.Width(), 0,
                    m_clipBox.Width());
  m_WeightVert.Calc(m_sizeY, m_clipBox.Height());
  switch (m_SrcComponents) {
    case 1:
      m_SrcFormat = FXCodec_8bppGray;
      break;
    case 3:
      m_SrcFormat = FXCodec_Rgb;
      break;
    case 4:
      m_SrcFormat = FXCodec_Cmyk;
      break;
  }
  GetTransMethod(pDIBitmap->GetFormat(), m_SrcFormat);
  m_status = FXCODEC_STATUS_DECODE_TOBECONTINUE;
  return m_status;
}

FXCODEC_STATUS ProgressiveDecoder::JpegContinueDecode() {
  JpegModule* pJpegModule = m_pCodecMgr->GetJpegModule();
  // Setting jump marker before calling ReadScanLine, since a longjmp to
  // the marker indicates a fatal error.
  if (setjmp(*pJpegModule->GetJumpMark(m_pJpegContext.get())) == -1) {
    m_pJpegContext.reset();
    m_status = FXCODEC_STATUS_ERROR;
    return FXCODEC_STATUS_ERROR;
  }

  while (true) {
    bool readRes =
        pJpegModule->ReadScanline(m_pJpegContext.get(), m_pDecodeBuf.get());
    while (!readRes) {
      FXCODEC_STATUS error_status = FXCODEC_STATUS_DECODE_FINISH;
      if (!JpegReadMoreData(pJpegModule, error_status)) {
        m_pDeviceBitmap = nullptr;
        m_pFile = nullptr;
        m_status = error_status;
        return m_status;
      }
      readRes =
          pJpegModule->ReadScanline(m_pJpegContext.get(), m_pDecodeBuf.get());
    }
    if (m_SrcFormat == FXCodec_Rgb) {
      int src_Bpp = (m_SrcFormat & 0xff) >> 3;
      RGB2BGR(m_pDecodeBuf.get() + m_clipBox.left * src_Bpp, m_clipBox.Width());
    }
    if (m_SrcRow >= m_clipBox.bottom) {
      m_pDeviceBitmap = nullptr;
      m_pFile = nullptr;
      m_status = FXCODEC_STATUS_DECODE_FINISH;
      return m_status;
    }
    Resample(m_pDeviceBitmap, m_SrcRow, m_pDecodeBuf.get(), m_SrcFormat);
    m_SrcRow++;
  }
}

#ifdef PDF_ENABLE_XFA_PNG
void ProgressiveDecoder::PngOneOneMapResampleHorz(
    const RetainPtr<CFX_DIBitmap>& pDeviceBitmap,
    int32_t dest_line,
    uint8_t* src_scan,
    FXCodec_Format src_format) {
  uint8_t* dest_scan = pDeviceBitmap->GetWritableScanline(dest_line);
  int32_t src_Bpp = (m_SrcFormat & 0xff) >> 3;
  int32_t dest_Bpp = pDeviceBitmap->GetBPP() >> 3;
  int32_t src_left = m_clipBox.left;
  int32_t dest_left = m_startX;
  src_scan += src_left * src_Bpp;
  dest_scan += dest_left * dest_Bpp;
  for (int32_t dest_col = 0; dest_col < m_sizeX; dest_col++) {
    PixelWeight* pPixelWeights = m_WeightHorzOO.GetPixelWeight(dest_col);
    switch (pDeviceBitmap->GetFormat()) {
      case FXDIB_1bppMask:
      case FXDIB_1bppRgb:
        NOTREACHED();
        return;
      case FXDIB_8bppMask:
      case FXDIB_8bppRgb: {
        if (pDeviceBitmap->GetPalette()) {
          return;
        }
        uint32_t dest_g = 0;
        dest_g +=
            pPixelWeights->m_Weights[0] * src_scan[pPixelWeights->m_SrcStart];
        dest_g +=
            pPixelWeights->m_Weights[1] * src_scan[pPixelWeights->m_SrcEnd];
        *dest_scan++ = (uint8_t)(dest_g >> 16);
      } break;
      case FXDIB_Rgb:
      case FXDIB_Rgb32: {
        uint32_t dest_b = 0;
        uint32_t dest_g = 0;
        uint32_t dest_r = 0;
        const uint8_t* p = src_scan;
        p = src_scan + pPixelWeights->m_SrcStart * src_Bpp;
        dest_b += pPixelWeights->m_Weights[0] * (*p++);
        dest_g += pPixelWeights->m_Weights[0] * (*p++);
        dest_r += pPixelWeights->m_Weights[0] * (*p);
        p = src_scan + pPixelWeights->m_SrcEnd * src_Bpp;
        dest_b += pPixelWeights->m_Weights[1] * (*p++);
        dest_g += pPixelWeights->m_Weights[1] * (*p++);
        dest_r += pPixelWeights->m_Weights[1] * (*p);
        *dest_scan++ = (uint8_t)((dest_b) >> 16);
        *dest_scan++ = (uint8_t)((dest_g) >> 16);
        *dest_scan++ = (uint8_t)((dest_r) >> 16);
        dest_scan += dest_Bpp - 3;
      } break;
      case FXDIB_Argb: {
        uint32_t dest_a = 0;
        uint32_t dest_b = 0;
        uint32_t dest_g = 0;
        uint32_t dest_r = 0;
        const uint8_t* p = src_scan;
        p = src_scan + pPixelWeights->m_SrcStart * src_Bpp;
        dest_b += pPixelWeights->m_Weights[0] * (*p++);
        dest_g += pPixelWeights->m_Weights[0] * (*p++);
        dest_r += pPixelWeights->m_Weights[0] * (*p++);
        dest_a += pPixelWeights->m_Weights[0] * (*p);
        p = src_scan + pPixelWeights->m_SrcEnd * src_Bpp;
        dest_b += pPixelWeights->m_Weights[1] * (*p++);
        dest_g += pPixelWeights->m_Weights[1] * (*p++);
        dest_r += pPixelWeights->m_Weights[1] * (*p++);
        dest_a += pPixelWeights->m_Weights[1] * (*p);
        *dest_scan++ = (uint8_t)((dest_b) >> 16);
        *dest_scan++ = (uint8_t)((dest_g) >> 16);
        *dest_scan++ = (uint8_t)((dest_r) >> 16);
        *dest_scan++ = (uint8_t)((dest_a) >> 16);
      } break;
      default:
        return;
    }
  }
}

bool ProgressiveDecoder::PngDetectImageTypeInBuffer(
    CFX_DIBAttribute* pAttribute) {
  PngModule* pPngModule = m_pCodecMgr->GetPngModule();
  if (!pPngModule) {
    m_status = FXCODEC_STATUS_ERR_MEMORY;
    return false;
  }
  m_pPngContext = pPngModule->Start(this);
  if (!m_pPngContext) {
    m_status = FXCODEC_STATUS_ERR_MEMORY;
    return false;
  }
  while (pPngModule->Input(m_pPngContext.get(), m_pCodecMemory, pAttribute)) {
    uint32_t remain_size = static_cast<uint32_t>(m_pFile->GetSize()) - m_offSet;
    uint32_t input_size =
        remain_size > FXCODEC_BLOCK_SIZE ? FXCODEC_BLOCK_SIZE : remain_size;
    if (input_size == 0) {
      m_pPngContext.reset();
      m_status = FXCODEC_STATUS_ERR_FORMAT;
      return false;
    }
    if (m_pCodecMemory && input_size > m_pCodecMemory->GetSize())
      m_pCodecMemory = pdfium::MakeRetain<CFX_CodecMemory>(input_size);

    if (!m_pFile->ReadBlockAtOffset(m_pCodecMemory->GetBuffer(), m_offSet,
                                    input_size)) {
      m_status = FXCODEC_STATUS_ERR_READ;
      return false;
    }
    m_offSet += input_size;
  }
  m_pPngContext.reset();
  if (m_SrcPassNumber == 0) {
    m_status = FXCODEC_STATUS_ERR_FORMAT;
    return false;
  }
  return true;
}

FXCODEC_STATUS ProgressiveDecoder::PngStartDecode(
    const RetainPtr<CFX_DIBitmap>& pDIBitmap) {
  PngModule* pPngModule = m_pCodecMgr->GetPngModule();
  if (!pPngModule) {
    m_pDeviceBitmap = nullptr;
    m_pFile = nullptr;
    m_status = FXCODEC_STATUS_ERR_MEMORY;
    return m_status;
  }
  m_pPngContext = pPngModule->Start(this);
  if (!m_pPngContext) {
    m_pDeviceBitmap = nullptr;
    m_pFile = nullptr;
    m_status = FXCODEC_STATUS_ERR_MEMORY;
    return m_status;
  }
  m_offSet = 0;
  switch (m_pDeviceBitmap->GetFormat()) {
    case FXDIB_8bppMask:
    case FXDIB_8bppRgb:
      m_SrcComponents = 1;
      m_SrcFormat = FXCodec_8bppGray;
      break;
    case FXDIB_Rgb:
      m_SrcComponents = 3;
      m_SrcFormat = FXCodec_Rgb;
      break;
    case FXDIB_Rgb32:
    case FXDIB_Argb:
      m_SrcComponents = 4;
      m_SrcFormat = FXCodec_Argb;
      break;
    default: {
      m_pDeviceBitmap = nullptr;
      m_pFile = nullptr;
      m_status = FXCODEC_STATUS_ERR_PARAMS;
      return m_status;
    }
  }
  GetTransMethod(m_pDeviceBitmap->GetFormat(), m_SrcFormat);
  int scanline_size = FxAlignToBoundary<4>(m_SrcWidth * m_SrcComponents);
  m_pDecodeBuf.reset(FX_Alloc(uint8_t, scanline_size));
  m_WeightHorzOO.Calc(m_sizeX, m_clipBox.Width());
  m_WeightVert.Calc(m_sizeY, m_clipBox.Height());
  m_status = FXCODEC_STATUS_DECODE_TOBECONTINUE;
  return m_status;
}

FXCODEC_STATUS ProgressiveDecoder::PngContinueDecode() {
  PngModule* pPngModule = m_pCodecMgr->GetPngModule();
  if (!pPngModule) {
    m_status = FXCODEC_STATUS_ERR_MEMORY;
    return m_status;
  }
  while (true) {
    uint32_t remain_size = (uint32_t)m_pFile->GetSize() - m_offSet;
    uint32_t input_size =
        remain_size > FXCODEC_BLOCK_SIZE ? FXCODEC_BLOCK_SIZE : remain_size;
    if (input_size == 0) {
      m_pPngContext.reset();
      m_pDeviceBitmap = nullptr;
      m_pFile = nullptr;
      m_status = FXCODEC_STATUS_DECODE_FINISH;
      return m_status;
    }
    if (m_pCodecMemory && input_size > m_pCodecMemory->GetSize())
      m_pCodecMemory = pdfium::MakeRetain<CFX_CodecMemory>(input_size);

    bool bResult = m_pFile->ReadBlockAtOffset(m_pCodecMemory->GetBuffer(),
                                              m_offSet, input_size);
    if (!bResult) {
      m_pDeviceBitmap = nullptr;
      m_pFile = nullptr;
      m_status = FXCODEC_STATUS_ERR_READ;
      return m_status;
    }
    m_offSet += input_size;
    bResult = pPngModule->Input(m_pPngContext.get(), m_pCodecMemory, nullptr);
    if (!bResult) {
      m_pDeviceBitmap = nullptr;
      m_pFile = nullptr;
      m_status = FXCODEC_STATUS_ERROR;
      return m_status;
    }
  }
}
#endif  // PDF_ENABLE_XFA_PNG

#ifdef PDF_ENABLE_XFA_TIFF
bool ProgressiveDecoder::TiffDetectImageTypeFromFile(
    CFX_DIBAttribute* pAttribute) {
  TiffModule* pTiffModule = m_pCodecMgr->GetTiffModule();
  if (!pTiffModule) {
    m_status = FXCODEC_STATUS_ERR_FORMAT;
    return false;
  }
  m_pTiffContext = pTiffModule->CreateDecoder(m_pFile);
  if (!m_pTiffContext) {
    m_status = FXCODEC_STATUS_ERR_FORMAT;
    return false;
  }
  int32_t dummy_bpc;
  bool ret = pTiffModule->LoadFrameInfo(m_pTiffContext.get(), 0, &m_SrcWidth,
                                        &m_SrcHeight, &m_SrcComponents,
                                        &dummy_bpc, pAttribute);
  m_SrcComponents = 4;
  m_clipBox = FX_RECT(0, 0, m_SrcWidth, m_SrcHeight);
  if (!ret) {
    m_pTiffContext.reset();
    m_status = FXCODEC_STATUS_ERR_FORMAT;
    return false;
  }
  return true;
}

FXCODEC_STATUS ProgressiveDecoder::TiffContinueDecode() {
  TiffModule* pTiffModule = m_pCodecMgr->GetTiffModule();
  if (!pTiffModule) {
    m_status = FXCODEC_STATUS_ERR_MEMORY;
    return m_status;
  }
  bool ret = false;
  if (m_pDeviceBitmap->GetBPP() == 32 &&
      m_pDeviceBitmap->GetWidth() == m_SrcWidth && m_SrcWidth == m_sizeX &&
      m_pDeviceBitmap->GetHeight() == m_SrcHeight && m_SrcHeight == m_sizeY &&
      m_startX == 0 && m_startY == 0 && m_clipBox.left == 0 &&
      m_clipBox.top == 0 && m_clipBox.right == m_SrcWidth &&
      m_clipBox.bottom == m_SrcHeight) {
    ret = pTiffModule->Decode(m_pTiffContext.get(), m_pDeviceBitmap);
    m_pDeviceBitmap = nullptr;
    m_pFile = nullptr;
    if (!ret) {
      m_status = FXCODEC_STATUS_ERROR;
      return m_status;
    }
    m_status = FXCODEC_STATUS_DECODE_FINISH;
    return m_status;
  }

  auto pDIBitmap = pdfium::MakeRetain<CFX_DIBitmap>();
  pDIBitmap->Create(m_SrcWidth, m_SrcHeight, FXDIB_Argb);
  if (!pDIBitmap->GetBuffer()) {
    m_pDeviceBitmap = nullptr;
    m_pFile = nullptr;
    m_status = FXCODEC_STATUS_ERR_MEMORY;
    return m_status;
  }
  ret = pTiffModule->Decode(m_pTiffContext.get(), pDIBitmap);
  if (!ret) {
    m_pDeviceBitmap = nullptr;
    m_pFile = nullptr;
    m_status = FXCODEC_STATUS_ERROR;
    return m_status;
  }
  RetainPtr<CFX_DIBitmap> pClipBitmap =
      (m_clipBox.left == 0 && m_clipBox.top == 0 &&
       m_clipBox.right == m_SrcWidth && m_clipBox.bottom == m_SrcHeight)
          ? pDIBitmap
          : pDIBitmap->Clone(&m_clipBox);
  if (!pClipBitmap) {
    m_pDeviceBitmap = nullptr;
    m_pFile = nullptr;
    m_status = FXCODEC_STATUS_ERR_MEMORY;
    return m_status;
  }
  RetainPtr<CFX_DIBitmap> pFormatBitmap;
  switch (m_pDeviceBitmap->GetFormat()) {
    case FXDIB_8bppRgb:
      pFormatBitmap = pdfium::MakeRetain<CFX_DIBitmap>();
      pFormatBitmap->Create(pClipBitmap->GetWidth(), pClipBitmap->GetHeight(),
                            FXDIB_8bppRgb);
      break;
    case FXDIB_8bppMask:
      pFormatBitmap = pdfium::MakeRetain<CFX_DIBitmap>();
      pFormatBitmap->Create(pClipBitmap->GetWidth(), pClipBitmap->GetHeight(),
                            FXDIB_8bppMask);
      break;
    case FXDIB_Rgb:
      pFormatBitmap = pdfium::MakeRetain<CFX_DIBitmap>();
      pFormatBitmap->Create(pClipBitmap->GetWidth(), pClipBitmap->GetHeight(),
                            FXDIB_Rgb);
      break;
    case FXDIB_Rgb32:
      pFormatBitmap = pdfium::MakeRetain<CFX_DIBitmap>();
      pFormatBitmap->Create(pClipBitmap->GetWidth(), pClipBitmap->GetHeight(),
                            FXDIB_Rgb32);
      break;
    case FXDIB_Argb:
      pFormatBitmap = pClipBitmap;
      break;
    default:
      break;
  }
  switch (m_pDeviceBitmap->GetFormat()) {
    case FXDIB_8bppRgb:
    case FXDIB_8bppMask: {
      for (int32_t row = 0; row < pClipBitmap->GetHeight(); row++) {
        const uint8_t* src_line = pClipBitmap->GetScanline(row);
        uint8_t* dest_line = pFormatBitmap->GetWritableScanline(row);
        for (int32_t col = 0; col < pClipBitmap->GetWidth(); col++) {
          uint8_t _a = 255 - src_line[3];
          uint8_t b = (src_line[0] * src_line[3] + 0xFF * _a) / 255;
          uint8_t g = (src_line[1] * src_line[3] + 0xFF * _a) / 255;
          uint8_t r = (src_line[2] * src_line[3] + 0xFF * _a) / 255;
          *dest_line++ = FXRGB2GRAY(r, g, b);
          src_line += 4;
        }
      }
    } break;
    case FXDIB_Rgb:
    case FXDIB_Rgb32: {
      int32_t desBpp = (m_pDeviceBitmap->GetFormat() == FXDIB_Rgb) ? 3 : 4;
      for (int32_t row = 0; row < pClipBitmap->GetHeight(); row++) {
        const uint8_t* src_line = pClipBitmap->GetScanline(row);
        uint8_t* dest_line = pFormatBitmap->GetWritableScanline(row);
        for (int32_t col = 0; col < pClipBitmap->GetWidth(); col++) {
          uint8_t _a = 255 - src_line[3];
          uint8_t b = (src_line[0] * src_line[3] + 0xFF * _a) / 255;
          uint8_t g = (src_line[1] * src_line[3] + 0xFF * _a) / 255;
          uint8_t r = (src_line[2] * src_line[3] + 0xFF * _a) / 255;
          *dest_line++ = b;
          *dest_line++ = g;
          *dest_line++ = r;
          dest_line += desBpp - 3;
          src_line += 4;
        }
      }
    } break;
    default:
      break;
  }
  if (!pFormatBitmap) {
    m_pDeviceBitmap = nullptr;
    m_pFile = nullptr;
    m_status = FXCODEC_STATUS_ERR_MEMORY;
    return m_status;
  }

  FXDIB_ResampleOptions options;
  options.bInterpolateBilinear = true;
  RetainPtr<CFX_DIBitmap> pStrechBitmap =
      pFormatBitmap->StretchTo(m_sizeX, m_sizeY, options, nullptr);
  pFormatBitmap = nullptr;
  if (!pStrechBitmap) {
    m_pDeviceBitmap = nullptr;
    m_pFile = nullptr;
    m_status = FXCODEC_STATUS_ERR_MEMORY;
    return m_status;
  }
  m_pDeviceBitmap->TransferBitmap(m_startX, m_startY, m_sizeX, m_sizeY,
                                  pStrechBitmap, 0, 0);
  m_pDeviceBitmap = nullptr;
  m_pFile = nullptr;
  m_status = FXCODEC_STATUS_DECODE_FINISH;
  return m_status;
}
#endif  // PDF_ENABLE_XFA_TIFF

bool ProgressiveDecoder::DetectImageType(FXCODEC_IMAGE_TYPE imageType,
                                         CFX_DIBAttribute* pAttribute) {
#ifdef PDF_ENABLE_XFA_TIFF
  if (imageType == FXCODEC_IMAGE_TIFF)
    return TiffDetectImageTypeFromFile(pAttribute);
#endif  // PDF_ENABLE_XFA_TIFF

  size_t size = std::min<size_t>(m_pFile->GetSize(), FXCODEC_BLOCK_SIZE);
  m_pCodecMemory = pdfium::MakeRetain<CFX_CodecMemory>(size);
  m_offSet = 0;
  if (!m_pFile->ReadBlockAtOffset(m_pCodecMemory->GetBuffer(), m_offSet,
                                  size)) {
    m_status = FXCODEC_STATUS_ERR_READ;
    return false;
  }
  m_offSet += size;

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

#ifdef PDF_ENABLE_XFA_BMP
  if (imageType == FXCODEC_IMAGE_BMP)
    return BmpDetectImageTypeInBuffer(pAttribute);
#endif  // PDF_ENABLE_XFA_BMP

#ifdef PDF_ENABLE_XFA_GIF
  if (imageType == FXCODEC_IMAGE_GIF)
    return GifDetectImageTypeInBuffer();
#endif  // PDF_ENABLE_XFA_GIF

#ifdef PDF_ENABLE_XFA_PNG
  if (imageType == FXCODEC_IMAGE_PNG)
    return PngDetectImageTypeInBuffer(pAttribute);
#endif  // PDF_ENABLE_XFA_PNG

  m_status = FXCODEC_STATUS_ERR_FORMAT;
  return false;
}

bool ProgressiveDecoder::ReadMoreData(ModuleIface* pModule,
                                      ModuleIface::Context* pContext,
                                      bool invalidate_buffer,
                                      FXCODEC_STATUS& err_status) {
  // Check for EOF.
  if (m_offSet >= static_cast<uint32_t>(m_pFile->GetSize()))
    return false;

  // Try to get whatever remains.
  uint32_t dwBytesToFetchFromFile = m_pFile->GetSize() - m_offSet;

  // Figure out if the codec stopped processing midway through the buffer.
  size_t dwUnconsumed = 0;
  if (!invalidate_buffer) {
    FX_SAFE_SIZE_T avail_input = pModule->GetAvailInput(pContext);
    if (!avail_input.IsValid())
      return false;
    dwUnconsumed = avail_input.ValueOrDie();
  }

  if (dwUnconsumed == m_pCodecMemory->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.
    dwBytesToFetchFromFile =
        std::min<uint32_t>(dwBytesToFetchFromFile, FXCODEC_BLOCK_SIZE);
    size_t dwNewSize = m_pCodecMemory->GetSize() + dwBytesToFetchFromFile;
    if (!m_pCodecMemory->TryResize(dwNewSize)) {
      err_status = FXCODEC_STATUS_ERR_MEMORY;
      return false;
    }
  } else {
    size_t dwConsumed = m_pCodecMemory->GetSize() - dwUnconsumed;
    m_pCodecMemory->Consume(dwConsumed);
    dwBytesToFetchFromFile =
        std::min<uint32_t>(dwBytesToFetchFromFile, dwConsumed);
  }

  // Append new data past the bytes not yet processed by the codec.
  if (!m_pFile->ReadBlockAtOffset(m_pCodecMemory->GetBuffer() + dwUnconsumed,
                                  m_offSet, dwBytesToFetchFromFile)) {
    err_status = FXCODEC_STATUS_ERR_READ;
    return false;
  }
  m_offSet += dwBytesToFetchFromFile;
  return pModule->Input(pContext, m_pCodecMemory, nullptr);
}

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

  switch (m_status) {
    case FXCODEC_STATUS_FRAME_READY:
    case FXCODEC_STATUS_FRAME_TOBECONTINUE:
    case FXCODEC_STATUS_DECODE_READY:
    case FXCODEC_STATUS_DECODE_TOBECONTINUE:
      return FXCODEC_STATUS_ERROR;
    default:
      break;
  }
  if (!pFile) {
    m_status = FXCODEC_STATUS_ERR_PARAMS;
    m_pFile = nullptr;
    return m_status;
  }
  m_pFile = pFile;
  m_offSet = 0;
  m_SrcWidth = m_SrcHeight = 0;
  m_SrcComponents = m_SrcBPC = 0;
  m_clipBox = FX_RECT();
  m_startX = m_startY = 0;
  m_sizeX = m_sizeY = 0;
  m_SrcPassNumber = 0;
  if (imageType != FXCODEC_IMAGE_UNKNOWN &&
      DetectImageType(imageType, pAttribute)) {
    m_imageType = imageType;
    m_status = FXCODEC_STATUS_FRAME_READY;
    return m_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 m_status;

  for (int type = FXCODEC_IMAGE_UNKNOWN + 1; type < FXCODEC_IMAGE_MAX; type++) {
    if (DetectImageType(static_cast<FXCODEC_IMAGE_TYPE>(type), pAttribute)) {
      m_imageType = static_cast<FXCODEC_IMAGE_TYPE>(type);
      m_status = FXCODEC_STATUS_FRAME_READY;
      return m_status;
    }
  }
  m_status = FXCODEC_STATUS_ERR_FORMAT;
  m_pFile = nullptr;
  return m_status;
}

void ProgressiveDecoder::SetClipBox(FX_RECT* clip) {
  if (m_status != FXCODEC_STATUS_FRAME_READY)
    return;

  if (clip->IsEmpty()) {
    m_clipBox = FX_RECT();
    return;
  }
  clip->left = std::max(clip->left, 0);
  clip->right = std::min(clip->right, m_SrcWidth);
  clip->top = std::max(clip->top, 0);
  clip->bottom = std::min(clip->bottom, m_SrcHeight);
  if (clip->IsEmpty()) {
    m_clipBox = FX_RECT();
    return;
  }
  m_clipBox = *clip;
}

void ProgressiveDecoder::GetDownScale(int& down_scale) {
  down_scale = 1;
  int ratio_w = m_clipBox.Width() / m_sizeX;
  int ratio_h = m_clipBox.Height() / m_sizeY;
  int ratio = (ratio_w > ratio_h) ? ratio_h : ratio_w;
  if (ratio >= 8) {
    down_scale = 8;
  } else if (ratio >= 4) {
    down_scale = 4;
  } else if (ratio >= 2) {
    down_scale = 2;
  }
  m_clipBox.left /= down_scale;
  m_clipBox.right /= down_scale;
  m_clipBox.top /= down_scale;
  m_clipBox.bottom /= down_scale;
  if (m_clipBox.right == m_clipBox.left) {
    m_clipBox.right = m_clipBox.left + 1;
  }
  if (m_clipBox.bottom == m_clipBox.top) {
    m_clipBox.bottom = m_clipBox.top + 1;
  }
}

void ProgressiveDecoder::GetTransMethod(FXDIB_Format dest_format,
                                        FXCodec_Format src_format) {
  switch (dest_format) {
    case FXDIB_1bppMask:
    case FXDIB_1bppRgb: {
      switch (src_format) {
        case FXCodec_1bppGray:
          m_TransMethod = 0;
          break;
        default:
          m_TransMethod = -1;
      }
    } break;
    case FXDIB_8bppMask:
    case FXDIB_8bppRgb: {
      switch (src_format) {
        case FXCodec_1bppGray:
          m_TransMethod = 1;
          break;
        case FXCodec_8bppGray:
          m_TransMethod = 2;
          break;
        case FXCodec_1bppRgb:
        case FXCodec_8bppRgb:
          m_TransMethod = 3;
          break;
        case FXCodec_Rgb:
        case FXCodec_Rgb32:
        case FXCodec_Argb:
          m_TransMethod = 4;
          break;
        case FXCodec_Cmyk:
          m_TransMethod = 5;
          break;
        default:
          m_TransMethod = -1;
      }
    } break;
    case FXDIB_Rgb: {
      switch (src_format) {
        case FXCodec_1bppGray:
          m_TransMethod = 6;
          break;
        case FXCodec_8bppGray:
          m_TransMethod = 7;
          break;
        case FXCodec_1bppRgb:
        case FXCodec_8bppRgb:
          m_TransMethod = 8;
          break;
        case FXCodec_Rgb:
        case FXCodec_Rgb32:
        case FXCodec_Argb:
          m_TransMethod = 9;
          break;
        case FXCodec_Cmyk:
          m_TransMethod = 10;
          break;
        default:
          m_TransMethod = -1;
      }
    } break;
    case FXDIB_Rgb32:
    case FXDIB_Argb: {
      switch (src_format) {
        case FXCodec_1bppGray:
          m_TransMethod = 6;
          break;
        case FXCodec_8bppGray:
          m_TransMethod = 7;
          break;
        case FXCodec_1bppRgb:
        case FXCodec_8bppRgb:
          if (dest_format == FXDIB_Argb) {
            m_TransMethod = 12;
          } else {
            m_TransMethod = 8;
          }
          break;
        case FXCodec_Rgb:
        case FXCodec_Rgb32:
          m_TransMethod = 9;
          break;
        case FXCodec_Cmyk:
          m_TransMethod = 10;
          break;
        case FXCodec_Argb:
          m_TransMethod = 11;
          break;
        default:
          m_TransMethod = -1;
      }
    } break;
    default:
      m_TransMethod = -1;
  }
}

void ProgressiveDecoder::ReSampleScanline(
    const RetainPtr<CFX_DIBitmap>& pDeviceBitmap,
    int dest_line,
    uint8_t* src_scan,
    FXCodec_Format src_format) {
  int src_left = m_clipBox.left;
  int dest_left = m_startX;
  uint8_t* dest_scan =
      pDeviceBitmap->GetBuffer() + dest_line * pDeviceBitmap->GetPitch();
  int src_bytes_per_pixel = (src_format & 0xff) / 8;
  int dest_bytes_per_pixel = pDeviceBitmap->GetBPP() / 8;
  src_scan += src_left * src_bytes_per_pixel;
  dest_scan += dest_left * dest_bytes_per_pixel;
  for (int dest_col = 0; dest_col < m_sizeX; dest_col++) {
    PixelWeight* pPixelWeights = m_WeightHorz.GetPixelWeight(dest_col);
    switch (m_TransMethod) {
      case -1:
        return;
      case 0:
        return;
      case 1:
        return;
      case 2: {
        uint32_t dest_g = 0;
        for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd;
             j++) {
          int pixel_weight =
              pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart];
          dest_g += pixel_weight * src_scan[j];
        }
        *dest_scan++ = (uint8_t)(dest_g >> 16);
      } break;
      case 3: {
        int dest_r = 0;
        int dest_g = 0;
        int dest_b = 0;
        for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd;
             j++) {
          int pixel_weight =
              pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart];
          unsigned long argb = m_pSrcPalette.get()[src_scan[j]];
          dest_r += pixel_weight * (uint8_t)(argb >> 16);
          dest_g += pixel_weight * (uint8_t)(argb >> 8);
          dest_b += pixel_weight * (uint8_t)argb;
        }
        *dest_scan++ =
            (uint8_t)FXRGB2GRAY((dest_r >> 16), (dest_g >> 16), (dest_b >> 16));
      } break;
      case 4: {
        uint32_t dest_b = 0;
        uint32_t dest_g = 0;
        uint32_t dest_r = 0;
        for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd;
             j++) {
          int pixel_weight =
              pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart];
          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++ =
            (uint8_t)FXRGB2GRAY((dest_r >> 16), (dest_g >> 16), (dest_b >> 16));
      } break;
      case 5: {
        uint32_t dest_b = 0;
        uint32_t dest_g = 0;
        uint32_t dest_r = 0;
        for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd;
             j++) {
          int pixel_weight =
              pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart];
          const uint8_t* src_pixel = src_scan + j * src_bytes_per_pixel;
          uint8_t src_b = 0;
          uint8_t src_g = 0;
          uint8_t src_r = 0;
          std::tie(src_r, src_g, src_b) =
              AdobeCMYK_to_sRGB1(255 - src_pixel[0], 255 - src_pixel[1],
                                 255 - src_pixel[2], 255 - src_pixel[3]);
          dest_b += pixel_weight * src_b;
          dest_g += pixel_weight * src_g;
          dest_r += pixel_weight * src_r;
        }
        *dest_scan++ =
            (uint8_t)FXRGB2GRAY((dest_r >> 16), (dest_g >> 16), (dest_b >> 16));
      } break;
      case 6:
        return;
      case 7: {
        uint32_t dest_g = 0;
        for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd;
             j++) {
          int pixel_weight =
              pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart];
          dest_g += pixel_weight * src_scan[j];
        }
        memset(dest_scan, (uint8_t)(dest_g >> 16), 3);
        dest_scan += dest_bytes_per_pixel;
      } break;
      case 8: {
        int dest_r = 0;
        int dest_g = 0;
        int dest_b = 0;
        for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd;
             j++) {
          int pixel_weight =
              pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart];
          unsigned long argb = m_pSrcPalette.get()[src_scan[j]];
          dest_r += pixel_weight * (uint8_t)(argb >> 16);
          dest_g += pixel_weight * (uint8_t)(argb >> 8);
          dest_b += pixel_weight * (uint8_t)argb;
        }
        *dest_scan++ = (uint8_t)((dest_b) >> 16);
        *dest_scan++ = (uint8_t)((dest_g) >> 16);
        *dest_scan++ = (uint8_t)((dest_r) >> 16);
        dest_scan += dest_bytes_per_pixel - 3;
      } break;
      case 12: {
#ifdef PDF_ENABLE_XFA_BMP
        if (m_pBmpContext) {
          int dest_r = 0;
          int dest_g = 0;
          int dest_b = 0;
          for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd;
               j++) {
            int pixel_weight =
                pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart];
            unsigned long argb = m_pSrcPalette.get()[src_scan[j]];
            dest_r += pixel_weight * (uint8_t)(argb >> 16);
            dest_g += pixel_weight * (uint8_t)(argb >> 8);
            dest_b += pixel_weight * (uint8_t)argb;
          }
          *dest_scan++ = (uint8_t)((dest_b) >> 16);
          *dest_scan++ = (uint8_t)((dest_g) >> 16);
          *dest_scan++ = (uint8_t)((dest_r) >> 16);
          *dest_scan++ = 0xFF;
          break;
        }
#endif  // PDF_ENABLE_XFA_BMP
        int dest_a = 0;
        int dest_r = 0;
        int dest_g = 0;
        int dest_b = 0;
        for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd;
             j++) {
          int pixel_weight =
              pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart];
          unsigned long argb = m_pSrcPalette.get()[src_scan[j]];
          dest_a += pixel_weight * (uint8_t)(argb >> 24);
          dest_r += pixel_weight * (uint8_t)(argb >> 16);
          dest_g += pixel_weight * (uint8_t)(argb >> 8);
          dest_b += pixel_weight * (uint8_t)argb;
        }
        *dest_scan++ = (uint8_t)((dest_b) >> 16);
        *dest_scan++ = (uint8_t)((dest_g) >> 16);
        *dest_scan++ = (uint8_t)((dest_r) >> 16);
        *dest_scan++ = (uint8_t)((dest_a) >> 16);
      } break;
      case 9: {
        uint32_t dest_b = 0;
        uint32_t dest_g = 0;
        uint32_t dest_r = 0;
        for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd;
             j++) {
          int pixel_weight =
              pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart];
          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++ = (uint8_t)((dest_b) >> 16);
        *dest_scan++ = (uint8_t)((dest_g) >> 16);
        *dest_scan++ = (uint8_t)((dest_r) >> 16);
        dest_scan += dest_bytes_per_pixel - 3;
      } break;
      case 10: {
        uint32_t dest_b = 0;
        uint32_t dest_g = 0;
        uint32_t dest_r = 0;
        for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd;
             j++) {
          int pixel_weight =
              pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart];
          const uint8_t* src_pixel = src_scan + j * src_bytes_per_pixel;
          uint8_t src_b = 0;
          uint8_t src_g = 0;
          uint8_t src_r = 0;
          std::tie(src_r, src_g, src_b) =
              AdobeCMYK_to_sRGB1(255 - src_pixel[0], 255 - src_pixel[1],
                                 255 - src_pixel[2], 255 - src_pixel[3]);
          dest_b += pixel_weight * src_b;
          dest_g += pixel_weight * src_g;
          dest_r += pixel_weight * src_r;
        }
        *dest_scan++ = (uint8_t)((dest_b) >> 16);
        *dest_scan++ = (uint8_t)((dest_g) >> 16);
        *dest_scan++ = (uint8_t)((dest_r) >> 16);
        dest_scan += dest_bytes_per_pixel - 3;
      } break;
      case 11: {
        uint32_t dest_alpha = 0;
        uint32_t dest_r = 0;
        uint32_t dest_g = 0;
        uint32_t dest_b = 0;
        for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd;
             j++) {
          int pixel_weight =
              pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart];
          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++ = (uint8_t)((dest_b) >> 16);
        *dest_scan++ = (uint8_t)((dest_g) >> 16);
        *dest_scan++ = (uint8_t)((dest_r) >> 16);
        *dest_scan++ = (uint8_t)((dest_alpha * 255) >> 16);
      } break;
      default:
        return;
    }
  }
}

void ProgressiveDecoder::ResampleVert(
    const RetainPtr<CFX_DIBitmap>& pDeviceBitmap,
    double scale_y,
    int dest_row) {
  int dest_Bpp = pDeviceBitmap->GetBPP() >> 3;
  uint32_t dest_ScanOffet = m_startX * dest_Bpp;
  int dest_top = m_startY;
  pdfium::base::CheckedNumeric<int> check_dest_row_1 = dest_row;
  check_dest_row_1 -= pdfium::base::checked_cast<int>(scale_y);
  int dest_row_1 = check_dest_row_1.ValueOrDie();
  if (dest_row_1 < dest_top) {
    int dest_bottom = dest_top + m_sizeY;
    if (dest_row + (int)scale_y >= dest_bottom - 1) {
      const uint8_t* scan_src =
          pDeviceBitmap->GetScanline(dest_row) + dest_ScanOffet;
      while (++dest_row < dest_bottom) {
        uint8_t* scan_des =
            pDeviceBitmap->GetWritableScanline(dest_row) + dest_ScanOffet;
        uint32_t size = m_sizeX * dest_Bpp;
        memmove(scan_des, scan_src, size);
      }
    }
    return;
  }
  for (; dest_row_1 < dest_row; dest_row_1++) {
    uint8_t* scan_des =
        pDeviceBitmap->GetWritableScanline(dest_row_1) + dest_ScanOffet;
    PixelWeight* pWeight = m_WeightVert.GetPixelWeight(dest_row_1 - dest_top);
    const uint8_t* scan_src1 =
        pDeviceBitmap->GetScanline(pWeight->m_SrcStart + dest_top) +
        dest_ScanOffet;
    const uint8_t* scan_src2 =
        pDeviceBitmap->GetScanline(pWeight->m_SrcEnd + dest_top) +
        dest_ScanOffet;
    for (int dest_col = 0; dest_col < m_sizeX; dest_col++) {
      switch (pDeviceBitmap->GetFormat()) {
        case FXDIB_Invalid:
        case FXDIB_1bppMask:
        case FXDIB_1bppRgb:
          return;
        case FXDIB_8bppMask:
        case FXDIB_8bppRgb: {
          if (pDeviceBitmap->GetPalette()) {
            return;
          }
          int dest_g = 0;
          dest_g += pWeight->m_Weights[0] * (*scan_src1++);
          dest_g += pWeight->m_Weights[1] * (*scan_src2++);
          *scan_des++ = (uint8_t)(dest_g >> 16);
        } break;
        case FXDIB_Rgb:
        case FXDIB_Rgb32: {
          uint32_t dest_b = 0;
          uint32_t dest_g = 0;
          uint32_t dest_r = 0;
          dest_b += pWeight->m_Weights[0] * (*scan_src1++);
          dest_g += pWeight->m_Weights[0] * (*scan_src1++);
          dest_r += pWeight->m_Weights[0] * (*scan_src1++);
          scan_src1 += dest_Bpp - 3;
          dest_b += pWeight->m_Weights[1] * (*scan_src2++);
          dest_g += pWeight->m_Weights[1] * (*scan_src2++);
          dest_r += pWeight->m_Weights[1] * (*scan_src2++);
          scan_src2 += dest_Bpp - 3;
          *scan_des++ = (uint8_t)((dest_b) >> 16);
          *scan_des++ = (uint8_t)((dest_g) >> 16);
          *scan_des++ = (uint8_t)((dest_r) >> 16);
          scan_des += dest_Bpp - 3;
        } break;
        case FXDIB_Argb: {
          uint32_t dest_a = 0;
          uint32_t dest_b = 0;
          uint32_t dest_g = 0;
          uint32_t dest_r = 0;
          dest_b += pWeight->m_Weights[0] * (*scan_src1++);
          dest_g += pWeight->m_Weights[0] * (*scan_src1++);
          dest_r += pWeight->m_Weights[0] * (*scan_src1++);
          dest_a += pWeight->m_Weights[0] * (*scan_src1++);
          dest_b += pWeight->m_Weights[1] * (*scan_src2++);
          dest_g += pWeight->m_Weights[1] * (*scan_src2++);
          dest_r += pWeight->m_Weights[1] * (*scan_src2++);
          dest_a += pWeight->m_Weights[1] * (*scan_src2++);
          *scan_des++ = (uint8_t)((dest_b) >> 16);
          *scan_des++ = (uint8_t)((dest_g) >> 16);
          *scan_des++ = (uint8_t)((dest_r) >> 16);
          *scan_des++ = (uint8_t)((dest_a) >> 16);
        } break;
        default:
          return;
      }
    }
  }
  int dest_bottom = dest_top + m_sizeY;
  if (dest_row + (int)scale_y >= dest_bottom - 1) {
    const uint8_t* scan_src =
        pDeviceBitmap->GetScanline(dest_row) + dest_ScanOffet;
    while (++dest_row < dest_bottom) {
      uint8_t* scan_des =
          pDeviceBitmap->GetWritableScanline(dest_row) + dest_ScanOffet;
      uint32_t size = m_sizeX * dest_Bpp;
      memmove(scan_des, scan_src, size);
    }
  }
}

void ProgressiveDecoder::Resample(const RetainPtr<CFX_DIBitmap>& pDeviceBitmap,
                                  int32_t src_line,
                                  uint8_t* src_scan,
                                  FXCodec_Format src_format) {
  int src_top = m_clipBox.top;
  int dest_top = m_startY;
  int src_height = m_clipBox.Height();
  int dest_height = m_sizeY;
  if (src_line >= src_top) {
    double scale_y = static_cast<double>(dest_height) / src_height;
    int src_row = src_line - src_top;
    int dest_row = (int)(src_row * scale_y) + dest_top;
    if (dest_row >= dest_top + dest_height)
      return;

    ReSampleScanline(pDeviceBitmap, dest_row, m_pDecodeBuf.get(), src_format);
    if (scale_y > 1.0)
      ResampleVert(pDeviceBitmap, scale_y, dest_row);
  }
}

std::pair<FXCODEC_STATUS, size_t> ProgressiveDecoder::GetFrames() {
  if (!(m_status == FXCODEC_STATUS_FRAME_READY ||
        m_status == FXCODEC_STATUS_FRAME_TOBECONTINUE)) {
    return {FXCODEC_STATUS_ERROR, 0};
  }

  switch (m_imageType) {
#ifdef PDF_ENABLE_XFA_BMP
    case FXCODEC_IMAGE_BMP:
#endif  // PDF_ENABLE_XFA_BMP
    case FXCODEC_IMAGE_JPG:
#ifdef PDF_ENABLE_XFA_PNG
    case FXCODEC_IMAGE_PNG:
#endif  // PDF_ENABLE_XFA_PNG
#ifdef PDF_ENABLE_XFA_TIFF
    case FXCODEC_IMAGE_TIFF:
#endif  // PDF_ENABLE_XFA_TIFF
      m_FrameNumber = 1;
      m_status = FXCODEC_STATUS_DECODE_READY;
      return {m_status, 1};
#ifdef PDF_ENABLE_XFA_GIF
    case FXCODEC_IMAGE_GIF: {
      GifModule* pGifModule = m_pCodecMgr->GetGifModule();
      if (!pGifModule) {
        m_status = FXCODEC_STATUS_ERR_MEMORY;
        return {m_status, 0};
      }
      while (true) {
        CFX_GifDecodeStatus readResult;
        std::tie(readResult, m_FrameNumber) =
            pGifModule->LoadFrameInfo(m_pGifContext.get());
        while (readResult == CFX_GifDecodeStatus::Unfinished) {
          FXCODEC_STATUS error_status = FXCODEC_STATUS_ERR_READ;
          if (!GifReadMoreData(pGifModule, error_status))
            return {error_status, 0};

          std::tie(readResult, m_FrameNumber) =
              pGifModule->LoadFrameInfo(m_pGifContext.get());
        }
        if (readResult == CFX_GifDecodeStatus::Success) {
          m_status = FXCODEC_STATUS_DECODE_READY;
          return {m_status, m_FrameNumber};
        }
        m_pGifContext = nullptr;
        m_status = FXCODEC_STATUS_ERROR;
        return {m_status, 0};
      }
    }
#endif  // PDF_ENABLE_XFA_GIF
    default:
      return {FXCODEC_STATUS_ERROR, 0};
  }
}

FXCODEC_STATUS ProgressiveDecoder::StartDecode(
    const RetainPtr<CFX_DIBitmap>& pDIBitmap,
    int start_x,
    int start_y,
    int size_x,
    int size_y) {
  if (m_status != FXCODEC_STATUS_DECODE_READY)
    return FXCODEC_STATUS_ERROR;

  if (!pDIBitmap || pDIBitmap->GetBPP() < 8 || m_FrameNumber == 0)
    return FXCODEC_STATUS_ERR_PARAMS;

  m_pDeviceBitmap = pDIBitmap;
  if (m_clipBox.IsEmpty())
    return FXCODEC_STATUS_ERR_PARAMS;
  if (size_x <= 0 || size_x > 65535 || size_y <= 0 || size_y > 65535)
    return FXCODEC_STATUS_ERR_PARAMS;

  FX_RECT device_rc =
      FX_RECT(start_x, start_y, start_x + size_x, start_y + size_y);
  int32_t out_range_x = device_rc.right - pDIBitmap->GetWidth();
  int32_t out_range_y = device_rc.bottom - pDIBitmap->GetHeight();
  device_rc.Intersect(
      FX_RECT(0, 0, pDIBitmap->GetWidth(), pDIBitmap->GetHeight()));
  if (device_rc.IsEmpty())
    return FXCODEC_STATUS_ERR_PARAMS;

  m_startX = device_rc.left;
  m_startY = device_rc.top;
  m_sizeX = device_rc.Width();
  m_sizeY = device_rc.Height();
  m_FrameCur = 0;
  if (start_x < 0 || out_range_x > 0) {
    float scaleX = (float)m_clipBox.Width() / (float)size_x;
    if (start_x < 0) {
      m_clipBox.left -= (int32_t)ceil((float)start_x * scaleX);
    }
    if (out_range_x > 0) {
      m_clipBox.right -= (int32_t)floor((float)out_range_x * scaleX);
    }
  }
  if (start_y < 0 || out_range_y > 0) {
    float scaleY = (float)m_clipBox.Height() / (float)size_y;
    if (start_y < 0) {
      m_clipBox.top -= (int32_t)ceil((float)start_y * scaleY);
    }
    if (out_range_y > 0) {
      m_clipBox.bottom -= (int32_t)floor((float)out_range_y * scaleY);
    }
  }
  if (m_clipBox.IsEmpty()) {
    return FXCODEC_STATUS_ERR_PARAMS;
  }
  switch (m_imageType) {
#ifdef PDF_ENABLE_XFA_BMP
    case FXCODEC_IMAGE_BMP:
      return BmpStartDecode(pDIBitmap);
#endif  // PDF_ENABLE_XFA_BMP
#ifdef PDF_ENABLE_XFA_GIF
    case FXCODEC_IMAGE_GIF:
      return GifStartDecode(pDIBitmap);
#endif  // PDF_ENABLE_XFA_GIF
    case FXCODEC_IMAGE_JPG:
      return JpegStartDecode(pDIBitmap);
#ifdef PDF_ENABLE_XFA_PNG
    case FXCODEC_IMAGE_PNG:
      return PngStartDecode(pDIBitmap);
#endif  // PDF_ENABLE_XFA_PNG
#ifdef PDF_ENABLE_XFA_TIFF
    case FXCODEC_IMAGE_TIFF:
      m_status = FXCODEC_STATUS_DECODE_TOBECONTINUE;
      return m_status;
#endif  // PDF_ENABLE_XFA_TIFF
    default:
      return FXCODEC_STATUS_ERROR;
  }
}

FXCODEC_STATUS ProgressiveDecoder::ContinueDecode() {
  if (m_status != FXCODEC_STATUS_DECODE_TOBECONTINUE)
    return FXCODEC_STATUS_ERROR;

  switch (m_imageType) {
    case FXCODEC_IMAGE_JPG:
      return JpegContinueDecode();
#ifdef PDF_ENABLE_XFA_BMP
    case FXCODEC_IMAGE_BMP:
      return BmpContinueDecode();
#endif  // PDF_ENABLE_XFA_BMP
#ifdef PDF_ENABLE_XFA_GIF
    case FXCODEC_IMAGE_GIF:
      return GifContinueDecode();
#endif  // PDF_ENABLE_XFA_GIF
#ifdef PDF_ENABLE_XFA_PNG
    case FXCODEC_IMAGE_PNG:
      return PngContinueDecode();
#endif  // PDF_ENABLE_XFA_PNG
#ifdef PDF_ENABLE_XFA_TIFF
    case FXCODEC_IMAGE_TIFF:
      return TiffContinueDecode();
#endif  // PDF_ENABLE_XFA_TIFF
    default:
      return FXCODEC_STATUS_ERROR;
  }
}

std::unique_ptr<ProgressiveDecoder> ModuleMgr::CreateProgressiveDecoder() {
  return pdfium::MakeUnique<ProgressiveDecoder>(this);
}

}  // namespace fxcodec
