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

            
66
static cairo_atomic_intptr_t __pixman_transparent_image; /*  (pixman_image_t *) */
67
static cairo_atomic_intptr_t __pixman_black_image;
68
static cairo_atomic_intptr_t __pixman_white_image;
69

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

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

            
77
    image = (pixman_image_t *) _cairo_atomic_ptr_get (&__pixman_transparent_image);
78
    if (unlikely (image == NULL)) {
79
	pixman_color_t color;
80

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

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

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

            
99
    return image;
100
}
101

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

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

            
109
    image = (pixman_image_t *) _cairo_atomic_ptr_get (&__pixman_black_image);
110
    if (unlikely (image == NULL)) {
111
	pixman_color_t color;
112

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

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

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

            
131
    return image;
132
}
133

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

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

            
141
    image = (pixman_image_t *) _cairo_atomic_ptr_get (&__pixman_white_image);
142
    if (unlikely (image == NULL)) {
143
	pixman_color_t color;
144

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

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

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

            
163
    return image;
164
}
165

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

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

            
181
#else  /* !PIXMAN_HAS_ATOMIC_OPS */
182

            
183
static pixman_image_t *
184
60
_pixman_transparent_image (void)
185
{
186
    TRACE ((stderr, "%s\n", __FUNCTION__));
187
60
    return _pixman_image_for_color (CAIRO_COLOR_TRANSPARENT);
188
}
189

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

            
197
static pixman_image_t *
198
1145
_pixman_white_image (void)
199
{
200
    TRACE ((stderr, "%s\n", __FUNCTION__));
201
1145
    return _pixman_image_for_color (CAIRO_COLOR_WHITE);
202
}
203

            
204
#endif /* !PIXMAN_HAS_ATOMIC_OPS */
205

            
206

            
207
pixman_image_t *
208
294147
_pixman_image_for_color (const cairo_color_t *cairo_color)
209
{
210
    pixman_color_t color;
211
    pixman_image_t *image;
212

            
213
#if PIXMAN_HAS_ATOMIC_OPS
214
    int i;
215

            
216
    if (CAIRO_COLOR_IS_CLEAR (cairo_color))
217
	return _pixman_transparent_image ();
218

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

            
227
	if (cairo_color->red_short >= 0xff00 &&
228
	    cairo_color->green_short >= 0xff00 &&
229
	    cairo_color->blue_short >= 0xff00)
230
	{
231
	    return _pixman_white_image ();
232
	}
233
    }
234

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

            
244
294147
    color.red   = cairo_color->red_short;
245
294147
    color.green = cairo_color->green_short;
246
294147
    color.blue  = cairo_color->blue_short;
247
294147
    color.alpha = cairo_color->alpha_short;
248

            
249
294147
    image = pixman_image_create_solid_fill (&color);
250
#if PIXMAN_HAS_ATOMIC_OPS
251
    if (image == NULL)
252
	goto UNLOCK;
253

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

            
263
UNLOCK:
264
    CAIRO_MUTEX_UNLOCK (_cairo_image_solid_cache_mutex);
265
#endif
266
294147
    return image;
267
}
268

            
269

            
270
void
271
609
_cairo_image_reset_static_data (void)
272
{
273
#if PIXMAN_HAS_ATOMIC_OPS
274
    while (n_cached)
275
	pixman_image_unref (cache[--n_cached].image);
276

            
277
    if (__pixman_transparent_image) {
278
	pixman_image_unref (__pixman_transparent_image);
279
	__pixman_transparent_image = NULL;
280
    }
281

            
282
    if (__pixman_black_image) {
283
	pixman_image_unref (__pixman_black_image);
284
	__pixman_black_image = NULL;
285
    }
286

            
287
    if (__pixman_white_image) {
288
	pixman_image_unref (__pixman_white_image);
289
	__pixman_white_image = NULL;
290
    }
291
#endif
292
609
}
293

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

            
309
    TRACE ((stderr, "%s\n", __FUNCTION__));
310

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

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

            
326
1554
    _cairo_gradient_pattern_fit_to_range (pattern, PIXMAN_MAX_INT >> 1, &matrix, extremes);
327

            
328
1554
    p1.x = _cairo_fixed_16_16_from_double (extremes[0].center.x);
329
1554
    p1.y = _cairo_fixed_16_16_from_double (extremes[0].center.y);
330
1554
    p2.x = _cairo_fixed_16_16_from_double (extremes[1].center.x);
331
1554
    p2.y = _cairo_fixed_16_16_from_double (extremes[1].center.y);
332

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

            
340
675
	r1   = _cairo_fixed_16_16_from_double (extremes[0].radius);
341
675
	r2   = _cairo_fixed_16_16_from_double (extremes[1].radius);
342

            
343
675
	pixman_image = pixman_image_create_radial_gradient (&p1, &p2, r1, r2,
344
							    pixman_stops,
345
675
							    pattern->n_stops);
