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