Coverage Report

Created: 2025-07-23 06:37

/src/mupdf/source/pdf/pdf-function.c
Line
Count
Source (jump to first uncovered line)
1
// Copyright (C) 2004-2025 Artifex Software, Inc.
2
//
3
// This file is part of MuPDF.
4
//
5
// MuPDF is free software: you can redistribute it and/or modify it under the
6
// terms of the GNU Affero General Public License as published by the Free
7
// Software Foundation, either version 3 of the License, or (at your option)
8
// any later version.
9
//
10
// MuPDF is distributed in the hope that it will be useful, but WITHOUT ANY
11
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12
// FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
13
// details.
14
//
15
// You should have received a copy of the GNU Affero General Public License
16
// along with MuPDF. If not, see <https://www.gnu.org/licenses/agpl-3.0.en.html>
17
//
18
// Alternative licensing terms are available from the licensor.
19
// For commercial licensing, see <https://www.artifex.com/> or contact
20
// Artifex Software, Inc., 39 Mesa Street, Suite 108A, San Francisco,
21
// CA 94129, USA, for further information.
22
23
#include "mupdf/fitz.h"
24
#include "mupdf/pdf.h"
25
26
#include <string.h>
27
#include <math.h>
28
#include <float.h>
29
#include <limits.h>
30
31
static pdf_function *pdf_load_function_imp(fz_context *ctx, pdf_obj *dict, int in, int out, pdf_cycle_list *cycle);
32
33
0
#define DIV_BY_ZERO(a, b, min, max) (((a) < 0) ^ ((b) < 0) ? (min) : (max))
34
35
enum
36
{
37
  MAX_N = FZ_MAX_COLORS,
38
  MAX_M = FZ_MAX_COLORS
39
};
40
41
enum
42
{
43
  SAMPLE = 0,
44
  EXPONENTIAL = 2,
45
  STITCHING = 3,
46
  POSTSCRIPT = 4
47
};
48
49
typedef struct
50
{
51
  int type;
52
  union
53
  {
54
    int b;        /* boolean (stack only) */
55
    int i;        /* integer (stack and code) */
56
    float f;      /* real (stack and code) */
57
    int op;       /* operator (code only) */
58
    int block;      /* if/ifelse block pointer (code only) */
59
  } u;
60
} psobj;
61
62
struct pdf_function
63
{
64
  fz_function super;
65
66
  float domain[MAX_M][2]; /* even index : min value, odd index : max value */
67
  float range[MAX_N][2];  /* even index : min value, odd index : max value */
68
  int has_range;
69
};
70
71
typedef struct
72
{
73
  pdf_function super;
74
75
  unsigned short bps;
76
  int size[MAX_M];
77
  float encode[MAX_M][2];
78
  float decode[MAX_N][2];
79
  float *samples;
80
} pdf_function_sa;
81
82
typedef struct
83
{
84
  pdf_function super;
85
86
  float n;
87
  float c0[MAX_N];
88
  float c1[MAX_N];
89
} pdf_function_e;
90
91
typedef struct
92
{
93
  pdf_function super;
94
95
  int k;
96
  pdf_function **funcs; /* k */
97
  float *bounds; /* k - 1 */
98
  float *encode; /* k * 2 */
99
} pdf_function_st;
100
101
typedef struct
102
{
103
  pdf_function super;
104
105
  psobj *code;
106
  int cap;
107
} pdf_function_p;
108
109
pdf_function *
110
pdf_keep_function(fz_context *ctx, pdf_function *func)
111
0
{
112
0
  return (pdf_function *)fz_keep_function(ctx, &func->super);
113
0
}
114
115
void
116
pdf_drop_function(fz_context *ctx, pdf_function *func)
117
8.66k
{
118
8.66k
  fz_drop_function(ctx, &func->super);
119
8.66k
}
120
121
size_t
122
pdf_function_size(fz_context *ctx, pdf_function *func)
123
2.63k
{
124
2.63k
  return fz_function_size(ctx, &func->super);
125
2.63k
}
126
127
static inline float lerp(float x, float xmin, float xmax, float ymin, float ymax)
128
2.19M
{
129
2.19M
  if (xmin == xmax)
130
16
    return ymin;
131
2.19M
  if (ymin == ymax)
132
12.7k
    return ymin;
133
2.17M
  return ymin + (x - xmin) * (ymax - ymin) / (xmax - xmin);
134
2.19M
}
135
136
/*
137
 * PostScript calculator
138
 */
