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