// Copyright 2017 PDFium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com

#include "core/fpdfapi/page/cpdf_dibbase.h"

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

#include "core/fpdfapi/page/cpdf_docpagedata.h"
#include "core/fpdfapi/page/cpdf_image.h"
#include "core/fpdfapi/page/cpdf_imageobject.h"
#include "core/fpdfapi/parser/cpdf_array.h"
#include "core/fpdfapi/parser/cpdf_dictionary.h"
#include "core/fpdfapi/parser/cpdf_document.h"
#include "core/fpdfapi/parser/cpdf_stream.h"
#include "core/fpdfapi/parser/cpdf_stream_acc.h"
#include "core/fpdfapi/parser/fpdf_parser_decode.h"
#include "core/fpdfapi/parser/fpdf_parser_utility.h"
#include "core/fxcodec/basic/basicmodule.h"
#include "core/fxcodec/fx_codec.h"
#include "core/fxcodec/jbig2/jbig2module.h"
#include "core/fxcodec/jpeg/jpegmodule.h"
#include "core/fxcodec/jpx/cjpx_decoder.h"
#include "core/fxcodec/jpx/jpxmodule.h"
#include "core/fxcodec/scanlinedecoder.h"
#include "core/fxcrt/cfx_fixedbufgrow.h"
#include "core/fxcrt/fx_safe_types.h"
#include "core/fxge/dib/cfx_dibitmap.h"
#include "third_party/base/ptr_util.h"
#include "third_party/base/stl_util.h"

namespace {

constexpr int kMaxImageDimension = 0x01FFFF;

unsigned int GetBits8(const uint8_t* pData, uint64_t bitpos, size_t nbits) {
  ASSERT(nbits == 1 || nbits == 2 || nbits == 4 || nbits == 8 || nbits == 16);
  ASSERT((bitpos & (nbits - 1)) == 0);
  unsigned int byte = pData[bitpos / 8];
  if (nbits == 8)
    return byte;

  if (nbits == 16)
    return byte * 256 + pData[bitpos / 8 + 1];

  return (byte >> (8 - nbits - (bitpos % 8))) & ((1 << nbits) - 1);
}

bool GetBitValue(const uint8_t* pSrc, uint32_t pos) {
  return pSrc[pos / 8] & (1 << (7 - pos % 8));
}

// Just to sanity check and filter out obvious bad values.
bool IsMaybeValidBitsPerComponent(int bpc) {
  return bpc >= 0 && bpc <= 16;
}

bool IsAllowedBitsPerComponent(int bpc) {
  return bpc == 1 || bpc == 2 || bpc == 4 || bpc == 8 || bpc == 16;
}

bool IsAllowedICCComponents(int nComp) {
  return nComp == 1 || nComp == 3 || nComp == 4;
}

bool IsColorIndexOutOfBounds(uint8_t index, const DIB_COMP_DATA& comp_datum) {
  return index < comp_datum.m_ColorKeyMin || index > comp_datum.m_ColorKeyMax;
}

bool AreColorIndicesOutOfBounds(const uint8_t* indices,
                                const DIB_COMP_DATA* comp_data,
                                size_t count) {
  for (size_t i = 0; i < count; ++i) {
    if (IsColorIndexOutOfBounds(indices[i], comp_data[i]))
      return true;
  }
  return false;
}

CJPX_Decoder::ColorSpaceOption ColorSpaceOptionFromColorSpace(
    CPDF_ColorSpace* pCS) {
  if (!pCS)
    return CJPX_Decoder::kNoColorSpace;
  if (pCS->GetFamily() == PDFCS_INDEXED)
    return CJPX_Decoder::kIndexedColorSpace;
  return CJPX_Decoder::kNormalColorSpace;
}

}  // namespace

CPDF_DIBBase::CPDF_DIBBase() = default;

CPDF_DIBBase::~CPDF_DIBBase() = default;

bool CPDF_DIBBase::Load(CPDF_Document* pDoc, const CPDF_Stream* pStream) {
  if (!pStream)
    return false;

  m_pDocument = pDoc;
  m_pDict.Reset(pStream->GetDict());
  if (!m_pDict)
    return false;

  m_pStream.Reset(pStream);
  m_Width = m_pDict->GetIntegerFor("Width");
  m_Height = m_pDict->GetIntegerFor("Height");
  if (m_Width <= 0 || m_Height <= 0 || m_Width > kMaxImageDimension ||
      m_Height > kMaxImageDimension) {
    return false;
  }
  m_GroupFamily = 0;
  m_bLoadMask = false;
  if (!LoadColorInfo(nullptr, nullptr))
    return false;

  if (m_bDoBpcCheck && (m_bpc == 0 || m_nComponents == 0))
    return false;

  FX_SAFE_UINT32 src_size =
      fxcodec::CalculatePitch8(m_bpc, m_nComponents, m_Width) * m_Height;
  if (!src_size.IsValid())
    return false;

  m_pStreamAcc = pdfium::MakeRetain<CPDF_StreamAcc>(pStream);
  m_pStreamAcc->LoadAllDataImageAcc(src_size.ValueOrDie());
  if (m_pStreamAcc->GetSize() == 0 || !m_pStreamAcc->GetData())
    return false;

  if (CreateDecoder() == LoadState::kFail)
    return false;

  if (m_bImageMask) {
    m_bpp = 1;
    m_bpc = 1;
    m_nComponents = 1;
    m_AlphaFlag = 1;
  } else if (m_bpc * m_nComponents == 1) {
    m_bpp = 1;
  } else if (m_bpc * m_nComponents <= 8) {
    m_bpp = 8;
  } else {
    m_bpp = 24;
  }
  FX_SAFE_UINT32 pitch = fxcodec::CalculatePitch32(m_bpp, m_Width);
  if (!pitch.IsValid())
    return false;

  m_pLineBuf.reset(FX_Alloc(uint8_t, pitch.ValueOrDie()));
  LoadPalette();
  if (m_bColorKey) {
    m_bpp = 32;
    m_AlphaFlag = 2;
    pitch = fxcodec::CalculatePitch32(m_bpp, m_Width);
    if (!pitch.IsValid())
      return false;

    m_pMaskedLine.reset(FX_Alloc(uint8_t, pitch.ValueOrDie()));
  }
  m_Pitch = pitch.ValueOrDie();
  return true;
}

bool CPDF_DIBBase::ContinueToLoadMask() {
  if (m_bImageMask) {
    m_bpp = 1;
    m_bpc = 1;
    m_nComponents = 1;
    m_AlphaFlag = 1;
  } else if (m_bpc * m_nComponents == 1) {
    m_bpp = 1;
  } else if (m_bpc * m_nComponents <= 8) {
    m_bpp = 8;
  } else {
    m_bpp = 24;
  }
  if (!m_bpc || !m_nComponents) {
    return false;
  }
  FX_SAFE_UINT32 pitch = fxcodec::CalculatePitch32(m_bpp, m_Width);
  if (!pitch.IsValid())
    return false;

  m_pLineBuf.reset(FX_Alloc(uint8_t, pitch.ValueOrDie()));
  if (m_pColorSpace && m_bStdCS) {
    m_pColorSpace->EnableStdConversion(true);
  }
  LoadPalette();
  if (m_bColorKey) {
    m_bpp = 32;
    m_AlphaFlag = 2;
    pitch = fxcodec::CalculatePitch32(m_bpp, m_Width);
    if (!pitch.IsValid())
      return false;
    m_pMaskedLine.reset(FX_Alloc(uint8_t, pitch.ValueOrDie()));
  }
  m_Pitch = pitch.ValueOrDie();
  return true;
}

