6adbdd61f19b33db5883d89d92dfb5cf8462a923
[framework/graphics/cairo.git] / src / cairo-image-surface.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 #include "cairoint.h"
41
42 #include "cairo-boxes-private.h"
43 #include "cairo-clip-private.h"
44 #include "cairo-composite-rectangles-private.h"
45 #include "cairo-compositor-private.h"
46 #include "cairo-default-context-private.h"
47 #include "cairo-error-private.h"
48 #include "cairo-image-surface-private.h"
49 #include "cairo-paginated-private.h"
50 #include "cairo-pattern-private.h"
51 #include "cairo-recording-surface-private.h"
52 #include "cairo-region-private.h"
53 #include "cairo-scaled-font-private.h"
54 #include "cairo-surface-snapshot-private.h"
55 #include "cairo-surface-subsurface-private.h"
56
57 /* Limit on the width / height of an image surface in pixels.  This is
58  * mainly determined by coordinates of things sent to pixman at the
59  * moment being in 16.16 format. */
60 #define MAX_IMAGE_SIZE 32767
61
62 /**
63  * SECTION:cairo-image
64  * @Title: Image Surfaces
65  * @Short_Description: Rendering to memory buffers
66  * @See_Also: #cairo_surface_t
67  *
68  * Image surfaces provide the ability to render to memory buffers
69  * either allocated by cairo or by the calling code.  The supported
70  * image formats are those defined in #cairo_format_t.
71  */
72
73 /**
74  * CAIRO_HAS_IMAGE_SURFACE:
75  *
76  * Defined if the image surface backend is available.
77  * The image surface backend is always built in.
78  * This macro was added for completeness in cairo 1.8.
79  *
80  * @Since: 1.8
81  */
82
83 static cairo_bool_t
84 _cairo_image_surface_is_size_valid (int width, int height)
85 {
86     return 0 <= width  &&  width <= MAX_IMAGE_SIZE &&
87            0 <= height && height <= MAX_IMAGE_SIZE;
88 }
89
90 cairo_format_t
91 _cairo_format_from_pixman_format (pixman_format_code_t pixman_format)
92 {
93     switch (pixman_format) {
94     case PIXMAN_a8r8g8b8:
95         return CAIRO_FORMAT_ARGB32;
96     case PIXMAN_x2r10g10b10:
97         return CAIRO_FORMAT_RGB30;
98     case PIXMAN_x8r8g8b8:
99         return CAIRO_FORMAT_RGB24;
100     case PIXMAN_a8:
101         return CAIRO_FORMAT_A8;
102     case PIXMAN_a1:
103         return CAIRO_FORMAT_A1;
104     case PIXMAN_r5g6b5:
105         return CAIRO_FORMAT_RGB16_565;
106     case PIXMAN_r8g8b8a8: case PIXMAN_r8g8b8x8:
107     case PIXMAN_a8b8g8r8: case PIXMAN_x8b8g8r8: case PIXMAN_r8g8b8:
108     case PIXMAN_b8g8r8:   case PIXMAN_b5g6r5:
109     case PIXMAN_a1r5g5b5: case PIXMAN_x1r5g5b5: case PIXMAN_a1b5g5r5:
110     case PIXMAN_x1b5g5r5: case PIXMAN_a4r4g4b4: case PIXMAN_x4r4g4b4:
111     case PIXMAN_a4b4g4r4: case PIXMAN_x4b4g4r4: case PIXMAN_r3g3b2:
112     case PIXMAN_b2g3r3:   case PIXMAN_a2r2g2b2: case PIXMAN_a2b2g2r2:
113     case PIXMAN_c8:       case PIXMAN_g8:       case PIXMAN_x4a4:
114     case PIXMAN_a4:       case PIXMAN_r1g2b1:   case PIXMAN_b1g2r1:
115     case PIXMAN_a1r1g1b1: case PIXMAN_a1b1g1r1: case PIXMAN_c4:
116     case PIXMAN_g4:       case PIXMAN_g1:
117     case PIXMAN_yuy2:     case PIXMAN_yv12:
118     case PIXMAN_b8g8r8x8:
119     case PIXMAN_b8g8r8a8:
120     case PIXMAN_a2b10g10r10:
121     case PIXMAN_x2b10g10r10:
122     case PIXMAN_a2r10g10b10:
123     case PIXMAN_x14r6g6b6:
124     default:
125         return CAIRO_FORMAT_INVALID;
126     }
127
128     return CAIRO_FORMAT_INVALID;
129 }
130
131 cairo_content_t
132 _cairo_content_from_pixman_format (pixman_format_code_t pixman_format)
133 {
134     cairo_content_t content;
135
136     content = 0;
137     if (PIXMAN_FORMAT_RGB (pixman_format))
138         content |= CAIRO_CONTENT_COLOR;
139     if (PIXMAN_FORMAT_A (pixman_format))
140         content |= CAIRO_CONTENT_ALPHA;
141
142     return content;
143 }
144
145 void
146 _cairo_image_surface_init (cairo_image_surface_t *surface,
147                            pixman_image_t       *pixman_image,
148                            pixman_format_code_t  pixman_format)
149 {
150     surface->pixman_image = pixman_image;
151
152     surface->pixman_format = pixman_format;
153     surface->format = _cairo_format_from_pixman_format (pixman_format);
154     surface->data = (uint8_t *) pixman_image_get_data (pixman_image);
155     surface->owns_data = FALSE;
156     surface->transparency = CAIRO_IMAGE_UNKNOWN;
157     surface->color = CAIRO_IMAGE_UNKNOWN_COLOR;
158
159     surface->width = pixman_image_get_width (pixman_image);
160     surface->height = pixman_image_get_height (pixman_image);
161     surface->stride = pixman_image_get_stride (pixman_image);
162     surface->depth = pixman_image_get_depth (pixman_image);
163
164     surface->base.is_clear = surface->width == 0 || surface->height == 0;
165
166     surface->compositor = _cairo_image_spans_compositor_get ();
167 }
168
169 cairo_surface_t *
170 _cairo_image_surface_create_for_pixman_image (pixman_image_t            *pixman_image,
171                                               pixman_format_code_t       pixman_format)
172 {
173     cairo_image_surface_t *surface;
174
175     surface = malloc (sizeof (cairo_image_surface_t));
176     if (unlikely (surface == NULL))
177         return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
178
179     _cairo_surface_init (&surface->base,
180                          &_cairo_image_surface_backend,
181                          NULL, /* device */
182                          _cairo_content_from_pixman_format (pixman_format));
183
184     _cairo_image_surface_init (surface, pixman_image, pixman_format);
185
186     return &surface->base;
187 }
188
189 cairo_bool_t
190 _pixman_format_from_masks (cairo_format_masks_t *masks,
191                            pixman_format_code_t *format_ret)
192 {
193     pixman_format_code_t format;
194     int format_type;
195     int a, r, g, b;
196     cairo_format_masks_t format_masks;
197
198     a = _cairo_popcount (masks->alpha_mask);
199     r = _cairo_popcount (masks->red_mask);
200     g = _cairo_popcount (masks->green_mask);
201     b = _cairo_popcount (masks->blue_mask);
202
203     if (masks->red_mask) {
204         if (masks->red_mask > masks->blue_mask)
205             format_type = PIXMAN_TYPE_ARGB;
206         else
207             format_type = PIXMAN_TYPE_ABGR;
208     } else if (masks->alpha_mask) {
209         format_type = PIXMAN_TYPE_A;
210     } else {
211         return FALSE;
212     }
213
214     format = PIXMAN_FORMAT (masks->bpp, format_type, a, r, g, b);
215
216     if (! pixman_format_supported_destination (format))
217         return FALSE;
218
219     /* Sanity check that we got out of PIXMAN_FORMAT exactly what we
220      * expected. This avoid any problems from something bizarre like
221      * alpha in the least-significant bits, or insane channel order,
222      * or whatever. */
223      if (!_pixman_format_to_masks (format, &format_masks) ||
224          masks->bpp        != format_masks.bpp            ||
225          masks->red_mask   != format_masks.red_mask       ||
226          masks->green_mask != format_masks.green_mask     ||
227          masks->blue_mask  != format_masks.blue_mask)
228      {
229          return FALSE;
230      }
231
232     *format_ret = format;
233     return TRUE;
234 }
235
236 /* A mask consisting of N bits set to 1. */
237 #define MASK(N) ((1UL << (N))-1)
238
239 cairo_bool_t
240 _pixman_format_to_masks (pixman_format_code_t    format,
241                          cairo_format_masks_t   *masks)
242 {
243     int a, r, g, b;
244
245     masks->bpp = PIXMAN_FORMAT_BPP (format);
246
247     /* Number of bits in each channel */
248     a = PIXMAN_FORMAT_A (format);
249     r = PIXMAN_FORMAT_R (format);
250     g = PIXMAN_FORMAT_G (format);
251     b = PIXMAN_FORMAT_B (format);
252
253     switch (PIXMAN_FORMAT_TYPE (format)) {
254     case PIXMAN_TYPE_ARGB:
255         masks->alpha_mask = MASK (a) << (r + g + b);
256         masks->red_mask   = MASK (r) << (g + b);
257         masks->green_mask = MASK (g) << (b);
258         masks->blue_mask  = MASK (b);
259         return TRUE;
260     case PIXMAN_TYPE_ABGR:
261         masks->alpha_mask = MASK (a) << (b + g + r);
262         masks->blue_mask  = MASK (b) << (g + r);
263         masks->green_mask = MASK (g) << (r);
264         masks->red_mask   = MASK (r);
265         return TRUE;
266 #ifdef PIXMAN_TYPE_BGRA
267     case PIXMAN_TYPE_BGRA:
268         masks->blue_mask  = MASK (b) << (masks->bpp - b);
269         masks->green_mask = MASK (g) << (masks->bpp - b - g);
270         masks->red_mask   = MASK (r) << (masks->bpp - b - g - r);
271         masks->alpha_mask = MASK (a);
272         return TRUE;
273 #endif
274     case PIXMAN_TYPE_A:
275         masks->alpha_mask = MASK (a);
276         masks->red_mask   = 0;
277         masks->green_mask = 0;
278         masks->blue_mask  = 0;
279         return TRUE;
280     case PIXMAN_TYPE_OTHER:
281     case PIXMAN_TYPE_COLOR:
282     case PIXMAN_TYPE_GRAY:
283     case PIXMAN_TYPE_YUY2:
284     case PIXMAN_TYPE_YV12:
285     default:
286         masks->alpha_mask = 0;
287         masks->red_mask   = 0;
288         masks->green_mask = 0;
289         masks->blue_mask  = 0;
290         return FALSE;
291     }
292 }
293
294 pixman_format_code_t
295 _cairo_format_to_pixman_format_code (cairo_format_t format)
296 {
297     pixman_format_code_t ret;
298     switch (format) {
299     case CAIRO_FORMAT_A1:
300         ret = PIXMAN_a1;
301         break;
302     case CAIRO_FORMAT_A8:
303         ret = PIXMAN_a8;
304         break;
305     case CAIRO_FORMAT_RGB24:
306         ret = PIXMAN_x8r8g8b8;
307         break;
308     case CAIRO_FORMAT_RGB30:
309         ret = PIXMAN_x2r10g10b10;
310         break;
311     case CAIRO_FORMAT_RGB16_565:
312         ret = PIXMAN_r5g6b5;
313         break;
314     case CAIRO_FORMAT_ARGB32:
315     case CAIRO_FORMAT_INVALID:
316     default:
317         ret = PIXMAN_a8r8g8b8;
318         break;
319     }
320     return ret;
321 }
322
323 cairo_surface_t *
324 _cairo_image_surface_create_with_pixman_format (unsigned char           *data,
325                                                 pixman_format_code_t     pixman_format,
326                                                 int                      width,
327                                                 int                      height,
328                                                 int                      stride)
329 {
330     cairo_surface_t *surface;
331     pixman_image_t *pixman_image;
332
333     if (! _cairo_image_surface_is_size_valid (width, height))
334     {
335         return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_SIZE));
336     }
337
338     pixman_image = pixman_image_create_bits (pixman_format, width, height,
339                                              (uint32_t *) data, stride);
340
341     if (unlikely (pixman_image == NULL))
342         return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
343
344     surface = _cairo_image_surface_create_for_pixman_image (pixman_image,
345                                                             pixman_format);
346     if (unlikely (surface->status)) {
347         pixman_image_unref (pixman_image);
348         return surface;
349     }
350
351     /* we can not make any assumptions about the initial state of user data */
352     surface->is_clear = data == NULL;
353     return surface;
354 }
355
356 /**
357  * cairo_image_surface_create:
358  * @format: format of pixels in the surface to create
359  * @width: width of the surface, in pixels
360  * @height: height of the surface, in pixels
361  *
362  * Creates an image surface of the specified format and
363  * dimensions. Initially the surface contents are all
364  * 0. (Specifically, within each pixel, each color or alpha channel
365  * belonging to format will be 0. The contents of bits within a pixel,
366  * but not belonging to the given format are undefined).
367  *
368  * Return value: a pointer to the newly created surface. The caller
369  * owns the surface and should call cairo_surface_destroy() when done
370  * with it.
371  *
372  * This function always returns a valid pointer, but it will return a
373  * pointer to a "nil" surface if an error such as out of memory
374  * occurs. You can use cairo_surface_status() to check for this.
375  **/
376 cairo_surface_t *
377 cairo_image_surface_create (cairo_format_t      format,
378                             int                 width,
379                             int                 height)
380 {
381     pixman_format_code_t pixman_format;
382
383     if (! CAIRO_FORMAT_VALID (format))
384         return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_FORMAT));
385
386     pixman_format = _cairo_format_to_pixman_format_code (format);
387
388     return _cairo_image_surface_create_with_pixman_format (NULL, pixman_format,
389                                                            width, height, -1);
390 }
391 slim_hidden_def (cairo_image_surface_create);
392
393     cairo_surface_t *
394 _cairo_image_surface_create_with_content (cairo_content_t       content,
395                                           int                   width,
396                                           int                   height)
397 {
398     return cairo_image_surface_create (_cairo_format_from_content (content),
399                                        width, height);
400 }
401
402 /**
403  * cairo_format_stride_for_width:
404  * @format: A #cairo_format_t value
405  * @width: The desired width of an image surface to be created.
406  *
407  * This function provides a stride value that will respect all
408  * alignment requirements of the accelerated image-rendering code
409  * within cairo. Typical usage will be of the form:
410  *
411  * <informalexample><programlisting>
412  * int stride;
413  * unsigned char *data;
414  * #cairo_surface_t *surface;
415  *
416  * stride = cairo_format_stride_for_width (format, width);
417  * data = malloc (stride * height);
418  * surface = cairo_image_surface_create_for_data (data, format,
419  *                                                width, height,
420  *                                                stride);
421  * </programlisting></informalexample>
422  *
423  * Return value: the appropriate stride to use given the desired
424  * format and width, or -1 if either the format is invalid or the width
425  * too large.
426  *
427  * Since: 1.6
428  **/
429     int
430 cairo_format_stride_for_width (cairo_format_t   format,
431                                int              width)
432 {
433     int bpp;
434
435     if (! CAIRO_FORMAT_VALID (format)) {
436         _cairo_error_throw (CAIRO_STATUS_INVALID_FORMAT);
437         return -1;
438     }
439
440     bpp = _cairo_format_bits_per_pixel (format);
441     if ((unsigned) (width) >= (INT32_MAX - 7) / (unsigned) (bpp))
442         return -1;
443
444     return CAIRO_STRIDE_FOR_WIDTH_BPP (width, bpp);
445 }
446 slim_hidden_def (cairo_format_stride_for_width);
447
448 /**
449  * cairo_image_surface_create_for_data:
450  * @data: a pointer to a buffer supplied by the application in which
451  *     to write contents. This pointer must be suitably aligned for any
452  *     kind of variable, (for example, a pointer returned by malloc).
453  * @format: the format of pixels in the buffer
454  * @width: the width of the image to be stored in the buffer
455  * @height: the height of the image to be stored in the buffer
456  * @stride: the number of bytes between the start of rows in the
457  *     buffer as allocated. This value should always be computed by
458  *     cairo_format_stride_for_width() before allocating the data
459  *     buffer.
460  *
461  * Creates an image surface for the provided pixel data. The output
462  * buffer must be kept around until the #cairo_surface_t is destroyed
463  * or cairo_surface_finish() is called on the surface.  The initial
464  * contents of @data will be used as the initial image contents; you
465  * must explicitly clear the buffer, using, for example,
466  * cairo_rectangle() and cairo_fill() if you want it cleared.
467  *
468  * Note that the stride may be larger than
469  * width*bytes_per_pixel to provide proper alignment for each pixel
470  * and row. This alignment is required to allow high-performance rendering
471  * within cairo. The correct way to obtain a legal stride value is to
472  * call cairo_format_stride_for_width() with the desired format and
473  * maximum image width value, and then use the resulting stride value
474  * to allocate the data and to create the image surface. See
475  * cairo_format_stride_for_width() for example code.
476  *
477  * Return value: a pointer to the newly created surface. The caller
478  * owns the surface and should call cairo_surface_destroy() when done
479  * with it.
480  *
481  * This function always returns a valid pointer, but it will return a
482  * pointer to a "nil" surface in the case of an error such as out of
483  * memory or an invalid stride value. In case of invalid stride value
484  * the error status of the returned surface will be
485  * %CAIRO_STATUS_INVALID_STRIDE.  You can use
486  * cairo_surface_status() to check for this.
487  *
488  * See cairo_surface_set_user_data() for a means of attaching a
489  * destroy-notification fallback to the surface if necessary.
490  **/
491     cairo_surface_t *
492 cairo_image_surface_create_for_data (unsigned char     *data,
493                                      cairo_format_t     format,
494                                      int                width,
495                                      int                height,
496                                      int                stride)
497 {
498     pixman_format_code_t pixman_format;
499     int minstride;
500
501     if (! CAIRO_FORMAT_VALID (format))
502         return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_FORMAT));
503
504     if ((stride & (CAIRO_STRIDE_ALIGNMENT-1)) != 0)
505         return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_STRIDE));
506
507     if (! _cairo_image_surface_is_size_valid (width, height))
508         return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_SIZE));
509
510     minstride = cairo_format_stride_for_width (format, width);
511     if (stride < 0) {
512         if (stride > -minstride) {
513             return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_STRIDE));
514         }
515     } else {
516         if (stride < minstride) {
517             return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_STRIDE));
518         }
519     }
520
521     pixman_format = _cairo_format_to_pixman_format_code (format);
522     return _cairo_image_surface_create_with_pixman_format (data,
523                                                            pixman_format,
524                                                            width, height,
525                                                            stride);
526 }
527 slim_hidden_def (cairo_image_surface_create_for_data);
528
529 /**
530  * cairo_image_surface_get_data:
531  * @surface: a #cairo_image_surface_t
532  *
533  * Get a pointer to the data of the image surface, for direct
534  * inspection or modification.
535  *
536  * A call to cairo_surface_flush() is required before accessing the
537  * pixel data to ensure that all pending drawing operations are
538  * finished. A call to cairo_surface_mark_dirty() is required after
539  * the data is modified.
540  *
541  * Return value: a pointer to the image data of this surface or %NULL
542  * if @surface is not an image surface, or if cairo_surface_finish()
543  * has been called.
544  *
545  * Since: 1.2
546  **/
547     unsigned char *
548 cairo_image_surface_get_data (cairo_surface_t *surface)
549 {
550     cairo_image_surface_t *image_surface = (cairo_image_surface_t *) surface;
551
552     if (! _cairo_surface_is_image (surface)) {
553         _cairo_error_throw (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
554         return NULL;
555     }
556
557     return image_surface->data;
558 }
559 slim_hidden_def (cairo_image_surface_get_data);
560
561 /**
562  * cairo_image_surface_get_format:
563  * @surface: a #cairo_image_surface_t
564  *
565  * Get the format of the surface.
566  *
567  * Return value: the format of the surface
568  *
569  * Since: 1.2
570  **/
571     cairo_format_t
572 cairo_image_surface_get_format (cairo_surface_t *surface)
573 {
574     cairo_image_surface_t *image_surface = (cairo_image_surface_t *) surface;
575
576     if (! _cairo_surface_is_image (surface)) {
577         _cairo_error_throw (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
578         return CAIRO_FORMAT_INVALID;
579     }
580
581     return image_surface->format;
582 }
583 slim_hidden_def (cairo_image_surface_get_format);
584
585 /**
586  * cairo_image_surface_get_width:
587  * @surface: a #cairo_image_surface_t
588  *
589  * Get the width of the image surface in pixels.
590  *
591  * Return value: the width of the surface in pixels.
592  **/
593     int
594 cairo_image_surface_get_width (cairo_surface_t *surface)
595 {
596     cairo_image_surface_t *image_surface = (cairo_image_surface_t *) surface;
597
598     if (! _cairo_surface_is_image (surface)) {
599         _cairo_error_throw (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
600         return 0;
601     }
602
603     return image_surface->width;
604 }
605 slim_hidden_def (cairo_image_surface_get_width);
606
607 /**
608  * cairo_image_surface_get_height:
609  * @surface: a #cairo_image_surface_t
610  *
611  * Get the height of the image surface in pixels.
612  *
613  * Return value: the height of the surface in pixels.
614  **/
615     int
616 cairo_image_surface_get_height (cairo_surface_t *surface)
617 {
618     cairo_image_surface_t *image_surface = (cairo_image_surface_t *) surface;
619
620     if (! _cairo_surface_is_image (surface)) {
621         _cairo_error_throw (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
622         return 0;
623     }
624
625     return image_surface->height;
626 }
627 slim_hidden_def (cairo_image_surface_get_height);
628
629 /**
630  * cairo_image_surface_get_stride:
631  * @surface: a #cairo_image_surface_t
632  *
633  * Get the stride of the image surface in bytes
634  *
635  * Return value: the stride of the image surface in bytes (or 0 if
636  * @surface is not an image surface). The stride is the distance in
637  * bytes from the beginning of one row of the image data to the
638  * beginning of the next row.
639  *
640  * Since: 1.2
641  **/
642     int
643 cairo_image_surface_get_stride (cairo_surface_t *surface)
644 {
645
646     cairo_image_surface_t *image_surface = (cairo_image_surface_t *) surface;
647
648     if (! _cairo_surface_is_image (surface)) {
649         _cairo_error_throw (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
650         return 0;
651     }
652
653     return image_surface->stride;
654 }
655 slim_hidden_def (cairo_image_surface_get_stride);
656
657     cairo_format_t
658 _cairo_format_from_content (cairo_content_t content)
659 {
660     switch (content) {
661     case CAIRO_CONTENT_COLOR:
662         return CAIRO_FORMAT_RGB24;
663     case CAIRO_CONTENT_ALPHA:
664         return CAIRO_FORMAT_A8;
665     case CAIRO_CONTENT_COLOR_ALPHA:
666         return CAIRO_FORMAT_ARGB32;
667     }
668
669     ASSERT_NOT_REACHED;
670     return CAIRO_FORMAT_INVALID;
671 }
672
673     cairo_content_t
674 _cairo_content_from_format (cairo_format_t format)
675 {
676     switch (format) {
677     case CAIRO_FORMAT_ARGB32:
678         return CAIRO_CONTENT_COLOR_ALPHA;
679     case CAIRO_FORMAT_RGB30:
680         return CAIRO_CONTENT_COLOR;
681     case CAIRO_FORMAT_RGB24:
682         return CAIRO_CONTENT_COLOR;
683     case CAIRO_FORMAT_RGB16_565:
684         return CAIRO_CONTENT_COLOR;
685     case CAIRO_FORMAT_A8:
686     case CAIRO_FORMAT_A1:
687         return CAIRO_CONTENT_ALPHA;
688     case CAIRO_FORMAT_INVALID:
689         break;
690     }
691
692     ASSERT_NOT_REACHED;
693     return CAIRO_CONTENT_COLOR_ALPHA;
694 }
695
696     int
697 _cairo_format_bits_per_pixel (cairo_format_t format)
698 {
699     switch (format) {
700     case CAIRO_FORMAT_ARGB32:
701     case CAIRO_FORMAT_RGB30:
702     case CAIRO_FORMAT_RGB24:
703         return 32;
704     case CAIRO_FORMAT_RGB16_565:
705         return 16;
706     case CAIRO_FORMAT_A8:
707         return 8;
708     case CAIRO_FORMAT_A1:
709         return 1;
710     case CAIRO_FORMAT_INVALID:
711     default:
712         ASSERT_NOT_REACHED;
713         return 0;
714     }
715 }
716
717     static cairo_surface_t *
718 _cairo_image_surface_create_similar (void              *abstract_other,
719                                      cairo_content_t    content,
720                                      int                width,
721                                      int                height)
722 {
723     cairo_image_surface_t *other = abstract_other;
724
725     if (! _cairo_image_surface_is_size_valid (width, height))
726         return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_SIZE));
727
728     if (content == other->base.content) {
729         return _cairo_image_surface_create_with_pixman_format (NULL,
730                                                                other->pixman_format,
731                                                                width, height,
732                                                                0);
733     }
734
735     return _cairo_image_surface_create_with_content (content,
736                                                      width, height);
737 }
738
739 cairo_surface_t *
740 _cairo_image_surface_snapshot (void *abstract_surface)
741 {
742     cairo_image_surface_t *image = abstract_surface;
743     cairo_image_surface_t *clone;
744
745     clone = (cairo_image_surface_t *)
746         _cairo_image_surface_create_with_pixman_format (NULL,
747                                                         image->pixman_format,
748                                                         image->width,
749                                                         image->height,
750                                                         0);
751     if (unlikely (clone->base.status))
752         return &clone->base;
753
754     if (clone->stride == image->stride) {
755         memcpy (clone->data, image->data, clone->stride * clone->height);
756     } else {
757         pixman_image_composite32 (PIXMAN_OP_SRC,
758                                   image->pixman_image, NULL, clone->pixman_image,
759                                   0, 0,
760                                   0, 0,
761                                   0, 0,
762                                   image->width, image->height);
763     }
764     clone->base.is_clear = FALSE;
765     return &clone->base;
766 }
767
768 cairo_surface_t *
769 _cairo_image_surface_map_to_image (void *abstract_other,
770                                    const cairo_rectangle_int_t *extents)
771 {
772     cairo_image_surface_t *other = abstract_other;
773     cairo_surface_t *surface;
774     uint8_t *data;
775
776     data = other->data;
777     data += extents->y * other->stride;
778     data += extents->x * PIXMAN_FORMAT_BPP (other->pixman_format)/ 8;
779
780     surface =
781         _cairo_image_surface_create_with_pixman_format (data,
782                                                         other->pixman_format,
783                                                         extents->width,
784                                                         extents->height,
785                                                         other->stride);
786
787     cairo_surface_set_device_offset (surface, -extents->x, -extents->y);
788     return surface;
789 }
790
791 cairo_int_status_t
792 _cairo_image_surface_unmap_image (void *abstract_surface,
793                                   cairo_image_surface_t *image)
794 {
795     return CAIRO_INT_STATUS_SUCCESS;
796 }
797
798 cairo_status_t
799 _cairo_image_surface_finish (void *abstract_surface)
800 {
801     cairo_image_surface_t *surface = abstract_surface;
802
803     if (surface->pixman_image) {
804         pixman_image_unref (surface->pixman_image);
805         surface->pixman_image = NULL;
806     }
807
808     if (surface->owns_data) {
809         free (surface->data);
810         surface->data = NULL;
811     }
812
813     return CAIRO_STATUS_SUCCESS;
814 }
815
816 void
817 _cairo_image_surface_assume_ownership_of_data (cairo_image_surface_t *surface)
818 {
819     surface->owns_data = TRUE;
820 }
821
822 cairo_status_t
823 _cairo_image_surface_acquire_source_image (void                    *abstract_surface,
824                                            cairo_image_surface_t  **image_out,
825                                            void                   **image_extra)
826 {
827     *image_out = abstract_surface;
828     *image_extra = NULL;
829
830     return CAIRO_STATUS_SUCCESS;
831 }
832
833 void
834 _cairo_image_surface_release_source_image (void                   *abstract_surface,
835                                            cairo_image_surface_t  *image,
836                                            void                   *image_extra)
837 {
838 }
839
840 /* high level image interface */
841 cairo_bool_t
842 _cairo_image_surface_get_extents (void                    *abstract_surface,
843                                   cairo_rectangle_int_t   *rectangle)
844 {
845     cairo_image_surface_t *surface = abstract_surface;
846
847     rectangle->x = 0;
848     rectangle->y = 0;
849     rectangle->width  = surface->width;
850     rectangle->height = surface->height;
851
852     return TRUE;
853 }
854
855 static cairo_int_status_t
856 _cairo_image_surface_paint (void                        *abstract_surface,
857                             cairo_operator_t             op,
858                             const cairo_pattern_t       *source,
859                             const cairo_clip_t          *clip)
860 {
861     cairo_image_surface_t *surface = abstract_surface;
862     return _cairo_compositor_paint (surface->compositor,
863                                     &surface->base, op, source, clip);
864 }
865
866 static cairo_int_status_t
867 _cairo_image_surface_mask (void                         *abstract_surface,
868                            cairo_operator_t              op,
869                            const cairo_pattern_t        *source,
870                            const cairo_pattern_t        *mask,
871                            const cairo_clip_t           *clip)
872 {
873     cairo_image_surface_t *surface = abstract_surface;
874     return _cairo_compositor_mask (surface->compositor,
875                                    &surface->base, op, source, mask, clip);
876 }
877
878 static cairo_int_status_t
879 _cairo_image_surface_stroke (void                       *abstract_surface,
880                              cairo_operator_t            op,
881                              const cairo_pattern_t      *source,
882                              const cairo_path_fixed_t   *path,
883                              const cairo_stroke_style_t *style,
884                              const cairo_matrix_t       *ctm,
885                              const cairo_matrix_t       *ctm_inverse,
886                              double                      tolerance,
887                              cairo_antialias_t           antialias,
888                              const cairo_clip_t         *clip)
889 {
890     cairo_image_surface_t *surface = abstract_surface;
891     return _cairo_compositor_stroke (surface->compositor, &surface->base,
892                                      op, source, path,
893                                      style, ctm, ctm_inverse,
894                                      tolerance, antialias, clip);
895 }
896
897 static cairo_int_status_t
898 _cairo_image_surface_fill (void                         *abstract_surface,
899                            cairo_operator_t              op,
900                            const cairo_pattern_t        *source,
901                            const cairo_path_fixed_t     *path,
902                            cairo_fill_rule_t             fill_rule,
903                            double                        tolerance,
904                            cairo_antialias_t             antialias,
905                            const cairo_clip_t           *clip)
906 {
907     cairo_image_surface_t *surface = abstract_surface;
908     return _cairo_compositor_fill (surface->compositor, &surface->base,
909                                    op, source, path,
910                                    fill_rule, tolerance, antialias,
911                                    clip);
912 }
913
914 static cairo_int_status_t
915 _cairo_image_surface_glyphs (void                       *abstract_surface,
916                              cairo_operator_t            op,
917                              const cairo_pattern_t      *source,
918                              cairo_glyph_t              *glyphs,
919                              int                         num_glyphs,
920                              cairo_scaled_font_t        *scaled_font,
921                              const cairo_clip_t         *clip)
922 {
923     cairo_image_surface_t *surface = abstract_surface;
924     return _cairo_compositor_glyphs (surface->compositor, &surface->base,
925                                      op, source,
926                                      glyphs, num_glyphs, scaled_font,
927                                      clip);
928 }
929
930 void
931 _cairo_image_surface_get_font_options (void                  *abstract_surface,
932                                        cairo_font_options_t  *options)
933 {
934     _cairo_font_options_init_default (options);
935
936     cairo_font_options_set_hint_metrics (options, CAIRO_HINT_METRICS_ON);
937     _cairo_font_options_set_round_glyph_positions (options, CAIRO_ROUND_GLYPH_POS_ON);
938 }
939
940 const cairo_surface_backend_t _cairo_image_surface_backend = {
941     CAIRO_SURFACE_TYPE_IMAGE,
942     _cairo_image_surface_finish,
943
944     _cairo_default_context_create,
945
946     _cairo_image_surface_create_similar,
947     NULL, /* create similar image */
948     _cairo_image_surface_map_to_image,
949     _cairo_image_surface_unmap_image,
950
951     _cairo_image_surface_acquire_source_image,
952     _cairo_image_surface_release_source_image,
953     _cairo_image_surface_snapshot,
954
955     NULL, /* copy_page */
956     NULL, /* show_page */
957
958     _cairo_image_surface_get_extents,
959     _cairo_image_surface_get_font_options,
960
961     NULL, /* flush */
962     NULL, /* mark dirty */
963
964     _cairo_image_surface_paint,
965     _cairo_image_surface_mask,
966     _cairo_image_surface_stroke,
967     _cairo_image_surface_fill,
968     NULL, /* fill-stroke */
969     _cairo_image_surface_glyphs,
970 };
971
972 /* A convenience function for when one needs to coerce an image
973  * surface to an alternate format. */
974 cairo_image_surface_t *
975 _cairo_image_surface_coerce (cairo_image_surface_t *surface)
976 {
977     return _cairo_image_surface_coerce_to_format (surface,
978                                                   _cairo_format_from_content (surface->base.content));
979 }
980
981 /* A convenience function for when one needs to coerce an image
982  * surface to an alternate format. */
983 cairo_image_surface_t *
984 _cairo_image_surface_coerce_to_format (cairo_image_surface_t *surface,
985                                        cairo_format_t         format)
986 {
987     cairo_image_surface_t *clone;
988     cairo_status_t status;
989
990     status = surface->base.status;
991     if (unlikely (status))
992         return (cairo_image_surface_t *)_cairo_surface_create_in_error (status);
993
994     if (surface->format == format)
995         return (cairo_image_surface_t *)cairo_surface_reference(&surface->base);
996
997     clone = (cairo_image_surface_t *)
998         cairo_image_surface_create (format, surface->width, surface->height);
999     if (unlikely (clone->base.status))
1000         return clone;
1001
1002     pixman_image_composite32 (PIXMAN_OP_SRC,
1003                               surface->pixman_image, NULL, clone->pixman_image,
1004                               0, 0,
1005                               0, 0,
1006                               0, 0,
1007                               surface->width, surface->height);
1008     clone->base.is_clear = FALSE;
1009
1010     clone->base.device_transform =
1011         surface->base.device_transform;
1012     clone->base.device_transform_inverse =
1013         surface->base.device_transform_inverse;
1014
1015     return clone;
1016 }
1017
1018 cairo_image_transparency_t
1019 _cairo_image_analyze_transparency (cairo_image_surface_t *image)
1020 {
1021     int x, y;
1022
1023     if (image->transparency != CAIRO_IMAGE_UNKNOWN)
1024         return image->transparency;
1025
1026     if ((image->base.content & CAIRO_CONTENT_ALPHA) == 0)
1027         return image->transparency = CAIRO_IMAGE_IS_OPAQUE;
1028
1029     if (image->base.is_clear)
1030         return image->transparency = CAIRO_IMAGE_HAS_BILEVEL_ALPHA;
1031
1032     if ((image->base.content & CAIRO_CONTENT_COLOR) == 0) {
1033         if (image->format == CAIRO_FORMAT_A1) {
1034             return image->transparency = CAIRO_IMAGE_HAS_BILEVEL_ALPHA;
1035         } else if (image->format == CAIRO_FORMAT_A8) {
1036             for (y = 0; y < image->height; y++) {
1037                 uint8_t *alpha = (uint8_t *) (image->data + y * image->stride);
1038
1039                 for (x = 0; x < image->width; x++, alpha++) {
1040                     if (*alpha > 0 && *alpha < 255)
1041                         return image->transparency = CAIRO_IMAGE_HAS_ALPHA;
1042                 }
1043             }
1044             return image->transparency = CAIRO_IMAGE_HAS_BILEVEL_ALPHA;
1045         } else {
1046             return image->transparency = CAIRO_IMAGE_HAS_ALPHA;
1047         }
1048     }
1049
1050     if (image->format == CAIRO_FORMAT_RGB16_565) {
1051         image->transparency = CAIRO_IMAGE_IS_OPAQUE;
1052         return CAIRO_IMAGE_IS_OPAQUE;
1053     }
1054
1055     if (image->format != CAIRO_FORMAT_ARGB32)
1056         return image->transparency = CAIRO_IMAGE_HAS_ALPHA;
1057
1058     image->transparency = CAIRO_IMAGE_IS_OPAQUE;
1059     for (y = 0; y < image->height; y++) {
1060         uint32_t *pixel = (uint32_t *) (image->data + y * image->stride);
1061
1062         for (x = 0; x < image->width; x++, pixel++) {
1063             int a = (*pixel & 0xff000000) >> 24;
1064             if (a > 0 && a < 255) {
1065                 return image->transparency = CAIRO_IMAGE_HAS_ALPHA;
1066             } else if (a == 0) {
1067                 image->transparency = CAIRO_IMAGE_HAS_BILEVEL_ALPHA;
1068             }
1069         }
1070     }
1071
1072     return image->transparency;
1073 }
1074
1075 cairo_image_color_t
1076 _cairo_image_analyze_color (cairo_image_surface_t      *image)
1077 {
1078     int x, y;
1079
1080     if (image->color != CAIRO_IMAGE_UNKNOWN_COLOR)
1081         return image->color;
1082
1083     if (image->format == CAIRO_FORMAT_A1 || image->format == CAIRO_FORMAT_A8)
1084         return image->color = CAIRO_IMAGE_IS_MONOCHROME;
1085
1086     if (image->format == CAIRO_FORMAT_ARGB32) {
1087         image->color = CAIRO_IMAGE_IS_MONOCHROME;
1088         for (y = 0; y < image->height; y++) {
1089             uint32_t *pixel = (uint32_t *) (image->data + y * image->stride);
1090
1091             for (x = 0; x < image->width; x++, pixel++) {
1092                 int a = (*pixel & 0xff000000) >> 24;
1093                 int r = (*pixel & 0x00ff0000) >> 16;
1094                 int g = (*pixel & 0x0000ff00) >> 8;
1095                 int b = (*pixel & 0x000000ff);
1096                 if (a == 0) {
1097                     r = g = b = 0;
1098                 } else {
1099                     r = (r * 255 + a / 2) / a;
1100                     g = (g * 255 + a / 2) / a;
1101                     b = (b * 255 + a / 2) / a;
1102                 }
1103                 if (!(r == g && g == b))
1104                     return image->color = CAIRO_IMAGE_IS_COLOR;
1105                 else if (r > 0 && r < 255)
1106                     image->color = CAIRO_IMAGE_IS_GRAYSCALE;
1107             }
1108         }
1109         return image->color;
1110     }
1111
1112     if (image->format == CAIRO_FORMAT_RGB24) {
1113         image->color = CAIRO_IMAGE_IS_MONOCHROME;
1114         for (y = 0; y < image->height; y++) {
1115             uint32_t *pixel = (uint32_t *) (image->data + y * image->stride);
1116
1117             for (x = 0; x < image->width; x++, pixel++) {
1118                 int r = (*pixel & 0x00ff0000) >> 16;
1119                 int g = (*pixel & 0x0000ff00) >>  8;
1120                 int b = (*pixel & 0x000000ff);
1121                 if (!(r == g && g == b))
1122                     return image->color = CAIRO_IMAGE_IS_COLOR;
1123                 else if (r > 0 && r < 255)
1124                     image->color = CAIRO_IMAGE_IS_GRAYSCALE;
1125             }
1126         }
1127         return image->color;
1128     }
1129
1130     return image->color = CAIRO_IMAGE_IS_COLOR;
1131 }