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-inline.h"
49
#include "cairo-paginated-private.h"
50
#include "cairo-pattern-private.h"
51
#include "cairo-pixman-private.h"
52
#include "cairo-recording-surface-private.h"
53
#include "cairo-region-private.h"
54
#include "cairo-scaled-font-private.h"
55
#include "cairo-surface-snapshot-inline.h"
56
#include "cairo-surface-snapshot-private.h"
57
#include "cairo-surface-subsurface-private.h"
58

            
59
/* Limit on the width / height of an image surface in pixels.  This is
60
 * mainly determined by coordinates of things sent to pixman at the
61
 * moment being in 16.16 format. */
62
#define MAX_IMAGE_SIZE 32767
63

            
64
/**
65
 * SECTION:cairo-image
66
 * @Title: Image Surfaces
67
 * @Short_Description: Rendering to memory buffers
68
 * @See_Also: #cairo_surface_t
69
 *
70
 * Image surfaces provide the ability to render to memory buffers
71
 * either allocated by cairo or by the calling code.  The supported
72
 * image formats are those defined in #cairo_format_t.
73
 **/
74

            
75
/**
76
 * CAIRO_HAS_IMAGE_SURFACE:
77
 *
78
 * Defined if the image surface backend is available.
79
 * The image surface backend is always built in.
80
 * This macro was added for completeness in cairo 1.8.
81
 *
82
 * Since: 1.8
83
 **/
84

            
85
static cairo_bool_t
86
68905
_cairo_image_surface_is_size_valid (int width, int height)
87
{
88
68905
    return 0 <= width  &&  width <= MAX_IMAGE_SIZE &&
89
137810
	   0 <= height && height <= MAX_IMAGE_SIZE;
90
}
91

            
92
cairo_format_t
93
54564
_cairo_format_from_pixman_format (pixman_format_code_t pixman_format)
94
{
95
54564
    switch (pixman_format) {
96
3
    case PIXMAN_rgba_float:
97
3
	return CAIRO_FORMAT_RGBA128F;
98
    case PIXMAN_rgb_float:
99
	return CAIRO_FORMAT_RGB96F;
100
13178
    case PIXMAN_a8r8g8b8:
101
13178
	return CAIRO_FORMAT_ARGB32;
102
    case PIXMAN_x2r10g10b10:
103
	return CAIRO_FORMAT_RGB30;
104
18737
    case PIXMAN_x8r8g8b8:
105
18737
	return CAIRO_FORMAT_RGB24;
106
10047
    case PIXMAN_a8:
107
10047
	return CAIRO_FORMAT_A8;
108
6047
    case PIXMAN_a1:
109
6047
	return CAIRO_FORMAT_A1;
110
6552
    case PIXMAN_r5g6b5:
111
6552
	return CAIRO_FORMAT_RGB16_565;
112
    case PIXMAN_r8g8b8a8: case PIXMAN_r8g8b8x8:
113
    case PIXMAN_a8r8g8b8_sRGB:
114
#if HAS_PIXMAN_r8g8b8_sRGB
115
    case PIXMAN_r8g8b8_sRGB:
116
#endif
117
    case PIXMAN_a8b8g8r8: case PIXMAN_x8b8g8r8: case PIXMAN_r8g8b8:
118
    case PIXMAN_b8g8r8:   case PIXMAN_b5g6r5:
119
    case PIXMAN_a1r5g5b5: case PIXMAN_x1r5g5b5: case PIXMAN_a1b5g5r5:
120
    case PIXMAN_x1b5g5r5: case PIXMAN_a4r4g4b4: case PIXMAN_x4r4g4b4:
121
    case PIXMAN_a4b4g4r4: case PIXMAN_x4b4g4r4: case PIXMAN_r3g3b2:
122
    case PIXMAN_b2g3r3:   case PIXMAN_a2r2g2b2: case PIXMAN_a2b2g2r2:
123
    case PIXMAN_c8:       case PIXMAN_g8:       case PIXMAN_x4a4:
124
    case PIXMAN_a4:       case PIXMAN_r1g2b1:   case PIXMAN_b1g2r1:
125
    case PIXMAN_a1r1g1b1: case PIXMAN_a1b1g1r1: case PIXMAN_c4:
126
    case PIXMAN_g4:       case PIXMAN_g1:
127
    case PIXMAN_yuy2:     case PIXMAN_yv12:
128
    case PIXMAN_b8g8r8x8:
129
    case PIXMAN_b8g8r8a8:
130
    case PIXMAN_a2b10g10r10:
131
    case PIXMAN_x2b10g10r10:
132
    case PIXMAN_a2r10g10b10:
133
    case PIXMAN_x14r6g6b6:
134
    default:
135
	return CAIRO_FORMAT_INVALID;
136
    }
137

            
138
    return CAIRO_FORMAT_INVALID;
139
}
140

            
141
cairo_content_t
142
54574
_cairo_content_from_pixman_format (pixman_format_code_t pixman_format)
143
{
144
    cairo_content_t content;
145

            
146
54574
    content = 0;
147
54574
    if (PIXMAN_FORMAT_RGB (pixman_format))
148
38480
	content |= CAIRO_CONTENT_COLOR;
149
54574
    if (PIXMAN_FORMAT_A (pixman_format))
150
29282
	content |= CAIRO_CONTENT_ALPHA;
151

            
152
54574
    return content;
153
}
154

            
155
void
156
54564
_cairo_image_surface_init (cairo_image_surface_t *surface,
157
			   pixman_image_t	*pixman_image,
158
			   pixman_format_code_t	 pixman_format)
159
{
160
54564
    surface->parent = NULL;
161
54564
    surface->pixman_image = pixman_image;
162

            
163
54564
    surface->pixman_format = pixman_format;
164
54564
    surface->format = _cairo_format_from_pixman_format (pixman_format);
165
54564
    surface->data = (uint8_t *) pixman_image_get_data (pixman_image);
166
54564
    surface->owns_data = FALSE;
167
54564
    surface->transparency = CAIRO_IMAGE_UNKNOWN;
168
54564
    surface->color = CAIRO_IMAGE_UNKNOWN_COLOR;
169

            
170
54564
    surface->width = pixman_image_get_width (pixman_image);
171
54564
    surface->height = pixman_image_get_height (pixman_image);
172
54564
    surface->stride = pixman_image_get_stride (pixman_image);
173
54564
    surface->depth = pixman_image_get_depth (pixman_image);
174

            
175
54564
    surface->base.is_clear = surface->width == 0 || surface->height == 0;
176

            
177
54564
    surface->compositor = _cairo_image_spans_compositor_get ();
178
54564
}
179

            
180
cairo_surface_t *
181
54561
_cairo_image_surface_create_for_pixman_image (pixman_image_t		*pixman_image,
182
					      pixman_format_code_t	 pixman_format)
