1
/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */
2
/* cairo - a vector graphics library with display and print output
3
 *
4
 * Copyright © 2003 University of Southern California
5
 * Copyright © 2009,2010,2011 Intel Corporation
6
 *
7
 * This library is free software; you can redistribute it and/or
8
 * modify it either under the terms of the GNU Lesser General Public
9
 * License version 2.1 as published by the Free Software Foundation
10
 * (the "LGPL") or, at your option, under the terms of the Mozilla
11
 * Public License Version 1.1 (the "MPL"). If you do not alter this
12
 * notice, a recipient may use your version of this file under either
13
 * the MPL or the LGPL.
14
 *
15
 * You should have received a copy of the LGPL along with this library
16
 * in the file COPYING-LGPL-2.1; if not, write to the Free Software
17
 * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
18
 * You should have received a copy of the MPL along with this library
19
 * in the file COPYING-MPL-1.1
20
 *
21
 * The contents of this file are subject to the Mozilla Public License
22
 * Version 1.1 (the "License"); you may not use this file except in
23
 * compliance with the License. You may obtain a copy of the License at
24
 * http://www.mozilla.org/MPL/
25
 *
26
 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
27
 * OF ANY KIND, either express or implied. See the LGPL or the MPL for
28
 * the specific language governing rights and limitations.
29
 *
30
 * The Original Code is the cairo graphics library.
31
 *
32
 * The Initial Developer of the Original Code is University of Southern
33
 * California.
34
 *
35
 * Contributor(s):
36
 *	Carl D. Worth <cworth@cworth.org>
37
 *	Chris Wilson <chris@chris-wilson.co.uk>
38
 */
39

            
40
/* The purpose of this file/surface is to simply translate a pattern
41
 * to a pixman_image_t and thence to feed it back to the general
42
 * compositor interface.
43
 */
44

            
45
#include "cairoint.h"
46

            
47
#include "cairo-image-surface-private.h"
48

            
49
#include "cairo-compositor-private.h"
50
#include "cairo-error-private.h"
51
#include "cairo-pattern-inline.h"
52
#include "cairo-paginated-private.h"
53
#include "cairo-recording-surface-private.h"
54
#include "cairo-surface-observer-private.h"
55
#include "cairo-surface-snapshot-inline.h"
56
#include "cairo-surface-subsurface-private.h"
57

            
58
#define PIXMAN_MAX_INT ((pixman_fixed_1 >> 1) - pixman_fixed_e) /* need to ensure deltas also fit */
59

            
60
#if CAIRO_NO_MUTEX
61
#define PIXMAN_HAS_ATOMIC_OPS 1
62
#endif
63

            
64
#if PIXMAN_HAS_ATOMIC_OPS
65
static pixman_image_t *__pixman_transparent_image;
66
static pixman_image_t *__pixman_black_image;
67
static pixman_image_t *__pixman_white_image;
68

            
69
static pixman_image_t *
70
_pixman_transparent_image (void)
71
{
72
    pixman_image_t *image;
73

            
74
    TRACE ((stderr, "%s\n", __FUNCTION__));
75

            
76
    image = __pixman_transparent_image;
77
    if (unlikely (image == NULL)) {
78
	pixman_color_t color;
79

            
80
	color.red   = 0x00;
81
	color.green = 0x00;
82
	color.blue  = 0x00;
83
	color.alpha = 0x00;
84

            
85
	image = pixman_image_create_solid_fill (&color);
86
	if (unlikely (image == NULL))
87
	    return NULL;
88

            
89
	if (_cairo_atomic_ptr_cmpxchg (&__pixman_transparent_image,
90
				       NULL, image))
91
	{
92
	    pixman_image_ref (image);
93
	}
94
    } else {
95
	pixman_image_ref (image);
96
    }
97

            
98
    return image;
99
}
100

            
101
static pixman_image_t *
102
_pixman_black_image (void)
103
{
104
    pixman_image_t *image;
105

            
106
    TRACE ((stderr, "%s\n", __FUNCTION__));
107

            
108
    image = __pixman_black_image;
109
    if (unlikely (image == NULL)) {
110
	pixman_color_t color;
111

            
112
	color.red   = 0x00;
113
	color.green = 0x00;
114
	color.blue  = 0x00;
115
	color.alpha = 0xffff;
116

            
117
	image = pixman_image_create_solid_fill (&color);
118
	if (unlikely (image == NULL))
119
	    return NULL;
120

            
121
	if (_cairo_atomic_ptr_cmpxchg (&__pixman_black_image,
122
				       NULL, image))
123
	{
124
	    pixman_image_ref (image);
125
	}
126
    } else {
127
	pixman_image_ref (image);
128
    }
129

            
130
    return image;
131
}
132

            
133
static pixman_image_t *
134
_pixman_white_image (void)
135
{
136
    pixman_image_t *image;
137

            
138
    TRACE ((stderr, "%s\n", __FUNCTION__));
139

            
140
    image = __pixman_white_image;
141
    if (unlikely (image == NULL)) {
142
	pixman_color_t color;
143

            
144
	color.red   = 0xffff;
145
	color.green = 0xffff;
146
	color.blue  = 0xffff;
147
	color.alpha = 0xffff;
148

            
149
	image = pixman_image_create_solid_fill (&color);
150
	if (unlikely (image == NULL))
151
	    return NULL;
152

            
153
	if (_cairo_atomic_ptr_cmpxchg (&__pixman_white_image,
154
				       NULL, image))
155
	{
156
	    pixman_image_ref (image);
157
	}
158
    } else {
159
	pixman_image_ref (image);
160
    }
161

            
162
    return image;
163
}
164

            
165
static uint32_t
166
hars_petruska_f54_1_random (void)
167
{
168
#define rol(x,k) ((x << k) | (x >> (32-k)))
169
    static uint32_t x;
170
    return x = (x ^ rol (x, 5) ^ rol (x, 24)) + 0x37798849;
171
#undef rol
172
}
173

            
174
static struct {
175
    cairo_color_t color;
176
    pixman_image_t *image;
177
} cache[16];
178
static int n_cached;
179

            
180
#else  /* !PIXMAN_HAS_ATOMIC_OPS */
181
static pixman_image_t *
182
60
_pixman_transparent_image (void)
183
{
184
    TRACE ((stderr, "%s\n", __FUNCTION__));
185
60
    return _pixman_image_for_color (CAIRO_COLOR_TRANSPARENT);
186
}
187

            
188
static pixman_image_t *
189
663
_pixman_black_image (void)
190
{
191
    TRACE ((stderr, "%s\n", __FUNCTION__));
192
663
    return _pixman_image_for_color (CAIRO_COLOR_BLACK);
193
}
194

            
195
static pixman_image_t *
196
1145
_pixman_white_image (void)
197
{
198
    TRACE ((stderr, "%s\n", __FUNCTION__));
199
1145
    return _pixman_image_for_color (CAIRO_COLOR_WHITE);
200
}
201
#endif /* !PIXMAN_HAS_ATOMIC_OPS */
202

            
203

            
204
pixman_image_t *
205
294155
_pixman_image_for_color (const cairo_color_t *cairo_color)
206
{
207
    pixman_color_t color;
208
    pixman_image_t *image;
209

            
210
#if PIXMAN_HAS_ATOMIC_OPS
211
    int i;
212

            
213
    if (CAIRO_COLOR_IS_CLEAR (cairo_color))
214
	return _pixman_transparent_image ();
215

            
216
    if (CAIRO_COLOR_IS_OPAQUE (cairo_color)) {
217
	if (cairo_color->red_short <= 0x00ff &&
218
	    cairo_color->green_short <= 0x00ff &&
219
	    cairo_color->blue_short <= 0x00ff)
220
	{
221
	    return _pixman_black_image ();
222
	}
223

            
224
	if (cairo_color->red_short >= 0xff00 &&
225
	    cairo_color->green_short >= 0xff00 &&
226
	    cairo_color->blue_short >= 0xff00)
227
	{
228
	    return _pixman_white_image ();
229
	}
230
    }
231

            
232
    CAIRO_MUTEX_LOCK (_cairo_image_solid_cache_mutex);
233
    for (i = 0; i < n_cached; i++) {
234
	if (_cairo_color_equal (&cache[i].color, cairo_color)) {
235
	    image = pixman_image_ref (cache[i].image);
236
	    goto UNLOCK;
237
	}
238
    }
239
#endif
240

            
241
294155
    color.red   = cairo_color->red_short;
242
294155
    color.green = cairo_color->green_short;
243
294155
    color.blue  = cairo_color->blue_short;
244
294155
    color.alpha = cairo_color->alpha_short;
245

            
246
294155
    image = pixman_image_create_solid_fill (&color);
247
#if PIXMAN_HAS_ATOMIC_OPS
248
    if (image == NULL)
249
	goto UNLOCK;
250

            
251
    if (n_cached < ARRAY_LENGTH (cache)) {
252
	i = n_cached++;
253
    } else {
254
	i = hars_petruska_f54_1_random () % ARRAY_LENGTH (cache);
255
	pixman_image_unref (cache[i].image);
256
    }
257
    cache[i].image = pixman_image_ref (image);
258
    cache[i].color = *cairo_color;
259

            
260
UNLOCK:
261
    CAIRO_MUTEX_UNLOCK (_cairo_image_solid_cache_mutex);
262
#endif
263
294155
    return image;
264
}
265

            
266

            
267
void
268
608
_cairo_image_reset_static_data (void)
269
{
270
#if PIXMAN_HAS_ATOMIC_OPS
271
    while (n_cached)
272
	pixman_image_unref (cache[--n_cached].image);
273

            
274
    if (__pixman_transparent_image) {
275
	pixman_image_unref (__pixman_transparent_image);
276
	__pixman_transparent_image = NULL;
277
    }
278

            
279
    if (__pixman_black_image) {
280
	pixman_image_unref (__pixman_black_image);
281
	__pixman_black_image = NULL;
282
    }
283

            
284
    if (__pixman_white_image) {
285
	pixman_image_unref (__pixman_white_image);
286
	__pixman_white_image = NULL;
287
    }
288
#endif
289
608
}
290

            
291
static pixman_image_t *
292
1554
_pixman_image_for_gradient (const cairo_gradient_pattern_t *pattern,
293
			    const cairo_rectangle_int_t *extents,
294
			    int *ix, int *iy)