346
    }
347

            
348
1554
    if (pixman_stops != pixman_stops_static)
349
630
	free (pixman_stops);
350

            
351
1554
    if (unlikely (pixman_image == NULL))
352
	return NULL;
353

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

            
368
    {
369
	pixman_repeat_t pixman_repeat;
370

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

            
387
1554
	pixman_image_set_repeat (pixman_image, pixman_repeat);
388
    }
389

            
390
1554
    return pixman_image;
391
}
392

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

            
401
    TRACE ((stderr, "%s\n", __FUNCTION__));
402

            
403
16899
    *tx = -extents->x;
404
16899
    *ty = -extents->y;
405
16899
    width = extents->width;
406
16899
    height = extents->height;
407

            
408
16899
    image = pixman_image_create_bits (PIXMAN_a8r8g8b8, width, height, NULL, 0);
409
16899
    if (unlikely (image == NULL))
410
	return NULL;
411

            
412
16899
    _cairo_mesh_pattern_rasterize (pattern,
413
16899
				   pixman_image_get_data (image),
414
				   width, height,
415
				   pixman_image_get_stride (image),
416
16899
				   *tx, *ty);
417
16899
    return image;
418
}
419

            
420
struct acquire_source_cleanup {
421
    cairo_surface_t *surface;
422
    cairo_image_surface_t *image;
423
    void *image_extra;
424
};
425

            
426
static void
427
138
_acquire_source_cleanup (pixman_image_t *pixman_image,
428
			 void *closure)
429
{
430
138
    struct acquire_source_cleanup *data = closure;
431

            
432
138
    _cairo_surface_release_source_image (data->surface,
433
					 data->image,
434
					 data->image_extra);
435
138
    free (data);
436
138
}
437

            
438
static void
439
41574
_defer_free_cleanup (pixman_image_t *pixman_image,
440
		     void *closure)
441
{
442
41574
    cairo_surface_destroy (closure);
443
41574
}
444

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

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

            
464
    TRACE ((stderr, "%s\n", __FUNCTION__));
465

            
466
3264
    switch (image->format) {
467
    default:
468
    case CAIRO_FORMAT_INVALID:
469
	ASSERT_NOT_REACHED;
470
	return NULL;
471

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

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

            
484
	color.red = color.green = color.blue = 0;
485
	return pixman_image_create_solid_fill (&color);
486

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

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

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

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

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

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

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

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

            
547
	if (color.alpha == 0xffff && rgba[0] == 0.f && rgba[1] == 0.f && rgba[2] == 0.f)
548
	    return _pixman_black_image ();
549
	if (color.alpha == 0xffff && rgba[0] == 1.f && rgba[1] == 1.f && rgba[2] == 1.f)
550
	    return _pixman_white_image ();
551

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

            
559
/* ========================================================================== */
560

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

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

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

            
588
/* Table of filters */
589
typedef struct
590
{
591
    kernel_t		kernel;
592
    kernel_func_t	func;
593
    kernel_width_func_t	width;
594
} filter_info_t;
595

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

            
602
static double
603
impulse_kernel (double x, double r)
604
{
605
    return 1;
606
}
607

            
608
static int
609
impulse_width (double r)
610
{
611
    return 1;
612
}
613

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

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

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

            
632
static int
633
90
box_width (double r)
634
{
635
90
    return r < 1.0 ? 2 : ceil(r + 1);
636
}
637

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

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

            
650
static double
651
linear_kernel (double x, double r)
652
{
653
    return MAX (1.0 - fabs(x), 0.0);
654
}
655

            
656
static int
657
linear_width (double r)
658
{
659
    return 2;
660
}
661

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

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

            
676
9984
    ax = fabs (x / r);
677

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

            
697
static int
698
12
cubic_width (double r)
699
{
700
12
    return MAX (2, ceil (r * 4));
701
}
702

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

            
710
static double
711
9984
cubic_kernel (double x, double r)
712
{
713
9984
    return general_cubic (x, r, 0.0, 0.5);
714
}
715

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

            
722
static double
723
mitchell_kernel (double x, double r)
724
{
725
    return general_cubic (x, r, 1/3.0, 1/3.0);
726
}
727

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

            
735
static double
736
notch_kernel (double x, double r)
737
{
738
    return general_cubic (x, r, 1.5, -0.25);
739
}
740

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

            
747
static double
748
sinc (double x)
749
{
750
    return x ? sin (M_PI * x) / (M_PI * x) : 1.0;
751
}
752

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

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

            
770
static int
771
lanczos3_width (double r)
772
{
773
    return MAX (2, ceil (r * 6));
774
}
775

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

            
781
static double
782
nice_kernel (double x, double r)
783
{
784
    return lanczos3_kernel (x, r * (4.0/3));
785
}
786

            
787
static int
788
nice_width (double r)
789
{
790
    return MAX (2.0, ceil (r * 8));
791
}
792

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

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

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

            
811
static int
812
tent_width (double r)
813
{
814
    return r < 1.0 ? 2 : ceil(2 * r);
815
}
816

            
817

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

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

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

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

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

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

            
871
	/* Put any error on center pixel */
872
9744
	p[width / 2] += (pixman_fixed_1 - new_total);
873

            
874
9744
	p += width;
875
    }
