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 "../../../src/fxcrt/fx_safe_types.h" 13 #include "../fpdf_page/pageint.h" 14 #include "render_int.h" 15 16 namespace { 17 18 unsigned int _GetBits8(FX_LPCBYTE pData, int bitpos, int nbits) 19 { 20 unsigned int byte = pData[bitpos / 8]; 21 if (nbits == 8) { 22 return byte; 23 } else if (nbits == 4) { 24 return (bitpos % 8) ? (byte & 0x0f) : (byte >> 4); 25 } else if (nbits == 2) { 26 return (byte >> (6 - bitpos % 8)) & 0x03; 27 } else if (nbits == 1) { 28 return (byte >> (7 - bitpos % 8)) & 0x01; 29 } else if (nbits == 16) { 30 return byte * 256 + pData[bitpos / 8 + 1]; 31 } 32 return 0; 33 } 34 35 FX_SAFE_DWORD CalculatePitch8(FX_DWORD bpc, 36 FX_DWORD components, 37 int width, 38 int height) 39 { 40 FX_SAFE_DWORD pitch = bpc; 41 pitch *= components; 42 pitch *= width; 43 pitch += 7; 44 pitch /= 8; 45 pitch *= height; 46 return pitch; 47 } 48 49 FX_SAFE_DWORD CalculatePitch32(int bpp, int width) 50 { 51 FX_SAFE_DWORD pitch = bpp; 52 pitch *= width; 53 pitch += 31; 54 pitch /= 8; 55 return pitch; 56 } 57 58 } // namespace 59 60 CFX_DIBSource* CPDF_Image::LoadDIBSource(CFX_DIBSource** ppMask, FX_DWORD* pMatteColor, FX_BOOL bStdCS, FX_DWORD GroupFamily, FX_BOOL bLoadMask) const 61 { 62 CPDF_DIBSource* pSource = new CPDF_DIBSource; 63 if (pSource->Load(m_pDocument, m_pStream, (CPDF_DIBSource**)ppMask, pMatteColor, NULL, NULL, bStdCS, GroupFamily, bLoadMask)) { 64 return pSource; 65 } 66 delete pSource; 67 return NULL; 68 } 69 CFX_DIBSource* CPDF_Image::DetachBitmap() 70 { 71 CFX_DIBSource* pBitmap = m_pDIBSource; 72 m_pDIBSource = NULL; 73 return pBitmap; 74 } 75 CFX_DIBSource* CPDF_Image::DetachMask() 76 { 77 CFX_DIBSource* pBitmap = m_pMask; 78 m_pMask = NULL; 79 return pBitmap; 80 } 81 FX_BOOL CPDF_Image::StartLoadDIBSource(CPDF_Dictionary* pFormResource, CPDF_Dictionary* pPageResource, FX_BOOL bStdCS, FX_DWORD GroupFamily, FX_BOOL bLoadMask) 82 { 83 m_pDIBSource = new CPDF_DIBSource; 84 int ret = ((CPDF_DIBSource*)m_pDIBSource)->StartLoadDIBSource(m_pDocument, m_pStream, TRUE, pFormResource, pPageResource, bStdCS, GroupFamily, bLoadMask); 85 if (ret == 2) { 86 return TRUE; 87 } 88 if (!ret) { 89 delete m_pDIBSource; 90 m_pDIBSource = NULL; 91 return FALSE; 92 } 93 m_pMask = ((CPDF_DIBSource*)m_pDIBSource)->DetachMask(); 94 m_MatteColor = ((CPDF_DIBSource*)m_pDIBSource)->m_MatteColor; 95 return FALSE; 96 } 97 FX_BOOL CPDF_Image::Continue(IFX_Pause* pPause) 98 { 99 int ret = ((CPDF_DIBSource*)m_pDIBSource)->ContinueLoadDIBSource(pPause); 100 if (ret == 2) { 101 return TRUE; 102 } 103 if (!ret) { 104 delete m_pDIBSource; 105 m_pDIBSource = NULL; 106 return FALSE; 107 } 108 m_pMask = ((CPDF_DIBSource*)m_pDIBSource)->DetachMask(); 109 m_MatteColor = ((CPDF_DIBSource*)m_pDIBSource)->m_MatteColor; 110 return FALSE; 111 } 112 CPDF_DIBSource::CPDF_DIBSource() 113 { 114 m_pDocument = NULL; 115 m_pStreamAcc = NULL; 116 m_pDict = NULL; 117 m_bpp = 0; 118 m_Width = m_Height = 0; 119 m_pColorSpace = NULL; 120 m_bDefaultDecode = TRUE; 121 m_bImageMask = FALSE; 122 m_bDoBpcCheck = TRUE; 123 m_pPalette = NULL; 124 m_pCompData = NULL; 125 m_bColorKey = FALSE; 126 m_pMaskedLine = m_pLineBuf = NULL; 127 m_pCachedBitmap = NULL; 128 m_pDecoder = NULL; 129 m_nComponents = 0; 130 m_bpc = 0; 131 m_bLoadMask = FALSE; 132 m_Family = 0; 133 m_pMask = NULL; 134 m_MatteColor = 0; 135 m_pJbig2Context = NULL; 136 m_pGlobalStream = NULL; 137 m_bStdCS = FALSE; 138 m_pMaskStream = NULL; 139 m_Status = 0; 140 m_bHasMask = FALSE; 141 } 142 CPDF_DIBSource::~CPDF_DIBSource() 143 { 144 delete m_pStreamAcc; 145 if (m_pMaskedLine) { 146 FX_Free(m_pMaskedLine); 147 } 148 if (m_pLineBuf) { 149 FX_Free(m_pLineBuf); 150 } 151 delete m_pCachedBitmap; 152 delete m_pDecoder; 153 if (m_pCompData) { 154 FX_Free(m_pCompData); 155 } 156 CPDF_ColorSpace* pCS = m_pColorSpace; 157 if (pCS && m_pDocument) { 158 m_pDocument->GetPageData()->ReleaseColorSpace(pCS->GetArray()); 159 } 160 if (m_pJbig2Context) { 161 ICodec_Jbig2Module* pJbig2Module = CPDF_ModuleMgr::Get()->GetJbig2Module(); 162 pJbig2Module->DestroyJbig2Context(m_pJbig2Context); 163 } 164 delete m_pGlobalStream; 165 } 166 CFX_DIBitmap* CPDF_DIBSource::GetBitmap() const 167 { 168 if (m_pCachedBitmap) { 169 return m_pCachedBitmap; 170 } 171 return Clone(); 172 } 173 void CPDF_DIBSource::ReleaseBitmap(CFX_DIBitmap* pBitmap) const 174 { 175 if (pBitmap && pBitmap != m_pCachedBitmap) { 176 delete pBitmap; 177 } 178 } 179 FX_BOOL CPDF_DIBSource::Load(CPDF_Document* pDoc, const CPDF_Stream* pStream, CPDF_DIBSource** ppMask, 180 FX_DWORD* pMatteColor, CPDF_Dictionary* pFormResources, CPDF_Dictionary* pPageResources, FX_BOOL bStdCS, FX_DWORD GroupFamily, FX_BOOL bLoadMask) 181 { 182 if (pStream == NULL) { 183 return FALSE; 184 } 185 m_pDocument = pDoc; 186 m_pDict = pStream->GetDict(); 187 if (m_pDict == NULL) { 188 return FALSE; 189 } 190 m_pStream = pStream; 191 m_Width = m_pDict->GetInteger(FX_BSTRC("Width")); 192 m_Height = m_pDict->GetInteger(FX_BSTRC("Height")); 193 if (m_Width <= 0 || m_Height <= 0 || m_Width > 0x01ffff || m_Height > 0x01ffff) { 194 return FALSE; 195 } 196 m_GroupFamily = GroupFamily; 197 m_bLoadMask = bLoadMask; 198 if (!LoadColorInfo(m_pStream->GetObjNum() != 0 ? NULL : pFormResources, pPageResources)) { 199 return FALSE; 200 } 201 if (m_bDoBpcCheck && (m_bpc == 0 || m_nComponents == 0)) { 202 return FALSE; 203 } 204 FX_SAFE_DWORD src_pitch = 205 CalculatePitch8(m_bpc, m_nComponents, m_Width, m_Height); 206 if (!src_pitch.IsValid()) { 207 return FALSE; 208 } 209 m_pStreamAcc = new CPDF_StreamAcc; 210 m_pStreamAcc->LoadAllData(pStream, FALSE, src_pitch.ValueOrDie(), TRUE); 211 if (m_pStreamAcc->GetSize() == 0 || m_pStreamAcc->GetData() == NULL) { 212 return FALSE; 213 } 214 if (!CreateDecoder()) { 215 return FALSE; 216 } 217 if (m_bImageMask) { 218 m_bpp = 1; 219 m_bpc = 1; 220 m_nComponents = 1; 221 m_AlphaFlag = 1; 222 } else if (m_bpc * m_nComponents == 1) { 223 m_bpp = 1; 224 } else if (m_bpc * m_nComponents <= 8) { 225 m_bpp = 8; 226 } else { 227 m_bpp = 24; 228 } 229 FX_SAFE_DWORD pitch = CalculatePitch32(m_bpp, m_Width); 230 if (!pitch.IsValid()) { 231 return FALSE; 232 } 233 m_pLineBuf = FX_Alloc(FX_BYTE, pitch.ValueOrDie()); 234 if (m_pColorSpace && bStdCS) { 235 m_pColorSpace->EnableStdConversion(TRUE); 236 } 237 LoadPalette(); 238 if (m_bColorKey) { 239 m_bpp = 32; 240 m_AlphaFlag = 2; 241 pitch = CalculatePitch32(m_bpp, m_Width); 242 if (!pitch.IsValid()) { 243 return FALSE; 244 } 245 m_pMaskedLine = FX_Alloc(FX_BYTE, pitch.ValueOrDie()); 246 } 247 m_Pitch = pitch.ValueOrDie(); 248 if (ppMask) { 249 *ppMask = LoadMask(*pMatteColor); 250 } 251 if (m_pColorSpace && bStdCS) { 252 m_pColorSpace->EnableStdConversion(FALSE); 253 } 254 return TRUE; 255 } 256 int CPDF_DIBSource::ContinueToLoadMask() 257 { 258 if (m_bImageMask) { 259 m_bpp = 1; 260 m_bpc = 1; 261 m_nComponents = 1; 262 m_AlphaFlag = 1; 263 } else if (m_bpc * m_nComponents == 1) { 264 m_bpp = 1; 265 } else if (m_bpc * m_nComponents <= 8) { 266 m_bpp = 8; 267 } else { 268 m_bpp = 24; 269 } 270 if (!m_bpc || !m_nComponents) { 271 return 0; 272 } 273 FX_SAFE_DWORD pitch = CalculatePitch32(m_bpp, m_Width); 274 if (!pitch.IsValid()) { 275 return 0; 276 } 277 m_pLineBuf = FX_Alloc(FX_BYTE, pitch.ValueOrDie()); 278 if (m_pColorSpace && m_bStdCS) { 279 m_pColorSpace->EnableStdConversion(TRUE); 280 } 281 LoadPalette(); 282 if (m_bColorKey) { 283 m_bpp = 32; 284 m_AlphaFlag = 2; 285 pitch = CalculatePitch32(m_bpp, m_Width); 286 if (!pitch.IsValid()) { 287 return 0; 288 } 289 m_pMaskedLine = FX_Alloc(FX_BYTE, pitch.ValueOrDie()); 290 } 291 m_Pitch = pitch.ValueOrDie(); 292 return 1; 293 } 294 int CPDF_DIBSource::StartLoadDIBSource(CPDF_Document* pDoc, const CPDF_Stream* pStream, FX_BOOL bHasMask, 295 CPDF_Dictionary* pFormResources, CPDF_Dictionary* pPageResources, 296 FX_BOOL bStdCS, FX_DWORD GroupFamily, FX_BOOL bLoadMask) 297 { 298 if (pStream == NULL) { 299 return 0; 300 } 301 m_pDocument = pDoc; 302 m_pDict = pStream->GetDict(); 303 m_pStream = pStream; 304 m_bStdCS = bStdCS; 305 m_bHasMask = bHasMask; 306 m_Width = m_pDict->GetInteger(FX_BSTRC("Width")); 307 m_Height = m_pDict->GetInteger(FX_BSTRC("Height")); 308 if (m_Width <= 0 || m_Height <= 0 || m_Width > 0x01ffff || m_Height > 0x01ffff) { 309 return 0; 310 } 311 m_GroupFamily = GroupFamily; 312 m_bLoadMask = bLoadMask; 313 if (!LoadColorInfo(m_pStream->GetObjNum() != 0 ? NULL : pFormResources, pPageResources)) { 314 return 0; 315 } 316 if (m_bDoBpcCheck && (m_bpc == 0 || m_nComponents == 0)) { 317 return 0; 318 } 319 FX_SAFE_DWORD src_pitch = 320 CalculatePitch8(m_bpc, m_nComponents, m_Width, m_Height); 321 if (!src_pitch.IsValid()) { 322 return 0; 323 } 324 m_pStreamAcc = new CPDF_StreamAcc; 325 m_pStreamAcc->LoadAllData(pStream, FALSE, src_pitch.ValueOrDie(), TRUE); 326 if (m_pStreamAcc->GetSize() == 0 || m_pStreamAcc->GetData() == NULL) { 327 return 0; 328 } 329 int ret = CreateDecoder(); 330 if (ret != 1) { 331 if (!ret) { 332 return ret; 333 } 334 if (!ContinueToLoadMask()) { 335 return 0; 336 } 337 if (m_bHasMask) { 338 StratLoadMask(); 339 } 340 return ret; 341 } 342 if (!ContinueToLoadMask()) { 343 return 0; 344 } 345 if (m_bHasMask) { 346 ret = StratLoadMask(); 347 } 348 if (ret == 2) { 349 return ret; 350 } 351 if (m_pColorSpace && m_bStdCS) { 352 m_pColorSpace->EnableStdConversion(FALSE); 353 } 354 return ret; 355 } 356 int CPDF_DIBSource::ContinueLoadDIBSource(IFX_Pause* pPause) 357 { 358 FXCODEC_STATUS ret; 359 if (m_Status == 1) { 360 const CFX_ByteString& decoder = m_pStreamAcc->GetImageDecoder(); 361 if (decoder == FX_BSTRC("JPXDecode")) { 362 return 0; 363 } 364 ICodec_Jbig2Module* pJbig2Module = CPDF_ModuleMgr::Get()->GetJbig2Module(); 365 if (m_pJbig2Context == NULL) { 366 m_pJbig2Context = pJbig2Module->CreateJbig2Context(); 367 if (m_pStreamAcc->GetImageParam()) { 368 CPDF_Stream* pGlobals = m_pStreamAcc->GetImageParam()->GetStream(FX_BSTRC("JBIG2Globals")); 369 if (pGlobals) { 370 m_pGlobalStream = new CPDF_StreamAcc; 371 m_pGlobalStream->LoadAllData(pGlobals, FALSE); 372 } 373 } 374 ret = pJbig2Module->StartDecode(m_pJbig2Context, m_Width, m_Height, m_pStreamAcc->GetData(), m_pStreamAcc->GetSize(), 375 m_pGlobalStream ? m_pGlobalStream->GetData() : NULL, m_pGlobalStream ? m_pGlobalStream->GetSize() : 0, m_pCachedBitmap->GetBuffer(), 376 m_pCachedBitmap->GetPitch(), pPause); 377 if (ret < 0) { 378 delete m_pCachedBitmap; 379 m_pCachedBitmap = NULL; 380 delete m_pGlobalStream; 381 m_pGlobalStream = NULL; 382 pJbig2Module->DestroyJbig2Context(m_pJbig2Context); 383 m_pJbig2Context = NULL; 384 return 0; 385 } 386 if (ret == FXCODEC_STATUS_DECODE_TOBECONTINUE) { 387 return 2; 388 } 389 int ret1 = 1; 390 if (m_bHasMask) { 391 ret1 = ContinueLoadMaskDIB(pPause); 392 m_Status = 2; 393 } 394 if (ret1 == 2) { 395 return ret1; 396 } 397 if (m_pColorSpace && m_bStdCS) { 398 m_pColorSpace->EnableStdConversion(FALSE); 399 } 400 return ret1; 401 } 402 FXCODEC_STATUS ret = pJbig2Module->ContinueDecode(m_pJbig2Context, pPause); 403 if (ret < 0) { 404 delete m_pCachedBitmap; 405 m_pCachedBitmap = NULL; 406 delete m_pGlobalStream; 407 m_pGlobalStream = NULL; 408 pJbig2Module->DestroyJbig2Context(m_pJbig2Context); 409 m_pJbig2Context = NULL; 410 return 0; 411 } 412 if (ret == FXCODEC_STATUS_DECODE_TOBECONTINUE) { 413 return 2; 414 } 415 int ret1 = 1; 416 if (m_bHasMask) { 417 ret1 = ContinueLoadMaskDIB(pPause); 418 m_Status = 2; 419 } 420 if (ret1 == 2) { 421 return ret1; 422 } 423 if (m_pColorSpace && m_bStdCS) { 424 m_pColorSpace->EnableStdConversion(FALSE); 425 } 426 return ret1; 427 } else if (m_Status == 2) { 428 return ContinueLoadMaskDIB(pPause); 429 } 430 return 0; 431 } 432 FX_BOOL CPDF_DIBSource::LoadColorInfo(CPDF_Dictionary* pFormResources, CPDF_Dictionary* pPageResources) 433 { 434 m_bpc_orig = m_pDict->GetInteger(FX_BSTRC("BitsPerComponent")); 435 if (m_pDict->GetInteger("ImageMask")) { 436 m_bImageMask = TRUE; 437 } 438 if (m_bImageMask || !m_pDict->KeyExist(FX_BSTRC("ColorSpace"))) { 439 if (!m_bImageMask) { 440 CPDF_Object* pFilter = m_pDict->GetElementValue(FX_BSTRC("Filter")); 441 if (pFilter) { 442 CFX_ByteString filter; 443 if (pFilter->GetType() == PDFOBJ_NAME) { 444 filter = pFilter->GetString(); 445 if (filter == FX_BSTRC("JPXDecode")) { 446 m_bDoBpcCheck = FALSE; 447 return TRUE; 448 } 449 } else if (pFilter->GetType() == PDFOBJ_ARRAY) { 450 CPDF_Array* pArray = (CPDF_Array*)pFilter; 451 if (pArray->GetString(pArray->GetCount() - 1) == FX_BSTRC("JPXDecode")) { 452 m_bDoBpcCheck = FALSE; 453 return TRUE; 454 } 455 } 456 } 457 } 458 m_bImageMask = TRUE; 459 m_bpc = m_nComponents = 1; 460 CPDF_Array* pDecode = m_pDict->GetArray(FX_BSTRC("Decode")); 461 m_bDefaultDecode = pDecode == NULL || pDecode->GetInteger(0) == 0; 462 return TRUE; 463 } 464 CPDF_Object* pCSObj = m_pDict->GetElementValue(FX_BSTRC("ColorSpace")); 465 if (pCSObj == NULL) { 466 return FALSE; 467 } 468 CPDF_DocPageData* pDocPageData = m_pDocument->GetPageData(); 469 if (pFormResources) { 470 m_pColorSpace = pDocPageData->GetColorSpace(pCSObj, pFormResources); 471 } 472 if (m_pColorSpace == NULL) { 473 m_pColorSpace = pDocPageData->GetColorSpace(pCSObj, pPageResources); 474 } 475 if (m_pColorSpace == NULL) { 476 return FALSE; 477 } 478 m_Family = m_pColorSpace->GetFamily(); 479 m_nComponents = m_pColorSpace->CountComponents(); 480 if (m_Family == PDFCS_ICCBASED && pCSObj->GetType() == PDFOBJ_NAME) { 481 CFX_ByteString cs = pCSObj->GetString(); 482 if (cs == FX_BSTRC("DeviceGray")) { 483 m_nComponents = 1; 484 } else if (cs == FX_BSTRC("DeviceRGB")) { 485 m_nComponents = 3; 486 } else if (cs == FX_BSTRC("DeviceCMYK")) { 487 m_nComponents = 4; 488 } 489 } 490 ValidateDictParam(); 491 m_pCompData = GetDecodeAndMaskArray(m_bDefaultDecode, m_bColorKey); 492 if (m_pCompData == NULL) { 493 return FALSE; 494 } 495 return TRUE; 496 } 497 DIB_COMP_DATA* CPDF_DIBSource::GetDecodeAndMaskArray(FX_BOOL& bDefaultDecode, FX_BOOL& bColorKey) 498 { 499 if (m_pColorSpace == NULL) { 500 return NULL; 501 } 502 DIB_COMP_DATA* pCompData = FX_Alloc(DIB_COMP_DATA, m_nComponents); 503 int max_data = (1 << m_bpc) - 1; 504 CPDF_Array* pDecode = m_pDict->GetArray(FX_BSTRC("Decode")); 505 if (pDecode) { 506 for (FX_DWORD i = 0; i < m_nComponents; i ++) { 507 pCompData[i].m_DecodeMin = pDecode->GetNumber(i * 2); 508 FX_FLOAT max = pDecode->GetNumber(i * 2 + 1); 509 pCompData[i].m_DecodeStep = (max - pCompData[i].m_DecodeMin) / max_data; 510 FX_FLOAT def_value, def_min, def_max; 511 m_pColorSpace->GetDefaultValue(i, def_value, def_min, def_max); 512 if (m_Family == PDFCS_INDEXED) { 513 def_max = (FX_FLOAT)max_data; 514 } 515 if (def_min != pCompData[i].m_DecodeMin || def_max != max) { 516 bDefaultDecode = FALSE; 517 } 518 } 519 } else { 520 for (FX_DWORD i = 0; i < m_nComponents; i ++) { 521 FX_FLOAT def_value; 522 m_pColorSpace->GetDefaultValue(i, def_value, pCompData[i].m_DecodeMin, pCompData[i].m_DecodeStep); 523 if (m_Family == PDFCS_INDEXED) { 524 pCompData[i].m_DecodeStep = (FX_FLOAT)max_data; 525 } 526 pCompData[i].m_DecodeStep = (pCompData[i].m_DecodeStep - pCompData[i].m_DecodeMin) / max_data; 527 } 528 } 529 if (!m_pDict->KeyExist(FX_BSTRC("SMask"))) { 530 CPDF_Object* pMask = m_pDict->GetElementValue(FX_BSTRC("Mask")); 531 if (pMask == NULL) { 532 return pCompData; 533 } 534 if (pMask->GetType() == PDFOBJ_ARRAY) { 535 CPDF_Array* pArray = (CPDF_Array*)pMask; 536 if (pArray->GetCount() >= m_nComponents * 2) { 537 for (FX_DWORD i = 0; i < m_nComponents; i++) { 538 int min_num = pArray->GetInteger(i * 2); 539 int max_num = pArray->GetInteger(i * 2 + 1); 540 pCompData[i].m_ColorKeyMin = FX_MAX(min_num, 0); 541 pCompData[i].m_ColorKeyMax = FX_MIN(max_num, max_data); 542 } 543 } 544 bColorKey = TRUE; 545 } 546 } 547 return pCompData; 548 } 549 ICodec_ScanlineDecoder* FPDFAPI_CreateFaxDecoder(FX_LPCBYTE src_buf, FX_DWORD src_size, int width, int height, 550 const CPDF_Dictionary* pParams); 551 ICodec_ScanlineDecoder* FPDFAPI_CreateFlateDecoder(FX_LPCBYTE src_buf, FX_DWORD src_size, int width, int height, 552 int nComps, int bpc, const CPDF_Dictionary* pParams); 553 int CPDF_DIBSource::CreateDecoder() 554 { 555 const CFX_ByteString& decoder = m_pStreamAcc->GetImageDecoder(); 556 if (decoder.IsEmpty()) { 557 return 1; 558 } 559 if (m_bDoBpcCheck && m_bpc == 0) { 560 return 0; 561 } 562 FX_LPCBYTE src_data = m_pStreamAcc->GetData(); 563 FX_DWORD src_size = m_pStreamAcc->GetSize(); 564 const CPDF_Dictionary* pParams = m_pStreamAcc->GetImageParam(); 565 if (decoder == FX_BSTRC("CCITTFaxDecode")) { 566 m_pDecoder = FPDFAPI_CreateFaxDecoder(src_data, src_size, m_Width, m_Height, pParams); 567 } else if (decoder == FX_BSTRC("DCTDecode")) { 568 m_pDecoder = CPDF_ModuleMgr::Get()->GetJpegModule()->CreateDecoder(src_data, src_size, m_Width, m_Height, 569 m_nComponents, pParams ? pParams->GetInteger(FX_BSTR("ColorTransform"), 1) : 1); 570 if (!m_pDecoder) { 571 FX_BOOL bTransform = FALSE; 572 int comps, bpc; 573 ICodec_JpegModule* pJpegModule = CPDF_ModuleMgr::Get()->GetJpegModule(); 574 if (pJpegModule->LoadInfo(src_data, src_size, m_Width, m_Height, comps, bpc, bTransform)) { 575 if (m_nComponents != comps) { 576 FX_Free(m_pCompData); 577 m_nComponents = comps; 578 if (m_Family == PDFCS_LAB && m_nComponents != 3) { 579 m_pCompData = NULL; 580 return 0; 581 } 582 m_pCompData = GetDecodeAndMaskArray(m_bDefaultDecode, m_bColorKey); 583 if (m_pCompData == NULL) { 584 return 0; 585 } 586 } 587 m_bpc = bpc; 588 m_pDecoder = CPDF_ModuleMgr::Get()->GetJpegModule()->CreateDecoder(src_data, src_size, m_Width, m_Height, 589 m_nComponents, bTransform); 590 } 591 } 592 } else if (decoder == FX_BSTRC("FlateDecode")) { 593 m_pDecoder = FPDFAPI_CreateFlateDecoder(src_data, src_size, m_Width, m_Height, m_nComponents, m_bpc, pParams); 594 } else if (decoder == FX_BSTRC("JPXDecode")) { 595 LoadJpxBitmap(); 596 return m_pCachedBitmap != NULL ? 1 : 0; 597 } else if (decoder == FX_BSTRC("JBIG2Decode")) { 598 m_pCachedBitmap = new CFX_DIBitmap; 599 if (!m_pCachedBitmap->Create(m_Width, m_Height, m_bImageMask ? FXDIB_1bppMask : FXDIB_1bppRgb)) { 600 delete m_pCachedBitmap; 601 m_pCachedBitmap = NULL; 602 return 0; 603 } 604 m_Status = 1; 605 return 2; 606 } else if (decoder == FX_BSTRC("RunLengthDecode")) { 607 m_pDecoder = CPDF_ModuleMgr::Get()->GetCodecModule()->GetBasicModule()->CreateRunLengthDecoder(src_data, src_size, m_Width, m_Height, m_nComponents, m_bpc); 608 } 609 if (!m_pDecoder) 610 return 0; 611 612 FX_SAFE_DWORD requested_pitch = 613 CalculatePitch8(m_bpc, m_nComponents, m_Width, 1); 614 if (!requested_pitch.IsValid()) { 615 return 0; 616 } 617 FX_SAFE_DWORD provided_pitch = CalculatePitch8(m_pDecoder->GetBPC(), 618 m_pDecoder->CountComps(), 619 m_pDecoder->GetWidth(), 620 1); 621 if (!provided_pitch.IsValid()) { 622 return 0; 623 } 624 if (provided_pitch.ValueOrDie() < requested_pitch.ValueOrDie()) { 625 return 0; 626 } 627 return 1; 628 } 629 void CPDF_DIBSource::LoadJpxBitmap() 630 { 631 ICodec_JpxModule* pJpxModule = CPDF_ModuleMgr::Get()->GetJpxModule(); 632 if (pJpxModule == NULL) { 633 return; 634 } 635 FX_LPVOID ctx = pJpxModule->CreateDecoder(m_pStreamAcc->GetData(), m_pStreamAcc->GetSize(), m_pColorSpace != NULL); 636 if (ctx == NULL) { 637 return; 638 } 639 FX_DWORD width = 0, height = 0, codestream_nComps = 0, image_nComps = 0; 640 pJpxModule->GetImageInfo(ctx, width, height, codestream_nComps, image_nComps); 641 if ((int)width < m_Width || (int)height < m_Height) { 642 pJpxModule->DestroyDecoder(ctx); 643 return; 644 } 645 int output_nComps; 646 FX_BOOL bTranslateColor, bSwapRGB = FALSE; 647 if (m_pColorSpace) { 648 if (codestream_nComps != (FX_DWORD)m_pColorSpace->CountComponents()) { 649 return; 650 } 651 output_nComps = codestream_nComps; 652 bTranslateColor = FALSE; 653 if (m_pColorSpace == CPDF_ColorSpace::GetStockCS(PDFCS_DEVICERGB)) { 654 bSwapRGB = TRUE; 655 m_pColorSpace = NULL; 656 } 657 } else { 658 bTranslateColor = TRUE; 659 if (image_nComps) { 660 output_nComps = image_nComps; 661 } else { 662 output_nComps = codestream_nComps; 663 } 664 if (output_nComps == 3) { 665 bSwapRGB = TRUE; 666 } else if (output_nComps == 4) { 667 m_pColorSpace = CPDF_ColorSpace::GetStockCS(PDFCS_DEVICECMYK); 668 bTranslateColor = FALSE; 669 } 670 m_nComponents = output_nComps; 671 } 672 FXDIB_Format format; 673 if (output_nComps == 1) { 674 format = FXDIB_8bppRgb; 675 } else if (output_nComps <= 3) { 676 format = FXDIB_Rgb; 677 } else if (output_nComps == 4) { 678 format = FXDIB_Rgb32; 679 } else { 680 width = (width * output_nComps + 2) / 3; 681 format = FXDIB_Rgb; 682 } 683 m_pCachedBitmap = new CFX_DIBitmap; 684 if (!m_pCachedBitmap->Create(width, height, format)) { 685 delete m_pCachedBitmap; 686 m_pCachedBitmap = NULL; 687 return; 688 } 689 m_pCachedBitmap->Clear(0xFFFFFFFF); 690 FX_LPBYTE output_offsets = FX_Alloc(FX_BYTE, output_nComps); 691 for (int i = 0; i < output_nComps; i ++) { 692 output_offsets[i] = i; 693 } 694 if (bSwapRGB) { 695 output_offsets[0] = 2; 696 output_offsets[2] = 0; 697 } 698 if (!pJpxModule->Decode(ctx, m_pCachedBitmap->GetBuffer(), m_pCachedBitmap->GetPitch(), bTranslateColor, output_offsets)) { 699 delete m_pCachedBitmap; 700 m_pCachedBitmap = NULL; 701 return; 702 } 703 FX_Free(output_offsets); 704 pJpxModule->DestroyDecoder(ctx); 705 if (m_pColorSpace && m_pColorSpace->GetFamily() == PDFCS_INDEXED && m_bpc < 8) { 706 int scale = 8 - m_bpc; 707 for (FX_DWORD row = 0; row < height; row ++) { 708 FX_LPBYTE scanline = (FX_LPBYTE)m_pCachedBitmap->GetScanline(row); 709 for (FX_DWORD col = 0; col < width; col ++) { 710 *scanline = (*scanline) >> scale; 711 scanline++; 712 } 713 } 714 } 715 m_bpc = 8; 716 } 717 CPDF_DIBSource* CPDF_DIBSource::LoadMask(FX_DWORD& MatteColor) 718 { 719 MatteColor = 0xffffffff; 720 CPDF_Stream* pSoftMask = m_pDict->GetStream(FX_BSTRC("SMask")); 721 if (pSoftMask) { 722 CPDF_Array* pMatte = pSoftMask->GetDict()->GetArray(FX_BSTRC("Matte")); 723 if (pMatte != NULL && m_pColorSpace && (FX_DWORD)m_pColorSpace->CountComponents() <= m_nComponents) { 724 FX_FLOAT* pColor = FX_Alloc(FX_FLOAT, m_nComponents); 725 for (FX_DWORD i = 0; i < m_nComponents; i ++) { 726 pColor[i] = pMatte->GetFloat(i); 727 } 728 FX_FLOAT R, G, B; 729 m_pColorSpace->GetRGB(pColor, R, G, B); 730 FX_Free(pColor); 731 MatteColor = FXARGB_MAKE(0, FXSYS_round(R * 255), FXSYS_round(G * 255), FXSYS_round(B * 255)); 732 } 733 return LoadMaskDIB(pSoftMask); 734 } 735 CPDF_Object* pMask = m_pDict->GetElementValue(FX_BSTRC("Mask")); 736 if (pMask == NULL) { 737 return NULL; 738 } 739 if (pMask->GetType() == PDFOBJ_STREAM) { 740 return LoadMaskDIB((CPDF_Stream*)pMask); 741 } 742 return NULL; 743 } 744 int CPDF_DIBSource::StratLoadMask() 745 { 746 m_MatteColor = 0xffffffff; 747 m_pMaskStream = m_pDict->GetStream(FX_BSTRC("SMask")); 748 if (m_pMaskStream) { 749 CPDF_Array* pMatte = m_pMaskStream->GetDict()->GetArray(FX_BSTRC("Matte")); 750 if (pMatte != NULL && m_pColorSpace && (FX_DWORD)m_pColorSpace->CountComponents() <= m_nComponents) { 751 FX_FLOAT R, G, B; 752 FX_FLOAT* pColor = FX_Alloc(FX_FLOAT, m_nComponents); 753 for (FX_DWORD i = 0; i < m_nComponents; i ++) { 754 pColor[i] = pMatte->GetFloat(i); 755 } 756 m_pColorSpace->GetRGB(pColor, R, G, B); 757 FX_Free(pColor); 758 m_MatteColor = FXARGB_MAKE(0, FXSYS_round(R * 255), FXSYS_round(G * 255), FXSYS_round(B * 255)); 759 } 760 return StartLoadMaskDIB(); 761 } 762 m_pMaskStream = m_pDict->GetElementValue(FX_BSTRC("Mask")); 763 if (m_pMaskStream == NULL) { 764 return 1; 765 } 766 if (m_pMaskStream->GetType() == PDFOBJ_STREAM) { 767 return StartLoadMaskDIB(); 768 } 769 return 1; 770 } 771 int CPDF_DIBSource::ContinueLoadMaskDIB(IFX_Pause* pPause) 772 { 773 if (m_pMask == NULL) { 774 return 1; 775 } 776 int ret = m_pMask->ContinueLoadDIBSource(pPause); 777 if (ret == 2) { 778 return ret; 779 } 780 if (m_pColorSpace && m_bStdCS) { 781 m_pColorSpace->EnableStdConversion(FALSE); 782 } 783 if (!ret) { 784 delete m_pMask; 785 m_pMask = NULL; 786 return ret; 787 } 788 return 1; 789 } 790 CPDF_DIBSource* CPDF_DIBSource::DetachMask() 791 { 792 CPDF_DIBSource* pDIBSource = m_pMask; 793 m_pMask = NULL; 794 return pDIBSource; 795 } 796 CPDF_DIBSource* CPDF_DIBSource::LoadMaskDIB(CPDF_Stream* pMask) 797 { 798 CPDF_DIBSource* pMaskSource = new CPDF_DIBSource; 799 if (!pMaskSource->Load(m_pDocument, pMask, NULL, NULL, NULL, NULL, TRUE)) { 800 delete pMaskSource; 801 return NULL; 802 } 803 return pMaskSource; 804 } 805 int CPDF_DIBSource::StartLoadMaskDIB() 806 { 807 m_pMask = new CPDF_DIBSource; 808 int ret = m_pMask->StartLoadDIBSource(m_pDocument, (CPDF_Stream*)m_pMaskStream, FALSE, NULL, NULL, TRUE); 809 if (ret == 2) { 810 if (m_Status == 0) { 811 m_Status = 2; 812 } 813 return 2; 814 } 815 if (!ret) { 816 delete m_pMask; 817 m_pMask = NULL; 818 return 1; 819 } 820 return 1; 821 } 822 void CPDF_DIBSource::LoadPalette() 823 { 824 if (m_bpc == 0) { 825 return; 826 } 827 if (m_bpc * m_nComponents > 8) { 828 return; 829 } 830 if (m_pColorSpace == NULL) { 831 return; 832 } 833 if (m_bpc * m_nComponents == 1) { 834 if (m_bDefaultDecode && (m_Family == PDFCS_DEVICEGRAY || m_Family == PDFCS_DEVICERGB)) { 835 return; 836 } 837 if (m_pColorSpace->CountComponents() > 3) { 838 return; 839 } 840 FX_FLOAT color_values[3]; 841 color_values[0] = m_pCompData[0].m_DecodeMin; 842 color_values[1] = color_values[2] = color_values[0]; 843 FX_FLOAT R=0.0f, G=0.0f, B=0.0f; 844 m_pColorSpace->GetRGB(color_values, R, G, B); 845 FX_ARGB argb0 = ArgbEncode(255, FXSYS_round(R * 255), FXSYS_round(G * 255), FXSYS_round(B * 255)); 846 color_values[0] += m_pCompData[0].m_DecodeStep; 847 color_values[1] += m_pCompData[0].m_DecodeStep; 848 color_values[2] += m_pCompData[0].m_DecodeStep; 849 m_pColorSpace->GetRGB(color_values, R, G, B); 850 FX_ARGB argb1 = ArgbEncode(255, FXSYS_round(R * 255), FXSYS_round(G * 255), FXSYS_round(B * 255)); 851 if (argb0 != 0xFF000000 || argb1 != 0xFFFFFFFF) { 852 SetPaletteArgb(0, argb0); 853 SetPaletteArgb(1, argb1); 854 } 855 return; 856 } 857 if (m_pColorSpace == CPDF_ColorSpace::GetStockCS(PDFCS_DEVICEGRAY) && m_bpc == 8 && m_bDefaultDecode) { 858 } else { 859 int palette_count = 1 << (m_bpc * m_nComponents); 860 CFX_FixedBufGrow<FX_FLOAT, 16> color_values(m_nComponents); 861 FX_FLOAT* color_value = color_values; 862 for (int i = 0; i < palette_count; i ++) { 863 int color_data = i; 864 for (FX_DWORD j = 0; j < m_nComponents; j ++) { 865 int encoded_component = color_data % (1 << m_bpc); 866 color_data /= 1 << m_bpc; 867 color_value[j] = m_pCompData[j].m_DecodeMin + m_pCompData[j].m_DecodeStep * encoded_component; 868 } 869 FX_FLOAT R = 0, G = 0, B = 0; 870 if (m_nComponents == 1 && m_Family == PDFCS_ICCBASED && m_pColorSpace->CountComponents() > 1) { 871 int nComponents = m_pColorSpace->CountComponents(); 872 FX_FLOAT* temp_buf = FX_Alloc(FX_FLOAT, nComponents); 873 for (int i = 0; i < nComponents; i++) { 874 temp_buf[i] = *color_value; 875 } 876 m_pColorSpace->GetRGB(temp_buf, R, G, B); 877 FX_Free(temp_buf); 878 } else { 879 m_pColorSpace->GetRGB(color_value, R, G, B); 880 } 881 SetPaletteArgb(i, ArgbEncode(255, FXSYS_round(R * 255), FXSYS_round(G * 255), FXSYS_round(B * 255))); 882 } 883 } 884 } 885 void CPDF_DIBSource::ValidateDictParam() 886 { 887 m_bpc = m_bpc_orig; 888 CPDF_Object * pFilter = m_pDict->GetElementValue(FX_BSTRC("Filter")); 889 if (pFilter) { 890 if (pFilter->GetType() == PDFOBJ_NAME) { 891 CFX_ByteString filter = pFilter->GetString(); 892 if (filter == FX_BSTRC("CCITTFaxDecode") || filter == FX_BSTRC("JBIG2Decode")) { 893 m_bpc = 1; 894 m_nComponents = 1; 895 } 896 if (filter == FX_BSTRC("RunLengthDecode") || filter == FX_BSTRC("DCTDecode")) { 897 m_bpc = 8; 898 } 899 } else if (pFilter->GetType() == PDFOBJ_ARRAY) { 900 CPDF_Array *pArray = (CPDF_Array *)pFilter; 901 if (pArray->GetString(pArray->GetCount() - 1) == FX_BSTRC("CCITTFaxDecode") || 902 pArray->GetString(pArray->GetCount() - 1) == FX_BSTRC("JBIG2Decode")) { 903 m_bpc = 1; 904 m_nComponents = 1; 905 } 906 if (pArray->GetString(pArray->GetCount() - 1) == FX_BSTRC("DCTDecode")) { 907 // Previously, pArray->GetString(pArray->GetCount() - 1) == FX_BSTRC("RunLengthDecode") was checked in the "if" statement as well, 908 // but too many documents don't conform to it. 909 m_bpc = 8; 910 } 911 } 912 } 913 if (m_bpc != 1 && m_bpc != 2 && m_bpc != 4 && m_bpc != 8 && m_bpc != 16) { 914 m_bpc = 0; 915 } 916 } 917 #define NORMALCOLOR_MAX(color, max) (color) > (max) ? (max) : (color) < 0 ? 0 : (color); 918 void CPDF_DIBSource::TranslateScanline24bpp(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan) const 919 { 920 if (m_bpc == 0) { 921 return; 922 } 923 int max_data = (1 << m_bpc) - 1; 924 if (m_bDefaultDecode) { 925 if (m_Family == PDFCS_DEVICERGB || m_Family == PDFCS_CALRGB) { 926 FX_LPCBYTE src_pos = src_scan; 927 switch (m_bpc) { 928 case 16: 929 for (int col = 0; col < m_Width; col ++) { 930 *dest_scan++ = src_pos[4]; 931 *dest_scan++ = src_pos[2]; 932 *dest_scan++ = *src_pos; 933 src_pos += 6; 934 } 935 break; 936 case 8: 937 for (int column = 0; column < m_Width; column ++) { 938 *dest_scan++ = src_pos[2]; 939 *dest_scan++ = src_pos[1]; 940 *dest_scan++ = *src_pos; 941 src_pos += 3; 942 } 943 break; 944 default: 945 int src_bit_pos = 0; 946 int dest_byte_pos = 0; 947 for (int column = 0; column < m_Width; column ++) { 948 int R = _GetBits8(src_scan, src_bit_pos, m_bpc); 949 src_bit_pos += m_bpc; 950 int G = _GetBits8(src_scan, src_bit_pos, m_bpc); 951 src_bit_pos += m_bpc; 952 int B = _GetBits8(src_scan, src_bit_pos, m_bpc); 953 src_bit_pos += m_bpc; 954 R = NORMALCOLOR_MAX(R, max_data); 955 G = NORMALCOLOR_MAX(G, max_data); 956 B = NORMALCOLOR_MAX(B, max_data); 957 dest_scan[dest_byte_pos] = B * 255 / max_data; 958 dest_scan[dest_byte_pos + 1] = G * 255 / max_data; 959 dest_scan[dest_byte_pos + 2] = R * 255 / max_data; 960 dest_byte_pos += 3; 961 } 962 break; 963 } 964 return; 965 } else if (m_bpc == 8) { 966 if (m_nComponents == m_pColorSpace->CountComponents()) 967 m_pColorSpace->TranslateImageLine(dest_scan, src_scan, m_Width, m_Width, m_Height, 968 m_bLoadMask && m_GroupFamily == PDFCS_DEVICECMYK && m_Family == PDFCS_DEVICECMYK); 969 return; 970 } 971 } 972 CFX_FixedBufGrow<FX_FLOAT, 16> color_values1(m_nComponents); 973 FX_FLOAT* color_values = color_values1; 974 FX_FLOAT R = 0.0f, G = 0.0f, B = 0.0f; 975 if (m_bpc == 8) { 976 int src_byte_pos = 0; 977 int dest_byte_pos = 0; 978 for (int column = 0; column < m_Width; column ++) { 979 for (FX_DWORD color = 0; color < m_nComponents; color ++) { 980 int data = src_scan[src_byte_pos ++]; 981 color_values[color] = m_pCompData[color].m_DecodeMin + 982 m_pCompData[color].m_DecodeStep * data; 983 } 984 if (m_bLoadMask && m_GroupFamily == PDFCS_DEVICECMYK && m_Family == PDFCS_DEVICECMYK) { 985 FX_FLOAT k = 1.0f - color_values[3]; 986 R = (1.0f - color_values[0]) * k; 987 G = (1.0f - color_values[1]) * k; 988 B = (1.0f - color_values[2]) * k; 989 } else { 990 m_pColorSpace->GetRGB(color_values, R, G, B); 991 } 992 R = NORMALCOLOR_MAX(R, 1); 993 G = NORMALCOLOR_MAX(G, 1); 994 B = NORMALCOLOR_MAX(B, 1); 995 dest_scan[dest_byte_pos] = (FX_INT32)(B * 255); 996 dest_scan[dest_byte_pos + 1] = (FX_INT32)(G * 255); 997 dest_scan[dest_byte_pos + 2] = (FX_INT32)(R * 255); 998 dest_byte_pos += 3; 999 } 1000 } else { 1001 int src_bit_pos = 0; 1002 int dest_byte_pos = 0; 1003 for (int column = 0; column < m_Width; column ++) { 1004 for (FX_DWORD color = 0; color < m_nComponents; color ++) { 1005 int data = _GetBits8(src_scan, src_bit_pos, m_bpc); 1006 color_values[color] = m_pCompData[color].m_DecodeMin + 1007 m_pCompData[color].m_DecodeStep * data; 1008 src_bit_pos += m_bpc; 1009 } 1010 if (m_bLoadMask && m_GroupFamily == PDFCS_DEVICECMYK && m_Family == PDFCS_DEVICECMYK) { 1011 FX_FLOAT k = 1.0f - color_values[3]; 1012 R = (1.0f - color_values[0]) * k; 1013 G = (1.0f - color_values[1]) * k; 1014 B = (1.0f - color_values[2]) * k; 1015 } else { 1016 m_pColorSpace->GetRGB(color_values, R, G, B); 1017 } 1018 R = NORMALCOLOR_MAX(R, 1); 1019 G = NORMALCOLOR_MAX(G, 1); 1020 B = NORMALCOLOR_MAX(B, 1); 1021 dest_scan[dest_byte_pos] = (FX_INT32)(B * 255); 1022 dest_scan[dest_byte_pos + 1] = (FX_INT32)(G * 255); 1023 dest_scan[dest_byte_pos + 2] = (FX_INT32)(R * 255); 1024 dest_byte_pos += 3; 1025 } 1026 } 1027 } 1028 FX_LPBYTE CPDF_DIBSource::GetBuffer() const 1029 { 1030 if (m_pCachedBitmap) { 1031 return m_pCachedBitmap->GetBuffer(); 1032 } 1033 return NULL; 1034 } 1035 FX_LPCBYTE CPDF_DIBSource::GetScanline(int line) const 1036 { 1037 if (m_bpc == 0) { 1038 return NULL; 1039 } 1040 FX_SAFE_DWORD src_pitch = CalculatePitch8(m_bpc, m_nComponents, m_Width, 1); 1041 if (!src_pitch.IsValid()) 1042 return NULL; 1043 FX_DWORD src_pitch_value = src_pitch.ValueOrDie(); 1044 FX_LPCBYTE pSrcLine = NULL; 1045 if (m_pCachedBitmap) { 1046 if (line >= m_pCachedBitmap->GetHeight()) { 1047 line = m_pCachedBitmap->GetHeight() - 1; 1048 } 1049 pSrcLine = m_pCachedBitmap->GetScanline(line); 1050 } else if (m_pDecoder) { 1051 pSrcLine = m_pDecoder->GetScanline(line); 1052 } else { 1053 if (m_pStreamAcc->GetSize() >= (line + 1) * src_pitch_value) { 1054 pSrcLine = m_pStreamAcc->GetData() + line * src_pitch_value; 1055 } 1056 } 1057 if (pSrcLine == NULL) { 1058 FX_LPBYTE pLineBuf = m_pMaskedLine ? m_pMaskedLine : m_pLineBuf; 1059 FXSYS_memset8(pLineBuf, 0xff, m_Pitch); 1060 return pLineBuf; 1061 } 1062 if (m_bpc * m_nComponents == 1) { 1063 if (m_bImageMask && m_bDefaultDecode) { 1064 for (FX_DWORD i = 0; i < src_pitch_value; i++) { 1065 m_pLineBuf[i] = ~pSrcLine[i]; 1066 } 1067 } else if (m_bColorKey) { 1068 FX_DWORD reset_argb, set_argb; 1069 reset_argb = m_pPalette ? m_pPalette[0] : 0xff000000; 1070 set_argb = m_pPalette ? m_pPalette[1] : 0xffffffff; 1071 if (m_pCompData[0].m_ColorKeyMin == 0) { 1072 reset_argb = 0; 1073 } 1074 if (m_pCompData[0].m_ColorKeyMax == 1) { 1075 set_argb = 0; 1076 } 1077 set_argb = FXARGB_TODIB(set_argb); 1078 reset_argb = FXARGB_TODIB(reset_argb); 1079 FX_DWORD* dest_scan = (FX_DWORD*)m_pMaskedLine; 1080 for (int col = 0; col < m_Width; col ++) { 1081 if (pSrcLine[col / 8] & (1 << (7 - col % 8))) { 1082 *dest_scan = set_argb; 1083 } else { 1084 *dest_scan = reset_argb; 1085 } 1086 dest_scan ++; 1087 } 1088 return m_pMaskedLine; 1089 } else { 1090 FXSYS_memcpy32(m_pLineBuf, pSrcLine, src_pitch_value); 1091 } 1092 return m_pLineBuf; 1093 } 1094 if (m_bpc * m_nComponents <= 8) { 1095 if (m_bpc == 8) { 1096 FXSYS_memcpy32(m_pLineBuf, pSrcLine, src_pitch_value); 1097 } else { 1098 int src_bit_pos = 0; 1099 for (int col = 0; col < m_Width; col ++) { 1100 int color_index = 0; 1101 for (FX_DWORD color = 0; color < m_nComponents; color ++) { 1102 int data = _GetBits8(pSrcLine, src_bit_pos, m_bpc); 1103 color_index |= data << (color * m_bpc); 1104 src_bit_pos += m_bpc; 1105 } 1106 m_pLineBuf[col] = color_index; 1107 } 1108 } 1109 if (m_bColorKey) { 1110 FX_LPBYTE pDestPixel = m_pMaskedLine; 1111 FX_LPCBYTE pSrcPixel = m_pLineBuf; 1112 for (int col = 0; col < m_Width; col ++) { 1113 FX_BYTE index = *pSrcPixel++; 1114 if (m_pPalette) { 1115 *pDestPixel++ = FXARGB_B(m_pPalette[index]); 1116 *pDestPixel++ = FXARGB_G(m_pPalette[index]); 1117 *pDestPixel++ = FXARGB_R(m_pPalette[index]); 1118 } else { 1119 *pDestPixel++ = index; 1120 *pDestPixel++ = index; 1121 *pDestPixel++ = index; 1122 } 1123 *pDestPixel = (index < m_pCompData[0].m_ColorKeyMin || index > m_pCompData[0].m_ColorKeyMax) ? 0xff : 0; 1124 pDestPixel ++ ; 1125 } 1126 return m_pMaskedLine; 1127 } 1128 return m_pLineBuf; 1129 } 1130 if (m_bColorKey) { 1131 if (m_nComponents == 3 && m_bpc == 8) { 1132 FX_LPBYTE alpha_channel = m_pMaskedLine + 3; 1133 for (int col = 0; col < m_Width; col ++) { 1134 FX_LPCBYTE pPixel = pSrcLine + col * 3; 1135 alpha_channel[col * 4] = (pPixel[0] < m_pCompData[0].m_ColorKeyMin || pPixel[0] > m_pCompData[0].m_ColorKeyMax || 1136 pPixel[1] < m_pCompData[1].m_ColorKeyMin || pPixel[1] > m_pCompData[1].m_ColorKeyMax || 1137 pPixel[2] < m_pCompData[2].m_ColorKeyMin || pPixel[2] > m_pCompData[2].m_ColorKeyMax) ? 0xff : 0; 1138 } 1139 } else { 1140 FXSYS_memset8(m_pMaskedLine, 0xff, m_Pitch); 1141 } 1142 } 1143 if (m_pColorSpace) { 1144 TranslateScanline24bpp(m_pLineBuf, pSrcLine); 1145 pSrcLine = m_pLineBuf; 1146 } 1147 if (m_bColorKey) { 1148 FX_LPCBYTE pSrcPixel = pSrcLine; 1149 FX_LPBYTE pDestPixel = m_pMaskedLine; 1150 for (int col = 0; col < m_Width; col ++) { 1151 *pDestPixel++ = *pSrcPixel++; 1152 *pDestPixel++ = *pSrcPixel++; 1153 *pDestPixel++ = *pSrcPixel++; 1154 pDestPixel ++; 1155 } 1156 return m_pMaskedLine; 1157 } 1158 return pSrcLine; 1159 } 1160 FX_BOOL CPDF_DIBSource::SkipToScanline(int line, IFX_Pause* pPause) const 1161 { 1162 if (m_pDecoder) { 1163 return m_pDecoder->SkipToScanline(line, pPause); 1164 } 1165 return FALSE; 1166 } 1167 void CPDF_DIBSource::DownSampleScanline(int line, FX_LPBYTE dest_scan, int dest_bpp, 1168 int dest_width, FX_BOOL bFlipX, int clip_left, int clip_width) const 1169 { 1170 if (line < 0 || dest_scan == NULL || dest_bpp <= 0 || 1171 dest_width <= 0 || clip_left < 0 || clip_width <= 0) { 1172 return; 1173 } 1174 1175 FX_DWORD src_width = m_Width; 1176 FX_SAFE_DWORD pitch = CalculatePitch8(m_bpc, m_nComponents, m_Width, 1); 1177 if (!pitch.IsValid()) { 1178 return; 1179 } 1180 1181 FX_LPCBYTE pSrcLine = NULL; 1182 if (m_pCachedBitmap) { 1183 pSrcLine = m_pCachedBitmap->GetScanline(line); 1184 } else if (m_pDecoder) { 1185 pSrcLine = m_pDecoder->GetScanline(line); 1186 } else { 1187 FX_DWORD src_pitch = pitch.ValueOrDie(); 1188 pitch *= (line+1); 1189 if (!pitch.IsValid()) { 1190 return; 1191 } 1192 1193 if (m_pStreamAcc->GetSize() >= pitch.ValueOrDie()) { 1194 pSrcLine = m_pStreamAcc->GetData() + line * src_pitch; 1195 } 1196 } 1197 int orig_Bpp = m_bpc * m_nComponents / 8; 1198 int dest_Bpp = dest_bpp / 8; 1199 if (pSrcLine == NULL) { 1200 FXSYS_memset32(dest_scan, 0xff, dest_Bpp * clip_width); 1201 return; 1202 } 1203 1204 FX_SAFE_INT32 max_src_x = clip_left; 1205 max_src_x += clip_width - 1; 1206 max_src_x *= src_width; 1207 max_src_x /= dest_width; 1208 if (!max_src_x.IsValid()) { 1209 return; 1210 } 1211 1212 CFX_FixedBufGrow<FX_BYTE, 128> temp(orig_Bpp); 1213 if (m_bpc * m_nComponents == 1) { 1214 FX_DWORD set_argb = (FX_DWORD) - 1, reset_argb = 0; 1215 if (m_bImageMask) { 1216 if (m_bDefaultDecode) { 1217 set_argb = 0; 1218 reset_argb = (FX_DWORD) - 1; 1219 } 1220 } else if (m_bColorKey) { 1221 reset_argb = m_pPalette ? m_pPalette[0] : 0xff000000; 1222 set_argb = m_pPalette ? m_pPalette[1] : 0xffffffff; 1223 if (m_pCompData[0].m_ColorKeyMin == 0) { 1224 reset_argb = 0; 1225 } 1226 if (m_pCompData[0].m_ColorKeyMax == 1) { 1227 set_argb = 0; 1228 } 1229 set_argb = FXARGB_TODIB(set_argb); 1230 reset_argb = FXARGB_TODIB(reset_argb); 1231 for (int i = 0; i < clip_width; i ++) { 1232 FX_DWORD src_x = (clip_left + i) * src_width / dest_width; 1233 if (bFlipX) { 1234 src_x = src_width - src_x - 1; 1235 } 1236 src_x %= src_width; 1237 if (pSrcLine[src_x / 8] & (1 << (7 - src_x % 8))) { 1238 ((FX_DWORD*)dest_scan)[i] = set_argb; 1239 } else { 1240 ((FX_DWORD*)dest_scan)[i] = reset_argb; 1241 } 1242 } 1243 return; 1244 } else { 1245 if (dest_Bpp == 1) { 1246 } else if (m_pPalette) { 1247 reset_argb = m_pPalette[0]; 1248 set_argb = m_pPalette[1]; 1249 } 1250 } 1251 for (int i = 0; i < clip_width; i ++) { 1252 FX_DWORD src_x = (clip_left + i) * src_width / dest_width; 1253 if (bFlipX) { 1254 src_x = src_width - src_x - 1; 1255 } 1256 src_x %= src_width; 1257 int dest_pos = i * dest_Bpp; 1258 if (pSrcLine[src_x / 8] & (1 << (7 - src_x % 8))) { 1259 if (dest_Bpp == 1) { 1260 dest_scan[dest_pos] = (FX_BYTE)set_argb; 1261 } else if (dest_Bpp == 3) { 1262 dest_scan[dest_pos] = FXARGB_B(set_argb); 1263 dest_scan[dest_pos + 1] = FXARGB_G(set_argb); 1264 dest_scan[dest_pos + 2] = FXARGB_R(set_argb); 1265 } else { 1266 *(FX_DWORD*)(dest_scan + dest_pos) = set_argb; 1267 } 1268 } else { 1269 if (dest_Bpp == 1) { 1270 dest_scan[dest_pos] = (FX_BYTE)reset_argb; 1271 } else if (dest_Bpp == 3) { 1272 dest_scan[dest_pos] = FXARGB_B(reset_argb); 1273 dest_scan[dest_pos + 1] = FXARGB_G(reset_argb); 1274 dest_scan[dest_pos + 2] = FXARGB_R(reset_argb); 1275 } else { 1276 *(FX_DWORD*)(dest_scan + dest_pos) = reset_argb; 1277 } 1278 } 1279 } 1280 return; 1281 } else if (m_bpc * m_nComponents <= 8) { 1282 if (m_bpc < 8) { 1283 int src_bit_pos = 0; 1284 for (FX_DWORD col = 0; col < src_width; col ++) { 1285 int color_index = 0; 1286 for (FX_DWORD color = 0; color < m_nComponents; color ++) { 1287 int data = _GetBits8(pSrcLine, src_bit_pos, m_bpc); 1288 color_index |= data << (color * m_bpc); 1289 src_bit_pos += m_bpc; 1290 } 1291 m_pLineBuf[col] = color_index; 1292 } 1293 pSrcLine = m_pLineBuf; 1294 } 1295 if (m_bColorKey) { 1296 for (int i = 0; i < clip_width; i ++) { 1297 FX_DWORD src_x = (clip_left + i) * src_width / dest_width; 1298 if (bFlipX) { 1299 src_x = src_width - src_x - 1; 1300 } 1301 src_x %= src_width; 1302 FX_LPBYTE pDestPixel = dest_scan + i * 4; 1303 FX_BYTE index = pSrcLine[src_x]; 1304 if (m_pPalette) { 1305 *pDestPixel++ = FXARGB_B(m_pPalette[index]); 1306 *pDestPixel++ = FXARGB_G(m_pPalette[index]); 1307 *pDestPixel++ = FXARGB_R(m_pPalette[index]); 1308 } else { 1309 *pDestPixel++ = index; 1310 *pDestPixel++ = index; 1311 *pDestPixel++ = index; 1312 } 1313 *pDestPixel = (index < m_pCompData[0].m_ColorKeyMin || index > m_pCompData[0].m_ColorKeyMax) ? 0xff : 0; 1314 } 1315 return; 1316 } 1317 for (int i = 0; i < clip_width; i ++) { 1318 FX_DWORD src_x = (clip_left + i) * src_width / dest_width; 1319 if (bFlipX) { 1320 src_x = src_width - src_x - 1; 1321 } 1322 src_x %= src_width; 1323 FX_BYTE index = pSrcLine[src_x]; 1324 if (dest_Bpp == 1) { 1325 dest_scan[i] = index; 1326 } else { 1327 int dest_pos = i * dest_Bpp; 1328 FX_ARGB argb = m_pPalette[index]; 1329 dest_scan[dest_pos] = FXARGB_B(argb); 1330 dest_scan[dest_pos + 1] = FXARGB_G(argb); 1331 dest_scan[dest_pos + 2] = FXARGB_R(argb); 1332 } 1333 } 1334 return; 1335 } else { 1336 int last_src_x = -1; 1337 FX_ARGB last_argb; 1338 FX_FLOAT orig_Not8Bpp = (FX_FLOAT)m_bpc * (FX_FLOAT)m_nComponents / 8.0f; 1339 FX_FLOAT unit_To8Bpc = 255.0f / ((1 << m_bpc) - 1); 1340 for (int i = 0; i < clip_width; i ++) { 1341 int dest_x = clip_left + i; 1342 FX_DWORD src_x = (bFlipX ? (dest_width - dest_x - 1) : dest_x) * (FX_INT64)src_width / dest_width; 1343 src_x %= src_width; 1344 FX_LPCBYTE pSrcPixel = NULL; 1345 if (m_bpc % 8 == 0) { 1346 pSrcPixel = pSrcLine + src_x * orig_Bpp; 1347 } else { 1348 pSrcPixel = pSrcLine + (int)(src_x * orig_Not8Bpp); 1349 } 1350 FX_LPBYTE pDestPixel = dest_scan + i * dest_Bpp; 1351 FX_ARGB argb; 1352 if (src_x == last_src_x) { 1353 argb = last_argb; 1354 } else { 1355 if (m_pColorSpace) { 1356 FX_BYTE color[4]; 1357 if (!m_bDefaultDecode) { 1358 for (int i = 0; i < m_nComponents; i ++) { 1359 int color_value = (int)((m_pCompData[i].m_DecodeMin + m_pCompData[i].m_DecodeStep * (FX_FLOAT)pSrcPixel[i]) * 255.0f + 0.5f); 1360 temp[i] = color_value > 255 ? 255 : (color_value < 0 ? 0 : color_value); 1361 } 1362 m_pColorSpace->TranslateImageLine(color, temp, 1, 0, 0, m_bLoadMask && m_GroupFamily == PDFCS_DEVICECMYK && m_Family == PDFCS_DEVICECMYK); 1363 } else { 1364 if (m_bpc < 8) { 1365 int src_bit_pos = 0; 1366 if (src_x % 2) { 1367 src_bit_pos = 4; 1368 } 1369 for (FX_DWORD i = 0; i < m_nComponents; i ++) { 1370 temp[i] = (FX_BYTE)(_GetBits8(pSrcPixel, src_bit_pos, m_bpc) * unit_To8Bpc); 1371 src_bit_pos += m_bpc; 1372 } 1373 m_pColorSpace->TranslateImageLine(color, temp, 1, 0, 0, m_bLoadMask && m_GroupFamily == PDFCS_DEVICECMYK && m_Family == PDFCS_DEVICECMYK); 1374 } else { 1375 m_pColorSpace->TranslateImageLine(color, pSrcPixel, 1, 0, 0, m_bLoadMask && m_GroupFamily == PDFCS_DEVICECMYK && m_Family == PDFCS_DEVICECMYK); 1376 } 1377 } 1378 argb = FXARGB_MAKE(0xff, color[2], color[1], color[0]); 1379 } else { 1380 argb = FXARGB_MAKE(0xff, pSrcPixel[2], pSrcPixel[1], pSrcPixel[0]); 1381 } 1382 if (m_bColorKey) { 1383 int alpha = 0xff; 1384 if (m_nComponents == 3 && m_bpc == 8) { 1385 alpha = (pSrcPixel[0] < m_pCompData[0].m_ColorKeyMin || 1386 pSrcPixel[0] > m_pCompData[0].m_ColorKeyMax || 1387 pSrcPixel[1] < m_pCompData[1].m_ColorKeyMin || 1388 pSrcPixel[1] > m_pCompData[1].m_ColorKeyMax || 1389 pSrcPixel[2] < m_pCompData[2].m_ColorKeyMin || 1390 pSrcPixel[2] > m_pCompData[2].m_ColorKeyMax) ? 0xff : 0; 1391 } 1392 argb &= 0xffffff; 1393 argb |= alpha << 24; 1394 } 1395 last_src_x = src_x; 1396 last_argb = argb; 1397 } 1398 if (dest_Bpp == 4) { 1399 *(FX_DWORD*)pDestPixel = FXARGB_TODIB(argb); 1400 } else { 1401 *pDestPixel++ = FXARGB_B(argb); 1402 *pDestPixel++ = FXARGB_G(argb); 1403 *pDestPixel = FXARGB_R(argb); 1404 } 1405 } 1406 } 1407 } 1408 void CPDF_DIBSource::SetDownSampleSize(int dest_width, int dest_height) const 1409 { 1410 if (m_pDecoder) { 1411 m_pDecoder->DownScale(dest_width, dest_height); 1412 ((CPDF_DIBSource*)this)->m_Width = m_pDecoder->GetWidth(); 1413 ((CPDF_DIBSource*)this)->m_Height = m_pDecoder->GetHeight(); 1414 } 1415 } 1416 void CPDF_DIBSource::ClearImageData() 1417 { 1418 if (m_pDecoder) { 1419 m_pDecoder->ClearImageData(); 1420 } 1421 } 1422 CPDF_ProgressiveImageLoaderHandle::CPDF_ProgressiveImageLoaderHandle() 1423 { 1424 m_pImageLoader = NULL; 1425 m_pCache = NULL; 1426 m_pImage = NULL; 1427 } 1428 CPDF_ProgressiveImageLoaderHandle::~CPDF_ProgressiveImageLoaderHandle() 1429 { 1430 } 1431 FX_BOOL CPDF_ProgressiveImageLoaderHandle::Start(CPDF_ImageLoader* pImageLoader, const CPDF_ImageObject* pImage, CPDF_PageRenderCache* pCache, FX_BOOL bStdCS, FX_DWORD GroupFamily, FX_BOOL bLoadMask, CPDF_RenderStatus* pRenderStatus, FX_INT32 nDownsampleWidth, FX_INT32 nDownsampleHeight) 1432 { 1433 m_pImageLoader = pImageLoader; 1434 m_pCache = pCache; 1435 m_pImage = (CPDF_ImageObject*)pImage; 1436 m_nDownsampleWidth = nDownsampleWidth; 1437 m_nDownsampleHeight = nDownsampleHeight; 1438 FX_BOOL ret; 1439 if (pCache) { 1440 ret = pCache->StartGetCachedBitmap(pImage->m_pImage->GetStream(), bStdCS, GroupFamily, bLoadMask, pRenderStatus, m_nDownsampleWidth, m_nDownsampleHeight); 1441 if (ret == FALSE) { 1442 m_pImageLoader->m_bCached = TRUE; 1443 m_pImageLoader->m_pBitmap = pCache->m_pCurImageCache->DetachBitmap(); 1444 m_pImageLoader->m_pMask = pCache->m_pCurImageCache->DetachMask(); 1445 m_pImageLoader->m_MatteColor = pCache->m_pCurImageCache->m_MatteColor; 1446 } 1447 } else { 1448 ret = pImage->m_pImage->StartLoadDIBSource(pRenderStatus->m_pFormResource, pRenderStatus->m_pPageResource, bStdCS, GroupFamily, bLoadMask); 1449 if (ret == FALSE) { 1450 m_pImageLoader->m_bCached = FALSE; 1451 m_pImageLoader->m_pBitmap = m_pImage->m_pImage->DetachBitmap(); 1452 m_pImageLoader->m_pMask = m_pImage->m_pImage->DetachMask(); 1453 m_pImageLoader->m_MatteColor = m_pImage->m_pImage->m_MatteColor; 1454 } 1455 } 1456 return ret; 1457 } 1458 FX_BOOL CPDF_ProgressiveImageLoaderHandle::Continue(IFX_Pause* pPause) 1459 { 1460 FX_BOOL ret; 1461 if (m_pCache) { 1462 ret = m_pCache->Continue(pPause); 1463 if (ret == FALSE) { 1464 m_pImageLoader->m_bCached = TRUE; 1465 m_pImageLoader->m_pBitmap = m_pCache->m_pCurImageCache->DetachBitmap(); 1466 m_pImageLoader->m_pMask = m_pCache->m_pCurImageCache->DetachMask(); 1467 m_pImageLoader->m_MatteColor = m_pCache->m_pCurImageCache->m_MatteColor; 1468 } 1469 } else { 1470 ret = m_pImage->m_pImage->Continue(pPause); 1471 if (ret == FALSE) { 1472 m_pImageLoader->m_bCached = FALSE; 1473 m_pImageLoader->m_pBitmap = m_pImage->m_pImage->DetachBitmap(); 1474 m_pImageLoader->m_pMask = m_pImage->m_pImage->DetachMask(); 1475 m_pImageLoader->m_MatteColor = m_pImage->m_pImage->m_MatteColor; 1476 } 1477 } 1478 return ret; 1479 } 1480 FX_BOOL CPDF_ImageLoader::Load(const CPDF_ImageObject* pImage, CPDF_PageRenderCache* pCache, FX_BOOL bStdCS, FX_DWORD GroupFamily, FX_BOOL bLoadMask, CPDF_RenderStatus* pRenderStatus) 1481 { 1482 if (pImage == NULL) { 1483 return FALSE; 1484 } 1485 if (pCache) { 1486 pCache->GetCachedBitmap(pImage->m_pImage->GetStream(), m_pBitmap, m_pMask, m_MatteColor, bStdCS, GroupFamily, bLoadMask, pRenderStatus, m_nDownsampleWidth, m_nDownsampleHeight); 1487 m_bCached = TRUE; 1488 } else { 1489 m_pBitmap = pImage->m_pImage->LoadDIBSource(&m_pMask, &m_MatteColor, bStdCS, GroupFamily, bLoadMask); 1490 m_bCached = FALSE; 1491 } 1492 return FALSE; 1493 } 1494 FX_BOOL CPDF_ImageLoader::StartLoadImage(const CPDF_ImageObject* pImage, CPDF_PageRenderCache* pCache, FX_LPVOID& LoadHandle, FX_BOOL bStdCS, FX_DWORD GroupFamily, FX_BOOL bLoadMask, CPDF_RenderStatus* pRenderStatus, FX_INT32 nDownsampleWidth, FX_INT32 nDownsampleHeight) 1495 { 1496 m_nDownsampleWidth = nDownsampleWidth; 1497 m_nDownsampleHeight = nDownsampleHeight; 1498 CPDF_ProgressiveImageLoaderHandle* pLoaderHandle = new CPDF_ProgressiveImageLoaderHandle; 1499 FX_BOOL ret = pLoaderHandle->Start(this, pImage, pCache, bStdCS, GroupFamily, bLoadMask, pRenderStatus, m_nDownsampleWidth, m_nDownsampleHeight); 1500 LoadHandle = pLoaderHandle; 1501 return ret; 1502 } 1503 FX_BOOL CPDF_ImageLoader::Continue(FX_LPVOID LoadHandle, IFX_Pause* pPause) 1504 { 1505 return ((CPDF_ProgressiveImageLoaderHandle*)LoadHandle)->Continue(pPause); 1506 } 1507 CPDF_ImageLoader::~CPDF_ImageLoader() 1508 { 1509 if (!m_bCached) { 1510 delete m_pBitmap; 1511 delete m_pMask; 1512 } 1513 } 1514