]>
Commit | Line | Data |
---|---|---|
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 <config.h> | |
13 | ||
14 | #ifdef USE_GCC_PRAGMAS | |
15 | #pragma interface | |
16 | #endif | |
17 | ||
18 | #include "gtypes.h" | |
19 | #include "Object.h" | |
20 | ||
21 | class Dict; | |
22 | class Stream; | |
23 | struct PSObject; | |
24 | class PSStack; | |
25 | ||
26 | //------------------------------------------------------------------------ | |
27 | // Function | |
28 | //------------------------------------------------------------------------ | |
29 | ||
30 | #define funcMaxInputs 8 | |
31 | #define funcMaxOutputs 32 | |
32 | ||
33 | class Function { | |
34 | public: | |
35 | ||
36 | Function(); | |
37 | ||
38 | virtual ~Function(); | |
39 | ||
40 | // Construct a function. Returns NULL if unsuccessful. | |
41 | static Function *parse(Object *funcObj); | |
42 | ||
43 | // Initialize the entries common to all function types. | |
44 | GBool init(Dict *dict); | |
45 | ||
46 | virtual Function *copy() = 0; | |
47 | ||
48 | // Return the function type: | |
49 | // -1 : identity | |
50 | // 0 : sampled | |
51 | // 2 : exponential | |
52 | // 3 : stitching | |
53 | // 4 : PostScript | |
54 | virtual int getType() = 0; | |
55 | ||
56 | // Return size of input and output tuples. | |
57 | int getInputSize() { return m; } | |
58 | int getOutputSize() { return n; } | |
59 | ||
60 | double getDomainMin(int i) { return domain[i][0]; } | |
61 | double getDomainMax(int i) { return domain[i][1]; } | |
62 | double getRangeMin(int i) { return range[i][0]; } | |
63 | double getRangeMax(int i) { return range[i][1]; } | |
64 | GBool getHasRange() { return hasRange; } | |
65 | ||
66 | // Transform an input tuple into an output tuple. | |
67 | virtual void transform(double *in, double *out) = 0; | |
68 | ||
69 | virtual GBool isOk() = 0; | |
70 | ||
71 | protected: | |
72 | ||
73 | int m, n; // size of input and output tuples | |
74 | double // min and max values for function domain | |
75 | domain[funcMaxInputs][2]; | |
76 | double // min and max values for function range | |
77 | range[funcMaxOutputs][2]; | |
78 | GBool hasRange; // set if range is defined | |
79 | }; | |
80 | ||
81 | //------------------------------------------------------------------------ | |
82 | // IdentityFunction | |
83 | //------------------------------------------------------------------------ | |
84 | ||
85 | class IdentityFunction: public Function { | |
86 | public: | |
87 | ||
88 | IdentityFunction(); | |
89 | virtual ~IdentityFunction(); | |
90 | virtual Function *copy() { return new IdentityFunction(); } | |
91 | virtual int getType() { return -1; } | |
92 | virtual void transform(double *in, double *out); | |
93 | virtual GBool isOk() { return gTrue; } | |
94 | ||
95 | private: | |
96 | }; | |
97 | ||
98 | //------------------------------------------------------------------------ | |
99 | // SampledFunction | |
100 | //------------------------------------------------------------------------ | |
101 | ||
102 | class SampledFunction: public Function { | |
103 | public: | |
104 | ||
105 | SampledFunction(Object *funcObj, Dict *dict); | |
106 | virtual ~SampledFunction(); | |
107 | virtual Function *copy() { return new SampledFunction(this); } | |
108 | virtual int getType() { return 0; } | |
109 | virtual void transform(double *in, double *out); | |
110 | virtual GBool isOk() { return ok; } | |
111 | ||
112 | int getSampleSize(int i) { return sampleSize[i]; } | |
113 | double getEncodeMin(int i) { return encode[i][0]; } | |
114 | double getEncodeMax(int i) { return encode[i][1]; } | |
115 | double getDecodeMin(int i) { return decode[i][0]; } | |
116 | double getDecodeMax(int i) { return decode[i][1]; } | |
117 | double *getSamples() { return samples; } | |
118 | ||
119 | private: | |
120 | ||
121 | SampledFunction(SampledFunction *func); | |
122 | ||
123 | int // number of samples for each domain element | |
124 | sampleSize[funcMaxInputs]; | |
125 | double // min and max values for domain encoder | |
126 | encode[funcMaxInputs][2]; | |
127 | double // min and max values for range decoder | |
128 | decode[funcMaxOutputs][2]; | |
129 | double // input multipliers | |
130 | inputMul[funcMaxInputs]; | |
131 | int idxMul[funcMaxInputs]; // sample array index multipliers | |
132 | double *samples; // the samples | |
133 | int nSamples; // size of the samples array | |
134 | GBool ok; | |
135 | }; | |
136 | ||
137 | //------------------------------------------------------------------------ | |
138 | // ExponentialFunction | |
139 | //------------------------------------------------------------------------ | |
140 | ||
141 | class ExponentialFunction: public Function { | |
142 | public: | |
143 | ||
144 | ExponentialFunction(Object *funcObj, Dict *dict); | |
145 | virtual ~ExponentialFunction(); | |
146 | virtual Function *copy() { return new ExponentialFunction(this); } | |
147 | virtual int getType() { return 2; } | |
148 | virtual void transform(double *in, double *out); | |
149 | virtual GBool isOk() { return ok; } | |
150 | ||
151 | double *getC0() { return c0; } | |
152 | double *getC1() { return c1; } | |
153 | double getE() { return e; } | |
154 | ||
155 | private: | |
156 | ||
157 | ExponentialFunction(ExponentialFunction *func); | |
158 | ||
159 | double c0[funcMaxOutputs]; | |
160 | double c1[funcMaxOutputs]; | |
161 | double e; | |
162 | GBool ok; | |
163 | }; | |
164 | ||
165 | //------------------------------------------------------------------------ | |
166 | // StitchingFunction | |
167 | //------------------------------------------------------------------------ | |
168 | ||
169 | class StitchingFunction: public Function { | |
170 | public: | |
171 | ||
172 | StitchingFunction(Object *funcObj, Dict *dict); | |
173 | virtual ~StitchingFunction(); | |
174 | virtual Function *copy() { return new StitchingFunction(this); } | |
175 | virtual int getType() { return 3; } | |
176 | virtual void transform(double *in, double *out); | |
177 | virtual GBool isOk() { return ok; } | |
178 | ||
179 | int getNumFuncs() { return k; } | |
180 | Function *getFunc(int i) { return funcs[i]; } | |
181 | double *getBounds() { return bounds; } | |
182 | double *getEncode() { return encode; } | |
183 | ||
184 | private: | |
185 | ||
186 | StitchingFunction(StitchingFunction *func); | |
187 | ||
188 | int k; | |
189 | Function **funcs; | |
190 | double *bounds; | |
191 | double *encode; | |
192 | GBool ok; | |
193 | }; | |
194 | ||
195 | //------------------------------------------------------------------------ | |
196 | // PostScriptFunction | |
197 | //------------------------------------------------------------------------ | |
198 | ||
199 | class PostScriptFunction: public Function { | |
200 | public: | |
201 | ||
202 | PostScriptFunction(Object *funcObj, Dict *dict); | |
203 | virtual ~PostScriptFunction(); | |
204 | virtual Function *copy() { return new PostScriptFunction(this); } | |
205 | virtual int getType() { return 4; } | |
206 | virtual void transform(double *in, double *out); | |
207 | virtual GBool isOk() { return ok; } | |
208 | ||
209 | GString *getCodeString() { return codeString; } | |
210 | ||
211 | private: | |
212 | ||
213 | PostScriptFunction(PostScriptFunction *func); | |
214 | GBool parseCode(Stream *str, int *codePtr); | |
215 | GString *getToken(Stream *str); | |
216 | void resizeCode(int newSize); | |
217 | void exec(PSStack *stack, int codePtr); | |
218 | ||
219 | GString *codeString; | |
220 | PSObject *code; | |
221 | int codeSize; | |
222 | GBool ok; | |
223 | }; | |
224 | ||
225 | #endif |