//======================================================================== // // Function.h // // Copyright 2001-2003 Glyph & Cog, LLC // //======================================================================== //======================================================================== // // Modified under the Poppler project - http://poppler.freedesktop.org // // All changes made under the Poppler project to this file are licensed // under GPL version 2 or later // // Copyright (C) 2009, 2010, 2018, 2019 Albert Astals Cid // Copyright (C) 2010 Christian Feuersänger // Copyright (C) 2011 Andrea Canciani // Copyright (C) 2012 Thomas Freitag // Copyright (C) 2012 Adam Reichold // // To see a description of the changes please see the Changelog file that // came with your tarball or type make ChangeLog if you are building from git // //======================================================================== #ifndef FUNCTION_H #define FUNCTION_H #include "Object.h" #include class Dict; class Stream; struct PSObject; class PSStack; //------------------------------------------------------------------------ // Function //------------------------------------------------------------------------ #define funcMaxInputs 32 #define funcMaxOutputs 32 #define sampledFuncMaxInputs 16 class Function { public: Function(); virtual ~Function(); Function(const Function &) = delete; Function &operator=(const Function &other) = delete; // Construct a function. Returns NULL if unsuccessful. static Function *parse(Object *funcObj); // Initialize the entries common to all function types. bool init(Dict *dict); virtual Function *copy() const = 0; // Return the function type: // -1 : identity // 0 : sampled // 2 : exponential // 3 : stitching // 4 : PostScript virtual int getType() const = 0; // Return size of input and output tuples. 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; } // Transform an input tuple into an output tuple. virtual void transform(const double *in, double *out) const = 0; virtual bool isOk() const = 0; protected: static Function *parse(Object *funcObj, std::set *usedParents); Function(const Function *func); 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]; bool hasRange; // set if range is defined }; //------------------------------------------------------------------------ // IdentityFunction //------------------------------------------------------------------------ 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: }; //------------------------------------------------------------------------ // SampledFunction //------------------------------------------------------------------------ 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: SampledFunction(const 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 mutable double cacheIn[funcMaxInputs]; mutable double cacheOut[funcMaxOutputs]; bool ok; }; //------------------------------------------------------------------------ // ExponentialFunction //------------------------------------------------------------------------ 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: ExponentialFunction(const ExponentialFunction *func); double c0[funcMaxOutputs]; double c1[funcMaxOutputs]; double e; bool isLinear; bool ok; }; //------------------------------------------------------------------------ // StitchingFunction //------------------------------------------------------------------------ class StitchingFunction : public Function { public: StitchingFunction(Object *funcObj, Dict *dict, std::set *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: StitchingFunction(const StitchingFunction *func); int k; Function **funcs; double *bounds; double *encode; double *scale; bool ok; }; //------------------------------------------------------------------------ // PostScriptFunction //------------------------------------------------------------------------ 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: PostScriptFunction(const PostScriptFunction *func); bool parseCode(Stream *str, int *codePtr); 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