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