• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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