1 | //======================================================================== |
2 | // |
3 | // Function.h |
4 | // |
5 | // Copyright 2001-2003 Glyph & Cog, LLC |
6 | // |
7 | //======================================================================== |
8 | |
9 | //======================================================================== |
10 | // |
11 | // Modified under the Poppler project - http://poppler.freedesktop.org |
12 | // |
13 | // All changes made under the Poppler project to this file are licensed |
14 | // under GPL version 2 or later |
15 | // |
16 | // Copyright (C) 2009, 2010, 2018, 2019, 2021, 2024 Albert Astals Cid <aacid@kde.org> |
17 | // Copyright (C) 2010 Christian Feuersänger <cfeuersaenger@googlemail.com> |
18 | // Copyright (C) 2011 Andrea Canciani <ranma42@gmail.com> |
19 | // Copyright (C) 2012 Thomas Freitag <Thomas.Freitag@alfa.de> |
20 | // Copyright (C) 2012 Adam Reichold <adamreichold@myopera.com> |
21 | // |
22 | // To see a description of the changes please see the Changelog file that |
23 | // came with your tarball or type make ChangeLog if you are building from git |
24 | // |
25 | //======================================================================== |
26 | |
27 | #ifndef FUNCTION_H |
28 | #define FUNCTION_H |
29 | |
30 | #include "Object.h" |
31 | #include <set> |
32 | |
33 | class Dict; |
34 | class Stream; |
35 | struct PSObject; |
36 | class PSStack; |
37 | |
38 | //------------------------------------------------------------------------ |
39 | // Function |
40 | //------------------------------------------------------------------------ |
41 | |
42 | #define funcMaxInputs 32 |
43 | #define funcMaxOutputs 32 |
44 | #define sampledFuncMaxInputs 16 |
45 | |
46 | class POPPLER_PRIVATE_EXPORT Function |
47 | { |
48 | public: |
49 | Function(); |
50 | |
51 | virtual ~Function(); |
52 | |
53 | Function(const Function &) = delete; |
54 | Function &operator=(const Function &other) = delete; |
55 | |
56 | // Construct a function. Returns NULL if unsuccessful. |
57 | static Function *parse(Object *funcObj); |
58 | |
59 | // Initialize the entries common to all function types. |
60 | bool init(Dict *dict); |
61 | |
62 | virtual Function *copy() const = 0; |
63 | |
64 | enum class Type |
65 | { |
66 | Identity, |
67 | Sampled, |
68 | Exponential, |
69 | Stitching, |
70 | PostScript |
71 | }; |
72 | |
73 | virtual Type getType() const = 0; |
74 | |
75 | // Return size of input and output tuples. |
76 | int getInputSize() const { return m; } |
77 | int getOutputSize() const { return n; } |
78 | |
79 | double getDomainMin(int i) const { return domain[i][0]; } |
80 | double getDomainMax(int i) const { return domain[i][1]; } |
81 | double getRangeMin(int i) const { return range[i][0]; } |
82 | double getRangeMax(int i) const { return range[i][1]; } |
83 | bool getHasRange() const { return hasRange; } |
84 | virtual bool hasDifferentResultSet(const Function *func) const { return false; } |
85 | |
86 | // Transform an input tuple into an output tuple. |
87 | virtual void transform(const double *in, double *out) const = 0; |
88 | |
89 | virtual bool isOk() const = 0; |
90 | |
91 | protected: |
92 | static Function *parse(Object *funcObj, std::set<int> *usedParents); |
93 | |
94 | explicit Function(const Function *func); |
95 | |
96 | int m, n; // size of input and output tuples |
97 | double // min and max values for function domain |
98 | domain[funcMaxInputs][2]; |
99 | double // min and max values for function range |
100 | range[funcMaxOutputs][2]; |
101 | bool hasRange; // set if range is defined |
102 | }; |
103 | |
104 | //------------------------------------------------------------------------ |
105 | // IdentityFunction |
106 | //------------------------------------------------------------------------ |
107 | |
108 | class IdentityFunction : public Function |
109 | { |
110 | public: |
111 | IdentityFunction(); |
112 | ~IdentityFunction() override; |
113 | Function *copy() const override { return new IdentityFunction(); } |
114 | Type getType() const override { return Type::Identity; } |
115 | void transform(const double *in, double *out) const override; |
116 | bool isOk() const override { return true; } |
117 | |
118 | private: |
119 | }; |
120 | |
121 | //------------------------------------------------------------------------ |
122 | // SampledFunction |
123 | //------------------------------------------------------------------------ |
124 | |
125 | class SampledFunction : public Function |
126 | { |
127 | public: |
128 | SampledFunction(Object *funcObj, Dict *dict); |
129 | ~SampledFunction() override; |
130 | Function *copy() const override { return new SampledFunction(this); } |
131 | Type getType() const override { return Type::Sampled; } |
132 | void transform(const double *in, double *out) const override; |
133 | bool isOk() const override { return ok; } |
134 | bool hasDifferentResultSet(const Function *func) const override; |
135 | |
136 | int getSampleSize(int i) const { return sampleSize[i]; } |
137 | double getEncodeMin(int i) const { return encode[i][0]; } |
138 | double getEncodeMax(int i) const { return encode[i][1]; } |
139 | double getDecodeMin(int i) const { return decode[i][0]; } |
140 | double getDecodeMax(int i) const { return decode[i][1]; } |
141 | const double *getSamples() const { return samples; } |
142 | int getSampleNumber() const { return nSamples; } |
143 | |
144 | private: |
145 | explicit SampledFunction(const SampledFunction *func); |
146 | |
147 | int // number of samples for each domain element |
148 | sampleSize[funcMaxInputs]; |
149 | double // min and max values for domain encoder |
150 | encode[funcMaxInputs][2]; |
151 | double // min and max values for range decoder |
152 | decode[funcMaxOutputs][2]; |
153 | double // input multipliers |
154 | inputMul[funcMaxInputs]; |
155 | int *idxOffset; |
156 | double *samples; // the samples |
157 | int nSamples; // size of the samples array |
158 | double *sBuf; // buffer for the transform function |
159 | mutable double cacheIn[funcMaxInputs]; |
160 | mutable double cacheOut[funcMaxOutputs]; |
161 | bool ok; |
162 | }; |
163 | |
164 | //------------------------------------------------------------------------ |
165 | // ExponentialFunction |
166 | //------------------------------------------------------------------------ |
167 | |
168 | class ExponentialFunction : public Function |
169 | { |
170 | public: |
171 | ExponentialFunction(Object *funcObj, Dict *dict); |
172 | ~ExponentialFunction() override; |
173 | Function *copy() const override { return new ExponentialFunction(this); } |
174 | Type getType() const override { return Type::Exponential; } |
175 | void transform(const double *in, double *out) const override; |
176 | bool isOk() const override { return ok; } |
177 | |
178 | const double *getC0() const { return c0; } |
179 | const double *getC1() const { return c1; } |
180 | double getE() const { return e; } |
181 | |
182 | private: |
183 | explicit ExponentialFunction(const ExponentialFunction *func); |
184 | |
185 | double c0[funcMaxOutputs]; |
186 | double c1[funcMaxOutputs]; |
187 | double e; |
188 | bool isLinear; |
189 | bool ok; |
190 | }; |
191 | |
192 | //------------------------------------------------------------------------ |
193 | // StitchingFunction |
194 | //------------------------------------------------------------------------ |
195 | |
196 | class StitchingFunction : public Function |
197 | { |
198 | public: |
199 | StitchingFunction(Object *funcObj, Dict *dict, std::set<int> *usedParents); |
200 | ~StitchingFunction() override; |
201 | Function *copy() const override { return new StitchingFunction(this); } |
202 | Type getType() const override { return Type::Stitching; } |
203 | void transform(const double *in, double *out) const override; |
204 | bool isOk() const override { return ok; } |
205 | |
206 | int getNumFuncs() const { return k; } |
207 | const Function *getFunc(int i) const { return funcs[i]; } |
208 | const double *getBounds() const { return bounds; } |
209 | const double *getEncode() const { return encode; } |
210 | const double *getScale() const { return scale; } |
211 | |
212 | private: |
213 | explicit StitchingFunction(const StitchingFunction *func); |
214 | |
215 | int k; |
216 | Function **funcs; |
217 | double *bounds; |
218 | double *encode; |
219 | double *scale; |
220 | bool ok; |
221 | }; |
222 | |
223 | //------------------------------------------------------------------------ |
224 | // PostScriptFunction |
225 | //------------------------------------------------------------------------ |
226 | |
227 | class PostScriptFunction : public Function |
228 | { |
229 | public: |
230 | PostScriptFunction(Object *funcObj, Dict *dict); |
231 | ~PostScriptFunction() override; |
232 | Function *copy() const override { return new PostScriptFunction(this); } |
233 | Type getType() const override { return Type::PostScript; } |
234 | void transform(const double *in, double *out) const override; |
235 | bool isOk() const override { return ok; } |
236 | |
237 | const GooString *getCodeString() const { return codeString; } |
238 | |
239 | private: |
240 | explicit PostScriptFunction(const PostScriptFunction *func); |
241 | bool parseCode(Stream *str, int *codePtr); |
242 | std::unique_ptr<GooString> getToken(Stream *str); |
243 | void resizeCode(int newSize); |
244 | void exec(PSStack *stack, int codePtr) const; |
245 | |
246 | GooString *codeString; |
247 | PSObject *code; |
248 | int codeSize; |
249 | mutable double cacheIn[funcMaxInputs]; |
250 | mutable double cacheOut[funcMaxOutputs]; |
251 | bool ok; |
252 | }; |
253 | |
254 | #endif |
255 | |