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
CPDF_ImageCacheEntry(CPDF_Document * pDoc,CPDF_Stream * pStream)21 CPDF_ImageCacheEntry::CPDF_ImageCacheEntry(CPDF_Document* pDoc,
22 CPDF_Stream* pStream)
23 : m_dwTimeCount(0),
24 m_MatteColor(0),
25 m_pRenderStatus(nullptr),
26 m_pDocument(pDoc),
27 m_pStream(pStream),
28 m_pCurBitmap(nullptr),
29 m_pCurMask(nullptr),
30 m_dwCacheSize(0) {}
31
~CPDF_ImageCacheEntry()32 CPDF_ImageCacheEntry::~CPDF_ImageCacheEntry() {}
33
Reset(const CFX_DIBitmap * pBitmap)34 void CPDF_ImageCacheEntry::Reset(const CFX_DIBitmap* pBitmap) {
35 m_pCachedBitmap.reset();
36 if (pBitmap)
37 m_pCachedBitmap = pBitmap->Clone();
38 CalcSize();
39 }
40
FPDF_ImageCache_EstimateImageSize(const CFX_DIBSource * pDIB)41 static uint32_t FPDF_ImageCache_EstimateImageSize(const CFX_DIBSource* pDIB) {
42 return pDIB && pDIB->GetBuffer()
43 ? (uint32_t)pDIB->GetHeight() * pDIB->GetPitch() +
44 (uint32_t)pDIB->GetPaletteSize() * 4
45 : 0;
46 }
47
DetachBitmap()48 CFX_DIBSource* CPDF_ImageCacheEntry::DetachBitmap() {
49 CFX_DIBSource* pDIBSource = m_pCurBitmap;
50 m_pCurBitmap = nullptr;
51 return pDIBSource;
52 }
53
DetachMask()54 CFX_DIBSource* CPDF_ImageCacheEntry::DetachMask() {
55 CFX_DIBSource* pDIBSource = m_pCurMask;
56 m_pCurMask = nullptr;
57 return pDIBSource;
58 }
59
StartGetCachedBitmap(CPDF_Dictionary * pFormResources,CPDF_Dictionary * pPageResources,bool bStdCS,uint32_t GroupFamily,bool bLoadMask,CPDF_RenderStatus * pRenderStatus,int32_t downsampleWidth,int32_t downsampleHeight)60 int CPDF_ImageCacheEntry::StartGetCachedBitmap(CPDF_Dictionary* pFormResources,
61 CPDF_Dictionary* pPageResources,
62 bool bStdCS,
63 uint32_t GroupFamily,
64 bool bLoadMask,
65 CPDF_RenderStatus* pRenderStatus,
66 int32_t downsampleWidth,
67 int32_t downsampleHeight) {
68 if (m_pCachedBitmap) {
69 m_pCurBitmap = m_pCachedBitmap.get();
70 m_pCurMask = m_pCachedMask.get();
71 return 1;
72 }
73 if (!pRenderStatus)
74 return 0;
75
76 m_pRenderStatus = pRenderStatus;
77 m_pCurBitmap = new CPDF_DIBSource;
78 int ret =
79 ((CPDF_DIBSource*)m_pCurBitmap)
80 ->StartLoadDIBSource(m_pDocument, m_pStream, true, pFormResources,
81 pPageResources, bStdCS, GroupFamily, bLoadMask);
82 if (ret == 2)
83 return ret;
84
85 if (!ret) {
86 delete m_pCurBitmap;
87 m_pCurBitmap = nullptr;
88 return 0;
89 }
90 ContinueGetCachedBitmap();
91 return 0;
92 }
93
ContinueGetCachedBitmap()94 void CPDF_ImageCacheEntry::ContinueGetCachedBitmap() {
95 m_MatteColor = ((CPDF_DIBSource*)m_pCurBitmap)->GetMatteColor();
96 m_pCurMask = ((CPDF_DIBSource*)m_pCurBitmap)->DetachMask();
97 CPDF_RenderContext* pContext = m_pRenderStatus->GetContext();
98 CPDF_PageRenderCache* pPageRenderCache = pContext->GetPageCache();
99 m_dwTimeCount = pPageRenderCache->GetTimeCount();
100 m_pCachedBitmap = pdfium::WrapUnique<CFX_DIBSource>(m_pCurBitmap);
101 if (m_pCurMask)
102 m_pCachedMask = pdfium::WrapUnique<CFX_DIBSource>(m_pCurMask);
103 else
104 m_pCurMask = m_pCachedMask.get();
105 CalcSize();
106 }
107
Continue(IFX_Pause * pPause)108 int CPDF_ImageCacheEntry::Continue(IFX_Pause* pPause) {
109 int ret = ((CPDF_DIBSource*)m_pCurBitmap)->ContinueLoadDIBSource(pPause);
110 if (ret == 2)
111 return ret;
112
113 if (!ret) {
114 delete m_pCurBitmap;
115 m_pCurBitmap = nullptr;
116 return 0;
117 }
118 ContinueGetCachedBitmap();
119 return 0;
120 }
121
CalcSize()122 void CPDF_ImageCacheEntry::CalcSize() {
123 m_dwCacheSize = FPDF_ImageCache_EstimateImageSize(m_pCachedBitmap.get()) +
124 FPDF_ImageCache_EstimateImageSize(m_pCachedMask.get());
125 }
126