// 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/codec/ccodec_progressivedecoder.h"

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

#include "core/fxcodec/fx_codec.h"
#include "core/fxcrt/fx_stream.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 {

#ifdef PDF_ENABLE_XFA_PNG
#if _FX_OS_ == _FX_OS_MACOSX_
const double kPngGamma = 1.7;
#else   // _FX_OS_ == _FX_OS_MACOSX_
const double kPngGamma = 2.2;
#endif  // _FX_OS_ == _FX_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

CCodec_ProgressiveDecoder::CFXCODEC_WeightTable::CFXCODEC_WeightTable() {}

CCodec_ProgressiveDecoder::CFXCODEC_WeightTable::~CFXCODEC_WeightTable() {}

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

CCodec_ProgressiveDecoder::CFXCODEC_HorzTable::CFXCODEC_HorzTable() {}

CCodec_ProgressiveDecoder::CFXCODEC_HorzTable::~CFXCODEC_HorzTable() {}

void CCodec_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;
  }
}

CCodec_ProgressiveDecoder::CFXCODEC_VertTable::CFXCODEC_VertTable() {}

CCodec_ProgressiveDecoder::CFXCODEC_VertTable::~CFXCODEC_VertTable() {}

void CCodec_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];
    }
  }
}

CCodec_ProgressiveDecoder::CCodec_ProgressiveDecoder(
    CCodec_ModuleMgr* pCodecMgr)
    : m_pCodecMgr(pCodecMgr) {}

CCodec_ProgressiveDecoder::~CCodec_ProgressiveDecoder() {}

#ifdef PDF_ENABLE_XFA_PNG
bool CCodec_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 CCodec_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 CCodec_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 CCodec_ProgressiveDecoder::GifRecordCurrentPosition(uint32_t& cur_pos) {
  uint32_t remain_size =
      m_pCodecMgr->GetGifModule()->GetAvailInput(m_pGifContext.get());
  cur_pos = m_offSet - remain_size;
}

