Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(805)

Side by Side Diff: core/src/fpdfapi/fpdf_page/fpdf_page_colors.cpp

Issue 1265503005: clang-format all pdfium code. (Closed) Base URL: https://pdfium.googlesource.com/pdfium.git@master
Patch Set: sigh Created 5 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2014 PDFium Authors. All rights reserved. 1 // Copyright 2014 PDFium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6 6
7 #include "../../../include/fpdfapi/fpdf_page.h" 7 #include "../../../include/fpdfapi/fpdf_page.h"
8 #include "../../../include/fpdfapi/fpdf_module.h" 8 #include "../../../include/fpdfapi/fpdf_module.h"
9 #include "../../../include/fxcodec/fx_codec.h" 9 #include "../../../include/fxcodec/fx_codec.h"
10 #include "pageint.h" 10 #include "pageint.h"
11 #include <limits.h> 11 #include <limits.h>
12 12
13 namespace { 13 namespace {
14 14
15 void sRGB_to_AdobeCMYK(FX_FLOAT R, FX_FLOAT G, FX_FLOAT B, FX_FLOAT& c, FX_FLOAT & m, FX_FLOAT& y, FX_FLOAT& k) 15 void sRGB_to_AdobeCMYK(FX_FLOAT R,
16 { 16 FX_FLOAT G,
17 c = 1.0f - R; 17 FX_FLOAT B,
18 m = 1.0f - G; 18 FX_FLOAT& c,
19 y = 1.0f - B; 19 FX_FLOAT& m,
20 k = c; 20 FX_FLOAT& y,
21 if (m < k) { 21 FX_FLOAT& k) {
22 k = m; 22 c = 1.0f - R;
23 } 23 m = 1.0f - G;
24 if (y < k) { 24 y = 1.0f - B;
25 k = y; 25 k = c;
26 } 26 if (m < k) {
27 k = m;
28 }
29 if (y < k) {
30 k = y;
31 }
27 } 32 }
28 33
29 int ComponentsForFamily(int family) { 34 int ComponentsForFamily(int family) {
30 if (family == PDFCS_DEVICERGB) 35 if (family == PDFCS_DEVICERGB)
31 return 3; 36 return 3;
32 if (family == PDFCS_DEVICEGRAY) 37 if (family == PDFCS_DEVICEGRAY)
33 return 1; 38 return 1;
34 return 4; 39 return 4;
35 } 40 }
36 41
37 } // namespace 42 } // namespace
38 43
39 CPDF_DeviceCS::CPDF_DeviceCS(CPDF_Document* pDoc, int family) 44 CPDF_DeviceCS::CPDF_DeviceCS(CPDF_Document* pDoc, int family)
40 : CPDF_ColorSpace(pDoc, family, ComponentsForFamily(family)) { 45 : CPDF_ColorSpace(pDoc, family, ComponentsForFamily(family)) {}
41 } 46
42 47 FX_BOOL CPDF_DeviceCS::GetRGB(FX_FLOAT* pBuf,
43 FX_BOOL CPDF_DeviceCS::GetRGB(FX_FLOAT* pBuf, FX_FLOAT& R, FX_FLOAT& G, FX_FLOAT & B) const 48 FX_FLOAT& R,
44 { 49 FX_FLOAT& G,
45 if (m_Family == PDFCS_DEVICERGB) { 50 FX_FLOAT& B) const {
46 R = pBuf[0]; 51 if (m_Family == PDFCS_DEVICERGB) {
47 if (R < 0) { 52 R = pBuf[0];
48 R = 0; 53 if (R < 0) {
49 } else if (R > 1) { 54 R = 0;
50 R = 1; 55 } else if (R > 1) {
51 } 56 R = 1;
52 G = pBuf[1]; 57 }
53 if (G < 0) { 58 G = pBuf[1];
54 G = 0; 59 if (G < 0) {
55 } else if (G > 1) { 60 G = 0;
56 G = 1; 61 } else if (G > 1) {
57 } 62 G = 1;
58 B = pBuf[2]; 63 }
59 if (B < 0) { 64 B = pBuf[2];
60 B = 0; 65 if (B < 0) {
61 } else if (B > 1) { 66 B = 0;
62 B = 1; 67 } else if (B > 1) {
63 } 68 B = 1;
64 } else if (m_Family == PDFCS_DEVICEGRAY) { 69 }
65 R = *pBuf; 70 } else if (m_Family == PDFCS_DEVICEGRAY) {
66 if (R < 0) { 71 R = *pBuf;
67 R = 0; 72 if (R < 0) {
68 } else if (R > 1) { 73 R = 0;
69 R = 1; 74 } else if (R > 1) {
70 } 75 R = 1;
71 G = B = R; 76 }
72 } else if (m_Family == PDFCS_DEVICECMYK) { 77 G = B = R;
73 if (!m_dwStdConversion) { 78 } else if (m_Family == PDFCS_DEVICECMYK) {
74 AdobeCMYK_to_sRGB(pBuf[0], pBuf[1], pBuf[2], pBuf[3], R, G, B); 79 if (!m_dwStdConversion) {
75 } else { 80 AdobeCMYK_to_sRGB(pBuf[0], pBuf[1], pBuf[2], pBuf[3], R, G, B);
76 FX_FLOAT k = pBuf[3];
77 R = 1.0f - FX_MIN(1.0f, pBuf[0] + k);
78 G = 1.0f - FX_MIN(1.0f, pBuf[1] + k);
79 B = 1.0f - FX_MIN(1.0f, pBuf[2] + k);
80 }
81 } else { 81 } else {
82 ASSERT(m_Family == PDFCS_PATTERN); 82 FX_FLOAT k = pBuf[3];
83 R = G = B = 0; 83 R = 1.0f - FX_MIN(1.0f, pBuf[0] + k);
84 return FALSE; 84 G = 1.0f - FX_MIN(1.0f, pBuf[1] + k);
85 } 85 B = 1.0f - FX_MIN(1.0f, pBuf[2] + k);
86 return TRUE; 86 }
87 } 87 } else {
88 FX_BOOL CPDF_DeviceCS::v_GetCMYK(FX_FLOAT* pBuf, FX_FLOAT& c, FX_FLOAT& m, FX_FL OAT& y, FX_FLOAT& k) const 88 ASSERT(m_Family == PDFCS_PATTERN);
89 { 89 R = G = B = 0;
90 if (m_Family != PDFCS_DEVICECMYK) { 90 return FALSE;
91 return FALSE; 91 }
92 } 92 return TRUE;
93 c = pBuf[0]; 93 }
94 m = pBuf[1]; 94 FX_BOOL CPDF_DeviceCS::v_GetCMYK(FX_FLOAT* pBuf,
95 y = pBuf[2]; 95 FX_FLOAT& c,
96 k = pBuf[3]; 96 FX_FLOAT& m,
97 return TRUE; 97 FX_FLOAT& y,
98 } 98 FX_FLOAT& k) const {
99 FX_BOOL CPDF_DeviceCS::SetRGB(FX_FLOAT* pBuf, FX_FLOAT R, FX_FLOAT G, FX_FLOAT B ) const 99 if (m_Family != PDFCS_DEVICECMYK) {
100 { 100 return FALSE;
101 if (m_Family == PDFCS_DEVICERGB) { 101 }
102 pBuf[0] = R; 102 c = pBuf[0];
103 pBuf[1] = G; 103 m = pBuf[1];
104 pBuf[2] = B; 104 y = pBuf[2];
105 return TRUE; 105 k = pBuf[3];
106 } 106 return TRUE;
107 if (m_Family == PDFCS_DEVICEGRAY) { 107 }
108 if (R == G && R == B) { 108 FX_BOOL CPDF_DeviceCS::SetRGB(FX_FLOAT* pBuf,
109 *pBuf = R; 109 FX_FLOAT R,
110 return TRUE; 110 FX_FLOAT G,
111 } 111 FX_FLOAT B) const {
112 return FALSE; 112 if (m_Family == PDFCS_DEVICERGB) {
113 }
114 if (m_Family == PDFCS_DEVICECMYK) {
115 sRGB_to_AdobeCMYK(R, G, B, pBuf[0], pBuf[1], pBuf[2], pBuf[3]);
116 return TRUE;
117 }
118 return FALSE;
119 }
120 FX_BOOL CPDF_DeviceCS::v_SetCMYK(FX_FLOAT* pBuf, FX_FLOAT c, FX_FLOAT m, FX_FLOA T y, FX_FLOAT k) const
121 {
122 if (m_Family == PDFCS_DEVICERGB) {
123 AdobeCMYK_to_sRGB(c, m, y, k, pBuf[0], pBuf[1], pBuf[2]);
124 return TRUE;
125 }
126 if (m_Family == PDFCS_DEVICECMYK) {
127 pBuf[0] = c;
128 pBuf[1] = m;
129 pBuf[2] = y;
130 pBuf[3] = k;
131 return TRUE;
132 }
133 return FALSE;
134 }
135 static void ReverseRGB(uint8_t* pDestBuf, const uint8_t* pSrcBuf, int pixels)
136 {
137 if (pDestBuf == pSrcBuf)
138 for (int i = 0; i < pixels; i ++) {
139 uint8_t temp = pDestBuf[2];
140 pDestBuf[2] = pDestBuf[0];
141 pDestBuf[0] = temp;
142 pDestBuf += 3;
143 }
144 else
145 for (int i = 0; i < pixels; i ++) {
146 *pDestBuf ++ = pSrcBuf[2];
147 *pDestBuf ++ = pSrcBuf[1];
148 *pDestBuf ++ = pSrcBuf[0];
149 pSrcBuf += 3;
150 }
151 }
152 void CPDF_DeviceCS::TranslateImageLine(uint8_t* pDestBuf, const uint8_t* pSrcBuf , int pixels, int image_width, int image_height, FX_BOOL bTransMask) const
153 {
154 if (bTransMask && m_Family == PDFCS_DEVICECMYK) {
155 for (int i = 0; i < pixels; i ++) {
156 int k = 255 - pSrcBuf[3];
157 pDestBuf[0] = ((255 - pSrcBuf[0]) * k) / 255;
158 pDestBuf[1] = ((255 - pSrcBuf[1]) * k) / 255;
159 pDestBuf[2] = ((255 - pSrcBuf[2]) * k) / 255;
160 pDestBuf += 3;
161 pSrcBuf += 4;
162 }
163 return;
164 }
165 if (m_Family == PDFCS_DEVICERGB) {
166 ReverseRGB(pDestBuf, pSrcBuf, pixels);
167 } else if (m_Family == PDFCS_DEVICEGRAY) {
168 for (int i = 0; i < pixels; i ++) {
169 *pDestBuf ++ = pSrcBuf[i];
170 *pDestBuf ++ = pSrcBuf[i];
171 *pDestBuf ++ = pSrcBuf[i];
172 }
173 } else {
174 for (int i = 0; i < pixels; i ++) {
175 if (!m_dwStdConversion) {
176 AdobeCMYK_to_sRGB1(pSrcBuf[0], pSrcBuf[1], pSrcBuf[2], pSrcBuf[3 ], pDestBuf[2], pDestBuf[1], pDestBuf[0]);
177 } else {
178 uint8_t k = pSrcBuf[3];
179 pDestBuf[2] = 255 - FX_MIN(255, pSrcBuf[0] + k);
180 pDestBuf[1] = 255 - FX_MIN(255, pSrcBuf[1] + k);
181 pDestBuf[0] = 255 - FX_MIN(255, pSrcBuf[2] + k);
182 }
183 pSrcBuf += 4;
184 pDestBuf += 3;
185 }
186 }
187 }
188 const uint8_t g_sRGBSamples1[] = {
189 0, 3, 6, 10, 13, 15, 18, 20, 22, 23, 25, 27, 28, 30, 31, 32 ,
190 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 4 9,
191 49, 50, 51, 52, 53, 53, 54, 55, 56, 56, 57, 58, 58, 59, 60, 6 1,
192 61, 62, 62, 63, 64, 64, 65, 66, 66, 67, 67, 68, 68, 69, 70, 7 0,
193 71, 71, 72, 72, 73, 73, 74, 74, 75, 76, 76, 77, 77, 78, 78, 7 9,
194 79, 79, 80, 80, 81, 81, 82, 82, 83, 83, 84, 84, 85, 85, 85, 8 6,
195 86, 87, 87, 88, 88, 88, 89, 89, 90, 90, 91, 91, 91, 92, 92, 9 3,
196 93, 93, 94, 94, 95, 95, 95, 96, 96, 97, 97, 97, 98, 98, 98, 9 9,
197 99, 99, 100, 100, 101, 101, 101, 102, 102, 102, 103, 103, 103, 104, 104, 10 4,
198 105, 105, 106, 106, 106, 107, 107, 107, 108, 108, 108, 109, 109, 109, 110, 1 10,
199 110, 110, 111, 111, 111, 112, 112, 112, 113, 113, 113, 114, 114, 114, 115, 1 15,
200 115, 115, 116, 116, 116, 117, 117, 117, 118, 118, 118, 118, 119, 119, 119, 1 20,
201 };
202 const uint8_t g_sRGBSamples2[] = {
203 120, 121, 122, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 1 36,
204 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 148, 149, 150, 1 51,
205 152, 153, 154, 155, 155, 156, 157, 158, 159, 159, 160, 161, 162, 163, 163, 1 64,
206 165, 166, 167, 167, 168, 169, 170, 170, 171, 172, 173, 173, 174, 175, 175, 1 76,
207 177, 178, 178, 179, 180, 180, 181, 182, 182, 183, 184, 185, 185, 186, 187, 1 87,
208 188, 189, 189, 190, 190, 191, 192, 192, 193, 194, 194, 195, 196, 196, 197, 1 97,
209 198, 199, 199, 200, 200, 201, 202, 202, 203, 203, 204, 205, 205, 206, 206, 2 07,
210 208, 208, 209, 209, 210, 210, 211, 212, 212, 213, 213, 214, 214, 215, 215, 2 16,
211 216, 217, 218, 218, 219, 219, 220, 220, 221, 221, 222, 222, 223, 223, 224, 2 24,
212 225, 226, 226, 227, 227, 228, 228, 229, 229, 230, 230, 231, 231, 232, 232, 2 33,
213 233, 234, 234, 235, 235, 236, 236, 237, 237, 238, 238, 238, 239, 239, 240, 2 40,
214 241, 241, 242, 242, 243, 243, 244, 244, 245, 245, 246, 246, 246, 247, 247, 2 48,
215 248, 249, 249, 250, 250, 251, 251, 251, 252, 252, 253, 253, 254, 254, 255, 2 55,
216 };
217
218 static FX_FLOAT RGB_Conversion(FX_FLOAT colorComponent)
219 {
220 if (colorComponent > 1) {
221 colorComponent = 1;
222 }
223 if (colorComponent < 0) {
224 colorComponent = 0;
225 }
226 int scale = (int)(colorComponent * 1023);
227 if (scale < 0) {
228 scale = 0;
229 }
230 if (scale < 192) {
231 colorComponent = (g_sRGBSamples1[scale] / 255.0f);
232 }
233 else {
234 colorComponent = (g_sRGBSamples2[scale / 4 - 48] / 255.0f);
235 }
236 return colorComponent;
237 }
238
239 static void XYZ_to_sRGB(FX_FLOAT X, FX_FLOAT Y, FX_FLOAT Z, FX_FLOAT& R, FX_FLOA T& G, FX_FLOAT& B)
240 {
241 FX_FLOAT R1 = 3.2410f * X - 1.5374f * Y - 0.4986f * Z;
242 FX_FLOAT G1 = -0.9692f * X + 1.8760f * Y + 0.0416f * Z;
243 FX_FLOAT B1 = 0.0556f * X - 0.2040f * Y + 1.0570f * Z;
244
245 R = RGB_Conversion(R1);
246 G = RGB_Conversion(G1);
247 B = RGB_Conversion(B1);
248 }
249
250 static void XYZ_to_sRGB_WhitePoint(FX_FLOAT X, FX_FLOAT Y, FX_FLOAT Z, FX_FLOAT& R, FX_FLOAT& G, FX_FLOAT& B, FX_FLOAT Xw, FX_FLOAT Yw, FX_FLOAT Zw)
251 {
252 // The following RGB_xyz is based on
253 // sRGB value {Rx,Ry}={0.64, 0.33}, {Gx,Gy}={0.30, 0.60}, {Bx,By}={0.15, 0.0 6}
254
255 FX_FLOAT Rx = 0.64f, Ry = 0.33f;
256 FX_FLOAT Gx = 0.30f, Gy = 0.60f;
257 FX_FLOAT Bx = 0.15f, By = 0.06f;
258 CFX_Matrix_3by3 RGB_xyz(Rx, Gx, Bx, Ry, Gy, By, 1 - Rx - Ry, 1 - Gx - Gy, 1 - Bx - By);
259 CFX_Vector_3by1 whitePoint(Xw, Yw, Zw);
260 CFX_Vector_3by1 XYZ(X, Y, Z);
261
262 CFX_Vector_3by1 RGB_Sum_XYZ = RGB_xyz.Inverse().TransformVector(whitePoint);
263 CFX_Matrix_3by3 RGB_SUM_XYZ_DIAG(RGB_Sum_XYZ.a, 0, 0, 0, RGB_Sum_XYZ.b, 0, 0 , 0, RGB_Sum_XYZ.c);
264 CFX_Matrix_3by3 M = RGB_xyz.Multiply(RGB_SUM_XYZ_DIAG);
265 CFX_Vector_3by1 RGB = M.Inverse().TransformVector(XYZ);
266
267 R = RGB_Conversion(RGB.a);
268 G = RGB_Conversion(RGB.b);
269 B = RGB_Conversion(RGB.c);
270 }
271 class CPDF_CalGray : public CPDF_ColorSpace
272 {
273 public:
274 explicit CPDF_CalGray(CPDF_Document* pDoc)
275 : CPDF_ColorSpace(pDoc, PDFCS_CALGRAY, 1) {
276 }
277 FX_BOOL v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) override;
278 FX_BOOL GetRGB(FX_FLOAT* pBuf, FX_FLOAT& R, FX_FLOAT& G, FX_FLOAT& B) const override;
279 FX_BOOL SetRGB(FX_FLOAT* pBuf, FX_FLOAT R, FX_FLOAT G, FX_FLOAT B) const override;
280 void TranslateImageLine(uint8_t* pDestBuf, const uint8_t* pSrcBuf, int pixel s, int image_width,
281 int image_height, FX_BOOL bTransMask = FALSE) const override;
282
283 private:
284 FX_FLOAT m_WhitePoint[3];
285 FX_FLOAT m_BlackPoint[3];
286 FX_FLOAT m_Gamma;
287 };
288
289 FX_BOOL CPDF_CalGray::v_Load(CPDF_Document* pDoc, CPDF_Array* pArray)
290 {
291 CPDF_Dictionary* pDict = pArray->GetDict(1);
292 CPDF_Array* pParam = pDict->GetArray(FX_BSTRC("WhitePoint"));
293 int i;
294 for (i = 0; i < 3; i ++) {
295 m_WhitePoint[i] = pParam ? pParam->GetNumber(i) : 0;
296 }
297 pParam = pDict->GetArray(FX_BSTRC("BlackPoint"));
298 for (i = 0; i < 3; i ++) {
299 m_BlackPoint[i] = pParam ? pParam->GetNumber(i) : 0;
300 }
301 m_Gamma = pDict->GetNumber(FX_BSTRC("Gamma"));
302 if (m_Gamma == 0) {
303 m_Gamma = 1.0f;
304 }
305 return TRUE;
306 }
307 FX_BOOL CPDF_CalGray::GetRGB(FX_FLOAT* pBuf, FX_FLOAT& R, FX_FLOAT& G, FX_FLOAT& B) const
308 {
309 R = G = B = *pBuf;
310 return TRUE;
311 }
312 FX_BOOL CPDF_CalGray::SetRGB(FX_FLOAT* pBuf, FX_FLOAT R, FX_FLOAT G, FX_FLOAT B) const
313 {
314 if (R == G && R == B) {
315 *pBuf = R;
316 return TRUE;
317 }
318 return FALSE;
319 }
320 void CPDF_CalGray::TranslateImageLine(uint8_t* pDestBuf, const uint8_t* pSrcBuf, int pixels, int image_width, int image_height, FX_BOOL bTransMask) const
321 {
322 for (int i = 0; i < pixels; i ++) {
323 *pDestBuf ++ = pSrcBuf[i];
324 *pDestBuf ++ = pSrcBuf[i];
325 *pDestBuf ++ = pSrcBuf[i];
326 }
327 }
328 class CPDF_CalRGB : public CPDF_ColorSpace
329 {
330 public:
331 explicit CPDF_CalRGB(CPDF_Document* pDoc)
332 : CPDF_ColorSpace(pDoc, PDFCS_CALRGB, 3) {
333 }
334 FX_BOOL v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) override;
335 FX_BOOL GetRGB(FX_FLOAT* pBuf, FX_FLOAT& R, FX_FLOAT& G, FX_FLOAT& B) const override;
336 FX_BOOL SetRGB(FX_FLOAT* pBuf, FX_FLOAT R, FX_FLOAT G, FX_FLOAT B) const ove rride;
337 void TranslateImageLine(uint8_t* pDestBuf, const uint8_t* pSrcBuf, int pixel s, int image_width,
338 int image_height, FX_BOOL bTransMask = FALSE) const override;
339
340 FX_FLOAT m_WhitePoint[3];
341 FX_FLOAT m_BlackPoint[3];
342 FX_FLOAT m_Gamma[3];
343 FX_FLOAT m_Matrix[9];
344 FX_BOOL m_bGamma;
345 FX_BOOL m_bMatrix;
346 };
347 FX_BOOL CPDF_CalRGB::v_Load(CPDF_Document* pDoc, CPDF_Array* pArray)
348 {
349 CPDF_Dictionary* pDict = pArray->GetDict(1);
350 if (!pDict)
351 return FALSE;
352
353 CPDF_Array* pParam = pDict->GetArray(FX_BSTRC("WhitePoint"));
354 int i;
355 for (i = 0; i < 3; i ++) {
356 m_WhitePoint[i] = pParam ? pParam->GetNumber(i) : 0;
357 }
358 pParam = pDict->GetArray(FX_BSTRC("BlackPoint"));
359 for (i = 0; i < 3; i ++) {
360 m_BlackPoint[i] = pParam ? pParam->GetNumber(i) : 0;
361 }
362 pParam = pDict->GetArray(FX_BSTRC("Gamma"));
363 if (pParam) {
364 m_bGamma = TRUE;
365 for (i = 0; i < 3; i ++) {
366 m_Gamma[i] = pParam->GetNumber(i);
367 }
368 } else {
369 m_bGamma = FALSE;
370 }
371 pParam = pDict->GetArray(FX_BSTRC("Matrix"));
372 if (pParam) {
373 m_bMatrix = TRUE;
374 for (i = 0; i < 9; i ++) {
375 m_Matrix[i] = pParam->GetNumber(i);
376 }
377 } else {
378 m_bMatrix = FALSE;
379 }
380 return TRUE;
381 }
382 FX_BOOL CPDF_CalRGB::GetRGB(FX_FLOAT* pBuf, FX_FLOAT& R, FX_FLOAT& G, FX_FLOAT& B) const
383 {
384 FX_FLOAT A_ = pBuf[0];
385 FX_FLOAT B_ = pBuf[1];
386 FX_FLOAT C_ = pBuf[2];
387 if (m_bGamma) {
388 A_ = (FX_FLOAT)FXSYS_pow(A_, m_Gamma[0]);
389 B_ = (FX_FLOAT)FXSYS_pow(B_, m_Gamma[1]);
390 C_ = (FX_FLOAT)FXSYS_pow(C_, m_Gamma[2]);
391 }
392 FX_FLOAT X, Y, Z;
393 if (m_bMatrix) {
394 X = m_Matrix[0] * A_ + m_Matrix[3] * B_ + m_Matrix[6] * C_;
395 Y = m_Matrix[1] * A_ + m_Matrix[4] * B_ + m_Matrix[7] * C_;
396 Z = m_Matrix[2] * A_ + m_Matrix[5] * B_ + m_Matrix[8] * C_;
397 } else {
398 X = A_;
399 Y = B_;
400 Z = C_;
401 }
402 XYZ_to_sRGB_WhitePoint(X, Y, Z, R, G, B, m_WhitePoint[0], m_WhitePoint[1], m _WhitePoint[2]);
403 return TRUE;
404 }
405 FX_BOOL CPDF_CalRGB::SetRGB(FX_FLOAT* pBuf, FX_FLOAT R, FX_FLOAT G, FX_FLOAT B) const
406 {
407 pBuf[0] = R; 113 pBuf[0] = R;
408 pBuf[1] = G; 114 pBuf[1] = G;
409 pBuf[2] = B; 115 pBuf[2] = B;
410 return TRUE; 116 return TRUE;
411 } 117 }
412 void CPDF_CalRGB::TranslateImageLine(uint8_t* pDestBuf, const uint8_t* pSrcBuf, int pixels, int image_width, int image_height, FX_BOOL bTransMask) const 118 if (m_Family == PDFCS_DEVICEGRAY) {
413 { 119 if (R == G && R == B) {
414 if (bTransMask) { 120 *pBuf = R;
415 FX_FLOAT Cal[3]; 121 return TRUE;
416 FX_FLOAT R, G, B; 122 }
417 for(int i = 0; i < pixels; i ++) { 123 return FALSE;
418 Cal[0] = ((FX_FLOAT)pSrcBuf[2]) / 255; 124 }
419 Cal[1] = ((FX_FLOAT)pSrcBuf[1]) / 255; 125 if (m_Family == PDFCS_DEVICECMYK) {
420 Cal[2] = ((FX_FLOAT)pSrcBuf[0]) / 255; 126 sRGB_to_AdobeCMYK(R, G, B, pBuf[0], pBuf[1], pBuf[2], pBuf[3]);
421 GetRGB(Cal, R, G, B); 127 return TRUE;
422 pDestBuf[0] = FXSYS_round(B * 255); 128 }
423 pDestBuf[1] = FXSYS_round(G * 255); 129 return FALSE;
424 pDestBuf[2] = FXSYS_round(R * 255); 130 }
425 pSrcBuf += 3; 131 FX_BOOL CPDF_DeviceCS::v_SetCMYK(FX_FLOAT* pBuf,
426 pDestBuf += 3; 132 FX_FLOAT c,
133 FX_FLOAT m,
134 FX_FLOAT y,
135 FX_FLOAT k) const {
136 if (m_Family == PDFCS_DEVICERGB) {
137 AdobeCMYK_to_sRGB(c, m, y, k, pBuf[0], pBuf[1], pBuf[2]);
138 return TRUE;
139 }
140 if (m_Family == PDFCS_DEVICECMYK) {
141 pBuf[0] = c;
142 pBuf[1] = m;
143 pBuf[2] = y;
144 pBuf[3] = k;
145 return TRUE;
146 }
147 return FALSE;
148 }
149 static void ReverseRGB(uint8_t* pDestBuf, const uint8_t* pSrcBuf, int pixels) {
150 if (pDestBuf == pSrcBuf)
151 for (int i = 0; i < pixels; i++) {
152 uint8_t temp = pDestBuf[2];
153 pDestBuf[2] = pDestBuf[0];
154 pDestBuf[0] = temp;
155 pDestBuf += 3;
156 }
157 else
158 for (int i = 0; i < pixels; i++) {
159 *pDestBuf++ = pSrcBuf[2];
160 *pDestBuf++ = pSrcBuf[1];
161 *pDestBuf++ = pSrcBuf[0];
162 pSrcBuf += 3;
163 }
164 }
165 void CPDF_DeviceCS::TranslateImageLine(uint8_t* pDestBuf,
166 const uint8_t* pSrcBuf,
167 int pixels,
168 int image_width,
169 int image_height,
170 FX_BOOL bTransMask) const {
171 if (bTransMask && m_Family == PDFCS_DEVICECMYK) {
172 for (int i = 0; i < pixels; i++) {
173 int k = 255 - pSrcBuf[3];
174 pDestBuf[0] = ((255 - pSrcBuf[0]) * k) / 255;
175 pDestBuf[1] = ((255 - pSrcBuf[1]) * k) / 255;
176 pDestBuf[2] = ((255 - pSrcBuf[2]) * k) / 255;
177 pDestBuf += 3;
178 pSrcBuf += 4;
179 }
180 return;
181 }
182 if (m_Family == PDFCS_DEVICERGB) {
183 ReverseRGB(pDestBuf, pSrcBuf, pixels);
184 } else if (m_Family == PDFCS_DEVICEGRAY) {
185 for (int i = 0; i < pixels; i++) {
186 *pDestBuf++ = pSrcBuf[i];
187 *pDestBuf++ = pSrcBuf[i];
188 *pDestBuf++ = pSrcBuf[i];
189 }
190 } else {
191 for (int i = 0; i < pixels; i++) {
192 if (!m_dwStdConversion) {
193 AdobeCMYK_to_sRGB1(pSrcBuf[0], pSrcBuf[1], pSrcBuf[2], pSrcBuf[3],
194 pDestBuf[2], pDestBuf[1], pDestBuf[0]);
195 } else {
196 uint8_t k = pSrcBuf[3];
197 pDestBuf[2] = 255 - FX_MIN(255, pSrcBuf[0] + k);
198 pDestBuf[1] = 255 - FX_MIN(255, pSrcBuf[1] + k);
199 pDestBuf[0] = 255 - FX_MIN(255, pSrcBuf[2] + k);
200 }
201 pSrcBuf += 4;
202 pDestBuf += 3;
203 }
204 }
205 }
206 const uint8_t g_sRGBSamples1[] = {
207 0, 3, 6, 10, 13, 15, 18, 20, 22, 23, 25, 27, 28, 30, 31,
208 32, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
209 48, 49, 49, 50, 51, 52, 53, 53, 54, 55, 56, 56, 57, 58, 58,
210 59, 60, 61, 61, 62, 62, 63, 64, 64, 65, 66, 66, 67, 67, 68,
211 68, 69, 70, 70, 71, 71, 72, 72, 73, 73, 74, 74, 75, 76, 76,
212 77, 77, 78, 78, 79, 79, 79, 80, 80, 81, 81, 82, 82, 83, 83,
213 84, 84, 85, 85, 85, 86, 86, 87, 87, 88, 88, 88, 89, 89, 90,
214 90, 91, 91, 91, 92, 92, 93, 93, 93, 94, 94, 95, 95, 95, 96,
215 96, 97, 97, 97, 98, 98, 98, 99, 99, 99, 100, 100, 101, 101, 101,
216 102, 102, 102, 103, 103, 103, 104, 104, 104, 105, 105, 106, 106, 106, 107,
217 107, 107, 108, 108, 108, 109, 109, 109, 110, 110, 110, 110, 111, 111, 111,
218 112, 112, 112, 113, 113, 113, 114, 114, 114, 115, 115, 115, 115, 116, 116,
219 116, 117, 117, 117, 118, 118, 118, 118, 119, 119, 119, 120,
220 };
221 const uint8_t g_sRGBSamples2[] = {
222 120, 121, 122, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135,
223 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 148, 149,
224 150, 151, 152, 153, 154, 155, 155, 156, 157, 158, 159, 159, 160, 161, 162,
225 163, 163, 164, 165, 166, 167, 167, 168, 169, 170, 170, 171, 172, 173, 173,
226 174, 175, 175, 176, 177, 178, 178, 179, 180, 180, 181, 182, 182, 183, 184,
227 185, 185, 186, 187, 187, 188, 189, 189, 190, 190, 191, 192, 192, 193, 194,
228 194, 195, 196, 196, 197, 197, 198, 199, 199, 200, 200, 201, 202, 202, 203,
229 203, 204, 205, 205, 206, 206, 207, 208, 208, 209, 209, 210, 210, 211, 212,
230 212, 213, 213, 214, 214, 215, 215, 216, 216, 217, 218, 218, 219, 219, 220,
231 220, 221, 221, 222, 222, 223, 223, 224, 224, 225, 226, 226, 227, 227, 228,
232 228, 229, 229, 230, 230, 231, 231, 232, 232, 233, 233, 234, 234, 235, 235,
233 236, 236, 237, 237, 238, 238, 238, 239, 239, 240, 240, 241, 241, 242, 242,
234 243, 243, 244, 244, 245, 245, 246, 246, 246, 247, 247, 248, 248, 249, 249,
235 250, 250, 251, 251, 251, 252, 252, 253, 253, 254, 254, 255, 255,
236 };
237
238 static FX_FLOAT RGB_Conversion(FX_FLOAT colorComponent) {
239 if (colorComponent > 1) {
240 colorComponent = 1;
241 }
242 if (colorComponent < 0) {
243 colorComponent = 0;
244 }
245 int scale = (int)(colorComponent * 1023);
246 if (scale < 0) {
247 scale = 0;
248 }
249 if (scale < 192) {
250 colorComponent = (g_sRGBSamples1[scale] / 255.0f);
251 } else {
252 colorComponent = (g_sRGBSamples2[scale / 4 - 48] / 255.0f);
253 }
254 return colorComponent;
255 }
256
257 static void XYZ_to_sRGB(FX_FLOAT X,
258 FX_FLOAT Y,
259 FX_FLOAT Z,
260 FX_FLOAT& R,
261 FX_FLOAT& G,
262 FX_FLOAT& B) {
263 FX_FLOAT R1 = 3.2410f * X - 1.5374f * Y - 0.4986f * Z;
264 FX_FLOAT G1 = -0.9692f * X + 1.8760f * Y + 0.0416f * Z;
265 FX_FLOAT B1 = 0.0556f * X - 0.2040f * Y + 1.0570f * Z;
266
267 R = RGB_Conversion(R1);
268 G = RGB_Conversion(G1);
269 B = RGB_Conversion(B1);
270 }
271
272 static void XYZ_to_sRGB_WhitePoint(FX_FLOAT X,
273 FX_FLOAT Y,
274 FX_FLOAT Z,
275 FX_FLOAT& R,
276 FX_FLOAT& G,
277 FX_FLOAT& B,
278 FX_FLOAT Xw,
279 FX_FLOAT Yw,
280 FX_FLOAT Zw) {
281 // The following RGB_xyz is based on
282 // sRGB value {Rx,Ry}={0.64, 0.33}, {Gx,Gy}={0.30, 0.60}, {Bx,By}={0.15, 0.06}
283
284 FX_FLOAT Rx = 0.64f, Ry = 0.33f;
285 FX_FLOAT Gx = 0.30f, Gy = 0.60f;
286 FX_FLOAT Bx = 0.15f, By = 0.06f;
287 CFX_Matrix_3by3 RGB_xyz(Rx, Gx, Bx, Ry, Gy, By, 1 - Rx - Ry, 1 - Gx - Gy,
288 1 - Bx - By);
289 CFX_Vector_3by1 whitePoint(Xw, Yw, Zw);
290 CFX_Vector_3by1 XYZ(X, Y, Z);
291
292 CFX_Vector_3by1 RGB_Sum_XYZ = RGB_xyz.Inverse().TransformVector(whitePoint);
293 CFX_Matrix_3by3 RGB_SUM_XYZ_DIAG(RGB_Sum_XYZ.a, 0, 0, 0, RGB_Sum_XYZ.b, 0, 0,
294 0, RGB_Sum_XYZ.c);
295 CFX_Matrix_3by3 M = RGB_xyz.Multiply(RGB_SUM_XYZ_DIAG);
296 CFX_Vector_3by1 RGB = M.Inverse().TransformVector(XYZ);
297
298 R = RGB_Conversion(RGB.a);
299 G = RGB_Conversion(RGB.b);
300 B = RGB_Conversion(RGB.c);
301 }
302 class CPDF_CalGray : public CPDF_ColorSpace {
303 public:
304 explicit CPDF_CalGray(CPDF_Document* pDoc)
305 : CPDF_ColorSpace(pDoc, PDFCS_CALGRAY, 1) {}
306 FX_BOOL v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) override;
307 FX_BOOL GetRGB(FX_FLOAT* pBuf,
308 FX_FLOAT& R,
309 FX_FLOAT& G,
310 FX_FLOAT& B) const override;
311 FX_BOOL SetRGB(FX_FLOAT* pBuf,
312 FX_FLOAT R,
313 FX_FLOAT G,
314 FX_FLOAT B) const override;
315 void TranslateImageLine(uint8_t* pDestBuf,
316 const uint8_t* pSrcBuf,
317 int pixels,
318 int image_width,
319 int image_height,
320 FX_BOOL bTransMask = FALSE) const override;
321
322 private:
323 FX_FLOAT m_WhitePoint[3];
324 FX_FLOAT m_BlackPoint[3];
325 FX_FLOAT m_Gamma;
326 };
327
328 FX_BOOL CPDF_CalGray::v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) {
329 CPDF_Dictionary* pDict = pArray->GetDict(1);
330 CPDF_Array* pParam = pDict->GetArray(FX_BSTRC("WhitePoint"));
331 int i;
332 for (i = 0; i < 3; i++) {
333 m_WhitePoint[i] = pParam ? pParam->GetNumber(i) : 0;
334 }
335 pParam = pDict->GetArray(FX_BSTRC("BlackPoint"));
336 for (i = 0; i < 3; i++) {
337 m_BlackPoint[i] = pParam ? pParam->GetNumber(i) : 0;
338 }
339 m_Gamma = pDict->GetNumber(FX_BSTRC("Gamma"));
340 if (m_Gamma == 0) {
341 m_Gamma = 1.0f;
342 }
343 return TRUE;
344 }
345 FX_BOOL CPDF_CalGray::GetRGB(FX_FLOAT* pBuf,
346 FX_FLOAT& R,
347 FX_FLOAT& G,
348 FX_FLOAT& B) const {
349 R = G = B = *pBuf;
350 return TRUE;
351 }
352 FX_BOOL CPDF_CalGray::SetRGB(FX_FLOAT* pBuf,
353 FX_FLOAT R,
354 FX_FLOAT G,
355 FX_FLOAT B) const {
356 if (R == G && R == B) {
357 *pBuf = R;
358 return TRUE;
359 }
360 return FALSE;
361 }
362 void CPDF_CalGray::TranslateImageLine(uint8_t* pDestBuf,
363 const uint8_t* pSrcBuf,
364 int pixels,
365 int image_width,
366 int image_height,
367 FX_BOOL bTransMask) const {
368 for (int i = 0; i < pixels; i++) {
369 *pDestBuf++ = pSrcBuf[i];
370 *pDestBuf++ = pSrcBuf[i];
371 *pDestBuf++ = pSrcBuf[i];
372 }
373 }
374 class CPDF_CalRGB : public CPDF_ColorSpace {
375 public:
376 explicit CPDF_CalRGB(CPDF_Document* pDoc)
377 : CPDF_ColorSpace(pDoc, PDFCS_CALRGB, 3) {}
378 FX_BOOL v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) override;
379 FX_BOOL GetRGB(FX_FLOAT* pBuf,
380 FX_FLOAT& R,
381 FX_FLOAT& G,
382 FX_FLOAT& B) const override;
383 FX_BOOL SetRGB(FX_FLOAT* pBuf,
384 FX_FLOAT R,
385 FX_FLOAT G,
386 FX_FLOAT B) const override;
387 void TranslateImageLine(uint8_t* pDestBuf,
388 const uint8_t* pSrcBuf,
389 int pixels,
390 int image_width,
391 int image_height,
392 FX_BOOL bTransMask = FALSE) const override;
393
394 FX_FLOAT m_WhitePoint[3];
395 FX_FLOAT m_BlackPoint[3];
396 FX_FLOAT m_Gamma[3];
397 FX_FLOAT m_Matrix[9];
398 FX_BOOL m_bGamma;
399 FX_BOOL m_bMatrix;
400 };
401 FX_BOOL CPDF_CalRGB::v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) {
402 CPDF_Dictionary* pDict = pArray->GetDict(1);
403 if (!pDict)
404 return FALSE;
405
406 CPDF_Array* pParam = pDict->GetArray(FX_BSTRC("WhitePoint"));
407 int i;
408 for (i = 0; i < 3; i++) {
409 m_WhitePoint[i] = pParam ? pParam->GetNumber(i) : 0;
410 }
411 pParam = pDict->GetArray(FX_BSTRC("BlackPoint"));
412 for (i = 0; i < 3; i++) {
413 m_BlackPoint[i] = pParam ? pParam->GetNumber(i) : 0;
414 }
415 pParam = pDict->GetArray(FX_BSTRC("Gamma"));
416 if (pParam) {
417 m_bGamma = TRUE;
418 for (i = 0; i < 3; i++) {
419 m_Gamma[i] = pParam->GetNumber(i);
420 }
421 } else {
422 m_bGamma = FALSE;
423 }
424 pParam = pDict->GetArray(FX_BSTRC("Matrix"));
425 if (pParam) {
426 m_bMatrix = TRUE;
427 for (i = 0; i < 9; i++) {
428 m_Matrix[i] = pParam->GetNumber(i);
429 }
430 } else {
431 m_bMatrix = FALSE;
432 }
433 return TRUE;
434 }
435 FX_BOOL CPDF_CalRGB::GetRGB(FX_FLOAT* pBuf,
436 FX_FLOAT& R,
437 FX_FLOAT& G,
438 FX_FLOAT& B) const {
439 FX_FLOAT A_ = pBuf[0];
440 FX_FLOAT B_ = pBuf[1];
441 FX_FLOAT C_ = pBuf[2];
442 if (m_bGamma) {
443 A_ = (FX_FLOAT)FXSYS_pow(A_, m_Gamma[0]);
444 B_ = (FX_FLOAT)FXSYS_pow(B_, m_Gamma[1]);
445 C_ = (FX_FLOAT)FXSYS_pow(C_, m_Gamma[2]);
446 }
447 FX_FLOAT X, Y, Z;
448 if (m_bMatrix) {
449 X = m_Matrix[0] * A_ + m_Matrix[3] * B_ + m_Matrix[6] * C_;
450 Y = m_Matrix[1] * A_ + m_Matrix[4] * B_ + m_Matrix[7] * C_;
451 Z = m_Matrix[2] * A_ + m_Matrix[5] * B_ + m_Matrix[8] * C_;
452 } else {
453 X = A_;
454 Y = B_;
455 Z = C_;
456 }
457 XYZ_to_sRGB_WhitePoint(X, Y, Z, R, G, B, m_WhitePoint[0], m_WhitePoint[1],
458 m_WhitePoint[2]);
459 return TRUE;
460 }
461 FX_BOOL CPDF_CalRGB::SetRGB(FX_FLOAT* pBuf,
462 FX_FLOAT R,
463 FX_FLOAT G,
464 FX_FLOAT B) const {
465 pBuf[0] = R;
466 pBuf[1] = G;
467 pBuf[2] = B;
468 return TRUE;
469 }
470 void CPDF_CalRGB::TranslateImageLine(uint8_t* pDestBuf,
471 const uint8_t* pSrcBuf,
472 int pixels,
473 int image_width,
474 int image_height,
475 FX_BOOL bTransMask) const {
476 if (bTransMask) {
477 FX_FLOAT Cal[3];
478 FX_FLOAT R, G, B;
479 for (int i = 0; i < pixels; i++) {
480 Cal[0] = ((FX_FLOAT)pSrcBuf[2]) / 255;
481 Cal[1] = ((FX_FLOAT)pSrcBuf[1]) / 255;
482 Cal[2] = ((FX_FLOAT)pSrcBuf[0]) / 255;
483 GetRGB(Cal, R, G, B);
484 pDestBuf[0] = FXSYS_round(B * 255);
485 pDestBuf[1] = FXSYS_round(G * 255);
486 pDestBuf[2] = FXSYS_round(R * 255);
487 pSrcBuf += 3;
488 pDestBuf += 3;
489 }
490 }
491 ReverseRGB(pDestBuf, pSrcBuf, pixels);
492 }
493 class CPDF_LabCS : public CPDF_ColorSpace {
494 public:
495 explicit CPDF_LabCS(CPDF_Document* pDoc)
496 : CPDF_ColorSpace(pDoc, PDFCS_LAB, 3) {}
497 void GetDefaultValue(int iComponent,
498 FX_FLOAT& value,
499 FX_FLOAT& min,
500 FX_FLOAT& max) const override;
501 FX_BOOL v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) override;
502 FX_BOOL GetRGB(FX_FLOAT* pBuf,
503 FX_FLOAT& R,
504 FX_FLOAT& G,
505 FX_FLOAT& B) const override;
506 FX_BOOL SetRGB(FX_FLOAT* pBuf,
507 FX_FLOAT R,
508 FX_FLOAT G,
509 FX_FLOAT B) const override;
510 void TranslateImageLine(uint8_t* pDestBuf,
511 const uint8_t* pSrcBuf,
512 int pixels,
513 int image_width,
514 int image_height,
515 FX_BOOL bTransMask = FALSE) const;
516
517 FX_FLOAT m_WhitePoint[3];
518 FX_FLOAT m_BlackPoint[3];
519 FX_FLOAT m_Ranges[4];
520 };
521 FX_BOOL CPDF_LabCS::v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) {
522 CPDF_Dictionary* pDict = pArray->GetDict(1);
523 if (!pDict) {
524 return FALSE;
525 }
526 CPDF_Array* pParam = pDict->GetArray(FX_BSTRC("WhitePoint"));
527 int i;
528 for (i = 0; i < 3; i++) {
529 m_WhitePoint[i] = pParam ? pParam->GetNumber(i) : 0;
530 }
531 pParam = pDict->GetArray(FX_BSTRC("BlackPoint"));
532 for (i = 0; i < 3; i++) {
533 m_BlackPoint[i] = pParam ? pParam->GetNumber(i) : 0;
534 }
535 pParam = pDict->GetArray(FX_BSTRC("Range"));
536 const FX_FLOAT def_ranges[4] = {-100 * 1.0f, 100 * 1.0f, -100 * 1.0f,
537 100 * 1.0f};
538 for (i = 0; i < 4; i++) {
539 m_Ranges[i] = pParam ? pParam->GetNumber(i) : def_ranges[i];
540 }
541 return TRUE;
542 }
543 void CPDF_LabCS::GetDefaultValue(int iComponent,
544 FX_FLOAT& value,
545 FX_FLOAT& min,
546 FX_FLOAT& max) const {
547 assert(iComponent < 3);
548 value = 0;
549 if (iComponent == 0) {
550 min = 0;
551 max = 100 * 1.0f;
552 } else {
553 min = m_Ranges[iComponent * 2 - 2];
554 max = m_Ranges[iComponent * 2 - 1];
555 if (value < min) {
556 value = min;
557 } else if (value > max) {
558 value = max;
559 }
560 }
561 }
562 FX_BOOL CPDF_LabCS::GetRGB(FX_FLOAT* pBuf,
563 FX_FLOAT& R,
564 FX_FLOAT& G,
565 FX_FLOAT& B) const {
566 FX_FLOAT Lstar = pBuf[0];
567 FX_FLOAT astar = pBuf[1];
568 FX_FLOAT bstar = pBuf[2];
569 FX_FLOAT M = (Lstar + 16.0f) / 116.0f;
570 FX_FLOAT L = M + astar / 500.0f;
571 FX_FLOAT N = M - bstar / 200.0f;
572 FX_FLOAT X, Y, Z;
573 if (L < 0.2069f) {
574 X = 0.957f * 0.12842f * (L - 0.1379f);
575 } else {
576 X = 0.957f * L * L * L;
577 }
578 if (M < 0.2069f) {
579 Y = 0.12842f * (M - 0.1379f);
580 } else {
581 Y = M * M * M;
582 }
583 if (N < 0.2069f) {
584 Z = 1.0889f * 0.12842f * (N - 0.1379f);
585 } else {
586 Z = 1.0889f * N * N * N;
587 }
588 XYZ_to_sRGB(X, Y, Z, R, G, B);
589 return TRUE;
590 }
591 FX_BOOL CPDF_LabCS::SetRGB(FX_FLOAT* pBuf,
592 FX_FLOAT R,
593 FX_FLOAT G,
594 FX_FLOAT B) const {
595 return FALSE;
596 }
597 void CPDF_LabCS::TranslateImageLine(uint8_t* pDestBuf,
598 const uint8_t* pSrcBuf,
599 int pixels,
600 int image_width,
601 int image_height,
602 FX_BOOL bTransMask) const {
603 for (int i = 0; i < pixels; i++) {
604 FX_FLOAT lab[3];
605 FX_FLOAT R, G, B;
606 lab[0] = (pSrcBuf[0] * 100 / 255.0f);
607 lab[1] = (FX_FLOAT)(pSrcBuf[1] - 128);
608 lab[2] = (FX_FLOAT)(pSrcBuf[2] - 128);
609 GetRGB(lab, R, G, B);
610 pDestBuf[0] = (int32_t)(B * 255);
611 pDestBuf[1] = (int32_t)(G * 255);
612 pDestBuf[2] = (int32_t)(R * 255);
613 pDestBuf += 3;
614 pSrcBuf += 3;
615 }
616 }
617 CPDF_IccProfile::CPDF_IccProfile(const uint8_t* pData, FX_DWORD dwSize)
618 : m_bsRGB(FALSE), m_pTransform(NULL), m_nSrcComponents(0) {
619 if (dwSize == 3144 &&
620 FXSYS_memcmp(pData + 0x190, "sRGB IEC61966-2.1", 17) == 0) {
621 m_bsRGB = TRUE;
622 m_nSrcComponents = 3;
623 } else if (CPDF_ModuleMgr::Get()->GetIccModule()) {
624 m_pTransform = CPDF_ModuleMgr::Get()->GetIccModule()->CreateTransform_sRGB(
625 pData, dwSize, m_nSrcComponents);
626 }
627 }
628 CPDF_IccProfile::~CPDF_IccProfile() {
629 if (m_pTransform) {
630 CPDF_ModuleMgr::Get()->GetIccModule()->DestroyTransform(m_pTransform);
631 }
632 }
633 class CPDF_ICCBasedCS : public CPDF_ColorSpace {
634 public:
635 explicit CPDF_ICCBasedCS(CPDF_Document* pDoc)
636 : CPDF_ColorSpace(pDoc, PDFCS_ICCBASED, 0),
637 m_pAlterCS(nullptr),
638 m_pProfile(nullptr),
639 m_pCache(nullptr),
640 m_pRanges(nullptr),
641 m_bOwn(FALSE) {}
642 ~CPDF_ICCBasedCS() override;
643
644 FX_BOOL v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) override;
645 FX_BOOL GetRGB(FX_FLOAT* pBuf,
646 FX_FLOAT& R,
647 FX_FLOAT& G,
648 FX_FLOAT& B) const override;
649 FX_BOOL SetRGB(FX_FLOAT* pBuf,
650 FX_FLOAT R,
651 FX_FLOAT G,
652 FX_FLOAT B) const override;
653 FX_BOOL v_GetCMYK(FX_FLOAT* pBuf,
654 FX_FLOAT& c,
655 FX_FLOAT& m,
656 FX_FLOAT& y,
657 FX_FLOAT& k) const override;
658 void EnableStdConversion(FX_BOOL bEnabled) override;
659 void TranslateImageLine(uint8_t* pDestBuf,
660 const uint8_t* pSrcBuf,
661 int pixels,
662 int image_width,
663 int image_height,
664 FX_BOOL bTransMask = FALSE) const override;
665
666 CPDF_ColorSpace* m_pAlterCS;
667 CPDF_IccProfile* m_pProfile;
668 uint8_t* m_pCache;
669 FX_FLOAT* m_pRanges;
670 FX_BOOL m_bOwn;
671 };
672
673 CPDF_ICCBasedCS::~CPDF_ICCBasedCS() {
674 if (m_pCache) {
675 FX_Free(m_pCache);
676 }
677 if (m_pRanges) {
678 FX_Free(m_pRanges);
679 }
680 if (m_pAlterCS && m_bOwn) {
681 m_pAlterCS->ReleaseCS();
682 }
683 if (m_pProfile && m_pDocument) {
684 m_pDocument->GetPageData()->ReleaseIccProfile(m_pProfile);
685 }
686 }
687
688 FX_BOOL CPDF_ICCBasedCS::v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) {
689 CPDF_Stream* pStream = pArray->GetStream(1);
690 if (pStream == NULL) {
691 return FALSE;
692 }
693 m_pProfile = pDoc->LoadIccProfile(pStream);
694 if (!m_pProfile) {
695 return FALSE;
696 }
697 m_nComponents =
698 m_pProfile
699 ->GetComponents(); // Try using the nComponents from ICC profile
700 CPDF_Dictionary* pDict = pStream->GetDict();
701 if (m_pProfile->m_pTransform == NULL) { // No valid ICC profile or using sRGB
702 CPDF_Object* pAlterCSObj =
703 pDict ? pDict->GetElementValue(FX_BSTRC("Alternate")) : NULL;
704 if (pAlterCSObj) {
705 CPDF_ColorSpace* pAlterCS = CPDF_ColorSpace::Load(pDoc, pAlterCSObj);
706 if (pAlterCS) {
707 if (m_nComponents == 0) { // NO valid ICC profile
708 if (pAlterCS->CountComponents() > 0) { // Use Alternative colorspace
709 m_nComponents = pAlterCS->CountComponents();
710 m_pAlterCS = pAlterCS;
711 m_bOwn = TRUE;
712 } else { // No valid alternative colorspace
713 pAlterCS->ReleaseCS();
714 int32_t nDictComponents =
715 pDict ? pDict->GetInteger(FX_BSTRC("N")) : 0;
716 if (nDictComponents != 1 && nDictComponents != 3 &&
717 nDictComponents != 4) {
718 return FALSE;
719 }
720 m_nComponents = nDictComponents;
721 }
722
723 } else { // Using sRGB
724 if (pAlterCS->CountComponents() != m_nComponents) {
725 pAlterCS->ReleaseCS();
726 } else {
727 m_pAlterCS = pAlterCS;
728 m_bOwn = TRUE;
729 }
427 } 730 }
428 } 731 }
732 }
733 if (!m_pAlterCS) {
734 if (m_nComponents == 1) {
735 m_pAlterCS = GetStockCS(PDFCS_DEVICEGRAY);
736 } else if (m_nComponents == 3) {
737 m_pAlterCS = GetStockCS(PDFCS_DEVICERGB);
738 } else if (m_nComponents == 4) {
739 m_pAlterCS = GetStockCS(PDFCS_DEVICECMYK);
740 }
741 }
742 }
743 CPDF_Array* pRanges = pDict->GetArray(FX_BSTRC("Range"));
744 m_pRanges = FX_Alloc2D(FX_FLOAT, m_nComponents, 2);
745 for (int i = 0; i < m_nComponents * 2; i++) {
746 if (pRanges) {
747 m_pRanges[i] = pRanges->GetNumber(i);
748 } else if (i % 2) {
749 m_pRanges[i] = 1.0f;
750 } else {
751 m_pRanges[i] = 0;
752 }
753 }
754 return TRUE;
755 }
756 FX_BOOL CPDF_ICCBasedCS::GetRGB(FX_FLOAT* pBuf,
757 FX_FLOAT& R,
758 FX_FLOAT& G,
759 FX_FLOAT& B) const {
760 if (m_pProfile && m_pProfile->m_bsRGB) {
761 R = pBuf[0];
762 G = pBuf[1];
763 B = pBuf[2];
764 return TRUE;
765 }
766 ICodec_IccModule* pIccModule = CPDF_ModuleMgr::Get()->GetIccModule();
767 if (m_pProfile->m_pTransform == NULL || pIccModule == NULL) {
768 if (m_pAlterCS) {
769 m_pAlterCS->GetRGB(pBuf, R, G, B);
770 } else {
771 R = G = B = 0.0f;
772 }
773 return TRUE;
774 }
775 FX_FLOAT rgb[3];
776 pIccModule->SetComponents(m_nComponents);
777 pIccModule->Translate(m_pProfile->m_pTransform, pBuf, rgb);
778 R = rgb[0];
779 G = rgb[1];
780 B = rgb[2];
781 return TRUE;
782 }
783 FX_BOOL CPDF_ICCBasedCS::v_GetCMYK(FX_FLOAT* pBuf,
784 FX_FLOAT& c,
785 FX_FLOAT& m,
786 FX_FLOAT& y,
787 FX_FLOAT& k) const {
788 if (m_nComponents != 4) {
789 return FALSE;
790 }
791 c = pBuf[0];
792 m = pBuf[1];
793 y = pBuf[2];
794 k = pBuf[3];
795 return TRUE;
796 }
797 FX_BOOL CPDF_ICCBasedCS::SetRGB(FX_FLOAT* pBuf,
798 FX_FLOAT R,
799 FX_FLOAT G,
800 FX_FLOAT B) const {
801 return FALSE;
802 }
803 void CPDF_ICCBasedCS::EnableStdConversion(FX_BOOL bEnabled) {
804 CPDF_ColorSpace::EnableStdConversion(bEnabled);
805 if (m_pAlterCS) {
806 m_pAlterCS->EnableStdConversion(bEnabled);
807 }
808 }
809 void CPDF_ICCBasedCS::TranslateImageLine(uint8_t* pDestBuf,
810 const uint8_t* pSrcBuf,
811 int pixels,
812 int image_width,
813 int image_height,
814 FX_BOOL bTransMask) const {
815 if (m_pProfile->m_bsRGB) {
429 ReverseRGB(pDestBuf, pSrcBuf, pixels); 816 ReverseRGB(pDestBuf, pSrcBuf, pixels);
430 } 817 } else if (m_pProfile->m_pTransform) {
431 class CPDF_LabCS : public CPDF_ColorSpace 818 int nMaxColors = 1;
432 { 819 for (int i = 0; i < m_nComponents; i++) {
433 public: 820 nMaxColors *= 52;
434 explicit CPDF_LabCS(CPDF_Document* pDoc) 821 }
435 : CPDF_ColorSpace(pDoc, PDFCS_LAB, 3) { 822 if (m_nComponents > 3 || image_width * image_height < nMaxColors * 3 / 2) {
436 } 823 CPDF_ModuleMgr::Get()->GetIccModule()->TranslateScanline(
437 void GetDefaultValue(int iComponent, FX_FLOAT& value, FX_FLOAT& min, FX_FLOA T& max) const override; 824 m_pProfile->m_pTransform, pDestBuf, pSrcBuf, pixels);
438 FX_BOOL v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) override; 825 } else {
439 FX_BOOL» GetRGB(FX_FLOAT* pBuf, FX_FLOAT& R, FX_FLOAT& G, FX_FLOAT& B) co nst override; 826 if (m_pCache == NULL) {
440 FX_BOOL» SetRGB(FX_FLOAT* pBuf, FX_FLOAT R, FX_FLOAT G, FX_FLOAT B) const override; 827 ((CPDF_ICCBasedCS*)this)->m_pCache = FX_Alloc2D(uint8_t, nMaxColors, 3);
441 void TranslateImageLine(uint8_t* pDestBuf, const uint8_t* pSrcBuf, int pixel s, int image_width, 828 uint8_t* temp_src = FX_Alloc2D(uint8_t, nMaxColors, m_nComponents);
442 int image_height, FX_BOOL bTransMask = FALSE) const; 829 uint8_t* pSrc = temp_src;
443 830 for (int i = 0; i < nMaxColors; i++) {
444 FX_FLOAT m_WhitePoint[3]; 831 FX_DWORD color = i;
445 FX_FLOAT m_BlackPoint[3]; 832 FX_DWORD order = nMaxColors / 52;
446 FX_FLOAT m_Ranges[4]; 833 for (int c = 0; c < m_nComponents; c++) {
834 *pSrc++ = (uint8_t)(color / order * 5);
835 color %= order;
836 order /= 52;
837 }
838 }
839 CPDF_ModuleMgr::Get()->GetIccModule()->TranslateScanline(
840 m_pProfile->m_pTransform, m_pCache, temp_src, nMaxColors);
841 FX_Free(temp_src);
842 }
843 for (int i = 0; i < pixels; i++) {
844 int index = 0;
845 for (int c = 0; c < m_nComponents; c++) {
846 index = index * 52 + (*pSrcBuf) / 5;
847 pSrcBuf++;
848 }
849 index *= 3;
850 *pDestBuf++ = m_pCache[index];
851 *pDestBuf++ = m_pCache[index + 1];
852 *pDestBuf++ = m_pCache[index + 2];
853 }
854 }
855 } else if (m_pAlterCS) {
856 m_pAlterCS->TranslateImageLine(pDestBuf, pSrcBuf, pixels, image_width,
857 image_height);
858 }
859 }
860 class CPDF_IndexedCS : public CPDF_ColorSpace {
861 public:
862 explicit CPDF_IndexedCS(CPDF_Document* pDoc)
863 : CPDF_ColorSpace(pDoc, PDFCS_INDEXED, 1),
864 m_pBaseCS(nullptr),
865 m_pCountedBaseCS(nullptr),
866 m_pCompMinMax(nullptr) {}
867 ~CPDF_IndexedCS() override;
868
869 FX_BOOL v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) override;
870 FX_BOOL GetRGB(FX_FLOAT* pBuf,
871 FX_FLOAT& R,
872 FX_FLOAT& G,
873 FX_FLOAT& B) const override;
874 CPDF_ColorSpace* GetBaseCS() const override;
875 void EnableStdConversion(FX_BOOL bEnabled) override;
876
877 CPDF_ColorSpace* m_pBaseCS;
878 CPDF_CountedColorSpace* m_pCountedBaseCS;
879 int m_nBaseComponents;
880 int m_MaxIndex;
881 CFX_ByteString m_Table;
882 FX_FLOAT* m_pCompMinMax;
447 }; 883 };
448 FX_BOOL CPDF_LabCS::v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) 884 CPDF_IndexedCS::~CPDF_IndexedCS() {
449 { 885 if (m_pCompMinMax) {
450 CPDF_Dictionary* pDict = pArray->GetDict(1); 886 FX_Free(m_pCompMinMax);
451 if (!pDict) { 887 }
452 return FALSE; 888 CPDF_ColorSpace* pCS = m_pCountedBaseCS ? m_pCountedBaseCS->get() : NULL;
453 } 889 if (pCS && m_pDocument) {
454 CPDF_Array* pParam = pDict->GetArray(FX_BSTRC("WhitePoint")); 890 m_pDocument->GetPageData()->ReleaseColorSpace(pCS->GetArray());
455 int i; 891 }
456 for (i = 0; i < 3; i ++) { 892 }
457 m_WhitePoint[i] = pParam ? pParam->GetNumber(i) : 0; 893 FX_BOOL CPDF_IndexedCS::v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) {
458 } 894 if (pArray->GetCount() < 4) {
459 pParam = pDict->GetArray(FX_BSTRC("BlackPoint")); 895 return FALSE;
460 for (i = 0; i < 3; i ++) { 896 }
461 m_BlackPoint[i] = pParam ? pParam->GetNumber(i) : 0; 897 CPDF_Object* pBaseObj = pArray->GetElementValue(1);
462 } 898 if (pBaseObj == m_pArray) {
463 pParam = pDict->GetArray(FX_BSTRC("Range")); 899 return FALSE;
464 const FX_FLOAT def_ranges[4] = { -100 * 1.0f, 100 * 1.0f, -100 * 1.0f, 100 * 1.0f}; 900 }
465 for (i = 0; i < 4; i ++) { 901 CPDF_DocPageData* pDocPageData = pDoc->GetPageData();
466 m_Ranges[i] = pParam ? pParam->GetNumber(i) : def_ranges[i]; 902 m_pBaseCS = pDocPageData->GetColorSpace(pBaseObj, NULL);
467 } 903 if (m_pBaseCS == NULL) {
468 return TRUE; 904 return FALSE;
469 } 905 }
470 void CPDF_LabCS::GetDefaultValue(int iComponent, FX_FLOAT& value, FX_FLOAT& min, FX_FLOAT& max) const 906 m_pCountedBaseCS = pDocPageData->FindColorSpacePtr(m_pBaseCS->GetArray());
471 { 907 m_nBaseComponents = m_pBaseCS->CountComponents();
472 assert(iComponent < 3); 908 m_pCompMinMax = FX_Alloc2D(FX_FLOAT, m_nBaseComponents, 2);
473 value = 0; 909 FX_FLOAT defvalue;
474 if (iComponent == 0) { 910 for (int i = 0; i < m_nBaseComponents; i++) {
475 min = 0; 911 m_pBaseCS->GetDefaultValue(i, defvalue, m_pCompMinMax[i * 2],
476 max = 100 * 1.0f; 912 m_pCompMinMax[i * 2 + 1]);
477 } else { 913 m_pCompMinMax[i * 2 + 1] -= m_pCompMinMax[i * 2];
478 min = m_Ranges[iComponent * 2 - 2]; 914 }
479 max = m_Ranges[iComponent * 2 - 1]; 915 m_MaxIndex = pArray->GetInteger(2);
480 if (value < min) { 916 CPDF_Object* pTableObj = pArray->GetElementValue(3);
481 value = min; 917 if (pTableObj == NULL) {
482 } else if (value > max) { 918 return FALSE;
483 value = max; 919 }
484 } 920 if (pTableObj->GetType() == PDFOBJ_STRING) {
485 } 921 m_Table = ((CPDF_String*)pTableObj)->GetString();
486 } 922 } else if (pTableObj->GetType() == PDFOBJ_STREAM) {
487 FX_BOOL CPDF_LabCS::GetRGB(FX_FLOAT* pBuf, FX_FLOAT& R, FX_FLOAT& G, FX_FLOAT& B ) const 923 CPDF_StreamAcc acc;
488 { 924 acc.LoadAllData((CPDF_Stream*)pTableObj, FALSE);
489 FX_FLOAT Lstar = pBuf[0]; 925 m_Table = CFX_ByteStringC(acc.GetData(), acc.GetSize());
490 FX_FLOAT astar = pBuf[1]; 926 }
491 FX_FLOAT bstar = pBuf[2]; 927 return TRUE;
492 FX_FLOAT M = (Lstar + 16.0f) / 116.0f; 928 }
493 FX_FLOAT L = M + astar / 500.0f; 929
494 FX_FLOAT N = M - bstar / 200.0f; 930 FX_BOOL CPDF_IndexedCS::GetRGB(FX_FLOAT* pBuf,
495 FX_FLOAT X, Y, Z; 931 FX_FLOAT& R,
496 if (L < 0.2069f) { 932 FX_FLOAT& G,
497 X = 0.957f * 0.12842f * (L - 0.1379f); 933 FX_FLOAT& B) const {
498 } else { 934 int index = (int32_t)(*pBuf);
499 X = 0.957f * L * L * L; 935 if (index < 0 || index > m_MaxIndex) {
500 } 936 return FALSE;
501 if (M < 0.2069f) { 937 }
502 Y = 0.12842f * (M - 0.1379f); 938 if (m_nBaseComponents) {
503 } else { 939 if (index == INT_MAX || (index + 1) > INT_MAX / m_nBaseComponents ||
504 Y = M * M * M; 940 (index + 1) * m_nBaseComponents > (int)m_Table.GetLength()) {
505 } 941 R = G = B = 0;
506 if (N < 0.2069f) { 942 return FALSE;
507 Z = 1.0889f * 0.12842f * (N - 0.1379f); 943 }
508 } else { 944 }
509 Z = 1.0889f * N * N * N; 945 CFX_FixedBufGrow<FX_FLOAT, 16> Comps(m_nBaseComponents);
510 } 946 FX_FLOAT* comps = Comps;
511 XYZ_to_sRGB(X, Y, Z, R, G, B); 947 const uint8_t* pTable = m_Table;
512 return TRUE; 948 for (int i = 0; i < m_nBaseComponents; i++) {
513 } 949 comps[i] =
514 FX_BOOL CPDF_LabCS::SetRGB(FX_FLOAT* pBuf, FX_FLOAT R, FX_FLOAT G, FX_FLOAT B) c onst 950 m_pCompMinMax[i * 2] +
515 { 951 m_pCompMinMax[i * 2 + 1] * pTable[index * m_nBaseComponents + i] / 255;
516 return FALSE; 952 }
517 } 953 m_pBaseCS->GetRGB(comps, R, G, B);
518 void CPDF_LabCS::TranslateImageLine(uint8_t* pDestBuf, const uint8_t* pSrcBuf, i nt pixels, int image_width, int image_height, FX_BOOL bTransMask) const 954 return TRUE;
519 { 955 }
520 for (int i = 0; i < pixels; i ++) { 956 CPDF_ColorSpace* CPDF_IndexedCS::GetBaseCS() const {
521 FX_FLOAT lab[3]; 957 return m_pBaseCS;
522 FX_FLOAT R, G, B; 958 }
523 lab[0] = (pSrcBuf[0] * 100 / 255.0f); 959 void CPDF_IndexedCS::EnableStdConversion(FX_BOOL bEnabled) {
524 lab[1] = (FX_FLOAT)(pSrcBuf[1] - 128); 960 CPDF_ColorSpace::EnableStdConversion(bEnabled);
525 lab[2] = (FX_FLOAT)(pSrcBuf[2] - 128); 961 if (m_pBaseCS) {
526 GetRGB(lab, R, G, B); 962 m_pBaseCS->EnableStdConversion(bEnabled);
527 pDestBuf[0] = (int32_t)(B * 255); 963 }
528 pDestBuf[1] = (int32_t)(G * 255); 964 }
529 pDestBuf[2] = (int32_t)(R * 255); 965 #define MAX_PATTERN_COLORCOMPS 16
530 pDestBuf += 3; 966 typedef struct _PatternValue {
531 pSrcBuf += 3; 967 CPDF_Pattern* m_pPattern;
532 } 968 CPDF_CountedPattern* m_pCountedPattern;
533 } 969 int m_nComps;
534 CPDF_IccProfile::CPDF_IccProfile(const uint8_t* pData, FX_DWORD dwSize): 970 FX_FLOAT m_Comps[MAX_PATTERN_COLORCOMPS];
535 m_bsRGB(FALSE), 971 } PatternValue;
536 m_pTransform(NULL), 972 CPDF_PatternCS::~CPDF_PatternCS() {
537 m_nSrcComponents(0) 973 CPDF_ColorSpace* pCS = m_pCountedBaseCS ? m_pCountedBaseCS->get() : NULL;
538 { 974 if (pCS && m_pDocument) {
539 if (dwSize == 3144 && FXSYS_memcmp(pData + 0x190, "sRGB IEC61966-2.1", 17) = = 0) { 975 m_pDocument->GetPageData()->ReleaseColorSpace(pCS->GetArray());
540 m_bsRGB = TRUE; 976 }
541 m_nSrcComponents = 3; 977 }
542 } 978 FX_BOOL CPDF_PatternCS::v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) {
543 else if (CPDF_ModuleMgr::Get()->GetIccModule()) { 979 CPDF_Object* pBaseCS = pArray->GetElementValue(1);
544 m_pTransform = CPDF_ModuleMgr::Get()->GetIccModule()->CreateTransform_sR GB(pData, dwSize, m_nSrcComponents); 980 if (pBaseCS == m_pArray) {
545 } 981 return FALSE;
546 } 982 }
547 CPDF_IccProfile::~CPDF_IccProfile() 983 CPDF_DocPageData* pDocPageData = pDoc->GetPageData();
548 { 984 m_pBaseCS = pDocPageData->GetColorSpace(pBaseCS, NULL);
549 if (m_pTransform) { 985 if (m_pBaseCS) {
550 CPDF_ModuleMgr::Get()->GetIccModule()->DestroyTransform(m_pTransform); 986 if (m_pBaseCS->GetFamily() == PDFCS_PATTERN) {
551 } 987 return FALSE;
552 } 988 }
553 class CPDF_ICCBasedCS : public CPDF_ColorSpace 989 m_pCountedBaseCS = pDocPageData->FindColorSpacePtr(m_pBaseCS->GetArray());
554 { 990 m_nComponents = m_pBaseCS->CountComponents() + 1;
555 public: 991 if (m_pBaseCS->CountComponents() > MAX_PATTERN_COLORCOMPS) {
556 explicit CPDF_ICCBasedCS(CPDF_Document* pDoc) 992 return FALSE;
557 : CPDF_ColorSpace(pDoc, PDFCS_ICCBASED, 0), 993 }
558 m_pAlterCS(nullptr), 994 } else {
559 m_pProfile(nullptr), 995 m_nComponents = 1;
560 m_pCache(nullptr), 996 }
561 m_pRanges(nullptr), 997 return TRUE;
562 m_bOwn(FALSE) { 998 }
563 } 999 FX_BOOL CPDF_PatternCS::GetRGB(FX_FLOAT* pBuf,
564 ~CPDF_ICCBasedCS() override; 1000 FX_FLOAT& R,
565 1001 FX_FLOAT& G,
566 FX_BOOL» v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) override; 1002 FX_FLOAT& B) const {
567 FX_BOOL GetRGB(FX_FLOAT* pBuf, FX_FLOAT& R, FX_FLOAT& G, FX_FLOAT& B) const override; 1003 if (m_pBaseCS) {
568 FX_BOOL» SetRGB(FX_FLOAT* pBuf, FX_FLOAT R, FX_FLOAT G, FX_FLOAT B) const override; 1004 ASSERT(m_pBaseCS->GetFamily() != PDFCS_PATTERN);
569 FX_BOOL» v_GetCMYK(FX_FLOAT* pBuf, FX_FLOAT& c, FX_FLOAT& m, FX_FLOAT& y, FX_FLOAT& k) const override; 1005 PatternValue* pvalue = (PatternValue*)pBuf;
570 void EnableStdConversion(FX_BOOL bEnabled) override; 1006 if (m_pBaseCS->GetRGB(pvalue->m_Comps, R, G, B)) {
571 void TranslateImageLine(uint8_t* pDestBuf, const uint8_t* pSrcBuf, int pixel s, int image_width, 1007 return TRUE;
572 int image_height, FX_BOOL bTransMask = FALSE) const override; 1008 }
573 1009 }
574 CPDF_ColorSpace* m_pAlterCS; 1010 R = G = B = 0.75f;
575 CPDF_IccProfile* m_pProfile; 1011 return FALSE;
576 uint8_t* m_pCache; 1012 }
577 FX_FLOAT* m_pRanges; 1013 CPDF_ColorSpace* CPDF_PatternCS::GetBaseCS() const {
578 FX_BOOL» m_bOwn; 1014 return m_pBaseCS;
1015 }
1016 class CPDF_SeparationCS : public CPDF_ColorSpace {
1017 public:
1018 CPDF_SeparationCS(CPDF_Document* pDoc)
1019 : CPDF_ColorSpace(pDoc, PDFCS_SEPARATION, 1),
1020 m_pAltCS(nullptr),
1021 m_pFunc(nullptr) {}
1022 ~CPDF_SeparationCS() override;
1023 void GetDefaultValue(int iComponent,
1024 FX_FLOAT& value,
1025 FX_FLOAT& min,
1026 FX_FLOAT& max) const override;
1027 FX_BOOL v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) override;
1028 FX_BOOL GetRGB(FX_FLOAT* pBuf,
1029 FX_FLOAT& R,
1030 FX_FLOAT& G,
1031 FX_FLOAT& B) const override;
1032 void EnableStdConversion(FX_BOOL bEnabled) override;
1033
1034 CPDF_ColorSpace* m_pAltCS;
1035 CPDF_Function* m_pFunc;
1036 enum { None, All, Colorant } m_Type;
579 }; 1037 };
580 1038 CPDF_SeparationCS::~CPDF_SeparationCS() {
581 CPDF_ICCBasedCS::~CPDF_ICCBasedCS() 1039 if (m_pAltCS) {
582 { 1040 m_pAltCS->ReleaseCS();
583 if (m_pCache) { 1041 }
584 FX_Free(m_pCache); 1042 delete m_pFunc;
585 } 1043 }
586 if (m_pRanges) { 1044 void CPDF_SeparationCS::GetDefaultValue(int iComponent,
587 FX_Free(m_pRanges); 1045 FX_FLOAT& value,
588 } 1046 FX_FLOAT& min,
589 if (m_pAlterCS && m_bOwn) { 1047 FX_FLOAT& max) const {
590 m_pAlterCS->ReleaseCS(); 1048 value = 1.0f;
591 } 1049 min = 0;
592 if (m_pProfile && m_pDocument) { 1050 max = 1.0f;
593 m_pDocument->GetPageData()->ReleaseIccProfile(m_pProfile); 1051 }
594 } 1052 FX_BOOL CPDF_SeparationCS::v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) {
595 } 1053 CFX_ByteString name = pArray->GetString(1);
596 1054 if (name == FX_BSTRC("None")) {
597 FX_BOOL CPDF_ICCBasedCS::v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) 1055 m_Type = None;
598 { 1056 } else {
599 CPDF_Stream* pStream = pArray->GetStream(1); 1057 m_Type = Colorant;
600 if (pStream == NULL) {
601 return FALSE;
602 }
603 m_pProfile = pDoc->LoadIccProfile(pStream);
604 if (!m_pProfile) {
605 return FALSE;
606 }
607 m_nComponents = m_pProfile->GetComponents(); //Try using the nComponents fro m ICC profile
608 CPDF_Dictionary* pDict = pStream->GetDict();
609 if (m_pProfile->m_pTransform == NULL) { // No valid ICC profile or using sRG B
610 CPDF_Object* pAlterCSObj = pDict ? pDict->GetElementValue(FX_BSTRC("Alte rnate")) : NULL;
611 if (pAlterCSObj) {
612 CPDF_ColorSpace* pAlterCS = CPDF_ColorSpace::Load(pDoc, pAlterCSObj) ;
613 if (pAlterCS) {
614 if (m_nComponents == 0) { // NO valid ICC profile
615 if (pAlterCS->CountComponents() > 0) { // Use Alternative co lorspace
616 m_nComponents = pAlterCS->CountComponents();
617 m_pAlterCS = pAlterCS;
618 m_bOwn = TRUE;
619 }
620 else { // No valid alternative colorspace
621 pAlterCS->ReleaseCS();
622 int32_t nDictComponents = pDict ? pDict->GetInteger(FX_B STRC("N")) : 0;
623 if (nDictComponents != 1 && nDictComponents != 3 && nDic tComponents != 4) {
624 return FALSE;
625 }
626 m_nComponents = nDictComponents;
627 }
628
629 }
630 else { // Using sRGB
631 if (pAlterCS->CountComponents() != m_nComponents) {
632 pAlterCS->ReleaseCS();
633 }
634 else {
635 m_pAlterCS = pAlterCS;
636 m_bOwn = TRUE;
637 }
638 }
639 }
640 }
641 if (!m_pAlterCS) {
642 if (m_nComponents == 1) {
643 m_pAlterCS = GetStockCS(PDFCS_DEVICEGRAY);
644 }
645 else if (m_nComponents == 3) {
646 m_pAlterCS = GetStockCS(PDFCS_DEVICERGB);
647 }
648 else if (m_nComponents == 4) {
649 m_pAlterCS = GetStockCS(PDFCS_DEVICECMYK);
650 }
651 }
652 }
653 CPDF_Array* pRanges = pDict->GetArray(FX_BSTRC("Range"));
654 m_pRanges = FX_Alloc2D(FX_FLOAT, m_nComponents, 2);
655 for (int i = 0; i < m_nComponents * 2; i ++) {
656 if (pRanges) {
657 m_pRanges[i] = pRanges->GetNumber(i);
658 } else if (i % 2) {
659 m_pRanges[i] = 1.0f;
660 } else {
661 m_pRanges[i] = 0;
662 }
663 }
664 return TRUE;
665 }
666 FX_BOOL CPDF_ICCBasedCS::GetRGB(FX_FLOAT* pBuf, FX_FLOAT& R, FX_FLOAT& G, FX_FLO AT& B) const
667 {
668 if (m_pProfile && m_pProfile->m_bsRGB) {
669 R = pBuf[0];
670 G = pBuf[1];
671 B = pBuf[2];
672 return TRUE;
673 }
674 ICodec_IccModule *pIccModule = CPDF_ModuleMgr::Get()->GetIccModule();
675 if (m_pProfile->m_pTransform == NULL || pIccModule == NULL) {
676 if (m_pAlterCS) {
677 m_pAlterCS->GetRGB(pBuf, R, G, B);
678 } else {
679 R = G = B = 0.0f;
680 }
681 return TRUE;
682 }
683 FX_FLOAT rgb[3];
684 pIccModule->SetComponents(m_nComponents);
685 pIccModule->Translate(m_pProfile->m_pTransform, pBuf, rgb);
686 R = rgb[0];
687 G = rgb[1];
688 B = rgb[2];
689 return TRUE;
690 }
691 FX_BOOL CPDF_ICCBasedCS::v_GetCMYK(FX_FLOAT* pBuf, FX_FLOAT& c, FX_FLOAT& m, FX_ FLOAT& y, FX_FLOAT& k) const
692 {
693 if (m_nComponents != 4) {
694 return FALSE;
695 }
696 c = pBuf[0];
697 m = pBuf[1];
698 y = pBuf[2];
699 k = pBuf[3];
700 return TRUE;
701 }
702 FX_BOOL CPDF_ICCBasedCS::SetRGB(FX_FLOAT* pBuf, FX_FLOAT R, FX_FLOAT G, FX_FLOAT B) const
703 {
704 return FALSE;
705 }
706 void CPDF_ICCBasedCS::EnableStdConversion(FX_BOOL bEnabled)
707 {
708 CPDF_ColorSpace::EnableStdConversion(bEnabled);
709 if (m_pAlterCS) {
710 m_pAlterCS->EnableStdConversion(bEnabled);
711 }
712 }
713 void CPDF_ICCBasedCS::TranslateImageLine(uint8_t* pDestBuf, const uint8_t* pSrcB uf, int pixels, int image_width, int image_height, FX_BOOL bTransMask) const
714 {
715 if (m_pProfile->m_bsRGB) {
716 ReverseRGB(pDestBuf, pSrcBuf, pixels);
717 } else if (m_pProfile->m_pTransform) {
718 int nMaxColors = 1;
719 for (int i = 0; i < m_nComponents; i ++) {
720 nMaxColors *= 52;
721 }
722 if (m_nComponents > 3 || image_width * image_height < nMaxColors * 3 / 2 ) {
723 CPDF_ModuleMgr::Get()->GetIccModule()->TranslateScanline(m_pProfile- >m_pTransform, pDestBuf, pSrcBuf, pixels);
724 } else {
725 if (m_pCache == NULL) {
726 ((CPDF_ICCBasedCS*)this)->m_pCache = FX_Alloc2D(uint8_t, nMaxCol ors, 3);
727 uint8_t* temp_src = FX_Alloc2D(uint8_t, nMaxColors, m_nComponent s);
728 uint8_t* pSrc = temp_src;
729 for (int i = 0; i < nMaxColors; i ++) {
730 FX_DWORD color = i;
731 FX_DWORD order = nMaxColors / 52;
732 for (int c = 0; c < m_nComponents; c ++) {
733 *pSrc++ = (uint8_t)(color / order * 5);
734 color %= order;
735 order /= 52;
736 }
737 }
738 CPDF_ModuleMgr::Get()->GetIccModule()->TranslateScanline(m_pProf ile->m_pTransform, m_pCache, temp_src, nMaxColors);
739 FX_Free(temp_src);
740 }
741 for (int i = 0; i < pixels; i ++) {
742 int index = 0;
743 for (int c = 0; c < m_nComponents; c ++) {
744 index = index * 52 + (*pSrcBuf) / 5;
745 pSrcBuf ++;
746 }
747 index *= 3;
748 *pDestBuf++ = m_pCache[index];
749 *pDestBuf++ = m_pCache[index + 1];
750 *pDestBuf++ = m_pCache[index + 2];
751 }
752 }
753 } else if (m_pAlterCS) {
754 m_pAlterCS->TranslateImageLine(pDestBuf, pSrcBuf, pixels, image_width, i mage_height);
755 }
756 }
757 class CPDF_IndexedCS : public CPDF_ColorSpace
758 {
759 public:
760 explicit CPDF_IndexedCS(CPDF_Document* pDoc)
761 : CPDF_ColorSpace(pDoc, PDFCS_INDEXED, 1),
762 m_pBaseCS(nullptr),
763 m_pCountedBaseCS(nullptr),
764 m_pCompMinMax(nullptr) {
765 }
766 ~CPDF_IndexedCS() override;
767
768 FX_BOOL v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) override;
769 FX_BOOL GetRGB(FX_FLOAT* pBuf, FX_FLOAT& R, FX_FLOAT& G, FX_FLOAT& B) co nst override;
770 CPDF_ColorSpace* GetBaseCS() const override;
771 void EnableStdConversion(FX_BOOL bEnabled) override;
772
773 CPDF_ColorSpace* m_pBaseCS;
774 CPDF_CountedColorSpace* m_pCountedBaseCS;
775 int m_nBaseComponents;
776 int m_MaxIndex;
777 CFX_ByteString m_Table;
778 FX_FLOAT* m_pCompMinMax;
779 };
780 CPDF_IndexedCS::~CPDF_IndexedCS()
781 {
782 if (m_pCompMinMax) {
783 FX_Free(m_pCompMinMax);
784 }
785 CPDF_ColorSpace* pCS = m_pCountedBaseCS ? m_pCountedBaseCS->get() : NULL;
786 if (pCS && m_pDocument) {
787 m_pDocument->GetPageData()->ReleaseColorSpace(pCS->GetArray());
788 }
789 }
790 FX_BOOL CPDF_IndexedCS::v_Load(CPDF_Document* pDoc, CPDF_Array* pArray)
791 {
792 if (pArray->GetCount() < 4) {
793 return FALSE;
794 }
795 CPDF_Object* pBaseObj = pArray->GetElementValue(1);
796 if (pBaseObj == m_pArray) {
797 return FALSE;
798 }
799 CPDF_DocPageData* pDocPageData = pDoc->GetPageData();
800 m_pBaseCS = pDocPageData->GetColorSpace(pBaseObj, NULL);
801 if (m_pBaseCS == NULL) {
802 return FALSE;
803 }
804 m_pCountedBaseCS = pDocPageData->FindColorSpacePtr(m_pBaseCS->GetArray());
805 m_nBaseComponents = m_pBaseCS->CountComponents();
806 m_pCompMinMax = FX_Alloc2D(FX_FLOAT, m_nBaseComponents, 2);
807 FX_FLOAT defvalue;
808 for (int i = 0; i < m_nBaseComponents; i ++) {
809 m_pBaseCS->GetDefaultValue(i, defvalue, m_pCompMinMax[i * 2], m_pCompMin Max[i * 2 + 1]);
810 m_pCompMinMax[i * 2 + 1] -= m_pCompMinMax[i * 2];
811 }
812 m_MaxIndex = pArray->GetInteger(2);
813 CPDF_Object* pTableObj = pArray->GetElementValue(3);
814 if (pTableObj == NULL) {
815 return FALSE;
816 }
817 if (pTableObj->GetType() == PDFOBJ_STRING) {
818 m_Table = ((CPDF_String*)pTableObj)->GetString();
819 } else if (pTableObj->GetType() == PDFOBJ_STREAM) {
820 CPDF_StreamAcc acc;
821 acc.LoadAllData((CPDF_Stream*)pTableObj, FALSE);
822 m_Table = CFX_ByteStringC(acc.GetData(), acc.GetSize());
823 }
824 return TRUE;
825 }
826
827 FX_BOOL CPDF_IndexedCS::GetRGB(FX_FLOAT* pBuf, FX_FLOAT& R, FX_FLOAT& G, FX_FLOA T& B) const
828 {
829 int index = (int32_t)(*pBuf);
830 if (index < 0 || index > m_MaxIndex) {
831 return FALSE;
832 }
833 if (m_nBaseComponents) {
834 if (index == INT_MAX || (index + 1) > INT_MAX / m_nBaseComponents ||
835 (index + 1)*m_nBaseComponents > (int)m_Table.GetLength()) {
836 R = G = B = 0;
837 return FALSE;
838 }
839 }
840 CFX_FixedBufGrow<FX_FLOAT, 16> Comps(m_nBaseComponents);
841 FX_FLOAT* comps = Comps;
842 const uint8_t* pTable = m_Table;
843 for (int i = 0; i < m_nBaseComponents; i ++) {
844 comps[i] = m_pCompMinMax[i * 2] + m_pCompMinMax[i * 2 + 1] * pTable[inde x * m_nBaseComponents + i] / 255;
845 }
846 m_pBaseCS->GetRGB(comps, R, G, B);
847 return TRUE;
848 }
849 CPDF_ColorSpace*CPDF_IndexedCS::GetBaseCS() const
850 {
851 return m_pBaseCS;
852 }
853 void CPDF_IndexedCS::EnableStdConversion(FX_BOOL bEnabled)
854 {
855 CPDF_ColorSpace::EnableStdConversion(bEnabled);
856 if (m_pBaseCS) {
857 m_pBaseCS->EnableStdConversion(bEnabled);
858 }
859 }
860 #define MAX_PATTERN_COLORCOMPS 16
861 typedef struct _PatternValue {
862 CPDF_Pattern* m_pPattern;
863 CPDF_CountedPattern* m_pCountedPattern;
864 int m_nComps;
865 FX_FLOAT m_Comps[MAX_PATTERN_COLORCOMPS];
866 } PatternValue;
867 CPDF_PatternCS::~CPDF_PatternCS()
868 {
869 CPDF_ColorSpace* pCS = m_pCountedBaseCS ? m_pCountedBaseCS->get() : NULL;
870 if (pCS && m_pDocument) {
871 m_pDocument->GetPageData()->ReleaseColorSpace(pCS->GetArray());
872 }
873 }
874 FX_BOOL CPDF_PatternCS::v_Load(CPDF_Document* pDoc, CPDF_Array* pArray)
875 {
876 CPDF_Object* pBaseCS = pArray->GetElementValue(1);
877 if (pBaseCS == m_pArray) {
878 return FALSE;
879 }
880 CPDF_DocPageData* pDocPageData = pDoc->GetPageData();
881 m_pBaseCS = pDocPageData->GetColorSpace(pBaseCS, NULL);
882 if (m_pBaseCS) {
883 if (m_pBaseCS->GetFamily() == PDFCS_PATTERN) {
884 return FALSE;
885 }
886 m_pCountedBaseCS = pDocPageData->FindColorSpacePtr(m_pBaseCS->GetArray() );
887 m_nComponents = m_pBaseCS->CountComponents() + 1;
888 if (m_pBaseCS->CountComponents() > MAX_PATTERN_COLORCOMPS) {
889 return FALSE;
890 }
891 } else {
892 m_nComponents = 1;
893 }
894 return TRUE;
895 }
896 FX_BOOL CPDF_PatternCS::GetRGB(FX_FLOAT* pBuf, FX_FLOAT& R, FX_FLOAT& G, FX_FLOA T& B) const
897 {
898 if (m_pBaseCS) {
899 ASSERT(m_pBaseCS->GetFamily() != PDFCS_PATTERN);
900 PatternValue* pvalue = (PatternValue*)pBuf;
901 if (m_pBaseCS->GetRGB(pvalue->m_Comps, R, G, B)) {
902 return TRUE;
903 }
904 }
905 R = G = B = 0.75f;
906 return FALSE;
907 }
908 CPDF_ColorSpace* CPDF_PatternCS::GetBaseCS() const
909 {
910 return m_pBaseCS;
911 }
912 class CPDF_SeparationCS : public CPDF_ColorSpace
913 {
914 public:
915 CPDF_SeparationCS(CPDF_Document* pDoc)
916 : CPDF_ColorSpace(pDoc, PDFCS_SEPARATION, 1),
917 m_pAltCS(nullptr),
918 m_pFunc(nullptr) {
919 }
920 ~CPDF_SeparationCS() override;
921 void GetDefaultValue(int iComponent, FX_FLOAT& value, FX_FLOAT& min, FX_FLOA T& max) const override;
922 FX_BOOL v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) override;
923 FX_BOOL GetRGB(FX_FLOAT* pBuf, FX_FLOAT& R, FX_FLOAT& G, FX_FLOAT& B) const override;
924 void EnableStdConversion(FX_BOOL bEnabled) override;
925
926 CPDF_ColorSpace* m_pAltCS;
927 CPDF_Function* m_pFunc;
928 enum { None, All, Colorant } m_Type;
929 };
930 CPDF_SeparationCS::~CPDF_SeparationCS()
931 {
932 if (m_pAltCS) {
933 m_pAltCS->ReleaseCS();
934 }
935 delete m_pFunc;
936 }
937 void CPDF_SeparationCS::GetDefaultValue(int iComponent, FX_FLOAT& value, FX_FLOA T& min, FX_FLOAT& max) const
938 {
939 value = 1.0f;
940 min = 0;
941 max = 1.0f;
942 }
943 FX_BOOL CPDF_SeparationCS::v_Load(CPDF_Document* pDoc, CPDF_Array* pArray)
944 {
945 CFX_ByteString name = pArray->GetString(1);
946 if (name == FX_BSTRC("None")) {
947 m_Type = None;
948 } else {
949 m_Type = Colorant;
950 CPDF_Object* pAltCS = pArray->GetElementValue(2);
951 if (pAltCS == m_pArray) {
952 return FALSE;
953 }
954 m_pAltCS = Load(pDoc, pAltCS);
955 if (!m_pAltCS) {
956 return FALSE;
957 }
958 CPDF_Object* pFuncObj = pArray->GetElementValue(3);
959 if (pFuncObj && pFuncObj->GetType() != PDFOBJ_NAME) {
960 m_pFunc = CPDF_Function::Load(pFuncObj);
961 }
962 if (m_pFunc && m_pFunc->CountOutputs() < m_pAltCS->CountComponents()) {
963 delete m_pFunc;
964 m_pFunc = NULL;
965 }
966 }
967 return TRUE;
968 }
969 FX_BOOL CPDF_SeparationCS::GetRGB(FX_FLOAT* pBuf, FX_FLOAT& R, FX_FLOAT& G, FX_F LOAT& B) const
970 {
971 if (m_Type == None) {
972 return FALSE;
973 }
974 if (m_pFunc == NULL) {
975 if (m_pAltCS == NULL) {
976 return FALSE;
977 }
978 int nComps = m_pAltCS->CountComponents();
979 CFX_FixedBufGrow<FX_FLOAT, 16> results(nComps);
980 for (int i = 0; i < nComps; i ++) {
981 results[i] = *pBuf;
982 }
983 m_pAltCS->GetRGB(results, R, G, B);
984 return TRUE;
985 }
986 CFX_FixedBufGrow<FX_FLOAT, 16> results(m_pFunc->CountOutputs());
987 int nresults = 0;
988 m_pFunc->Call(pBuf, 1, results, nresults);
989 if (nresults == 0) {
990 return FALSE;
991 }
992 if (m_pAltCS) {
993 m_pAltCS->GetRGB(results, R, G, B);
994 return TRUE;
995 }
996 R = G = B = 0;
997 return FALSE;
998 }
999 void CPDF_SeparationCS::EnableStdConversion(FX_BOOL bEnabled)
1000 {
1001 CPDF_ColorSpace::EnableStdConversion(bEnabled);
1002 if (m_pAltCS) {
1003 m_pAltCS->EnableStdConversion(bEnabled);
1004 }
1005 }
1006 class CPDF_DeviceNCS : public CPDF_ColorSpace
1007 {
1008 public:
1009 CPDF_DeviceNCS(CPDF_Document* pDoc)
1010 : CPDF_ColorSpace(pDoc, PDFCS_DEVICEN, 0),
1011 m_pAltCS(nullptr),
1012 m_pFunc(nullptr) {
1013 }
1014 ~CPDF_DeviceNCS() override;
1015 void GetDefaultValue(int iComponent, FX_FLOAT& value, FX_FLOAT& min, FX_FLOA T& max) const override;
1016 FX_BOOL v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) override;
1017 FX_BOOL GetRGB(FX_FLOAT* pBuf, FX_FLOAT& R, FX_FLOAT& G, FX_FLOAT& B) const override;
1018 void EnableStdConversion(FX_BOOL bEnabled) override;
1019
1020 CPDF_ColorSpace* m_pAltCS;
1021 CPDF_Function* m_pFunc;
1022 };
1023 CPDF_DeviceNCS::~CPDF_DeviceNCS()
1024 {
1025 delete m_pFunc;
1026 if (m_pAltCS) {
1027 m_pAltCS->ReleaseCS();
1028 }
1029 }
1030 void CPDF_DeviceNCS::GetDefaultValue(int iComponent, FX_FLOAT& value, FX_FLOAT& min, FX_FLOAT& max) const
1031 {
1032 value = 1.0f;
1033 min = 0;
1034 max = 1.0f;
1035 }
1036 FX_BOOL CPDF_DeviceNCS::v_Load(CPDF_Document* pDoc, CPDF_Array* pArray)
1037 {
1038 CPDF_Object* pObj = pArray->GetElementValue(1);
1039 if (!pObj) {
1040 return FALSE;
1041 }
1042 if (pObj->GetType() != PDFOBJ_ARRAY) {
1043 return FALSE;
1044 }
1045 m_nComponents = ((CPDF_Array*)pObj)->GetCount();
1046 CPDF_Object* pAltCS = pArray->GetElementValue(2); 1058 CPDF_Object* pAltCS = pArray->GetElementValue(2);
1047 if (!pAltCS || pAltCS == m_pArray) { 1059 if (pAltCS == m_pArray) {
1048 return FALSE; 1060 return FALSE;
1049 } 1061 }
1050 m_pAltCS = Load(pDoc, pAltCS); 1062 m_pAltCS = Load(pDoc, pAltCS);
1051 m_pFunc = CPDF_Function::Load(pArray->GetElementValue(3)); 1063 if (!m_pAltCS) {
1052 if (m_pAltCS == NULL || m_pFunc == NULL) { 1064 return FALSE;
1053 return FALSE; 1065 }
1054 } 1066 CPDF_Object* pFuncObj = pArray->GetElementValue(3);
1055 if (m_pFunc->CountOutputs() < m_pAltCS->CountComponents()) { 1067 if (pFuncObj && pFuncObj->GetType() != PDFOBJ_NAME) {
1056 return FALSE; 1068 m_pFunc = CPDF_Function::Load(pFuncObj);
1057 } 1069 }
1058 return TRUE; 1070 if (m_pFunc && m_pFunc->CountOutputs() < m_pAltCS->CountComponents()) {
1059 } 1071 delete m_pFunc;
1060 FX_BOOL CPDF_DeviceNCS::GetRGB(FX_FLOAT* pBuf, FX_FLOAT& R, FX_FLOAT& G, FX_FLOA T& B) const 1072 m_pFunc = NULL;
1061 { 1073 }
1062 if (m_pFunc == NULL) { 1074 }
1063 return FALSE; 1075 return TRUE;
1064 } 1076 }
1065 CFX_FixedBufGrow<FX_FLOAT, 16> results(m_pFunc->CountOutputs()); 1077 FX_BOOL CPDF_SeparationCS::GetRGB(FX_FLOAT* pBuf,
1066 int nresults = 0; 1078 FX_FLOAT& R,
1067 m_pFunc->Call(pBuf, m_nComponents, results, nresults); 1079 FX_FLOAT& G,
1068 if (nresults == 0) { 1080 FX_FLOAT& B) const {
1069 return FALSE; 1081 if (m_Type == None) {
1082 return FALSE;
1083 }
1084 if (m_pFunc == NULL) {
1085 if (m_pAltCS == NULL) {
1086 return FALSE;
1087 }
1088 int nComps = m_pAltCS->CountComponents();
1089 CFX_FixedBufGrow<FX_FLOAT, 16> results(nComps);
1090 for (int i = 0; i < nComps; i++) {
1091 results[i] = *pBuf;
1070 } 1092 }
1071 m_pAltCS->GetRGB(results, R, G, B); 1093 m_pAltCS->GetRGB(results, R, G, B);
1072 return TRUE; 1094 return TRUE;
1073 } 1095 }
1074 void CPDF_DeviceNCS::EnableStdConversion(FX_BOOL bEnabled) 1096 CFX_FixedBufGrow<FX_FLOAT, 16> results(m_pFunc->CountOutputs());
1075 { 1097 int nresults = 0;
1076 CPDF_ColorSpace::EnableStdConversion(bEnabled); 1098 m_pFunc->Call(pBuf, 1, results, nresults);
1077 if (m_pAltCS) { 1099 if (nresults == 0) {
1078 m_pAltCS->EnableStdConversion(bEnabled); 1100 return FALSE;
1079 } 1101 }
1080 } 1102 if (m_pAltCS) {
1081 CPDF_ColorSpace* CPDF_ColorSpace::GetStockCS(int family) 1103 m_pAltCS->GetRGB(results, R, G, B);
1082 { 1104 return TRUE;
1083 return CPDF_ModuleMgr::Get()->GetPageModule()->GetStockCS(family);; 1105 }
1084 } 1106 R = G = B = 0;
1085 CPDF_ColorSpace* _CSFromName(const CFX_ByteString& name) 1107 return FALSE;
1086 { 1108 }
1087 if (name == FX_BSTRC("DeviceRGB") || name == FX_BSTRC("RGB")) { 1109 void CPDF_SeparationCS::EnableStdConversion(FX_BOOL bEnabled) {
1088 return CPDF_ColorSpace::GetStockCS(PDFCS_DEVICERGB); 1110 CPDF_ColorSpace::EnableStdConversion(bEnabled);
1089 } 1111 if (m_pAltCS) {
1090 if (name == FX_BSTRC("DeviceGray") || name == FX_BSTRC("G")) { 1112 m_pAltCS->EnableStdConversion(bEnabled);
1091 return CPDF_ColorSpace::GetStockCS(PDFCS_DEVICEGRAY); 1113 }
1092 } 1114 }
1093 if (name == FX_BSTRC("DeviceCMYK") || name == FX_BSTRC("CMYK")) { 1115 class CPDF_DeviceNCS : public CPDF_ColorSpace {
1094 return CPDF_ColorSpace::GetStockCS(PDFCS_DEVICECMYK); 1116 public:
1095 } 1117 CPDF_DeviceNCS(CPDF_Document* pDoc)
1096 if (name == FX_BSTRC("Pattern")) { 1118 : CPDF_ColorSpace(pDoc, PDFCS_DEVICEN, 0),
1097 return CPDF_ColorSpace::GetStockCS(PDFCS_PATTERN); 1119 m_pAltCS(nullptr),
1098 } 1120 m_pFunc(nullptr) {}
1121 ~CPDF_DeviceNCS() override;
1122 void GetDefaultValue(int iComponent,
1123 FX_FLOAT& value,
1124 FX_FLOAT& min,
1125 FX_FLOAT& max) const override;
1126 FX_BOOL v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) override;
1127 FX_BOOL GetRGB(FX_FLOAT* pBuf,
1128 FX_FLOAT& R,
1129 FX_FLOAT& G,
1130 FX_FLOAT& B) const override;
1131 void EnableStdConversion(FX_BOOL bEnabled) override;
1132
1133 CPDF_ColorSpace* m_pAltCS;
1134 CPDF_Function* m_pFunc;
1135 };
1136 CPDF_DeviceNCS::~CPDF_DeviceNCS() {
1137 delete m_pFunc;
1138 if (m_pAltCS) {
1139 m_pAltCS->ReleaseCS();
1140 }
1141 }
1142 void CPDF_DeviceNCS::GetDefaultValue(int iComponent,
1143 FX_FLOAT& value,
1144 FX_FLOAT& min,
1145 FX_FLOAT& max) const {
1146 value = 1.0f;
1147 min = 0;
1148 max = 1.0f;
1149 }
1150 FX_BOOL CPDF_DeviceNCS::v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) {
1151 CPDF_Object* pObj = pArray->GetElementValue(1);
1152 if (!pObj) {
1153 return FALSE;
1154 }
1155 if (pObj->GetType() != PDFOBJ_ARRAY) {
1156 return FALSE;
1157 }
1158 m_nComponents = ((CPDF_Array*)pObj)->GetCount();
1159 CPDF_Object* pAltCS = pArray->GetElementValue(2);
1160 if (!pAltCS || pAltCS == m_pArray) {
1161 return FALSE;
1162 }
1163 m_pAltCS = Load(pDoc, pAltCS);
1164 m_pFunc = CPDF_Function::Load(pArray->GetElementValue(3));
1165 if (m_pAltCS == NULL || m_pFunc == NULL) {
1166 return FALSE;
1167 }
1168 if (m_pFunc->CountOutputs() < m_pAltCS->CountComponents()) {
1169 return FALSE;
1170 }
1171 return TRUE;
1172 }
1173 FX_BOOL CPDF_DeviceNCS::GetRGB(FX_FLOAT* pBuf,
1174 FX_FLOAT& R,
1175 FX_FLOAT& G,
1176 FX_FLOAT& B) const {
1177 if (m_pFunc == NULL) {
1178 return FALSE;
1179 }
1180 CFX_FixedBufGrow<FX_FLOAT, 16> results(m_pFunc->CountOutputs());
1181 int nresults = 0;
1182 m_pFunc->Call(pBuf, m_nComponents, results, nresults);
1183 if (nresults == 0) {
1184 return FALSE;
1185 }
1186 m_pAltCS->GetRGB(results, R, G, B);
1187 return TRUE;
1188 }
1189 void CPDF_DeviceNCS::EnableStdConversion(FX_BOOL bEnabled) {
1190 CPDF_ColorSpace::EnableStdConversion(bEnabled);
1191 if (m_pAltCS) {
1192 m_pAltCS->EnableStdConversion(bEnabled);
1193 }
1194 }
1195 CPDF_ColorSpace* CPDF_ColorSpace::GetStockCS(int family) {
1196 return CPDF_ModuleMgr::Get()->GetPageModule()->GetStockCS(family);
1197 ;
1198 }
1199 CPDF_ColorSpace* _CSFromName(const CFX_ByteString& name) {
1200 if (name == FX_BSTRC("DeviceRGB") || name == FX_BSTRC("RGB")) {
1201 return CPDF_ColorSpace::GetStockCS(PDFCS_DEVICERGB);
1202 }
1203 if (name == FX_BSTRC("DeviceGray") || name == FX_BSTRC("G")) {
1204 return CPDF_ColorSpace::GetStockCS(PDFCS_DEVICEGRAY);
1205 }
1206 if (name == FX_BSTRC("DeviceCMYK") || name == FX_BSTRC("CMYK")) {
1207 return CPDF_ColorSpace::GetStockCS(PDFCS_DEVICECMYK);
1208 }
1209 if (name == FX_BSTRC("Pattern")) {
1210 return CPDF_ColorSpace::GetStockCS(PDFCS_PATTERN);
1211 }
1212 return NULL;
1213 }
1214 CPDF_ColorSpace* CPDF_ColorSpace::Load(CPDF_Document* pDoc, CPDF_Object* pObj) {
1215 if (pObj == NULL) {
1099 return NULL; 1216 return NULL;
1100 } 1217 }
1101 CPDF_ColorSpace* CPDF_ColorSpace::Load(CPDF_Document* pDoc, CPDF_Object* pObj) 1218 if (pObj->GetType() == PDFOBJ_NAME) {
1102 { 1219 return _CSFromName(pObj->GetString());
1103 if (pObj == NULL) { 1220 }
1104 return NULL; 1221 if (pObj->GetType() == PDFOBJ_STREAM) {
1105 } 1222 CPDF_Dictionary* pDict = ((CPDF_Stream*)pObj)->GetDict();
1106 if (pObj->GetType() == PDFOBJ_NAME) { 1223 if (!pDict) {
1107 return _CSFromName(pObj->GetString()); 1224 return NULL;
1108 } 1225 }
1109 if (pObj->GetType() == PDFOBJ_STREAM) { 1226 CPDF_ColorSpace* pRet = NULL;
1110 CPDF_Dictionary *pDict = ((CPDF_Stream *)pObj)->GetDict(); 1227 FX_POSITION pos = pDict->GetStartPos();
1111 if (!pDict) { 1228 while (pos) {
1112 return NULL; 1229 CFX_ByteString bsKey;
1113 } 1230 CPDF_Object* pValue = pDict->GetNextElement(pos, bsKey);
1114 CPDF_ColorSpace *pRet = NULL; 1231 if (pValue && pValue->GetType() == PDFOBJ_NAME) {
1115 FX_POSITION pos = pDict->GetStartPos(); 1232 pRet = _CSFromName(pValue->GetString());
1116 while (pos) { 1233 }
1117 CFX_ByteString bsKey; 1234 if (pRet) {
1118 CPDF_Object *pValue = pDict->GetNextElement(pos, bsKey); 1235 return pRet;
1119 if (pValue && pValue->GetType() == PDFOBJ_NAME) { 1236 }
1120 pRet = _CSFromName(pValue->GetString()); 1237 }
1121 } 1238 return NULL;
1122 if (pRet) { 1239 }
1123 return pRet; 1240 if (pObj->GetType() != PDFOBJ_ARRAY) {
1124 } 1241 return NULL;
1125 } 1242 }
1126 return NULL; 1243 CPDF_Array* pArray = (CPDF_Array*)pObj;
1127 } 1244 if (pArray->GetCount() == 0) {
1128 if (pObj->GetType() != PDFOBJ_ARRAY) { 1245 return NULL;
1129 return NULL; 1246 }
1130 } 1247 CPDF_Object* pFamilyObj = pArray->GetElementValue(0);
1131 CPDF_Array* pArray = (CPDF_Array*)pObj; 1248 if (!pFamilyObj) {
1132 if (pArray->GetCount() == 0) { 1249 return NULL;
1133 return NULL; 1250 }
1134 } 1251 CFX_ByteString familyname = pFamilyObj->GetString();
1135 CPDF_Object *pFamilyObj = pArray->GetElementValue(0); 1252 if (pArray->GetCount() == 1) {
1136 if (!pFamilyObj) { 1253 return _CSFromName(familyname);
1137 return NULL; 1254 }
1138 } 1255 CPDF_ColorSpace* pCS = NULL;
1139 CFX_ByteString familyname = pFamilyObj->GetString(); 1256 FX_DWORD id = familyname.GetID();
1140 if (pArray->GetCount() == 1) { 1257 if (id == FXBSTR_ID('C', 'a', 'l', 'G')) {
1141 return _CSFromName(familyname); 1258 pCS = new CPDF_CalGray(pDoc);
1142 } 1259 } else if (id == FXBSTR_ID('C', 'a', 'l', 'R')) {
1143 CPDF_ColorSpace* pCS = NULL; 1260 pCS = new CPDF_CalRGB(pDoc);
1144 FX_DWORD id = familyname.GetID(); 1261 } else if (id == FXBSTR_ID('L', 'a', 'b', 0)) {
1145 if (id == FXBSTR_ID('C', 'a', 'l', 'G')) { 1262 pCS = new CPDF_LabCS(pDoc);
1146 pCS = new CPDF_CalGray(pDoc); 1263 } else if (id == FXBSTR_ID('I', 'C', 'C', 'B')) {
1147 } else if (id == FXBSTR_ID('C', 'a', 'l', 'R')) { 1264 pCS = new CPDF_ICCBasedCS(pDoc);
1148 pCS = new CPDF_CalRGB(pDoc); 1265 } else if (id == FXBSTR_ID('I', 'n', 'd', 'e') ||
1149 } else if (id == FXBSTR_ID('L', 'a', 'b', 0)) { 1266 id == FXBSTR_ID('I', 0, 0, 0)) {
1150 pCS = new CPDF_LabCS(pDoc); 1267 pCS = new CPDF_IndexedCS(pDoc);
1151 } else if (id == FXBSTR_ID('I', 'C', 'C', 'B')) { 1268 } else if (id == FXBSTR_ID('S', 'e', 'p', 'a')) {
1152 pCS = new CPDF_ICCBasedCS(pDoc); 1269 pCS = new CPDF_SeparationCS(pDoc);
1153 } else if (id == FXBSTR_ID('I', 'n', 'd', 'e') || id == FXBSTR_ID('I', 0, 0, 0)) { 1270 } else if (id == FXBSTR_ID('D', 'e', 'v', 'i')) {
1154 pCS = new CPDF_IndexedCS(pDoc); 1271 pCS = new CPDF_DeviceNCS(pDoc);
1155 } else if (id == FXBSTR_ID('S', 'e', 'p', 'a')) { 1272 } else if (id == FXBSTR_ID('P', 'a', 't', 't')) {
1156 pCS = new CPDF_SeparationCS(pDoc); 1273 pCS = new CPDF_PatternCS(pDoc);
1157 } else if (id == FXBSTR_ID('D', 'e', 'v', 'i')) { 1274 } else {
1158 pCS = new CPDF_DeviceNCS(pDoc); 1275 return NULL;
1159 } else if (id == FXBSTR_ID('P', 'a', 't', 't')) { 1276 }
1160 pCS = new CPDF_PatternCS(pDoc); 1277 pCS->m_pArray = pArray;
1161 } else { 1278 if (!pCS->v_Load(pDoc, pArray)) {
1162 return NULL; 1279 pCS->ReleaseCS();
1163 } 1280 return NULL;
1164 pCS->m_pArray = pArray; 1281 }
1165 if (!pCS->v_Load(pDoc, pArray)) { 1282 return pCS;
1166 pCS->ReleaseCS(); 1283 }
1167 return NULL; 1284 void CPDF_ColorSpace::ReleaseCS() {
1168 } 1285 if (this == GetStockCS(PDFCS_DEVICERGB)) {
1169 return pCS; 1286 return;
1170 } 1287 }
1171 void CPDF_ColorSpace::ReleaseCS() 1288 if (this == GetStockCS(PDFCS_DEVICEGRAY)) {
1172 { 1289 return;
1173 if (this == GetStockCS(PDFCS_DEVICERGB)) { 1290 }
1174 return; 1291 if (this == GetStockCS(PDFCS_DEVICECMYK)) {
1175 } 1292 return;
1176 if (this == GetStockCS(PDFCS_DEVICEGRAY)) { 1293 }
1177 return; 1294 if (this == GetStockCS(PDFCS_PATTERN)) {
1178 } 1295 return;
1179 if (this == GetStockCS(PDFCS_DEVICECMYK)) { 1296 }
1180 return; 1297 delete this;
1181 } 1298 }
1182 if (this == GetStockCS(PDFCS_PATTERN)) { 1299 int CPDF_ColorSpace::GetBufSize() const {
1183 return; 1300 if (m_Family == PDFCS_PATTERN) {
1184 } 1301 return sizeof(PatternValue);
1185 delete this; 1302 }
1186 } 1303 return m_nComponents * sizeof(FX_FLOAT);
1187 int CPDF_ColorSpace::GetBufSize() const 1304 }
1188 { 1305 FX_FLOAT* CPDF_ColorSpace::CreateBuf() {
1189 if (m_Family == PDFCS_PATTERN) { 1306 int size = GetBufSize();
1190 return sizeof(PatternValue); 1307 uint8_t* pBuf = FX_Alloc(uint8_t, size);
1191 } 1308 return (FX_FLOAT*)pBuf;
1192 return m_nComponents * sizeof(FX_FLOAT); 1309 }
1193 } 1310 FX_BOOL CPDF_ColorSpace::sRGB() const {
1194 FX_FLOAT* CPDF_ColorSpace::CreateBuf() 1311 if (m_Family == PDFCS_DEVICERGB) {
1195 {
1196 int size = GetBufSize();
1197 uint8_t* pBuf = FX_Alloc(uint8_t, size);
1198 return (FX_FLOAT*)pBuf;
1199 }
1200 FX_BOOL CPDF_ColorSpace::sRGB() const
1201 {
1202 if (m_Family == PDFCS_DEVICERGB) {
1203 return TRUE;
1204 }
1205 if (m_Family != PDFCS_ICCBASED) {
1206 return FALSE;
1207 }
1208 CPDF_ICCBasedCS* pCS = (CPDF_ICCBasedCS*)this;
1209 return pCS->m_pProfile->m_bsRGB;
1210 }
1211 FX_BOOL CPDF_ColorSpace::GetCMYK(FX_FLOAT* pBuf, FX_FLOAT& c, FX_FLOAT& m, FX_FL OAT& y, FX_FLOAT& k) const
1212 {
1213 if (v_GetCMYK(pBuf, c, m, y, k)) {
1214 return TRUE;
1215 }
1216 FX_FLOAT R, G, B;
1217 if (!GetRGB(pBuf, R, G, B)) {
1218 return FALSE;
1219 }
1220 sRGB_to_AdobeCMYK(R, G, B, c, m, y, k);
1221 return TRUE; 1312 return TRUE;
1222 } 1313 }
1223 FX_BOOL CPDF_ColorSpace::SetCMYK(FX_FLOAT* pBuf, FX_FLOAT c, FX_FLOAT m, FX_FLOA T y, FX_FLOAT k) const 1314 if (m_Family != PDFCS_ICCBASED) {
1224 { 1315 return FALSE;
1225 if (v_SetCMYK(pBuf, c, m, y, k)) { 1316 }
1226 return TRUE; 1317 CPDF_ICCBasedCS* pCS = (CPDF_ICCBasedCS*)this;
1227 } 1318 return pCS->m_pProfile->m_bsRGB;
1228 FX_FLOAT R, G, B; 1319 }
1229 AdobeCMYK_to_sRGB(c, m, y, k, R, G, B); 1320 FX_BOOL CPDF_ColorSpace::GetCMYK(FX_FLOAT* pBuf,
1230 return SetRGB(pBuf, R, G, B); 1321 FX_FLOAT& c,
1231 } 1322 FX_FLOAT& m,
1232 void CPDF_ColorSpace::GetDefaultColor(FX_FLOAT* buf) const 1323 FX_FLOAT& y,
1233 { 1324 FX_FLOAT& k) const {
1234 if (buf == NULL || m_Family == PDFCS_PATTERN) { 1325 if (v_GetCMYK(pBuf, c, m, y, k)) {
1235 return; 1326 return TRUE;
1236 } 1327 }
1237 FX_FLOAT min, max; 1328 FX_FLOAT R, G, B;
1238 for (int i = 0; i < m_nComponents; i ++) { 1329 if (!GetRGB(pBuf, R, G, B)) {
1239 GetDefaultValue(i, buf[i], min, max); 1330 return FALSE;
1240 } 1331 }
1241 } 1332 sRGB_to_AdobeCMYK(R, G, B, c, m, y, k);
1242 int CPDF_ColorSpace::GetMaxIndex() const 1333 return TRUE;
1243 { 1334 }
1244 if (m_Family != PDFCS_INDEXED) { 1335 FX_BOOL CPDF_ColorSpace::SetCMYK(FX_FLOAT* pBuf,
1245 return 0; 1336 FX_FLOAT c,
1246 } 1337 FX_FLOAT m,
1247 CPDF_IndexedCS* pCS = (CPDF_IndexedCS*)this; 1338 FX_FLOAT y,
1248 return pCS->m_MaxIndex; 1339 FX_FLOAT k) const {
1249 } 1340 if (v_SetCMYK(pBuf, c, m, y, k)) {
1250 void CPDF_ColorSpace::TranslateImageLine(uint8_t* dest_buf, const uint8_t* src_b uf, int pixels, int image_width, int image_height, FX_BOOL bTransMask) const 1341 return TRUE;
1251 { 1342 }
1252 CFX_FixedBufGrow<FX_FLOAT, 16> srcbuf(m_nComponents); 1343 FX_FLOAT R, G, B;
1253 FX_FLOAT* src = srcbuf; 1344 AdobeCMYK_to_sRGB(c, m, y, k, R, G, B);
1254 FX_FLOAT R, G, B; 1345 return SetRGB(pBuf, R, G, B);
1255 for (int i = 0; i < pixels; i ++) { 1346 }
1256 for (int j = 0; j < m_nComponents; j ++) 1347 void CPDF_ColorSpace::GetDefaultColor(FX_FLOAT* buf) const {
1257 if (m_Family == PDFCS_INDEXED) { 1348 if (buf == NULL || m_Family == PDFCS_PATTERN) {
1258 src[j] = (FX_FLOAT)(*src_buf ++); 1349 return;
1259 } else { 1350 }
1260 src[j] = (FX_FLOAT)(*src_buf ++) / 255; 1351 FX_FLOAT min, max;
1261 } 1352 for (int i = 0; i < m_nComponents; i++) {
1262 GetRGB(src, R, G, B); 1353 GetDefaultValue(i, buf[i], min, max);
1263 *dest_buf ++ = (int32_t)(B * 255); 1354 }
1264 *dest_buf ++ = (int32_t)(G * 255); 1355 }
1265 *dest_buf ++ = (int32_t)(R * 255); 1356 int CPDF_ColorSpace::GetMaxIndex() const {
1266 } 1357 if (m_Family != PDFCS_INDEXED) {
1267 } 1358 return 0;
1268 void CPDF_ColorSpace::EnableStdConversion(FX_BOOL bEnabled) 1359 }
1269 { 1360 CPDF_IndexedCS* pCS = (CPDF_IndexedCS*)this;
1270 if (bEnabled) { 1361 return pCS->m_MaxIndex;
1271 m_dwStdConversion ++; 1362 }
1272 } else if (m_dwStdConversion) { 1363 void CPDF_ColorSpace::TranslateImageLine(uint8_t* dest_buf,
1273 m_dwStdConversion --; 1364 const uint8_t* src_buf,
1274 } 1365 int pixels,
1275 } 1366 int image_width,
1276 CPDF_Color::CPDF_Color(int family) 1367 int image_height,
1277 { 1368 FX_BOOL bTransMask) const {
1278 m_pCS = CPDF_ColorSpace::GetStockCS(family); 1369 CFX_FixedBufGrow<FX_FLOAT, 16> srcbuf(m_nComponents);
1279 int nComps = 3; 1370 FX_FLOAT* src = srcbuf;
1280 if (family == PDFCS_DEVICEGRAY) { 1371 FX_FLOAT R, G, B;
1281 nComps = 1; 1372 for (int i = 0; i < pixels; i++) {
1282 } else if (family == PDFCS_DEVICECMYK) { 1373 for (int j = 0; j < m_nComponents; j++)
1283 nComps = 4; 1374 if (m_Family == PDFCS_INDEXED) {
1284 } 1375 src[j] = (FX_FLOAT)(*src_buf++);
1285 m_pBuffer = FX_Alloc(FX_FLOAT, nComps); 1376 } else {
1286 for (int i = 0; i < nComps; i ++) { 1377 src[j] = (FX_FLOAT)(*src_buf++) / 255;
1287 m_pBuffer[i] = 0; 1378 }
1288 } 1379 GetRGB(src, R, G, B);
1289 } 1380 *dest_buf++ = (int32_t)(B * 255);
1290 CPDF_Color::~CPDF_Color() 1381 *dest_buf++ = (int32_t)(G * 255);
1291 { 1382 *dest_buf++ = (int32_t)(R * 255);
1292 ReleaseBuffer(); 1383 }
1293 ReleaseColorSpace(); 1384 }
1294 } 1385 void CPDF_ColorSpace::EnableStdConversion(FX_BOOL bEnabled) {
1295 void CPDF_Color::ReleaseBuffer() 1386 if (bEnabled) {
1296 { 1387 m_dwStdConversion++;
1297 if (!m_pBuffer) { 1388 } else if (m_dwStdConversion) {
1298 return; 1389 m_dwStdConversion--;
1299 } 1390 }
1300 if (m_pCS->GetFamily() == PDFCS_PATTERN) { 1391 }
1301 PatternValue* pvalue = (PatternValue*)m_pBuffer; 1392 CPDF_Color::CPDF_Color(int family) {
1302 CPDF_Pattern* pPattern = pvalue->m_pCountedPattern ? pvalue->m_pCountedP attern->get() : NULL; 1393 m_pCS = CPDF_ColorSpace::GetStockCS(family);
1303 if (pPattern && pPattern->m_pDocument) { 1394 int nComps = 3;
1304 CPDF_DocPageData *pPageData = pPattern->m_pDocument->GetPageData(); 1395 if (family == PDFCS_DEVICEGRAY) {
1305 if (pPageData) { 1396 nComps = 1;
1306 pPageData->ReleasePattern(pPattern->m_pPatternObj); 1397 } else if (family == PDFCS_DEVICECMYK) {
1307 } 1398 nComps = 4;
1308 } 1399 }
1309 } 1400 m_pBuffer = FX_Alloc(FX_FLOAT, nComps);
1310 FX_Free(m_pBuffer); 1401 for (int i = 0; i < nComps; i++) {
1311 m_pBuffer = NULL; 1402 m_pBuffer[i] = 0;
1312 } 1403 }
1313 void CPDF_Color::ReleaseColorSpace() 1404 }
1314 { 1405 CPDF_Color::~CPDF_Color() {
1315 if (m_pCS && m_pCS->m_pDocument && m_pCS->GetArray()) { 1406 ReleaseBuffer();
1316 m_pCS->m_pDocument->GetPageData()->ReleaseColorSpace(m_pCS->GetArray()); 1407 ReleaseColorSpace();
1317 m_pCS = NULL; 1408 }
1318 } 1409 void CPDF_Color::ReleaseBuffer() {
1319 } 1410 if (!m_pBuffer) {
1320 void CPDF_Color::SetColorSpace(CPDF_ColorSpace* pCS) 1411 return;
1321 { 1412 }
1322 if (m_pCS == pCS) { 1413 if (m_pCS->GetFamily() == PDFCS_PATTERN) {
1323 if (m_pBuffer == NULL) { 1414 PatternValue* pvalue = (PatternValue*)m_pBuffer;
1324 m_pBuffer = pCS->CreateBuf(); 1415 CPDF_Pattern* pPattern =
1325 } 1416 pvalue->m_pCountedPattern ? pvalue->m_pCountedPattern->get() : NULL;
1326 ReleaseColorSpace(); 1417 if (pPattern && pPattern->m_pDocument) {
1327 m_pCS = pCS; 1418 CPDF_DocPageData* pPageData = pPattern->m_pDocument->GetPageData();
1328 return; 1419 if (pPageData) {
1329 } 1420 pPageData->ReleasePattern(pPattern->m_pPatternObj);
1330 ReleaseBuffer(); 1421 }
1422 }
1423 }
1424 FX_Free(m_pBuffer);
1425 m_pBuffer = NULL;
1426 }
1427 void CPDF_Color::ReleaseColorSpace() {
1428 if (m_pCS && m_pCS->m_pDocument && m_pCS->GetArray()) {
1429 m_pCS->m_pDocument->GetPageData()->ReleaseColorSpace(m_pCS->GetArray());
1430 m_pCS = NULL;
1431 }
1432 }
1433 void CPDF_Color::SetColorSpace(CPDF_ColorSpace* pCS) {
1434 if (m_pCS == pCS) {
1435 if (m_pBuffer == NULL) {
1436 m_pBuffer = pCS->CreateBuf();
1437 }
1331 ReleaseColorSpace(); 1438 ReleaseColorSpace();
1332 m_pCS = pCS; 1439 m_pCS = pCS;
1333 if (m_pCS) { 1440 return;
1334 m_pBuffer = pCS->CreateBuf(); 1441 }
1335 pCS->GetDefaultColor(m_pBuffer); 1442 ReleaseBuffer();
1336 } 1443 ReleaseColorSpace();
1337 } 1444 m_pCS = pCS;
1338 void CPDF_Color::SetValue(FX_FLOAT* comps) 1445 if (m_pCS) {
1339 { 1446 m_pBuffer = pCS->CreateBuf();
1340 if (m_pBuffer == NULL) { 1447 pCS->GetDefaultColor(m_pBuffer);
1341 return; 1448 }
1342 } 1449 }
1343 if (m_pCS->GetFamily() != PDFCS_PATTERN) { 1450 void CPDF_Color::SetValue(FX_FLOAT* comps) {
1344 FXSYS_memcpy(m_pBuffer, comps, m_pCS->CountComponents() * sizeof(FX_FLOA T)); 1451 if (m_pBuffer == NULL) {
1345 } 1452 return;
1346 } 1453 }
1347 void CPDF_Color::SetValue(CPDF_Pattern* pPattern, FX_FLOAT* comps, int ncomps) 1454 if (m_pCS->GetFamily() != PDFCS_PATTERN) {
1348 { 1455 FXSYS_memcpy(m_pBuffer, comps, m_pCS->CountComponents() * sizeof(FX_FLOAT));
1349 if (ncomps > MAX_PATTERN_COLORCOMPS) { 1456 }
1350 return; 1457 }
1351 } 1458 void CPDF_Color::SetValue(CPDF_Pattern* pPattern, FX_FLOAT* comps, int ncomps) {
1352 if (m_pCS == NULL || m_pCS->GetFamily() != PDFCS_PATTERN) { 1459 if (ncomps > MAX_PATTERN_COLORCOMPS) {
1353 if (m_pBuffer) { 1460 return;
1354 FX_Free(m_pBuffer); 1461 }
1355 } 1462 if (m_pCS == NULL || m_pCS->GetFamily() != PDFCS_PATTERN) {
1356 m_pCS = CPDF_ColorSpace::GetStockCS(PDFCS_PATTERN); 1463 if (m_pBuffer) {
1357 m_pBuffer = m_pCS->CreateBuf(); 1464 FX_Free(m_pBuffer);
1358 } 1465 }
1359 CPDF_DocPageData *pDocPageData = NULL; 1466 m_pCS = CPDF_ColorSpace::GetStockCS(PDFCS_PATTERN);
1467 m_pBuffer = m_pCS->CreateBuf();
1468 }
1469 CPDF_DocPageData* pDocPageData = NULL;
1470 PatternValue* pvalue = (PatternValue*)m_pBuffer;
1471 if (pvalue->m_pPattern && pvalue->m_pPattern->m_pDocument) {
1472 pDocPageData = pvalue->m_pPattern->m_pDocument->GetPageData();
1473 if (pDocPageData) {
1474 pDocPageData->ReleasePattern(pvalue->m_pPattern->m_pPatternObj);
1475 }
1476 }
1477 pvalue->m_nComps = ncomps;
1478 pvalue->m_pPattern = pPattern;
1479 if (ncomps) {
1480 FXSYS_memcpy(pvalue->m_Comps, comps, ncomps * sizeof(FX_FLOAT));
1481 }
1482 pvalue->m_pCountedPattern = NULL;
1483 if (pPattern && pPattern->m_pDocument) {
1484 if (!pDocPageData) {
1485 pDocPageData = pPattern->m_pDocument->GetPageData();
1486 }
1487 pvalue->m_pCountedPattern =
1488 pDocPageData->FindPatternPtr(pPattern->m_pPatternObj);
1489 }
1490 }
1491 void CPDF_Color::Copy(const CPDF_Color* pSrc) {
1492 ReleaseBuffer();
1493 ReleaseColorSpace();
1494 m_pCS = pSrc->m_pCS;
1495 if (m_pCS && m_pCS->m_pDocument) {
1496 CPDF_Array* pArray = m_pCS->GetArray();
1497 if (pArray) {
1498 m_pCS = m_pCS->m_pDocument->GetPageData()->GetCopiedColorSpace(pArray);
1499 }
1500 }
1501 if (m_pCS == NULL) {
1502 return;
1503 }
1504 m_pBuffer = m_pCS->CreateBuf();
1505 FXSYS_memcpy(m_pBuffer, pSrc->m_pBuffer, m_pCS->GetBufSize());
1506 if (m_pCS->GetFamily() == PDFCS_PATTERN) {
1360 PatternValue* pvalue = (PatternValue*)m_pBuffer; 1507 PatternValue* pvalue = (PatternValue*)m_pBuffer;
1361 if (pvalue->m_pPattern && pvalue->m_pPattern->m_pDocument) { 1508 if (pvalue->m_pPattern && pvalue->m_pPattern->m_pDocument) {
1362 pDocPageData = pvalue->m_pPattern->m_pDocument->GetPageData(); 1509 pvalue->m_pPattern =
1363 if (pDocPageData) { 1510 pvalue->m_pPattern->m_pDocument->GetPageData()->GetPattern(
1364 pDocPageData->ReleasePattern(pvalue->m_pPattern->m_pPatternObj); 1511 pvalue->m_pPattern->m_pPatternObj, FALSE,
1365 } 1512 &pvalue->m_pPattern->m_ParentMatrix);
1366 } 1513 }
1367 pvalue->m_nComps = ncomps; 1514 }
1368 pvalue->m_pPattern = pPattern; 1515 }
1369 if (ncomps) { 1516 FX_BOOL CPDF_Color::GetRGB(int& R, int& G, int& B) const {
1370 FXSYS_memcpy(pvalue->m_Comps, comps, ncomps * sizeof(FX_FLOAT)); 1517 if (m_pCS == NULL || m_pBuffer == NULL) {
1371 } 1518 return FALSE;
1372 pvalue->m_pCountedPattern = NULL; 1519 }
1373 if (pPattern && pPattern->m_pDocument) 1520 FX_FLOAT r = 0.0f, g = 0.0f, b = 0.0f;
1374 { 1521 if (!m_pCS->GetRGB(m_pBuffer, r, g, b)) {
1375 if (!pDocPageData) { 1522 return FALSE;
1376 pDocPageData = pPattern->m_pDocument->GetPageData(); 1523 }
1377 } 1524 R = (int32_t)(r * 255 + 0.5f);
1378 pvalue->m_pCountedPattern = pDocPageData->FindPatternPtr(pPattern->m_pPa tternObj); 1525 G = (int32_t)(g * 255 + 0.5f);
1379 } 1526 B = (int32_t)(b * 255 + 0.5f);
1380 } 1527 return TRUE;
1381 void CPDF_Color::Copy(const CPDF_Color* pSrc) 1528 }
1382 { 1529 CPDF_Pattern* CPDF_Color::GetPattern() const {
1383 ReleaseBuffer(); 1530 if (m_pBuffer == NULL || m_pCS->GetFamily() != PDFCS_PATTERN) {
1384 ReleaseColorSpace(); 1531 return NULL;
1385 m_pCS = pSrc->m_pCS; 1532 }
1386 if (m_pCS && m_pCS->m_pDocument) { 1533 PatternValue* pvalue = (PatternValue*)m_pBuffer;
1387 CPDF_Array* pArray = m_pCS->GetArray(); 1534 return pvalue->m_pPattern;
1388 if (pArray) { 1535 }
1389 m_pCS = m_pCS->m_pDocument->GetPageData()->GetCopiedColorSpace(pArra y); 1536 CPDF_ColorSpace* CPDF_Color::GetPatternCS() const {
1390 } 1537 if (m_pBuffer == NULL || m_pCS->GetFamily() != PDFCS_PATTERN) {
1391 } 1538 return NULL;
1392 if (m_pCS == NULL) { 1539 }
1393 return; 1540 return m_pCS->GetBaseCS();
1394 } 1541 }
1395 m_pBuffer = m_pCS->CreateBuf(); 1542 FX_FLOAT* CPDF_Color::GetPatternColor() const {
1396 FXSYS_memcpy(m_pBuffer, pSrc->m_pBuffer, m_pCS->GetBufSize()); 1543 if (m_pBuffer == NULL || m_pCS->GetFamily() != PDFCS_PATTERN) {
1397 if (m_pCS->GetFamily() == PDFCS_PATTERN) { 1544 return NULL;
1398 PatternValue* pvalue = (PatternValue*)m_pBuffer; 1545 }
1399 if (pvalue->m_pPattern && pvalue->m_pPattern->m_pDocument) { 1546 PatternValue* pvalue = (PatternValue*)m_pBuffer;
1400 pvalue->m_pPattern = pvalue->m_pPattern->m_pDocument->GetPageData()- >GetPattern(pvalue->m_pPattern->m_pPatternObj, FALSE, &pvalue->m_pPattern->m_Par entMatrix); 1547 return pvalue->m_nComps ? pvalue->m_Comps : NULL;
1401 } 1548 }
1402 } 1549 FX_BOOL CPDF_Color::IsEqual(const CPDF_Color& other) const {
1403 } 1550 if (m_pCS != other.m_pCS || m_pCS == NULL) {
1404 FX_BOOL CPDF_Color::GetRGB(int& R, int& G, int& B) const 1551 return FALSE;
1405 { 1552 }
1406 if (m_pCS == NULL || m_pBuffer == NULL) { 1553 return FXSYS_memcmp(m_pBuffer, other.m_pBuffer, m_pCS->GetBufSize()) == 0;
1407 return FALSE; 1554 }
1408 }
1409 FX_FLOAT r=0.0f, g=0.0f, b=0.0f;
1410 if (!m_pCS->GetRGB(m_pBuffer, r, g, b)) {
1411 return FALSE;
1412 }
1413 R = (int32_t)(r * 255 + 0.5f);
1414 G = (int32_t)(g * 255 + 0.5f);
1415 B = (int32_t)(b * 255 + 0.5f);
1416 return TRUE;
1417 }
1418 CPDF_Pattern* CPDF_Color::GetPattern() const
1419 {
1420 if (m_pBuffer == NULL || m_pCS->GetFamily() != PDFCS_PATTERN) {
1421 return NULL;
1422 }
1423 PatternValue* pvalue = (PatternValue*)m_pBuffer;
1424 return pvalue->m_pPattern;
1425 }
1426 CPDF_ColorSpace* CPDF_Color::GetPatternCS() const
1427 {
1428 if (m_pBuffer == NULL || m_pCS->GetFamily() != PDFCS_PATTERN) {
1429 return NULL;
1430 }
1431 return m_pCS->GetBaseCS();
1432 }
1433 FX_FLOAT* CPDF_Color::GetPatternColor() const
1434 {
1435 if (m_pBuffer == NULL || m_pCS->GetFamily() != PDFCS_PATTERN) {
1436 return NULL;
1437 }
1438 PatternValue* pvalue = (PatternValue*)m_pBuffer;
1439 return pvalue->m_nComps ? pvalue->m_Comps : NULL;
1440 }
1441 FX_BOOL CPDF_Color::IsEqual(const CPDF_Color& other) const
1442 {
1443 if (m_pCS != other.m_pCS || m_pCS == NULL) {
1444 return FALSE;
1445 }
1446 return FXSYS_memcmp(m_pBuffer, other.m_pBuffer, m_pCS->GetBufSize()) == 0;
1447 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698