| OLD | NEW |
| 1 // Copyright 2016 PDFium Authors. All rights reserved. | 1 // Copyright 2016 PDFium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com | 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com |
| 6 | 6 |
| 7 #include "core/fpdfapi/page/cpdf_image.h" | 7 #include "core/fpdfapi/page/cpdf_image.h" |
| 8 | 8 |
| 9 #include <algorithm> | 9 #include <algorithm> |
| 10 #include <memory> | 10 #include <memory> |
| (...skipping 17 matching lines...) Expand all Loading... |
| 28 #include "core/fxge/fx_dib.h" | 28 #include "core/fxge/fx_dib.h" |
| 29 #include "third_party/base/numerics/safe_conversions.h" | 29 #include "third_party/base/numerics/safe_conversions.h" |
| 30 #include "third_party/base/ptr_util.h" | 30 #include "third_party/base/ptr_util.h" |
| 31 | 31 |
| 32 CPDF_Image::CPDF_Image(CPDF_Document* pDoc) : m_pDocument(pDoc) {} | 32 CPDF_Image::CPDF_Image(CPDF_Document* pDoc) : m_pDocument(pDoc) {} |
| 33 | 33 |
| 34 CPDF_Image::CPDF_Image(CPDF_Document* pDoc, | 34 CPDF_Image::CPDF_Image(CPDF_Document* pDoc, |
| 35 std::unique_ptr<CPDF_Stream> pStream) | 35 std::unique_ptr<CPDF_Stream> pStream) |
| 36 : m_bIsInline(true), | 36 : m_bIsInline(true), |
| 37 m_pDocument(pDoc), | 37 m_pDocument(pDoc), |
| 38 m_pStream(pStream.get()), | 38 m_pStream(std::move(pStream)), |
| 39 m_pOwnedStream(std::move(pStream)) { | 39 m_pDict(ToDictionary(m_pStream->GetDict()->Clone())) { |
| 40 m_pOwnedDict = | 40 ASSERT(m_pStream.IsOwned()); |
| 41 ToDictionary(std::unique_ptr<CPDF_Object>(m_pStream->GetDict()->Clone())); | 41 ASSERT(m_pDict.IsOwned()); |
| 42 m_pDict = m_pOwnedDict.get(); | |
| 43 FinishInitialization(); | 42 FinishInitialization(); |
| 44 } | 43 } |
| 45 | 44 |
| 46 CPDF_Image::CPDF_Image(CPDF_Document* pDoc, uint32_t dwStreamObjNum) | 45 CPDF_Image::CPDF_Image(CPDF_Document* pDoc, uint32_t dwStreamObjNum) |
| 47 : m_pDocument(pDoc), | 46 : m_pDocument(pDoc), |
| 48 m_pStream(ToStream(pDoc->GetIndirectObject(dwStreamObjNum))) { | 47 m_pStream(ToStream(pDoc->GetIndirectObject(dwStreamObjNum))), |
| 49 m_pDict = m_pStream->GetDict(); | 48 m_pDict(m_pStream->GetDict()) { |
| 49 ASSERT(!m_pStream.IsOwned()); |
| 50 ASSERT(!m_pDict.IsOwned()); |
| 50 FinishInitialization(); | 51 FinishInitialization(); |
| 51 } | 52 } |
| 52 | 53 |
| 53 CPDF_Image::~CPDF_Image() {} | 54 CPDF_Image::~CPDF_Image() {} |
| 54 | 55 |
| 55 void CPDF_Image::FinishInitialization() { | 56 void CPDF_Image::FinishInitialization() { |
| 56 m_pOC = m_pDict->GetDictFor("OC"); | 57 m_pOC = m_pDict->GetDictFor("OC"); |
| 57 m_bIsMask = | 58 m_bIsMask = |
| 58 !m_pDict->KeyExist("ColorSpace") || m_pDict->GetIntegerFor("ImageMask"); | 59 !m_pDict->KeyExist("ColorSpace") || m_pDict->GetIntegerFor("ImageMask"); |
| 59 m_bInterpolate = !!m_pDict->GetIntegerFor("Interpolate"); | 60 m_bInterpolate = !!m_pDict->GetIntegerFor("Interpolate"); |
| 60 m_Height = m_pDict->GetIntegerFor("Height"); | 61 m_Height = m_pDict->GetIntegerFor("Height"); |
| 61 m_Width = m_pDict->GetIntegerFor("Width"); | 62 m_Width = m_pDict->GetIntegerFor("Width"); |
| 62 } | 63 } |
| 63 | 64 |
| 64 void CPDF_Image::ConvertStreamToIndirectObject() { | 65 void CPDF_Image::ConvertStreamToIndirectObject() { |
| 65 if (!m_pStream->IsInline()) | 66 if (!m_pStream->IsInline()) |
| 66 return; | 67 return; |
| 67 | 68 |
| 68 ASSERT(m_pOwnedStream); | 69 ASSERT(m_pStream.IsOwned()); |
| 69 m_pDocument->AddIndirectObject(std::move(m_pOwnedStream)); | 70 m_pDocument->AddIndirectObject(m_pStream.Release()); |
| 70 } | 71 } |
| 71 | 72 |
| 72 std::unique_ptr<CPDF_Dictionary> CPDF_Image::InitJPEG(uint8_t* pData, | 73 std::unique_ptr<CPDF_Dictionary> CPDF_Image::InitJPEG(uint8_t* pData, |
| 73 uint32_t size) { | 74 uint32_t size) { |
| 74 int32_t width; | 75 int32_t width; |
| 75 int32_t height; | 76 int32_t height; |
| 76 int32_t num_comps; | 77 int32_t num_comps; |
| 77 int32_t bits; | 78 int32_t bits; |
| 78 bool color_trans; | 79 bool color_trans; |
| 79 if (!CPDF_ModuleMgr::Get()->GetJpegModule()->LoadInfo( | 80 if (!CPDF_ModuleMgr::Get()->GetJpegModule()->LoadInfo( |
| (...skipping 23 matching lines...) Expand all Loading... |
| 103 pDict->SetNewFor<CPDF_Name>("ColorSpace", csname); | 104 pDict->SetNewFor<CPDF_Name>("ColorSpace", csname); |
| 104 pDict->SetNewFor<CPDF_Number>("BitsPerComponent", bits); | 105 pDict->SetNewFor<CPDF_Number>("BitsPerComponent", bits); |
| 105 pDict->SetNewFor<CPDF_Name>("Filter", "DCTDecode"); | 106 pDict->SetNewFor<CPDF_Name>("Filter", "DCTDecode"); |
| 106 if (!color_trans) { | 107 if (!color_trans) { |
| 107 CPDF_Dictionary* pParms = pDict->SetNewFor<CPDF_Dictionary>("DecodeParms"); | 108 CPDF_Dictionary* pParms = pDict->SetNewFor<CPDF_Dictionary>("DecodeParms"); |
| 108 pParms->SetNewFor<CPDF_Number>("ColorTransform", 0); | 109 pParms->SetNewFor<CPDF_Number>("ColorTransform", 0); |
| 109 } | 110 } |
| 110 m_bIsMask = false; | 111 m_bIsMask = false; |
| 111 m_Width = width; | 112 m_Width = width; |
| 112 m_Height = height; | 113 m_Height = height; |
| 113 if (!m_pStream) { | 114 if (!m_pStream) |
| 114 m_pOwnedStream = pdfium::MakeUnique<CPDF_Stream>(); | 115 m_pStream = pdfium::MakeUnique<CPDF_Stream>(); |
| 115 m_pStream = m_pOwnedStream.get(); | |
| 116 } | |
| 117 return pDict; | 116 return pDict; |
| 118 } | 117 } |
| 119 | 118 |
| 120 void CPDF_Image::SetJpegImage(IFX_SeekableReadStream* pFile) { | 119 void CPDF_Image::SetJpegImage(IFX_SeekableReadStream* pFile) { |
| 121 uint32_t size = pdfium::base::checked_cast<uint32_t>(pFile->GetSize()); | 120 uint32_t size = pdfium::base::checked_cast<uint32_t>(pFile->GetSize()); |
| 122 if (!size) | 121 if (!size) |
| 123 return; | 122 return; |
| 124 | 123 |
| 125 uint32_t dwEstimateSize = std::min(size, 8192U); | 124 uint32_t dwEstimateSize = std::min(size, 8192U); |
| 126 std::vector<uint8_t> data(dwEstimateSize); | 125 std::vector<uint8_t> data(dwEstimateSize); |
| (...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 284 pDest[dest_offset + 1] = (uint8_t)(src_buf[src_offset + 1] * alpha); | 283 pDest[dest_offset + 1] = (uint8_t)(src_buf[src_offset + 1] * alpha); |
| 285 pDest[dest_offset + 2] = (uint8_t)(src_buf[src_offset] * alpha); | 284 pDest[dest_offset + 2] = (uint8_t)(src_buf[src_offset] * alpha); |
| 286 dest_offset += 3; | 285 dest_offset += 3; |
| 287 src_offset += bpp == 24 ? 3 : 4; | 286 src_offset += bpp == 24 ? 3 : 4; |
| 288 } | 287 } |
| 289 | 288 |
| 290 pDest += dest_pitch; | 289 pDest += dest_pitch; |
| 291 dest_offset = 0; | 290 dest_offset = 0; |
| 292 } | 291 } |
| 293 } | 292 } |
| 294 if (!m_pStream) { | 293 if (!m_pStream) |
| 295 m_pOwnedStream = pdfium::MakeUnique<CPDF_Stream>(); | 294 m_pStream = pdfium::MakeUnique<CPDF_Stream>(); |
| 296 m_pStream = m_pOwnedStream.get(); | 295 |
| 297 } | |
| 298 m_pStream->InitStream(dest_buf, dest_size, std::move(pDict)); | 296 m_pStream->InitStream(dest_buf, dest_size, std::move(pDict)); |
| 299 m_bIsMask = pBitmap->IsAlphaMask(); | 297 m_bIsMask = pBitmap->IsAlphaMask(); |
| 300 m_Width = BitmapWidth; | 298 m_Width = BitmapWidth; |
| 301 m_Height = BitmapHeight; | 299 m_Height = BitmapHeight; |
| 302 FX_Free(dest_buf); | 300 FX_Free(dest_buf); |
| 303 } | 301 } |
| 304 | 302 |
| 305 void CPDF_Image::ResetCache(CPDF_Page* pPage, const CFX_DIBitmap* pBitmap) { | 303 void CPDF_Image::ResetCache(CPDF_Page* pPage, const CFX_DIBitmap* pBitmap) { |
| 306 pPage->GetRenderCache()->ResetBitmap(m_pStream, pBitmap); | 304 pPage->GetRenderCache()->ResetBitmap(m_pStream.Get(), pBitmap); |
| 307 } | 305 } |
| 308 | 306 |
| 309 CFX_DIBSource* CPDF_Image::LoadDIBSource(CFX_DIBSource** ppMask, | 307 CFX_DIBSource* CPDF_Image::LoadDIBSource(CFX_DIBSource** ppMask, |
| 310 uint32_t* pMatteColor, | 308 uint32_t* pMatteColor, |
| 311 bool bStdCS, | 309 bool bStdCS, |
| 312 uint32_t GroupFamily, | 310 uint32_t GroupFamily, |
| 313 bool bLoadMask) const { | 311 bool bLoadMask) const { |
| 314 auto source = pdfium::MakeUnique<CPDF_DIBSource>(); | 312 auto source = pdfium::MakeUnique<CPDF_DIBSource>(); |
| 315 if (source->Load(m_pDocument, m_pStream, | 313 if (source->Load(m_pDocument, m_pStream.Get(), |
| 316 reinterpret_cast<CPDF_DIBSource**>(ppMask), pMatteColor, | 314 reinterpret_cast<CPDF_DIBSource**>(ppMask), pMatteColor, |
| 317 nullptr, nullptr, bStdCS, GroupFamily, bLoadMask)) { | 315 nullptr, nullptr, bStdCS, GroupFamily, bLoadMask)) { |
| 318 return source.release(); | 316 return source.release(); |
| 319 } | 317 } |
| 320 return nullptr; | 318 return nullptr; |
| 321 } | 319 } |
| 322 | 320 |
| 323 CFX_DIBSource* CPDF_Image::DetachBitmap() { | 321 CFX_DIBSource* CPDF_Image::DetachBitmap() { |
| 324 CFX_DIBSource* pBitmap = m_pDIBSource; | 322 CFX_DIBSource* pBitmap = m_pDIBSource; |
| 325 m_pDIBSource = nullptr; | 323 m_pDIBSource = nullptr; |
| 326 return pBitmap; | 324 return pBitmap; |
| 327 } | 325 } |
| 328 | 326 |
| 329 CFX_DIBSource* CPDF_Image::DetachMask() { | 327 CFX_DIBSource* CPDF_Image::DetachMask() { |
| 330 CFX_DIBSource* pBitmap = m_pMask; | 328 CFX_DIBSource* pBitmap = m_pMask; |
| 331 m_pMask = nullptr; | 329 m_pMask = nullptr; |
| 332 return pBitmap; | 330 return pBitmap; |
| 333 } | 331 } |
| 334 | 332 |
| 335 bool CPDF_Image::StartLoadDIBSource(CPDF_Dictionary* pFormResource, | 333 bool CPDF_Image::StartLoadDIBSource(CPDF_Dictionary* pFormResource, |
| 336 CPDF_Dictionary* pPageResource, | 334 CPDF_Dictionary* pPageResource, |
| 337 bool bStdCS, | 335 bool bStdCS, |
| 338 uint32_t GroupFamily, | 336 uint32_t GroupFamily, |
| 339 bool bLoadMask) { | 337 bool bLoadMask) { |
| 340 auto source = pdfium::MakeUnique<CPDF_DIBSource>(); | 338 auto source = pdfium::MakeUnique<CPDF_DIBSource>(); |
| 341 int ret = | 339 int ret = source->StartLoadDIBSource(m_pDocument, m_pStream.Get(), true, |
| 342 source->StartLoadDIBSource(m_pDocument, m_pStream, true, pFormResource, | 340 pFormResource, pPageResource, bStdCS, |
| 343 pPageResource, bStdCS, GroupFamily, bLoadMask); | 341 GroupFamily, bLoadMask); |
| 344 if (ret == 2) { | 342 if (ret == 2) { |
| 345 m_pDIBSource = source.release(); | 343 m_pDIBSource = source.release(); |
| 346 return true; | 344 return true; |
| 347 } | 345 } |
| 348 if (!ret) { | 346 if (!ret) { |
| 349 m_pDIBSource = nullptr; | 347 m_pDIBSource = nullptr; |
| 350 return false; | 348 return false; |
| 351 } | 349 } |
| 352 m_pMask = source->DetachMask(); | 350 m_pMask = source->DetachMask(); |
| 353 m_MatteColor = source->GetMatteColor(); | 351 m_MatteColor = source->GetMatteColor(); |
| 354 m_pDIBSource = source.release(); | 352 m_pDIBSource = source.release(); |
| 355 return false; | 353 return false; |
| 356 } | 354 } |
| 357 | 355 |
| 358 bool CPDF_Image::Continue(IFX_Pause* pPause) { | 356 bool CPDF_Image::Continue(IFX_Pause* pPause) { |
| 359 CPDF_DIBSource* pSource = static_cast<CPDF_DIBSource*>(m_pDIBSource); | 357 CPDF_DIBSource* pSource = static_cast<CPDF_DIBSource*>(m_pDIBSource); |
| 360 int ret = pSource->ContinueLoadDIBSource(pPause); | 358 int ret = pSource->ContinueLoadDIBSource(pPause); |
| 361 if (ret == 2) { | 359 if (ret == 2) { |
| 362 return true; | 360 return true; |
| 363 } | 361 } |
| 364 if (!ret) { | 362 if (!ret) { |
| 365 delete m_pDIBSource; | 363 delete m_pDIBSource; |
| 366 m_pDIBSource = nullptr; | 364 m_pDIBSource = nullptr; |
| 367 return false; | 365 return false; |
| 368 } | 366 } |
| 369 m_pMask = pSource->DetachMask(); | 367 m_pMask = pSource->DetachMask(); |
| 370 m_MatteColor = pSource->GetMatteColor(); | 368 m_MatteColor = pSource->GetMatteColor(); |
| 371 return false; | 369 return false; |
| 372 } | 370 } |
| OLD | NEW |