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
 
3
typedef unsigned char byte;
4
 
5
static inline float roundup(float x)
6
{
7
	return (x < 0) ? floorf(x) : ceilf(x);
8
}
9
 
10
static inline int lerp(int a, int b, int t)
11
{
12
	return a + (((b - a) * t) >> 16);
13
}
14
 
15
static inline int bilerp(int a, int b, int c, int d, int u, int v)
16
{
17
	return lerp(lerp(a, b, u), lerp(c, d, u), v);
18
}
19
 
20
static inline byte *sample_nearest(byte *s, int w, int h, int n, int u, int v)
21
{
22
	if (u < 0) u = 0;
23
	if (v < 0) v = 0;
24
	if (u >= w) u = w - 1;
25
	if (v >= h) v = h - 1;
26
	return s + (v * w + u) * n;
27
}
28
 
29
/* Blend premultiplied source image in constant alpha over destination */
30
 
31
static inline void
32
fz_paint_affine_alpha_N_lerp(byte *dp, byte *sp, int sw, int sh, int u, int v, int fa, int fb, int w, int n, int alpha, byte *hp)
33
{
34
	int k;
35
	int n1 = n-1;
36
 
37
	while (w--)
38
	{
39
		int ui = u >> 16;
40
		int vi = v >> 16;
41
		if (ui >= 0 && ui < sw && vi >= 0 && vi < sh)
42
		{
43
			int uf = u & 0xffff;
44
			int vf = v & 0xffff;
45
			byte *a = sample_nearest(sp, sw, sh, n, ui, vi);
46
			byte *b = sample_nearest(sp, sw, sh, n, ui+1, vi);
47
			byte *c = sample_nearest(sp, sw, sh, n, ui, vi+1);
48
			byte *d = sample_nearest(sp, sw, sh, n, ui+1, vi+1);
49
			int xa = bilerp(a[n1], b[n1], c[n1], d[n1], uf, vf);
50
			int t;
51
			xa = fz_mul255(xa, alpha);
52
			t = 255 - xa;
53
			for (k = 0; k < n1; k++)
54
			{
55
				int x = bilerp(a[k], b[k], c[k], d[k], uf, vf);
56
				dp[k] = fz_mul255(x, alpha) + fz_mul255(dp[k], t);
57
			}
58
			dp[n1] = xa + fz_mul255(dp[n1], t);
59
			if (hp)
60
				hp[0] = xa + fz_mul255(hp[n1], t);
61
		}
62
		dp += n;
63
		if (hp)
64
			hp++;
65
		u += fa;
66
		v += fb;
67
	}
68
}
69
 
70
/* Special case code for gray -> rgb */
71
static inline void
72
fz_paint_affine_alpha_g2rgb_lerp(byte *dp, byte *sp, int sw, int sh, int u, int v, int fa, int fb, int w, int alpha, byte *hp)
73
{
74
	while (w--)
75
	{
76
		int ui = u >> 16;
77
		int vi = v >> 16;
78
		if (ui >= 0 && ui < sw && vi >= 0 && vi < sh)
79
		{
80
			int uf = u & 0xffff;
81
			int vf = v & 0xffff;
82
			byte *a = sample_nearest(sp, sw, sh, 2, ui, vi);
83
			byte *b = sample_nearest(sp, sw, sh, 2, ui+1, vi);
84
			byte *c = sample_nearest(sp, sw, sh, 2, ui, vi+1);
85
			byte *d = sample_nearest(sp, sw, sh, 2, ui+1, vi+1);
86
			int y = bilerp(a[1], b[1], c[1], d[1], uf, vf);
87
			int x = bilerp(a[0], b[0], c[0], d[0], uf, vf);
88
			int t;
89
			x = fz_mul255(x, alpha);
90
			y = fz_mul255(y, alpha);
91
			t = 255 - y;
92
			dp[0] = x + fz_mul255(dp[0], t);
93
			dp[1] = x + fz_mul255(dp[1], t);
94
			dp[2] = x + fz_mul255(dp[2], t);
95
			dp[3] = y + fz_mul255(dp[3], t);
96
			if (hp)
97
				hp[0] = y + fz_mul255(hp[0], t);
98
		}
99
		dp += 4;
100
		if (hp)
101
			hp++;
102
		u += fa;
103
		v += fb;
104
	}
105
}
106
 
