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

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

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

Powered by Google App Engine
This is Rietveld 408576698