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