OLD | NEW |
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 } | |
OLD | NEW |