876
}
877

            
878

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

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

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

            
904
51
    *n_values = 4 + size_x + size_y;
905
51
    params = _cairo_malloc (*n_values * sizeof (pixman_fixed_t));
906
51
    if (!params) return 0;
907

            
908
51
    params[0] = pixman_int_to_fixed (xwidth);
909
51
    params[1] = pixman_int_to_fixed (ywidth);
910
51
    params[2] = pixman_int_to_fixed (xsubsample);
911
51
    params[3] = pixman_int_to_fixed (ysubsample);
912

            
913
51
    get_filter(xfilter, sx, xwidth, xsubsample, params + 4);
914
51
    get_filter(yfilter, sy, ywidth, ysubsample, params + 4 + size_x);
915

            
916
51
    return params;
917
}
918

            
919
/* ========================================================================== */
920

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

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

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

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

            
969
40668
	switch (pattern->filter) {
970
6
	case CAIRO_FILTER_FAST:
971
6
	    pixman_filter = PIXMAN_FILTER_FAST;
972
6
	    break;
973
45
	case CAIRO_FILTER_GOOD:
974
45
	    pixman_filter = PIXMAN_FILTER_SEPARABLE_CONVOLUTION;
975
45
	    kernel = KERNEL_BOX;
976
	    /* Clip the filter size to prevent extreme slowness. This
977
	       value could be raised if 2-pass filtering is done */
978
45
	    if (dx > 16.0) dx = 16.0;
979
45
	    if (dy > 16.0) dy = 16.0;
980
	    /* Match the bilinear filter for scales > .75: */
981
45
	    if (dx < 1.0/0.75) dx = 1.0;
982
45
	    if (dy < 1.0/0.75) dy = 1.0;
983
45
	    break;
984
6
	case CAIRO_FILTER_BEST:
985
6
	    pixman_filter = PIXMAN_FILTER_SEPARABLE_CONVOLUTION;
986
6
	    kernel = KERNEL_CATMULL_ROM; /* LANCZOS3 is better but not much */
987
	    /* Clip the filter size to prevent extreme slowness. This
988
	       value could be raised if 2-pass filtering is done */
989
6
	    if (dx > 16.0) { dx = 16.0; kernel = KERNEL_BOX; }
990
	    /* blur up to 2x scale, then blend to square pixels for larger: */
991
6
	    else if (dx < 1.0) {
992
		if (dx < 1.0/128) dx = 1.0/127;
993
		else if (dx < 0.5) dx = 1.0 / (1.0 / dx - 1.0);
994
		else dx = 1.0;
995
	    }
996
6
	    if (dy > 16.0) { dy = 16.0; kernel = KERNEL_BOX; }
997
6
	    else if (dy < 1.0) {
998
		if (dy < 1.0/128) dy = 1.0/127;
999
		else if (dy < 0.5) dy = 1.0 / (1.0 / dy - 1.0);
		else dy = 1.0;
	    }
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 *
300704
_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)
{
300704
    *tx = *ty = 0;
    TRACE ((stderr, "%s\n", __FUNCTION__));
300704
    if (pattern == NULL)
551
	return _pixman_white_image ();
300153
    switch (pattern->type) {
    default:
	ASSERT_NOT_REACHED;
    case CAIRO_PATTERN_TYPE_SOLID:
209325
	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
147770
_cairo_image_source_finish (void *abstract_surface)
{
147770
    cairo_image_source_t *source = abstract_surface;
147770
    pixman_image_unref (source->pixman_image);
147770
    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 *
147770
_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__));
147770
    source = _cairo_calloc (sizeof (cairo_image_source_t));
147770
    if (unlikely (source == NULL))
	return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
147770
    source->pixman_image =
147770
	_pixman_image_for_pattern ((cairo_image_surface_t *)dst,
				   pattern, is_mask,
				   extents, sample,
				   src_x, src_y);
147770
    if (unlikely (source->pixman_image == NULL)) {
	free (source);
	return _cairo_surface_create_in_error (CAIRO_STATUS_NO_MEMORY);
    }
147770
    _cairo_surface_init (&source->base,
			 &_cairo_image_source_backend,
			 NULL, /* device */
			 CAIRO_CONTENT_COLOR_ALPHA,
			 FALSE); /* is_vector */
147770
    source->is_opaque_solid =
147770
	pattern == NULL || _cairo_pattern_is_opaque_solid (pattern);
147770
    return &source->base;
}