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

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

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

#include <stdint.h>

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

#include "core/fpdfapi/page/cpdf_colorspace.h"
#include "core/fpdfapi/page/cpdf_docpagedata.h"
#include "core/fpdfapi/page/cpdf_image.h"
#include "core/fpdfapi/page/cpdf_imageobject.h"
#include "core/fpdfapi/page/cpdf_indexedcs.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_name.h"
#include "core/fpdfapi/parser/cpdf_number.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/icc/icc_transform.h"
#include "core/fxcodec/jbig2/jbig2_decoder.h"
#include "core/fxcodec/jpeg/jpegmodule.h"
#include "core/fxcodec/jpx/cjpx_decoder.h"
#include "core/fxcodec/scanlinedecoder.h"
#include "core/fxcrt/data_vector.h"
#include "core/fxcrt/fx_safe_types.h"
#include "core/fxcrt/span_util.h"
#include "core/fxge/calculate_pitch.h"
#include "core/fxge/dib/cfx_dibitmap.h"
#include "third_party/base/check.h"
#include "third_party/base/check_op.h"

namespace {

bool IsValidDimension(int value) {
  constexpr int kMaxImageDimension = 0x01FFFF;
  return value > 0 && value <= kMaxImageDimension;
}

unsigned int GetBits8(const uint8_t* pData, uint64_t bitpos, size_t nbits) {
  DCHECK(nbits == 1 || nbits == 2 || nbits == 4 || nbits == 8 || nbits == 16);
  DCHECK_EQ((bitpos & (nbits - 1)), 0u);
  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 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;
}

int CalculateBitsPerPixel(uint32_t bpc, uint32_t comps) {
  uint32_t bpp = bpc * comps;
  CHECK(bpp);
  if (bpp == 1)
    return 1;
  if (bpp <= 8)
    return 8;
  return 24;
}

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

enum class JpxDecodeAction {
  kFail,
  kDoNothing,
  kUseGray,
  kUseRgb,
  kUseCmyk,
  kConvertArgbToRgb,
};

// Decides which JpxDecodeAction to use based on the colorspace information from
// the PDF and the JPX image. Called only when the PDF's image object contains a
// "/ColorSpace" entry.
JpxDecodeAction GetJpxDecodeActionFromColorSpaces(
    const CJPX_Decoder::JpxImageInfo& jpx_info,
    const CPDF_ColorSpace* pdf_colorspace) {
  if (pdf_colorspace ==
      CPDF_ColorSpace::GetStockCS(CPDF_ColorSpace::Family::kDeviceGray)) {
    if (jpx_info.colorspace != OPJ_CLRSPC_GRAY &&
        jpx_info.colorspace != OPJ_CLRSPC_UNSPECIFIED) {
      return JpxDecodeAction::kFail;
    }
    return JpxDecodeAction::kUseGray;
  }

  if (pdf_colorspace ==
      CPDF_ColorSpace::GetStockCS(CPDF_ColorSpace::Family::kDeviceRGB)) {
    if (jpx_info.colorspace != OPJ_CLRSPC_SRGB &&
        jpx_info.colorspace != OPJ_CLRSPC_UNSPECIFIED) {
      return JpxDecodeAction::kFail;
    }

    // The channel count of a JPX image can be different from the PDF color
    // space's component count.
    if (jpx_info.channels > 3) {
      return JpxDecodeAction::kConvertArgbToRgb;
    }
    return JpxDecodeAction::kUseRgb;
  }

  if (pdf_colorspace ==
      CPDF_ColorSpace::GetStockCS(CPDF_ColorSpace::Family::kDeviceCMYK)) {
    if (jpx_info.colorspace != OPJ_CLRSPC_CMYK &&
        jpx_info.colorspace != OPJ_CLRSPC_UNSPECIFIED) {
      return JpxDecodeAction::kFail;
    }
    return JpxDecodeAction::kUseCmyk;
  }

  return JpxDecodeAction::kDoNothing;
}

JpxDecodeAction GetJpxDecodeActionFromImageColorSpace(
    const CJPX_Decoder::JpxImageInfo& jpx_info) {
  switch (jpx_info.colorspace) {
    case OPJ_CLRSPC_SYCC:
    case OPJ_CLRSPC_EYCC:
    case OPJ_CLRSPC_UNKNOWN:
    case OPJ_CLRSPC_UNSPECIFIED:
      return JpxDecodeAction::kDoNothing;

    case OPJ_CLRSPC_SRGB:
      if (jpx_info.channels > 3) {
        return JpxDecodeAction::kConvertArgbToRgb;
      }

      return JpxDecodeAction::kUseRgb;

    case OPJ_CLRSPC_GRAY:
      return JpxDecodeAction::kUseGray;

    case OPJ_CLRSPC_CMYK:
      return JpxDecodeAction::kUseCmyk;
  }
}

JpxDecodeAction GetJpxDecodeAction(const CJPX_Decoder::JpxImageInfo& jpx_info,
                                   const CPDF_ColorSpace* pdf_colorspace) {
  if (pdf_colorspace) {
    return GetJpxDecodeActionFromColorSpaces(jpx_info, pdf_colorspace);
  }

  // When PDF does not provide a color space, check the image color space.
  return GetJpxDecodeActionFromImageColorSpace(jpx_info);
}

int GetComponentCountFromOpjColorSpace(OPJ_COLOR_SPACE colorspace) {
  switch (colorspace) {
    case OPJ_CLRSPC_GRAY:
      return 1;

    case OPJ_CLRSPC_SRGB:
    case OPJ_CLRSPC_SYCC:
    case OPJ_CLRSPC_EYCC:
      return 3;

    case OPJ_CLRSPC_CMYK:
      return 4;

    default:
      return 0;
  }
}

}  // namespace

