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
33class Dict;
34class Stream;
35struct PSObject;
36class PSStack;
37
38//------------------------------------------------------------------------
39// Function
40//------------------------------------------------------------------------
41
42#define funcMaxInputs 32
43#define funcMaxOutputs 32
44#define sampledFuncMaxInputs 16
45
46class POPPLER_PRIVATE_EXPORT Function
47{
48public:
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
91protected:
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
108class IdentityFunction : public Function
109{
110public:
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
118private:
119};
120
121//------------------------------------------------------------------------
122// SampledFunction
123//------------------------------------------------------------------------
124
125class SampledFunction : public Function
126{
127public:
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
144private:
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
168class ExponentialFunction : public Function
169{
170public:
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
182private:
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
196class StitchingFunction : public Function
197{
198public:
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
212private:
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
227class PostScriptFunction : public Function
228{
229public:
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
239private:
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

source code of poppler/poppler/Function.h