|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#ifndef FUNCTION_H |
|
#define FUNCTION_H |
|
|
|
#include "Object.h" |
|
#include <set> |
|
|
|
class Dict; |
|
class Stream; |
|
struct PSObject; |
|
class PSStack; |
|
|
|
|
|
|
|
|
|
|
|
#define funcMaxInputs 32 |
|
#define funcMaxOutputs 32 |
|
#define sampledFuncMaxInputs 16 |
|
|
|
class POPPLER_PRIVATE_EXPORT Function |
|
{ |
|
public: |
|
Function(); |
|
|
|
virtual ~Function(); |
|
|
|
Function(const Function &) = delete; |
|
Function &operator=(const Function &other) = delete; |
|
|
|
|
|
static Function *parse(Object *funcObj); |
|
|
|
|
|
bool init(Dict *dict); |
|
|
|
virtual Function *copy() const = 0; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
virtual int getType() const = 0; |
|
|
|
|
|
int getInputSize() const { return m; } |
|
int getOutputSize() const { return n; } |
|
|
|
double getDomainMin(int i) const { return domain[i][0]; } |
|
double getDomainMax(int i) const { return domain[i][1]; } |
|
double getRangeMin(int i) const { return range[i][0]; } |
|
double getRangeMax(int i) const { return range[i][1]; } |
|
bool getHasRange() const { return hasRange; } |
|
virtual bool hasDifferentResultSet(const Function *func) const { return false; } |
|
|
|
|
|
virtual void transform(const double *in, double *out) const = 0; |
|
|
|
virtual bool isOk() const = 0; |
|
|
|
protected: |
|
static Function *parse(Object *funcObj, std::set<int> *usedParents); |
|
|
|
explicit Function(const Function *func); |
|
|
|
int m, n; |
|
double |
|
domain[funcMaxInputs][2]; |
|
double |
|
range[funcMaxOutputs][2]; |
|
bool hasRange; |
|
}; |
|
|
|
|
|
|
|
|
|
|
|
class IdentityFunction : public Function |
|
{ |
|
public: |
|
IdentityFunction(); |
|
~IdentityFunction() override; |
|
Function *copy() const override { return new IdentityFunction(); } |
|
int getType() const override { return -1; } |
|
void transform(const double *in, double *out) const override; |
|
bool isOk() const override { return true; } |
|
|
|
private: |
|
}; |
|
|
|
|
|
|
|
|
|
|
|
class SampledFunction : public Function |
|
{ |
|
public: |
|
SampledFunction(Object *funcObj, Dict *dict); |
|
~SampledFunction() override; |
|
Function *copy() const override { return new SampledFunction(this); } |
|
int getType() const override { return 0; } |
|
void transform(const double *in, double *out) const override; |
|
bool isOk() const override { return ok; } |
|
bool hasDifferentResultSet(const Function *func) const override; |
|
|
|
int getSampleSize(int i) const { return sampleSize[i]; } |
|
double getEncodeMin(int i) const { return encode[i][0]; } |
|
double getEncodeMax(int i) const { return encode[i][1]; } |
|
double getDecodeMin(int i) const { return decode[i][0]; } |
|
double getDecodeMax(int i) const { return decode[i][1]; } |
|
const double *getSamples() const { return samples; } |
|
int getSampleNumber() const { return nSamples; } |
|
|
|
private: |
|
explicit SampledFunction(const SampledFunction *func); |
|
|
|
int |
|
sampleSize[funcMaxInputs]; |
|
double |
|
encode[funcMaxInputs][2]; |
|
double |
|
decode[funcMaxOutputs][2]; |
|
double |
|
inputMul[funcMaxInputs]; |
|
int *idxOffset; |
|
double *samples; |
|
int nSamples; |
|
double *sBuf; |
|
mutable double cacheIn[funcMaxInputs]; |
|
mutable double cacheOut[funcMaxOutputs]; |
|
bool ok; |
|
}; |
|
|
|
|
|
|
|
|
|
|
|
class ExponentialFunction : public Function |
|
{ |
|
public: |
|
ExponentialFunction(Object *funcObj, Dict *dict); |
|
~ExponentialFunction() override; |
|
Function *copy() const override { return new ExponentialFunction(this); } |
|
int getType() const override { return 2; } |
|
void transform(const double *in, double *out) const override; |
|
bool isOk() const override { return ok; } |
|
|
|
const double *getC0() const { return c0; } |
|
const double *getC1() const { return c1; } |
|
double getE() const { return e; } |
|
|
|
private: |
|
explicit ExponentialFunction(const ExponentialFunction *func); |
|
|
|
double c0[funcMaxOutputs]; |
|
double c1[funcMaxOutputs]; |
|
double e; |
|
bool isLinear; |
|
bool ok; |
|
}; |
|
|
|
|
|
|
|
|
|
|
|
class StitchingFunction : public Function |
|
{ |
|
public: |
|
StitchingFunction(Object *funcObj, Dict *dict, std::set<int> *usedParents); |
|
~StitchingFunction() override; |
|
Function *copy() const override { return new StitchingFunction(this); } |
|
int getType() const override { return 3; } |
|
void transform(const double *in, double *out) const override; |
|
bool isOk() const override { return ok; } |
|
|
|
int getNumFuncs() const { return k; } |
|
const Function *getFunc(int i) const { return funcs[i]; } |
|
const double *getBounds() const { return bounds; } |
|
const double *getEncode() const { return encode; } |
|
const double *getScale() const { return scale; } |
|
|
|
private: |
|
explicit StitchingFunction(const StitchingFunction *func); |
|
|
|
int k; |
|
Function **funcs; |
|
double *bounds; |
|
double *encode; |
|
double *scale; |
|
bool ok; |
|
}; |
|
|
|
|
|
|
|
|
|
|
|
class PostScriptFunction : public Function |
|
{ |
|
public: |
|
PostScriptFunction(Object *funcObj, Dict *dict); |
|
~PostScriptFunction() override; |
|
Function *copy() const override { return new PostScriptFunction(this); } |
|
int getType() const override { return 4; } |
|
void transform(const double *in, double *out) const override; |
|
bool isOk() const override { return ok; } |
|
|
|
const GooString *getCodeString() const { return codeString; } |
|
|
|
private: |
|
explicit PostScriptFunction(const PostScriptFunction *func); |
|
bool parseCode(Stream *str, int *codePtr); |
|
std::unique_ptr<GooString> getToken(Stream *str); |
|
void resizeCode(int newSize); |
|
void exec(PSStack *stack, int codePtr) const; |
|
|
|
GooString *codeString; |
|
PSObject *code; |
|
int codeSize; |
|
mutable double cacheIn[funcMaxInputs]; |
|
mutable double cacheOut[funcMaxOutputs]; |
|
bool ok; |
|
}; |
|
|
|
#endif |
|
|