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