107
static inline void
108
fz_paint_affine_alpha_N_near(byte *dp, byte *sp, int sw, int sh, int u, int v, int fa, int fb, int w, int n, int alpha, byte *hp)
109
{
110
	int k;
111
	int n1 = n-1;
112
 
113
	while (w--)
114
	{
115
		int ui = u >> 16;
116
		int vi = v >> 16;
117
		if (ui >= 0 && ui < sw && vi >= 0 && vi < sh)
118
		{
119
			byte *sample = sp + ((vi * sw + ui) * n);
120
			int a = fz_mul255(sample[n-1], alpha);
121
			int t = 255 - a;
122
			for (k = 0; k < n1; k++)
123
				dp[k] = fz_mul255(sample[k], alpha) + fz_mul255(dp[k], t);
124
			dp[n1] = a + fz_mul255(dp[n1], t);
125
			if (hp)
126
				hp[0] = a + fz_mul255(hp[n1], t);
127
		}
128
		dp += n;
129
		if (hp)
130
			hp++;
131
		u += fa;
132
		v += fb;
133
	}
134
}
135
 
136
static inline void
137
fz_paint_affine_alpha_g2rgb_near(byte *dp, byte *sp, int sw, int sh, int u, int v, int fa, int fb, int w, int alpha, byte *hp)
138
{
139
	while (w--)
140
	{
141
		int ui = u >> 16;
142
		int vi = v >> 16;
143
		if (ui >= 0 && ui < sw && vi >= 0 && vi < sh)
144
		{
145
			byte *sample = sp + ((vi * sw + ui) * 2);
146
			int x = fz_mul255(sample[0], alpha);
147
			int a = fz_mul255(sample[1], alpha);
148
			int t = 255 - a;
149
			dp[0] = x + fz_mul255(dp[0], t);
150
			dp[1] = x + fz_mul255(dp[1], t);
151
			dp[2] = x + fz_mul255(dp[2], t);
152
			dp[3] = a + fz_mul255(dp[3], t);
153
			if (hp)
154
				hp[0] = a + fz_mul255(hp[0], t);
155
		}
156
		dp += 4;
157
		if (hp)
158
			hp++;
159
		u += fa;
160
		v += fb;
161
	}
162
}
163
 
164
/* Blend premultiplied source image over destination */
165
 
166
static inline void
167
fz_paint_affine_N_lerp(byte *dp, byte *sp, int sw, int sh, int u, int v, int fa, int fb, int w, int n, byte *hp)
168
{
169
	int k;
170
	int n1 = n-1;
171
 
172
	while (w--)
173
	{
174
		int ui = u >> 16;
175
		int vi = v >> 16;
176
		if (ui >= 0 && ui < sw && vi >= 0 && vi < sh)
177
		{
178
			int uf = u & 0xffff;
179
			int vf = v & 0xffff;
180
			byte *a = sample_nearest(sp, sw, sh, n, ui, vi);
181
			byte *b = sample_nearest(sp, sw, sh, n, ui+1, vi);
182
			byte *c = sample_nearest(sp, sw, sh, n, ui, vi+1);
183
			byte *d = sample_nearest(sp, sw, sh, n, ui+1, vi+1);
184
			int y = bilerp(a[n1], b[n1], c[n1], d[n1], uf, vf);
185
			int t = 255 - y;
186
			for (k = 0; k < n1; k++)
187
			{
188
				int x = bilerp(a[k], b[k], c[k], d[k], uf, vf);
189
				dp[k] = x + fz_mul255(dp[k], t);
190
			}
191
			dp[n1] = y + fz_mul255(dp[n1], t);
192
			if (hp)
193
				hp[0] = y + fz_mul255(hp[0], t);
194
		}
195
		dp += n;
196
		if (hp)
197
			hp++;
198
		u += fa;
199
		v += fb;
200
	}
201
}
202
 
