Consolidate colorspace code into intermediate CPDF_BasedCS class
Provide a common member name and eliminate N duplicate implementations
of EnableStdConversion().
-- add initializer in one place.
-- rename one confusing local variable.
Change-Id: I54241e6ff86d88b120469693ece0c3638d25d38d
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/84712
Commit-Queue: Tom Sepez <tsepez@chromium.org>
Reviewed-by: Lei Zhang <thestig@chromium.org>
diff --git a/core/fpdfapi/page/BUILD.gn b/core/fpdfapi/page/BUILD.gn
index 9f39824..1a9607b 100644
--- a/core/fpdfapi/page/BUILD.gn
+++ b/core/fpdfapi/page/BUILD.gn
@@ -11,6 +11,8 @@
"cpdf_allstates.h",
"cpdf_annotcontext.cpp",
"cpdf_annotcontext.h",
+ "cpdf_basedcs.cpp",
+ "cpdf_basedcs.h",
"cpdf_clippath.cpp",
"cpdf_clippath.h",
"cpdf_color.cpp",
diff --git a/core/fpdfapi/page/cpdf_basedcs.cpp b/core/fpdfapi/page/cpdf_basedcs.cpp
new file mode 100644
index 0000000..71dea0a
--- /dev/null
+++ b/core/fpdfapi/page/cpdf_basedcs.cpp
@@ -0,0 +1,17 @@
+// Copyright 2021 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "core/fpdfapi/page/cpdf_basedcs.h"
+
+CPDF_BasedCS::CPDF_BasedCS(Family family) : CPDF_ColorSpace(family) {}
+
+CPDF_BasedCS::~CPDF_BasedCS() = default;
+
+void CPDF_BasedCS::EnableStdConversion(bool bEnabled) {
+ CPDF_ColorSpace::EnableStdConversion(bEnabled);
+ if (m_pBaseCS)
+ m_pBaseCS->EnableStdConversion(bEnabled);
+}
diff --git a/core/fpdfapi/page/cpdf_basedcs.h b/core/fpdfapi/page/cpdf_basedcs.h
new file mode 100644
index 0000000..0dcfcd8
--- /dev/null
+++ b/core/fpdfapi/page/cpdf_basedcs.h
@@ -0,0 +1,29 @@
+// Copyright 2021 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef CORE_FPDFAPI_PAGE_CPDF_BASEDCS_H_
+#define CORE_FPDFAPI_PAGE_CPDF_BASEDCS_H_
+
+#include "core/fpdfapi/page/cpdf_colorspace.h"
+#include "core/fxcrt/retain_ptr.h"
+
+// Represents a color space that is based on another color space. This includes
+// all the special color spaces in ISO 32000, table 62, as well as the ICCBased
+// color space.
+class CPDF_BasedCS : public CPDF_ColorSpace {
+ public:
+ CONSTRUCT_VIA_MAKE_RETAIN;
+ ~CPDF_BasedCS() override;
+
+ void EnableStdConversion(bool bEnabled) final;
+
+ protected:
+ explicit CPDF_BasedCS(Family family);
+
+ RetainPtr<CPDF_ColorSpace> m_pBaseCS; // May be fallback CS in some cases.
+};
+
+#endif // CORE_FPDFAPI_PAGE_CPDF_BASEDCS_H_
diff --git a/core/fpdfapi/page/cpdf_colorspace.cpp b/core/fpdfapi/page/cpdf_colorspace.cpp
index 18c6ce7..3f62209 100644
--- a/core/fpdfapi/page/cpdf_colorspace.cpp
+++ b/core/fpdfapi/page/cpdf_colorspace.cpp
@@ -211,7 +211,7 @@
float m_Ranges[kRangesCount];
};
-class CPDF_ICCBasedCS final : public CPDF_ColorSpace {
+class CPDF_ICCBasedCS final : public CPDF_BasedCS {
public:
CONSTRUCT_VIA_MAKE_RETAIN;
~CPDF_ICCBasedCS() override;
@@ -221,7 +221,6 @@
float* R,
float* G,
float* B) const override;
- void EnableStdConversion(bool bEnabled) override;
void TranslateImageLine(uint8_t* pDestBuf,
const uint8_t* pSrcBuf,
int pixels,
@@ -246,13 +245,12 @@
static std::vector<float> GetRanges(const CPDF_Dictionary* pDict,
uint32_t nComponents);
- RetainPtr<CPDF_ColorSpace> m_pAlterCS;
RetainPtr<CPDF_IccProfile> m_pProfile;
mutable std::vector<uint8_t, FxAllocAllocator<uint8_t>> m_pCache;
std::vector<float> m_pRanges;
};
-class CPDF_IndexedCS final : public CPDF_ColorSpace {
+class CPDF_IndexedCS final : public CPDF_BasedCS {
public:
CONSTRUCT_VIA_MAKE_RETAIN;
~CPDF_IndexedCS() override;
@@ -262,7 +260,6 @@
float* R,
float* G,
float* B) const override;
- void EnableStdConversion(bool bEnabled) override;
uint32_t v_Load(CPDF_Document* pDoc,
const CPDF_Array* pArray,
std::set<const CPDF_Object*>* pVisited) override;
@@ -270,14 +267,13 @@
private:
CPDF_IndexedCS();
- RetainPtr<CPDF_ColorSpace> m_pBaseCS;
uint32_t m_nBaseComponents = 0;
int m_MaxIndex = 0;
ByteString m_Table;
std::vector<float> m_pCompMinMax;
};
-class CPDF_SeparationCS final : public CPDF_ColorSpace {
+class CPDF_SeparationCS final : public CPDF_BasedCS {
public:
CONSTRUCT_VIA_MAKE_RETAIN;
~CPDF_SeparationCS() override;
@@ -291,7 +287,6 @@
float* value,
float* min,
float* max) const override;
- void EnableStdConversion(bool bEnabled) override;
uint32_t v_Load(CPDF_Document* pDoc,
const CPDF_Array* pArray,
std::set<const CPDF_Object*>* pVisited) override;
@@ -299,12 +294,11 @@
private:
CPDF_SeparationCS();
- bool m_IsNoneType;
- RetainPtr<CPDF_ColorSpace> m_pAltCS;
+ bool m_IsNoneType = false;
std::unique_ptr<const CPDF_Function> m_pFunc;
};
-class CPDF_DeviceNCS final : public CPDF_ColorSpace {
+class CPDF_DeviceNCS final : public CPDF_BasedCS {
public:
CONSTRUCT_VIA_MAKE_RETAIN;
~CPDF_DeviceNCS() override;
@@ -318,7 +312,6 @@
float* value,
float* min,
float* max) const override;
- void EnableStdConversion(bool bEnabled) override;
uint32_t v_Load(CPDF_Document* pDoc,
const CPDF_Array* pArray,
std::set<const CPDF_Object*>* pVisited) override;
@@ -326,7 +319,6 @@
private:
CPDF_DeviceNCS();
- RetainPtr<CPDF_ColorSpace> m_pAltCS;
std::unique_ptr<const CPDF_Function> m_pFunc;
};
@@ -909,7 +901,7 @@
}
}
-CPDF_ICCBasedCS::CPDF_ICCBasedCS() : CPDF_ColorSpace(Family::kICCBased) {}
+CPDF_ICCBasedCS::CPDF_ICCBasedCS() : CPDF_BasedCS(Family::kICCBased) {}
CPDF_ICCBasedCS::~CPDF_ICCBasedCS() = default;
@@ -947,8 +939,8 @@
!FindAlternateProfile(pDoc, pDict, pVisited, nComponents)) {
// If there is no alternate profile, use a stock profile as mentioned in
// the PDF 1.7 spec in table 4.16 in the "Alternate" key description.
- DCHECK(!m_pAlterCS);
- m_pAlterCS = GetStockAlternateProfile(nComponents);
+ DCHECK(!m_pBaseCS);
+ m_pBaseCS = GetStockAlternateProfile(nComponents);
}
m_pRanges = GetRanges(pDict, nComponents);
@@ -974,8 +966,8 @@
*B = rgb[2];
return true;
}
- if (m_pAlterCS)
- return m_pAlterCS->GetRGB(pBuf, R, G, B);
+ if (m_pBaseCS)
+ return m_pBaseCS->GetRGB(pBuf, R, G, B);
*R = 0.0f;
*G = 0.0f;
@@ -983,12 +975,6 @@
return true;
}
-void CPDF_ICCBasedCS::EnableStdConversion(bool bEnabled) {
- CPDF_ColorSpace::EnableStdConversion(bEnabled);
- if (m_pAlterCS)
- m_pAlterCS->EnableStdConversion(bEnabled);
-}
-
void CPDF_ICCBasedCS::TranslateImageLine(uint8_t* pDestBuf,
const uint8_t* pSrcBuf,
int pixels,
@@ -1000,9 +986,9 @@
return;
}
if (!m_pProfile->transform()) {
- if (m_pAlterCS) {
- m_pAlterCS->TranslateImageLine(pDestBuf, pSrcBuf, pixels, image_width,
- image_height, false);
+ if (m_pBaseCS) {
+ m_pBaseCS->TranslateImageLine(pDestBuf, pSrcBuf, pixels, image_width,
+ image_height, false);
}
return;
}
@@ -1063,8 +1049,8 @@
return true;
if (m_pProfile->transform())
return m_pProfile->transform()->IsNormal();
- if (m_pAlterCS)
- return m_pAlterCS->IsNormal();
+ if (m_pBaseCS)
+ return m_pBaseCS->IsNormal();
return false;
}
@@ -1087,7 +1073,7 @@
if (pAlterCS->CountComponents() != nExpectedComponents)
return false;
- m_pAlterCS = std::move(pAlterCS);
+ m_pBaseCS = std::move(pAlterCS);
return true;
}
@@ -1123,7 +1109,7 @@
return ranges;
}
-CPDF_IndexedCS::CPDF_IndexedCS() : CPDF_ColorSpace(Family::kIndexed) {}
+CPDF_IndexedCS::CPDF_IndexedCS() : CPDF_BasedCS(Family::kIndexed) {}
CPDF_IndexedCS::~CPDF_IndexedCS() = default;
@@ -1202,13 +1188,7 @@
return m_pBaseCS->GetRGB(comps, R, G, B);
}
-void CPDF_IndexedCS::EnableStdConversion(bool bEnabled) {
- CPDF_ColorSpace::EnableStdConversion(bEnabled);
- if (m_pBaseCS)
- m_pBaseCS->EnableStdConversion(bEnabled);
-}
-
-CPDF_SeparationCS::CPDF_SeparationCS() : CPDF_ColorSpace(Family::kSeparation) {}
+CPDF_SeparationCS::CPDF_SeparationCS() : CPDF_BasedCS(Family::kSeparation) {}
CPDF_SeparationCS::~CPDF_SeparationCS() = default;
@@ -1228,21 +1208,21 @@
if (m_IsNoneType)
return 1;
- const CPDF_Object* pAltCS = pArray->GetDirectObjectAt(2);
- if (pAltCS == m_pArray)
+ const CPDF_Object* pAltArray = pArray->GetDirectObjectAt(2);
+ if (pAltArray == m_pArray)
return 0;
- m_pAltCS = Load(pDoc, pAltCS, pVisited);
- if (!m_pAltCS)
+ m_pBaseCS = Load(pDoc, pAltArray, pVisited);
+ if (!m_pBaseCS)
return 0;
- if (m_pAltCS->IsSpecial())
+ if (m_pBaseCS->IsSpecial())
return 0;
const CPDF_Object* pFuncObj = pArray->GetDirectObjectAt(3);
if (pFuncObj && !pFuncObj->IsName()) {
auto pFunc = CPDF_Function::Load(pFuncObj);
- if (pFunc && pFunc->CountOutputs() >= m_pAltCS->CountComponents())
+ if (pFunc && pFunc->CountOutputs() >= m_pBaseCS->CountComponents())
m_pFunc = std::move(pFunc);
}
return 1;
@@ -1256,14 +1236,14 @@
return false;
if (!m_pFunc) {
- if (!m_pAltCS)
+ if (!m_pBaseCS)
return false;
- int nComps = m_pAltCS->CountComponents();
+ int nComps = m_pBaseCS->CountComponents();
std::vector<float> results(nComps);
for (int i = 0; i < nComps; i++)
results[i] = pBuf[0];
- return m_pAltCS->GetRGB(results, R, G, B);
+ return m_pBaseCS->GetRGB(results, R, G, B);
}
// Using at least 16 elements due to the call m_pAltCS->GetRGB() below.
@@ -1272,8 +1252,8 @@
if (nresults == 0)
return false;
- if (m_pAltCS)
- return m_pAltCS->GetRGB(results, R, G, B);
+ if (m_pBaseCS)
+ return m_pBaseCS->GetRGB(results, R, G, B);
R = 0;
G = 0;
@@ -1281,13 +1261,7 @@
return false;
}
-void CPDF_SeparationCS::EnableStdConversion(bool bEnabled) {
- CPDF_ColorSpace::EnableStdConversion(bEnabled);
- if (m_pAltCS)
- m_pAltCS->EnableStdConversion(bEnabled);
-}
-
-CPDF_DeviceNCS::CPDF_DeviceNCS() : CPDF_ColorSpace(Family::kDeviceN) {}
+CPDF_DeviceNCS::CPDF_DeviceNCS() : CPDF_BasedCS(Family::kDeviceN) {}
CPDF_DeviceNCS::~CPDF_DeviceNCS() = default;
@@ -1311,15 +1285,15 @@
if (!pAltCS || pAltCS == m_pArray)
return 0;
- m_pAltCS = Load(pDoc, pAltCS, pVisited);
+ m_pBaseCS = Load(pDoc, pAltCS, pVisited);
m_pFunc = CPDF_Function::Load(pArray->GetDirectObjectAt(3));
- if (!m_pAltCS || !m_pFunc)
+ if (!m_pBaseCS || !m_pFunc)
return 0;
- if (m_pAltCS->IsSpecial())
+ if (m_pBaseCS->IsSpecial())
return 0;
- if (m_pFunc->CountOutputs() < m_pAltCS->CountComponents())
+ if (m_pFunc->CountOutputs() < m_pBaseCS->CountComponents())
return 0;
return pObj->size();
@@ -1341,12 +1315,5 @@
if (nresults == 0)
return false;
- return m_pAltCS->GetRGB(results, R, G, B);
-}
-
-void CPDF_DeviceNCS::EnableStdConversion(bool bEnabled) {
- CPDF_ColorSpace::EnableStdConversion(bEnabled);
- if (m_pAltCS) {
- m_pAltCS->EnableStdConversion(bEnabled);
- }
+ return m_pBaseCS->GetRGB(results, R, G, B);
}
diff --git a/core/fpdfapi/page/cpdf_patterncs.cpp b/core/fpdfapi/page/cpdf_patterncs.cpp
index adb15c8..f66a41c 100644
--- a/core/fpdfapi/page/cpdf_patterncs.cpp
+++ b/core/fpdfapi/page/cpdf_patterncs.cpp
@@ -11,7 +11,7 @@
#include "core/fpdfapi/parser/cpdf_document.h"
#include "third_party/base/notreached.h"
-CPDF_PatternCS::CPDF_PatternCS() : CPDF_ColorSpace(Family::kPattern) {}
+CPDF_PatternCS::CPDF_PatternCS() : CPDF_BasedCS(Family::kPattern) {}
CPDF_PatternCS::~CPDF_PatternCS() = default;
diff --git a/core/fpdfapi/page/cpdf_patterncs.h b/core/fpdfapi/page/cpdf_patterncs.h
index 7b14e04..dda1d28 100644
--- a/core/fpdfapi/page/cpdf_patterncs.h
+++ b/core/fpdfapi/page/cpdf_patterncs.h
@@ -9,12 +9,12 @@
#include <set>
-#include "core/fpdfapi/page/cpdf_colorspace.h"
+#include "core/fpdfapi/page/cpdf_basedcs.h"
#include "core/fxcrt/retain_ptr.h"
class CPDF_Document;
-class CPDF_PatternCS final : public CPDF_ColorSpace {
+class CPDF_PatternCS final : public CPDF_BasedCS {
public:
CONSTRUCT_VIA_MAKE_RETAIN;
~CPDF_PatternCS() override;
@@ -41,8 +41,6 @@
private:
CPDF_PatternCS();
-
- RetainPtr<CPDF_ColorSpace> m_pBaseCS;
};
#endif // CORE_FPDFAPI_PAGE_CPDF_PATTERNCS_H_