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