CPDF_DIBBase::LoadState CPDF_DIBBase::StartLoadDIBBase(
    CPDF_Document* pDoc,
    const CPDF_Stream* pStream,
    bool bHasMask,
    const CPDF_Dictionary* pFormResources,
    CPDF_Dictionary* pPageResources,
    bool bStdCS,
    uint32_t GroupFamily,
    bool bLoadMask) {
  if (!pStream)
    return LoadState::kFail;

  m_pDocument = pDoc;
  m_pDict.Reset(pStream->GetDict());
  m_pStream.Reset(pStream);
  m_bStdCS = bStdCS;
  m_bHasMask = bHasMask;
  m_Width = m_pDict->GetIntegerFor("Width");
  m_Height = m_pDict->GetIntegerFor("Height");
  if (m_Width <= 0 || m_Height <= 0 || m_Width > kMaxImageDimension ||
      m_Height > kMaxImageDimension) {
    return LoadState::kFail;
  }
  m_GroupFamily = GroupFamily;
  m_bLoadMask = bLoadMask;
  if (!LoadColorInfo(m_pStream->IsInline() ? pFormResources : nullptr,
                     pPageResources)) {
    return LoadState::kFail;
  }
  if (m_bDoBpcCheck && (m_bpc == 0 || m_nComponents == 0))
    return LoadState::kFail;

  FX_SAFE_UINT32 src_size =
      fxcodec::CalculatePitch8(m_bpc, m_nComponents, m_Width) * m_Height;
  if (!src_size.IsValid())
    return LoadState::kFail;

  m_pStreamAcc = pdfium::MakeRetain<CPDF_StreamAcc>(pStream);
  m_pStreamAcc->LoadAllDataImageAcc(src_size.ValueOrDie());
  if (m_pStreamAcc->GetSize() == 0 || !m_pStreamAcc->GetData())
    return LoadState::kFail;

  LoadState iCreatedDecoder = CreateDecoder();
  if (iCreatedDecoder == LoadState::kFail)
    return LoadState::kFail;

  if (!ContinueToLoadMask())
    return LoadState::kFail;

  LoadState iLoadedMask = m_bHasMask ? StartLoadMask() : LoadState::kSuccess;
  if (iCreatedDecoder == LoadState::kContinue ||
      iLoadedMask == LoadState::kContinue) {
    return LoadState::kContinue;
  }

  ASSERT(iCreatedDecoder == LoadState::kSuccess);
  ASSERT(iLoadedMask == LoadState::kSuccess);
  if (m_pColorSpace && m_bStdCS)
    m_pColorSpace->EnableStdConversion(false);
  return LoadState::kSuccess;
}

CPDF_DIBBase::LoadState CPDF_DIBBase::ContinueLoadDIBBase(
    PauseIndicatorIface* pPause) {
  if (m_Status == LoadState::kContinue)
    return ContinueLoadMaskDIB(pPause);

  ByteString decoder = m_pStreamAcc->GetImageDecoder();
  if (decoder == "JPXDecode")
    return LoadState::kFail;

  if (decoder != "JBIG2Decode")
    return LoadState::kSuccess;

  if (m_Status == LoadState::kFail)
    return LoadState::kFail;

  FXCODEC_STATUS iDecodeStatus;
  Jbig2Module* pJbig2Module =
      fxcodec::ModuleMgr::GetInstance()->GetJbig2Module();
  if (!m_pJbig2Context) {
    m_pJbig2Context = pdfium::MakeUnique<Jbig2Context>();
    if (m_pStreamAcc->GetImageParam()) {
      const CPDF_Stream* pGlobals =
          m_pStreamAcc->GetImageParam()->GetStreamFor("JBIG2Globals");
      if (pGlobals) {
        m_pGlobalAcc = pdfium::MakeRetain<CPDF_StreamAcc>(pGlobals);
        m_pGlobalAcc->LoadAllDataFiltered();
      }
    }
    uint32_t nSrcObjNum = 0;
    pdfium::span<const uint8_t> pSrcSpan;
    if (m_pStreamAcc) {
      pSrcSpan = m_pStreamAcc->GetSpan();
      if (m_pStreamAcc->GetStream())
        nSrcObjNum = m_pStreamAcc->GetStream()->GetObjNum();
    }
    uint32_t nGlobalObjNum = 0;
    pdfium::span<const uint8_t> pGlobalSpan;
    if (m_pGlobalAcc) {
      pGlobalSpan = m_pGlobalAcc->GetSpan();
      if (m_pGlobalAcc->GetStream())
        nGlobalObjNum = m_pGlobalAcc->GetStream()->GetObjNum();
    }
    iDecodeStatus = pJbig2Module->StartDecode(
        m_pJbig2Context.get(), m_pDocument->CodecContext(), m_Width, m_Height,
        pSrcSpan, nSrcObjNum, pGlobalSpan, nGlobalObjNum,
        m_pCachedBitmap->GetBuffer(), m_pCachedBitmap->GetPitch(), pPause);
  } else {
    iDecodeStatus = pJbig2Module->ContinueDecode(m_pJbig2Context.get(), pPause);
  }

  if (iDecodeStatus < 0) {
    m_pJbig2Context.reset();
    m_pCachedBitmap.Reset();
    m_pGlobalAcc.Reset();
    return LoadState::kFail;
  }
  if (iDecodeStatus == FXCODEC_STATUS_DECODE_TOBECONTINUE)
    return LoadState::kContinue;

  LoadState iContinueStatus = LoadState::kSuccess;
  if (m_bHasMask) {
    if (ContinueLoadMaskDIB(pPause) == LoadState::kContinue) {
      iContinueStatus = LoadState::kContinue;
      m_Status = LoadState::kContinue;
    }
  }
  if (iContinueStatus == LoadState::kContinue)
    return LoadState::kContinue;

  if (m_pColorSpace && m_bStdCS)
    m_pColorSpace->EnableStdConversion(false);
  return iContinueStatus;
}

