Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

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