139
140
enum { PS_BOOL, PS_INT, PS_REAL, PS_OPERATOR, PS_BLOCK };
141
142
enum
143
{
144
  PS_OP_ABS, PS_OP_ADD, PS_OP_AND, PS_OP_ATAN, PS_OP_BITSHIFT,
145
  PS_OP_CEILING, PS_OP_COPY, PS_OP_COS, PS_OP_CVI, PS_OP_CVR,
146
  PS_OP_DIV, PS_OP_DUP, PS_OP_EQ, PS_OP_EXCH, PS_OP_EXP,
147
  PS_OP_FALSE, PS_OP_FLOOR, PS_OP_GE, PS_OP_GT, PS_OP_IDIV, PS_OP_IF,
148
  PS_OP_IFELSE, PS_OP_INDEX, PS_OP_LE, PS_OP_LN, PS_OP_LOG, PS_OP_LT,
149
  PS_OP_MOD, PS_OP_MUL, PS_OP_NE, PS_OP_NEG, PS_OP_NOT, PS_OP_OR,
150
  PS_OP_POP, PS_OP_RETURN, PS_OP_ROLL, PS_OP_ROUND, PS_OP_SIN,
151
  PS_OP_SQRT, PS_OP_SUB, PS_OP_TRUE, PS_OP_TRUNCATE, PS_OP_XOR
152
};
153
154
static char *ps_op_names[] =
155
{
156
  "abs", "add", "and", "atan", "bitshift", "ceiling", "copy",
157
  "cos", "cvi", "cvr", "div", "dup", "eq", "exch", "exp",
158
  "false", "floor", "ge", "gt", "idiv", "if", "ifelse", "index", "le", "ln",
159
  "log", "lt", "mod", "mul", "ne", "neg", "not", "or", "pop", "return",
160
  "roll", "round", "sin", "sqrt", "sub", "true", "truncate", "xor"
161
};
162
163
typedef struct
164
{
165
  psobj stack[100];
166
  int sp;
167
} ps_stack;
168
169
static void
170
ps_init_stack(ps_stack *st)
171
2.61M
{
172
2.61M
  memset(st->stack, 0, sizeof(st->stack));
173
2.61M
  st->sp = 0;
174
2.61M
}
175
176
static inline int ps_overflow(ps_stack *st, int n)
177
65.6M
{
178
65.6M
  return n < 0 || st->sp + n >= (int)nelem(st->stack);
179
65.6M
}
180
181
static inline int ps_underflow(ps_stack *st, int n)
182
195M
{
183
195M
  return n < 0 || n > st->sp;
184
195M
}
185
186
static inline int ps_is_type(ps_stack *st, int t)
187
96.9M
{
188
96.9M
  return !ps_underflow(st, 1) && st->stack[st->sp - 1].type == t;
189
96.9M
}
190
191
static inline int ps_is_type2(ps_stack *st, int t)
192
10.7M
{
193
10.7M
  return !ps_underflow(st, 2) && st->stack[st->sp - 1].type == t && st->stack[st->sp - 2].type == t;
194
10.7M
}
195
196
static void
197
ps_push_bool(ps_stack *st, int b)
198
1.04M
{
199
1.04M
  if (!ps_overflow(st, 1))
200
1.04M
  {
201
1.04M
    st->stack[st->sp].type = PS_BOOL;
202
1.04M
    st->stack[st->sp].u.b = b;
203
1.04M
    st->sp++;
204
1.04M
  }
205
1.04M
}
206
207
static void
208
ps_push_int(ps_stack *st, int n)
209
26.6M
{
210
26.6M
  if (!ps_overflow(st, 1))
211
26.6M
  {
212
26.6M
    st->stack[st->sp].type = PS_INT;
213
26.6M
    st->stack[st->sp].u.i = n;
214
26.6M
    st->sp++;
215
26.6M
  }
216
26.6M
}
217
218
static void
219
ps_push_real(ps_stack *st, float n)
220
32.8M
{
221
32.8M
  if (!ps_overflow(st, 1))
222
32.8M
  {
223
32.8M
    st->stack[st->sp].type = PS_REAL;
224
32.8M
    if (isnan(n))
225
0
    {
226
      /* Push 1.0, as it's a small known value that won't
227
       * cause a divide by 0. Same reason as in fz_atof. */
228
0
      n = 1.0f;
229
0
    }
230
32.8M
    st->stack[st->sp].u.f = fz_clamp(n, -FLT_MAX, FLT_MAX);
231
32.8M
    st->sp++;
232
32.8M
  }
233
32.8M
}
234
235
static int
236
ps_pop_bool(ps_stack *st)
237
1.04M
{
238
1.04M
  if (!ps_underflow(st, 1))
239
1.04M
  {
240
1.04M
    if (ps_is_type(st, PS_BOOL))
241
1.04M
      return st->stack[--st->sp].u.b;
242
1.04M
  }
243
0
  return 0;
244
1.04M
}
245
246
static int
247
ps_pop_int(ps_stack *st)
248
20.9M
{
249
20.9M
  if (!ps_underflow(st, 1))
250
20.9M
  {
251
20.9M
    if (ps_is_type(st, PS_INT))
252
20.9M
      return st->stack[--st->sp].u.i;
253
27.4k
    if (ps_is_type(st, PS_REAL))
254
27.4k
      return st->stack[--st->sp].u.f;
255
27.4k
  }
256
0
  return 0;
257
20.9M
}
258
259
static float
260
ps_pop_real(ps_stack *st)
261
39.7M
{
262
39.7M
  if (!ps_underflow(st, 1))
263
39.7M
  {
264
39.7M
    if (ps_is_type(st, PS_INT))
265
5.63M
      return st->stack[--st->sp].u.i;
266
34.0M
    if (ps_is_type(st, PS_REAL))
267
34.0M
      return st->stack[--st->sp].u.f;
268
34.0M
  }
269
27.4k
  return 0;
270
39.7M
}
271
272
static void
273
ps_copy(ps_stack *st, int n)
274
3.86M
{
275
3.86M
  if (!ps_underflow(st, n) && !ps_overflow(st, n))
276
3.86M
  {
277
3.86M
    memcpy(st->stack + st->sp, st->stack + st->sp - n, n * sizeof(psobj));
278
3.86M
    st->sp += n;
279
3.86M
  }
280
3.86M
}
281
282
static void
283
ps_roll(ps_stack *st, int n, int j)
284
17.0M
{
285
17.0M
  psobj tmp;
286
17.0M
  int i;
287
288
17.0M
  if (ps_underflow(st, n) || j == 0 || n == 0)
289
109k
    return;
290
291
16.9M
  if (j >= 0)
292
14.2M
  {
293
14.2M
    j %= n;
294
14.2M
  }
295
2.72M
  else
296
2.72M
  {
297
2.72M
    j = -j % n;
298
2.72M
    if (j != 0)
299
2.72M
      j = n - j;
300
2.72M
  }
301
302
16.9M
  if (j*2 > n)
303
3.39M
  {
304
6.79M
    for (i = j; i < n; i++)
305
3.39M
    {
306
3.39M
      tmp = st->stack[st->sp - n];
307
3.39M
      memmove(st->stack + st->sp - n, st->stack + st->sp - n + 1, (n-1) * sizeof(psobj));
308
3.39M
      st->stack[st->sp - 1] = tmp;
309
3.39M
    }
310
3.39M
  }
311
13.5M
  else
312
13.5M
  {
313
27.0M
    for (i = 0; i < j; i++)
314
13.5M
    {
315
13.5M
      tmp = st->stack[st->sp - 1];
316
13.5M
      memmove(st->stack + st->sp - n + 1, st->stack + st->sp - n, (n-1) * sizeof(psobj));
317
13.5M
      st->stack[st->sp - n] = tmp;
318
13.5M
    }
319
13.5M
  }
320
16.9M
}
321
322
static void
323
ps_index(ps_stack *st, int n)
324
1.27M
{
325
1.27M
  if (!ps_overflow(st, 1) && !ps_underflow(st, n + 1))
326
1.27M
  {
327
1.27M
    st->stack[st->sp] = st->stack[st->sp - n - 1];
328
1.27M
    st->sp++;
329
1.27M
  }
330
1.27M
}
331
332
static void
333
ps_run(fz_context *ctx, psobj *code, ps_stack *st, int pc)
334
3.39M
{
335
3.39M
  int i1, i2;
336
3.39M
  float r1, r2;
337
3.39M
  int b1, b2;
338
339
83.3M
  while (1)
340
83.3M
  {
341
83.3M
    switch (code[pc].type)
342
83.3M
    {
343
25.8M
    case PS_INT:
344
25.8M
      ps_push_int(st, code[pc++].u.i);
345
25.8M
      break;
346
347
6.55M
    case PS_REAL:
348
6.55M
      ps_push_real(st, code[pc++].u.f);
349
6.55M
      break;
350
351
50.9M
    case PS_OPERATOR:
352
50.9M
      switch (code[pc++].u.op)
353
50.9M
      {
354
1.04M
      case PS_OP_ABS:
355
1.04M
        if (ps_is_type(st, PS_INT))
356
0
          ps_push_int(st, fz_absi(ps_pop_int(st)));
357
1.04M
        else
358
1.04M
          ps_push_real(st, fz_abs(ps_pop_real(st)));
359
1.04M
        break;
360
361
327k
      case PS_OP_ADD:
362
327k
        if (ps_is_type2(st, PS_INT)) {
363
0
          i2 = ps_pop_int(st);
364
0
          i1 = ps_pop_int(st);
365
0
          ps_push_int(st, i1 + i2);
366
0
        }
367
327k
        else {
368
327k
          r2 = ps_pop_real(st);
369
327k
          r1 = ps_pop_real(st);
370
327k
          ps_push_real(st, r1 + r2);
371
327k
        }
372
327k
        break;
373
374
0
      case PS_OP_AND:
375
0
        if (ps_is_type2(st, PS_INT)) {
376
0
          i2 = ps_pop_int(st);
377
0
          i1 = ps_pop_int(st);
378
0
          ps_push_int(st, i1 & i2);
379
0
        }
380
0
        else {
381
0
          b2 = ps_pop_bool(st);
382
0
          b1 = ps_pop_bool(st);
383
0
          ps_push_bool(st, b1 && b2);
384
0
        }
385
0
        break;
386
387
720k
      case PS_OP_ATAN:
388
720k
        r2 = ps_pop_real(st);
389
720k
        r1 = ps_pop_real(st);
390
720k
        r1 = atan2f(r1, r2) * FZ_RADIAN;
391
720k
        if (r1 < 0)
392
244k
          r1 += 360;
393
720k
        ps_push_real(st, r1);
394
720k
        break;
395
396
0
      case PS_OP_BITSHIFT:
397
0
        i2 = ps_pop_int(st);
398
0
        i1 = ps_pop_int(st);
399
0
        if (i2 > 0 && i2 < 8 * (int)sizeof (i2))
400
0
          ps_push_int(st, i1 << i2);
401
0
        else if (i2 < 0 && i2 > -8 * (int)sizeof (i2))
402
0
          ps_push_int(st, (int)((unsigned int)i1 >> -i2));
403
0
        else
404
0
          ps_push_int(st, i1);
405
0
        break;
406
407
0
      case PS_OP_CEILING:
408
0
        r1 = ps_pop_real(st);
409
0
        ps_push_real(st, ceilf(r1));
410
0
        break;
411
412
0
      case PS_OP_COPY:
413
0
        ps_copy(st, ps_pop_int(st));
414
0
        break;
415
416
720k
      case PS_OP_COS:
417
720k
        r1 = ps_pop_real(st);
418
720k
        ps_push_real(st, cosf(r1/FZ_RADIAN));
419
720k
        break;
420
421
0
      case PS_OP_CVI:
422
0
        ps_push_int(st, ps_pop_int(st));
423
0
        break;
424
425
4.03M
      case PS_OP_CVR:
426
4.03M
        ps_push_real(st, ps_pop_real(st));
427
4.03M
        break;
428
429
1.04M
      case PS_OP_DIV:
430
1.04M
        r2 = ps_pop_real(st);
431
1.04M
        r1 = ps_pop_real(st);
432
1.04M
        if (fabsf(r2) >= FLT_EPSILON)
433
1.04M
          ps_push_real(st, r1 / r2);
434
0
        else
435
0
          ps_push_real(st, DIV_BY_ZERO(r1, r2, -FLT_MAX, FLT_MAX));
436
1.04M
        break;
437
438
3.86M
      case PS_OP_DUP:
439
3.86M
        ps_copy(st, 1);
440
3.86M
        break;
441
442
0
      case PS_OP_EQ:
443
0
        if (ps_is_type2(st, PS_BOOL)) {
444
0
          b2 = ps_pop_bool(st);
445
0
          b1 = ps_pop_bool(st);
446
0
          ps_push_bool(st, b1 == b2);
447
0
        }
448
0
        else if (ps_is_type2(st, PS_INT)) {
449
0
          i2 = ps_pop_int(st);
450
0
          i1 = ps_pop_int(st);
451
0
          ps_push_bool(st, i1 == i2);
452
0
        }
453
0
        else {
454
0
          r2 = ps_pop_real(st);
455
0
          r1 = ps_pop_real(st);
456
0
          ps_push_bool(st, r1 == r2);
457
0
        }
458
0
        break;
459
460
7.96M
      case PS_OP_EXCH:
461
7.96M
        ps_roll(st, 2, 1);
462
7.96M
        break;
463
464
0
      case PS_OP_EXP:
465
0
        r2 = ps_pop_real(st);
466
0
        r1 = ps_pop_real(st);
467
0
        ps_push_real(st, powf(r1, r2));
468
0
        break;
469
470
0
      case PS_OP_FALSE:
471
0
        ps_push_bool(st, 0);
472
0
        break;
473
474
0
      case PS_OP_FLOOR:
475
0
        r1 = ps_pop_real(st);
476
0
        ps_push_real(st, floorf(r1));
477
0
        break;
478
479
0
      case PS_OP_GE:
480
0
        if (ps_is_type2(st, PS_INT)) {
481
0
          i2 = ps_pop_int(st);
482
0
          i1 = ps_pop_int(st);
483
0
          ps_push_bool(st, i1 >= i2);
484
0
        }
485
0
        else {
486
0
          r2 = ps_pop_real(st);
487
0
          r1 = ps_pop_real(st);
488
0
          ps_push_bool(st, r1 >= r2);
489
0
        }
490
0
        break;
491
492
4
      case PS_OP_GT:
493
4
        if (ps_is_type2(st, PS_INT)) {
494
3
          i2 = ps_pop_int(st);
495
3
          i1 = ps_pop_int(st);
496
3
          ps_push_bool(st, i1 > i2);
497
3
        }
498
1
        else {
499
1
          r2 = ps_pop_real(st);
500
1
          r1 = ps_pop_real(st);
501
1
          ps_push_bool(st, r1 > r2);
502
1
        }
503
4
        break;
504
505
0
      case PS_OP_IDIV:
506
0
        i2 = ps_pop_int(st);
507
0
        i1 = ps_pop_int(st);
508
0
        if (i2 == 0) {
509
0
          ps_push_int(st, DIV_BY_ZERO(i1, i2, INT_MIN, INT_MAX));
510
0
        }
511
0
        else if (i1 == INT_MIN && i2 == -1) {
512
0
          ps_push_int(st, INT_MAX);
513
0
        }
514
0
        else {
515
0
          ps_push_int(st, i1 / i2);
516
0
        }
517
0
        break;
518
519
1.27M
      case PS_OP_INDEX:
520
1.27M
        ps_index(st, ps_pop_int(st));
521
1.27M
        break;
522
523
0
      case PS_OP_LE:
524
0
        if (ps_is_type2(st, PS_INT)) {
525
0
          i2 = ps_pop_int(st);
526
0
          i1 = ps_pop_int(st);
527
0
          ps_push_bool(st, i1 <= i2);
528
0
        }
529
0
        else {
530
0
          r2 = ps_pop_real(st);
531
0
          r1 = ps_pop_real(st);
532
0
          ps_push_bool(st, r1 <= r2);
533
0
        }
534
0
        break;
535
536
0
      case PS_OP_LN:
537
0
        r1 = ps_pop_real(st);
538
        /* Bug 692941 - logf as separate statement */
539
0
        r2 = logf(r1);
540
0
        ps_push_real(st, r2);
541
0
        break;
542
543
0
      case PS_OP_LOG:
544
0
        r1 = ps_pop_real(st);
545
0
        ps_push_real(st, log10f(r1));
546
0
        break;
547
548
1.04M
      case PS_OP_LT:
549
1.04M
        if (ps_is_type2(st, PS_INT)) {
550
0
          i2 = ps_pop_int(st);
551
0
          i1 = ps_pop_int(st);
552
0
          ps_push_bool(st, i1 < i2);
553
0
        }
554
1.04M
        else {
555
1.04M
          r2 = ps_pop_real(st);
556
1.04M
          r1 = ps_pop_real(st);
557
1.04M
          ps_push_bool(st, r1 < r2);
558
1.04M
        }
559
1.04M
        break;
560
561
0
      case PS_OP_MOD:
562
0
        i2 = ps_pop_int(st);
563
0
        i1 = ps_pop_int(st);
564
0
        if (i2 == 0) {
565
0
          ps_push_int(st, DIV_BY_ZERO(i1, i2, INT_MIN, INT_MAX));
566
0
        }
567
0
        else if (i1 == INT_MIN && i2 == -1) {
568
0
          ps_push_int(st, 0);
569
0
        }
570
0
        else {
571
0
          ps_push_int(st, i1 % i2);
572
0
        }
573
0
        break;
574
575
2.09M
      case PS_OP_MUL:
576
2.09M
        if (ps_is_type2(st, PS_INT)) {
577
770k
          i2 = ps_pop_int(st);
578
770k
          i1 = ps_pop_int(st);
579
770k
          ps_push_int(st, i1 * i2);
580
770k
        }
581
1.32M
        else {
582
1.32M
          r2 = ps_pop_real(st);
583
1.32M
          r1 = ps_pop_real(st);
584
1.32M
          ps_push_real(st, r1 * r2);
585
1.32M
        }
586
2.09M
        break;
587
588
0
      case PS_OP_NE:
589
0
        if (ps_is_type2(st, PS_BOOL)) {
590
0
          b2 = ps_pop_bool(st);
591
0
          b1 = ps_pop_bool(st);
592
0
          ps_push_bool(st, b1 != b2);
593
0
        }
594
0
        else if (ps_is_type2(st, PS_INT)) {
595
0
          i2 = ps_pop_int(st);
596
0
          i1 = ps_pop_int(st);
597
0
          ps_push_bool(st, i1 != i2);
598
0
        }
599
0
        else {
600
0
          r2 = ps_pop_real(st);
601
0
          r1 = ps_pop_real(st);
602
0
          ps_push_bool(st, r1 != r2);
603
0
        }
604
0
        break;
605
606
0
      case PS_OP_NEG:
607
0
        if (ps_is_type(st, PS_INT))
608
0
          ps_push_int(st, -ps_pop_int(st));
609
0
        else
610
0
          ps_push_real(st, -ps_pop_real(st));
611
0
        break;
612
613
0
      case PS_OP_NOT:
614
0
        if (ps_is_type(st, PS_BOOL))
615
0
          ps_push_bool(st, !ps_pop_bool(st));
616
0
        else
617
0
          ps_push_int(st, ~ps_pop_int(st));
618
0
        break;
619
620
0
      case PS_OP_OR:
621
0
        if (ps_is_type2(st, PS_BOOL)) {
622
0
          b2 = ps_pop_bool(st);
623
0
          b1 = ps_pop_bool(st);
624
0
          ps_push_bool(st, b1 || b2);
625
0
        }
626
0
        else {
627
0
          i2 = ps_pop_int(st);
628
0
          i1 = ps_pop_int(st);
629
0
          ps_push_int(st, i1 | i2);
630
0
        }
631
0
        break;
632
633
3.91M
      case PS_OP_POP:
634
3.91M
        if (!ps_underflow(st, 1))
635
3.91M
          st->sp--;
636
3.91M
        break;
637
638
9.08M
      case PS_OP_ROLL:
639
9.08M
        i2 = ps_pop_int(st);
640
9.08M
        i1 = ps_pop_int(st);
641
9.08M
        ps_roll(st, i1, i2);
642
9.08M
        break;
643
644
0
      case PS_OP_ROUND:
645
0
        if (!ps_is_type(st, PS_INT)) {
646
0
          r1 = ps_pop_real(st);
647
0
          ps_push_real(st, (r1 >= 0) ? floorf(r1 + 0.5f) : ceilf(r1 - 0.5f));
648
0
        }
649
0
        break;
650
651
1.04M
      case PS_OP_SIN:
652
1.04M
        r1 = ps_pop_real(st);
653
1.04M
        ps_push_real(st, sinf(r1/FZ_RADIAN));
654
1.04M
        break;
655
656
1.04M
      case PS_OP_SQRT:
657
1.04M
        r1 = ps_pop_real(st);
658
1.04M
        ps_push_real(st, sqrtf(r1));
659
1.04M
        break;
660
661
7.24M
      case PS_OP_SUB:
662
7.24M
        if (ps_is_type2(st, PS_INT)) {
663
0
          i2 = ps_pop_int(st);
664
0
          i1 = ps_pop_int(st);
665
0
          ps_push_int(st, i1 - i2);
666
0
        }
667
7.24M
        else {
668
7.24M
          r2 = ps_pop_real(st);
669
7.24M
          r1 = ps_pop_real(st);
670
7.24M
          ps_push_real(st, r1 - r2);
671
7.24M
        }
672
7.24M
        break;
673
674
0
      case PS_OP_TRUE:
675
0
        ps_push_bool(st, 1);
676
0
        break;
677
678
0
      case PS_OP_TRUNCATE:
679
0
        if (!ps_is_type(st, PS_INT)) {
680
0
          r1 = ps_pop_real(st);
681
0
          ps_push_real(st, (r1 >= 0) ? floorf(r1) : ceilf(r1));
682
0
        }
683
0
        break;
684
685
0
      case PS_OP_XOR:
686
0
        if (ps_is_type2(st, PS_BOOL)) {
687
0
          b2 = ps_pop_bool(st);
688
0
          b1 = ps_pop_bool(st);
689
0
          ps_push_bool(st, b1 ^ b2);
690
0
        }
691
0
        else {
692
0
          i2 = ps_pop_int(st);
693
0
          i1 = ps_pop_int(st);
694
0
          ps_push_int(st, i1 ^ i2);
695
0
        }
696
0
        break;
697
698
1.04M
      case PS_OP_IF:
699
1.04M
        b1 = ps_pop_bool(st);
700
1.04M
        if (b1)
701
770k
          ps_run(ctx, code, st, code[pc + 1].u.block);
702
1.04M
        pc = code[pc + 2].u.block;
703
1.04M
        break;
704
705
0
      case PS_OP_IFELSE:
706
0
        b1 = ps_pop_bool(st);
707
0
        if (b1)
708
0
          ps_run(ctx, code, st, code[pc + 1].u.block);
709
0
        else
710
0
          ps_run(ctx, code, st, code[pc + 0].u.block);
711
0
        pc = code[pc + 2].u.block;
712
0
        break;
713
714
3.39M
      case PS_OP_RETURN:
715
3.39M
        return;
716
717
0
      default:
718
0
        fz_warn(ctx, "foreign operator in calculator function");
719
0
        return;
720
50.9M
      }
721
47.5M
      break;
722
723
47.5M
    default:
724
0
      fz_warn(ctx, "foreign object in calculator function");
725
0
      return;
726
83.3M
    }
727
83.3M
  }
728
3.39M
}
729
730
static void
731
resize_code(fz_context *ctx, pdf_function_p *func, int newsize)
732
11.6k
{
733
11.6k
  if (newsize >= func->cap)
734
592
  {
735
592
    int new_cap = func->cap + 64;
736
592
    func->code = fz_realloc_array(ctx, func->code, new_cap, psobj);
737
592
    func->cap = new_cap;
738
592
  }
739
11.6k
}
740
741
static void
742
parse_code(fz_context *ctx, pdf_function_p *func, fz_stream *stream, int *codeptr, pdf_lexbuf *buf, int depth)
743
725
{
744
725
  pdf_token tok;
745
725
  int opptr, elseptr, ifptr;
746
725
  int a, b, mid, cmp;
747
748
725
  if (depth > 100)
749
2
    fz_throw(ctx, FZ_ERROR_SYNTAX, "too much nesting in calculator function");
750
751
11.6k
  while (1)
752
11.6k
  {
753
11.6k
    tok = pdf_lex(ctx, stream, buf);
754
755
11.6k
    switch (tok)
756
11.6k
    {
757
0
    case PDF_TOK_EOF:
758
0
      fz_throw(ctx, FZ_ERROR_SYNTAX, "truncated calculator function");
759
760
4.44k
    case PDF_TOK_INT:
761
4.44k
      resize_code(ctx, func, *codeptr);
762
4.44k
      func->code[*codeptr].type = PS_INT;
763
4.44k
      func->code[*codeptr].u.i = buf->i;
764
4.44k
      ++*codeptr;
765
4.44k
      break;
766
767
0
    case PDF_TOK_TRUE:
768
0
      resize_code(ctx, func, *codeptr);
769
0
      func->code[*codeptr].type = PS_BOOL;
770
0
      func->code[*codeptr].u.b = 1;
771
0
      ++*codeptr;
772
0
      break;
773
774
0
    case PDF_TOK_FALSE:
775
0
      resize_code(ctx, func, *codeptr);
776
0
      func->code[*codeptr].type = PS_BOOL;
777
0
      func->code[*codeptr].u.b = 0;
778
0
      ++*codeptr;
779
0
      break;
780
781
707
    case PDF_TOK_REAL:
782
707
      resize_code(ctx, func, *codeptr);
783
707
      func->code[*codeptr].type = PS_REAL;
784
707
      func->code[*codeptr].u.f = buf->f;
785
707
      ++*codeptr;
786
707
      break;
787
788
222
    case PDF_TOK_OPEN_BRACE:
789
222
      opptr = *codeptr;
790
222
      *codeptr += 4;
791
792
222
      resize_code(ctx, func, *codeptr);
793
794
222
      ifptr = *codeptr;
795
222
      parse_code(ctx, func, stream, codeptr, buf, depth + 1);
796
797
222
      tok = pdf_lex(ctx, stream, buf);
798
799
222
      if (tok == PDF_TOK_OPEN_BRACE)
800
0
      {
801
0
        elseptr = *codeptr;
802
0
        parse_code(ctx, func, stream, codeptr, buf, depth + 1);
803
804
0
        tok = pdf_lex(ctx, stream, buf);
805
0
      }
806
222
      else
807
222
      {
808
222
        elseptr = -1;
809
222
      }
810
811
222
      if (tok != PDF_TOK_KEYWORD)
812
0
        fz_throw(ctx, FZ_ERROR_SYNTAX, "missing keyword in 'if-else' context");
813
814
222
      if (!strcmp(buf->scratch, "if"))
815
20
      {
816
20
        if (elseptr >= 0)
817
0
          fz_throw(ctx, FZ_ERROR_SYNTAX, "too many branches for 'if'");
818
20
        func->code[opptr].type = PS_OPERATOR;
819
20
        func->code[opptr].u.op = PS_OP_IF;
820
20
        func->code[opptr+2].type = PS_BLOCK;
821
20
        func->code[opptr+2].u.block = ifptr;
822
20
        func->code[opptr+3].type = PS_BLOCK;
823
20
        func->code[opptr+3].u.block = *codeptr;
824
20
      }
825
202
      else if (!strcmp(buf->scratch, "ifelse"))
826
0
      {
827
0
        if (elseptr < 0)
828
0
          fz_throw(ctx, FZ_ERROR_SYNTAX, "not enough branches for 'ifelse'");
829
0
        func->code[opptr].type = PS_OPERATOR;
830
0
        func->code[opptr].u.op = PS_OP_IFELSE;
831
0
        func->code[opptr+1].type = PS_BLOCK;
832
0
        func->code[opptr+1].u.block = elseptr;
833
0
        func->code[opptr+2].type = PS_BLOCK;
834
0
        func->code[opptr+2].u.block = ifptr;
835
0
        func->code[opptr+3].type = PS_BLOCK;
836
0
        func->code[opptr+3].u.block = *codeptr;
837
0
      }
838
202
      else
839
202
      {
840
202
        fz_throw(ctx, FZ_ERROR_SYNTAX, "unknown keyword in 'if-else' context: '%s'", buf->scratch);
841
202
      }
842
20
      break;
843
844
469
    case PDF_TOK_CLOSE_BRACE:
845
469
      resize_code(ctx, func, *codeptr);
846
469
      func->code[*codeptr].type = PS_OPERATOR;
847
469
      func->code[*codeptr].u.op = PS_OP_RETURN;
848
469
      ++*codeptr;
849
469
      return;
850
851
5.78k
    case PDF_TOK_KEYWORD:
852
5.78k
      cmp = -1;
853
5.78k
      a = -1;
854
5.78k
      b = nelem(ps_op_names);
855
36.4k
      while (b - a > 1)
856
30.7k
      {
857
30.7k
        mid = (a + b) / 2;
858
30.7k
        cmp = strcmp(buf->scratch, ps_op_names[mid]);
859
30.7k
        if (cmp > 0)
860
15.5k
          a = mid;
861
15.1k
        else if (cmp < 0)
862
9.38k
          b = mid;
863
5.78k
        else
864
5.78k
          a = b = mid;
865
30.7k
      }
866
5.78k
      if (cmp != 0)
867
0
        fz_throw(ctx, FZ_ERROR_SYNTAX, "unknown operator: '%s'", buf->scratch);
868
5.78k
      if (a == PS_OP_IFELSE)
869
0
        fz_throw(ctx, FZ_ERROR_SYNTAX, "illegally positioned ifelse operator in function");
870
5.78k
      if (a == PS_OP_IF)
871
0
        fz_throw(ctx, FZ_ERROR_SYNTAX, "illegally positioned if operator in function");
872
873
5.78k
      resize_code(ctx, func, *codeptr);
874
5.78k
      func->code[*codeptr].type = PS_OPERATOR;
875
5.78k
      func->code[*codeptr].u.op = a;
876
5.78k
      ++*codeptr;
877
5.78k
      break;
878
879
52
    default:
880
52
      fz_throw(ctx, FZ_ERROR_SYNTAX, "calculator function syntax error");
881
11.6k
    }
882
11.6k
  }
883
723
}
884
885
static void
886
load_postscript_func(fz_context *ctx, pdf_function *func_, pdf_obj *dict)
887
510
{
888
510
  pdf_function_p *func = (pdf_function_p *)func_;
889
510
  fz_stream *stream = NULL;
890
510
  int codeptr;
891
510
  pdf_lexbuf buf;
892
510
  pdf_token tok;
893
894
510
  pdf_lexbuf_init(ctx, &buf, PDF_LEXBUF_SMALL);
895
896
510
  fz_var(stream);
897
898
1.02k
  fz_try(ctx)
899
1.02k
  {
900
510
    stream = pdf_open_stream(ctx, dict);
901
902
510
    tok = pdf_lex(ctx, stream, &buf);
903
510
    if (tok != PDF_TOK_OPEN_BRACE)
904
6
    {
905
6
      fz_throw(ctx, FZ_ERROR_SYNTAX, "stream is not a calculator function");
906
6
    }
907
908
504
    func->code = NULL;
909
504
    func->cap = 0;
910
911
504
    codeptr = 0;
912
504
    parse_code(ctx, func, stream, &codeptr, &buf, 0);
913
504
  }
914
1.02k
  fz_always(ctx)
915
510
  {
916
510
    fz_drop_stream(ctx, stream);
917
510
    pdf_lexbuf_fin(ctx, &buf);
918
510
  }
919
510
  fz_catch(ctx)
920
61
  {
921
61
    fz_rethrow(ctx);
922
61
  }
923
924
443
  func->super.super.size += func->cap * sizeof(psobj);
925
443
}
926
927
static void
928
eval_postscript_func(fz_context *ctx, fz_function *func_, const float *in, float *out)
929
2.61M
{
930
2.61M
  pdf_function_p *func = (pdf_function_p *)func_;
931
2.61M
  ps_stack st;
932
2.61M
  float x;
933
2.61M
  int i;
934
935
2.61M
  ps_init_stack(&st);
936
937
10.3M
  for (i = 0; i < func->super.super.m; i++)
938
7.72M
  {
939
7.72M
    x = fz_clamp(in[i], func->super.domain[i][0], func->super.domain[i][1]);
940
7.72M
    ps_push_real(&st, x);
941
7.72M
  }
942
943
2.61M
  ps_run(ctx, func->code, &st, 0);
944
945
11.0M
  for (i = func->super.super.n - 1; i >= 0; i--)
946
8.41M
  {
947
8.41M
    x = ps_pop_real(&st);
948
8.41M
    out[i] = fz_clamp(x, func->super.range[i][0], func->super.range[i][1]);
949
8.41M
  }
950
2.61M
}
951
952
/*
953
 * Sample function
954
 */
