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