CPDF_DIB::CPDF_DIB(CPDF_Document* pDoc, RetainPtr<const CPDF_Stream> pStream)
    : m_pDocument(pDoc), m_pStream(std::move(pStream)) {}

CPDF_DIB::~CPDF_DIB() = default;

CPDF_DIB::JpxSMaskInlineData::JpxSMaskInlineData() = default;

CPDF_DIB::JpxSMaskInlineData::~JpxSMaskInlineData() = default;

bool CPDF_DIB::Load() {
  if (!LoadInternal(nullptr, nullptr))
    return false;

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

  return ContinueInternal();
}

bool CPDF_DIB::ContinueToLoadMask() {
  if (m_pColorSpace && m_bStdCS)
    m_pColorSpace->EnableStdConversion(true);

  return ContinueInternal();
}

bool CPDF_DIB::ContinueInternal() {
  if (m_bImageMask) {
    SetMaskProperties();
  } else {
    if (!m_bpc || !m_nComponents)
      return false;

    m_Format = MakeRGBFormat(CalculateBitsPerPixel(m_bpc, m_nComponents));
  }

  std::optional<uint32_t> pitch =
      fxge::CalculatePitch32(GetBppFromFormat(m_Format), m_Width);
  if (!pitch.has_value())
    return false;

  m_LineBuf = DataVector<uint8_t>(pitch.value());
  LoadPalette();
  if (m_bColorKey) {
    m_Format = FXDIB_Format::kArgb;
    pitch = fxge::CalculatePitch32(GetBppFromFormat(m_Format), m_Width);
    if (!pitch.has_value())
      return false;
    m_MaskBuf = DataVector<uint8_t>(pitch.value());
  }
  m_Pitch = pitch.value();
  return true;
}

CPDF_DIB::LoadState CPDF_DIB::StartLoadDIBBase(
    bool bHasMask,
    const CPDF_Dictionary* pFormResources,
    const CPDF_Dictionary* pPageResources,
    bool bStdCS,
    CPDF_ColorSpace::Family GroupFamily,
    bool bLoadMask,
    const CFX_Size& max_size_required) {
  m_bStdCS = bStdCS;
  m_bHasMask = bHasMask;
  m_GroupFamily = GroupFamily;
  m_bLoadMask = bLoadMask;

  if (!m_pStream->IsInline())
    pFormResources = nullptr;

  if (!LoadInternal(pFormResources, pPageResources))
    return LoadState::kFail;

  uint8_t resolution_levels_to_skip = 0;
  if (max_size_required.width != 0 && max_size_required.height != 0) {
    resolution_levels_to_skip = static_cast<uint8_t>(
        std::log2(std::max(1, std::min(m_Width / max_size_required.width,
                                       m_Height / max_size_required.height))));
  }

  LoadState iCreatedDecoder = CreateDecoder(resolution_levels_to_skip);
  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;
  }

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

