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>
15static 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}
31CFX_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}
40CFX_DIBSource* CPDF_Image::DetachBitmap()
41{
42    CFX_DIBSource* pBitmap = m_pDIBSource;
43    m_pDIBSource = NULL;
44    return pBitmap;
45}
46CFX_DIBSource* CPDF_Image::DetachMask()
47{
48    CFX_DIBSource* pBitmap = m_pMask;
49    m_pMask = NULL;
50    return pBitmap;
51}
52FX_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}
68FX_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}
83CPDF_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}
112CPDF_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}
146CFX_DIBitmap* CPDF_DIBSource::GetBitmap() const
147{
148    if (m_pCachedBitmap) {
149        return m_pCachedBitmap;
150    }
151    return Clone();
152}
153void CPDF_DIBSource::ReleaseBitmap(CFX_DIBitmap* pBitmap) const
154{
155    if (pBitmap && pBitmap != m_pCachedBitmap) {
156        delete pBitmap;
157    }
158}
159FX_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}
262int	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}
311int	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}
388int	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}
468FX_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}
574ICodec_ScanlineDecoder* FPDFAPI_CreateFaxDecoder(FX_LPCBYTE src_buf, FX_DWORD src_size, int width, int height,
575        const CPDF_Dictionary* pParams);
576ICodec_ScanlineDecoder* FPDFAPI_CreateFlateDecoder(FX_LPCBYTE src_buf, FX_DWORD src_size, int width, int height,
577        int nComps, int bpc, const CPDF_Dictionary* pParams);
578int 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}
630void 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}
718void 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}
749CPDF_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}
776int	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}
803int	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}
822CPDF_DIBSource*	CPDF_DIBSource::DetachMask()
823{
824    CPDF_DIBSource* pDIBSource = m_pMask;
825    m_pMask = NULL;
826    return pDIBSource;
827}
828CPDF_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}
837int 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}
854void 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
915FX_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);
946void 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}
1058FX_LPBYTE CPDF_DIBSource::GetBuffer() const
1059{
1060    if (m_pCachedBitmap) {
1061        return m_pCachedBitmap->GetBuffer();
1062    }
1063    return NULL;
1064}
1065FX_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}
1185FX_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}
1192void 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}
1410void 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}
1418void CPDF_DIBSource::ClearImageData()
1419{
1420    if (m_pDecoder) {
1421        m_pDecoder->ClearImageData();
1422    }
1423}
1424CPDF_ProgressiveImageLoaderHandle::CPDF_ProgressiveImageLoaderHandle()
1425{
1426    m_pImageLoader = NULL;
1427    m_pCache = NULL;
1428    m_pImage = NULL;
1429}
1430CPDF_ProgressiveImageLoaderHandle::~CPDF_ProgressiveImageLoaderHandle()
1431{
1432    m_pImageLoader = NULL;
1433    m_pCache = NULL;
1434    m_pImage = NULL;
1435}
1436FX_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}
1463FX_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}
1485FX_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}
1499FX_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}
1509FX_BOOL	CPDF_ImageLoader::Continue(FX_LPVOID LoadHandle, IFX_Pause* pPause)
1510{
1511    return ((CPDF_ProgressiveImageLoaderHandle*)LoadHandle)->Continue(pPause);
1512}
1513CPDF_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