Ensure CPDF_ColorSpace classes are only created via MakeRetain<>.
These are retainable, and it would be bad if somehow someone made
a retain pointer to a non heap-based object.
- Remove stale comment from cpdf_colorspace.h
- Re-organize a few methods in cpdf_colorspace.h, so that simple
accessors come before pure virtuals come before virtuals etc.
Change-Id: I2afc644c7a7e8e407ec3df28d87d5b1a933dae9a
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/56731
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 20adc6a..338025f 100644
--- a/core/fpdfapi/page/cpdf_colorspace.cpp
+++ b/core/fpdfapi/page/cpdf_colorspace.cpp
@@ -107,14 +107,16 @@
class CPDF_CalGray final : public CPDF_ColorSpace {
public:
- explicit CPDF_CalGray(CPDF_Document* pDoc);
- ~CPDF_CalGray() override {}
+ template <typename T, typename... Args>
+ friend RetainPtr<T> pdfium::MakeRetain(Args&&... args);
+
+ ~CPDF_CalGray() override;
// CPDF_ColorSpace:
+ bool GetRGB(const float* pBuf, float* R, float* G, float* B) const override;
uint32_t v_Load(CPDF_Document* pDoc,
const CPDF_Array* pArray,
std::set<const CPDF_Object*>* pVisited) override;
- bool GetRGB(const float* pBuf, float* R, float* G, float* B) const override;
void TranslateImageLine(uint8_t* pDestBuf,
const uint8_t* pSrcBuf,
int pixels,
@@ -125,6 +127,8 @@
private:
static constexpr float kDefaultGamma = 1.0f;
+ explicit CPDF_CalGray(CPDF_Document* pDoc);
+
float m_Gamma = kDefaultGamma;
float m_WhitePoint[kBlackWhitePointCount];
float m_BlackPoint[kBlackWhitePointCount];
@@ -132,26 +136,29 @@
class CPDF_CalRGB final : public CPDF_ColorSpace {
public:
- explicit CPDF_CalRGB(CPDF_Document* pDoc);
- ~CPDF_CalRGB() override {}
+ template <typename T, typename... Args>
+ friend RetainPtr<T> pdfium::MakeRetain(Args&&... args);
- uint32_t v_Load(CPDF_Document* pDoc,
- const CPDF_Array* pArray,
- std::set<const CPDF_Object*>* pVisited) override;
+ ~CPDF_CalRGB() override;
+ // CPDF_ColorSpace:
bool GetRGB(const float* pBuf, float* R, float* G, float* B) const override;
-
void TranslateImageLine(uint8_t* pDestBuf,
const uint8_t* pSrcBuf,
int pixels,
int image_width,
int image_height,
bool bTransMask) const override;
+ uint32_t v_Load(CPDF_Document* pDoc,
+ const CPDF_Array* pArray,
+ std::set<const CPDF_Object*>* pVisited) override;
private:
static constexpr size_t kGammaCount = 3;
static constexpr size_t kMatrixCount = 9;
+ explicit CPDF_CalRGB(CPDF_Document* pDoc);
+
float m_WhitePoint[kBlackWhitePointCount];
float m_BlackPoint[kBlackWhitePointCount];
float m_Gamma[kGammaCount];
@@ -162,29 +169,32 @@
class CPDF_LabCS final : public CPDF_ColorSpace {
public:
- explicit CPDF_LabCS(CPDF_Document* pDoc);
- ~CPDF_LabCS() override {}
+ template <typename T, typename... Args>
+ friend RetainPtr<T> pdfium::MakeRetain(Args&&... args);
- uint32_t v_Load(CPDF_Document* pDoc,
- const CPDF_Array* pArray,
- std::set<const CPDF_Object*>* pVisited) override;
+ ~CPDF_LabCS() override;
+ // CPDF_ColorSpace:
+ bool GetRGB(const float* pBuf, float* R, float* G, float* B) const override;
void GetDefaultValue(int iComponent,
float* value,
float* min,
float* max) const override;
- bool GetRGB(const float* pBuf, float* R, float* G, float* B) const override;
-
void TranslateImageLine(uint8_t* pDestBuf,
const uint8_t* pSrcBuf,
int pixels,
int image_width,
int image_height,
bool bTransMask) const override;
+ uint32_t v_Load(CPDF_Document* pDoc,
+ const CPDF_Array* pArray,
+ std::set<const CPDF_Object*>* pVisited) override;
private:
static constexpr size_t kRangesCount = 4;
+ explicit CPDF_LabCS(CPDF_Document* pDoc);
+
float m_WhitePoint[kBlackWhitePointCount];
float m_BlackPoint[kBlackWhitePointCount];
float m_Ranges[kRangesCount];
@@ -192,13 +202,12 @@
class CPDF_ICCBasedCS final : public CPDF_ColorSpace {
public:
- explicit CPDF_ICCBasedCS(CPDF_Document* pDoc);
+ template <typename T, typename... Args>
+ friend RetainPtr<T> pdfium::MakeRetain(Args&&... args);
+
~CPDF_ICCBasedCS() override;
// CPDF_ColorSpace:
- uint32_t v_Load(CPDF_Document* pDoc,
- const CPDF_Array* pArray,
- std::set<const CPDF_Object*>* pVisited) override;
bool GetRGB(const float* pBuf, float* R, float* G, float* B) const override;
void EnableStdConversion(bool bEnabled) override;
void TranslateImageLine(uint8_t* pDestBuf,
@@ -208,8 +217,13 @@
int image_height,
bool bTransMask) const override;
bool IsNormal() const override;
+ uint32_t v_Load(CPDF_Document* pDoc,
+ const CPDF_Array* pArray,
+ std::set<const CPDF_Object*>* pVisited) override;
private:
+ explicit CPDF_ICCBasedCS(CPDF_Document* pDoc);
+
// If no valid ICC profile or using sRGB, try looking for an alternate.
bool FindAlternateProfile(CPDF_Document* pDoc,
const CPDF_Dictionary* pDict,
@@ -229,18 +243,22 @@
class CPDF_IndexedCS final : public CPDF_ColorSpace {
public:
- explicit CPDF_IndexedCS(CPDF_Document* pDoc);
+ template <typename T, typename... Args>
+ friend RetainPtr<T> pdfium::MakeRetain(Args&&... args);
+
~CPDF_IndexedCS() override;
+ // CPDF_ColorSpace:
+ bool GetRGB(const float* pBuf, 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;
- bool GetRGB(const float* pBuf, float* R, float* G, float* B) const override;
-
- void EnableStdConversion(bool bEnabled) override;
private:
+ explicit CPDF_IndexedCS(CPDF_Document* pDoc);
+
RetainPtr<CPDF_ColorSpace> m_pBaseCS;
uint32_t m_nBaseComponents = 0;
int m_MaxIndex = 0;
@@ -250,43 +268,52 @@
class CPDF_SeparationCS final : public CPDF_ColorSpace {
public:
- explicit CPDF_SeparationCS(CPDF_Document* pDoc);
+ template <typename T, typename... Args>
+ friend RetainPtr<T> pdfium::MakeRetain(Args&&... args);
+
~CPDF_SeparationCS() override;
// CPDF_ColorSpace:
+ bool GetRGB(const float* pBuf, float* R, float* G, float* B) const override;
void GetDefaultValue(int iComponent,
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;
- bool GetRGB(const float* pBuf, float* R, float* G, float* B) const override;
- void EnableStdConversion(bool bEnabled) override;
private:
enum { None, All, Colorant } m_Type;
+
+ explicit CPDF_SeparationCS(CPDF_Document* pDoc);
+
RetainPtr<CPDF_ColorSpace> m_pAltCS;
std::unique_ptr<const CPDF_Function> m_pFunc;
};
class CPDF_DeviceNCS final : public CPDF_ColorSpace {
public:
- explicit CPDF_DeviceNCS(CPDF_Document* pDoc);
+ template <typename T, typename... Args>
+ friend RetainPtr<T> pdfium::MakeRetain(Args&&... args);
+
~CPDF_DeviceNCS() override;
// CPDF_ColorSpace:
+ bool GetRGB(const float* pBuf, float* R, float* G, float* B) const override;
void GetDefaultValue(int iComponent,
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;
- bool GetRGB(const float* pBuf, float* R, float* G, float* B) const override;
- void EnableStdConversion(bool bEnabled) override;
private:
+ explicit CPDF_DeviceNCS(CPDF_Document* pDoc);
+
RetainPtr<CPDF_ColorSpace> m_pAltCS;
std::unique_ptr<const CPDF_Function> m_pFunc;
};
@@ -629,7 +656,7 @@
CPDF_ColorSpace::CPDF_ColorSpace(CPDF_Document* pDoc, int family)
: m_pDocument(pDoc), m_Family(family) {}
-CPDF_ColorSpace::~CPDF_ColorSpace() {}
+CPDF_ColorSpace::~CPDF_ColorSpace() = default;
void CPDF_ColorSpace::SetComponentsForStockCS(uint32_t nComponents) {
ASSERT(!m_pDocument); // Stock colorspace is not associated with a document.
@@ -639,6 +666,8 @@
CPDF_CalGray::CPDF_CalGray(CPDF_Document* pDoc)
: CPDF_ColorSpace(pDoc, PDFCS_CALGRAY) {}
+CPDF_CalGray::~CPDF_CalGray() = default;
+
uint32_t CPDF_CalGray::v_Load(CPDF_Document* pDoc,
const CPDF_Array* pArray,
std::set<const CPDF_Object*>* pVisited) {
@@ -683,6 +712,8 @@
CPDF_CalRGB::CPDF_CalRGB(CPDF_Document* pDoc)
: CPDF_ColorSpace(pDoc, PDFCS_CALRGB) {}
+CPDF_CalRGB::~CPDF_CalRGB() = default;
+
uint32_t CPDF_CalRGB::v_Load(CPDF_Document* pDoc,
const CPDF_Array* pArray,
std::set<const CPDF_Object*>* pVisited) {
@@ -770,6 +801,8 @@
CPDF_LabCS::CPDF_LabCS(CPDF_Document* pDoc)
: CPDF_ColorSpace(pDoc, PDFCS_LAB) {}
+CPDF_LabCS::~CPDF_LabCS() = default;
+
void CPDF_LabCS::GetDefaultValue(int iComponent,
float* value,
float* min,
@@ -1178,7 +1211,7 @@
CPDF_SeparationCS::CPDF_SeparationCS(CPDF_Document* pDoc)
: CPDF_ColorSpace(pDoc, PDFCS_SEPARATION) {}
-CPDF_SeparationCS::~CPDF_SeparationCS() {}
+CPDF_SeparationCS::~CPDF_SeparationCS() = default;
void CPDF_SeparationCS::GetDefaultValue(int iComponent,
float* value,
@@ -1261,7 +1294,7 @@
CPDF_DeviceNCS::CPDF_DeviceNCS(CPDF_Document* pDoc)
: CPDF_ColorSpace(pDoc, PDFCS_DEVICEN) {}
-CPDF_DeviceNCS::~CPDF_DeviceNCS() {}
+CPDF_DeviceNCS::~CPDF_DeviceNCS() = default;
void CPDF_DeviceNCS::GetDefaultValue(int iComponent,
float* value,
diff --git a/core/fpdfapi/page/cpdf_colorspace.h b/core/fpdfapi/page/cpdf_colorspace.h
index 333d9b9..193268b 100644
--- a/core/fpdfapi/page/cpdf_colorspace.h
+++ b/core/fpdfapi/page/cpdf_colorspace.h
@@ -55,6 +55,8 @@
std::set<const CPDF_Object*>* pVisited);
static uint32_t ComponentsForFamily(int family);
+ const CPDF_Array* GetArray() const { return m_pArray.Get(); }
+ CPDF_Document* GetDocument() const { return m_pDocument.Get(); }
size_t GetBufSize() const;
float* CreateBuf() const;
@@ -68,16 +70,15 @@
GetFamily() == PDFCS_INDEXED || GetFamily() == PDFCS_PATTERN;
}
- virtual void GetDefaultValue(int iComponent,
- float* value,
- float* min,
- float* max) const;
-
virtual bool GetRGB(const float* pBuf,
float* R,
float* G,
float* B) const = 0;
+ virtual void GetDefaultValue(int iComponent,
+ float* value,
+ float* min,
+ float* max) const;
virtual void TranslateImageLine(uint8_t* dest_buf,
const uint8_t* src_buf,
int pixels,
@@ -85,11 +86,8 @@
int image_height,
bool bTransMask) const;
virtual void EnableStdConversion(bool bEnabled);
-
virtual bool IsNormal() const;
- // Only call these 3 methods below if GetFamily() returns |PDFCS_PATTERN|.
-
// Returns |this| as a CPDF_PatternCS* if |this| is a pattern.
virtual CPDF_PatternCS* AsPatternCS();
virtual const CPDF_PatternCS* AsPatternCS() const;
@@ -100,9 +98,6 @@
float* G,
float* B) const;
- const CPDF_Array* GetArray() const { return m_pArray.Get(); }
- CPDF_Document* GetDocument() const { return m_pDocument.Get(); }
-
protected:
CPDF_ColorSpace(CPDF_Document* pDoc, int family);
~CPDF_ColorSpace() override;
diff --git a/core/fpdfapi/page/cpdf_devicecs.h b/core/fpdfapi/page/cpdf_devicecs.h
index ab88d74..c8e256c 100644
--- a/core/fpdfapi/page/cpdf_devicecs.h
+++ b/core/fpdfapi/page/cpdf_devicecs.h
@@ -10,16 +10,16 @@
#include <set>
#include "core/fpdfapi/page/cpdf_colorspace.h"
+#include "core/fxcrt/retain_ptr.h"
class CPDF_DeviceCS final : public CPDF_ColorSpace {
public:
- explicit CPDF_DeviceCS(int family);
+ template <typename T, typename... Args>
+ friend RetainPtr<T> pdfium::MakeRetain(Args&&... args);
+
~CPDF_DeviceCS() override;
// CPDF_ColorSpace:
- uint32_t v_Load(CPDF_Document* pDoc,
- const CPDF_Array* pArray,
- std::set<const CPDF_Object*>* pVisited) override;
bool GetRGB(const float* pBuf, float* R, float* G, float* B) const override;
void TranslateImageLine(uint8_t* pDestBuf,
const uint8_t* pSrcBuf,
@@ -27,6 +27,12 @@
int image_width,
int image_height,
bool bTransMask) const override;
+ uint32_t v_Load(CPDF_Document* pDoc,
+ const CPDF_Array* pArray,
+ std::set<const CPDF_Object*>* pVisited) override;
+
+ private:
+ explicit CPDF_DeviceCS(int family);
};
#endif // CORE_FPDFAPI_PAGE_CPDF_DEVICECS_H_
diff --git a/core/fpdfapi/page/cpdf_devicecs_unittest.cpp b/core/fpdfapi/page/cpdf_devicecs_unittest.cpp
index a171d01..fbf2558 100644
--- a/core/fpdfapi/page/cpdf_devicecs_unittest.cpp
+++ b/core/fpdfapi/page/cpdf_devicecs_unittest.cpp
@@ -5,46 +5,48 @@
// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
#include "core/fpdfapi/page/cpdf_devicecs.h"
+
+#include "core/fxcrt/retain_ptr.h"
#include "testing/gtest/include/gtest/gtest.h"
TEST(CPDF_DeviceCSTest, GetRGBFromGray) {
float R;
float G;
float B;
- CPDF_DeviceCS device_gray(PDFCS_DEVICEGRAY);
+ auto device_gray = pdfium::MakeRetain<CPDF_DeviceCS>(PDFCS_DEVICEGRAY);
// Test normal values. For gray, only first value from buf should be used.
float buf[3] = {0.43f, 0.11f, 0.34f};
- ASSERT_TRUE(device_gray.GetRGB(buf, &R, &G, &B));
+ ASSERT_TRUE(device_gray->GetRGB(buf, &R, &G, &B));
EXPECT_FLOAT_EQ(0.43f, R);
EXPECT_FLOAT_EQ(0.43f, G);
EXPECT_FLOAT_EQ(0.43f, B);
buf[0] = 0.872f;
- ASSERT_TRUE(device_gray.GetRGB(buf, &R, &G, &B));
+ ASSERT_TRUE(device_gray->GetRGB(buf, &R, &G, &B));
EXPECT_FLOAT_EQ(0.872f, R);
EXPECT_FLOAT_EQ(0.872f, G);
EXPECT_FLOAT_EQ(0.872f, B);
// Test boundary values
buf[0] = {0.0f};
- ASSERT_TRUE(device_gray.GetRGB(buf, &R, &G, &B));
+ ASSERT_TRUE(device_gray->GetRGB(buf, &R, &G, &B));
EXPECT_FLOAT_EQ(0.0f, R);
EXPECT_FLOAT_EQ(0.0f, G);
EXPECT_FLOAT_EQ(0.0f, B);
buf[0] = 1.0f;
- ASSERT_TRUE(device_gray.GetRGB(buf, &R, &G, &B));
+ ASSERT_TRUE(device_gray->GetRGB(buf, &R, &G, &B));
EXPECT_FLOAT_EQ(1.0f, R);
EXPECT_FLOAT_EQ(1.0f, G);
EXPECT_FLOAT_EQ(1.0f, B);
// Test out of range values
buf[0] = -0.01f;
- ASSERT_TRUE(device_gray.GetRGB(buf, &R, &G, &B));
+ ASSERT_TRUE(device_gray->GetRGB(buf, &R, &G, &B));
EXPECT_FLOAT_EQ(0.0f, R);
EXPECT_FLOAT_EQ(0.0f, G);
EXPECT_FLOAT_EQ(0.0f, B);
buf[0] = 12.5f;
- ASSERT_TRUE(device_gray.GetRGB(buf, &R, &G, &B));
+ ASSERT_TRUE(device_gray->GetRGB(buf, &R, &G, &B));
EXPECT_FLOAT_EQ(1.0f, R);
EXPECT_FLOAT_EQ(1.0f, G);
EXPECT_FLOAT_EQ(1.0f, B);
@@ -54,18 +56,18 @@
float R;
float G;
float B;
- CPDF_DeviceCS device_rgb(PDFCS_DEVICERGB);
+ auto device_rgb = pdfium::MakeRetain<CPDF_DeviceCS>(PDFCS_DEVICERGB);
// Test normal values
float buf[3] = {0.13f, 1.0f, 0.652f};
- ASSERT_TRUE(device_rgb.GetRGB(buf, &R, &G, &B));
+ ASSERT_TRUE(device_rgb->GetRGB(buf, &R, &G, &B));
EXPECT_FLOAT_EQ(0.13f, R);
EXPECT_FLOAT_EQ(1.0f, G);
EXPECT_FLOAT_EQ(0.652f, B);
buf[0] = 0.0f;
buf[1] = 0.52f;
buf[2] = 0.78f;
- ASSERT_TRUE(device_rgb.GetRGB(buf, &R, &G, &B));
+ ASSERT_TRUE(device_rgb->GetRGB(buf, &R, &G, &B));
EXPECT_FLOAT_EQ(0.0f, R);
EXPECT_FLOAT_EQ(0.52f, G);
EXPECT_FLOAT_EQ(0.78f, B);
@@ -73,7 +75,7 @@
// Test out of range values
buf[0] = -10.5f;
buf[1] = 100.0f;
- ASSERT_TRUE(device_rgb.GetRGB(buf, &R, &G, &B));
+ ASSERT_TRUE(device_rgb->GetRGB(buf, &R, &G, &B));
EXPECT_FLOAT_EQ(0.0f, R);
EXPECT_FLOAT_EQ(1.0f, G);
EXPECT_FLOAT_EQ(0.78f, B);
@@ -83,23 +85,23 @@
float R;
float G;
float B;
- CPDF_DeviceCS device_cmyk(PDFCS_DEVICECMYK);
+ auto device_cmyk = pdfium::MakeRetain<CPDF_DeviceCS>(PDFCS_DEVICECMYK);
// Test normal values
float buf[4] = {0.6f, 0.5f, 0.3f, 0.9f};
- ASSERT_TRUE(device_cmyk.GetRGB(buf, &R, &G, &B));
+ ASSERT_TRUE(device_cmyk->GetRGB(buf, &R, &G, &B));
EXPECT_FLOAT_EQ(0.0627451f, R);
EXPECT_FLOAT_EQ(0.0627451f, G);
EXPECT_FLOAT_EQ(0.10588236f, B);
buf[0] = 0.15f;
buf[2] = 0.0f;
- ASSERT_TRUE(device_cmyk.GetRGB(buf, &R, &G, &B));
+ ASSERT_TRUE(device_cmyk->GetRGB(buf, &R, &G, &B));
EXPECT_FLOAT_EQ(0.2f, R);
EXPECT_FLOAT_EQ(0.0862745f, G);
EXPECT_FLOAT_EQ(0.16470589f, B);
buf[2] = 1.0f;
buf[3] = 0.0f;
- ASSERT_TRUE(device_cmyk.GetRGB(buf, &R, &G, &B));
+ ASSERT_TRUE(device_cmyk->GetRGB(buf, &R, &G, &B));
EXPECT_FLOAT_EQ(0.85098046f, R);
EXPECT_FLOAT_EQ(0.552941f, G);
EXPECT_FLOAT_EQ(0.15686275f, B);
@@ -107,7 +109,7 @@
// Test out of range values
buf[2] = 1.5f;
buf[3] = -0.6f;
- ASSERT_TRUE(device_cmyk.GetRGB(buf, &R, &G, &B));
+ ASSERT_TRUE(device_cmyk->GetRGB(buf, &R, &G, &B));
EXPECT_FLOAT_EQ(0.85098046f, R);
EXPECT_FLOAT_EQ(0.552941f, G);
EXPECT_FLOAT_EQ(0.15686275f, B);
diff --git a/core/fpdfapi/page/cpdf_patterncs.h b/core/fpdfapi/page/cpdf_patterncs.h
index e0e2a8a..b6b46f6 100644
--- a/core/fpdfapi/page/cpdf_patterncs.h
+++ b/core/fpdfapi/page/cpdf_patterncs.h
@@ -16,7 +16,9 @@
class CPDF_PatternCS final : public CPDF_ColorSpace {
public:
- explicit CPDF_PatternCS(CPDF_Document* pDoc);
+ template <typename T, typename... Args>
+ friend RetainPtr<T> pdfium::MakeRetain(Args&&... args);
+
~CPDF_PatternCS() override;
// Called for the stock pattern, since it is not initialized via
@@ -24,18 +26,20 @@
void InitializeStockPattern();
// CPDF_ColorSpace:
- uint32_t v_Load(CPDF_Document* pDoc,
- const CPDF_Array* pArray,
- std::set<const CPDF_Object*>* pVisited) override;
bool GetRGB(const float* pBuf, float* R, float* G, float* B) const override;
- CPDF_PatternCS* AsPatternCS() override;
- const CPDF_PatternCS* AsPatternCS() const override;
bool GetPatternRGB(const PatternValue& value,
float* R,
float* G,
float* B) const override;
+ CPDF_PatternCS* AsPatternCS() override;
+ const CPDF_PatternCS* AsPatternCS() const override;
+ uint32_t v_Load(CPDF_Document* pDoc,
+ const CPDF_Array* pArray,
+ std::set<const CPDF_Object*>* pVisited) override;
private:
+ explicit CPDF_PatternCS(CPDF_Document* pDoc);
+
RetainPtr<CPDF_ColorSpace> m_pBaseCS;
};