CPDF_DIB::LoadState CPDF_DIB::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;
  if (!m_pJbig2Context) {
    m_pJbig2Context = std::make_unique<Jbig2Context>();
    if (m_pStreamAcc->GetImageParam()) {
      RetainPtr<const CPDF_Stream> pGlobals =
          m_pStreamAcc->GetImageParam()->GetStreamFor("JBIG2Globals");
      if (pGlobals) {
        m_pGlobalAcc = pdfium::MakeRetain<CPDF_StreamAcc>(std::move(pGlobals));
        m_pGlobalAcc->LoadAllDataFiltered();
      }
    }
    uint64_t nSrcKey = 0;
    pdfium::span<const uint8_t> pSrcSpan;
    if (m_pStreamAcc) {
      pSrcSpan = m_pStreamAcc->GetSpan();
      nSrcKey = m_pStreamAcc->KeyForCache();
    }
    uint64_t nGlobalKey = 0;
    pdfium::span<const uint8_t> pGlobalSpan;
    if (m_pGlobalAcc) {
      pGlobalSpan = m_pGlobalAcc->GetSpan();
      nGlobalKey = m_pGlobalAcc->KeyForCache();
    }
    iDecodeStatus = Jbig2Decoder::StartDecode(
        m_pJbig2Context.get(), m_pDocument->GetOrCreateCodecContext(), m_Width,
        m_Height, pSrcSpan, nSrcKey, pGlobalSpan, nGlobalKey,
        m_pCachedBitmap->GetWritableBuffer(), m_pCachedBitmap->GetPitch(),
        pPause);
  } else {
    iDecodeStatus = Jbig2Decoder::ContinueDecode(m_pJbig2Context.get(), pPause);
  }

  if (iDecodeStatus == FXCODEC_STATUS::kError) {
    m_pJbig2Context.reset();
    m_pCachedBitmap.Reset();
    m_pGlobalAcc.Reset();
    return LoadState::kFail;
  }
  if (iDecodeStatus == FXCODEC_STATUS::kDecodeToBeContinued)
    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_DIB::LoadColorInfo(const CPDF_Dictionary* pFormResources,
                             const CPDF_Dictionary* pPageResources) {
  std::optional<DecoderArray> decoder_array = GetDecoderArray(m_pDict);
  if (!decoder_array.has_value())
    return false;

  m_bpc_orig = m_pDict->GetIntegerFor("BitsPerComponent");
  if (!IsMaybeValidBitsPerComponent(m_bpc_orig))
    return false;

  m_bImageMask = m_pDict->GetBooleanFor("ImageMask", /*bDefault=*/false);

  if (m_bImageMask || !m_pDict->KeyExist("ColorSpace")) {
    if (!m_bImageMask && !decoder_array.value().empty()) {
      const ByteString& filter = decoder_array.value().back().first;
      if (filter == "JPXDecode") {
        m_bDoBpcCheck = false;
        return true;
      }
    }
    m_bImageMask = true;
    m_bpc = m_nComponents = 1;
    RetainPtr<const CPDF_Array> pDecode = m_pDict->GetArrayFor("Decode");
    m_bDefaultDecode = !pDecode || !pDecode->GetIntegerAt(0);
    return true;
  }

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

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

  // If the checks above failed to find a colorspace, and the next line to set
  // |m_nComponents| does not get reached, then a decoder can try to set
  // |m_nComponents| based on the number of channels in the image being
  // decoded.
  m_nComponents = m_pColorSpace->CountComponents();
  m_Family = m_pColorSpace->GetFamily();
  if (m_Family == CPDF_ColorSpace::Family::kICCBased && 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;
  }

  ByteString filter;
  if (!decoder_array.value().empty())
    filter = decoder_array.value().back().first;

  if (!ValidateDictParam(filter))
    return false;

  return GetDecodeAndMaskArray();
}

bool CPDF_DIB::GetDecodeAndMaskArray() {
  if (!m_pColorSpace)
    return false;

  m_CompData.resize(m_nComponents);
  int max_data = (1 << m_bpc) - 1;
  RetainPtr<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->GetFloatAt(i * 2);
      float max = pDecode->GetFloatAt(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 == CPDF_ColorSpace::Family::kIndexed)
        def_max = max_data;
      if (def_min != m_CompData[i].m_DecodeMin || def_max != max)
        m_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 == CPDF_ColorSpace::Family::kIndexed)
        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;

  RetainPtr<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);
      }
    }
    m_bColorKey = true;
  }
  return true;
}

