Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(147)

Side by Side Diff: core/fpdfapi/fpdf_render/fpdf_render_image.cpp

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

Powered by Google App Engine
This is Rietveld 408576698