bool CPDF_DIBBase::LoadColorInfo(const CPDF_Dictionary* pFormResources,
                                 const CPDF_Dictionary* pPageResources) {
  m_bpc_orig = m_pDict->GetIntegerFor("BitsPerComponent");
  if (!IsMaybeValidBitsPerComponent(m_bpc_orig))
    return false;

  if (m_pDict->GetIntegerFor("ImageMask"))
    m_bImageMask = true;

  if (m_bImageMask || !m_pDict->KeyExist("ColorSpace")) {
    if (!m_bImageMask) {
      const CPDF_Object* pFilter = m_pDict->GetDirectObjectFor("Filter");
      if (pFilter) {
        ByteString filter;
        if (pFilter->IsName()) {
          filter = pFilter->GetString();
        } else if (const CPDF_Array* pArray = pFilter->AsArray()) {
          if (!ValidateDecoderPipeline(pArray))
            return false;
          filter = pArray->GetStringAt(pArray->size() - 1);
        }

        if (filter == "JPXDecode") {
          m_bDoBpcCheck = false;
          return true;
        }
      }
    }
    m_bImageMask = true;
    m_bpc = m_nComponents = 1;
    const CPDF_Array* pDecode = m_pDict->GetArrayFor("Decode");
    m_bDefaultDecode = !pDecode || !pDecode->GetIntegerAt(0);
    return true;
  }

  const CPDF_Object* pCSObj = m_pDict->GetDirectObjectFor("ColorSpace");
  if (!pCSObj)
    return false;

  auto* pDocPageData = CPDF_DocPageData::FromDocument(m_pDocument.Get());
  if (pFormResources)
    m_pColorSpace = pDocPageData->GetColorSpace(pCSObj, pFormResources);
  if (!m_pColorSpace)
    m_pColorSpace = pDocPageData->GetColorSpace(pCSObj, pPageResources);
  if (!m_pColorSpace)
    return false;

  m_Family = m_pColorSpace->GetFamily();
  m_nComponents = m_pColorSpace->CountComponents();
  if (m_Family == PDFCS_ICCBASED && pCSObj->IsName()) {
    ByteString cs = pCSObj->GetString();
    if (cs == "DeviceGray")
      m_nComponents = 1;
    else if (cs == "DeviceRGB")
      m_nComponents = 3;
    else if (cs == "DeviceCMYK")
      m_nComponents = 4;
  }
  ValidateDictParam();
  return GetDecodeAndMaskArray(&m_bDefaultDecode, &m_bColorKey);
}

bool CPDF_DIBBase::GetDecodeAndMaskArray(bool* bDefaultDecode,
                                         bool* bColorKey) {
  if (!m_pColorSpace)
    return false;

  m_CompData.resize(m_nComponents);
  int max_data = (1 << m_bpc) - 1;
  const CPDF_Array* pDecode = m_pDict->GetArrayFor("Decode");
  if (pDecode) {
    for (uint32_t i = 0; i < m_nComponents; i++) {
      m_CompData[i].m_DecodeMin = pDecode->GetNumberAt(i * 2);
      float max = pDecode->GetNumberAt(i * 2 + 1);
      m_CompData[i].m_DecodeStep = (max - m_CompData[i].m_DecodeMin) / max_data;
      float def_value;
      float def_min;
      float def_max;
      m_pColorSpace->GetDefaultValue(i, &def_value, &def_min, &def_max);
      if (m_Family == PDFCS_INDEXED)
        def_max = max_data;
      if (def_min != m_CompData[i].m_DecodeMin || def_max != max)
        *bDefaultDecode = false;
    }
  } else {
    for (uint32_t i = 0; i < m_nComponents; i++) {
      float def_value;
      m_pColorSpace->GetDefaultValue(i, &def_value, &m_CompData[i].m_DecodeMin,
                                     &m_CompData[i].m_DecodeStep);
      if (m_Family == PDFCS_INDEXED)
        m_CompData[i].m_DecodeStep = max_data;
      m_CompData[i].m_DecodeStep =
          (m_CompData[i].m_DecodeStep - m_CompData[i].m_DecodeMin) / max_data;
    }
  }
  if (m_pDict->KeyExist("SMask"))
    return true;

  const CPDF_Object* pMask = m_pDict->GetDirectObjectFor("Mask");
  if (!pMask)
    return true;

  if (const CPDF_Array* pArray = pMask->AsArray()) {
    if (pArray->size() >= m_nComponents * 2) {
      for (uint32_t i = 0; i < m_nComponents; i++) {
        int min_num = pArray->GetIntegerAt(i * 2);
        int max_num = pArray->GetIntegerAt(i * 2 + 1);
        m_CompData[i].m_ColorKeyMin = std::max(min_num, 0);
        m_CompData[i].m_ColorKeyMax = std::min(max_num, max_data);
      }
    }
    *bColorKey = true;
  }
  return true;
}

CPDF_DIBBase::LoadState CPDF_DIBBase::CreateDecoder() {
  ByteString decoder = m_pStreamAcc->GetImageDecoder();
  if (decoder.IsEmpty())
    return LoadState::kSuccess;

  if (m_bDoBpcCheck && m_bpc == 0)
    return LoadState::kFail;

  if (decoder == "JPXDecode") {
    m_pCachedBitmap = LoadJpxBitmap();
    return m_pCachedBitmap ? LoadState::kSuccess : LoadState::kFail;
  }

  if (decoder == "JBIG2Decode") {
    m_pCachedBitmap = pdfium::MakeRetain<CFX_DIBitmap>();
    if (!m_pCachedBitmap->Create(
            m_Width, m_Height, m_bImageMask ? FXDIB_1bppMask : FXDIB_1bppRgb)) {
      m_pCachedBitmap.Reset();
      return LoadState::kFail;
    }
    m_Status = LoadState::kSuccess;
    return LoadState::kContinue;
  }

  pdfium::span<const uint8_t> src_span = m_pStreamAcc->GetSpan();
  const CPDF_Dictionary* pParams = m_pStreamAcc->GetImageParam();
  if (decoder == "CCITTFaxDecode") {
    m_pDecoder = CreateFaxDecoder(src_span, m_Width, m_Height, pParams);
  } else if (decoder == "FlateDecode") {
    m_pDecoder = CreateFlateDecoder(src_span, m_Width, m_Height, m_nComponents,
                                    m_bpc, pParams);
  } else if (decoder == "RunLengthDecode") {
    m_pDecoder = BasicModule::CreateRunLengthDecoder(
        src_span, m_Width, m_Height, m_nComponents, m_bpc);
  } else if (decoder == "DCTDecode") {
    if (!CreateDCTDecoder(src_span, pParams))
      return LoadState::kFail;
  }
  if (!m_pDecoder)
    return LoadState::kFail;

  FX_SAFE_UINT32 requested_pitch =
      fxcodec::CalculatePitch8(m_bpc, m_nComponents, m_Width);
  if (!requested_pitch.IsValid())
    return LoadState::kFail;
  FX_SAFE_UINT32 provided_pitch = fxcodec::CalculatePitch8(
      m_pDecoder->GetBPC(), m_pDecoder->CountComps(), m_pDecoder->GetWidth());
  if (!provided_pitch.IsValid())
    return LoadState::kFail;
  if (provided_pitch.ValueOrDie() < requested_pitch.ValueOrDie())
    return LoadState::kFail;
  return LoadState::kSuccess;
}