CPDF_DIB::LoadState CPDF_DIB::CreateDecoder(uint8_t resolution_levels_to_skip) {
  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(resolution_levels_to_skip);
    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_Format::k1bppMask : FXDIB_Format::k1bppRgb)) {
      m_pCachedBitmap.Reset();
      return LoadState::kFail;
    }
    m_Status = LoadState::kSuccess;
    return LoadState::kContinue;
  }

  pdfium::span<const uint8_t> src_span = m_pStreamAcc->GetSpan();
  RetainPtr<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;

  const std::optional<uint32_t> requested_pitch =
      fxge::CalculatePitch8(m_bpc, m_nComponents, m_Width);
  if (!requested_pitch.has_value())
    return LoadState::kFail;
  const std::optional<uint32_t> provided_pitch = fxge::CalculatePitch8(
      m_pDecoder->GetBPC(), m_pDecoder->CountComps(), m_pDecoder->GetWidth());
  if (!provided_pitch.has_value())
    return LoadState::kFail;
  if (provided_pitch.value() < requested_pitch.value())
    return LoadState::kFail;
  return LoadState::kSuccess;
}

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

  std::optional<JpegModule::ImageInfo> info_opt =
      JpegModule::LoadInfo(src_span);
  if (!info_opt.has_value())
    return false;

  const JpegModule::ImageInfo& info = info_opt.value();
  m_Width = info.width;
  m_Height = info.height;

  if (!CPDF_Image::IsValidJpegComponent(info.num_components) ||
      !CPDF_Image::IsValidJpegBitsPerComponent(info.bits_per_components)) {
    return false;
  }

  if (m_nComponents == static_cast<uint32_t>(info.num_components)) {
    m_bpc = info.bits_per_components;
    m_pDecoder = JpegModule::CreateDecoder(src_span, m_Width, m_Height,
                                           m_nComponents, info.color_transform);
    return true;
  }

  m_nComponents = static_cast<uint32_t>(info.num_components);
  m_CompData.clear();
  if (m_pColorSpace) {
    uint32_t colorspace_comps = m_pColorSpace->CountComponents();
    switch (m_Family) {
      case CPDF_ColorSpace::Family::kDeviceGray:
      case CPDF_ColorSpace::Family::kDeviceRGB:
      case CPDF_ColorSpace::Family::kDeviceCMYK: {
        uint32_t dwMinComps = CPDF_ColorSpace::ComponentsForFamily(m_Family);
        if (colorspace_comps < dwMinComps || m_nComponents < dwMinComps)
          return false;
        break;
      }
      case CPDF_ColorSpace::Family::kLab: {
        if (m_nComponents != 3 || colorspace_comps < 3)
          return false;
        break;
      }
      case CPDF_ColorSpace::Family::kICCBased: {
        if (!fxcodec::IccTransform::IsValidIccComponents(colorspace_comps) ||
            !fxcodec::IccTransform::IsValidIccComponents(m_nComponents) ||
            colorspace_comps < m_nComponents) {
          return false;
        }
        break;
      }
      default: {
        if (colorspace_comps != m_nComponents)
          return false;
        break;
      }
    }
  } else {
    if (m_Family == CPDF_ColorSpace::Family::kLab && m_nComponents != 3)
      return false;
  }
  if (!GetDecodeAndMaskArray())
    return false;

  m_bpc = info.bits_per_components;
  m_pDecoder = JpegModule::CreateDecoder(src_span, m_Width, m_Height,
                                         m_nComponents, info.color_transform);
  return true;
}

