Delete scanFetchProc type. Use fetch_scanline_t instead.
[profile/ivi/pixman.git] / pixman / pixman-access.c
1 /*
2  *
3  * Copyright © 2000 Keith Packard, member of The XFree86 Project, Inc.
4  *             2005 Lars Knoll & Zack Rusin, Trolltech
5  *             2008 Aaron Plattner, NVIDIA Corporation
6  *
7  * Permission to use, copy, modify, distribute, and sell this software and its
8  * documentation for any purpose is hereby granted without fee, provided that
9  * the above copyright notice appear in all copies and that both that
10  * copyright notice and this permission notice appear in supporting
11  * documentation, and that the name of Keith Packard not be used in
12  * advertising or publicity pertaining to distribution of the software without
13  * specific, written prior permission.  Keith Packard makes no
14  * representations about the suitability of this software for any purpose.  It
15  * is provided "as is" without express or implied warranty.
16  *
17  * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
18  * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
19  * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
20  * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
21  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
22  * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
23  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
24  * SOFTWARE.
25  */
26
27 #ifdef HAVE_CONFIG_H
28 #include <config.h>
29 #endif
30
31 #include <stdlib.h>
32 #include <string.h>
33 #include <assert.h>
34
35 #include "pixman-private.h"
36 #include "pixman-accessor.h"
37
38 #define CvtR8G8B8toY15(s)       (((((s) >> 16) & 0xff) * 153 + \
39                                   (((s) >>  8) & 0xff) * 301 +          \
40                                   (((s)      ) & 0xff) * 58) >> 2)
41 #define miCvtR8G8B8to15(s) ((((s) >> 3) & 0x001f) |  \
42                             (((s) >> 6) & 0x03e0) |  \
43                             (((s) >> 9) & 0x7c00))
44 #define miIndexToEnt15(mif,rgb15) ((mif)->ent[rgb15])
45 #define miIndexToEnt24(mif,rgb24) miIndexToEnt15(mif,miCvtR8G8B8to15(rgb24))
46
47 #define miIndexToEntY24(mif,rgb24) ((mif)->ent[CvtR8G8B8toY15(rgb24)])
48
49 /*
50  * YV12 setup and access macros
51  */
52
53 #define YV12_SETUP(image)                                               \
54     bits_image_t *__bits_image = (bits_image_t *)image;                 \
55     uint32_t *bits = __bits_image->bits;                                        \
56     int stride = __bits_image->rowstride;                                       \
57     int offset0 = stride < 0 ?                                          \
58         ((-stride) >> 1) * ((__bits_image->height - 1) >> 1) - stride : \
59         stride * __bits_image->height;                                  \
60     int offset1 = stride < 0 ?                                          \
61         offset0 + ((-stride) >> 1) * ((__bits_image->height) >> 1) :    \
62         offset0 + (offset0 >> 2)
63 /* Note no trailing semicolon on the above macro; if it's there, then
64  * the typical usage of YV12_SETUP(pict); will have an extra trailing ;
65  * that some compilers will interpret as a statement -- and then any further
66  * variable declarations will cause an error.
67  */
68
69 #define YV12_Y(line)            \
70     ((uint8_t *) ((bits) + (stride) * (line)))
71
72 #define YV12_U(line)          \
73     ((uint8_t *) ((bits) + offset1 + \
74                 ((stride) >> 1) * ((line) >> 1)))
75
76 #define YV12_V(line)          \
77     ((uint8_t *) ((bits) + offset0 + \
78                 ((stride) >> 1) * ((line) >> 1)))
79
80 /*********************************** Fetch ************************************/
81
82 static void
83 fbFetch_a8r8g8b8 (pixman_image_t *image, int x, int y, int width, uint32_t *buffer,
84                   const uint32_t *mask, uint32_t mask_bits)
85 {
86     const uint32_t *bits = image->bits.bits + y*image->bits.rowstride;
87     MEMCPY_WRAPPED(image,
88                    buffer, (const uint32_t *)bits + x,
89                    width*sizeof(uint32_t));
90 }
91
92 static void
93 fbFetch_x8r8g8b8 (pixman_image_t *image, int x, int y, int width, uint32_t *buffer,
94                   const uint32_t *mask, uint32_t mask_bits)
95 {
96     const uint32_t *bits = image->bits.bits + y*image->bits.rowstride;
97     const uint32_t *pixel = (const uint32_t *)bits + x;
98     const uint32_t *end = pixel + width;
99     while (pixel < end) {
100         *buffer++ = READ(image, pixel++) | 0xff000000;
101     }
102 }
103
104 static void
105 fbFetch_a8b8g8r8 (pixman_image_t *image, int x, int y, int width, uint32_t *buffer,
106                   const uint32_t *mask, uint32_t mask_bits)
107 {
108     const uint32_t *bits = image->bits.bits + y*image->bits.rowstride;
109     const uint32_t *pixel = (uint32_t *)bits + x;
110     const uint32_t *end = pixel + width;
111     while (pixel < end) {
112         uint32_t p = READ(image, pixel++);
113         *buffer++ = (p & 0xff00ff00) |
114                     ((p >> 16) & 0xff) |
115             ((p & 0xff) << 16);
116     }
117 }
118
119 static void
120 fbFetch_x8b8g8r8 (pixman_image_t *image, int x, int y, int width, uint32_t *buffer,
121                   const uint32_t *mask, uint32_t mask_bits)
122 {
123     const uint32_t *bits = image->bits.bits + y*image->bits.rowstride;
124     const uint32_t *pixel = (uint32_t *)bits + x;
125     const uint32_t *end = pixel + width;
126     while (pixel < end) {
127         uint32_t p = READ(image, pixel++);
128         *buffer++ = 0xff000000 |
129             (p & 0x0000ff00) |
130             ((p >> 16) & 0xff) |
131             ((p & 0xff) << 16);
132     }
133 }
134
135 static void
136 fbFetch_b8g8r8a8 (pixman_image_t *image, int x, int y, int width, uint32_t *buffer,
137                   const uint32_t *mask, uint32_t mask_bits)
138 {
139     const uint32_t *bits = image->bits.bits + y*image->bits.rowstride;
140     const uint32_t *pixel = (uint32_t *)bits + x;
141     const uint32_t *end = pixel + width;
142     while (pixel < end) {
143         uint32_t p = READ(image, pixel++);
144         *buffer++ = ((p & 0xff000000) >> 24) |
145             ((p & 0x00ff0000) >> 8) |
146             ((p & 0x0000ff00) << 8) |
147             ((p & 0x000000ff) << 24);
148     }
149 }
150
151 static void
152 fbFetch_b8g8r8x8 (pixman_image_t *image, int x, int y, int width, uint32_t *buffer,
153                   const uint32_t *mask, uint32_t mask_bits)
154 {
155     const uint32_t *bits = image->bits.bits + y*image->bits.rowstride;
156     const uint32_t *pixel = (uint32_t *)bits + x;
157     const uint32_t *end = pixel + width;
158     while (pixel < end) {
159         uint32_t p = READ(image, pixel++);
160         *buffer++ = 0xff000000 |
161             ((p & 0xff000000) >> 24) |
162             ((p & 0x00ff0000) >> 8) |
163             ((p & 0x0000ff00) << 8);
164     }
165 }
166
167 /* Expects a uint64_t buffer */
168 static void
169 fbFetch_a2b10g10r10 (pixman_image_t *image, int x, int y, int width, uint32_t *b,
170                      const uint32_t *mask, uint32_t mask_bits)
171 {
172     const uint32_t *bits = image->bits.bits + y*image->bits.rowstride;
173     const uint32_t *pixel = bits + x;
174     const uint32_t *end = pixel + width;
175     uint64_t *buffer = (uint64_t *)b;
176     
177     while (pixel < end) {
178         uint32_t p = READ(image, pixel++);
179         uint64_t a = p >> 30;
180         uint64_t b = (p >> 20) & 0x3ff;
181         uint64_t g = (p >> 10) & 0x3ff;
182         uint64_t r = p & 0x3ff;
183
184         r = r << 6 | r >> 4;
185         g = g << 6 | g >> 4;
186         b = b << 6 | b >> 4;
187
188         a <<= 62;
189         a |= a >> 2;
190         a |= a >> 4;
191         a |= a >> 8;
192
193         *buffer++ = a << 48 | r << 32 | g << 16 | b;
194     }
195 }
196
197 /* Expects a uint64_t buffer */
198 static void
199 fbFetch_x2b10g10r10 (pixman_image_t *image, int x, int y, int width, uint32_t *b,
200                      const uint32_t *mask, uint32_t mask_bits)
201 {
202     const uint32_t *bits = image->bits.bits + y*image->bits.rowstride;
203     const uint32_t *pixel = (uint32_t *)bits + x;
204     const uint32_t *end = pixel + width;
205     uint64_t *buffer = (uint64_t *)b;
206     
207     while (pixel < end) {
208         uint32_t p = READ(image, pixel++);
209         uint64_t b = (p >> 20) & 0x3ff;
210         uint64_t g = (p >> 10) & 0x3ff;
211         uint64_t r = p & 0x3ff;
212
213         r = r << 6 | r >> 4;
214         g = g << 6 | g >> 4;
215         b = b << 6 | b >> 4;
216
217         *buffer++ = 0xffffULL << 48 | r << 32 | g << 16 | b;
218     }
219 }
220
221 static void
222 fbFetch_r8g8b8 (pixman_image_t *image, int x, int y, int width, uint32_t *buffer,
223                 const uint32_t *mask, uint32_t mask_bits)
224 {
225     const uint32_t *bits = image->bits.bits + y*image->bits.rowstride;
226     const uint8_t *pixel = (const uint8_t *)bits + 3*x;
227     const uint8_t *end = pixel + 3*width;
228     while (pixel < end) {
229         uint32_t b = 0xff000000;
230 #ifdef WORDS_BIGENDIAN
231         b |= (READ(image, pixel++) << 16);
232         b |= (READ(image, pixel++) << 8);
233         b |= (READ(image, pixel++));
234 #else
235         b |= (READ(image, pixel++));
236         b |= (READ(image, pixel++) << 8);
237         b |= (READ(image, pixel++) << 16);
238 #endif
239         *buffer++ = b;
240     }
241 }
242
243 static void
244 fbFetch_b8g8r8 (pixman_image_t *image, int x, int y, int width, uint32_t *buffer,
245                 const uint32_t *mask, uint32_t mask_bits)
246 {
247     const uint32_t *bits = image->bits.bits + y*image->bits.rowstride;
248     const uint8_t *pixel = (const uint8_t *)bits + 3*x;
249     const uint8_t *end = pixel + 3*width;
250     while (pixel < end) {
251         uint32_t b = 0xff000000;
252 #ifdef WORDS_BIGENDIAN
253         b |= (READ(image, pixel++));
254         b |= (READ(image, pixel++) << 8);
255         b |= (READ(image, pixel++) << 16);
256 #else
257         b |= (READ(image, pixel++) << 16);
258         b |= (READ(image, pixel++) << 8);
259         b |= (READ(image, pixel++));
260 #endif
261         *buffer++ = b;
262     }
263 }
264
265 static void
266 fbFetch_r5g6b5 (pixman_image_t *image, int x, int y, int width, uint32_t *buffer,
267                 const uint32_t *mask, uint32_t mask_bits)
268 {
269     const uint32_t *bits = image->bits.bits + y*image->bits.rowstride;
270     const uint16_t *pixel = (const uint16_t *)bits + x;
271     const uint16_t *end = pixel + width;
272     while (pixel < end) {
273         uint32_t p = READ(image, pixel++);
274         uint32_t r = (((p) << 3) & 0xf8) |
275             (((p) << 5) & 0xfc00) |
276             (((p) << 8) & 0xf80000);
277         r |= (r >> 5) & 0x70007;
278         r |= (r >> 6) & 0x300;
279         *buffer++ = 0xff000000 | r;
280     }
281 }
282
283 static void
284 fbFetch_b5g6r5 (pixman_image_t *image, int x, int y, int width, uint32_t *buffer,
285                 const uint32_t *mask, uint32_t mask_bits)
286 {
287     uint32_t  r,g,b;
288     const uint32_t *bits = image->bits.bits + y*image->bits.rowstride;
289     const uint16_t *pixel = (const uint16_t *)bits + x;
290     const uint16_t *end = pixel + width;
291     while (pixel < end) {
292         uint32_t  p = READ(image, pixel++);
293         b = ((p & 0xf800) | ((p & 0xe000) >> 5)) >> 8;
294         g = ((p & 0x07e0) | ((p & 0x0600) >> 6)) << 5;
295         r = ((p & 0x001c) | ((p & 0x001f) << 5)) << 14;
296         *buffer++ = 0xff000000 | r | g | b;
297     }
298 }
299
300 static void
301 fbFetch_a1r5g5b5 (pixman_image_t *image, int x, int y, int width, uint32_t *buffer,
302                   const uint32_t *mask, uint32_t mask_bits)
303 {
304     uint32_t  r,g,b, a;
305     const uint32_t *bits = image->bits.bits + y*image->bits.rowstride;
306     const uint16_t *pixel = (const uint16_t *)bits + x;
307     const uint16_t *end = pixel + width;
308     while (pixel < end) {
309         uint32_t  p = READ(image, pixel++);
310
311         a = (uint32_t) ((uint8_t) (0 - ((p & 0x8000) >> 15))) << 24;
312         r = ((p & 0x7c00) | ((p & 0x7000) >> 5)) << 9;
313         g = ((p & 0x03e0) | ((p & 0x0380) >> 5)) << 6;
314         b = ((p & 0x001c) | ((p & 0x001f) << 5)) >> 2;
315         *buffer++ = a | r | g | b;
316     }
317 }
318
319 static void
320 fbFetch_x1r5g5b5 (pixman_image_t *image, int x, int y, int width, uint32_t *buffer,
321                   const uint32_t *mask, uint32_t mask_bits)
322 {
323     uint32_t  r,g,b;
324     const uint32_t *bits = image->bits.bits + y*image->bits.rowstride;
325     const uint16_t *pixel = (const uint16_t *)bits + x;
326     const uint16_t *end = pixel + width;
327     while (pixel < end) {
328         uint32_t  p = READ(image, pixel++);
329
330         r = ((p & 0x7c00) | ((p & 0x7000) >> 5)) << 9;
331         g = ((p & 0x03e0) | ((p & 0x0380) >> 5)) << 6;
332         b = ((p & 0x001c) | ((p & 0x001f) << 5)) >> 2;
333         *buffer++ = 0xff000000 | r | g | b;
334     }
335 }
336
337 static void
338 fbFetch_a1b5g5r5 (pixman_image_t *image, int x, int y, int width, uint32_t *buffer,
339                   const uint32_t *mask, uint32_t mask_bits)
340 {
341     uint32_t  r,g,b, a;
342     const uint32_t *bits = image->bits.bits + y*image->bits.rowstride;
343     const uint16_t *pixel = (const uint16_t *)bits + x;
344     const uint16_t *end = pixel + width;
345     while (pixel < end) {
346         uint32_t  p = READ(image, pixel++);
347
348         a = (uint32_t) ((uint8_t) (0 - ((p & 0x8000) >> 15))) << 24;
349         b = ((p & 0x7c00) | ((p & 0x7000) >> 5)) >> 7;
350         g = ((p & 0x03e0) | ((p & 0x0380) >> 5)) << 6;
351         r = ((p & 0x001c) | ((p & 0x001f) << 5)) << 14;
352         *buffer++ = a | r | g | b;
353     }
354 }
355
356 static void
357 fbFetch_x1b5g5r5 (pixman_image_t *image, int x, int y, int width, uint32_t *buffer,
358                   const uint32_t *mask, uint32_t mask_bits)
359 {
360     uint32_t  r,g,b;
361     const uint32_t *bits = image->bits.bits + y*image->bits.rowstride;
362     const uint16_t *pixel = (const uint16_t *)bits + x;
363     const uint16_t *end = pixel + width;
364     while (pixel < end) {
365         uint32_t  p = READ(image, pixel++);
366
367         b = ((p & 0x7c00) | ((p & 0x7000) >> 5)) >> 7;
368         g = ((p & 0x03e0) | ((p & 0x0380) >> 5)) << 6;
369         r = ((p & 0x001c) | ((p & 0x001f) << 5)) << 14;
370         *buffer++ = 0xff000000 | r | g | b;
371     }
372 }
373
374 static void
375 fbFetch_a4r4g4b4 (pixman_image_t *image, int x, int y, int width, uint32_t *buffer,
376                   const uint32_t *mask, uint32_t mask_bits)
377 {
378     uint32_t  r,g,b, a;
379     const uint32_t *bits = image->bits.bits + y*image->bits.rowstride;
380     const uint16_t *pixel = (const uint16_t *)bits + x;
381     const uint16_t *end = pixel + width;
382     while (pixel < end) {
383         uint32_t  p = READ(image, pixel++);
384
385         a = ((p & 0xf000) | ((p & 0xf000) >> 4)) << 16;
386         r = ((p & 0x0f00) | ((p & 0x0f00) >> 4)) << 12;
387         g = ((p & 0x00f0) | ((p & 0x00f0) >> 4)) << 8;
388         b = ((p & 0x000f) | ((p & 0x000f) << 4));
389         *buffer++ = a | r | g | b;
390     }
391 }
392
393 static void
394 fbFetch_x4r4g4b4 (pixman_image_t *image, int x, int y, int width, uint32_t *buffer,
395                   const uint32_t *mask, uint32_t mask_bits)
396 {
397     uint32_t  r,g,b;
398     const uint32_t *bits = image->bits.bits + y*image->bits.rowstride;
399     const uint16_t *pixel = (const uint16_t *)bits + x;
400     const uint16_t *end = pixel + width;
401     while (pixel < end) {
402         uint32_t  p = READ(image, pixel++);
403
404         r = ((p & 0x0f00) | ((p & 0x0f00) >> 4)) << 12;
405         g = ((p & 0x00f0) | ((p & 0x00f0) >> 4)) << 8;
406         b = ((p & 0x000f) | ((p & 0x000f) << 4));
407         *buffer++ = 0xff000000 | r | g | b;
408     }
409 }
410
411 static void
412 fbFetch_a4b4g4r4 (pixman_image_t *image, int x, int y, int width, uint32_t *buffer,
413                   const uint32_t *mask, uint32_t mask_bits)
414 {
415     uint32_t  r,g,b, a;
416     const uint32_t *bits = image->bits.bits + y*image->bits.rowstride;
417     const uint16_t *pixel = (const uint16_t *)bits + x;
418     const uint16_t *end = pixel + width;
419     while (pixel < end) {
420         uint32_t  p = READ(image, pixel++);
421
422         a = ((p & 0xf000) | ((p & 0xf000) >> 4)) << 16;
423         b = ((p & 0x0f00) | ((p & 0x0f00) >> 4)) >> 4;
424         g = ((p & 0x00f0) | ((p & 0x00f0) >> 4)) << 8;
425         r = ((p & 0x000f) | ((p & 0x000f) << 4)) << 16;
426         *buffer++ = a | r | g | b;
427     }
428 }
429
430 static void
431 fbFetch_x4b4g4r4 (pixman_image_t *image, int x, int y, int width, uint32_t *buffer,
432                   const uint32_t *mask, uint32_t mask_bits)
433 {
434     uint32_t  r,g,b;
435     const uint32_t *bits = image->bits.bits + y*image->bits.rowstride;
436     const uint16_t *pixel = (const uint16_t *)bits + x;
437     const uint16_t *end = pixel + width;
438     while (pixel < end) {
439         uint32_t  p = READ(image, pixel++);
440
441         b = ((p & 0x0f00) | ((p & 0x0f00) >> 4)) >> 4;
442         g = ((p & 0x00f0) | ((p & 0x00f0) >> 4)) << 8;
443         r = ((p & 0x000f) | ((p & 0x000f) << 4)) << 16;
444         *buffer++ = 0xff000000 | r | g | b;
445     }
446 }
447
448 static void
449 fbFetch_a8 (pixman_image_t *image, int x, int y, int width, uint32_t *buffer,
450             const uint32_t *mask, uint32_t mask_bits)
451 {
452     const uint32_t *bits = image->bits.bits + y*image->bits.rowstride;
453     const uint8_t *pixel = (const uint8_t *)bits + x;
454     const uint8_t *end = pixel + width;
455     while (pixel < end) {
456         *buffer++ = READ(image, pixel++) << 24;
457     }
458 }
459
460 static void
461 fbFetch_r3g3b2 (pixman_image_t *image, int x, int y, int width, uint32_t *buffer,
462                 const uint32_t *mask, uint32_t mask_bits)
463 {
464     uint32_t  r,g,b;
465     const uint32_t *bits = image->bits.bits + y*image->bits.rowstride;
466     const uint8_t *pixel = (const uint8_t *)bits + x;
467     const uint8_t *end = pixel + width;
468     while (pixel < end) {
469         uint32_t  p = READ(image, pixel++);
470
471         r = ((p & 0xe0) | ((p & 0xe0) >> 3) | ((p & 0xc0) >> 6)) << 16;
472         g = ((p & 0x1c) | ((p & 0x18) >> 3) | ((p & 0x1c) << 3)) << 8;
473         b = (((p & 0x03)     ) |
474              ((p & 0x03) << 2) |
475              ((p & 0x03) << 4) |
476              ((p & 0x03) << 6));
477         *buffer++ = 0xff000000 | r | g | b;
478     }
479 }
480
481 static void
482 fbFetch_b2g3r3 (pixman_image_t *image, int x, int y, int width, uint32_t *buffer,
483                 const uint32_t *mask, uint32_t mask_bits)
484 {
485     uint32_t  r,g,b;
486     const uint32_t *bits = image->bits.bits + y*image->bits.rowstride;
487     const uint8_t *pixel = (const uint8_t *)bits + x;
488     const uint8_t *end = pixel + width;
489     while (pixel < end) {
490         uint32_t  p = READ(image, pixel++);
491
492         b = (((p & 0xc0)     ) |
493              ((p & 0xc0) >> 2) |
494              ((p & 0xc0) >> 4) |
495              ((p & 0xc0) >> 6));
496         g = ((p & 0x38) | ((p & 0x38) >> 3) | ((p & 0x30) << 2)) << 8;
497         r = (((p & 0x07)     ) |
498              ((p & 0x07) << 3) |
499              ((p & 0x06) << 6)) << 16;
500         *buffer++ = 0xff000000 | r | g | b;
501     }
502 }
503
504 static void
505 fbFetch_a2r2g2b2 (pixman_image_t *image, int x, int y, int width, uint32_t *buffer,
506                   const uint32_t *mask, uint32_t mask_bits)
507 {
508     uint32_t   a,r,g,b;
509     const uint32_t *bits = image->bits.bits + y*image->bits.rowstride;
510     const uint8_t *pixel = (const uint8_t *)bits + x;
511     const uint8_t *end = pixel + width;
512     while (pixel < end) {
513         uint32_t  p = READ(image, pixel++);
514
515         a = ((p & 0xc0) * 0x55) << 18;
516         r = ((p & 0x30) * 0x55) << 12;
517         g = ((p & 0x0c) * 0x55) << 6;
518         b = ((p & 0x03) * 0x55);
519         *buffer++ = a|r|g|b;
520     }
521 }
522
523 static void
524 fbFetch_a2b2g2r2 (pixman_image_t *image, int x, int y, int width, uint32_t *buffer,
525                   const uint32_t *mask, uint32_t mask_bits)
526 {
527     uint32_t   a,r,g,b;
528     const uint32_t *bits = image->bits.bits + y*image->bits.rowstride;
529     const uint8_t *pixel = (const uint8_t *)bits + x;
530     const uint8_t *end = pixel + width;
531     while (pixel < end) {
532         uint32_t  p = READ(image, pixel++);
533
534         a = ((p & 0xc0) * 0x55) << 18;
535         b = ((p & 0x30) * 0x55) >> 6;
536         g = ((p & 0x0c) * 0x55) << 6;
537         r = ((p & 0x03) * 0x55) << 16;
538         *buffer++ = a|r|g|b;
539     }
540 }
541
542 static void
543 fbFetch_c8 (pixman_image_t *image, int x, int y, int width, uint32_t *buffer,
544             const uint32_t *mask, uint32_t mask_bits)
545 {
546     const uint32_t *bits = image->bits.bits + y*image->bits.rowstride;
547     const pixman_indexed_t * indexed = image->bits.indexed;
548     const uint8_t *pixel = (const uint8_t *)bits + x;
549     const uint8_t *end = pixel + width;
550     while (pixel < end) {
551         uint32_t  p = READ(image, pixel++);
552         *buffer++ = indexed->rgba[p];
553     }
554 }
555
556 static void
557 fbFetch_x4a4 (pixman_image_t *image, int x, int y, int width, uint32_t *buffer,
558               const uint32_t *mask, uint32_t mask_bits)
559 {
560     const uint32_t *bits = image->bits.bits + y*image->bits.rowstride;
561     const uint8_t *pixel = (const uint8_t *)bits + x;
562     const uint8_t *end = pixel + width;
563     while (pixel < end) {
564         uint8_t p = READ(image, pixel++) & 0xf;
565         *buffer++ = (p | (p << 4)) << 24;
566     }
567 }
568
569 #define Fetch8(img,l,o)    (READ(img, (uint8_t *)(l) + ((o) >> 2)))
570 #ifdef WORDS_BIGENDIAN
571 #define Fetch4(img,l,o)    ((o) & 2 ? Fetch8(img,l,o) & 0xf : Fetch8(img,l,o) >> 4)
572 #else
573 #define Fetch4(img,l,o)    ((o) & 2 ? Fetch8(img,l,o) >> 4 : Fetch8(img,l,o) & 0xf)
574 #endif
575
576 static void
577 fbFetch_a4 (pixman_image_t *image, int x, int y, int width, uint32_t *buffer,
578             const uint32_t *mask, uint32_t mask_bits)
579 {
580     const uint32_t *bits = image->bits.bits + y*image->bits.rowstride;
581     int i;
582     for (i = 0; i < width; ++i) {
583         uint32_t  p = Fetch4(image, bits, i + x);
584
585         p |= p << 4;
586         *buffer++ = p << 24;
587     }
588 }
589
590 static void
591 fbFetch_r1g2b1 (pixman_image_t *image, int x, int y, int width, uint32_t *buffer,
592                 const uint32_t *mask, uint32_t mask_bits)
593 {
594     uint32_t  r,g,b;
595     const uint32_t *bits = image->bits.bits + y*image->bits.rowstride;
596     int i;
597     for (i = 0; i < width; ++i) {
598         uint32_t  p = Fetch4(image, bits, i + x);
599
600         r = ((p & 0x8) * 0xff) << 13;
601         g = ((p & 0x6) * 0x55) << 7;
602         b = ((p & 0x1) * 0xff);
603         *buffer++ = 0xff000000|r|g|b;
604     }
605 }
606
607 static void
608 fbFetch_b1g2r1 (pixman_image_t *image, int x, int y, int width, uint32_t *buffer,
609                 const uint32_t *mask, uint32_t mask_bits)
610 {
611     uint32_t  r,g,b;
612     const uint32_t *bits = image->bits.bits + y*image->bits.rowstride;
613     int i;
614     for (i = 0; i < width; ++i) {
615         uint32_t  p = Fetch4(image, bits, i + x);
616
617         b = ((p & 0x8) * 0xff) >> 3;
618         g = ((p & 0x6) * 0x55) << 7;
619         r = ((p & 0x1) * 0xff) << 16;
620         *buffer++ = 0xff000000|r|g|b;
621     }
622 }
623
624 static void
625 fbFetch_a1r1g1b1 (pixman_image_t *image, int x, int y, int width, uint32_t *buffer,
626                   const uint32_t *mask, uint32_t mask_bits)
627 {
628     uint32_t  a,r,g,b;
629     const uint32_t *bits = image->bits.bits + y*image->bits.rowstride;
630     int i;
631     for (i = 0; i < width; ++i) {
632         uint32_t  p = Fetch4(image, bits, i + x);
633
634         a = ((p & 0x8) * 0xff) << 21;
635         r = ((p & 0x4) * 0xff) << 14;
636         g = ((p & 0x2) * 0xff) << 7;
637         b = ((p & 0x1) * 0xff);
638         *buffer++ = a|r|g|b;
639     }
640 }
641
642 static void
643 fbFetch_a1b1g1r1 (pixman_image_t *image, int x, int y, int width, uint32_t *buffer,
644                   const uint32_t *mask, uint32_t mask_bits)
645 {
646     uint32_t  a,r,g,b;
647     const uint32_t *bits = image->bits.bits + y*image->bits.rowstride;
648     int i;
649     for (i = 0; i < width; ++i) {
650         uint32_t  p = Fetch4(image, bits, i + x);
651
652         a = ((p & 0x8) * 0xff) << 21;
653         r = ((p & 0x4) * 0xff) >> 3;
654         g = ((p & 0x2) * 0xff) << 7;
655         b = ((p & 0x1) * 0xff) << 16;
656         *buffer++ = a|r|g|b;
657     }
658 }
659
660 static void
661 fbFetch_c4 (pixman_image_t *image, int x, int y, int width, uint32_t *buffer,
662             const uint32_t *mask, uint32_t mask_bits)
663 {
664     const uint32_t *bits = image->bits.bits + y*image->bits.rowstride;
665     const pixman_indexed_t * indexed = image->bits.indexed;
666     int i;
667     for (i = 0; i < width; ++i) {
668         uint32_t  p = Fetch4 (image, bits, i + x);
669
670         *buffer++ = indexed->rgba[p];
671     }
672 }
673
674
675 static void
676 fbFetch_a1 (pixman_image_t *image, int x, int y, int width, uint32_t *buffer,
677             const uint32_t *mask, uint32_t mask_bits)
678 {
679     const uint32_t *bits = image->bits.bits + y*image->bits.rowstride;
680     int i;
681     for (i = 0; i < width; ++i) {
682         uint32_t  p = READ(image, bits + ((i + x) >> 5));
683         uint32_t  a;
684 #ifdef WORDS_BIGENDIAN
685         a = p >> (0x1f - ((i+x) & 0x1f));
686 #else
687         a = p >> ((i+x) & 0x1f);
688 #endif
689         a = a & 1;
690         a |= a << 1;
691         a |= a << 2;
692         a |= a << 4;
693         *buffer++ = a << 24;
694     }
695 }
696
697 static void
698 fbFetch_g1 (pixman_image_t *image, int x, int y, int width, uint32_t *buffer,
699             const uint32_t *mask, uint32_t mask_bits)
700 {
701     const uint32_t *bits = image->bits.bits + y*image->bits.rowstride;
702     const pixman_indexed_t * indexed = image->bits.indexed;
703     int i;
704     for (i = 0; i < width; ++i) {
705         uint32_t p = READ(image, bits + ((i+x) >> 5));
706         uint32_t a;
707 #ifdef WORDS_BIGENDIAN
708         a = p >> (0x1f - ((i+x) & 0x1f));
709 #else
710         a = p >> ((i+x) & 0x1f);
711 #endif
712         a = a & 1;
713         *buffer++ = indexed->rgba[a];
714     }
715 }
716
717 static void
718 fbFetch_yuy2 (pixman_image_t *image, int x, int line, int width, uint32_t *buffer,
719               const uint32_t *mask, uint32_t mask_bits)
720 {
721     int16_t y, u, v;
722     int32_t r, g, b;
723     int   i;
724
725     const uint32_t *bits = image->bits.bits + image->bits.rowstride * line;
726
727     for (i = 0; i < width; i++)
728     {
729         y = ((uint8_t *) bits)[(x + i) << 1] - 16;
730         u = ((uint8_t *) bits)[(((x + i) << 1) & -4) + 1] - 128;
731         v = ((uint8_t *) bits)[(((x + i) << 1) & -4) + 3] - 128;
732
733         /* R = 1.164(Y - 16) + 1.596(V - 128) */
734         r = 0x012b27 * y + 0x019a2e * v;
735         /* G = 1.164(Y - 16) - 0.813(V - 128) - 0.391(U - 128) */
736         g = 0x012b27 * y - 0x00d0f2 * v - 0x00647e * u;
737         /* B = 1.164(Y - 16) + 2.018(U - 128) */
738         b = 0x012b27 * y + 0x0206a2 * u;
739
740         *buffer++ = 0xff000000 |
741             (r >= 0 ? r < 0x1000000 ? r         & 0xff0000 : 0xff0000 : 0) |
742             (g >= 0 ? g < 0x1000000 ? (g >> 8)  & 0x00ff00 : 0x00ff00 : 0) |
743             (b >= 0 ? b < 0x1000000 ? (b >> 16) & 0x0000ff : 0x0000ff : 0);
744     }
745 }
746
747 static void
748 fbFetch_yv12 (pixman_image_t *image, int x, int line, int width, uint32_t *buffer,
749               const uint32_t *mask, uint32_t mask_bits)
750 {
751     YV12_SETUP(image);
752     uint8_t *pY = YV12_Y (line);
753     uint8_t *pU = YV12_U (line);
754     uint8_t *pV = YV12_V (line);
755     int16_t y, u, v;
756     int32_t r, g, b;
757     int   i;
758
759     for (i = 0; i < width; i++)
760     {
761         y = pY[x + i] - 16;
762         u = pU[(x + i) >> 1] - 128;
763         v = pV[(x + i) >> 1] - 128;
764
765         /* R = 1.164(Y - 16) + 1.596(V - 128) */
766         r = 0x012b27 * y + 0x019a2e * v;
767         /* G = 1.164(Y - 16) - 0.813(V - 128) - 0.391(U - 128) */
768         g = 0x012b27 * y - 0x00d0f2 * v - 0x00647e * u;
769         /* B = 1.164(Y - 16) + 2.018(U - 128) */
770         b = 0x012b27 * y + 0x0206a2 * u;
771
772         *buffer++ = 0xff000000 |
773             (r >= 0 ? r < 0x1000000 ? r         & 0xff0000 : 0xff0000 : 0) |
774             (g >= 0 ? g < 0x1000000 ? (g >> 8)  & 0x00ff00 : 0x00ff00 : 0) |
775             (b >= 0 ? b < 0x1000000 ? (b >> 16) & 0x0000ff : 0x0000ff : 0);
776     }
777 }
778
779 /**************************** Pixel wise fetching *****************************/
780
781 /* Despite the type, expects a uint64_t buffer */
782 static void
783 fbFetchPixel_a2b10g10r10_64 (bits_image_t *pict, uint32_t *b, int n_pixels)
784 {
785     int i;
786     uint64_t *buffer = (uint64_t *)b;
787
788     for (i = 0; i < n_pixels; ++i)
789     {
790         int offset = ((uint32_t *)buffer)[2 * i];
791         int line = ((uint32_t *)buffer)[2 * i + 1];
792
793         if (offset == 0xffffffff || line == 0xffffffff)
794         {
795             buffer[i] = 0;
796         }
797         else
798         {
799             uint32_t *bits = pict->bits + line*pict->rowstride;
800             uint32_t p = READ(pict, bits + offset);
801             uint64_t a = p >> 30;
802             uint64_t b = (p >> 20) & 0x3ff;
803             uint64_t g = (p >> 10) & 0x3ff;
804             uint64_t r = p & 0x3ff;
805             
806             r = r << 6 | r >> 4;
807             g = g << 6 | g >> 4;
808             b = b << 6 | b >> 4;
809             
810             a <<= 62;
811             a |= a >> 2;
812             a |= a >> 4;
813             a |= a >> 8;
814             
815             buffer[i] = a << 48 | r << 32 | g << 16 | b;
816         }
817     }
818 }
819
820 /* Despite the type, this function expects a uint64_t buffer */
821 static void
822 fbFetchPixel_x2b10g10r10_64 (bits_image_t *pict, uint32_t *b, int n_pixels)
823 {
824     uint64_t *buffer = (uint64_t *)b;
825     int i;
826     
827     for (i = 0; i < n_pixels; ++i)
828     {
829         int offset = ((uint32_t *)buffer)[2 * i];
830         int line = ((uint32_t *)buffer)[2 * i + 1];
831
832         if (offset == 0xffffffff || line == 0xffffffff)
833         {
834             buffer[i] = 0;
835         }
836         else
837         {
838             uint32_t *bits = pict->bits + line*pict->rowstride;
839             uint32_t p = READ(pict, bits + offset);
840             uint64_t b = (p >> 20) & 0x3ff;
841             uint64_t g = (p >> 10) & 0x3ff;
842             uint64_t r = p & 0x3ff;
843             
844             r = r << 6 | r >> 4;
845             g = g << 6 | g >> 4;
846             b = b << 6 | b >> 4;
847             
848             buffer[i] = 0xffffULL << 48 | r << 32 | g << 16 | b;
849         }
850     }
851 }
852
853 static void
854 fbFetchPixel_a8r8g8b8 (bits_image_t *pict, uint32_t *buffer, int n_pixels)
855 {
856     int i;
857     
858     for (i = 0; i < n_pixels; ++i)
859     {
860         int offset = buffer[2 * i];
861         int line = buffer[2 * i + 1];
862         
863         if (offset == 0xffffffff || line == 0xffffffff)
864         {
865             buffer[i] = 0;
866         }
867         else
868         {
869             uint32_t *bits = pict->bits + line*pict->rowstride;
870             buffer[i] = READ(pict, (uint32_t *)bits + offset);
871         }
872     }
873 }
874
875 static void
876 fbFetchPixel_x8r8g8b8 (bits_image_t *pict, uint32_t *buffer, int n_pixels)
877 {
878     int i;
879     
880     for (i = 0; i < n_pixels; ++i)
881     {
882         int offset = buffer[2 * i];
883         int line = buffer[2 * i + 1];
884         
885         if (offset == 0xffffffff || line == 0xffffffff)
886         {
887             buffer[i] = 0;
888         }
889         else
890         {
891             uint32_t *bits = pict->bits + line*pict->rowstride;
892             buffer[i] = READ(pict, (uint32_t *)bits + offset) | 0xff000000;
893         }
894     }
895 }
896
897 static void
898 fbFetchPixel_a8b8g8r8 (bits_image_t *pict, uint32_t *buffer, int n_pixels)
899 {
900     int i;
901     
902     for (i = 0; i < n_pixels; ++i)
903     {
904         int offset = buffer[2 * i];
905         int line = buffer[2 * i + 1];
906         
907         if (offset == 0xffffffff || line == 0xffffffff)
908         {
909             buffer[i] = 0;
910         }
911         else
912         {
913             uint32_t *bits = pict->bits + line*pict->rowstride;
914             uint32_t  pixel = READ(pict, (uint32_t *)bits + offset);
915             
916             buffer[i] = ((pixel & 0xff000000) |
917                          ((pixel >> 16) & 0xff) |
918                          (pixel & 0x0000ff00) |
919                          ((pixel & 0xff) << 16));
920         }
921     }
922 }
923
924 static void
925 fbFetchPixel_x8b8g8r8 (bits_image_t *pict, uint32_t *buffer, int n_pixels)
926 {
927     int i;
928     
929     for (i = 0; i < n_pixels; ++i)
930     {
931         int offset = buffer[2 * i];
932         int line = buffer[2 * i + 1];
933         
934         if (offset == 0xffffffff || line == 0xffffffff)
935         {
936             buffer[i] = 0;
937         }
938         else
939         {
940             uint32_t *bits = pict->bits + line*pict->rowstride;
941             uint32_t  pixel = READ(pict, (uint32_t *)bits + offset);
942             
943             buffer[i] = ((0xff000000) |
944                          ((pixel >> 16) & 0xff) |
945                          (pixel & 0x0000ff00) |
946                          ((pixel & 0xff) << 16));
947         }
948     }
949 }
950
951 static void
952 fbFetchPixel_b8g8r8a8 (bits_image_t *pict, uint32_t *buffer, int n_pixels)
953 {
954     int i;
955
956     for (i = 0; i < n_pixels; ++i)
957     {
958         int offset = buffer[2 * i];
959         int line = buffer[2 * i + 1];
960
961         if (offset == 0xffffffff || line == 0xffffffff)
962         {
963             buffer[i] = 0;
964         }
965         else
966         {
967             uint32_t *bits = pict->bits + line*pict->rowstride;
968             uint32_t  pixel = READ(pict, (uint32_t *)bits + offset);
969             
970             buffer[i] = ((pixel & 0xff000000) >> 24 |
971                          (pixel & 0x00ff0000) >> 8 |
972                          (pixel & 0x0000ff00) << 8 |
973                          (pixel & 0x000000ff) << 24);
974         }
975     }
976 }
977
978 static void
979 fbFetchPixel_b8g8r8x8 (bits_image_t *pict, uint32_t *buffer, int n_pixels)
980 {
981     int i;
982
983     for (i = 0; i < n_pixels; ++i)
984     {
985         int offset = buffer[2 * i];
986         int line = buffer[2 * i + 1];
987         
988         if (offset == 0xffffffff || line == 0xffffffff)
989         {
990             buffer[i] = 0;
991         }
992         else
993         {
994             uint32_t *bits = pict->bits + line*pict->rowstride;
995             uint32_t  pixel = READ(pict, (uint32_t *)bits + offset);
996             
997             buffer[i] = ((0xff000000) |
998                          (pixel & 0xff000000) >> 24 |
999                          (pixel & 0x00ff0000) >> 8 |
1000                          (pixel & 0x0000ff00) << 8);
1001         }
1002     }
1003 }
1004
1005 static void
1006 fbFetchPixel_r8g8b8 (bits_image_t *pict, uint32_t *buffer, int n_pixels)
1007 {
1008     int i;
1009
1010     for (i = 0; i < n_pixels; ++i)
1011     {
1012         int offset = buffer[2 * i];
1013         int line = buffer[2 * i + 1];
1014
1015         if (offset == 0xffffffff || line == 0xffffffff)
1016         {
1017             buffer[i] = 0;
1018         }
1019         else
1020         {
1021             uint32_t *bits = pict->bits + line*pict->rowstride;
1022             uint8_t   *pixel = ((uint8_t *) bits) + (offset*3);
1023 #ifdef WORDS_BIGENDIAN
1024             buffer[i] = (0xff000000 |
1025                          (READ(pict, pixel + 0) << 16) |
1026                          (READ(pict, pixel + 1) << 8) |
1027                          (READ(pict, pixel + 2)));
1028 #else
1029             buffer[i] = (0xff000000 |
1030                          (READ(pict, pixel + 2) << 16) |
1031                          (READ(pict, pixel + 1) << 8) |
1032                          (READ(pict, pixel + 0)));
1033 #endif
1034         }
1035     }
1036 }
1037
1038 static void
1039 fbFetchPixel_b8g8r8 (bits_image_t *pict, uint32_t *buffer, int n_pixels)
1040 {
1041     int i;
1042
1043     for (i = 0; i < n_pixels; ++i)
1044     {
1045         int offset = buffer[2 * i];
1046         int line = buffer[2 * i + 1];
1047
1048         if (offset == 0xffffffff || line == 0xffffffff)
1049         {
1050             buffer[i] = 0;
1051         }
1052         else
1053         {
1054             uint32_t *bits = pict->bits + line*pict->rowstride;
1055             uint8_t   *pixel = ((uint8_t *) bits) + (offset*3);
1056 #ifdef WORDS_BIGENDIAN
1057             buffer[i] = (0xff000000 |
1058                          (READ(pict, pixel + 2) << 16) |
1059                          (READ(pict, pixel + 1) << 8) |
1060                          (READ(pict, pixel + 0)));
1061 #else
1062             buffer[i] = (0xff000000 |
1063                          (READ(pict, pixel + 0) << 16) |
1064                          (READ(pict, pixel + 1) << 8) |
1065                          (READ(pict, pixel + 2)));
1066 #endif
1067         }
1068     }
1069 }
1070
1071 static void
1072 fbFetchPixel_r5g6b5 (bits_image_t *pict, uint32_t *buffer, int n_pixels)
1073 {
1074     int i;
1075
1076     for (i = 0; i < n_pixels; ++i)
1077     {
1078         int offset = buffer[2 * i];
1079         int line = buffer[2 * i + 1];
1080
1081         if (offset == 0xffffffff || line == 0xffffffff)
1082         {
1083             buffer[i] = 0;
1084         }
1085         else
1086         {
1087             uint32_t  r,g,b;
1088             uint32_t *bits = pict->bits + line*pict->rowstride;
1089             uint32_t  pixel = READ(pict, (uint16_t *) bits + offset);
1090             
1091             r = ((pixel & 0xf800) | ((pixel & 0xe000) >> 5)) << 8;
1092             g = ((pixel & 0x07e0) | ((pixel & 0x0600) >> 6)) << 5;
1093             b = ((pixel & 0x001c) | ((pixel & 0x001f) << 5)) >> 2;
1094             buffer[i] = (0xff000000 | r | g | b);
1095         }
1096     }
1097 }
1098
1099 static void
1100 fbFetchPixel_b5g6r5 (bits_image_t *pict, uint32_t *buffer, int n_pixels)
1101 {
1102     int i;
1103
1104     for (i = 0; i < n_pixels; ++i)
1105     {
1106         int offset = buffer[2 * i];
1107         int line = buffer[2 * i + 1];
1108
1109         if (offset == 0xffffffff || line == 0xffffffff)
1110         {
1111             buffer[i] = 0;
1112         }
1113         else
1114         {
1115             uint32_t  r,g,b;
1116             uint32_t *bits = pict->bits + line*pict->rowstride;
1117             uint32_t  pixel = READ(pict, (uint16_t *) bits + offset);
1118             
1119             b = ((pixel & 0xf800) | ((pixel & 0xe000) >> 5)) >> 8;
1120             g = ((pixel & 0x07e0) | ((pixel & 0x0600) >> 6)) << 5;
1121             r = ((pixel & 0x001c) | ((pixel & 0x001f) << 5)) << 14;
1122             buffer[i] = (0xff000000 | r | g | b);
1123         }
1124     }
1125 }
1126
1127 static void
1128 fbFetchPixel_a1r5g5b5 (bits_image_t *pict, uint32_t *buffer, int n_pixels)
1129 {
1130     int i;
1131
1132     for (i = 0; i < n_pixels; ++i)
1133     {
1134         int offset = buffer[2 * i];
1135         int line = buffer[2 * i + 1];
1136
1137         if (offset == 0xffffffff || line == 0xffffffff)
1138         {
1139             buffer[i] = 0;
1140         }
1141         else
1142         {
1143             uint32_t  a,r,g,b;
1144             uint32_t *bits = pict->bits + line*pict->rowstride;
1145             uint32_t  pixel = READ(pict, (uint16_t *) bits + offset);
1146             
1147             a = (uint32_t) ((uint8_t) (0 - ((pixel & 0x8000) >> 15))) << 24;
1148             r = ((pixel & 0x7c00) | ((pixel & 0x7000) >> 5)) << 9;
1149             g = ((pixel & 0x03e0) | ((pixel & 0x0380) >> 5)) << 6;
1150             b = ((pixel & 0x001c) | ((pixel & 0x001f) << 5)) >> 2;
1151             buffer[i] = (a | r | g | b);
1152         }
1153     }
1154 }
1155
1156 static void
1157 fbFetchPixel_x1r5g5b5 (bits_image_t *pict, uint32_t *buffer, int n_pixels)
1158 {
1159     int i;
1160
1161     for (i = 0; i < n_pixels; ++i)
1162     {
1163         int offset = buffer[2 * i];
1164         int line = buffer[2 * i + 1];
1165
1166         if (offset == 0xffffffff || line == 0xffffffff)
1167         {
1168             buffer[i] = 0;
1169         }
1170         else
1171         {
1172             uint32_t  r,g,b;
1173             uint32_t *bits = pict->bits + line*pict->rowstride;
1174             uint32_t  pixel = READ(pict, (uint16_t *) bits + offset);
1175             
1176             r = ((pixel & 0x7c00) | ((pixel & 0x7000) >> 5)) << 9;
1177             g = ((pixel & 0x03e0) | ((pixel & 0x0380) >> 5)) << 6;
1178             b = ((pixel & 0x001c) | ((pixel & 0x001f) << 5)) >> 2;
1179             buffer[i] = (0xff000000 | r | g | b);
1180         }
1181     }
1182 }
1183
1184 static void
1185 fbFetchPixel_a1b5g5r5 (bits_image_t *pict, uint32_t *buffer, int n_pixels)
1186 {
1187     int i;
1188
1189     for (i = 0; i < n_pixels; ++i)
1190     {
1191         int offset = buffer[2 * i];
1192         int line = buffer[2 * i + 1];
1193
1194         if (offset == 0xffffffff || line == 0xffffffff)
1195         {
1196             buffer[i] = 0;
1197         }
1198         else
1199         {
1200             uint32_t  a,r,g,b;
1201             uint32_t *bits = pict->bits + line*pict->rowstride;
1202             uint32_t  pixel = READ(pict, (uint16_t *) bits + offset);
1203             
1204             a = (uint32_t) ((uint8_t) (0 - ((pixel & 0x8000) >> 15))) << 24;
1205             b = ((pixel & 0x7c00) | ((pixel & 0x7000) >> 5)) >> 7;
1206             g = ((pixel & 0x03e0) | ((pixel & 0x0380) >> 5)) << 6;
1207             r = ((pixel & 0x001c) | ((pixel & 0x001f) << 5)) << 14;
1208             buffer[i] = (a | r | g | b);
1209         }
1210     }
1211 }
1212
1213 static void
1214 fbFetchPixel_x1b5g5r5 (bits_image_t *pict, uint32_t *buffer, int n_pixels)
1215 {
1216     int i;
1217
1218     for (i = 0; i < n_pixels; ++i)
1219     {
1220         int offset = buffer[2 * i];
1221         int line = buffer[2 * i + 1];
1222
1223         if (offset == 0xffffffff || line == 0xffffffff)
1224         {
1225             buffer[i] = 0;
1226         }
1227         else
1228         {
1229             uint32_t  r,g,b;
1230             uint32_t *bits = pict->bits + line*pict->rowstride;
1231             uint32_t  pixel = READ(pict, (uint16_t *) bits + offset);
1232             
1233             b = ((pixel & 0x7c00) | ((pixel & 0x7000) >> 5)) >> 7;
1234             g = ((pixel & 0x03e0) | ((pixel & 0x0380) >> 5)) << 6;
1235             r = ((pixel & 0x001c) | ((pixel & 0x001f) << 5)) << 14;
1236             buffer[i] = (0xff000000 | r | g | b);
1237         }
1238     }
1239 }
1240
1241 static void
1242 fbFetchPixel_a4r4g4b4 (bits_image_t *pict, uint32_t *buffer, int n_pixels)
1243 {
1244     int i;
1245
1246     for (i = 0; i < n_pixels; ++i)
1247     {
1248         int offset = buffer[2 * i];
1249         int line = buffer[2 * i + 1];
1250
1251         if (offset == 0xffffffff || line == 0xffffffff)
1252         {
1253             buffer[i] = 0;
1254         }
1255         else
1256         {
1257             uint32_t  a,r,g,b;
1258             uint32_t *bits = pict->bits + line*pict->rowstride;
1259             uint32_t  pixel = READ(pict, (uint16_t *) bits + offset);
1260             
1261             a = ((pixel & 0xf000) | ((pixel & 0xf000) >> 4)) << 16;
1262             r = ((pixel & 0x0f00) | ((pixel & 0x0f00) >> 4)) << 12;
1263             g = ((pixel & 0x00f0) | ((pixel & 0x00f0) >> 4)) << 8;
1264             b = ((pixel & 0x000f) | ((pixel & 0x000f) << 4));
1265             buffer[i] = (a | r | g | b);
1266         }
1267     }
1268 }
1269
1270 static void
1271 fbFetchPixel_x4r4g4b4 (bits_image_t *pict, uint32_t *buffer, int n_pixels)
1272 {
1273     int i;
1274
1275     for (i = 0; i < n_pixels; ++i)
1276     {
1277         int offset = buffer[2 * i];
1278         int line = buffer[2 * i + 1];
1279
1280         if (offset == 0xffffffff || line == 0xffffffff)
1281         {
1282             buffer[i] = 0;
1283         }
1284         else
1285         {
1286             uint32_t  r,g,b;
1287             uint32_t *bits = pict->bits + line*pict->rowstride;
1288             uint32_t  pixel = READ(pict, (uint16_t *) bits + offset);
1289             
1290             r = ((pixel & 0x0f00) | ((pixel & 0x0f00) >> 4)) << 12;
1291             g = ((pixel & 0x00f0) | ((pixel & 0x00f0) >> 4)) << 8;
1292             b = ((pixel & 0x000f) | ((pixel & 0x000f) << 4));
1293             buffer[i] = (0xff000000 | r | g | b);
1294         }
1295     }
1296 }
1297
1298 static void
1299 fbFetchPixel_a4b4g4r4 (bits_image_t *pict, uint32_t *buffer, int n_pixels)
1300 {
1301     int i;
1302
1303     for (i = 0; i < n_pixels; ++i)
1304     {
1305         int offset = buffer[2 * i];
1306         int line = buffer[2 * i + 1];
1307
1308         if (offset == 0xffffffff || line == 0xffffffff)
1309         {
1310             buffer[i] = 0;
1311         }
1312         else
1313         {
1314             uint32_t  a,r,g,b;
1315             uint32_t *bits = pict->bits + line*pict->rowstride;
1316             uint32_t  pixel = READ(pict, (uint16_t *) bits + offset);
1317             
1318             a = ((pixel & 0xf000) | ((pixel & 0xf000) >> 4)) << 16;
1319             b = ((pixel & 0x0f00) | ((pixel & 0x0f00) >> 4)) >> 4;
1320             g = ((pixel & 0x00f0) | ((pixel & 0x00f0) >> 4)) << 8;
1321             r = ((pixel & 0x000f) | ((pixel & 0x000f) << 4)) << 16;
1322             buffer[i] = (a | r | g | b);
1323         }
1324     }
1325 }
1326
1327 static void
1328 fbFetchPixel_x4b4g4r4 (bits_image_t *pict, uint32_t *buffer, int n_pixels)
1329 {
1330     int i;
1331
1332     for (i = 0; i < n_pixels; ++i)
1333     {
1334         int offset = buffer[2 * i];
1335         int line = buffer[2 * i + 1];
1336
1337         if (offset == 0xffffffff || line == 0xffffffff)
1338         {
1339             buffer[i] = 0;
1340         }
1341         else
1342         {
1343             uint32_t  r,g,b;
1344             uint32_t *bits = pict->bits + line*pict->rowstride;
1345             uint32_t  pixel = READ(pict, (uint16_t *) bits + offset);
1346             
1347             b = ((pixel & 0x0f00) | ((pixel & 0x0f00) >> 4)) >> 4;
1348             g = ((pixel & 0x00f0) | ((pixel & 0x00f0) >> 4)) << 8;
1349             r = ((pixel & 0x000f) | ((pixel & 0x000f) << 4)) << 16;
1350             buffer[i] = (0xff000000 | r | g | b);
1351         }
1352     }
1353 }
1354
1355 static void
1356 fbFetchPixel_a8 (bits_image_t *pict, uint32_t *buffer, int n_pixels)
1357 {
1358     int i;
1359
1360     for (i = 0; i < n_pixels; ++i)
1361     {
1362         int offset = buffer[2 * i];
1363         int line = buffer[2 * i + 1];
1364
1365         if (offset == 0xffffffff || line == 0xffffffff)
1366         {
1367             buffer[i] = 0;
1368         }
1369         else
1370         {
1371             uint32_t *bits = pict->bits + line*pict->rowstride;
1372             uint32_t   pixel = READ(pict, (uint8_t *) bits + offset);
1373             
1374             buffer[i] = pixel << 24;
1375         }
1376     }
1377 }
1378
1379 static void
1380 fbFetchPixel_r3g3b2 (bits_image_t *pict, uint32_t *buffer, int n_pixels)
1381 {
1382     int i;
1383
1384     for (i = 0; i < n_pixels; ++i)
1385     {
1386         int offset = buffer[2 * i];
1387         int line = buffer[2 * i + 1];
1388
1389         if (offset == 0xffffffff || line == 0xffffffff)
1390         {
1391             buffer[i] = 0;
1392         }
1393         else
1394         {
1395             uint32_t  r,g,b;
1396             uint32_t *bits = pict->bits + line*pict->rowstride;
1397             uint32_t   pixel = READ(pict, (uint8_t *) bits + offset);
1398             
1399             r = ((pixel & 0xe0) | ((pixel & 0xe0) >> 3) | ((pixel & 0xc0) >> 6)) << 16;
1400             g = ((pixel & 0x1c) | ((pixel & 0x18) >> 3) | ((pixel & 0x1c) << 3)) << 8;
1401             b = (((pixel & 0x03)     ) |
1402                  ((pixel & 0x03) << 2) |
1403                  ((pixel & 0x03) << 4) |
1404                  ((pixel & 0x03) << 6));
1405             buffer[i] = (0xff000000 | r | g | b);
1406         }
1407     }
1408 }
1409
1410 static void
1411 fbFetchPixel_b2g3r3 (bits_image_t *pict, uint32_t *buffer, int n_pixels)
1412 {
1413     int i;
1414
1415     for (i = 0; i < n_pixels; ++i)
1416     {
1417         int offset = buffer[2 * i];
1418         int line = buffer[2 * i + 1];
1419
1420         if (offset == 0xffffffff || line == 0xffffffff)
1421         {
1422             buffer[i] = 0;
1423         }
1424         else
1425         {
1426             uint32_t  r,g,b;
1427             uint32_t *bits = pict->bits + line*pict->rowstride;
1428             uint32_t   pixel = READ(pict, (uint8_t *) bits + offset);
1429             
1430             b = (((pixel & 0xc0)     ) |
1431                  ((pixel & 0xc0) >> 2) |
1432                  ((pixel & 0xc0) >> 4) |
1433                  ((pixel & 0xc0) >> 6));
1434             g = ((pixel & 0x38) | ((pixel & 0x38) >> 3) | ((pixel & 0x30) << 2)) << 8;
1435             r = (((pixel & 0x07)     ) |
1436                  ((pixel & 0x07) << 3) |
1437                  ((pixel & 0x06) << 6)) << 16;
1438             buffer[i] = (0xff000000 | r | g | b);
1439         }
1440     }
1441 }
1442
1443 static void
1444 fbFetchPixel_a2r2g2b2 (bits_image_t *pict, uint32_t *buffer, int n_pixels)
1445 {
1446     int i;
1447
1448     for (i = 0; i < n_pixels; ++i)
1449     {
1450         int offset = buffer[2 * i];
1451         int line = buffer[2 * i + 1];
1452
1453         if (offset == 0xffffffff || line == 0xffffffff)
1454         {
1455             buffer[i] = 0;
1456         }
1457         else
1458         {
1459             uint32_t   a,r,g,b;
1460             uint32_t *bits = pict->bits + line*pict->rowstride;
1461             uint32_t   pixel = READ(pict, (uint8_t *) bits + offset);
1462             
1463             a = ((pixel & 0xc0) * 0x55) << 18;
1464             r = ((pixel & 0x30) * 0x55) << 12;
1465             g = ((pixel & 0x0c) * 0x55) << 6;
1466             b = ((pixel & 0x03) * 0x55);
1467             buffer[i] = a|r|g|b;
1468         }
1469     }
1470 }
1471
1472 static void
1473 fbFetchPixel_a2b2g2r2 (bits_image_t *pict, uint32_t *buffer, int n_pixels)
1474 {
1475     int i;
1476
1477     for (i = 0; i < n_pixels; ++i)
1478     {
1479         int offset = buffer[2 * i];
1480         int line = buffer[2 * i + 1];
1481
1482         if (offset == 0xffffffff || line == 0xffffffff)
1483         {
1484             buffer[i] = 0;
1485         }
1486         else
1487         {
1488             uint32_t   a,r,g,b;
1489             uint32_t *bits = pict->bits + line*pict->rowstride;
1490             uint32_t   pixel = READ(pict, (uint8_t *) bits + offset);
1491             
1492             a = ((pixel & 0xc0) * 0x55) << 18;
1493             b = ((pixel & 0x30) * 0x55) >> 6;
1494             g = ((pixel & 0x0c) * 0x55) << 6;
1495             r = ((pixel & 0x03) * 0x55) << 16;
1496             buffer[i] = a|r|g|b;
1497         }
1498     }
1499 }
1500
1501 static void
1502 fbFetchPixel_c8 (bits_image_t *pict, uint32_t *buffer, int n_pixels)
1503 {
1504     int i;
1505
1506     for (i = 0; i < n_pixels; ++i)
1507     {
1508         int offset = buffer[2 * i];
1509         int line = buffer[2 * i + 1];
1510
1511         if (offset == 0xffffffff || line == 0xffffffff)
1512         {
1513             buffer[i] = 0;
1514         }
1515         else
1516         {
1517             uint32_t *bits = pict->bits + line*pict->rowstride;
1518             uint32_t   pixel = READ(pict, (uint8_t *) bits + offset);
1519             const pixman_indexed_t * indexed = pict->indexed;
1520             buffer[i] = indexed->rgba[pixel];
1521         }
1522     }
1523 }
1524
1525 static void
1526 fbFetchPixel_x4a4 (bits_image_t *pict, uint32_t *buffer, int n_pixels)
1527 {
1528     int i;
1529
1530     for (i = 0; i < n_pixels; ++i)
1531     {
1532         int offset = buffer[2 * i];
1533         int line = buffer[2 * i + 1];
1534
1535         if (offset == 0xffffffff || line == 0xffffffff)
1536         {
1537             buffer[i] = 0;
1538         }
1539         else
1540         {
1541             uint32_t *bits = pict->bits + line*pict->rowstride;
1542             uint32_t   pixel = READ(pict, (uint8_t *) bits + offset);
1543             
1544             buffer[i] = ((pixel & 0xf) | ((pixel & 0xf) << 4)) << 24;
1545         }
1546     }
1547 }
1548
1549 static void
1550 fbFetchPixel_a4 (bits_image_t *pict, uint32_t *buffer, int n_pixels)
1551 {
1552     int i;
1553
1554     for (i = 0; i < n_pixels; ++i)
1555     {
1556         int offset = buffer[2 * i];
1557         int line = buffer[2 * i + 1];
1558
1559         if (offset == 0xffffffff || line == 0xffffffff)
1560         {
1561             buffer[i] = 0;
1562         }
1563         else
1564         {
1565             uint32_t *bits = pict->bits + line*pict->rowstride;
1566             uint32_t  pixel = Fetch4 (pict, bits, offset);
1567             
1568             pixel |= pixel << 4;
1569             buffer[i] = pixel << 24;
1570         }
1571     }
1572 }
1573
1574 static void
1575 fbFetchPixel_r1g2b1 (bits_image_t *pict, uint32_t *buffer, int n_pixels)
1576 {
1577     int i;
1578
1579     for (i = 0; i < n_pixels; ++i)
1580     {
1581         int offset = buffer[2 * i];
1582         int line = buffer[2 * i + 1];
1583         
1584         if (offset == 0xffffffff || line == 0xffffffff)
1585         {
1586             buffer[i] = 0;
1587         }
1588         else
1589         {
1590             uint32_t  r,g,b;
1591             uint32_t *bits = pict->bits + line*pict->rowstride;
1592             uint32_t  pixel = Fetch4 (pict, bits, offset);
1593             
1594             r = ((pixel & 0x8) * 0xff) << 13;
1595             g = ((pixel & 0x6) * 0x55) << 7;
1596             b = ((pixel & 0x1) * 0xff);
1597             buffer[i] = 0xff000000|r|g|b;
1598         }
1599     }
1600 }
1601
1602 static void
1603 fbFetchPixel_b1g2r1 (bits_image_t *pict, uint32_t *buffer, int n_pixels)
1604 {
1605     int i;
1606
1607     for (i = 0; i < n_pixels; ++i)
1608     {
1609         int offset = buffer[2 * i];
1610         int line = buffer[2 * i + 1];
1611
1612         if (offset == 0xffffffff || line == 0xffffffff)
1613         {
1614             buffer[i] = 0;
1615         }
1616         else
1617         {
1618             uint32_t  r,g,b;
1619             uint32_t *bits = pict->bits + line*pict->rowstride;
1620             uint32_t  pixel = Fetch4 (pict, bits, offset);
1621             
1622             b = ((pixel & 0x8) * 0xff) >> 3;
1623             g = ((pixel & 0x6) * 0x55) << 7;
1624             r = ((pixel & 0x1) * 0xff) << 16;
1625             buffer[i] = 0xff000000|r|g|b;
1626         }
1627     }
1628 }
1629
1630 static void
1631 fbFetchPixel_a1r1g1b1 (bits_image_t *pict, uint32_t *buffer, int n_pixels)
1632 {
1633     int i;
1634
1635     for (i = 0; i < n_pixels; ++i)
1636     {
1637         int offset = buffer[2 * i];
1638         int line = buffer[2 * i + 1];
1639
1640         if (offset == 0xffffffff || line == 0xffffffff)
1641         {
1642             buffer[i] = 0;
1643         }
1644         else
1645         {
1646             uint32_t  a,r,g,b;
1647             uint32_t *bits = pict->bits + line*pict->rowstride;
1648             uint32_t  pixel = Fetch4 (pict, bits, offset);
1649             
1650             a = ((pixel & 0x8) * 0xff) << 21;
1651             r = ((pixel & 0x4) * 0xff) << 14;
1652             g = ((pixel & 0x2) * 0xff) << 7;
1653             b = ((pixel & 0x1) * 0xff);
1654             buffer[i] = a|r|g|b;
1655         }
1656     }
1657 }
1658
1659 static void
1660 fbFetchPixel_a1b1g1r1 (bits_image_t *pict, uint32_t *buffer, int n_pixels)
1661 {
1662     int i;
1663
1664     for (i = 0; i < n_pixels; ++i)
1665     {
1666         int offset = buffer[2 * i];
1667         int line = buffer[2 * i + 1];
1668
1669         if (offset == 0xffffffff || line == 0xffffffff)
1670         {
1671             buffer[i] = 0;
1672         }
1673         else
1674         {
1675             uint32_t  a,r,g,b;
1676             uint32_t *bits = pict->bits + line*pict->rowstride;
1677             uint32_t  pixel = Fetch4 (pict, bits, offset);
1678             
1679             a = ((pixel & 0x8) * 0xff) << 21;
1680             r = ((pixel & 0x4) * 0xff) >> 3;
1681             g = ((pixel & 0x2) * 0xff) << 7;
1682             b = ((pixel & 0x1) * 0xff) << 16;
1683             buffer[i] = a|r|g|b;
1684         }
1685     }
1686 }
1687
1688 static void
1689 fbFetchPixel_c4 (bits_image_t *pict, uint32_t *buffer, int n_pixels)
1690 {
1691     int i;
1692
1693     for (i = 0; i < n_pixels; ++i)
1694     {
1695         int offset = buffer[2 * i];
1696         int line = buffer[2 * i + 1];
1697
1698         if (offset == 0xffffffff || line == 0xffffffff)
1699         {
1700             buffer[i] = 0;
1701         }
1702         else
1703         {
1704             uint32_t *bits = pict->bits + line*pict->rowstride;
1705             uint32_t  pixel = Fetch4 (pict, bits, offset);
1706             const pixman_indexed_t * indexed = pict->indexed;
1707             
1708             buffer[i] = indexed->rgba[pixel];
1709         }
1710     }
1711 }
1712
1713
1714 static void
1715 fbFetchPixel_a1 (bits_image_t *pict, uint32_t *buffer, int n_pixels)
1716 {
1717     int i;
1718
1719     for (i = 0; i < n_pixels; ++i)
1720     {
1721         int offset = buffer[2 * i];
1722         int line = buffer[2 * i + 1];
1723
1724         if (offset == 0xffffffff || line == 0xffffffff)
1725         {
1726             buffer[i] = 0;
1727         }
1728         else
1729         {
1730             uint32_t *bits = pict->bits + line*pict->rowstride;
1731             uint32_t  pixel = READ(pict, bits + (offset >> 5));
1732             uint32_t  a;
1733 #ifdef WORDS_BIGENDIAN
1734             a = pixel >> (0x1f - (offset & 0x1f));
1735 #else
1736             a = pixel >> (offset & 0x1f);
1737 #endif
1738             a = a & 1;
1739             a |= a << 1;
1740             a |= a << 2;
1741             a |= a << 4;
1742             buffer[i] = a << 24;
1743         }
1744     }
1745 }
1746
1747 static void
1748 fbFetchPixel_g1 (bits_image_t *pict, uint32_t *buffer, int n_pixels)
1749 {
1750     int i;
1751
1752     for (i = 0; i < n_pixels; ++i)
1753     {
1754         int offset = buffer[2 * i];
1755         int line = buffer[2 * i + 1];
1756
1757         if (offset == 0xffffffff || line == 0xffffffff)
1758         {
1759             buffer[i] = 0;
1760         }
1761         else
1762         {
1763             uint32_t *bits = pict->bits + line*pict->rowstride;
1764             uint32_t pixel = READ(pict, bits + (offset >> 5));
1765             const pixman_indexed_t * indexed = pict->indexed;
1766             uint32_t a;
1767 #ifdef WORDS_BIGENDIAN
1768             a = pixel >> (0x1f - (offset & 0x1f));
1769 #else
1770             a = pixel >> (offset & 0x1f);
1771 #endif
1772             a = a & 1;
1773             buffer[i] = indexed->rgba[a];
1774         }
1775     }
1776 }
1777
1778 static void
1779 fbFetchPixel_yuy2 (bits_image_t *pict, uint32_t *buffer, int n_pixels)
1780 {
1781     int i;
1782
1783     for (i = 0; i < n_pixels; ++i)
1784     {
1785         int offset = buffer[2 * i];
1786         int line = buffer[2 * i + 1];
1787
1788         if (offset == 0xffffffff || line == 0xffffffff)
1789         {
1790             buffer[i] = 0;
1791         }
1792         else
1793         {
1794             int16_t y, u, v;
1795             int32_t r, g, b;
1796             
1797             const uint32_t *bits = pict->bits + pict->rowstride * line;
1798             
1799             y = ((uint8_t *) bits)[offset << 1] - 16;
1800             u = ((uint8_t *) bits)[((offset << 1) & -4) + 1] - 128;
1801             v = ((uint8_t *) bits)[((offset << 1) & -4) + 3] - 128;
1802             
1803             /* R = 1.164(Y - 16) + 1.596(V - 128) */
1804             r = 0x012b27 * y + 0x019a2e * v;
1805             /* G = 1.164(Y - 16) - 0.813(V - 128) - 0.391(U - 128) */
1806             g = 0x012b27 * y - 0x00d0f2 * v - 0x00647e * u;
1807             /* B = 1.164(Y - 16) + 2.018(U - 128) */
1808             b = 0x012b27 * y + 0x0206a2 * u;
1809             
1810             buffer[i] = 0xff000000 |
1811                 (r >= 0 ? r < 0x1000000 ? r         & 0xff0000 : 0xff0000 : 0) |
1812                 (g >= 0 ? g < 0x1000000 ? (g >> 8)  & 0x00ff00 : 0x00ff00 : 0) |
1813                 (b >= 0 ? b < 0x1000000 ? (b >> 16) & 0x0000ff : 0x0000ff : 0);
1814         }
1815     }
1816 }
1817
1818 static void
1819 fbFetchPixel_yv12 (bits_image_t *pict, uint32_t *buffer, int n_pixels)
1820 {
1821     int i;
1822
1823     for (i = 0; i < n_pixels; ++i)
1824     {
1825         int offset = buffer[2 * i];
1826         int line = buffer[2 * i + 1];
1827
1828         if (offset == 0xffffffff || line == 0xffffffff)
1829         {
1830             buffer[i] = 0;
1831         }
1832         else
1833         {
1834             YV12_SETUP(pict);
1835             int16_t y = YV12_Y (line)[offset] - 16;
1836             int16_t u = YV12_U (line)[offset >> 1] - 128;
1837             int16_t v = YV12_V (line)[offset >> 1] - 128;
1838             int32_t r, g, b;
1839             
1840             /* R = 1.164(Y - 16) + 1.596(V - 128) */
1841             r = 0x012b27 * y + 0x019a2e * v;
1842             /* G = 1.164(Y - 16) - 0.813(V - 128) - 0.391(U - 128) */
1843             g = 0x012b27 * y - 0x00d0f2 * v - 0x00647e * u;
1844             /* B = 1.164(Y - 16) + 2.018(U - 128) */
1845             b = 0x012b27 * y + 0x0206a2 * u;
1846             
1847             buffer[i] = 0xff000000 |
1848                 (r >= 0 ? r < 0x1000000 ? r         & 0xff0000 : 0xff0000 : 0) |
1849                 (g >= 0 ? g < 0x1000000 ? (g >> 8)  & 0x00ff00 : 0x00ff00 : 0) |
1850                 (b >= 0 ? b < 0x1000000 ? (b >> 16) & 0x0000ff : 0x0000ff : 0);
1851         }
1852     }
1853 }
1854
1855 /*********************************** Store ************************************/
1856
1857 #define Splita(v)       uint32_t        a = ((v) >> 24), r = ((v) >> 16) & 0xff, g = ((v) >> 8) & 0xff, b = (v) & 0xff
1858 #define Split(v)        uint32_t        r = ((v) >> 16) & 0xff, g = ((v) >> 8) & 0xff, b = (v) & 0xff
1859
1860 static void
1861 fbStore_a2b10g10r10 (bits_image_t *image, int x, int y, int width, const uint32_t *v)
1862 {
1863     uint32_t *bits = image->bits + image->rowstride * y;
1864     uint32_t *pixel = bits + x;
1865     uint64_t *values = (uint64_t *)v;
1866     int i;
1867     
1868     for (i = 0; i < width; ++i) {
1869         WRITE(image, pixel++,
1870             ((values[i] >> 32) & 0xc0000000) | // A
1871             ((values[i] >> 38) & 0x3ff) |      // R
1872             ((values[i] >> 12) & 0xffc00) |    // G
1873             ((values[i] << 14) & 0x3ff00000)); // B
1874     }
1875 }
1876
1877 static void
1878 fbStore_x2b10g10r10 (bits_image_t *image, int x, int y, int width, const uint32_t *v)
1879 {
1880     uint32_t *bits = image->bits + image->rowstride * y;
1881     uint64_t *values = (uint64_t *)v;
1882     uint32_t *pixel = bits + x;
1883     int i;
1884     
1885     for (i = 0; i < width; ++i) {
1886         WRITE(image, pixel++,
1887             ((values[i] >> 38) & 0x3ff) |      // R
1888             ((values[i] >> 12) & 0xffc00) |    // G
1889             ((values[i] << 14) & 0x3ff00000)); // B
1890     }
1891 }
1892
1893 static void
1894 fbStore_a8r8g8b8 (bits_image_t *image,
1895                   int x, int y, int width,
1896                   const uint32_t *values)
1897 {
1898     uint32_t *bits = image->bits + image->rowstride * y;
1899     
1900     MEMCPY_WRAPPED(image, ((uint32_t *)bits) + x, values, width*sizeof(uint32_t));
1901 }
1902
1903 static void
1904 fbStore_x8r8g8b8 (bits_image_t *image,
1905                   int x, int y, int width,
1906                   const uint32_t *values)
1907 {
1908     uint32_t *bits = image->bits + image->rowstride * y;
1909     uint32_t *pixel = (uint32_t *)bits + x;
1910     int i;
1911     
1912     for (i = 0; i < width; ++i)
1913         WRITE(image, pixel++, values[i] & 0xffffff);
1914 }
1915
1916 static void
1917 fbStore_a8b8g8r8 (bits_image_t *image,
1918                   int x, int y, int width,
1919                   const uint32_t *values)
1920 {
1921     uint32_t *bits = image->bits + image->rowstride * y;
1922     uint32_t *pixel = (uint32_t *)bits + x;
1923     int i;
1924     
1925     for (i = 0; i < width; ++i)
1926         WRITE(image, pixel++, (values[i] & 0xff00ff00) | ((values[i] >> 16) & 0xff) | ((values[i] & 0xff) << 16));
1927 }
1928
1929 static void
1930 fbStore_x8b8g8r8 (bits_image_t *image,
1931                   int x, int y, int width,
1932                   const uint32_t *values)
1933 {
1934     uint32_t *bits = image->bits + image->rowstride * y;
1935     uint32_t *pixel = (uint32_t *)bits + x;
1936     int i;
1937     
1938     for (i = 0; i < width; ++i)
1939         WRITE(image, pixel++, (values[i] & 0x0000ff00) | ((values[i] >> 16) & 0xff) | ((values[i] & 0xff) << 16));
1940 }
1941
1942 static void
1943 fbStore_b8g8r8a8 (bits_image_t *image,
1944                   int x, int y, int width,
1945                   const uint32_t *values)
1946 {
1947     uint32_t *bits = image->bits + image->rowstride * y;
1948     uint32_t *pixel = (uint32_t *)bits + x;
1949     int i;
1950
1951     for (i = 0; i < width; ++i)
1952         WRITE(image, pixel++,
1953             ((values[i] >> 24) & 0x000000ff) |
1954             ((values[i] >>  8) & 0x0000ff00) |
1955             ((values[i] <<  8) & 0x00ff0000) |
1956             ((values[i] << 24) & 0xff000000));
1957 }
1958
1959 static void
1960 fbStore_b8g8r8x8 (bits_image_t *image,
1961                   int x, int y, int width,
1962                   const uint32_t *values)
1963 {
1964     uint32_t *bits = image->bits + image->rowstride * y;
1965     uint32_t *pixel = (uint32_t *)bits + x;
1966     int i;
1967
1968     for (i = 0; i < width; ++i)
1969         WRITE(image, pixel++,
1970             ((values[i] >>  8) & 0x0000ff00) |
1971             ((values[i] <<  8) & 0x00ff0000) |
1972             ((values[i] << 24) & 0xff000000));
1973 }
1974
1975 static void
1976 fbStore_r8g8b8 (bits_image_t *image,
1977                 int x, int y, int width,
1978                 const uint32_t *values)
1979 {
1980     uint32_t *bits = image->bits + image->rowstride * y;
1981     uint8_t *pixel = ((uint8_t *) bits) + 3*x;
1982     int i;
1983
1984     for (i = 0; i < width; ++i)
1985     {
1986         uint32_t val = values[i];
1987 #ifdef WORDS_BIGENDIAN
1988         WRITE(image, pixel++, (val & 0x00ff0000) >> 16);
1989         WRITE(image, pixel++, (val & 0x0000ff00) >>  8);
1990         WRITE(image, pixel++, (val & 0x000000ff) >>  0);
1991 #else
1992         WRITE(image, pixel++, (val & 0x000000ff) >>  0);
1993         WRITE(image, pixel++, (val & 0x0000ff00) >>  8);
1994         WRITE(image, pixel++, (val & 0x00ff0000) >> 16);
1995 #endif
1996     }
1997 }
1998
1999 static void
2000 fbStore_b8g8r8 (bits_image_t *image,
2001                 int x, int y, int width,
2002                 const uint32_t *values)
2003 {
2004     uint32_t *bits = image->bits + image->rowstride * y;
2005     uint8_t *pixel = ((uint8_t *) bits) + 3*x;
2006     int i;
2007
2008     for (i = 0; i < width; ++i)
2009     {
2010         uint32_t val = values[i];
2011 #ifdef WORDS_BIGENDIAN
2012         WRITE(image, pixel++, (val & 0x000000ff) >>  0);
2013         WRITE(image, pixel++, (val & 0x0000ff00) >>  8);
2014         WRITE(image, pixel++, (val & 0x00ff0000) >> 16);
2015 #else
2016         WRITE(image, pixel++, (val & 0x00ff0000) >> 16);
2017         WRITE(image, pixel++, (val & 0x0000ff00) >>  8);
2018         WRITE(image, pixel++, (val & 0x000000ff) >>  0);
2019 #endif
2020     }
2021 }
2022
2023 static void
2024 fbStore_r5g6b5 (bits_image_t *image,
2025                 int x, int y, int width,
2026                 const uint32_t *values)
2027 {
2028     uint32_t *bits = image->bits + image->rowstride * y;
2029     uint16_t *pixel = ((uint16_t *) bits) + x;
2030     int i;
2031
2032     for (i = 0; i < width; ++i) {
2033         uint32_t s = values[i];
2034         WRITE(image, pixel++, ((s >> 3) & 0x001f) |
2035               ((s >> 5) & 0x07e0) |
2036               ((s >> 8) & 0xf800));
2037     }
2038 }
2039
2040 static void
2041 fbStore_b5g6r5 (bits_image_t *image,
2042                 int x, int y, int width,
2043                 const uint32_t *values)
2044 {
2045     uint32_t *bits = image->bits + image->rowstride * y;
2046     uint16_t  *pixel = ((uint16_t *) bits) + x;
2047     int i;
2048
2049     for (i = 0; i < width; ++i) {
2050         Split(values[i]);
2051         WRITE(image, pixel++, ((b << 8) & 0xf800) |
2052               ((g << 3) & 0x07e0) |
2053               ((r >> 3)         ));
2054     }
2055 }
2056
2057 static void
2058 fbStore_a1r5g5b5 (bits_image_t *image,
2059                   int x, int y, int width,
2060                   const uint32_t *values)
2061 {
2062     uint32_t *bits = image->bits + image->rowstride * y;
2063     uint16_t  *pixel = ((uint16_t *) bits) + x;
2064     int i;
2065
2066     for (i = 0; i < width; ++i) {
2067         Splita(values[i]);
2068         WRITE(image, pixel++, ((a << 8) & 0x8000) |
2069               ((r << 7) & 0x7c00) |
2070               ((g << 2) & 0x03e0) |
2071               ((b >> 3)         ));
2072     }
2073 }
2074
2075 static void
2076 fbStore_x1r5g5b5 (bits_image_t *image,
2077                   int x, int y, int width,
2078                   const uint32_t *values)
2079 {
2080     uint32_t *bits = image->bits + image->rowstride * y;
2081     uint16_t  *pixel = ((uint16_t *) bits) + x;
2082     int i;
2083
2084     for (i = 0; i < width; ++i) {
2085         Split(values[i]);
2086         WRITE(image, pixel++, ((r << 7) & 0x7c00) |
2087               ((g << 2) & 0x03e0) |
2088               ((b >> 3)         ));
2089     }
2090 }
2091
2092 static void
2093 fbStore_a1b5g5r5 (bits_image_t *image,
2094                   int x, int y, int width,
2095                   const uint32_t *values)
2096 {
2097     uint32_t *bits = image->bits + image->rowstride * y;
2098     uint16_t  *pixel = ((uint16_t *) bits) + x;
2099     int i;
2100
2101     for (i = 0; i < width; ++i) {
2102         Splita(values[i]);
2103         WRITE(image, pixel++, ((a << 8) & 0x8000) |
2104               ((b << 7) & 0x7c00) |
2105               ((g << 2) & 0x03e0) |
2106               ((r >> 3)         ));
2107     }
2108 }
2109
2110 static void
2111 fbStore_x1b5g5r5 (bits_image_t *image,
2112                   int x, int y, int width,
2113                   const uint32_t *values)
2114 {
2115     uint32_t *bits = image->bits + image->rowstride * y;
2116     uint16_t  *pixel = ((uint16_t *) bits) + x;
2117     int i;
2118
2119     for (i = 0; i < width; ++i) {
2120         Split(values[i]);
2121         WRITE(image, pixel++, ((b << 7) & 0x7c00) |
2122               ((g << 2) & 0x03e0) |
2123               ((r >> 3)         ));
2124     }
2125 }
2126
2127 static void
2128 fbStore_a4r4g4b4 (bits_image_t *image,
2129                   int x, int y, int width,
2130                   const uint32_t *values)
2131 {
2132     uint32_t *bits = image->bits + image->rowstride * y;
2133     uint16_t  *pixel = ((uint16_t *) bits) + x;
2134     int i;
2135
2136     for (i = 0; i < width; ++i) {
2137         Splita(values[i]);
2138         WRITE(image, pixel++, ((a << 8) & 0xf000) |
2139               ((r << 4) & 0x0f00) |
2140               ((g     ) & 0x00f0) |
2141               ((b >> 4)         ));
2142     }
2143 }
2144
2145 static void
2146 fbStore_x4r4g4b4 (bits_image_t *image,
2147                   int x, int y, int width,
2148                   const uint32_t *values)
2149 {
2150     uint32_t *bits = image->bits + image->rowstride * y;
2151     uint16_t  *pixel = ((uint16_t *) bits) + x;
2152     int i;
2153
2154     for (i = 0; i < width; ++i) {
2155         Split(values[i]);
2156         WRITE(image, pixel++, ((r << 4) & 0x0f00) |
2157               ((g     ) & 0x00f0) |
2158               ((b >> 4)         ));
2159     }
2160 }
2161
2162 static void
2163 fbStore_a4b4g4r4 (bits_image_t *image,
2164                   int x, int y, int width,
2165                   const uint32_t *values)
2166 {
2167     uint32_t *bits = image->bits + image->rowstride * y;
2168     uint16_t  *pixel = ((uint16_t *) bits) + x;
2169     int i;
2170
2171     for (i = 0; i < width; ++i) {
2172         Splita(values[i]);
2173         WRITE(image, pixel++, ((a << 8) & 0xf000) |
2174               ((b << 4) & 0x0f00) |
2175               ((g     ) & 0x00f0) |
2176               ((r >> 4)         ));
2177     }
2178 }
2179
2180 static void
2181 fbStore_x4b4g4r4 (bits_image_t *image,
2182                   int x, int y, int width,
2183                   const uint32_t *values)
2184 {
2185     uint32_t *bits = image->bits + image->rowstride * y;
2186     uint16_t  *pixel = ((uint16_t *) bits) + x;
2187     int i;
2188
2189     for (i = 0; i < width; ++i) {
2190         Split(values[i]);
2191         WRITE(image, pixel++, ((b << 4) & 0x0f00) |
2192               ((g     ) & 0x00f0) |
2193               ((r >> 4)         ));
2194     }
2195 }
2196
2197 static void
2198 fbStore_a8 (bits_image_t *image,
2199             int x, int y, int width,
2200             const uint32_t *values)
2201 {
2202     uint32_t *bits = image->bits + image->rowstride * y;
2203     uint8_t   *pixel = ((uint8_t *) bits) + x;
2204     int i;
2205
2206     for (i = 0; i < width; ++i) {
2207         WRITE(image, pixel++, values[i] >> 24);
2208     }
2209 }
2210
2211 static void
2212 fbStore_r3g3b2 (bits_image_t *image,
2213                 int x, int y, int width,
2214                 const uint32_t *values)
2215 {
2216     uint32_t *bits = image->bits + image->rowstride * y;
2217     uint8_t   *pixel = ((uint8_t *) bits) + x;
2218     int i;
2219
2220     for (i = 0; i < width; ++i) {
2221         Split(values[i]);
2222         WRITE(image, pixel++,
2223               ((r     ) & 0xe0) |
2224               ((g >> 3) & 0x1c) |
2225               ((b >> 6)       ));
2226     }
2227 }
2228
2229 static void
2230 fbStore_b2g3r3 (bits_image_t *image,
2231                 int x, int y, int width,
2232                 const uint32_t *values)
2233 {
2234     uint32_t *bits = image->bits + image->rowstride * y;
2235     uint8_t   *pixel = ((uint8_t *) bits) + x;
2236     int i;
2237
2238     for (i = 0; i < width; ++i) {
2239         Split(values[i]);
2240         WRITE(image, pixel++,
2241               ((b     ) & 0xc0) |
2242               ((g >> 2) & 0x38) |
2243               ((r >> 5)       ));
2244     }
2245 }
2246
2247 static void
2248 fbStore_a2r2g2b2 (bits_image_t *image,
2249                   int x, int y, int width,
2250                   const uint32_t *values)
2251 {
2252     uint32_t *bits = image->bits + image->rowstride * y;
2253     uint8_t   *pixel = ((uint8_t *) bits) + x;
2254     int i;
2255
2256     for (i = 0; i < width; ++i) {
2257         Splita(values[i]);
2258         WRITE(image, pixel++, ((a     ) & 0xc0) |
2259               ((r >> 2) & 0x30) |
2260               ((g >> 4) & 0x0c) |
2261               ((b >> 6)       ));
2262     }
2263 }
2264
2265 static void
2266 fbStore_a2b2g2r2 (bits_image_t *image,
2267                   int x, int y, int width,
2268                   const uint32_t *values)
2269 {
2270     uint32_t *bits = image->bits + image->rowstride * y;
2271     uint8_t   *pixel = ((uint8_t *) bits) + x;
2272     int i;
2273
2274     for (i = 0; i < width; ++i) {
2275         Splita(values[i]);
2276         *(pixel++) =  ((a     ) & 0xc0) |
2277             ((b >> 2) & 0x30) |
2278             ((g >> 4) & 0x0c) |
2279             ((r >> 6)       );
2280     }
2281 }
2282
2283 static void
2284 fbStore_c8 (bits_image_t *image,
2285             int x, int y, int width,
2286             const uint32_t *values)
2287 {
2288     uint32_t *bits = image->bits + image->rowstride * y;
2289     uint8_t *pixel = ((uint8_t *) bits) + x;
2290     const pixman_indexed_t *indexed = image->indexed;
2291     int i;
2292     
2293     for (i = 0; i < width; ++i) {
2294         WRITE(image, pixel++, miIndexToEnt24(indexed,values[i]));
2295     }
2296 }
2297
2298 static void
2299 fbStore_x4a4 (bits_image_t *image,
2300               int x, int y, int width,
2301               const uint32_t *values)
2302 {
2303     uint32_t *bits = image->bits + image->rowstride * y;
2304     uint8_t   *pixel = ((uint8_t *) bits) + x;
2305     int i;
2306
2307     for (i = 0; i < width; ++i) {
2308         WRITE(image, pixel++, values[i] >> 28);
2309     }
2310 }
2311
2312 #define Store8(img,l,o,v)  (WRITE(img, (uint8_t *)(l) + ((o) >> 3), (v)))
2313 #ifdef WORDS_BIGENDIAN
2314 #define Store4(img,l,o,v)  Store8(img,l,o,((o) & 4 ?                            \
2315                                    (Fetch8(img,l,o) & 0xf0) | (v) :             \
2316                                    (Fetch8(img,l,o) & 0x0f) | ((v) << 4)))
2317 #else
2318 #define Store4(img,l,o,v)  Store8(img,l,o,((o) & 4 ?                           \
2319                                    (Fetch8(img,l,o) & 0x0f) | ((v) << 4) : \
2320                                    (Fetch8(img,l,o) & 0xf0) | (v)))
2321 #endif
2322
2323 static void
2324 fbStore_a4 (bits_image_t *image,
2325             int x, int y, int width,
2326             const uint32_t *values)
2327 {
2328     uint32_t *bits = image->bits + image->rowstride * y;
2329     int i;
2330     
2331     for (i = 0; i < width; ++i) {
2332         Store4(image, bits, i + x, values[i]>>28);
2333     }
2334 }
2335
2336 static void
2337 fbStore_r1g2b1 (bits_image_t *image,
2338                 int x, int y, int width,
2339                 const uint32_t *values)
2340 {
2341     uint32_t *bits = image->bits + image->rowstride * y;
2342     int i;
2343     
2344     for (i = 0; i < width; ++i) {
2345         uint32_t  pixel;
2346
2347         Split(values[i]);
2348         pixel = (((r >> 4) & 0x8) |
2349                  ((g >> 5) & 0x6) |
2350                  ((b >> 7)      ));
2351         Store4(image, bits, i + x, pixel);
2352     }
2353 }
2354
2355 static void
2356 fbStore_b1g2r1 (bits_image_t *image,
2357                 int x, int y, int width,
2358                 const uint32_t *values)
2359 {
2360     uint32_t *bits = image->bits + image->rowstride * y;
2361     int i;
2362     
2363     for (i = 0; i < width; ++i) {
2364         uint32_t  pixel;
2365
2366         Split(values[i]);
2367         pixel = (((b >> 4) & 0x8) |
2368                  ((g >> 5) & 0x6) |
2369                  ((r >> 7)      ));
2370         Store4(image, bits, i + x, pixel);
2371     }
2372 }
2373
2374 static void
2375 fbStore_a1r1g1b1 (bits_image_t *image,
2376                   int x, int y, int width,
2377                   const uint32_t *values)
2378 {
2379     uint32_t *bits = image->bits + image->rowstride * y;
2380     int i;
2381     
2382     for (i = 0; i < width; ++i) {
2383         uint32_t  pixel;
2384         Splita(values[i]);
2385         pixel = (((a >> 4) & 0x8) |
2386                  ((r >> 5) & 0x4) |
2387                  ((g >> 6) & 0x2) |
2388                  ((b >> 7)      ));
2389         Store4(image, bits, i + x, pixel);
2390     }
2391 }
2392
2393 static void
2394 fbStore_a1b1g1r1 (bits_image_t *image,
2395                   int x, int y, int width,
2396                   const uint32_t *values)
2397 {
2398     uint32_t *bits = image->bits + image->rowstride * y;
2399     int i;
2400     
2401     for (i = 0; i < width; ++i) {
2402         uint32_t  pixel;
2403         Splita(values[i]);
2404         pixel = (((a >> 4) & 0x8) |
2405                  ((b >> 5) & 0x4) |
2406                  ((g >> 6) & 0x2) |
2407                  ((r >> 7)      ));
2408         Store4(image, bits, i + x, pixel);
2409     }
2410 }
2411
2412 static void
2413 fbStore_c4 (bits_image_t *image,
2414             int x, int y, int width,
2415             const uint32_t *values)
2416 {
2417     uint32_t *bits = image->bits + image->rowstride * y;
2418     const pixman_indexed_t *indexed = image->indexed;
2419     int i;
2420     
2421     for (i = 0; i < width; ++i) {
2422         uint32_t  pixel;
2423
2424         pixel = miIndexToEnt24(indexed, values[i]);
2425         Store4(image, bits, i + x, pixel);
2426     }
2427 }
2428
2429 static void
2430 fbStore_a1 (bits_image_t *image,
2431             int x, int y, int width,
2432             const uint32_t *values)
2433 {
2434     uint32_t *bits = image->bits + image->rowstride * y;
2435     int i;
2436     
2437     for (i = 0; i < width; ++i)
2438     {
2439         uint32_t  *pixel = ((uint32_t *) bits) + ((i+x) >> 5);
2440         uint32_t mask, v;
2441 #ifdef WORDS_BIGENDIAN
2442         mask = 1 << (0x1f - ((i+x) & 0x1f));
2443 #else
2444         mask = 1 << ((i+x) & 0x1f);
2445 #endif
2446         v = values[i] & 0x80000000 ? mask : 0;
2447         WRITE(image, pixel, (READ(image, pixel) & ~mask) | v);
2448     }
2449 }
2450
2451 static void
2452 fbStore_g1 (bits_image_t *image,
2453             int x, int y, int width,
2454             const uint32_t *values)
2455 {
2456     uint32_t *bits = image->bits + image->rowstride * y;
2457     const pixman_indexed_t *indexed = image->indexed;
2458     int i;
2459     
2460     for (i = 0; i < width; ++i)
2461     {
2462         uint32_t  *pixel = ((uint32_t *) bits) + ((i+x) >> 5);
2463         uint32_t  mask, v;
2464 #ifdef WORDS_BIGENDIAN
2465         mask = 1 << (0x1f - ((i+x) & 0x1f));
2466 #else
2467         mask = 1 << ((i + x) & 0x1f);
2468 #endif
2469         v = miIndexToEntY24 (indexed, values[i]) ? mask : 0;
2470         WRITE(image, pixel, (READ(image, pixel) & ~mask) | v);
2471     }
2472 }
2473
2474 /*
2475  * Contracts a 64bpp image to 32bpp and then stores it using a regular 32-bit
2476  * store proc. Despite the type, this function expects a uint64_t buffer.
2477  */
2478 static void
2479 fbStore64_generic (bits_image_t *image, int x, int y, int width, const uint32_t *values)
2480 {
2481     uint32_t *argb8Pixels;
2482
2483     assert(image->common.type == BITS);
2484
2485     argb8Pixels = pixman_malloc_ab (width, sizeof(uint32_t));
2486     if (!argb8Pixels)
2487         return;
2488
2489     /* Contract the scanline.  We could do this in place if values weren't
2490      * const.
2491      */
2492     pixman_contract(argb8Pixels, (uint64_t *)values, width);
2493     
2494     image->store_scanline_raw_32 (image, x, y, width, argb8Pixels);
2495
2496     free(argb8Pixels);
2497 }
2498
2499 /* Despite the type, this function expects both buffer and mask to be uint64_t */
2500 static void
2501 fbFetch64_generic (pixman_image_t *image, int x, int y, int width, uint32_t *buffer,
2502                    const uint32_t *mask, uint32_t mask_bits)
2503 {
2504     /* Fetch the pixels into the first half of buffer and then expand them in
2505      * place.
2506      */
2507     image->bits.fetch_scanline_raw_32 (image, x, y, width, buffer, NULL, 0);
2508     
2509     pixman_expand ((uint64_t *)buffer, buffer, image->bits.format, width);
2510 }
2511
2512 /* Despite the type, this function expects a uint64_t *buffer */
2513 static void
2514 fbFetchPixel64_generic (bits_image_t *pict, uint32_t *buffer, int n_pixels)
2515 {
2516     pict->fetch_pixels_raw_32 (pict, buffer, n_pixels);
2517     
2518     pixman_expand ((uint64_t *)buffer, buffer, pict->format, n_pixels);
2519 }
2520
2521 /*
2522  * XXX: The transformed fetch path only works at 32-bpp so far.  When all paths
2523  * have wide versions, this can be removed.
2524  *
2525  * WARNING: This function loses precision!
2526  */
2527 static void
2528 fbFetchPixel32_generic_lossy (bits_image_t *pict, uint32_t *buffer, int n_pixels)
2529 {
2530     /* Since buffer contains n_pixels coordinate pairs, it also has enough room for
2531      * n_pixels 64 bit pixels.
2532      */
2533     pict->fetch_pixels_raw_64 (pict, buffer, n_pixels);
2534     
2535     pixman_contract (buffer, (uint64_t *)buffer, n_pixels);
2536 }
2537
2538 typedef struct
2539 {
2540     pixman_format_code_t                format;
2541     fetch_scanline_t                            fetch_scanline_raw_32;
2542     fetch_scanline_t                            fetch_scanline_raw_64;
2543     fetch_pixels_t                      fetch_pixels_raw_32;
2544     fetch_pixels_t                      fetch_pixels_raw_64;
2545     store_scanline_t                    store_scanline_raw_32;
2546     store_scanline_t                    store_scanline_raw_64;
2547 } format_info_t;
2548
2549 #define FORMAT_INFO(format)                                             \
2550     {                                                                   \
2551         PIXMAN_##format,                                                \
2552             fbFetch_##format, fbFetch64_generic,                        \
2553             fbFetchPixel_##format, fbFetchPixel64_generic,              \
2554             fbStore_##format, fbStore64_generic                         \
2555     }
2556
2557 static const format_info_t accessors[] =
2558 {
2559 /* 32 bpp formats */
2560     FORMAT_INFO (a8r8g8b8),
2561     FORMAT_INFO (x8r8g8b8),
2562     FORMAT_INFO (a8b8g8r8),
2563     FORMAT_INFO (x8b8g8r8),
2564     FORMAT_INFO (b8g8r8a8),
2565     FORMAT_INFO (b8g8r8x8),
2566
2567 /* 24bpp formats */
2568     FORMAT_INFO (r8g8b8),
2569     FORMAT_INFO (b8g8r8),
2570     
2571 /* 16bpp formats */
2572     FORMAT_INFO (r5g6b5),
2573     FORMAT_INFO (b5g6r5),
2574     
2575     FORMAT_INFO (a1r5g5b5),
2576     FORMAT_INFO (x1r5g5b5),
2577     FORMAT_INFO (a1b5g5r5),
2578     FORMAT_INFO (x1b5g5r5),
2579     FORMAT_INFO (a4r4g4b4),
2580     FORMAT_INFO (x4r4g4b4),
2581     FORMAT_INFO (a4b4g4r4),
2582     FORMAT_INFO (x4b4g4r4),
2583     
2584 /* 8bpp formats */
2585     FORMAT_INFO (a8),
2586     FORMAT_INFO (r3g3b2),
2587     FORMAT_INFO (b2g3r3),
2588     FORMAT_INFO (a2r2g2b2),
2589     FORMAT_INFO (a2b2g2r2),
2590     
2591     FORMAT_INFO (c8),
2592
2593 #define fbFetch_g8 fbFetch_c8
2594 #define fbFetchPixel_g8 fbFetchPixel_c8
2595 #define fbStore_g8 fbStore_c8
2596     FORMAT_INFO (g8),
2597 #define fbFetch_x4c4 fbFetch_c8
2598 #define fbFetchPixel_x4c4 fbFetchPixel_c8
2599 #define fbStore_x4c4 fbStore_c8
2600     FORMAT_INFO (x4c4),
2601 #define fbFetch_x4g4 fbFetch_c8
2602 #define fbFetchPixel_x4g4 fbFetchPixel_c8
2603 #define fbStore_x4g4 fbStore_c8
2604     FORMAT_INFO (x4g4),
2605     
2606     FORMAT_INFO (x4a4),
2607     
2608 /* 4bpp formats */
2609     FORMAT_INFO (a4),
2610     FORMAT_INFO (r1g2b1),
2611     FORMAT_INFO (b1g2r1),
2612     FORMAT_INFO (a1r1g1b1),
2613     FORMAT_INFO (a1b1g1r1),
2614     
2615     FORMAT_INFO (c4),
2616 #define fbFetch_g4 fbFetch_c4
2617 #define fbFetchPixel_g4 fbFetchPixel_c4
2618 #define fbStore_g4 fbStore_c4
2619     FORMAT_INFO (g4),
2620     
2621 /* 1bpp formats */
2622     FORMAT_INFO (a1),
2623     FORMAT_INFO (g1),
2624
2625 /* Wide formats */
2626     
2627     { PIXMAN_a2b10g10r10,
2628       NULL, fbFetch_a2b10g10r10,
2629       fbFetchPixel32_generic_lossy, fbFetchPixel_a2b10g10r10_64,
2630       NULL, fbStore_a2b10g10r10 },
2631
2632     { PIXMAN_x2b10g10r10,
2633       NULL, fbFetch_x2b10g10r10,
2634       fbFetchPixel32_generic_lossy, fbFetchPixel_x2b10g10r10_64,
2635       NULL, fbStore_x2b10g10r10 },
2636
2637 /* YUV formats */
2638     { PIXMAN_yuy2,
2639       fbFetch_yuy2, fbFetch64_generic,
2640       fbFetchPixel_yuy2, fbFetchPixel64_generic,
2641       NULL, NULL },
2642
2643     { PIXMAN_yv12,
2644       fbFetch_yv12, fbFetch64_generic,
2645       fbFetchPixel_yv12, fbFetchPixel64_generic,
2646       NULL, NULL },
2647     
2648     { PIXMAN_null },
2649 };
2650
2651 static void
2652 setup_accessors (bits_image_t *image)
2653 {
2654     const format_info_t *info = accessors;
2655
2656     while (info->format != PIXMAN_null)
2657     {
2658         if (info->format == image->format)
2659         {
2660             image->fetch_scanline_raw_32 = info->fetch_scanline_raw_32;
2661             image->fetch_scanline_raw_64 = info->fetch_scanline_raw_64;
2662             image->fetch_pixels_raw_32 = info->fetch_pixels_raw_32;
2663             image->fetch_pixels_raw_64 = info->fetch_pixels_raw_64;
2664             image->store_scanline_raw_32 = info->store_scanline_raw_32;
2665             image->store_scanline_raw_64 = info->store_scanline_raw_64;
2666
2667             return;
2668         }
2669
2670         info++;
2671     }
2672 }
2673
2674 #ifndef PIXMAN_FB_ACCESSORS
2675 void
2676 _pixman_bits_image_setup_raw_accessors_accessors (bits_image_t *image);
2677
2678 void
2679 _pixman_bits_image_setup_raw_accessors (bits_image_t *image)
2680 {
2681     if (image->common.read_func || image->common.write_func)
2682         _pixman_bits_image_setup_raw_accessors_accessors (image);
2683     else
2684         setup_accessors (image);
2685 }
2686
2687 #else
2688
2689 void
2690 _pixman_bits_image_setup_raw_accessors_accessors (bits_image_t *image)
2691 {
2692     setup_accessors (image);
2693 }
2694
2695 #endif