bool CPDF_DIBBase::CreateDCTDecoder(pdfium::span<const uint8_t> src_span,
                                    const CPDF_Dictionary* pParams) {
  JpegModule* pJpegModule = fxcodec::ModuleMgr::GetInstance()->GetJpegModule();
  m_pDecoder = pJpegModule->CreateDecoder(
      src_span, m_Width, m_Height, m_nComponents,
      !pParams || pParams->GetIntegerFor("ColorTransform", 1));
  if (m_pDecoder)
    return true;

  bool bTransform = false;
  int comps;
  int bpc;
  if (!pJpegModule->LoadInfo(src_span, &m_Width, &m_Height, &comps, &bpc,
                             &bTransform)) {
    return false;
  }
  if (!CPDF_Image::IsValidJpegComponent(comps) ||
      !CPDF_Image::IsValidJpegBitsPerComponent(bpc)) {
    return false;
  }

  if (m_nComponents == static_cast<uint32_t>(comps)) {
    m_bpc = bpc;
    m_pDecoder = pJpegModule->CreateDecoder(src_span, m_Width, m_Height,
                                            m_nComponents, bTransform);
    return true;
  }

  m_nComponents = static_cast<uint32_t>(comps);
  m_CompData.clear();
  if (m_pColorSpace) {
    switch (m_Family) {
      case PDFCS_DEVICEGRAY:
      case PDFCS_DEVICERGB:
      case PDFCS_DEVICECMYK: {
        uint32_t dwMinComps = CPDF_ColorSpace::ComponentsForFamily(m_Family);
        if (m_pColorSpace->CountComponents() < dwMinComps ||
            m_nComponents < dwMinComps) {
          return false;
        }
        break;
      }
      case PDFCS_LAB: {
        if (m_nComponents != 3 || m_pColorSpace->CountComponents() < 3)
          return false;
        break;
      }
      case PDFCS_ICCBASED: {
        if (!IsAllowedICCComponents(m_nComponents) ||
            !IsAllowedICCComponents(m_pColorSpace->CountComponents()) ||
            m_pColorSpace->CountComponents() < m_nComponents) {
          return false;
        }
        break;
      }
      default: {
        if (m_pColorSpace->CountComponents() != m_nComponents)
          return false;
        break;
      }
    }
  } else {
    if (m_Family == PDFCS_LAB && m_nComponents != 3)
      return false;
  }
  if (!GetDecodeAndMaskArray(&m_bDefaultDecode, &m_bColorKey))
    return false;

  m_bpc = bpc;
  m_pDecoder = pJpegModule->CreateDecoder(src_span, m_Width, m_Height,
                                          m_nComponents, bTransform);
  return true;
}

RetainPtr<CFX_DIBitmap> CPDF_DIBBase::LoadJpxBitmap() {
  std::unique_ptr<CJPX_Decoder> decoder = JpxModule::CreateDecoder(
      m_pStreamAcc->GetSpan(),
      ColorSpaceOptionFromColorSpace(m_pColorSpace.Get()));
  if (!decoder)
    return nullptr;

  if (!decoder->StartDecode())
    return nullptr;

  uint32_t width = 0;
  uint32_t height = 0;
  uint32_t components = 0;
  decoder->GetInfo(&width, &height, &components);
  if (static_cast<int>(width) < m_Width || static_cast<int>(height) < m_Height)
    return nullptr;

  bool bSwapRGB = false;
  if (m_pColorSpace) {
    if (components != m_pColorSpace->CountComponents())
      return nullptr;

    if (m_pColorSpace == CPDF_ColorSpace::GetStockCS(PDFCS_DEVICERGB)) {
      bSwapRGB = true;
      m_pColorSpace = nullptr;
    }
  } else {
    if (components == 3) {
      bSwapRGB = true;
    } else if (components == 4) {
      m_pColorSpace = CPDF_ColorSpace::GetStockCS(PDFCS_DEVICECMYK);
    }
    m_nComponents = components;
  }

  FXDIB_Format format;
  if (components == 1) {
    format = FXDIB_8bppRgb;
  } else if (components <= 3) {
    format = FXDIB_Rgb;
  } else if (components == 4) {
    format = FXDIB_Rgb32;
  } else {
    width = (width * components + 2) / 3;
    format = FXDIB_Rgb;
  }

  auto pCachedBitmap = pdfium::MakeRetain<CFX_DIBitmap>();
  if (!pCachedBitmap->Create(width, height, format))
    return nullptr;

  pCachedBitmap->Clear(0xFFFFFFFF);
  std::vector<uint8_t> output_offsets(components);
  for (uint32_t i = 0; i < components; ++i)
    output_offsets[i] = i;
  if (bSwapRGB) {
    output_offsets[0] = 2;
    output_offsets[2] = 0;
  }
  if (!decoder->Decode(pCachedBitmap->GetBuffer(), pCachedBitmap->GetPitch(),
                       output_offsets)) {
    return nullptr;
  }

  if (m_pColorSpace && m_pColorSpace->GetFamily() == PDFCS_INDEXED &&
      m_bpc < 8) {
    int scale = 8 - m_bpc;
    for (uint32_t row = 0; row < height; ++row) {
      uint8_t* scanline = pCachedBitmap->GetWritableScanline(row);
      for (uint32_t col = 0; col < width; ++col) {
        *scanline = (*scanline) >> scale;
        ++scanline;
      }
    }
  }
  m_bpc = 8;
  return pCachedBitmap;
}

CPDF_DIBBase::LoadState CPDF_DIBBase::StartLoadMask() {
  m_MatteColor = 0XFFFFFFFF;
  m_pMaskStream.Reset(m_pDict->GetStreamFor("SMask"));
  if (!m_pMaskStream) {
    m_pMaskStream.Reset(ToStream(m_pDict->GetDirectObjectFor("Mask")));
    return m_pMaskStream ? StartLoadMaskDIB() : LoadState::kSuccess;
  }

  const CPDF_Array* pMatte = m_pMaskStream->GetDict()->GetArrayFor("Matte");
  if (pMatte && m_pColorSpace && m_Family != PDFCS_PATTERN &&
      m_pColorSpace->CountComponents() <= m_nComponents) {
    std::vector<float> colors =
        ReadArrayElementsToVector(pMatte, m_nComponents);

    float R;
    float G;
    float B;
    m_pColorSpace->GetRGB(colors.data(), &R, &G, &B);
    m_MatteColor = ArgbEncode(0, FXSYS_roundf(R * 255), FXSYS_roundf(G * 255),
                              FXSYS_roundf(B * 255));
  }
  return StartLoadMaskDIB();
}

CPDF_DIBBase::LoadState CPDF_DIBBase::ContinueLoadMaskDIB(
    PauseIndicatorIface* pPause) {
  if (!m_pMask)
    return LoadState::kSuccess;

  LoadState ret = m_pMask->ContinueLoadDIBBase(pPause);
  if (ret == LoadState::kContinue)
    return LoadState::kContinue;

  if (m_pColorSpace && m_bStdCS)
    m_pColorSpace->EnableStdConversion(false);

  if (ret == LoadState::kFail) {
    m_pMask.Reset();
    return LoadState::kFail;
  }
  return LoadState::kSuccess;
}