RetainPtr<CFX_DIBitmap> CPDF_DIB::LoadJpxBitmap(
    uint8_t resolution_levels_to_skip) {
  std::unique_ptr<CJPX_Decoder> decoder =
      CJPX_Decoder::Create(m_pStreamAcc->GetSpan(),
                           ColorSpaceOptionFromColorSpace(m_pColorSpace.Get()),
                           resolution_levels_to_skip);
  if (!decoder)
    return nullptr;

  m_Height >>= resolution_levels_to_skip;
  m_Width >>= resolution_levels_to_skip;

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

  CJPX_Decoder::JpxImageInfo image_info = decoder->GetInfo();
  if (static_cast<int>(image_info.width) < m_Width ||
      static_cast<int>(image_info.height) < m_Height) {
    return nullptr;
  }

  RetainPtr<CPDF_ColorSpace> original_colorspace = m_pColorSpace;
  bool swap_rgb = false;
  bool convert_argb_to_rgb = false;
  auto action = GetJpxDecodeAction(image_info, m_pColorSpace.Get());
  switch (action) {
    case JpxDecodeAction::kFail:
      return nullptr;

    case JpxDecodeAction::kDoNothing:
      break;

    case JpxDecodeAction::kUseGray:
      m_pColorSpace =
          CPDF_ColorSpace::GetStockCS(CPDF_ColorSpace::Family::kDeviceGray);
      break;

    case JpxDecodeAction::kUseRgb:
      DCHECK(image_info.channels >= 3);
      swap_rgb = true;
      m_pColorSpace = nullptr;
      break;

    case JpxDecodeAction::kUseCmyk:
      m_pColorSpace =
          CPDF_ColorSpace::GetStockCS(CPDF_ColorSpace::Family::kDeviceCMYK);
      break;

    case JpxDecodeAction::kConvertArgbToRgb:
      swap_rgb = true;
      convert_argb_to_rgb = true;
      m_pColorSpace.Reset();
  }

  // If |original_colorspace| exists, then LoadColorInfo() already set
  // |m_nComponents|.
  if (original_colorspace) {
    DCHECK_NE(0u, m_nComponents);
  } else {
    DCHECK_EQ(0u, m_nComponents);
    m_nComponents = GetComponentCountFromOpjColorSpace(image_info.colorspace);
    if (m_nComponents == 0) {
      return nullptr;
    }
  }

  FXDIB_Format format;
  if (action == JpxDecodeAction::kUseGray) {
    format = FXDIB_Format::k8bppRgb;
  } else if (action == JpxDecodeAction::kUseRgb && image_info.channels == 3) {
    format = FXDIB_Format::kRgb;
  } else if (action == JpxDecodeAction::kConvertArgbToRgb &&
             image_info.channels == 4) {
    format = FXDIB_Format::kRgb32;
  } else if (action == JpxDecodeAction::kUseRgb && image_info.channels == 4) {
    format = FXDIB_Format::kRgb32;
  } else {
    image_info.width = (image_info.width * image_info.channels + 2) / 3;
    format = FXDIB_Format::kRgb;
  }

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

  result_bitmap->Clear(0xFFFFFFFF);
  if (!decoder->Decode(result_bitmap->GetWritableBuffer(),
                       result_bitmap->GetPitch(), swap_rgb, m_nComponents)) {
    return nullptr;
  }

  if (convert_argb_to_rgb) {
    DCHECK_EQ(3u, m_nComponents);
    auto rgb_bitmap = pdfium::MakeRetain<CFX_DIBitmap>();
    if (!rgb_bitmap->Create(image_info.width, image_info.height,
                            FXDIB_Format::kRgb)) {
      return nullptr;
    }
    if (m_pDict->GetIntegerFor("SMaskInData") == 1) {
      // TODO(thestig): Acrobat does not support "/SMaskInData 1" combined with
      // filters. Check for that and fail early.
      DCHECK(m_JpxInlineData.data.empty());
      m_JpxInlineData.width = image_info.width;
      m_JpxInlineData.height = image_info.height;
      m_JpxInlineData.data.reserve(image_info.width * image_info.height);
      for (uint32_t row = 0; row < image_info.height; ++row) {
        const uint8_t* src = result_bitmap->GetScanline(row).data();
        uint8_t* dest = rgb_bitmap->GetWritableScanline(row).data();
        for (uint32_t col = 0; col < image_info.width; ++col) {
          uint8_t a = src[3];
          m_JpxInlineData.data.push_back(a);
          uint8_t na = 255 - a;
          uint8_t b = (src[0] * a + 255 * na) / 255;
          uint8_t g = (src[1] * a + 255 * na) / 255;
          uint8_t r = (src[2] * a + 255 * na) / 255;
          dest[0] = b;
          dest[1] = g;
          dest[2] = r;
          src += 4;
          dest += 3;
        }
      }
    } else {
      // TODO(thestig): Is there existing code that does this already?
      for (uint32_t row = 0; row < image_info.height; ++row) {
        const uint8_t* src = result_bitmap->GetScanline(row).data();
        uint8_t* dest = rgb_bitmap->GetWritableScanline(row).data();
        for (uint32_t col = 0; col < image_info.width; ++col) {
          memcpy(dest, src, 3);
          src += 4;
          dest += 3;
        }
      }
    }
    result_bitmap = std::move(rgb_bitmap);
  } else if (m_pColorSpace &&
             m_pColorSpace->GetFamily() == CPDF_ColorSpace::Family::kIndexed &&
             m_bpc < 8) {
    int scale = 8 - m_bpc;
    for (uint32_t row = 0; row < image_info.height; ++row) {
      uint8_t* scanline = result_bitmap->GetWritableScanline(row).data();
      for (uint32_t col = 0; col < image_info.width; ++col) {
        *scanline = (*scanline) >> scale;
        ++scanline;
      }
    }
  }

  // TODO(crbug.com/pdfium/1747): Handle SMaskInData entries for different
  // color space types.

  m_bpc = 8;
  return result_bitmap;
}