955
956
4.64k
#define MAX_SAMPLE_FUNCTION_SIZE (100 << 20)
957
958
static void
959
load_sample_func(fz_context *ctx, pdf_function *func_, pdf_obj *dict)
960
2.54k
{
961
2.54k
  pdf_function_sa *func = (pdf_function_sa *)func_;
962
2.54k
  fz_stream *stream;
963
2.54k
  pdf_obj *obj;
964
2.54k
  int samplecount;
965
2.54k
  int bps;
966
2.54k
  int i;
967
968
2.54k
  func->samples = NULL;
969
970
2.54k
  obj = pdf_dict_get(ctx, dict, PDF_NAME(Size));
971
2.54k
  if (pdf_array_len(ctx, obj) < func->super.super.m)
972
228
    fz_throw(ctx, FZ_ERROR_SYNTAX, "too few sample function dimension sizes");
973
2.31k
  if (pdf_array_len(ctx, obj) > func->super.super.m)
974
0
    fz_warn(ctx, "too many sample function dimension sizes");
975
4.64k
  for (i = 0; i < func->super.super.m; i++)
976
2.33k
  {
977
2.33k
    func->size[i] = pdf_array_get_int(ctx, obj, i);
978
2.33k
    if (func->size[i] <= 0)
979
0
    {
980
0
      fz_warn(ctx, "non-positive sample function dimension size");
981
0
      func->size[i] = 1;
982
0
    }
983
2.33k
  }
984
985
2.31k
  func->bps = bps = pdf_dict_get_int(ctx, dict, PDF_NAME(BitsPerSample));
986
987
4.64k
  for (i = 0; i < func->super.super.m; i++)
988
2.33k
  {
989
2.33k
    func->encode[i][0] = 0;
990
2.33k
    func->encode[i][1] = func->size[i] - 1;
991
2.33k
  }
992
2.31k
  obj = pdf_dict_get(ctx, dict, PDF_NAME(Encode));
993
2.31k
  if (pdf_is_array(ctx, obj))
994
1.53k
  {
995
1.53k
    int ranges = fz_mini(func->super.super.m, pdf_array_len(ctx, obj) / 2);
996
1.53k
    if (ranges != func->super.super.m)
997
1
      fz_warn(ctx, "wrong number of sample function input mappings");
998
999
3.05k
    for (i = 0; i < ranges; i++)
1000
1.52k
    {
1001
1.52k
      func->encode[i][0] = pdf_array_get_real(ctx, obj, i * 2 + 0);
1002
1.52k
      func->encode[i][1] = pdf_array_get_real(ctx, obj, i * 2 + 1);
1003
1.52k
    }
1004
1.53k
  }
1005
1006
8.27k
  for (i = 0; i < func->super.super.n; i++)
1007
5.96k
  {
1008
5.96k
    func->decode[i][0] = func->super.range[i][0];
1009
5.96k
    func->decode[i][1] = func->super.range[i][1];
1010
5.96k
  }
1011
1012
2.31k
  obj = pdf_dict_get(ctx, dict, PDF_NAME(Decode));
1013
2.31k
  if (pdf_is_array(ctx, obj))
1014
1.53k
  {
1015
1.53k
    int ranges = fz_mini(func->super.super.n, pdf_array_len(ctx, obj) / 2);
1016
1.53k
    if (ranges != func->super.super.n)
1017
0
      fz_warn(ctx, "wrong number of sample function output mappings");
1018
1019
6.13k
    for (i = 0; i < ranges; i++)
1020
4.59k
    {
1021
4.59k
      func->decode[i][0] = pdf_array_get_real(ctx, obj, i * 2 + 0);
1022
4.59k
      func->decode[i][1] = pdf_array_get_real(ctx, obj, i * 2 + 1);
1023
4.59k
    }
1024
1.53k
  }
1025
1026
4.64k
  for (i = 0, samplecount = func->super.super.n; i < func->super.super.m; i++)
1027
2.33k
  {
1028
2.33k
    if (samplecount > MAX_SAMPLE_FUNCTION_SIZE / func->size[i])
1029
2
      fz_throw(ctx, FZ_ERROR_SYNTAX, "sample function too large");
1030
2.32k
    samplecount *= func->size[i];
1031
2.32k
  }
1032
1033
2.31k
  if (samplecount > MAX_SAMPLE_FUNCTION_SIZE)
1034
0
    fz_throw(ctx, FZ_ERROR_SYNTAX, "sample function too large");
1035
1036
2.31k
  func->samples = Memento_label(fz_malloc_array(ctx, samplecount, float), "function_samples");
1037
2.31k
  func->super.super.size += samplecount * sizeof(float);
1038
1039
2.31k
  stream = pdf_open_stream(ctx, dict);
1040
1041
4.62k
  fz_try(ctx)
1042
4.62k
  {
1043
    /* read samples */
1044
7.99M
    for (i = 0; i < samplecount; i++)
1045
7.99M
    {
1046
7.99M
      float s;
1047
1048
7.99M
      if (fz_is_eof_bits(ctx, stream))
1049
322
        fz_throw(ctx, FZ_ERROR_SYNTAX, "truncated sample function stream");
1050
1051
7.99M
      switch (bps)
1052
7.99M
      {
1053
0
      case 1: s = fz_read_bits(ctx, stream, 1); break;
1054
0
      case 2: s = fz_read_bits(ctx, stream, 2) / 3.0f; break;
1055
0
      case 4: s = fz_read_bits(ctx, stream, 4) / 15.0f; break;
1056
7.99M
      case 8: s = fz_read_byte(ctx, stream) / 255.0f; break;
1057
0
      case 12: s = fz_read_bits(ctx, stream, 12) / 4095.0f; break;
1058
0
      case 16: s = fz_read_uint16(ctx, stream) / 65535.0f; break;
1059
0
      case 24: s = fz_read_uint24(ctx, stream) / 16777215.0f; break;
1060
0
      case 32: s = fz_read_uint32(ctx, stream) / 4294967295.0f; break;
1061
2
      default: fz_throw(ctx, FZ_ERROR_SYNTAX, "sample stream bit depth %d unsupported", bps);
1062
7.99M
      }
1063
1064
7.99M
      func->samples[i] = s;
1065
7.99M
    }
1066
2.31k
  }
1067
4.62k
  fz_always(ctx)
1068
2.31k
  {
1069
2.31k
    fz_drop_stream(ctx, stream);
1070
2.31k
  }
1071
2.31k
  fz_catch(ctx)
1072
324
  {
1073
324
    fz_rethrow(ctx);
1074
324
  }
1075
1.99k
}
1076
1077
static float
1078
interpolate_sample(pdf_function_sa *func, int *scale, int *e0, int *e1, float *efrac, int dim, int idx)
1079
63
{
1080
63
  float a, b;
1081
63
  int idx0, idx1;
1082
1083
63
  idx0 = e0[dim] * scale[dim] + idx;
1084
63
  idx1 = e1[dim] * scale[dim] + idx;
1085
1086
63
  if (dim == 0)
1087
36
  {
1088
36
    a = func->samples[idx0];
1089
36
    b = func->samples[idx1];
1090
36
  }
1091
27
  else
1092
27
  {
1093
27
    a = interpolate_sample(func, scale, e0, e1, efrac, dim - 1, idx0);
1094
27
    b = interpolate_sample(func, scale, e0, e1, efrac, dim - 1, idx1);
1095
27
  }
1096
1097
63
  return a + (b - a) * efrac[dim];
1098
63
}
1099
1100
static void
1101
eval_sample_func(fz_context *ctx, fz_function *func_, const float *in, float *out)
1102
541k
{
1103
541k
  pdf_function_sa *func = (pdf_function_sa *)func_;
1104
541k
  int e0[MAX_M], e1[MAX_M], scale[MAX_M];
1105
541k
  float efrac[MAX_M];
1106
541k
  float x;
1107
541k
  int i;
1108
1109
  /* encode input coordinates */
1110
1.08M
  for (i = 0; i < func->super.super.m; i++)
1111
541k
  {
1112
541k
    x = fz_clamp(in[i], func->super.domain[i][0], func->super.domain[i][1]);
1113
541k
    x = lerp(x, func->super.domain[i][0], func->super.domain[i][1],
1114
541k
      func->encode[i][0], func->encode[i][1]);
1115
541k
    x = fz_clamp(x, 0, func->size[i] - 1);
1116
541k
    e0[i] = floorf(x);
1117
541k
    e1[i] = ceilf(x);
1118
541k
    efrac[i] = x - e0[i];
1119
541k
  }
1120
1121
541k
  scale[0] = func->super.super.n;
1122
541k
  for (i = 1; i < func->super.super.m; i++)
1123
6
    scale[i] = scale[i - 1] * func->size[i-1];
1124
1125
1.96M
  for (i = 0; i < func->super.super.n; i++)
1126
1.42M
  {
1127
1.42M
    if (func->super.super.m == 1)
1128
1.42M
    {
1129
1.42M
      float a = func->samples[e0[0] * func->super.super.n + i];
1130
1.42M
      float b = func->samples[e1[0] * func->super.super.n + i];
1131
1132
1.42M
      float ab = a + (b - a) * efrac[0];
1133
1134
1.42M
      out[i] = lerp(ab, 0, 1, func->decode[i][0], func->decode[i][1]);
1135
1.42M
      out[i] = fz_clamp(out[i], func->super.range[i][0], func->super.range[i][1]);
1136
1.42M
    }
1137
1138
9
    else if (func->super.super.m == 2)
1139
0
    {
1140
0
      int s0 = func->super.super.n;
1141
0
      int s1 = s0 * func->size[0];
1142
1143
0
      float a = func->samples[e0[0] * s0 + e0[1] * s1 + i];
1144
0
      float b = func->samples[e1[0] * s0 + e0[1] * s1 + i];
1145
0
      float c = func->samples[e0[0] * s0 + e1[1] * s1 + i];
1146
0
      float d = func->samples[e1[0] * s0 + e1[1] * s1 + i];
1147
1148
0
      float ab = a + (b - a) * efrac[0];
1149
0
      float cd = c + (d - c) * efrac[0];
1150
0
      float abcd = ab + (cd - ab) * efrac[1];
1151
1152
0
      out[i] = lerp(abcd, 0, 1, func->decode[i][0], func->decode[i][1]);
1153
0
      out[i] = fz_clamp(out[i], func->super.range[i][0], func->super.range[i][1]);
1154
0
    }
1155
1156
9
    else
1157
9
    {
1158
9
      x = interpolate_sample(func, scale, e0, e1, efrac, func->super.super.m - 1, i);
1159
9
      out[i] = lerp(x, 0, 1, func->decode[i][0], func->decode[i][1]);
1160
9
      out[i] = fz_clamp(out[i], func->super.range[i][0], func->super.range[i][1]);
1161
9
    }
1162
1.42M
  }
1163
541k
}
1164
1165
/*
1166
 * Exponential function
1167
 */