RetainPtr<CPDF_DIBBase> CPDF_DIBBase::DetachMask() {
  return std::move(m_pMask);
}

bool CPDF_DIBBase::IsJBigImage() const {
  return m_pStreamAcc->GetImageDecoder() == "JBIG2Decode";
}

CPDF_DIBBase::LoadState CPDF_DIBBase::StartLoadMaskDIB() {
  m_pMask = pdfium::MakeRetain<CPDF_DIBBase>();
  LoadState ret =
      m_pMask->StartLoadDIBBase(m_pDocument.Get(), m_pMaskStream.Get(), false,
                                nullptr, nullptr, true, 0, false);
  if (ret == LoadState::kContinue) {
    if (m_Status == LoadState::kFail)
      m_Status = LoadState::kContinue;
    return LoadState::kContinue;
  }
  if (ret == LoadState::kFail)
    m_pMask.Reset();
  return LoadState::kSuccess;
}

void CPDF_DIBBase::LoadPalette() {
  if (!m_pColorSpace || m_Family == PDFCS_PATTERN)
    return;

  if (m_bpc == 0)
    return;

  // Use FX_SAFE_UINT32 just to be on the safe side, in case |m_bpc| or
  // |m_nComponents| somehow gets a bad value.
  FX_SAFE_UINT32 safe_bits = m_bpc;
  safe_bits *= m_nComponents;
  uint32_t bits = safe_bits.ValueOrDefault(255);
  if (bits > 8)
    return;

  if (bits == 1) {
    if (m_bDefaultDecode &&
        (m_Family == PDFCS_DEVICEGRAY || m_Family == PDFCS_DEVICERGB)) {
      return;
    }
    if (m_pColorSpace->CountComponents() > 3) {
      return;
    }
    float color_values[3];
    color_values[0] = m_CompData[0].m_DecodeMin;
    color_values[1] = color_values[0];
    color_values[2] = color_values[0];

    float R = 0.0f;
    float G = 0.0f;
    float B = 0.0f;
    m_pColorSpace->GetRGB(color_values, &R, &G, &B);

    FX_ARGB argb0 = ArgbEncode(255, FXSYS_roundf(R * 255),
                               FXSYS_roundf(G * 255), FXSYS_roundf(B * 255));
    color_values[0] += m_CompData[0].m_DecodeStep;
    color_values[1] += m_CompData[0].m_DecodeStep;
    color_values[2] += m_CompData[0].m_DecodeStep;
    m_pColorSpace->GetRGB(color_values, &R, &G, &B);
    FX_ARGB argb1 = ArgbEncode(255, FXSYS_roundf(R * 255),
                               FXSYS_roundf(G * 255), FXSYS_roundf(B * 255));
    if (argb0 != 0xFF000000 || argb1 != 0xFFFFFFFF) {
      SetPaletteArgb(0, argb0);
      SetPaletteArgb(1, argb1);
    }
    return;
  }
  if (m_bpc == 8 && m_bDefaultDecode &&
      m_pColorSpace == CPDF_ColorSpace::GetStockCS(PDFCS_DEVICEGRAY)) {
    return;
  }

  int palette_count = 1 << bits;
  // Using at least 16 elements due to the call m_pColorSpace->GetRGB().
  std::vector<float> color_values(std::max(m_nComponents, 16u));
  for (int i = 0; i < palette_count; i++) {
    int color_data = i;
    for (uint32_t j = 0; j < m_nComponents; j++) {
      int encoded_component = color_data % (1 << m_bpc);
      color_data /= 1 << m_bpc;
      color_values[j] = m_CompData[j].m_DecodeMin +
                        m_CompData[j].m_DecodeStep * encoded_component;
    }
    float R = 0;
    float G = 0;
    float B = 0;
    if (m_nComponents == 1 && m_Family == PDFCS_ICCBASED &&
        m_pColorSpace->CountComponents() > 1) {
      int nComponents = m_pColorSpace->CountComponents();
      std::vector<float> temp_buf(nComponents);
      for (int k = 0; k < nComponents; ++k)
        temp_buf[k] = color_values[0];
      m_pColorSpace->GetRGB(temp_buf.data(), &R, &G, &B);
    } else {
      m_pColorSpace->GetRGB(color_values.data(), &R, &G, &B);
    }
    SetPaletteArgb(i, ArgbEncode(255, FXSYS_roundf(R * 255),
                                 FXSYS_roundf(G * 255), FXSYS_roundf(B * 255)));
  }
}

void CPDF_DIBBase::ValidateDictParam() {
  m_bpc = m_bpc_orig;
  const CPDF_Object* pFilter = m_pDict->GetDirectObjectFor("Filter");
  if (pFilter) {
    if (pFilter->IsName()) {
      ByteString filter = pFilter->GetString();
      if (filter == "CCITTFaxDecode" || filter == "JBIG2Decode") {
        m_bpc = 1;
        m_nComponents = 1;
      } else if (filter == "RunLengthDecode") {
        if (m_bpc != 1) {
          m_bpc = 8;
        }
      } else if (filter == "DCTDecode") {
        m_bpc = 8;
      }
    } else if (const CPDF_Array* pArray = pFilter->AsArray()) {
      ByteString filter = pArray->GetStringAt(pArray->size() - 1);
      if (filter == "CCITTFaxDecode" || filter == "JBIG2Decode") {
        m_bpc = 1;
        m_nComponents = 1;
      } else if (filter == "DCTDecode") {
        // Previously, filter == "RunLengthDecode" was checked in the "if"
        // statement as well, but too many documents don't conform to it.
        m_bpc = 8;
      }
    }
  }

  if (!IsAllowedBitsPerComponent(m_bpc))
    m_bpc = 0;
}

void CPDF_DIBBase::TranslateScanline24bpp(uint8_t* dest_scan,
                                          const uint8_t* src_scan) const {
  if (m_bpc == 0)
    return;

  if (TranslateScanline24bppDefaultDecode(dest_scan, src_scan))
    return;

  // Using at least 16 elements due to the call m_pColorSpace->GetRGB().
  std::vector<float> color_values(std::max(m_nComponents, 16u));
  float R = 0.0f;
  float G = 0.0f;
  float B = 0.0f;
  uint64_t src_bit_pos = 0;
  uint64_t src_byte_pos = 0;
  size_t dest_byte_pos = 0;
  const bool bpp8 = m_bpc == 8;
  for (int column = 0; column < m_Width; column++) {
    for (uint32_t color = 0; color < m_nComponents; color++) {
      if (bpp8) {
        uint8_t data = src_scan[src_byte_pos++];
        color_values[color] = m_CompData[color].m_DecodeMin +
                              m_CompData[color].m_DecodeStep * data;
      } else {
        unsigned int data = GetBits8(src_scan, src_bit_pos, m_bpc);
        color_values[color] = m_CompData[color].m_DecodeMin +
                              m_CompData[color].m_DecodeStep * data;
        src_bit_pos += m_bpc;
      }
    }

    if (TransMask()) {
      float k = 1.0f - color_values[3];
      R = (1.0f - color_values[0]) * k;
      G = (1.0f - color_values[1]) * k;
      B = (1.0f - color_values[2]) * k;
    } else if (m_Family != PDFCS_PATTERN) {
      m_pColorSpace->GetRGB(color_values.data(), &R, &G, &B);
    }
    R = pdfium::clamp(R, 0.0f, 1.0f);
    G = pdfium::clamp(G, 0.0f, 1.0f);
    B = pdfium::clamp(B, 0.0f, 1.0f);
    dest_scan[dest_byte_pos] = static_cast<uint8_t>(B * 255);
    dest_scan[dest_byte_pos + 1] = static_cast<uint8_t>(G * 255);
    dest_scan[dest_byte_pos + 2] = static_cast<uint8_t>(R * 255);
    dest_byte_pos += 3;
  }
}

