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