183
{
184
    cairo_image_surface_t *surface;
185

            
186
54561
    surface = _cairo_calloc (sizeof (cairo_image_surface_t));
187
54561
    if (unlikely (surface == NULL))
188
	return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
189

            
190
54561
    _cairo_surface_init (&surface->base,
191
			 &_cairo_image_surface_backend,
192
			 NULL, /* device */
193
			 _cairo_content_from_pixman_format (pixman_format),
194
			 FALSE); /* is_vector */
195

            
196
54561
    _cairo_image_surface_init (surface, pixman_image, pixman_format);
197

            
198
54561
    return &surface->base;
199
}
200

            
201
cairo_bool_t
202
103
_pixman_format_from_masks (cairo_format_masks_t *masks,
203
			   pixman_format_code_t *format_ret)
204
{
205
    pixman_format_code_t format;
206
    int format_type;
207
    int a, r, g, b;
208
    cairo_format_masks_t format_masks;
209

            
210
103
    a = _cairo_popcount (masks->alpha_mask);
211
103
    r = _cairo_popcount (masks->red_mask);
212
103
    g = _cairo_popcount (masks->green_mask);
213
103
    b = _cairo_popcount (masks->blue_mask);
214

            
215
103
    if (masks->red_mask) {
216
91
	if (masks->red_mask > masks->blue_mask)
217
47
	    format_type = PIXMAN_TYPE_ARGB;
218
	else
219
44
	    format_type = PIXMAN_TYPE_ABGR;
220
12
    } else if (masks->alpha_mask) {
221
12
	format_type = PIXMAN_TYPE_A;
222
    } else {
223
	return FALSE;
224
    }
225

            
226
103
    format = PIXMAN_FORMAT (masks->bpp, format_type, a, r, g, b);
227

            
228
103
    if (! pixman_format_supported_destination (format))
229
	return FALSE;
230

            
231
    /* Sanity check that we got out of PIXMAN_FORMAT exactly what we
232
     * expected. This avoid any problems from something bizarre like
233
     * alpha in the least-significant bits, or insane channel order,
234
     * or whatever. */
235
103
     if (!_pixman_format_to_masks (format, &format_masks) ||
236
103
         masks->bpp        != format_masks.bpp            ||
237
103
	 masks->red_mask   != format_masks.red_mask       ||
238
95
	 masks->green_mask != format_masks.green_mask     ||
239
95
	 masks->blue_mask  != format_masks.blue_mask)
240
     {
241
8
	 return FALSE;
242
     }
243

            
244
95
    *format_ret = format;
245
95
    return TRUE;
246
}
247

            
248
/* Convenience function to convert #cairo_dither_t into #pixman_dither_t */
249
static pixman_dither_t
250
638635
_cairo_dither_to_pixman_dither (cairo_dither_t dither)
251
{
252
638635
    switch (dither) {
253
    case CAIRO_DITHER_FAST:
254
        return PIXMAN_DITHER_FAST;
255
    case CAIRO_DITHER_GOOD:
256
        return PIXMAN_DITHER_GOOD;
257
18
    case CAIRO_DITHER_BEST:
258
18
        return PIXMAN_DITHER_BEST;
259
638617
    case CAIRO_DITHER_NONE:
260
    case CAIRO_DITHER_DEFAULT:
261
    default:
262
638617
        return PIXMAN_DITHER_NONE;
263
    }
264
}
265

            
266
/* A mask consisting of N bits set to 1. */
267
#define MASK(N) ((1UL << (N))-1)
268

            
269
cairo_bool_t
270
103
_pixman_format_to_masks (pixman_format_code_t	 format,
271
			 cairo_format_masks_t	*masks)
272
{
273
    int a, r, g, b;
274

            
275
103
    masks->bpp = PIXMAN_FORMAT_BPP (format);
276

            
277
    /* Number of bits in each channel */
278
103
    a = PIXMAN_FORMAT_A (format);
279
103
    r = PIXMAN_FORMAT_R (format);
280
103
    g = PIXMAN_FORMAT_G (format);
281
103
    b = PIXMAN_FORMAT_B (format);
282

            
283
103
    switch (PIXMAN_FORMAT_TYPE (format)) {
284
47
    case PIXMAN_TYPE_ARGB:
285
47
        masks->alpha_mask = MASK (a) << (r + g + b);
286
47
        masks->red_mask   = MASK (r) << (g + b);
287
47
        masks->green_mask = MASK (g) << (b);
288
47
        masks->blue_mask  = MASK (b);
289
47
        return TRUE;
290
44
    case PIXMAN_TYPE_ABGR:
291
44
        masks->alpha_mask = MASK (a) << (b + g + r);
292
44
        masks->blue_mask  = MASK (b) << (g + r);
293
44
        masks->green_mask = MASK (g) << (r);
294
44
        masks->red_mask   = MASK (r);
295
44
        return TRUE;
296
#ifdef PIXMAN_TYPE_BGRA
297
    case PIXMAN_TYPE_BGRA:
298
        masks->blue_mask  = MASK (b) << (masks->bpp - b);
299
        masks->green_mask = MASK (g) << (masks->bpp - b - g);
300
        masks->red_mask   = MASK (r) << (masks->bpp - b - g - r);
301
        masks->alpha_mask = MASK (a);
302
        return TRUE;
303
#endif
304
12
    case PIXMAN_TYPE_A:
305
12
        masks->alpha_mask = MASK (a);
306
12
        masks->red_mask   = 0;
307
12
        masks->green_mask = 0;
308
12
        masks->blue_mask  = 0;
309
12
        return TRUE;
310
    case PIXMAN_TYPE_OTHER:
311
    case PIXMAN_TYPE_COLOR:
312
    case PIXMAN_TYPE_GRAY:
313
    case PIXMAN_TYPE_YUY2:
314
    case PIXMAN_TYPE_YV12:
315
    default:
316
        masks->alpha_mask = 0;
317
        masks->red_mask   = 0;
318
        masks->green_mask = 0;
319
        masks->blue_mask  = 0;
320
        return FALSE;
321
    }
322
}
323

            
324
pixman_format_code_t
325
47428
_cairo_format_to_pixman_format_code (cairo_format_t format)
326
{
327
    pixman_format_code_t ret;
328
47428
    switch (format) {
329
6032
    case CAIRO_FORMAT_A1:
330
6032
	ret = PIXMAN_a1;
331
6032
	break;
332
10038
    case CAIRO_FORMAT_A8:
333
10038
	ret = PIXMAN_a8;
334
10038
	break;
335
16280
    case CAIRO_FORMAT_RGB24:
336
16280
	ret = PIXMAN_x8r8g8b8;
337
16280
	break;
338
    case CAIRO_FORMAT_RGB30:
339
	ret = PIXMAN_x2r10g10b10;
340
	break;
341
4251
    case CAIRO_FORMAT_RGB16_565:
342
4251
	ret = PIXMAN_r5g6b5;
343
4251
	break;
344
    case CAIRO_FORMAT_RGB96F:
345
	ret = PIXMAN_rgb_float;
346
	break;
347
3
    case CAIRO_FORMAT_RGBA128F:
348
3
	ret = PIXMAN_rgba_float;
349
3
	break;
350
10824
    case CAIRO_FORMAT_ARGB32:
351
    case CAIRO_FORMAT_INVALID:
352
    default:
353
10824
	ret = PIXMAN_a8r8g8b8;
354
10824
	break;
355
    }
356
47428
    return ret;
357
}
358

            
359
cairo_surface_t *
360
54690
_cairo_image_surface_create_with_pixman_format (unsigned char		*data,
361
						pixman_format_code_t	 pixman_format,
362
						int			 width,
363
						int			 height,
364
						int			 stride)
