237 lines
6.3 KiB
C
237 lines
6.3 KiB
C
|
//========================================================================
|
||
|
//
|
||
|
// Function.h
|
||
|
//
|
||
|
// Copyright 2001-2003 Glyph & Cog, LLC
|
||
|
//
|
||
|
//========================================================================
|
||
|
|
||
|
#ifndef FUNCTION_H
|
||
|
#define FUNCTION_H
|
||
|
|
||
|
#include <aconf.h>
|
||
|
|
||
|
#ifdef USE_GCC_PRAGMAS
|
||
|
#pragma interface
|
||
|
#endif
|
||
|
|
||
|
#include "gtypes.h"
|
||
|
#include "Object.h"
|
||
|
|
||
|
class GList;
|
||
|
class Dict;
|
||
|
class Stream;
|
||
|
struct PSCode;
|
||
|
|
||
|
//------------------------------------------------------------------------
|
||
|
// Function
|
||
|
//------------------------------------------------------------------------
|
||
|
|
||
|
#define funcMaxInputs 32
|
||
|
#define funcMaxOutputs 32
|
||
|
#define sampledFuncMaxInputs 16
|
||
|
|
||
|
class Function {
|
||
|
public:
|
||
|
|
||
|
Function();
|
||
|
|
||
|
virtual ~Function();
|
||
|
|
||
|
// Construct a function. Returns NULL if unsuccessful.
|
||
|
static Function *parse(Object *funcObj, int recursion = 0);
|
||
|
|
||
|
// Initialize the entries common to all function types.
|
||
|
GBool init(Dict *dict);
|
||
|
|
||
|
virtual Function *copy() = 0;
|
||
|
|
||
|
// Return the function type:
|
||
|
// -1 : identity
|
||
|
// 0 : sampled
|
||
|
// 2 : exponential
|
||
|
// 3 : stitching
|
||
|
// 4 : PostScript
|
||
|
virtual int getType() = 0;
|
||
|
|
||
|
// Return size of input and output tuples.
|
||
|
int getInputSize() { return m; }
|
||
|
int getOutputSize() { return n; }
|
||
|
|
||
|
double getDomainMin(int i) { return domain[i][0]; }
|
||
|
double getDomainMax(int i) { return domain[i][1]; }
|
||
|
double getRangeMin(int i) { return range[i][0]; }
|
||
|
double getRangeMax(int i) { return range[i][1]; }
|
||
|
GBool getHasRange() { return hasRange; }
|
||
|
|
||
|
// Transform an input tuple into an output tuple.
|
||
|
virtual void transform(double *in, double *out) = 0;
|
||
|
|
||
|
virtual GBool isOk() = 0;
|
||
|
|
||
|
protected:
|
||
|
|
||
|
int m, n; // size of input and output tuples
|
||
|
double // min and max values for function domain
|
||
|
domain[funcMaxInputs][2];
|
||
|
double // min and max values for function range
|
||
|
range[funcMaxOutputs][2];
|
||
|
GBool hasRange; // set if range is defined
|
||
|
};
|
||
|
|
||
|
//------------------------------------------------------------------------
|
||
|
// IdentityFunction
|
||
|
//------------------------------------------------------------------------
|
||
|
|
||
|
class IdentityFunction: public Function {
|
||
|
public:
|
||
|
|
||
|
IdentityFunction();
|
||
|
virtual ~IdentityFunction();
|
||
|
virtual Function *copy() { return new IdentityFunction(); }
|
||
|
virtual int getType() { return -1; }
|
||
|
virtual void transform(double *in, double *out);
|
||
|
virtual GBool isOk() { return gTrue; }
|
||
|
|
||
|
private:
|
||
|
};
|
||
|
|
||
|
//------------------------------------------------------------------------
|
||
|
// SampledFunction
|
||
|
//------------------------------------------------------------------------
|
||
|
|
||
|
class SampledFunction: public Function {
|
||
|
public:
|
||
|
|
||
|
SampledFunction(Object *funcObj, Dict *dict);
|
||
|
virtual ~SampledFunction();
|
||
|
virtual Function *copy() { return new SampledFunction(this); }
|
||
|
virtual int getType() { return 0; }
|
||
|
virtual void transform(double *in, double *out);
|
||
|
virtual GBool isOk() { return ok; }
|
||
|
|
||
|
int getSampleSize(int i) { return sampleSize[i]; }
|
||
|
double getEncodeMin(int i) { return encode[i][0]; }
|
||
|
double getEncodeMax(int i) { return encode[i][1]; }
|
||
|
double getDecodeMin(int i) { return decode[i][0]; }
|
||
|
double getDecodeMax(int i) { return decode[i][1]; }
|
||
|
double *getSamples() { return samples; }
|
||
|
|
||
|
private:
|
||
|
|
||
|
SampledFunction(SampledFunction *func);
|
||
|
|
||
|
int // number of samples for each domain element
|
||
|
sampleSize[funcMaxInputs];
|
||
|
double // min and max values for domain encoder
|
||
|
encode[funcMaxInputs][2];
|
||
|
double // min and max values for range decoder
|
||
|
decode[funcMaxOutputs][2];
|
||
|
double // input multipliers
|
||
|
inputMul[funcMaxInputs];
|
||
|
int *idxOffset;
|
||
|
double *samples; // the samples
|
||
|
int nSamples; // size of the samples array
|
||
|
double *sBuf; // buffer for the transform function
|
||
|
double cacheIn[funcMaxInputs];
|
||
|
double cacheOut[funcMaxOutputs];
|
||
|
GBool ok;
|
||
|
};
|
||
|
|
||
|
//------------------------------------------------------------------------
|
||
|
// ExponentialFunction
|
||
|
//------------------------------------------------------------------------
|
||
|
|
||
|
class ExponentialFunction: public Function {
|
||
|
public:
|
||
|
|
||
|
ExponentialFunction(Object *funcObj, Dict *dict);
|
||
|
virtual ~ExponentialFunction();
|
||
|
virtual Function *copy() { return new ExponentialFunction(this); }
|
||
|
virtual int getType() { return 2; }
|
||
|
virtual void transform(double *in, double *out);
|
||
|
virtual GBool isOk() { return ok; }
|
||
|
|
||
|
double *getC0() { return c0; }
|
||
|
double *getC1() { return c1; }
|
||
|
double getE() { return e; }
|
||
|
|
||
|
private:
|
||
|
|
||
|
ExponentialFunction(ExponentialFunction *func);
|
||
|
|
||
|
double c0[funcMaxOutputs];
|
||
|
double c1[funcMaxOutputs];
|
||
|
double e;
|
||
|
GBool ok;
|
||
|
};
|
||
|
|
||
|
//------------------------------------------------------------------------
|
||
|
// StitchingFunction
|
||
|
//------------------------------------------------------------------------
|
||
|
|
||
|
class StitchingFunction: public Function {
|
||
|
public:
|
||
|
|
||
|
StitchingFunction(Object *funcObj, Dict *dict, int recursion);
|
||
|
virtual ~StitchingFunction();
|
||
|
virtual Function *copy() { return new StitchingFunction(this); }
|
||
|
virtual int getType() { return 3; }
|
||
|
virtual void transform(double *in, double *out);
|
||
|
virtual GBool isOk() { return ok; }
|
||
|
|
||
|
int getNumFuncs() { return k; }
|
||
|
Function *getFunc(int i) { return funcs[i]; }
|
||
|
double *getBounds() { return bounds; }
|
||
|
double *getEncode() { return encode; }
|
||
|
double *getScale() { return scale; }
|
||
|
|
||
|
private:
|
||
|
|
||
|
StitchingFunction(StitchingFunction *func);
|
||
|
|
||
|
int k;
|
||
|
Function **funcs;
|
||
|
double *bounds;
|
||
|
double *encode;
|
||
|
double *scale;
|
||
|
GBool ok;
|
||
|
};
|
||
|
|
||
|
//------------------------------------------------------------------------
|
||
|
// PostScriptFunction
|
||
|
//------------------------------------------------------------------------
|
||
|
|
||
|
class PostScriptFunction: public Function {
|
||
|
public:
|
||
|
|
||
|
PostScriptFunction(Object *funcObj, Dict *dict);
|
||
|
virtual ~PostScriptFunction();
|
||
|
virtual Function *copy() { return new PostScriptFunction(this); }
|
||
|
virtual int getType() { return 4; }
|
||
|
virtual void transform(double *in, double *out);
|
||
|
virtual GBool isOk() { return ok; }
|
||
|
|
||
|
GString *getCodeString() { return codeString; }
|
||
|
|
||
|
private:
|
||
|
|
||
|
PostScriptFunction(PostScriptFunction *func);
|
||
|
GBool parseCode(GList *tokens, int *tokPtr, int *codePtr);
|
||
|
void addCode(int *codePtr, int op);
|
||
|
void addCodeI(int *codePtr, int op, int x);
|
||
|
void addCodeD(int *codePtr, int op, double x);
|
||
|
GString *getToken(Stream *str);
|
||
|
int exec(double *stack, int sp0);
|
||
|
|
||
|
GString *codeString;
|
||
|
PSCode *code;
|
||
|
int codeLen;
|
||
|
int codeSize;
|
||
|
double cacheIn[funcMaxInputs];
|
||
|
double cacheOut[funcMaxOutputs];
|
||
|
GBool ok;
|
||
|
};
|
||
|
|
||
|
#endif
|