Home | History | Annotate | Download | only in render
      1 // Copyright 2017 PDFium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
      6 
      7 #include "core/fpdfapi/render/cpdf_dibsource.h"
      8 
      9 #include <algorithm>
     10 #include <memory>
     11 #include <utility>
     12 #include <vector>
     13 
     14 #include "core/fpdfapi/cpdf_modulemgr.h"
     15 #include "core/fpdfapi/page/cpdf_docpagedata.h"
     16 #include "core/fpdfapi/page/cpdf_image.h"
     17 #include "core/fpdfapi/page/cpdf_imageobject.h"
     18 #include "core/fpdfapi/parser/cpdf_array.h"
     19 #include "core/fpdfapi/parser/cpdf_dictionary.h"
     20 #include "core/fpdfapi/parser/cpdf_document.h"
     21 #include "core/fpdfapi/parser/fpdf_parser_decode.h"
     22 #include "core/fpdfapi/render/cpdf_pagerendercache.h"
     23 #include "core/fpdfapi/render/cpdf_renderstatus.h"
     24 #include "core/fxcodec/codec/ccodec_basicmodule.h"
     25 #include "core/fxcodec/codec/ccodec_jbig2module.h"
     26 #include "core/fxcodec/codec/ccodec_jpegmodule.h"
     27 #include "core/fxcodec/codec/ccodec_jpxmodule.h"
     28 #include "core/fxcodec/codec/ccodec_scanlinedecoder.h"
     29 #include "core/fxcodec/codec/cjpx_decoder.h"
     30 #include "core/fxcodec/fx_codec.h"
     31 #include "core/fxcrt/cfx_fixedbufgrow.h"
     32 #include "core/fxcrt/fx_safe_types.h"
     33 #include "core/fxge/dib/cfx_dibitmap.h"
     34 #include "third_party/base/ptr_util.h"
     35 
     36 namespace {
     37 
     38 unsigned int GetBits8(const uint8_t* pData, uint64_t bitpos, size_t nbits) {
     39   ASSERT(nbits == 1 || nbits == 2 || nbits == 4 || nbits == 8 || nbits == 16);
     40   ASSERT((bitpos & (nbits - 1)) == 0);
     41   unsigned int byte = pData[bitpos / 8];
     42   if (nbits == 8)
     43     return byte;
     44 
     45   if (nbits == 16)
     46     return byte * 256 + pData[bitpos / 8 + 1];
     47 
     48   return (byte >> (8 - nbits - (bitpos % 8))) & ((1 << nbits) - 1);
     49 }
     50 
     51 FX_SAFE_UINT32 CalculatePitch8(uint32_t bpc, uint32_t components, int width) {
     52   FX_SAFE_UINT32 pitch = bpc;
     53   pitch *= components;
     54   pitch *= width;
     55   pitch += 7;
     56   pitch /= 8;
     57   return pitch;
     58 }
     59 
     60 FX_SAFE_UINT32 CalculatePitch32(int bpp, int width) {
     61   FX_SAFE_UINT32 pitch = bpp;
     62   pitch *= width;
     63   pitch += 31;
     64   pitch /= 32;  // quantized to number of 32-bit words.
     65   pitch *= 4;   // and then back to bytes, (not just /8 in one step).
     66   return pitch;
     67 }
     68 
     69 bool IsAllowedBPCValue(int bpc) {
     70   return bpc == 1 || bpc == 2 || bpc == 4 || bpc == 8 || bpc == 16;
     71 }
     72 
     73 bool IsAllowedICCComponents(int nComp) {
     74   return nComp == 1 || nComp == 3 || nComp == 4;
     75 }
     76 
     77 template <typename T>
     78 T ClampValue(T value, T max_value) {
     79   value = std::min(value, max_value);
     80   value = std::max<T>(0, value);
     81   return value;
     82 }
     83 
     84 // Wrapper class to use with std::unique_ptr for CJPX_Decoder.
     85 class JpxBitMapContext {
     86  public:
     87   explicit JpxBitMapContext(CCodec_JpxModule* jpx_module)
     88       : jpx_module_(jpx_module), decoder_(nullptr) {}
     89 
     90   ~JpxBitMapContext() {}
     91 
     92   void set_decoder(std::unique_ptr<CJPX_Decoder> decoder) {
     93     decoder_ = std::move(decoder);
     94   }
     95 
     96   CJPX_Decoder* decoder() { return decoder_.get(); }
     97 
     98  private:
     99   CCodec_JpxModule* const jpx_module_;  // Weak pointer.
    100   std::unique_ptr<CJPX_Decoder> decoder_;
    101 
    102   // Disallow evil constructors
    103   JpxBitMapContext(const JpxBitMapContext&);
    104   void operator=(const JpxBitMapContext&);
    105 };
    106 
    107 const int kMaxImageDimension = 0x01FFFF;
    108 
    109 }  // namespace
    110 
    111 CPDF_DIBSource::CPDF_DIBSource()
    112     : m_pDocument(nullptr),
    113       m_pStream(nullptr),
    114       m_pDict(nullptr),
    115       m_pColorSpace(nullptr),
    116       m_Family(0),
    117       m_bpc(0),
    118       m_bpc_orig(0),
    119       m_nComponents(0),
    120       m_GroupFamily(0),
    121       m_MatteColor(0),
    122       m_bLoadMask(false),
    123       m_bDefaultDecode(true),
    124       m_bImageMask(false),
    125       m_bDoBpcCheck(true),
    126       m_bColorKey(false),
    127       m_bHasMask(false),
    128       m_bStdCS(false),
    129       m_pCompData(nullptr),
    130       m_pLineBuf(nullptr),
    131       m_pMaskedLine(nullptr),
    132       m_pMask(nullptr),
    133       m_pMaskStream(nullptr),
    134       m_Status(0) {}
    135 
    136 CPDF_DIBSource::~CPDF_DIBSource() {
    137   FX_Free(m_pMaskedLine);
    138   FX_Free(m_pLineBuf);
    139   m_pCachedBitmap.Reset();  // TODO(tsepez): determine if required early here.
    140   FX_Free(m_pCompData);
    141   if (m_pColorSpace && m_pDocument) {
    142     auto* pPageData = m_pDocument->GetPageData();
    143     if (pPageData)
    144       pPageData->ReleaseColorSpace(m_pColorSpace->GetArray());
    145   }
    146 }
    147 
    148 bool CPDF_DIBSource::Load(CPDF_Document* pDoc, const CPDF_Stream* pStream) {
    149   if (!pStream)
    150     return false;
    151 
    152   m_pDocument = pDoc;
    153   m_pDict = pStream->GetDict();
    154   if (!m_pDict)
    155     return false;
    156 
    157   m_pStream = pStream;
    158   m_Width = m_pDict->GetIntegerFor("Width");
    159   m_Height = m_pDict->GetIntegerFor("Height");
    160   if (m_Width <= 0 || m_Height <= 0 || m_Width > kMaxImageDimension ||
    161       m_Height > kMaxImageDimension) {
    162     return false;
    163   }
    164   m_GroupFamily = 0;
    165   m_bLoadMask = false;
    166   if (!LoadColorInfo(nullptr, nullptr))
    167     return false;
    168 
    169   if (m_bDoBpcCheck && (m_bpc == 0 || m_nComponents == 0))
    170     return false;
    171 
    172   FX_SAFE_UINT32 src_size =
    173       CalculatePitch8(m_bpc, m_nComponents, m_Width) * m_Height;
    174   if (!src_size.IsValid())
    175     return false;
    176 
    177   m_pStreamAcc = pdfium::MakeRetain<CPDF_StreamAcc>(pStream);
    178   m_pStreamAcc->LoadAllData(false, src_size.ValueOrDie(), true);
    179   if (m_pStreamAcc->GetSize() == 0 || !m_pStreamAcc->GetData())
    180     return false;
    181 
    182   if (!CreateDecoder())
    183     return false;
    184 
    185   if (m_bImageMask) {
    186     m_bpp = 1;
    187     m_bpc = 1;
    188     m_nComponents = 1;
    189     m_AlphaFlag = 1;
    190   } else if (m_bpc * m_nComponents == 1) {
    191     m_bpp = 1;
    192   } else if (m_bpc * m_nComponents <= 8) {
    193     m_bpp = 8;
    194   } else {
    195     m_bpp = 24;
    196   }
    197   FX_SAFE_UINT32 pitch = CalculatePitch32(m_bpp, m_Width);
    198   if (!pitch.IsValid())
    199     return false;
    200 
    201   m_pLineBuf = FX_Alloc(uint8_t, pitch.ValueOrDie());
    202   LoadPalette();
    203   if (m_bColorKey) {
    204     m_bpp = 32;
    205     m_AlphaFlag = 2;
    206     pitch = CalculatePitch32(m_bpp, m_Width);
    207     if (!pitch.IsValid())
    208       return false;
    209 
    210     m_pMaskedLine = FX_Alloc(uint8_t, pitch.ValueOrDie());
    211   }
    212   m_Pitch = pitch.ValueOrDie();
    213   return true;
    214 }
    215 
    216 bool CPDF_DIBSource::ContinueToLoadMask() {
    217   if (m_bImageMask) {
    218     m_bpp = 1;
    219     m_bpc = 1;
    220     m_nComponents = 1;
    221     m_AlphaFlag = 1;
    222   } else if (m_bpc * m_nComponents == 1) {
    223     m_bpp = 1;
    224   } else if (m_bpc * m_nComponents <= 8) {
    225     m_bpp = 8;
    226   } else {
    227     m_bpp = 24;
    228   }
    229   if (!m_bpc || !m_nComponents) {
    230     return false;
    231   }
    232   FX_SAFE_UINT32 pitch = CalculatePitch32(m_bpp, m_Width);
    233   if (!pitch.IsValid())
    234     return false;
    235 
    236   m_pLineBuf = FX_Alloc(uint8_t, pitch.ValueOrDie());
    237   if (m_pColorSpace && m_bStdCS) {
    238     m_pColorSpace->EnableStdConversion(true);
    239   }
    240   LoadPalette();
    241   if (m_bColorKey) {
    242     m_bpp = 32;
    243     m_AlphaFlag = 2;
    244     pitch = CalculatePitch32(m_bpp, m_Width);
    245     if (!pitch.IsValid())
    246       return false;
    247     m_pMaskedLine = FX_Alloc(uint8_t, pitch.ValueOrDie());
    248   }
    249   m_Pitch = pitch.ValueOrDie();
    250   return true;
    251 }
    252 
    253 int CPDF_DIBSource::StartLoadDIBSource(CPDF_Document* pDoc,
    254                                        const CPDF_Stream* pStream,
    255                                        bool bHasMask,
    256                                        CPDF_Dictionary* pFormResources,
    257                                        CPDF_Dictionary* pPageResources,
    258                                        bool bStdCS,
    259                                        uint32_t GroupFamily,
    260                                        bool bLoadMask) {
    261   if (!pStream)
    262     return 0;
    263 
    264   m_pDocument = pDoc;
    265   m_pDict = pStream->GetDict();
    266   m_pStream = pStream;
    267   m_bStdCS = bStdCS;
    268   m_bHasMask = bHasMask;
    269   m_Width = m_pDict->GetIntegerFor("Width");
    270   m_Height = m_pDict->GetIntegerFor("Height");
    271   if (m_Width <= 0 || m_Height <= 0 || m_Width > kMaxImageDimension ||
    272       m_Height > kMaxImageDimension) {
    273     return 0;
    274   }
    275   m_GroupFamily = GroupFamily;
    276   m_bLoadMask = bLoadMask;
    277   if (!LoadColorInfo(m_pStream->IsInline() ? pFormResources : nullptr,
    278                      pPageResources)) {
    279     return 0;
    280   }
    281   if (m_bDoBpcCheck && (m_bpc == 0 || m_nComponents == 0))
    282     return 0;
    283 
    284   FX_SAFE_UINT32 src_size =
    285       CalculatePitch8(m_bpc, m_nComponents, m_Width) * m_Height;
    286   if (!src_size.IsValid())
    287     return 0;
    288 
    289   m_pStreamAcc = pdfium::MakeRetain<CPDF_StreamAcc>(pStream);
    290   m_pStreamAcc->LoadAllData(false, src_size.ValueOrDie(), true);
    291   if (m_pStreamAcc->GetSize() == 0 || !m_pStreamAcc->GetData())
    292     return 0;
    293 
    294   int iCreatedDecoder = CreateDecoder();
    295   if (!iCreatedDecoder)
    296     return 0;
    297 
    298   if (!ContinueToLoadMask())
    299     return 0;
    300 
    301   int iLoadedMask = m_bHasMask ? StartLoadMask() : 1;
    302   if (iCreatedDecoder == 2 || iLoadedMask == 2)
    303     return 2;
    304 
    305   ASSERT(iCreatedDecoder == 1);
    306   ASSERT(iLoadedMask == 1);
    307   if (m_pColorSpace && m_bStdCS)
    308     m_pColorSpace->EnableStdConversion(false);
    309   return 1;
    310 }
    311 
    312 int CPDF_DIBSource::ContinueLoadDIBSource(IFX_PauseIndicator* pPause) {
    313   if (m_Status == 2)
    314     return ContinueLoadMaskDIB(pPause);
    315 
    316   if (m_Status != 1)
    317     return 0;
    318 
    319   const ByteString& decoder = m_pStreamAcc->GetImageDecoder();
    320   if (decoder == "JPXDecode")
    321     return 0;
    322 
    323   FXCODEC_STATUS iDecodeStatus;
    324   CCodec_Jbig2Module* pJbig2Module = CPDF_ModuleMgr::Get()->GetJbig2Module();
    325   if (!m_pJbig2Context) {
    326     m_pJbig2Context = pdfium::MakeUnique<CCodec_Jbig2Context>();
    327     if (m_pStreamAcc->GetImageParam()) {
    328       CPDF_Stream* pGlobals =
    329           m_pStreamAcc->GetImageParam()->GetStreamFor("JBIG2Globals");
    330       if (pGlobals) {
    331         m_pGlobalStream = pdfium::MakeRetain<CPDF_StreamAcc>(pGlobals);
    332         m_pGlobalStream->LoadAllDataFiltered();
    333       }
    334     }
    335     iDecodeStatus = pJbig2Module->StartDecode(
    336         m_pJbig2Context.get(), m_pDocument->CodecContext(), m_Width, m_Height,
    337         m_pStreamAcc, m_pGlobalStream, m_pCachedBitmap->GetBuffer(),
    338         m_pCachedBitmap->GetPitch(), pPause);
    339   } else {
    340     iDecodeStatus = pJbig2Module->ContinueDecode(m_pJbig2Context.get(), pPause);
    341   }
    342 
    343   if (iDecodeStatus < 0) {
    344     m_pCachedBitmap.Reset();
    345     m_pGlobalStream.Reset();
    346     m_pJbig2Context.reset();
    347     return 0;
    348   }
    349   if (iDecodeStatus == FXCODEC_STATUS_DECODE_TOBECONTINUE)
    350     return 2;
    351 
    352   int iContinueStatus = 1;
    353   if (m_bHasMask) {
    354     iContinueStatus = ContinueLoadMaskDIB(pPause);
    355     m_Status = 2;
    356   }
    357   if (iContinueStatus == 2)
    358     return 2;
    359 
    360   if (m_pColorSpace && m_bStdCS)
    361     m_pColorSpace->EnableStdConversion(false);
    362   return iContinueStatus;
    363 }
    364 
    365 bool CPDF_DIBSource::LoadColorInfo(const CPDF_Dictionary* pFormResources,
    366                                    const CPDF_Dictionary* pPageResources) {
    367   m_bpc_orig = m_pDict->GetIntegerFor("BitsPerComponent");
    368   if (m_pDict->GetIntegerFor("ImageMask"))
    369     m_bImageMask = true;
    370 
    371   if (m_bImageMask || !m_pDict->KeyExist("ColorSpace")) {
    372     if (!m_bImageMask) {
    373       CPDF_Object* pFilter = m_pDict->GetDirectObjectFor("Filter");
    374       if (pFilter) {
    375         ByteString filter;
    376         if (pFilter->IsName()) {
    377           filter = pFilter->GetString();
    378         } else if (CPDF_Array* pArray = pFilter->AsArray()) {
    379           filter = pArray->GetStringAt(pArray->GetCount() - 1);
    380         }
    381 
    382         if (filter == "JPXDecode") {
    383           m_bDoBpcCheck = false;
    384           return true;
    385         }
    386       }
    387     }
    388     m_bImageMask = true;
    389     m_bpc = m_nComponents = 1;
    390     CPDF_Array* pDecode = m_pDict->GetArrayFor("Decode");
    391     m_bDefaultDecode = !pDecode || !pDecode->GetIntegerAt(0);
    392     return true;
    393   }
    394 
    395   CPDF_Object* pCSObj = m_pDict->GetDirectObjectFor("ColorSpace");
    396   if (!pCSObj)
    397     return false;
    398 
    399   CPDF_DocPageData* pDocPageData = m_pDocument->GetPageData();
    400   if (pFormResources)
    401     m_pColorSpace = pDocPageData->GetColorSpace(pCSObj, pFormResources);
    402   if (!m_pColorSpace)
    403     m_pColorSpace = pDocPageData->GetColorSpace(pCSObj, pPageResources);
    404   if (!m_pColorSpace)
    405     return false;
    406 
    407   m_Family = m_pColorSpace->GetFamily();
    408   m_nComponents = m_pColorSpace->CountComponents();
    409   if (m_Family == PDFCS_ICCBASED && pCSObj->IsName()) {
    410     ByteString cs = pCSObj->GetString();
    411     if (cs == "DeviceGray")
    412       m_nComponents = 1;
    413     else if (cs == "DeviceRGB")
    414       m_nComponents = 3;
    415     else if (cs == "DeviceCMYK")
    416       m_nComponents = 4;
    417   }
    418   ValidateDictParam();
    419   m_pCompData = GetDecodeAndMaskArray(&m_bDefaultDecode, &m_bColorKey);
    420   return !!m_pCompData;
    421 }
    422 
    423 DIB_COMP_DATA* CPDF_DIBSource::GetDecodeAndMaskArray(bool* bDefaultDecode,
    424                                                      bool* bColorKey) {
    425   if (!m_pColorSpace)
    426     return nullptr;
    427 
    428   DIB_COMP_DATA* const pCompData = FX_Alloc(DIB_COMP_DATA, m_nComponents);
    429   int max_data = (1 << m_bpc) - 1;
    430   CPDF_Array* pDecode = m_pDict->GetArrayFor("Decode");
    431   if (pDecode) {
    432     for (uint32_t i = 0; i < m_nComponents; i++) {
    433       pCompData[i].m_DecodeMin = pDecode->GetNumberAt(i * 2);
    434       float max = pDecode->GetNumberAt(i * 2 + 1);
    435       pCompData[i].m_DecodeStep = (max - pCompData[i].m_DecodeMin) / max_data;
    436       float def_value;
    437       float def_min;
    438       float def_max;
    439       m_pColorSpace->GetDefaultValue(i, &def_value, &def_min, &def_max);
    440       if (m_Family == PDFCS_INDEXED)
    441         def_max = max_data;
    442       if (def_min != pCompData[i].m_DecodeMin || def_max != max)
    443         *bDefaultDecode = false;
    444     }
    445   } else {
    446     for (uint32_t i = 0; i < m_nComponents; i++) {
    447       float def_value;
    448       m_pColorSpace->GetDefaultValue(i, &def_value, &pCompData[i].m_DecodeMin,
    449                                      &pCompData[i].m_DecodeStep);
    450       if (m_Family == PDFCS_INDEXED)
    451         pCompData[i].m_DecodeStep = max_data;
    452       pCompData[i].m_DecodeStep =
    453           (pCompData[i].m_DecodeStep - pCompData[i].m_DecodeMin) / max_data;
    454     }
    455   }
    456   if (m_pDict->KeyExist("SMask"))
    457     return pCompData;
    458 
    459   CPDF_Object* pMask = m_pDict->GetDirectObjectFor("Mask");
    460   if (!pMask)
    461     return pCompData;
    462 
    463   if (CPDF_Array* pArray = pMask->AsArray()) {
    464     if (pArray->GetCount() >= m_nComponents * 2) {
    465       for (uint32_t i = 0; i < m_nComponents; i++) {
    466         int min_num = pArray->GetIntegerAt(i * 2);
    467         int max_num = pArray->GetIntegerAt(i * 2 + 1);
    468         pCompData[i].m_ColorKeyMin = std::max(min_num, 0);
    469         pCompData[i].m_ColorKeyMax = std::min(max_num, max_data);
    470       }
    471     }
    472     *bColorKey = true;
    473   }
    474   return pCompData;
    475 }
    476 
    477 int CPDF_DIBSource::CreateDecoder() {
    478   const ByteString& decoder = m_pStreamAcc->GetImageDecoder();
    479   if (decoder.IsEmpty())
    480     return 1;
    481 
    482   if (m_bDoBpcCheck && m_bpc == 0)
    483     return 0;
    484 
    485   if (decoder == "JPXDecode") {
    486     LoadJpxBitmap();
    487     return m_pCachedBitmap ? 1 : 0;
    488   }
    489   if (decoder == "JBIG2Decode") {
    490     m_pCachedBitmap = pdfium::MakeRetain<CFX_DIBitmap>();
    491     if (!m_pCachedBitmap->Create(
    492             m_Width, m_Height, m_bImageMask ? FXDIB_1bppMask : FXDIB_1bppRgb)) {
    493       m_pCachedBitmap.Reset();
    494       return 0;
    495     }
    496     m_Status = 1;
    497     return 2;
    498   }
    499 
    500   const uint8_t* src_data = m_pStreamAcc->GetData();
    501   uint32_t src_size = m_pStreamAcc->GetSize();
    502   const CPDF_Dictionary* pParams = m_pStreamAcc->GetImageParam();
    503   if (decoder == "CCITTFaxDecode") {
    504     m_pDecoder = FPDFAPI_CreateFaxDecoder(src_data, src_size, m_Width, m_Height,
    505                                           pParams);
    506   } else if (decoder == "FlateDecode") {
    507     m_pDecoder = FPDFAPI_CreateFlateDecoder(
    508         src_data, src_size, m_Width, m_Height, m_nComponents, m_bpc, pParams);
    509   } else if (decoder == "RunLengthDecode") {
    510     CCodec_ModuleMgr* pEncoders = CPDF_ModuleMgr::Get()->GetCodecModule();
    511     m_pDecoder = pEncoders->GetBasicModule()->CreateRunLengthDecoder(
    512         src_data, src_size, m_Width, m_Height, m_nComponents, m_bpc);
    513   } else if (decoder == "DCTDecode") {
    514     if (!CreateDCTDecoder(src_data, src_size, pParams))
    515       return 0;
    516   }
    517   if (!m_pDecoder)
    518     return 0;
    519 
    520   FX_SAFE_UINT32 requested_pitch =
    521       CalculatePitch8(m_bpc, m_nComponents, m_Width);
    522   if (!requested_pitch.IsValid())
    523     return 0;
    524   FX_SAFE_UINT32 provided_pitch = CalculatePitch8(
    525       m_pDecoder->GetBPC(), m_pDecoder->CountComps(), m_pDecoder->GetWidth());
    526   if (!provided_pitch.IsValid())
    527     return 0;
    528   if (provided_pitch.ValueOrDie() < requested_pitch.ValueOrDie())
    529     return 0;
    530   return 1;
    531 }
    532 
    533 bool CPDF_DIBSource::CreateDCTDecoder(const uint8_t* src_data,
    534                                       uint32_t src_size,
    535                                       const CPDF_Dictionary* pParams) {
    536   CCodec_JpegModule* pJpegModule = CPDF_ModuleMgr::Get()->GetJpegModule();
    537   m_pDecoder = pJpegModule->CreateDecoder(
    538       src_data, src_size, m_Width, m_Height, m_nComponents,
    539       !pParams || pParams->GetIntegerFor("ColorTransform", 1));
    540   if (m_pDecoder)
    541     return true;
    542 
    543   bool bTransform = false;
    544   int comps;
    545   int bpc;
    546   if (!pJpegModule->LoadInfo(src_data, src_size, &m_Width, &m_Height, &comps,
    547                              &bpc, &bTransform)) {
    548     return false;
    549   }
    550 
    551   if (m_nComponents == static_cast<uint32_t>(comps)) {
    552     m_bpc = bpc;
    553     m_pDecoder = pJpegModule->CreateDecoder(
    554         src_data, src_size, m_Width, m_Height, m_nComponents, bTransform);
    555     return true;
    556   }
    557 
    558   m_nComponents = static_cast<uint32_t>(comps);
    559   FX_Free(m_pCompData);
    560   m_pCompData = nullptr;
    561   if (m_pColorSpace) {
    562     switch (m_Family) {
    563       case PDFCS_DEVICEGRAY:
    564       case PDFCS_DEVICERGB:
    565       case PDFCS_DEVICECMYK: {
    566         uint32_t dwMinComps = ComponentsForFamily(m_Family);
    567         if (m_pColorSpace->CountComponents() < dwMinComps ||
    568             m_nComponents < dwMinComps) {
    569           return false;
    570         }
    571         break;
    572       }
    573       case PDFCS_LAB: {
    574         if (m_nComponents != 3 || m_pColorSpace->CountComponents() < 3)
    575           return false;
    576         break;
    577       }
    578       case PDFCS_ICCBASED: {
    579         if (!IsAllowedICCComponents(m_nComponents) ||
    580             !IsAllowedICCComponents(m_pColorSpace->CountComponents()) ||
    581             m_pColorSpace->CountComponents() < m_nComponents) {
    582           return false;
    583         }
    584         break;
    585       }
    586       default: {
    587         if (m_pColorSpace->CountComponents() != m_nComponents)
    588           return false;
    589         break;
    590       }
    591     }
    592   } else {
    593     if (m_Family == PDFCS_LAB && m_nComponents != 3)
    594       return false;
    595   }
    596   m_pCompData = GetDecodeAndMaskArray(&m_bDefaultDecode, &m_bColorKey);
    597   if (!m_pCompData)
    598     return false;
    599 
    600   m_bpc = bpc;
    601   m_pDecoder = pJpegModule->CreateDecoder(src_data, src_size, m_Width, m_Height,
    602                                           m_nComponents, bTransform);
    603   return true;
    604 }
    605 
    606 void CPDF_DIBSource::LoadJpxBitmap() {
    607   CCodec_JpxModule* pJpxModule = CPDF_ModuleMgr::Get()->GetJpxModule();
    608   auto context = pdfium::MakeUnique<JpxBitMapContext>(pJpxModule);
    609   context->set_decoder(pJpxModule->CreateDecoder(
    610       m_pStreamAcc->GetData(), m_pStreamAcc->GetSize(), m_pColorSpace));
    611   if (!context->decoder())
    612     return;
    613 
    614   uint32_t width = 0;
    615   uint32_t height = 0;
    616   uint32_t components = 0;
    617   pJpxModule->GetImageInfo(context->decoder(), &width, &height, &components);
    618   if (static_cast<int>(width) < m_Width || static_cast<int>(height) < m_Height)
    619     return;
    620 
    621   bool bSwapRGB = false;
    622   if (m_pColorSpace) {
    623     if (components != m_pColorSpace->CountComponents())
    624       return;
    625 
    626     if (m_pColorSpace == CPDF_ColorSpace::GetStockCS(PDFCS_DEVICERGB)) {
    627       bSwapRGB = true;
    628       m_pColorSpace = nullptr;
    629     }
    630   } else {
    631     if (components == 3) {
    632       bSwapRGB = true;
    633     } else if (components == 4) {
    634       m_pColorSpace = CPDF_ColorSpace::GetStockCS(PDFCS_DEVICECMYK);
    635     }
    636     m_nComponents = components;
    637   }
    638 
    639   FXDIB_Format format;
    640   if (components == 1) {
    641     format = FXDIB_8bppRgb;
    642   } else if (components <= 3) {
    643     format = FXDIB_Rgb;
    644   } else if (components == 4) {
    645     format = FXDIB_Rgb32;
    646   } else {
    647     width = (width * components + 2) / 3;
    648     format = FXDIB_Rgb;
    649   }
    650 
    651   m_pCachedBitmap = pdfium::MakeRetain<CFX_DIBitmap>();
    652   if (!m_pCachedBitmap->Create(width, height, format)) {
    653     m_pCachedBitmap.Reset();
    654     return;
    655   }
    656   m_pCachedBitmap->Clear(0xFFFFFFFF);
    657   std::vector<uint8_t> output_offsets(components);
    658   for (uint32_t i = 0; i < components; ++i)
    659     output_offsets[i] = i;
    660   if (bSwapRGB) {
    661     output_offsets[0] = 2;
    662     output_offsets[2] = 0;
    663   }
    664   if (!pJpxModule->Decode(context->decoder(), m_pCachedBitmap->GetBuffer(),
    665                           m_pCachedBitmap->GetPitch(), output_offsets)) {
    666     m_pCachedBitmap.Reset();
    667     return;
    668   }
    669   if (m_pColorSpace && m_pColorSpace->GetFamily() == PDFCS_INDEXED &&
    670       m_bpc < 8) {
    671     int scale = 8 - m_bpc;
    672     for (uint32_t row = 0; row < height; ++row) {
    673       uint8_t* scanline =
    674           const_cast<uint8_t*>(m_pCachedBitmap->GetScanline(row));
    675       for (uint32_t col = 0; col < width; ++col) {
    676         *scanline = (*scanline) >> scale;
    677         ++scanline;
    678       }
    679     }
    680   }
    681   m_bpc = 8;
    682 }
    683 
    684 int CPDF_DIBSource::StartLoadMask() {
    685   m_MatteColor = 0XFFFFFFFF;
    686   m_pMaskStream = m_pDict->GetStreamFor("SMask");
    687   if (m_pMaskStream) {
    688     CPDF_Array* pMatte = m_pMaskStream->GetDict()->GetArrayFor("Matte");
    689     if (pMatte && m_pColorSpace &&
    690         m_pColorSpace->CountComponents() <= m_nComponents) {
    691       float R, G, B;
    692       std::vector<float> colors(m_nComponents);
    693       for (uint32_t i = 0; i < m_nComponents; i++)
    694         colors[i] = pMatte->GetFloatAt(i);
    695 
    696       m_pColorSpace->GetRGB(colors.data(), &R, &G, &B);
    697       m_MatteColor = FXARGB_MAKE(0, FXSYS_round(R * 255), FXSYS_round(G * 255),
    698                                  FXSYS_round(B * 255));
    699     }
    700     return StartLoadMaskDIB();
    701   }
    702 
    703   m_pMaskStream = ToStream(m_pDict->GetDirectObjectFor("Mask"));
    704   return m_pMaskStream ? StartLoadMaskDIB() : 1;
    705 }
    706 
    707 int CPDF_DIBSource::ContinueLoadMaskDIB(IFX_PauseIndicator* pPause) {
    708   if (!m_pMask)
    709     return 1;
    710 
    711   int ret = m_pMask->ContinueLoadDIBSource(pPause);
    712   if (ret == 2)
    713     return 2;
    714 
    715   if (m_pColorSpace && m_bStdCS)
    716     m_pColorSpace->EnableStdConversion(false);
    717 
    718   if (!ret) {
    719     m_pMask.Reset();
    720     return 0;
    721   }
    722   return 1;
    723 }
    724 
    725 RetainPtr<CPDF_DIBSource> CPDF_DIBSource::DetachMask() {
    726   return std::move(m_pMask);
    727 }
    728 
    729 int CPDF_DIBSource::StartLoadMaskDIB() {
    730   m_pMask = pdfium::MakeRetain<CPDF_DIBSource>();
    731   int ret = m_pMask->StartLoadDIBSource(m_pDocument.Get(), m_pMaskStream.Get(),
    732                                         false, nullptr, nullptr, true);
    733   if (ret == 2) {
    734     if (m_Status == 0)
    735       m_Status = 2;
    736     return 2;
    737   }
    738   if (!ret) {
    739     m_pMask.Reset();
    740     return 1;
    741   }
    742   return 1;
    743 }
    744 
    745 void CPDF_DIBSource::LoadPalette() {
    746   if (m_bpc == 0) {
    747     return;
    748   }
    749   if (m_bpc * m_nComponents > 8) {
    750     return;
    751   }
    752   if (!m_pColorSpace) {
    753     return;
    754   }
    755   if (m_bpc * m_nComponents == 1) {
    756     if (m_bDefaultDecode &&
    757         (m_Family == PDFCS_DEVICEGRAY || m_Family == PDFCS_DEVICERGB)) {
    758       return;
    759     }
    760     if (m_pColorSpace->CountComponents() > 3) {
    761       return;
    762     }
    763     float color_values[3];
    764     color_values[0] = m_pCompData[0].m_DecodeMin;
    765     color_values[1] = color_values[2] = color_values[0];
    766     float R = 0.0f, G = 0.0f, B = 0.0f;
    767     m_pColorSpace->GetRGB(color_values, &R, &G, &B);
    768     FX_ARGB argb0 = ArgbEncode(255, FXSYS_round(R * 255), FXSYS_round(G * 255),
    769                                FXSYS_round(B * 255));
    770     color_values[0] += m_pCompData[0].m_DecodeStep;
    771     color_values[1] += m_pCompData[0].m_DecodeStep;
    772     color_values[2] += m_pCompData[0].m_DecodeStep;
    773     m_pColorSpace->GetRGB(color_values, &R, &G, &B);
    774     FX_ARGB argb1 = ArgbEncode(255, FXSYS_round(R * 255), FXSYS_round(G * 255),
    775                                FXSYS_round(B * 255));
    776     if (argb0 != 0xFF000000 || argb1 != 0xFFFFFFFF) {
    777       SetPaletteArgb(0, argb0);
    778       SetPaletteArgb(1, argb1);
    779     }
    780     return;
    781   }
    782   if (m_pColorSpace == CPDF_ColorSpace::GetStockCS(PDFCS_DEVICEGRAY) &&
    783       m_bpc == 8 && m_bDefaultDecode) {
    784   } else {
    785     int palette_count = 1 << (m_bpc * m_nComponents);
    786     CFX_FixedBufGrow<float, 16> color_values(m_nComponents);
    787     float* color_value = color_values;
    788     for (int i = 0; i < palette_count; i++) {
    789       int color_data = i;
    790       for (uint32_t j = 0; j < m_nComponents; j++) {
    791         int encoded_component = color_data % (1 << m_bpc);
    792         color_data /= 1 << m_bpc;
    793         color_value[j] = m_pCompData[j].m_DecodeMin +
    794                          m_pCompData[j].m_DecodeStep * encoded_component;
    795       }
    796       float R = 0, G = 0, B = 0;
    797       if (m_nComponents == 1 && m_Family == PDFCS_ICCBASED &&
    798           m_pColorSpace->CountComponents() > 1) {
    799         int nComponents = m_pColorSpace->CountComponents();
    800         std::vector<float> temp_buf(nComponents);
    801         for (int k = 0; k < nComponents; k++) {
    802           temp_buf[k] = *color_value;
    803         }
    804         m_pColorSpace->GetRGB(temp_buf.data(), &R, &G, &B);
    805       } else {
    806         m_pColorSpace->GetRGB(color_value, &R, &G, &B);
    807       }
    808       SetPaletteArgb(i, ArgbEncode(255, FXSYS_round(R * 255),
    809                                    FXSYS_round(G * 255), FXSYS_round(B * 255)));
    810     }
    811   }
    812 }
    813 
    814 void CPDF_DIBSource::ValidateDictParam() {
    815   m_bpc = m_bpc_orig;
    816   CPDF_Object* pFilter = m_pDict->GetDirectObjectFor("Filter");
    817   if (pFilter) {
    818     if (pFilter->IsName()) {
    819       ByteString filter = pFilter->GetString();
    820       if (filter == "CCITTFaxDecode" || filter == "JBIG2Decode") {
    821         m_bpc = 1;
    822         m_nComponents = 1;
    823       } else if (filter == "RunLengthDecode") {
    824         if (m_bpc != 1) {
    825           m_bpc = 8;
    826         }
    827       } else if (filter == "DCTDecode") {
    828         m_bpc = 8;
    829       }
    830     } else if (CPDF_Array* pArray = pFilter->AsArray()) {
    831       ByteString filter = pArray->GetStringAt(pArray->GetCount() - 1);
    832       if (filter == "CCITTFaxDecode" || filter == "JBIG2Decode") {
    833         m_bpc = 1;
    834         m_nComponents = 1;
    835       } else if (filter == "DCTDecode") {
    836         // Previously, filter == "RunLengthDecode" was checked in the "if"
    837         // statement as well, but too many documents don't conform to it.
    838         m_bpc = 8;
    839       }
    840     }
    841   }
    842 
    843   if (!IsAllowedBPCValue(m_bpc))
    844     m_bpc = 0;
    845 }
    846 
    847 void CPDF_DIBSource::TranslateScanline24bpp(uint8_t* dest_scan,
    848                                             const uint8_t* src_scan) const {
    849   if (m_bpc == 0)
    850     return;
    851 
    852   unsigned int max_data = (1 << m_bpc) - 1;
    853   if (m_bDefaultDecode) {
    854     if (m_Family == PDFCS_DEVICERGB || m_Family == PDFCS_CALRGB) {
    855       if (m_nComponents != 3)
    856         return;
    857 
    858       const uint8_t* src_pos = src_scan;
    859       switch (m_bpc) {
    860         case 8:
    861           for (int column = 0; column < m_Width; column++) {
    862             *dest_scan++ = src_pos[2];
    863             *dest_scan++ = src_pos[1];
    864             *dest_scan++ = *src_pos;
    865             src_pos += 3;
    866           }
    867           break;
    868         case 16:
    869           for (int col = 0; col < m_Width; col++) {
    870             *dest_scan++ = src_pos[4];
    871             *dest_scan++ = src_pos[2];
    872             *dest_scan++ = *src_pos;
    873             src_pos += 6;
    874           }
    875           break;
    876         default:
    877           uint64_t src_bit_pos = 0;
    878           size_t dest_byte_pos = 0;
    879           for (int column = 0; column < m_Width; column++) {
    880             unsigned int R = GetBits8(src_scan, src_bit_pos, m_bpc);
    881             src_bit_pos += m_bpc;
    882             unsigned int G = GetBits8(src_scan, src_bit_pos, m_bpc);
    883             src_bit_pos += m_bpc;
    884             unsigned int B = GetBits8(src_scan, src_bit_pos, m_bpc);
    885             src_bit_pos += m_bpc;
    886             R = std::min(R, max_data);
    887             G = std::min(G, max_data);
    888             B = std::min(B, max_data);
    889             dest_scan[dest_byte_pos] = B * 255 / max_data;
    890             dest_scan[dest_byte_pos + 1] = G * 255 / max_data;
    891             dest_scan[dest_byte_pos + 2] = R * 255 / max_data;
    892             dest_byte_pos += 3;
    893           }
    894           break;
    895       }
    896       return;
    897     }
    898     if (m_bpc == 8) {
    899       if (m_nComponents == m_pColorSpace->CountComponents())
    900         m_pColorSpace->TranslateImageLine(dest_scan, src_scan, m_Width, m_Width,
    901                                           m_Height, TransMask());
    902       return;
    903     }
    904   }
    905 
    906   CFX_FixedBufGrow<float, 16> color_values1(m_nComponents);
    907   float* color_values = color_values1;
    908   float R = 0.0f;
    909   float G = 0.0f;
    910   float B = 0.0f;
    911   if (m_bpc == 8) {
    912     uint64_t src_byte_pos = 0;
    913     size_t dest_byte_pos = 0;
    914     for (int column = 0; column < m_Width; column++) {
    915       for (uint32_t color = 0; color < m_nComponents; color++) {
    916         uint8_t data = src_scan[src_byte_pos++];
    917         color_values[color] = m_pCompData[color].m_DecodeMin +
    918                               m_pCompData[color].m_DecodeStep * data;
    919       }
    920       if (TransMask()) {
    921         float k = 1.0f - color_values[3];
    922         R = (1.0f - color_values[0]) * k;
    923         G = (1.0f - color_values[1]) * k;
    924         B = (1.0f - color_values[2]) * k;
    925       } else {
    926         m_pColorSpace->GetRGB(color_values, &R, &G, &B);
    927       }
    928       R = ClampValue(R, 1.0f);
    929       G = ClampValue(G, 1.0f);
    930       B = ClampValue(B, 1.0f);
    931       dest_scan[dest_byte_pos] = static_cast<uint8_t>(B * 255);
    932       dest_scan[dest_byte_pos + 1] = static_cast<uint8_t>(G * 255);
    933       dest_scan[dest_byte_pos + 2] = static_cast<uint8_t>(R * 255);
    934       dest_byte_pos += 3;
    935     }
    936   } else {
    937     uint64_t src_bit_pos = 0;
    938     size_t dest_byte_pos = 0;
    939     for (int column = 0; column < m_Width; column++) {
    940       for (uint32_t color = 0; color < m_nComponents; color++) {
    941         unsigned int data = GetBits8(src_scan, src_bit_pos, m_bpc);
    942         color_values[color] = m_pCompData[color].m_DecodeMin +
    943                               m_pCompData[color].m_DecodeStep * data;
    944         src_bit_pos += m_bpc;
    945       }
    946       if (TransMask()) {
    947         float k = 1.0f - color_values[3];
    948         R = (1.0f - color_values[0]) * k;
    949         G = (1.0f - color_values[1]) * k;
    950         B = (1.0f - color_values[2]) * k;
    951       } else {
    952         m_pColorSpace->GetRGB(color_values, &R, &G, &B);
    953       }
    954       R = ClampValue(R, 1.0f);
    955       G = ClampValue(G, 1.0f);
    956       B = ClampValue(B, 1.0f);
    957       dest_scan[dest_byte_pos] = static_cast<uint8_t>(B * 255);
    958       dest_scan[dest_byte_pos + 1] = static_cast<uint8_t>(G * 255);
    959       dest_scan[dest_byte_pos + 2] = static_cast<uint8_t>(R * 255);
    960       dest_byte_pos += 3;
    961     }
    962   }
    963 }
    964 
    965 uint8_t* CPDF_DIBSource::GetBuffer() const {
    966   return m_pCachedBitmap ? m_pCachedBitmap->GetBuffer() : nullptr;
    967 }
    968 
    969 const uint8_t* CPDF_DIBSource::GetScanline(int line) const {
    970   if (m_bpc == 0) {
    971     return nullptr;
    972   }
    973   FX_SAFE_UINT32 src_pitch = CalculatePitch8(m_bpc, m_nComponents, m_Width);
    974   if (!src_pitch.IsValid())
    975     return nullptr;
    976   uint32_t src_pitch_value = src_pitch.ValueOrDie();
    977   const uint8_t* pSrcLine = nullptr;
    978   if (m_pCachedBitmap && src_pitch_value <= m_pCachedBitmap->GetPitch()) {
    979     if (line >= m_pCachedBitmap->GetHeight()) {
    980       line = m_pCachedBitmap->GetHeight() - 1;
    981     }
    982     pSrcLine = m_pCachedBitmap->GetScanline(line);
    983   } else if (m_pDecoder) {
    984     pSrcLine = m_pDecoder->GetScanline(line);
    985   } else {
    986     if (m_pStreamAcc->GetSize() >= (line + 1) * src_pitch_value) {
    987       pSrcLine = m_pStreamAcc->GetData() + line * src_pitch_value;
    988     }
    989   }
    990   if (!pSrcLine) {
    991     uint8_t* pLineBuf = m_pMaskedLine ? m_pMaskedLine : m_pLineBuf;
    992     memset(pLineBuf, 0xFF, m_Pitch);
    993     return pLineBuf;
    994   }
    995   if (m_bpc * m_nComponents == 1) {
    996     if (m_bImageMask && m_bDefaultDecode) {
    997       for (uint32_t i = 0; i < src_pitch_value; i++) {
    998         m_pLineBuf[i] = ~pSrcLine[i];
    999       }
   1000     } else if (m_bColorKey) {
   1001       uint32_t reset_argb, set_argb;
   1002       reset_argb = m_pPalette ? m_pPalette.get()[0] : 0xFF000000;
   1003       set_argb = m_pPalette ? m_pPalette.get()[1] : 0xFFFFFFFF;
   1004       if (m_pCompData[0].m_ColorKeyMin == 0) {
   1005         reset_argb = 0;
   1006       }
   1007       if (m_pCompData[0].m_ColorKeyMax == 1) {
   1008         set_argb = 0;
   1009       }
   1010       set_argb = FXARGB_TODIB(set_argb);
   1011       reset_argb = FXARGB_TODIB(reset_argb);
   1012       uint32_t* dest_scan = reinterpret_cast<uint32_t*>(m_pMaskedLine);
   1013       for (int col = 0; col < m_Width; col++) {
   1014         if (pSrcLine[col / 8] & (1 << (7 - col % 8))) {
   1015           *dest_scan = set_argb;
   1016         } else {
   1017           *dest_scan = reset_argb;
   1018         }
   1019         dest_scan++;
   1020       }
   1021       return m_pMaskedLine;
   1022     } else {
   1023       memcpy(m_pLineBuf, pSrcLine, src_pitch_value);
   1024     }
   1025     return m_pLineBuf;
   1026   }
   1027   if (m_bpc * m_nComponents <= 8) {
   1028     if (m_bpc == 8) {
   1029       memcpy(m_pLineBuf, pSrcLine, src_pitch_value);
   1030     } else {
   1031       uint64_t src_bit_pos = 0;
   1032       for (int col = 0; col < m_Width; col++) {
   1033         unsigned int color_index = 0;
   1034         for (uint32_t color = 0; color < m_nComponents; color++) {
   1035           unsigned int data = GetBits8(pSrcLine, src_bit_pos, m_bpc);
   1036           color_index |= data << (color * m_bpc);
   1037           src_bit_pos += m_bpc;
   1038         }
   1039         m_pLineBuf[col] = color_index;
   1040       }
   1041     }
   1042     if (!m_bColorKey)
   1043       return m_pLineBuf;
   1044 
   1045     uint8_t* pDestPixel = m_pMaskedLine;
   1046     const uint8_t* pSrcPixel = m_pLineBuf;
   1047     for (int col = 0; col < m_Width; col++) {
   1048       uint8_t index = *pSrcPixel++;
   1049       if (m_pPalette) {
   1050         *pDestPixel++ = FXARGB_B(m_pPalette.get()[index]);
   1051         *pDestPixel++ = FXARGB_G(m_pPalette.get()[index]);
   1052         *pDestPixel++ = FXARGB_R(m_pPalette.get()[index]);
   1053       } else {
   1054         *pDestPixel++ = index;
   1055         *pDestPixel++ = index;
   1056         *pDestPixel++ = index;
   1057       }
   1058       *pDestPixel = (index < m_pCompData[0].m_ColorKeyMin ||
   1059                      index > m_pCompData[0].m_ColorKeyMax)
   1060                         ? 0xFF
   1061                         : 0;
   1062       pDestPixel++;
   1063     }
   1064     return m_pMaskedLine;
   1065   }
   1066   if (m_bColorKey) {
   1067     if (m_nComponents == 3 && m_bpc == 8) {
   1068       uint8_t* alpha_channel = m_pMaskedLine + 3;
   1069       for (int col = 0; col < m_Width; col++) {
   1070         const uint8_t* pPixel = pSrcLine + col * 3;
   1071         alpha_channel[col * 4] = (pPixel[0] < m_pCompData[0].m_ColorKeyMin ||
   1072                                   pPixel[0] > m_pCompData[0].m_ColorKeyMax ||
   1073                                   pPixel[1] < m_pCompData[1].m_ColorKeyMin ||
   1074                                   pPixel[1] > m_pCompData[1].m_ColorKeyMax ||
   1075                                   pPixel[2] < m_pCompData[2].m_ColorKeyMin ||
   1076                                   pPixel[2] > m_pCompData[2].m_ColorKeyMax)
   1077                                      ? 0xFF
   1078                                      : 0;
   1079       }
   1080     } else {
   1081       memset(m_pMaskedLine, 0xFF, m_Pitch);
   1082     }
   1083   }
   1084   if (m_pColorSpace) {
   1085     TranslateScanline24bpp(m_pLineBuf, pSrcLine);
   1086     pSrcLine = m_pLineBuf;
   1087   }
   1088   if (!m_bColorKey)
   1089     return pSrcLine;
   1090 
   1091   const uint8_t* pSrcPixel = pSrcLine;
   1092   uint8_t* pDestPixel = m_pMaskedLine;
   1093   for (int col = 0; col < m_Width; col++) {
   1094     *pDestPixel++ = *pSrcPixel++;
   1095     *pDestPixel++ = *pSrcPixel++;
   1096     *pDestPixel++ = *pSrcPixel++;
   1097     pDestPixel++;
   1098   }
   1099   return m_pMaskedLine;
   1100 }
   1101 
   1102 bool CPDF_DIBSource::SkipToScanline(int line,
   1103                                     IFX_PauseIndicator* pPause) const {
   1104   return m_pDecoder && m_pDecoder->SkipToScanline(line, pPause);
   1105 }
   1106 
   1107 void CPDF_DIBSource::DownSampleScanline(int line,
   1108                                         uint8_t* dest_scan,
   1109                                         int dest_bpp,
   1110                                         int dest_width,
   1111                                         bool bFlipX,
   1112                                         int clip_left,
   1113                                         int clip_width) const {
   1114   if (line < 0 || !dest_scan || dest_bpp <= 0 || dest_width <= 0 ||
   1115       clip_left < 0 || clip_width <= 0) {
   1116     return;
   1117   }
   1118 
   1119   uint32_t src_width = m_Width;
   1120   FX_SAFE_UINT32 pitch = CalculatePitch8(m_bpc, m_nComponents, m_Width);
   1121   if (!pitch.IsValid())
   1122     return;
   1123 
   1124   const uint8_t* pSrcLine = nullptr;
   1125   if (m_pCachedBitmap) {
   1126     pSrcLine = m_pCachedBitmap->GetScanline(line);
   1127   } else if (m_pDecoder) {
   1128     pSrcLine = m_pDecoder->GetScanline(line);
   1129   } else {
   1130     uint32_t src_pitch = pitch.ValueOrDie();
   1131     pitch *= (line + 1);
   1132     if (!pitch.IsValid()) {
   1133       return;
   1134     }
   1135 
   1136     if (m_pStreamAcc->GetSize() >= pitch.ValueOrDie()) {
   1137       pSrcLine = m_pStreamAcc->GetData() + line * src_pitch;
   1138     }
   1139   }
   1140   int orig_Bpp = m_bpc * m_nComponents / 8;
   1141   int dest_Bpp = dest_bpp / 8;
   1142   if (!pSrcLine) {
   1143     memset(dest_scan, 0xFF, dest_Bpp * clip_width);
   1144     return;
   1145   }
   1146 
   1147   FX_SAFE_INT32 max_src_x = clip_left;
   1148   max_src_x += clip_width - 1;
   1149   max_src_x *= src_width;
   1150   max_src_x /= dest_width;
   1151   if (!max_src_x.IsValid())
   1152     return;
   1153 
   1154   if (m_bpc * m_nComponents == 1) {
   1155     DownSampleScanline1Bit(orig_Bpp, dest_Bpp, src_width, pSrcLine, dest_scan,
   1156                            dest_width, bFlipX, clip_left, clip_width);
   1157   } else if (m_bpc * m_nComponents <= 8) {
   1158     DownSampleScanline8Bit(orig_Bpp, dest_Bpp, src_width, pSrcLine, dest_scan,
   1159                            dest_width, bFlipX, clip_left, clip_width);
   1160   } else {
   1161     DownSampleScanline32Bit(orig_Bpp, dest_Bpp, src_width, pSrcLine, dest_scan,
   1162                             dest_width, bFlipX, clip_left, clip_width);
   1163   }
   1164 }
   1165 
   1166 void CPDF_DIBSource::DownSampleScanline1Bit(int orig_Bpp,
   1167                                             int dest_Bpp,
   1168                                             uint32_t src_width,
   1169                                             const uint8_t* pSrcLine,
   1170                                             uint8_t* dest_scan,
   1171                                             int dest_width,
   1172                                             bool bFlipX,
   1173                                             int clip_left,
   1174                                             int clip_width) const {
   1175   uint32_t set_argb = 0xFFFFFFFF;
   1176   uint32_t reset_argb = 0;
   1177   if (m_bImageMask) {
   1178     if (m_bDefaultDecode) {
   1179       set_argb = 0;
   1180       reset_argb = 0xFFFFFFFF;
   1181     }
   1182   } else if (m_bColorKey) {
   1183     reset_argb = m_pPalette ? m_pPalette.get()[0] : 0xFF000000;
   1184     set_argb = m_pPalette ? m_pPalette.get()[1] : 0xFFFFFFFF;
   1185     if (m_pCompData[0].m_ColorKeyMin == 0) {
   1186       reset_argb = 0;
   1187     }
   1188     if (m_pCompData[0].m_ColorKeyMax == 1) {
   1189       set_argb = 0;
   1190     }
   1191     set_argb = FXARGB_TODIB(set_argb);
   1192     reset_argb = FXARGB_TODIB(reset_argb);
   1193     uint32_t* dest_scan_dword = reinterpret_cast<uint32_t*>(dest_scan);
   1194     for (int i = 0; i < clip_width; i++) {
   1195       uint32_t src_x = (clip_left + i) * src_width / dest_width;
   1196       if (bFlipX) {
   1197         src_x = src_width - src_x - 1;
   1198       }
   1199       src_x %= src_width;
   1200       if (pSrcLine[src_x / 8] & (1 << (7 - src_x % 8))) {
   1201         dest_scan_dword[i] = set_argb;
   1202       } else {
   1203         dest_scan_dword[i] = reset_argb;
   1204       }
   1205     }
   1206     return;
   1207   } else {
   1208     if (dest_Bpp == 1) {
   1209     } else if (m_pPalette) {
   1210       reset_argb = m_pPalette.get()[0];
   1211       set_argb = m_pPalette.get()[1];
   1212     }
   1213   }
   1214   for (int i = 0; i < clip_width; i++) {
   1215     uint32_t src_x = (clip_left + i) * src_width / dest_width;
   1216     if (bFlipX) {
   1217       src_x = src_width - src_x - 1;
   1218     }
   1219     src_x %= src_width;
   1220     int dest_pos = i * dest_Bpp;
   1221     if (pSrcLine[src_x / 8] & (1 << (7 - src_x % 8))) {
   1222       if (dest_Bpp == 1) {
   1223         dest_scan[dest_pos] = static_cast<uint8_t>(set_argb);
   1224       } else if (dest_Bpp == 3) {
   1225         dest_scan[dest_pos] = FXARGB_B(set_argb);
   1226         dest_scan[dest_pos + 1] = FXARGB_G(set_argb);
   1227         dest_scan[dest_pos + 2] = FXARGB_R(set_argb);
   1228       } else {
   1229         *reinterpret_cast<uint32_t*>(dest_scan + dest_pos) = set_argb;
   1230       }
   1231     } else {
   1232       if (dest_Bpp == 1) {
   1233         dest_scan[dest_pos] = static_cast<uint8_t>(reset_argb);
   1234       } else if (dest_Bpp == 3) {
   1235         dest_scan[dest_pos] = FXARGB_B(reset_argb);
   1236         dest_scan[dest_pos + 1] = FXARGB_G(reset_argb);
   1237         dest_scan[dest_pos + 2] = FXARGB_R(reset_argb);
   1238       } else {
   1239         *reinterpret_cast<uint32_t*>(dest_scan + dest_pos) = reset_argb;
   1240       }
   1241     }
   1242   }
   1243 }
   1244 
   1245 void CPDF_DIBSource::DownSampleScanline8Bit(int orig_Bpp,
   1246                                             int dest_Bpp,
   1247                                             uint32_t src_width,
   1248                                             const uint8_t* pSrcLine,
   1249                                             uint8_t* dest_scan,
   1250                                             int dest_width,
   1251                                             bool bFlipX,
   1252                                             int clip_left,
   1253                                             int clip_width) const {
   1254   if (m_bpc < 8) {
   1255     uint64_t src_bit_pos = 0;
   1256     for (uint32_t col = 0; col < src_width; col++) {
   1257       unsigned int color_index = 0;
   1258       for (uint32_t color = 0; color < m_nComponents; color++) {
   1259         unsigned int data = GetBits8(pSrcLine, src_bit_pos, m_bpc);
   1260         color_index |= data << (color * m_bpc);
   1261         src_bit_pos += m_bpc;
   1262       }
   1263       m_pLineBuf[col] = color_index;
   1264     }
   1265     pSrcLine = m_pLineBuf;
   1266   }
   1267   if (m_bColorKey) {
   1268     for (int i = 0; i < clip_width; i++) {
   1269       uint32_t src_x = (clip_left + i) * src_width / dest_width;
   1270       if (bFlipX) {
   1271         src_x = src_width - src_x - 1;
   1272       }
   1273       src_x %= src_width;
   1274       uint8_t* pDestPixel = dest_scan + i * 4;
   1275       uint8_t index = pSrcLine[src_x];
   1276       if (m_pPalette) {
   1277         *pDestPixel++ = FXARGB_B(m_pPalette.get()[index]);
   1278         *pDestPixel++ = FXARGB_G(m_pPalette.get()[index]);
   1279         *pDestPixel++ = FXARGB_R(m_pPalette.get()[index]);
   1280       } else {
   1281         *pDestPixel++ = index;
   1282         *pDestPixel++ = index;
   1283         *pDestPixel++ = index;
   1284       }
   1285       *pDestPixel = (index < m_pCompData[0].m_ColorKeyMin ||
   1286                      index > m_pCompData[0].m_ColorKeyMax)
   1287                         ? 0xFF
   1288                         : 0;
   1289     }
   1290     return;
   1291   }
   1292   for (int i = 0; i < clip_width; i++) {
   1293     uint32_t src_x = (clip_left + i) * src_width / dest_width;
   1294     if (bFlipX) {
   1295       src_x = src_width - src_x - 1;
   1296     }
   1297     src_x %= src_width;
   1298     uint8_t index = pSrcLine[src_x];
   1299     if (dest_Bpp == 1) {
   1300       dest_scan[i] = index;
   1301     } else {
   1302       int dest_pos = i * dest_Bpp;
   1303       FX_ARGB argb = m_pPalette.get()[index];
   1304       dest_scan[dest_pos] = FXARGB_B(argb);
   1305       dest_scan[dest_pos + 1] = FXARGB_G(argb);
   1306       dest_scan[dest_pos + 2] = FXARGB_R(argb);
   1307     }
   1308   }
   1309 }
   1310 
   1311 void CPDF_DIBSource::DownSampleScanline32Bit(int orig_Bpp,
   1312                                              int dest_Bpp,
   1313                                              uint32_t src_width,
   1314                                              const uint8_t* pSrcLine,
   1315                                              uint8_t* dest_scan,
   1316                                              int dest_width,
   1317                                              bool bFlipX,
   1318                                              int clip_left,
   1319                                              int clip_width) const {
   1320   // last_src_x used to store the last seen src_x position which should be
   1321   // in [0, src_width). Set the initial value to be an invalid src_x value.
   1322   uint32_t last_src_x = src_width;
   1323   FX_ARGB last_argb = FXARGB_MAKE(0xFF, 0xFF, 0xFF, 0xFF);
   1324   float unit_To8Bpc = 255.0f / ((1 << m_bpc) - 1);
   1325   for (int i = 0; i < clip_width; i++) {
   1326     int dest_x = clip_left + i;
   1327     uint32_t src_x = (bFlipX ? (dest_width - dest_x - 1) : dest_x) *
   1328                      (int64_t)src_width / dest_width;
   1329     src_x %= src_width;
   1330 
   1331     uint8_t* pDestPixel = dest_scan + i * dest_Bpp;
   1332     FX_ARGB argb;
   1333     if (src_x == last_src_x) {
   1334       argb = last_argb;
   1335     } else {
   1336       CFX_FixedBufGrow<uint8_t, 16> extracted_components(m_nComponents);
   1337       const uint8_t* pSrcPixel = nullptr;
   1338       if (m_bpc % 8 != 0) {
   1339         // No need to check for 32-bit overflow, as |src_x| is bounded by
   1340         // |src_width| and DownSampleScanline() already checked for overflow
   1341         // with the pitch calculation.
   1342         size_t num_bits = src_x * m_bpc * m_nComponents;
   1343         uint64_t src_bit_pos = num_bits % 8;
   1344         pSrcPixel = pSrcLine + num_bits / 8;
   1345         for (uint32_t j = 0; j < m_nComponents; ++j) {
   1346           extracted_components[j] = static_cast<uint8_t>(
   1347               GetBits8(pSrcPixel, src_bit_pos, m_bpc) * unit_To8Bpc);
   1348           src_bit_pos += m_bpc;
   1349         }
   1350         pSrcPixel = extracted_components;
   1351       } else {
   1352         pSrcPixel = pSrcLine + src_x * orig_Bpp;
   1353         if (m_bpc == 16) {
   1354           for (uint32_t j = 0; j < m_nComponents; ++j)
   1355             extracted_components[j] = pSrcPixel[j * 2];
   1356           pSrcPixel = extracted_components;
   1357         }
   1358       }
   1359 
   1360       if (m_pColorSpace) {
   1361         uint8_t color[4];
   1362         const bool bTransMask = TransMask();
   1363         if (!m_bDefaultDecode) {
   1364           for (uint32_t j = 0; j < m_nComponents; ++j) {
   1365             float component_value = static_cast<float>(pSrcPixel[j]);
   1366             int color_value = static_cast<int>(
   1367                 (m_pCompData[j].m_DecodeMin +
   1368                  m_pCompData[j].m_DecodeStep * component_value) *
   1369                     255.0f +
   1370                 0.5f);
   1371             extracted_components[j] = pdfium::clamp(color_value, 0, 255);
   1372           }
   1373         }
   1374         const uint8_t* pSrc =
   1375             m_bDefaultDecode ? pSrcPixel : extracted_components;
   1376         m_pColorSpace->TranslateImageLine(color, pSrc, 1, 0, 0, bTransMask);
   1377         argb = FXARGB_MAKE(0xFF, color[2], color[1], color[0]);
   1378       } else {
   1379         argb = FXARGB_MAKE(0xFF, pSrcPixel[2], pSrcPixel[1], pSrcPixel[0]);
   1380       }
   1381       if (m_bColorKey) {
   1382         int alpha = 0xFF;
   1383         if (m_nComponents == 3 && m_bpc == 8) {
   1384           alpha = (pSrcPixel[0] < m_pCompData[0].m_ColorKeyMin ||
   1385                    pSrcPixel[0] > m_pCompData[0].m_ColorKeyMax ||
   1386                    pSrcPixel[1] < m_pCompData[1].m_ColorKeyMin ||
   1387                    pSrcPixel[1] > m_pCompData[1].m_ColorKeyMax ||
   1388                    pSrcPixel[2] < m_pCompData[2].m_ColorKeyMin ||
   1389                    pSrcPixel[2] > m_pCompData[2].m_ColorKeyMax)
   1390                       ? 0xFF
   1391                       : 0;
   1392         }
   1393         argb &= 0xFFFFFF;
   1394         argb |= alpha << 24;
   1395       }
   1396       last_src_x = src_x;
   1397       last_argb = argb;
   1398     }
   1399     if (dest_Bpp == 4) {
   1400       *reinterpret_cast<uint32_t*>(pDestPixel) = FXARGB_TODIB(argb);
   1401     } else {
   1402       *pDestPixel++ = FXARGB_B(argb);
   1403       *pDestPixel++ = FXARGB_G(argb);
   1404       *pDestPixel = FXARGB_R(argb);
   1405     }
   1406   }
   1407 }
   1408 
   1409 bool CPDF_DIBSource::TransMask() const {
   1410   return m_bLoadMask && m_GroupFamily == PDFCS_DEVICECMYK &&
   1411          m_Family == PDFCS_DEVICECMYK;
   1412 }
   1413