365
{
366
    cairo_surface_t *surface;
367
    pixman_image_t *pixman_image;
368

            
369
54690
    if (! _cairo_image_surface_is_size_valid (width, height))
370
    {
371
153
	return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_SIZE));
372
    }
373

            
374
54537
    pixman_image = pixman_image_create_bits (pixman_format, width, height,
375
					     (uint32_t *) data, stride);
376

            
377
54537
    if (unlikely (pixman_image == NULL))
378
	return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
379

            
380
54537
    surface = _cairo_image_surface_create_for_pixman_image (pixman_image,
381
							    pixman_format);
382
54537
    if (unlikely (surface->status)) {
383
	pixman_image_unref (pixman_image);
384
	return surface;
385
    }
386

            
387
    /* we can not make any assumptions about the initial state of user data */
388
54537
    surface->is_clear = data == NULL;
389
54537
    return surface;
390
}
391

            
392
/**
393
 * cairo_image_surface_create:
394
 * @format: format of pixels in the surface to create
395
 * @width: width of the surface, in pixels
396
 * @height: height of the surface, in pixels
397
 *
398
 * Creates an image surface of the specified format and
399
 * dimensions. Initially the surface contents are set to 0.
400
 * (Specifically, within each pixel, each color or alpha channel
401
 * belonging to format will be 0. The contents of bits within a pixel,
402
 * but not belonging to the given format are undefined).
403
 *
404
 * Return value: a pointer to the newly created surface. The caller
405
 * owns the surface and should call cairo_surface_destroy() when done
406
 * with it.
407
 *
408
 * This function always returns a valid pointer, but it will return a
409
 * pointer to a "nil" surface if an error such as out of memory
410
 * occurs. You can use cairo_surface_status() to check for this.
411
 *
412
 * Since: 1.0
413
 **/
414
cairo_surface_t *
415
42359
cairo_image_surface_create (cairo_format_t	format,
416
			    int			width,
417
			    int			height)
418
{
419
    pixman_format_code_t pixman_format;
420

            
421
42359
    if (! CAIRO_FORMAT_VALID (format))
422
	return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_FORMAT));
423

            
424
42359
    pixman_format = _cairo_format_to_pixman_format_code (format);
425

            
426
42359
    return _cairo_image_surface_create_with_pixman_format (NULL, pixman_format,
427
							   width, height, -1);
428
}
429

            
430
cairo_surface_t *
431
5984
_cairo_image_surface_create_with_content (cairo_content_t	content,
432
					  int			width,
433
					  int			height)
434
{
435
5984
    return cairo_image_surface_create (_cairo_format_from_content (content),
436
				       width, height);
437
}
438

            
439
/**
440
 * cairo_format_stride_for_width:
441
 * @format: A #cairo_format_t value
442
 * @width: The desired width of an image surface to be created.
443
 *
444
 * This function provides a stride value that will respect all
445
 * alignment requirements of the accelerated image-rendering code
446
 * within cairo. Typical usage will be of the form:
447
 *
448
 * <informalexample><programlisting>
449
 * int stride;
450
 * unsigned char *data;
451
 * cairo_surface_t *surface;
452
 *
453
 * stride = cairo_format_stride_for_width (format, width);
454
 * data = malloc (stride * height);
455
 * surface = cairo_image_surface_create_for_data (data, format,
456
 *						  width, height,
457
 *						  stride);
458
 * </programlisting></informalexample>
459
 *
460
 * Return value: the appropriate stride to use given the desired
461
 * format and width, or -1 if either the format is invalid or the width
462
 * too large.
463
 *
464
 * Since: 1.6
465
 **/
466
int
467
6895
cairo_format_stride_for_width (cairo_format_t	format,
468
			       int		width)