bool CPDF_DIB::LoadInternal(const CPDF_Dictionary* pFormResources,
                            const CPDF_Dictionary* pPageResources) {
  if (!m_pStream)
    return false;

  m_pDict = m_pStream->GetDict();
  m_Width = m_pDict->GetIntegerFor("Width");
  m_Height = m_pDict->GetIntegerFor("Height");
  if (!IsValidDimension(m_Width) || !IsValidDimension(m_Height))
    return false;

  if (!LoadColorInfo(pFormResources, pPageResources))
    return false;

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

  const std::optional<uint32_t> maybe_size =
      fxge::CalculatePitch8(m_bpc, m_nComponents, m_Width);
  if (!maybe_size.has_value())
    return false;

  FX_SAFE_UINT32 src_size = maybe_size.value();
  src_size *= m_Height;
  if (!src_size.IsValid())
    return false;

  m_pStreamAcc = pdfium::MakeRetain<CPDF_StreamAcc>(m_pStream);
  m_pStreamAcc->LoadAllDataImageAcc(src_size.ValueOrDie());
  return !m_pStreamAcc->GetSpan().empty();
}

CPDF_DIB::LoadState CPDF_DIB::StartLoadMask() {
  m_MatteColor = 0XFFFFFFFF;

  if (!m_JpxInlineData.data.empty()) {
    auto dict = pdfium::MakeRetain<CPDF_Dictionary>();
    dict->SetNewFor<CPDF_Name>("Type", "XObject");
    dict->SetNewFor<CPDF_Name>("Subtype", "Image");
    dict->SetNewFor<CPDF_Name>("ColorSpace", "DeviceGray");
    dict->SetNewFor<CPDF_Number>("Width", m_JpxInlineData.width);
    dict->SetNewFor<CPDF_Number>("Height", m_JpxInlineData.height);
    dict->SetNewFor<CPDF_Number>("BitsPerComponent", 8);

    return StartLoadMaskDIB(
        pdfium::MakeRetain<CPDF_Stream>(m_JpxInlineData.data, std::move(dict)));
  }

  RetainPtr<const CPDF_Stream> mask(m_pDict->GetStreamFor("SMask"));
  if (!mask) {
    mask = ToStream(m_pDict->GetDirectObjectFor("Mask"));
    return mask ? StartLoadMaskDIB(std::move(mask)) : LoadState::kSuccess;
  }

  RetainPtr<const CPDF_Array> pMatte = mask->GetDict()->GetArrayFor("Matte");
  if (pMatte && m_pColorSpace &&
      m_Family != CPDF_ColorSpace::Family::kPattern &&
      pMatte->size() == m_nComponents &&
      m_pColorSpace->CountComponents() <= m_nComponents) {
    std::vector<float> colors =
        ReadArrayElementsToVector(pMatte.Get(), m_nComponents);

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

CPDF_DIB::LoadState CPDF_DIB::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_DIB> CPDF_DIB::DetachMask() {
  return std::move(m_pMask);
}

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

CPDF_DIB::LoadState CPDF_DIB::StartLoadMaskDIB(
    RetainPtr<const CPDF_Stream> mask_stream) {
  m_pMask = pdfium::MakeRetain<CPDF_DIB>(m_pDocument, std::move(mask_stream));
  LoadState ret = m_pMask->StartLoadDIBBase(false, nullptr, nullptr, true,
                                            CPDF_ColorSpace::Family::kUnknown,
                                            false, {0, 0});
  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_DIB::LoadPalette() {
  if (!m_pColorSpace || m_Family == CPDF_ColorSpace::Family::kPattern)
    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 == CPDF_ColorSpace::Family::kDeviceGray ||
                             m_Family == CPDF_ColorSpace::Family::kDeviceRGB)) {
      return;
    }
    if (m_pColorSpace->CountComponents() > 3) {
      return;
    }
    float color_values[3];
    std::fill(std::begin(color_values), std::end(color_values),
              m_CompData[0].m_DecodeMin);

    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));
    FX_ARGB argb1;
    const CPDF_IndexedCS* indexed_cs = m_pColorSpace->AsIndexedCS();
    if (indexed_cs && indexed_cs->GetMaxIndex() == 0) {
      // If an indexed color space's hival value is 0, only 1 color is specified
      // in the lookup table. Another color should be set to 0xFF000000 by
      // default to set the range of the color space.
      argb1 = 0xFF000000;
    } else {
      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);
      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(CPDF_ColorSpace::Family::kDeviceGray)) {
    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 == CPDF_ColorSpace::Family::kICCBased &&
        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, &R, &G, &B);
    } else {
      m_pColorSpace->GetRGB(color_values, &R, &G, &B);
    }
    SetPaletteArgb(i, ArgbEncode(255, FXSYS_roundf(R * 255),
                                 FXSYS_roundf(G * 255), FXSYS_roundf(B * 255)));
  }
}