1168
1169
static void
1170
load_exponential_func(fz_context *ctx, pdf_function *func_, pdf_obj *dict)
1171
3.80k
{
1172
3.80k
  pdf_function_e *func = (pdf_function_e *)func_;
1173
3.80k
  pdf_obj *obj;
1174
3.80k
  int i;
1175
1176
3.80k
  if (func->super.super.m > 1)
1177
0
    fz_warn(ctx, "exponential functions have at most one input");
1178
3.80k
  func->super.super.m = 1;
1179
1180
3.80k
  func->n = pdf_dict_get_real(ctx, dict, PDF_NAME(N));
1181
1182
  /* See exponential functions (PDF 1.7 section 3.9.2) */
1183
3.80k
  if (func->n != (int) func->n)
1184
683
  {
1185
    /* If N is non-integer, input values may never be negative */
1186
1.36k
    for (i = 0; i < func->super.super.m; i++)
1187
683
      if (func->super.domain[i][0] < 0 || func->super.domain[i][1] < 0)
1188
0
        fz_warn(ctx, "exponential function input domain includes illegal negative input values");
1189
683
  }
1190
3.11k
  else if (func->n < 0)
1191
0
  {
1192
    /* if N is negative, input values may never be zero */
1193
0
    for (i = 0; i < func->super.super.m; i++)
1194
0
      if (func->super.domain[i][0] == 0 || func->super.domain[i][1] == 0 ||
1195
0
        (func->super.domain[i][0] < 0 && func->super.domain[i][1] > 0))
1196
0
        fz_warn(ctx, "exponential function input domain includes illegal input value zero");
1197
0
  }
1198
1199
12.6k
  for (i = 0; i < func->super.super.n; i++)
1200
8.83k
  {
1201
8.83k
    func->c0[i] = 0;
1202
8.83k
    func->c1[i] = 1;
1203
8.83k
  }
1204
1205
3.80k
  obj = pdf_dict_get(ctx, dict, PDF_NAME(C0));
1206
3.80k
  if (pdf_is_array(ctx, obj))
1207
3.80k
  {
1208
3.80k
    int ranges = fz_mini(func->super.super.n, pdf_array_len(ctx, obj));
1209
3.80k
    if (ranges != func->super.super.n)
1210
1
      fz_warn(ctx, "wrong number of C0 constants for exponential function");
1211
1212
12.6k
    for (i = 0; i < ranges; i++)
1213
8.83k
      func->c0[i] = pdf_array_get_real(ctx, obj, i);
1214
3.80k
  }
1215
1216
3.80k
  obj = pdf_dict_get(ctx, dict, PDF_NAME(C1));
1217
3.80k
  if (pdf_is_array(ctx, obj))
1218
3.79k
  {
1219
3.79k
    int ranges = fz_mini(func->super.super.n, pdf_array_len(ctx, obj));
1220
3.79k
    if (ranges != func->super.super.n)
1221
1
      fz_warn(ctx, "wrong number of C1 constants for exponential function");
1222
1223
12.6k
    for (i = 0; i < ranges; i++)
1224
8.82k
      func->c1[i] = pdf_array_get_real(ctx, obj, i);
1225
3.79k
  }
1226
3.80k
}
1227
1228
static void
1229
eval_exponential_func(fz_context *ctx, fz_function *func_, const float *in, float *out)
1230
21.8M
{
1231
21.8M
  pdf_function_e *func = (pdf_function_e *)func_;
1232
21.8M
  float x = *in;
1233
21.8M
  float tmp;
1234
21.8M
  int i;
1235
1236
21.8M
  x = fz_clamp(x, func->super.domain[0][0], func->super.domain[0][1]);
1237
1238
  /* Default output is zero, which is suitable for violated constraints */
1239
21.8M
  if ((func->n != (int)func->n && x < 0) || (func->n < 0 && x == 0))
1240
0
  {
1241
0
    for (i = 0; i < func->super.super.n; i++)
1242
0
      out[i] = 0;
1243
0
    return;
1244
0
  }
1245
1246
21.8M
  tmp = powf(x, func->n);
1247
87.0M
  for (i = 0; i < func->super.super.n; i++)
1248
65.2M
  {
1249
65.2M
    out[i] = func->c0[i] + tmp * (func->c1[i] - func->c0[i]);
1250
65.2M
    if (func->super.has_range)
1251
63.8M
      out[i] = fz_clamp(out[i], func->super.range[i][0], func->super.range[i][1]);
1252
65.2M
  }
1253
21.8M
}
1254
1255
/*
1256
 * Stitching function
1257
 */