203
static inline void
204
fz_paint_affine_solid_g2rgb_lerp(byte *dp, byte *sp, int sw, int sh, int u, int v, int fa, int fb, int w, byte *hp)
205
{
206
	while (w--)
207
	{
208
		int ui = u >> 16;
209
		int vi = v >> 16;
210
		if (ui >= 0 && ui < sw && vi >= 0 && vi < sh)
211
		{
212
			int uf = u & 0xffff;
213
			int vf = v & 0xffff;
214
			byte *a = sample_nearest(sp, sw, sh, 2, ui, vi);
215
			byte *b = sample_nearest(sp, sw, sh, 2, ui+1, vi);
216
			byte *c = sample_nearest(sp, sw, sh, 2, ui, vi+1);
217
			byte *d = sample_nearest(sp, sw, sh, 2, ui+1, vi+1);
218
			int y = bilerp(a[1], b[1], c[1], d[1], uf, vf);
219
			int t = 255 - y;
220
			int x = bilerp(a[0], b[0], c[0], d[0], uf, vf);
221
			dp[0] = x + fz_mul255(dp[0], t);
222
			dp[1] = x + fz_mul255(dp[1], t);
223
			dp[2] = x + fz_mul255(dp[2], t);
224
			dp[3] = y + fz_mul255(dp[3], t);
225
			if (hp)
226
				hp[0] = y + fz_mul255(hp[0], t);
227
		}
228
		dp += 4;
229
		if (hp)
230
			hp++;
231
		u += fa;
232
		v += fb;
233
	}
234
}
235
 
236
static inline void
237
fz_paint_affine_N_near(byte *dp, byte *sp, int sw, int sh, int u, int v, int fa, int fb, int w, int n, byte *hp)
238
{
239
	int k;
240
	int n1 = n-1;
241
 
242
	while (w--)
243
	{
244
		int ui = u >> 16;
245
		int vi = v >> 16;
246
		if (ui >= 0 && ui < sw && vi >= 0 && vi < sh)
247
		{
248
			byte *sample = sp + ((vi * sw + ui) * n);
249
			int a = sample[n1];
250
			int t = 255 - a;
251
			for (k = 0; k < n1; k++)
252
				dp[k] = sample[k] + fz_mul255(dp[k], t);
253
			dp[n1] = a + fz_mul255(dp[n1], t);
254
			if (hp)
255
				hp[0] = a + fz_mul255(hp[0], t);
256
		}
257
		dp += n;
258
		if (hp)
259
			hp++;
260
		u += fa;
261
		v += fb;
262
	}
263
}
264
 
265
static inline void
266
fz_paint_affine_solid_g2rgb_near(byte *dp, byte *sp, int sw, int sh, int u, int v, int fa, int fb, int w, byte *hp)
267
{
268
	while (w--)
269
	{
270
		int ui = u >> 16;
271
		int vi = v >> 16;
272
		if (ui >= 0 && ui < sw && vi >= 0 && vi < sh)
273
		{
274
			byte *sample = sp + ((vi * sw + ui) * 2);
275
			int x = sample[0];
276
			int a = sample[1];
277
			int t = 255 - a;
278
			dp[0] = x + fz_mul255(dp[0], t);
279
			dp[1] = x + fz_mul255(dp[1], t);
280
			dp[2] = x + fz_mul255(dp[2], t);
281
			dp[3] = a + fz_mul255(dp[3], t);
282
			if (hp)
283
				hp[0] = a + fz_mul255(hp[0], t);
284
		}
285
		dp += 4;
286
		if (hp)
287
			hp++;
288
		u += fa;
289
		v += fb;
290
	}
291
}
292
 
293
/* Blend non-premultiplied color in source image mask over destination */
294
 
295
static inline void
296
fz_paint_affine_color_N_lerp(byte *dp, byte *sp, int sw, int sh, int u, int v, int fa, int fb, int w, int n, byte *color, byte *hp)
297
{
298
	int n1 = n - 1;
299
	int sa = color[n1];
300
	int k;
301
 
302
	while (w--)
303
	{
304
		int ui = u >> 16;
305
		int vi = v >> 16;
306
		if (ui >= 0 && ui < sw && vi >= 0 && vi < sh)
307
		{
308
			int uf = u & 0xffff;
309
			int vf = v & 0xffff;
310
			byte *a = sample_nearest(sp, sw, sh, 1, ui, vi);
311
			byte *b = sample_nearest(sp, sw, sh, 1, ui+1, vi);
312
			byte *c = sample_nearest(sp, sw, sh, 1, ui, vi+1);
313
			byte *d = sample_nearest(sp, sw, sh, 1, ui+1, vi+1);
314
			int ma = bilerp(a[0], b[0], c[0], d[0], uf, vf);
315
			int masa = FZ_COMBINE(FZ_EXPAND(ma), sa);
316
			for (k = 0; k < n1; k++)
317
				dp[k] = FZ_BLEND(color[k], dp[k], masa);
318
			dp[n1] = FZ_BLEND(255, dp[n1], masa);
319
			if (hp)
320
				hp[0] = FZ_BLEND(255, hp[0], masa);
321
		}
322
		dp += n;
323
		if (hp)
324
			hp++;
325
		u += fa;
326
		v += fb;
327
	}
328
}
329
 
