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