Bug Summary

File:IccProfLib/IccMpeCalc.cpp
Warning:line 4720, column 5
Value stored to 'rv' is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-apple-macosx14.0.0 -Wundef-prefix=TARGET_OS_ -Werror=undef-prefix -Wdeprecated-objc-isa-usage -Werror=deprecated-objc-isa-usage -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name IccMpeCalc.cpp -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=osx -analyzer-checker=security.insecureAPI.decodeValueOfObjCType -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -mframe-pointer=all -ffp-contract=on -fno-rounding-math -funwind-tables=2 -target-sdk-version=14.0 -fcompatibility-qualified-id-block-type-checking -fvisibility-inlines-hidden-static-local-var -target-cpu penryn -tune-cpu generic -debugger-tuning=lldb -target-linker-version 1015.7 -fprofile-instrument=clang -fcoverage-mapping -fcoverage-compilation-dir=/Users/xss/DemoIccMAX-hoyt-master/build/IccProfLib -resource-dir /usr/local/Cellar/llvm/17.0.3/lib/clang/17 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX14.0.sdk -D IccProfLib2_EXPORTS -I /Users/xss/DemoIccMAX-hoyt-master/build/Cmake/../../IccProfLib -I /Developer/Headers/FlatCarbon -F/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX14.0.sdk/System/Library/Frameworks -internal-isystem /usr/local/Cellar/llvm/17.0.3/bin/../include/c++/v1 -internal-isystem /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX14.0.sdk/usr/local/include -internal-isystem /usr/local/Cellar/llvm/17.0.3/lib/clang/17/include -internal-externc-isystem /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX14.0.sdk/usr/include -std=gnu++17 -fdeprecated-macro -fdebug-compilation-dir=/Users/xss/DemoIccMAX-hoyt-master/build/IccProfLib -ferror-limit 19 -fsanitize=address -fsanitize-system-ignorelist=/usr/local/Cellar/llvm/17.0.3/lib/clang/17/share/asan_ignorelist.txt -fno-sanitize-memory-param-retval -fsanitize-address-use-after-scope -fsanitize-address-globals-dead-stripping -fno-assume-sane-operator-new -stack-protector 1 -fblocks -fencode-extended-block-signature -fregister-global-dtors-with-atexit -fgnuc-version=4.2.1 -fcxx-exceptions -fexceptions -fmax-type-align=16 -analyzer-output=html -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /var/folders/l9/sd9kj1px4yq2wc5_lkwhlt6w0000gn/T/scan-build-2023-10-28-102616-57860-1 -x c++ /Users/xss/DemoIccMAX-hoyt-master/IccProfLib/IccMpeCalc.cpp
1/** @file
2 File: IccMpeCalc.cpp
3
4 Contains: Implementation of Calculator Element
5
6 Version: V1
7
8 Copyright: (c) see ICC Software License
9*/
10
11/*
12 * The ICC Software License, Version 0.1
13 *
14 *
15 * Copyright (c) 2003-2006 The International Color Consortium. All rights
16 * reserved.
17 *
18 * Redistribution and use in source and binary forms, with or without
19 * modification, are permitted provided that the following conditions
20 * are met:
21 *
22 * 1. Redistributions of source code must retain the above copyright
23 * notice, this list of conditions and the following disclaimer.
24 *
25 * 2. Redistributions in binary form must reproduce the above copyright
26 * notice, this list of conditions and the following disclaimer in
27 * the documentation and/or other materials provided with the
28 * distribution.
29 *
30 * 3. In the absence of prior written permission, the names "ICC" and "The
31 * International Color Consortium" must not be used to imply that the
32 * ICC organization endorses or promotes products derived from this
33 * software.
34 *
35 *
36 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
37 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
38 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
39 * DISCLAIMED. IN NO EVENT SHALL THE INTERNATIONAL COLOR CONSORTIUM OR
40 * ITS CONTRIBUTING MEMBERS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
42 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
43 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
44 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
45 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
46 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
47 * SUCH DAMAGE.
48 * ====================================================================
49 *
50 * This software consists of voluntary contributions made by many
51 * individuals on behalf of the The International Color Consortium.
52 *
53 *
54 * Membership in the ICC is encouraged when this software is used for
55 * commercial purposes.
56 *
57 *
58 * For more information on The International Color Consortium, please
59 * see <http://www.color.org/>.
60 *
61 *
62 */
63
64//////////////////////////////////////////////////////////////////////
65// HISTORY:
66//
67// -Initial implementation by Max Derhak 1-30-2006
68//
69//////////////////////////////////////////////////////////////////////
70
71#ifdef WIN32
72#pragma warning( disable: 4786) //disable warning in <list.h>
73#endif
74
75#include <stdio.h>
76#include <math.h>
77#include <string.h>
78#include <stdlib.h>
79#include "IccMpeBasic.h"
80#include "IccMpeCalc.h"
81#include "IccIO.h"
82#include <map>
83#include "IccUtil.h"
84
85//#define ICC_VERBOSE_CALC_APPLY 1
86
87
88class CIccConsoleDebugger : public IIccCalcDebugger
89{
90public:
91
92 virtual ~CIccConsoleDebugger() {}
93
94 virtual void BeginApply()
95 {
96 printf("\nBegin Calc Apply\n");
97 }
98
99 virtual void EndApply()
100 {
101 printf("End Calculator Apply\n\n");
102 fflush(stdout__stdoutp);
103 }
104
105 virtual bool BeforeOp(SIccCalcOp *op, SIccOpState &os, SIccCalcOp *ops)
106 {
107 if (op->sig == icSigIfOp || op->sig == icSigSelectOp) {
108 printf("Start:");
109 std::string opDesc;
110 op->Describe(opDesc);
111 printf("%9s\t", opDesc.c_str());
112 for (int j = 0; j < (int)os.pStack->size(); j++)
113 printf(" %.4f", (*os.pStack)[j]);
114 printf("\n");
115 }
116 return false;
117 }
118
119 virtual bool AfterOp(SIccCalcOp *op, SIccOpState &os, SIccCalcOp *ops)
120 {
121 if (op->sig == icSigDataOp) {
122 printf("%9s\t", "data");
123 }
124 else {
125 if (op->sig == icSigIfOp || op->sig == icSigSelectOp) {
126 printf("End:");
127 }
128 std::string opDesc;
129 op->Describe(opDesc);
130 printf("%9s\t", opDesc.c_str());
131 }
132
133 for (int j = 0; j < (int)os.pStack->size(); j++)
134 printf(" %.4f", (*os.pStack)[j]);
135 printf("\n");
136
137 if (op->sig==icSigIfOp || op->sig==icSigSelectOp)
138 printf("\n");
139 fflush(stdout__stdoutp);
140
141 return false;
142 }
143 virtual void Error(const char *szMsg)
144 {
145 printf("%s\n", szMsg);
146 }
147};
148
149static CIccConsoleDebugger g_ConsoleDebugger;
150
151#ifdef ICC_VERBOSE_CALC_APPLY
152static IIccCalcDebugger *g_pDebugger = &g_ConsoleDebugger;
153#else
154static IIccCalcDebugger *g_pDebugger = icCalcDebuggerNone((IIccCalcDebugger*)0);
155#endif
156
157void IIccCalcDebugger::SetDebugger(IIccCalcDebugger *pDebugger)
158{
159 if (pDebugger == icCalcDebuggerConsole((IIccCalcDebugger*)-1))
160 g_pDebugger = &g_ConsoleDebugger;
161 else
162 g_pDebugger = pDebugger;
163}
164
165#define OsPopArg(X){ if (!os.pStack->size()) return false; X = *(os.pStack->
rbegin()); os.pStack->pop_back(); }
{ \
166 if (!os.pStack->size()) \
167 return false; \
168 X = *(os.pStack->rbegin()); \
169 os.pStack->pop_back(); \
170}
171
172#define OsPopArgs(X, N){ icUInt32Number nv=(N); size_t ss = os.pStack->size(); if
(nv>ss) return false; icFloatNumber *sv = &(*os.pStack
)[ss-nv]; memcpy((X), sv, nv*sizeof(icFloatNumber)); os.pStack
->resize(ss-nv); }
{ \
173 icUInt32Number nv=(N); \
174 size_t ss = os.pStack->size(); \
175 if (nv>ss) \
176 return false; \
177 icFloatNumber *sv = &(*os.pStack)[ss-nv]; \
178 memcpy((X), sv, nv*sizeof(icFloatNumber)); \
179 os.pStack->resize(ss-nv); \
180}
181
182
183#define OsPushArg(X){ icFloatNumber V = (X); os.pStack->push_back(V); } { \
184 icFloatNumber V = (X); \
185 os.pStack->push_back(V); \
186}
187
188#define OsPushArgs(X, N){ size_t ss = os.pStack->size(); icUInt32Number nv=(N); os
.pStack->resize(ss+nv); icFloatNumber *sv = &(*os.pStack
)[ss]; memcpy(sv, (X), nv*sizeof(icFloatNumber)); }
{ \
189 size_t ss = os.pStack->size(); \
190 icUInt32Number nv=(N); \
191 os.pStack->resize(ss+nv); \
192 icFloatNumber *sv = &(*os.pStack)[ss]; \
193 memcpy(sv, (X), nv*sizeof(icFloatNumber)); \
194}
195
196#define OsShrinkArgs(N){ icUInt32Number nv = (N); size_t ss = os.pStack->size(); if
(nv>ss) return false; os.pStack->resize(ss-nv); }
{ \
197 icUInt32Number nv = (N); \
198 size_t ss = os.pStack->size(); \
199 if (nv>ss) \
200 return false; \
201 os.pStack->resize(ss-nv); \
202}
203
204#define OsExtendArgs(N){ size_t ss = os.pStack->size(); os.pStack->resize(ss+(
N)); }
{ \
205 size_t ss = os.pStack->size(); \
206 os.pStack->resize(ss+(N)); \
207}
208
209
210class CIccOpDefInvalid : public IIccOpDef
211{
212public:
213 virtual bool IsValid(CIccMpeCalculator *pCalc, SIccCalcOp &op) { return false; }
214 virtual bool Exec(SIccCalcOp *op, SIccOpState &os)
215 {
216 if (g_pDebugger)
217 {
218 std::string opDesc;
219 op->Describe(opDesc);
220 std::string line = "Unknown operator: ";
221 line += opDesc;
222 g_pDebugger->Error(line.c_str());
223 }
224 return false;
225 }
226};
227
228class CIccOpDefData : public IIccOpDef
229{
230public:
231 virtual bool Exec(SIccCalcOp *op, SIccOpState &os)
232 {
233 icUInt32Number n, j;
234 if (!op->extra) {
235 for (n=1; n+os.idx<os.nOps; n++)
236 if (op[n].sig!=icSigDataOp)
237 break;
238 op->extra = n;
239 }
240 else {
241 n=(icUInt32Number)op->extra;
242 }
243 size_t ss = os.pStack->size();
244 os.pStack->resize(ss+n);
245 icFloatNumber *s = &(*os.pStack)[ss];
246 for (j=0; j<n; j++) {
247 s[j] = op[j].data.num;
248 }
249 os.idx += n-1;
250 return true;
251 }
252};
253
254class CIccOpDefPop : public IIccOpDef
255{
256public:
257 virtual bool Exec(SIccCalcOp *op, SIccOpState &os)
258 {
259 size_t ss = os.pStack->size();
260 if ((size_t)(op->data.select.v1+1)>ss)
261 return false;
262 os.pStack->resize(ss-(op->data.select.v1+1));
263 return true;
264 }
265};
266
267class CIccOpDefOutputChan : public IIccOpDef
268{
269public:
270 virtual bool Exec(SIccCalcOp *op, SIccOpState &os)
271 {
272 OsPopArgs(&os.output[op->data.select.v1], op->data.select.v2+1){ icUInt32Number nv=(op->data.select.v2+1); size_t ss = os
.pStack->size(); if (nv>ss) return false; icFloatNumber
*sv = &(*os.pStack)[ss-nv]; memcpy((&os.output[op->
data.select.v1]), sv, nv*sizeof(icFloatNumber)); os.pStack->
resize(ss-nv); }
;
273 return true;
274 }
275};
276
277class CIccOpDefInputChan : public IIccOpDef
278{
279public:
280 virtual bool Exec(SIccCalcOp *op, SIccOpState &os)
281 {
282 OsPushArgs(&os.pixel[op->data.select.v1], op->data.select.v2+1){ size_t ss = os.pStack->size(); icUInt32Number nv=(op->
data.select.v2+1); os.pStack->resize(ss+nv); icFloatNumber
*sv = &(*os.pStack)[ss]; memcpy(sv, (&os.pixel[op->
data.select.v1]), nv*sizeof(icFloatNumber)); }
;
283 return true;
284 }
285};
286
287class CIccOpDefTempGetChan : public IIccOpDef
288{
289public:
290 virtual bool Exec(SIccCalcOp *op, SIccOpState &os)
291 {
292 OsPushArgs(&os.temp[op->data.select.v1], op->data.select.v2+1){ size_t ss = os.pStack->size(); icUInt32Number nv=(op->
data.select.v2+1); os.pStack->resize(ss+nv); icFloatNumber
*sv = &(*os.pStack)[ss]; memcpy(sv, (&os.temp[op->
data.select.v1]), nv*sizeof(icFloatNumber)); }
;
293 return true;
294 }
295};
296
297class CIccOpDefTempPutChan : public IIccOpDef
298{
299public:
300 virtual bool Exec(SIccCalcOp *op, SIccOpState &os)
301 {
302 OsPopArgs(&os.temp[op->data.select.v1], op->data.select.v2+1){ icUInt32Number nv=(op->data.select.v2+1); size_t ss = os
.pStack->size(); if (nv>ss) return false; icFloatNumber
*sv = &(*os.pStack)[ss-nv]; memcpy((&os.temp[op->
data.select.v1]), sv, nv*sizeof(icFloatNumber)); os.pStack->
resize(ss-nv); }
303 return true;
304 }
305};
306
307class CIccOpDefTempSaveChan : public IIccOpDef
308{
309public:
310 virtual bool Exec(SIccCalcOp *op, SIccOpState &os)
311 {
312 size_t ss = os.pStack->size();
313 size_t n=op->data.select.v2+1;
314
315 if (n>ss)
316 return false;
317
318 icFloatNumber *s = &(*os.pStack)[ss - n];
319 memcpy(&os.temp[op->data.select.v1], s, n*sizeof(icFloatNumber));
320 return true;
321 }
322};
323
324class CIccOpDefEnvVar : public IIccOpDef
325{
326public:
327 virtual bool Exec(SIccCalcOp *op, SIccOpState &os)
328 {
329 icSigCmmEnvVar sig = (icSigCmmEnvVar) op->data.size;
330 icFloatNumber val=0.0;
331
332 if (sig==icSigTrueVar) {
333 OsPushArg((icFloatNumber)1.0){ icFloatNumber V = ((icFloatNumber)1.0); os.pStack->push_back
(V); }
;
334 OsPushArg((icFloatNumber)1.0){ icFloatNumber V = ((icFloatNumber)1.0); os.pStack->push_back
(V); }
;
335 }
336 else if (sig==icSigNotDefVar) {
337 OsPushArg((icFloatNumber)0.0){ icFloatNumber V = ((icFloatNumber)0.0); os.pStack->push_back
(V); }
;
338 OsPushArg((icFloatNumber)0.0){ icFloatNumber V = ((icFloatNumber)0.0); os.pStack->push_back
(V); }
;
339 }
340 else if (os.pApply->GetEnvVar(sig, val)) {
341 OsPushArg((icFloatNumber)val){ icFloatNumber V = ((icFloatNumber)val); os.pStack->push_back
(V); }
;
342 OsPushArg((icFloatNumber)1.0){ icFloatNumber V = ((icFloatNumber)1.0); os.pStack->push_back
(V); }
;
343 }
344 else {
345 OsPushArg((icFloatNumber)0.0){ icFloatNumber V = ((icFloatNumber)0.0); os.pStack->push_back
(V); }
;
346 OsPushArg((icFloatNumber)0.0){ icFloatNumber V = ((icFloatNumber)0.0); os.pStack->push_back
(V); }
;
347 }
348 return true;
349 }
350};
351
352class CIccOpDefSubElement : public IIccOpDef
353{
354public:
355 virtual bool Exec(SIccCalcOp *op, SIccOpState &os)
356 {
357 CIccSubCalcApply *pElemApply = os.pApply->GetApply(op->data.select.v1);
358 if (!pElemApply)
359 return false;
360
361 icUInt16Number nSrc = pElemApply->NumInputChannels();
362 icUInt16Number nDst = pElemApply->NumOutputChannels();
363
364 size_t ss = os.pStack->size();
365 if (nSrc>ss)
366 return false;
367 icFloatNumber *s = &(*os.pStack)[ss - nSrc];
368
369 if (os.pScratch->size()<(size_t)nDst)
370 os.pScratch->resize(nDst);
371
372 icFloatNumber *d = &(*os.pScratch)[0];
373
374 pElemApply->Apply(d, s);
375
376 int ns = (int)ss + (int)nDst - (int)nSrc;
377
378 if (ns != ss)
379 os.pStack->resize(ns);
380
381 s = &(*os.pStack)[ns - nDst];
382 memcpy(s, d, nDst*sizeof(icFloatNumber));
383 return true;
384 }
385};
386
387class CIccOpDefCopy : public IIccOpDef
388{
389public:
390 virtual bool Exec(SIccCalcOp *op, SIccOpState &os)
391 {
392 size_t ss = os.pStack->size();
393 int j;
394 int n=op->data.select.v1+1;
395 int t=op->data.select.v2+1;
396 if (n>(int)ss)
397 return false;
398
399 if (n && t) {
400 OsExtendArgs(n*t){ size_t ss = os.pStack->size(); os.pStack->resize(ss+(
n*t)); }
;
401
402 icFloatNumber *to = &(*os.pStack)[ss];
403 icFloatNumber *from = to-n;
404
405 for (j=0; j<t; j++) {
406 memcpy(to, from, n*sizeof(icFloatNumber));
407 to+=n;
408 }
409 }
410 return true;
411 }
412};
413
414class CIccOpDefPositionDup : public IIccOpDef
415{
416public:
417 virtual bool Exec(SIccCalcOp *op, SIccOpState &os)
418 {
419 size_t ss = os.pStack->size();
420 int j, n=op->data.select.v1+1;
421 int t=op->data.select.v2+1;
422 if (n>(int)ss)
423 return false;
424
425 if (n && t) {
426 OsExtendArgs(t){ size_t ss = os.pStack->size(); os.pStack->resize(ss+(
t)); }
;
427
428 icFloatNumber *to = &(*os.pStack)[ss];
429 icFloatNumber *from = to-n;
430
431 for (j=0; j<t; j++) {
432 to[j] = *from;
433 }
434 }
435 return true;
436 }
437};
438
439class CIccOpDefFlip : public IIccOpDef
440{
441public:
442 virtual bool Exec(SIccCalcOp *op, SIccOpState &os)
443 {
444 int n = op->data.select.v1+2;
445 size_t ss = os.pStack->size();
446 if (n>(int)ss)
447 return false;
448 icFloatNumber *s = &(*os.pStack)[ss-n];
449 icFloatNumber t;
450 int j, k;
451 for (j=0, k=n-1; j<k; j++, k--) {
452 t = s[j];
453 s[j] = s[k];
454 s[k] = t;
455 }
456 return true;
457 }
458};
459
460class CIccOpDefRotateLeft : public IIccOpDef
461{
462public:
463 virtual bool Exec(SIccCalcOp *op, SIccOpState &os)
464 {
465 int nCopy = op->data.select.v1+1;
466 int nPos = op->data.select.v2+1;
467
468 if (nCopy) {
469 int next = nPos;
470 if (os.pScratch->size()<(size_t)nCopy)
471 os.pScratch->resize(nCopy);
472
473 icFloatNumber *copyList = &(*os.pScratch)[0];
474
475 OsPopArgs(copyList, nCopy){ icUInt32Number nv=(nCopy); size_t ss = os.pStack->size()
; if (nv>ss) return false; icFloatNumber *sv = &(*os.pStack
)[ss-nv]; memcpy((copyList), sv, nv*sizeof(icFloatNumber)); os
.pStack->resize(ss-nv); }
;
476
477 int j;
478 for (j=0; j<nCopy; j++) {
479 OsPushArg(copyList[(j+next)%nCopy]){ icFloatNumber V = (copyList[(j+next)%nCopy]); os.pStack->
push_back(V); }
;
480 }
481 }
482 return true;
483 }
484};
485
486class CIccOpDefRotateRight : public IIccOpDef
487{
488public:
489 virtual bool Exec(SIccCalcOp *op, SIccOpState &os)
490 {
491 int nCopy = op->data.select.v1+1;
492 int nPos = (op->data.select.v2+1)%nCopy;
493
494 if (nCopy) {
495 int next = nCopy - nPos;
496 if (os.pScratch->size()<(size_t)nCopy)
497 os.pScratch->resize(nCopy);
498
499 icFloatNumber *copyList = &(*os.pScratch)[0];
500
501 OsPopArgs(copyList, nCopy){ icUInt32Number nv=(nCopy); size_t ss = os.pStack->size()
; if (nv>ss) return false; icFloatNumber *sv = &(*os.pStack
)[ss-nv]; memcpy((copyList), sv, nv*sizeof(icFloatNumber)); os
.pStack->resize(ss-nv); }
;
502
503 int j;
504 for (j=0; j<nCopy; j++) {
505 OsPushArg(copyList[(j+next)%nCopy]){ icFloatNumber V = (copyList[(j+next)%nCopy]); os.pStack->
push_back(V); }
;
506 }
507 }
508 return true;
509 }
510};
511
512class CIccOpDefTranspose : public IIccOpDef
513{
514public:
515 virtual bool Exec(SIccCalcOp *op, SIccOpState &os)
516 {
517 size_t ss = os.pStack->size();
518 int r=op->data.select.v1+1;
519 int c=op->data.select.v2+1;
520 int nSize = r*c;
521
522 if (nSize>(int)ss)
523 return false;
524
525 if (r>1 && c>1) {
526 int j, k;
527
528 if (os.pScratch->size()<(size_t)nSize)
529 os.pScratch->resize(nSize);
530
531 icFloatNumber *ptrStack = &(*os.pStack)[ss-nSize];
532 icFloatNumber *ptrScratch = &(*os.pScratch)[0];
533 icFloatNumber *start = ptrStack;
534 icFloatNumber *to = ptrScratch;
535
536 for (k=0; k<c; k++) {
537 icFloatNumber *from = start;
538 for (j=0; j<r; j++) {
539 *to++ = *from;
540 from += c;
541 }
542 start++;
543 }
544 memcpy(ptrStack, ptrScratch, nSize*sizeof(icFloatNumber));
545 }
546 return true;
547 }
548};
549
550class CIccOpDefSolve : public IIccOpDef
551{
552public:
553 virtual bool Exec(SIccCalcOp *op, SIccOpState &os)
554 {
555 size_t ss = os.pStack->size();
556 int r=op->data.select.v1+1;
557 int c=op->data.select.v2+1;
558 int nMSize = r*c;
559 int nSize = nMSize + c;
560
561 if (nSize>(int)ss)
562 return false;
563
564 if (r>1 && c>1) {
565
566 if (os.pScratch->size()<(size_t)c)
567 os.pScratch->resize(c);
568
569 icFloatNumber *ptrStack = &(*os.pStack)[ss-nSize];
570 icFloatNumber *x = &(*os.pScratch)[0];
571 icFloatNumber *mtx = ptrStack;
572 icFloatNumber *y = &ptrStack[nMSize];
573
574 bool bResult = false;
575
576 if (g_pIccMatrixSolver) {
577 bResult = g_pIccMatrixSolver->Solve(x, mtx, y, r, c);
578 }
579 if (bResult) {
580 memcpy(ptrStack, x, c*sizeof(icFloatNumber));
581 ptrStack[c] = 1.0;
582 }
583 else {
584 memset(ptrStack, 0, c*sizeof(icFloatNumber));
585 ptrStack[c] = 0.0;
586 }
587 os.pStack->resize(ss-nSize+r+1);
588 }
589 return true;
590 }
591};
592
593class CIccOpDefPi : public IIccOpDef
594{
595public:
596 virtual bool Exec(SIccCalcOp *op, SIccOpState &os)
597 {
598 OsPushArg((icFloatNumber)icPiNum){ icFloatNumber V = ((icFloatNumber)3.14159265358979323846); os
.pStack->push_back(V); }
;
599 return true;
600 }
601};
602
603class CIccOpDefPosInfinity : public IIccOpDef
604{
605public:
606 virtual bool Exec(SIccCalcOp *op, SIccOpState &os)
607 {
608 OsPushArg((icFloatNumber)icPosInfinity){ icFloatNumber V = ((icFloatNumber)(std::numeric_limits<icFloatNumber
>::infinity())); os.pStack->push_back(V); }
;
609 return true;
610 }
611};
612
613class CIccOpDefNegInfinity : public IIccOpDef
614{
615public:
616 virtual bool Exec(SIccCalcOp *op, SIccOpState &os)
617 {
618 OsPushArg((icFloatNumber)icNegInfinity){ icFloatNumber V = ((icFloatNumber)(-std::numeric_limits<
icFloatNumber>::infinity())); os.pStack->push_back(V); }
;
619 return true;
620 }
621};
622
623class CIccOpDefNotANumber : public IIccOpDef
624{
625public:
626 virtual bool Exec(SIccCalcOp *op, SIccOpState &os)
627 {
628 OsPushArg((icFloatNumber)icNotANumber){ icFloatNumber V = ((icFloatNumber)(std::numeric_limits<icFloatNumber
>::quiet_NaN())); os.pStack->push_back(V); }
;
629 return true;
630 }
631};
632
633class CIccOpDefSum : public IIccOpDef
634{
635public:
636 virtual bool Exec(SIccCalcOp *op, SIccOpState &os)
637 {
638 int j, n = op->data.select.v1+2;
639 size_t ss = os.pStack->size();
640 if (n>(int)ss)
641 return false;
642 icFloatNumber *s = &(*os.pStack)[ss-n];
643 if (n==2) {
644 s[0] += s[1];
645 OsShrinkArgs(1){ icUInt32Number nv = (1); size_t ss = os.pStack->size(); if
(nv>ss) return false; os.pStack->resize(ss-nv); }
;
646 }
647 else {
648 for (j=1; j<n; j++) {
649 s[0] += s[j];
650 }
651 OsShrinkArgs(n-1){ icUInt32Number nv = (n-1); size_t ss = os.pStack->size()
; if (nv>ss) return false; os.pStack->resize(ss-nv); }
;
652 }
653 return true;
654 }
655};
656
657class CIccOpDefProduct : public IIccOpDef
658{
659public:
660 virtual bool Exec(SIccCalcOp *op, SIccOpState &os)
661 {
662 int j, n = op->data.select.v1+2;
663 size_t ss = os.pStack->size();
664 if (n>(int)ss)
665 return false;
666 icFloatNumber *s = &(*os.pStack)[ss-n];
667 if (n==2) {
668 s[0] *= s[1];
669 OsShrinkArgs(1){ icUInt32Number nv = (1); size_t ss = os.pStack->size(); if
(nv>ss) return false; os.pStack->resize(ss-nv); }
;
670 }
671 else {
672 for (j=1; j<n; j++) {
673 s[0] *= s[j];
674 }
675 OsShrinkArgs(n-1){ icUInt32Number nv = (n-1); size_t ss = os.pStack->size()
; if (nv>ss) return false; os.pStack->resize(ss-nv); }
;
676 }
677 return true;
678 }
679};
680
681class CIccOpDefMinimum : public IIccOpDef
682{
683public:
684 virtual bool Exec(SIccCalcOp *op, SIccOpState &os)
685 {
686 int j, n = op->data.select.v1+2;
687 size_t ss = os.pStack->size();
688 if (n>(int)ss)
689 return false;
690 icFloatNumber *s = &(*os.pStack)[ss-n];
691 if (n==2) {
692 s[0] = icMin(s[0], s[1]);
693 OsShrinkArgs(1){ icUInt32Number nv = (1); size_t ss = os.pStack->size(); if
(nv>ss) return false; os.pStack->resize(ss-nv); }
;
694 }
695 else {
696 icFloatNumber mv = s[0];
697 for (j=1; j<n; j++) {
698 if (s[j]<mv)
699 mv = s[j];
700 }
701 s[0] = mv;
702 OsShrinkArgs(n-1){ icUInt32Number nv = (n-1); size_t ss = os.pStack->size()
; if (nv>ss) return false; os.pStack->resize(ss-nv); }
;
703 }
704 return true;
705 }
706};
707
708class CIccOpDefMaximum : public IIccOpDef
709{
710public:
711 virtual bool Exec(SIccCalcOp *op, SIccOpState &os)
712 {
713 int j, n = op->data.select.v1+2;
714 size_t ss = os.pStack->size();
715 if (n>(int)ss)
716 return false;
717 icFloatNumber *s = &(*os.pStack)[ss-n];
718 if (n==2) {
719 s[0] = icMax(s[0], s[1]);
720 OsShrinkArgs(1){ icUInt32Number nv = (1); size_t ss = os.pStack->size(); if
(nv>ss) return false; os.pStack->resize(ss-nv); }
;
721 }
722 else {
723 icFloatNumber mv = s[0];
724 for (j=1; j<n; j++) {
725 if (s[j]>mv)
726 mv = s[j];
727 }
728 s[0] = mv;
729 OsShrinkArgs(n-1){ icUInt32Number nv = (n-1); size_t ss = os.pStack->size()
; if (nv>ss) return false; os.pStack->resize(ss-nv); }
;
730 }
731 return true;
732 }
733};
734
735class CIccOpDefAnd : public IIccOpDef
736{
737public:
738 virtual bool Exec(SIccCalcOp *op, SIccOpState &os)
739 {
740 int j, n = op->data.select.v1+2;
741 size_t ss = os.pStack->size();
742 if (n>(int)ss)
743 return false;
744 icFloatNumber *s = &(*os.pStack)[ss-n];
745
746 for (j=0; j<n; j++) {
747 if (s[j]<0.5f)
748 break;
749 }
750 s[0] = j<n ? 0.0f : 1.0f;
751
752 OsShrinkArgs(n-1){ icUInt32Number nv = (n-1); size_t ss = os.pStack->size()
; if (nv>ss) return false; os.pStack->resize(ss-nv); }
;
753 return true;
754 }
755};
756
757class CIccOpDefOr : public IIccOpDef
758{
759public:
760 virtual bool Exec(SIccCalcOp *op, SIccOpState &os)
761 {
762 int j,n = op->data.select.v1+2;
763 size_t ss = os.pStack->size();
764 if (n>(int)ss)
765 return false;
766 icFloatNumber *s = &(*os.pStack)[ss-n];
767
768 for (j=0; j<n; j++) {
769 if (s[j]>=0.5f)
770 break;
771 }
772 s[0] = j<n ? 1.0f : 0.0f;
773
774 OsShrinkArgs(n-1){ icUInt32Number nv = (n-1); size_t ss = os.pStack->size()
; if (nv>ss) return false; os.pStack->resize(ss-nv); }
;
775 return true;
776 }
777};
778
779class CIccOpDefVectorMinimum : public IIccOpDef
780{
781public:
782 virtual bool Exec(SIccCalcOp *op, SIccOpState &os)
783 {
784 int j, n = op->data.select.v1+1;
785 int tn = n*2;
786 size_t ss = os.pStack->size();
787 if (tn>(int)ss)
788 return false;
789 icFloatNumber *s = &(*os.pStack)[ss-tn];
790 for (j=0; j<n; j++) {
791 s[j] = icMin(s[j], s[j+n]);
792 }
793 OsShrinkArgs(n){ icUInt32Number nv = (n); size_t ss = os.pStack->size(); if
(nv>ss) return false; os.pStack->resize(ss-nv); }
;
794 return true;
795 }
796};
797
798class CIccOpDefVectorMaximum : public IIccOpDef
799{
800public:
801 virtual bool Exec(SIccCalcOp *op, SIccOpState &os)
802 {
803 int j, n = op->data.select.v1+1;
804 int tn = n*2;
805 size_t ss = os.pStack->size();
806 if (tn>(int)ss)
807 return false;
808 icFloatNumber *s = &(*os.pStack)[ss-tn];
809 for (j=0; j<n; j++) {
810 s[j] = icMax(s[j], s[j+n]);
811 }
812 OsShrinkArgs(n){ icUInt32Number nv = (n); size_t ss = os.pStack->size(); if
(nv>ss) return false; os.pStack->resize(ss-nv); }
;
813 return true;
814 }
815};
816
817class CIccOpDefVectorAnd : public IIccOpDef
818{
819public:
820 virtual bool Exec(SIccCalcOp *op, SIccOpState &os)
821 {
822 int j, n = op->data.select.v1+1;
823 int tn = n*2;
824 size_t ss = os.pStack->size();
825 if (tn>(int)ss)
826 return false;
827 icFloatNumber *s = &(*os.pStack)[ss-tn];
828 for (j=0; j<n; j++) {
829 s[j] = (s[j]>=0.5f && s[j+n]>=0.5) ? 1.0f : 0.0f;
830 }
831 OsShrinkArgs(n){ icUInt32Number nv = (n); size_t ss = os.pStack->size(); if
(nv>ss) return false; os.pStack->resize(ss-nv); }
;
832 return true;
833 }
834};
835
836class CIccOpDefVectorOr : public IIccOpDef
837{
838public:
839 virtual bool Exec(SIccCalcOp *op, SIccOpState &os)
840 {
841 int j, n = op->data.select.v1+1;
842 int tn = n*2;
843 size_t ss = os.pStack->size();
844 if (tn>(int)ss)
845 return false;
846 icFloatNumber *s = &(*os.pStack)[ss-tn];
847 for (j=0; j<n; j++) {
848 s[j] = (s[j]>=0.5f || s[j+n]>=0.5) ? 1.0f : 0.0f;
849 }
850 OsShrinkArgs(n){ icUInt32Number nv = (n); size_t ss = os.pStack->size(); if
(nv>ss) return false; os.pStack->resize(ss-nv); }
;
851 return true;
852 }
853};
854
855class CIccOpDefAdd : public IIccOpDef
856{
857public:
858 virtual bool Exec(SIccCalcOp *op, SIccOpState &os)
859 {
860 int j, n = op->data.select.v1+1;
861 int tn = n*2;
862 size_t ss = os.pStack->size();
863 if (tn>(int)ss)
864 return false;
865 icFloatNumber *s = &(*os.pStack)[ss-tn];
866 for (j=0; j<n; j++) {
867 s[j] += s[j+n];
868 }
869 OsShrinkArgs(n){ icUInt32Number nv = (n); size_t ss = os.pStack->size(); if
(nv>ss) return false; os.pStack->resize(ss-nv); }
;
870 return true;
871 }
872};
873
874class CIccOpDefSubtract : public IIccOpDef
875{
876public:
877 virtual bool Exec(SIccCalcOp *op, SIccOpState &os)
878 {
879 int j, n = op->data.select.v1+1;
880 int tn = n*2;
881 size_t ss = os.pStack->size();
882 if (tn>(int)ss)
883 return false;
884 icFloatNumber *s = &(*os.pStack)[ss-tn];
885 for (j=0; j<n; j++) {
886 s[j] -= s[j+n];
887 }
888 OsShrinkArgs(n){ icUInt32Number nv = (n); size_t ss = os.pStack->size(); if
(nv>ss) return false; os.pStack->resize(ss-nv); }
;
889 return true;
890 }
891};
892
893class CIccOpDefMultiply : public IIccOpDef
894{
895public:
896 virtual bool Exec(SIccCalcOp *op, SIccOpState &os)
897 {
898 int j, n = op->data.select.v1+1;
899 int tn = n*2;
900 size_t ss = os.pStack->size();
901 if (tn>(int)ss)
902 return false;
903 icFloatNumber *s = &(*os.pStack)[ss-tn];
904 for (j=0; j<n; j++) {
905 s[j] *= s[j+n];
906 }
907 OsShrinkArgs(n){ icUInt32Number nv = (n); size_t ss = os.pStack->size(); if
(nv>ss) return false; os.pStack->resize(ss-nv); }
;
908 return true;
909 }
910};
911
912class CIccOpDefDivide : public IIccOpDef
913{
914public:
915 virtual bool Exec(SIccCalcOp *op, SIccOpState &os)
916 {
917 int j, n = op->data.select.v1+1;
918 int tn = n*2;
919 size_t ss = os.pStack->size();
920 if (tn>(int)ss)
921 return false;
922 icFloatNumber *s = &(*os.pStack)[ss-tn];
923 for (j=0; j<n; j++) {
924 s[j] /= s[j+n];
925 }
926 OsShrinkArgs(n){ icUInt32Number nv = (n); size_t ss = os.pStack->size(); if
(nv>ss) return false; os.pStack->resize(ss-nv); }
;
927 return true;
928 }
929};
930
931class CIccOpDefModulus : public IIccOpDef
932{
933public:
934 virtual bool Exec(SIccCalcOp *op, SIccOpState &os)
935 {
936 int j, n = op->data.select.v1+1;
937 int tn = n*2;
938 size_t ss = os.pStack->size();
939 if (tn>(int)ss)
940 return false;
941 icFloatNumber *s = &(*os.pStack)[ss-tn];
942 for (j=0; j<n; j++) {
943 s[j] = s[j] - (icFloatNumber)((int)(s[j] / s[j+n]))*s[j+n];
944 }
945 OsShrinkArgs(n){ icUInt32Number nv = (n); size_t ss = os.pStack->size(); if
(nv>ss) return false; os.pStack->resize(ss-nv); }
;
946 return true;
947 }
948};
949
950class CIccOpDefGamma : public IIccOpDef
951{
952public:
953 virtual bool Exec(SIccCalcOp *op, SIccOpState &os)
954 {
955 int j, n = op->data.select.v1+1;
956 int tn = n+1;
957 size_t ss = os.pStack->size();
958 if (tn>(int)ss)
959 return false;
960 icFloatNumber *s = &(*os.pStack)[ss-tn];
961 icFloatNumber p = s[n];
962 for (j=0; j<n; j++) {
963 s[j] = (icFloatNumber)pow(s[j], p);
964 }
965 OsShrinkArgs(1){ icUInt32Number nv = (1); size_t ss = os.pStack->size(); if
(nv>ss) return false; os.pStack->resize(ss-nv); }
;
966 return true;
967 }
968};
969
970class CIccOpDefScalarAdd : public IIccOpDef
971{
972public:
973 virtual bool Exec(SIccCalcOp *op, SIccOpState &os)
974 {
975 int j, n = op->data.select.v1+1;
976 int tn = n+1;
977 size_t ss = os.pStack->size();
978 if (tn>(int)ss)
979 return false;
980 icFloatNumber *s = &(*os.pStack)[ss-tn];
981 icFloatNumber p = s[n];
982 for (j=0; j<n; j++) {
983 s[j] = s[j] + p;
984 }
985 OsShrinkArgs(1){ icUInt32Number nv = (1); size_t ss = os.pStack->size(); if
(nv>ss) return false; os.pStack->resize(ss-nv); }
;
986 return true;
987 }
988};
989
990class CIccOpDefScalarSubtract : public IIccOpDef
991{
992public:
993 virtual bool Exec(SIccCalcOp *op, SIccOpState &os)
994 {
995 int j, n = op->data.select.v1+1;
996 int tn = n+1;
997 size_t ss = os.pStack->size();
998 if (tn>(int)ss)
999 return false;
1000 icFloatNumber *s = &(*os.pStack)[ss-tn];
1001 icFloatNumber p = s[n];
1002 for (j=0; j<n; j++) {
1003 s[j] = s[j] - p;
1004 }
1005 OsShrinkArgs(1){ icUInt32Number nv = (1); size_t ss = os.pStack->size(); if
(nv>ss) return false; os.pStack->resize(ss-nv); }
;
1006 return true;
1007 }
1008};
1009
1010class CIccOpDefScalarMultiply : public IIccOpDef
1011{
1012public:
1013 virtual bool Exec(SIccCalcOp *op, SIccOpState &os)
1014 {
1015 int j, n = op->data.select.v1+1;
1016 int tn = n+1;
1017 size_t ss = os.pStack->size();
1018 if (tn>(int)ss)
1019 return false;
1020 icFloatNumber *s = &(*os.pStack)[ss-tn];
1021 icFloatNumber p = s[n];
1022 for (j=0; j<n; j++) {
1023 s[j] = s[j] * p;
1024 }
1025 OsShrinkArgs(1){ icUInt32Number nv = (1); size_t ss = os.pStack->size(); if
(nv>ss) return false; os.pStack->resize(ss-nv); }
;
1026 return true;
1027 }
1028};
1029
1030class CIccOpDefScalarDivide : public IIccOpDef
1031{
1032public:
1033 virtual bool Exec(SIccCalcOp *op, SIccOpState &os)
1034 {
1035 int j, n = op->data.select.v1+1;
1036 int tn = n+1;
1037 size_t ss = os.pStack->size();
1038 if (tn>(int)ss)
1039 return false;
1040 icFloatNumber *s = &(*os.pStack)[ss-tn];
1041 icFloatNumber p = s[n];
1042 for (j=0; j<n; j++) {
1043 s[j] = s[j] / p;
1044 }
1045 OsShrinkArgs(1){ icUInt32Number nv = (1); size_t ss = os.pStack->size(); if
(nv>ss) return false; os.pStack->resize(ss-nv); }
;
1046 return true;
1047 }
1048};
1049
1050class CIccOpDefPow : public IIccOpDef
1051{
1052public:
1053 virtual bool Exec(SIccCalcOp *op, SIccOpState &os)
1054 {
1055 int j, n = op->data.select.v1+1;
1056 int tn = n*2;
1057 size_t ss = os.pStack->size();
1058 if (tn>(int)ss)
1059 return false;
1060 icFloatNumber *s = &(*os.pStack)[ss-tn];
1061 for (j=0; j<n; j++) {
1062 s[j] = (icFloatNumber)pow(s[j], s[j+n]);
1063 }
1064 OsShrinkArgs(n){ icUInt32Number nv = (n); size_t ss = os.pStack->size(); if
(nv>ss) return false; os.pStack->resize(ss-nv); }
;
1065 return true;
1066 }
1067};
1068
1069class CIccOpDefSquare : public IIccOpDef
1070{
1071public:
1072 virtual bool Exec(SIccCalcOp *op, SIccOpState &os)
1073 {
1074 int j, n = op->data.select.v1+1;
1075 icFloatNumber a1;
1076 size_t ss = os.pStack->size();
1077 if (n>(int)ss)
1078 return false;
1079 icFloatNumber *s = &(*os.pStack)[ss-n];
1080 for (j=0; j<n; j++) {
1081 a1 = s[j];
1082 s[j] = a1*a1;
1083 }
1084 return true;
1085 }
1086};
1087
1088class CIccOpDefSquareRoot : public IIccOpDef
1089{
1090public:
1091 virtual bool Exec(SIccCalcOp *op, SIccOpState &os)
1092 {
1093 int j, n = op->data.select.v1+1;
1094 icFloatNumber a1;
1095 size_t ss = os.pStack->size();
1096 if (n>(int)ss)
1097 return false;
1098 icFloatNumber *s = &(*os.pStack)[ss-n];
1099 for (j=0; j<n; j++) {
1100 a1 = s[j];
1101 s[j] = (icFloatNumber)sqrt(a1);
1102 }
1103 return true;
1104 }
1105};
1106
1107class CIccOpDefCube : public IIccOpDef
1108{
1109public:
1110 virtual bool Exec(SIccCalcOp *op, SIccOpState &os)
1111 {
1112 int j, n = op->data.select.v1+1;
1113 icFloatNumber a1;
1114 size_t ss = os.pStack->size();
1115 if (n>(int)ss)
1116 return false;
1117 icFloatNumber *s = &(*os.pStack)[ss-n];
1118 for (j=0; j<n; j++) {
1119 a1 = s[j];
1120 s[j] = a1*a1*a1;
1121 }
1122 return true;
1123 }
1124};
1125
1126class CIccOpDefCubeRoot : public IIccOpDef
1127{
1128public:
1129 virtual bool Exec(SIccCalcOp *op, SIccOpState &os)
1130 {
1131 int j, n = op->data.select.v1+1;
1132 icFloatNumber a1;
1133 size_t ss = os.pStack->size();
1134 if (n>(int)ss)
1135 return false;
1136 icFloatNumber *s = &(*os.pStack)[ss-n];
1137 for (j=0; j<n; j++) {
1138 a1 = s[j];
1139 s[j] = (icFloatNumber)ICC_CBRTF(a1)cbrtf(a1);
1140 }
1141 return true;
1142 }
1143};
1144
1145class CIccOpDefSign : public IIccOpDef
1146{
1147public:
1148 virtual bool Exec(SIccCalcOp *op, SIccOpState &os)
1149 {
1150 int j, n = op->data.select.v1 + 1;
1151 icFloatNumber a1;
1152 size_t ss = os.pStack->size();
1153 if (n > (int)ss)
1154 return false;
1155 icFloatNumber *s = &(*os.pStack)[ss - n];
1156 for (j = 0; j < n; j++) {
1157 a1 = s[j];
1158 s[j] = (icFloatNumber)(a1 < 0 ? -1 : (a1 > 0 ? 1 : 0));
1159 }
1160 return true;
1161 }
1162};
1163
1164class CIccOpDefAbsoluteVal : public IIccOpDef
1165{
1166public:
1167 virtual bool Exec(SIccCalcOp *op, SIccOpState &os)
1168 {
1169 int j, n = op->data.select.v1+1;
1170 icFloatNumber a1;
1171 size_t ss = os.pStack->size();
1172 if (n>(int)ss)
1173 return false;
1174 icFloatNumber *s = &(*os.pStack)[ss-n];
1175 for (j=0; j<n; j++) {
1176 a1 = s[j];
1177 s[j] = (a1 < 0 ? -a1 : a1);
1178 }
1179 return true;
1180 }
1181};
1182
1183class CIccOpDefTruncate : public IIccOpDef
1184{
1185public:
1186 virtual bool Exec(SIccCalcOp *op, SIccOpState &os)
1187 {
1188 int j, n = op->data.select.v1+1;
1189 size_t ss = os.pStack->size();
1190 if (n>(int)ss)
1191 return false;
1192 icFloatNumber *s = &(*os.pStack)[ss-n];
1193 for (j=0; j<n; j++) {
1194 //Casting to an int results in truncation
1195 s[j] = (icFloatNumber)((int)(s[j]));
1196 }
1197 return true;
1198 }
1199};
1200
1201class CIccOpDefFloor : public IIccOpDef
1202{
1203public:
1204 virtual bool Exec(SIccCalcOp *op, SIccOpState &os)
1205 {
1206 int j, n = op->data.select.v1+1;
1207 size_t ss = os.pStack->size();
1208 if (n>(int)ss)
1209 return false;
1210 icFloatNumber *s = &(*os.pStack)[ss-n];
1211 for (j=0; j<n; j++) {
1212 s[j] = (icFloatNumber)floor(s[j]);
1213 }
1214 return true;
1215 }
1216};
1217
1218class CIccOpDefCeiling : public IIccOpDef
1219{
1220public:
1221 virtual bool Exec(SIccCalcOp *op, SIccOpState &os)
1222 {
1223 int j, n = op->data.select.v1+1;
1224 size_t ss = os.pStack->size();
1225 if (n>(int)ss)
1226 return false;
1227 icFloatNumber *s = &(*os.pStack)[ss-n];
1228 for (j=0; j<n; j++) {
1229 s[j] = (icFloatNumber)ceil(s[j]);
1230 }
1231 return true;
1232 }
1233};
1234
1235class CIccOpDefRound : public IIccOpDef
1236{
1237public:
1238 virtual bool Exec(SIccCalcOp *op, SIccOpState &os)
1239 {
1240 int j, n = op->data.select.v1+1;
1241 size_t ss = os.pStack->size();
1242 if (n>(int)ss)
1243 return false;
1244 icFloatNumber *s = &(*os.pStack)[ss-n];
1245 for (j=0; j<n; j++) {
1246 if (s[j]<0.0)
1247 s[j] = icFloatNumber((int)(s[j]-0.5));
1248 else
1249 s[j] = icFloatNumber((int)(s[j]+0.5));
1250 }
1251 return true;
1252 }
1253};
1254
1255class CIccOpDefExp : public IIccOpDef
1256{
1257public:
1258 virtual bool Exec(SIccCalcOp *op, SIccOpState &os)
1259 {
1260 int j, n = op->data.select.v1+1;
1261 icFloatNumber a1;
1262 size_t ss = os.pStack->size();
1263 if (n>(int)ss)
1264 return false;
1265 icFloatNumber *s = &(*os.pStack)[ss-n];
1266 for (j=0; j<n; j++) {
1267 a1 = s[j];
1268 s[j] = (icFloatNumber)exp(a1);
1269 }
1270 return true;
1271 }
1272};
1273
1274class CIccOpDefLogrithm : public IIccOpDef
1275{
1276public:
1277 virtual bool Exec(SIccCalcOp *op, SIccOpState &os)
1278 {
1279 int j, n = op->data.select.v1+1;
1280 icFloatNumber a1;
1281 size_t ss = os.pStack->size();
1282 if (n>(int)ss)
1283 return false;
1284 icFloatNumber *s = &(*os.pStack)[ss-n];
1285 for (j=0; j<n; j++) {
1286 a1 = s[j];
1287 s[j] = (icFloatNumber)log10(a1);
1288 }
1289 return true;
1290 }
1291};
1292
1293class CIccOpDefNaturalLog : public IIccOpDef
1294{
1295public:
1296 virtual bool Exec(SIccCalcOp *op, SIccOpState &os)
1297 {
1298 int j, n = op->data.select.v1+1;
1299 icFloatNumber a1;
1300 size_t ss = os.pStack->size();
1301 if (n>(int)ss)
1302 return false;
1303 icFloatNumber *s = &(*os.pStack)[ss-n];
1304 for (j=0; j<n; j++) {
1305 a1 = s[j];
1306 s[j] = (icFloatNumber)log(a1);
1307 }
1308 return true;
1309 }
1310};
1311
1312class CIccOpDefSine : public IIccOpDef
1313{
1314public:
1315 virtual bool Exec(SIccCalcOp *op, SIccOpState &os)
1316 {
1317 int j, n = op->data.select.v1+1;
1318 icFloatNumber a1;
1319 size_t ss = os.pStack->size();
1320 if (n>(int)ss)
1321 return false;
1322 icFloatNumber *s = &(*os.pStack)[ss-n];
1323 for (j=0; j<n; j++) {
1324 a1 = s[j];
1325 s[j] = (icFloatNumber)sin(a1);
1326 }
1327 return true;
1328 }
1329};
1330
1331class CIccOpDefCosine : public IIccOpDef
1332{
1333public:
1334 virtual bool Exec(SIccCalcOp *op, SIccOpState &os)
1335 {
1336 int j, n = op->data.select.v1+1;
1337 icFloatNumber a1;
1338 size_t ss = os.pStack->size();
1339 if (n>(int)ss)
1340 return false;
1341 icFloatNumber *s = &(*os.pStack)[ss-n];
1342 for (j=0; j<n; j++) {
1343 a1 = s[j];
1344 s[j] = (icFloatNumber)cos(a1);
1345 }
1346 return true;
1347 }
1348};
1349
1350class CIccOpDefTangent : public IIccOpDef
1351{
1352public:
1353 virtual bool Exec(SIccCalcOp *op, SIccOpState &os)
1354 {
1355 int j, n = op->data.select.v1+1;
1356 icFloatNumber a1;
1357 size_t ss = os.pStack->size();
1358 if (n>(int)ss)
1359 return false;
1360 icFloatNumber *s = &(*os.pStack)[ss-n];
1361 for (j=0; j<n; j++) {
1362 a1 = s[j];
1363 s[j] = (icFloatNumber)tan(a1);
1364 }
1365 return true;
1366 }
1367};
1368
1369class CIccOpDefArcSine : public IIccOpDef
1370{
1371public:
1372 virtual bool Exec(SIccCalcOp *op, SIccOpState &os)
1373 {
1374 int j, n = op->data.select.v1+1;
1375 icFloatNumber a1;
1376 size_t ss = os.pStack->size();
1377 if (n>(int)ss)
1378 return false;
1379 icFloatNumber *s = &(*os.pStack)[ss-n];
1380 for (j=0; j<n; j++) {
1381 a1 = s[j];
1382 s[j] = (icFloatNumber)asin(a1);
1383 }
1384 return true;
1385 }
1386};
1387
1388class CIccOpDefArcCosine : public IIccOpDef
1389{
1390public:
1391 virtual bool Exec(SIccCalcOp *op, SIccOpState &os)
1392 {
1393 int j, n = op->data.select.v1+1;
1394 icFloatNumber a1;
1395 size_t ss = os.pStack->size();
1396 if (n>(int)ss)
1397 return false;
1398 icFloatNumber *s = &(*os.pStack)[ss-n];
1399 for (j=0; j<n; j++) {
1400 a1 = s[j];
1401 s[j] = (icFloatNumber)acos(a1);
1402 }
1403 return true;
1404 }
1405};
1406
1407class CIccOpDefArcTangent : public IIccOpDef
1408{
1409public:
1410 virtual bool Exec(SIccCalcOp *op, SIccOpState &os)
1411 {
1412 int j, n = op->data.select.v1+1;
1413 icFloatNumber a1;
1414 size_t ss = os.pStack->size();
1415 if (n>(int)ss)
1416 return false;
1417 icFloatNumber *s = &(*os.pStack)[ss-n];
1418 for (j=0; j<n; j++) {
1419 a1 = s[j];
1420 s[j] = (icFloatNumber)atan(a1);
1421 }
1422 return true;
1423 }
1424};
1425
1426class CIccOpDefArcTan2 : public IIccOpDef
1427{
1428public:
1429 virtual bool Exec(SIccCalcOp *op, SIccOpState &os)
1430 {
1431 int j, n = op->data.select.v1+1;
1432 icFloatNumber a1, a2;
1433 int tn = n*2;
1434 size_t ss = os.pStack->size();
1435 if (tn>(int)ss)
1436 return false;
1437 icFloatNumber *s = &(*os.pStack)[ss-tn];
1438 for (j=0; j<n; j++) {
1439 a1 = s[j];
1440 a2 = s[j+n];
1441 s[j] = (icFloatNumber)atan2(a2, a1);
1442 }
1443 OsShrinkArgs(n){ icUInt32Number nv = (n); size_t ss = os.pStack->size(); if
(nv>ss) return false; os.pStack->resize(ss-nv); }
;
1444 return true;
1445 }
1446};
1447
1448class CIccOpDefCartesianToPolar : public IIccOpDef
1449{
1450public:
1451 virtual bool Exec(SIccCalcOp *op, SIccOpState &os)
1452 {
1453 int j, n = op->data.select.v1+1;
1454 icFloatNumber a1, a2;
1455 int tn = n*2;
1456 size_t ss = os.pStack->size();
1457 if (tn>(int)ss)
1458 return false;
1459 icFloatNumber *s = &(*os.pStack)[ss-tn];
1460 for (j=0; j<n; j++) {
1461 a1 = s[j];
1462 a2 = s[j+n];
1463 s[j] = (icFloatNumber)sqrt(a2*a2 + a1*a1);
1464 icFloatNumber h = (icFloatNumber)atan2(a2, a1) * 180.0f / (icFloatNumber)icPiNum3.14159265358979323846;
1465 if (h<0.0f)
1466 h += 360.0f;
1467 s[j+n] = h;
1468 }
1469 return true;
1470 }
1471};
1472
1473class CIccOpDefPolarToCartesian : public IIccOpDef
1474{
1475public:
1476 virtual bool Exec(SIccCalcOp *op, SIccOpState &os)
1477 {
1478 int j, n = op->data.select.v1+1;
1479 icFloatNumber a1, a2;
1480 int tn = n*2;
1481 size_t ss = os.pStack->size();
1482 if (tn>(int)ss)
1483 return false;
1484 icFloatNumber *s = &(*os.pStack)[ss-tn];
1485 for (j=0; j<n; j++) {
1486 a1 = s[j];
1487 a2 = s[j+n] * (icFloatNumber)icPiNum3.14159265358979323846 / 180.0f;
1488
1489 s[j] = a1 * (icFloatNumber)cos(a2);
1490 s[j+n] = a1 * (icFloatNumber)sin(a2);
1491 }
1492 return true;
1493 }
1494};
1495
1496class CIccOpDefLessThan : public IIccOpDef
1497{
1498public:
1499 virtual bool Exec(SIccCalcOp *op, SIccOpState &os)
1500 {
1501 int j, n =op->data.select.v1+1;
1502 icFloatNumber a1, a2;
1503 int tn = n*2;
1504 size_t ss = os.pStack->size();
1505 if (tn>(int)ss)
1506 return false;
1507 icFloatNumber *s = &(*os.pStack)[ss-tn];
1508 for (j=0; j<n; j++) {
1509 a1 = s[j];
1510 a2 = s[j+n];
1511 s[j] = (a1 < a2 ? (icFloatNumber)1.0 : (icFloatNumber)0.0);
1512 }
1513 OsShrinkArgs(n){ icUInt32Number nv = (n); size_t ss = os.pStack->size(); if
(nv>ss) return false; os.pStack->resize(ss-nv); }
;
1514 return true;
1515 }
1516};
1517
1518class CIccOpDefRealNumber : public IIccOpDef
1519{
1520public:
1521 virtual bool Exec(SIccCalcOp *op, SIccOpState &os)
1522 {
1523 int j, n = op->data.select.v1+1;
1524 icFloatNumber a1;
1525 size_t ss = os.pStack->size();
1526 if (n>(int)ss)
1527 return false;
1528 icFloatNumber *s = &(*os.pStack)[ss-n];
1529 icFloatNumber nan = icNotANumber(std::numeric_limits<icFloatNumber>::quiet_NaN());
1530 for (j=0; j<n; j++) {
1531 a1 = s[j];
1532 if (a1==icPosInfinity(std::numeric_limits<icFloatNumber>::infinity()) || a1==icNegInfinity(-std::numeric_limits<icFloatNumber>::infinity()) || !memcmp(&a1,&nan, sizeof(nan)))
1533 s[j] = 0.0;
1534 else
1535 s[j] = 1.0;
1536 }
1537 return true;
1538 }
1539};
1540
1541class CIccOpDefLessThanEqual : public IIccOpDef
1542{
1543public:
1544 virtual bool Exec(SIccCalcOp *op, SIccOpState &os)
1545 {
1546 int j, n = op->data.select.v1+1;
1547 icFloatNumber a1, a2;
1548 int tn = n*2;
1549 size_t ss = os.pStack->size();
1550 if (tn>(int)ss)
1551 return false;
1552 icFloatNumber *s = &(*os.pStack)[ss-tn];
1553 for (j=0; j<n; j++) {
1554 a1 = s[j];
1555 a2 = s[j+n];
1556 s[j] = (a1 <= a2 ? (icFloatNumber)1.0 : (icFloatNumber)0.0);
1557 }
1558 OsShrinkArgs(n){ icUInt32Number nv = (n); size_t ss = os.pStack->size(); if
(nv>ss) return false; os.pStack->resize(ss-nv); }
;
1559 return true;
1560 }
1561};
1562
1563class CIccOpDefEqual : public IIccOpDef
1564{
1565public:
1566 virtual bool Exec(SIccCalcOp *op, SIccOpState &os)
1567 {
1568 int j, n = op->data.select.v1+1;
1569 icFloatNumber a1, a2;
1570 int tn = n*2;
1571 size_t ss = os.pStack->size();
1572 if (tn>(int)ss)
1573 return false;
1574 icFloatNumber nan = icNotANumber(std::numeric_limits<icFloatNumber>::quiet_NaN());
1575 icFloatNumber *s = &(*os.pStack)[ss-tn];
1576 for (j=0; j<n; j++) {
1577 a1 = s[j];
1578 a2 = s[j+n];
1579 s[j] = (a1 == a2 ?
1580 (icFloatNumber)1.0 :
1581 ((!memcmp(&a1, &nan, sizeof(icFloatNumber)) && !memcmp(&a1, &a2, sizeof(a1))) ?
1582 (icFloatNumber)1.0 :
1583 (icFloatNumber)0.0));
1584 }
1585 OsShrinkArgs(n){ icUInt32Number nv = (n); size_t ss = os.pStack->size(); if
(nv>ss) return false; os.pStack->resize(ss-nv); }
;
1586 return true;
1587 }
1588};
1589
1590class CIccOpDefNear : public IIccOpDef
1591{
1592public:
1593 virtual bool Exec(SIccCalcOp *op, SIccOpState &os)
1594 {
1595 int j, n = op->data.select.v1+1;
1596 icFloatNumber a1, a2;
1597 int tn = n*2;
1598 size_t ss = os.pStack->size();
1599 if (tn>(int)ss)
1600 return false;
1601 icFloatNumber *s = &(*os.pStack)[ss-tn];
1602 for (j=0; j<n; j++) {
1603 a1 = s[j];
1604 a2 = s[j+n];
1605 s[j] = (fabs(a1-a2)<1.0e-5 ? (icFloatNumber)1.0 : (icFloatNumber)0.0);
1606 }
1607 OsShrinkArgs(n){ icUInt32Number nv = (n); size_t ss = os.pStack->size(); if
(nv>ss) return false; os.pStack->resize(ss-nv); }
;
1608 return true;
1609 }
1610};
1611
1612class CIccOpDefGreaterThanEqual : public IIccOpDef
1613{
1614public:
1615 virtual bool Exec(SIccCalcOp *op, SIccOpState &os)
1616 {
1617 int j, n = op->data.select.v1+1;
1618 icFloatNumber a1, a2;
1619 int tn = n*2;
1620 size_t ss = os.pStack->size();
1621 if (tn>(int)ss)
1622 return false;
1623 icFloatNumber *s = &(*os.pStack)[ss-tn];
1624 for (j=0; j<n; j++) {
1625 a1 = s[j];
1626 a2 = s[j+n];
1627 s[j] = (a1 >= a2 ? (icFloatNumber)1.0 : (icFloatNumber)0.0);
1628 }
1629 OsShrinkArgs(n){ icUInt32Number nv = (n); size_t ss = os.pStack->size(); if
(nv>ss) return false; os.pStack->resize(ss-nv); }
;
1630 return true;
1631 }
1632};
1633
1634class CIccOpDefGreaterThan : public IIccOpDef
1635{
1636public:
1637 virtual bool Exec(SIccCalcOp *op, SIccOpState &os)
1638 {
1639 int j, n = op->data.select.v1+1;
1640 icFloatNumber a1, a2;
1641 int tn = n*2;
1642 size_t ss = os.pStack->size();
1643 if (tn>(int)ss)
1644 return false;
1645 icFloatNumber *s = &(*os.pStack)[ss-tn];
1646 for (j=0; j<n; j++) {
1647 a1 = s[j];
1648 a2 = s[j+n];
1649 s[j] = (a1 > a2 ? (icFloatNumber)1.0 : (icFloatNumber)0.0);
1650 }
1651 OsShrinkArgs(n){ icUInt32Number nv = (n); size_t ss = os.pStack->size(); if
(nv>ss) return false; os.pStack->resize(ss-nv); }
;
1652 return true;
1653 }
1654};
1655
1656class CIccOpDefNot : public IIccOpDef
1657{
1658public:
1659 virtual bool Exec(SIccCalcOp *op, SIccOpState &os)
1660 {
1661 int j, n = op->data.select.v1+1;
1662 icFloatNumber a1;
1663 size_t ss = os.pStack->size();
1664 if (n>(int)ss)
1665 return false;
1666 icFloatNumber *s = &(*os.pStack)[ss-n];
1667 for (j=0; j<n; j++) {
1668 a1 = s[j];
1669 s[j] = (a1 >= (icFloatNumber)0.5 ? (icFloatNumber)0.0 : (icFloatNumber)1.0);
1670 }
1671 return true;
1672 }
1673};
1674
1675class CIccOpDefNeg : public IIccOpDef
1676{
1677public:
1678 virtual bool Exec(SIccCalcOp *op, SIccOpState &os)
1679 {
1680 int j, n = op->data.select.v1+1;
1681 icFloatNumber a1;
1682 size_t ss = os.pStack->size();
1683 if (n>(int)ss)
1684 return false;
1685 icFloatNumber *s = &(*os.pStack)[ss-n];
1686 for (j=0; j<n; j++) {
1687 a1 = s[j];
1688 s[j] = -a1;
1689 }
1690 return true;
1691 }
1692};
1693
1694class CIccOpDefToLab : public IIccOpDef
1695{
1696public:
1697 virtual bool Exec(SIccCalcOp *op, SIccOpState &os)
1698 {
1699 int j, n = op->data.select.v1+1;
1700 int n2 = n+n;
1701 int tn = n*3;
1702 icFloatNumber a1, a2, a3;
1703 size_t ss = os.pStack->size();
1704 if (tn>(int)ss)
1705 return false;
1706 icFloatNumber *s = &(*os.pStack)[ss-tn];
1707 for (j=0; j<n; j++) {
1708 a1 = icCubeth(s[j]);
1709 a2 = icCubeth(s[j+n]);
1710 a3 = icCubeth(s[j+n2]);
1711
1712 s[j] = (icFloatNumber)(116.0 * a2 - 16.0);
1713 s[j+n] = (icFloatNumber)(500.0 * (a1 - a2));
1714 s[j+n2] = (icFloatNumber)(200.0 * (a2 - a3));
1715 }
1716 return true;
1717 }
1718};
1719
1720class CIccOpDefFromLab : public IIccOpDef
1721{
1722public:
1723 virtual bool Exec(SIccCalcOp *op, SIccOpState &os)
1724 {
1725 int j, n = op->data.select.v1+1;
1726 int n2 = n+n;
1727 int tn = n*3;
1728 icFloatNumber a1, a2, a3;
1729 size_t ss = os.pStack->size();
1730 if (tn>(int)ss)
1731 return false;
1732 icFloatNumber fy, *s = &(*os.pStack)[ss-tn];
1733 for (j=0; j<n; j++) {
1734 a1 = s[j];
1735 a2 = s[j+n];
1736 a3 = s[j+n2];
1737
1738 fy = (icFloatNumber)((a1 + 16.0f) / 116.0f);
1739
1740 s[j] = icICubeth((icFloatNumber)(a2/500.0 + fy));
1741 s[j+n] = icICubeth(fy);
1742 s[j+n2] = icICubeth((icFloatNumber)(fy - a3/200.0));
1743 }
1744 return true;
1745 }
1746};
1747
1748
1749
1750/**
1751******************************************************************************
1752* Name: SIccCalcOp::Describe
1753*
1754* Purpose:
1755*
1756* Args:
1757*
1758* Return:
1759******************************************************************************/
1760void SIccCalcOp::Describe(std::string &desc)
1761{
1762 char buf[300];
1763 if (sig==icSigDataOp) {
1764 sprintf(buf, "%.8g", data.num);
1765 desc = buf;
1766 return;
1767 }
1768
1769 char name[10];
1770 int i;
1771
1772 icGetSig(name, sig, false);
1773 name[5]=0;
1774 for (i=4; i>0; i--)
1775 if (name[i]==' ')
1776 name[i] = 0;
1777 if (!name[1])
1778 name[1] = '?';
1779 desc = &name[1];
1780
1781 switch (sig) {
1782 case icSigInputChanOp:
1783 case icSigOutputChanOp:
1784 case icSigTempGetChanOp:
1785 case icSigTempPutChanOp:
1786 case icSigTempSaveChanOp:
1787 if (!data.select.v2)
1788 sprintf(buf, "[%d]", data.select.v1);
1789 else
1790 sprintf(buf, "[%d,%d]", data.select.v1, data.select.v2+1);
1791 desc += buf;
1792 break;
1793
1794 case icSigEnvVarOp:
1795 {
1796 char varName[10];
1797 icGetSigStr(varName, (icSignature)data.size);
1798 int l=(int)strlen(varName);
1799 if (l==9) { //Remove h at end
1800 varName[8]=0;
1801 }
1802 else {
1803 for (l--; l>0; l--) {
1804 if (varName[l]!=' ')
1805 break;
1806 varName[l]=0;
1807 }
1808 }
1809 sprintf(buf, "(%s)", varName);
1810 desc += buf;
1811 }
1812 break;
1813
1814 case icSigApplyCurvesOp:
1815 case icSigApplyMatrixOp:
1816 case icSigApplyCLutOp:
1817 case icSigApplyTintOp:
1818 case icSigApplyToJabOp:
1819 case icSigApplyFromJabOp:
1820 case icSigApplyCalcOp:
1821 case icSigApplyElemOp:
1822 sprintf(buf, "(%d)", data.select.v1);
1823 desc += buf;
1824 break;
1825
1826 case icSigPopOp:
1827 sprintf(buf, "(%d)", data.select.v1+1);
1828 desc += buf;
1829 break;
1830
1831 case icSigSolveOp:
1832 case icSigTransposeOp:
1833 sprintf(buf, "(%d,%d)", data.select.v1+1, data.select.v2+1);
1834 desc += buf;
1835 break;
1836
1837 case icSigRotateLeftOp:
1838 case icSigRotateRightOp:
1839 sprintf(buf, "(%d,%d)", data.select.v1, data.select.v2);
1840 break;
1841
1842 case icSigCopyOp:
1843 case icSigPositionDupOp:
1844 if (!data.select.v2) {
1845 if (data.select.v1) {
1846 sprintf(buf, "(%d)", data.select.v1+1);
1847 desc += buf;
1848 }
1849 }
1850 else {
1851 sprintf(buf, "(%d,%d)", data.select.v1+1, data.select.v2+1);
1852 desc += buf;
1853 }
1854 break;
1855
1856 case icSigFlipOp:
1857 case icSigSumOp:
1858 case icSigProductOp:
1859 case icSigMinimumOp:
1860 case icSigMaximumOp:
1861 case icSigAndOp:
1862 case icSigOrOp:
1863 if (data.select.v1) {
1864 sprintf(buf, "(%d)", data.select.v1+2);
1865 desc += buf;
1866 }
1867 break;
1868
1869 case icSigGammaOp:
1870 case icSigScalarAddOp:
1871 case icSigScalarSubtractOp:
1872 case icSigScalarMultiplyOp:
1873 case icSigScalarDivideOp:
1874 case icSigAddOp:
1875 case icSigSubtractOp:
1876 case icSigMultiplyOp:
1877 case icSigDivideOp:
1878 case icSigModulusOp:
1879 case icSigPowOp:
1880 case icSigArcTan2Op:
1881 case icSigLessThanOp:
1882 case icSigLessThanEqualOp:
1883 case icSigEqualOp:
1884 case icSigNearOp:
1885 case icSigGreaterThanEqualOp:
1886 case icSigGreaterThanOp:
1887 case icSigSquareOp:
1888 case icSigSquareRootOp:
1889 case icSigCubeOp:
1890 case icSigCubeRootOp:
1891 case icSigSignOp:
1892 case icSigAbsoluteValOp:
1893 case icSigTruncateOp:
1894 case icSigFloorOp:
1895 case icSigCeilingOp:
1896 case icSigRoundOp:
1897 case icSigRealNumberOp:
1898 case icSigNegOp:
1899 case icSigExpOp:
1900 case icSigLogrithmOp:
1901 case icSigNaturalLogOp:
1902 case icSigSineOp:
1903 case icSigCosineOp:
1904 case icSigTangentOp:
1905 case icSigArcSineOp:
1906 case icSigArcCosineOp:
1907 case icSigArcTangentOp:
1908 case icSigCartesianToPolarOp:
1909 case icSigPolarToCartesianOp:
1910 case icSigNotOp:
1911 case icSigToLabOp:
1912 case icSigToXYZOp:
1913 case icSigVectorMinimumOp:
1914 case icSigVectorMaximumOp:
1915 case icSigVectorAndOp:
1916 case icSigVectorOrOp:
1917 if (data.select.v1) {
1918 sprintf(buf, "[%d]", data.select.v1+1);
1919 desc += buf;
1920 }
1921 break;
1922 }
1923}
1924
1925typedef std::map<icSigCalcOp, IIccOpDef*> icCalcOpMap;
1926
1927class CIccCalcOpMgr
1928{
1929 CIccCalcOpMgr();
1930 static CIccCalcOpMgr* m_inst;
1931public:
1932 static CIccCalcOpMgr* GetInstance();
1933 static IIccOpDef *getOpDef(icSigCalcOp opSig);
1934
1935protected:
1936 icCalcOpMap m_map;
1937 CIccOpDefInvalid m_invalid;
1938};
1939CIccCalcOpMgr *CIccCalcOpMgr::m_inst = NULL__null;
1940
1941CIccCalcOpMgr::CIccCalcOpMgr()
1942{
1943 m_map[icSigDataOp] = new CIccOpDefData();
1944 m_map[icSigInputChanOp] = new CIccOpDefInputChan();
1945 m_map[icSigOutputChanOp] = new CIccOpDefOutputChan();
1946 m_map[icSigTempGetChanOp] = new CIccOpDefTempGetChan();
1947 m_map[icSigTempPutChanOp] = new CIccOpDefTempPutChan();
1948 m_map[icSigTempSaveChanOp] = new CIccOpDefTempSaveChan();
1949 m_map[icSigEnvVarOp] = new CIccOpDefEnvVar();
1950 m_map[icSigApplyCurvesOp] = new CIccOpDefSubElement();
1951 m_map[icSigApplyMatrixOp] = new CIccOpDefSubElement();
1952 m_map[icSigApplyCLutOp] = new CIccOpDefSubElement();
1953 m_map[icSigApplyTintOp] = new CIccOpDefSubElement();
1954 m_map[icSigApplyToJabOp] = new CIccOpDefSubElement();
1955 m_map[icSigApplyFromJabOp] = new CIccOpDefSubElement();
1956 m_map[icSigApplyCalcOp] = new CIccOpDefSubElement();
1957 m_map[icSigApplyElemOp] = new CIccOpDefSubElement();
1958 m_map[icSigCopyOp] = new CIccOpDefCopy();
1959 m_map[icSigRotateLeftOp] = new CIccOpDefRotateLeft();
1960 m_map[icSigRotateRightOp] = new CIccOpDefRotateRight();
1961 m_map[icSigPositionDupOp] = new CIccOpDefPositionDup();
1962 m_map[icSigFlipOp] = new CIccOpDefFlip();
1963 m_map[icSigPopOp] = new CIccOpDefPop();
1964 m_map[icSigSolveOp] = new CIccOpDefSolve();
1965 m_map[icSigTransposeOp] = new CIccOpDefTranspose();
1966 m_map[icSigPiOp] = new CIccOpDefPi();
1967 m_map[icSigPosInfinityOp] = new CIccOpDefPosInfinity();
1968 m_map[icSigNegInfinityOp] = new CIccOpDefNegInfinity();
1969 m_map[icSigNotaNumberOp] = new CIccOpDefNotANumber();
1970 m_map[icSigSumOp] = new CIccOpDefSum();
1971 m_map[icSigProductOp] = new CIccOpDefProduct();
1972 m_map[icSigAddOp] = new CIccOpDefAdd();
1973 m_map[icSigSubtractOp] = new CIccOpDefSubtract();
1974 m_map[icSigMultiplyOp] = new CIccOpDefMultiply();
1975 m_map[icSigDivideOp] = new CIccOpDefDivide();
1976 m_map[icSigModulusOp] = new CIccOpDefModulus();
1977 m_map[icSigPowOp] = new CIccOpDefPow();
1978 m_map[icSigGammaOp] = new CIccOpDefGamma();
1979 m_map[icSigScalarAddOp] = new CIccOpDefScalarAdd();
1980 m_map[icSigScalarSubtractOp] = new CIccOpDefScalarSubtract();
1981 m_map[icSigScalarMultiplyOp] = new CIccOpDefScalarMultiply();
1982 m_map[icSigScalarDivideOp] = new CIccOpDefScalarDivide();
1983 m_map[icSigSquareOp] = new CIccOpDefSquare();
1984 m_map[icSigSquareRootOp] = new CIccOpDefSquareRoot();
1985 m_map[icSigCubeOp] = new CIccOpDefCube();
1986 m_map[icSigCubeRootOp] = new CIccOpDefCubeRoot();
1987 m_map[icSigSignOp] = new CIccOpDefSign();
1988 m_map[icSigAbsoluteValOp] = new CIccOpDefAbsoluteVal();
1989 m_map[icSigTruncateOp] = new CIccOpDefTruncate();
1990 m_map[icSigFloorOp] = new CIccOpDefFloor();
1991 m_map[icSigCeilingOp] = new CIccOpDefCeiling();
1992 m_map[icSigRoundOp] = new CIccOpDefRound();
1993 m_map[icSigNegOp] = new CIccOpDefNeg();
1994 m_map[icSigExpOp] = new CIccOpDefExp();
1995 m_map[icSigLogrithmOp] = new CIccOpDefLogrithm();
1996 m_map[icSigNaturalLogOp] = new CIccOpDefNaturalLog();
1997 m_map[icSigSineOp] = new CIccOpDefSine();
1998 m_map[icSigCosineOp] = new CIccOpDefCosine();
1999 m_map[icSigTangentOp] = new CIccOpDefTangent();
2000 m_map[icSigArcSineOp] = new CIccOpDefArcSine();
2001 m_map[icSigArcCosineOp] = new CIccOpDefArcCosine();
2002 m_map[icSigArcTangentOp] = new CIccOpDefArcTangent();
2003 m_map[icSigArcTan2Op] = new CIccOpDefArcTan2();
2004 m_map[icSigCartesianToPolarOp] = new CIccOpDefCartesianToPolar();
2005 m_map[icSigPolarToCartesianOp] = new CIccOpDefPolarToCartesian();
2006 m_map[icSigVectorMinimumOp] = new CIccOpDefVectorMinimum();
2007 m_map[icSigVectorMaximumOp] = new CIccOpDefVectorMaximum();
2008 m_map[icSigVectorAndOp] = new CIccOpDefVectorAnd();
2009 m_map[icSigVectorOrOp] = new CIccOpDefVectorOr();
2010 m_map[icSigMinimumOp] = new CIccOpDefMinimum();
2011 m_map[icSigMaximumOp] = new CIccOpDefMaximum();
2012 m_map[icSigRealNumberOp] = new CIccOpDefRealNumber();
2013 m_map[icSigLessThanOp] = new CIccOpDefLessThan();
2014 m_map[icSigLessThanEqualOp] = new CIccOpDefLessThanEqual();
2015 m_map[icSigEqualOp] = new CIccOpDefEqual();
2016 m_map[icSigNearOp] = new CIccOpDefNear();
2017 m_map[icSigGreaterThanEqualOp] = new CIccOpDefGreaterThanEqual();
2018 m_map[icSigGreaterThanOp] = new CIccOpDefGreaterThan();
2019 m_map[icSigAndOp] = new CIccOpDefAnd();
2020 m_map[icSigOrOp] = new CIccOpDefOr();
2021 m_map[icSigNotOp] = new CIccOpDefNot();
2022 m_map[icSigToLabOp] = new CIccOpDefToLab();
2023 m_map[icSigToXYZOp] = new CIccOpDefFromLab();
2024}
2025
2026CIccCalcOpMgr *CIccCalcOpMgr::GetInstance()
2027{
2028 if (!m_inst)
2029 m_inst = new CIccCalcOpMgr();
2030 return m_inst;
2031}
2032
2033
2034/**
2035******************************************************************************
2036* Name: SIccCalcOp::IsValidOp
2037*
2038* Purpose:
2039*
2040* Args:
2041*
2042* Return:
2043******************************************************************************/
2044bool SIccCalcOp::IsValidOp(icSigCalcOp sig)
2045{
2046 switch (sig) {
2047 case icSigDataOp:
2048 case icSigInputChanOp:
2049 case icSigOutputChanOp:
2050 case icSigTempGetChanOp:
2051 case icSigTempPutChanOp:
2052 case icSigTempSaveChanOp:
2053 case icSigEnvVarOp:
2054 case icSigApplyCurvesOp:
2055 case icSigApplyMatrixOp:
2056 case icSigApplyCLutOp:
2057 case icSigApplyTintOp:
2058 case icSigApplyToJabOp:
2059 case icSigApplyFromJabOp:
2060 case icSigApplyCalcOp:
2061 case icSigApplyElemOp:
2062 case icSigCopyOp:
2063 case icSigRotateLeftOp:
2064 case icSigRotateRightOp:
2065 case icSigPositionDupOp:
2066 case icSigFlipOp:
2067 case icSigPopOp:
2068 case icSigSolveOp:
2069 case icSigTransposeOp:
2070 case icSigPiOp:
2071 case icSigPosInfinityOp:
2072 case icSigNegInfinityOp:
2073 case icSigNotaNumberOp:
2074 case icSigSumOp:
2075 case icSigProductOp:
2076 case icSigAddOp:
2077 case icSigSubtractOp:
2078 case icSigMultiplyOp:
2079 case icSigDivideOp:
2080 case icSigModulusOp:
2081 case icSigPowOp:
2082 case icSigGammaOp:
2083 case icSigScalarAddOp:
2084 case icSigScalarSubtractOp:
2085 case icSigScalarMultiplyOp:
2086 case icSigScalarDivideOp:
2087 case icSigSquareOp:
2088 case icSigSquareRootOp:
2089 case icSigCubeOp:
2090 case icSigCubeRootOp:
2091 case icSigSignOp:
2092 case icSigAbsoluteValOp:
2093 case icSigTruncateOp:
2094 case icSigFloorOp:
2095 case icSigCeilingOp:
2096 case icSigRoundOp:
2097 case icSigNegOp:
2098 case icSigExpOp:
2099 case icSigLogrithmOp:
2100 case icSigNaturalLogOp:
2101 case icSigSineOp:
2102 case icSigCosineOp:
2103 case icSigTangentOp:
2104 case icSigArcSineOp:
2105 case icSigArcCosineOp:
2106 case icSigArcTangentOp:
2107 case icSigArcTan2Op:
2108 case icSigCartesianToPolarOp:
2109 case icSigPolarToCartesianOp:
2110 case icSigVectorMinimumOp:
2111 case icSigVectorMaximumOp:
2112 case icSigVectorAndOp:
2113 case icSigVectorOrOp:
2114 case icSigMinimumOp:
2115 case icSigMaximumOp:
2116 case icSigRealNumberOp:
2117 case icSigLessThanOp:
2118 case icSigLessThanEqualOp:
2119 case icSigEqualOp:
2120 case icSigNearOp:
2121 case icSigGreaterThanEqualOp:
2122 case icSigGreaterThanOp:
2123 case icSigAndOp:
2124 case icSigOrOp:
2125 case icSigNotOp:
2126 case icSigToLabOp:
2127 case icSigToXYZOp:
2128 case icSigIfOp:
2129 case icSigElseOp:
2130 case icSigSelectOp:
2131 case icSigCaseOp:
2132 case icSigDefaultOp:
2133 return true;
2134
2135 default:
2136 return false;
2137 }
2138}
2139
2140IIccOpDef *CIccCalcOpMgr::getOpDef(icSigCalcOp opSig)
2141{
2142 icCalcOpMap::iterator pos;
2143 CIccCalcOpMgr *inst = GetInstance();
2144 pos = inst->m_map.find(opSig);
2145 if (pos==inst->m_map.end())
2146 return &inst->m_invalid;
2147 return pos->second;
2148}
2149
2150
2151
2152/******************************************************************************
2153* Name: SIccCalcOp::IsValidOp
2154*
2155* Purpose:
2156*
2157* Args:
2158*
2159* Return:
2160******************************************************************************/
2161bool SIccCalcOp::IsValidOp(CIccMpeCalculator *pCalc)
2162{
2163 switch(sig) {
2164 case icSigApplyCurvesOp:
2165 case icSigApplyMatrixOp:
2166 case icSigApplyCLutOp:
2167 case icSigApplyTintOp:
2168 case icSigApplyToJabOp:
2169 case icSigApplyFromJabOp:
2170 case icSigApplyCalcOp:
2171 case icSigApplyElemOp:
2172 {
2173 CIccMultiProcessElement *pMpe = pCalc->GetElem(sig, data.select.v1);
2174 return pMpe != NULL__null;
2175 }
2176
2177 default:
2178 return IsValidOp(sig);
2179 }
2180}
2181
2182/**
2183******************************************************************************
2184* Name: SIccCalcOp::ArgsUsed
2185*
2186* Purpose:
2187*
2188* Args:
2189*
2190* Return:
2191******************************************************************************/
2192icUInt16Number SIccCalcOp::ArgsUsed(CIccMpeCalculator *pCalc)
2193{
2194 switch (sig) {
2195 case icSigDataOp:
2196 case icSigPiOp:
2197 case icSigPosInfinityOp:
2198 case icSigNegInfinityOp:
2199 case icSigNotaNumberOp:
2200 case icSigInputChanOp:
2201 case icSigTempGetChanOp:
2202 case icSigEnvVarOp:
2203 return 0;
2204
2205 case icSigApplyCurvesOp:
2206 case icSigApplyMatrixOp:
2207 case icSigApplyCLutOp:
2208 case icSigApplyTintOp:
2209 case icSigApplyToJabOp:
2210 case icSigApplyFromJabOp:
2211 case icSigApplyCalcOp:
2212 case icSigApplyElemOp:
2213 {
2214 CIccMultiProcessElement *pMpe = pCalc->GetElem(sig, data.select.v1);
2215 return (pMpe ? pMpe->NumInputChannels() : 0);
2216 }
2217
2218 case icSigOutputChanOp:
2219 case icSigTempPutChanOp:
2220 case icSigTempSaveChanOp:
2221 return data.select.v2+1;
2222
2223 case icSigCopyOp:
2224 case icSigRotateLeftOp:
2225 case icSigRotateRightOp:
2226 case icSigPositionDupOp:
2227 case icSigPopOp:
2228 return data.select.v1+1;
2229
2230 case icSigSolveOp:
2231 return (data.select.v1+1)*(data.select.v2+1) + (data.select.v1+1);
2232
2233 case icSigTransposeOp:
2234 return (data.select.v1+1)*(data.select.v2+1);
2235
2236 case icSigFlipOp:
2237 return data.select.v1+2;
2238
2239 case icSigSumOp:
2240 case icSigProductOp:
2241 case icSigMinimumOp:
2242 case icSigMaximumOp:
2243 case icSigAndOp:
2244 case icSigOrOp:
2245 return data.select.v1+2;
2246
2247 case icSigGammaOp:
2248 case icSigScalarAddOp:
2249 case icSigScalarSubtractOp:
2250 case icSigScalarMultiplyOp:
2251 case icSigScalarDivideOp:
2252 return data.select.v1+2;
2253
2254 case icSigAddOp:
2255 case icSigSubtractOp:
2256 case icSigMultiplyOp:
2257 case icSigDivideOp:
2258 case icSigModulusOp:
2259 case icSigPowOp:
2260 case icSigArcTan2Op:
2261 case icSigLessThanOp:
2262 case icSigLessThanEqualOp:
2263 case icSigEqualOp:
2264 case icSigNearOp:
2265 case icSigGreaterThanEqualOp:
2266 case icSigGreaterThanOp:
2267 case icSigCartesianToPolarOp:
2268 case icSigPolarToCartesianOp:
2269 case icSigVectorMinimumOp:
2270 case icSigVectorMaximumOp:
2271 case icSigVectorAndOp:
2272 case icSigVectorOrOp:
2273 return (data.select.v1+1)*2;
2274
2275 case icSigSquareOp:
2276 case icSigSquareRootOp:
2277 case icSigCubeOp:
2278 case icSigCubeRootOp:
2279 case icSigSignOp:
2280 case icSigAbsoluteValOp:
2281 case icSigTruncateOp:
2282 case icSigFloorOp:
2283 case icSigCeilingOp:
2284 case icSigRoundOp:
2285 case icSigRealNumberOp:
2286 case icSigNegOp:
2287 case icSigExpOp:
2288 case icSigLogrithmOp:
2289 case icSigNaturalLogOp:
2290 case icSigSineOp:
2291 case icSigCosineOp:
2292 case icSigTangentOp:
2293 case icSigArcSineOp:
2294 case icSigArcCosineOp:
2295 case icSigArcTangentOp:
2296 case icSigNotOp:
2297 return data.select.v1+1;
2298
2299 case icSigToLabOp:
2300 case icSigToXYZOp:
2301 return (data.select.v1+1)*3;
2302
2303 case icSigIfOp:
2304 case icSigSelectOp:
2305 return 1;
2306
2307 default:
2308 return 0;
2309 }
2310}
2311
2312
2313/**
2314******************************************************************************
2315* Name: SIccCalcOp::ArgsPushed
2316*
2317* Purpose:
2318*
2319* Args:
2320*
2321* Return:
2322******************************************************************************/
2323icUInt16Number SIccCalcOp::ArgsPushed(CIccMpeCalculator *pCalc)
2324{
2325 switch (sig) {
2326 case icSigOutputChanOp:
2327 case icSigTempPutChanOp:
2328
2329 case icSigPopOp:
2330 case icSigIfOp:
2331 case icSigSelectOp:
2332 /*case icSigElseOp:*/ //This is only valid after an icSigIfOp is parsed
2333 /*case icSigCaseOp:*/ //This is only valid after an icSigSelectOp is parsed
2334 /*case icSigDefaultOp:*/ //This is only valid after an icSigSelectOp is parsed
2335 return 0;
2336
2337 case icSigDataOp:
2338 case icSigPiOp:
2339 case icSigPosInfinityOp:
2340 case icSigNegInfinityOp:
2341 case icSigNotaNumberOp:
2342 return 1;
2343
2344 case icSigEnvVarOp:
2345 return 2;
2346
2347 case icSigInputChanOp:
2348 case icSigTempGetChanOp:
2349 case icSigTempSaveChanOp:
2350 return data.select.v2+1;
2351
2352 case icSigApplyCurvesOp:
2353 case icSigApplyMatrixOp:
2354 case icSigApplyCLutOp:
2355 case icSigApplyTintOp:
2356 case icSigApplyToJabOp:
2357 case icSigApplyFromJabOp:
2358 case icSigApplyCalcOp:
2359 case icSigApplyElemOp:
2360 {
2361 CIccMultiProcessElement *pMpe = pCalc->GetElem(sig, data.select.v1);
2362 return (pMpe ? pMpe->NumOutputChannels() : 0);
2363 }
2364
2365 case icSigCopyOp:
2366 return (data.select.v1+1)*(data.select.v2+2);
2367 case icSigRotateLeftOp:
2368 case icSigRotateRightOp:
2369 return (data.select.v1+1);
2370
2371 case icSigFlipOp:
2372 return (data.select.v1+2);
2373
2374 case icSigPositionDupOp:
2375 return data.select.v1+2+data.select.v2;
2376
2377 case icSigSolveOp:
2378 return (data.select.v2+1) + 1;
2379
2380 case icSigTransposeOp:
2381 return (data.select.v1+1)*(data.select.v2+1);
2382
2383 case icSigSumOp:
2384 case icSigProductOp:
2385 case icSigMinimumOp:
2386 case icSigMaximumOp:
2387 case icSigAndOp:
2388 case icSigOrOp:
2389 return 1;
2390
2391 case icSigAddOp:
2392 case icSigSubtractOp:
2393 case icSigMultiplyOp:
2394 case icSigDivideOp:
2395 case icSigModulusOp:
2396 case icSigPowOp:
2397 case icSigGammaOp:
2398 case icSigScalarAddOp:
2399 case icSigScalarSubtractOp:
2400 case icSigScalarMultiplyOp:
2401 case icSigScalarDivideOp:
2402 case icSigSquareOp:
2403 case icSigSquareRootOp:
2404 case icSigCubeOp:
2405 case icSigCubeRootOp:
2406 case icSigSignOp:
2407 case icSigAbsoluteValOp:
2408 case icSigTruncateOp:
2409 case icSigFloorOp:
2410 case icSigCeilingOp:
2411 case icSigRoundOp:
2412 case icSigRealNumberOp:
2413 case icSigNegOp:
2414 case icSigExpOp:
2415 case icSigLogrithmOp:
2416 case icSigNaturalLogOp:
2417 case icSigSineOp:
2418 case icSigCosineOp:
2419 case icSigTangentOp:
2420 case icSigArcSineOp:
2421 case icSigArcCosineOp:
2422 case icSigArcTangentOp:
2423 case icSigArcTan2Op:
2424 case icSigLessThanOp:
2425 case icSigLessThanEqualOp:
2426 case icSigEqualOp:
2427 case icSigNearOp:
2428 case icSigGreaterThanEqualOp:
2429 case icSigGreaterThanOp:
2430 case icSigNotOp:
2431 case icSigVectorMinimumOp:
2432 case icSigVectorMaximumOp:
2433 case icSigVectorAndOp:
2434 case icSigVectorOrOp:
2435 return data.select.v1+1;
2436
2437 case icSigCartesianToPolarOp:
2438 case icSigPolarToCartesianOp:
2439 return (data.select.v1+1)*2;
2440
2441 case icSigToLabOp:
2442 case icSigToXYZOp:
2443 return (data.select.v1+1)*3;
2444
2445 default:
2446 return 0;
2447 }
2448}
2449
2450CIccFuncTokenizer::CIccFuncTokenizer(const char *szText, bool bAllowNamedReferences)
2451{
2452 m_token = new std::string();
2453 m_text = szText;
2454 m_bUseRefs = bAllowNamedReferences;
2455}
2456
2457CIccFuncTokenizer::~CIccFuncTokenizer()
2458{
2459 delete m_token;
2460}
2461
2462
2463bool CIccFuncTokenizer::GetNext(bool bForceNoRefs)
2464{
2465 m_token->clear();
2466
2467try_again:
2468
2469 while (*m_text && IsWhiteSpace())
2470 m_text++;
2471
2472 if (!*m_text) {
2473 return false;
2474 }
2475
2476 if (!m_bUseRefs || bForceNoRefs) {
2477 if (*m_text == '{') {
2478 m_text++;
2479 *m_token = "{";
2480 return true;
2481 }
2482
2483 if (*m_text == '}') {
2484 m_text++;
2485 *m_token = "}";
2486 return true;
2487 }
2488
2489 if (*m_text == '[') {
2490 m_text++;
2491 *m_token = "[";
2492 while (*m_text && *m_text != ']') {
2493 *m_token += *m_text;
2494 m_text++;
2495 }
2496 }
2497
2498 if (*m_text == '(') {
2499 m_text++;
2500 *m_token = "(";
2501 while (*m_text && *m_text != ')') {
2502 *m_token += *m_text;
2503 m_text++;
2504 }
2505 if (!*m_text) {
2506 return false;
2507 }
2508 }
2509 }
2510
2511 if (!*m_text) {
2512 return false;
2513 }
2514
2515 if (IsComment()) {
2516 SkipComment();
2517 goto try_again;
2518 }
2519
2520 if (m_bUseRefs && !bForceNoRefs) {
2521 while (!IsWhiteSpace() && *m_text && !IsComment()) {
2522 *m_token += *m_text;
2523 m_text++;
2524 }
2525 }
2526 else {
2527 while (!IsWhiteSpace() && *m_text && *m_text != '{' && *m_text != '[' &&
2528 *m_text != '(' && *m_text != '}' && !IsComment()) {
2529 *m_token += *m_text;
2530 m_text++;
2531 }
2532 }
2533 return true;
2534}
2535
2536
2537icSigCalcOp CIccFuncTokenizer::GetSig()
2538{
2539 const unsigned char *szToken = (unsigned char*) m_token->c_str();
2540 int i;
2541
2542 if ((szToken[0]>='0' && szToken[0]<='9') || szToken[0]=='.' || (szToken[0]=='-' && szToken[1]!='I')) {
2543 return icSigDataOp;
2544 }
2545
2546 if (szToken[0]=='{')
2547 return icSigBeginBlockOp((icSigCalcOp)0x7b202020);
2548
2549 if (szToken[0]=='}')
2550 return icSigEndBlockOp((icSigCalcOp)0x7d202020);
2551
2552 if (szToken[0]=='[')
2553 return icSigBadOp((icSigCalcOp)0);
2554
2555 icUInt32Number sig = 0;
2556 for (i=0; i<4 && szToken[i]; i++) {
2557 sig <<= 8;
2558 sig |= szToken[i];
2559 }
2560
2561 for (;i<4; i++) {
2562 sig <<= 8;
2563 sig |= 0x20;
2564 }
2565
2566 return (icSigCalcOp)sig;
2567}
2568
2569std::string CIccFuncTokenizer::GetName() const
2570{
2571 std::string rv;
2572 const char *pos = m_token->c_str();
2573
2574 while (*pos && *pos != '{' && *pos != '[' && *pos != '(') {
2575 rv += *pos;
2576 pos++;
2577 }
2578
2579 return rv;
2580}
2581
2582std::string CIccFuncTokenizer::GetReference() const
2583{
2584 const char *pos = strchr(m_token->c_str(), '{');
2585 if (!m_bUseRefs || !pos)
2586 return "";
2587
2588 std::string rv;
2589 pos++;
2590 while (*pos && *pos != '}') {
2591 rv += *pos;
2592 pos++;
2593 }
2594
2595 return rv;
2596}
2597
2598bool CIccFuncTokenizer::GetIndex(icUInt16Number &v1, icUInt16Number &v2, icUInt16Number initV1, icUInt16Number initV2)
2599{
2600 unsigned int iv1, iv2;
2601 const char *pos = GetPos();
2602
2603 if (!GetNext(true))
2604 return false;
2605 iv1=initV1;
2606 iv2=initV2;
2607 const char *szToken = m_token->c_str();
2608 if (*szToken=='[' || *szToken=='(') {
2609 if (strchr(szToken, ',')) {
2610 if (*szToken=='(')
2611 sscanf(m_token->c_str(), "(%u,%u)", &iv1, &iv2);
2612 else
2613 sscanf(m_token->c_str(), "[%u,%u]", &iv1, &iv2);
2614 }
2615 else {
2616 if (*szToken=='(')
2617 sscanf(m_token->c_str(), "(%u)", &iv1);
2618 else
2619 sscanf(m_token->c_str(), "[%u]", &iv1);
2620 }
2621 }
2622 else {
2623 SetPos(pos); //Undo get token
2624 }
2625 v1 = (icUInt16Number)iv1 - initV1;
2626 v2 = (icUInt16Number)iv2 - initV2;
2627
2628 return true;
2629}
2630
2631
2632icFloat32Number CIccFuncTokenizer::GetValue()
2633{
2634 const char * ascii = m_token->c_str();
2635 char * p = NULL__null;
2636 double d = strtod( ascii, &p );
2637 return (icFloat32Number)d;
2638}
2639
2640
2641bool CIccFuncTokenizer::GetEnvSig(icSigCmmEnvVar &envSig)
2642{
2643 const char *pos = GetPos();
2644
2645 if (!GetNext())
2646 return false;
2647 const char *szToken = m_token->c_str();
2648 int l=(int)strlen(szToken);
2649 if ((*szToken=='[' && szToken[l-1]==']') ||
2650 (*szToken=='(' && szToken[l-1]==')')) {
2651
2652 int i;
2653
2654 icUInt32Number sig = 0;
2655 if (l==10) {
2656 sscanf(szToken+1, "%x", &sig);
2657
2658 envSig = (icSigCmmEnvVar)sig;
2659 return true;
2660 }
2661
2662 for (i=1; i<=4 && i<l-1; i++) {
2663 sig <<= 8;
2664 sig |= szToken[i];
2665 }
2666
2667 for (;i<=4; i++) {
2668 sig <<= 8;
2669 sig |= 0x20;
2670 }
2671
2672 envSig = (icSigCmmEnvVar)sig;
2673 }
2674 else {
2675 SetPos(pos); //Undo get token
2676 envSig = (icSigCmmEnvVar)0;
2677 return false;
2678 }
2679
2680 return true;
2681}
2682
2683
2684bool CIccFuncTokenizer::IsWhiteSpace()
2685{
2686 if (*m_text==' ' || *m_text=='\n' || *m_text=='\r' || *m_text=='\t')
2687 return true;
2688 return false;
2689}
2690
2691bool CIccFuncTokenizer::IsComment()
2692{
2693 if (*m_text=='%' || *m_text==';' || *m_text=='/')
2694 return true;
2695 return false;
2696}
2697
2698void CIccFuncTokenizer::SkipComment()
2699{
2700 while(*m_text && !(*m_text=='\n' || *m_text=='\r')) {
2701 m_text++;
2702 }
2703}
2704
2705/**
2706 ******************************************************************************
2707 * Name: CIccCalculatorFunc::CIccCalculatorFunc
2708 *
2709 * Purpose:
2710 *
2711 * Args:
2712 *
2713 * Return:
2714 ******************************************************************************/
2715CIccCalculatorFunc::CIccCalculatorFunc(CIccMpeCalculator *pCalc)
2716{
2717 m_pCalc = pCalc;
2718 m_nReserved = 0;
2719
2720 m_nOps = 0;
2721 m_Op = NULL__null;
2722}
2723
2724/**
2725 ******************************************************************************
2726 * Name: CIccCalculatorFunc::CIccCalculatorFunc
2727 *
2728 * Purpose:
2729 *
2730 * Args:
2731 *
2732 * Return:
2733 ******************************************************************************/
2734CIccCalculatorFunc::CIccCalculatorFunc(const CIccCalculatorFunc &func)
2735{
2736 m_pCalc = func.m_pCalc;
2737
2738 m_nReserved= func.m_nReserved;
2739
2740 m_nOps = func.m_nOps;
2741
2742 if (m_nOps) {
2743 m_Op = (SIccCalcOp*)malloc(m_nOps * sizeof(SIccCalcOp));
2744 memcpy(m_Op, func.m_Op, m_nOps*sizeof(SIccCalcOp));
2745 }
2746 else
2747 m_Op = NULL__null;
2748}
2749
2750/**
2751 ******************************************************************************
2752 * Name: &CIccCalculatorFunc::operator=
2753 *
2754 * Purpose:
2755 *
2756 * Args:
2757 *
2758 * Return:
2759 ******************************************************************************/
2760CIccCalculatorFunc &CIccCalculatorFunc::operator=(const CIccCalculatorFunc &func)
2761{
2762 m_pCalc = func.m_pCalc;
2763
2764 m_nReserved= func.m_nReserved;
2765
2766 if (m_Op)
2767 free(m_Op);
2768
2769 m_nOps = func.m_nOps;
2770
2771 if (m_nOps) {
2772 m_Op = (SIccCalcOp*)malloc(m_nOps * sizeof(SIccCalcOp));
2773 memcpy(m_Op, func.m_Op, m_nOps*sizeof(SIccCalcOp));
2774 }
2775 else
2776 m_Op = NULL__null;
2777
2778 return (*this);
2779}
2780
2781/**
2782 ******************************************************************************
2783 * Name: CIccCalculatorFunc::~CIccChannelFunc
2784 *
2785 * Purpose:
2786 *
2787 * Args:
2788 *
2789 * Return:
2790 ******************************************************************************/
2791CIccCalculatorFunc::~CIccCalculatorFunc()
2792{
2793 if (m_Op) {
2794 free(m_Op);
2795 }
2796}
2797
2798void CIccCalculatorFunc::InsertBlanks(std::string &sDescription, int nBlanks)
2799{
2800 char blanks[21]=" ";
2801 int i;
2802
2803 while (nBlanks>0) {
2804 i = nBlanks < 20 ? nBlanks : 20;
2805 blanks[i] = 0;
2806 sDescription += blanks;
2807 nBlanks -= i;
2808 }
2809}
2810
2811void CIccCalculatorFunc::DescribeSequence(std::string &sDescription,
2812 icUInt32Number nOps, SIccCalcOp *op, int nBlanks)
2813{
2814 icUInt32Number i;
2815 int pos;
2816 std::string opName;
2817 std::string funcDesc;
2818
2819 InsertBlanks(funcDesc, nBlanks);
2820 funcDesc += "{ ";
2821
2822 pos = nBlanks + 2;
2823
2824 for (i=0; i<nOps;) {
2825 if (pos >nBlanks + 65) {
2826 funcDesc += "\n";
2827 InsertBlanks(funcDesc, nBlanks + 2);
2828 pos = nBlanks + 2;
2829 }
2830
2831 op->Describe(opName);
2832 funcDesc += opName;
2833 funcDesc += " ";
2834 pos += opName.size() + 1;
2835
2836 if (op->sig == icSigIfOp) {
2837 SIccCalcOp *ifop = op;
2838
2839 if (i+1<nOps && op[1].sig == icSigElseOp) {
2840 SIccCalcOp *elseop = &op[1];
2841 icUInt32Number nSubOps = (icUInt32Number)icIntMin(nOps-i, ifop->data.size);
2842 op++;
2843 i++;
2844 funcDesc += "\n";
2845 DescribeSequence(funcDesc, nSubOps, &op[1], nBlanks+2);
2846 op += nSubOps;
2847 i += nSubOps;
2848
2849 InsertBlanks(funcDesc, nBlanks+2);
2850 funcDesc += "else\n";
2851 pos = 0;
2852
2853 nSubOps = (icUInt32Number)icIntMin(nOps-i, elseop->data.size);
2854 DescribeSequence(funcDesc, nSubOps, &op[1], nBlanks+2);
2855 op += nSubOps;
2856 i += nSubOps;
2857 }
2858 else {
2859 icUInt32Number nSubOps = (icUInt32Number)icIntMin(nOps-i, ifop->data.size);
2860 funcDesc += "\n";
2861 DescribeSequence(funcDesc, nSubOps, &op[1], nBlanks+2);
2862 op += nSubOps;
2863 i += nSubOps;
2864 }
2865
2866 InsertBlanks(funcDesc, nBlanks + 2);
2867 pos = nBlanks + 2;
2868 }
2869 else if (op->sig == icSigSelectOp) {
2870 op++;
2871 i++;
2872 funcDesc += "\n";
2873
2874 int j, n;
2875
2876 for (n=0; i+n<nOps; ) {
2877 if (op[n].sig==icSigCaseOp)
2878 n++;
2879 else if (n>1 && op[n].sig==icSigDefaultOp) {
2880 n++;
2881 break;
2882 }
2883 else
2884 break;
2885 }
2886
2887 int p = n;
2888 for (j=0; j<n; j++) {
2889 icUInt32Number nSubOps = (icUInt32Number)icIntMin(nOps-(i+p), op[j].data.size);
2890 InsertBlanks(funcDesc, nBlanks+2);
2891 if (op[j].sig==icSigCaseOp)
2892 funcDesc += "case\n";
2893 else
2894 funcDesc += "dflt\n";
2895
2896 DescribeSequence(funcDesc, nSubOps, &op[p], nBlanks+2);
2897 p += nSubOps;
2898 }
2899
2900 op += p-1;
2901 i += p-1;
2902
2903 InsertBlanks(funcDesc, nBlanks + 2);
2904 pos = nBlanks + 2;
2905 }
2906 op++;
2907 i++;
2908 }
2909 funcDesc += "}\n";
2910
2911 sDescription += funcDesc;
2912}
2913
2914/**
2915 ******************************************************************************
2916 * Name: CIccCalculatorFunc::Describe
2917 *
2918 * Purpose:
2919 *
2920 * Args:
2921 *
2922 * Return:
2923 ******************************************************************************/
2924void CIccCalculatorFunc::Describe(std::string &sDescription, int nBlanks)
2925{
2926 if (m_nOps) {
2927 DescribeSequence(sDescription, m_nOps, m_Op, nBlanks);
2928 }
2929 else {
2930 sDescription += "Undefined Function!\n";
2931 }
2932}
2933
2934static void AppendOpList(CIccCalcOpList &toList, const CIccCalcOpList &fromList)
2935{
2936 CIccCalcOpList::const_iterator o;
2937
2938 for (o=fromList.begin(); o!=fromList.end(); o++) {
2939 toList.push_back(*o);
2940 }
2941}
2942
2943/**
2944******************************************************************************
2945* Name: CIccCalculatorFunc::ParseFuncDef
2946*
2947* Purpose:
2948*
2949* Args:
2950*
2951* Return:
2952******************************************************************************/
2953const char *CIccCalculatorFunc::ParseFuncDef(const char *szFuncDef, CIccCalcOpList &scanList, std::string &sReport)
2954{
2955 SIccCalcOp op;
2956 op.extra = 0;
2957 op.def=NULL__null;
2958
2959 scanList.clear();
2960
2961 if (!szFuncDef)
2962 return szFuncDef;
2963
2964 CIccFuncTokenizer scan(szFuncDef);
2965 if (!scan.GetNext())
2966 return NULL__null;
2967
2968 if (scan.GetSig() != icSigBeginBlockOp((icSigCalcOp)0x7b202020))
2969 return NULL__null;
2970
2971 while(scan.GetNext()) {
2972 op.sig = scan.GetSig();
2973
2974 if (op.sig == icSigEndBlockOp((icSigCalcOp)0x7d202020))
2975 return scan.GetPos();
2976
2977 switch(op.sig) {
2978 case icSigDataOp:
2979 op.data.num = scan.GetValue();
2980 scanList.push_back(op);
2981 break;
2982
2983 case icSigIfOp:
2984 {
2985 CIccCalcOpList trueList, falseList;
2986 bool bHasElse;
2987
2988 szFuncDef = ParseFuncDef(scan.GetPos(), trueList, sReport);
2989 if (!szFuncDef)
2990 return NULL__null;
2991
2992 scan.SetPos(szFuncDef);
2993 bHasElse = false;
2994 if (scan.GetNext() && scan.GetSig()==icSigElseOp) {
2995 bHasElse = true;
2996 szFuncDef = ParseFuncDef(scan.GetPos(), falseList, sReport);
2997
2998 if (!szFuncDef)
2999 return NULL__null;
3000 }
3001
3002 scan.SetPos(szFuncDef);
3003 op.data.size = (icUInt32Number)trueList.size();
3004 scanList.push_back(op);
3005
3006 if (bHasElse) {
3007 op.sig = icSigElseOp;
3008 op.data.size = (icUInt32Number)falseList.size();
3009 scanList.push_back(op);
3010
3011 AppendOpList(scanList, trueList);
3012 AppendOpList(scanList, falseList);
3013 }
3014 else {
3015 AppendOpList(scanList, trueList);
3016 }
3017 }
3018 break;
3019
3020 case icSigSelectOp:
3021 {
3022 op.sig = icSigSelectOp;
3023 op.data.size = 0;
3024 scanList.push_back(op);
3025
3026 int c;
3027 CIccCalcOpListPtrList selList;
3028 for (c=0; ; c++) {
3029 szFuncDef = scan.GetPos();
3030 scan.GetNext();
3031 if (scan.GetSig()==icSigCaseOp) {
3032 CIccCalcOpListPtr pCaseList = new CIccCalcOpList();
3033
3034 szFuncDef = ParseFuncDef(scan.GetPos(), *pCaseList, sReport);
3035
3036 if (!szFuncDef) {
3037 delete pCaseList;
3038 return NULL__null;
3039 }
3040
3041 scan.SetPos(szFuncDef);
3042 op.sig = icSigCaseOp;
3043 op.data.size = (icUInt32Number)pCaseList->size();
3044 scanList.push_back(op);
3045
3046 selList.push_back(pCaseList);
3047 }
3048 else if (c && scan.GetSig()==icSigDefaultOp) {
3049 CIccCalcOpListPtr pDefaultList = new CIccCalcOpList();
3050
3051 szFuncDef = ParseFuncDef(scan.GetPos(), *pDefaultList, sReport);
3052
3053 if (!szFuncDef) {
3054 delete pDefaultList;
3055 return NULL__null;
3056 }
3057
3058 scan.SetPos(szFuncDef);
3059 op.sig = icSigDefaultOp;
3060 op.data.size = (icUInt32Number)pDefaultList->size();
3061 scanList.push_back(op);
3062
3063 selList.push_back(pDefaultList);
3064 break;
3065 }
3066 else {
3067 scan.SetPos(szFuncDef);
3068 break;
3069 }
3070 }
3071 CIccCalcOpListPtrList::iterator l;
3072 for (l=selList.begin(); l!=selList.end(); l++) {
3073 CIccCalcOpListPtr pCaseList = *l;
3074
3075 AppendOpList(scanList, *pCaseList);
3076 delete pCaseList;
3077 }
3078 }
3079 break;
3080
3081 case icSigInputChanOp:
3082 case icSigOutputChanOp:
3083 case icSigTempGetChanOp:
3084 case icSigTempPutChanOp:
3085 case icSigTempSaveChanOp:
3086 if (!scan.GetIndex(op.data.select.v1, op.data.select.v2, 0, 1))
3087 return NULL__null;
3088 scanList.push_back(op);
3089 break;
3090
3091 case icSigEnvVarOp:
3092 {
3093 icSigCmmEnvVar envSig;
3094 if (!scan.GetEnvSig(envSig))
3095 return NULL__null;
3096 op.data.size = (icUInt32Number)envSig;
3097 scanList.push_back(op);
3098 }
3099 break;
3100
3101 case icSigCopyOp:
3102 case icSigRotateLeftOp:
3103 case icSigRotateRightOp:
3104 case icSigPositionDupOp:
3105 case icSigSolveOp:
3106 case icSigTransposeOp:
3107 if (!scan.GetIndex(op.data.select.v1, op.data.select.v2, 1, 1))
3108 return NULL__null;
3109 scanList.push_back(op);
3110 break;
3111
3112 case icSigPopOp:
3113 if (!scan.GetIndex(op.data.select.v1, op.data.select.v2, 1))
3114 return NULL__null;
3115 op.data.select.v2 = 0;
3116 scanList.push_back(op);
3117 break;
3118
3119 case icSigFlipOp:
3120 case icSigSumOp:
3121 case icSigProductOp:
3122 case icSigMinimumOp:
3123 case icSigMaximumOp:
3124 case icSigAndOp:
3125 case icSigOrOp:
3126 if (!scan.GetIndex(op.data.select.v1, op.data.select.v2, 2))
3127 return NULL__null;
3128 op.data.select.v2 = 0;
3129 scanList.push_back(op);
3130 break;
3131
3132 case icSigApplyCurvesOp:
3133 case icSigApplyMatrixOp:
3134 case icSigApplyCLutOp:
3135 case icSigApplyTintOp:
3136 case icSigApplyToJabOp:
3137 case icSigApplyFromJabOp:
3138 case icSigApplyCalcOp:
3139 case icSigApplyElemOp:
3140 if (!scan.GetIndex(op.data.select.v1, op.data.select.v2))
3141 return NULL__null;
3142 op.data.select.v2 = 0;
3143 scanList.push_back(op);
3144 break;
3145
3146 case icSigGammaOp:
3147 case icSigScalarAddOp:
3148 case icSigScalarSubtractOp:
3149 case icSigScalarMultiplyOp:
3150 case icSigScalarDivideOp:
3151 case icSigAddOp:
3152 case icSigSubtractOp:
3153 case icSigMultiplyOp:
3154 case icSigDivideOp:
3155 case icSigModulusOp:
3156 case icSigPowOp:
3157 case icSigArcTan2Op:
3158 case icSigLessThanOp:
3159 case icSigLessThanEqualOp:
3160 case icSigEqualOp:
3161 case icSigNearOp:
3162 case icSigGreaterThanEqualOp:
3163 case icSigGreaterThanOp:
3164 case icSigSquareOp:
3165 case icSigSquareRootOp:
3166 case icSigCubeOp:
3167 case icSigCubeRootOp:
3168 case icSigSignOp:
3169 case icSigAbsoluteValOp:
3170 case icSigTruncateOp:
3171 case icSigFloorOp:
3172 case icSigCeilingOp:
3173 case icSigRoundOp:
3174 case icSigRealNumberOp:
3175 case icSigNegOp:
3176 case icSigExpOp:
3177 case icSigLogrithmOp:
3178 case icSigNaturalLogOp:
3179 case icSigSineOp:
3180 case icSigCosineOp:
3181 case icSigTangentOp:
3182 case icSigArcSineOp:
3183 case icSigArcCosineOp:
3184 case icSigArcTangentOp:
3185 case icSigCartesianToPolarOp:
3186 case icSigPolarToCartesianOp:
3187 case icSigNotOp:
3188 case icSigToLabOp:
3189 case icSigToXYZOp:
3190 case icSigVectorMinimumOp:
3191 case icSigVectorMaximumOp:
3192 case icSigVectorAndOp:
3193 case icSigVectorOrOp:
3194 if (!scan.GetIndex(op.data.select.v1, op.data.select.v2, 1))
3195 return NULL__null;
3196 op.data.select.v2 = 0;
3197 scanList.push_back(op);
3198 break;
3199
3200 default:
3201 if (!SIccCalcOp::IsValidOp(op.sig)) {
3202 std::string opDesc;
3203
3204 op.Describe(opDesc);
3205 sReport += "Invalid Operator \"";
3206 sReport += opDesc;
3207 sReport += "\"\r\n";
3208
3209 if (scanList.rbegin()!=scanList.rend()) {
3210 sReport += "Last Few operators in reverse:\n";
3211
3212 CIccCalcOpList::reverse_iterator opi;
3213 int i;
3214 for (i=0, opi=scanList.rbegin(); i<10 && opi!=scanList.rend(); i++, opi++) {
3215 opi->Describe(opDesc);
3216 sReport += " ";
3217 sReport += opDesc;
3218 }
3219 sReport += "\r\n";
3220 }
3221 return NULL__null;
3222 }
3223 op.data.select.v1 = 0;
3224 op.data.select.v2 = 0;
3225 scanList.push_back(op);
3226 break;
3227 }
3228 }
3229 return NULL__null;
3230}
3231
3232
3233/**
3234 ******************************************************************************
3235 * Name: CIccCalculatorFunc::SetFunction
3236 *
3237 * Purpose:
3238 *
3239 * Args:
3240 *
3241 * Return:
3242 ******************************************************************************/
3243icFuncParseStatus CIccCalculatorFunc::SetFunction(const char *szFuncDef, std::string &sReport)
3244{
3245 CIccCalcOpList opList;
3246
3247 if (ParseFuncDef(szFuncDef, opList, sReport)) {
3248 return SetFunction(opList, sReport);
3249 }
3250 return icFuncParseSyntaxError;
3251}
3252
3253/**
3254******************************************************************************
3255* Name: CIccCalculatorFunc::SetFunction
3256*
3257* Purpose:
3258*
3259* Args:
3260*
3261* Return:
3262******************************************************************************/
3263icFuncParseStatus CIccCalculatorFunc::SetFunction(CIccCalcOpList &opList, std::string &sReport)
3264{
3265 if (m_Op) {
3266 free(m_Op);
3267 }
3268
3269 m_nOps = (icUInt32Number)opList.size();
3270
3271 if (m_nOps) {
3272 CIccCalcOpList::iterator i;
3273 int j;
3274
3275 m_Op = (SIccCalcOp*)calloc(m_nOps , sizeof(SIccCalcOp));
3276
3277 for (i=opList.begin(), j=0; i!= opList.end(); i++, j++) {
3278 m_Op[j] = *i;
3279 }
3280 }
3281 else {
3282 return icFuncParseEmptyFunction;
3283 }
3284
3285 if (!HasValidOperations(sReport))
3286 return icFuncParseInvalidOperation;
3287
3288 return DoesStackUnderflowOverflow(sReport);
3289}
3290
3291/**
3292 ******************************************************************************
3293 * Name: CIccCalculatorFunc::Read
3294 *
3295 * Purpose:
3296 *
3297 * Args:
3298 *
3299 * Return:
3300 ******************************************************************************/
3301bool CIccCalculatorFunc::Read(icUInt32Number size, CIccIO *pIO)
3302{
3303 icUInt32Number headerSize = sizeof(icUInt32Number);
3304
3305 headerSize += sizeof(icChannelFuncSignature) + sizeof(icUInt32Number);
3306
3307 if (headerSize > size)
3308 return false;
3309
3310 if (!pIO) {
3311 return false;
3312 }
3313
3314 icChannelFuncSignature sig;
3315
3316 if (!pIO->Read32(&sig))
3317 return false;
3318
3319 if (sig!= GetType())
3320 return false;
3321
3322 if (!pIO->Read32(&m_nReserved))
3323 return false;
3324
3325 if (!pIO->Read32(&m_nOps))
3326 return false;
3327
3328 if ((icUInt64Number)m_nOps * sizeof(icUInt32Number) * 2 > (icUInt64Number)size - headerSize)
3329 return false;
3330
3331 if (m_Op) {
3332 free(m_Op);
3333 }
3334
3335 if (m_nOps) {
3336 m_Op = (SIccCalcOp*)calloc(m_nOps, sizeof(SIccCalcOp));
3337
3338 if (!m_Op) {
3339 m_nOps = 0;
3340 return false;
3341 }
3342
3343 icUInt32Number i;
3344 for (i=0; i<m_nOps; i++) {
3345 if (!pIO->Read32(&m_Op[i].sig))
3346 return false;
3347 if (!pIO->Read32(&m_Op[i].data.num))
3348 return false;
3349 }
3350 }
3351
3352 return true;
3353}
3354
3355/**
3356 ******************************************************************************
3357 * Name: CIccCalculatorFunc::Write
3358 *
3359 * Purpose:
3360 *
3361 * Args:
3362 *
3363 * Return:
3364 ******************************************************************************/
3365bool CIccCalculatorFunc::Write(CIccIO *pIO)
3366{
3367 if (!pIO)
3368 return false;
3369
3370 icChannelFuncSignature sig;
3371 sig = GetType();
3372 if (!pIO->Write32(&sig))
3373 return false;
3374
3375 if (!pIO->Write32(&m_nReserved))
3376 return false;
3377
3378 if (!pIO->Write32(&m_nOps))
3379 return false;
3380
3381 icUInt32Number i;
3382 for (i=0; i<m_nOps; i++) {
3383 if (!pIO->Write32(&m_Op[i].sig))
3384 return false;
3385 if (!pIO->Write32(&m_Op[i].data.num))
3386 return false;
3387 }
3388
3389 return true;
3390}
3391
3392
3393/**
3394 ******************************************************************************
3395 * Name: CIccCalculatorFunc::SetOpDefs
3396 *
3397 * Purpose:
3398 *
3399 * Args:
3400 *
3401 * Return:
3402 ******************************************************************************/
3403bool CIccCalculatorFunc::SetOpDefs()
3404{
3405 if (!m_Op)
3406 return false;
3407
3408 icUInt32Number i;
3409 for (i=0; i<m_nOps; i++) {
3410 m_Op[i].def = CIccCalcOpMgr::getOpDef(m_Op[i].sig);
3411 if (!m_Op[i].def)
3412 return false;
3413 }
3414 return true;
3415}
3416
3417
3418/**
3419 ******************************************************************************
3420 * Name: CIccCalculatorFunc::Begin
3421 *
3422 * Purpose:
3423 *
3424 * Args:
3425 *
3426 * Return:
3427 ******************************************************************************/
3428bool CIccCalculatorFunc::Begin(const CIccMpeCalculator *pChannelCalc, CIccTagMultiProcessElement *pMPE)
3429{
3430 if (!pChannelCalc)
3431 return false;
3432 std::string sReport;
3433
3434 if (!InitSelectOps())
3435 return false;
3436
3437 if (!HasValidOperations(sReport))
3438 return false;
3439
3440 if (!SetOpDefs())
3441 return false;
3442
3443 if (DoesOverflowInput(pChannelCalc->NumInputChannels()))
3444 return false;
3445
3446 if (DoesOverflowOutput(pChannelCalc->NumOutputChannels()))
3447 return false;
3448
3449 if (DoesStackUnderflowOverflow(sReport)!=icFuncParseNoError)
3450 return false;
3451
3452 return true;
3453}
3454
3455/**
3456 ******************************************************************************
3457 * Name: CIccCalculatorFunc::InitSelectOps
3458 *
3459 * Purpose:
3460 *
3461 * Args:
3462 *
3463 * Return:
3464 ******************************************************************************/
3465bool CIccCalculatorFunc::InitSelectOps()
3466{
3467 icUInt32Number i;
3468
3469 for (i=0; i<m_nOps; i++) {
3470 if (m_Op[i].sig==icSigSelectOp) {
3471 if (!InitSelectOp(&m_Op[i], m_nOps-i))
3472 return false;
3473 }
3474 }
3475
3476 return true;
3477}
3478
3479/**
3480 ******************************************************************************
3481 * Name: CIccCalculatorFunc::InitSelectOp
3482 *
3483 * Purpose:
3484 *
3485 * Args:
3486 *
3487 * Return:
3488 ******************************************************************************/
3489bool CIccCalculatorFunc::InitSelectOp(SIccCalcOp *ops, icUInt32Number nOps)
3490{
3491
3492 if (ops->sig != icSigSelectOp)
3493 return false;
3494
3495 if (ops->extra)
3496 return true;
3497
3498
3499 icUInt32Number i, n, pos;
3500 for (n=0; n<nOps && ops[n+1].sig==icSigCaseOp; n++);
3501 ops->extra=n;
3502 if (ops[n+1].sig==icSigDefaultOp) {
3503 n++;
3504 }
3505 pos = n;
3506 for (i=1; i<=n && pos<nOps; i++) {
3507 ops[i].extra = pos;
3508 pos += ops[i].data.size;
3509 }
3510
3511 if (i<=n)
3512 return false;
3513
3514 return true;
3515}
3516
3517/**
3518******************************************************************************
3519* Name: CIccCalculatorFunc::ApplySequence
3520*
3521* Purpose:
3522*
3523* Args:
3524*
3525* Return:
3526******************************************************************************/
3527bool CIccCalculatorFunc::ApplySequence(CIccApplyMpeCalculator *pApply, icUInt32Number nOps, SIccCalcOp *ops) const
3528{
3529 SIccCalcOp *op;
3530 SIccOpState os;
3531
3532 os.pApply = pApply;
3533 os.pStack = pApply->GetStack();
3534 os.pScratch = pApply->GetScratch();
3535 os.temp = pApply->GetTemp();
3536 os.pixel = pApply->GetInput();
3537 os.output = pApply->GetOutput();
3538 os.nOps = nOps;
3539
3540 for (os.idx=0; os.idx<os.nOps; os.idx++) {
3541 op = &ops[os.idx];
3542
3543 if (g_pDebugger)
3544 g_pDebugger->BeforeOp(op, os, ops);
3545
3546 if (op->sig==icSigIfOp) {
3547 icFloatNumber a1;
3548 OsPopArg(a1){ if (!os.pStack->size()) return false; a1 = *(os.pStack->
rbegin()); os.pStack->pop_back(); }
;
3549
3550 if (os.idx+1<nOps && ops[os.idx+1].sig==icSigElseOp) {
3551 os.idx++;
3552 if (a1>=0.5) {
3553 if (os.idx+1 + op->data.size >= nOps)
3554 return false;
3555
3556 if (!ApplySequence(pApply, op->data.size, &ops[os.idx+1]))
3557 return false;
3558 }
3559 else {
3560 if (os.idx+1 + op->data.size + ops[os.idx].data.size > nOps)
3561 return false;
3562
3563 if (!ApplySequence(pApply, ops[os.idx].data.size, &ops[os.idx+1 + op->data.size]))
3564 return false;
3565 }
3566 os.idx += op->data.size + ops[os.idx].data.size;
3567 }
3568 else {
3569 if (a1>=0.5) {
3570 if (os.idx+op->data.size >= nOps)
3571 return false;
3572
3573 if (!ApplySequence(pApply, op->data.size, &ops[os.idx+1]))
3574 return false;
3575 }
3576 os.idx+= op->data.size;
3577 }
3578 }
3579 else if (op->sig==icSigSelectOp) {
3580 icFloatNumber a1;
3581 OsPopArg(a1){ if (!os.pStack->size()) return false; a1 = *(os.pStack->
rbegin()); os.pStack->pop_back(); }
;
3582 icInt32Number nSel = (a1 >= 0.0) ? (icInt32Number)(a1+0.5f) : (icInt32Number)(a1-0.5f);
3583
3584 if (!op->extra) {
3585 return false;
3586 }
3587
3588 icUInt32Number nDefOff = (icUInt32Number)(os.idx+1 + op->extra);
3589 if (nDefOff >= nOps)
3590 return false;
3591
3592 if (nSel<0 || (icUInt32Number)nSel>=op->extra) {
3593
3594 if (ops[nDefOff].sig==icSigDefaultOp) {
3595 if (os.idx+1 + ops[nDefOff].extra >= nOps)
3596 return false;
3597
3598 if (!ApplySequence(pApply, ops[nDefOff].data.size, &ops[os.idx+1 + ops[nDefOff].extra]))
3599 break;
3600 }
3601 }
3602 else {
3603 icUInt32Number nOff = os.idx+1 + nSel;
3604
3605 if (nOff >= nOps)
3606 return false;
3607
3608 if (!ApplySequence(pApply, ops[nOff].data.size, &ops[os.idx+1 + ops[nOff].extra]))
3609 break;
3610 }
3611
3612 if (ops[nDefOff].sig==icSigDefaultOp) {
3613 if (os.idx+1 + ops[nDefOff].extra + ops[nDefOff].data.size >nOps)
3614 return false;
3615
3616 os.idx = (icUInt32Number)(os.idx + ops[nDefOff].extra + ops[nDefOff].data.size);
3617 }
3618 else if (op->extra) {
3619 unsigned long nOff = os.idx + op->extra;
3620
3621 if (os.idx+1 + ops[nOff].extra + ops[nOff].data.size > nOps)
3622 return false;
3623
3624 os.idx = (icUInt32Number)(os.idx + ops[nOff].extra + ops[nOff].data.size);
3625 }
3626 else
3627 return false;
3628 }
3629 else {
3630 if (!op->def->Exec(op, os))
3631 return false;
3632 }
3633
3634 if (g_pDebugger) {
3635 g_pDebugger->AfterOp(op, os, ops);
3636 }
3637 }
3638 return true;
3639}
3640
3641/**
3642 ******************************************************************************
3643 * Name: CIccCalculatorFunc::Apply
3644 *
3645 * Purpose:
3646 *
3647 * Args:
3648 *
3649 * Return:
3650 ******************************************************************************/
3651bool CIccCalculatorFunc::Apply(CIccApplyMpeCalculator *pApply) const
3652{
3653 CIccFloatVector *pStack = pApply->GetStack();
3654
3655 pStack->clear();
3656
3657 if (!ApplySequence(pApply, m_nOps, m_Op)) {
3658 icFloatNumber *pOut = pApply->GetOutput();
3659 icUInt32Number i;
3660 for (i=0; i<m_pCalc->NumOutputChannels(); i++)
3661 pOut[i] = -1;
3662 return false;
3663 }
3664
3665 return true;
3666}
3667
3668/**
3669 ******************************************************************************
3670 * Name: CIccCalculatorFunc::Validate
3671 *
3672 * Purpose:
3673 *
3674 * Args:
3675 *
3676 * Return:
3677 ******************************************************************************/
3678icValidateStatus CIccCalculatorFunc::Validate(std::string sigPath, std::string &sReport,
3679 const CIccMpeCalculator* pChannelCalc/*=NULL*/) const
3680{
3681 CIccInfo Info;
3682 std::string sSigPathName = Info.GetSigPathName(sigPath);
3683
3684 icValidateStatus rv = icValidateOK;
3685 if (m_nReserved) {
3686 sReport += icMsgValidateWarning;
3687 sReport += sSigPathName;
3688 sReport += " function has non zero reserved data.\r\n";
3689 rv = icValidateWarning;
3690 }
3691
3692 if (GetMaxTemp()>65535) {
3693 sReport += icMsgValidateCriticalError;
3694 sReport += sSigPathName;
3695 sReport += " accesses illegal temporary channels.\r\n";
3696 return icValidateCriticalError;
3697 }
3698
3699 if (!HasValidOperations(sReport)) {
3700 sReport += icMsgValidateCriticalError;
3701 sReport += sSigPathName;
3702 sReport += " function has invalid operations.\r\n";
3703 return icValidateCriticalError;
3704 }
3705
3706 if (DoesOverflowInput(pChannelCalc->NumInputChannels())) {
3707 sReport += icMsgValidateCriticalError;
3708 sReport += sSigPathName;
3709 sReport += " accesses illegal input channels.\r\n";
3710 return icValidateCriticalError;
3711 }
3712
3713 if (DoesOverflowOutput(pChannelCalc->NumOutputChannels())) {
3714 sReport += icMsgValidateCriticalError;
3715 sReport += sSigPathName;
3716 sReport += " accesses illegal output channels.\r\n";
3717 return icValidateCriticalError;
3718 }
3719
3720 icFuncParseStatus parseStat = DoesStackUnderflowOverflow(sReport);
3721 if (parseStat!=icFuncParseNoError) {
3722 sReport += icMsgValidateCriticalError;
3723 sReport += sSigPathName;
3724 if (parseStat==icFuncParseStackUnderflow)
3725 sReport += " causes an evaluation stack underflow.\r\n";
3726 else
3727 sReport += " causes an evaluation stack overflow.\r\n";
3728 return icValidateCriticalError;
3729 }
3730
3731 return rv;
3732}
3733
3734/**
3735******************************************************************************
3736* Name: CIccCalculatorFunc::GetMaxTemp
3737*
3738* Purpose:
3739*
3740* Args:
3741*
3742* Return:
3743******************************************************************************/
3744icUInt32Number CIccCalculatorFunc::GetMaxTemp() const
3745{
3746 icUInt32Number i, nMaxTemp = 0;
3747
3748 for (i=0; i<m_nOps; i++) {
3749 if (m_Op[i].sig == icSigTempGetChanOp || m_Op[i].sig == icSigTempPutChanOp || m_Op[i].sig == icSigTempSaveChanOp ) {
3750 icUInt32Number last = (icUInt32Number)(m_Op[i].data.select.v1) + (icUInt32Number)(m_Op[i].data.select.v2);
3751 if (last>nMaxTemp)
3752 nMaxTemp = last;
3753 }
3754 }
3755 return nMaxTemp;
3756}
3757
3758/**
3759******************************************************************************
3760* Name: CIccCalculatorFunc::NeedTempReset
3761*
3762* Purpose:
3763*
3764* Args:
3765*
3766* Return:
3767******************************************************************************/
3768bool CIccCalculatorFunc::NeedTempReset(icUInt8Number *tempUsage, icUInt32Number nMaxTemp)
3769{
3770 return SequenceNeedTempReset(m_Op, m_nOps, tempUsage, nMaxTemp);
3771}
3772
3773/**
3774******************************************************************************
3775* Name: CIccCalculatorFunc::SequenceNeedTempReset
3776*
3777* Purpose:
3778*
3779* Args:
3780*
3781* Return:
3782******************************************************************************/
3783bool CIccCalculatorFunc::SequenceNeedTempReset(SIccCalcOp *op, icUInt32Number nOps, icUInt8Number *tempUsage, icUInt32Number nMaxTemp)
3784{
3785 icUInt32Number i, j;
3786
3787 for (i=0; i<nOps; i++) {
3788 icSigCalcOp sig = op[i].sig;
3789 if (sig==icSigTempGetChanOp) {
3790 icUInt32Number p = op[i].data.select.v1;
3791 icUInt32Number n = op[i].data.select.v2+1;
3792 for (j=0; j<n; j++) {
3793 if (!tempUsage[p+j]) {
3794 return true;
3795 }
3796 }
3797 }
3798 else if (sig==icSigTempPutChanOp) {
3799 icUInt32Number p = op[i].data.select.v1;
3800 icUInt32Number n = op[i].data.select.v2+1;
3801 memset(tempUsage+p, 1, n);
3802 }
3803 else if (sig==icSigTempSaveChanOp) {
3804 icUInt32Number p = op[i].data.select.v1;
3805 icUInt32Number n = op[i].data.select.v2+1;
3806 memset(tempUsage+p, 1, n);
3807 }
3808 else if (sig==icSigIfOp) {
3809 bool rv = false;
3810 icUInt8Number *ifTemps = (icUInt8Number *)malloc(nMaxTemp);
3811 icUInt32Number p;
3812 if (!ifTemps)
3813 return true;
3814
3815 memcpy(ifTemps, tempUsage, nMaxTemp);
3816
3817 p=i+2;
3818 rv = rv || SequenceNeedTempReset(&op[p], icIntMin(nOps-p, op[i].data.size), ifTemps, nMaxTemp);
3819
3820 if (i<nOps && op[i+1].sig==icSigElseOp) {
3821 icUInt8Number *elseTemps = (icUInt8Number *)malloc(nMaxTemp);
3822 if (!elseTemps) {
3823 free(ifTemps);
3824 return true;
3825 }
3826
3827 memcpy(elseTemps, tempUsage, nMaxTemp);
3828
3829 p=i+2+op[i].data.size;
3830 rv = rv || SequenceNeedTempReset(&op[p], icIntMin(nOps-p, op[i+1].data.size), elseTemps, nMaxTemp);
3831
3832 if (!rv) {
3833 for (j=0; j<nMaxTemp; j++) {
3834 tempUsage[j] |= (ifTemps[j] && elseTemps[j]);
3835 }
3836 }
3837
3838 free(elseTemps);
3839
3840 i += 1 + op[i].data.size + op[i+1].data.size;
3841 }
3842 else {
3843 i += op[i].data.size;
3844 }
3845
3846 free(ifTemps);
3847
3848 if (rv)
3849 return true;
3850 }
3851 }
3852 return false;
3853}
3854
3855
3856/**
3857******************************************************************************
3858* Name: CIccCalculatorFunc::CheckUnderflow
3859*
3860* Purpose:
3861*
3862* Args:
3863*
3864* Return:
3865******************************************************************************/
3866int CIccCalculatorFunc::CheckUnderflowOverflow(SIccCalcOp *op, icUInt32Number nOps, int nArgs, bool bCheckUnderflow, std::string &sReport) const
3867{
3868 icUInt32Number i, p;
3869 int n, nIfArgs, nElseArgs, nSelArgs, nCaseArgs;
3870
3871 for (i=0; i<nOps; i++) {
3872 n = op[i].ArgsUsed(m_pCalc);
3873
3874#if 0
3875 std::string opstr;
3876 op[i].Describe(opstr);
3877 printf("%s : %d %d\n", opstr.c_str(), n, nArgs);
3878#endif
3879
3880 if (n > nArgs) {
3881 std::string opDesc;
3882 icUInt32Number j, l;
3883 icInt32Number f;
3884
3885 op[i].Describe(opDesc);
3886 sReport += "Stack underflow at operation \"" + opDesc + "\" in \"";
3887 f=i-2;
3888 if (f<0) f=0;
3889 l=i+2;
3890 if (l>nOps-1)
3891 l=nOps-1;
3892 for (j=(icUInt32Number)f; j<=l; j++) {
3893 op[j].Describe(opDesc);
3894 if (j!=f)
3895 sReport += " ";
3896 sReport += opDesc;
3897 }
3898 sReport += "\"\r\n";
3899 return -1;
3900 }
3901
3902 nArgs -= n;
3903 nArgs += op[i].ArgsPushed(m_pCalc);
3904
3905 if (nArgs>icMaxDataStackSize65535)
3906 return -2;
3907
3908 if (op[i].sig == icSigIfOp) {
3909 int incI = 0;
3910 if (i+1<nOps && op[i+1].sig==icSigElseOp) {
3911 p = i+2;
3912 nIfArgs = CheckUnderflowOverflow(&op[p], icIntMin(nOps-p, op[i].data.size), nArgs, bCheckUnderflow, sReport);
3913 if (nIfArgs<0)
3914 return -1;
3915 incI =op[i].data.size;
3916
3917 p = i+2+op[i].data.size;
3918 nElseArgs = CheckUnderflowOverflow(&op[p], icIntMin(nOps-p, op[i+1].data.size), nArgs, bCheckUnderflow, sReport);
3919 if (nElseArgs<0)
3920 return -1;
3921 incI += op[i+1].data.size;
3922
3923 nArgs = bCheckUnderflow ? icIntMin(nIfArgs, nElseArgs) : icIntMax(nIfArgs, nElseArgs) ;
3924 i++;
3925 i+=incI;
3926 }
3927 else {
3928 p = i+1;
3929 nIfArgs = CheckUnderflowOverflow(&op[p], icIntMin(nOps-p, op[i].data.size), nArgs, bCheckUnderflow, sReport);
3930 if (nIfArgs<0)
3931 return -1;
3932 nArgs = bCheckUnderflow ? icIntMin(nArgs, nIfArgs) : icIntMax(nArgs, nIfArgs);
3933
3934 i+= op[i].data.size;
3935 }
3936 }
3937 else if (op[i].sig == icSigSelectOp) {
3938 icUInt32Number n;
3939 nSelArgs = nArgs;
3940
3941 for (n=1; i+n<nOps; ) {
3942 if (op[i+n].sig==icSigCaseOp)
3943 n++;
3944 else if (n>1 && op[i+n].sig==icSigDefaultOp) {
3945 n++;
3946 break;
3947 }
3948 else
3949 break;
3950 }
3951 n--;
3952
3953 if (!n)
3954 return -1;
3955
3956 icUInt32Number pos = i+1 + n;
3957 for (p=0; p<n; p++) {
3958 SIccCalcOp *sop = &op[i+1+p];
3959 int len = sop->data.size;
3960 if (pos>=nOps)
3961 return -1;
3962
3963 nCaseArgs = CheckUnderflowOverflow(&op[pos], icIntMin(nOps-pos, len), nArgs, bCheckUnderflow, sReport);
3964 if (nCaseArgs<0)
3965 return -1;
3966
3967 if (!p)
3968 nSelArgs = nCaseArgs;
3969 else
3970 nSelArgs = bCheckUnderflow ? icIntMin(nSelArgs, nCaseArgs) : icIntMax(nSelArgs, nCaseArgs);
3971
3972 pos += sop->data.size;
3973 }
3974 nArgs = nSelArgs;
3975
3976 i = pos - 1;
3977 }
3978 }
3979
3980 return nArgs;
3981}
3982
3983/**
3984******************************************************************************
3985* Name: CIccCalculatorFunc::DoesStackUnderflowOverflow
3986*
3987* Purpose:
3988*
3989* Args:
3990*
3991* Return:
3992******************************************************************************/
3993icFuncParseStatus CIccCalculatorFunc::DoesStackUnderflowOverflow(std::string &sReport) const
3994{
3995 int rv = CheckUnderflowOverflow(m_Op, m_nOps, 0, true, sReport);
3996
3997 if (rv==-1)
3998 return icFuncParseStackUnderflow;
3999 else if (rv<0)
4000 return icFuncParseStackOverflow;
4001
4002 rv = CheckUnderflowOverflow(m_Op, m_nOps, 0, false, sReport);
4003
4004 if (rv==-1)
4005 return icFuncParseStackUnderflow;
4006 else if (rv<0)
4007 return icFuncParseStackOverflow;
4008
4009 return icFuncParseNoError;
4010}
4011
4012/**
4013******************************************************************************
4014* Name: CIccCalculatorFunc::HasValidOperations
4015*
4016* Purpose:
4017*
4018* Args:
4019*
4020* Return:
4021******************************************************************************/
4022bool CIccCalculatorFunc::HasValidOperations(std::string &sReport) const
4023{
4024 icUInt32Number i;
4025 for (i=0; i<m_nOps; i++) {
4026 if (!m_Op[i].IsValidOp(m_pCalc)) {
4027 std::string opDesc;
4028 m_Op[i].Describe(opDesc);
4029 sReport += "Invalid Operation (" + opDesc + ")\r\n";
4030 return false;
4031 }
4032 if (m_Op[i].sig==icSigSelectOp && i+1<m_nOps && m_Op[i+1].sig!=icSigCaseOp) {
4033 sReport += "A case operator does not follow a sel operator\r\n";
4034 return false;
4035 }
4036 if (i) {
4037 if (m_Op[i].sig==icSigElseOp) {
4038 if (m_Op[i-1].sig!=icSigIfOp) {
4039 sReport += "An else operator has no proceeding if operator\r\n";
4040 return false;
4041 }
4042 }
4043 else if (m_Op[i].sig==icSigCaseOp) {
4044 if (m_Op[i-1].sig!=icSigSelectOp && m_Op[i-1].sig!=icSigCaseOp) {
4045 sReport += "A case operator has no proceeding sel or case operator\r\n";
4046 return false;
4047 }
4048 }
4049 else if (m_Op[i].sig==icSigDefaultOp) {
4050 if (m_Op[i-1].sig!=icSigCaseOp) {
4051 sReport += "An dflt operator has no proceeding case operator\r\n";
4052 return false;
4053 }
4054 }
4055 }
4056 }
4057 return true;
4058}
4059
4060/**
4061******************************************************************************
4062* Name: CIccChannelFunc::DoesOverflowInput
4063*
4064* Purpose:
4065*
4066* Args:
4067*
4068* Return:
4069******************************************************************************/
4070bool CIccCalculatorFunc::DoesOverflowInput(icUInt16Number nInputChannels) const
4071{
4072 icUInt32Number i;
4073 for (i=0; i<m_nOps; i++) {
4074 if (m_Op[i].sig == icSigInputChanOp) {
4075 if (m_Op[i].data.select.v1+m_Op[i].data.select.v2 >= nInputChannels)
4076 return true;
4077 }
4078 }
4079 return false;
4080}
4081
4082
4083/**
4084******************************************************************************
4085* Name: CIccChannelFunc::DoesOverflowOutput
4086*
4087* Purpose:
4088*
4089* Args:
4090*
4091* Return:
4092******************************************************************************/
4093bool CIccCalculatorFunc::DoesOverflowOutput(icUInt16Number nOutputChannels) const
4094{
4095 icUInt32Number i;
4096 for (i=0; i<m_nOps; i++) {
4097 if (m_Op[i].sig == icSigOutputChanOp) {
4098 if (m_Op[i].data.select.v1 + m_Op[i].data.select.v2 >= nOutputChannels)
4099 return true;
4100 }
4101 }
4102 return false;
4103}
4104
4105
4106/**
4107 ******************************************************************************
4108 * Name: CIccMpeCalculator::CIccMpeCalculator
4109 *
4110 * Purpose:
4111 *
4112 * Args:
4113 *
4114 * Return:
4115 ******************************************************************************/
4116CIccMpeCalculator::CIccMpeCalculator(icUInt16Number nInputChannels /*=0*/,
4117 icUInt16Number nOutputChannels /*=0*/)
4118{
4119 m_nReserved = 0;
4120 m_nInputChannels = nInputChannels;
4121 m_nOutputChannels = nOutputChannels;
4122 m_nTempChannels = 0;
4123 m_bNeedTempReset = true;
4124 m_nSubElem = 0;
4125 m_SubElem = NULL__null;
4126 m_calcFunc = NULL__null;
4127 m_pCmmEnvVarLookup = NULL__null;
4128}
4129
4130/**
4131 ******************************************************************************
4132 * Name: CIccMpeCalculator::CIccMpeCalculator
4133 *
4134 * Purpose:
4135 *
4136 * Args:
4137 *
4138 * Return:
4139 ******************************************************************************/
4140CIccMpeCalculator::CIccMpeCalculator(const CIccMpeCalculator &channelGen)
4141{
4142 m_nReserved = channelGen.m_nReserved;
4143
4144 m_nInputChannels = channelGen.m_nInputChannels;
4145 m_nOutputChannels = channelGen.m_nOutputChannels;
4146 m_nTempChannels = channelGen.m_nTempChannels;
4147
4148 m_pCmmEnvVarLookup = channelGen.m_pCmmEnvVarLookup;
4149
4150 m_nSubElem = channelGen.m_nSubElem;
4151 m_bNeedTempReset = channelGen.m_bNeedTempReset;
4152
4153 m_pCmmEnvVarLookup = channelGen.m_pCmmEnvVarLookup;
4154
4155 icCalculatorFuncPtr ptr = channelGen.m_calcFunc;
4156
4157 if (ptr)
4158 m_calcFunc = ptr->NewCopy();
4159 else
4160 m_calcFunc = NULL__null;
4161
4162 if (channelGen.m_nSubElem) {
4163 icUInt32Number i;
4164
4165 m_SubElem = (CIccMultiProcessElement**)calloc(m_nSubElem, sizeof(CIccMultiProcessElement*));
4166 if (m_SubElem) {
4167 for (i=0; i<m_nSubElem; i++) {
4168 if (channelGen.m_SubElem[i])
4169 m_SubElem[i] = channelGen.m_SubElem[i]->NewCopy();
4170 }
4171 }
4172 else {
4173 m_nSubElem = 0;
4174 m_SubElem = NULL__null;
4175 }
4176 }
4177 else {
4178 m_nSubElem = 0;
4179 m_SubElem = NULL__null;
4180 }
4181}
4182
4183/**
4184 ******************************************************************************
4185 * Name: &CIccMpeCalculator::operator=
4186 *
4187 * Purpose:
4188 *
4189 * Args:
4190 *
4191 * Return:
4192 ******************************************************************************/
4193CIccMpeCalculator &CIccMpeCalculator::operator=(const CIccMpeCalculator &channelGen)
4194{
4195 m_nReserved = channelGen.m_nReserved;
4196
4197 SetSize(0,0);
4198
4199 m_nInputChannels= channelGen.m_nInputChannels;
4200 m_nOutputChannels = channelGen.m_nOutputChannels;
4201
4202 m_pCmmEnvVarLookup = channelGen.m_pCmmEnvVarLookup;
4203
4204 icCalculatorFuncPtr ptr = channelGen.m_calcFunc;
4205
4206 if (ptr)
4207 m_calcFunc = ptr->NewCopy();
4208 else
4209 m_calcFunc = NULL__null;
4210
4211 if (channelGen.m_nSubElem) {
4212 icUInt32Number i;
4213
4214 m_SubElem = (CIccMultiProcessElement**)calloc(m_nSubElem, sizeof(CIccMultiProcessElement*));
4215 if (m_SubElem) {
4216 for (i=0; i<m_nSubElem; i++) {
4217 if (channelGen.m_SubElem[i])
4218 m_SubElem[i] = channelGen.m_SubElem[i]->NewCopy();
4219 }
4220 }
4221 else {
4222 m_nSubElem = 0;
4223 m_SubElem = NULL__null;
4224 }
4225 }
4226 else {
4227 m_nSubElem = 0;
4228 m_SubElem = NULL__null;
4229 }
4230
4231 return *this;
4232}
4233
4234/**
4235 ******************************************************************************
4236 * Name: CIccMpeCalculator::~CIccMpeCalculator
4237 *
4238 * Purpose:
4239 *
4240 * Args:
4241 *
4242 * Return:
4243 ******************************************************************************/
4244CIccMpeCalculator::~CIccMpeCalculator()
4245{
4246 SetSize(0,0);
4247}
4248
4249/**
4250 ******************************************************************************
4251 * Name: CIccMpeCalculator::SetSize
4252 *
4253 * Purpose:
4254 *
4255 * Args:
4256 *
4257 * Return:
4258 ******************************************************************************/
4259void CIccMpeCalculator::SetSize(icUInt16Number nInputChannels, icUInt16Number nOutputChannels)
4260{
4261 if (m_calcFunc) {
4262 delete m_calcFunc;
4263 m_calcFunc = NULL__null;
4264 }
4265 icUInt32Number i;
4266
4267 if (m_SubElem) {
4268 for (i=0; i<m_nSubElem; i++) {
4269 if (m_SubElem[i])
4270 delete m_SubElem[i];
4271 }
4272 free(m_SubElem);
4273 m_SubElem = NULL__null;
4274 m_nSubElem = 0;
4275 }
4276
4277 m_nInputChannels = nInputChannels;
4278 m_nOutputChannels = nOutputChannels;
4279}
4280
4281/**
4282 ******************************************************************************
4283 * Name: CIccMpeCalculator::SetCalcFunc
4284 *
4285 * Purpose:
4286 *
4287 * Args:
4288 *
4289 * Return:
4290 ******************************************************************************/
4291icFuncParseStatus CIccMpeCalculator::SetCalcFunc(icCalculatorFuncPtr newChannelFunc)
4292{
4293 if (m_calcFunc) {
4294 delete m_calcFunc;
4295 }
4296 m_calcFunc = newChannelFunc;
4297
4298 return icFuncParseNoError;
4299}
4300
4301/**
4302******************************************************************************
4303* Name: CIccMpeCalculator::SetCalcFunc
4304*
4305* Purpose:
4306*
4307* Args:
4308*
4309* Return:
4310******************************************************************************/
4311icFuncParseStatus CIccMpeCalculator::SetCalcFunc(const char *szFuncDef, std::string &sReport)
4312{
4313
4314 if (m_calcFunc) {
4315 delete m_calcFunc;
4316 m_calcFunc = NULL__null;
4317 }
4318
4319 CIccCalculatorFunc *pFunc = new CIccCalculatorFunc(this);
4320 icFuncParseStatus rv = pFunc->SetFunction(szFuncDef, sReport);
4321
4322 if (rv!=icFuncParseNoError) {
4323 delete pFunc;
4324 m_calcFunc = NULL__null;
4325
4326 return rv;
4327 }
4328
4329 m_calcFunc = pFunc;
4330
4331 return rv;
4332}
4333
4334
4335/**
4336 ******************************************************************************
4337 * Name: CIccMpeCalculator::Describe
4338 *
4339 * Purpose:
4340 *
4341 * Args:
4342 *
4343 * Return:
4344 ******************************************************************************/
4345void CIccMpeCalculator::Describe(std::string &sDescription)
4346{
4347 if (m_calcFunc) {
4348 icChar buf[81];
4349
4350 sprintf(buf, "BEGIN_CALC_ELEMENT %u %u\r\n", m_nInputChannels, m_nOutputChannels);
4351 sDescription += buf;
4352
4353 if (m_nSubElem && m_SubElem) {
4354 icUInt32Number i;
4355 for (i=0; i<m_nSubElem; i++) {
4356 sprintf(buf, "BEGIN_SUBCALCELEM %u\r\n", i);
4357 sDescription += buf;
4358 m_SubElem[i]->Describe(sDescription);
4359 sprintf(buf, "END_SUBCALCELEM %u\r\n\r\n", i);
4360 sDescription += buf;
4361 }
4362 }
4363
4364 if (m_calcFunc) {
4365 sDescription += "BEGIN_CALC_FUNCTION\r\n";
4366 m_calcFunc->Describe(sDescription);
4367 sDescription += "END_CALC_FUNCTION\r\n";
4368 }
4369
4370 sprintf(buf, "END_CALC_ELEMENT\r\n");
4371 sDescription += buf;
4372
4373 }
4374}
4375
4376typedef std::map<icUInt32Number, CIccCalculatorFunc*> icChannelFuncOffsetMap;
4377typedef std::map<CIccCalculatorFunc*, icPositionNumber> icChannelFuncPtrMap;
4378
4379/**
4380 ******************************************************************************
4381 * Name: CIccMpeCalculator::Read
4382 *
4383 * Purpose:
4384 *
4385 * Args:
4386 *
4387 * Return:
4388 ******************************************************************************/
4389bool CIccMpeCalculator::Read(icUInt32Number size, CIccIO *pIO)
4390{
4391 icElemTypeSignature sig;
4392
4393 icUInt32Number startPos = pIO->Tell();
4394
4395 icUInt32Number headerSize = sizeof(icTagTypeSignature) +
4396 sizeof(icUInt32Number) +
4397 sizeof(icUInt16Number) +
4398 sizeof(icUInt16Number) +
4399 sizeof(icUInt16Number) +
4400 sizeof(icUInt16Number) +
4401 sizeof(icUInt16Number) +
4402 sizeof(icUInt16Number);
4403
4404 if (headerSize > size)
4405 return false;
4406
4407 if (!pIO) {
4408 return false;
4409 }
4410
4411 icUInt16Number nInputChannels, nOutputChannels;
4412
4413 if (!pIO->Read32(&sig))
4414 return false;
4415
4416 if (!pIO->Read32(&m_nReserved))
4417 return false;
4418
4419 if (!pIO->Read16(&nInputChannels))
4420 return false;
4421
4422 if (!pIO->Read16(&nOutputChannels))
4423 return false;
4424
4425 SetSize(nInputChannels, nOutputChannels);
4426
4427 icUInt32Number nSubElem;
4428
4429 if (!pIO->Read32(&nSubElem))
4430 return false;
4431
4432 icUInt32Number nPos = nSubElem + 1;
4433
4434 if (headerSize + (icUInt64Number)nPos*sizeof(icPositionNumber) > size) {
4435 return false;
4436 }
4437
4438 icPositionNumber *pos, *posvals = (icPositionNumber*)malloc(nPos*sizeof(icPositionNumber));
4439 if (!posvals) {
4440 return false;
4441 }
4442
4443 icUInt32Number n = nPos * (sizeof(icPositionNumber)/sizeof(icUInt32Number));
4444 if (pIO->Read32(posvals, n)!=n) {
4445 free(posvals);
4446 return false;
4447 }
4448
4449 pos = &posvals[1];
4450 if (nSubElem) {
4451 icElemTypeSignature elemSig;
4452
4453 SetSubElem(nSubElem-1, NULL__null); //Initialize array
4454
4455 for (n=0; n<nSubElem; n++) {
4456 if (pos->offset + pos->size > size) {
4457 free(posvals);
4458 return false;
4459 }
4460 pIO->Seek(startPos + pos->offset, icSeekSet);
4461
4462 if (!pIO->Read32(&elemSig)) {
4463 free(posvals);
4464 return false;
4465 }
4466
4467 CIccMultiProcessElement *pElem = CIccMultiProcessElement::Create(elemSig);
4468 if (!pElem) {
4469 free(posvals);
4470 return false;
4471 }
4472
4473 pIO->Seek(startPos + pos->offset, icSeekSet);
4474 if (!pElem->Read(pos->size, pIO)) {
4475 free(posvals);
4476 return false;
4477 }
4478 SetSubElem((icUInt16Number)n, (CIccMpeCalculator*)pElem);
4479 pos++;
4480 }
4481 }
4482
4483 m_calcFunc = new CIccCalculatorFunc(this);
4484 pos = posvals;
4485
4486 if (!m_calcFunc || pos->offset + pos->size > size) {
4487 free(posvals);
4488 return false;
4489 }
4490
4491 pIO->Seek(startPos + pos->offset, icSeekSet);
4492
4493 if (!m_calcFunc->Read(pos->size, pIO)) {
4494 return false;
4495 }
4496 free(posvals);
4497
4498 pIO->Seek(startPos + size, icSeekSet);
4499
4500 return true;
4501}
4502
4503/**
4504 ******************************************************************************
4505 * Name: CIccMpeCalculator::Write
4506 *
4507 * Purpose:
4508 *
4509 * Args:
4510 *
4511 * Return:
4512 ******************************************************************************/
4513bool CIccMpeCalculator::Write(CIccIO *pIO)
4514{
4515 icElemTypeSignature sig = GetType();
4516
4517 if (!pIO)
4518 return false;
4519
4520 icUInt32Number elemStart = pIO->Tell();
4521
4522 if (!pIO->Write32(&sig))
4523 return false;
4524
4525 if (!pIO->Write32(&m_nReserved))
4526 return false;
4527
4528 if (!pIO->Write16(&m_nInputChannels))
4529 return false;
4530
4531 if (!pIO->Write16(&m_nOutputChannels))
4532 return false;
4533
4534 if (!pIO->Write32(&m_nSubElem))
4535 return false;
4536
4537 icUInt32Number nPos = m_nSubElem + 1;
4538
4539 icPositionNumber *pos, *posvals = (icPositionNumber*)calloc(nPos, sizeof(icPositionNumber));
4540 if (!posvals) {
4541 return false;
4542 }
4543 icUInt32Number nPositionStart = pIO->Tell();
4544
4545 icUInt32Number n, np = nPos * (sizeof(icPositionNumber)/sizeof(icUInt32Number));
4546 if (pIO->Write32(posvals, np)!=np) {
4547 free(posvals);
4548 return false;
4549 }
4550
4551 if (m_calcFunc) {
4552 posvals[0].offset = pIO->Tell()-elemStart;
4553 if (!m_calcFunc->Write(pIO)) {
4554 free(posvals);
4555 return false;
4556 }
4557 posvals[0].size = pIO->Tell()-elemStart - posvals[nPos-1].offset;
4558 pIO->Align32();
4559 }
4560
4561 pos = &posvals[1];
4562
4563 if (m_nSubElem) {
4564 for(n=0; n<m_nSubElem; n++) {
4565 if (m_SubElem[n]) {
4566 pos->offset = pIO->Tell()-elemStart;
4567 if (!m_SubElem[n]->Write(pIO)) {
4568 free(posvals);
4569 return false;
4570 }
4571 pos->size = pIO->Tell()-elemStart - pos->offset;
4572 pIO->Align32();
4573 }
4574 pos++;
4575 }
4576 }
4577 icUInt32Number endPos = pIO->Tell();
4578
4579 pIO->Seek(nPositionStart, icSeekSet);
4580
4581 if (pIO->Write32(posvals, np)!=np) {
4582 free(posvals);
4583 return false;
4584 }
4585 free(posvals);
4586
4587 pIO->Seek(endPos, icSeekSet);
4588
4589 return true;
4590}
4591
4592/**
4593 ******************************************************************************
4594 * Name: CIccMpeCalculator::Begin
4595 *
4596 * Purpose:
4597 *
4598 * Args:
4599 *
4600 * Return:
4601 ******************************************************************************/
4602bool CIccMpeCalculator::Begin(icElemInterp nInterp, CIccTagMultiProcessElement *pMPE)
4603{
4604 if (!m_calcFunc)
4605 return false;
4606
4607 m_nTempChannels = m_calcFunc->GetMaxTemp()+1;
4608
4609 m_pCmmEnvVarLookup = pMPE->GetCmmEnvLookup();
4610
4611 if (m_nTempChannels>65536)
4612 return false;
4613
4614 if (m_nTempChannels) {
4615 icUInt8Number *tempUsage = (icUInt8Number *)calloc(m_nTempChannels, sizeof(icUInt8Number));
4616 if (tempUsage) {
4617 m_bNeedTempReset = m_calcFunc->NeedTempReset(tempUsage, m_nTempChannels);
4618 free(tempUsage);
4619 }
4620 else
4621 m_bNeedTempReset = true;
4622 }
4623 else {
4624 m_bNeedTempReset = false;
4625 }
4626
4627 if (!m_calcFunc->Begin(this, pMPE))
4628 return false;
4629
4630 icUInt32Number n;
4631 for (n=0; n<m_nSubElem; n++) {
4632 if (m_SubElem[n] && !m_SubElem[n]->Begin(nInterp, pMPE))
4633 return false;
4634 }
4635
4636 return true;
4637}
4638
4639/**
4640******************************************************************************
4641* Name: CIccMpeCalculator::Begin
4642*
4643* Purpose:
4644*
4645* Args:
4646*
4647* Return:
4648******************************************************************************/
4649CIccApplyMpe *CIccMpeCalculator::GetNewApply(CIccApplyTagMpe *pApplyTag)
4650{
4651 CIccApplyTagMpe *pApplyTagEx = (CIccApplyTagMpe*)pApplyTag;
4652
4653 CIccApplyMpeCalculator *pApply = new CIccApplyMpeCalculator(this);
4654
4655 if (!pApply)
4656 return NULL__null;
4657
4658 if (m_nTempChannels) {
4659 pApply->m_temp = (icFloatNumber*)malloc(m_nTempChannels*sizeof(icFloatNumber));
4660 }
4661 pApply->m_stack = new CIccFloatVector;
4662 pApply->m_scratch = new CIccFloatVector;
4663 pApply->m_scratch->resize(50);
4664 pApply->m_pCmmEnvVarLookup = m_pCmmEnvVarLookup;
4665
4666 icUInt32Number i;
4667
4668 pApply->m_nSubElem = m_nSubElem;
4669 if(m_nSubElem) {
4670 pApply->m_SubElem = (CIccSubCalcApply **)calloc(m_nSubElem, sizeof(CIccSubCalcApply));
4671
4672 if (m_SubElem) {
4673 for (i=0; i<m_nSubElem; i++) {
4674 if (m_SubElem[i]) {
4675 pApply->m_SubElem[i] = new CIccSubCalcApply(m_SubElem[i]->GetNewApply(pApplyTag));
4676 }
4677 }
4678 }
4679 }
4680 else {
4681 m_SubElem=NULL__null;
4682 }
4683 return pApply;
4684}
4685
4686
4687/**
4688 ******************************************************************************
4689 * Name: CIccMpeCalculator::Apply
4690 *
4691 * Purpose:
4692 *
4693 * Args:
4694 *
4695 * Return:
4696 ******************************************************************************/
4697void CIccMpeCalculator::Apply(CIccApplyMpe *pApply, icFloatNumber *pDestPixel, const icFloatNumber *pSrcPixel) const
4698{
4699 CIccApplyMpeCalculator *pApplyCalc = (CIccApplyMpeCalculator*)pApply;
4700 icFloatNumber *pSrcTemp = pApplyCalc->m_temp;
4701 bool rv;
4702
4703 pApplyCalc->m_temp = pSrcTemp;
4704 pApplyCalc->m_input = pSrcPixel;
4705 pApplyCalc->m_output = pDestPixel;
4706
4707 if (m_bNeedTempReset) {
4708 memset(pSrcTemp, 0, m_nTempChannels*sizeof(icFloatNumber));
4709 }
4710
4711 if (g_pDebugger) {
4712 g_pDebugger->BeginApply();
4713 rv = m_calcFunc->Apply(pApplyCalc);
4714 if (!rv)
4715 g_pDebugger->Error("Calc Function Apply Terminated with an error!");
4716
4717 g_pDebugger->EndApply();
4718 }
4719 else {
4720 rv = m_calcFunc->Apply(pApplyCalc);
Value stored to 'rv' is never read
4721 }
4722}
4723
4724/**
4725 ******************************************************************************
4726 * Name: CIccMpeCalculator::Validate
4727 *
4728 * Purpose:
4729 *
4730 * Args:
4731 *
4732 * Return:
4733 ******************************************************************************/
4734icValidateStatus CIccMpeCalculator::Validate(std::string sigPath, std::string &sReport, const CIccTagMultiProcessElement* pMPE/*=NULL*/) const
4735{
4736 std::string mpeSigPath = sigPath + icGetSigPath(GetType());
4737 icValidateStatus rv = CIccMultiProcessElement::Validate(sigPath, sReport, pMPE);
4738
4739 icUInt32Number i;
4740
4741 if (m_SubElem) {
4742 for (i=0; i<m_nSubElem; i++) {
4743 if (m_SubElem[i])
4744 rv = icMaxStatus(rv, m_SubElem[i]->Validate(mpeSigPath, sReport, pMPE));
4745 }
4746 }
4747
4748 bool empty=false;
4749 if (m_calcFunc) {
4750 rv = icMaxStatus(rv, m_calcFunc->Validate(mpeSigPath, sReport, this));
4751 }
4752 else
4753 empty = true;
4754
4755 if (empty) {
4756 CIccInfo Info;
4757 std::string sSigPathName = Info.GetSigPathName(sigPath);
4758
4759 sReport += icMsgValidateCriticalError;
4760 sReport += sSigPathName;
4761 sReport += " - Has an Empty Calculator Functions!\r\n";
4762 rv = icMaxStatus(rv, icValidateCriticalError);
4763 }
4764
4765 return rv;
4766}
4767
4768
4769/**
4770 ******************************************************************************
4771 * Name: CIccMpeCalculator::IsLateBinding
4772 *
4773 * Purpose:
4774 *
4775 * Args:
4776 *
4777 * Return:
4778 ******************************************************************************/
4779bool CIccMpeCalculator::IsLateBinding() const
4780{
4781 icUInt32Number i;
4782
4783 if (m_SubElem) {
4784 for (i=0; i<m_nSubElem; i++) {
4785 if (m_SubElem[i] && m_SubElem[i]->IsLateBinding())
4786 return true;
4787 }
4788 }
4789
4790 return false;
4791}
4792
4793/**
4794 ******************************************************************************
4795 * Name: CIccMpeCalculator::IsLateBindingReflectance
4796 *
4797 * Purpose:
4798 *
4799 * Args:
4800 *
4801 * Return:
4802 ******************************************************************************/
4803bool CIccMpeCalculator::IsLateBindingReflectance() const
4804{
4805 icUInt32Number i;
4806
4807 if (m_SubElem) {
4808 for (i=0; i<m_nSubElem; i++) {
4809 if (m_SubElem[i] && m_SubElem[i]->IsLateBindingReflectance())
4810 return true;
4811 }
4812 }
4813
4814 return false;
4815}
4816
4817
4818/**
4819******************************************************************************
4820* Name: CIccMpeCalculator::GetSubApply
4821*
4822* Purpose:
4823*
4824* Args:
4825*
4826* Return:
4827******************************************************************************/
4828CIccMultiProcessElement *CIccMpeCalculator::GetElem(icSigCalcOp opsig, icUInt16Number index)
4829{
4830 if (m_SubElem && index<m_nSubElem) {
4831 CIccMultiProcessElement *pMpe = m_SubElem[index];
4832 if (opsig==icSigApplyElemOp)
4833 return pMpe;
4834
4835 if ((opsig==icSigApplyCurvesOp && pMpe->GetType() != icSigCurveSetElemType) ||
4836 (opsig==icSigApplyMatrixOp && pMpe->GetType() != icSigMatrixElemType) ||
4837 (opsig==icSigApplyCLutOp && !(pMpe->GetType() == icSigCLutElemType || pMpe->GetType() == icSigExtCLutElemType)) ||
4838 (opsig==icSigApplyTintOp && pMpe->GetType() != icSigTintArrayElemType) ||
4839 (opsig==icSigApplyToJabOp && pMpe->GetType() != icSigXYZToJabElemType) ||
4840 (opsig==icSigApplyFromJabOp && pMpe->GetType() != icSigJabToXYZElemType) ||
4841 (opsig==icSigApplyCalcOp && pMpe->GetType() != icSigCalculatorElemType))
4842 return NULL__null;
4843
4844 return pMpe;
4845 }
4846
4847 return NULL__null;
4848}
4849
4850
4851/**
4852******************************************************************************
4853* Name: CIccMpeCalculator::GetSubApply
4854*
4855* Purpose:
4856*
4857* Args:
4858*
4859* Return:
4860******************************************************************************/
4861bool CIccMpeCalculator::SetElem(icUInt32Number idx, CIccMultiProcessElement *pElem, icUInt32Number &count, CIccMultiProcessElement ***pArray)
4862{
4863 bool rv = true;
4864
4865 if (idx+1>count) {
4866 if (*pArray) {
4867 *pArray = (CIccMultiProcessElement**)icRealloc(*pArray, (idx+1)*sizeof(CIccMultiProcessElement*));
4868
4869 if (!(*pArray))
4870 return false;
4871
4872 icUInt32Number i;
4873 for (i=count; i<=idx; i++) {
4874 (*pArray)[i] = NULL__null;
4875 }
4876 }
4877 else {
4878 *pArray = (CIccMultiProcessElement**)calloc(idx+1, sizeof(CIccMultiProcessElement*));
4879
4880 if (!(*pArray))
4881 return false;
4882 }
4883 count = idx+1;
4884 }
4885
4886 if ((*pArray)[idx]) {
4887 delete (*pArray)[idx];
4888 rv = false;
4889 }
4890
4891 (*pArray)[idx] = pElem;
4892
4893 return rv;
4894}
4895
4896/**
4897******************************************************************************
4898* Name: CIccMpeCalculator::CIccApplyMpeCalculator
4899*
4900* Purpose:
4901*
4902* Args:
4903*
4904* Return:
4905******************************************************************************/
4906CIccApplyMpeCalculator::CIccApplyMpeCalculator(CIccMultiProcessElement *pElem) : CIccApplyMpe(pElem)
4907{
4908 m_temp = NULL__null;
4909
4910 m_input = NULL__null;
4911 m_output = NULL__null;
4912
4913 m_stack = NULL__null;
4914 m_scratch = NULL__null;
4915
4916 m_nSubElem = 0;
4917 m_SubElem = NULL__null;
4918
4919}
4920
4921
4922/**
4923******************************************************************************
4924* Name: CIccMpeCalculator::~CIccApplyMpeCalculator
4925*
4926* Purpose:
4927*
4928* Args:
4929*
4930* Return:
4931******************************************************************************/
4932CIccApplyMpeCalculator::~CIccApplyMpeCalculator()
4933{
4934 if (m_stack) {
4935 delete m_stack;
4936 }
4937 if (m_scratch) {
4938 delete m_scratch;
4939 }
4940
4941 if (m_temp) {
4942 free(m_temp);
4943 }
4944
4945 icUInt32Number i;
4946
4947 if (m_SubElem) {
4948 for (i=0; i<m_nSubElem; i++) {
4949 if (m_SubElem[i])
4950 delete m_SubElem[i];
4951 }
4952 }
4953}
4954
4955/**
4956******************************************************************************
4957* Name: CIccApplyMpeCalculator::GetSubApply
4958*
4959* Purpose:
4960*
4961* Args:
4962*
4963* Return:
4964******************************************************************************/
4965CIccSubCalcApply *CIccApplyMpeCalculator::GetApply(icUInt16Number index)
4966{
4967 if (m_SubElem && index<m_nSubElem)
4968 return m_SubElem[index];
4969
4970 return NULL__null;
4971}
4972
4973
4974/**
4975******************************************************************************
4976* Name: CIccApplyMpeCalculator::GetSubApply
4977*
4978* Purpose:
4979*
4980* Args:
4981*
4982* Return:
4983******************************************************************************/
4984bool CIccApplyMpeCalculator::GetEnvVar(icSigCmmEnvVar sigEnv, icFloatNumber &val)
4985{
4986 if (!m_pCmmEnvVarLookup) {
4987 val = 0;
4988 return false;
4989 }
4990 return m_pCmmEnvVarLookup->GetEnvVar(sigEnv, val);
4991}
4992
4993
4994