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