Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download
7639 views
1
#include "mupdf/pdf.h"
2
3
typedef struct psobj_s psobj;
4
5
enum
6
{
7
SAMPLE = 0,
8
EXPONENTIAL = 2,
9
STITCHING = 3,
10
POSTSCRIPT = 4
11
};
12
13
typedef struct pdf_function_s pdf_function;
14
15
struct pdf_function_s
16
{
17
fz_function base;
18
int type; /* 0=sample 2=exponential 3=stitching 4=postscript */
19
float domain[FZ_FN_MAXM][2]; /* even index : min value, odd index : max value */
20
float range[FZ_FN_MAXN][2]; /* even index : min value, odd index : max value */
21
int has_range;
22
23
union
24
{
25
struct {
26
unsigned short bps;
27
int size[FZ_FN_MAXM];
28
float encode[FZ_FN_MAXM][2];
29
float decode[FZ_FN_MAXN][2];
30
float *samples;
31
} sa;
32
33
struct {
34
float n;
35
float c0[FZ_FN_MAXN];
36
float c1[FZ_FN_MAXN];
37
} e;
38
39
struct {
40
int k;
41
fz_function **funcs; /* k */
42
float *bounds; /* k - 1 */
43
float *encode; /* k * 2 */
44
} st;
45
46
struct {
47
psobj *code;
48
int cap;
49
} p;
50
} u;
51
};
52
53
#define RADIAN 57.2957795
54
55
static inline float lerp(float x, float xmin, float xmax, float ymin, float ymax)
56
{
57
if (xmin == xmax)
58
return ymin;
59
if (ymin == ymax)
60
return ymin;
61
return ymin + (x - xmin) * (ymax - ymin) / (xmax - xmin);
62
}
63
64
/*
65
* PostScript calculator
66
*/
67
68
enum { PS_BOOL, PS_INT, PS_REAL, PS_OPERATOR, PS_BLOCK };
69
70
enum
71
{
72
PS_OP_ABS, PS_OP_ADD, PS_OP_AND, PS_OP_ATAN, PS_OP_BITSHIFT,
73
PS_OP_CEILING, PS_OP_COPY, PS_OP_COS, PS_OP_CVI, PS_OP_CVR,
74
PS_OP_DIV, PS_OP_DUP, PS_OP_EQ, PS_OP_EXCH, PS_OP_EXP,
75
PS_OP_FALSE, PS_OP_FLOOR, PS_OP_GE, PS_OP_GT, PS_OP_IDIV, PS_OP_IF,
76
PS_OP_IFELSE, PS_OP_INDEX, PS_OP_LE, PS_OP_LN, PS_OP_LOG, PS_OP_LT,
77
PS_OP_MOD, PS_OP_MUL, PS_OP_NE, PS_OP_NEG, PS_OP_NOT, PS_OP_OR,
78
PS_OP_POP, PS_OP_RETURN, PS_OP_ROLL, PS_OP_ROUND, PS_OP_SIN,
79
PS_OP_SQRT, PS_OP_SUB, PS_OP_TRUE, PS_OP_TRUNCATE, PS_OP_XOR
80
};
81
82
static char *ps_op_names[] =
83
{
84
"abs", "add", "and", "atan", "bitshift", "ceiling", "copy",
85
"cos", "cvi", "cvr", "div", "dup", "eq", "exch", "exp",
86
"false", "floor", "ge", "gt", "idiv", "if", "ifelse", "index", "le", "ln",
87
"log", "lt", "mod", "mul", "ne", "neg", "not", "or", "pop", "return",
88
"roll", "round", "sin", "sqrt", "sub", "true", "truncate", "xor"
89
};
90
91
struct psobj_s
92
{
93
int type;
94
union
95
{
96
int b; /* boolean (stack only) */
97
int i; /* integer (stack and code) */
98
float f; /* real (stack and code) */
99
int op; /* operator (code only) */
100
int block; /* if/ifelse block pointer (code only) */
101
} u;
102
};
103
104
typedef struct ps_stack_s ps_stack;
105
106
struct ps_stack_s
107
{
108
psobj stack[100];
109
int sp;
110
};
111
112
#ifndef NDEBUG
113
void
114
pdf_debug_ps_stack(fz_context *ctx, ps_stack *st)
115
{
116
int i;
117
118
printf("stack: ");
119
120
for (i = 0; i < st->sp; i++)
121
{
122
switch (st->stack[i].type)
123
{
124
case PS_BOOL:
125
if (st->stack[i].u.b)
126
printf("true ");
127
else
128
printf("false ");
129
break;
130
131
case PS_INT:
132
printf("%d ", st->stack[i].u.i);
133
break;
134
135
case PS_REAL:
136
printf("%g ", st->stack[i].u.f);
137
break;
138
}
139
}
140
printf("\n");
141
142
}
143
#endif
144
145
static void
146
ps_init_stack(ps_stack *st)
147
{
148
memset(st->stack, 0, sizeof(st->stack));
149
st->sp = 0;
150
}
151
152
static inline int ps_overflow(ps_stack *st, int n)
153
{
154
return n < 0 || st->sp + n >= nelem(st->stack);
155
}
156
157
static inline int ps_underflow(ps_stack *st, int n)
158
{
159
return n < 0 || st->sp - n < 0;
160
}
161
162
static inline int ps_is_type(ps_stack *st, int t)
163
{
164
return !ps_underflow(st, 1) && st->stack[st->sp - 1].type == t;
165
}
166
167
static inline int ps_is_type2(ps_stack *st, int t)
168
{
169
return !ps_underflow(st, 2) && st->stack[st->sp - 1].type == t && st->stack[st->sp - 2].type == t;
170
}
171
172
static void
173
ps_push_bool(ps_stack *st, int b)
174
{
175
if (!ps_overflow(st, 1))
176
{
177
st->stack[st->sp].type = PS_BOOL;
178
st->stack[st->sp].u.b = b;
179
st->sp++;
180
}
181
}
182
183
static void
184
ps_push_int(ps_stack *st, int n)
185
{
186
if (!ps_overflow(st, 1))
187
{
188
st->stack[st->sp].type = PS_INT;
189
st->stack[st->sp].u.i = n;
190
st->sp++;
191
}
192
}
193
194
static void
195
ps_push_real(ps_stack *st, float n)
196
{
197
if (!ps_overflow(st, 1))
198
{
199
st->stack[st->sp].type = PS_REAL;
200
if (isnan(n))
201
{
202
/* Push 1.0, as it's a small known value that won't
203
* cause a divide by 0. Same reason as in fz_atof. */
204
n = 1.0;
205
}
206
st->stack[st->sp].u.f = fz_clamp(n, -FLT_MAX, FLT_MAX);
207
st->sp++;
208
}
209
}
210
211
static int
212
ps_pop_bool(ps_stack *st)
213
{
214
if (!ps_underflow(st, 1))
215
{
216
if (ps_is_type(st, PS_BOOL))
217
return st->stack[--st->sp].u.b;
218
}
219
return 0;
220
}
221
222
static int
223
ps_pop_int(ps_stack *st)
224
{
225
if (!ps_underflow(st, 1))
226
{
227
if (ps_is_type(st, PS_INT))
228
return st->stack[--st->sp].u.i;
229
if (ps_is_type(st, PS_REAL))
230
return st->stack[--st->sp].u.f;
231
}
232
return 0;
233
}
234
235
static float
236
ps_pop_real(ps_stack *st)
237
{
238
if (!ps_underflow(st, 1))
239
{
240
if (ps_is_type(st, PS_INT))
241
return st->stack[--st->sp].u.i;
242
if (ps_is_type(st, PS_REAL))
243
return st->stack[--st->sp].u.f;
244
}
245
return 0;
246
}
247
248
static void
249
ps_copy(ps_stack *st, int n)
250
{
251
if (!ps_underflow(st, n) && !ps_overflow(st, n))
252
{
253
memcpy(st->stack + st->sp, st->stack + st->sp - n, n * sizeof(psobj));
254
st->sp += n;
255
}
256
}
257
258
static void
259
ps_roll(ps_stack *st, int n, int j)
260
{
261
psobj tmp;
262
int i;
263
264
if (ps_underflow(st, n) || j == 0 || n == 0)
265
return;
266
267
if (j >= 0)
268
{
269
j %= n;
270
}
271
else
272
{
273
j = -j % n;
274
if (j != 0)
275
j = n - j;
276
}
277
278
for (i = 0; i < j; i++)
279
{
280
tmp = st->stack[st->sp - 1];
281
memmove(st->stack + st->sp - n + 1, st->stack + st->sp - n, n * sizeof(psobj));
282
st->stack[st->sp - n] = tmp;
283
}
284
}
285
286
static void
287
ps_index(ps_stack *st, int n)
288
{
289
if (!ps_overflow(st, 1) && !ps_underflow(st, n))
290
{
291
st->stack[st->sp] = st->stack[st->sp - n - 1];
292
st->sp++;
293
}
294
}
295
296
static void
297
ps_run(fz_context *ctx, psobj *code, ps_stack *st, int pc)
298
{
299
int i1, i2;
300
float r1, r2;
301
int b1, b2;
302
303
while (1)
304
{
305
switch (code[pc].type)
306
{
307
case PS_INT:
308
ps_push_int(st, code[pc++].u.i);
309
break;
310
311
case PS_REAL:
312
ps_push_real(st, code[pc++].u.f);
313
break;
314
315
case PS_OPERATOR:
316
switch (code[pc++].u.op)
317
{
318
case PS_OP_ABS:
319
if (ps_is_type(st, PS_INT))
320
ps_push_int(st, abs(ps_pop_int(st)));
321
else
322
ps_push_real(st, fabsf(ps_pop_real(st)));
323
break;
324
325
case PS_OP_ADD:
326
if (ps_is_type2(st, PS_INT)) {
327
i2 = ps_pop_int(st);
328
i1 = ps_pop_int(st);
329
ps_push_int(st, i1 + i2);
330
}
331
else {
332
r2 = ps_pop_real(st);
333
r1 = ps_pop_real(st);
334
ps_push_real(st, r1 + r2);
335
}
336
break;
337
338
case PS_OP_AND:
339
if (ps_is_type2(st, PS_INT)) {
340
i2 = ps_pop_int(st);
341
i1 = ps_pop_int(st);
342
ps_push_int(st, i1 & i2);
343
}
344
else {
345
b2 = ps_pop_bool(st);
346
b1 = ps_pop_bool(st);
347
ps_push_bool(st, b1 && b2);
348
}
349
break;
350
351
case PS_OP_ATAN:
352
r2 = ps_pop_real(st);
353
r1 = ps_pop_real(st);
354
r1 = atan2f(r1, r2) * RADIAN;
355
if (r1 < 0)
356
r1 += 360;
357
ps_push_real(st, r1);
358
break;
359
360
case PS_OP_BITSHIFT:
361
i2 = ps_pop_int(st);
362
i1 = ps_pop_int(st);
363
if (i2 > 0 && i2 < 8 * sizeof (i2))
364
ps_push_int(st, i1 << i2);
365
else if (i2 < 0 && i2 > -8 * (int)sizeof (i2))
366
ps_push_int(st, (int)((unsigned int)i1 >> -i2));
367
else
368
ps_push_int(st, i1);
369
break;
370
371
case PS_OP_CEILING:
372
r1 = ps_pop_real(st);
373
ps_push_real(st, ceilf(r1));
374
break;
375
376
case PS_OP_COPY:
377
ps_copy(st, ps_pop_int(st));
378
break;
379
380
case PS_OP_COS:
381
r1 = ps_pop_real(st);
382
ps_push_real(st, cosf(r1/RADIAN));
383
break;
384
385
case PS_OP_CVI:
386
ps_push_int(st, ps_pop_int(st));
387
break;
388
389
case PS_OP_CVR:
390
ps_push_real(st, ps_pop_real(st));
391
break;
392
393
case PS_OP_DIV:
394
r2 = ps_pop_real(st);
395
r1 = ps_pop_real(st);
396
if (fabsf(r2) >= FLT_EPSILON)
397
ps_push_real(st, r1 / r2);
398
else
399
ps_push_real(st, DIV_BY_ZERO(r1, r2, -FLT_MAX, FLT_MAX));
400
break;
401
402
case PS_OP_DUP:
403
ps_copy(st, 1);
404
break;
405
406
case PS_OP_EQ:
407
if (ps_is_type2(st, PS_BOOL)) {
408
b2 = ps_pop_bool(st);
409
b1 = ps_pop_bool(st);
410
ps_push_bool(st, b1 == b2);
411
}
412
else if (ps_is_type2(st, PS_INT)) {
413
i2 = ps_pop_int(st);
414
i1 = ps_pop_int(st);
415
ps_push_bool(st, i1 == i2);
416
}
417
else {
418
r2 = ps_pop_real(st);
419
r1 = ps_pop_real(st);
420
ps_push_bool(st, r1 == r2);
421
}
422
break;
423
424
case PS_OP_EXCH:
425
ps_roll(st, 2, 1);
426
break;
427
428
case PS_OP_EXP:
429
r2 = ps_pop_real(st);
430
r1 = ps_pop_real(st);
431
ps_push_real(st, powf(r1, r2));
432
break;
433
434
case PS_OP_FALSE:
435
ps_push_bool(st, 0);
436
break;
437
438
case PS_OP_FLOOR:
439
r1 = ps_pop_real(st);
440
ps_push_real(st, floorf(r1));
441
break;
442
443
case PS_OP_GE:
444
if (ps_is_type2(st, PS_INT)) {
445
i2 = ps_pop_int(st);
446
i1 = ps_pop_int(st);
447
ps_push_bool(st, i1 >= i2);
448
}
449
else {
450
r2 = ps_pop_real(st);
451
r1 = ps_pop_real(st);
452
ps_push_bool(st, r1 >= r2);
453
}
454
break;
455
456
case PS_OP_GT:
457
if (ps_is_type2(st, PS_INT)) {
458
i2 = ps_pop_int(st);
459
i1 = ps_pop_int(st);
460
ps_push_bool(st, i1 > i2);
461
}
462
else {
463
r2 = ps_pop_real(st);
464
r1 = ps_pop_real(st);
465
ps_push_bool(st, r1 > r2);
466
}
467
break;
468
469
case PS_OP_IDIV:
470
i2 = ps_pop_int(st);
471
i1 = ps_pop_int(st);
472
if (i2 != 0)
473
ps_push_int(st, i1 / i2);
474
else
475
ps_push_int(st, DIV_BY_ZERO(i1, i2, INT_MIN, INT_MAX));
476
break;
477
478
case PS_OP_INDEX:
479
ps_index(st, ps_pop_int(st));
480
break;
481
482
case PS_OP_LE:
483
if (ps_is_type2(st, PS_INT)) {
484
i2 = ps_pop_int(st);
485
i1 = ps_pop_int(st);
486
ps_push_bool(st, i1 <= i2);
487
}
488
else {
489
r2 = ps_pop_real(st);
490
r1 = ps_pop_real(st);
491
ps_push_bool(st, r1 <= r2);
492
}
493
break;
494
495
case PS_OP_LN:
496
r1 = ps_pop_real(st);
497
/* Bug 692941 - logf as separate statement */
498
r2 = logf(r1);
499
ps_push_real(st, r2);
500
break;
501
502
case PS_OP_LOG:
503
r1 = ps_pop_real(st);
504
ps_push_real(st, log10f(r1));
505
break;
506
507
case PS_OP_LT:
508
if (ps_is_type2(st, PS_INT)) {
509
i2 = ps_pop_int(st);
510
i1 = ps_pop_int(st);
511
ps_push_bool(st, i1 < i2);
512
}
513
else {
514
r2 = ps_pop_real(st);
515
r1 = ps_pop_real(st);
516
ps_push_bool(st, r1 < r2);
517
}
518
break;
519
520
case PS_OP_MOD:
521
i2 = ps_pop_int(st);
522
i1 = ps_pop_int(st);
523
if (i2 != 0)
524
ps_push_int(st, i1 % i2);
525
else
526
ps_push_int(st, DIV_BY_ZERO(i1, i2, INT_MIN, INT_MAX));
527
break;
528
529
case PS_OP_MUL:
530
if (ps_is_type2(st, PS_INT)) {
531
i2 = ps_pop_int(st);
532
i1 = ps_pop_int(st);
533
ps_push_int(st, i1 * i2);
534
}
535
else {
536
r2 = ps_pop_real(st);
537
r1 = ps_pop_real(st);
538
ps_push_real(st, r1 * r2);
539
}
540
break;
541
542
case PS_OP_NE:
543
if (ps_is_type2(st, PS_BOOL)) {
544
b2 = ps_pop_bool(st);
545
b1 = ps_pop_bool(st);
546
ps_push_bool(st, b1 != b2);
547
}
548
else if (ps_is_type2(st, PS_INT)) {
549
i2 = ps_pop_int(st);
550
i1 = ps_pop_int(st);
551
ps_push_bool(st, i1 != i2);
552
}
553
else {
554
r2 = ps_pop_real(st);
555
r1 = ps_pop_real(st);
556
ps_push_bool(st, r1 != r2);
557
}
558
break;
559
560
case PS_OP_NEG:
561
if (ps_is_type(st, PS_INT))
562
ps_push_int(st, -ps_pop_int(st));
563
else
564
ps_push_real(st, -ps_pop_real(st));
565
break;
566
567
case PS_OP_NOT:
568
if (ps_is_type(st, PS_BOOL))
569
ps_push_bool(st, !ps_pop_bool(st));
570
else
571
ps_push_int(st, ~ps_pop_int(st));
572
break;
573
574
case PS_OP_OR:
575
if (ps_is_type2(st, PS_BOOL)) {
576
b2 = ps_pop_bool(st);
577
b1 = ps_pop_bool(st);
578
ps_push_bool(st, b1 || b2);
579
}
580
else {
581
i2 = ps_pop_int(st);
582
i1 = ps_pop_int(st);
583
ps_push_int(st, i1 | i2);
584
}
585
break;
586
587
case PS_OP_POP:
588
if (!ps_underflow(st, 1))
589
st->sp--;
590
break;
591
592
case PS_OP_ROLL:
593
i2 = ps_pop_int(st);
594
i1 = ps_pop_int(st);
595
ps_roll(st, i1, i2);
596
break;
597
598
case PS_OP_ROUND:
599
if (!ps_is_type(st, PS_INT)) {
600
r1 = ps_pop_real(st);
601
ps_push_real(st, (r1 >= 0) ? floorf(r1 + 0.5f) : ceilf(r1 - 0.5f));
602
}
603
break;
604
605
case PS_OP_SIN:
606
r1 = ps_pop_real(st);
607
ps_push_real(st, sinf(r1/RADIAN));
608
break;
609
610
case PS_OP_SQRT:
611
r1 = ps_pop_real(st);
612
ps_push_real(st, sqrtf(r1));
613
break;
614
615
case PS_OP_SUB:
616
if (ps_is_type2(st, PS_INT)) {
617
i2 = ps_pop_int(st);
618
i1 = ps_pop_int(st);
619
ps_push_int(st, i1 - i2);
620
}
621
else {
622
r2 = ps_pop_real(st);
623
r1 = ps_pop_real(st);
624
ps_push_real(st, r1 - r2);
625
}
626
break;
627
628
case PS_OP_TRUE:
629
ps_push_bool(st, 1);
630
break;
631
632
case PS_OP_TRUNCATE:
633
if (!ps_is_type(st, PS_INT)) {
634
r1 = ps_pop_real(st);
635
ps_push_real(st, (r1 >= 0) ? floorf(r1) : ceilf(r1));
636
}
637
break;
638
639
case PS_OP_XOR:
640
if (ps_is_type2(st, PS_BOOL)) {
641
b2 = ps_pop_bool(st);
642
b1 = ps_pop_bool(st);
643
ps_push_bool(st, b1 ^ b2);
644
}
645
else {
646
i2 = ps_pop_int(st);
647
i1 = ps_pop_int(st);
648
ps_push_int(st, i1 ^ i2);
649
}
650
break;
651
652
case PS_OP_IF:
653
b1 = ps_pop_bool(st);
654
if (b1)
655
ps_run(ctx, code, st, code[pc + 1].u.block);
656
pc = code[pc + 2].u.block;
657
break;
658
659
case PS_OP_IFELSE:
660
b1 = ps_pop_bool(st);
661
if (b1)
662
ps_run(ctx, code, st, code[pc + 1].u.block);
663
else
664
ps_run(ctx, code, st, code[pc + 0].u.block);
665
pc = code[pc + 2].u.block;
666
break;
667
668
case PS_OP_RETURN:
669
return;
670
671
default:
672
fz_warn(ctx, "foreign operator in calculator function");
673
return;
674
}
675
break;
676
677
default:
678
fz_warn(ctx, "foreign object in calculator function");
679
return;
680
}
681
}
682
}
683
684
static void
685
resize_code(fz_context *ctx, pdf_function *func, int newsize)
686
{
687
if (newsize >= func->u.p.cap)
688
{
689
int new_cap = func->u.p.cap + 64;
690
func->u.p.code = fz_resize_array(ctx, func->u.p.code, new_cap, sizeof(psobj));
691
func->u.p.cap = new_cap;
692
}
693
}
694
695
static void
696
parse_code(fz_context *ctx, pdf_function *func, fz_stream *stream, int *codeptr, pdf_lexbuf *buf)
697
{
698
pdf_token tok;
699
int opptr, elseptr, ifptr;
700
int a, b, mid, cmp;
701
702
while (1)
703
{
704
tok = pdf_lex(ctx, stream, buf);
705
706
switch (tok)
707
{
708
case PDF_TOK_EOF:
709
fz_throw(ctx, FZ_ERROR_GENERIC, "truncated calculator function");
710
711
case PDF_TOK_INT:
712
resize_code(ctx, func, *codeptr);
713
func->u.p.code[*codeptr].type = PS_INT;
714
func->u.p.code[*codeptr].u.i = buf->i;
715
++*codeptr;
716
break;
717
718
case PDF_TOK_TRUE:
719
resize_code(ctx, func, *codeptr);
720
func->u.p.code[*codeptr].type = PS_BOOL;
721
func->u.p.code[*codeptr].u.b = 1;
722
++*codeptr;
723
break;
724
725
case PDF_TOK_FALSE:
726
resize_code(ctx, func, *codeptr);
727
func->u.p.code[*codeptr].type = PS_BOOL;
728
func->u.p.code[*codeptr].u.b = 0;
729
++*codeptr;
730
break;
731
732
case PDF_TOK_REAL:
733
resize_code(ctx, func, *codeptr);
734
func->u.p.code[*codeptr].type = PS_REAL;
735
func->u.p.code[*codeptr].u.f = buf->f;
736
++*codeptr;
737
break;
738
739
case PDF_TOK_OPEN_BRACE:
740
opptr = *codeptr;
741
*codeptr += 4;
742
743
resize_code(ctx, func, *codeptr);
744
745
ifptr = *codeptr;
746
parse_code(ctx, func, stream, codeptr, buf);
747
748
tok = pdf_lex(ctx, stream, buf);
749
750
if (tok == PDF_TOK_OPEN_BRACE)
751
{
752
elseptr = *codeptr;
753
parse_code(ctx, func, stream, codeptr, buf);
754
755
tok = pdf_lex(ctx, stream, buf);
756
}
757
else
758
{
759
elseptr = -1;
760
}
761
762
if (tok != PDF_TOK_KEYWORD)
763
fz_throw(ctx, FZ_ERROR_GENERIC, "missing keyword in 'if-else' context");
764
765
if (!strcmp(buf->scratch, "if"))
766
{
767
if (elseptr >= 0)
768
fz_throw(ctx, FZ_ERROR_GENERIC, "too many branches for 'if'");
769
func->u.p.code[opptr].type = PS_OPERATOR;
770
func->u.p.code[opptr].u.op = PS_OP_IF;
771
func->u.p.code[opptr+2].type = PS_BLOCK;
772
func->u.p.code[opptr+2].u.block = ifptr;
773
func->u.p.code[opptr+3].type = PS_BLOCK;
774
func->u.p.code[opptr+3].u.block = *codeptr;
775
}
776
else if (!strcmp(buf->scratch, "ifelse"))
777
{
778
if (elseptr < 0)
779
fz_throw(ctx, FZ_ERROR_GENERIC, "not enough branches for 'ifelse'");
780
func->u.p.code[opptr].type = PS_OPERATOR;
781
func->u.p.code[opptr].u.op = PS_OP_IFELSE;
782
func->u.p.code[opptr+1].type = PS_BLOCK;
783
func->u.p.code[opptr+1].u.block = elseptr;
784
func->u.p.code[opptr+2].type = PS_BLOCK;
785
func->u.p.code[opptr+2].u.block = ifptr;
786
func->u.p.code[opptr+3].type = PS_BLOCK;
787
func->u.p.code[opptr+3].u.block = *codeptr;
788
}
789
else
790
{
791
fz_throw(ctx, FZ_ERROR_GENERIC, "unknown keyword in 'if-else' context: '%s'", buf->scratch);
792
}
793
break;
794
795
case PDF_TOK_CLOSE_BRACE:
796
resize_code(ctx, func, *codeptr);
797
func->u.p.code[*codeptr].type = PS_OPERATOR;
798
func->u.p.code[*codeptr].u.op = PS_OP_RETURN;
799
++*codeptr;
800
return;
801
802
case PDF_TOK_KEYWORD:
803
cmp = -1;
804
a = -1;
805
b = nelem(ps_op_names);
806
while (b - a > 1)
807
{
808
mid = (a + b) / 2;
809
cmp = strcmp(buf->scratch, ps_op_names[mid]);
810
if (cmp > 0)
811
a = mid;
812
else if (cmp < 0)
813
b = mid;
814
else
815
a = b = mid;
816
}
817
if (cmp != 0)
818
fz_throw(ctx, FZ_ERROR_GENERIC, "unknown operator: '%s'", buf->scratch);
819
if (a == PS_OP_IFELSE)
820
fz_throw(ctx, FZ_ERROR_GENERIC, "illegally positioned ifelse operator in function");
821
if (a == PS_OP_IF)
822
fz_throw(ctx, FZ_ERROR_GENERIC, "illegally positioned if operator in function");
823
824
resize_code(ctx, func, *codeptr);
825
func->u.p.code[*codeptr].type = PS_OPERATOR;
826
func->u.p.code[*codeptr].u.op = a;
827
++*codeptr;
828
break;
829
830
default:
831
fz_throw(ctx, FZ_ERROR_GENERIC, "calculator function syntax error");
832
}
833
}
834
}
835
836
static void
837
load_postscript_func(fz_context *ctx, pdf_document *doc, pdf_function *func, pdf_obj *dict, int num, int gen)
838
{
839
fz_stream *stream = NULL;
840
int codeptr;
841
pdf_lexbuf buf;
842
pdf_token tok;
843
int locked = 0;
844
845
pdf_lexbuf_init(ctx, &buf, PDF_LEXBUF_SMALL);
846
847
fz_var(stream);
848
fz_var(locked);
849
850
fz_try(ctx)
851
{
852
stream = pdf_open_stream(ctx, doc, num, gen);
853
854
tok = pdf_lex(ctx, stream, &buf);
855
if (tok != PDF_TOK_OPEN_BRACE)
856
{
857
fz_throw(ctx, FZ_ERROR_GENERIC, "stream is not a calculator function");
858
}
859
860
func->u.p.code = NULL;
861
func->u.p.cap = 0;
862
863
codeptr = 0;
864
parse_code(ctx, func, stream, &codeptr, &buf);
865
}
866
fz_always(ctx)
867
{
868
fz_drop_stream(ctx, stream);
869
pdf_lexbuf_fin(ctx, &buf);
870
}
871
fz_catch(ctx)
872
{
873
fz_rethrow_message(ctx, "cannot parse calculator function (%d %d R)", num, gen);
874
}
875
876
func->base.size += func->u.p.cap * sizeof(psobj);
877
}
878
879
static void
880
eval_postscript_func(fz_context *ctx, pdf_function *func, const float *in, float *out)
881
{
882
ps_stack st;
883
float x;
884
int i;
885
886
ps_init_stack(&st);
887
888
for (i = 0; i < func->base.m; i++)
889
{
890
x = fz_clamp(in[i], func->domain[i][0], func->domain[i][1]);
891
ps_push_real(&st, x);
892
}
893
894
ps_run(ctx, func->u.p.code, &st, 0);
895
896
for (i = func->base.n - 1; i >= 0; i--)
897
{
898
x = ps_pop_real(&st);
899
out[i] = fz_clamp(x, func->range[i][0], func->range[i][1]);
900
}
901
}
902
903
/*
904
* Sample function
905
*/
906
907
#define MAX_SAMPLE_FUNCTION_SIZE (100 << 20)
908
909
static void
910
load_sample_func(fz_context *ctx, pdf_document *doc, pdf_function *func, pdf_obj *dict, int num, int gen)
911
{
912
fz_stream *stream;
913
pdf_obj *obj;
914
int samplecount;
915
int bps;
916
int i;
917
918
fz_var(stream);
919
920
func->u.sa.samples = NULL;
921
922
obj = pdf_dict_get(ctx, dict, PDF_NAME_Size);
923
if (pdf_array_len(ctx, obj) < func->base.m)
924
fz_throw(ctx, FZ_ERROR_GENERIC, "too few sample function dimension sizes");
925
if (pdf_array_len(ctx, obj) > func->base.m)
926
fz_warn(ctx, "too many sample function dimension sizes");
927
for (i = 0; i < func->base.m; i++)
928
{
929
func->u.sa.size[i] = pdf_to_int(ctx, pdf_array_get(ctx, obj, i));
930
if (func->u.sa.size[i] <= 0)
931
{
932
fz_warn(ctx, "non-positive sample function dimension size");
933
func->u.sa.size[i] = 1;
934
}
935
}
936
937
obj = pdf_dict_get(ctx, dict, PDF_NAME_BitsPerSample);
938
func->u.sa.bps = bps = pdf_to_int(ctx, obj);
939
940
for (i = 0; i < func->base.m; i++)
941
{
942
func->u.sa.encode[i][0] = 0;
943
func->u.sa.encode[i][1] = func->u.sa.size[i] - 1;
944
}
945
obj = pdf_dict_get(ctx, dict, PDF_NAME_Encode);
946
if (pdf_is_array(ctx, obj))
947
{
948
int ranges = fz_mini(func->base.m, pdf_array_len(ctx, obj) / 2);
949
if (ranges != func->base.m)
950
fz_warn(ctx, "wrong number of sample function input mappings");
951
952
for (i = 0; i < ranges; i++)
953
{
954
func->u.sa.encode[i][0] = pdf_to_real(ctx, pdf_array_get(ctx, obj, i * 2 + 0));
955
func->u.sa.encode[i][1] = pdf_to_real(ctx, pdf_array_get(ctx, obj, i * 2 + 1));
956
}
957
}
958
959
for (i = 0; i < func->base.n; i++)
960
{
961
func->u.sa.decode[i][0] = func->range[i][0];
962
func->u.sa.decode[i][1] = func->range[i][1];
963
}
964
965
obj = pdf_dict_get(ctx, dict, PDF_NAME_Decode);
966
if (pdf_is_array(ctx, obj))
967
{
968
int ranges = fz_mini(func->base.n, pdf_array_len(ctx, obj) / 2);
969
if (ranges != func->base.n)
970
fz_warn(ctx, "wrong number of sample function output mappings");
971
972
for (i = 0; i < ranges; i++)
973
{
974
func->u.sa.decode[i][0] = pdf_to_real(ctx, pdf_array_get(ctx, obj, i * 2 + 0));
975
func->u.sa.decode[i][1] = pdf_to_real(ctx, pdf_array_get(ctx, obj, i * 2 + 1));
976
}
977
}
978
979
for (i = 0, samplecount = func->base.n; i < func->base.m; i++)
980
samplecount *= func->u.sa.size[i];
981
982
if (samplecount > MAX_SAMPLE_FUNCTION_SIZE)
983
fz_throw(ctx, FZ_ERROR_GENERIC, "sample function too large");
984
985
func->u.sa.samples = fz_malloc_array(ctx, samplecount, sizeof(float));
986
func->base.size += samplecount * sizeof(float);
987
988
stream = pdf_open_stream(ctx, doc, num, gen);
989
990
fz_try(ctx)
991
{
992
/* read samples */
993
for (i = 0; i < samplecount; i++)
994
{
995
unsigned int x;
996
float s;
997
998
if (fz_is_eof_bits(ctx, stream))
999
fz_throw(ctx, FZ_ERROR_GENERIC, "truncated sample function stream");
1000
1001
switch (bps)
1002
{
1003
case 1: s = fz_read_bits(ctx, stream, 1); break;
1004
case 2: s = fz_read_bits(ctx, stream, 2) / 3.0f; break;
1005
case 4: s = fz_read_bits(ctx, stream, 4) / 15.0f; break;
1006
case 8: s = fz_read_byte(ctx, stream) / 255.0f; break;
1007
case 12: s = fz_read_bits(ctx, stream, 12) / 4095.0f; break;
1008
case 16:
1009
x = fz_read_byte(ctx, stream) << 8;
1010
x |= fz_read_byte(ctx, stream);
1011
s = x / 65535.0f;
1012
break;
1013
case 24:
1014
x = fz_read_byte(ctx, stream) << 16;
1015
x |= fz_read_byte(ctx, stream) << 8;
1016
x |= fz_read_byte(ctx, stream);
1017
s = x / 16777215.0f;
1018
break;
1019
case 32:
1020
x = fz_read_byte(ctx, stream) << 24;
1021
x |= fz_read_byte(ctx, stream) << 16;
1022
x |= fz_read_byte(ctx, stream) << 8;
1023
x |= fz_read_byte(ctx, stream);
1024
s = x / 4294967295.0f;
1025
break;
1026
default:
1027
fz_throw(ctx, FZ_ERROR_GENERIC, "sample stream bit depth %d unsupported", bps);
1028
}
1029
1030
func->u.sa.samples[i] = s;
1031
}
1032
}
1033
fz_always(ctx)
1034
{
1035
fz_drop_stream(ctx, stream);
1036
}
1037
fz_catch(ctx)
1038
{
1039
fz_rethrow(ctx);
1040
}
1041
}
1042
1043
static float
1044
interpolate_sample(pdf_function *func, int *scale, int *e0, int *e1, float *efrac, int dim, int idx)
1045
{
1046
float a, b;
1047
int idx0, idx1;
1048
1049
idx0 = e0[dim] * scale[dim] + idx;
1050
idx1 = e1[dim] * scale[dim] + idx;
1051
1052
if (dim == 0)
1053
{
1054
a = func->u.sa.samples[idx0];
1055
b = func->u.sa.samples[idx1];
1056
}
1057
else
1058
{
1059
a = interpolate_sample(func, scale, e0, e1, efrac, dim - 1, idx0);
1060
b = interpolate_sample(func, scale, e0, e1, efrac, dim - 1, idx1);
1061
}
1062
1063
return a + (b - a) * efrac[dim];
1064
}
1065
1066
static void
1067
eval_sample_func(fz_context *ctx, pdf_function *func, const float *in, float *out)
1068
{
1069
int e0[FZ_FN_MAXM], e1[FZ_FN_MAXM], scale[FZ_FN_MAXM];
1070
float efrac[FZ_FN_MAXM];
1071
float x;
1072
int i;
1073
1074
/* encode input coordinates */
1075
for (i = 0; i < func->base.m; i++)
1076
{
1077
x = fz_clamp(in[i], func->domain[i][0], func->domain[i][1]);
1078
x = lerp(x, func->domain[i][0], func->domain[i][1],
1079
func->u.sa.encode[i][0], func->u.sa.encode[i][1]);
1080
x = fz_clamp(x, 0, func->u.sa.size[i] - 1);
1081
e0[i] = floorf(x);
1082
e1[i] = ceilf(x);
1083
efrac[i] = x - floorf(x);
1084
}
1085
1086
scale[0] = func->base.n;
1087
for (i = 1; i < func->base.m; i++)
1088
scale[i] = scale[i - 1] * func->u.sa.size[i-1];
1089
1090
for (i = 0; i < func->base.n; i++)
1091
{
1092
if (func->base.m == 1)
1093
{
1094
float a = func->u.sa.samples[e0[0] * func->base.n + i];
1095
float b = func->u.sa.samples[e1[0] * func->base.n + i];
1096
1097
float ab = a + (b - a) * efrac[0];
1098
1099
out[i] = lerp(ab, 0, 1, func->u.sa.decode[i][0], func->u.sa.decode[i][1]);
1100
out[i] = fz_clamp(out[i], func->range[i][0], func->range[i][1]);
1101
}
1102
1103
else if (func->base.m == 2)
1104
{
1105
int s0 = func->base.n;
1106
int s1 = s0 * func->u.sa.size[0];
1107
1108
float a = func->u.sa.samples[e0[0] * s0 + e0[1] * s1 + i];
1109
float b = func->u.sa.samples[e1[0] * s0 + e0[1] * s1 + i];
1110
float c = func->u.sa.samples[e0[0] * s0 + e1[1] * s1 + i];
1111
float d = func->u.sa.samples[e1[0] * s0 + e1[1] * s1 + i];
1112
1113
float ab = a + (b - a) * efrac[0];
1114
float cd = c + (d - c) * efrac[0];
1115
float abcd = ab + (cd - ab) * efrac[1];
1116
1117
out[i] = lerp(abcd, 0, 1, func->u.sa.decode[i][0], func->u.sa.decode[i][1]);
1118
out[i] = fz_clamp(out[i], func->range[i][0], func->range[i][1]);
1119
}
1120
1121
else
1122
{
1123
x = interpolate_sample(func, scale, e0, e1, efrac, func->base.m - 1, i);
1124
out[i] = lerp(x, 0, 1, func->u.sa.decode[i][0], func->u.sa.decode[i][1]);
1125
out[i] = fz_clamp(out[i], func->range[i][0], func->range[i][1]);
1126
}
1127
}
1128
}
1129
1130
/*
1131
* Exponential function
1132
*/
1133
1134
static void
1135
load_exponential_func(fz_context *ctx, pdf_document *doc, pdf_function *func, pdf_obj *dict)
1136
{
1137
pdf_obj *obj;
1138
int i;
1139
1140
if (func->base.m > 1)
1141
fz_warn(ctx, "exponential functions have at most one input");
1142
func->base.m = 1;
1143
1144
obj = pdf_dict_get(ctx, dict, PDF_NAME_N);
1145
func->u.e.n = pdf_to_real(ctx, obj);
1146
1147
/* See exponential functions (PDF 1.7 section 3.9.2) */
1148
if (func->u.e.n != (int) func->u.e.n)
1149
{
1150
/* If N is non-integer, input values may never be negative */
1151
for (i = 0; i < func->base.m; i++)
1152
if (func->domain[i][0] < 0 || func->domain[i][1] < 0)
1153
fz_warn(ctx, "exponential function input domain includes illegal negative input values");
1154
}
1155
else if (func->u.e.n < 0)
1156
{
1157
/* if N is negative, input values may never be zero */
1158
for (i = 0; i < func->base.m; i++)
1159
if (func->domain[i][0] == 0 || func->domain[i][1] == 0 ||
1160
(func->domain[i][0] < 0 && func->domain[i][1] > 0))
1161
fz_warn(ctx, "exponential function input domain includes illegal input value zero");
1162
}
1163
1164
for (i = 0; i < func->base.n; i++)
1165
{
1166
func->u.e.c0[i] = 0;
1167
func->u.e.c1[i] = 1;
1168
}
1169
1170
obj = pdf_dict_get(ctx, dict, PDF_NAME_C0);
1171
if (pdf_is_array(ctx, obj))
1172
{
1173
int ranges = fz_mini(func->base.n, pdf_array_len(ctx, obj));
1174
if (ranges != func->base.n)
1175
fz_warn(ctx, "wrong number of C0 constants for exponential function");
1176
1177
for (i = 0; i < ranges; i++)
1178
func->u.e.c0[i] = pdf_to_real(ctx, pdf_array_get(ctx, obj, i));
1179
}
1180
1181
obj = pdf_dict_get(ctx, dict, PDF_NAME_C1);
1182
if (pdf_is_array(ctx, obj))
1183
{
1184
int ranges = fz_mini(func->base.n, pdf_array_len(ctx, obj));
1185
if (ranges != func->base.n)
1186
fz_warn(ctx, "wrong number of C1 constants for exponential function");
1187
1188
for (i = 0; i < ranges; i++)
1189
func->u.e.c1[i] = pdf_to_real(ctx, pdf_array_get(ctx, obj, i));
1190
}
1191
}
1192
1193
static void
1194
eval_exponential_func(fz_context *ctx, pdf_function *func, float in, float *out)
1195
{
1196
float x = in;
1197
float tmp;
1198
int i;
1199
1200
x = fz_clamp(x, func->domain[0][0], func->domain[0][1]);
1201
1202
/* Default output is zero, which is suitable for violated constraints */
1203
if ((func->u.e.n != (int)func->u.e.n && x < 0) || (func->u.e.n < 0 && x == 0))
1204
return;
1205
1206
tmp = powf(x, func->u.e.n);
1207
for (i = 0; i < func->base.n; i++)
1208
{
1209
out[i] = func->u.e.c0[i] + tmp * (func->u.e.c1[i] - func->u.e.c0[i]);
1210
if (func->has_range)
1211
out[i] = fz_clamp(out[i], func->range[i][0], func->range[i][1]);
1212
}
1213
}
1214
1215
/*
1216
* Stitching function
1217
*/
1218
1219
static void
1220
load_stitching_func(fz_context *ctx, pdf_document *doc, pdf_function *func, pdf_obj *dict)
1221
{
1222
fz_function **funcs;
1223
pdf_obj *obj;
1224
pdf_obj *sub;
1225
pdf_obj *num;
1226
int k;
1227
int i;
1228
1229
func->u.st.k = 0;
1230
1231
if (func->base.m > 1)
1232
fz_warn(ctx, "stitching functions have at most one input");
1233
func->base.m = 1;
1234
1235
obj = pdf_dict_get(ctx, dict, PDF_NAME_Functions);
1236
if (!pdf_is_array(ctx, obj))
1237
fz_throw(ctx, FZ_ERROR_GENERIC, "stitching function has no input functions");
1238
1239
fz_try(ctx)
1240
{
1241
pdf_mark_obj(ctx, obj);
1242
k = pdf_array_len(ctx, obj);
1243
1244
func->u.st.funcs = fz_malloc_array(ctx, k, sizeof(fz_function*));
1245
func->u.st.bounds = fz_malloc_array(ctx, k - 1, sizeof(float));
1246
func->u.st.encode = fz_malloc_array(ctx, k * 2, sizeof(float));
1247
funcs = func->u.st.funcs;
1248
1249
for (i = 0; i < k; i++)
1250
{
1251
sub = pdf_array_get(ctx, obj, i);
1252
funcs[i] = pdf_load_function(ctx, doc, sub, 1, func->base.n);
1253
1254
func->base.size += fz_function_size(ctx, funcs[i]);
1255
func->u.st.k ++;
1256
1257
if (funcs[i]->m != func->base.m)
1258
fz_warn(ctx, "wrong number of inputs for sub function %d", i);
1259
if (funcs[i]->n != func->base.n)
1260
fz_warn(ctx, "wrong number of outputs for sub function %d", i);
1261
}
1262
}
1263
fz_always(ctx)
1264
{
1265
pdf_unmark_obj(ctx, obj);
1266
}
1267
fz_catch(ctx)
1268
{
1269
fz_rethrow(ctx);
1270
}
1271
1272
obj = pdf_dict_get(ctx, dict, PDF_NAME_Bounds);
1273
if (!pdf_is_array(ctx, obj))
1274
fz_throw(ctx, FZ_ERROR_GENERIC, "stitching function has no bounds");
1275
{
1276
if (pdf_array_len(ctx, obj) < k - 1)
1277
fz_throw(ctx, FZ_ERROR_GENERIC, "too few subfunction boundaries");
1278
if (pdf_array_len(ctx, obj) > k)
1279
fz_warn(ctx, "too many subfunction boundaries");
1280
1281
for (i = 0; i < k - 1; i++)
1282
{
1283
num = pdf_array_get(ctx, obj, i);
1284
func->u.st.bounds[i] = pdf_to_real(ctx, num);
1285
if (i && func->u.st.bounds[i - 1] > func->u.st.bounds[i])
1286
fz_throw(ctx, FZ_ERROR_GENERIC, "subfunction %d boundary out of range", i);
1287
}
1288
1289
if (k > 1 && (func->domain[0][0] > func->u.st.bounds[0] ||
1290
func->domain[0][1] < func->u.st.bounds[k - 2]))
1291
fz_warn(ctx, "subfunction boundaries outside of input mapping");
1292
}
1293
1294
for (i = 0; i < k; i++)
1295
{
1296
func->u.st.encode[i * 2 + 0] = 0;
1297
func->u.st.encode[i * 2 + 1] = 0;
1298
}
1299
1300
obj = pdf_dict_get(ctx, dict, PDF_NAME_Encode);
1301
if (pdf_is_array(ctx, obj))
1302
{
1303
int ranges = fz_mini(k, pdf_array_len(ctx, obj) / 2);
1304
if (ranges != k)
1305
fz_warn(ctx, "wrong number of stitching function input mappings");
1306
1307
for (i = 0; i < ranges; i++)
1308
{
1309
func->u.st.encode[i * 2 + 0] = pdf_to_real(ctx, pdf_array_get(ctx, obj, i * 2 + 0));
1310
func->u.st.encode[i * 2 + 1] = pdf_to_real(ctx, pdf_array_get(ctx, obj, i * 2 + 1));
1311
}
1312
}
1313
}
1314
1315
static void
1316
eval_stitching_func(fz_context *ctx, pdf_function *func, float in, float *out)
1317
{
1318
float low, high;
1319
int k = func->u.st.k;
1320
float *bounds = func->u.st.bounds;
1321
int i;
1322
1323
in = fz_clamp(in, func->domain[0][0], func->domain[0][1]);
1324
1325
for (i = 0; i < k - 1; i++)
1326
{
1327
if (in < bounds[i])
1328
break;
1329
}
1330
1331
if (i == 0 && k == 1)
1332
{
1333
low = func->domain[0][0];
1334
high = func->domain[0][1];
1335
}
1336
else if (i == 0)
1337
{
1338
low = func->domain[0][0];
1339
high = bounds[0];
1340
}
1341
else if (i == k - 1)
1342
{
1343
low = bounds[k - 2];
1344
high = func->domain[0][1];
1345
}
1346
else
1347
{
1348
low = bounds[i - 1];
1349
high = bounds[i];
1350
}
1351
1352
in = lerp(in, low, high, func->u.st.encode[i * 2 + 0], func->u.st.encode[i * 2 + 1]);
1353
1354
fz_eval_function(ctx, func->u.st.funcs[i], &in, 1, out, func->u.st.funcs[i]->n);
1355
}
1356
1357
/*
1358
* Common
1359
*/
1360
1361
static void
1362
pdf_drop_function_imp(fz_context *ctx, fz_storable *func_)
1363
{
1364
pdf_function *func = (pdf_function *)func_;
1365
int i;
1366
1367
switch (func->type)
1368
{
1369
case SAMPLE:
1370
fz_free(ctx, func->u.sa.samples);
1371
break;
1372
case EXPONENTIAL:
1373
break;
1374
case STITCHING:
1375
for (i = 0; i < func->u.st.k; i++)
1376
fz_drop_function(ctx, func->u.st.funcs[i]);
1377
fz_free(ctx, func->u.st.funcs);
1378
fz_free(ctx, func->u.st.bounds);
1379
fz_free(ctx, func->u.st.encode);
1380
break;
1381
case POSTSCRIPT:
1382
fz_free(ctx, func->u.p.code);
1383
break;
1384
}
1385
fz_free(ctx, func);
1386
}
1387
1388
static void
1389
pdf_eval_function(fz_context *ctx, fz_function *func_, const float *in, float *out)
1390
{
1391
pdf_function *func = (pdf_function *)func_;
1392
1393
switch (func->type)
1394
{
1395
case SAMPLE: eval_sample_func(ctx, func, in, out); break;
1396
case EXPONENTIAL: eval_exponential_func(ctx, func, *in, out); break;
1397
case STITCHING: eval_stitching_func(ctx, func, *in, out); break;
1398
case POSTSCRIPT: eval_postscript_func(ctx, func, in, out); break;
1399
}
1400
}
1401
1402
/*
1403
* Debugging prints
1404
*/
1405
1406
#ifndef NDEBUG
1407
static void
1408
pdf_debug_indent(char *prefix, int level, char *suffix)
1409
{
1410
int i;
1411
1412
printf("%s", prefix);
1413
1414
for (i = 0; i < level; i++)
1415
printf("\t");
1416
1417
printf("%s", suffix);
1418
}
1419
1420
static void
1421
pdf_debug_ps_func_code(psobj *funccode, psobj *code, int level)
1422
{
1423
int eof, wasop;
1424
1425
pdf_debug_indent("", level, "{");
1426
1427
/* Print empty blocks as { }, instead of separating braces on different lines. */
1428
if (code->type == PS_OPERATOR && code->u.op == PS_OP_RETURN)
1429
{
1430
printf(" } ");
1431
return;
1432
}
1433
1434
pdf_debug_indent("\n", ++level, "");
1435
1436
eof = 0;
1437
wasop = 0;
1438
while (!eof)
1439
{
1440
switch (code->type)
1441
{
1442
case PS_INT:
1443
if (wasop)
1444
pdf_debug_indent("\n", level, "");
1445
1446
printf("%d ", code->u.i);
1447
wasop = 0;
1448
code++;
1449
break;
1450
1451
case PS_REAL:
1452
if (wasop)
1453
pdf_debug_indent("\n", level, "");
1454
1455
printf("%g ", code->u.f);
1456
wasop = 0;
1457
code++;
1458
break;
1459
1460
case PS_OPERATOR:
1461
if (code->u.op == PS_OP_RETURN)
1462
{
1463
printf("\n");
1464
eof = 1;
1465
}
1466
else if (code->u.op == PS_OP_IF)
1467
{
1468
printf("\n");
1469
pdf_debug_ps_func_code(funccode, &funccode[(code + 2)->u.block], level);
1470
1471
printf("%s", ps_op_names[code->u.op]);
1472
code = &funccode[(code + 3)->u.block];
1473
if (code->type != PS_OPERATOR || code->u.op != PS_OP_RETURN)
1474
pdf_debug_indent("\n", level, "");
1475
1476
wasop = 0;
1477
}
1478
else if (code->u.op == PS_OP_IFELSE)
1479
{
1480
printf("\n");
1481
pdf_debug_ps_func_code(funccode, &funccode[(code + 2)->u.block], level);
1482
1483
printf("\n");
1484
pdf_debug_ps_func_code(funccode, &funccode[(code + 1)->u.block], level);
1485
1486
printf("%s", ps_op_names[code->u.op]);
1487
code = &funccode[(code + 3)->u.block];
1488
if (code->type != PS_OPERATOR || code->u.op != PS_OP_RETURN)
1489
pdf_debug_indent("\n", level, "");
1490
1491
wasop = 0;
1492
}
1493
else
1494
{
1495
printf("%s ", ps_op_names[code->u.op]);
1496
code++;
1497
wasop = 1;
1498
}
1499
break;
1500
}
1501
}
1502
1503
pdf_debug_indent("", --level, "} ");
1504
}
1505
1506
static void
1507
pdf_debug_function_imp(fz_function *func_, int level)
1508
{
1509
int i;
1510
pdf_function *func = (pdf_function *)func_;
1511
1512
pdf_debug_indent("", level, "function {\n");
1513
1514
pdf_debug_indent("", ++level, "");
1515
switch (func->type)
1516
{
1517
case SAMPLE:
1518
printf("sampled");
1519
break;
1520
case EXPONENTIAL:
1521
printf("exponential");
1522
break;
1523
case STITCHING:
1524
printf("stitching");
1525
break;
1526
case POSTSCRIPT:
1527
printf("postscript");
1528
break;
1529
}
1530
1531
pdf_debug_indent("\n", level, "");
1532
printf("%d input -> %d output\n", func->base.m, func->base.n);
1533
1534
pdf_debug_indent("", level, "domain ");
1535
for (i = 0; i < func->base.m; i++)
1536
printf("%g %g ", func->domain[i][0], func->domain[i][1]);
1537
printf("\n");
1538
1539
if (func->has_range)
1540
{
1541
pdf_debug_indent("", level, "range ");
1542
for (i = 0; i < func->base.n; i++)
1543
printf("%g %g ", func->range[i][0], func->range[i][1]);
1544
printf("\n");
1545
}
1546
1547
switch (func->type)
1548
{
1549
case SAMPLE:
1550
pdf_debug_indent("", level, "");
1551
printf("bps: %d\n", func->u.sa.bps);
1552
1553
pdf_debug_indent("", level, "");
1554
printf("size: [ ");
1555
for (i = 0; i < func->base.m; i++)
1556
printf("%d ", func->u.sa.size[i]);
1557
printf("]\n");
1558
1559
pdf_debug_indent("", level, "");
1560
printf("encode: [ ");
1561
for (i = 0; i < func->base.m; i++)
1562
printf("%g %g ", func->u.sa.encode[i][0], func->u.sa.encode[i][1]);
1563
printf("]\n");
1564
1565
pdf_debug_indent("", level, "");
1566
printf("decode: [ ");
1567
for (i = 0; i < func->base.m; i++)
1568
printf("%g %g ", func->u.sa.decode[i][0], func->u.sa.decode[i][1]);
1569
printf("]\n");
1570
break;
1571
1572
case EXPONENTIAL:
1573
pdf_debug_indent("", level, "");
1574
printf("n: %g\n", func->u.e.n);
1575
1576
pdf_debug_indent("", level, "");
1577
printf("c0: [ ");
1578
for (i = 0; i < func->base.n; i++)
1579
printf("%g ", func->u.e.c0[i]);
1580
printf("]\n");
1581
1582
pdf_debug_indent("", level, "");
1583
printf("c1: [ ");
1584
for (i = 0; i < func->base.n; i++)
1585
printf("%g ", func->u.e.c1[i]);
1586
printf("]\n");
1587
break;
1588
1589
case STITCHING:
1590
pdf_debug_indent("", level, "");
1591
printf("%d functions\n", func->u.st.k);
1592
1593
pdf_debug_indent("", level, "");
1594
printf("bounds: [ ");
1595
for (i = 0; i < func->u.st.k - 1; i++)
1596
printf("%g ", func->u.st.bounds[i]);
1597
printf("]\n");
1598
1599
pdf_debug_indent("", level, "");
1600
printf("encode: [ ");
1601
for (i = 0; i < func->u.st.k * 2; i++)
1602
printf("%g ", func->u.st.encode[i]);
1603
printf("]\n");
1604
1605
for (i = 0; i < func->u.st.k; i++)
1606
pdf_debug_function_imp(func->u.st.funcs[i], level);
1607
break;
1608
1609
case POSTSCRIPT:
1610
pdf_debug_ps_func_code(func->u.p.code, func->u.p.code, level);
1611
printf("\n");
1612
break;
1613
}
1614
1615
pdf_debug_indent("", --level, "}\n");
1616
}
1617
1618
void
1619
pdf_debug_function(fz_context *ctx, fz_function *func)
1620
{
1621
pdf_debug_function_imp(func, 0);
1622
}
1623
#endif
1624
1625
fz_function *
1626
pdf_load_function(fz_context *ctx, pdf_document *doc, pdf_obj *dict, int in, int out)
1627
{
1628
pdf_function *func;
1629
pdf_obj *obj;
1630
int i;
1631
1632
if (pdf_obj_marked(ctx, dict))
1633
fz_throw(ctx, FZ_ERROR_GENERIC, "Recursion in function definition");
1634
1635
if ((func = pdf_find_item(ctx, pdf_drop_function_imp, dict)) != NULL)
1636
{
1637
return (fz_function *)func;
1638
}
1639
1640
func = fz_malloc_struct(ctx, pdf_function);
1641
FZ_INIT_STORABLE(&func->base, 1, pdf_drop_function_imp);
1642
func->base.size = sizeof(*func);
1643
func->base.evaluate = pdf_eval_function;
1644
#ifndef NDEBUG
1645
func->base.debug = pdf_debug_function;
1646
#endif
1647
1648
obj = pdf_dict_get(ctx, dict, PDF_NAME_FunctionType);
1649
func->type = pdf_to_int(ctx, obj);
1650
1651
/* required for all */
1652
obj = pdf_dict_get(ctx, dict, PDF_NAME_Domain);
1653
func->base.m = fz_clampi(pdf_array_len(ctx, obj) / 2, 1, FZ_FN_MAXM);
1654
for (i = 0; i < func->base.m; i++)
1655
{
1656
func->domain[i][0] = pdf_to_real(ctx, pdf_array_get(ctx, obj, i * 2 + 0));
1657
func->domain[i][1] = pdf_to_real(ctx, pdf_array_get(ctx, obj, i * 2 + 1));
1658
}
1659
1660
/* required for type0 and type4, optional otherwise */
1661
obj = pdf_dict_get(ctx, dict, PDF_NAME_Range);
1662
if (pdf_is_array(ctx, obj))
1663
{
1664
func->has_range = 1;
1665
func->base.n = fz_clampi(pdf_array_len(ctx, obj) / 2, 1, FZ_FN_MAXN);
1666
for (i = 0; i < func->base.n; i++)
1667
{
1668
func->range[i][0] = pdf_to_real(ctx, pdf_array_get(ctx, obj, i * 2 + 0));
1669
func->range[i][1] = pdf_to_real(ctx, pdf_array_get(ctx, obj, i * 2 + 1));
1670
}
1671
}
1672
else
1673
{
1674
func->has_range = 0;
1675
func->base.n = out;
1676
}
1677
1678
if (func->base.m != in)
1679
fz_warn(ctx, "wrong number of function inputs");
1680
if (func->base.n != out)
1681
fz_warn(ctx, "wrong number of function outputs");
1682
1683
fz_try(ctx)
1684
{
1685
switch (func->type)
1686
{
1687
case SAMPLE:
1688
load_sample_func(ctx, doc, func, dict, pdf_to_num(ctx, dict), pdf_to_gen(ctx, dict));
1689
break;
1690
1691
case EXPONENTIAL:
1692
load_exponential_func(ctx, doc, func, dict);
1693
break;
1694
1695
case STITCHING:
1696
load_stitching_func(ctx, doc, func, dict);
1697
break;
1698
1699
case POSTSCRIPT:
1700
load_postscript_func(ctx, doc, func, dict, pdf_to_num(ctx, dict), pdf_to_gen(ctx, dict));
1701
break;
1702
1703
default:
1704
fz_throw(ctx, FZ_ERROR_GENERIC, "unknown function type (%d %d R)", pdf_to_num(ctx, dict), pdf_to_gen(ctx, dict));
1705
}
1706
1707
pdf_store_item(ctx, dict, func, func->base.size);
1708
}
1709
fz_catch(ctx)
1710
{
1711
int type = func->type;
1712
fz_drop_function(ctx, (fz_function *)func);
1713
fz_rethrow_message(ctx, "cannot load %s function (%d %d R)",
1714
type == SAMPLE ? "sampled" :
1715
type == EXPONENTIAL ? "exponential" :
1716
type == STITCHING ? "stitching" :
1717
type == POSTSCRIPT ? "calculator" :
1718
"unknown",
1719
pdf_to_num(ctx, dict), pdf_to_gen(ctx, dict));
1720
}
1721
1722
return (fz_function *)func;
1723
}
1724
1725