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() { return m; }
getOutputSize()59   int getOutputSize() { return n; }
60 
getDomainMin(int i)61   double getDomainMin(int i) { return domain[i][0]; }
getDomainMax(int i)62   double getDomainMax(int i) { return domain[i][1]; }
getRangeMin(int i)63   double getRangeMin(int i) { return range[i][0]; }
getRangeMax(int i)64   double getRangeMax(int i) { return range[i][1]; }
getHasRange()65   GBool getHasRange() { return hasRange; }
66 
67   // Transform an input tuple into an output tuple.
68   virtual void transform(double *in, double *out) = 0;
69 
70   virtual GBool isOk() = 0;
71 
72 protected:
73 
74   int m, n;			// size of input and output tuples
75   double			// min and max values for function domain
76     domain[funcMaxInputs][2];
77   double			// min and max values for function range
78     range[funcMaxOutputs][2];
79   GBool hasRange;		// set if range is defined
80 };
81 
82 //------------------------------------------------------------------------
83 // IdentityFunction
84 //------------------------------------------------------------------------
85 
86 class IdentityFunction: public Function {
87 public:
88 
89   IdentityFunction();
90   virtual ~IdentityFunction();
copy()91   virtual Function *copy() { return new IdentityFunction(); }
getType()92   virtual int getType() { return -1; }
93   virtual void transform(double *in, double *out);
isOk()94   virtual GBool isOk() { return gTrue; }
95 
96 private:
97 };
98 
99 //------------------------------------------------------------------------
100 // SampledFunction
101 //------------------------------------------------------------------------
102 
103 class SampledFunction: public Function {
104 public:
105 
106   SampledFunction(Object *funcObj, Dict *dict);
107   virtual ~SampledFunction();
copy()108   virtual Function *copy() { return new SampledFunction(this); }
getType()109   virtual int getType() { return 0; }
110   virtual void transform(double *in, double *out);
isOk()111   virtual GBool isOk() { return ok; }
112 
getSampleSize(int i)113   int getSampleSize(int i) { return sampleSize[i]; }
getEncodeMin(int i)114   double getEncodeMin(int i) { return encode[i][0]; }
getEncodeMax(int i)115   double getEncodeMax(int i) { return encode[i][1]; }
getDecodeMin(int i)116   double getDecodeMin(int i) { return decode[i][0]; }
getDecodeMax(int i)117   double getDecodeMax(int i) { return decode[i][1]; }
getSamples()118   double *getSamples() { return samples; }
119 
120 private:
121 
122   SampledFunction(SampledFunction *func);
123 
124   int				// number of samples for each domain element
125     sampleSize[funcMaxInputs];
126   double			// min and max values for domain encoder
127     encode[funcMaxInputs][2];
128   double			// min and max values for range decoder
129     decode[funcMaxOutputs][2];
130   double			// input multipliers
131     inputMul[funcMaxInputs];
132   int *idxOffset;
133   double *samples;		// the samples
134   int nSamples;			// size of the samples array
135   double *sBuf;			// buffer for the transform function
136   double cacheIn[funcMaxInputs];
137   double cacheOut[funcMaxOutputs];
138   GBool ok;
139 };
140 
141 //------------------------------------------------------------------------
142 // ExponentialFunction
143 //------------------------------------------------------------------------
144 
145 class ExponentialFunction: public Function {
146 public:
147 
148   ExponentialFunction(Object *funcObj, Dict *dict);
149   virtual ~ExponentialFunction();
copy()150   virtual Function *copy() { return new ExponentialFunction(this); }
getType()151   virtual int getType() { return 2; }
152   virtual void transform(double *in, double *out);
isOk()153   virtual GBool isOk() { return ok; }
154 
getC0()155   double *getC0() { return c0; }
getC1()156   double *getC1() { return c1; }
getE()157   double getE() { return e; }
158 
159 private:
160 
161   ExponentialFunction(ExponentialFunction *func);
162 
163   double c0[funcMaxOutputs];
164   double c1[funcMaxOutputs];
165   double e;
166   GBool ok;
167 };
168 
169 //------------------------------------------------------------------------
170 // StitchingFunction
171 //------------------------------------------------------------------------
172 
173 class StitchingFunction: public Function {
174 public:
175 
176   StitchingFunction(Object *funcObj, Dict *dict, int recursion);
177   virtual ~StitchingFunction();
copy()178   virtual Function *copy() { return new StitchingFunction(this); }
getType()179   virtual int getType() { return 3; }
180   virtual void transform(double *in, double *out);
isOk()181   virtual GBool isOk() { return ok; }
182 
getNumFuncs()183   int getNumFuncs() { return k; }
getFunc(int i)184   Function *getFunc(int i) { return funcs[i]; }
getBounds()185   double *getBounds() { return bounds; }
getEncode()186   double *getEncode() { return encode; }
getScale()187   double *getScale() { return scale; }
188 
189 private:
190 
191   StitchingFunction(StitchingFunction *func);
192 
193   int k;
194   Function **funcs;
195   double *bounds;
196   double *encode;
197   double *scale;
198   GBool ok;
199 };
200 
201 //------------------------------------------------------------------------
202 // PostScriptFunction
203 //------------------------------------------------------------------------
204 
205 class PostScriptFunction: public Function {
206 public:
207 
208   PostScriptFunction(Object *funcObj, Dict *dict);
209   virtual ~PostScriptFunction();
copy()210   virtual Function *copy() { return new PostScriptFunction(this); }
getType()211   virtual int getType() { return 4; }
212   virtual void transform(double *in, double *out);
isOk()213   virtual GBool isOk() { return ok; }
214 
getCodeString()215   GString *getCodeString() { return codeString; }
216 
217 private:
218 
219   PostScriptFunction(PostScriptFunction *func);
220   GBool parseCode(GList *tokens, int *tokPtr, int *codePtr);
221   void addCode(int *codePtr, int op);
222   void addCodeI(int *codePtr, int op, int x);
223   void addCodeD(int *codePtr, int op, double x);
224   GString *getToken(Stream *str);
225   int exec(double *stack, int sp0);
226 
227   GString *codeString;
228   PSCode *code;
229   int codeLen;
230   int codeSize;
231   double cacheIn[funcMaxInputs];
232   double cacheOut[funcMaxOutputs];
233   GBool ok;
234 };
235 
236 #endif
237