295
{
296
    pixman_image_t	  *pixman_image;
297
    pixman_gradient_stop_t pixman_stops_static[2];
298
1554
    pixman_gradient_stop_t *pixman_stops = pixman_stops_static;
299
    pixman_transform_t      pixman_transform;
300
    cairo_matrix_t matrix;
301
    cairo_circle_double_t extremes[2];
302
    pixman_point_fixed_t p1, p2;
303
    unsigned int i;
304
    cairo_int_status_t status;
305

            
306
    TRACE ((stderr, "%s\n", __FUNCTION__));
307

            
308
1554
    if (pattern->n_stops > ARRAY_LENGTH(pixman_stops_static)) {
309
630
	pixman_stops = _cairo_malloc_ab (pattern->n_stops,
310
					 sizeof(pixman_gradient_stop_t));
311
630
	if (unlikely (pixman_stops == NULL))
312
	    return NULL;
313
    }
314

            
315
5304
    for (i = 0; i < pattern->n_stops; i++) {
316
3750
	pixman_stops[i].x = _cairo_fixed_16_16_from_double (pattern->stops[i].offset);
317
3750
	pixman_stops[i].color.red   = pattern->stops[i].color.red_short;
318
3750
	pixman_stops[i].color.green = pattern->stops[i].color.green_short;
319
3750
	pixman_stops[i].color.blue  = pattern->stops[i].color.blue_short;
320
3750
	pixman_stops[i].color.alpha = pattern->stops[i].color.alpha_short;
321
    }
322

            
323
1554
    _cairo_gradient_pattern_fit_to_range (pattern, PIXMAN_MAX_INT >> 1, &matrix, extremes);
324

            
325
1554
    p1.x = _cairo_fixed_16_16_from_double (extremes[0].center.x);
326
1554
    p1.y = _cairo_fixed_16_16_from_double (extremes[0].center.y);
327
1554
    p2.x = _cairo_fixed_16_16_from_double (extremes[1].center.x);
328
1554
    p2.y = _cairo_fixed_16_16_from_double (extremes[1].center.y);
329

            
330
1554
    if (pattern->base.type == CAIRO_PATTERN_TYPE_LINEAR) {
331
879
	pixman_image = pixman_image_create_linear_gradient (&p1, &p2,
332
							    pixman_stops,
333
879
							    pattern->n_stops);
334
    } else {
335
	pixman_fixed_t r1, r2;
336

            
337
675
	r1   = _cairo_fixed_16_16_from_double (extremes[0].radius);
338
675
	r2   = _cairo_fixed_16_16_from_double (extremes[1].radius);
339

            
340
675
	pixman_image = pixman_image_create_radial_gradient (&p1, &p2, r1, r2,
341
							    pixman_stops,
342
675
							    pattern->n_stops);
343
    }
344

            
345
1554
    if (pixman_stops != pixman_stops_static)
346
630
	free (pixman_stops);
347

            
348
1554
    if (unlikely (pixman_image == NULL))
349
	return NULL;
350

            
351
1554
    *ix = *iy = 0;
352
1554
    status = _cairo_matrix_to_pixman_matrix_offset (&matrix, pattern->base.filter,
353
1554
						    extents->x + extents->width/2.,
354
1554
						    extents->y + extents->height/2.,
355
						    &pixman_transform, ix, iy);
356
1554
    if (status != CAIRO_INT_STATUS_NOTHING_TO_DO) {
357
1680
	if (unlikely (status != CAIRO_INT_STATUS_SUCCESS) ||
358
840
	    ! pixman_image_set_transform (pixman_image, &pixman_transform))
359
	{
360
	    pixman_image_unref (pixman_image);
361
	    return NULL;
362
	}
363
    }
364

            
365
    {
366
	pixman_repeat_t pixman_repeat;
367

            
368
1554
	switch (pattern->base.extend) {
369
138
	default:
370
	case CAIRO_EXTEND_NONE:
371
138
	    pixman_repeat = PIXMAN_REPEAT_NONE;
372
138
	    break;
373
159
	case CAIRO_EXTEND_REPEAT:
374
159
	    pixman_repeat = PIXMAN_REPEAT_NORMAL;
375
159
	    break;
376
162
	case CAIRO_EXTEND_REFLECT:
377
162
	    pixman_repeat = PIXMAN_REPEAT_REFLECT;
378
162
	    break;
379
1095
	case CAIRO_EXTEND_PAD:
380
1095
	    pixman_repeat = PIXMAN_REPEAT_PAD;
381
1095
	    break;
382
	}
383

            
384
1554
	pixman_image_set_repeat (pixman_image, pixman_repeat);
385
    }
386

            
387
1554
    return pixman_image;
388
}
389

            
390
static pixman_image_t *
391
16899
_pixman_image_for_mesh (const cairo_mesh_pattern_t *pattern,
392
			const cairo_rectangle_int_t *extents,
393
			int *tx, int *ty)