330
static inline void
331
fz_paint_affine_color_N_near(byte *dp, byte *sp, int sw, int sh, int u, int v, int fa, int fb, int w, int n, byte *color, byte *hp)
332
{
333
	int n1 = n-1;
334
	int sa = color[n1];
335
	int k;
336
 
337
	while (w--)
338
	{
339
		int ui = u >> 16;
340
		int vi = v >> 16;
341
		if (ui >= 0 && ui < sw && vi >= 0 && vi < sh)
342
		{
343
			int ma = sp[vi * sw + ui];
344
			int masa = FZ_COMBINE(FZ_EXPAND(ma), sa);
345
			for (k = 0; k < n1; k++)
346
				dp[k] = FZ_BLEND(color[k], dp[k], masa);
347
			dp[n1] = FZ_BLEND(255, dp[n1], masa);
348
			if (hp)
349
				hp[n1] = FZ_BLEND(255, hp[n1], masa);
350
		}
351
		dp += n;
352
		if (hp)
353
			hp++;
354
		u += fa;
355
		v += fb;
356
	}
357
}
358
 
359
static void
360
fz_paint_affine_lerp(byte *dp, byte *sp, int sw, int sh, int u, int v, int fa, int fb, int w, int n, int alpha, byte *color/*unused*/, byte *hp)
361
{
362
	if (alpha == 255)
363
	{
364
		switch (n)
365
		{
366
		case 1: fz_paint_affine_N_lerp(dp, sp, sw, sh, u, v, fa, fb, w, 1, hp); break;
367
		case 2: fz_paint_affine_N_lerp(dp, sp, sw, sh, u, v, fa, fb, w, 2, hp); break;
368
		case 4: fz_paint_affine_N_lerp(dp, sp, sw, sh, u, v, fa, fb, w, 4, hp); break;
369
		default: fz_paint_affine_N_lerp(dp, sp, sw, sh, u, v, fa, fb, w, n, hp); break;
370
		}
371
	}
372
	else if (alpha > 0)
373
	{
374
		switch (n)
375
		{
376
		case 1: fz_paint_affine_alpha_N_lerp(dp, sp, sw, sh, u, v, fa, fb, w, 1, alpha, hp); break;
377
		case 2: fz_paint_affine_alpha_N_lerp(dp, sp, sw, sh, u, v, fa, fb, w, 2, alpha, hp); break;
378
		case 4: fz_paint_affine_alpha_N_lerp(dp, sp, sw, sh, u, v, fa, fb, w, 4, alpha, hp); break;
379
		default: fz_paint_affine_alpha_N_lerp(dp, sp, sw, sh, u, v, fa, fb, w, n, alpha, hp); break;
380
		}
381
	}
382
}
383
 
384
static void
385
fz_paint_affine_g2rgb_lerp(byte *dp, byte *sp, int sw, int sh, int u, int v, int fa, int fb, int w, int n, int alpha, byte *color/*unused*/, byte *hp)
386
{
387
	if (alpha == 255)
388
	{
389
		fz_paint_affine_solid_g2rgb_lerp(dp, sp, sw, sh, u, v, fa, fb, w, hp);
390
	}
391
	else if (alpha > 0)
392
	{
393
		fz_paint_affine_alpha_g2rgb_lerp(dp, sp, sw, sh, u, v, fa, fb, w, alpha, hp);
394
	}
395
}
396
 