bool CPDF_DIBBase::TranslateScanline24bppDefaultDecode(
    uint8_t* dest_scan,
    const uint8_t* src_scan) const {
  if (!m_bDefaultDecode)
    return false;

  if (m_Family != PDFCS_DEVICERGB && m_Family != PDFCS_CALRGB) {
    if (m_bpc != 8)
      return false;

    if (m_nComponents == m_pColorSpace->CountComponents()) {
      m_pColorSpace->TranslateImageLine(dest_scan, src_scan, m_Width, m_Width,
                                        m_Height, TransMask());
    }
    return true;
  }

  if (m_nComponents != 3)
    return true;

  const uint8_t* src_pos = src_scan;
  switch (m_bpc) {
    case 8:
      for (int column = 0; column < m_Width; column++) {
        *dest_scan++ = src_pos[2];
        *dest_scan++ = src_pos[1];
        *dest_scan++ = *src_pos;
        src_pos += 3;
      }
      break;
    case 16:
      for (int col = 0; col < m_Width; col++) {
        *dest_scan++ = src_pos[4];
        *dest_scan++ = src_pos[2];
        *dest_scan++ = *src_pos;
        src_pos += 6;
      }
      break;
    default:
      const unsigned int max_data = (1 << m_bpc) - 1;
      uint64_t src_bit_pos = 0;
      size_t dest_byte_pos = 0;
      for (int column = 0; column < m_Width; column++) {
        unsigned int R = GetBits8(src_scan, src_bit_pos, m_bpc);
        src_bit_pos += m_bpc;
        unsigned int G = GetBits8(src_scan, src_bit_pos, m_bpc);
        src_bit_pos += m_bpc;
        unsigned int B = GetBits8(src_scan, src_bit_pos, m_bpc);
        src_bit_pos += m_bpc;
        R = std::min(R, max_data);
        G = std::min(G, max_data);
        B = std::min(B, max_data);
        dest_scan[dest_byte_pos] = B * 255 / max_data;
        dest_scan[dest_byte_pos + 1] = G * 255 / max_data;
        dest_scan[dest_byte_pos + 2] = R * 255 / max_data;
        dest_byte_pos += 3;
      }
      break;
  }
  return true;
}

uint8_t* CPDF_DIBBase::GetBuffer() const {
  return m_pCachedBitmap ? m_pCachedBitmap->GetBuffer() : nullptr;
}

const uint8_t* CPDF_DIBBase::GetScanline(int line) const {
  if (m_bpc == 0)
    return nullptr;

  FX_SAFE_UINT32 src_pitch =
      fxcodec::CalculatePitch8(m_bpc, m_nComponents, m_Width);
  if (!src_pitch.IsValid())
    return nullptr;
  uint32_t src_pitch_value = src_pitch.ValueOrDie();

  const uint8_t* pSrcLine = nullptr;
  if (m_pCachedBitmap && src_pitch_value <= m_pCachedBitmap->GetPitch()) {
    if (line >= m_pCachedBitmap->GetHeight()) {
      line = m_pCachedBitmap->GetHeight() - 1;
    }
    pSrcLine = m_pCachedBitmap->GetScanline(line);
  } else if (m_pDecoder) {
    pSrcLine = m_pDecoder->GetScanline(line);
  } else if (m_pStreamAcc->GetSize() >= (line + 1) * src_pitch_value) {
    pSrcLine = m_pStreamAcc->GetData() + line * src_pitch_value;
  }
  if (!pSrcLine) {
    uint8_t* pLineBuf = m_pMaskedLine ? m_pMaskedLine.get() : m_pLineBuf.get();
    memset(pLineBuf, 0xFF, m_Pitch);
    return pLineBuf;
  }

  if (m_bpc * m_nComponents == 1) {
    if (m_bImageMask && m_bDefaultDecode) {
      for (uint32_t i = 0; i < src_pitch_value; i++)
        m_pLineBuf.get()[i] = ~pSrcLine[i];
      return m_pLineBuf.get();
    }

    if (!m_bColorKey) {
      memcpy(m_pLineBuf.get(), pSrcLine, src_pitch_value);
      return m_pLineBuf.get();
    }

    uint32_t reset_argb = m_pPalette ? m_pPalette.get()[0] : 0xFF000000;
    uint32_t set_argb = m_pPalette ? m_pPalette.get()[1] : 0xFFFFFFFF;
    if (m_CompData[0].m_ColorKeyMin == 0)
      reset_argb = 0;
    if (m_CompData[0].m_ColorKeyMax == 1)
      set_argb = 0;
    set_argb = FXARGB_TODIB(set_argb);
    reset_argb = FXARGB_TODIB(reset_argb);
    uint32_t* dest_scan = reinterpret_cast<uint32_t*>(m_pMaskedLine.get());
    for (int col = 0; col < m_Width; col++) {
      *dest_scan = GetBitValue(pSrcLine, col) ? set_argb : reset_argb;
      dest_scan++;
    }
    return m_pMaskedLine.get();
  }
  if (m_bpc * m_nComponents <= 8) {
    if (m_bpc == 8) {
      memcpy(m_pLineBuf.get(), pSrcLine, src_pitch_value);
    } else {
      uint64_t src_bit_pos = 0;
      for (int col = 0; col < m_Width; col++) {
        unsigned int color_index = 0;
        for (uint32_t color = 0; color < m_nComponents; color++) {
          unsigned int data = GetBits8(pSrcLine, src_bit_pos, m_bpc);
          color_index |= data << (color * m_bpc);
          src_bit_pos += m_bpc;
        }
        m_pLineBuf.get()[col] = color_index;
      }
    }
    if (!m_bColorKey)
      return m_pLineBuf.get();

    uint8_t* pDestPixel = m_pMaskedLine.get();
    const uint8_t* pSrcPixel = m_pLineBuf.get();
    for (int col = 0; col < m_Width; col++) {
      uint8_t index = *pSrcPixel++;
      if (m_pPalette) {
        *pDestPixel++ = FXARGB_B(m_pPalette.get()[index]);
        *pDestPixel++ = FXARGB_G(m_pPalette.get()[index]);
        *pDestPixel++ = FXARGB_R(m_pPalette.get()[index]);
      } else {
        *pDestPixel++ = index;
        *pDestPixel++ = index;
        *pDestPixel++ = index;
      }
      *pDestPixel = IsColorIndexOutOfBounds(index, m_CompData[0]) ? 0xFF : 0;
      pDestPixel++;
    }
    return m_pMaskedLine.get();
  }
  if (m_bColorKey) {
    if (m_nComponents == 3 && m_bpc == 8) {
      uint8_t* alpha_channel = m_pMaskedLine.get() + 3;
      for (int col = 0; col < m_Width; col++) {
        const uint8_t* pPixel = pSrcLine + col * 3;
        alpha_channel[col * 4] =
            AreColorIndicesOutOfBounds(pPixel, m_CompData.data(), 3) ? 0xFF : 0;
      }
    } else {
      memset(m_pMaskedLine.get(), 0xFF, m_Pitch);
    }
  }
  if (m_pColorSpace) {
    TranslateScanline24bpp(m_pLineBuf.get(), pSrcLine);
    pSrcLine = m_pLineBuf.get();
  }
  if (!m_bColorKey)
    return pSrcLine;

  const uint8_t* pSrcPixel = pSrcLine;
  uint8_t* pDestPixel = m_pMaskedLine.get();
  for (int col = 0; col < m_Width; col++) {
    *pDestPixel++ = *pSrcPixel++;
    *pDestPixel++ = *pSrcPixel++;
    *pDestPixel++ = *pSrcPixel++;
    pDestPixel++;
  }
  return m_pMaskedLine.get();
}