394
{
395
    pixman_image_t *image;
396
    int width, height;
397

            
398
    TRACE ((stderr, "%s\n", __FUNCTION__));
399

            
400
16899
    *tx = -extents->x;
401
16899
    *ty = -extents->y;
402
16899
    width = extents->width;
403
16899
    height = extents->height;
404

            
405
16899
    image = pixman_image_create_bits (PIXMAN_a8r8g8b8, width, height, NULL, 0);
406
16899
    if (unlikely (image == NULL))
407
	return NULL;
408

            
409
16899
    _cairo_mesh_pattern_rasterize (pattern,
410
16899
				   pixman_image_get_data (image),
411
				   width, height,
412
				   pixman_image_get_stride (image),
413
16899
				   *tx, *ty);
414
16899
    return image;
415
}
416

            
417
struct acquire_source_cleanup {
418
    cairo_surface_t *surface;
419
    cairo_image_surface_t *image;
420
    void *image_extra;
421
};
422

            
423
static void
424
138
_acquire_source_cleanup (pixman_image_t *pixman_image,
425
			 void *closure)
426
{
427
138
    struct acquire_source_cleanup *data = closure;
428

            
429
138
    _cairo_surface_release_source_image (data->surface,
430
					 data->image,
431
					 data->image_extra);
432
138
    free (data);
433
138
}
434

            
435
static void
436
41574
_defer_free_cleanup (pixman_image_t *pixman_image,
437
		     void *closure)