bool CPDF_DIB::ValidateDictParam(const ByteString& filter) {
  m_bpc = m_bpc_orig;

  // Per spec, |m_bpc| should always be 8 for RunLengthDecode, but too many
  // documents do not conform to it. So skip this check.

  if (filter == "JPXDecode") {
    m_bDoBpcCheck = false;
    return true;
  }

  if (filter == "CCITTFaxDecode" || filter == "JBIG2Decode") {
    m_bpc = 1;
    m_nComponents = 1;
  } else if (filter == "DCTDecode") {
    m_bpc = 8;
  }

  if (!IsAllowedBitsPerComponent(m_bpc)) {
    m_bpc = 0;
    return false;
  }
  return true;
}

void CPDF_DIB::TranslateScanline24bpp(
    pdfium::span<uint8_t> dest_scan,
    pdfium::span<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.data(), 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 != CPDF_ColorSpace::Family::kPattern) {
      m_pColorSpace->GetRGB(color_values, &R, &G, &B);
    }
    R = std::clamp(R, 0.0f, 1.0f);
    G = std::clamp(G, 0.0f, 1.0f);
    B = std::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_DIB::TranslateScanline24bppDefaultDecode(
    pdfium::span<uint8_t> dest_scan,
    pdfium::span<const uint8_t> src_scan) const {
  if (!m_bDefaultDecode)
    return false;

  if (m_Family != CPDF_ColorSpace::Family::kDeviceRGB &&
      m_Family != CPDF_ColorSpace::Family::kCalRGB) {
    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;

  uint8_t* dest_pos = dest_scan.data();
  const uint8_t* src_pos = src_scan.data();
  switch (m_bpc) {
    case 8:
      for (int column = 0; column < m_Width; column++) {
        *dest_pos++ = src_pos[2];
        *dest_pos++ = src_pos[1];
        *dest_pos++ = *src_pos;
        src_pos += 3;
      }
      break;
    case 16:
      for (int col = 0; col < m_Width; col++) {
        *dest_pos++ = src_pos[4];
        *dest_pos++ = src_pos[2];
        *dest_pos++ = *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.data(), src_bit_pos, m_bpc);
        src_bit_pos += m_bpc;
        unsigned int G = GetBits8(src_scan.data(), src_bit_pos, m_bpc);
        src_bit_pos += m_bpc;
        unsigned int B = GetBits8(src_scan.data(), 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_pos[dest_byte_pos] = B * 255 / max_data;
        dest_pos[dest_byte_pos + 1] = G * 255 / max_data;
        dest_pos[dest_byte_pos + 2] = R * 255 / max_data;
        dest_byte_pos += 3;
      }
      break;
  }
  return true;
}

pdfium::span<const uint8_t> CPDF_DIB::GetScanline(int line) const {
  if (m_bpc == 0)
    return pdfium::span<const uint8_t>();

  const std::optional<uint32_t> src_pitch =
      fxge::CalculatePitch8(m_bpc, m_nComponents, m_Width);
  if (!src_pitch.has_value())
    return pdfium::span<const uint8_t>();

  uint32_t src_pitch_value = src_pitch.value();
  // This is used as the buffer of `pSrcLine` when the stream is truncated,
  // and the remaining bytes count is less than `src_pitch_value`
  DataVector<uint8_t> temp_buffer;
  pdfium::span<const uint8_t> pSrcLine;

  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 * src_pitch_value) {
    pdfium::span<const uint8_t> remaining_bytes =
        m_pStreamAcc->GetSpan().subspan(line * src_pitch_value);
    if (remaining_bytes.size() >= src_pitch_value) {
      pSrcLine = remaining_bytes.first(src_pitch_value);
    } else {
      temp_buffer = DataVector<uint8_t>(src_pitch_value);
      pdfium::span<uint8_t> result = temp_buffer;
      fxcrt::spancpy(result, remaining_bytes);
      pSrcLine = result;
    }
  }

  if (pSrcLine.empty()) {
    pdfium::span<uint8_t> result = !m_MaskBuf.empty() ? m_MaskBuf : m_LineBuf;
    fxcrt::spanset(result, 0);
    return result;
  }
  if (m_bpc * m_nComponents == 1) {
    if (m_bImageMask && m_bDefaultDecode) {
      for (uint32_t i = 0; i < src_pitch_value; i++) {
        // TODO(tsepez): Bounds check if cost is acceptable.
        m_LineBuf[i] = ~pSrcLine.data()[i];
      }
      return pdfium::make_span(m_LineBuf).first(src_pitch_value);
    }
    if (!m_bColorKey) {
      pdfium::span<uint8_t> result = m_LineBuf;
      fxcrt::spancpy(result, pSrcLine.first(src_pitch_value));
      return result.first(src_pitch_value);
    }
    uint32_t reset_argb = Get1BitResetValue();
    uint32_t set_argb = Get1BitSetValue();
    uint32_t* dest_scan = reinterpret_cast<uint32_t*>(m_MaskBuf.data());
    for (int col = 0; col < m_Width; col++, dest_scan++) {
      *dest_scan = GetBitValue(pSrcLine.data(), col) ? set_argb : reset_argb;
    }
    return pdfium::make_span(m_MaskBuf).first(m_Width * sizeof(uint32_t));
  }
  if (m_bpc * m_nComponents <= 8) {
    pdfium::span<uint8_t> result = m_LineBuf;
    if (m_bpc == 8) {
      fxcrt::spancpy(result, pSrcLine.first(src_pitch_value));
      result = result.first(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.data(), src_bit_pos, m_bpc);
          color_index |= data << (color * m_bpc);
          src_bit_pos += m_bpc;
        }
        m_LineBuf[col] = color_index;
      }
      result = result.first(m_Width);
    }
    if (!m_bColorKey)
      return result;

    uint8_t* pDestPixel = m_MaskBuf.data();
    const uint8_t* pSrcPixel = m_LineBuf.data();
    pdfium::span<const uint32_t> palette = GetPaletteSpan();
    if (HasPalette()) {
      for (int col = 0; col < m_Width; col++) {
        uint8_t index = *pSrcPixel++;
        *pDestPixel++ = FXARGB_B(palette[index]);
        *pDestPixel++ = FXARGB_G(palette[index]);
        *pDestPixel++ = FXARGB_R(palette[index]);
        *pDestPixel++ =
            IsColorIndexOutOfBounds(index, m_CompData[0]) ? 0xFF : 0;
      }
    } else {
      for (int col = 0; col < m_Width; col++) {
        uint8_t index = *pSrcPixel++;
        *pDestPixel++ = index;
        *pDestPixel++ = index;
        *pDestPixel++ = index;
        *pDestPixel++ =
            IsColorIndexOutOfBounds(index, m_CompData[0]) ? 0xFF : 0;
      }
    }
    return pdfium::make_span(m_MaskBuf).first(4 * m_Width);
  }
  if (m_bColorKey) {
    if (m_nComponents == 3 && m_bpc == 8) {
      uint8_t* alpha_channel = m_MaskBuf.data() + 3;
      for (int col = 0; col < m_Width; col++) {
        const uint8_t* pPixel = pSrcLine.data() + col * 3;
        alpha_channel[col * 4] =
            AreColorIndicesOutOfBounds(pPixel, m_CompData.data(), 3) ? 0xFF : 0;
      }
    } else {
      fxcrt::spanset(pdfium::make_span(m_MaskBuf), 0xFF);
    }
  }
  if (m_pColorSpace) {
    TranslateScanline24bpp(m_LineBuf, pSrcLine);
    src_pitch_value = 3 * m_Width;
    pSrcLine = pdfium::make_span(m_LineBuf).first(src_pitch_value);
  }
  if (!m_bColorKey)
    return pSrcLine;

  // TODO(tsepez): Bounds check if cost is acceptable.
  const uint8_t* pSrcPixel = pSrcLine.data();
  uint8_t* pDestPixel = m_MaskBuf.data();
  for (int col = 0; col < m_Width; col++) {
    *pDestPixel++ = *pSrcPixel++;
    *pDestPixel++ = *pSrcPixel++;
    *pDestPixel++ = *pSrcPixel++;
    pDestPixel++;
  }
  return pdfium::make_span(m_MaskBuf).first(4 * m_Width);
}

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

size_t CPDF_DIB::GetEstimatedImageMemoryBurden() const {
  return m_pCachedBitmap ? m_pCachedBitmap->GetEstimatedImageMemoryBurden() : 0;
}

bool CPDF_DIB::TransMask() const {
  return m_bLoadMask && m_GroupFamily == CPDF_ColorSpace::Family::kDeviceCMYK &&
         m_Family == CPDF_ColorSpace::Family::kDeviceCMYK;
}

void CPDF_DIB::SetMaskProperties() {
  m_bpc = 1;
  m_nComponents = 1;
  m_Format = FXDIB_Format::k1bppMask;
}

uint32_t CPDF_DIB::Get1BitSetValue() const {
  if (m_CompData[0].m_ColorKeyMax == 1)
    return 0x00000000;
  return HasPalette() ? GetPaletteSpan()[1] : 0xFFFFFFFF;
}

uint32_t CPDF_DIB::Get1BitResetValue() const {
  if (m_CompData[0].m_ColorKeyMin == 0)
    return 0x00000000;
  return HasPalette() ? GetPaletteSpan()[0] : 0xFF000000;
}