397
static void
398
fz_paint_affine_near(byte *dp, byte *sp, int sw, int sh, int u, int v, int fa, int fb, int w, int n, int alpha, byte *color/*unused */, byte *hp)
399
{
400
	if (alpha == 255)
401
	{
402
		switch (n)
403
		{
404
		case 1: fz_paint_affine_N_near(dp, sp, sw, sh, u, v, fa, fb, w, 1, hp); break;
405
		case 2: fz_paint_affine_N_near(dp, sp, sw, sh, u, v, fa, fb, w, 2, hp); break;
406
		case 4: fz_paint_affine_N_near(dp, sp, sw, sh, u, v, fa, fb, w, 4, hp); break;
407
		default: fz_paint_affine_N_near(dp, sp, sw, sh, u, v, fa, fb, w, n, hp); break;
408
		}
409
	}
410
	else if (alpha > 0)
411
	{
412
		switch (n)
413
		{
414
		case 1: fz_paint_affine_alpha_N_near(dp, sp, sw, sh, u, v, fa, fb, w, 1, alpha, hp); break;
415
		case 2: fz_paint_affine_alpha_N_near(dp, sp, sw, sh, u, v, fa, fb, w, 2, alpha, hp); break;
416
		case 4: fz_paint_affine_alpha_N_near(dp, sp, sw, sh, u, v, fa, fb, w, 4, alpha, hp); break;
417
		default: fz_paint_affine_alpha_N_near(dp, sp, sw, sh, u, v, fa, fb, w, n, alpha, hp); break;
418
		}
419
	}
420
}
421
 
422
static void
423
fz_paint_affine_g2rgb_near(byte *dp, byte *sp, int sw, int sh, int u, int v, int fa, int fb, int w, int n, int alpha, byte *color/*unused*/, byte *hp)
424
{
425
	if (alpha == 255)
426
	{
427
		fz_paint_affine_solid_g2rgb_near(dp, sp, sw, sh, u, v, fa, fb, w, hp);
428
	}
429
	else if (alpha > 0)
430
	{
431
		fz_paint_affine_alpha_g2rgb_near(dp, sp, sw, sh, u, v, fa, fb, w, alpha, hp);
432
	}
433
}
434
 
435
static void
436
fz_paint_affine_color_lerp(byte *dp, byte *sp, int sw, int sh, int u, int v, int fa, int fb, int w, int n, int alpha/*unused*/, byte *color, byte *hp)
437
{
438
	switch (n)
439
	{
440
	case 2: fz_paint_affine_color_N_lerp(dp, sp, sw, sh, u, v, fa, fb, w, 2, color, hp); break;
441
	case 4: fz_paint_affine_color_N_lerp(dp, sp, sw, sh, u, v, fa, fb, w, 4, color, hp); break;
442
	default: fz_paint_affine_color_N_lerp(dp, sp, sw, sh, u, v, fa, fb, w, n, color, hp); break;
443
	}
444
}
445
 
446
static void
447
fz_paint_affine_color_near(byte *dp, byte *sp, int sw, int sh, int u, int v, int fa, int fb, int w, int n, int alpha/*unused*/, byte *color, byte *hp)
448
{
449
	switch (n)
450
	{
451
	case 2: fz_paint_affine_color_N_near(dp, sp, sw, sh, u, v, fa, fb, w, 2, color, hp); break;
452
	case 4: fz_paint_affine_color_N_near(dp, sp, sw, sh, u, v, fa, fb, w, 4, color, hp); break;
453
	default: fz_paint_affine_color_N_near(dp, sp, sw, sh, u, v, fa, fb, w, n, color, hp); break;
454
	}
455
}
456
 
457
/* Draw an image with an affine transform on destination */
458
 
