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