1 //========================================================================
2 //
3 // Function.h
4 //
5 // Copyright 2001-2003 Glyph & Cog, LLC
6 //
7 //========================================================================
8 
9 #ifndef FUNCTION_H
10 #define FUNCTION_H
11 
12 #include <aconf.h>
13 
14 #ifdef USE_GCC_PRAGMAS
15 #pragma interface
16 #endif
17 
18 #include "gtypes.h"
19 #include "Object.h"
20 
21 class GList;
22 class Dict;
23 class Stream;
24 struct PSCode;
25 
26 //------------------------------------------------------------------------
27 // Function
28 //------------------------------------------------------------------------
29 
30 #define funcMaxInputs        32
31 #define funcMaxOutputs       32
32 #define sampledFuncMaxInputs 16
33 
34 class Function {
35 public:
36 
37     Function();
38 
39     virtual ~Function();
40 
41     // Construct a function.  Returns NULL if unsuccessful.
42     static Function *parse(Object *funcObj, int recursion = 0);
43 
44     // Initialize the entries common to all function types.
45     GBool init(Dict *dict);
46 
47     virtual Function *copy() = 0;
48 
49     // Return the function type:
50     //   -1 : identity
51     //    0 : sampled
52     //    2 : exponential
53     //    3 : stitching
54     //    4 : PostScript
55     virtual int getType() = 0;
56 
57     // Return size of input and output tuples.
getInputSize()58     int getInputSize() {
59         return m;
60     }
getOutputSize()61     int getOutputSize() {
62         return n;
63     }
64 
getDomainMin(int i)65     double getDomainMin(int i) {
66         return domain[i][0];
67     }
getDomainMax(int i)68     double getDomainMax(int i) {
69         return domain[i][1];
70     }
getRangeMin(int i)71     double getRangeMin(int i) {
72         return range[i][0];
73     }
getRangeMax(int i)74     double getRangeMax(int i) {
75         return range[i][1];
76     }
getHasRange()77     GBool getHasRange() {
78         return hasRange;
79     }
80 
81     // Transform an input tuple into an output tuple.
82     virtual void transform(double *in, double *out) = 0;
83 
84     virtual GBool isOk() = 0;
85 
86 protected:
87 
88     int m, n;       // size of input and output tuples
89     double          // min and max values for function domain
90         domain[funcMaxInputs][2];
91     double          // min and max values for function range
92         range[funcMaxOutputs][2];
93     GBool hasRange;     // set if range is defined
94 };
95 
96 //------------------------------------------------------------------------
97 // IdentityFunction
98 //------------------------------------------------------------------------
99 
100 class IdentityFunction : public Function {
101 public:
102 
103     IdentityFunction();
104     virtual ~IdentityFunction();
copy()105     virtual Function *copy() {
106         return new IdentityFunction();
107     }
getType()108     virtual int getType() {
109         return -1;
110     }
111     virtual void transform(double *in, double *out);
isOk()112     virtual GBool isOk() {
113         return gTrue;
114     }
115 
116 private:
117 };
118 
119 //------------------------------------------------------------------------
120 // SampledFunction
121 //------------------------------------------------------------------------
122 
123 class SampledFunction : public Function {
124 public:
125 
126     SampledFunction(Object *funcObj, Dict *dict);
127     virtual ~SampledFunction();
copy()128     virtual Function *copy() {
129         return new SampledFunction(this);
130     }
getType()131     virtual int getType() {
132         return 0;
133     }
134     virtual void transform(double *in, double *out);
isOk()135     virtual GBool isOk() {
136         return ok;
137     }
138 
getSampleSize(int i)139     int getSampleSize(int i) {
140         return sampleSize[i];
141     }
getEncodeMin(int i)142     double getEncodeMin(int i) {
143         return encode[i][0];
144     }
getEncodeMax(int i)145     double getEncodeMax(int i) {
146         return encode[i][1];
147     }
getDecodeMin(int i)148     double getDecodeMin(int i) {
149         return decode[i][0];
150     }
getDecodeMax(int i)151     double getDecodeMax(int i) {
152         return decode[i][1];
153     }
getSamples()154     double *getSamples() {
155         return samples;
156     }
157 
158 private:
159 
160     SampledFunction(SampledFunction *func);
161 
162     int             // number of samples for each domain element
163         sampleSize[funcMaxInputs];
164     double          // min and max values for domain encoder
165         encode[funcMaxInputs][2];
166     double          // min and max values for range decoder
167         decode[funcMaxOutputs][2];
168     double          // input multipliers
169         inputMul[funcMaxInputs];
170     int *idxOffset;
171     double *samples;    // the samples
172     int nSamples;       // size of the samples array
173     double *sBuf;       // buffer for the transform function
174     double cacheIn[funcMaxInputs];
175     double cacheOut[funcMaxOutputs];
176     GBool ok;
177 };
178 
179 //------------------------------------------------------------------------
180 // ExponentialFunction
181 //------------------------------------------------------------------------
182 
183 class ExponentialFunction : public Function {
184 public:
185 
186     ExponentialFunction(Object *funcObj, Dict *dict);
187     virtual ~ExponentialFunction();
copy()188     virtual Function *copy() {
189         return new ExponentialFunction(this);
190     }
getType()191     virtual int getType() {
192         return 2;
193     }
194     virtual void transform(double *in, double *out);
isOk()195     virtual GBool isOk() {
196         return ok;
197     }
198 
getC0()199     double *getC0() {
200         return c0;
201     }
getC1()202     double *getC1() {
203         return c1;
204     }
getE()205     double getE() {
206         return e;
207     }
208 
209 private:
210 
211     ExponentialFunction(ExponentialFunction *func);
212 
213     double c0[funcMaxOutputs];
214     double c1[funcMaxOutputs];
215     double e;
216     GBool ok;
217 };
218 
219 //------------------------------------------------------------------------
220 // StitchingFunction
221 //------------------------------------------------------------------------
222 
223 class StitchingFunction : public Function {
224 public:
225 
226     StitchingFunction(Object *funcObj, Dict *dict, int recursion);
227     virtual ~StitchingFunction();
copy()228     virtual Function *copy() {
229         return new StitchingFunction(this);
230     }
getType()231     virtual int getType() {
232         return 3;
233     }
234     virtual void transform(double *in, double *out);
isOk()235     virtual GBool isOk() {
236         return ok;
237     }
238 
getNumFuncs()239     int getNumFuncs() {
240         return k;
241     }
getFunc(int i)242     Function *getFunc(int i) {
243         return funcs[i];
244     }
getBounds()245     double *getBounds() {
246         return bounds;
247     }
getEncode()248     double *getEncode() {
249         return encode;
250     }
getScale()251     double *getScale() {
252         return scale;
253     }
254 
255 private:
256 
257     StitchingFunction(StitchingFunction *func);
258 
259     int k;
260     Function **funcs;
261     double *bounds;
262     double *encode;
263     double *scale;
264     GBool ok;
265 };
266 
267 //------------------------------------------------------------------------
268 // PostScriptFunction
269 //------------------------------------------------------------------------
270 
271 class PostScriptFunction : public Function {
272 public:
273 
274     PostScriptFunction(Object *funcObj, Dict *dict);
275     virtual ~PostScriptFunction();
copy()276     virtual Function *copy() {
277         return new PostScriptFunction(this);
278     }
getType()279     virtual int getType() {
280         return 4;
281     }
282     virtual void transform(double *in, double *out);
isOk()283     virtual GBool isOk() {
284         return ok;
285     }
286 
getCodeString()287     GString *getCodeString() {
288         return codeString;
289     }
290 
291 private:
292 
293     PostScriptFunction(PostScriptFunction *func);
294     GBool parseCode(GList *tokens, int *tokPtr, int *codePtr);
295     void addCode(int *codePtr, int op);
296     void addCodeI(int *codePtr, int op, int x);
297     void addCodeD(int *codePtr, int op, double x);
298     GString *getToken(Stream *str);
299     int exec(double *stack, int sp0);
300 
301     GString *codeString;
302     PSCode *code;
303     int codeLen;
304     int codeSize;
305     double cacheIn[funcMaxInputs];
306     double cacheOut[funcMaxOutputs];
307     GBool ok;
308 };
309 
310 #endif
311