459
static void
460
fz_paint_image_imp(fz_pixmap *dst, fz_bbox scissor, fz_pixmap *shape, fz_pixmap *img, fz_matrix ctm, byte *color, int alpha)
461
{
462
	byte *dp, *sp, *hp;
463
	int u, v, fa, fb, fc, fd;
464
	int x, y, w, h;
465
	int sw, sh, n, hw;
466
	fz_matrix inv;
467
	fz_bbox bbox;
468
	int dolerp;
469
	void (*paintfn)(byte *dp, byte *sp, int sw, int sh, int u, int v, int fa, int fb, int w, int n, int alpha, byte *color, byte *hp);
470
 
471
	/* grid fit the image */
472
	if (fz_is_rectilinear(ctm))
473
	{
474
		ctm.a = roundup(ctm.a);
475
		ctm.b = roundup(ctm.b);
476
		ctm.c = roundup(ctm.c);
477
		ctm.d = roundup(ctm.d);
478
		ctm.e = floorf(ctm.e);
479
		ctm.f = floorf(ctm.f);
480
	}
481
 
482
	/* turn on interpolation for upscaled and non-rectilinear transforms */
483
	dolerp = 0;
484
	if (!fz_is_rectilinear(ctm))
485
		dolerp = 1;
486
	if (sqrtf(ctm.a * ctm.a + ctm.b * ctm.b) > img->w)
487
		dolerp = 1;
488
	if (sqrtf(ctm.c * ctm.c + ctm.d * ctm.d) > img->h)
489
		dolerp = 1;
490
 
491
	/* except when we shouldn't, at large magnifications */
492
	if (!img->interpolate)
493
	{
494
		if (sqrtf(ctm.a * ctm.a + ctm.b * ctm.b) > img->w * 2)
495
			dolerp = 0;
496
		if (sqrtf(ctm.c * ctm.c + ctm.d * ctm.d) > img->h * 2)
497
			dolerp = 0;
498
	}
499
 
500
	bbox = fz_round_rect(fz_transform_rect(ctm, fz_unit_rect));
501
	bbox = fz_intersect_bbox(bbox, scissor);
502
	x = bbox.x0;
503
	y = bbox.y0;
504
	w = bbox.x1 - bbox.x0;
505
	h = bbox.y1 - bbox.y0;
506
 
507
	/* map from screen space (x,y) to image space (u,v) */
508
	inv = fz_scale(1.0f / img->w, -1.0f / img->h);
509
	inv = fz_concat(inv, fz_translate(0, 1));
510
	inv = fz_concat(inv, ctm);
511
	inv = fz_invert_matrix(inv);
512
 
513
	fa = inv.a * 65536;
514
	fb = inv.b * 65536;
515
	fc = inv.c * 65536;
516
	fd = inv.d * 65536;
517
 
518
	/* Calculate initial texture positions. Do a half step to start. */
519
	u = (fa * x) + (fc * y) + inv.e * 65536 + ((fa + fc) >> 1);
520
	v = (fb * x) + (fd * y) + inv.f * 65536 + ((fb + fd) >> 1);
521
 
522
	dp = dst->samples + ((y - dst->y) * dst->w + (x - dst->x)) * dst->n;
523
	n = dst->n;
524
	sp = img->samples;
525
	sw = img->w;
526
	sh = img->h;
527
	if (shape)
528
	{
529
		hw = shape->w;
530
		hp = shape->samples + ((y - shape->y) * hw) + x - dst->x;
531
	}
532
	else
533
	{
534
		hw = 0;
535
		hp = NULL;
536
	}
537
 
538
	/* TODO: if (fb == 0 && fa == 1) call fz_paint_span */
539
 
540
	if (dst->n == 4 && img->n == 2)
541
	{
542
		assert(color == NULL);
543
		if (dolerp)
544
			paintfn = fz_paint_affine_g2rgb_lerp;
545
		else
546
			paintfn = fz_paint_affine_g2rgb_near;
547
	}
548
	else
549
	{
550
		if (dolerp)
551
		{
552
			if (color)
553
				paintfn = fz_paint_affine_color_lerp;
554
			else
555
				paintfn = fz_paint_affine_lerp;
556
		}
557
		else
558
		{
559
			if (color)
560
				paintfn = fz_paint_affine_color_near;
561
			else
562
				paintfn = fz_paint_affine_near;
563
		}
564
	}
565
 
566
	while (h--)
567
	{
568
		paintfn(dp, sp, sw, sh, u, v, fa, fb, w, n, alpha, color, hp);
569
		dp += dst->w * n;
570
		hp += hw;
571
		u += fc;
572
		v += fd;
573
	}
574
}
575
 
576
void
577
fz_paint_image_with_color(fz_pixmap *dst, fz_bbox scissor, fz_pixmap *shape, fz_pixmap *img, fz_matrix ctm, byte *color)
578
{
579
	assert(img->n == 1);
580
	fz_paint_image_imp(dst, scissor, shape, img, ctm, color, 255);
581
}
582
 
583
void
584
fz_paint_image(fz_pixmap *dst, fz_bbox scissor, fz_pixmap *shape, fz_pixmap *img, fz_matrix ctm, int alpha)
585
{
586
	assert(dst->n == img->n || (dst->n == 4 && img->n == 2));
587
	fz_paint_image_imp(dst, scissor, shape, img, ctm, NULL, alpha);
588
}