1 // Copyright 2016 The PDFium Authors 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 #ifndef CORE_FPDFAPI_PAGE_CPDF_COLORSPACE_H_ 8 #define CORE_FPDFAPI_PAGE_CPDF_COLORSPACE_H_ 9 10 #include <stddef.h> 11 #include <stdint.h> 12 13 #include <array> 14 #include <optional> 15 #include <set> 16 #include <utility> 17 #include <vector> 18 19 #include "core/fpdfapi/page/cpdf_pattern.h" 20 #include "core/fpdfapi/parser/cpdf_array.h" 21 #include "core/fpdfapi/parser/cpdf_object.h" 22 #include "core/fxcrt/bytestring.h" 23 #include "core/fxcrt/observed_ptr.h" 24 #include "core/fxcrt/retain_ptr.h" 25 #include "core/fxcrt/span.h" 26 #include "core/fxcrt/unowned_ptr.h" 27 #include "core/fxge/dib/fx_dib.h" 28 29 class CPDF_Document; 30 class CPDF_IndexedCS; 31 class CPDF_PatternCS; 32 33 constexpr size_t kMaxPatternColorComps = 16; 34 35 class PatternValue { 36 public: 37 PatternValue(); 38 PatternValue(const PatternValue& that); 39 ~PatternValue(); 40 41 void SetComps(pdfium::span<const float> comps); GetComps()42 pdfium::span<const float> GetComps() const { return m_Comps; } GetPattern()43 RetainPtr<CPDF_Pattern> GetPattern() const { return m_pRetainedPattern; } SetPattern(RetainPtr<CPDF_Pattern> pPattern)44 void SetPattern(RetainPtr<CPDF_Pattern> pPattern) { 45 m_pRetainedPattern = std::move(pPattern); 46 } 47 48 private: 49 RetainPtr<CPDF_Pattern> m_pRetainedPattern; 50 std::array<float, kMaxPatternColorComps> m_Comps = {}; 51 }; 52 53 class CPDF_ColorSpace : public Retainable, public Observable { 54 public: 55 enum class Family { 56 kUnknown = 0, 57 kDeviceGray = 1, 58 kDeviceRGB = 2, 59 kDeviceCMYK = 3, 60 kCalGray = 4, 61 kCalRGB = 5, 62 kLab = 6, 63 kICCBased = 7, 64 kSeparation = 8, 65 kDeviceN = 9, 66 kIndexed = 10, 67 kPattern = 11, 68 }; 69 70 static void InitializeGlobals(); 71 static void DestroyGlobals(); 72 73 // `family` must be one of the following: 74 // - `kDeviceGray` 75 // - `kDeviceRGB` 76 // - `kDeviceCMYK` 77 // - `kPattern` 78 static RetainPtr<CPDF_ColorSpace> GetStockCS(Family family); 79 static RetainPtr<CPDF_ColorSpace> GetStockCSForName(const ByteString& name); 80 static RetainPtr<CPDF_ColorSpace> Load( 81 CPDF_Document* pDoc, 82 const CPDF_Object* pObj, 83 std::set<const CPDF_Object*>* pVisited); 84 85 static RetainPtr<CPDF_ColorSpace> AllocateColorSpaceForID( 86 CPDF_Document* pDocument, 87 uint32_t family_id); 88 89 static uint32_t ComponentsForFamily(Family family); 90 91 // Should only be called if this colorspace is not a pattern. 92 std::vector<float> CreateBufAndSetDefaultColor() const; 93 94 uint32_t ComponentCount() const; GetFamily()95 Family GetFamily() const { return m_Family; } IsSpecial()96 bool IsSpecial() const { 97 return GetFamily() == Family::kSeparation || 98 GetFamily() == Family::kDeviceN || GetFamily() == Family::kIndexed || 99 GetFamily() == Family::kPattern; 100 } 101 102 // Wrapper around GetRGB() that returns black (0, 0, 0) when an actual value 103 // can not be determined. GetRGBOrZerosOnError(pdfium::span<const float> pBuf)104 FX_RGB_STRUCT<float> GetRGBOrZerosOnError( 105 pdfium::span<const float> pBuf) const { 106 return GetRGB(pBuf).value_or(FX_RGB_STRUCT<float>{}); 107 } 108 109 // Use CPDF_Pattern::GetPatternColorRef() instead of GetRGB() for patterns. 110 virtual std::optional<FX_RGB_STRUCT<float>> GetRGB( 111 pdfium::span<const float> pBuf) const = 0; 112 113 virtual void GetDefaultValue(int iComponent, 114 float* value, 115 float* min, 116 float* max) const; 117 118 virtual void TranslateImageLine(pdfium::span<uint8_t> dest_span, 119 pdfium::span<const uint8_t> src_span, 120 int pixels, 121 int image_width, 122 int image_height, 123 bool bTransMask) const; 124 virtual void EnableStdConversion(bool bEnabled); 125 virtual bool IsNormal() const; 126 127 // Returns `this` as a CPDF_PatternCS* if `this` is a pattern. 128 virtual const CPDF_PatternCS* AsPatternCS() const; 129 130 // Returns `this` as a CPDF_IndexedCS* if `this` is indexed. 131 virtual const CPDF_IndexedCS* AsIndexedCS() const; 132 133 protected: 134 explicit CPDF_ColorSpace(Family family); 135 ~CPDF_ColorSpace() override; 136 137 // Returns the number of components, or 0 on failure. 138 virtual uint32_t v_Load(CPDF_Document* pDoc, 139 const CPDF_Array* pArray, 140 std::set<const CPDF_Object*>* pVisited) = 0; 141 142 // Stock colorspaces are not loaded normally. This initializes their 143 // components count. 144 void SetComponentsForStockCS(uint32_t nComponents); 145 IsStdConversionEnabled()146 bool IsStdConversionEnabled() const { return m_dwStdConversion != 0; } HasSameArray(const CPDF_Object * pObj)147 bool HasSameArray(const CPDF_Object* pObj) const { return m_pArray == pObj; } 148 149 private: 150 friend class CPDFCalGrayTest_TranslateImageLine_Test; 151 friend class CPDFCalRGBTest_TranslateImageLine_Test; 152 153 static RetainPtr<CPDF_ColorSpace> AllocateColorSpace( 154 ByteStringView bsFamilyName); 155 156 const Family m_Family; 157 uint32_t m_dwStdConversion = 0; 158 uint32_t m_nComponents = 0; 159 RetainPtr<const CPDF_Array> m_pArray; 160 }; 161 162 #endif // CORE_FPDFAPI_PAGE_CPDF_COLORSPACE_H_ 163