1 // Copyright 2014 PDFium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6
7 #include "../../../include/fxge/fx_ge.h"
8 #include "../../../include/fxcodec/fx_codec.h"
9 #include "../../../include/fpdfapi/fpdf_module.h"
10 #include "../../../include/fpdfapi/fpdf_render.h"
11 #include "../../../include/fpdfapi/fpdf_pageobj.h"
12 #include "../fpdf_page/pageint.h"
13 #include "render_int.h"
ProcessImage(CPDF_ImageObject * pImageObj,const CFX_AffineMatrix * pObj2Device)14 FX_BOOL CPDF_RenderStatus::ProcessImage(CPDF_ImageObject* pImageObj, const CFX_AffineMatrix* pObj2Device)
15 {
16 CPDF_ImageRenderer render;
17 if (render.Start(this, pImageObj, pObj2Device, m_bStdCS, m_curBlend)) {
18 render.Continue(NULL);
19 }
20 #ifdef _FPDFAPI_MINI_
21 if (m_DitherBits) {
22 DitherObjectArea(pImageObj, pObj2Device);
23 }
24 #endif
25 return render.m_Result;
26 }
27 #if defined(_FPDFAPI_MINI_)
ProcessInlines(CPDF_InlineImages * pInlines,const CFX_AffineMatrix * pObj2Device)28 FX_BOOL CPDF_RenderStatus::ProcessInlines(CPDF_InlineImages* pInlines, const CFX_AffineMatrix* pObj2Device)
29 {
30 int bitmap_alpha = 255;
31 if (!pInlines->m_GeneralState.IsNull()) {
32 bitmap_alpha = FXSYS_round(pInlines->m_GeneralState.GetObject()->m_FillAlpha * 255);
33 }
34 if (pInlines->m_pStream) {
35 CPDF_DIBSource dibsrc;
36 if (!dibsrc.Load(m_pContext->m_pDocument, pInlines->m_pStream, NULL, NULL, NULL, NULL)) {
37 return TRUE;
38 }
39 pInlines->m_pBitmap = dibsrc.Clone();
40 pInlines->m_pStream->Release();
41 pInlines->m_pStream = NULL;
42 }
43 if (pInlines->m_pBitmap == NULL) {
44 return TRUE;
45 }
46 FX_ARGB fill_argb = 0;
47 if (pInlines->m_pBitmap->IsAlphaMask()) {
48 fill_argb = GetFillArgb(pInlines);
49 }
50 int flags = 0;
51 if (m_Options.m_Flags & RENDER_FORCE_DOWNSAMPLE) {
52 flags |= RENDER_FORCE_DOWNSAMPLE;
53 } else if (m_Options.m_Flags & RENDER_FORCE_HALFTONE) {
54 flags = 0;
55 }
56 for (int i = 0; i < pInlines->m_Matrices.GetSize(); i ++) {
57 CFX_AffineMatrix image_matrix = pInlines->m_Matrices.GetAt(i);
58 image_matrix.Concat(*pObj2Device);
59 CPDF_ImageRenderer renderer;
60 if (renderer.Start(this, pInlines->m_pBitmap, fill_argb, bitmap_alpha, &image_matrix, flags, FALSE, m_curBlend)) {
61 renderer.Continue(NULL);
62 }
63 }
64 return TRUE;
65 }
66 #endif
CompositeDIBitmap(CFX_DIBitmap * pDIBitmap,int left,int top,FX_ARGB mask_argb,int bitmap_alpha,int blend_mode,int Transparency)67 void CPDF_RenderStatus::CompositeDIBitmap(CFX_DIBitmap* pDIBitmap, int left, int top, FX_ARGB mask_argb,
68 int bitmap_alpha, int blend_mode, int Transparency)
69 {
70 if (pDIBitmap == NULL) {
71 return;
72 }
73 FX_BOOL bIsolated = Transparency & PDFTRANS_ISOLATED;
74 FX_BOOL bGroup = Transparency & PDFTRANS_GROUP;
75 if (blend_mode == FXDIB_BLEND_NORMAL) {
76 if (!pDIBitmap->IsAlphaMask()) {
77 if (bitmap_alpha < 255) {
78 pDIBitmap->MultiplyAlpha(bitmap_alpha);
79 }
80 if (m_pDevice->SetDIBits(pDIBitmap, left, top)) {
81 return;
82 }
83 } else {
84 FX_DWORD fill_argb = m_Options.TranslateColor(mask_argb);
85 if (bitmap_alpha < 255) {
86 ((FX_BYTE*)&fill_argb)[3] = ((FX_BYTE*)&fill_argb)[3] * bitmap_alpha / 255;
87 }
88 if (m_pDevice->SetBitMask(pDIBitmap, left, top, fill_argb)) {
89 return;
90 }
91 }
92 }
93 FX_BOOL bBackAlphaRequired = blend_mode && bIsolated && !m_bDropObjects;
94 FX_BOOL bGetBackGround = ((m_pDevice->GetRenderCaps() & FXRC_ALPHA_OUTPUT)) ||
95 (!(m_pDevice->GetRenderCaps() & FXRC_ALPHA_OUTPUT) && (m_pDevice->GetRenderCaps()
96 & FXRC_GET_BITS) && !bBackAlphaRequired);
97 if (bGetBackGround) {
98 if (bIsolated || !bGroup) {
99 if (pDIBitmap->IsAlphaMask()) {
100 return;
101 }
102 m_pDevice->SetDIBits(pDIBitmap, left, top, blend_mode);
103 } else {
104 FX_RECT rect(left, top, left + pDIBitmap->GetWidth(), top + pDIBitmap->GetHeight());
105 rect.Intersect(m_pDevice->GetClipBox());
106 CFX_DIBitmap* pClone = NULL;
107 FX_BOOL bClone = FALSE;
108 if (m_pDevice->GetBackDrop() && m_pDevice->GetBitmap()) {
109 bClone = TRUE;
110 pClone = m_pDevice->GetBackDrop()->Clone(&rect);
111 CFX_DIBitmap *pForeBitmap = m_pDevice->GetBitmap();
112 pClone->CompositeBitmap(0, 0, pClone->GetWidth(), pClone->GetHeight(), pForeBitmap, rect.left, rect.top);
113 left = left >= 0 ? 0 : left;
114 top = top >= 0 ? 0 : top;
115 if (!pDIBitmap->IsAlphaMask())
116 pClone->CompositeBitmap(0, 0, pClone->GetWidth(), pClone->GetHeight(), pDIBitmap,
117 left, top, blend_mode);
118 else
119 pClone->CompositeMask(0, 0, pClone->GetWidth(), pClone->GetHeight(), pDIBitmap,
120 mask_argb, left, top, blend_mode);
121 } else {
122 pClone = pDIBitmap;
123 }
124 if (m_pDevice->GetBackDrop()) {
125 m_pDevice->SetDIBits(pClone, rect.left, rect.top);
126 } else {
127 if (pDIBitmap->IsAlphaMask()) {
128 return;
129 }
130 m_pDevice->SetDIBits(pDIBitmap, rect.left, rect.top, blend_mode);
131 }
132 if (bClone) {
133 delete pClone;
134 }
135 }
136 return;
137 }
138 int back_left, back_top;
139 FX_RECT rect(left, top, left + pDIBitmap->GetWidth(), top + pDIBitmap->GetHeight());
140 CFX_DIBitmap* pBackdrop = GetBackdrop(m_pCurObj, rect, back_left, back_top, blend_mode > FXDIB_BLEND_NORMAL && bIsolated);
141 if (!pBackdrop) {
142 return;
143 }
144 if (!pDIBitmap->IsAlphaMask())
145 pBackdrop->CompositeBitmap(left - back_left, top - back_top, pDIBitmap->GetWidth(), pDIBitmap->GetHeight(), pDIBitmap,
146 0, 0, blend_mode);
147 else
148 pBackdrop->CompositeMask(left - back_left, top - back_top, pDIBitmap->GetWidth(), pDIBitmap->GetHeight(), pDIBitmap,
149 mask_argb, 0, 0, blend_mode);
150 CFX_DIBitmap* pBackdrop1 = FX_NEW CFX_DIBitmap;
151 pBackdrop1->Create(pBackdrop->GetWidth(), pBackdrop->GetHeight(), FXDIB_Rgb32);
152 pBackdrop1->Clear((FX_DWORD) - 1);
153 pBackdrop1->CompositeBitmap(0, 0, pBackdrop->GetWidth(), pBackdrop->GetHeight(), pBackdrop, 0, 0);
154 delete pBackdrop;
155 pBackdrop = pBackdrop1;
156 m_pDevice->SetDIBits(pBackdrop, back_left, back_top);
157 delete pBackdrop;
158 }
TranslateColor(FX_COLORREF rgb)159 FX_COLORREF CPDF_TransferFunc::TranslateColor(FX_COLORREF rgb)
160 {
161 return FXSYS_RGB(m_Samples[FXSYS_GetRValue(rgb)], m_Samples[256 + FXSYS_GetGValue(rgb)],
162 m_Samples[512 + FXSYS_GetBValue(rgb)]);
163 }
TranslateImage(const CFX_DIBSource * pSrc,FX_BOOL bAutoDropSrc)164 CFX_DIBSource* CPDF_TransferFunc::TranslateImage(const CFX_DIBSource* pSrc, FX_BOOL bAutoDropSrc)
165 {
166 CPDF_DIBTransferFunc* pDest = FX_NEW CPDF_DIBTransferFunc(this);
167 pDest->LoadSrc(pSrc, bAutoDropSrc);
168 return pDest;
169 }
GetDestFormat()170 FXDIB_Format CPDF_DIBTransferFunc::GetDestFormat()
171 {
172 if (m_pSrc->IsAlphaMask()) {
173 return FXDIB_8bppMask;
174 }
175 #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
176 return (m_pSrc->HasAlpha()) ? FXDIB_Argb : FXDIB_Rgb32;
177 #else
178 return (m_pSrc->HasAlpha()) ? FXDIB_Argb : FXDIB_Rgb;
179 #endif
180 }
CPDF_DIBTransferFunc(const CPDF_TransferFunc * pTransferFunc)181 CPDF_DIBTransferFunc::CPDF_DIBTransferFunc(const CPDF_TransferFunc* pTransferFunc)
182 {
183 m_RampR = pTransferFunc->m_Samples;
184 m_RampG = &pTransferFunc->m_Samples[256];
185 m_RampB = &pTransferFunc->m_Samples[512];
186 }
TranslateScanline(FX_LPBYTE dest_buf,FX_LPCBYTE src_buf) const187 void CPDF_DIBTransferFunc::TranslateScanline(FX_LPBYTE dest_buf, FX_LPCBYTE src_buf) const
188 {
189 int i;
190 FX_BOOL bSkip = FALSE;
191 switch (m_pSrc->GetFormat()) {
192 case FXDIB_1bppRgb: {
193 int r0 = m_RampR[0], g0 = m_RampG[0], b0 = m_RampB[0];
194 int r1 = m_RampR[255], g1 = m_RampG[255], b1 = m_RampB[255];
195 for (i = 0; i < m_Width; i ++) {
196 if (src_buf[i / 8] & (1 << (7 - i % 8))) {
197 *dest_buf++ = b1;
198 *dest_buf++ = g1;
199 *dest_buf++ = r1;
200 } else {
201 *dest_buf++ = b0;
202 *dest_buf++ = g0;
203 *dest_buf++ = r0;
204 }
205 #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
206 dest_buf++;
207 #endif
208 }
209 break;
210 }
211 case FXDIB_1bppMask: {
212 int m0 = m_RampR[0], m1 = m_RampR[255];
213 for (i = 0; i < m_Width; i ++) {
214 if (src_buf[i / 8] & (1 << (7 - i % 8))) {
215 *dest_buf++ = m1;
216 } else {
217 *dest_buf++ = m0;
218 }
219 }
220 break;
221 }
222 case FXDIB_8bppRgb: {
223 FX_ARGB* pPal = m_pSrc->GetPalette();
224 for (i = 0; i < m_Width; i ++) {
225 if (pPal) {
226 FX_ARGB src_argb = pPal[*src_buf];
227 *dest_buf++ = m_RampB[FXARGB_R(src_argb)];
228 *dest_buf++ = m_RampG[FXARGB_G(src_argb)];
229 *dest_buf++ = m_RampR[FXARGB_B(src_argb)];
230 } else {
231 FX_DWORD src_byte = *src_buf;
232 *dest_buf++ = m_RampB[src_byte];
233 *dest_buf++ = m_RampG[src_byte];
234 *dest_buf++ = m_RampR[src_byte];
235 }
236 src_buf ++;
237 #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
238 dest_buf++;
239 #endif
240 }
241 break;
242 }
243 case FXDIB_8bppMask:
244 for (i = 0; i < m_Width; i ++) {
245 *dest_buf++ = m_RampR[*(src_buf++)];
246 }
247 break;
248 case FXDIB_Rgb:
249 for (i = 0; i < m_Width; i ++) {
250 *dest_buf++ = m_RampB[*(src_buf++)];
251 *dest_buf++ = m_RampG[*(src_buf++)];
252 *dest_buf++ = m_RampR[*(src_buf++)];
253 #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
254 dest_buf++;
255 #endif
256 }
257 break;
258 case FXDIB_Rgb32:
259 bSkip = TRUE;
260 case FXDIB_Argb:
261 for (i = 0; i < m_Width; i ++) {
262 *dest_buf++ = m_RampB[*(src_buf++)];
263 *dest_buf++ = m_RampG[*(src_buf++)];
264 *dest_buf++ = m_RampR[*(src_buf++)];
265 if (!bSkip) {
266 *dest_buf++ = *src_buf;
267 }
268 #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
269 else {
270 dest_buf++;
271 }
272 #endif
273 src_buf ++;
274 }
275 break;
276 default:
277 break;
278 }
279 }
TranslateDownSamples(FX_LPBYTE dest_buf,FX_LPCBYTE src_buf,int pixels,int Bpp) const280 void CPDF_DIBTransferFunc::TranslateDownSamples(FX_LPBYTE dest_buf, FX_LPCBYTE src_buf, int pixels, int Bpp) const
281 {
282 if (Bpp == 8) {
283 for (int i = 0; i < pixels; i ++) {
284 *dest_buf++ = m_RampR[*(src_buf++)];
285 }
286 } else if (Bpp == 24) {
287 for (int i = 0; i < pixels; i ++) {
288 *dest_buf++ = m_RampB[*(src_buf++)];
289 *dest_buf++ = m_RampG[*(src_buf++)];
290 *dest_buf++ = m_RampR[*(src_buf++)];
291 }
292 } else {
293 #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
294 if (!m_pSrc->HasAlpha()) {
295 for (int i = 0; i < pixels; i ++) {
296 *dest_buf++ = m_RampB[*(src_buf++)];
297 *dest_buf++ = m_RampG[*(src_buf++)];
298 *dest_buf++ = m_RampR[*(src_buf++)];
299 dest_buf++;
300 src_buf++;
301 }
302 } else
303 #endif
304 for (int i = 0; i < pixels; i ++) {
305 *dest_buf++ = m_RampB[*(src_buf++)];
306 *dest_buf++ = m_RampG[*(src_buf++)];
307 *dest_buf++ = m_RampR[*(src_buf++)];
308 *dest_buf++ = *(src_buf++);
309 }
310 }
311 }
_IsSupported(CPDF_ColorSpace * pCS)312 static FX_BOOL _IsSupported(CPDF_ColorSpace* pCS)
313 {
314 if (pCS->GetFamily() == PDFCS_DEVICERGB || pCS->GetFamily() == PDFCS_DEVICEGRAY ||
315 pCS->GetFamily() == PDFCS_DEVICECMYK || pCS->GetFamily() == PDFCS_CALGRAY ||
316 pCS->GetFamily() == PDFCS_CALRGB) {
317 return TRUE;
318 }
319 if (pCS->GetFamily() == PDFCS_INDEXED && _IsSupported(pCS->GetBaseCS())) {
320 return TRUE;
321 }
322 return FALSE;
323 }
CPDF_ImageRenderer()324 CPDF_ImageRenderer::CPDF_ImageRenderer()
325 {
326 m_pRenderStatus = NULL;
327 m_pImageObject = NULL;
328 m_Result = TRUE;
329 m_Status = 0;
330 m_pQuickStretcher = NULL;
331 m_pTransformer = NULL;
332 m_DeviceHandle = NULL;
333 m_LoadHandle = NULL;
334 m_pClone = NULL;
335 m_bStdCS = FALSE;
336 m_bPatternColor = FALSE;
337 m_BlendType = FXDIB_BLEND_NORMAL;
338 m_pPattern = NULL;
339 m_pObj2Device = NULL;
340 }
~CPDF_ImageRenderer()341 CPDF_ImageRenderer::~CPDF_ImageRenderer()
342 {
343 if (m_pQuickStretcher) {
344 delete m_pQuickStretcher;
345 }
346 if (m_pTransformer) {
347 delete m_pTransformer;
348 }
349 if (m_DeviceHandle) {
350 m_pRenderStatus->m_pDevice->CancelDIBits(m_DeviceHandle);
351 }
352 if (m_LoadHandle) {
353 delete (CPDF_ProgressiveImageLoaderHandle*)m_LoadHandle;
354 }
355 if (m_pClone) {
356 delete m_pClone;
357 }
358 }
StartLoadDIBSource()359 FX_BOOL CPDF_ImageRenderer::StartLoadDIBSource()
360 {
361 CFX_FloatRect image_rect_f = m_ImageMatrix.GetUnitRect();
362 FX_RECT image_rect = image_rect_f.GetOutterRect();
363 int dest_width = image_rect.Width();
364 int dest_height = image_rect.Height();
365 if (m_ImageMatrix.a < 0) {
366 dest_width = -dest_width;
367 }
368 if (m_ImageMatrix.d > 0) {
369 dest_height = -dest_height;
370 }
371 if (m_Loader.StartLoadImage(m_pImageObject, m_pRenderStatus->m_pContext->m_pPageCache, m_LoadHandle, m_bStdCS,
372 m_pRenderStatus->m_GroupFamily, m_pRenderStatus->m_bLoadMask, m_pRenderStatus, dest_width, dest_height)) {
373 if (m_LoadHandle != NULL) {
374 m_Status = 4;
375 return TRUE;
376 }
377 return FALSE;
378 }
379 return FALSE;
380 }
StartRenderDIBSource()381 FX_BOOL CPDF_ImageRenderer::StartRenderDIBSource()
382 {
383 if (m_Loader.m_pBitmap == NULL) {
384 return FALSE;
385 }
386 m_BitmapAlpha = 255;
387 const CPDF_GeneralStateData* pGeneralState = m_pImageObject->m_GeneralState;
388 if (pGeneralState) {
389 m_BitmapAlpha = FXSYS_round(pGeneralState->m_FillAlpha * 255);
390 }
391 m_pDIBSource = m_Loader.m_pBitmap;
392 if (m_pRenderStatus->m_Options.m_ColorMode == RENDER_COLOR_ALPHA && m_Loader.m_pMask == NULL) {
393 return StartBitmapAlpha();
394 }
395 #ifndef _FPDFAPI_MINI_
396 if (pGeneralState && pGeneralState->m_pTR) {
397 if (!pGeneralState->m_pTransferFunc) {
398 ((CPDF_GeneralStateData*)pGeneralState)->m_pTransferFunc = m_pRenderStatus->GetTransferFunc(pGeneralState->m_pTR);
399 }
400 if (pGeneralState->m_pTransferFunc && !pGeneralState->m_pTransferFunc->m_bIdentity) {
401 m_pDIBSource = m_Loader.m_pBitmap = pGeneralState->m_pTransferFunc->TranslateImage(m_Loader.m_pBitmap, !m_Loader.m_bCached);
402 if (m_Loader.m_bCached && m_Loader.m_pMask) {
403 m_Loader.m_pMask = m_Loader.m_pMask->Clone();
404 }
405 m_Loader.m_bCached = FALSE;
406 }
407 }
408 #endif
409 m_FillArgb = 0;
410 m_bPatternColor = FALSE;
411 m_pPattern = NULL;
412 if (m_pDIBSource->IsAlphaMask()) {
413 CPDF_Color* pColor = m_pImageObject->m_ColorState.GetFillColor();
414 if (pColor && pColor->IsPattern()) {
415 m_pPattern = pColor->GetPattern();
416 if (m_pPattern != NULL) {
417 m_bPatternColor = TRUE;
418 }
419 }
420 m_FillArgb = m_pRenderStatus->GetFillArgb(m_pImageObject);
421 } else if (m_pRenderStatus->m_Options.m_ColorMode == RENDER_COLOR_GRAY) {
422 m_pClone = m_pDIBSource->Clone();
423 m_pClone->ConvertColorScale(m_pRenderStatus->m_Options.m_BackColor, m_pRenderStatus->m_Options.m_ForeColor);
424 m_pDIBSource = m_pClone;
425 }
426 m_Flags = 0;
427 #if !defined(_FPDFAPI_MINI_)
428 if (m_pRenderStatus->m_Options.m_Flags & RENDER_FORCE_DOWNSAMPLE) {
429 m_Flags |= RENDER_FORCE_DOWNSAMPLE;
430 } else if (m_pRenderStatus->m_Options.m_Flags & RENDER_FORCE_HALFTONE) {
431 m_Flags |= RENDER_FORCE_HALFTONE;
432 }
433 #else
434 if (!(m_pRenderStatus->m_Options.m_Flags & RENDER_FORCE_HALFTONE)) {
435 if (m_pRenderStatus->m_HalftoneLimit) {
436 CFX_FloatRect image_rect_f = m_ImageMatrix.GetUnitRect();
437 FX_RECT image_rect = image_rect_f.GetOutterRect();
438 FX_RECT image_clip = image_rect;
439 image_rect.Intersect(m_pRenderStatus->m_pDevice->GetClipBox());
440 if (image_rect.Width() && image_rect.Height()) {
441 if ((image_clip.Width() * m_pDIBSource->GetWidth() / image_rect.Width()) *
442 (image_clip.Height() * m_pDIBSource->GetHeight() / image_rect.Height()) >
443 m_pRenderStatus->m_HalftoneLimit) {
444 m_Flags |= RENDER_FORCE_DOWNSAMPLE;
445 }
446 }
447 } else {
448 m_Flags |= RENDER_FORCE_DOWNSAMPLE;
449 }
450 }
451 #endif
452 #ifndef _FPDFAPI_MINI_
453 if (m_pRenderStatus->m_pDevice->GetDeviceClass() != FXDC_DISPLAY) {
454 CPDF_Object* pFilters = m_pImageObject->m_pImage->GetStream()->GetDict()->GetElementValue(FX_BSTRC("Filter"));
455 if (pFilters) {
456 if (pFilters->GetType() == PDFOBJ_NAME) {
457 CFX_ByteStringC bsDecodeType = pFilters->GetConstString();
458 if (bsDecodeType == FX_BSTRC("DCTDecode") || bsDecodeType == FX_BSTRC("JPXDecode")) {
459 m_Flags |= FXRENDER_IMAGE_LOSSY;
460 }
461 } else if (pFilters->GetType() == PDFOBJ_ARRAY) {
462 CPDF_Array* pArray = (CPDF_Array*)pFilters;
463 for (FX_DWORD i = 0; i < pArray->GetCount(); i ++) {
464 CFX_ByteStringC bsDecodeType = pArray->GetConstString(i);
465 if (bsDecodeType == FX_BSTRC("DCTDecode") || bsDecodeType == FX_BSTRC("JPXDecode")) {
466 m_Flags |= FXRENDER_IMAGE_LOSSY;
467 break;
468 }
469 }
470 }
471 }
472 }
473 if (m_pRenderStatus->m_Options.m_Flags & RENDER_NOIMAGESMOOTH) {
474 m_Flags |= FXDIB_NOSMOOTH;
475 } else if (m_pImageObject->m_pImage->IsInterpol()) {
476 m_Flags |= FXDIB_INTERPOL;
477 }
478 #endif
479 if (m_Loader.m_pMask) {
480 return DrawMaskedImage();
481 }
482 if (m_bPatternColor) {
483 return DrawPatternImage(m_pObj2Device);
484 }
485 #if !defined(_FPDFAPI_MINI_) || defined(_FXCORE_FEATURE_ALL_)
486 if (m_BitmapAlpha == 255 && pGeneralState && pGeneralState->m_FillOP &&
487 pGeneralState->m_OPMode == 0 && pGeneralState->m_BlendType == FXDIB_BLEND_NORMAL && pGeneralState->m_StrokeAlpha == 1 && pGeneralState->m_FillAlpha == 1) {
488 CPDF_Document* pDocument = NULL;
489 CPDF_Page* pPage = NULL;
490 if (m_pRenderStatus->m_pContext->m_pPageCache) {
491 pPage = m_pRenderStatus->m_pContext->m_pPageCache->GetPage();
492 pDocument = pPage->m_pDocument;
493 } else {
494 pDocument = m_pImageObject->m_pImage->GetDocument();
495 }
496 CPDF_Dictionary* pPageResources = pPage ? pPage->m_pPageResources : NULL;
497 CPDF_Object* pCSObj = m_pImageObject->m_pImage->GetStream()->GetDict()->GetElementValue(FX_BSTRC("ColorSpace"));
498 CPDF_ColorSpace* pColorSpace = pDocument->LoadColorSpace(pCSObj, pPageResources);
499 if (pColorSpace) {
500 int format = pColorSpace->GetFamily();
501 if (format == PDFCS_DEVICECMYK || format == PDFCS_SEPARATION || format == PDFCS_DEVICEN) {
502 m_BlendType = FXDIB_BLEND_DARKEN;
503 }
504 pDocument->GetPageData()->ReleaseColorSpace(pCSObj);
505 }
506 }
507 #endif
508 return StartDIBSource();
509 }
Start(CPDF_RenderStatus * pStatus,const CPDF_PageObject * pObj,const CFX_AffineMatrix * pObj2Device,FX_BOOL bStdCS,int blendType)510 FX_BOOL CPDF_ImageRenderer::Start(CPDF_RenderStatus* pStatus, const CPDF_PageObject* pObj, const CFX_AffineMatrix* pObj2Device, FX_BOOL bStdCS, int blendType)
511 {
512 m_pRenderStatus = pStatus;
513 m_bStdCS = bStdCS;
514 m_pImageObject = (CPDF_ImageObject*)pObj;
515 m_BlendType = blendType;
516 m_pObj2Device = pObj2Device;
517 #ifndef _FPDFAPI_MINI_
518 CPDF_Dictionary* pOC = m_pImageObject->m_pImage->GetOC();
519 if (pOC && m_pRenderStatus->m_Options.m_pOCContext && !m_pRenderStatus->m_Options.m_pOCContext->CheckOCGVisible(pOC)) {
520 return FALSE;
521 }
522 #endif
523 m_ImageMatrix = m_pImageObject->m_Matrix;
524 m_ImageMatrix.Concat(*pObj2Device);
525 if (StartLoadDIBSource()) {
526 return TRUE;
527 }
528 return StartRenderDIBSource();
529 }
Start(CPDF_RenderStatus * pStatus,const CFX_DIBSource * pDIBSource,FX_ARGB bitmap_argb,int bitmap_alpha,const CFX_AffineMatrix * pImage2Device,FX_DWORD flags,FX_BOOL bStdCS,int blendType)530 FX_BOOL CPDF_ImageRenderer::Start(CPDF_RenderStatus* pStatus, const CFX_DIBSource* pDIBSource, FX_ARGB bitmap_argb,
531 int bitmap_alpha, const CFX_AffineMatrix* pImage2Device, FX_DWORD flags, FX_BOOL bStdCS, int blendType)
532 {
533 m_pRenderStatus = pStatus;
534 m_pDIBSource = pDIBSource;
535 m_FillArgb = bitmap_argb;
536 m_BitmapAlpha = bitmap_alpha;
537 m_ImageMatrix = *pImage2Device;
538 m_Flags = flags;
539 m_bStdCS = bStdCS;
540 m_BlendType = blendType;
541 return StartDIBSource();
542 }
DrawPatternImage(const CFX_Matrix * pObj2Device)543 FX_BOOL CPDF_ImageRenderer::DrawPatternImage(const CFX_Matrix* pObj2Device)
544 {
545 if (m_pRenderStatus->m_bPrint && !(m_pRenderStatus->m_pDevice->GetRenderCaps() & FXRC_BLEND_MODE)) {
546 m_Result = FALSE;
547 return FALSE;
548 }
549 FX_RECT rect = m_ImageMatrix.GetUnitRect().GetOutterRect();
550 rect.Intersect(m_pRenderStatus->m_pDevice->GetClipBox());
551 if (rect.IsEmpty()) {
552 return FALSE;
553 }
554 CFX_AffineMatrix new_matrix = m_ImageMatrix;
555 new_matrix.TranslateI(-rect.left, -rect.top);
556 int width = rect.Width();
557 int height = rect.Height();
558 CFX_FxgeDevice bitmap_device1;
559 if (!bitmap_device1.Create(rect.Width(), rect.Height(), FXDIB_Rgb32)) {
560 return TRUE;
561 }
562 bitmap_device1.GetBitmap()->Clear(0xffffff);
563 {
564 CPDF_RenderStatus bitmap_render;
565 bitmap_render.Initialize(m_pRenderStatus->m_Level + 1, m_pRenderStatus->m_pContext, &bitmap_device1, NULL, NULL,
566 NULL, NULL, &m_pRenderStatus->m_Options, 0, m_pRenderStatus->m_bDropObjects, NULL, TRUE);
567 CFX_Matrix patternDevice = *pObj2Device;
568 patternDevice.Translate((FX_FLOAT) - rect.left, (FX_FLOAT) - rect.top);
569 if(m_pPattern->m_PatternType == PATTERN_TILING) {
570 bitmap_render.DrawTilingPattern((CPDF_TilingPattern*)m_pPattern, m_pImageObject, &patternDevice, FALSE);
571 } else {
572 bitmap_render.DrawShadingPattern((CPDF_ShadingPattern*)m_pPattern, m_pImageObject, &patternDevice, FALSE);
573 }
574 }
575 {
576 CFX_FxgeDevice bitmap_device2;
577 if (!bitmap_device2.Create(rect.Width(), rect.Height(), FXDIB_8bppRgb)) {
578 return TRUE;
579 }
580 bitmap_device2.GetBitmap()->Clear(0);
581 CPDF_RenderStatus bitmap_render;
582 bitmap_render.Initialize(m_pRenderStatus->m_Level + 1, m_pRenderStatus->m_pContext, &bitmap_device2, NULL, NULL,
583 NULL, NULL, NULL, 0, m_pRenderStatus->m_bDropObjects, NULL, TRUE);
584 CPDF_ImageRenderer image_render;
585 if (image_render.Start(&bitmap_render, m_pDIBSource, 0xffffffff, 255, &new_matrix, m_Flags, TRUE)) {
586 image_render.Continue(NULL);
587 }
588 if (m_Loader.m_MatteColor != 0xffffffff) {
589 int matte_r = FXARGB_R(m_Loader.m_MatteColor);
590 int matte_g = FXARGB_G(m_Loader.m_MatteColor);
591 int matte_b = FXARGB_B(m_Loader.m_MatteColor);
592 for (int row = 0; row < height; row ++) {
593 FX_LPBYTE dest_scan = (FX_LPBYTE)bitmap_device1.GetBitmap()->GetScanline(row);
594 FX_LPCBYTE mask_scan = bitmap_device2.GetBitmap()->GetScanline(row);
595 for (int col = 0; col < width; col ++) {
596 int alpha = *mask_scan ++;
597 if (alpha) {
598 int orig = (*dest_scan - matte_b) * 255 / alpha + matte_b;
599 if (orig < 0) {
600 orig = 0;
601 } else if (orig > 255) {
602 orig = 255;
603 }
604 *dest_scan++ = orig;
605 orig = (*dest_scan - matte_g) * 255 / alpha + matte_g;
606 if (orig < 0) {
607 orig = 0;
608 } else if (orig > 255) {
609 orig = 255;
610 }
611 *dest_scan++ = orig;
612 orig = (*dest_scan - matte_r) * 255 / alpha + matte_r;
613 if (orig < 0) {
614 orig = 0;
615 } else if (orig > 255) {
616 orig = 255;
617 }
618 *dest_scan++ = orig;
619 dest_scan ++;
620 } else {
621 dest_scan += 4;
622 }
623 }
624 }
625 }
626 bitmap_device2.GetBitmap()->ConvertFormat(FXDIB_8bppMask);
627 bitmap_device1.GetBitmap()->MultiplyAlpha(bitmap_device2.GetBitmap());
628 bitmap_device1.GetBitmap()->MultiplyAlpha(255);
629 }
630 m_pRenderStatus->m_pDevice->SetDIBits(bitmap_device1.GetBitmap(), rect.left, rect.top, m_BlendType);
631 return FALSE;
632 }
DrawMaskedImage()633 FX_BOOL CPDF_ImageRenderer::DrawMaskedImage()
634 {
635 if (m_pRenderStatus->m_bPrint && !(m_pRenderStatus->m_pDevice->GetRenderCaps() & FXRC_BLEND_MODE)) {
636 m_Result = FALSE;
637 return FALSE;
638 }
639 FX_RECT rect = m_ImageMatrix.GetUnitRect().GetOutterRect();
640 rect.Intersect(m_pRenderStatus->m_pDevice->GetClipBox());
641 if (rect.IsEmpty()) {
642 return FALSE;
643 }
644 CFX_AffineMatrix new_matrix = m_ImageMatrix;
645 new_matrix.TranslateI(-rect.left, -rect.top);
646 int width = rect.Width();
647 int height = rect.Height();
648 CFX_FxgeDevice bitmap_device1;
649 if (!bitmap_device1.Create(width, height, FXDIB_Rgb32)) {
650 return TRUE;
651 }
652 bitmap_device1.GetBitmap()->Clear(0xffffff);
653 {
654 CPDF_RenderStatus bitmap_render;
655 bitmap_render.Initialize(m_pRenderStatus->m_Level + 1, m_pRenderStatus->m_pContext, &bitmap_device1, NULL, NULL,
656 NULL, NULL, NULL, 0, m_pRenderStatus->m_bDropObjects, NULL, TRUE);
657 CPDF_ImageRenderer image_render;
658 if (image_render.Start(&bitmap_render, m_pDIBSource, 0, 255, &new_matrix, m_Flags, TRUE)) {
659 image_render.Continue(NULL);
660 }
661 }
662 {
663 CFX_FxgeDevice bitmap_device2;
664 if (!bitmap_device2.Create(width, height, FXDIB_8bppRgb)) {
665 return TRUE;
666 }
667 bitmap_device2.GetBitmap()->Clear(0);
668 CPDF_RenderStatus bitmap_render;
669 bitmap_render.Initialize(m_pRenderStatus->m_Level + 1, m_pRenderStatus->m_pContext, &bitmap_device2, NULL, NULL,
670 NULL, NULL, NULL, 0, m_pRenderStatus->m_bDropObjects, NULL, TRUE);
671 CPDF_ImageRenderer image_render;
672 if (image_render.Start(&bitmap_render, m_Loader.m_pMask, 0xffffffff, 255, &new_matrix, m_Flags, TRUE)) {
673 image_render.Continue(NULL);
674 }
675 if (m_Loader.m_MatteColor != 0xffffffff) {
676 int matte_r = FXARGB_R(m_Loader.m_MatteColor);
677 int matte_g = FXARGB_G(m_Loader.m_MatteColor);
678 int matte_b = FXARGB_B(m_Loader.m_MatteColor);
679 for (int row = 0; row < height; row ++) {
680 FX_LPBYTE dest_scan = (FX_LPBYTE)bitmap_device1.GetBitmap()->GetScanline(row);
681 FX_LPCBYTE mask_scan = bitmap_device2.GetBitmap()->GetScanline(row);
682 for (int col = 0; col < width; col ++) {
683 int alpha = *mask_scan ++;
684 if (alpha) {
685 int orig = (*dest_scan - matte_b) * 255 / alpha + matte_b;
686 if (orig < 0) {
687 orig = 0;
688 } else if (orig > 255) {
689 orig = 255;
690 }
691 *dest_scan++ = orig;
692 orig = (*dest_scan - matte_g) * 255 / alpha + matte_g;
693 if (orig < 0) {
694 orig = 0;
695 } else if (orig > 255) {
696 orig = 255;
697 }
698 *dest_scan++ = orig;
699 orig = (*dest_scan - matte_r) * 255 / alpha + matte_r;
700 if (orig < 0) {
701 orig = 0;
702 } else if (orig > 255) {
703 orig = 255;
704 }
705 *dest_scan++ = orig;
706 dest_scan ++;
707 } else {
708 dest_scan += 4;
709 }
710 }
711 }
712 }
713 bitmap_device2.GetBitmap()->ConvertFormat(FXDIB_8bppMask);
714 bitmap_device1.GetBitmap()->MultiplyAlpha(bitmap_device2.GetBitmap());
715 if (m_BitmapAlpha < 255) {
716 bitmap_device1.GetBitmap()->MultiplyAlpha(m_BitmapAlpha);
717 }
718 }
719 m_pRenderStatus->m_pDevice->SetDIBits(bitmap_device1.GetBitmap(), rect.left, rect.top, m_BlendType);
720 return FALSE;
721 }
StartDIBSource()722 FX_BOOL CPDF_ImageRenderer::StartDIBSource()
723 {
724 #if !defined(_FPDFAPI_MINI_)
725 if (!(m_Flags & RENDER_FORCE_DOWNSAMPLE) && m_pDIBSource->GetBPP() > 1) {
726 int image_size = m_pDIBSource->GetBPP() / 8 * m_pDIBSource->GetWidth() * m_pDIBSource->GetHeight();
727 if (image_size > FPDF_HUGE_IMAGE_SIZE && !(m_Flags & RENDER_FORCE_HALFTONE)) {
728 m_Flags |= RENDER_FORCE_DOWNSAMPLE;
729 }
730 }
731 #endif
732 if (m_pRenderStatus->m_pDevice->StartDIBits(m_pDIBSource, m_BitmapAlpha, m_FillArgb,
733 &m_ImageMatrix, m_Flags, m_DeviceHandle, 0, NULL, m_BlendType)) {
734 if (m_DeviceHandle != NULL) {
735 m_Status = 3;
736 return TRUE;
737 }
738 return FALSE;
739 }
740 #if !defined(_FPDFAPI_MINI_) || defined(_FXCORE_FEATURE_ALL_)
741 CFX_FloatRect image_rect_f = m_ImageMatrix.GetUnitRect();
742 FX_RECT image_rect = image_rect_f.GetOutterRect();
743 int dest_width = image_rect.Width();
744 int dest_height = image_rect.Height();
745 if ((FXSYS_fabs(m_ImageMatrix.b) >= 0.5f || m_ImageMatrix.a == 0) ||
746 (FXSYS_fabs(m_ImageMatrix.c) >= 0.5f || m_ImageMatrix.d == 0) ) {
747 if (m_pRenderStatus->m_bPrint && !(m_pRenderStatus->m_pDevice->GetRenderCaps() & FXRC_BLEND_MODE)) {
748 m_Result = FALSE;
749 return FALSE;
750 }
751 FX_RECT clip_box = m_pRenderStatus->m_pDevice->GetClipBox();
752 clip_box.Intersect(image_rect);
753 m_Status = 2;
754 m_pTransformer = FX_NEW CFX_ImageTransformer;
755 m_pTransformer->Start(m_pDIBSource, &m_ImageMatrix, m_Flags, &clip_box);
756 return TRUE;
757 }
758 if (m_ImageMatrix.a < 0) {
759 dest_width = -dest_width;
760 }
761 if (m_ImageMatrix.d > 0) {
762 dest_height = -dest_height;
763 }
764 int dest_left, dest_top;
765 dest_left = dest_width > 0 ? image_rect.left : image_rect.right;
766 dest_top = dest_height > 0 ? image_rect.top : image_rect.bottom;
767 if (m_pDIBSource->IsOpaqueImage() && m_BitmapAlpha == 255) {
768 if (m_pRenderStatus->m_pDevice->StretchDIBits(m_pDIBSource, dest_left, dest_top,
769 dest_width, dest_height, m_Flags, NULL, m_BlendType)) {
770 return FALSE;
771 }
772 }
773 if (m_pDIBSource->IsAlphaMask()) {
774 if (m_BitmapAlpha != 255) {
775 m_FillArgb = FXARGB_MUL_ALPHA(m_FillArgb, m_BitmapAlpha);
776 }
777 if (m_pRenderStatus->m_pDevice->StretchBitMask(m_pDIBSource, dest_left, dest_top, dest_width, dest_height, m_FillArgb, m_Flags)) {
778 return FALSE;
779 }
780 }
781 if (m_pRenderStatus->m_bPrint && !(m_pRenderStatus->m_pDevice->GetRenderCaps() & FXRC_BLEND_MODE)) {
782 m_Result = FALSE;
783 return TRUE;
784 }
785 FX_RECT clip_box = m_pRenderStatus->m_pDevice->GetClipBox();
786 FX_RECT dest_rect = clip_box;
787 dest_rect.Intersect(image_rect);
788 FX_RECT dest_clip(dest_rect.left - image_rect.left, dest_rect.top - image_rect.top,
789 dest_rect.right - image_rect.left, dest_rect.bottom - image_rect.top);
790 CFX_DIBitmap* pStretched = m_pDIBSource->StretchTo(dest_width, dest_height, m_Flags, &dest_clip);
791 if (pStretched) {
792 m_pRenderStatus->CompositeDIBitmap(pStretched, dest_rect.left, dest_rect.top, m_FillArgb,
793 m_BitmapAlpha, m_BlendType, FALSE);
794 delete pStretched;
795 pStretched = NULL;
796 }
797 #endif
798 return FALSE;
799 }
StartBitmapAlpha()800 FX_BOOL CPDF_ImageRenderer::StartBitmapAlpha()
801 {
802 #ifndef _FPDFAPI_MINI_
803 if (m_pDIBSource->IsOpaqueImage()) {
804 CFX_PathData path;
805 path.AppendRect(0, 0, 1, 1);
806 path.Transform(&m_ImageMatrix);
807 FX_DWORD fill_color = ArgbEncode(0xff, m_BitmapAlpha, m_BitmapAlpha, m_BitmapAlpha);
808 m_pRenderStatus->m_pDevice->DrawPath(&path, NULL, NULL, fill_color, 0, FXFILL_WINDING);
809 } else {
810 const CFX_DIBSource* pAlphaMask = m_pDIBSource->IsAlphaMask() ? m_pDIBSource : m_pDIBSource->GetAlphaMask();
811 if (FXSYS_fabs(m_ImageMatrix.b) >= 0.5f || FXSYS_fabs(m_ImageMatrix.c) >= 0.5f) {
812 int left, top;
813 CFX_DIBitmap* pTransformed = pAlphaMask->TransformTo(&m_ImageMatrix, left, top);
814 if (pTransformed == NULL) {
815 return TRUE;
816 }
817 m_pRenderStatus->m_pDevice->SetBitMask(pTransformed, left, top, ArgbEncode(0xff, m_BitmapAlpha, m_BitmapAlpha, m_BitmapAlpha));
818 delete pTransformed;
819 } else {
820 CFX_FloatRect image_rect_f = m_ImageMatrix.GetUnitRect();
821 FX_RECT image_rect = image_rect_f.GetOutterRect();
822 int dest_width = m_ImageMatrix.a > 0 ? image_rect.Width() : -image_rect.Width();
823 int dest_height = m_ImageMatrix.d > 0 ? -image_rect.Height() : image_rect.Height();
824 int left = dest_width > 0 ? image_rect.left : image_rect.right;
825 int top = dest_height > 0 ? image_rect.top : image_rect.bottom;
826 m_pRenderStatus->m_pDevice->StretchBitMask(pAlphaMask, left, top, dest_width, dest_height,
827 ArgbEncode(0xff, m_BitmapAlpha, m_BitmapAlpha, m_BitmapAlpha));
828 }
829 if (m_pDIBSource != pAlphaMask) {
830 delete pAlphaMask;
831 }
832 }
833 #endif
834 return FALSE;
835 }
Continue(IFX_Pause * pPause)836 FX_BOOL CPDF_ImageRenderer::Continue(IFX_Pause* pPause)
837 {
838 if (m_Status == 1) {
839 #ifndef _FPDFAPI_MINI_
840 if (m_pQuickStretcher->Continue(pPause)) {
841 return TRUE;
842 }
843 if (m_pQuickStretcher->m_pBitmap->IsAlphaMask())
844 m_pRenderStatus->m_pDevice->SetBitMask(m_pQuickStretcher->m_pBitmap, m_pQuickStretcher->m_ResultLeft,
845 m_pQuickStretcher->m_ResultTop, m_FillArgb);
846 else
847 m_pRenderStatus->m_pDevice->SetDIBits(m_pQuickStretcher->m_pBitmap, m_pQuickStretcher->m_ResultLeft,
848 m_pQuickStretcher->m_ResultTop, m_BlendType);
849 return FALSE;
850 #endif
851 } else if (m_Status == 2) {
852 #if !defined(_FPDFAPI_MINI_) || defined(_FXCORE_FEATURE_ALL_)
853 if (m_pTransformer->Continue(pPause)) {
854 return TRUE;
855 }
856 CFX_DIBitmap* pBitmap = m_pTransformer->m_Storer.Detach();
857 if (pBitmap == NULL) {
858 return FALSE;
859 }
860 if (pBitmap->IsAlphaMask()) {
861 if (m_BitmapAlpha != 255) {
862 m_FillArgb = FXARGB_MUL_ALPHA(m_FillArgb, m_BitmapAlpha);
863 }
864 m_Result = m_pRenderStatus->m_pDevice->SetBitMask(pBitmap,
865 m_pTransformer->m_ResultLeft, m_pTransformer->m_ResultTop, m_FillArgb);
866 } else {
867 if (m_BitmapAlpha != 255) {
868 pBitmap->MultiplyAlpha(m_BitmapAlpha);
869 }
870 m_Result = m_pRenderStatus->m_pDevice->SetDIBits(pBitmap,
871 m_pTransformer->m_ResultLeft, m_pTransformer->m_ResultTop, m_BlendType);
872 }
873 delete pBitmap;
874 return FALSE;
875 #endif
876 } else if (m_Status == 3) {
877 return m_pRenderStatus->m_pDevice->ContinueDIBits(m_DeviceHandle, pPause);
878 } else if (m_Status == 4) {
879 if (m_Loader.Continue(m_LoadHandle, pPause)) {
880 return TRUE;
881 }
882 if (StartRenderDIBSource()) {
883 return Continue(pPause);
884 }
885 return FALSE;
886 }
887 return FALSE;
888 }
CPDF_QuickStretcher()889 CPDF_QuickStretcher::CPDF_QuickStretcher()
890 {
891 m_pBitmap = NULL;
892 m_pDecoder = NULL;
893 m_pCS = NULL;
894 }
~CPDF_QuickStretcher()895 CPDF_QuickStretcher::~CPDF_QuickStretcher()
896 {
897 if (m_pBitmap) {
898 delete m_pBitmap;
899 }
900 if (m_pCS) {
901 m_pCS->ReleaseCS();
902 }
903 if (m_pDecoder) {
904 delete m_pDecoder;
905 }
906 }
907 ICodec_ScanlineDecoder* FPDFAPI_CreateFlateDecoder(FX_LPCBYTE src_buf, FX_DWORD src_size, int width, int height,
908 int nComps, int bpc, const CPDF_Dictionary* pParams);
Start(CPDF_ImageObject * pImageObj,CFX_AffineMatrix * pImage2Device,const FX_RECT * pClipBox)909 FX_BOOL CPDF_QuickStretcher::Start(CPDF_ImageObject* pImageObj, CFX_AffineMatrix* pImage2Device, const FX_RECT* pClipBox)
910 {
911 if (FXSYS_fabs(pImage2Device->a) < FXSYS_fabs(pImage2Device->b) * 10 && FXSYS_fabs(pImage2Device->d) < FXSYS_fabs(pImage2Device->c) * 10) {
912 return FALSE;
913 }
914 CFX_FloatRect image_rect_f = pImage2Device->GetUnitRect();
915 FX_RECT image_rect = image_rect_f.GetOutterRect();
916 m_DestWidth = image_rect.Width();
917 m_DestHeight = image_rect.Height();
918 m_bFlipX = pImage2Device->a < 0;
919 m_bFlipY = pImage2Device->d > 0;
920 FX_RECT result_rect = *pClipBox;
921 result_rect.Intersect(image_rect);
922 if (result_rect.IsEmpty()) {
923 return FALSE;
924 }
925 m_ResultWidth = result_rect.Width();
926 m_ResultHeight = result_rect.Height();
927 m_ResultLeft = result_rect.left;
928 m_ResultTop = result_rect.top;
929 m_ClipLeft = result_rect.left - image_rect.left;
930 m_ClipTop = result_rect.top - image_rect.top;
931 CPDF_Dictionary* pDict = pImageObj->m_pImage->GetDict();
932 if (pDict->GetInteger(FX_BSTRC("BitsPerComponent")) != 8) {
933 return FALSE;
934 }
935 if (pDict->KeyExist(FX_BSTRC("SMask")) || pDict->KeyExist(FX_BSTRC("Mask"))) {
936 return FALSE;
937 }
938 m_SrcWidth = pDict->GetInteger(FX_BSTRC("Width"));
939 m_SrcHeight = pDict->GetInteger(FX_BSTRC("Height"));
940 m_pCS = NULL;
941 m_Bpp = 3;
942 CPDF_Object* pCSObj = pDict->GetElementValue(FX_BSTRC("ColorSpace"));
943 if (pCSObj == NULL) {
944 return FALSE;
945 }
946 m_pCS = CPDF_ColorSpace::Load(pImageObj->m_pImage->GetDocument(), pCSObj);
947 if (m_pCS == NULL) {
948 return FALSE;
949 }
950 if (!_IsSupported(m_pCS)) {
951 return FALSE;
952 }
953 m_Bpp = m_pCS->CountComponents();
954 if (m_pCS->sRGB()) {
955 m_pCS->ReleaseCS();
956 m_pCS = NULL;
957 }
958 CPDF_Stream* pStream = pImageObj->m_pImage->GetStream();
959 m_StreamAcc.LoadAllData(pStream, FALSE, m_SrcWidth * m_SrcHeight * m_Bpp, TRUE);
960 m_pDecoder = NULL;
961 if (!m_StreamAcc.GetImageDecoder().IsEmpty()) {
962 if (m_StreamAcc.GetImageDecoder() == FX_BSTRC("DCTDecode")) {
963 const CPDF_Dictionary* pParam = m_StreamAcc.GetImageParam();
964 m_pDecoder = CPDF_ModuleMgr::Get()->GetJpegModule()->CreateDecoder(
965 m_StreamAcc.GetData(), m_StreamAcc.GetSize(), m_SrcWidth, m_SrcHeight, m_Bpp,
966 pParam ? pParam->GetInteger(FX_BSTRC("ColorTransform"), 1) : 1);
967 } else if (m_StreamAcc.GetImageDecoder() == FX_BSTRC("FlateDecode")) {
968 m_pDecoder = FPDFAPI_CreateFlateDecoder(
969 m_StreamAcc.GetData(), m_StreamAcc.GetSize(), m_SrcWidth, m_SrcHeight, m_Bpp, 8,
970 m_StreamAcc.GetImageParam());
971 } else {
972 return FALSE;
973 }
974 m_pDecoder->DownScale(m_DestWidth, m_DestHeight);
975 }
976 m_pBitmap = FX_NEW CFX_DIBitmap;
977 #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
978 m_pBitmap->Create(m_ResultWidth, m_ResultHeight, FXDIB_Rgb32);
979 #else
980 m_pBitmap->Create(m_ResultWidth, m_ResultHeight, FXDIB_Rgb);
981 #endif
982 m_LineIndex = 0;
983 return TRUE;
984 }
Continue(IFX_Pause * pPause)985 FX_BOOL CPDF_QuickStretcher::Continue(IFX_Pause* pPause)
986 {
987 FX_LPBYTE result_buf = m_pBitmap->GetBuffer();
988 int src_width = m_pDecoder ? m_pDecoder->GetWidth() : m_SrcWidth;
989 int src_height = m_pDecoder ? m_pDecoder->GetHeight() : m_SrcHeight;
990 int src_pitch = src_width * m_Bpp;
991 while (m_LineIndex < m_ResultHeight) {
992 int dest_y, src_y;
993 if (m_bFlipY) {
994 dest_y = m_ResultHeight - m_LineIndex - 1;
995 src_y = (m_DestHeight - (dest_y + m_ClipTop) - 1) * src_height / m_DestHeight;
996 } else {
997 dest_y = m_LineIndex;
998 src_y = (dest_y + m_ClipTop) * src_height / m_DestHeight;
999 }
1000 FX_LPCBYTE src_scan;
1001 if (m_pDecoder) {
1002 src_scan = m_pDecoder->GetScanline(src_y);
1003 if (src_scan == NULL) {
1004 break;
1005 }
1006 } else {
1007 src_scan = m_StreamAcc.GetData();
1008 if (src_scan == NULL) {
1009 break;
1010 }
1011 src_scan += src_y * src_pitch;
1012 }
1013 FX_LPBYTE result_scan = result_buf + dest_y * m_pBitmap->GetPitch();
1014 for (int x = 0; x < m_ResultWidth; x ++) {
1015 int dest_x = m_ClipLeft + x;
1016 int src_x = (m_bFlipX ? (m_DestWidth - dest_x - 1) : dest_x) * src_width / m_DestWidth;
1017 FX_LPCBYTE src_pixel = src_scan + src_x * m_Bpp;
1018 if (m_pCS == NULL) {
1019 *result_scan = src_pixel[2];
1020 result_scan ++;
1021 *result_scan = src_pixel[1];
1022 result_scan ++;
1023 *result_scan = src_pixel[0];
1024 result_scan ++;
1025 #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
1026 result_scan ++;
1027 #endif
1028 } else {
1029 m_pCS->TranslateImageLine(result_scan, src_pixel, 1, 0, 0);
1030 #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
1031 result_scan += 4;
1032 #else
1033 result_scan += 3;
1034 #endif
1035 }
1036 }
1037 m_LineIndex ++;
1038 if (pPause && pPause->NeedToPauseNow()) {
1039 return TRUE;
1040 }
1041 }
1042 return FALSE;
1043 }
LoadSMask(CPDF_Dictionary * pSMaskDict,FX_RECT * pClipRect,const CFX_AffineMatrix * pMatrix)1044 CFX_DIBitmap* CPDF_RenderStatus::LoadSMask(CPDF_Dictionary* pSMaskDict,
1045 FX_RECT* pClipRect, const CFX_AffineMatrix* pMatrix)
1046 {
1047 if (pSMaskDict == NULL) {
1048 return NULL;
1049 }
1050 CFX_DIBitmap* pMask = NULL;
1051 int width = pClipRect->right - pClipRect->left;
1052 int height = pClipRect->bottom - pClipRect->top;
1053 FX_BOOL bLuminosity = FALSE;
1054 bLuminosity = pSMaskDict->GetConstString(FX_BSTRC("S")) != FX_BSTRC("Alpha");
1055 CPDF_Stream* pGroup = pSMaskDict->GetStream(FX_BSTRC("G"));
1056 if (pGroup == NULL) {
1057 return NULL;
1058 }
1059 CPDF_Function* pFunc = NULL;
1060 CPDF_Object* pFuncObj = pSMaskDict->GetElementValue(FX_BSTRC("TR"));
1061 if (pFuncObj && (pFuncObj->GetType() == PDFOBJ_DICTIONARY || pFuncObj->GetType() == PDFOBJ_STREAM)) {
1062 pFunc = CPDF_Function::Load(pFuncObj);
1063 }
1064 CFX_AffineMatrix matrix = *pMatrix;
1065 matrix.TranslateI(-pClipRect->left, -pClipRect->top);
1066 CPDF_Form form(m_pContext->m_pDocument, m_pContext->m_pPageResources, pGroup);
1067 form.ParseContent(NULL, NULL, NULL, NULL);
1068 CFX_FxgeDevice bitmap_device;
1069 #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
1070 if (!bitmap_device.Create(width, height, bLuminosity ? FXDIB_Rgb32 : FXDIB_8bppMask)) {
1071 return NULL;
1072 }
1073 #else
1074 if (!bitmap_device.Create(width, height, bLuminosity ? FXDIB_Rgb : FXDIB_8bppMask)) {
1075 return NULL;
1076 }
1077 #endif
1078 CFX_DIBitmap& bitmap = *bitmap_device.GetBitmap();
1079 CPDF_Object* pCSObj = NULL;
1080 CPDF_ColorSpace* pCS = NULL;
1081 if (bLuminosity) {
1082 CPDF_Array* pBC = pSMaskDict->GetArray(FX_BSTRC("BC"));
1083 FX_ARGB back_color = 0xff000000;
1084 if (pBC) {
1085 pCSObj = pGroup->GetDict()->GetDict(FX_BSTRC("Group"))->GetElementValue(FX_BSTRC("CS"));
1086 pCS = m_pContext->m_pDocument->LoadColorSpace(pCSObj);
1087 if (pCS) {
1088 FX_FLOAT R, G, B;
1089 FX_DWORD num_floats = 8;
1090 if (pCS->CountComponents() > (FX_INT32)num_floats) {
1091 num_floats = (FX_DWORD)pCS->CountComponents();
1092 }
1093 CFX_FixedBufGrow<FX_FLOAT, 8> float_array(num_floats);
1094 FX_FLOAT* pFloats = float_array;
1095 FXSYS_memset32(pFloats, 0, num_floats * sizeof(FX_FLOAT));
1096 int count = pBC->GetCount() > 8 ? 8 : pBC->GetCount();
1097 for (int i = 0; i < count; i ++) {
1098 pFloats[i] = pBC->GetNumber(i);
1099 }
1100 pCS->GetRGB(pFloats, R, G, B);
1101 back_color = 0xff000000 | ((FX_INT32)(R * 255) << 16) | ((FX_INT32)(G * 255) << 8) | (FX_INT32)(B * 255);
1102 m_pContext->m_pDocument->GetPageData()->ReleaseColorSpace(pCSObj);
1103 }
1104 }
1105 bitmap.Clear(back_color);
1106 } else {
1107 bitmap.Clear(0);
1108 }
1109 CPDF_Dictionary* pFormResource = NULL;
1110 if (form.m_pFormDict) {
1111 pFormResource = form.m_pFormDict->GetDict(FX_BSTRC("Resources"));
1112 }
1113 CPDF_RenderOptions options;
1114 options.m_ColorMode = bLuminosity ? RENDER_COLOR_NORMAL : RENDER_COLOR_ALPHA;
1115 CPDF_RenderStatus status;
1116 status.Initialize(m_Level + 1, m_pContext, &bitmap_device, NULL, NULL, NULL, NULL,
1117 &options, 0, m_bDropObjects, pFormResource, TRUE, NULL, 0, pCS ? pCS->GetFamily() : 0, bLuminosity);
1118 status.RenderObjectList(&form, &matrix);
1119 pMask = FX_NEW CFX_DIBitmap;
1120 if (!pMask->Create(width, height, FXDIB_8bppMask)) {
1121 delete pMask;
1122 return NULL;
1123 }
1124 FX_LPBYTE dest_buf = pMask->GetBuffer();
1125 int dest_pitch = pMask->GetPitch();
1126 FX_LPBYTE src_buf = bitmap.GetBuffer();
1127 int src_pitch = bitmap.GetPitch();
1128 FX_LPBYTE pTransfer = FX_Alloc(FX_BYTE, 256);
1129 if (pFunc) {
1130 CFX_FixedBufGrow<FX_FLOAT, 16> results(pFunc->CountOutputs());
1131 for (int i = 0; i < 256; i ++) {
1132 FX_FLOAT input = (FX_FLOAT)i / 255.0f;
1133 int nresult;
1134 pFunc->Call(&input, 1, results, nresult);
1135 pTransfer[i] = FXSYS_round(results[0] * 255);
1136 }
1137 } else {
1138 for (int i = 0; i < 256; i ++) {
1139 pTransfer[i] = i;
1140 }
1141 }
1142 if (bLuminosity) {
1143 int Bpp = bitmap.GetBPP() / 8;
1144 for (int row = 0; row < height; row ++) {
1145 FX_LPBYTE dest_pos = dest_buf + row * dest_pitch;
1146 FX_LPBYTE src_pos = src_buf + row * src_pitch;
1147 for (int col = 0; col < width; col ++) {
1148 *dest_pos ++ = pTransfer[FXRGB2GRAY(src_pos[2], src_pos[1], *src_pos)];
1149 src_pos += Bpp;
1150 }
1151 }
1152 } else if (pFunc) {
1153 int size = dest_pitch * height;
1154 for (int i = 0; i < size; i ++) {
1155 dest_buf[i] = pTransfer[src_buf[i]];
1156 }
1157 } else {
1158 FXSYS_memcpy32(dest_buf, src_buf, dest_pitch * height);
1159 }
1160 if (pFunc) {
1161 delete pFunc;
1162 }
1163 FX_Free(pTransfer);
1164 return pMask;
1165 }
1166