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