469
{
470
    int bpp;
471

            
472
6895
    if (! CAIRO_FORMAT_VALID (format)) {
473
	_cairo_error_throw (CAIRO_STATUS_INVALID_FORMAT);
474
	return -1;
475
    }
476

            
477
6895
    bpp = _cairo_format_bits_per_pixel (format);
478
6895
    if ((unsigned) (width) >= (INT32_MAX - 7) / (unsigned) (bpp))
479
	return -1;
480

            
481
6895
    return CAIRO_STRIDE_FOR_WIDTH_BPP (width, bpp);
482
}
483

            
484
/**
485
 * cairo_image_surface_create_for_data:
486
 * @data: a pointer to a buffer supplied by the application in which
487
 *     to write contents. This pointer must be suitably aligned for any
488
 *     kind of variable, (for example, a pointer returned by malloc).
489
 * @format: the format of pixels in the buffer
490
 * @width: the width of the image to be stored in the buffer
491
 * @height: the height of the image to be stored in the buffer
492
 * @stride: the number of bytes between the start of rows in the
493
 *     buffer as allocated. This value should always be computed by
494
 *     cairo_format_stride_for_width() before allocating the data
495
 *     buffer.
496
 *
497
 * Creates an image surface for the provided pixel data. The output
498
 * buffer must be kept around until the #cairo_surface_t is destroyed
499
 * or cairo_surface_finish() is called on the surface.  The initial
500
 * contents of @data will be used as the initial image contents; you
501
 * must explicitly clear the buffer, using, for example,
502
 * cairo_rectangle() and cairo_fill() if you want it cleared.
503
 *
504
 * Note that the stride may be larger than
505
 * width*bytes_per_pixel to provide proper alignment for each pixel
506
 * and row. This alignment is required to allow high-performance rendering
507
 * within cairo. The correct way to obtain a legal stride value is to
508
 * call cairo_format_stride_for_width() with the desired format and
509
 * maximum image width value, and then use the resulting stride value
510
 * to allocate the data and to create the image surface. See
511
 * cairo_format_stride_for_width() for example code.
512
 *
513
 * Return value: a pointer to the newly created surface. The caller
514
 * owns the surface and should call cairo_surface_destroy() when done
515
 * with it.
516
 *
517
 * This function always returns a valid pointer, but it will return a
518
 * pointer to a "nil" surface in the case of an error such as out of
519
 * memory or an invalid stride value. In case of invalid stride value
520
 * the error status of the returned surface will be
521
 * %CAIRO_STATUS_INVALID_STRIDE.  You can use
522
 * cairo_surface_status() to check for this.
523
 *
524
 * See cairo_surface_set_user_data() for a means of attaching a
525
 * destroy-notification fallback to the surface if necessary.
526
 *
527
 * Since: 1.0
528
 **/
529
cairo_surface_t *
530
5191
cairo_image_surface_create_for_data (unsigned char     *data,
531
				     cairo_format_t	format,
532
				     int		width,
533
				     int		height,
534
				     int		stride)
535
{
536
    pixman_format_code_t pixman_format;
537
    int minstride;
538

            
539
5191
    if (! CAIRO_FORMAT_VALID (format))
540
	return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_FORMAT));
541

            
542
5191
    if ((stride & (CAIRO_STRIDE_ALIGNMENT-1)) != 0)
543
122
	return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_STRIDE));
544

            
545
5069
    if (! _cairo_image_surface_is_size_valid (width, height))
546
	return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_SIZE));
547

            
548
5069
    minstride = cairo_format_stride_for_width (format, width);
549
5069
    if (stride < 0) {
550
98
	if (stride > -minstride) {
551
	    return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_STRIDE));
552
	}
553
    } else {
554
4971
	if (stride < minstride) {
555
	    return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_STRIDE));
556
	}
557
    }
558

            
559
5069
    pixman_format = _cairo_format_to_pixman_format_code (format);
560
5069
    return _cairo_image_surface_create_with_pixman_format (data,
561
							   pixman_format,
562
							   width, height,
563
							   stride);
564
}
565

            
566
/**
567
 * cairo_image_surface_get_data:
568
 * @surface: a #cairo_image_surface_t
569
 *
570
 * Get a pointer to the data of the image surface, for direct
571
 * inspection or modification.
572
 *
573
 * A call to cairo_surface_flush() is required before accessing the
574
 * pixel data to ensure that all pending drawing operations are
575
 * finished. A call to cairo_surface_mark_dirty() is required after
576
 * the data is modified.
577
 *
578
 * Return value: a pointer to the image data of this surface or %NULL
579
 * if @surface is not an image surface, or if cairo_surface_finish()
580
 * has been called.
581
 *
582
 * Since: 1.2
583
 **/
