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

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

Issue 1265503005: clang-format all pdfium code. (Closed) Base URL: https://pdfium.googlesource.com/pdfium.git@master
Patch Set: Created 5 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2014 PDFium Authors. All rights reserved. 1 // Copyright 2014 PDFium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6 6
7 #include <limits.h> 7 #include <limits.h>
8 8
9 #include "../../../include/fpdfapi/fpdf_module.h" 9 #include "../../../include/fpdfapi/fpdf_module.h"
10 #include "../../../include/fpdfapi/fpdf_page.h" 10 #include "../../../include/fpdfapi/fpdf_page.h"
11 #include "../../../include/fxcrt/fx_safe_types.h" 11 #include "../../../include/fxcrt/fx_safe_types.h"
12 #include "../../../third_party/base/numerics/safe_conversions_impl.h" 12 #include "../../../third_party/base/numerics/safe_conversions_impl.h"
13 #include "pageint.h" 13 #include "pageint.h"
14 14
15 class CPDF_PSEngine; 15 class CPDF_PSEngine;
16 typedef enum {PSOP_ADD, PSOP_SUB, PSOP_MUL, PSOP_DIV, PSOP_IDIV, PSOP_MOD, 16 typedef enum {
17 PSOP_NEG, PSOP_ABS, PSOP_CEILING, PSOP_FLOOR, PSOP_ROUND, PSOP_TRU NCATE, 17 PSOP_ADD,
18 PSOP_SQRT, PSOP_SIN, PSOP_COS, PSOP_ATAN, PSOP_EXP, PSOP_LN, PSOP_ LOG, 18 PSOP_SUB,
19 PSOP_CVI, PSOP_CVR, PSOP_EQ, PSOP_NE, PSOP_GT, PSOP_GE, PSOP_LT, P SOP_LE, 19 PSOP_MUL,
20 PSOP_AND, PSOP_OR, PSOP_XOR, PSOP_NOT, PSOP_BITSHIFT, PSOP_TRUE, P SOP_FALSE, 20 PSOP_DIV,
21 PSOP_IF, PSOP_IFELSE, PSOP_POP, PSOP_EXCH, PSOP_DUP, PSOP_COPY, 21 PSOP_IDIV,
22 PSOP_INDEX, PSOP_ROLL, PSOP_PROC, PSOP_CONST 22 PSOP_MOD,
23 } PDF_PSOP; 23 PSOP_NEG,
24 class CPDF_PSProc 24 PSOP_ABS,
25 { 25 PSOP_CEILING,
26 public: 26 PSOP_FLOOR,
27 ~CPDF_PSProc(); 27 PSOP_ROUND,
28 FX_BOOL» Parse(CPDF_SimpleParser& parser); 28 PSOP_TRUNCATE,
29 FX_BOOL» Execute(CPDF_PSEngine* pEngine); 29 PSOP_SQRT,
30 CFX_PtrArray» » m_Operators; 30 PSOP_SIN,
31 PSOP_COS,
32 PSOP_ATAN,
33 PSOP_EXP,
34 PSOP_LN,
35 PSOP_LOG,
36 PSOP_CVI,
37 PSOP_CVR,
38 PSOP_EQ,
39 PSOP_NE,
40 PSOP_GT,
41 PSOP_GE,
42 PSOP_LT,
43 PSOP_LE,
44 PSOP_AND,
45 PSOP_OR,
46 PSOP_XOR,
47 PSOP_NOT,
48 PSOP_BITSHIFT,
49 PSOP_TRUE,
50 PSOP_FALSE,
51 PSOP_IF,
52 PSOP_IFELSE,
53 PSOP_POP,
54 PSOP_EXCH,
55 PSOP_DUP,
56 PSOP_COPY,
57 PSOP_INDEX,
58 PSOP_ROLL,
59 PSOP_PROC,
60 PSOP_CONST
61 } PDF_PSOP;
62 class CPDF_PSProc {
63 public:
64 ~CPDF_PSProc();
65 FX_BOOL Parse(CPDF_SimpleParser& parser);
66 FX_BOOL Execute(CPDF_PSEngine* pEngine);
67 CFX_PtrArray m_Operators;
31 }; 68 };
32 #define PSENGINE_STACKSIZE 100 69 #define PSENGINE_STACKSIZE 100
33 class CPDF_PSEngine 70 class CPDF_PSEngine {
34 { 71 public:
35 public: 72 CPDF_PSEngine();
36 CPDF_PSEngine(); 73 ~CPDF_PSEngine();
37 ~CPDF_PSEngine(); 74 FX_BOOL Parse(const FX_CHAR* string, int size);
38 FX_BOOL» Parse(const FX_CHAR* string, int size); 75 FX_BOOL Execute() { return m_MainProc.Execute(this); }
39 FX_BOOL» Execute() 76 FX_BOOL DoOperator(PDF_PSOP op);
40 { 77 void Reset() { m_StackCount = 0; }
41 return m_MainProc.Execute(this); 78 void Push(FX_FLOAT value);
42 } 79 void Push(int value) { Push((FX_FLOAT)value); }
43 FX_BOOL» DoOperator(PDF_PSOP op); 80 FX_FLOAT Pop();
44 void» Reset() 81 int GetStackSize() { return m_StackCount; }
45 { 82
46 m_StackCount = 0; 83 private:
47 } 84 FX_FLOAT m_Stack[PSENGINE_STACKSIZE];
48 void» Push(FX_FLOAT value); 85 int m_StackCount;
49 void» Push(int value) 86 CPDF_PSProc m_MainProc;
50 {
51 Push((FX_FLOAT)value);
52 }
53 FX_FLOAT» Pop();
54 int»» GetStackSize()
55 {
56 return m_StackCount;
57 }
58 private:
59 FX_FLOAT» m_Stack[PSENGINE_STACKSIZE];
60 int»» m_StackCount;
61 CPDF_PSProc»m_MainProc;
62 }; 87 };
63 CPDF_PSProc::~CPDF_PSProc() 88 CPDF_PSProc::~CPDF_PSProc() {
64 { 89 int size = m_Operators.GetSize();
65 int size = m_Operators.GetSize(); 90 for (int i = 0; i < size; i++) {
66 for (int i = 0; i < size; i ++) { 91 if (m_Operators[i] == (void*)PSOP_PROC) {
67 if (m_Operators[i] == (void*)PSOP_PROC) { 92 delete (CPDF_PSProc*)m_Operators[i + 1];
68 delete (CPDF_PSProc*)m_Operators[i + 1]; 93 i++;
69 i ++; 94 } else if (m_Operators[i] == (void*)PSOP_CONST) {
70 } else if (m_Operators[i] == (void*)PSOP_CONST) { 95 FX_Free((FX_FLOAT*)m_Operators[i + 1]);
71 FX_Free((FX_FLOAT*)m_Operators[i + 1]); 96 i++;
72 i ++; 97 }
98 }
99 }
100 FX_BOOL CPDF_PSProc::Execute(CPDF_PSEngine* pEngine) {
101 int size = m_Operators.GetSize();
102 for (int i = 0; i < size; i++) {
103 PDF_PSOP op = (PDF_PSOP)(uintptr_t)m_Operators[i];
104 if (op == PSOP_PROC) {
105 i++;
106 } else if (op == PSOP_CONST) {
107 pEngine->Push(*(FX_FLOAT*)m_Operators[i + 1]);
108 i++;
109 } else if (op == PSOP_IF) {
110 if (i < 2 || m_Operators[i - 2] != (void*)PSOP_PROC) {
111 return FALSE;
112 }
113 if ((int)pEngine->Pop()) {
114 ((CPDF_PSProc*)m_Operators[i - 1])->Execute(pEngine);
115 }
116 } else if (op == PSOP_IFELSE) {
117 if (i < 4 || m_Operators[i - 2] != (void*)PSOP_PROC ||
118 m_Operators[i - 4] != (void*)PSOP_PROC) {
119 return FALSE;
120 }
121 if ((int)pEngine->Pop()) {
122 ((CPDF_PSProc*)m_Operators[i - 3])->Execute(pEngine);
123 } else {
124 ((CPDF_PSProc*)m_Operators[i - 1])->Execute(pEngine);
125 }
126 } else {
127 pEngine->DoOperator(op);
128 }
129 }
130 return TRUE;
131 }
132 CPDF_PSEngine::CPDF_PSEngine() {
133 m_StackCount = 0;
134 }
135 CPDF_PSEngine::~CPDF_PSEngine() {}
136 void CPDF_PSEngine::Push(FX_FLOAT v) {
137 if (m_StackCount == 100) {
138 return;
139 }
140 m_Stack[m_StackCount++] = v;
141 }
142 FX_FLOAT CPDF_PSEngine::Pop() {
143 if (m_StackCount == 0) {
144 return 0;
145 }
146 return m_Stack[--m_StackCount];
147 }
148 const struct _PDF_PSOpName {
149 const FX_CHAR* name;
150 PDF_PSOP op;
151 } _PDF_PSOpNames[] = {{"add", PSOP_ADD}, {"sub", PSOP_SUB},
152 {"mul", PSOP_MUL}, {"div", PSOP_DIV},
153 {"idiv", PSOP_IDIV}, {"mod", PSOP_MOD},
154 {"neg", PSOP_NEG}, {"abs", PSOP_ABS},
155 {"ceiling", PSOP_CEILING}, {"floor", PSOP_FLOOR},
156 {"round", PSOP_ROUND}, {"truncate", PSOP_TRUNCATE},
157 {"sqrt", PSOP_SQRT}, {"sin", PSOP_SIN},
158 {"cos", PSOP_COS}, {"atan", PSOP_ATAN},
159 {"exp", PSOP_EXP}, {"ln", PSOP_LN},
160 {"log", PSOP_LOG}, {"cvi", PSOP_CVI},
161 {"cvr", PSOP_CVR}, {"eq", PSOP_EQ},
162 {"ne", PSOP_NE}, {"gt", PSOP_GT},
163 {"ge", PSOP_GE}, {"lt", PSOP_LT},
164 {"le", PSOP_LE}, {"and", PSOP_AND},
165 {"or", PSOP_OR}, {"xor", PSOP_XOR},
166 {"not", PSOP_NOT}, {"bitshift", PSOP_BITSHIFT},
167 {"true", PSOP_TRUE}, {"false", PSOP_FALSE},
168 {"if", PSOP_IF}, {"ifelse", PSOP_IFELSE},
169 {"pop", PSOP_POP}, {"exch", PSOP_EXCH},
170 {"dup", PSOP_DUP}, {"copy", PSOP_COPY},
171 {"index", PSOP_INDEX}, {"roll", PSOP_ROLL},
172 {NULL, PSOP_PROC}};
173 FX_BOOL CPDF_PSEngine::Parse(const FX_CHAR* string, int size) {
174 CPDF_SimpleParser parser((uint8_t*)string, size);
175 CFX_ByteStringC word = parser.GetWord();
176 if (word != FX_BSTRC("{")) {
177 return FALSE;
178 }
179 return m_MainProc.Parse(parser);
180 }
181 FX_BOOL CPDF_PSProc::Parse(CPDF_SimpleParser& parser) {
182 while (1) {
183 CFX_ByteStringC word = parser.GetWord();
184 if (word.IsEmpty()) {
185 return FALSE;
186 }
187 if (word == FX_BSTRC("}")) {
188 return TRUE;
189 }
190 if (word == FX_BSTRC("{")) {
191 CPDF_PSProc* pProc = new CPDF_PSProc;
192 m_Operators.Add((void*)PSOP_PROC);
193 m_Operators.Add(pProc);
194 if (!pProc->Parse(parser)) {
195 return FALSE;
196 }
197 } else {
198 int i = 0;
199 while (_PDF_PSOpNames[i].name) {
200 if (word == CFX_ByteStringC(_PDF_PSOpNames[i].name)) {
201 m_Operators.Add((void*)_PDF_PSOpNames[i].op);
202 break;
73 } 203 }
74 } 204 i++;
75 } 205 }
76 FX_BOOL CPDF_PSProc::Execute(CPDF_PSEngine* pEngine) 206 if (_PDF_PSOpNames[i].name == NULL) {
77 { 207 FX_FLOAT* pd = FX_Alloc(FX_FLOAT, 1);
78 int size = m_Operators.GetSize(); 208 *pd = FX_atof(word);
79 for (int i = 0; i < size; i ++) { 209 m_Operators.Add((void*)PSOP_CONST);
80 PDF_PSOP op = (PDF_PSOP)(uintptr_t)m_Operators[i]; 210 m_Operators.Add(pd);
81 if (op == PSOP_PROC) { 211 }
82 i ++; 212 }
83 } else if (op == PSOP_CONST) { 213 }
84 pEngine->Push(*(FX_FLOAT*)m_Operators[i + 1]); 214 }
85 i ++; 215 #define PI 3.1415926535897932384626433832795f
86 } else if (op == PSOP_IF) { 216 FX_BOOL CPDF_PSEngine::DoOperator(PDF_PSOP op) {
87 if (i < 2 || m_Operators[i - 2] != (void*)PSOP_PROC) { 217 int i1, i2;
88 return FALSE; 218 FX_FLOAT d1, d2;
89 } 219 switch (op) {
90 if ((int)pEngine->Pop()) { 220 case PSOP_ADD:
91 ((CPDF_PSProc*)m_Operators[i - 1])->Execute(pEngine); 221 d1 = Pop();
92 } 222 d2 = Pop();
93 } else if (op == PSOP_IFELSE) { 223 Push(d1 + d2);
94 if (i < 4 || m_Operators[i - 2] != (void*)PSOP_PROC || 224 break;
95 m_Operators[i - 4] != (void*)PSOP_PROC) { 225 case PSOP_SUB:
96 return FALSE; 226 d2 = Pop();
97 } 227 d1 = Pop();
98 if ((int)pEngine->Pop()) { 228 Push(d1 - d2);
99 ((CPDF_PSProc*)m_Operators[i - 3])->Execute(pEngine); 229 break;
100 } else { 230 case PSOP_MUL:
101 ((CPDF_PSProc*)m_Operators[i - 1])->Execute(pEngine); 231 d1 = Pop();
102 } 232 d2 = Pop();
103 } else { 233 Push(d1 * d2);
104 pEngine->DoOperator(op); 234 break;
235 case PSOP_DIV:
236 d2 = Pop();
237 d1 = Pop();
238 Push(d1 / d2);
239 break;
240 case PSOP_IDIV:
241 i2 = (int)Pop();
242 i1 = (int)Pop();
243 Push(i1 / i2);
244 break;
245 case PSOP_MOD:
246 i2 = (int)Pop();
247 i1 = (int)Pop();
248 Push(i1 % i2);
249 break;
250 case PSOP_NEG:
251 d1 = Pop();
252 Push(-d1);
253 break;
254 case PSOP_ABS:
255 d1 = Pop();
256 Push((FX_FLOAT)FXSYS_fabs(d1));
257 break;
258 case PSOP_CEILING:
259 d1 = Pop();
260 Push((FX_FLOAT)FXSYS_ceil(d1));
261 break;
262 case PSOP_FLOOR:
263 d1 = Pop();
264 Push((FX_FLOAT)FXSYS_floor(d1));
265 break;
266 case PSOP_ROUND:
267 d1 = Pop();
268 Push(FXSYS_round(d1));
269 break;
270 case PSOP_TRUNCATE:
271 i1 = (int)Pop();
272 Push(i1);
273 break;
274 case PSOP_SQRT:
275 d1 = Pop();
276 Push((FX_FLOAT)FXSYS_sqrt(d1));
277 break;
278 case PSOP_SIN:
279 d1 = Pop();
280 Push((FX_FLOAT)FXSYS_sin(d1 * PI / 180.0f));
281 break;
282 case PSOP_COS:
283 d1 = Pop();
284 Push((FX_FLOAT)FXSYS_cos(d1 * PI / 180.0f));
285 break;
286 case PSOP_ATAN:
287 d2 = Pop();
288 d1 = Pop();
289 d1 = (FX_FLOAT)(FXSYS_atan2(d1, d2) * 180.0 / PI);
290 if (d1 < 0) {
291 d1 += 360;
292 }
293 Push(d1);
294 break;
295 case PSOP_EXP:
296 d2 = Pop();
297 d1 = Pop();
298 Push((FX_FLOAT)FXSYS_pow(d1, d2));
299 break;
300 case PSOP_LN:
301 d1 = Pop();
302 Push((FX_FLOAT)FXSYS_log(d1));
303 break;
304 case PSOP_LOG:
305 d1 = Pop();
306 Push((FX_FLOAT)FXSYS_log10(d1));
307 break;
308 case PSOP_CVI:
309 i1 = (int)Pop();
310 Push(i1);
311 break;
312 case PSOP_CVR:
313 break;
314 case PSOP_EQ:
315 d2 = Pop();
316 d1 = Pop();
317 Push((int)(d1 == d2));
318 break;
319 case PSOP_NE:
320 d2 = Pop();
321 d1 = Pop();
322 Push((int)(d1 != d2));
323 break;
324 case PSOP_GT:
325 d2 = Pop();
326 d1 = Pop();
327 Push((int)(d1 > d2));
328 break;
329 case PSOP_GE:
330 d2 = Pop();
331 d1 = Pop();
332 Push((int)(d1 >= d2));
333 break;
334 case PSOP_LT:
335 d2 = Pop();
336 d1 = Pop();
337 Push((int)(d1 < d2));
338 break;
339 case PSOP_LE:
340 d2 = Pop();
341 d1 = Pop();
342 Push((int)(d1 <= d2));
343 break;
344 case PSOP_AND:
345 i1 = (int)Pop();
346 i2 = (int)Pop();
347 Push(i1 & i2);
348 break;
349 case PSOP_OR:
350 i1 = (int)Pop();
351 i2 = (int)Pop();
352 Push(i1 | i2);
353 break;
354 case PSOP_XOR:
355 i1 = (int)Pop();
356 i2 = (int)Pop();
357 Push(i1 ^ i2);
358 break;
359 case PSOP_NOT:
360 i1 = (int)Pop();
361 Push((int)!i1);
362 break;
363 case PSOP_BITSHIFT: {
364 int shift = (int)Pop();
365 int i = (int)Pop();
366 if (shift > 0) {
367 Push(i << shift);
368 } else {
369 Push(i >> -shift);
370 }
371 break;
372 }
373 case PSOP_TRUE:
374 Push(1);
375 break;
376 case PSOP_FALSE:
377 Push(0);
378 break;
379 case PSOP_POP:
380 Pop();
381 break;
382 case PSOP_EXCH:
383 d2 = Pop();
384 d1 = Pop();
385 Push(d2);
386 Push(d1);
387 break;
388 case PSOP_DUP:
389 d1 = Pop();
390 Push(d1);
391 Push(d1);
392 break;
393 case PSOP_COPY: {
394 int n = (int)Pop();
395 if (n < 0 || n > PSENGINE_STACKSIZE ||
396 m_StackCount + n > PSENGINE_STACKSIZE || n > m_StackCount) {
397 break;
398 }
399 for (int i = 0; i < n; i++) {
400 m_Stack[m_StackCount + i] = m_Stack[m_StackCount + i - n];
401 }
402 m_StackCount += n;
403 break;
404 }
405 case PSOP_INDEX: {
406 int n = (int)Pop();
407 if (n < 0 || n >= m_StackCount) {
408 break;
409 }
410 Push(m_Stack[m_StackCount - n - 1]);
411 break;
412 }
413 case PSOP_ROLL: {
414 int j = (int)Pop();
415 int n = (int)Pop();
416 if (m_StackCount == 0) {
417 break;
418 }
419 if (n < 0 || n > m_StackCount) {
420 break;
421 }
422 if (j < 0)
423 for (int i = 0; i < -j; i++) {
424 FX_FLOAT first = m_Stack[m_StackCount - n];
425 for (int ii = 0; ii < n - 1; ii++) {
426 m_Stack[m_StackCount - n + ii] = m_Stack[m_StackCount - n + ii + 1];
427 }
428 m_Stack[m_StackCount - 1] = first;
105 } 429 }
106 } 430 else
107 return TRUE; 431 for (int i = 0; i < j; i++) {
108 } 432 FX_FLOAT last = m_Stack[m_StackCount - 1];
109 CPDF_PSEngine::CPDF_PSEngine() 433 int ii;
110 { 434 for (ii = 0; ii < n - 1; ii++) {
111 m_StackCount = 0; 435 m_Stack[m_StackCount - ii - 1] = m_Stack[m_StackCount - ii - 2];
112 } 436 }
113 CPDF_PSEngine::~CPDF_PSEngine() 437 m_Stack[m_StackCount - ii - 1] = last;
114 { 438 }
115 } 439 break;
116 void CPDF_PSEngine::Push(FX_FLOAT v) 440 }
117 { 441 default:
118 if (m_StackCount == 100) { 442 break;
119 return; 443 }
120 } 444 return TRUE;
121 m_Stack[m_StackCount++] = v; 445 }
122 } 446 static FX_FLOAT PDF_Interpolate(FX_FLOAT x,
123 FX_FLOAT CPDF_PSEngine::Pop() 447 FX_FLOAT xmin,
124 { 448 FX_FLOAT xmax,
125 if (m_StackCount == 0) { 449 FX_FLOAT ymin,
126 return 0; 450 FX_FLOAT ymax) {
127 } 451 return ((x - xmin) * (ymax - ymin) / (xmax - xmin)) + ymin;
128 return m_Stack[--m_StackCount]; 452 }
129 } 453 static FX_DWORD _GetBits32(const uint8_t* pData, int bitpos, int nbits) {
130 const struct _PDF_PSOpName { 454 int result = 0;
131 const FX_CHAR* name; 455 for (int i = 0; i < nbits; i++)
132 PDF_PSOP op; 456 if (pData[(bitpos + i) / 8] & (1 << (7 - (bitpos + i) % 8))) {
133 } _PDF_PSOpNames[] = { 457 result |= 1 << (nbits - i - 1);
134 {"add", PSOP_ADD}, {"sub", PSOP_SUB}, {"mul", PSOP_MUL}, {"div", PSOP_DIV}, 458 }
135 {"idiv", PSOP_IDIV}, {"mod", PSOP_MOD}, {"neg", PSOP_NEG}, {"abs", PSOP_ABS} , 459 return result;
136 {"ceiling", PSOP_CEILING}, {"floor", PSOP_FLOOR}, {"round", PSOP_ROUND}, 460 }
137 {"truncate", PSOP_TRUNCATE}, {"sqrt", PSOP_SQRT}, {"sin", PSOP_SIN}, 461 typedef struct {
138 {"cos", PSOP_COS}, {"atan", PSOP_ATAN}, {"exp", PSOP_EXP}, {"ln", PSOP_LN}, 462 FX_FLOAT encode_max, encode_min;
139 {"log", PSOP_LOG}, {"cvi", PSOP_CVI}, {"cvr", PSOP_CVR}, {"eq", PSOP_EQ}, 463 int sizes;
140 {"ne", PSOP_NE}, {"gt", PSOP_GT}, {"ge", PSOP_GE}, {"lt", PSOP_LT}, 464 } SampleEncodeInfo;
141 {"le", PSOP_LE}, {"and", PSOP_AND}, {"or", PSOP_OR}, {"xor", PSOP_XOR}, 465 typedef struct { FX_FLOAT decode_max, decode_min; } SampleDecodeInfo;
142 {"not", PSOP_NOT}, {"bitshift", PSOP_BITSHIFT}, {"true", PSOP_TRUE}, 466 class CPDF_SampledFunc : public CPDF_Function {
143 {"false", PSOP_FALSE}, {"if", PSOP_IF}, {"ifelse", PSOP_IFELSE}, 467 public:
144 {"pop", PSOP_POP}, {"exch", PSOP_EXCH}, {"dup", PSOP_DUP}, 468 CPDF_SampledFunc();
145 {"copy", PSOP_COPY}, {"index", PSOP_INDEX}, {"roll", PSOP_ROLL}, 469 virtual ~CPDF_SampledFunc();
146 {NULL, PSOP_PROC} 470 virtual FX_BOOL v_Init(CPDF_Object* pObj);
471 virtual FX_BOOL v_Call(FX_FLOAT* inputs, FX_FLOAT* results) const;
472 SampleEncodeInfo* m_pEncodeInfo;
473 SampleDecodeInfo* m_pDecodeInfo;
474 FX_DWORD m_nBitsPerSample;
475 FX_DWORD m_SampleMax;
476 CPDF_StreamAcc* m_pSampleStream;
147 }; 477 };
148 FX_BOOL CPDF_PSEngine::Parse(const FX_CHAR* string, int size) 478 CPDF_SampledFunc::CPDF_SampledFunc() {
149 { 479 m_pSampleStream = NULL;
150 CPDF_SimpleParser parser((uint8_t*)string, size); 480 m_pEncodeInfo = NULL;
151 CFX_ByteStringC word = parser.GetWord(); 481 m_pDecodeInfo = NULL;
152 if (word != FX_BSTRC("{")) { 482 }
153 return FALSE; 483 CPDF_SampledFunc::~CPDF_SampledFunc() {
154 } 484 delete m_pSampleStream;
155 return m_MainProc.Parse(parser); 485 if (m_pEncodeInfo) {
156 } 486 FX_Free(m_pEncodeInfo);
157 FX_BOOL CPDF_PSProc::Parse(CPDF_SimpleParser& parser) 487 }
158 { 488 if (m_pDecodeInfo) {
159 while (1) { 489 FX_Free(m_pDecodeInfo);
160 CFX_ByteStringC word = parser.GetWord(); 490 }
161 if (word.IsEmpty()) { 491 }
162 return FALSE; 492 FX_BOOL CPDF_SampledFunc::v_Init(CPDF_Object* pObj) {
493 if (pObj->GetType() != PDFOBJ_STREAM) {
494 return FALSE;
495 }
496 CPDF_Stream* pStream = (CPDF_Stream*)pObj;
497 CPDF_Dictionary* pDict = pStream->GetDict();
498 CPDF_Array* pSize = pDict->GetArray(FX_BSTRC("Size"));
499 CPDF_Array* pEncode = pDict->GetArray(FX_BSTRC("Encode"));
500 CPDF_Array* pDecode = pDict->GetArray(FX_BSTRC("Decode"));
501 m_nBitsPerSample = pDict->GetInteger(FX_BSTRC("BitsPerSample"));
502 if (m_nBitsPerSample > 32) {
503 return FALSE;
504 }
505 m_SampleMax = 0xffffffff >> (32 - m_nBitsPerSample);
506 m_pSampleStream = new CPDF_StreamAcc;
507 m_pSampleStream->LoadAllData(pStream, FALSE);
508 m_pEncodeInfo = FX_Alloc(SampleEncodeInfo, m_nInputs);
509 FX_SAFE_DWORD nTotalSampleBits = 1;
510 for (int i = 0; i < m_nInputs; i++) {
511 m_pEncodeInfo[i].sizes = pSize ? pSize->GetInteger(i) : 0;
512 if (!pSize && i == 0) {
513 m_pEncodeInfo[i].sizes = pDict->GetInteger(FX_BSTRC("Size"));
514 }
515 nTotalSampleBits *= m_pEncodeInfo[i].sizes;
516 if (pEncode) {
517 m_pEncodeInfo[i].encode_min = pEncode->GetFloat(i * 2);
518 m_pEncodeInfo[i].encode_max = pEncode->GetFloat(i * 2 + 1);
519 } else {
520 m_pEncodeInfo[i].encode_min = 0;
521 if (m_pEncodeInfo[i].sizes == 1) {
522 m_pEncodeInfo[i].encode_max = 1;
523 } else {
524 m_pEncodeInfo[i].encode_max = (FX_FLOAT)m_pEncodeInfo[i].sizes - 1;
525 }
526 }
527 }
528 nTotalSampleBits *= m_nBitsPerSample;
529 nTotalSampleBits *= m_nOutputs;
530 FX_SAFE_DWORD nTotalSampleBytes = nTotalSampleBits;
531 nTotalSampleBytes += 7;
532 nTotalSampleBytes /= 8;
533 if (!nTotalSampleBytes.IsValid() || nTotalSampleBytes.ValueOrDie() == 0 ||
534 nTotalSampleBytes.ValueOrDie() > m_pSampleStream->GetSize()) {
535 return FALSE;
536 }
537 m_pDecodeInfo = FX_Alloc(SampleDecodeInfo, m_nOutputs);
538 for (int i = 0; i < m_nOutputs; i++) {
539 if (pDecode) {
540 m_pDecodeInfo[i].decode_min = pDecode->GetFloat(2 * i);
541 m_pDecodeInfo[i].decode_max = pDecode->GetFloat(2 * i + 1);
542 } else {
543 m_pDecodeInfo[i].decode_min = m_pRanges[i * 2];
544 m_pDecodeInfo[i].decode_max = m_pRanges[i * 2 + 1];
545 }
546 }
547 return TRUE;
548 }
549 FX_BOOL CPDF_SampledFunc::v_Call(FX_FLOAT* inputs, FX_FLOAT* results) const {
550 int pos = 0;
551 CFX_FixedBufGrow<FX_FLOAT, 16> encoded_input_buf(m_nInputs);
552 FX_FLOAT* encoded_input = encoded_input_buf;
553 CFX_FixedBufGrow<int, 32> int_buf(m_nInputs * 2);
554 int* index = int_buf;
555 int* blocksize = index + m_nInputs;
556 for (int i = 0; i < m_nInputs; i++) {
557 if (i == 0) {
558 blocksize[i] = 1;
559 } else {
560 blocksize[i] = blocksize[i - 1] * m_pEncodeInfo[i - 1].sizes;
561 }
562 encoded_input[i] = PDF_Interpolate(
563 inputs[i], m_pDomains[i * 2], m_pDomains[i * 2 + 1],
564 m_pEncodeInfo[i].encode_min, m_pEncodeInfo[i].encode_max);
565 index[i] = (int)encoded_input[i];
566 if (index[i] < 0) {
567 index[i] = 0;
568 } else if (index[i] > m_pEncodeInfo[i].sizes - 1) {
569 index[i] = m_pEncodeInfo[i].sizes - 1;
570 }
571 pos += index[i] * blocksize[i];
572 }
573 FX_SAFE_INT32 bits_to_output = m_nOutputs;
574 bits_to_output *= m_nBitsPerSample;
575 if (!bits_to_output.IsValid()) {
576 return FALSE;
577 }
578 FX_SAFE_INT32 bitpos = pos;
579 bitpos *= bits_to_output.ValueOrDie();
580 if (!bitpos.IsValid()) {
581 return FALSE;
582 }
583 FX_SAFE_INT32 range_check = bitpos;
584 range_check += bits_to_output.ValueOrDie();
585 if (!range_check.IsValid()) {
586 return FALSE;
587 }
588 const uint8_t* pSampleData = m_pSampleStream->GetData();
589 if (!pSampleData) {
590 return FALSE;
591 }
592 for (int j = 0; j < m_nOutputs; j++) {
593 FX_DWORD sample =
594 _GetBits32(pSampleData, bitpos.ValueOrDie() + j * m_nBitsPerSample,
595 m_nBitsPerSample);
596 FX_FLOAT encoded = (FX_FLOAT)sample;
597 for (int i = 0; i < m_nInputs; i++) {
598 if (index[i] == m_pEncodeInfo[i].sizes - 1) {
599 if (index[i] == 0) {
600 encoded = encoded_input[i] * (FX_FLOAT)sample;
163 } 601 }
164 if (word == FX_BSTRC("}")) { 602 } else {
165 return TRUE; 603 FX_SAFE_INT32 bitpos2 = blocksize[i];
604 bitpos2 += pos;
605 bitpos2 *= m_nOutputs;
606 bitpos2 += j;
607 bitpos2 *= m_nBitsPerSample;
608 if (!bitpos2.IsValid()) {
609 return FALSE;
166 } 610 }
167 if (word == FX_BSTRC("{")) { 611 FX_DWORD sample1 =
168 CPDF_PSProc* pProc = new CPDF_PSProc; 612 _GetBits32(pSampleData, bitpos2.ValueOrDie(), m_nBitsPerSample);
169 m_Operators.Add((void*)PSOP_PROC); 613 encoded += (encoded_input[i] - index[i]) *
170 m_Operators.Add(pProc); 614 ((FX_FLOAT)sample1 - (FX_FLOAT)sample);
171 if (!pProc->Parse(parser)) { 615 }
172 return FALSE; 616 }
173 } 617 results[j] = PDF_Interpolate(encoded, 0, (FX_FLOAT)m_SampleMax,
174 } else { 618 m_pDecodeInfo[j].decode_min,
175 int i = 0; 619 m_pDecodeInfo[j].decode_max);
176 while (_PDF_PSOpNames[i].name) { 620 }
177 if (word == CFX_ByteStringC(_PDF_PSOpNames[i].name)) { 621 return TRUE;
178 m_Operators.Add((void*)_PDF_PSOpNames[i].op); 622 }
179 break; 623 class CPDF_PSFunc : public CPDF_Function {
180 } 624 public:
181 i ++; 625 virtual FX_BOOL v_Init(CPDF_Object* pObj);
182 } 626 virtual FX_BOOL v_Call(FX_FLOAT* inputs, FX_FLOAT* results) const;
183 if (_PDF_PSOpNames[i].name == NULL) { 627 CPDF_PSEngine m_PS;
184 FX_FLOAT* pd = FX_Alloc(FX_FLOAT, 1);
185 *pd = FX_atof(word);
186 m_Operators.Add((void*)PSOP_CONST);
187 m_Operators.Add(pd);
188 }
189 }
190 }
191 }
192 #define PI 3.1415926535897932384626433832795f
193 FX_BOOL CPDF_PSEngine::DoOperator(PDF_PSOP op)
194 {
195 int i1, i2;
196 FX_FLOAT d1, d2;
197 switch (op) {
198 case PSOP_ADD:
199 d1 = Pop();
200 d2 = Pop();
201 Push(d1 + d2);
202 break;
203 case PSOP_SUB:
204 d2 = Pop();
205 d1 = Pop();
206 Push(d1 - d2);
207 break;
208 case PSOP_MUL:
209 d1 = Pop();
210 d2 = Pop();
211 Push(d1 * d2);
212 break;
213 case PSOP_DIV:
214 d2 = Pop();
215 d1 = Pop();
216 Push(d1 / d2);
217 break;
218 case PSOP_IDIV:
219 i2 = (int)Pop();
220 i1 = (int)Pop();
221 Push(i1 / i2);
222 break;
223 case PSOP_MOD:
224 i2 = (int)Pop();
225 i1 = (int)Pop();
226 Push(i1 % i2);
227 break;
228 case PSOP_NEG:
229 d1 = Pop();
230 Push(-d1);
231 break;
232 case PSOP_ABS:
233 d1 = Pop();
234 Push((FX_FLOAT)FXSYS_fabs(d1));
235 break;
236 case PSOP_CEILING:
237 d1 = Pop();
238 Push((FX_FLOAT)FXSYS_ceil(d1));
239 break;
240 case PSOP_FLOOR:
241 d1 = Pop();
242 Push((FX_FLOAT)FXSYS_floor(d1));
243 break;
244 case PSOP_ROUND:
245 d1 = Pop();
246 Push(FXSYS_round(d1));
247 break;
248 case PSOP_TRUNCATE:
249 i1 = (int)Pop();
250 Push(i1);
251 break;
252 case PSOP_SQRT:
253 d1 = Pop();
254 Push((FX_FLOAT)FXSYS_sqrt(d1));
255 break;
256 case PSOP_SIN:
257 d1 = Pop();
258 Push((FX_FLOAT)FXSYS_sin(d1 * PI / 180.0f));
259 break;
260 case PSOP_COS:
261 d1 = Pop();
262 Push((FX_FLOAT)FXSYS_cos(d1 * PI / 180.0f));
263 break;
264 case PSOP_ATAN:
265 d2 = Pop();
266 d1 = Pop();
267 d1 = (FX_FLOAT)(FXSYS_atan2(d1, d2) * 180.0 / PI);
268 if (d1 < 0) {
269 d1 += 360;
270 }
271 Push(d1);
272 break;
273 case PSOP_EXP:
274 d2 = Pop();
275 d1 = Pop();
276 Push((FX_FLOAT)FXSYS_pow(d1, d2));
277 break;
278 case PSOP_LN:
279 d1 = Pop();
280 Push((FX_FLOAT)FXSYS_log(d1));
281 break;
282 case PSOP_LOG:
283 d1 = Pop();
284 Push((FX_FLOAT)FXSYS_log10(d1));
285 break;
286 case PSOP_CVI:
287 i1 = (int)Pop();
288 Push(i1);
289 break;
290 case PSOP_CVR:
291 break;
292 case PSOP_EQ:
293 d2 = Pop();
294 d1 = Pop();
295 Push((int)(d1 == d2));
296 break;
297 case PSOP_NE:
298 d2 = Pop();
299 d1 = Pop();
300 Push((int)(d1 != d2));
301 break;
302 case PSOP_GT:
303 d2 = Pop();
304 d1 = Pop();
305 Push((int)(d1 > d2));
306 break;
307 case PSOP_GE:
308 d2 = Pop();
309 d1 = Pop();
310 Push((int)(d1 >= d2));
311 break;
312 case PSOP_LT:
313 d2 = Pop();
314 d1 = Pop();
315 Push((int)(d1 < d2));
316 break;
317 case PSOP_LE:
318 d2 = Pop();
319 d1 = Pop();
320 Push((int)(d1 <= d2));
321 break;
322 case PSOP_AND:
323 i1 = (int)Pop();
324 i2 = (int)Pop();
325 Push(i1 & i2);
326 break;
327 case PSOP_OR:
328 i1 = (int)Pop();
329 i2 = (int)Pop();
330 Push(i1 | i2);
331 break;
332 case PSOP_XOR:
333 i1 = (int)Pop();
334 i2 = (int)Pop();
335 Push(i1 ^ i2);
336 break;
337 case PSOP_NOT:
338 i1 = (int)Pop();
339 Push((int)!i1);
340 break;
341 case PSOP_BITSHIFT: {
342 int shift = (int)Pop();
343 int i = (int)Pop();
344 if (shift > 0) {
345 Push(i << shift);
346 } else {
347 Push(i >> -shift);
348 }
349 break;
350 }
351 case PSOP_TRUE:
352 Push(1);
353 break;
354 case PSOP_FALSE:
355 Push(0);
356 break;
357 case PSOP_POP:
358 Pop();
359 break;
360 case PSOP_EXCH:
361 d2 = Pop();
362 d1 = Pop();
363 Push(d2);
364 Push(d1);
365 break;
366 case PSOP_DUP:
367 d1 = Pop();
368 Push(d1);
369 Push(d1);
370 break;
371 case PSOP_COPY: {
372 int n = (int)Pop();
373 if (n < 0 || n > PSENGINE_STACKSIZE || m_StackCount + n > PSENGI NE_STACKSIZE || n > m_StackCount) {
374 break;
375 }
376 for (int i = 0; i < n; i ++) {
377 m_Stack[m_StackCount + i] = m_Stack[m_StackCount + i - n];
378 }
379 m_StackCount += n;
380 break;
381 }
382 case PSOP_INDEX: {
383 int n = (int)Pop();
384 if (n < 0 || n >= m_StackCount) {
385 break;
386 }
387 Push(m_Stack[m_StackCount - n - 1]);
388 break;
389 }
390 case PSOP_ROLL: {
391 int j = (int)Pop();
392 int n = (int)Pop();
393 if (m_StackCount == 0) {
394 break;
395 }
396 if (n < 0 || n > m_StackCount) {
397 break;
398 }
399 if (j < 0)
400 for (int i = 0; i < -j; i ++) {
401 FX_FLOAT first = m_Stack[m_StackCount - n];
402 for (int ii = 0; ii < n - 1; ii ++) {
403 m_Stack[m_StackCount - n + ii] = m_Stack[m_StackCoun t - n + ii + 1];
404 }
405 m_Stack[m_StackCount - 1] = first;
406 }
407 else
408 for (int i = 0; i < j; i ++) {
409 FX_FLOAT last = m_Stack[m_StackCount - 1];
410 int ii;
411 for (ii = 0; ii < n - 1; ii ++) {
412 m_Stack[m_StackCount - ii - 1] = m_Stack[m_StackCoun t - ii - 2];
413 }
414 m_Stack[m_StackCount - ii - 1] = last;
415 }
416 break;
417 }
418 default:
419 break;
420 }
421 return TRUE;
422 }
423 static FX_FLOAT PDF_Interpolate(FX_FLOAT x, FX_FLOAT xmin, FX_FLOAT xmax, FX_FLO AT ymin, FX_FLOAT ymax)
424 {
425 return ((x - xmin) * (ymax - ymin) / (xmax - xmin)) + ymin;
426 }
427 static FX_DWORD _GetBits32(const uint8_t* pData, int bitpos, int nbits)
428 {
429 int result = 0;
430 for (int i = 0; i < nbits; i ++)
431 if (pData[(bitpos + i) / 8] & (1 << (7 - (bitpos + i) % 8))) {
432 result |= 1 << (nbits - i - 1);
433 }
434 return result;
435 }
436 typedef struct {
437 FX_FLOAT» encode_max, encode_min;
438 int»» » sizes;
439 } SampleEncodeInfo;
440 typedef struct {
441 FX_FLOAT» decode_max, decode_min;
442 } SampleDecodeInfo;
443 class CPDF_SampledFunc : public CPDF_Function
444 {
445 public:
446 CPDF_SampledFunc();
447 virtual ~CPDF_SampledFunc();
448 virtual FX_BOOL» » v_Init(CPDF_Object* pObj);
449 virtual FX_BOOL» » v_Call(FX_FLOAT* inputs, FX_FLOAT* results) cons t;
450 SampleEncodeInfo*» m_pEncodeInfo;
451 SampleDecodeInfo*» m_pDecodeInfo;
452 FX_DWORD» m_nBitsPerSample;
453 FX_DWORD» m_SampleMax;
454 CPDF_StreamAcc*» m_pSampleStream;
455 }; 628 };
456 CPDF_SampledFunc::CPDF_SampledFunc() 629 FX_BOOL CPDF_PSFunc::v_Init(CPDF_Object* pObj) {
457 { 630 CPDF_Stream* pStream = (CPDF_Stream*)pObj;
458 m_pSampleStream = NULL; 631 CPDF_StreamAcc acc;
459 m_pEncodeInfo = NULL; 632 acc.LoadAllData(pStream, FALSE);
460 m_pDecodeInfo = NULL; 633 return m_PS.Parse((const FX_CHAR*)acc.GetData(), acc.GetSize());
461 } 634 }
462 CPDF_SampledFunc::~CPDF_SampledFunc() 635 FX_BOOL CPDF_PSFunc::v_Call(FX_FLOAT* inputs, FX_FLOAT* results) const {
463 { 636 CPDF_PSEngine& PS = (CPDF_PSEngine&)m_PS;
464 delete m_pSampleStream; 637 PS.Reset();
465 if (m_pEncodeInfo) { 638 int i;
466 FX_Free(m_pEncodeInfo); 639 for (i = 0; i < m_nInputs; i++) {
467 } 640 PS.Push(inputs[i]);
468 if (m_pDecodeInfo) { 641 }
469 FX_Free(m_pDecodeInfo); 642 PS.Execute();
470 } 643 if (PS.GetStackSize() < m_nOutputs) {
471 } 644 return FALSE;
472 FX_BOOL CPDF_SampledFunc::v_Init(CPDF_Object* pObj) 645 }
473 { 646 for (i = 0; i < m_nOutputs; i++) {
474 if (pObj->GetType() != PDFOBJ_STREAM) { 647 results[m_nOutputs - i - 1] = PS.Pop();
475 return FALSE; 648 }
476 } 649 return TRUE;
477 CPDF_Stream* pStream = (CPDF_Stream*)pObj; 650 }
478 CPDF_Dictionary* pDict = pStream->GetDict(); 651 class CPDF_ExpIntFunc : public CPDF_Function {
479 CPDF_Array* pSize = pDict->GetArray(FX_BSTRC("Size")); 652 public:
480 CPDF_Array* pEncode = pDict->GetArray(FX_BSTRC("Encode")); 653 CPDF_ExpIntFunc();
481 CPDF_Array* pDecode = pDict->GetArray(FX_BSTRC("Decode")); 654 virtual ~CPDF_ExpIntFunc();
482 m_nBitsPerSample = pDict->GetInteger(FX_BSTRC("BitsPerSample")); 655 virtual FX_BOOL v_Init(CPDF_Object* pObj);
483 if (m_nBitsPerSample > 32) { 656 virtual FX_BOOL v_Call(FX_FLOAT* inputs, FX_FLOAT* results) const;
484 return FALSE; 657 FX_FLOAT m_Exponent;
485 } 658 FX_FLOAT* m_pBeginValues;
486 m_SampleMax = 0xffffffff >> (32 - m_nBitsPerSample); 659 FX_FLOAT* m_pEndValues;
487 m_pSampleStream = new CPDF_StreamAcc; 660 int m_nOrigOutputs;
488 m_pSampleStream->LoadAllData(pStream, FALSE);
489 m_pEncodeInfo = FX_Alloc(SampleEncodeInfo, m_nInputs);
490 FX_SAFE_DWORD nTotalSampleBits = 1;
491 for (int i = 0; i < m_nInputs; i ++) {
492 m_pEncodeInfo[i].sizes = pSize ? pSize->GetInteger(i) : 0;
493 if (!pSize && i == 0) {
494 m_pEncodeInfo[i].sizes = pDict->GetInteger(FX_BSTRC("Size"));
495 }
496 nTotalSampleBits *= m_pEncodeInfo[i].sizes;
497 if (pEncode) {
498 m_pEncodeInfo[i].encode_min = pEncode->GetFloat(i * 2);
499 m_pEncodeInfo[i].encode_max = pEncode->GetFloat(i * 2 + 1);
500 } else {
501 m_pEncodeInfo[i].encode_min = 0;
502 if (m_pEncodeInfo[i].sizes == 1) {
503 m_pEncodeInfo[i].encode_max = 1;
504 } else {
505 m_pEncodeInfo[i].encode_max = (FX_FLOAT)m_pEncodeInfo[i].sizes - 1;
506 }
507 }
508 }
509 nTotalSampleBits *= m_nBitsPerSample;
510 nTotalSampleBits *= m_nOutputs;
511 FX_SAFE_DWORD nTotalSampleBytes = nTotalSampleBits;
512 nTotalSampleBytes += 7;
513 nTotalSampleBytes /= 8;
514 if (!nTotalSampleBytes.IsValid() ||
515 nTotalSampleBytes.ValueOrDie() == 0 ||
516 nTotalSampleBytes.ValueOrDie() > m_pSampleStream->GetSize()) {
517 return FALSE;
518 }
519 m_pDecodeInfo = FX_Alloc(SampleDecodeInfo, m_nOutputs);
520 for (int i = 0; i < m_nOutputs; i ++) {
521 if (pDecode) {
522 m_pDecodeInfo[i].decode_min = pDecode->GetFloat(2 * i);
523 m_pDecodeInfo[i].decode_max = pDecode->GetFloat(2 * i + 1);
524 } else {
525 m_pDecodeInfo[i].decode_min = m_pRanges[i * 2];
526 m_pDecodeInfo[i].decode_max = m_pRanges[i * 2 + 1];
527 }
528 }
529 return TRUE;
530 }
531 FX_BOOL CPDF_SampledFunc::v_Call(FX_FLOAT* inputs, FX_FLOAT* results) const
532 {
533 int pos = 0;
534 CFX_FixedBufGrow<FX_FLOAT, 16> encoded_input_buf(m_nInputs);
535 FX_FLOAT* encoded_input = encoded_input_buf;
536 CFX_FixedBufGrow<int, 32> int_buf(m_nInputs * 2);
537 int* index = int_buf;
538 int* blocksize = index + m_nInputs;
539 for (int i = 0; i < m_nInputs; i ++) {
540 if (i == 0) {
541 blocksize[i] = 1;
542 } else {
543 blocksize[i] = blocksize[i - 1] * m_pEncodeInfo[i - 1].sizes;
544 }
545 encoded_input[i] = PDF_Interpolate(inputs[i], m_pDomains[i * 2], m_pDoma ins[i * 2 + 1],
546 m_pEncodeInfo[i].encode_min, m_pEncod eInfo[i].encode_max);
547 index[i] = (int)encoded_input[i];
548 if (index[i] < 0) {
549 index[i] = 0;
550 } else if (index[i] > m_pEncodeInfo[i].sizes - 1) {
551 index[i] = m_pEncodeInfo[i].sizes - 1;
552 }
553 pos += index[i] * blocksize[i];
554 }
555 FX_SAFE_INT32 bits_to_output = m_nOutputs;
556 bits_to_output *= m_nBitsPerSample;
557 if (!bits_to_output.IsValid()) {
558 return FALSE;
559 }
560 FX_SAFE_INT32 bitpos = pos;
561 bitpos *= bits_to_output.ValueOrDie();
562 if (!bitpos.IsValid()) {
563 return FALSE;
564 }
565 FX_SAFE_INT32 range_check = bitpos;
566 range_check += bits_to_output.ValueOrDie();
567 if (!range_check.IsValid()) {
568 return FALSE;
569 }
570 const uint8_t* pSampleData = m_pSampleStream->GetData();
571 if (!pSampleData) {
572 return FALSE;
573 }
574 for (int j = 0; j < m_nOutputs; j ++) {
575 FX_DWORD sample = _GetBits32(pSampleData, bitpos.ValueOrDie() + j * m_nB itsPerSample, m_nBitsPerSample);
576 FX_FLOAT encoded = (FX_FLOAT)sample;
577 for (int i = 0; i < m_nInputs; i ++) {
578 if (index[i] == m_pEncodeInfo[i].sizes - 1) {
579 if (index[i] == 0) {
580 encoded = encoded_input[i] * (FX_FLOAT)sample;
581 }
582 } else {
583 FX_SAFE_INT32 bitpos2 = blocksize[i];
584 bitpos2 += pos;
585 bitpos2 *= m_nOutputs;
586 bitpos2 += j;
587 bitpos2 *= m_nBitsPerSample;
588 if (!bitpos2.IsValid()) {
589 return FALSE;
590 }
591 FX_DWORD sample1 = _GetBits32(pSampleData, bitpos2.ValueOrDie(), m_nBitsPerSample);
592 encoded += (encoded_input[i] - index[i]) * ((FX_FLOAT)sample1 - (FX_FLOAT)sample);
593 }
594 }
595 results[j] = PDF_Interpolate(encoded, 0, (FX_FLOAT)m_SampleMax,
596 m_pDecodeInfo[j].decode_min, m_pDecodeInfo[ j].decode_max);
597 }
598 return TRUE;
599 }
600 class CPDF_PSFunc : public CPDF_Function
601 {
602 public:
603 virtual FX_BOOL» » v_Init(CPDF_Object* pObj);
604 virtual FX_BOOL» » v_Call(FX_FLOAT* inputs, FX_FLOAT* results) cons t;
605 CPDF_PSEngine m_PS;
606 }; 661 };
607 FX_BOOL CPDF_PSFunc::v_Init(CPDF_Object* pObj) 662 CPDF_ExpIntFunc::CPDF_ExpIntFunc() {
608 { 663 m_pBeginValues = NULL;
609 CPDF_Stream* pStream = (CPDF_Stream*)pObj; 664 m_pEndValues = NULL;
610 CPDF_StreamAcc acc; 665 }
611 acc.LoadAllData(pStream, FALSE); 666 CPDF_ExpIntFunc::~CPDF_ExpIntFunc() {
612 return m_PS.Parse((const FX_CHAR*)acc.GetData(), acc.GetSize()); 667 if (m_pBeginValues) {
613 } 668 FX_Free(m_pBeginValues);
614 FX_BOOL CPDF_PSFunc::v_Call(FX_FLOAT* inputs, FX_FLOAT* results) const 669 }
615 { 670 if (m_pEndValues) {
616 CPDF_PSEngine& PS = (CPDF_PSEngine&)m_PS; 671 FX_Free(m_pEndValues);
617 PS.Reset(); 672 }
618 int i; 673 }
619 for (i = 0; i < m_nInputs; i ++) { 674 FX_BOOL CPDF_ExpIntFunc::v_Init(CPDF_Object* pObj) {
620 PS.Push(inputs[i]); 675 CPDF_Dictionary* pDict = pObj->GetDict();
621 } 676 if (pDict == NULL) {
622 PS.Execute(); 677 return FALSE;
623 if (PS.GetStackSize() < m_nOutputs) { 678 }
624 return FALSE; 679 CPDF_Array* pArray0 = pDict->GetArray(FX_BSTRC("C0"));
625 } 680 if (m_nOutputs == 0) {
626 for (i = 0; i < m_nOutputs; i ++) { 681 m_nOutputs = 1;
627 results[m_nOutputs - i - 1] = PS.Pop(); 682 if (pArray0) {
628 } 683 m_nOutputs = pArray0->GetCount();
629 return TRUE; 684 }
630 } 685 }
631 class CPDF_ExpIntFunc : public CPDF_Function 686 CPDF_Array* pArray1 = pDict->GetArray(FX_BSTRC("C1"));
632 { 687 m_pBeginValues = FX_Alloc2D(FX_FLOAT, m_nOutputs, 2);
633 public: 688 m_pEndValues = FX_Alloc2D(FX_FLOAT, m_nOutputs, 2);
634 CPDF_ExpIntFunc(); 689 for (int i = 0; i < m_nOutputs; i++) {
635 virtual ~CPDF_ExpIntFunc(); 690 m_pBeginValues[i] = pArray0 ? pArray0->GetFloat(i) : 0.0f;
636 virtual FX_BOOL» » v_Init(CPDF_Object* pObj); 691 m_pEndValues[i] = pArray1 ? pArray1->GetFloat(i) : 1.0f;
637 virtual FX_BOOL» » v_Call(FX_FLOAT* inputs, FX_FLOAT* results) cons t; 692 }
638 FX_FLOAT» m_Exponent; 693 m_Exponent = pDict->GetFloat(FX_BSTRC("N"));
639 FX_FLOAT*» m_pBeginValues; 694 m_nOrigOutputs = m_nOutputs;
640 FX_FLOAT*» m_pEndValues; 695 if (m_nOutputs && m_nInputs > INT_MAX / m_nOutputs) {
641 int»» m_nOrigOutputs; 696 return FALSE;
697 }
698 m_nOutputs *= m_nInputs;
699 return TRUE;
700 }
701 FX_BOOL CPDF_ExpIntFunc::v_Call(FX_FLOAT* inputs, FX_FLOAT* results) const {
702 for (int i = 0; i < m_nInputs; i++)
703 for (int j = 0; j < m_nOrigOutputs; j++) {
704 results[i * m_nOrigOutputs + j] =
705 m_pBeginValues[j] +
706 (FX_FLOAT)FXSYS_pow(inputs[i], m_Exponent) *
707 (m_pEndValues[j] - m_pBeginValues[j]);
708 }
709 return TRUE;
710 }
711 class CPDF_StitchFunc : public CPDF_Function {
712 public:
713 CPDF_StitchFunc();
714 virtual ~CPDF_StitchFunc();
715 virtual FX_BOOL v_Init(CPDF_Object* pObj);
716 virtual FX_BOOL v_Call(FX_FLOAT* inputs, FX_FLOAT* results) const;
717 int m_nSubs;
718 CPDF_Function** m_pSubFunctions;
719 FX_FLOAT* m_pBounds;
720 FX_FLOAT* m_pEncode;
642 }; 721 };
643 CPDF_ExpIntFunc::CPDF_ExpIntFunc() 722 CPDF_StitchFunc::CPDF_StitchFunc() {
644 { 723 m_nSubs = 0;
645 m_pBeginValues = NULL; 724 m_pSubFunctions = NULL;
646 m_pEndValues = NULL; 725 m_pBounds = NULL;
647 } 726 m_pEncode = NULL;
648 CPDF_ExpIntFunc::~CPDF_ExpIntFunc() 727 }
649 { 728 CPDF_StitchFunc::~CPDF_StitchFunc() {
650 if (m_pBeginValues) { 729 for (int i = 0; i < m_nSubs; i++)
651 FX_Free(m_pBeginValues); 730 delete m_pSubFunctions[i];
652 } 731 if (m_pSubFunctions) {
653 if (m_pEndValues) { 732 FX_Free(m_pSubFunctions);
654 FX_Free(m_pEndValues); 733 }
655 } 734 if (m_pBounds) {
656 } 735 FX_Free(m_pBounds);
657 FX_BOOL CPDF_ExpIntFunc::v_Init(CPDF_Object* pObj) 736 }
658 { 737 if (m_pEncode) {
659 CPDF_Dictionary* pDict = pObj->GetDict(); 738 FX_Free(m_pEncode);
660 if (pDict == NULL) { 739 }
661 return FALSE; 740 }
662 } 741 FX_BOOL CPDF_StitchFunc::v_Init(CPDF_Object* pObj) {
663 CPDF_Array* pArray0 = pDict->GetArray(FX_BSTRC("C0")); 742 CPDF_Dictionary* pDict = pObj->GetDict();
664 if (m_nOutputs == 0) { 743 if (pDict == NULL) {
665 m_nOutputs = 1; 744 return FALSE;
666 if (pArray0) { 745 }
667 m_nOutputs = pArray0->GetCount(); 746 CPDF_Array* pArray = pDict->GetArray(FX_BSTRC("Functions"));
668 } 747 if (pArray == NULL) {
669 } 748 return FALSE;
670 CPDF_Array* pArray1 = pDict->GetArray(FX_BSTRC("C1")); 749 }
671 m_pBeginValues = FX_Alloc2D(FX_FLOAT, m_nOutputs, 2); 750 m_nSubs = pArray->GetCount();
672 m_pEndValues = FX_Alloc2D(FX_FLOAT, m_nOutputs, 2); 751 if (m_nSubs == 0) {
673 for (int i = 0; i < m_nOutputs; i ++) { 752 return FALSE;
674 m_pBeginValues[i] = pArray0 ? pArray0->GetFloat(i) : 0.0f; 753 }
675 m_pEndValues[i] = pArray1 ? pArray1->GetFloat(i) : 1.0f; 754 m_pSubFunctions = FX_Alloc(CPDF_Function*, m_nSubs);
676 } 755 m_nOutputs = 0;
677 m_Exponent = pDict->GetFloat(FX_BSTRC("N")); 756 int i;
678 m_nOrigOutputs = m_nOutputs; 757 for (i = 0; i < m_nSubs; i++) {
679 if (m_nOutputs && m_nInputs > INT_MAX / m_nOutputs) { 758 CPDF_Object* pSub = pArray->GetElementValue(i);
680 return FALSE; 759 if (pSub == pObj) {
681 } 760 return FALSE;
682 m_nOutputs *= m_nInputs; 761 }
683 return TRUE; 762 m_pSubFunctions[i] = CPDF_Function::Load(pSub);
684 }
685 FX_BOOL CPDF_ExpIntFunc::v_Call(FX_FLOAT* inputs, FX_FLOAT* results) const
686 {
687 for (int i = 0; i < m_nInputs; i ++)
688 for (int j = 0; j < m_nOrigOutputs; j ++) {
689 results[i * m_nOrigOutputs + j] = m_pBeginValues[j] + (FX_FLOAT)FXSY S_pow(inputs[i], m_Exponent) *
690 (m_pEndValues[j] - m_pBeginValues[ j]);
691 }
692 return TRUE;
693 }
694 class CPDF_StitchFunc : public CPDF_Function
695 {
696 public:
697 CPDF_StitchFunc();
698 virtual ~CPDF_StitchFunc();
699 virtual FX_BOOL» » v_Init(CPDF_Object* pObj);
700 virtual FX_BOOL» » v_Call(FX_FLOAT* inputs, FX_FLOAT* results) cons t;
701 int»» » m_nSubs;
702 CPDF_Function** m_pSubFunctions;
703 FX_FLOAT*» m_pBounds;
704 FX_FLOAT*» m_pEncode;
705 };
706 CPDF_StitchFunc::CPDF_StitchFunc()
707 {
708 m_nSubs = 0;
709 m_pSubFunctions = NULL;
710 m_pBounds = NULL;
711 m_pEncode = NULL;
712 }
713 CPDF_StitchFunc::~CPDF_StitchFunc()
714 {
715 for (int i = 0; i < m_nSubs; i ++)
716 delete m_pSubFunctions[i];
717 if (m_pSubFunctions) {
718 FX_Free(m_pSubFunctions);
719 }
720 if (m_pBounds) {
721 FX_Free(m_pBounds);
722 }
723 if (m_pEncode) {
724 FX_Free(m_pEncode);
725 }
726 }
727 FX_BOOL CPDF_StitchFunc::v_Init(CPDF_Object* pObj)
728 {
729 CPDF_Dictionary* pDict = pObj->GetDict();
730 if (pDict == NULL) {
731 return FALSE;
732 }
733 CPDF_Array* pArray = pDict->GetArray(FX_BSTRC("Functions"));
734 if (pArray == NULL) {
735 return FALSE;
736 }
737 m_nSubs = pArray->GetCount();
738 if (m_nSubs == 0) {
739 return FALSE;
740 }
741 m_pSubFunctions = FX_Alloc(CPDF_Function*, m_nSubs);
742 m_nOutputs = 0;
743 int i;
744 for (i = 0; i < m_nSubs; i ++) {
745 CPDF_Object* pSub = pArray->GetElementValue(i);
746 if (pSub == pObj) {
747 return FALSE;
748 }
749 m_pSubFunctions[i] = CPDF_Function::Load(pSub);
750 if (m_pSubFunctions[i] == NULL) {
751 return FALSE;
752 }
753 if (m_pSubFunctions[i]->CountOutputs() > m_nOutputs) {
754 m_nOutputs = m_pSubFunctions[i]->CountOutputs();
755 }
756 }
757 m_pBounds = FX_Alloc(FX_FLOAT, m_nSubs + 1);
758 m_pBounds[0] = m_pDomains[0];
759 pArray = pDict->GetArray(FX_BSTRC("Bounds"));
760 if (pArray == NULL) {
761 return FALSE;
762 }
763 for (i = 0; i < m_nSubs - 1; i ++) {
764 m_pBounds[i + 1] = pArray->GetFloat(i);
765 }
766 m_pBounds[m_nSubs] = m_pDomains[1];
767 m_pEncode = FX_Alloc2D(FX_FLOAT, m_nSubs, 2);
768 pArray = pDict->GetArray(FX_BSTRC("Encode"));
769 if (pArray == NULL) {
770 return FALSE;
771 }
772 for (i = 0; i < m_nSubs * 2; i ++) {
773 m_pEncode[i] = pArray->GetFloat(i);
774 }
775 return TRUE;
776 }
777 FX_BOOL CPDF_StitchFunc::v_Call(FX_FLOAT* inputs, FX_FLOAT* outputs) const
778 {
779 FX_FLOAT input = inputs[0];
780 int i;
781 for (i = 0; i < m_nSubs - 1; i ++)
782 if (input < m_pBounds[i + 1]) {
783 break;
784 }
785 if (m_pSubFunctions[i] == NULL) { 763 if (m_pSubFunctions[i] == NULL) {
786 return FALSE; 764 return FALSE;
787 } 765 }
788 input = PDF_Interpolate(input, m_pBounds[i], m_pBounds[i + 1], m_pEncode[i * 2], m_pEncode[i * 2 + 1]); 766 if (m_pSubFunctions[i]->CountOutputs() > m_nOutputs) {
789 int nresults; 767 m_nOutputs = m_pSubFunctions[i]->CountOutputs();
790 m_pSubFunctions[i]->Call(&input, m_nInputs, outputs, nresults); 768 }
791 return TRUE; 769 }
792 } 770 m_pBounds = FX_Alloc(FX_FLOAT, m_nSubs + 1);
793 CPDF_Function* CPDF_Function::Load(CPDF_Object* pFuncObj) 771 m_pBounds[0] = m_pDomains[0];
794 { 772 pArray = pDict->GetArray(FX_BSTRC("Bounds"));
795 if (pFuncObj == NULL) { 773 if (pArray == NULL) {
796 return NULL; 774 return FALSE;
797 } 775 }
798 CPDF_Function* pFunc = NULL; 776 for (i = 0; i < m_nSubs - 1; i++) {
799 int type; 777 m_pBounds[i + 1] = pArray->GetFloat(i);
800 if (pFuncObj->GetType() == PDFOBJ_STREAM) { 778 }
801 type = ((CPDF_Stream*)pFuncObj)->GetDict()->GetInteger(FX_BSTRC("Functio nType")); 779 m_pBounds[m_nSubs] = m_pDomains[1];
802 } else if (pFuncObj->GetType() == PDFOBJ_DICTIONARY) { 780 m_pEncode = FX_Alloc2D(FX_FLOAT, m_nSubs, 2);
803 type = ((CPDF_Dictionary*)pFuncObj)->GetInteger(FX_BSTRC("FunctionType") ); 781 pArray = pDict->GetArray(FX_BSTRC("Encode"));
804 } else { 782 if (pArray == NULL) {
805 return NULL; 783 return FALSE;
806 } 784 }
807 if (type == 0) { 785 for (i = 0; i < m_nSubs * 2; i++) {
808 pFunc = new CPDF_SampledFunc; 786 m_pEncode[i] = pArray->GetFloat(i);
809 } else if (type == 2) { 787 }
810 pFunc = new CPDF_ExpIntFunc; 788 return TRUE;
811 } else if (type == 3) { 789 }
812 pFunc = new CPDF_StitchFunc; 790 FX_BOOL CPDF_StitchFunc::v_Call(FX_FLOAT* inputs, FX_FLOAT* outputs) const {
813 } else if (type == 4) { 791 FX_FLOAT input = inputs[0];
814 pFunc = new CPDF_PSFunc; 792 int i;
815 } else { 793 for (i = 0; i < m_nSubs - 1; i++)
816 return NULL; 794 if (input < m_pBounds[i + 1]) {
817 } 795 break;
818 if (!pFunc->Init(pFuncObj)) { 796 }
819 delete pFunc; 797 if (m_pSubFunctions[i] == NULL) {
820 return NULL; 798 return FALSE;
821 } 799 }
822 return pFunc; 800 input = PDF_Interpolate(input, m_pBounds[i], m_pBounds[i + 1],
823 } 801 m_pEncode[i * 2], m_pEncode[i * 2 + 1]);
824 CPDF_Function::CPDF_Function() 802 int nresults;
825 { 803 m_pSubFunctions[i]->Call(&input, m_nInputs, outputs, nresults);
804 return TRUE;
805 }
806 CPDF_Function* CPDF_Function::Load(CPDF_Object* pFuncObj) {
807 if (pFuncObj == NULL) {
808 return NULL;
809 }
810 CPDF_Function* pFunc = NULL;
811 int type;
812 if (pFuncObj->GetType() == PDFOBJ_STREAM) {
813 type = ((CPDF_Stream*)pFuncObj)
814 ->GetDict()
815 ->GetInteger(FX_BSTRC("FunctionType"));
816 } else if (pFuncObj->GetType() == PDFOBJ_DICTIONARY) {
817 type = ((CPDF_Dictionary*)pFuncObj)->GetInteger(FX_BSTRC("FunctionType"));
818 } else {
819 return NULL;
820 }
821 if (type == 0) {
822 pFunc = new CPDF_SampledFunc;
823 } else if (type == 2) {
824 pFunc = new CPDF_ExpIntFunc;
825 } else if (type == 3) {
826 pFunc = new CPDF_StitchFunc;
827 } else if (type == 4) {
828 pFunc = new CPDF_PSFunc;
829 } else {
830 return NULL;
831 }
832 if (!pFunc->Init(pFuncObj)) {
833 delete pFunc;
834 return NULL;
835 }
836 return pFunc;
837 }
838 CPDF_Function::CPDF_Function() {
839 m_pDomains = NULL;
840 m_pRanges = NULL;
841 }
842 CPDF_Function::~CPDF_Function() {
843 if (m_pDomains) {
844 FX_Free(m_pDomains);
826 m_pDomains = NULL; 845 m_pDomains = NULL;
846 }
847 if (m_pRanges) {
848 FX_Free(m_pRanges);
827 m_pRanges = NULL; 849 m_pRanges = NULL;
828 } 850 }
829 CPDF_Function::~CPDF_Function() 851 }
830 { 852 FX_BOOL CPDF_Function::Init(CPDF_Object* pObj) {
831 if (m_pDomains) { 853 CPDF_Dictionary* pDict;
832 FX_Free(m_pDomains); 854 if (pObj->GetType() == PDFOBJ_STREAM) {
833 m_pDomains = NULL; 855 pDict = ((CPDF_Stream*)pObj)->GetDict();
834 } 856 } else {
857 pDict = (CPDF_Dictionary*)pObj;
858 }
859 CPDF_Array* pDomains = pDict->GetArray(FX_BSTRC("Domain"));
860 if (pDomains == NULL) {
861 return FALSE;
862 }
863 m_nInputs = pDomains->GetCount() / 2;
864 if (m_nInputs == 0) {
865 return FALSE;
866 }
867 m_pDomains = FX_Alloc2D(FX_FLOAT, m_nInputs, 2);
868 for (int i = 0; i < m_nInputs * 2; i++) {
869 m_pDomains[i] = pDomains->GetFloat(i);
870 }
871 CPDF_Array* pRanges = pDict->GetArray(FX_BSTRC("Range"));
872 m_nOutputs = 0;
873 if (pRanges) {
874 m_nOutputs = pRanges->GetCount() / 2;
875 m_pRanges = FX_Alloc2D(FX_FLOAT, m_nOutputs, 2);
876 for (int i = 0; i < m_nOutputs * 2; i++) {
877 m_pRanges[i] = pRanges->GetFloat(i);
878 }
879 }
880 FX_DWORD old_outputs = m_nOutputs;
881 if (!v_Init(pObj)) {
882 return FALSE;
883 }
884 if (m_pRanges && m_nOutputs > (int)old_outputs) {
885 m_pRanges = FX_Realloc(FX_FLOAT, m_pRanges, m_nOutputs * 2);
835 if (m_pRanges) { 886 if (m_pRanges) {
836 FX_Free(m_pRanges); 887 FXSYS_memset(m_pRanges + (old_outputs * 2), 0,
837 m_pRanges = NULL; 888 sizeof(FX_FLOAT) * (m_nOutputs - old_outputs) * 2);
838 } 889 }
839 } 890 }
840 FX_BOOL CPDF_Function::Init(CPDF_Object* pObj) 891 return TRUE;
841 { 892 }
842 CPDF_Dictionary* pDict; 893 FX_BOOL CPDF_Function::Call(FX_FLOAT* inputs,
843 if (pObj->GetType() == PDFOBJ_STREAM) { 894 int ninputs,
844 pDict = ((CPDF_Stream*)pObj)->GetDict(); 895 FX_FLOAT* results,
845 } else { 896 int& nresults) const {
846 pDict = (CPDF_Dictionary*)pObj; 897 if (m_nInputs != ninputs) {
847 } 898 return FALSE;
848 CPDF_Array* pDomains = pDict->GetArray(FX_BSTRC("Domain")); 899 }
849 if (pDomains == NULL) { 900 nresults = m_nOutputs;
850 return FALSE; 901 for (int i = 0; i < m_nInputs; i++) {
851 } 902 if (inputs[i] < m_pDomains[i * 2]) {
852 m_nInputs = pDomains->GetCount() / 2; 903 inputs[i] = m_pDomains[i * 2];
853 if (m_nInputs == 0) { 904 } else if (inputs[i] > m_pDomains[i * 2 + 1]) {
854 return FALSE; 905 inputs[i] = m_pDomains[i * 2] + 1;
855 } 906 }
856 m_pDomains = FX_Alloc2D(FX_FLOAT, m_nInputs, 2); 907 }
857 for (int i = 0; i < m_nInputs * 2; i ++) { 908 v_Call(inputs, results);
858 m_pDomains[i] = pDomains->GetFloat(i); 909 if (m_pRanges) {
859 } 910 for (int i = 0; i < m_nOutputs; i++) {
860 CPDF_Array* pRanges = pDict->GetArray(FX_BSTRC("Range")); 911 if (results[i] < m_pRanges[i * 2]) {
861 m_nOutputs = 0; 912 results[i] = m_pRanges[i * 2];
862 if (pRanges) { 913 } else if (results[i] > m_pRanges[i * 2 + 1]) {
863 m_nOutputs = pRanges->GetCount() / 2; 914 results[i] = m_pRanges[i * 2 + 1];
864 m_pRanges = FX_Alloc2D(FX_FLOAT, m_nOutputs, 2); 915 }
865 for (int i = 0; i < m_nOutputs * 2; i ++) { 916 }
866 m_pRanges[i] = pRanges->GetFloat(i); 917 }
867 } 918 return TRUE;
868 } 919 }
869 FX_DWORD old_outputs = m_nOutputs;
870 if (!v_Init(pObj)) {
871 return FALSE;
872 }
873 if (m_pRanges && m_nOutputs > (int)old_outputs) {
874 m_pRanges = FX_Realloc(FX_FLOAT, m_pRanges, m_nOutputs * 2);
875 if (m_pRanges) {
876 FXSYS_memset(m_pRanges + (old_outputs * 2), 0, sizeof(FX_FLOAT) * (m _nOutputs - old_outputs) * 2);
877 }
878 }
879 return TRUE;
880 }
881 FX_BOOL CPDF_Function::Call(FX_FLOAT* inputs, int ninputs, FX_FLOAT* results, in t& nresults) const
882 {
883 if (m_nInputs != ninputs) {
884 return FALSE;
885 }
886 nresults = m_nOutputs;
887 for (int i = 0; i < m_nInputs; i ++) {
888 if (inputs[i] < m_pDomains[i * 2]) {
889 inputs[i] = m_pDomains[i * 2];
890 } else if (inputs[i] > m_pDomains[i * 2 + 1]) {
891 inputs[i] = m_pDomains[i * 2] + 1;
892 }
893 }
894 v_Call(inputs, results);
895 if (m_pRanges) {
896 for (int i = 0; i < m_nOutputs; i ++) {
897 if (results[i] < m_pRanges[i * 2]) {
898 results[i] = m_pRanges[i * 2];
899 } else if (results[i] > m_pRanges[i * 2 + 1]) {
900 results[i] = m_pRanges[i * 2 + 1];
901 }
902 }
903 }
904 return TRUE;
905 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698