438
{
439
41574
    cairo_surface_destroy (closure);
440
41574
}
441

            
442
static uint16_t
443
expand_channel (uint16_t v, uint32_t bits)
444
{
445
    int offset = 16 - bits;
446
    while (offset > 0) {
447
	v |= v >> bits;
448
	offset -= bits;
449
	bits += bits;
450
    }
451
    return v;
452
}
453

            
454
static pixman_image_t *
455
3264
_pixel_to_solid (cairo_image_surface_t *image, int x, int y)
456
{
457
    uint32_t pixel;
458
    float *rgba;
459
    pixman_color_t color;
460

            
461
    TRACE ((stderr, "%s\n", __FUNCTION__));
462

            
463
3264
    switch (image->format) {
464
    default:
465
    case CAIRO_FORMAT_INVALID:
466
	ASSERT_NOT_REACHED;
467
	return NULL;
468

            
469
    case CAIRO_FORMAT_A1:
470
	pixel = *(uint8_t *) (image->data + y * image->stride + x/8);
471
	return pixel & (1 << (x&7)) ? _pixman_black_image () : _pixman_transparent_image ();
472

            
473
300
    case CAIRO_FORMAT_A8:
474
300
	color.alpha = *(uint8_t *) (image->data + y * image->stride + x);
475
300
	color.alpha |= color.alpha << 8;
476
300
	if (color.alpha == 0)
477
	    return _pixman_transparent_image ();
478
300
	if (color.alpha == 0xffff)
479
300
	    return _pixman_black_image ();
480

            
481
	color.red = color.green = color.blue = 0;
482
	return pixman_image_create_solid_fill (&color);
483

            
484
    case CAIRO_FORMAT_RGB16_565:
485
	pixel = *(uint16_t *) (image->data + y * image->stride + 2 * x);
486
	if (pixel == 0)
487
	    return _pixman_black_image ();
488
	if (pixel == 0xffff)
489
	    return _pixman_white_image ();
490

            
491
	color.alpha = 0xffff;
492
	color.red = expand_channel ((pixel >> 11 & 0x1f) << 11, 5);
493
	color.green = expand_channel ((pixel >> 5 & 0x3f) << 10, 6);
494
	color.blue = expand_channel ((pixel & 0x1f) << 11, 5);
495
	return pixman_image_create_solid_fill (&color);
496

            
497
    case CAIRO_FORMAT_RGB30:
498
	pixel = *(uint32_t *) (image->data + y * image->stride + 4 * x);
499
	pixel &= 0x3fffffff; /* ignore alpha bits */
500
	if (pixel == 0)
501
	    return _pixman_black_image ();
502
	if (pixel == 0x3fffffff)
503
	    return _pixman_white_image ();
504

            
505
	/* convert 10bpc to 16bpc */
506
	color.alpha = 0xffff;
507
	color.red = expand_channel((pixel >> 20) & 0x3fff, 10);
508
	color.green = expand_channel((pixel >> 10) & 0x3fff, 10);
509
	color.blue = expand_channel(pixel & 0x3fff, 10);
510
	return pixman_image_create_solid_fill (&color);
511

            
512
2964
    case CAIRO_FORMAT_ARGB32:
513
    case CAIRO_FORMAT_RGB24:
514
2964
	pixel = *(uint32_t *) (image->data + y * image->stride + 4 * x);
515
2964
	color.alpha = image->format == CAIRO_FORMAT_ARGB32 ? (pixel >> 24) | (pixel >> 16 & 0xff00) : 0xffff;
516
2964
	if (color.alpha == 0)
517
60
	    return _pixman_transparent_image ();
518
2904
	if (pixel == 0xffffffff)
519
594
	    return _pixman_white_image ();
520
2310
	if (color.alpha == 0xffff && (pixel & 0xffffff) == 0)
521
363
	    return _pixman_black_image ();
522

            
523
1947
	color.red = (pixel >> 16 & 0xff) | (pixel >> 8 & 0xff00);
524
1947
	color.green = (pixel >> 8 & 0xff) | (pixel & 0xff00);
525
1947
	color.blue = (pixel & 0xff) | (pixel << 8 & 0xff00);
526
1947
	return pixman_image_create_solid_fill (&color);
527

            
528
    case CAIRO_FORMAT_RGB96F:
529
    case CAIRO_FORMAT_RGBA128F:
530
	if (image->format == CAIRO_FORMAT_RGBA128F)
531
	{
532
	    rgba = (float *)&image->data[y * image->stride + 16 * x];
533
	    color.alpha = 65535.f * rgba[3];
534

            
535
	    if (color.alpha == 0)
536
		return _pixman_transparent_image ();
537
	}
538
	else
539
	{
540
	    rgba = (float *)&image->data[y * image->stride + 12 * x];
541
	    color.alpha = 0xffff;
542
	}
543

            
544
	if (color.alpha == 0xffff && rgba[0] == 0.f && rgba[1] == 0.f && rgba[2] == 0.f)
545
	    return _pixman_black_image ();
546
	if (color.alpha == 0xffff && rgba[0] == 1.f && rgba[1] == 1.f && rgba[2] == 1.f)
547
	    return _pixman_white_image ();
548

            
549
	color.red = rgba[0] * 65535.f;
550
	color.green = rgba[1] * 65535.f;
551
	color.blue = rgba[2] * 65535.f;
552
	return pixman_image_create_solid_fill (&color);
553
    }
554
}
555

            
556
/* ========================================================================== */
557

            
558
/* Index into filter table */
559
typedef enum
560
{
561
    KERNEL_IMPULSE,
562
    KERNEL_BOX,
563
    KERNEL_LINEAR,
564
    KERNEL_MITCHELL,
565
    KERNEL_NOTCH,
566
    KERNEL_CATMULL_ROM,
567
    KERNEL_LANCZOS3,
568
    KERNEL_LANCZOS3_STRETCHED,
569
    KERNEL_TENT
570
} kernel_t;
571

            
572
/* Produce contribution of a filter of size r for pixel centered on x.
573
   For a typical low-pass function this evaluates the function at x/r.
574
   If the frequency is higher than 1/2, such as when r is less than 1,
575
   this may need to integrate several samples, see cubic for examples.
576
*/
577
typedef double (* kernel_func_t) (double x, double r);
578

            
579
/* Return maximum number of pixels that will be non-zero. Except for
580
   impluse this is the maximum of 2 and the width of the non-zero part
581
   of the filter rounded up to the next integer.
582
*/
583
typedef int (* kernel_width_func_t) (double r);
584

            
585
/* Table of filters */
586
typedef struct
587
{
588
    kernel_t		kernel;
589
    kernel_func_t	func;
590
    kernel_width_func_t	width;
591
} filter_info_t;
592

            
593
/* PIXMAN_KERNEL_IMPULSE: Returns pixel nearest the center.  This
594
   matches PIXMAN_FILTER_NEAREST. This is useful if you wish to
595
   combine the result of nearest in one direction with another filter
596
   in the other.
597
*/
598

            
599
static double
600
impulse_kernel (double x, double r)
601
{
602
    return 1;
603
}
604

            
605
static int
606
impulse_width (double r)
607
{
608
    return 1;
609
}
610

            
611
/* PIXMAN_KERNEL_BOX: Intersection of a box of width r with square
612
   pixels. This is the smallest possible filter such that the output
613
   image contains an equal contribution from all the input
614
   pixels. Lots of software uses this. The function is a trapazoid of
615
   width r+1, not a box.
616

            
617
   When r == 1.0, PIXMAN_KERNEL_BOX, PIXMAN_KERNEL_LINEAR, and
618
   PIXMAN_KERNEL_TENT all produce the same filter, allowing
619
   them to be exchanged at this point.
620
*/
621

            
622
static double
623
30096
box_kernel (double x, double r)
624
{
625
30096
    return MAX (0.0, MIN (MIN (r, 1.0),
626
			  MIN ((r + 1) / 2 - x, (r + 1) / 2 + x)));
627
}
628

            
629
static int
630
90
box_width (double r)
631
{
632
90
    return r < 1.0 ? 2 : ceil(r + 1);
633
}
634

            
635
/* PIXMAN_KERNEL_LINEAR: Weighted sum of the two pixels nearest the
636
   center, or a triangle of width 2. This matches
637
   PIXMAN_FILTER_BILINEAR. This is useful if you wish to combine the
638
   result of bilinear in one direction with another filter in the
639
   other.  This is not a good filter if r > 1. You may actually want
640
   PIXMAN_FILTER_TENT.
641

            
642
   When r == 1.0, PIXMAN_KERNEL_BOX, PIXMAN_KERNEL_LINEAR, and
643
   PIXMAN_KERNEL_TENT all produce the same filter, allowing
644
   them to be exchanged at this point.
645
*/
646

            
647
static double
648
linear_kernel (double x, double r)
649
{
650
    return MAX (1.0 - fabs(x), 0.0);
651
}
652

            
653
static int
654
linear_width (double r)
655
{
656
    return 2;
657
}
658

            
659
/* Cubic functions described in the Mitchell-Netravali paper.
660
   http://mentallandscape.com/Papers_siggraph88.pdf. This describes
661
   all possible cubic functions that can be used for sampling.
662
*/
663

            
664
static double
665
9984
general_cubic (double x, double r, double B, double C)
666
{
667
    double ax;
668
9984
    if (r < 1.0)
669
	return
670
	    general_cubic(x * 2 - .5, r * 2, B, C) +
671
	    general_cubic(x * 2 + .5, r * 2, B, C);
672

            
673
9984
    ax = fabs (x / r);
674

            
675
9984
    if (ax < 1)
676
    {
677
4620
	return (((12 - 9 * B - 6 * C) * ax +
678
4620
		 (-18 + 12 * B + 6 * C)) * ax * ax +
679
4620
		(6 - 2 * B)) / 6;
680
    }
681
5364
    else if (ax < 2)
682
    {
683
4632
	return ((((-B - 6 * C) * ax +
684
4632
		 (6 * B + 30 * C)) * ax +
685
4632
		(-12 * B - 48 * C)) * ax +
686
4632
		(8 * B + 24 * C)) / 6;
687
    }
688
    else
689
    {
690
732
	return 0.0;
691
    }
692
}
693

            
694
static int
695
12
cubic_width (double r)
696
{
697
12
    return MAX (2, ceil (r * 4));
698
}
699

            
700
/* PIXMAN_KERNEL_CATMULL_ROM: Catmull-Rom interpolation. Often called
701
   "cubic interpolation", "b-spline", or just "cubic" by other
702
   software. This filter has negative values so it can produce ringing
703
   and output pixels outside the range of input pixels. This is very
704
   close to lanczos2 so there is no reason to supply that as well.
705
*/
706

            
707
static double
708
9984
cubic_kernel (double x, double r)
709
{
710
9984
    return general_cubic (x, r, 0.0, 0.5);
711
}
712

            
713
/* PIXMAN_KERNEL_MITCHELL: Cubic recommended by the Mitchell-Netravali
714
   paper.  This has negative values and because the values at +/-1 are
715
   not zero it does not interpolate the pixels, meaning it will change
716
   an image even if there is no translation.
717
*/
718

            
719
static double
720
mitchell_kernel (double x, double r)
721
{
722
    return general_cubic (x, r, 1/3.0, 1/3.0);
723
}
724

            
725
/* PIXMAN_KERNEL_NOTCH: Cubic recommended by the Mitchell-Netravali
726
   paper to remove postaliasing artifacts. This does not remove
727
   aliasing already present in the source image, though it may appear
728
   to due to it's excessive blurriness. In any case this is more
729
   useful than gaussian for image reconstruction.
730
*/
731

            
732
static double
733
notch_kernel (double x, double r)
734
{
735
    return general_cubic (x, r, 1.5, -0.25);
736
}
737

            
738
/* PIXMAN_KERNEL_LANCZOS3: lanczos windowed sinc function from -3 to
739
   +3. Very popular with high-end software though I think any
740
   advantage over cubics is hidden by quantization and programming
741
   mistakes. You will see LANCZOS5 or even 7 sometimes.
742
*/
743

            
744
static double
745
sinc (double x)
746
{
747
    return x ? sin (M_PI * x) / (M_PI * x) : 1.0;
748
}
749

            
750
static double
751
lanczos (double x, double n)
752
{
753
    return fabs (x) < n ? sinc (x) * sinc (x * (1.0 / n)) : 0.0;
754
}
755

            
756
static double
757
lanczos3_kernel (double x, double r)
758
{
759
    if (r < 1.0)
760
	return
761
	    lanczos3_kernel (x * 2 - .5, r * 2) +
762
	    lanczos3_kernel (x * 2 + .5, r * 2);
763
    else
764
	return lanczos (x / r, 3.0);
765
}
766

            
767
static int
768
lanczos3_width (double r)
769
{
770
    return MAX (2, ceil (r * 6));
771
}
772

            
773
/* PIXMAN_KERNEL_LANCZOS3_STRETCHED - The LANCZOS3 kernel widened by
774
   4/3.  Recommended by Jim Blinn
775
   http://graphics.cs.cmu.edu/nsp/course/15-462/Fall07/462/papers/jaggy.pdf
776
*/
777

            
778
static double
779
nice_kernel (double x, double r)
780
{
781
    return lanczos3_kernel (x, r * (4.0/3));
782
}
783

            
784
static int
785
nice_width (double r)
786
{
787
    return MAX (2.0, ceil (r * 8));
788
}
789

            
790
/* PIXMAN_KERNEL_TENT: Triangle of width 2r. Lots of software uses
791
   this as a "better" filter, twice the size of a box but smaller than
792
   a cubic.
793

            
794
   When r == 1.0, PIXMAN_KERNEL_BOX, PIXMAN_KERNEL_LINEAR, and
795
   PIXMAN_KERNEL_TENT all produce the same filter, allowing
796
   them to be exchanged at this point.
797
*/
798

            
799
static double
800
tent_kernel (double x, double r)
801
{
802
    if (r < 1.0)
803
	return box_kernel(x, r);
804
    else
805
	return MAX (1.0 - fabs(x / r), 0.0);
806
}
807

            
808
static int
809
tent_width (double r)
810
{
811
    return r < 1.0 ? 2 : ceil(2 * r);
812
}
813

            
814

            
815
static const filter_info_t filters[] =
816
{
817
    { KERNEL_IMPULSE,		impulse_kernel,   impulse_width },
818
    { KERNEL_BOX,		box_kernel,       box_width },
819
    { KERNEL_LINEAR,		linear_kernel,    linear_width },
820
    { KERNEL_MITCHELL,		mitchell_kernel,  cubic_width },
821
    { KERNEL_NOTCH,		notch_kernel,     cubic_width },
822
    { KERNEL_CATMULL_ROM,	cubic_kernel,     cubic_width },
823
    { KERNEL_LANCZOS3,		lanczos3_kernel,  lanczos3_width },
824
    { KERNEL_LANCZOS3_STRETCHED,nice_kernel,      nice_width },
825
    { KERNEL_TENT,		tent_kernel,	  tent_width }
826
};
827

            
828
/* Fills in one dimension of the filter array */
829
102
static void get_filter(kernel_t filter, double r,
830
		       int width, int subsample,
831
		       pixman_fixed_t* out)
