Weakly cache CPDF_IccProfile in CPDF_DocPageData
Change-Id: I591c8a91bcb0d338281d22adbaf0255b7b76a21a
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/58231
Reviewed-by: Lei Zhang <thestig@chromium.org>
Commit-Queue: Tom Sepez <tsepez@chromium.org>
diff --git a/core/fpdfapi/page/cpdf_colorspace.cpp b/core/fpdfapi/page/cpdf_colorspace.cpp
index 40cadc5..1365f8a 100644
--- a/core/fpdfapi/page/cpdf_colorspace.cpp
+++ b/core/fpdfapi/page/cpdf_colorspace.cpp
@@ -902,15 +902,7 @@
CPDF_ICCBasedCS::CPDF_ICCBasedCS(CPDF_Document* pDoc)
: CPDF_ColorSpace(pDoc, PDFCS_ICCBASED) {}
-CPDF_ICCBasedCS::~CPDF_ICCBasedCS() {
- if (m_pProfile && m_pDocument) {
- const CPDF_Stream* pStream = m_pProfile->GetStream();
- m_pProfile.Reset(); // Give up our reference first.
- auto* pPageData = CPDF_DocPageData::FromDocument(m_pDocument.Get());
- if (pPageData)
- pPageData->MaybePurgeIccProfile(pStream);
- }
-}
+CPDF_ICCBasedCS::~CPDF_ICCBasedCS() = default;
uint32_t CPDF_ICCBasedCS::v_Load(CPDF_Document* pDoc,
const CPDF_Array* pArray,
diff --git a/core/fpdfapi/page/cpdf_docpagedata.cpp b/core/fpdfapi/page/cpdf_docpagedata.cpp
index 978de5c..08cbd31 100644
--- a/core/fpdfapi/page/cpdf_docpagedata.cpp
+++ b/core/fpdfapi/page/cpdf_docpagedata.cpp
@@ -165,15 +165,16 @@
CPDF_DocPageData::CPDF_DocPageData() = default;
CPDF_DocPageData::~CPDF_DocPageData() {
+ m_PatternMap.clear();
+
Clear(false);
Clear(true);
- m_PatternMap.clear();
-
for (auto& it : m_FontMap)
delete it.second;
m_FontMap.clear();
+ m_ImageMap.clear();
}
void CPDF_DocPageData::ClearStockFont() {
@@ -183,8 +184,6 @@
void CPDF_DocPageData::Clear(bool bForceRelease) {
m_bForceClear = bForceRelease;
- m_PatternMap.clear();
-
for (auto& it : m_FontMap) {
CPDF_CountedFont* fontData = it.second;
if (!fontData->get())
@@ -196,27 +195,11 @@
m_ColorSpaceMap.clear();
- for (auto it = m_IccProfileMap.begin(); it != m_IccProfileMap.end();) {
- auto curr_it = it++;
- if (bForceRelease || curr_it->second->HasOneRef()) {
- for (auto hash_it = m_HashProfileMap.begin();
- hash_it != m_HashProfileMap.end(); ++hash_it) {
- if (curr_it->first == hash_it->second) {
- m_HashProfileMap.erase(hash_it);
- break;
- }
- }
- m_IccProfileMap.erase(curr_it);
- }
- }
-
for (auto it = m_FontFileMap.begin(); it != m_FontFileMap.end();) {
auto curr_it = it++;
if (bForceRelease || curr_it->second->HasOneRef())
m_FontFileMap.erase(curr_it);
}
-
- m_ImageMap.clear();
}
CPDF_Font* CPDF_DocPageData::GetFont(CPDF_Dictionary* pFontDict) {
@@ -458,8 +441,8 @@
return nullptr;
auto it = m_IccProfileMap.find(pProfileStream);
- if (it != m_IccProfileMap.end())
- return it->second;
+ if (it != m_IccProfileMap.end() && it->second)
+ return pdfium::WrapRetain(it->second.Get());
auto pAccessor = pdfium::MakeRetain<CPDF_StreamAcc>(pProfileStream);
pAccessor->LoadAllDataFiltered();
@@ -470,24 +453,17 @@
ByteString bsDigest(digest, 20);
auto hash_it = m_HashProfileMap.find(bsDigest);
if (hash_it != m_HashProfileMap.end()) {
- auto it_copied_stream = m_IccProfileMap.find(hash_it->second);
- if (it_copied_stream != m_IccProfileMap.end())
- return it_copied_stream->second;
+ auto it_copied_stream = m_IccProfileMap.find(hash_it->second.Get());
+ if (it_copied_stream != m_IccProfileMap.end() && it_copied_stream->second)
+ return pdfium::WrapRetain(it_copied_stream->second.Get());
}
auto pProfile =
pdfium::MakeRetain<CPDF_IccProfile>(pProfileStream, pAccessor->GetSpan());
- m_IccProfileMap[pProfileStream] = pProfile;
- m_HashProfileMap[bsDigest] = pProfileStream;
+ m_IccProfileMap[pProfileStream].Reset(pProfile.Get());
+ m_HashProfileMap[bsDigest].Reset(pProfileStream);
return pProfile;
}
-void CPDF_DocPageData::MaybePurgeIccProfile(const CPDF_Stream* pProfileStream) {
- ASSERT(pProfileStream);
- auto it = m_IccProfileMap.find(pProfileStream);
- if (it != m_IccProfileMap.end() && it->second->HasOneRef())
- m_IccProfileMap.erase(it);
-}
-
RetainPtr<CPDF_StreamAcc> CPDF_DocPageData::GetFontFileStreamAcc(
const CPDF_Stream* pFontStream) {
ASSERT(pFontStream);
diff --git a/core/fpdfapi/page/cpdf_docpagedata.h b/core/fpdfapi/page/cpdf_docpagedata.h
index 89d8264..9fda806 100644
--- a/core/fpdfapi/page/cpdf_docpagedata.h
+++ b/core/fpdfapi/page/cpdf_docpagedata.h
@@ -84,7 +84,6 @@
void MaybePurgeImage(uint32_t dwStreamObjNum);
RetainPtr<CPDF_IccProfile> GetIccProfile(const CPDF_Stream* pProfileStream);
- void MaybePurgeIccProfile(const CPDF_Stream* pProfileStream);
private:
using CPDF_CountedFont = CPDF_CountedObject<CPDF_Font>;
@@ -109,11 +108,11 @@
void Clear(bool bForceRelease);
bool m_bForceClear = false;
- std::map<ByteString, const CPDF_Stream*> m_HashProfileMap;
+ std::map<ByteString, RetainPtr<const CPDF_Stream>> m_HashProfileMap;
std::map<const CPDF_Object*, ObservedPtr<CPDF_ColorSpace>> m_ColorSpaceMap;
std::map<const CPDF_Stream*, RetainPtr<CPDF_StreamAcc>> m_FontFileMap;
std::map<const CPDF_Dictionary*, CPDF_CountedFont*> m_FontMap;
- std::map<const CPDF_Stream*, RetainPtr<CPDF_IccProfile>> m_IccProfileMap;
+ std::map<const CPDF_Stream*, ObservedPtr<CPDF_IccProfile>> m_IccProfileMap;
std::map<uint32_t, RetainPtr<CPDF_Image>> m_ImageMap;
std::map<const CPDF_Object*, ObservedPtr<CPDF_Pattern>> m_PatternMap;
};
diff --git a/core/fpdfapi/page/cpdf_iccprofile.h b/core/fpdfapi/page/cpdf_iccprofile.h
index 2ee1b07..070f884 100644
--- a/core/fpdfapi/page/cpdf_iccprofile.h
+++ b/core/fpdfapi/page/cpdf_iccprofile.h
@@ -9,6 +9,7 @@
#include <memory>
+#include "core/fxcrt/observed_ptr.h"
#include "core/fxcrt/retain_ptr.h"
#include "third_party/base/span.h"
@@ -18,7 +19,7 @@
class CLcmsCmm;
} // namespace fxcodec
-class CPDF_IccProfile final : public Retainable {
+class CPDF_IccProfile final : public Retainable, public Observable {
public:
template <typename T, typename... Args>
friend RetainPtr<T> pdfium::MakeRetain(Args&&... args);