1 // Copyright 2016 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 "core/fpdfapi/render/cpdf_imagecacheentry.h" 8 9 #include <memory> 10 #include <utility> 11 12 #include "core/fpdfapi/page/cpdf_page.h" 13 #include "core/fpdfapi/parser/cpdf_dictionary.h" 14 #include "core/fpdfapi/parser/cpdf_document.h" 15 #include "core/fpdfapi/parser/cpdf_stream.h" 16 #include "core/fpdfapi/render/cpdf_dibsource.h" 17 #include "core/fpdfapi/render/cpdf_pagerendercache.h" 18 #include "core/fpdfapi/render/cpdf_rendercontext.h" 19 #include "core/fpdfapi/render/cpdf_renderstatus.h" 20 #include "core/fxge/dib/cfx_dibitmap.h" 21 22 CPDF_ImageCacheEntry::CPDF_ImageCacheEntry(CPDF_Document* pDoc, 23 const RetainPtr<CPDF_Image>& pImage) 24 : m_dwTimeCount(0), 25 m_MatteColor(0), 26 m_pDocument(pDoc), 27 m_pImage(pImage), 28 m_dwCacheSize(0) {} 29 30 CPDF_ImageCacheEntry::~CPDF_ImageCacheEntry() {} 31 32 void CPDF_ImageCacheEntry::Reset(const RetainPtr<CFX_DIBitmap>& pBitmap) { 33 m_pCachedBitmap.Reset(); 34 if (pBitmap) 35 m_pCachedBitmap = pBitmap->Clone(nullptr); 36 CalcSize(); 37 } 38 39 static uint32_t FPDF_ImageCache_EstimateImageSize( 40 const RetainPtr<CFX_DIBSource>& pDIB) { 41 return pDIB && pDIB->GetBuffer() 42 ? (uint32_t)pDIB->GetHeight() * pDIB->GetPitch() + 43 (uint32_t)pDIB->GetPaletteSize() * 4 44 : 0; 45 } 46 47 RetainPtr<CFX_DIBSource> CPDF_ImageCacheEntry::DetachBitmap() { 48 return std::move(m_pCurBitmap); 49 } 50 51 RetainPtr<CFX_DIBSource> CPDF_ImageCacheEntry::DetachMask() { 52 return std::move(m_pCurMask); 53 } 54 55 int CPDF_ImageCacheEntry::StartGetCachedBitmap( 56 CPDF_Dictionary* pFormResources, 57 CPDF_Dictionary* pPageResources, 58 bool bStdCS, 59 uint32_t GroupFamily, 60 bool bLoadMask, 61 CPDF_RenderStatus* pRenderStatus) { 62 ASSERT(pRenderStatus); 63 64 if (m_pCachedBitmap) { 65 m_pCurBitmap = m_pCachedBitmap; 66 m_pCurMask = m_pCachedMask; 67 return 1; 68 } 69 70 m_pCurBitmap = pdfium::MakeRetain<CPDF_DIBSource>(); 71 int ret = m_pCurBitmap.As<CPDF_DIBSource>()->StartLoadDIBSource( 72 m_pDocument.Get(), m_pImage->GetStream(), true, pFormResources, 73 pPageResources, bStdCS, GroupFamily, bLoadMask); 74 if (ret == 2) 75 return ret; 76 77 if (!ret) { 78 m_pCurBitmap.Reset(); 79 return 0; 80 } 81 ContinueGetCachedBitmap(pRenderStatus); 82 return 0; 83 } 84 85 void CPDF_ImageCacheEntry::ContinueGetCachedBitmap( 86 CPDF_RenderStatus* pRenderStatus) { 87 m_MatteColor = m_pCurBitmap.As<CPDF_DIBSource>()->GetMatteColor(); 88 m_pCurMask = m_pCurBitmap.As<CPDF_DIBSource>()->DetachMask(); 89 CPDF_RenderContext* pContext = pRenderStatus->GetContext(); 90 CPDF_PageRenderCache* pPageRenderCache = pContext->GetPageCache(); 91 m_dwTimeCount = pPageRenderCache->GetTimeCount(); 92 if (m_pCurBitmap->GetPitch() * m_pCurBitmap->GetHeight() < 93 FPDF_HUGE_IMAGE_SIZE) { 94 m_pCachedBitmap = m_pCurBitmap->Clone(nullptr); 95 m_pCurBitmap.Reset(); 96 } else { 97 m_pCachedBitmap = m_pCurBitmap; 98 } 99 if (m_pCurMask) { 100 m_pCachedMask = m_pCurMask->Clone(nullptr); 101 m_pCurMask.Reset(); 102 } 103 m_pCurBitmap = m_pCachedBitmap; 104 m_pCurMask = m_pCachedMask; 105 CalcSize(); 106 } 107 108 int CPDF_ImageCacheEntry::Continue(IFX_PauseIndicator* pPause, 109 CPDF_RenderStatus* pRenderStatus) { 110 int ret = m_pCurBitmap.As<CPDF_DIBSource>()->ContinueLoadDIBSource(pPause); 111 if (!ret) { 112 m_pCurBitmap.Reset(); 113 return 0; 114 } 115 if (ret == 2) 116 return ret; 117 118 ContinueGetCachedBitmap(pRenderStatus); 119 return 0; 120 } 121 122 void CPDF_ImageCacheEntry::CalcSize() { 123 m_dwCacheSize = FPDF_ImageCache_EstimateImageSize(m_pCachedBitmap) + 124 FPDF_ImageCache_EstimateImageSize(m_pCachedMask); 125 } 126