Fix bug in _cairo_gl_has_extension
[platform/core/graphics/cairo.git] / src / cairo-image-source.c
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 #include "cairo-image-filters-private.h"
58
59 #define PIXMAN_MAX_INT ((pixman_fixed_1 >> 1) - pixman_fixed_e) /* need to ensure deltas also fit */
60
61 #if CAIRO_NO_MUTEX
62 #define PIXMAN_HAS_ATOMIC_OPS 1
63 #endif
64
65 #define SEPARABLE_CONVOLUTION 0
66
67 #if PIXMAN_HAS_ATOMIC_OPS
68 static pixman_image_t *__pixman_transparent_image;
69 static pixman_image_t *__pixman_black_image;
70 static pixman_image_t *__pixman_white_image;
71
72 static pixman_image_t *
73 _pixman_transparent_image (void)
74 {
75     pixman_image_t *image;
76
77     TRACE ((stderr, "%s\n", __FUNCTION__));
78
79     image = __pixman_transparent_image;
80     if (unlikely (image == NULL)) {
81         pixman_color_t color;
82
83         color.red   = 0x00;
84         color.green = 0x00;
85         color.blue  = 0x00;
86         color.alpha = 0x00;
87
88         image = pixman_image_create_solid_fill (&color);
89         if (unlikely (image == NULL))
90             return NULL;
91
92         if (_cairo_atomic_ptr_cmpxchg (&__pixman_transparent_image,
93                                        NULL, image))
94         {
95             pixman_image_ref (image);
96         }
97     } else {
98         pixman_image_ref (image);
99     }
100
101     return image;
102 }
103
104 static pixman_image_t *
105 _pixman_black_image (void)
106 {
107     pixman_image_t *image;
108
109     TRACE ((stderr, "%s\n", __FUNCTION__));
110
111     image = __pixman_black_image;
112     if (unlikely (image == NULL)) {
113         pixman_color_t color;
114
115         color.red   = 0x00;
116         color.green = 0x00;
117         color.blue  = 0x00;
118         color.alpha = 0xffff;
119
120         image = pixman_image_create_solid_fill (&color);
121         if (unlikely (image == NULL))
122             return NULL;
123
124         if (_cairo_atomic_ptr_cmpxchg (&__pixman_black_image,
125                                        NULL, image))
126         {
127             pixman_image_ref (image);
128         }
129     } else {
130         pixman_image_ref (image);
131     }
132
133     return image;
134 }
135
136 static pixman_image_t *
137 _pixman_white_image (void)
138 {
139     pixman_image_t *image;
140
141     TRACE ((stderr, "%s\n", __FUNCTION__));
142
143     image = __pixman_white_image;
144     if (unlikely (image == NULL)) {
145         pixman_color_t color;
146
147         color.red   = 0xffff;
148         color.green = 0xffff;
149         color.blue  = 0xffff;
150         color.alpha = 0xffff;
151
152         image = pixman_image_create_solid_fill (&color);
153         if (unlikely (image == NULL))
154             return NULL;
155
156         if (_cairo_atomic_ptr_cmpxchg (&__pixman_white_image,
157                                        NULL, image))
158         {
159             pixman_image_ref (image);
160         }
161     } else {
162         pixman_image_ref (image);
163     }
164
165     return image;
166 }
167
168 static uint32_t
169 hars_petruska_f54_1_random (void)
170 {
171 #define rol(x,k) ((x << k) | (x >> (32-k)))
172     static uint32_t x;
173     return x = (x ^ rol (x, 5) ^ rol (x, 24)) + 0x37798849;
174 #undef rol
175 }
176
177 static struct {
178     cairo_color_t color;
179     pixman_image_t *image;
180 } cache[16];
181 static int n_cached;
182
183 #else  /* !PIXMAN_HAS_ATOMIC_OPS */
184 static pixman_image_t *
185 _pixman_transparent_image (void)
186 {
187     TRACE ((stderr, "%s\n", __FUNCTION__));
188     return _pixman_image_for_color (CAIRO_COLOR_TRANSPARENT);
189 }
190
191 static pixman_image_t *
192 _pixman_black_image (void)
193 {
194     TRACE ((stderr, "%s\n", __FUNCTION__));
195     return _pixman_image_for_color (CAIRO_COLOR_BLACK);
196 }
197
198 static pixman_image_t *
199 _pixman_white_image (void)
200 {
201     TRACE ((stderr, "%s\n", __FUNCTION__));
202     return _pixman_image_for_color (CAIRO_COLOR_WHITE);
203 }
204 #endif /* !PIXMAN_HAS_ATOMIC_OPS */
205
206
207 pixman_image_t *
208 _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     color.red   = cairo_color->red_short;
245     color.green = cairo_color->green_short;
246     color.blue  = cairo_color->blue_short;
247     color.alpha = cairo_color->alpha_short;
248
249     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     return image;
267 }
268
269
270 void
271 _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 }
293
294 static pixman_image_t *
295 _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     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     if (pattern->n_stops > ARRAY_LENGTH(pixman_stops_static)) {
312         pixman_stops = _cairo_malloc_ab (pattern->n_stops,
313                                          sizeof(pixman_gradient_stop_t));
314         if (unlikely (pixman_stops == NULL))
315             return NULL;
316     }
317
318     for (i = 0; i < pattern->n_stops; i++) {
319         pixman_stops[i].x = _cairo_fixed_16_16_from_double (pattern->stops[i].offset);
320         pixman_stops[i].color.red   = pattern->stops[i].color.red_short;
321         pixman_stops[i].color.green = pattern->stops[i].color.green_short;
322         pixman_stops[i].color.blue  = pattern->stops[i].color.blue_short;
323         pixman_stops[i].color.alpha = pattern->stops[i].color.alpha_short;
324     }
325
326     _cairo_gradient_pattern_fit_to_range (pattern, PIXMAN_MAX_INT >> 1, &matrix, extremes);
327
328     p1.x = _cairo_fixed_16_16_from_double (extremes[0].center.x);
329     p1.y = _cairo_fixed_16_16_from_double (extremes[0].center.y);
330     p2.x = _cairo_fixed_16_16_from_double (extremes[1].center.x);
331     p2.y = _cairo_fixed_16_16_from_double (extremes[1].center.y);
332
333     if (pattern->base.type == CAIRO_PATTERN_TYPE_LINEAR) {
334         pixman_image = pixman_image_create_linear_gradient (&p1, &p2,
335                                                             pixman_stops,
336                                                             pattern->n_stops);
337     } else {
338         pixman_fixed_t r1, r2;
339
340         r1   = _cairo_fixed_16_16_from_double (extremes[0].radius);
341         r2   = _cairo_fixed_16_16_from_double (extremes[1].radius);
342
343         pixman_image = pixman_image_create_radial_gradient (&p1, &p2, r1, r2,
344                                                             pixman_stops,
345                                                             pattern->n_stops);
346     }
347
348     if (pixman_stops != pixman_stops_static)
349         free (pixman_stops);
350
351     if (unlikely (pixman_image == NULL))
352         return NULL;
353
354     *ix = *iy = 0;
355     status = _cairo_matrix_to_pixman_matrix_offset (&matrix, pattern->base.filter,
356                                                     extents->x + extents->width/2.,
357                                                     extents->y + extents->height/2.,
358                                                     &pixman_transform, ix, iy);
359     if (status != CAIRO_INT_STATUS_NOTHING_TO_DO) {
360         if (unlikely (status != CAIRO_INT_STATUS_SUCCESS) ||
361             ! 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         switch (pattern->base.extend) {
372         default:
373         case CAIRO_EXTEND_NONE:
374             pixman_repeat = PIXMAN_REPEAT_NONE;
375             break;
376         case CAIRO_EXTEND_REPEAT:
377             pixman_repeat = PIXMAN_REPEAT_NORMAL;
378             break;
379         case CAIRO_EXTEND_REFLECT:
380             pixman_repeat = PIXMAN_REPEAT_REFLECT;
381             break;
382         case CAIRO_EXTEND_PAD:
383             pixman_repeat = PIXMAN_REPEAT_PAD;
384             break;
385         }
386
387         pixman_image_set_repeat (pixman_image, pixman_repeat);
388     }
389
390     return pixman_image;
391 }
392
393 static pixman_image_t *
394 _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     *tx = -extents->x;
404     *ty = -extents->y;
405     width = extents->width;
406     height = extents->height;
407
408     image = pixman_image_create_bits (PIXMAN_a8r8g8b8, width, height, NULL, 0);
409     if (unlikely (image == NULL))
410         return NULL;
411
412     _cairo_mesh_pattern_rasterize (pattern,
413                                    pixman_image_get_data (image),
414                                    width, height,
415                                    pixman_image_get_stride (image),
416                                    *tx, *ty);
417     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 _acquire_source_cleanup (pixman_image_t *pixman_image,
428                          void *closure)
429 {
430     struct acquire_source_cleanup *data = closure;
431
432     _cairo_surface_release_source_image (data->surface,
433                                          data->image,
434                                          data->image_extra);
435     free (data);
436 }
437
438 static void
439 _defer_free_cleanup (pixman_image_t *pixman_image,
440                      void *closure)
441 {
442     cairo_surface_destroy (closure);
443 }
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 _pixel_to_solid (cairo_image_surface_t *image, int x, int y)
459 {
460     uint32_t pixel;
461     pixman_color_t color;
462
463     TRACE ((stderr, "%s\n", __FUNCTION__));
464
465     switch (image->format) {
466     default:
467     case CAIRO_FORMAT_INVALID:
468         ASSERT_NOT_REACHED;
469         return NULL;
470
471     case CAIRO_FORMAT_A1:
472         pixel = *(uint8_t *) (image->data + y * image->stride + x/8);
473         return pixel & (1 << (x&7)) ? _pixman_black_image () : _pixman_transparent_image ();
474
475     case CAIRO_FORMAT_A8:
476         color.alpha = *(uint8_t *) (image->data + y * image->stride + x);
477         color.alpha |= color.alpha << 8;
478         if (color.alpha == 0)
479             return _pixman_transparent_image ();
480         if (color.alpha == 0xffff)
481             return _pixman_black_image ();
482
483         color.red = color.green = color.blue = 0;
484         return pixman_image_create_solid_fill (&color);
485
486     case CAIRO_FORMAT_RGB16_565:
487         pixel = *(uint16_t *) (image->data + y * image->stride + 2 * x);
488         if (pixel == 0)
489             return _pixman_black_image ();
490         if (pixel == 0xffff)
491             return _pixman_white_image ();
492
493         color.alpha = 0xffff;
494         color.red = expand_channel ((pixel >> 11 & 0x1f) << 11, 5);
495         color.green = expand_channel ((pixel >> 5 & 0x3f) << 10, 6);
496         color.blue = expand_channel ((pixel & 0x1f) << 11, 5);
497         return pixman_image_create_solid_fill (&color);
498
499     case CAIRO_FORMAT_RGB30:
500         pixel = *(uint32_t *) (image->data + y * image->stride + 4 * x);
501         pixel &= 0x3fffffff; /* ignore alpha bits */
502         if (pixel == 0)
503             return _pixman_black_image ();
504         if (pixel == 0x3fffffff)
505             return _pixman_white_image ();
506
507         /* convert 10bpc to 16bpc */
508         color.alpha = 0xffff;
509         color.red = expand_channel((pixel >> 20) & 0x3fff, 10);
510         color.green = expand_channel((pixel >> 10) & 0x3fff, 10);
511         color.blue = expand_channel(pixel & 0x3fff, 10);
512         return pixman_image_create_solid_fill (&color);
513
514     case CAIRO_FORMAT_ARGB32:
515     case CAIRO_FORMAT_RGB24:
516         pixel = *(uint32_t *) (image->data + y * image->stride + 4 * x);
517         color.alpha = image->format == CAIRO_FORMAT_ARGB32 ? (pixel >> 24) | (pixel >> 16 & 0xff00) : 0xffff;
518         if (color.alpha == 0)
519             return _pixman_transparent_image ();
520         if (pixel == 0xffffffff)
521             return _pixman_white_image ();
522         if (color.alpha == 0xffff && (pixel & 0xffffff) == 0)
523             return _pixman_black_image ();
524
525         color.red = (pixel >> 16 & 0xff) | (pixel >> 8 & 0xff00);
526         color.green = (pixel >> 8 & 0xff) | (pixel & 0xff00);
527         color.blue = (pixel & 0xff) | (pixel << 8 & 0xff00);
528         return pixman_image_create_solid_fill (&color);
529     }
530 }
531
532 /* ========================================================================== */
533
534 /* Index into filter table */
535 typedef enum
536 {
537     KERNEL_IMPULSE,
538     KERNEL_BOX,
539     KERNEL_LINEAR,
540     KERNEL_MITCHELL,
541     KERNEL_NOTCH,
542     KERNEL_CATMULL_ROM,
543     KERNEL_LANCZOS3,
544     KERNEL_LANCZOS3_STRETCHED,
545     KERNEL_TENT
546 } kernel_t;
547
548 /* Produce contribution of a filter of size r for pixel centered on x.
549    For a typical low-pass function this evaluates the function at x/r.
550    If the frequency is higher than 1/2, such as when r is less than 1,
551    this may need to integrate several samples, see cubic for examples.
552 */
553 typedef double (* kernel_func_t) (double x, double r);
554
555 /* Return maximum number of pixels that will be non-zero. Except for
556    impluse this is the maximum of 2 and the width of the non-zero part
557    of the filter rounded up to the next integer.
558 */
559 typedef int (* kernel_width_func_t) (double r);
560
561 /* Table of filters */
562 typedef struct
563 {
564     kernel_t            kernel;
565     kernel_func_t       func;
566     kernel_width_func_t width;
567 } filter_info_t;
568
569 /* PIXMAN_KERNEL_IMPULSE: Returns pixel nearest the center.  This
570    matches PIXMAN_FILTER_NEAREST. This is useful if you wish to
571    combine the result of nearest in one direction with another filter
572    in the other.
573 */
574
575 static double
576 impulse_kernel (double x, double r)
577 {
578     return 1;
579 }
580
581 static int
582 impulse_width (double r)
583 {
584     return 1;
585 }
586
587 /* PIXMAN_KERNEL_BOX: Intersection of a box of width r with square
588    pixels. This is the smallest possible filter such that the output
589    image contains an equal contribution from all the input
590    pixels. Lots of software uses this. The function is a trapazoid of
591    width r+1, not a box.
592
593    When r == 1.0, PIXMAN_KERNEL_BOX, PIXMAN_KERNEL_LINEAR, and
594    PIXMAN_KERNEL_TENT all produce the same filter, allowing
595    them to be exchanged at this point.
596 */
597
598 static double
599 box_kernel (double x, double r)
600 {
601     return MAX (0.0, MIN (MIN (r, 1.0),
602                           MIN ((r + 1) / 2 - x, (r + 1) / 2 + x)));
603 }
604
605 static int
606 box_width (double r)
607 {
608     return r < 1.0 ? 2 : ceil(r + 1);
609 }
610
611 /* PIXMAN_KERNEL_LINEAR: Weighted sum of the two pixels nearest the
612    center, or a triangle of width 2. This matches
613    PIXMAN_FILTER_BILINEAR. This is useful if you wish to combine the
614    result of bilinear in one direction with another filter in the
615    other.  This is not a good filter if r > 1. You may actually want
616    PIXMAN_FILTER_TENT.
617
618    When r == 1.0, PIXMAN_KERNEL_BOX, PIXMAN_KERNEL_LINEAR, and
619    PIXMAN_KERNEL_TENT all produce the same filter, allowing
620    them to be exchanged at this point.
621 */
622
623 static double
624 linear_kernel (double x, double r)
625 {
626     return MAX (1.0 - fabs(x), 0.0);
627 }
628
629 static int
630 linear_width (double r)
631 {
632     return 2;
633 }
634
635 /* Cubic functions described in the Mitchell-Netravali paper.
636    http://mentallandscape.com/Papers_siggraph88.pdf. This describes
637    all possible cubic functions that can be used for sampling.
638 */
639
640 static double
641 general_cubic (double x, double r, double B, double C)
642 {
643     double ax;
644     if (r < 1.0)
645         return
646             general_cubic(x * 2 - .5, r * 2, B, C) +
647             general_cubic(x * 2 + .5, r * 2, B, C);
648
649     ax = fabs (x / r);
650
651     if (ax < 1)
652     {
653         return (((12 - 9 * B - 6 * C) * ax +
654                  (-18 + 12 * B + 6 * C)) * ax * ax +
655                 (6 - 2 * B)) / 6;
656     }
657     else if (ax < 2)
658     {
659         return ((((-B - 6 * C) * ax +
660                  (6 * B + 30 * C)) * ax +
661                 (-12 * B - 48 * C)) * ax +
662                 (8 * B + 24 * C)) / 6;
663     }
664     else
665     {
666         return 0.0;
667     }
668 }
669
670 static int
671 cubic_width (double r)
672 {
673     return MAX (2, ceil (r * 4));
674 }
675
676 /* PIXMAN_KERNEL_CATMULL_ROM: Catmull-Rom interpolation. Often called
677    "cubic interpolation", "b-spline", or just "cubic" by other
678    software. This filter has negative values so it can produce ringing
679    and output pixels outside the range of input pixels. This is very
680    close to lanczos2 so there is no reason to supply that as well.
681 */
682
683 static double
684 cubic_kernel (double x, double r)
685 {
686     return general_cubic (x, r, 0.0, 0.5);
687 }
688
689 /* PIXMAN_KERNEL_MITCHELL: Cubic recommended by the Mitchell-Netravali
690    paper.  This has negative values and because the values at +/-1 are
691    not zero it does not interpolate the pixels, meaning it will change
692    an image even if there is no translation.
693 */
694
695 static double
696 mitchell_kernel (double x, double r)
697 {
698     return general_cubic (x, r, 1/3.0, 1/3.0);
699 }
700
701 /* PIXMAN_KERNEL_NOTCH: Cubic recommended by the Mitchell-Netravali
702    paper to remove postaliasing artifacts. This does not remove
703    aliasing already present in the source image, though it may appear
704    to due to it's excessive blurriness. In any case this is more
705    useful than gaussian for image reconstruction.
706 */
707
708 static double
709 notch_kernel (double x, double r)
710 {
711     return general_cubic (x, r, 1.5, -0.25);
712 }
713
714 /* PIXMAN_KERNEL_LANCZOS3: lanczos windowed sinc function from -3 to
715    +3. Very popular with high-end software though I think any
716    advantage over cubics is hidden by quantization and programming
717    mistakes. You will see LANCZOS5 or even 7 sometimes.
718 */
719
720 static double
721 sinc (double x)
722 {
723     return x ? sin (M_PI * x) / (M_PI * x) : 1.0;
724 }
725
726 static double
727 lanczos (double x, double n)
728 {
729     return fabs (x) < n ? sinc (x) * sinc (x * (1.0 / n)) : 0.0;
730 }
731
732 static double
733 lanczos3_kernel (double x, double r)
734 {
735     if (r < 1.0)
736         return
737             lanczos3_kernel (x * 2 - .5, r * 2) +
738             lanczos3_kernel (x * 2 + .5, r * 2);
739     else
740         return lanczos (x / r, 3.0);
741 }
742
743 static int
744 lanczos3_width (double r)
745 {
746     return MAX (2, ceil (r * 6));
747 }
748
749 /* PIXMAN_KERNEL_LANCZOS3_STRETCHED - The LANCZOS3 kernel widened by
750    4/3.  Recommended by Jim Blinn
751    http://graphics.cs.cmu.edu/nsp/course/15-462/Fall07/462/papers/jaggy.pdf
752 */
753
754 static double
755 nice_kernel (double x, double r)
756 {
757     return lanczos3_kernel (x, r * (4.0/3));
758 }
759
760 static int
761 nice_width (double r)
762 {
763     return MAX (2.0, ceil (r * 8));
764 }
765
766 /* PIXMAN_KERNEL_TENT: Triangle of width 2r. Lots of software uses
767    this as a "better" filter, twice the size of a box but smaller than
768    a cubic.
769
770    When r == 1.0, PIXMAN_KERNEL_BOX, PIXMAN_KERNEL_LINEAR, and
771    PIXMAN_KERNEL_TENT all produce the same filter, allowing
772    them to be exchanged at this point.
773 */
774
775 static double
776 tent_kernel (double x, double r)
777 {
778     if (r < 1.0)
779         return box_kernel(x, r);
780     else
781         return MAX (1.0 - fabs(x / r), 0.0);
782 }
783
784 static int
785 tent_width (double r)
786 {
787     return r < 1.0 ? 2 : ceil(2 * r);
788 }
789
790
791 static const filter_info_t filters[] =
792 {
793     { KERNEL_IMPULSE,           impulse_kernel,   impulse_width },
794     { KERNEL_BOX,               box_kernel,       box_width },
795     { KERNEL_LINEAR,            linear_kernel,    linear_width },
796     { KERNEL_MITCHELL,          mitchell_kernel,  cubic_width },
797     { KERNEL_NOTCH,             notch_kernel,     cubic_width },
798     { KERNEL_CATMULL_ROM,       cubic_kernel,     cubic_width },
799     { KERNEL_LANCZOS3,          lanczos3_kernel,  lanczos3_width },
800     { KERNEL_LANCZOS3_STRETCHED,nice_kernel,      nice_width },
801     { KERNEL_TENT,              tent_kernel,      tent_width }
802 };
803
804 /* Fills in one dimension of the filter array */
805 static void get_filter(kernel_t filter, double r,
806                        int width, int subsample,
807                        pixman_fixed_t* out)
808 {
809     int i;
810     pixman_fixed_t *p = out;
811     int n_phases = 1 << subsample;
812     double step = 1.0 / n_phases;
813     kernel_func_t func = filters[filter].func;
814
815     /* special-case the impulse filter: */
816     if (width <= 1)
817     {
818         for (i = 0; i < n_phases; ++i)
819             *p++ = pixman_fixed_1;
820         return;
821     }
822
823     for (i = 0; i < n_phases; ++i)
824     {
825         double frac = (i + .5) * step;
826         /* Center of left-most pixel: */
827         double x1 = ceil (frac - width / 2.0 - 0.5) - frac + 0.5;
828         double total = 0;
829         pixman_fixed_t new_total = 0;
830         int j;
831
832         for (j = 0; j < width; ++j)
833         {
834             double v = func(x1 + j, r);
835             total += v;
836             p[j] = pixman_double_to_fixed (v);
837         }
838
839         /* Normalize */
840         total = 1 / total;
841         for (j = 0; j < width; ++j)
842             new_total += (p[j] *= total);
843
844         /* Put any error on center pixel */
845         p[width / 2] += (pixman_fixed_1 - new_total);
846
847         p += width;
848     }
849 }
850
851
852 /* Create the parameter list for a SEPARABLE_CONVOLUTION filter
853  * with the given kernels and scale parameters. 
854  */
855 static pixman_fixed_t *
856 create_separable_convolution (int *n_values,
857                               kernel_t xfilter,
858                               double sx,
859                               kernel_t yfilter,
860                               double sy)
861 {
862     int xwidth, xsubsample, ywidth, ysubsample, size_x, size_y;
863     pixman_fixed_t *params;
864
865     xwidth = filters[xfilter].width(sx);
866     xsubsample = 0;
867     if (xwidth > 1)
868         while (sx * (1 << xsubsample) <= 128.0) xsubsample++;
869     size_x = (1 << xsubsample) * xwidth;
870
871     ywidth = filters[yfilter].width(sy);
872     ysubsample = 0;
873     if (ywidth > 1)
874         while (sy * (1 << ysubsample) <= 128.0) ysubsample++;
875     size_y = (1 << ysubsample) * ywidth;
876
877     *n_values = 4 + size_x + size_y;
878     params = malloc (*n_values * sizeof (pixman_fixed_t));
879     if (!params) return 0;
880
881     params[0] = pixman_int_to_fixed (xwidth);
882     params[1] = pixman_int_to_fixed (ywidth);
883     params[2] = pixman_int_to_fixed (xsubsample);
884     params[3] = pixman_int_to_fixed (ysubsample);
885
886     get_filter(xfilter, sx, xwidth, xsubsample, params + 4);
887     get_filter(yfilter, sy, ywidth, ysubsample, params + 4 + size_x);
888
889     return params;
890 }
891
892 /* ========================================================================== */
893
894 static cairo_bool_t
895 _pixman_image_set_properties (pixman_image_t *pixman_image,
896                               const cairo_pattern_t *pattern,
897                               const cairo_rectangle_int_t *extents,
898                               int *ix,int *iy)
899 {
900     pixman_transform_t pixman_transform;
901     cairo_int_status_t status;
902
903     status = _cairo_matrix_to_pixman_matrix_offset (&pattern->matrix,
904                                                     pattern->filter,
905                                                     extents->x + extents->width/2.,
906                                                     extents->y + extents->height/2.,
907                                                     &pixman_transform, ix, iy);
908     if (status == CAIRO_INT_STATUS_NOTHING_TO_DO)
909     {
910         /* If the transform is an identity, we don't need to set it
911          * and we can use any filtering, so choose the fastest one. */
912         pixman_image_set_filter (pixman_image, PIXMAN_FILTER_NEAREST, NULL, 0);
913     }
914     else if (unlikely (status != CAIRO_INT_STATUS_SUCCESS ||
915                        ! pixman_image_set_transform (pixman_image,
916                                                      &pixman_transform)))
917     {
918         return FALSE;
919     }
920     else
921     {
922         pixman_filter_t pixman_filter;
923         kernel_t kernel;
924         double dx, dy;
925
926         /* Compute scale factors from the pattern matrix. These scale
927          * factors are from user to pattern space, and as such they
928          * are greater than 1.0 for downscaling and less than 1.0 for
929          * upscaling. The factors are the size of an axis-aligned
930          * rectangle with the same area as the parallelgram a 1x1
931          * square transforms to.
932          */
933         dx = hypot (pattern->matrix.xx, pattern->matrix.xy);
934         dy = hypot (pattern->matrix.yx, pattern->matrix.yy);
935
936         /* Clip at maximum pixman_fixed number. Besides making it
937          * passable to pixman, this avoids errors from inf and nan.
938          */
939         if (! (dx < 0x7FFF)) dx = 0x7FFF;
940         if (! (dy < 0x7FFF)) dy = 0x7FFF;
941
942         switch (pattern->filter) {
943         case CAIRO_FILTER_FAST:
944             pixman_filter = PIXMAN_FILTER_FAST;
945             break;
946         /* In order to prevent performance drop, Disable PIXMAN_FILTER_SEPERABLE_CONVOLTION
947          * same as cairo 1.12.14 in Tizen2.4
948          */
949 #if SEPARABLE_CONVOLUTION
950         case CAIRO_FILTER_GOOD:
951             pixman_filter = PIXMAN_FILTER_SEPARABLE_CONVOLUTION;
952             kernel = KERNEL_BOX;
953             /* Clip the filter size to prevent extreme slowness. This
954                value could be raised if 2-pass filtering is done */
955             if (dx > 16.0) dx = 16.0;
956             if (dy > 16.0) dy = 16.0;
957             /* Match the bilinear filter for scales > .75: */
958             if (dx < 1.0/0.75) dx = 1.0;
959             if (dy < 1.0/0.75) dy = 1.0;
960             break;
961         case CAIRO_FILTER_BEST:
962             pixman_filter = PIXMAN_FILTER_SEPARABLE_CONVOLUTION;
963             kernel = KERNEL_CATMULL_ROM; /* LANCZOS3 is better but not much */
964             /* Clip the filter size to prevent extreme slowness. This
965                value could be raised if 2-pass filtering is done */
966             if (dx > 16.0) { dx = 16.0; kernel = KERNEL_BOX; }
967             /* blur up to 2x scale, then blend to square pixels for larger: */
968             else if (dx < 1.0) {
969                 if (dx < 1.0/128) dx = 1.0/127;
970                 else if (dx < 0.5) dx = 1.0 / (1.0 / dx - 1.0);
971                 else dx = 1.0;
972             }
973             if (dy > 16.0) { dy = 16.0; kernel = KERNEL_BOX; }
974             else if (dy < 1.0) {
975                 if (dy < 1.0/128) dy = 1.0/127;
976                 else if (dy < 0.5) dy = 1.0 / (1.0 / dy - 1.0);
977                 else dy = 1.0;
978             }
979             break;
980 #else
981         case CAIRO_FILTER_GOOD:
982             pixman_filter = PIXMAN_FILTER_GOOD;
983             break;
984         case CAIRO_FILTER_BEST:
985             pixman_filter = PIXMAN_FILTER_BEST;
986             break;
987 #endif
988         case CAIRO_FILTER_NEAREST:
989             pixman_filter = PIXMAN_FILTER_NEAREST;
990             break;
991         case CAIRO_FILTER_BILINEAR:
992             pixman_filter = PIXMAN_FILTER_BILINEAR;
993             break;
994         case CAIRO_FILTER_GAUSSIAN:
995             /* XXX: The GAUSSIAN value has no implementation in cairo
996              * whatsoever, so it was really a mistake to have it in the
997              * API. We could fix this by officially deprecating it, or
998              * else inventing semantics and providing an actual
999              * implementation for it. */
1000         default:
1001             pixman_filter = PIXMAN_FILTER_BEST;
1002         }
1003
1004         if (pixman_filter == PIXMAN_FILTER_SEPARABLE_CONVOLUTION) {
1005             int n_params;
1006             pixman_fixed_t *params;
1007             params = create_separable_convolution
1008                 (&n_params, kernel, dx, kernel, dy);
1009             pixman_image_set_filter (pixman_image, pixman_filter,
1010                                      params, n_params);
1011             free (params);
1012         } else {
1013             pixman_image_set_filter (pixman_image, pixman_filter, NULL, 0);
1014         }
1015     }
1016
1017     {
1018         pixman_repeat_t pixman_repeat;
1019
1020         switch (pattern->extend) {
1021         default:
1022         case CAIRO_EXTEND_NONE:
1023             pixman_repeat = PIXMAN_REPEAT_NONE;
1024             break;
1025         case CAIRO_EXTEND_REPEAT:
1026             pixman_repeat = PIXMAN_REPEAT_NORMAL;
1027             break;
1028         case CAIRO_EXTEND_REFLECT:
1029             pixman_repeat = PIXMAN_REPEAT_REFLECT;
1030             break;
1031         case CAIRO_EXTEND_PAD:
1032             pixman_repeat = PIXMAN_REPEAT_PAD;
1033             break;
1034         }
1035
1036         pixman_image_set_repeat (pixman_image, pixman_repeat);
1037     }
1038
1039     if (pattern->has_component_alpha)
1040         pixman_image_set_component_alpha (pixman_image, TRUE);
1041
1042     return TRUE;
1043 }
1044
1045 struct proxy {
1046     cairo_surface_t base;
1047     cairo_surface_t *image;
1048 };
1049
1050 static cairo_status_t
1051 proxy_acquire_source_image (void                         *abstract_surface,
1052                             cairo_image_surface_t       **image_out,
1053                             void                        **image_extra)
1054 {
1055     struct proxy *proxy = abstract_surface;
1056     return _cairo_surface_acquire_source_image (proxy->image, image_out, image_extra);
1057 }
1058
1059 static void
1060 proxy_release_source_image (void                        *abstract_surface,
1061                             cairo_image_surface_t       *image,
1062                             void                        *image_extra)
1063 {
1064     struct proxy *proxy = abstract_surface;
1065     _cairo_surface_release_source_image (proxy->image, image, image_extra);
1066 }
1067
1068 static cairo_status_t
1069 proxy_finish (void *abstract_surface)
1070 {
1071     return CAIRO_STATUS_SUCCESS;
1072 }
1073
1074 static const cairo_surface_backend_t proxy_backend  = {
1075     CAIRO_INTERNAL_SURFACE_TYPE_NULL,
1076     proxy_finish,
1077     NULL,
1078
1079     NULL, /* create similar */
1080     NULL, /* create similar image */
1081     NULL, /* map to image */
1082     NULL, /* unmap image */
1083
1084     _cairo_surface_default_source,
1085     proxy_acquire_source_image,
1086     proxy_release_source_image,
1087 };
1088
1089 static cairo_surface_t *
1090 attach_proxy (cairo_surface_t *source,
1091               cairo_surface_t *image)
1092 {
1093     struct proxy *proxy;
1094
1095     proxy = malloc (sizeof (*proxy));
1096     if (unlikely (proxy == NULL))
1097         return _cairo_surface_create_in_error (CAIRO_STATUS_NO_MEMORY);
1098
1099     _cairo_surface_init (&proxy->base, &proxy_backend, NULL, image->content);
1100
1101     proxy->image = image;
1102     _cairo_surface_attach_snapshot (source, &proxy->base, NULL);
1103
1104     return &proxy->base;
1105 }
1106
1107 static void
1108 detach_proxy (cairo_surface_t *source,
1109               cairo_surface_t *proxy)
1110 {
1111     cairo_surface_finish (proxy);
1112     cairo_surface_destroy (proxy);
1113 }
1114
1115 static cairo_surface_t *
1116 get_proxy (cairo_surface_t *proxy)
1117 {
1118     return ((struct proxy *)proxy)->image;
1119 }
1120
1121 static pixman_image_t *
1122 _pixman_image_for_recording (cairo_image_surface_t *dst,
1123                              const cairo_surface_pattern_t *pattern,
1124                              cairo_bool_t is_mask,
1125                              const cairo_rectangle_int_t *extents,
1126                              const cairo_rectangle_int_t *sample,
1127                              int *ix, int *iy)
1128 {
1129     cairo_surface_t *source, *clone, *proxy;
1130     cairo_rectangle_int_t limit;
1131     pixman_image_t *pixman_image;
1132     cairo_status_t status;
1133     cairo_extend_t extend;
1134     cairo_matrix_t *m, matrix;
1135     int tx = 0, ty = 0;
1136     cairo_surface_t *blurred_surface;
1137
1138     TRACE ((stderr, "%s\n", __FUNCTION__));
1139
1140     *ix = *iy = 0;
1141
1142     source = _cairo_pattern_get_source (pattern, &limit);
1143
1144     extend = pattern->base.extend;
1145     if (_cairo_rectangle_contains_rectangle (&limit, sample))
1146         extend = CAIRO_EXTEND_NONE;
1147     if (extend == CAIRO_EXTEND_NONE) {
1148         if (! _cairo_rectangle_intersect (&limit, sample))
1149             return _pixman_transparent_image ();
1150
1151         if (! _cairo_matrix_is_identity (&pattern->base.matrix)) {
1152             double x1, y1, x2, y2;
1153
1154             matrix = pattern->base.matrix;
1155             status = cairo_matrix_invert (&matrix);
1156             assert (status == CAIRO_STATUS_SUCCESS);
1157
1158             x1 = limit.x;
1159             y1 = limit.y;
1160             x2 = limit.x + limit.width;
1161             y2 = limit.y + limit.height;
1162
1163             _cairo_matrix_transform_bounding_box (&matrix,
1164                                                   &x1, &y1, &x2, &y2, NULL);
1165
1166             limit.x = floor (x1);
1167             limit.y = floor (y1);
1168             limit.width  = ceil (x2) - limit.x;
1169             limit.height = ceil (y2) - limit.y;
1170         }
1171     }
1172     tx = limit.x;
1173     ty = limit.y;
1174
1175     /* XXX transformations! */
1176     proxy = _cairo_surface_has_snapshot (source, &proxy_backend);
1177     if (proxy != NULL) {
1178         clone = cairo_surface_reference (get_proxy (proxy));
1179         goto done;
1180     }
1181
1182     if (is_mask) {
1183             clone = cairo_image_surface_create (CAIRO_FORMAT_A8,
1184                                                 limit.width, limit.height);
1185     } else {
1186         if (dst->base.content == source->content)
1187             clone = cairo_image_surface_create (dst->format,
1188                                                 limit.width, limit.height);
1189         else
1190             clone = _cairo_image_surface_create_with_content (source->content,
1191                                                               limit.width,
1192                                                               limit.height);
1193     }
1194
1195     m = NULL;
1196     if (extend == CAIRO_EXTEND_NONE) {
1197         matrix = pattern->base.matrix;
1198         if (tx | ty)
1199             cairo_matrix_translate (&matrix, tx, ty);
1200         m = &matrix;
1201     } else {
1202         /* XXX extract scale factor for repeating patterns */
1203     }
1204
1205     /* Handle recursion by returning future reads from the current image */
1206     proxy = attach_proxy (source, clone);
1207     status = _cairo_recording_surface_replay_with_clip (source, m, clone, NULL);
1208     detach_proxy (source, proxy);
1209     if (unlikely (status)) {
1210         cairo_surface_destroy (clone);
1211         return NULL;
1212     }
1213
1214 done:
1215     /* filter with gaussian */
1216     blurred_surface = _cairo_image_gaussian_filter (clone,  &pattern->base);
1217     
1218     pixman_image = pixman_image_ref (((cairo_image_surface_t *)blurred_surface)->pixman_image);
1219     cairo_surface_destroy (blurred_surface);
1220     cairo_surface_destroy (clone);
1221
1222     *ix = -limit.x;
1223     *iy = -limit.y;
1224     if (extend != CAIRO_EXTEND_NONE) {
1225         if (! _pixman_image_set_properties (pixman_image,
1226                                             &pattern->base, extents,
1227                                             ix, iy)) {
1228             pixman_image_unref (pixman_image);
1229             pixman_image= NULL;
1230         }
1231     }
1232
1233     return pixman_image;
1234 }
1235
1236 static pixman_image_t *
1237 _pixman_image_for_surface (cairo_image_surface_t *dst,
1238                            const cairo_surface_pattern_t *pattern,
1239                            cairo_bool_t is_mask,
1240                            const cairo_rectangle_int_t *extents,
1241                            const cairo_rectangle_int_t *sample,
1242                            int *ix, int *iy)
1243 {
1244     cairo_extend_t extend = pattern->base.extend;
1245     pixman_image_t *pixman_image = NULL;
1246     pixman_image_t *blurred_pixman_image = NULL;
1247     cairo_surface_t *blurred_surface = NULL;
1248
1249     TRACE ((stderr, "%s\n", __FUNCTION__));
1250
1251     *ix = *iy = 0;
1252     pixman_image = NULL;
1253     if (pattern->surface->type == CAIRO_SURFACE_TYPE_RECORDING)
1254         return _pixman_image_for_recording(dst, pattern,
1255                                            is_mask, extents, sample,
1256                                            ix, iy);
1257
1258     if (pattern->surface->type == CAIRO_SURFACE_TYPE_IMAGE &&
1259         (! is_mask || ! pattern->base.has_component_alpha ||
1260          (pattern->surface->content & CAIRO_CONTENT_COLOR) == 0))
1261     {
1262         cairo_surface_t *defer_free = NULL;
1263         cairo_image_surface_t *source = (cairo_image_surface_t *) pattern->surface;
1264         cairo_surface_type_t type;
1265
1266         if (_cairo_surface_is_snapshot (&source->base)) {
1267             defer_free = _cairo_surface_snapshot_get_target (&source->base);
1268             source = (cairo_image_surface_t *) defer_free;
1269         }
1270
1271         type = source->base.backend->type;
1272         if (type == CAIRO_SURFACE_TYPE_IMAGE) {
1273             if (extend != CAIRO_EXTEND_NONE &&
1274                 sample->x >= 0 &&
1275                 sample->y >= 0 &&
1276                 sample->x + sample->width  <= source->width &&
1277                 sample->y + sample->height <= source->height)
1278             {
1279                 extend = CAIRO_EXTEND_NONE;
1280             }
1281
1282             if (sample->width == 1 && sample->height == 1) {
1283                 if (sample->x < 0 ||
1284                     sample->y < 0 ||
1285                     sample->x >= source->width ||
1286                     sample->y >= source->height)
1287                 {
1288                     if (extend == CAIRO_EXTEND_NONE) {
1289                         cairo_surface_destroy (defer_free);
1290                         return _pixman_transparent_image ();
1291                     }
1292                 }
1293                 else
1294                 {
1295                     pixman_image = _pixel_to_solid (source,
1296                                                     sample->x, sample->y);
1297                     if (pixman_image) {
1298                         cairo_surface_destroy (defer_free);
1299                         return pixman_image;
1300                     }
1301                 }
1302             }
1303
1304 #if PIXMAN_HAS_ATOMIC_OPS
1305             /* avoid allocating a 'pattern' image if we can reuse the original */
1306             if (extend == CAIRO_EXTEND_NONE &&
1307                 _cairo_matrix_is_pixman_translation (&pattern->base.matrix,
1308                                                      pattern->base.filter,
1309                                                      ix, iy))
1310             {
1311                 cairo_surface_destroy (defer_free);
1312                 /* filter with gaussian */
1313                 if (pattern->filter == CAIRO_FILTER_GAUSSIAN) {
1314                     blurred_surface = _cairo_image_gaussian_filter (&source->base,  &pattern->base);
1315                     blurred_pixman_image = pixman_image_ref (((cairo_image_surface_t *)blurred_surface)->pixman_image);
1316                     cairo_surface_destroy (blurred_surface);
1317                     return blurred_pixman_image;
1318                 }
1319                 else
1320                     return pixman_image_ref (source->pixman_image);
1321             }
1322 #endif
1323
1324             if (pattern->base.filter != CAIRO_FILTER_GAUSSIAN) {
1325                 pixman_image = pixman_image_create_bits (source->pixman_format,
1326                                                          source->width,
1327                                                          source->height,
1328                                                          (uint32_t *) source->data,
1329                                                          source->stride);
1330                 if (unlikely (pixman_image == NULL)) {
1331                     cairo_surface_destroy (defer_free);
1332                     if (blurred_surface)
1333                     cairo_surface_destroy (blurred_surface);
1334                     if (blurred_pixman_image)
1335                         pixman_image_unref (blurred_pixman_image);
1336                     return NULL;
1337                 }
1338
1339                 if (defer_free) {
1340                     pixman_image_set_destroy_function (pixman_image,
1341                                                        _defer_free_cleanup,
1342                                                        defer_free);
1343                 }
1344             }
1345             else
1346                 blurred_surface = _cairo_image_gaussian_filter (&source->base,  &pattern->base);
1347         } else if (type == CAIRO_SURFACE_TYPE_SUBSURFACE) {
1348             cairo_surface_subsurface_t *sub;
1349             cairo_bool_t is_contained = FALSE;
1350
1351             sub = (cairo_surface_subsurface_t *) source;
1352             source = (cairo_image_surface_t *) sub->target;
1353
1354             if (sample->x >= 0 &&
1355                 sample->y >= 0 &&
1356                 sample->x + sample->width  <= sub->extents.width &&
1357                 sample->y + sample->height <= sub->extents.height)
1358             {
1359                 is_contained = TRUE;
1360             }
1361
1362             if (sample->width == 1 && sample->height == 1) {
1363                 if (is_contained) {
1364                     pixman_image = _pixel_to_solid (source,
1365                                                     sub->extents.x + sample->x,
1366                                                     sub->extents.y + sample->y);
1367                     if (pixman_image)
1368                         return pixman_image;
1369                 } else {
1370                     if (extend == CAIRO_EXTEND_NONE)
1371                         return _pixman_transparent_image ();
1372                 }
1373             }
1374
1375 #if PIXMAN_HAS_ATOMIC_OPS
1376             *ix = sub->extents.x;
1377             *iy = sub->extents.y;
1378             if (is_contained &&
1379                 _cairo_matrix_is_pixman_translation (&pattern->base.matrix,
1380                                                      pattern->base.filter,
1381                                                      ix, iy))
1382             {
1383                 /* filter with gaussian */
1384                 if (pattern->filter == CAIRO_FILTER_GAUSSIAN) {
1385                     blurred_surface = _cairo_image_gaussian_filter (&source->base,  &pattern->base);
1386                     blurred_pixman_image = pixman_image_ref (((cairo_image_surface_t *)blurred_surface)->pixman_image);
1387                     cairo_surface_destroy (blurred_surface);
1388                     return blurred_pixman_image;
1389                 }
1390             }
1391 #endif
1392
1393             /* Avoid sub-byte offsets, force a copy in that case. */
1394             if (pattern->base.filter != CAIRO_FILTER_GAUSSIAN) {
1395                 if (PIXMAN_FORMAT_BPP (source->pixman_format) >= 8) {
1396                     if (is_contained) {
1397                         void *data = source->data
1398                             + sub->extents.x * PIXMAN_FORMAT_BPP(source->pixman_format)/8
1399                             + sub->extents.y * source->stride;
1400                         pixman_image = pixman_image_create_bits (source->pixman_format,
1401                                                                  sub->extents.width,
1402                                                                  sub->extents.height,
1403                                                                  data,
1404                                                                  source->stride);
1405                         if (unlikely (pixman_image == NULL)) {
1406                             if (blurred_surface)
1407                                 cairo_surface_destroy (blurred_surface);
1408                             if (blurred_pixman_image)
1409                                 pixman_image_unref (blurred_pixman_image);
1410                             return NULL;
1411                         }
1412                     } else {
1413                     /* XXX for a simple translation and EXTEND_NONE we can
1414                      * fix up the pattern matrix instead.
1415                      */
1416                     }
1417                 }
1418             }
1419             else
1420             /* filter */
1421                 blurred_surface = _cairo_image_gaussian_filter (&source->base,  &pattern->base);
1422         }
1423     }
1424
1425     if (pixman_image == NULL && blurred_surface == NULL) {
1426         struct acquire_source_cleanup *cleanup;
1427         cairo_image_surface_t *image;
1428         void *extra;
1429         cairo_status_t status;
1430
1431         status = _cairo_surface_acquire_source_image (pattern->surface, &image, &extra);
1432         if (unlikely (status)) {
1433             if (blurred_surface)
1434                 cairo_surface_destroy (blurred_surface);
1435             if (blurred_pixman_image)
1436                 pixman_image_unref (blurred_pixman_image);
1437             return NULL;
1438         }
1439
1440         if (pattern->base.filter != CAIRO_FILTER_GAUSSIAN) {
1441             pixman_image = pixman_image_create_bits (image->pixman_format,
1442                                                      image->width,
1443                                                      image->height,
1444                                                      (uint32_t *) image->data,
1445                                                      image->stride);
1446             if (unlikely (pixman_image == NULL)) {
1447                 _cairo_surface_release_source_image (pattern->surface, image, extra);
1448                 if (blurred_surface)
1449                     cairo_surface_destroy (blurred_surface);
1450                 if (blurred_pixman_image)
1451                     pixman_image_unref (blurred_pixman_image);
1452                 return NULL;
1453             }
1454         }
1455         else
1456         /* filter with gaussian */
1457             blurred_surface = _cairo_image_gaussian_filter (&image->base,  &pattern->base);
1458
1459         cleanup = malloc (sizeof (*cleanup));
1460         if (unlikely (cleanup == NULL)) {
1461             _cairo_surface_release_source_image (pattern->surface, image, extra);
1462             if (pixman_image)
1463                 pixman_image_unref (pixman_image);
1464             if (blurred_surface)
1465                 cairo_surface_destroy (blurred_surface);
1466             if (blurred_pixman_image)
1467                 pixman_image_unref (blurred_pixman_image);
1468             return NULL;
1469         }
1470
1471         if (pixman_image) {
1472             cleanup->surface = pattern->surface;
1473             cleanup->image = image;
1474             cleanup->image_extra = extra;
1475             pixman_image_set_destroy_function (pixman_image,
1476                                                _acquire_source_cleanup, cleanup);
1477         }
1478     }
1479
1480     if (blurred_surface) {
1481         blurred_pixman_image = pixman_image_ref (((cairo_image_surface_t *)blurred_surface)->pixman_image);
1482         cairo_surface_destroy (blurred_surface);
1483     }
1484
1485     if (blurred_pixman_image) {
1486         if (! _pixman_image_set_properties (blurred_pixman_image,
1487                                             &pattern->base, extents,
1488                                             ix, iy)) {
1489             pixman_image_unref (blurred_pixman_image);
1490             blurred_pixman_image= NULL;
1491         }
1492     }
1493     if (pixman_image) {
1494         if (! _pixman_image_set_properties (pixman_image,
1495                                             &pattern->base, extents,
1496                                             ix, iy)) {
1497             pixman_image_unref (pixman_image);
1498             pixman_image= NULL;
1499         }
1500     }
1501
1502     if (blurred_pixman_image) {
1503         if (pixman_image)
1504             pixman_image_unref (pixman_image);
1505     }
1506     else
1507         blurred_pixman_image = pixman_image;
1508
1509     return blurred_pixman_image;
1510 }
1511
1512 struct raster_source_cleanup {
1513     const cairo_pattern_t *pattern;
1514     cairo_surface_t *surface;
1515     cairo_image_surface_t *image;
1516     void *image_extra;
1517 };
1518
1519 static void
1520 _raster_source_cleanup (pixman_image_t *pixman_image,
1521                         void *closure)
1522 {
1523     struct raster_source_cleanup *data = closure;
1524
1525     _cairo_surface_release_source_image (data->surface,
1526                                          data->image,
1527                                          data->image_extra);
1528
1529     _cairo_raster_source_pattern_release (data->pattern,
1530                                           data->surface);
1531
1532     free (data);
1533 }
1534
1535 static pixman_image_t *
1536 _pixman_image_for_raster (cairo_image_surface_t *dst,
1537                           const cairo_raster_source_pattern_t *pattern,
1538                           cairo_bool_t is_mask,
1539                           const cairo_rectangle_int_t *extents,
1540                           const cairo_rectangle_int_t *sample,
1541                           int *ix, int *iy)
1542 {
1543     pixman_image_t *pixman_image;
1544     struct raster_source_cleanup *cleanup;
1545     cairo_image_surface_t *image;
1546     void *extra;
1547     cairo_status_t status;
1548     cairo_surface_t *surface;
1549
1550     TRACE ((stderr, "%s\n", __FUNCTION__));
1551
1552     *ix = *iy = 0;
1553
1554     surface = _cairo_raster_source_pattern_acquire (&pattern->base,
1555                                                     &dst->base, NULL);
1556     if (unlikely (surface == NULL || surface->status))
1557         return NULL;
1558
1559     status = _cairo_surface_acquire_source_image (surface, &image, &extra);
1560     if (unlikely (status)) {
1561         _cairo_raster_source_pattern_release (&pattern->base, surface);
1562         return NULL;
1563     }
1564
1565     assert (image->width == pattern->extents.width);
1566     assert (image->height == pattern->extents.height);
1567
1568     pixman_image = pixman_image_create_bits (image->pixman_format,
1569                                              image->width,
1570                                              image->height,
1571                                              (uint32_t *) image->data,
1572                                              image->stride);
1573     if (unlikely (pixman_image == NULL)) {
1574         _cairo_surface_release_source_image (surface, image, extra);
1575         _cairo_raster_source_pattern_release (&pattern->base, surface);
1576         return NULL;
1577     }
1578
1579     cleanup = malloc (sizeof (*cleanup));
1580     if (unlikely (cleanup == NULL)) {
1581         pixman_image_unref (pixman_image);
1582         _cairo_surface_release_source_image (surface, image, extra);
1583         _cairo_raster_source_pattern_release (&pattern->base, surface);
1584         return NULL;
1585     }
1586
1587     cleanup->pattern = &pattern->base;
1588     cleanup->surface = surface;
1589     cleanup->image = image;
1590     cleanup->image_extra = extra;
1591     pixman_image_set_destroy_function (pixman_image,
1592                                        _raster_source_cleanup, cleanup);
1593
1594     if (! _pixman_image_set_properties (pixman_image,
1595                                         &pattern->base, extents,
1596                                         ix, iy)) {
1597         pixman_image_unref (pixman_image);
1598         pixman_image= NULL;
1599     }
1600
1601     return pixman_image;
1602 }
1603
1604 pixman_image_t *
1605 _pixman_image_for_pattern (cairo_image_surface_t *dst,
1606                            const cairo_pattern_t *pattern,
1607                            cairo_bool_t is_mask,
1608                            const cairo_rectangle_int_t *extents,
1609                            const cairo_rectangle_int_t *sample,
1610                            int *tx, int *ty)
1611 {
1612     *tx = *ty = 0;
1613
1614     TRACE ((stderr, "%s\n", __FUNCTION__));
1615
1616     if (pattern == NULL)
1617         return _pixman_white_image ();
1618
1619     switch (pattern->type) {
1620     default:
1621         ASSERT_NOT_REACHED;
1622     case CAIRO_PATTERN_TYPE_SOLID:
1623         return _pixman_image_for_color (&((const cairo_solid_pattern_t *) pattern)->color);
1624
1625     case CAIRO_PATTERN_TYPE_RADIAL:
1626     case CAIRO_PATTERN_TYPE_LINEAR:
1627         return _pixman_image_for_gradient ((const cairo_gradient_pattern_t *) pattern,
1628                                            extents, tx, ty);
1629
1630     case CAIRO_PATTERN_TYPE_MESH:
1631         return _pixman_image_for_mesh ((const cairo_mesh_pattern_t *) pattern,
1632                                            extents, tx, ty);
1633
1634     case CAIRO_PATTERN_TYPE_SURFACE:
1635         return _pixman_image_for_surface (dst,
1636                                           (const cairo_surface_pattern_t *) pattern,
1637                                           is_mask, extents, sample,
1638                                           tx, ty);
1639
1640     case CAIRO_PATTERN_TYPE_RASTER_SOURCE:
1641         return _pixman_image_for_raster (dst,
1642                                          (const cairo_raster_source_pattern_t *) pattern,
1643                                          is_mask, extents, sample,
1644                                          tx, ty);
1645     }
1646 }
1647
1648 static cairo_status_t
1649 _cairo_image_source_finish (void *abstract_surface)
1650 {
1651     cairo_image_source_t *source = abstract_surface;
1652
1653     pixman_image_unref (source->pixman_image);
1654     return CAIRO_STATUS_SUCCESS;
1655 }
1656
1657 const cairo_surface_backend_t _cairo_image_source_backend = {
1658     CAIRO_SURFACE_TYPE_IMAGE,
1659     _cairo_image_source_finish,
1660     NULL, /* read-only wrapper */
1661 };
1662
1663 cairo_surface_t *
1664 _cairo_image_source_create_for_pattern (cairo_surface_t *dst,
1665                                          const cairo_pattern_t *pattern,
1666                                          cairo_bool_t is_mask,
1667                                          const cairo_rectangle_int_t *extents,
1668                                          const cairo_rectangle_int_t *sample,
1669                                          int *src_x, int *src_y)
1670 {
1671     cairo_image_source_t *source;
1672
1673     TRACE ((stderr, "%s\n", __FUNCTION__));
1674
1675     source = malloc (sizeof (cairo_image_source_t));
1676     if (unlikely (source == NULL))
1677         return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
1678
1679     source->pixman_image =
1680         _pixman_image_for_pattern ((cairo_image_surface_t *)dst,
1681                                    pattern, is_mask,
1682                                    extents, sample,
1683                                    src_x, src_y);
1684     if (unlikely (source->pixman_image == NULL)) {
1685         free (source);
1686         return _cairo_surface_create_in_error (CAIRO_STATUS_NO_MEMORY);
1687     }
1688
1689     _cairo_surface_init (&source->base,
1690                          &_cairo_image_source_backend,
1691                          NULL, /* device */
1692                          CAIRO_CONTENT_COLOR_ALPHA);
1693
1694     source->is_opaque_solid =
1695         pattern == NULL || _cairo_pattern_is_opaque_solid (pattern);
1696
1697     return &source->base;
1698 }