bool CPDF_DIBBase::SkipToScanline(int line, PauseIndicatorIface* pPause) const {
  return m_pDecoder && m_pDecoder->SkipToScanline(line, pPause);
}

void CPDF_DIBBase::DownSampleScanline(int line,
                                      uint8_t* dest_scan,
                                      int dest_bpp,
                                      int dest_width,
                                      bool bFlipX,
                                      int clip_left,
                                      int clip_width) const {
  if (line < 0 || !dest_scan || dest_bpp <= 0 || dest_width <= 0 ||
      clip_left < 0 || clip_width <= 0) {
    return;
  }

  uint32_t src_width = m_Width;
  FX_SAFE_UINT32 pitch =
      fxcodec::CalculatePitch8(m_bpc, m_nComponents, m_Width);
  if (!pitch.IsValid())
    return;

  const uint8_t* pSrcLine = nullptr;
  if (m_pCachedBitmap) {
    pSrcLine = m_pCachedBitmap->GetScanline(line);
  } else if (m_pDecoder) {
    pSrcLine = m_pDecoder->GetScanline(line);
  } else {
    uint32_t src_pitch = pitch.ValueOrDie();
    pitch *= (line + 1);
    if (!pitch.IsValid()) {
      return;
    }

    if (m_pStreamAcc->GetSize() >= pitch.ValueOrDie()) {
      pSrcLine = m_pStreamAcc->GetData() + line * src_pitch;
    }
  }
  int orig_Bpp = m_bpc * m_nComponents / 8;
  int dest_Bpp = dest_bpp / 8;
  if (!pSrcLine) {
    memset(dest_scan, 0xFF, dest_Bpp * clip_width);
    return;
  }

  FX_SAFE_INT32 max_src_x = clip_left;
  max_src_x += clip_width - 1;
  max_src_x *= src_width;
  max_src_x /= dest_width;
  if (!max_src_x.IsValid())
    return;

  if (m_bpc * m_nComponents == 1) {
    DownSampleScanline1Bit(orig_Bpp, dest_Bpp, src_width, pSrcLine, dest_scan,
                           dest_width, bFlipX, clip_left, clip_width);
  } else if (m_bpc * m_nComponents <= 8) {
    DownSampleScanline8Bit(orig_Bpp, dest_Bpp, src_width, pSrcLine, dest_scan,
                           dest_width, bFlipX, clip_left, clip_width);
  } else {
    DownSampleScanline32Bit(orig_Bpp, dest_Bpp, src_width, pSrcLine, dest_scan,
                            dest_width, bFlipX, clip_left, clip_width);
  }
}

void CPDF_DIBBase::DownSampleScanline1Bit(int orig_Bpp,
                                          int dest_Bpp,
                                          uint32_t src_width,
                                          const uint8_t* pSrcLine,
                                          uint8_t* dest_scan,
                                          int dest_width,
                                          bool bFlipX,
                                          int clip_left,
                                          int clip_width) const {
  if (m_bColorKey && !m_bImageMask) {
    uint32_t reset_argb = m_pPalette ? m_pPalette.get()[0] : 0xFF000000;
    uint32_t set_argb = m_pPalette ? m_pPalette.get()[1] : 0xFFFFFFFF;
    if (m_CompData[0].m_ColorKeyMin == 0)
      reset_argb = 0;
    if (m_CompData[0].m_ColorKeyMax == 1)
      set_argb = 0;
    set_argb = FXARGB_TODIB(set_argb);
    reset_argb = FXARGB_TODIB(reset_argb);
    uint32_t* dest_scan_dword = reinterpret_cast<uint32_t*>(dest_scan);
    for (int i = 0; i < clip_width; i++) {
      uint32_t src_x = (clip_left + i) * src_width / dest_width;
      if (bFlipX)
        src_x = src_width - src_x - 1;
      src_x %= src_width;
      dest_scan_dword[i] = GetBitValue(pSrcLine, src_x) ? set_argb : reset_argb;
    }
    return;
  }

  uint32_t set_argb = 0xFFFFFFFF;
  uint32_t reset_argb = 0;
  if (m_bImageMask) {
    if (m_bDefaultDecode) {
      set_argb = 0;
      reset_argb = 0xFFFFFFFF;
    }
  } else if (m_pPalette && dest_Bpp != 1) {
    reset_argb = m_pPalette.get()[0];
    set_argb = m_pPalette.get()[1];
  }
  for (int i = 0; i < clip_width; i++) {
    uint32_t src_x = (clip_left + i) * src_width / dest_width;
    if (bFlipX)
      src_x = src_width - src_x - 1;
    src_x %= src_width;
    int dest_pos = i * dest_Bpp;
    uint32_t value_argb = GetBitValue(pSrcLine, src_x) ? set_argb : reset_argb;
    if (dest_Bpp == 1) {
      dest_scan[dest_pos] = static_cast<uint8_t>(value_argb);
    } else if (dest_Bpp == 3) {
      dest_scan[dest_pos] = FXARGB_B(value_argb);
      dest_scan[dest_pos + 1] = FXARGB_G(value_argb);
      dest_scan[dest_pos + 2] = FXARGB_R(value_argb);
    } else {
      *reinterpret_cast<uint32_t*>(dest_scan + dest_pos) = value_argb;
    }
  }
}

