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