2 * Copyright © 2000 SuSE, Inc.
3 * Copyright © 2007 Red Hat, Inc.
5 * Permission to use, copy, modify, distribute, and sell this software and its
6 * documentation for any purpose is hereby granted without fee, provided that
7 * the above copyright notice appear in all copies and that both that
8 * copyright notice and this permission notice appear in supporting
9 * documentation, and that the name of SuSE not be used in advertising or
10 * publicity pertaining to distribution of the software without specific,
11 * written prior permission. SuSE makes no representations about the
12 * suitability of this software for any purpose. It is provided "as is"
13 * without express or implied warranty.
15 * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
17 * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
18 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
19 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
20 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
32 #include "pixman-private.h"
34 static const pixman_color_t transparent_black
= { 0, 0, 0, 0 };
37 gradient_property_changed (pixman_image_t
*image
)
39 gradient_t
*gradient
= &image
->gradient
;
40 int n
= gradient
->n_stops
;
41 pixman_gradient_stop_t
*stops
= gradient
->stops
;
42 pixman_gradient_stop_t
*begin
= &(gradient
->stops
[-1]);
43 pixman_gradient_stop_t
*end
= &(gradient
->stops
[n
]);
45 switch (gradient
->common
.repeat
)
48 case PIXMAN_REPEAT_NONE
:
50 begin
->color
= transparent_black
;
52 end
->color
= transparent_black
;
55 case PIXMAN_REPEAT_NORMAL
:
56 begin
->x
= stops
[n
- 1].x
- pixman_fixed_1
;
57 begin
->color
= stops
[n
- 1].color
;
58 end
->x
= stops
[0].x
+ pixman_fixed_1
;
59 end
->color
= stops
[0].color
;
62 case PIXMAN_REPEAT_REFLECT
:
63 begin
->x
= - stops
[0].x
;
64 begin
->color
= stops
[0].color
;
65 end
->x
= pixman_int_to_fixed (2) - stops
[n
- 1].x
;
66 end
->color
= stops
[n
- 1].color
;
69 case PIXMAN_REPEAT_PAD
:
71 begin
->color
= stops
[0].color
;
73 end
->color
= stops
[n
- 1].color
;
79 _pixman_init_gradient (gradient_t
* gradient
,
80 const pixman_gradient_stop_t
*stops
,
83 return_val_if_fail (n_stops
> 0, FALSE
);
85 /* We allocate two extra stops, one before the beginning of the stop list,
86 * and one after the end. These stops are initialized to whatever color
87 * would be used for positions outside the range of the stop list.
89 * This saves a bit of computation in the gradient walker.
91 * The pointer we store in the gradient_t struct still points to the
92 * first user-supplied struct, so when freeing, we will have to
96 pixman_malloc_ab (n_stops
+ 2, sizeof (pixman_gradient_stop_t
));
100 gradient
->stops
+= 1;
101 memcpy (gradient
->stops
, stops
, n_stops
* sizeof (pixman_gradient_stop_t
));
102 gradient
->n_stops
= n_stops
;
104 gradient
->common
.property_changed
= gradient_property_changed
;
110 _pixman_image_init (pixman_image_t
*image
)
112 image_common_t
*common
= &image
->common
;
114 pixman_region32_init (&common
->clip_region
);
116 common
->alpha_count
= 0;
117 common
->have_clip_region
= FALSE
;
118 common
->clip_sources
= FALSE
;
119 common
->transform
= NULL
;
120 common
->repeat
= PIXMAN_REPEAT_NONE
;
121 common
->filter
= PIXMAN_FILTER_NEAREST
;
122 common
->filter_params
= NULL
;
123 common
->n_filter_params
= 0;
124 common
->alpha_map
= NULL
;
125 common
->component_alpha
= FALSE
;
126 common
->ref_count
= 1;
127 common
->property_changed
= NULL
;
128 common
->client_clip
= FALSE
;
129 common
->destroy_func
= NULL
;
130 common
->destroy_data
= NULL
;
131 common
->dirty
= TRUE
;
135 _pixman_image_fini (pixman_image_t
*image
)
137 image_common_t
*common
= (image_common_t
*)image
;
141 if (common
->ref_count
== 0)
143 if (image
->common
.destroy_func
)
144 image
->common
.destroy_func (image
, image
->common
.destroy_data
);
146 pixman_region32_fini (&common
->clip_region
);
148 free (common
->transform
);
149 free (common
->filter_params
);
151 if (common
->alpha_map
)
152 pixman_image_unref ((pixman_image_t
*)common
->alpha_map
);
154 if (image
->type
== LINEAR
||
155 image
->type
== RADIAL
||
156 image
->type
== CONICAL
)
158 if (image
->gradient
.stops
)
160 /* See _pixman_init_gradient() for an explanation of the - 1 */
161 free (image
->gradient
.stops
- 1);
164 /* This will trigger if someone adds a property_changed
165 * method to the linear/radial/conical gradient overwriting
169 image
->common
.property_changed
== gradient_property_changed
);
172 if (image
->type
== BITS
&& image
->bits
.free_me
)
173 free (image
->bits
.free_me
);
182 _pixman_image_allocate (void)
184 pixman_image_t
*image
= malloc (sizeof (pixman_image_t
));
187 _pixman_image_init (image
);
193 image_property_changed (pixman_image_t
*image
)
195 image
->common
.dirty
= TRUE
;
199 PIXMAN_EXPORT pixman_image_t
*
200 pixman_image_ref (pixman_image_t
*image
)
202 image
->common
.ref_count
++;
207 /* returns TRUE when the image is freed */
208 PIXMAN_EXPORT pixman_bool_t
209 pixman_image_unref (pixman_image_t
*image
)
211 if (_pixman_image_fini (image
))
221 pixman_image_set_destroy_function (pixman_image_t
* image
,
222 pixman_image_destroy_func_t func
,
225 image
->common
.destroy_func
= func
;
226 image
->common
.destroy_data
= data
;
230 pixman_image_get_destroy_data (pixman_image_t
*image
)
232 return image
->common
.destroy_data
;
236 _pixman_image_reset_clip_region (pixman_image_t
*image
)
238 image
->common
.have_clip_region
= FALSE
;
241 /* Executive Summary: This function is a no-op that only exists
242 * for historical reasons.
244 * There used to be a bug in the X server where it would rely on
245 * out-of-bounds accesses when it was asked to composite with a
246 * window as the source. It would create a pixman image pointing
247 * to some bogus position in memory, but then set a clip region
248 * to the position where the actual bits were.
250 * Due to a bug in old versions of pixman, where it would not clip
251 * against the image bounds when a clip region was set, this would
252 * actually work. So when the pixman bug was fixed, a workaround was
253 * added to allow certain out-of-bound accesses. This function disabled
256 * Since 0.21.2, pixman doesn't do these workarounds anymore, so now
257 * this function is a no-op.
260 pixman_disable_out_of_bounds_workaround (void)
265 compute_image_info (pixman_image_t
*image
)
267 pixman_format_code_t code
;
271 if (!image
->common
.transform
)
273 flags
|= (FAST_PATH_ID_TRANSFORM
|
274 FAST_PATH_X_UNIT_POSITIVE
|
275 FAST_PATH_Y_UNIT_ZERO
|
276 FAST_PATH_AFFINE_TRANSFORM
);
280 flags
|= FAST_PATH_HAS_TRANSFORM
;
282 if (image
->common
.transform
->matrix
[2][0] == 0 &&
283 image
->common
.transform
->matrix
[2][1] == 0 &&
284 image
->common
.transform
->matrix
[2][2] == pixman_fixed_1
)
286 flags
|= FAST_PATH_AFFINE_TRANSFORM
;
288 if (image
->common
.transform
->matrix
[0][1] == 0 &&
289 image
->common
.transform
->matrix
[1][0] == 0)
291 if (image
->common
.transform
->matrix
[0][0] == -pixman_fixed_1
&&
292 image
->common
.transform
->matrix
[1][1] == -pixman_fixed_1
)
294 flags
|= FAST_PATH_ROTATE_180_TRANSFORM
;
296 flags
|= FAST_PATH_SCALE_TRANSFORM
;
298 else if (image
->common
.transform
->matrix
[0][0] == 0 &&
299 image
->common
.transform
->matrix
[1][1] == 0)
301 pixman_fixed_t m01
= image
->common
.transform
->matrix
[0][1];
302 pixman_fixed_t m10
= image
->common
.transform
->matrix
[1][0];
304 if (m01
== -pixman_fixed_1
&& m10
== pixman_fixed_1
)
305 flags
|= FAST_PATH_ROTATE_90_TRANSFORM
;
306 else if (m01
== pixman_fixed_1
&& m10
== -pixman_fixed_1
)
307 flags
|= FAST_PATH_ROTATE_270_TRANSFORM
;
311 if (image
->common
.transform
->matrix
[0][0] > 0)
312 flags
|= FAST_PATH_X_UNIT_POSITIVE
;
314 if (image
->common
.transform
->matrix
[1][0] == 0)
315 flags
|= FAST_PATH_Y_UNIT_ZERO
;
319 switch (image
->common
.filter
)
321 case PIXMAN_FILTER_NEAREST
:
322 case PIXMAN_FILTER_FAST
:
323 flags
|= (FAST_PATH_NEAREST_FILTER
| FAST_PATH_NO_CONVOLUTION_FILTER
);
326 case PIXMAN_FILTER_BILINEAR
:
327 case PIXMAN_FILTER_GOOD
:
328 case PIXMAN_FILTER_BEST
:
329 flags
|= (FAST_PATH_BILINEAR_FILTER
| FAST_PATH_NO_CONVOLUTION_FILTER
);
331 /* Here we have a chance to optimize BILINEAR filter to NEAREST if
332 * they are equivalent for the currently used transformation matrix.
334 if (flags
& FAST_PATH_ID_TRANSFORM
)
336 flags
|= FAST_PATH_NEAREST_FILTER
;
339 /* affine and integer translation components in matrix ... */
340 ((flags
& FAST_PATH_AFFINE_TRANSFORM
) &&
341 !pixman_fixed_frac (image
->common
.transform
->matrix
[0][2] |
342 image
->common
.transform
->matrix
[1][2])) &&
344 /* ... combined with a simple rotation */
345 (flags
& (FAST_PATH_ROTATE_90_TRANSFORM
|
346 FAST_PATH_ROTATE_180_TRANSFORM
|
347 FAST_PATH_ROTATE_270_TRANSFORM
)) ||
348 /* ... or combined with a simple non-rotated translation */
349 (image
->common
.transform
->matrix
[0][0] == pixman_fixed_1
&&
350 image
->common
.transform
->matrix
[1][1] == pixman_fixed_1
&&
351 image
->common
.transform
->matrix
[0][1] == 0 &&
352 image
->common
.transform
->matrix
[1][0] == 0)
356 /* FIXME: there are some affine-test failures, showing that
357 * handling of BILINEAR and NEAREST filter is not quite
358 * equivalent when getting close to 32K for the translation
359 * components of the matrix. That's likely some bug, but for
360 * now just skip BILINEAR->NEAREST optimization in this case.
362 pixman_fixed_t magic_limit
= pixman_int_to_fixed (30000);
363 if (image
->common
.transform
->matrix
[0][2] <= magic_limit
&&
364 image
->common
.transform
->matrix
[1][2] <= magic_limit
&&
365 image
->common
.transform
->matrix
[0][2] >= -magic_limit
&&
366 image
->common
.transform
->matrix
[1][2] >= -magic_limit
)
368 flags
|= FAST_PATH_NEAREST_FILTER
;
373 case PIXMAN_FILTER_CONVOLUTION
:
376 case PIXMAN_FILTER_SEPARABLE_CONVOLUTION
:
377 flags
|= FAST_PATH_SEPARABLE_CONVOLUTION_FILTER
;
381 flags
|= FAST_PATH_NO_CONVOLUTION_FILTER
;
386 switch (image
->common
.repeat
)
388 case PIXMAN_REPEAT_NONE
:
390 FAST_PATH_NO_REFLECT_REPEAT
|
391 FAST_PATH_NO_PAD_REPEAT
|
392 FAST_PATH_NO_NORMAL_REPEAT
;
395 case PIXMAN_REPEAT_REFLECT
:
397 FAST_PATH_NO_PAD_REPEAT
|
398 FAST_PATH_NO_NONE_REPEAT
|
399 FAST_PATH_NO_NORMAL_REPEAT
;
402 case PIXMAN_REPEAT_PAD
:
404 FAST_PATH_NO_REFLECT_REPEAT
|
405 FAST_PATH_NO_NONE_REPEAT
|
406 FAST_PATH_NO_NORMAL_REPEAT
;
411 FAST_PATH_NO_REFLECT_REPEAT
|
412 FAST_PATH_NO_PAD_REPEAT
|
413 FAST_PATH_NO_NONE_REPEAT
;
417 /* Component alpha */
418 if (image
->common
.component_alpha
)
419 flags
|= FAST_PATH_COMPONENT_ALPHA
;
421 flags
|= FAST_PATH_UNIFIED_ALPHA
;
423 flags
|= (FAST_PATH_NO_ACCESSORS
| FAST_PATH_NARROW_FORMAT
);
425 /* Type specific checks */
431 if (image
->solid
.color
.alpha
== 0xffff)
432 flags
|= FAST_PATH_IS_OPAQUE
;
436 if (image
->bits
.width
== 1 &&
437 image
->bits
.height
== 1 &&
438 image
->common
.repeat
!= PIXMAN_REPEAT_NONE
)
444 code
= image
->bits
.format
;
445 flags
|= FAST_PATH_BITS_IMAGE
;
448 if (!PIXMAN_FORMAT_A (image
->bits
.format
) &&
449 PIXMAN_FORMAT_TYPE (image
->bits
.format
) != PIXMAN_TYPE_GRAY
&&
450 PIXMAN_FORMAT_TYPE (image
->bits
.format
) != PIXMAN_TYPE_COLOR
)
452 flags
|= FAST_PATH_SAMPLES_OPAQUE
;
454 if (image
->common
.repeat
!= PIXMAN_REPEAT_NONE
)
455 flags
|= FAST_PATH_IS_OPAQUE
;
458 if (image
->bits
.read_func
|| image
->bits
.write_func
)
459 flags
&= ~FAST_PATH_NO_ACCESSORS
;
461 if (PIXMAN_FORMAT_IS_WIDE (image
->bits
.format
))
462 flags
&= ~FAST_PATH_NARROW_FORMAT
;
466 code
= PIXMAN_unknown
;
469 * As explained in pixman-radial-gradient.c, every point of
470 * the plane has a valid associated radius (and thus will be
471 * colored) if and only if a is negative (i.e. one of the two
472 * circles contains the other one).
475 if (image
->radial
.a
>= 0)
482 code
= PIXMAN_unknown
;
484 if (image
->common
.repeat
!= PIXMAN_REPEAT_NONE
)
488 flags
|= FAST_PATH_IS_OPAQUE
;
489 for (i
= 0; i
< image
->gradient
.n_stops
; ++i
)
491 if (image
->gradient
.stops
[i
].color
.alpha
!= 0xffff)
493 flags
&= ~FAST_PATH_IS_OPAQUE
;
501 code
= PIXMAN_unknown
;
505 /* Alpha maps are only supported for BITS images, so it's always
506 * safe to ignore their presense for non-BITS images
508 if (!image
->common
.alpha_map
|| image
->type
!= BITS
)
510 flags
|= FAST_PATH_NO_ALPHA_MAP
;
514 if (PIXMAN_FORMAT_IS_WIDE (image
->common
.alpha_map
->format
))
515 flags
&= ~FAST_PATH_NARROW_FORMAT
;
518 /* Both alpha maps and convolution filters can introduce
519 * non-opaqueness in otherwise opaque images. Also
520 * an image with component alpha turned on is only opaque
521 * if all channels are opaque, so we simply turn it off
522 * unconditionally for those images.
524 if (image
->common
.alpha_map
||
525 image
->common
.filter
== PIXMAN_FILTER_CONVOLUTION
||
526 image
->common
.filter
== PIXMAN_FILTER_SEPARABLE_CONVOLUTION
||
527 image
->common
.component_alpha
)
529 flags
&= ~(FAST_PATH_IS_OPAQUE
| FAST_PATH_SAMPLES_OPAQUE
);
532 image
->common
.flags
= flags
;
533 image
->common
.extended_format_code
= code
;
537 _pixman_image_validate (pixman_image_t
*image
)
539 if (image
->common
.dirty
)
541 compute_image_info (image
);
543 /* It is important that property_changed is
544 * called *after* compute_image_info() because
545 * property_changed() can make use of the flags
546 * to set up accessors etc.
548 if (image
->common
.property_changed
)
549 image
->common
.property_changed (image
);
551 image
->common
.dirty
= FALSE
;
554 if (image
->common
.alpha_map
)
555 _pixman_image_validate ((pixman_image_t
*)image
->common
.alpha_map
);
558 PIXMAN_EXPORT pixman_bool_t
559 pixman_image_set_clip_region32 (pixman_image_t
* image
,
560 pixman_region32_t
*region
)
562 image_common_t
*common
= (image_common_t
*)image
;
563 pixman_bool_t result
;
567 if ((result
= pixman_region32_copy (&common
->clip_region
, region
)))
568 image
->common
.have_clip_region
= TRUE
;
572 _pixman_image_reset_clip_region (image
);
577 image_property_changed (image
);
582 PIXMAN_EXPORT pixman_bool_t
583 pixman_image_set_clip_region (pixman_image_t
* image
,
584 pixman_region16_t
*region
)
586 image_common_t
*common
= (image_common_t
*)image
;
587 pixman_bool_t result
;
591 if ((result
= pixman_region32_copy_from_region16 (&common
->clip_region
, region
)))
592 image
->common
.have_clip_region
= TRUE
;
596 _pixman_image_reset_clip_region (image
);
601 image_property_changed (image
);
607 pixman_image_set_has_client_clip (pixman_image_t
*image
,
608 pixman_bool_t client_clip
)
610 image
->common
.client_clip
= client_clip
;
613 PIXMAN_EXPORT pixman_bool_t
614 pixman_image_set_transform (pixman_image_t
* image
,
615 const pixman_transform_t
*transform
)
617 static const pixman_transform_t id
=
619 { { pixman_fixed_1
, 0, 0 },
620 { 0, pixman_fixed_1
, 0 },
621 { 0, 0, pixman_fixed_1
} }
624 image_common_t
*common
= (image_common_t
*)image
;
625 pixman_bool_t result
;
627 if (common
->transform
== transform
)
630 if (!transform
|| memcmp (&id
, transform
, sizeof (pixman_transform_t
)) == 0)
632 free (common
->transform
);
633 common
->transform
= NULL
;
639 if (common
->transform
&&
640 memcmp (common
->transform
, transform
, sizeof (pixman_transform_t
)) == 0)
645 if (common
->transform
== NULL
)
646 common
->transform
= malloc (sizeof (pixman_transform_t
));
648 if (common
->transform
== NULL
)
655 memcpy (common
->transform
, transform
, sizeof(pixman_transform_t
));
660 image_property_changed (image
);
666 pixman_image_set_repeat (pixman_image_t
*image
,
667 pixman_repeat_t repeat
)
669 if (image
->common
.repeat
== repeat
)
672 image
->common
.repeat
= repeat
;
674 image_property_changed (image
);
677 PIXMAN_EXPORT pixman_bool_t
678 pixman_image_set_filter (pixman_image_t
* image
,
679 pixman_filter_t filter
,
680 const pixman_fixed_t
*params
,
683 image_common_t
*common
= (image_common_t
*)image
;
684 pixman_fixed_t
*new_params
;
686 if (params
== common
->filter_params
&& filter
== common
->filter
)
689 if (filter
== PIXMAN_FILTER_SEPARABLE_CONVOLUTION
)
691 int width
= pixman_fixed_to_int (params
[0]);
692 int height
= pixman_fixed_to_int (params
[1]);
693 int x_phase_bits
= pixman_fixed_to_int (params
[2]);
694 int y_phase_bits
= pixman_fixed_to_int (params
[3]);
695 int n_x_phases
= (1 << x_phase_bits
);
696 int n_y_phases
= (1 << y_phase_bits
);
699 n_params
== 4 + n_x_phases
* width
+ n_y_phases
* height
, FALSE
);
705 new_params
= pixman_malloc_ab (n_params
, sizeof (pixman_fixed_t
));
710 params
, n_params
* sizeof (pixman_fixed_t
));
713 common
->filter
= filter
;
715 if (common
->filter_params
)
716 free (common
->filter_params
);
718 common
->filter_params
= new_params
;
719 common
->n_filter_params
= n_params
;
721 image_property_changed (image
);
726 pixman_image_set_source_clipping (pixman_image_t
*image
,
727 pixman_bool_t clip_sources
)
729 if (image
->common
.clip_sources
== clip_sources
)
732 image
->common
.clip_sources
= clip_sources
;
734 image_property_changed (image
);
737 /* Unlike all the other property setters, this function does not
738 * copy the content of indexed. Doing this copying is simply
739 * way, way too expensive.
742 pixman_image_set_indexed (pixman_image_t
* image
,
743 const pixman_indexed_t
*indexed
)
745 bits_image_t
*bits
= (bits_image_t
*)image
;
747 if (bits
->indexed
== indexed
)
750 bits
->indexed
= indexed
;
752 image_property_changed (image
);
756 pixman_image_set_alpha_map (pixman_image_t
*image
,
757 pixman_image_t
*alpha_map
,
761 image_common_t
*common
= (image_common_t
*)image
;
763 return_if_fail (!alpha_map
|| alpha_map
->type
== BITS
);
765 if (alpha_map
&& common
->alpha_count
> 0)
767 /* If this image is being used as an alpha map itself,
768 * then you can't give it an alpha map of its own.
773 if (alpha_map
&& alpha_map
->common
.alpha_map
)
775 /* If the image has an alpha map of its own,
776 * then it can't be used as an alpha map itself
781 if (common
->alpha_map
!= (bits_image_t
*)alpha_map
)
783 if (common
->alpha_map
)
785 common
->alpha_map
->common
.alpha_count
--;
787 pixman_image_unref ((pixman_image_t
*)common
->alpha_map
);
792 common
->alpha_map
= (bits_image_t
*)pixman_image_ref (alpha_map
);
794 common
->alpha_map
->common
.alpha_count
++;
798 common
->alpha_map
= NULL
;
802 common
->alpha_origin_x
= x
;
803 common
->alpha_origin_y
= y
;
805 image_property_changed (image
);
809 pixman_image_set_component_alpha (pixman_image_t
*image
,
810 pixman_bool_t component_alpha
)
812 if (image
->common
.component_alpha
== component_alpha
)
815 image
->common
.component_alpha
= component_alpha
;
817 image_property_changed (image
);
820 PIXMAN_EXPORT pixman_bool_t
821 pixman_image_get_component_alpha (pixman_image_t
*image
)
823 return image
->common
.component_alpha
;
827 pixman_image_set_accessors (pixman_image_t
* image
,
828 pixman_read_memory_func_t read_func
,
829 pixman_write_memory_func_t write_func
)
831 return_if_fail (image
!= NULL
);
833 if (image
->type
== BITS
)
835 image
->bits
.read_func
= read_func
;
836 image
->bits
.write_func
= write_func
;
838 image_property_changed (image
);
842 PIXMAN_EXPORT
uint32_t *
843 pixman_image_get_data (pixman_image_t
*image
)
845 if (image
->type
== BITS
)
846 return image
->bits
.bits
;
852 pixman_image_get_width (pixman_image_t
*image
)
854 if (image
->type
== BITS
)
855 return image
->bits
.width
;
861 pixman_image_get_height (pixman_image_t
*image
)
863 if (image
->type
== BITS
)
864 return image
->bits
.height
;
870 pixman_image_get_stride (pixman_image_t
*image
)
872 if (image
->type
== BITS
)
873 return image
->bits
.rowstride
* (int) sizeof (uint32_t);
879 pixman_image_get_depth (pixman_image_t
*image
)
881 if (image
->type
== BITS
)
882 return PIXMAN_FORMAT_DEPTH (image
->bits
.format
);
887 PIXMAN_EXPORT pixman_format_code_t
888 pixman_image_get_format (pixman_image_t
*image
)
890 if (image
->type
== BITS
)
891 return image
->bits
.format
;
897 _pixman_image_get_solid (pixman_implementation_t
*imp
,
898 pixman_image_t
* image
,
899 pixman_format_code_t format
)
903 if (image
->type
== SOLID
)
905 result
= image
->solid
.color_32
;
907 else if (image
->type
== BITS
)
909 if (image
->bits
.format
== PIXMAN_a8r8g8b8
)
910 result
= image
->bits
.bits
[0];
911 else if (image
->bits
.format
== PIXMAN_x8r8g8b8
)
912 result
= image
->bits
.bits
[0] | 0xff000000;
913 else if (image
->bits
.format
== PIXMAN_a8
)
914 result
= (*(uint8_t *)image
->bits
.bits
) << 24;
923 _pixman_implementation_iter_init (
924 imp
, &iter
, image
, 0, 0, 1, 1,
926 ITER_NARROW
| ITER_SRC
, image
->common
.flags
);
928 result
= *iter
.get_scanline (&iter
, NULL
);
934 /* If necessary, convert RGB <--> BGR. */
935 if (PIXMAN_FORMAT_TYPE (format
) != PIXMAN_TYPE_ARGB
936 && PIXMAN_FORMAT_TYPE (format
) != PIXMAN_TYPE_ARGB_SRGB
)
938 result
= (((result
& 0xff000000) >> 0) |
939 ((result
& 0x00ff0000) >> 16) |
940 ((result
& 0x0000ff00) >> 0) |
941 ((result
& 0x000000ff) << 16));