1258
1259
static void
1260
load_stitching_func(fz_context *ctx, pdf_function *func_, pdf_obj *dict, pdf_cycle_list *cycle_up)
1261
1.01k
{
1262
1.01k
  pdf_function_st *func =  (pdf_function_st *)func_;
1263
1.01k
  pdf_function **funcs;
1264
1.01k
  pdf_obj *obj;
1265
1.01k
  pdf_obj *sub;
1266
1.01k
  int k;
1267
1.01k
  int i;
1268
1269
1.01k
  func->k = 0;
1270
1271
1.01k
  if (func->super.super.m > 1)
1272
4
    fz_warn(ctx, "stitching functions have at most one input");
1273
1.01k
  func->super.super.m = 1;
1274
1275
1.01k
  obj = pdf_dict_get(ctx, dict, PDF_NAME(Functions));
1276
1.01k
  if (!pdf_is_array(ctx, obj))
1277
4
    fz_throw(ctx, FZ_ERROR_SYNTAX, "stitching function has no input functions");
1278
1279
1.01k
  k = pdf_array_len(ctx, obj);
1280
1281
1.01k
  func->funcs = Memento_label(fz_malloc_array(ctx, k, pdf_function*), "stitch_fns");
1282
1.01k
  func->bounds = Memento_label(fz_malloc_array(ctx, k - 1, float), "stitch_bounds");
1283
1.01k
  func->encode = Memento_label(fz_malloc_array(ctx, k * 2, float), "stitch_encode");
1284
1.01k
  funcs = func->funcs;
1285
1286
3.78k
  for (i = 0; i < k; i++)
1287
2.77k
  {
1288
2.77k
    sub = pdf_array_get(ctx, obj, i);
1289
2.77k
    funcs[i] = pdf_load_function_imp(ctx, sub, 1, func->super.super.n, cycle_up);
1290
1291
2.77k
    func->super.super.size += pdf_function_size(ctx, funcs[i]);
1292
2.77k
    func->k ++;
1293
1294
2.77k
    if (funcs[i]->super.m != func->super.super.m)
1295
0
      fz_warn(ctx, "wrong number of inputs for sub function %d", i);
1296
2.77k
    if (funcs[i]->super.n != func->super.super.n)
1297
0
      fz_warn(ctx, "wrong number of outputs for sub function %d", i);
1298
2.77k
  }
1299
1300
1.01k
  obj = pdf_dict_get(ctx, dict, PDF_NAME(Bounds));
1301
1.01k
  if (!pdf_is_array(ctx, obj))
1302
0
    fz_throw(ctx, FZ_ERROR_SYNTAX, "stitching function has no bounds");
1303
1.01k
  {
1304
1.01k
    if (pdf_array_len(ctx, obj) < k - 1)
1305
0
      fz_throw(ctx, FZ_ERROR_SYNTAX, "too few subfunction boundaries");
1306
1.01k
    if (pdf_array_len(ctx, obj) > k)
1307
0
      fz_warn(ctx, "too many subfunction boundaries");
1308
1309
2.73k
    for (i = 0; i < k - 1; i++)
1310
1.72k
    {
1311
1.72k
      func->bounds[i] = pdf_array_get_real(ctx, obj, i);
1312
1.72k
      if (i && func->bounds[i - 1] > func->bounds[i])
1313
0
        fz_throw(ctx, FZ_ERROR_SYNTAX, "subfunction %d boundary out of range", i);
1314
1.72k
    }
1315
1316
1.01k
    if (k > 1 && (func->super.domain[0][0] > func->bounds[0] ||
1317
562
      func->super.domain[0][1] < func->bounds[k - 2]))
1318
0
      fz_warn(ctx, "subfunction boundaries outside of input mapping");
1319
1.01k
  }
1320
1321
3.61k
  for (i = 0; i < k; i++)
1322
2.60k
  {
1323
2.60k
    func->encode[i * 2 + 0] = 0;
1324
2.60k
    func->encode[i * 2 + 1] = 0;
1325
2.60k
  }
1326
1327
1.01k
  obj = pdf_dict_get(ctx, dict, PDF_NAME(Encode));
1328
1.01k
  if (pdf_is_array(ctx, obj))
1329
872
  {
1330
872
    int ranges = fz_mini(k, pdf_array_len(ctx, obj) / 2);
1331
872
    if (ranges != k)
1332
0
      fz_warn(ctx, "wrong number of stitching function input mappings");
1333
1334
3.47k
    for (i = 0; i < ranges; i++)
1335
2.60k
    {
1336
2.60k
      func->encode[i * 2 + 0] = pdf_array_get_real(ctx, obj, i * 2 + 0);
1337
2.60k
      func->encode[i * 2 + 1] = pdf_array_get_real(ctx, obj, i * 2 + 1);
1338
2.60k
    }
1339
872
  }
1340
1.01k
}
1341
1342
static void
1343
eval_stitching_func(fz_context *ctx, fz_function *func_, const float *inp, float *out)
1344
227k
{
1345
227k
  pdf_function_st *func = (pdf_function_st *)func_;
1346
227k
  float low, high;
1347
227k
  int k = func->k;
1348
227k
  float *bounds = func->bounds;
1349
227k
  int i;
1350
227k
  float in = fz_clamp(*inp, func->super.domain[0][0], func->super.domain[0][1]);
1351
1352
454k
  for (i = 0; i < k - 1; i++)
1353
323k
  {
1354
323k
    if (in < bounds[i])
1355
96.4k
      break;
1356
323k
  }
1357
1358
227k
  if (i == 0 && k == 1)
1359
79.6k
  {
1360
79.6k
    low = func->super.domain[0][0];
1361
79.6k
    high = func->super.domain[0][1];
1362
79.6k
  }
1363
147k
  else if (i == 0)
1364
41.2k
  {
1365
41.2k
    low = func->super.domain[0][0];
1366
41.2k
    high = bounds[0];
1367
41.2k
  }
1368
106k
  else if (i == k - 1)
1369
51.0k
  {
1370
51.0k
    low = bounds[k - 2];
1371
51.0k
    high = func->super.domain[0][1];
1372
51.0k
  }
1373
55.1k
  else
1374
55.1k
  {
1375
55.1k
    low = bounds[i - 1];
1376
55.1k
    high = bounds[i];
1377
55.1k
  }
1378
1379
227k
  in = lerp(in, low, high, func->encode[i * 2 + 0], func->encode[i * 2 + 1]);
1380
1381
227k
  pdf_eval_function(ctx, func->funcs[i], &in, 1, out, func->super.super.n);
1382
227k
}
1383
1384
/*
1385
 * Common
1386
 */
