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