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