584
unsigned char *
585
6867
cairo_image_surface_get_data (cairo_surface_t *surface)
586
{
587
6867
    cairo_image_surface_t *image_surface = (cairo_image_surface_t *) surface;
588

            
589
6867
    if (! _cairo_surface_is_image (surface)) {
590
1
	_cairo_error_throw (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
591
1
	return NULL;
592
    }
593

            
594
6866
    return image_surface->data;
595
}
596

            
597
/**
598
 * cairo_image_surface_get_format:
599
 * @surface: a #cairo_image_surface_t
600
 *
601
 * Get the format of the surface.
602
 *
603
 * Return value: the format of the surface
604
 *
605
 * Since: 1.2
606
 **/
607
cairo_format_t
608
6851
cairo_image_surface_get_format (cairo_surface_t *surface)
609
{
610
6851
    cairo_image_surface_t *image_surface = (cairo_image_surface_t *) surface;
611

            
612
6851
    if (! _cairo_surface_is_image (surface)) {
613
1
	_cairo_error_throw (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
614
1
	return CAIRO_FORMAT_INVALID;
615
    }
616

            
617
6850
    return image_surface->format;
618
}
619

            
620
/**
621
 * cairo_image_surface_get_width:
622
 * @surface: a #cairo_image_surface_t
623
 *
624
 * Get the width of the image surface in pixels.
625
 *
626
 * Return value: the width of the surface in pixels.
627
 *
628
 * Since: 1.0
629
 **/
630
int
631
10506
cairo_image_surface_get_width (cairo_surface_t *surface)
632
{
633
10506
    cairo_image_surface_t *image_surface = (cairo_image_surface_t *) surface;
634

            
635
10506
    if (! _cairo_surface_is_image (surface)) {
636
1
	_cairo_error_throw (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
637
1
	return 0;
638
    }
639

            
640
10505
    return image_surface->width;
641
}
642

            
643
/**
644
 * cairo_image_surface_get_height:
645
 * @surface: a #cairo_image_surface_t
646
 *
647
 * Get the height of the image surface in pixels.
648
 *
649
 * Return value: the height of the surface in pixels.
650
 *
651
 * Since: 1.0
652
 **/
653
int
654
10506
cairo_image_surface_get_height (cairo_surface_t *surface)
655
{
656
10506
    cairo_image_surface_t *image_surface = (cairo_image_surface_t *) surface;
657

            
658
10506
    if (! _cairo_surface_is_image (surface)) {
659
1
	_cairo_error_throw (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
660
1
	return 0;
661
    }
662

            
663
10505
    return image_surface->height;
664
}
665

            
666
/**
667
 * cairo_image_surface_get_stride:
668
 * @surface: a #cairo_image_surface_t
669
 *
670
 * Get the stride of the image surface in bytes
671
 *
672
 * Return value: the stride of the image surface in bytes (or 0 if
673
 * @surface is not an image surface). The stride is the distance in
674
 * bytes from the beginning of one row of the image data to the
675
 * beginning of the next row.
676
 *
677
 * Since: 1.2
678
 **/
679
int
680
5473
cairo_image_surface_get_stride (cairo_surface_t *surface)
681
{
682

            
683
5473
    cairo_image_surface_t *image_surface = (cairo_image_surface_t *) surface;
684

            
685
5473
    if (! _cairo_surface_is_image (surface)) {
686
1
	_cairo_error_throw (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
687
1
	return 0;
688
    }
689

            
690
5472
    return image_surface->stride;
691
}
692

            
693
cairo_format_t
694
8036
_cairo_format_from_content (cairo_content_t content)
695
{
696
8036
    switch (content) {
697
4884
    case CAIRO_CONTENT_COLOR:
698
4884
	return CAIRO_FORMAT_RGB24;
699
1344
    case CAIRO_CONTENT_ALPHA:
700
1344
	return CAIRO_FORMAT_A8;
701
1808
    case CAIRO_CONTENT_COLOR_ALPHA:
702
1808
	return CAIRO_FORMAT_ARGB32;
703
    }
704

            
705
    ASSERT_NOT_REACHED;
706
    return CAIRO_FORMAT_INVALID;
707
}
708

            
709
cairo_content_t
710
_cairo_content_from_format (cairo_format_t format)
711
{
712
    switch (format) {
713
    case CAIRO_FORMAT_RGBA128F:
714
    case CAIRO_FORMAT_ARGB32:
715
	return CAIRO_CONTENT_COLOR_ALPHA;
716
    case CAIRO_FORMAT_RGB96F:
717
    case CAIRO_FORMAT_RGB30:
718
	return CAIRO_CONTENT_COLOR;
719
    case CAIRO_FORMAT_RGB24:
720
	return CAIRO_CONTENT_COLOR;
721
    case CAIRO_FORMAT_RGB16_565:
722
	return CAIRO_CONTENT_COLOR;
723
    case CAIRO_FORMAT_A8:
724
    case CAIRO_FORMAT_A1:
725
	return CAIRO_CONTENT_ALPHA;
726
    case CAIRO_FORMAT_INVALID:
727
	break;
728
    }
729

            
730
    ASSERT_NOT_REACHED;
731
    return CAIRO_CONTENT_COLOR_ALPHA;
732
}
733

            
734
int
735
6895
_cairo_format_bits_per_pixel (cairo_format_t format)
736
{
737
6895
    switch (format) {
738
6
    case CAIRO_FORMAT_RGBA128F:
739
6
	return 128;
740
    case CAIRO_FORMAT_RGB96F:
741
	return 96;
742
3725
    case CAIRO_FORMAT_ARGB32:
743
    case CAIRO_FORMAT_RGB30:
744
    case CAIRO_FORMAT_RGB24:
745
3725
	return 32;
746
    case CAIRO_FORMAT_RGB16_565:
747
	return 16;
748
2765
    case CAIRO_FORMAT_A8:
749
2765
	return 8;
750
399
    case CAIRO_FORMAT_A1:
751
399
	return 1;
752
    case CAIRO_FORMAT_INVALID:
753
    default:
754
	ASSERT_NOT_REACHED;
755
	return 0;
756
    }
757
}
758

            
759
cairo_surface_t *
760
9146
_cairo_image_surface_create_similar (void	       *abstract_other,
761
				     cairo_content_t	content,
762
				     int		width,
763
				     int		height)
764
{
765
9146
    cairo_image_surface_t *other = abstract_other;
766

            
767
    TRACE ((stderr, "%s (other=%u)\n", __FUNCTION__, other->base.unique_id));
768

            
769
9146
    if (! _cairo_image_surface_is_size_valid (width, height))
770
	return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_SIZE));
771

            
772
9146
    if (content == other->base.content) {
773
7091
	return _cairo_image_surface_create_with_pixman_format (NULL,
774
							       other->pixman_format,
775
							       width, height,
776
							       0);
777
    }
778

            
779
2055
    return _cairo_image_surface_create_with_content (content,
780
						     width, height);
781
}
782

            
783
cairo_surface_t *
784
177
_cairo_image_surface_snapshot (void *abstract_surface)
785
{
786
177
    cairo_image_surface_t *image = abstract_surface;
787
    cairo_image_surface_t *clone;
788

            
789
    /* If we own the image, we can simply steal the memory for the snapshot */
790
177
    if (image->owns_data && image->base._finishing) {
791
	clone = (cairo_image_surface_t *)
792
24
	    _cairo_image_surface_create_for_pixman_image (image->pixman_image,
793
							  image->pixman_format);
794
24
	if (unlikely (clone->base.status))
795
	    return &clone->base;
796

            
797
24
	image->pixman_image = NULL;
798
24
	image->owns_data = FALSE;
799

            
800
24
	clone->transparency = image->transparency;
801
24
	clone->color = image->color;
802

            
803
24
	clone->owns_data = TRUE;
804
24
	return &clone->base;
805
    }
806

            
807
    clone = (cairo_image_surface_t *)
808
153
	_cairo_image_surface_create_with_pixman_format (NULL,
809
							image->pixman_format,
810
							image->width,
811
							image->height,
812
							0);
813
153
    if (unlikely (clone->base.status))
814
	return &clone->base;
815

            
816
153
    if (clone->stride == image->stride) {
817
153
	memcpy (clone->data, image->data, clone->stride * clone->height);
818
    } else {
819
	pixman_image_composite32 (PIXMAN_OP_SRC,
820
				  image->pixman_image, NULL, clone->pixman_image,
821
				  0, 0,
822
				  0, 0,
823
				  0, 0,
824
				  image->width, image->height);
825
    }
826
153
    clone->base.is_clear = FALSE;
827
153
    return &clone->base;
828
}
829

            
830
cairo_image_surface_t *
831
15
_cairo_image_surface_map_to_image (void *abstract_other,
832
				   const cairo_rectangle_int_t *extents)
833
{
834
15
    cairo_image_surface_t *other = abstract_other;
835
    cairo_surface_t *surface;
836
    uint8_t *data;
837

            
838
15
    data = other->data;
839
15
    data += extents->y * other->stride;
840
15
    data += extents->x * PIXMAN_FORMAT_BPP (other->pixman_format)/ 8;
841

            
842
    surface =
843
15
	_cairo_image_surface_create_with_pixman_format (data,
844
							other->pixman_format,
845
15
							extents->width,
846
15
							extents->height,
847
15
							other->stride);
848

            
849
15
    cairo_surface_set_device_offset (surface, -extents->x, -extents->y);
850
15
    return (cairo_image_surface_t *) surface;
851
}
852

            
853
cairo_int_status_t
854
9
_cairo_image_surface_unmap_image (void *abstract_surface,
855
				  cairo_image_surface_t *image)
856
{
857
9
    cairo_surface_finish (&image->base);
858
9
    cairo_surface_destroy (&image->base);
859

            
860
9
    return CAIRO_INT_STATUS_SUCCESS;
861
}
862

            
863
cairo_status_t
864
49175
_cairo_image_surface_finish (void *abstract_surface)
865
{
866
49175
    cairo_image_surface_t *surface = abstract_surface;
867

            
868
49175
    if (surface->pixman_image) {
869
49151
	pixman_image_unref (surface->pixman_image);
870
49151
	surface->pixman_image = NULL;
871
    }
872

            
873
49175
    if (surface->owns_data) {
874
470
	free (surface->data);
875
470
	surface->data = NULL;
876
    }
877

            
878
49175
    if (surface->parent) {
879
	cairo_surface_t *parent = surface->parent;
880
	surface->parent = NULL;
881
	cairo_surface_destroy (parent);
882
    }
883

            
884
49175
    return CAIRO_STATUS_SUCCESS;
885
}
886

            
887
void
888
4620
_cairo_image_surface_assume_ownership_of_data (cairo_image_surface_t *surface)
889
{
890
4620
    surface->owns_data = TRUE;
891
4620
}
892

            
893
cairo_surface_t *
894
32558
_cairo_image_surface_source (void			*abstract_surface,
895
			     cairo_rectangle_int_t	*extents)
896
{
897
32558
    cairo_image_surface_t *surface = abstract_surface;
898

            
899
32558
    if (extents) {
900
32558
	extents->x = extents->y = 0;
901
32558
	extents->width = surface->width;
902
32558
	extents->height = surface->height;
903
    }
904

            
905
32558
    return &surface->base;
906
}
907

            
908
cairo_status_t
909
2131
_cairo_image_surface_acquire_source_image (void                    *abstract_surface,
910
					   cairo_image_surface_t  **image_out,
911
					   void                   **image_extra)
912
{
913
2131
    *image_out = abstract_surface;
914
2131
    *image_extra = NULL;
915

            
916
2131
    return CAIRO_STATUS_SUCCESS;
917
}
918

            
919
void
920
2131
_cairo_image_surface_release_source_image (void                   *abstract_surface,
921
					   cairo_image_surface_t  *image,
922
					   void                   *image_extra)
923
{
924
2131
}
925

            
926
/* high level image interface */
927
cairo_bool_t
928
2061481
_cairo_image_surface_get_extents (void			  *abstract_surface,
929
				  cairo_rectangle_int_t   *rectangle)
930
{
931
2061481
    cairo_image_surface_t *surface = abstract_surface;
932

            
933
2061481
    rectangle->x = 0;
934
2061481
    rectangle->y = 0;
935
2061481
    rectangle->width  = surface->width;
936
2061481
    rectangle->height = surface->height;
937

            
938
2061481
    return TRUE;
939
}
940

            
941
cairo_int_status_t
942
638635
_cairo_image_surface_paint (void			*abstract_surface,
943
			    cairo_operator_t		 op,
944
			    const cairo_pattern_t	*source,
945
			    const cairo_clip_t		*clip)
946
{
947
638635
    cairo_image_surface_t *surface = abstract_surface;
948
638635
    pixman_dither_t pixman_dither = _cairo_dither_to_pixman_dither (source->dither);
949
638635
    pixman_image_set_dither (surface->pixman_image, pixman_dither);
950

            
951
    TRACE ((stderr, "%s (surface=%d)\n",
952
	    __FUNCTION__, surface->base.unique_id));
953

            
954
638635
    return _cairo_compositor_paint (surface->compositor,
955
				    &surface->base, op, source, clip);
956
}
957

            
958
cairo_int_status_t
959
4614
_cairo_image_surface_mask (void				*abstract_surface,
960
			   cairo_operator_t		 op,
961
			   const cairo_pattern_t	*source,
962
			   const cairo_pattern_t	*mask,
963
			   const cairo_clip_t		*clip)
964
{
965
4614
    cairo_image_surface_t *surface = abstract_surface;
966

            
967
    TRACE ((stderr, "%s (surface=%d)\n",
968
	    __FUNCTION__, surface->base.unique_id));
969

            
970
4614
    return _cairo_compositor_mask (surface->compositor,
971
				   &surface->base, op, source, mask, clip);
972
}
973

            
974
cairo_int_status_t
975
40053
_cairo_image_surface_stroke (void			*abstract_surface,
976
			     cairo_operator_t		 op,
977
			     const cairo_pattern_t	*source,
978
			     const cairo_path_fixed_t	*path,
979
			     const cairo_stroke_style_t	*style,
980
			     const cairo_matrix_t	*ctm,
981
			     const cairo_matrix_t	*ctm_inverse,
982
			     double			 tolerance,
983
			     cairo_antialias_t		 antialias,
984
			     const cairo_clip_t		*clip)
985
{
986
40053
    cairo_image_surface_t *surface = abstract_surface;
987

            
988
    TRACE ((stderr, "%s (surface=%d)\n",
989
	    __FUNCTION__, surface->base.unique_id));
990

            
991
40053
    return _cairo_compositor_stroke (surface->compositor, &surface->base,
992
				     op, source, path,
993
				     style, ctm, ctm_inverse,
994
				     tolerance, antialias, clip);
995
}
996

            
997
cairo_int_status_t
998
498630
_cairo_image_surface_fill (void				*abstract_surface,
999
			   cairo_operator_t		 op,
			   const cairo_pattern_t	*source,
			   const cairo_path_fixed_t	*path,
			   cairo_fill_rule_t		 fill_rule,
			   double			 tolerance,
			   cairo_antialias_t		 antialias,
			   const cairo_clip_t		*clip)
{
498630
    cairo_image_surface_t *surface = abstract_surface;
    TRACE ((stderr, "%s (surface=%d)\n",
	    __FUNCTION__, surface->base.unique_id));
498630
    return _cairo_compositor_fill (surface->compositor, &surface->base,
				   op, source, path,
				   fill_rule, tolerance, antialias,
				   clip);
}
cairo_int_status_t
69792
_cairo_image_surface_glyphs (void			*abstract_surface,
			     cairo_operator_t		 op,
			     const cairo_pattern_t	*source,
			     cairo_glyph_t		*glyphs,
			     int			 num_glyphs,
			     cairo_scaled_font_t	*scaled_font,
			     const cairo_clip_t		*clip)
{
69792
    cairo_image_surface_t *surface = abstract_surface;
    TRACE ((stderr, "%s (surface=%d)\n",
	    __FUNCTION__, surface->base.unique_id));
69792
    return _cairo_compositor_glyphs (surface->compositor, &surface->base,
				     op, source,
				     glyphs, num_glyphs, scaled_font,
				     clip);
}
void
22045
_cairo_image_surface_get_font_options (void                  *abstract_surface,
				       cairo_font_options_t  *options)
{
22045
    _cairo_font_options_init_default (options);
22045
    cairo_font_options_set_hint_metrics (options, CAIRO_HINT_METRICS_ON);
22045
    _cairo_font_options_set_round_glyph_positions (options, CAIRO_ROUND_GLYPH_POS_ON);
22045
}
const cairo_surface_backend_t _cairo_image_surface_backend = {
    CAIRO_SURFACE_TYPE_IMAGE,
    _cairo_image_surface_finish,
    _cairo_default_context_create,
    _cairo_image_surface_create_similar,
    NULL, /* create similar image */
    _cairo_image_surface_map_to_image,
    _cairo_image_surface_unmap_image,
    _cairo_image_surface_source,
    _cairo_image_surface_acquire_source_image,
    _cairo_image_surface_release_source_image,
    _cairo_image_surface_snapshot,
    NULL, /* copy_page */
    NULL, /* show_page */
    _cairo_image_surface_get_extents,
    _cairo_image_surface_get_font_options,
    NULL, /* flush */
    NULL,
    _cairo_image_surface_paint,
    _cairo_image_surface_mask,
    _cairo_image_surface_stroke,
    _cairo_image_surface_fill,
    NULL, /* fill-stroke */
    _cairo_image_surface_glyphs,
};
/* A convenience function for when one needs to coerce an image
 * surface to an alternate format. */
cairo_image_surface_t *
2052
_cairo_image_surface_coerce (cairo_image_surface_t *surface)
{
2052
    return _cairo_image_surface_coerce_to_format (surface,
		                                  _cairo_format_from_content (surface->base.content));
}
/* A convenience function for when one needs to coerce an image
 * surface to an alternate format. */
cairo_image_surface_t *
2229
_cairo_image_surface_coerce_to_format (cairo_image_surface_t *surface,
			               cairo_format_t	      format)
{
    cairo_image_surface_t *clone;
    cairo_status_t status;
2229
    status = surface->base.status;
2229
    if (unlikely (status))
	return (cairo_image_surface_t *)_cairo_surface_create_in_error (status);
2229
    if (surface->format == format)
2118
	return (cairo_image_surface_t *)cairo_surface_reference(&surface->base);
    clone = (cairo_image_surface_t *)
111
	cairo_image_surface_create (format, surface->width, surface->height);
111
    if (unlikely (clone->base.status))
	return clone;
111
    pixman_image_composite32 (PIXMAN_OP_SRC,
                              surface->pixman_image, NULL, clone->pixman_image,
                              0, 0,
                              0, 0,
                              0, 0,
                              surface->width, surface->height);
111
    clone->base.is_clear = FALSE;
111
    clone->base.device_transform =
	surface->base.device_transform;
111
    clone->base.device_transform_inverse =
	surface->base.device_transform_inverse;
111
    return clone;
}
cairo_image_surface_t *
_cairo_image_surface_create_from_image (cairo_image_surface_t *other,
					pixman_format_code_t format,
					int x, int y,
					int width, int height, int stride)
{
    cairo_image_surface_t *surface;
    cairo_status_t status;
    pixman_image_t *image;
    void *mem = NULL;
    status = other->base.status;
    if (unlikely (status))
	goto cleanup;
    if (stride) {
	mem = _cairo_malloc_ab (height, stride);
	if (unlikely (mem == NULL)) {
	    status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
	    goto cleanup;
	}
    }
    image = pixman_image_create_bits (format, width, height, mem, stride);
    if (unlikely (image == NULL)) {
	status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
	goto cleanup_mem;
    }
    surface = (cairo_image_surface_t *)
	_cairo_image_surface_create_for_pixman_image (image, format);
    if (unlikely (surface->base.status)) {
	status = surface->base.status;
	goto cleanup_image;
    }
    pixman_image_composite32 (PIXMAN_OP_SRC,
                              other->pixman_image, NULL, image,
                              x, y,
                              0, 0,
                              0, 0,
                              width, height);
    surface->base.is_clear = FALSE;
    surface->owns_data = mem != NULL;
    return surface;
cleanup_image:
    pixman_image_unref (image);
cleanup_mem:
    free (mem);
cleanup:
    return (cairo_image_surface_t *) _cairo_surface_create_in_error (status);
}
static cairo_image_transparency_t
972
_cairo_image_compute_transparency (cairo_image_surface_t *image)
{
    int x, y;
    cairo_image_transparency_t transparency;
972
    if ((image->base.content & CAIRO_CONTENT_ALPHA) == 0)
	return CAIRO_IMAGE_IS_OPAQUE;
972
    if (image->base.is_clear)
370
	return CAIRO_IMAGE_HAS_BILEVEL_ALPHA;
602
    if ((image->base.content & CAIRO_CONTENT_COLOR) == 0) {
	if (image->format == CAIRO_FORMAT_A1) {
	    return CAIRO_IMAGE_HAS_BILEVEL_ALPHA;
	} else if (image->format == CAIRO_FORMAT_A8) {
	    for (y = 0; y < image->height; y++) {
		uint8_t *alpha = (uint8_t *) (image->data + y * image->stride);
		for (x = 0; x < image->width; x++, alpha++) {
		    if (*alpha > 0 && *alpha < 255)
			return CAIRO_IMAGE_HAS_ALPHA;
		}
	    }
	    return CAIRO_IMAGE_HAS_BILEVEL_ALPHA;
	} else {
	    return CAIRO_IMAGE_HAS_ALPHA;
	}
    }
602
    if (image->format == CAIRO_FORMAT_RGB16_565) {
	return CAIRO_IMAGE_IS_OPAQUE;
    }
602
    if (image->format != CAIRO_FORMAT_ARGB32)
	return CAIRO_IMAGE_HAS_ALPHA;
602
    transparency = CAIRO_IMAGE_IS_OPAQUE;
60307
    for (y = 0; y < image->height; y++) {
59823
	uint32_t *pixel = (uint32_t *) (image->data + y * image->stride);
24396400
	for (x = 0; x < image->width; x++, pixel++) {
24336695
	    int a = (*pixel & 0xff000000) >> 24;
24336695
	    if (a > 0 && a < 255) {
118
		return CAIRO_IMAGE_HAS_ALPHA;
24336577
	    } else if (a == 0) {
267014
		transparency = CAIRO_IMAGE_HAS_BILEVEL_ALPHA;
	    }
	}
    }
484
    return transparency;
}
cairo_image_transparency_t
972
_cairo_image_analyze_transparency (cairo_image_surface_t *image)
{
972
    if (_cairo_surface_is_snapshot (&image->base)) {
	if (image->transparency == CAIRO_IMAGE_UNKNOWN)
	    image->transparency = _cairo_image_compute_transparency (image);
	return image->transparency;
    }
972
    return _cairo_image_compute_transparency (image);
}
static cairo_image_color_t
27
_cairo_image_compute_color (cairo_image_surface_t      *image)
{
    int x, y;
    cairo_image_color_t color;
27
    if (image->width == 0 || image->height == 0)
	return CAIRO_IMAGE_IS_MONOCHROME;
27
    if (image->format == CAIRO_FORMAT_A1)
	return CAIRO_IMAGE_IS_MONOCHROME;
27
    if (image->format == CAIRO_FORMAT_A8)
	return CAIRO_IMAGE_IS_GRAYSCALE;
27
    if (image->format == CAIRO_FORMAT_ARGB32) {
7
	color = CAIRO_IMAGE_IS_MONOCHROME;
7
	for (y = 0; y < image->height; y++) {
7
	    uint32_t *pixel = (uint32_t *) (image->data + y * image->stride);
82
	    for (x = 0; x < image->width; x++, pixel++) {
82
		int a = (*pixel & 0xff000000) >> 24;
82
		int r = (*pixel & 0x00ff0000) >> 16;
82
		int g = (*pixel & 0x0000ff00) >> 8;
82
		int b = (*pixel & 0x000000ff);
82
		if (a == 0) {
75
		    r = g = b = 0;
		} else {
7
		    r = (r * 255 + a / 2) / a;
7
		    g = (g * 255 + a / 2) / a;
7
		    b = (b * 255 + a / 2) / a;
		}
82
		if (!(r == g && g == b))
7
		    return CAIRO_IMAGE_IS_COLOR;
75
		else if (r > 0 && r < 255)
		    color = CAIRO_IMAGE_IS_GRAYSCALE;
	    }
	}
	return color;
    }
20
    if (image->format == CAIRO_FORMAT_RGB24) {
20
	color = CAIRO_IMAGE_IS_MONOCHROME;
564
	for (y = 0; y < image->height; y++) {
560
	    uint32_t *pixel = (uint32_t *) (image->data + y * image->stride);
89548
	    for (x = 0; x < image->width; x++, pixel++) {
89004
		int r = (*pixel & 0x00ff0000) >> 16;
89004
		int g = (*pixel & 0x0000ff00) >>  8;
89004
		int b = (*pixel & 0x000000ff);
89004
		if (!(r == g && g == b))
16
		    return CAIRO_IMAGE_IS_COLOR;
88988
		else if (r > 0 && r < 255)
		    color = CAIRO_IMAGE_IS_GRAYSCALE;
	    }
	}
4
	return color;
    }
    return CAIRO_IMAGE_IS_COLOR;
}
cairo_image_color_t
27
_cairo_image_analyze_color (cairo_image_surface_t      *image)
{
27
    if (_cairo_surface_is_snapshot (&image->base)) {
	if (image->color == CAIRO_IMAGE_UNKNOWN_COLOR)
	    image->color = _cairo_image_compute_color (image);
	return image->color;
    }
27
    return _cairo_image_compute_color (image);
}
cairo_image_surface_t *
_cairo_image_surface_clone_subimage (cairo_surface_t             *surface,
				     const cairo_rectangle_int_t *extents)
{
    cairo_surface_t *image;
    cairo_surface_pattern_t pattern;
    cairo_status_t status;
    image = cairo_surface_create_similar_image (surface,
						_cairo_format_from_content (surface->content),
						extents->width,
						extents->height);
    if (image->status)
	return to_image_surface (image);
    /* TODO: check me with non-identity device_transform. Should we
     * clone the scaling, too? */
    cairo_surface_set_device_offset (image,
				     -extents->x,
				     -extents->y);
    _cairo_pattern_init_for_surface (&pattern, surface);
    pattern.base.filter = CAIRO_FILTER_NEAREST;
    status = _cairo_surface_paint (image,
				   CAIRO_OPERATOR_SOURCE,
				   &pattern.base,
				   NULL);
    _cairo_pattern_fini (&pattern.base);
    if (unlikely (status))
	goto error;
    /* We use the parent as a flag during map-to-image/umap-image that the
     * resultant image came from a fallback rather than as direct call
     * to the backend's map_to_image(). Whilst we use it as a simple flag,
     * we need to make sure the parent surface obeys the reference counting
     * semantics and is consistent for all callers.
     */
    _cairo_image_surface_set_parent (to_image_surface (image),
				     cairo_surface_reference (surface));
    return to_image_surface (image);
error:
    cairo_surface_destroy (image);
    return to_image_surface (_cairo_surface_create_in_error (status));
}