/src/poppler/poppler/Function.h
Line | Count | Source |
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-2026 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 | | // Copyright (C) 2025, 2026 g10 Code GmbH, Author: Sune Stolborg Vuorela <sune@vuorela.dk> |
22 | | // Copyright (C) 2026 Stefan Brüns <stefan.bruens@rwth-aachen.de> |
23 | | // |
24 | | // To see a description of the changes please see the Changelog file that |
25 | | // came with your tarball or type make ChangeLog if you are building from git |
26 | | // |
27 | | //======================================================================== |
28 | | |
29 | | #ifndef FUNCTION_H |
30 | | #define FUNCTION_H |
31 | | |
32 | | #include "poppler_private_export.h" |
33 | | |
34 | | #include <array> |
35 | | #include <memory> |
36 | | #include <vector> |
37 | | |
38 | | class Dict; |
39 | | class Object; |
40 | | class Stream; |
41 | | struct PSObject; |
42 | | class PSStack; |
43 | | struct RefRecursionChecker; |
44 | | |
45 | | //------------------------------------------------------------------------ |
46 | | // Function |
47 | | //------------------------------------------------------------------------ |
48 | | |
49 | 0 | #define funcMaxInputs 32 |
50 | 0 | #define funcMaxOutputs 32 |
51 | 0 | #define sampledFuncMaxInputs 16 |
52 | | |
53 | | class POPPLER_PRIVATE_EXPORT Function |
54 | | { |
55 | | public: |
56 | | Function(); |
57 | | |
58 | | virtual ~Function(); |
59 | | |
60 | | Function(const Function &) = delete; |
61 | | Function &operator=(const Function &other) = delete; |
62 | | |
63 | | // Construct a function. Returns NULL if unsuccessful. |
64 | | static std::unique_ptr<Function> parse(Object *funcObj); |
65 | | |
66 | | // Initialize the entries common to all function types. |
67 | | bool init(Dict *dict); |
68 | | |
69 | | virtual std::unique_ptr<Function> copy() const = 0; |
70 | | |
71 | | enum class Type |
72 | | { |
73 | | Identity, |
74 | | Sampled, |
75 | | Exponential, |
76 | | Stitching, |
77 | | PostScript |
78 | | }; |
79 | | |
80 | | virtual Type getType() const = 0; |
81 | | |
82 | | // Return size of input and output tuples. |
83 | 0 | int getInputSize() const { return m; } |
84 | 0 | int getOutputSize() const { return n; } |
85 | | |
86 | 0 | double getDomainMin(int i) const { return domain[i][0]; } |
87 | 0 | double getDomainMax(int i) const { return domain[i][1]; } |
88 | 0 | double getRangeMin(int i) const { return range[i][0]; } |
89 | 0 | double getRangeMax(int i) const { return range[i][1]; } |
90 | 0 | bool getHasRange() const { return hasRange; } |
91 | 0 | virtual bool hasDifferentResultSet(const Function * /*func*/) const { return false; } |
92 | | |
93 | | // Transform an input tuple into an output tuple. |
94 | | virtual void transform(const double *in, double *out) const = 0; |
95 | | |
96 | | virtual bool isOk() const = 0; |
97 | | |
98 | | protected: |
99 | | static std::unique_ptr<Function> parse(Object *funcObj, RefRecursionChecker &usedParents); |
100 | | |
101 | | explicit Function(const Function *func); |
102 | | |
103 | | int m, n; // size of input and output tuples |
104 | | double // min and max values for function domain |
105 | | domain[funcMaxInputs][2]; |
106 | | double // min and max values for function range |
107 | | range[funcMaxOutputs][2]; |
108 | | bool hasRange; // set if range is defined |
109 | | }; |
110 | | |
111 | | //------------------------------------------------------------------------ |
112 | | // IdentityFunction |
113 | | //------------------------------------------------------------------------ |
114 | | |
115 | | class IdentityFunction : public Function |
116 | | { |
117 | | public: |
118 | | IdentityFunction(); |
119 | | ~IdentityFunction() override; |
120 | 0 | std::unique_ptr<Function> copy() const override { return std::make_unique<IdentityFunction>(); } |
121 | 0 | Type getType() const override { return Type::Identity; } |
122 | | void transform(const double *in, double *out) const override; |
123 | 0 | bool isOk() const override { return true; } |
124 | | |
125 | | private: |
126 | | }; |
127 | | |
128 | | //------------------------------------------------------------------------ |
129 | | // SampledFunction |
130 | | //------------------------------------------------------------------------ |
131 | | |
132 | | class SampledFunction : public Function |
133 | | { |
134 | | class PrivateTag |
135 | | { |
136 | | }; |
137 | | |
138 | | public: |
139 | | SampledFunction(Object *funcObj, Dict *dict); |
140 | | ~SampledFunction() override; |
141 | 0 | std::unique_ptr<Function> copy() const override { return std::make_unique<SampledFunction>(this); } |
142 | 0 | Type getType() const override { return Type::Sampled; } |
143 | | void transform(const double *in, double *out) const override; |
144 | 0 | bool isOk() const override { return ok; } |
145 | | bool hasDifferentResultSet(const Function *func) const override; |
146 | | |
147 | 0 | int getSampleSize(int i) const { return sampleSize[i]; } |
148 | 0 | double getEncodeMin(int i) const { return encode[i][0]; } |
149 | 0 | double getEncodeMax(int i) const { return encode[i][1]; } |
150 | 0 | double getDecodeMin(int i) const { return decode[i][0]; } |
151 | 0 | double getDecodeMax(int i) const { return decode[i][1]; } |
152 | 0 | const double *getSamples() const { return samples; } |
153 | 0 | int getSampleNumber() const { return nSamples; } |
154 | | |
155 | | explicit SampledFunction(const SampledFunction *func, PrivateTag /*unused*/ = {}); |
156 | | |
157 | | private: |
158 | | int // number of samples for each domain element |
159 | | sampleSize[funcMaxInputs]; |
160 | | double // min and max values for domain encoder |
161 | | encode[funcMaxInputs][2]; |
162 | | double // min and max values for range decoder |
163 | | decode[funcMaxOutputs][2]; |
164 | | double // input multipliers |
165 | | inputMul[funcMaxInputs]; |
166 | | int *idxOffset; |
167 | | double *samples; // the samples |
168 | | int nSamples; // size of the samples array |
169 | | double *sBuf; // buffer for the transform function |
170 | | mutable double cacheIn[funcMaxInputs]; |
171 | | mutable double cacheOut[funcMaxOutputs]; |
172 | | bool ok; |
173 | | }; |
174 | | |
175 | | //------------------------------------------------------------------------ |
176 | | // ExponentialFunction |
177 | | //------------------------------------------------------------------------ |
178 | | |
179 | | class ExponentialFunction : public Function |
180 | | { |
181 | | class PrivateTag |
182 | | { |
183 | | }; |
184 | | |
185 | | public: |
186 | | explicit ExponentialFunction(Dict *dict); |
187 | | ~ExponentialFunction() override; |
188 | 0 | std::unique_ptr<Function> copy() const override { return std::make_unique<ExponentialFunction>(this); } |
189 | 0 | Type getType() const override { return Type::Exponential; } |
190 | | void transform(const double *in, double *out) const override; |
191 | 0 | bool isOk() const override { return ok; } |
192 | | |
193 | 0 | const double *getC0() const { return c0; } |
194 | 0 | const double *getC1() const { return c1; } |
195 | 0 | double getE() const { return e; } |
196 | | |
197 | | explicit ExponentialFunction(const ExponentialFunction *func, PrivateTag /*unused*/ = {}); |
198 | | |
199 | | private: |
200 | | double c0[funcMaxOutputs]; |
201 | | double c1[funcMaxOutputs]; |
202 | | double e; |
203 | | bool isLinear; |
204 | | bool ok; |
205 | | }; |
206 | | |
207 | | //------------------------------------------------------------------------ |
208 | | // StitchingFunction |
209 | | //------------------------------------------------------------------------ |
210 | | |
211 | | class StitchingFunction : public Function |
212 | | { |
213 | | class PrivateTag |
214 | | { |
215 | | }; |
216 | | |
217 | | public: |
218 | | StitchingFunction(Dict *dict, RefRecursionChecker &usedParents); |
219 | | ~StitchingFunction() override; |
220 | 0 | std::unique_ptr<Function> copy() const override { return std::make_unique<StitchingFunction>(this); } |
221 | 0 | Type getType() const override { return Type::Stitching; } |
222 | | void transform(const double *in, double *out) const override; |
223 | 0 | bool isOk() const override { return ok; } |
224 | | |
225 | 0 | int getNumFuncs() const { return funcs.size(); } |
226 | 0 | const Function *getFunc(int i) const { return funcs[i].get(); } |
227 | 0 | const double *getBounds() const { return bounds; } |
228 | 0 | const double *getEncode() const { return encode; } |
229 | 0 | const double *getScale() const { return scale; } |
230 | | |
231 | | explicit StitchingFunction(const StitchingFunction *func, PrivateTag /*unused*/ = {}); |
232 | | |
233 | | private: |
234 | | std::vector<std::unique_ptr<Function>> funcs; |
235 | | double *bounds; |
236 | | double *encode; |
237 | | double *scale; |
238 | | bool ok; |
239 | | }; |
240 | | |
241 | | //------------------------------------------------------------------------ |
242 | | // PostScriptFunction |
243 | | //------------------------------------------------------------------------ |
244 | | |
245 | | class PostScriptFunction : public Function |
246 | | { |
247 | | class PrivateTag |
248 | | { |
249 | | }; |
250 | | |
251 | | public: |
252 | | PostScriptFunction(Object *funcObj, Dict *dict); |
253 | | ~PostScriptFunction() override; |
254 | 0 | std::unique_ptr<Function> copy() const override { return std::make_unique<PostScriptFunction>(this); } |
255 | 0 | Type getType() const override { return Type::PostScript; } |
256 | | void transform(const double *in, double *out) const override; |
257 | 0 | bool isOk() const override { return ok; } |
258 | | |
259 | 0 | const std::string &getCodeString() const { return codeString; } |
260 | | |
261 | | explicit PostScriptFunction(const PostScriptFunction *func, PrivateTag /*unused*/ = {}); |
262 | | |
263 | | private: |
264 | | bool parseCode(Stream *str, int *codePtr, int &recursionCounter); |
265 | | std::string getToken(Stream *str); |
266 | | void resizeCode(int newSize); |
267 | | void exec(PSStack *stack, int codePtr) const; |
268 | | |
269 | | std::string codeString; |
270 | | std::vector<PSObject> code; |
271 | | mutable std::array<double, funcMaxInputs> cacheIn; |
272 | | mutable std::array<double, funcMaxOutputs> cacheOut; |
273 | | bool ok; |
274 | | }; |
275 | | |
276 | | #endif |