832
{
833
    int i;
834
102
    pixman_fixed_t *p = out;
835
102
    int n_phases = 1 << subsample;
836
102
    double step = 1.0 / n_phases;
837
102
    kernel_func_t func = filters[filter].func;
838

            
839
    /* special-case the impulse filter: */
840
102
    if (width <= 1)
841
    {
842
	for (i = 0; i < n_phases; ++i)
843
	    *p++ = pixman_fixed_1;
844
	return;
845
    }
846

            
847
9846
    for (i = 0; i < n_phases; ++i)
848
    {
849
9744
	double frac = (i + .5) * step;
850
	/* Center of left-most pixel: */
851
9744
	double x1 = ceil (frac - width / 2.0 - 0.5) - frac + 0.5;
852
9744
	double total = 0;
853
9744
	pixman_fixed_t new_total = 0;
854
	int j;
855

            
856
49824
	for (j = 0; j < width; ++j)
857
	{
858
40080
	    double v = func(x1 + j, r);
859
40080
	    total += v;
860
40080
	    p[j] = pixman_double_to_fixed (v);
861
	}
862

            
863
	/* Normalize */
864
9744
        total = 1 / total;
865
49824
	for (j = 0; j < width; ++j)
866
40080
	    new_total += (p[j] *= total);
867

            
868
	/* Put any error on center pixel */
869
9744
	p[width / 2] += (pixman_fixed_1 - new_total);
870

            
871
9744
	p += width;
872
    }
873
}
874

            
875

            
876
/* Create the parameter list for a SEPARABLE_CONVOLUTION filter
877
 * with the given kernels and scale parameters. 
878
 */
879
static pixman_fixed_t *
880
51
create_separable_convolution (int *n_values,
881
			      kernel_t xfilter,
882
			      double sx,
883
			      kernel_t yfilter,
884
			      double sy)
885
{
886
    int xwidth, xsubsample, ywidth, ysubsample, size_x, size_y;
887
    pixman_fixed_t *params;
888

            
889
51
    xwidth = filters[xfilter].width(sx);
890
51
    xsubsample = 0;
891
51
    if (xwidth > 1)
892
357
	while (sx * (1 << xsubsample) <= 128.0) xsubsample++;
893
51
    size_x = (1 << xsubsample) * xwidth;
894

            
895
51
    ywidth = filters[yfilter].width(sy);
896
51
    ysubsample = 0;
897
51
    if (ywidth > 1)
898
384
	while (sy * (1 << ysubsample) <= 128.0) ysubsample++;
899
51
    size_y = (1 << ysubsample) * ywidth;
900

            
901
51
    *n_values = 4 + size_x + size_y;
902
51
    params = _cairo_malloc (*n_values * sizeof (pixman_fixed_t));
903
51
    if (!params) return 0;
904

            
905
51
    params[0] = pixman_int_to_fixed (xwidth);
906
51
    params[1] = pixman_int_to_fixed (ywidth);
907
51
    params[2] = pixman_int_to_fixed (xsubsample);
908
51
    params[3] = pixman_int_to_fixed (ysubsample);
909

            
910
51
    get_filter(xfilter, sx, xwidth, xsubsample, params + 4);
911
51
    get_filter(yfilter, sy, ywidth, ysubsample, params + 4 + size_x);
912

            
913
51
    return params;
914
}
915

            
916
/* ========================================================================== */
917

            
918
static cairo_bool_t
919
68805
_pixman_image_set_properties (pixman_image_t *pixman_image,
920
			      const cairo_pattern_t *pattern,
921
			      const cairo_rectangle_int_t *extents,
922
			      int *ix,int *iy)
