Remove the class field from source_image_t
[profile/ivi/pixman.git] / pixman / pixman-image.c
1 /*
2  * Copyright © 2000 SuSE, Inc.
3  * Copyright © 2007 Red Hat, Inc.
4  *
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.
14  *
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.
21  */
22
23 #ifdef HAVE_CONFIG_H
24 #include <config.h>
25 #endif
26
27 #include <stdlib.h>
28 #include <stdio.h>
29 #include <string.h>
30 #include <assert.h>
31
32 #include "pixman-private.h"
33 #include "pixman-combine32.h"
34
35 pixman_bool_t
36 _pixman_init_gradient (gradient_t *                  gradient,
37                        const pixman_gradient_stop_t *stops,
38                        int                           n_stops)
39 {
40     return_val_if_fail (n_stops > 0, FALSE);
41
42     gradient->stops = pixman_malloc_ab (n_stops, sizeof (pixman_gradient_stop_t));
43     if (!gradient->stops)
44         return FALSE;
45
46     memcpy (gradient->stops, stops, n_stops * sizeof (pixman_gradient_stop_t));
47
48     gradient->n_stops = n_stops;
49
50     gradient->stop_range = 0xffff;
51
52     return TRUE;
53 }
54
55 /*
56  * By default, just evaluate the image at 32bpp and expand.  Individual image
57  * types can plug in a better scanline getter if they want to. For example
58  * we  could produce smoother gradients by evaluating them at higher color
59  * depth, but that's a project for the future.
60  */
61 void
62 _pixman_image_get_scanline_generic_64 (pixman_image_t * image,
63                                        int              x,
64                                        int              y,
65                                        int              width,
66                                        uint32_t *       buffer,
67                                        const uint32_t * mask)
68 {
69     uint32_t *mask8 = NULL;
70
71     /* Contract the mask image, if one exists, so that the 32-bit fetch
72      * function can use it.
73      */
74     if (mask)
75     {
76         mask8 = pixman_malloc_ab (width, sizeof(uint32_t));
77         if (!mask8)
78             return;
79
80         pixman_contract (mask8, (uint64_t *)mask, width);
81     }
82
83     /* Fetch the source image into the first half of buffer. */
84     _pixman_image_get_scanline_32 (image, x, y, width, (uint32_t*)buffer, mask8);
85
86     /* Expand from 32bpp to 64bpp in place. */
87     pixman_expand ((uint64_t *)buffer, buffer, PIXMAN_a8r8g8b8, width);
88
89     free (mask8);
90 }
91
92 pixman_image_t *
93 _pixman_image_allocate (void)
94 {
95     pixman_image_t *image = malloc (sizeof (pixman_image_t));
96
97     if (image)
98     {
99         image_common_t *common = &image->common;
100
101         pixman_region32_init (&common->clip_region);
102
103         common->alpha_count = 0;
104         common->have_clip_region = FALSE;
105         common->clip_sources = FALSE;
106         common->transform = NULL;
107         common->repeat = PIXMAN_REPEAT_NONE;
108         common->filter = PIXMAN_FILTER_NEAREST;
109         common->filter_params = NULL;
110         common->n_filter_params = 0;
111         common->alpha_map = NULL;
112         common->component_alpha = FALSE;
113         common->ref_count = 1;
114         common->classify = NULL;
115         common->client_clip = FALSE;
116         common->destroy_func = NULL;
117         common->destroy_data = NULL;
118         common->dirty = TRUE;
119     }
120
121     return image;
122 }
123
124 source_image_class_t
125 _pixman_image_classify (pixman_image_t *image,
126                         int             x,
127                         int             y,
128                         int             width,
129                         int             height)
130 {
131     if (image->common.classify)
132         return image->common.classify (image, x, y, width, height);
133     else
134         return SOURCE_IMAGE_CLASS_UNKNOWN;
135 }
136
137 void
138 _pixman_image_get_scanline_32 (pixman_image_t *image,
139                                int             x,
140                                int             y,
141                                int             width,
142                                uint32_t *      buffer,
143                                const uint32_t *mask)
144 {
145     image->common.get_scanline_32 (image, x, y, width, buffer, mask);
146 }
147
148 /* Even thought the type of buffer is uint32_t *, the function actually expects
149  * a uint64_t *buffer.
150  */
151 void
152 _pixman_image_get_scanline_64 (pixman_image_t *image,
153                                int             x,
154                                int             y,
155                                int             width,
156                                uint32_t *      buffer,
157                                const uint32_t *unused)
158 {
159     image->common.get_scanline_64 (image, x, y, width, buffer, unused);
160 }
161
162 static void
163 image_property_changed (pixman_image_t *image)
164 {
165     image->common.dirty = TRUE;
166 }
167
168 /* Ref Counting */
169 PIXMAN_EXPORT pixman_image_t *
170 pixman_image_ref (pixman_image_t *image)
171 {
172     image->common.ref_count++;
173
174     return image;
175 }
176
177 /* returns TRUE when the image is freed */
178 PIXMAN_EXPORT pixman_bool_t
179 pixman_image_unref (pixman_image_t *image)
180 {
181     image_common_t *common = (image_common_t *)image;
182
183     common->ref_count--;
184
185     if (common->ref_count == 0)
186     {
187         if (image->common.destroy_func)
188             image->common.destroy_func (image, image->common.destroy_data);
189
190         pixman_region32_fini (&common->clip_region);
191
192         if (common->transform)
193             free (common->transform);
194
195         if (common->filter_params)
196             free (common->filter_params);
197
198         if (common->alpha_map)
199             pixman_image_unref ((pixman_image_t *)common->alpha_map);
200
201         if (image->type == LINEAR ||
202             image->type == RADIAL ||
203             image->type == CONICAL)
204         {
205             if (image->gradient.stops)
206                 free (image->gradient.stops);
207         }
208
209         if (image->type == BITS && image->bits.free_me)
210             free (image->bits.free_me);
211
212         free (image);
213
214         return TRUE;
215     }
216
217     return FALSE;
218 }
219
220 PIXMAN_EXPORT void
221 pixman_image_set_destroy_function (pixman_image_t *            image,
222                                    pixman_image_destroy_func_t func,
223                                    void *                      data)
224 {
225     image->common.destroy_func = func;
226     image->common.destroy_data = data;
227 }
228
229 PIXMAN_EXPORT void *
230 pixman_image_get_destroy_data (pixman_image_t *image)
231 {
232   return image->common.destroy_data;
233 }
234
235 void
236 _pixman_image_reset_clip_region (pixman_image_t *image)
237 {
238     image->common.have_clip_region = FALSE;
239 }
240
241 static pixman_bool_t out_of_bounds_workaround = TRUE;
242
243 /* Old X servers rely on out-of-bounds accesses when they are asked
244  * to composite with a window as the source. They create a pixman image
245  * pointing to some bogus position in memory, but then they set a clip
246  * region to the position where the actual bits are.
247  *
248  * Due to a bug in old versions of pixman, where it would not clip
249  * against the image bounds when a clip region was set, this would
250  * actually work. So by default we allow certain out-of-bound access
251  * to happen unless explicitly disabled.
252  *
253  * Fixed X servers should call this function to disable the workaround.
254  */
255 PIXMAN_EXPORT void
256 pixman_disable_out_of_bounds_workaround (void)
257 {
258     out_of_bounds_workaround = FALSE;
259 }
260
261 static pixman_bool_t
262 source_image_needs_out_of_bounds_workaround (bits_image_t *image)
263 {
264     if (image->common.clip_sources                      &&
265         image->common.repeat == PIXMAN_REPEAT_NONE      &&
266         image->common.have_clip_region                  &&
267         out_of_bounds_workaround)
268     {
269         if (!image->common.client_clip)
270         {
271             /* There is no client clip, so if the clip region extends beyond the
272              * drawable geometry, it must be because the X server generated the
273              * bogus clip region.
274              */
275             const pixman_box32_t *extents =
276                 pixman_region32_extents (&image->common.clip_region);
277
278             if (extents->x1 >= 0 && extents->x2 <= image->width &&
279                 extents->y1 >= 0 && extents->y2 <= image->height)
280             {
281                 return FALSE;
282             }
283         }
284
285         return TRUE;
286     }
287
288     return FALSE;
289 }
290
291 static void
292 compute_image_info (pixman_image_t *image)
293 {
294     pixman_format_code_t code;
295     uint32_t flags = 0;
296
297     /* Transform */
298     if (!image->common.transform)
299     {
300         flags |= (FAST_PATH_ID_TRANSFORM        |
301                   FAST_PATH_X_UNIT_POSITIVE     |
302                   FAST_PATH_Y_UNIT_ZERO         |
303                   FAST_PATH_AFFINE_TRANSFORM);
304     }
305     else
306     {
307         flags |= FAST_PATH_HAS_TRANSFORM;
308
309         if (image->common.transform->matrix[2][0] == 0                  &&
310             image->common.transform->matrix[2][1] == 0                  &&
311             image->common.transform->matrix[2][2] == pixman_fixed_1)
312         {
313             flags |= FAST_PATH_AFFINE_TRANSFORM;
314
315             if (image->common.transform->matrix[0][1] == 0 &&
316                 image->common.transform->matrix[1][0] == 0)
317             {
318                 flags |= FAST_PATH_SCALE_TRANSFORM;
319             }
320         }
321
322         if (image->common.transform->matrix[0][0] > 0)
323             flags |= FAST_PATH_X_UNIT_POSITIVE;
324
325         if (image->common.transform->matrix[1][0] == 0)
326             flags |= FAST_PATH_Y_UNIT_ZERO;
327     }
328
329     /* Filter */
330     switch (image->common.filter)
331     {
332     case PIXMAN_FILTER_NEAREST:
333     case PIXMAN_FILTER_FAST:
334         flags |= (FAST_PATH_NEAREST_FILTER | FAST_PATH_NO_CONVOLUTION_FILTER);
335         break;
336
337     case PIXMAN_FILTER_BILINEAR:
338     case PIXMAN_FILTER_GOOD:
339     case PIXMAN_FILTER_BEST:
340         flags |= (FAST_PATH_BILINEAR_FILTER | FAST_PATH_NO_CONVOLUTION_FILTER);
341         break;
342
343     case PIXMAN_FILTER_CONVOLUTION:
344         break;
345
346     default:
347         flags |= FAST_PATH_NO_CONVOLUTION_FILTER;
348         break;
349     }
350
351     /* Repeat mode */
352     switch (image->common.repeat)
353     {
354     case PIXMAN_REPEAT_NONE:
355         flags |=
356             FAST_PATH_NO_REFLECT_REPEAT         |
357             FAST_PATH_NO_PAD_REPEAT             |
358             FAST_PATH_NO_NORMAL_REPEAT;
359         break;
360
361     case PIXMAN_REPEAT_REFLECT:
362         flags |=
363             FAST_PATH_NO_PAD_REPEAT             |
364             FAST_PATH_NO_NONE_REPEAT            |
365             FAST_PATH_NO_NORMAL_REPEAT;
366         break;
367
368     case PIXMAN_REPEAT_PAD:
369         flags |=
370             FAST_PATH_NO_REFLECT_REPEAT         |
371             FAST_PATH_NO_NONE_REPEAT            |
372             FAST_PATH_NO_NORMAL_REPEAT;
373         break;
374
375     default:
376         flags |=
377             FAST_PATH_NO_REFLECT_REPEAT         |
378             FAST_PATH_NO_PAD_REPEAT             |
379             FAST_PATH_NO_NONE_REPEAT;
380         break;
381     }
382
383     /* Component alpha */
384     if (image->common.component_alpha)
385         flags |= FAST_PATH_COMPONENT_ALPHA;
386     else
387         flags |= FAST_PATH_UNIFIED_ALPHA;
388
389     flags |= (FAST_PATH_NO_ACCESSORS | FAST_PATH_NARROW_FORMAT);
390
391     /* Type specific checks */
392     switch (image->type)
393     {
394     case SOLID:
395         code = PIXMAN_solid;
396
397         if (image->solid.color.alpha == 0xffff)
398             flags |= FAST_PATH_IS_OPAQUE;
399         break;
400
401     case BITS:
402         if (image->bits.width == 1      &&
403             image->bits.height == 1     &&
404             image->common.repeat != PIXMAN_REPEAT_NONE)
405         {
406             code = PIXMAN_solid;
407         }
408         else
409         {
410             code = image->bits.format;
411         }
412
413         if (!PIXMAN_FORMAT_A (image->bits.format)                               &&
414             PIXMAN_FORMAT_TYPE (image->bits.format) != PIXMAN_TYPE_GRAY         &&
415             PIXMAN_FORMAT_TYPE (image->bits.format) != PIXMAN_TYPE_COLOR)
416         {
417             flags |= FAST_PATH_SAMPLES_OPAQUE;
418
419             if (image->common.repeat != PIXMAN_REPEAT_NONE)
420                 flags |= FAST_PATH_IS_OPAQUE;
421         }
422
423         if (source_image_needs_out_of_bounds_workaround (&image->bits))
424             flags |= FAST_PATH_NEEDS_WORKAROUND;
425
426         if (image->bits.read_func || image->bits.write_func)
427             flags &= ~FAST_PATH_NO_ACCESSORS;
428
429         if (PIXMAN_FORMAT_IS_WIDE (image->bits.format))
430             flags &= ~FAST_PATH_NARROW_FORMAT;
431         break;
432
433     case LINEAR:
434     case RADIAL:
435         code = PIXMAN_unknown;
436
437         if (image->common.repeat != PIXMAN_REPEAT_NONE)
438         {
439             int i;
440
441             flags |= FAST_PATH_IS_OPAQUE;
442             for (i = 0; i < image->gradient.n_stops; ++i)
443             {
444                 if (image->gradient.stops[i].color.alpha != 0xffff)
445                 {
446                     flags &= ~FAST_PATH_IS_OPAQUE;
447                     break;
448                 }
449             }
450         }
451         break;
452
453     default:
454         code = PIXMAN_unknown;
455         break;
456     }
457
458     /* Alpha map */
459     if (!image->common.alpha_map)
460     {
461         flags |= FAST_PATH_NO_ALPHA_MAP;
462     }
463     else
464     {
465         if (PIXMAN_FORMAT_IS_WIDE (image->common.alpha_map->format))
466             flags &= ~FAST_PATH_NARROW_FORMAT;
467     }
468
469     /* Both alpha maps and convolution filters can introduce
470      * non-opaqueness in otherwise opaque images. Also
471      * an image with component alpha turned on is only opaque
472      * if all channels are opaque, so we simply turn it off
473      * unconditionally for those images.
474      */
475     if (image->common.alpha_map                                 ||
476         image->common.filter == PIXMAN_FILTER_CONVOLUTION       ||
477         image->common.component_alpha)
478     {
479         flags &= ~(FAST_PATH_IS_OPAQUE | FAST_PATH_SAMPLES_OPAQUE);
480     }
481
482     image->common.flags = flags;
483     image->common.extended_format_code = code;
484 }
485
486 void
487 _pixman_image_validate (pixman_image_t *image)
488 {
489     if (image->common.dirty)
490     {
491         compute_image_info (image);
492
493         /* It is important that property_changed is
494          * called *after* compute_image_info() because
495          * property_changed() can make use of the flags
496          * to set up accessors etc.
497          */
498         image->common.property_changed (image);
499
500         image->common.dirty = FALSE;
501     }
502
503     if (image->common.alpha_map)
504         _pixman_image_validate ((pixman_image_t *)image->common.alpha_map);
505 }
506
507 PIXMAN_EXPORT pixman_bool_t
508 pixman_image_set_clip_region32 (pixman_image_t *   image,
509                                 pixman_region32_t *region)
510 {
511     image_common_t *common = (image_common_t *)image;
512     pixman_bool_t result;
513
514     if (region)
515     {
516         if ((result = pixman_region32_copy (&common->clip_region, region)))
517             image->common.have_clip_region = TRUE;
518     }
519     else
520     {
521         _pixman_image_reset_clip_region (image);
522
523         result = TRUE;
524     }
525
526     image_property_changed (image);
527
528     return result;
529 }
530
531 PIXMAN_EXPORT pixman_bool_t
532 pixman_image_set_clip_region (pixman_image_t *   image,
533                               pixman_region16_t *region)
534 {
535     image_common_t *common = (image_common_t *)image;
536     pixman_bool_t result;
537
538     if (region)
539     {
540         if ((result = pixman_region32_copy_from_region16 (&common->clip_region, region)))
541             image->common.have_clip_region = TRUE;
542     }
543     else
544     {
545         _pixman_image_reset_clip_region (image);
546
547         result = TRUE;
548     }
549
550     image_property_changed (image);
551
552     return result;
553 }
554
555 PIXMAN_EXPORT void
556 pixman_image_set_has_client_clip (pixman_image_t *image,
557                                   pixman_bool_t   client_clip)
558 {
559     image->common.client_clip = client_clip;
560 }
561
562 PIXMAN_EXPORT pixman_bool_t
563 pixman_image_set_transform (pixman_image_t *          image,
564                             const pixman_transform_t *transform)
565 {
566     static const pixman_transform_t id =
567     {
568         { { pixman_fixed_1, 0, 0 },
569           { 0, pixman_fixed_1, 0 },
570           { 0, 0, pixman_fixed_1 } }
571     };
572
573     image_common_t *common = (image_common_t *)image;
574     pixman_bool_t result;
575
576     if (common->transform == transform)
577         return TRUE;
578
579     if (memcmp (&id, transform, sizeof (pixman_transform_t)) == 0)
580     {
581         free (common->transform);
582         common->transform = NULL;
583         result = TRUE;
584
585         goto out;
586     }
587
588     if (common->transform == NULL)
589         common->transform = malloc (sizeof (pixman_transform_t));
590
591     if (common->transform == NULL)
592     {
593         result = FALSE;
594
595         goto out;
596     }
597
598     memcpy (common->transform, transform, sizeof(pixman_transform_t));
599
600     result = TRUE;
601
602 out:
603     image_property_changed (image);
604
605     return result;
606 }
607
608 PIXMAN_EXPORT void
609 pixman_image_set_repeat (pixman_image_t *image,
610                          pixman_repeat_t repeat)
611 {
612     image->common.repeat = repeat;
613
614     image_property_changed (image);
615 }
616
617 PIXMAN_EXPORT pixman_bool_t
618 pixman_image_set_filter (pixman_image_t *      image,
619                          pixman_filter_t       filter,
620                          const pixman_fixed_t *params,
621                          int                   n_params)
622 {
623     image_common_t *common = (image_common_t *)image;
624     pixman_fixed_t *new_params;
625
626     if (params == common->filter_params && filter == common->filter)
627         return TRUE;
628
629     new_params = NULL;
630     if (params)
631     {
632         new_params = pixman_malloc_ab (n_params, sizeof (pixman_fixed_t));
633         if (!new_params)
634             return FALSE;
635
636         memcpy (new_params,
637                 params, n_params * sizeof (pixman_fixed_t));
638     }
639
640     common->filter = filter;
641
642     if (common->filter_params)
643         free (common->filter_params);
644
645     common->filter_params = new_params;
646     common->n_filter_params = n_params;
647
648     image_property_changed (image);
649     return TRUE;
650 }
651
652 PIXMAN_EXPORT void
653 pixman_image_set_source_clipping (pixman_image_t *image,
654                                   pixman_bool_t   clip_sources)
655 {
656     image->common.clip_sources = clip_sources;
657
658     image_property_changed (image);
659 }
660
661 /* Unlike all the other property setters, this function does not
662  * copy the content of indexed. Doing this copying is simply
663  * way, way too expensive.
664  */
665 PIXMAN_EXPORT void
666 pixman_image_set_indexed (pixman_image_t *        image,
667                           const pixman_indexed_t *indexed)
668 {
669     bits_image_t *bits = (bits_image_t *)image;
670
671     bits->indexed = indexed;
672
673     image_property_changed (image);
674 }
675
676 PIXMAN_EXPORT void
677 pixman_image_set_alpha_map (pixman_image_t *image,
678                             pixman_image_t *alpha_map,
679                             int16_t         x,
680                             int16_t         y)
681 {
682     image_common_t *common = (image_common_t *)image;
683
684     return_if_fail (!alpha_map || alpha_map->type == BITS);
685
686     if (alpha_map && common->alpha_count > 0)
687     {
688         /* If this image is being used as an alpha map itself,
689          * then you can't give it an alpha map of its own.
690          */
691         return;
692     }
693
694     if (alpha_map && alpha_map->common.alpha_map)
695     {
696         /* If the image has an alpha map of its own,
697          * then it can't be used as an alpha map itself
698          */
699         return;
700     }
701
702     if (common->alpha_map != (bits_image_t *)alpha_map)
703     {
704         if (common->alpha_map)
705         {
706             common->alpha_map->common.alpha_count--;
707
708             pixman_image_unref ((pixman_image_t *)common->alpha_map);
709         }
710
711         if (alpha_map)
712         {
713             common->alpha_map = (bits_image_t *)pixman_image_ref (alpha_map);
714
715             common->alpha_map->common.alpha_count++;
716         }
717         else
718         {
719             common->alpha_map = NULL;
720         }
721     }
722
723     common->alpha_origin_x = x;
724     common->alpha_origin_y = y;
725
726     image_property_changed (image);
727 }
728
729 PIXMAN_EXPORT void
730 pixman_image_set_component_alpha   (pixman_image_t *image,
731                                     pixman_bool_t   component_alpha)
732 {
733     image->common.component_alpha = component_alpha;
734
735     image_property_changed (image);
736 }
737
738 PIXMAN_EXPORT pixman_bool_t
739 pixman_image_get_component_alpha   (pixman_image_t       *image)
740 {
741     return image->common.component_alpha;
742 }
743
744 PIXMAN_EXPORT void
745 pixman_image_set_accessors (pixman_image_t *           image,
746                             pixman_read_memory_func_t  read_func,
747                             pixman_write_memory_func_t write_func)
748 {
749     return_if_fail (image != NULL);
750
751     if (image->type == BITS)
752     {
753         image->bits.read_func = read_func;
754         image->bits.write_func = write_func;
755
756         image_property_changed (image);
757     }
758 }
759
760 PIXMAN_EXPORT uint32_t *
761 pixman_image_get_data (pixman_image_t *image)
762 {
763     if (image->type == BITS)
764         return image->bits.bits;
765
766     return NULL;
767 }
768
769 PIXMAN_EXPORT int
770 pixman_image_get_width (pixman_image_t *image)
771 {
772     if (image->type == BITS)
773         return image->bits.width;
774
775     return 0;
776 }
777
778 PIXMAN_EXPORT int
779 pixman_image_get_height (pixman_image_t *image)
780 {
781     if (image->type == BITS)
782         return image->bits.height;
783
784     return 0;
785 }
786
787 PIXMAN_EXPORT int
788 pixman_image_get_stride (pixman_image_t *image)
789 {
790     if (image->type == BITS)
791         return image->bits.rowstride * (int) sizeof (uint32_t);
792
793     return 0;
794 }
795
796 PIXMAN_EXPORT int
797 pixman_image_get_depth (pixman_image_t *image)
798 {
799     if (image->type == BITS)
800         return PIXMAN_FORMAT_DEPTH (image->bits.format);
801
802     return 0;
803 }
804
805 PIXMAN_EXPORT pixman_format_code_t
806 pixman_image_get_format (pixman_image_t *image)
807 {
808     if (image->type == BITS)
809         return image->bits.format;
810
811     return 0;
812 }
813
814 uint32_t
815 _pixman_image_get_solid (pixman_image_t *     image,
816                          pixman_format_code_t format)
817 {
818     uint32_t result;
819
820     _pixman_image_get_scanline_32 (image, 0, 0, 1, &result, NULL);
821
822     /* If necessary, convert RGB <--> BGR. */
823     if (PIXMAN_FORMAT_TYPE (format) != PIXMAN_TYPE_ARGB)
824     {
825         result = (((result & 0xff000000) >>  0) |
826                   ((result & 0x00ff0000) >> 16) |
827                   ((result & 0x0000ff00) >>  0) |
828                   ((result & 0x000000ff) << 16));
829     }
830
831     return result;
832 }