1387
1388
static void
1389
pdf_drop_function_sa(fz_context *ctx, fz_storable *func_)
1390
2.54k
{
1391
2.54k
  pdf_function_sa *func = (pdf_function_sa *)func_;
1392
1393
2.54k
  fz_free(ctx, func->samples);
1394
2.54k
  fz_free(ctx, func);
1395
2.54k
}
1396
1397
static void
1398
pdf_drop_function_e(fz_context *ctx, fz_storable *func)
1399
3.80k
{
1400
3.80k
  fz_free(ctx, func);
1401
3.80k
}
1402
1403
static void
1404
pdf_drop_function_st(fz_context *ctx, fz_storable *func_)
1405
1.01k
{
1406
1.01k
  pdf_function_st *func = (pdf_function_st *)func_;
1407
1.01k
  int i;
1408
1409
3.64k
  for (i = 0; i < func->k; i++)
1410
2.63k
    pdf_drop_function(ctx, func->funcs[i]);
1411
1.01k
  fz_free(ctx, func->funcs);
1412
1.01k
  fz_free(ctx, func->bounds);
1413
1.01k
  fz_free(ctx, func->encode);
1414
1.01k
  fz_free(ctx, func);
1415
1.01k
}
1416
1417
static void
1418
pdf_drop_function_p(fz_context *ctx, fz_storable *func_)
1419
510
{
1420
510
  pdf_function_p *func = (pdf_function_p *)func_;
1421
1422
510
  fz_free(ctx, func->code);
1423
510
  fz_free(ctx, func);
1424
510
}
1425
1426
void
1427
pdf_eval_function(fz_context *ctx, pdf_function *func, const float *in, int inlen, float *out, int outlen)
1428
25.1M
{
1429
25.1M
  fz_eval_function(ctx, &func->super, in, inlen, out, outlen);
1430
25.1M
}
1431
1432
static pdf_function *
1433
pdf_load_function_imp(fz_context *ctx, pdf_obj *dict, int in, int out, pdf_cycle_list *cycle_up)
1434
8.40k
{
1435
8.40k
  pdf_cycle_list cycle;
1436
8.40k
  pdf_function *func;
1437
8.40k
  pdf_obj *obj;
1438
8.40k
  int i;
1439
8.40k
  int type;
1440
8.40k
  fz_store_drop_fn *drop;
1441
1442
8.40k
  if (pdf_cycle(ctx, &cycle, cycle_up, dict))
1443
0
    fz_throw(ctx, FZ_ERROR_SYNTAX, "recursive function");
1444
1445
8.40k
  type = pdf_dict_get_int(ctx, dict, PDF_NAME(FunctionType));
1446
1447
8.40k
  switch (type)
1448
8.40k
  {
1449
2.60k
  case SAMPLE:
1450
2.60k
    drop = pdf_drop_function_sa;
1451
2.60k
    break;
1452
1453
4.19k
  case EXPONENTIAL:
1454
4.19k
    drop = pdf_drop_function_e;
1455
4.19k
    break;
1456
1457
1.02k
  case STITCHING:
1458
1.02k
    drop = pdf_drop_function_st;
1459
1.02k
    break;
1460
1461
580
  case POSTSCRIPT:
1462
580
    drop = pdf_drop_function_p;
1463
580
    break;
1464
1465
2
  default:
1466
2
    fz_throw(ctx, FZ_ERROR_SYNTAX, "unknown function type (%d 0 R)", pdf_to_num(ctx, dict));
1467
8.40k
  }
1468
1469
8.40k
  if ((func = pdf_find_item(ctx, drop, dict)) != NULL)
1470
537
    return func;
1471
1472
7.87k
  switch (type)
1473
7.87k
  {
1474
2.54k
  case SAMPLE:
1475
2.54k
    func = &fz_new_derived_function(ctx, pdf_function_sa, sizeof(pdf_function_sa), 1, 1, eval_sample_func, pdf_drop_function_sa)->super;
1476
2.54k
    break;
1477
1478
3.80k
  case EXPONENTIAL:
1479
3.80k
    func = &fz_new_derived_function(ctx, pdf_function_e, sizeof(pdf_function_e), 1, 1, eval_exponential_func, pdf_drop_function_e)->super;
1480
3.80k
    break;
1481
1482
1.01k
  case STITCHING:
1483
1.01k
    func = &fz_new_derived_function(ctx, pdf_function_st, sizeof(pdf_function_st), 1, 1, eval_stitching_func, pdf_drop_function_st)->super;
1484
1.01k
    break;
1485
1486
510
  case POSTSCRIPT:
1487
510
    func = &fz_new_derived_function(ctx, pdf_function_p, sizeof(pdf_function_p), 1, 1, eval_postscript_func, pdf_drop_function_p)->super;
1488
510
    break;
1489
7.87k
  }
1490
1491
  /* required for all */
1492
7.87k
  obj = pdf_dict_get(ctx, dict, PDF_NAME(Domain));
1493
7.87k
  func->super.m = fz_clampi(pdf_array_len(ctx, obj) / 2, 1, MAX_M);
1494
15.9k
  for (i = 0; i < func->super.m; i++)
1495
8.05k
  {
1496
8.05k
    func->domain[i][0] = pdf_array_get_real(ctx, obj, i * 2 + 0);
1497
8.05k
    func->domain[i][1] = pdf_array_get_real(ctx, obj, i * 2 + 1);
1498
8.05k
  }
1499
1500
  /* required for type0 and type4, optional otherwise */
1501
7.87k
  obj = pdf_dict_get(ctx, dict, PDF_NAME(Range));
1502
7.87k
  if (pdf_is_array(ctx, obj))
1503
3.10k
  {
1504
3.10k
    func->has_range = 1;
1505
3.10k
    func->super.n = fz_clampi(pdf_array_len(ctx, obj) / 2, 1, MAX_N);
1506
11.0k
    for (i = 0; i < func->super.n; i++)
1507
7.96k
    {
1508
7.96k
      func->range[i][0] = pdf_array_get_real(ctx, obj, i * 2 + 0);
1509
7.96k
      func->range[i][1] = pdf_array_get_real(ctx, obj, i * 2 + 1);
1510
7.96k
    }
1511
3.10k
  }
1512
4.76k
  else
1513
4.76k
  {
1514
4.76k
    func->has_range = 0;
1515
4.76k
    func->super.n = out;
1516
4.76k
  }
1517
1518
7.87k
  if (func->super.m != in)
1519
11
    fz_warn(ctx, "wrong number of function inputs");
1520
7.87k
  if (func->super.n != out)
1521
1
    fz_warn(ctx, "wrong number of function outputs");
1522
1523
15.7k
  fz_try(ctx)
1524
15.7k
  {
1525
7.87k
    switch (type)
1526
7.87k
    {
1527
2.54k
    case SAMPLE:
1528
2.54k
      load_sample_func(ctx, func, dict);
1529
2.54k
      break;
1530
1531
3.80k
    case EXPONENTIAL:
1532
3.80k
      load_exponential_func(ctx, func, dict);
1533
3.80k
      break;
1534
1535
1.01k
    case STITCHING:
1536
1.01k
      load_stitching_func(ctx, func, dict, &cycle);
1537
1.01k
      break;
1538
1539
510
    case POSTSCRIPT:
1540
510
      load_postscript_func(ctx, func, dict);
1541
510
      break;
1542
1543
0
    default:
1544
0
      fz_throw(ctx, FZ_ERROR_SYNTAX, "unknown function type (%d 0 R)", pdf_to_num(ctx, dict));
1545
7.87k
    }
1546
1547
7.11k
    pdf_store_item(ctx, dict, func, func->super.size);
1548
7.11k
  }
1549
15.7k
  fz_catch(ctx)
1550
759
  {
1551
759
    pdf_drop_function(ctx, func);
1552
759
    fz_rethrow(ctx);
1553
759
  }
1554
1555
6.35k
  return func;
1556
7.11k
}
1557
1558
pdf_function *
1559
pdf_load_function(fz_context *ctx, pdf_obj *dict, int in, int out)
1560
5.63k
{
1561
5.63k
  return pdf_load_function_imp(ctx, dict, in, out, NULL);
1562
5.63k
}