• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2016 PDFium Authors. All rights reserved.
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 #include "core/fpdfapi/page/cpdf_color.h"
8 
9 #include "core/fpdfapi/page/cpdf_docpagedata.h"
10 #include "core/fpdfapi/parser/cpdf_array.h"
11 #include "core/fpdfapi/parser/cpdf_document.h"
12 #include "core/fxcrt/fx_system.h"
13 
CPDF_Color()14 CPDF_Color::CPDF_Color() {}
15 
~CPDF_Color()16 CPDF_Color::~CPDF_Color() {
17   ReleaseBuffer();
18   ReleaseColorSpace();
19 }
20 
IsPattern() const21 bool CPDF_Color::IsPattern() const {
22   return m_pCS && IsPatternInternal();
23 }
24 
ReleaseBuffer()25 void CPDF_Color::ReleaseBuffer() {
26   if (!m_pBuffer)
27     return;
28 
29   if (IsPatternInternal()) {
30     PatternValue* pvalue = reinterpret_cast<PatternValue*>(m_pBuffer);
31     CPDF_Pattern* pPattern =
32         pvalue->m_pCountedPattern ? pvalue->m_pCountedPattern->get() : nullptr;
33     if (pPattern) {
34       CPDF_DocPageData* pPageData = pPattern->document()->GetPageData();
35       if (pPageData)
36         pPageData->ReleasePattern(pPattern->pattern_obj());
37     }
38   }
39   FX_Free(m_pBuffer);
40   m_pBuffer = nullptr;
41 }
42 
ReleaseColorSpace()43 void CPDF_Color::ReleaseColorSpace() {
44   if (!m_pCS)
45     return;
46 
47   CPDF_Document* pDoc = m_pCS->GetDocument();
48   if (!pDoc)
49     return;
50 
51   auto* pPageData = pDoc->GetPageData();
52   if (pPageData)
53     pPageData->ReleaseColorSpace(m_pCS->GetArray());
54 
55   m_pCS = nullptr;
56 }
57 
IsPatternInternal() const58 bool CPDF_Color::IsPatternInternal() const {
59   return m_pCS->GetFamily() == PDFCS_PATTERN;
60 }
61 
SetColorSpace(CPDF_ColorSpace * pCS)62 void CPDF_Color::SetColorSpace(CPDF_ColorSpace* pCS) {
63   if (m_pCS == pCS) {
64     if (!m_pBuffer)
65       m_pBuffer = pCS->CreateBuf();
66 
67     ReleaseColorSpace();
68     m_pCS = pCS;
69     return;
70   }
71   ReleaseBuffer();
72   ReleaseColorSpace();
73 
74   m_pCS = pCS;
75   if (pCS) {
76     m_pBuffer = pCS->CreateBuf();
77     pCS->GetDefaultColor(m_pBuffer);
78   }
79 }
80 
SetValue(const float * comps)81 void CPDF_Color::SetValue(const float* comps) {
82   if (!m_pBuffer)
83     return;
84   if (!IsPatternInternal())
85     memcpy(m_pBuffer, comps, m_pCS->CountComponents() * sizeof(float));
86 }
87 
SetValue(CPDF_Pattern * pPattern,const float * comps,uint32_t ncomps)88 void CPDF_Color::SetValue(CPDF_Pattern* pPattern,
89                           const float* comps,
90                           uint32_t ncomps) {
91   if (ncomps > kMaxPatternColorComps)
92     return;
93 
94   if (!IsPattern()) {
95     FX_Free(m_pBuffer);
96     m_pCS = CPDF_ColorSpace::GetStockCS(PDFCS_PATTERN);
97     m_pBuffer = m_pCS->CreateBuf();
98   }
99 
100   CPDF_DocPageData* pDocPageData = nullptr;
101   PatternValue* pvalue = reinterpret_cast<PatternValue*>(m_pBuffer);
102   if (pvalue->m_pPattern) {
103     pDocPageData = pvalue->m_pPattern->document()->GetPageData();
104     pDocPageData->ReleasePattern(pvalue->m_pPattern->pattern_obj());
105   }
106   pvalue->m_nComps = ncomps;
107   pvalue->m_pPattern = pPattern;
108   if (ncomps)
109     memcpy(pvalue->m_Comps, comps, ncomps * sizeof(float));
110 
111   pvalue->m_pCountedPattern = nullptr;
112   if (pPattern) {
113     if (!pDocPageData)
114       pDocPageData = pPattern->document()->GetPageData();
115 
116     pvalue->m_pCountedPattern =
117         pDocPageData->FindPatternPtr(pPattern->pattern_obj());
118   }
119 }
120 
Copy(const CPDF_Color * pSrc)121 void CPDF_Color::Copy(const CPDF_Color* pSrc) {
122   ReleaseBuffer();
123   ReleaseColorSpace();
124   m_pCS = pSrc->m_pCS;
125   if (!m_pCS)
126     return;
127 
128   CPDF_Document* pDoc = m_pCS->GetDocument();
129   CPDF_Array* pArray = m_pCS->GetArray();
130   if (pDoc && pArray) {
131     m_pCS = pDoc->GetPageData()->GetCopiedColorSpace(pArray);
132     if (!m_pCS)
133       return;
134   }
135   m_pBuffer = m_pCS->CreateBuf();
136   memcpy(m_pBuffer, pSrc->m_pBuffer, m_pCS->GetBufSize());
137   if (!IsPatternInternal())
138     return;
139 
140   PatternValue* pValue = reinterpret_cast<PatternValue*>(m_pBuffer);
141   CPDF_Pattern* pPattern = pValue->m_pPattern;
142   if (!pPattern)
143     return;
144 
145   pValue->m_pPattern = pPattern->document()->GetPageData()->GetPattern(
146       pPattern->pattern_obj(), false, pPattern->parent_matrix());
147 }
148 
GetRGB(int * R,int * G,int * B) const149 bool CPDF_Color::GetRGB(int* R, int* G, int* B) const {
150   if (!m_pCS || !m_pBuffer)
151     return false;
152 
153   float r = 0.0f;
154   float g = 0.0f;
155   float b = 0.0f;
156   if (!m_pCS->GetRGB(m_pBuffer, &r, &g, &b))
157     return false;
158 
159   *R = static_cast<int32_t>(r * 255 + 0.5f);
160   *G = static_cast<int32_t>(g * 255 + 0.5f);
161   *B = static_cast<int32_t>(b * 255 + 0.5f);
162   return true;
163 }
164 
GetPattern() const165 CPDF_Pattern* CPDF_Color::GetPattern() const {
166   if (!m_pBuffer || !IsPatternInternal())
167     return nullptr;
168 
169   PatternValue* pvalue = reinterpret_cast<PatternValue*>(m_pBuffer);
170   return pvalue->m_pPattern;
171 }
172