Coverage Report

Created: 2026-07-30 07:17

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/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