void CPDF_DIBBase::DownSampleScanline8Bit(int orig_Bpp,
                                          int dest_Bpp,
                                          uint32_t src_width,
                                          const uint8_t* pSrcLine,
                                          uint8_t* dest_scan,
                                          int dest_width,
                                          bool bFlipX,
                                          int clip_left,
                                          int clip_width) const {
  if (m_bpc < 8) {
    uint64_t src_bit_pos = 0;
    for (uint32_t col = 0; col < src_width; col++) {
      unsigned int color_index = 0;
      for (uint32_t color = 0; color < m_nComponents; color++) {
        unsigned int data = GetBits8(pSrcLine, src_bit_pos, m_bpc);
        color_index |= data << (color * m_bpc);
        src_bit_pos += m_bpc;
      }
      m_pLineBuf.get()[col] = color_index;
    }
    pSrcLine = m_pLineBuf.get();
  }
  if (m_bColorKey) {
    for (int i = 0; i < clip_width; i++) {
      uint32_t src_x = (clip_left + i) * src_width / dest_width;
      if (bFlipX) {
        src_x = src_width - src_x - 1;
      }
      src_x %= src_width;
      uint8_t* pDestPixel = dest_scan + i * 4;
      uint8_t index = pSrcLine[src_x];
      if (m_pPalette) {
        *pDestPixel++ = FXARGB_B(m_pPalette.get()[index]);
        *pDestPixel++ = FXARGB_G(m_pPalette.get()[index]);
        *pDestPixel++ = FXARGB_R(m_pPalette.get()[index]);
      } else {
        *pDestPixel++ = index;
        *pDestPixel++ = index;
        *pDestPixel++ = index;
      }
      *pDestPixel = (index < m_CompData[0].m_ColorKeyMin ||
                     index > m_CompData[0].m_ColorKeyMax)
                        ? 0xFF
                        : 0;
    }
    return;
  }
  for (int i = 0; i < clip_width; i++) {
    uint32_t src_x = (clip_left + i) * src_width / dest_width;
    if (bFlipX)
      src_x = src_width - src_x - 1;
    src_x %= src_width;
    uint8_t index = pSrcLine[src_x];
    if (dest_Bpp == 1) {
      dest_scan[i] = index;
    } else {
      int dest_pos = i * dest_Bpp;
      FX_ARGB argb = m_pPalette.get()[index];
      dest_scan[dest_pos] = FXARGB_B(argb);
      dest_scan[dest_pos + 1] = FXARGB_G(argb);
      dest_scan[dest_pos + 2] = FXARGB_R(argb);
    }
  }
}

void CPDF_DIBBase::DownSampleScanline32Bit(int orig_Bpp,
                                           int dest_Bpp,
                                           uint32_t src_width,
                                           const uint8_t* pSrcLine,
                                           uint8_t* dest_scan,
                                           int dest_width,
                                           bool bFlipX,
                                           int clip_left,
                                           int clip_width) const {
  // last_src_x used to store the last seen src_x position which should be
  // in [0, src_width). Set the initial value to be an invalid src_x value.
  uint32_t last_src_x = src_width;
  FX_ARGB last_argb = ArgbEncode(0xFF, 0xFF, 0xFF, 0xFF);
  float unit_To8Bpc = 255.0f / ((1 << m_bpc) - 1);
  for (int i = 0; i < clip_width; i++) {
    int dest_x = clip_left + i;
    uint32_t src_x = (bFlipX ? (dest_width - dest_x - 1) : dest_x) *
                     (int64_t)src_width / dest_width;
    src_x %= src_width;

    uint8_t* pDestPixel = dest_scan + i * dest_Bpp;
    FX_ARGB argb;
    if (src_x == last_src_x) {
      argb = last_argb;
    } else {
      CFX_FixedBufGrow<uint8_t, 16> extracted_components(m_nComponents);
      const uint8_t* pSrcPixel = nullptr;
      if (m_bpc % 8 != 0) {
        // No need to check for 32-bit overflow, as |src_x| is bounded by
        // |src_width| and DownSampleScanline() already checked for overflow
        // with the pitch calculation.
        size_t num_bits = src_x * m_bpc * m_nComponents;
        uint64_t src_bit_pos = num_bits % 8;
        pSrcPixel = pSrcLine + num_bits / 8;
        for (uint32_t j = 0; j < m_nComponents; ++j) {
          extracted_components[j] = static_cast<uint8_t>(
              GetBits8(pSrcPixel, src_bit_pos, m_bpc) * unit_To8Bpc);
          src_bit_pos += m_bpc;
        }
        pSrcPixel = extracted_components;
      } else {
        pSrcPixel = pSrcLine + src_x * orig_Bpp;
        if (m_bpc == 16) {
          for (uint32_t j = 0; j < m_nComponents; ++j)
            extracted_components[j] = pSrcPixel[j * 2];
          pSrcPixel = extracted_components;
        }
      }

      if (m_pColorSpace) {
        uint8_t color[4];
        const bool bTransMask = TransMask();
        if (!m_bDefaultDecode) {
          for (uint32_t j = 0; j < m_nComponents; ++j) {
            float component_value = static_cast<float>(pSrcPixel[j]);
            int color_value = static_cast<int>(
                (m_CompData[j].m_DecodeMin +
                 m_CompData[j].m_DecodeStep * component_value) *
                    255.0f +
                0.5f);
            extracted_components[j] = pdfium::clamp(color_value, 0, 255);
          }
        }
        const uint8_t* pSrc =
            m_bDefaultDecode ? pSrcPixel : extracted_components;
        m_pColorSpace->TranslateImageLine(color, pSrc, 1, 0, 0, bTransMask);
        argb = ArgbEncode(0xFF, color[2], color[1], color[0]);
      } else {
        argb = ArgbEncode(0xFF, pSrcPixel[2], pSrcPixel[1], pSrcPixel[0]);
      }
      if (m_bColorKey) {
        int alpha = 0xFF;
        if (m_nComponents == 3 && m_bpc == 8) {
          alpha = (pSrcPixel[0] < m_CompData[0].m_ColorKeyMin ||
                   pSrcPixel[0] > m_CompData[0].m_ColorKeyMax ||
                   pSrcPixel[1] < m_CompData[1].m_ColorKeyMin ||
                   pSrcPixel[1] > m_CompData[1].m_ColorKeyMax ||
                   pSrcPixel[2] < m_CompData[2].m_ColorKeyMin ||
                   pSrcPixel[2] > m_CompData[2].m_ColorKeyMax)
                      ? 0xFF
                      : 0;
        }
        argb &= 0xFFFFFF;
        argb |= alpha << 24;
      }
      last_src_x = src_x;
      last_argb = argb;
    }
    if (dest_Bpp == 4) {
      *reinterpret_cast<uint32_t*>(pDestPixel) = FXARGB_TODIB(argb);
    } else {
      *pDestPixel++ = FXARGB_B(argb);
      *pDestPixel++ = FXARGB_G(argb);
      *pDestPixel = FXARGB_R(argb);
    }
  }
}

bool CPDF_DIBBase::TransMask() const {
  return m_bLoadMask && m_GroupFamily == PDFCS_DEVICECMYK &&
         m_Family == PDFCS_DEVICECMYK;
}