bool CCodec_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 CCodec_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 CCodec_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 CCodec_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 CCodec_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 CCodec_ProgressiveDecoder::BmpDetectImageTypeInBuffer(
    CFX_DIBAttribute* pAttribute) {
  CCodec_BmpModule* pBmpModule = m_pCodecMgr->GetBmpModule();
  if (!pBmpModule) {
    m_status = FXCODEC_STATUS_ERR_MEMORY;
    return false;
  }

  std::unique_ptr<CodecModuleIface::Context> pBmpContext =
      pBmpModule->Start(this);
  pBmpModule->Input(pBmpContext.get(),
                    pdfium::MakeRetain<CFX_CodecMemory>(
                        pdfium::make_span(m_pSrcBuf.get(), m_SrcSize)),
                    nullptr);

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

  if (readResult != 1) {
    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_SrcSize > m_offSet ? m_SrcSize - 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 CCodec_ProgressiveDecoder::BmpReadMoreData(
    CCodec_BmpModule* pBmpModule,
    CodecModuleIface::Context* pContext,
    FXCODEC_STATUS& err_status) {
  return ReadMoreData(pBmpModule, pContext, false, err_status);
}

FXCODEC_STATUS CCodec_ProgressiveDecoder::BmpStartDecode(
    const RetainPtr<CFX_DIBitmap>& pDIBitmap) {
  CCodec_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 CCodec_ProgressiveDecoder::BmpContinueDecode() {
  CCodec_BmpModule* pBmpModule = m_pCodecMgr->GetBmpModule();
  if (!pBmpModule) {
    m_status = FXCODEC_STATUS_ERR_MEMORY;
    return m_status;
  }
  while (true) {
    int32_t readRes = pBmpModule->LoadImage(m_pBmpContext.get());
    while (readRes == 2) {
      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;
      }
      readRes = pBmpModule->LoadImage(m_pBmpContext.get());
    }
    if (readRes == 1) {
      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 CCodec_ProgressiveDecoder::GifReadMoreData(CCodec_GifModule* pGifModule,
                                                FXCODEC_STATUS& err_status) {
  if (!ReadMoreData(pGifModule, m_pGifContext.get(), m_InvalidateGifBuffer,
                    err_status)) {
    return false;
  }
  m_InvalidateGifBuffer = false;
  return true;
}

bool CCodec_ProgressiveDecoder::GifDetectImageTypeInBuffer(
    CFX_DIBAttribute* pAttribute) {
  CCodec_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(),
                    pdfium::MakeRetain<CFX_CodecMemory>(
                        pdfium::make_span(m_pSrcBuf.get(), m_SrcSize)),
                    nullptr);
  m_SrcComponents = 1;
  CFX_GifDecodeStatus readResult = pGifModule->ReadHeader(
      m_pGifContext.get(), &m_SrcWidth, &m_SrcHeight, &m_GifPltNumber,
      &m_pGifPalette, &m_GifBgIndex, nullptr);
  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, nullptr);
  }
  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 CCodec_ProgressiveDecoder::GifStartDecode(
    const RetainPtr<CFX_DIBitmap>& pDIBitmap) {
  CCodec_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 CCodec_ProgressiveDecoder::GifContinueDecode() {
  CCodec_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, nullptr);
  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, nullptr);
  }

  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 CCodec_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 CCodec_ProgressiveDecoder::JpegReadMoreData(CCodec_JpegModule* pJpegModule,
                                                 FXCODEC_STATUS& err_status) {
  return ReadMoreData(pJpegModule, m_pJpegContext.get(), false, err_status);
}

bool CCodec_ProgressiveDecoder::JpegDetectImageTypeInBuffer(
    CFX_DIBAttribute* pAttribute) {
  CCodec_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(),
                     pdfium::MakeRetain<CFX_CodecMemory>(
                         pdfium::make_span(m_pSrcBuf.get(), m_SrcSize)),
                     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 CCodec_ProgressiveDecoder::JpegStartDecode(
    const RetainPtr<CFX_DIBitmap>& pDIBitmap) {
  CCodec_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 CCodec_ProgressiveDecoder::JpegContinueDecode() {
  CCodec_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 CCodec_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 CCodec_ProgressiveDecoder::PngDetectImageTypeInBuffer(
    CFX_DIBAttribute* pAttribute) {
  CCodec_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;
  }
  bool bResult =
      pPngModule->Input(m_pPngContext.get(),
                        pdfium::MakeRetain<CFX_CodecMemory>(
                            pdfium::make_span(m_pSrcBuf.get(), m_SrcSize)),
                        pAttribute);
  while (bResult) {
    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_pSrcBuf && input_size > m_SrcSize) {
      m_pSrcBuf.reset(FX_Alloc(uint8_t, input_size));
      m_SrcSize = input_size;
    }
    bResult = m_pFile->ReadBlock(m_pSrcBuf.get(), m_offSet, input_size);
    if (!bResult) {
      m_status = FXCODEC_STATUS_ERR_READ;
      return false;
    }
    m_offSet += input_size;
    bResult =
        pPngModule->Input(m_pPngContext.get(),
                          pdfium::MakeRetain<CFX_CodecMemory>(
                              pdfium::make_span(m_pSrcBuf.get(), input_size)),
                          pAttribute);
  }
  m_pPngContext.reset();
  if (m_SrcPassNumber == 0) {
    m_status = FXCODEC_STATUS_ERR_FORMAT;
    return false;
  }
  return true;
}

FXCODEC_STATUS CCodec_ProgressiveDecoder::PngStartDecode(
    const RetainPtr<CFX_DIBitmap>& pDIBitmap) {
  CCodec_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 CCodec_ProgressiveDecoder::PngContinueDecode() {
  CCodec_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_pSrcBuf && input_size > m_SrcSize) {
      m_pSrcBuf.reset(FX_Alloc(uint8_t, input_size));
      m_SrcSize = input_size;
    }
    bool bResult = m_pFile->ReadBlock(m_pSrcBuf.get(), 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(),
                          pdfium::MakeRetain<CFX_CodecMemory>(
                              pdfium::make_span(m_pSrcBuf.get(), input_size)),
                          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 CCodec_ProgressiveDecoder::TiffDetectImageTypeFromFile(
    CFX_DIBAttribute* pAttribute) {
  CCodec_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 CCodec_ProgressiveDecoder::TiffContinueDecode() {
  CCodec_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;
  }
  RetainPtr<CFX_DIBitmap> pStrechBitmap =
      pFormatBitmap->StretchTo(m_sizeX, m_sizeY, FXDIB_INTERPOL, 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 CCodec_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_SrcSize = static_cast<uint32_t>(size);
  m_pSrcBuf.reset(FX_Alloc(uint8_t, m_SrcSize));

  m_offSet = 0;
  if (!m_pFile->ReadBlock(m_pSrcBuf.get(), m_offSet, m_SrcSize)) {
    m_status = FXCODEC_STATUS_ERR_READ;
    return false;
  }
  m_offSet += m_SrcSize;

  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(pAttribute);
#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 CCodec_ProgressiveDecoder::ReadMoreData(
    CodecModuleIface* pModule,
    CodecModuleIface::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.
  uint32_t dwUnconsumed = 0;
  if (!invalidate_buffer) {
    FX_SAFE_UINT32 avail_input = pModule->GetAvailInput(pContext);
    if (!avail_input.IsValid())
      return false;
    dwUnconsumed = avail_input.ValueOrDie();
  }

  if (dwUnconsumed == m_SrcSize) {
    // 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);
    uint32_t dwNewSize = m_SrcSize + dwBytesToFetchFromFile;
    uint8_t* pNewBuf = FX_TryRealloc(uint8_t, m_pSrcBuf.release(), dwNewSize);
    if (!pNewBuf) {
      err_status = FXCODEC_STATUS_ERR_MEMORY;
      return false;
    }
    m_SrcSize = dwNewSize;
    m_pSrcBuf.reset(pNewBuf);
  } else {
    uint32_t dwConsumed = m_SrcSize - dwUnconsumed;
    memmove(m_pSrcBuf.get(), m_pSrcBuf.get() + dwConsumed, dwUnconsumed);
    dwBytesToFetchFromFile = std::min(dwBytesToFetchFromFile, dwConsumed);
    m_SrcSize = dwBytesToFetchFromFile + dwUnconsumed;
  }

  // Append new data past the bytes not yet processed by the codec.
  if (!m_pFile->ReadBlock(m_pSrcBuf.get() + dwUnconsumed, m_offSet,
                          dwBytesToFetchFromFile)) {
    err_status = FXCODEC_STATUS_ERR_READ;
    return false;
  }
  m_offSet += dwBytesToFetchFromFile;
  return pModule->Input(pContext,
                        pdfium::MakeRetain<CFX_CodecMemory>(
                            pdfium::make_span(m_pSrcBuf.get(), m_SrcSize)),
                        nullptr);
}

FXCODEC_STATUS CCodec_ProgressiveDecoder::LoadImageInfo(
    const RetainPtr<IFX_SeekableReadStream>& pFile,
    FXCODEC_IMAGE_TYPE imageType,
    CFX_DIBAttribute* pAttribute,
    bool bSkipImageTypeCheck) {
  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(0, 0, 0, 0);
  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 CCodec_ProgressiveDecoder::SetClipBox(FX_RECT* clip) {
  if (m_status != FXCODEC_STATUS_FRAME_READY)
    return;

  if (clip->IsEmpty()) {
    m_clipBox = FX_RECT(0, 0, 0, 0);
    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(0, 0, 0, 0);
    return;
  }
  m_clipBox = *clip;
}

void CCodec_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 CCodec_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 CCodec_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 CCodec_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 CCodec_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> CCodec_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: {
      CCodec_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 CCodec_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 CCodec_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<CCodec_ProgressiveDecoder>
CCodec_ModuleMgr::CreateProgressiveDecoder() {
  return pdfium::MakeUnique<CCodec_ProgressiveDecoder>(this);
}