923
{
924
    pixman_transform_t pixman_transform;
925
    cairo_int_status_t status;
926

            
927
68805
    status = _cairo_matrix_to_pixman_matrix_offset (&pattern->matrix,
928
68805
						    pattern->filter,
929
68805
						    extents->x + extents->width/2.,
930
68805
						    extents->y + extents->height/2.,
931
						    &pixman_transform, ix, iy);
932
68805
    if (status == CAIRO_INT_STATUS_NOTHING_TO_DO)
933
    {
934
	/* If the transform is an identity, we don't need to set it
935
	 * and we can use any filtering, so choose the fastest one. */
936
28137
	pixman_image_set_filter (pixman_image, PIXMAN_FILTER_NEAREST, NULL, 0);
937
    }
938
40668
    else if (unlikely (status != CAIRO_INT_STATUS_SUCCESS ||
939
		       ! pixman_image_set_transform (pixman_image,
940
						     &pixman_transform)))
941
    {
942
	return FALSE;
943
    }
944
    else
945
    {
946
	pixman_filter_t pixman_filter;
947
	kernel_t kernel;
948
	double dx, dy;
949

            
950
	/* Compute scale factors from the pattern matrix. These scale
951
	 * factors are from user to pattern space, and as such they
952
	 * are greater than 1.0 for downscaling and less than 1.0 for
953
	 * upscaling. The factors are the size of an axis-aligned
954
	 * rectangle with the same area as the parallelgram a 1x1
955
	 * square transforms to.
956
	 */
957
40668
	dx = hypot (pattern->matrix.xx, pattern->matrix.xy);
958
40668
	dy = hypot (pattern->matrix.yx, pattern->matrix.yy);
959

            
960
	/* Clip at maximum pixman_fixed number. Besides making it
961
	 * passable to pixman, this avoids errors from inf and nan.
962
	 */
963
40668
	if (! (dx < 0x7FFF)) dx = 0x7FFF;
964
40668
	if (! (dy < 0x7FFF)) dy = 0x7FFF;
965

            
966
40668
	switch (pattern->filter) {
967
6
	case CAIRO_FILTER_FAST:
968
6
	    pixman_filter = PIXMAN_FILTER_FAST;
969
6
	    break;
970
45
	case CAIRO_FILTER_GOOD:
971
45
	    pixman_filter = PIXMAN_FILTER_SEPARABLE_CONVOLUTION;
972
45
	    kernel = KERNEL_BOX;
973
	    /* Clip the filter size to prevent extreme slowness. This
974
	       value could be raised if 2-pass filtering is done */
975
45
	    if (dx > 16.0) dx = 16.0;
976
45
	    if (dy > 16.0) dy = 16.0;
977
	    /* Match the bilinear filter for scales > .75: */
978
45
	    if (dx < 1.0/0.75) dx = 1.0;
979
45
	    if (dy < 1.0/0.75) dy = 1.0;
980
45
	    break;
981
6
	case CAIRO_FILTER_BEST:
982
6
	    pixman_filter = PIXMAN_FILTER_SEPARABLE_CONVOLUTION;
983
6
	    kernel = KERNEL_CATMULL_ROM; /* LANCZOS3 is better but not much */
984
	    /* Clip the filter size to prevent extreme slowness. This
985
	       value could be raised if 2-pass filtering is done */
986
6
	    if (dx > 16.0) { dx = 16.0; kernel = KERNEL_BOX; }
987
	    /* blur up to 2x scale, then blend to square pixels for larger: */
988
6
	    else if (dx < 1.0) {
989
		if (dx < 1.0/128) dx = 1.0/127;
990
		else if (dx < 0.5) dx = 1.0 / (1.0 / dx - 1.0);
991
		else dx = 1.0;
992
	    }
993
6
	    if (dy > 16.0) { dy = 16.0; kernel = KERNEL_BOX; }
994
6
	    else if (dy < 1.0) {
995
		if (dy < 1.0/128) dy = 1.0/127;
996
		else if (dy < 0.5) dy = 1.0 / (1.0 / dy - 1.0);
997
		else dy = 1.0;
998
	    }
999
6
	    break;
27876
	case CAIRO_FILTER_NEAREST:
27876
	    pixman_filter = PIXMAN_FILTER_NEAREST;
27876
	    break;
12735
	case CAIRO_FILTER_BILINEAR:
12735
	    pixman_filter = PIXMAN_FILTER_BILINEAR;
12735
	    break;
	case CAIRO_FILTER_GAUSSIAN:
	    /* XXX: The GAUSSIAN value has no implementation in cairo
	     * whatsoever, so it was really a mistake to have it in the
	     * API. We could fix this by officially deprecating it, or
	     * else inventing semantics and providing an actual
	     * implementation for it. */
	default:
	    pixman_filter = PIXMAN_FILTER_BEST;
	}
40668
	if (pixman_filter == PIXMAN_FILTER_SEPARABLE_CONVOLUTION) {
	    int n_params;
	    pixman_fixed_t *params;
51
	    params = create_separable_convolution
		(&n_params, kernel, dx, kernel, dy);
51
	    pixman_image_set_filter (pixman_image, pixman_filter,
				     params, n_params);
51
	    free (params);
	} else {
40617
	    pixman_image_set_filter (pixman_image, pixman_filter, NULL, 0);
	}
    }
    {
	pixman_repeat_t pixman_repeat;
68805
	switch (pattern->extend) {
7042
	default:
	case CAIRO_EXTEND_NONE:
7042
	    pixman_repeat = PIXMAN_REPEAT_NONE;
7042
	    break;
40808
	case CAIRO_EXTEND_REPEAT:
40808
	    pixman_repeat = PIXMAN_REPEAT_NORMAL;
40808
	    break;
10476
	case CAIRO_EXTEND_REFLECT:
10476
	    pixman_repeat = PIXMAN_REPEAT_REFLECT;
10476
	    break;
10479
	case CAIRO_EXTEND_PAD:
10479
	    pixman_repeat = PIXMAN_REPEAT_PAD;
10479
	    break;
	}
68805
	pixman_image_set_repeat (pixman_image, pixman_repeat);
    }
68805
    if (pattern->has_component_alpha)
	pixman_image_set_component_alpha (pixman_image, TRUE);
68805
    return TRUE;
}
struct proxy {
    cairo_surface_t base;
    cairo_surface_t *image;
};
static cairo_status_t
proxy_acquire_source_image (void			 *abstract_surface,
			    cairo_image_surface_t	**image_out,
			    void			**image_extra)
{
    struct proxy *proxy = abstract_surface;
    return _cairo_surface_acquire_source_image (proxy->image, image_out, image_extra);
}
static void
proxy_release_source_image (void			*abstract_surface,
			    cairo_image_surface_t	*image,
			    void			*image_extra)
{
    struct proxy *proxy = abstract_surface;
    _cairo_surface_release_source_image (proxy->image, image, image_extra);
}
static cairo_status_t
11358
proxy_finish (void *abstract_surface)
{
11358
    return CAIRO_STATUS_SUCCESS;
}
static const cairo_surface_backend_t proxy_backend  = {
    CAIRO_INTERNAL_SURFACE_TYPE_NULL,
    proxy_finish,
    NULL,
    NULL, /* create similar */
    NULL, /* create similar image */
    NULL, /* map to image */
    NULL, /* unmap image */
    _cairo_surface_default_source,
    proxy_acquire_source_image,
    proxy_release_source_image,
};
static cairo_surface_t *
11358
attach_proxy (cairo_surface_t *source,
	      cairo_surface_t *image)
{
    struct proxy *proxy;
11358
    proxy = _cairo_calloc (sizeof (*proxy));
11358
    if (unlikely (proxy == NULL))
	return _cairo_surface_create_in_error (CAIRO_STATUS_NO_MEMORY);
11358
    _cairo_surface_init (&proxy->base, &proxy_backend, NULL, image->content, FALSE);
11358
    proxy->image = image;
11358
    _cairo_surface_attach_snapshot (source, &proxy->base, NULL);
11358
    return &proxy->base;
}
static void
11358
detach_proxy (cairo_surface_t *source,
	      cairo_surface_t *proxy)
{
11358
    cairo_surface_finish (proxy);
11358
    cairo_surface_destroy (proxy);
11358
}
static cairo_surface_t *
get_proxy (cairo_surface_t *proxy)
{
    return ((struct proxy *)proxy)->image;
}
static pixman_image_t *
11358
_pixman_image_for_recording (cairo_image_surface_t *dst,
			     const cairo_surface_pattern_t *pattern,
			     cairo_bool_t is_mask,
			     const cairo_rectangle_int_t *extents,
			     const cairo_rectangle_int_t *sample,
			     int *ix, int *iy)
{
    cairo_surface_t *source, *clone, *proxy;
    cairo_rectangle_int_t limit;
    cairo_rectangle_int_t src_limit;
    pixman_image_t *pixman_image;
    cairo_status_t status;
    cairo_extend_t extend;
    cairo_matrix_t *m, matrix;
11358
    double sx = 1.0, sy = 1.0;
11358
    int tx = 0, ty = 0;
    TRACE ((stderr, "%s\n", __FUNCTION__));
11358
    *ix = *iy = 0;
11358
    source = _cairo_pattern_get_source (pattern, &limit);
11358
    src_limit = limit;
11358
    extend = pattern->base.extend;
11358
    if (_cairo_rectangle_contains_rectangle (&limit, sample))
294
	extend = CAIRO_EXTEND_NONE;
11358
    if (extend == CAIRO_EXTEND_NONE) {
306
	if (! _cairo_rectangle_intersect (&limit, sample))
	    return _pixman_transparent_image ();
    }
11358
    if (! _cairo_matrix_is_identity (&pattern->base.matrix)) {
	double x1, y1, x2, y2;
11355
	matrix = pattern->base.matrix;
11355
	status = cairo_matrix_invert (&matrix);
11355
	assert (status == CAIRO_STATUS_SUCCESS);
11355
	x1 = limit.x;
11355
	y1 = limit.y;
11355
	x2 = limit.x + limit.width;
11355
	y2 = limit.y + limit.height;
11355
	_cairo_matrix_transform_bounding_box (&matrix,
					      &x1, &y1, &x2, &y2, NULL);
11355
	limit.x = floor (x1);
11355
	limit.y = floor (y1);
11355
	limit.width  = ceil (x2) - limit.x;
11355
	limit.height = ceil (y2) - limit.y;
11355
	sx = (double)src_limit.width / limit.width;
11355
	sy = (double)src_limit.height / limit.height;
    }
11358
    tx = limit.x;
11358
    ty = limit.y;
    /* XXX transformations! */
11358
    proxy = _cairo_surface_has_snapshot (source, &proxy_backend);
11358
    if (proxy != NULL) {
	clone = cairo_surface_reference (get_proxy (proxy));
	goto done;
    }
11358
    if (is_mask) {
	    clone = cairo_image_surface_create (CAIRO_FORMAT_A8,
						limit.width, limit.height);
    } else {
11358
	if (dst->base.content == source->content)
7591
	    clone = cairo_image_surface_create (dst->format,
						limit.width, limit.height);
	else
3767
	    clone = _cairo_image_surface_create_with_content (source->content,
							      limit.width,
							      limit.height);
11358
	if (dst->base.foreground_source)
90
	    clone->foreground_source = cairo_pattern_reference (dst->base.foreground_source);
    }
11358
    m = NULL;
11358
    if (extend == CAIRO_EXTEND_NONE) {
306
	matrix = pattern->base.matrix;
306
	if (tx | ty)
201
	    cairo_matrix_translate (&matrix, tx, ty);
306
	m = &matrix;
    } else {
11052
	cairo_matrix_init_scale (&matrix, sx, sy);
11052
	cairo_matrix_translate (&matrix, src_limit.x/sx, src_limit.y/sy);
11052
	m = &matrix;
    }
    /* Handle recursion by returning future reads from the current image */
11358
    proxy = attach_proxy (source, clone);
11358
    status = _cairo_recording_surface_replay_with_clip (source, m, clone, NULL);
11358
    if (clone->foreground_used)
9
	dst->base.foreground_used = clone->foreground_used;
11358
    detach_proxy (source, proxy);
11358
    if (unlikely (status)) {
	cairo_surface_destroy (clone);
	return NULL;
    }
11358
done:
11358
    pixman_image = pixman_image_ref (((cairo_image_surface_t *)clone)->pixman_image);
11358
    cairo_surface_destroy (clone);
11358
    if (extend == CAIRO_EXTEND_NONE) {
306
	*ix = -limit.x;
306
	*iy = -limit.y;
    } else {
	cairo_pattern_union_t tmp_pattern;
11052
	_cairo_pattern_init_static_copy (&tmp_pattern.base, &pattern->base);
11052
	matrix = pattern->base.matrix;
11052
	status = cairo_matrix_invert(&matrix);
11052
	assert (status == CAIRO_STATUS_SUCCESS);
11052
	cairo_matrix_translate (&matrix, src_limit.x, src_limit.y);
11052
	cairo_matrix_scale (&matrix, sx, sy);
11052
	status = cairo_matrix_invert(&matrix);
11052
	assert (status == CAIRO_STATUS_SUCCESS);
11052
	cairo_pattern_set_matrix (&tmp_pattern.base, &matrix);
11052
	if (! _pixman_image_set_properties (pixman_image,
					    &tmp_pattern.base, extents,
					    ix, iy)) {
	    pixman_image_unref (pixman_image);
	    pixman_image= NULL;
	}
    }
11358
    return pixman_image;
}
static pixman_image_t *
72327
_pixman_image_for_surface (cairo_image_surface_t *dst,
			   const cairo_surface_pattern_t *pattern,
			   cairo_bool_t is_mask,
			   const cairo_rectangle_int_t *extents,
			   const cairo_rectangle_int_t *sample,
			   int *ix, int *iy)
{
72327
    cairo_extend_t extend = pattern->base.extend;
    pixman_image_t *pixman_image;
    TRACE ((stderr, "%s\n", __FUNCTION__));
72327
    *ix = *iy = 0;
72327
    pixman_image = NULL;
72327
    if (pattern->surface->type == CAIRO_SURFACE_TYPE_RECORDING)
11358
	return _pixman_image_for_recording(dst, pattern,
					   is_mask, extents, sample,
					   ix, iy);
60969
    if (pattern->surface->type == CAIRO_SURFACE_TYPE_IMAGE &&
1788
	(! is_mask || ! pattern->base.has_component_alpha ||
	 (pattern->surface->content & CAIRO_CONTENT_COLOR) == 0))
    {
60954
	cairo_surface_t *defer_free = NULL;
60954
	cairo_image_surface_t *source = (cairo_image_surface_t *) pattern->surface;
	cairo_surface_type_t type;
60954
	if (_cairo_surface_is_snapshot (&source->base)) {
44115
	    defer_free = _cairo_surface_snapshot_get_target (&source->base);
44115
	    source = (cairo_image_surface_t *) defer_free;
	}
60954
	type = source->base.backend->type;
60954
	if (type == CAIRO_SURFACE_TYPE_IMAGE) {
60803
	    if (extend != CAIRO_EXTEND_NONE &&
50747
		sample->x >= 0 &&
45353
		sample->y >= 0 &&
42596
		sample->x + sample->width  <= source->width &&
19124
		sample->y + sample->height <= source->height)
	    {
14825
		extend = CAIRO_EXTEND_NONE;
	    }
60803
	    if (sample->width == 1 && sample->height == 1) {
3744
		if (sample->x < 0 ||
3744
		    sample->y < 0 ||
3744
		    sample->x >= source->width ||
3408
		    sample->y >= source->height)
		{
480
		    if (extend == CAIRO_EXTEND_NONE) {
			cairo_surface_destroy (defer_free);
			return _pixman_transparent_image ();
		    }
		}
		else
		{
3264
		    pixman_image = _pixel_to_solid (source,
3264
						    sample->x, sample->y);
3264
                    if (pixman_image) {
3264
			cairo_surface_destroy (defer_free);
3264
                        return pixman_image;
		    }
		}
	    }
#if PIXMAN_HAS_ATOMIC_OPS
	    /* avoid allocating a 'pattern' image if we can reuse the original */
	    if (extend == CAIRO_EXTEND_NONE &&
		_cairo_matrix_is_pixman_translation (&pattern->base.matrix,
						     pattern->base.filter,
						     ix, iy))
	    {
		cairo_surface_destroy (defer_free);
		return pixman_image_ref (source->pixman_image);
	    }
#endif
57539
	    pixman_image = pixman_image_create_bits (source->pixman_format,
						     source->width,
						     source->height,
57539
						     (uint32_t *) source->data,
57539
						     source->stride);
57539
	    if (unlikely (pixman_image == NULL)) {
		cairo_surface_destroy (defer_free);
		return NULL;
	    }
57539
	    if (defer_free) {
41574
		pixman_image_set_destroy_function (pixman_image,
						   _defer_free_cleanup,
						   defer_free);
	    }
151
	} else if (type == CAIRO_SURFACE_TYPE_SUBSURFACE) {
	    cairo_surface_subsurface_t *sub;
151
	    cairo_bool_t is_contained = FALSE;
151
	    sub = (cairo_surface_subsurface_t *) source;
151
	    source = (cairo_image_surface_t *) sub->target;
151
	    if (sample->x >= 0 &&
28
		sample->y >= 0 &&
28
		sample->x + sample->width  <= sub->extents.width &&
28
		sample->y + sample->height <= sub->extents.height)
	    {
28
		is_contained = TRUE;
	    }
151
	    if (sample->width == 1 && sample->height == 1) {
		if (is_contained) {
		    pixman_image = _pixel_to_solid (source,
                                                    sub->extents.x + sample->x,
                                                    sub->extents.y + sample->y);
                    if (pixman_image)
                        return pixman_image;
		} else {
		    if (extend == CAIRO_EXTEND_NONE)
			return _pixman_transparent_image ();
		}
	    }
#if PIXMAN_HAS_ATOMIC_OPS
	    *ix = sub->extents.x;
	    *iy = sub->extents.y;
	    if (is_contained &&
		_cairo_matrix_is_pixman_translation (&pattern->base.matrix,
						     pattern->base.filter,
						     ix, iy))
	    {
		return pixman_image_ref (source->pixman_image);
	    }
#endif
	    /* Avoid sub-byte offsets, force a copy in that case. */
151
	    if (PIXMAN_FORMAT_BPP (source->pixman_format) >= 8) {
151
		if (is_contained) {
28
		    void *data = source->data
28
			+ sub->extents.x * PIXMAN_FORMAT_BPP(source->pixman_format)/8
28
			+ sub->extents.y * source->stride;
28
		    pixman_image = pixman_image_create_bits (source->pixman_format,
							     sub->extents.width,
							     sub->extents.height,
							     data,
28
							     source->stride);
28
		    if (unlikely (pixman_image == NULL))
			return NULL;
		} else {
		    /* XXX for a simple translation and EXTEND_NONE we can
		     * fix up the pattern matrix instead.
		     */
		}
	    }
	}
    }
57705
    if (pixman_image == NULL) {
	struct acquire_source_cleanup *cleanup;
	cairo_image_surface_t *image;
	void *extra;
	cairo_status_t status;
138
	status = _cairo_surface_acquire_source_image (pattern->surface, &image, &extra);
138
	if (unlikely (status))
	    return NULL;
138
	pixman_image = pixman_image_create_bits (image->pixman_format,
138
						 image->width,
138
						 image->height,
138
						 (uint32_t *) image->data,
138
						 image->stride);
138
	if (unlikely (pixman_image == NULL)) {
	    _cairo_surface_release_source_image (pattern->surface, image, extra);
	    return NULL;
	}
138
	cleanup = _cairo_malloc (sizeof (*cleanup));
138
	if (unlikely (cleanup == NULL)) {
	    _cairo_surface_release_source_image (pattern->surface, image, extra);
	    pixman_image_unref (pixman_image);
	    return NULL;
	}
138
	cleanup->surface = pattern->surface;
138
	cleanup->image = image;
138
	cleanup->image_extra = extra;
138
	pixman_image_set_destroy_function (pixman_image,
					   _acquire_source_cleanup, cleanup);
    }
57705
    if (! _pixman_image_set_properties (pixman_image,
					&pattern->base, extents,
					ix, iy)) {
	pixman_image_unref (pixman_image);
	pixman_image= NULL;
    }
57705
    return pixman_image;
}
struct raster_source_cleanup {
    const cairo_pattern_t *pattern;
    cairo_surface_t *surface;
    cairo_image_surface_t *image;
    void *image_extra;
};
static void
48
_raster_source_cleanup (pixman_image_t *pixman_image,
			void *closure)
{
48
    struct raster_source_cleanup *data = closure;
48
    _cairo_surface_release_source_image (data->surface,
					 data->image,
					 data->image_extra);
48
    _cairo_raster_source_pattern_release (data->pattern,
					  data->surface);
48
    free (data);
48
}
static pixman_image_t *
48
_pixman_image_for_raster (cairo_image_surface_t *dst,
			  const cairo_raster_source_pattern_t *pattern,
			  cairo_bool_t is_mask,
			  const cairo_rectangle_int_t *extents,
			  const cairo_rectangle_int_t *sample,
			  int *ix, int *iy)
{
    pixman_image_t *pixman_image;
    struct raster_source_cleanup *cleanup;
    cairo_image_surface_t *image;
    void *extra;
    cairo_status_t status;
    cairo_surface_t *surface;
    TRACE ((stderr, "%s\n", __FUNCTION__));
48
    *ix = *iy = 0;
48
    surface = _cairo_raster_source_pattern_acquire (&pattern->base,
						    &dst->base, NULL);
48
    if (unlikely (surface == NULL || surface->status))
	return NULL;
48
    status = _cairo_surface_acquire_source_image (surface, &image, &extra);
48
    if (unlikely (status)) {
	_cairo_raster_source_pattern_release (&pattern->base, surface);
	return NULL;
    }
48
    assert (image->width == pattern->extents.width);
48
    assert (image->height == pattern->extents.height);
48
    pixman_image = pixman_image_create_bits (image->pixman_format,
48
					     image->width,
48
					     image->height,
48
					     (uint32_t *) image->data,
48
					     image->stride);
48
    if (unlikely (pixman_image == NULL)) {
	_cairo_surface_release_source_image (surface, image, extra);
	_cairo_raster_source_pattern_release (&pattern->base, surface);
	return NULL;
    }
48
    cleanup = _cairo_calloc (sizeof (*cleanup));
48
    if (unlikely (cleanup == NULL)) {
	pixman_image_unref (pixman_image);
	_cairo_surface_release_source_image (surface, image, extra);
	_cairo_raster_source_pattern_release (&pattern->base, surface);
	return NULL;
    }
48
    cleanup->pattern = &pattern->base;
48
    cleanup->surface = surface;
48
    cleanup->image = image;
48
    cleanup->image_extra = extra;
48
    pixman_image_set_destroy_function (pixman_image,
				       _raster_source_cleanup, cleanup);
48
    if (! _pixman_image_set_properties (pixman_image,
					&pattern->base, extents,
					ix, iy)) {
	pixman_image_unref (pixman_image);
	pixman_image= NULL;
    }
48
    return pixman_image;
}
pixman_image_t *
300712
_pixman_image_for_pattern (cairo_image_surface_t *dst,
			   const cairo_pattern_t *pattern,
			   cairo_bool_t is_mask,
			   const cairo_rectangle_int_t *extents,
			   const cairo_rectangle_int_t *sample,
			   int *tx, int *ty)
{
300712
    *tx = *ty = 0;
    TRACE ((stderr, "%s\n", __FUNCTION__));
300712
    if (pattern == NULL)
551
	return _pixman_white_image ();
300161
    switch (pattern->type) {
    default:
	ASSERT_NOT_REACHED;
    case CAIRO_PATTERN_TYPE_SOLID:
209333
	return _pixman_image_for_color (&((const cairo_solid_pattern_t *) pattern)->color);
1554
    case CAIRO_PATTERN_TYPE_RADIAL:
    case CAIRO_PATTERN_TYPE_LINEAR:
1554
	return _pixman_image_for_gradient ((const cairo_gradient_pattern_t *) pattern,
					   extents, tx, ty);
16899
    case CAIRO_PATTERN_TYPE_MESH:
16899
	return _pixman_image_for_mesh ((const cairo_mesh_pattern_t *) pattern,
					   extents, tx, ty);
72327
    case CAIRO_PATTERN_TYPE_SURFACE:
72327
	return _pixman_image_for_surface (dst,
					  (const cairo_surface_pattern_t *) pattern,
					  is_mask, extents, sample,
					  tx, ty);
48
    case CAIRO_PATTERN_TYPE_RASTER_SOURCE:
48
	return _pixman_image_for_raster (dst,
					 (const cairo_raster_source_pattern_t *) pattern,
					 is_mask, extents, sample,
					 tx, ty);
    }
}
static cairo_status_t
147776
_cairo_image_source_finish (void *abstract_surface)
{
147776
    cairo_image_source_t *source = abstract_surface;
147776
    pixman_image_unref (source->pixman_image);
147776
    return CAIRO_STATUS_SUCCESS;
}
const cairo_surface_backend_t _cairo_image_source_backend = {
    CAIRO_SURFACE_TYPE_IMAGE,
    _cairo_image_source_finish,
    NULL, /* read-only wrapper */
};
cairo_surface_t *
147776
_cairo_image_source_create_for_pattern (cairo_surface_t *dst,
					 const cairo_pattern_t *pattern,
					 cairo_bool_t is_mask,
					 const cairo_rectangle_int_t *extents,
					 const cairo_rectangle_int_t *sample,
					 int *src_x, int *src_y)
{
    cairo_image_source_t *source;
    TRACE ((stderr, "%s\n", __FUNCTION__));
147776
    source = _cairo_calloc (sizeof (cairo_image_source_t));
147776
    if (unlikely (source == NULL))
	return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
147776
    source->pixman_image =
147776
	_pixman_image_for_pattern ((cairo_image_surface_t *)dst,
				   pattern, is_mask,
				   extents, sample,
				   src_x, src_y);
147776
    if (unlikely (source->pixman_image == NULL)) {
	free (source);
	return _cairo_surface_create_in_error (CAIRO_STATUS_NO_MEMORY);
    }
147776
    _cairo_surface_init (&source->base,
			 &_cairo_image_source_backend,
			 NULL, /* device */
			 CAIRO_CONTENT_COLOR_ALPHA,
			 FALSE); /* is_vector */
147776
    source->is_opaque_solid =
147776
	pattern == NULL || _cairo_pattern_is_opaque_solid (pattern);
147776
    return &source->base;
}