Make use of SSE2 blt/fill in more places
[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_a2b10g10r10 (bits_image_t *pict, int x, int y, int width, uint64_t *buffer)
124 {
125     const uint32_t *bits = pict->bits + y*pict->rowstride;
126     const uint32_t *pixel = bits + x;
127     const uint32_t *end = pixel + width;
128     while (pixel < end) {
129         uint32_t p = READ(pict, pixel++);
130         uint64_t a = p >> 30;
131         uint64_t b = (p >> 20) & 0x3ff;
132         uint64_t g = (p >> 10) & 0x3ff;
133         uint64_t r = p & 0x3ff;
134
135         r = r << 6 | r >> 4;
136         g = g << 6 | g >> 4;
137         b = b << 6 | b >> 4;
138
139         a <<= 62;
140         a |= a >> 2;
141         a |= a >> 4;
142         a |= a >> 8;
143
144         *buffer++ = a << 48 | r << 32 | g << 16 | b;
145     }
146 }
147
148 static FASTCALL void
149 fbFetch_x2b10g10r10 (bits_image_t *pict, int x, int y, int width, uint64_t *buffer)
150 {
151     const uint32_t *bits = pict->bits + y*pict->rowstride;
152     const uint32_t *pixel = (uint32_t *)bits + x;
153     const uint32_t *end = pixel + width;
154     while (pixel < end) {
155         uint32_t p = READ(pict, pixel++);
156         uint64_t b = (p >> 20) & 0x3ff;
157         uint64_t g = (p >> 10) & 0x3ff;
158         uint64_t r = p & 0x3ff;
159
160         r = r << 6 | r >> 4;
161         g = g << 6 | g >> 4;
162         b = b << 6 | b >> 4;
163
164         *buffer++ = 0xffffULL << 48 | r << 32 | g << 16 | b;
165     }
166 }
167
168 static FASTCALL void
169 fbFetch_r8g8b8 (bits_image_t *pict, int x, int y, int width, uint32_t *buffer)
170 {
171     const uint32_t *bits = pict->bits + y*pict->rowstride;
172     const uint8_t *pixel = (const uint8_t *)bits + 3*x;
173     const uint8_t *end = pixel + 3*width;
174     while (pixel < end) {
175         uint32_t b = Fetch24(pict, pixel) | 0xff000000;
176         pixel += 3;
177         *buffer++ = b;
178     }
179 }
180
181 static FASTCALL void
182 fbFetch_b8g8r8 (bits_image_t *pict, int x, int y, int width, uint32_t *buffer)
183 {
184     const uint32_t *bits = pict->bits + y*pict->rowstride;
185     const uint8_t *pixel = (const uint8_t *)bits + 3*x;
186     const uint8_t *end = pixel + 3*width;
187     while (pixel < end) {
188         uint32_t b = 0xff000000;
189 #if IMAGE_BYTE_ORDER == MSBFirst
190         b |= (READ(pict, pixel++));
191         b |= (READ(pict, pixel++) << 8);
192         b |= (READ(pict, pixel++) << 16);
193 #else
194         b |= (READ(pict, pixel++) << 16);
195         b |= (READ(pict, pixel++) << 8);
196         b |= (READ(pict, pixel++));
197 #endif
198         *buffer++ = b;
199     }
200 }
201
202 static FASTCALL void
203 fbFetch_r5g6b5 (bits_image_t *pict, int x, int y, int width, uint32_t *buffer)
204 {
205     const uint32_t *bits = pict->bits + y*pict->rowstride;
206     const uint16_t *pixel = (const uint16_t *)bits + x;
207     const uint16_t *end = pixel + width;
208     while (pixel < end) {
209         uint32_t p = READ(pict, pixel++);
210         uint32_t r = (((p) << 3) & 0xf8) |
211             (((p) << 5) & 0xfc00) |
212             (((p) << 8) & 0xf80000);
213         r |= (r >> 5) & 0x70007;
214         r |= (r >> 6) & 0x300;
215         *buffer++ = 0xff000000 | r;
216     }
217 }
218
219 static FASTCALL void
220 fbFetch_b5g6r5 (bits_image_t *pict, int x, int y, int width, uint32_t *buffer)
221 {
222     uint32_t  r,g,b;
223     const uint32_t *bits = pict->bits + y*pict->rowstride;
224     const uint16_t *pixel = (const uint16_t *)bits + x;
225     const uint16_t *end = pixel + width;
226     while (pixel < end) {
227         uint32_t  p = READ(pict, pixel++);
228         b = ((p & 0xf800) | ((p & 0xe000) >> 5)) >> 8;
229         g = ((p & 0x07e0) | ((p & 0x0600) >> 6)) << 5;
230         r = ((p & 0x001c) | ((p & 0x001f) << 5)) << 14;
231         *buffer++ = 0xff000000 | r | g | b;
232     }
233 }
234
235 static FASTCALL void
236 fbFetch_a1r5g5b5 (bits_image_t *pict, int x, int y, int width, uint32_t *buffer)
237 {
238     uint32_t  r,g,b, a;
239     const uint32_t *bits = pict->bits + y*pict->rowstride;
240     const uint16_t *pixel = (const uint16_t *)bits + x;
241     const uint16_t *end = pixel + width;
242     while (pixel < end) {
243         uint32_t  p = READ(pict, pixel++);
244
245         a = (uint32_t) ((uint8_t) (0 - ((p & 0x8000) >> 15))) << 24;
246         r = ((p & 0x7c00) | ((p & 0x7000) >> 5)) << 9;
247         g = ((p & 0x03e0) | ((p & 0x0380) >> 5)) << 6;
248         b = ((p & 0x001c) | ((p & 0x001f) << 5)) >> 2;
249         *buffer++ = a | r | g | b;
250     }
251 }
252
253 static FASTCALL void
254 fbFetch_x1r5g5b5 (bits_image_t *pict, int x, int y, int width, uint32_t *buffer)
255 {
256     uint32_t  r,g,b;
257     const uint32_t *bits = pict->bits + y*pict->rowstride;
258     const uint16_t *pixel = (const uint16_t *)bits + x;
259     const uint16_t *end = pixel + width;
260     while (pixel < end) {
261         uint32_t  p = READ(pict, pixel++);
262
263         r = ((p & 0x7c00) | ((p & 0x7000) >> 5)) << 9;
264         g = ((p & 0x03e0) | ((p & 0x0380) >> 5)) << 6;
265         b = ((p & 0x001c) | ((p & 0x001f) << 5)) >> 2;
266         *buffer++ = 0xff000000 | r | g | b;
267     }
268 }
269
270 static FASTCALL void
271 fbFetch_a1b5g5r5 (bits_image_t *pict, int x, int y, int width, uint32_t *buffer)
272 {
273     uint32_t  r,g,b, a;
274     const uint32_t *bits = pict->bits + y*pict->rowstride;
275     const uint16_t *pixel = (const uint16_t *)bits + x;
276     const uint16_t *end = pixel + width;
277     while (pixel < end) {
278         uint32_t  p = READ(pict, pixel++);
279
280         a = (uint32_t) ((uint8_t) (0 - ((p & 0x8000) >> 15))) << 24;
281         b = ((p & 0x7c00) | ((p & 0x7000) >> 5)) >> 7;
282         g = ((p & 0x03e0) | ((p & 0x0380) >> 5)) << 6;
283         r = ((p & 0x001c) | ((p & 0x001f) << 5)) << 14;
284         *buffer++ = a | r | g | b;
285     }
286 }
287
288 static FASTCALL void
289 fbFetch_x1b5g5r5 (bits_image_t *pict, int x, int y, int width, uint32_t *buffer)
290 {
291     uint32_t  r,g,b;
292     const uint32_t *bits = pict->bits + y*pict->rowstride;
293     const uint16_t *pixel = (const uint16_t *)bits + x;
294     const uint16_t *end = pixel + width;
295     while (pixel < end) {
296         uint32_t  p = READ(pict, pixel++);
297
298         b = ((p & 0x7c00) | ((p & 0x7000) >> 5)) >> 7;
299         g = ((p & 0x03e0) | ((p & 0x0380) >> 5)) << 6;
300         r = ((p & 0x001c) | ((p & 0x001f) << 5)) << 14;
301         *buffer++ = 0xff000000 | r | g | b;
302     }
303 }
304
305 static FASTCALL void
306 fbFetch_a4r4g4b4 (bits_image_t *pict, int x, int y, int width, uint32_t *buffer)
307 {
308     uint32_t  r,g,b, a;
309     const uint32_t *bits = pict->bits + y*pict->rowstride;
310     const uint16_t *pixel = (const uint16_t *)bits + x;
311     const uint16_t *end = pixel + width;
312     while (pixel < end) {
313         uint32_t  p = READ(pict, pixel++);
314
315         a = ((p & 0xf000) | ((p & 0xf000) >> 4)) << 16;
316         r = ((p & 0x0f00) | ((p & 0x0f00) >> 4)) << 12;
317         g = ((p & 0x00f0) | ((p & 0x00f0) >> 4)) << 8;
318         b = ((p & 0x000f) | ((p & 0x000f) << 4));
319         *buffer++ = a | r | g | b;
320     }
321 }
322
323 static FASTCALL void
324 fbFetch_x4r4g4b4 (bits_image_t *pict, int x, int y, int width, uint32_t *buffer)
325 {
326     uint32_t  r,g,b;
327     const uint32_t *bits = pict->bits + y*pict->rowstride;
328     const uint16_t *pixel = (const uint16_t *)bits + x;
329     const uint16_t *end = pixel + width;
330     while (pixel < end) {
331         uint32_t  p = READ(pict, pixel++);
332
333         r = ((p & 0x0f00) | ((p & 0x0f00) >> 4)) << 12;
334         g = ((p & 0x00f0) | ((p & 0x00f0) >> 4)) << 8;
335         b = ((p & 0x000f) | ((p & 0x000f) << 4));
336         *buffer++ = 0xff000000 | r | g | b;
337     }
338 }
339
340 static FASTCALL void
341 fbFetch_a4b4g4r4 (bits_image_t *pict, int x, int y, int width, uint32_t *buffer)
342 {
343     uint32_t  r,g,b, a;
344     const uint32_t *bits = pict->bits + y*pict->rowstride;
345     const uint16_t *pixel = (const uint16_t *)bits + x;
346     const uint16_t *end = pixel + width;
347     while (pixel < end) {
348         uint32_t  p = READ(pict, pixel++);
349
350         a = ((p & 0xf000) | ((p & 0xf000) >> 4)) << 16;
351         b = ((p & 0x0f00) | ((p & 0x0f00) >> 4)) >> 4;
352         g = ((p & 0x00f0) | ((p & 0x00f0) >> 4)) << 8;
353         r = ((p & 0x000f) | ((p & 0x000f) << 4)) << 16;
354         *buffer++ = a | r | g | b;
355     }
356 }
357
358 static FASTCALL void
359 fbFetch_x4b4g4r4 (bits_image_t *pict, int x, int y, int width, uint32_t *buffer)
360 {
361     uint32_t  r,g,b;
362     const uint32_t *bits = pict->bits + y*pict->rowstride;
363     const uint16_t *pixel = (const uint16_t *)bits + x;
364     const uint16_t *end = pixel + width;
365     while (pixel < end) {
366         uint32_t  p = READ(pict, pixel++);
367
368         b = ((p & 0x0f00) | ((p & 0x0f00) >> 4)) >> 4;
369         g = ((p & 0x00f0) | ((p & 0x00f0) >> 4)) << 8;
370         r = ((p & 0x000f) | ((p & 0x000f) << 4)) << 16;
371         *buffer++ = 0xff000000 | r | g | b;
372     }
373 }
374
375 static FASTCALL void
376 fbFetch_a8 (bits_image_t *pict, int x, int y, int width, uint32_t *buffer)
377 {
378     const uint32_t *bits = pict->bits + y*pict->rowstride;
379     const uint8_t *pixel = (const uint8_t *)bits + x;
380     const uint8_t *end = pixel + width;
381     while (pixel < end) {
382         *buffer++ = READ(pict, pixel++) << 24;
383     }
384 }
385
386 static FASTCALL void
387 fbFetch_r3g3b2 (bits_image_t *pict, int x, int y, int width, uint32_t *buffer)
388 {
389     uint32_t  r,g,b;
390     const uint32_t *bits = pict->bits + y*pict->rowstride;
391     const uint8_t *pixel = (const uint8_t *)bits + x;
392     const uint8_t *end = pixel + width;
393     while (pixel < end) {
394         uint32_t  p = READ(pict, pixel++);
395
396         r = ((p & 0xe0) | ((p & 0xe0) >> 3) | ((p & 0xc0) >> 6)) << 16;
397         g = ((p & 0x1c) | ((p & 0x18) >> 3) | ((p & 0x1c) << 3)) << 8;
398         b = (((p & 0x03)     ) |
399              ((p & 0x03) << 2) |
400              ((p & 0x03) << 4) |
401              ((p & 0x03) << 6));
402         *buffer++ = 0xff000000 | r | g | b;
403     }
404 }
405
406 static FASTCALL void
407 fbFetch_b2g3r3 (bits_image_t *pict, int x, int y, int width, uint32_t *buffer)
408 {
409     uint32_t  r,g,b;
410     const uint32_t *bits = pict->bits + y*pict->rowstride;
411     const uint8_t *pixel = (const uint8_t *)bits + x;
412     const uint8_t *end = pixel + width;
413     while (pixel < end) {
414         uint32_t  p = READ(pict, pixel++);
415
416         b = (((p & 0xc0)     ) |
417              ((p & 0xc0) >> 2) |
418              ((p & 0xc0) >> 4) |
419              ((p & 0xc0) >> 6));
420         g = ((p & 0x38) | ((p & 0x38) >> 3) | ((p & 0x30) << 2)) << 8;
421         r = (((p & 0x07)     ) |
422              ((p & 0x07) << 3) |
423              ((p & 0x06) << 6)) << 16;
424         *buffer++ = 0xff000000 | r | g | b;
425     }
426 }
427
428 static FASTCALL void
429 fbFetch_a2r2g2b2 (bits_image_t *pict, int x, int y, int width, uint32_t *buffer)
430 {
431     uint32_t   a,r,g,b;
432     const uint32_t *bits = pict->bits + y*pict->rowstride;
433     const uint8_t *pixel = (const uint8_t *)bits + x;
434     const uint8_t *end = pixel + width;
435     while (pixel < end) {
436         uint32_t  p = READ(pict, pixel++);
437
438         a = ((p & 0xc0) * 0x55) << 18;
439         r = ((p & 0x30) * 0x55) << 12;
440         g = ((p & 0x0c) * 0x55) << 6;
441         b = ((p & 0x03) * 0x55);
442         *buffer++ = a|r|g|b;
443     }
444 }
445
446 static FASTCALL void
447 fbFetch_a2b2g2r2 (bits_image_t *pict, int x, int y, int width, uint32_t *buffer)
448 {
449     uint32_t   a,r,g,b;
450     const uint32_t *bits = pict->bits + y*pict->rowstride;
451     const uint8_t *pixel = (const uint8_t *)bits + x;
452     const uint8_t *end = pixel + width;
453     while (pixel < end) {
454         uint32_t  p = READ(pict, pixel++);
455
456         a = ((p & 0xc0) * 0x55) << 18;
457         b = ((p & 0x30) * 0x55) >> 6;
458         g = ((p & 0x0c) * 0x55) << 6;
459         r = ((p & 0x03) * 0x55) << 16;
460         *buffer++ = a|r|g|b;
461     }
462 }
463
464 static FASTCALL void
465 fbFetch_c8 (bits_image_t *pict, int x, int y, int width, uint32_t *buffer)
466 {
467     const uint32_t *bits = pict->bits + y*pict->rowstride;
468     const pixman_indexed_t * indexed = pict->indexed;
469     const uint8_t *pixel = (const uint8_t *)bits + x;
470     const uint8_t *end = pixel + width;
471     while (pixel < end) {
472         uint32_t  p = READ(pict, pixel++);
473         *buffer++ = indexed->rgba[p];
474     }
475 }
476
477 static FASTCALL void
478 fbFetch_x4a4 (bits_image_t *pict, int x, int y, int width, uint32_t *buffer)
479 {
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         uint8_t p = READ(pict, pixel++) & 0xf;
485         *buffer++ = (p | (p << 4)) << 24;
486     }
487 }
488
489 #define Fetch8(img,l,o)    (READ(img, (uint8_t *)(l) + ((o) >> 2)))
490 #if IMAGE_BYTE_ORDER == MSBFirst
491 #define Fetch4(img,l,o)    ((o) & 2 ? Fetch8(img,l,o) & 0xf : Fetch8(img,l,o) >> 4)
492 #else
493 #define Fetch4(img,l,o)    ((o) & 2 ? Fetch8(img,l,o) >> 4 : Fetch8(img,l,o) & 0xf)
494 #endif
495
496 static FASTCALL void
497 fbFetch_a4 (bits_image_t *pict, int x, int y, int width, uint32_t *buffer)
498 {
499     const uint32_t *bits = pict->bits + y*pict->rowstride;
500     int i;
501     for (i = 0; i < width; ++i) {
502         uint32_t  p = Fetch4(pict, bits, i + x);
503
504         p |= p << 4;
505         *buffer++ = p << 24;
506     }
507 }
508
509 static FASTCALL void
510 fbFetch_r1g2b1 (bits_image_t *pict, int x, int y, int width, uint32_t *buffer)
511 {
512     uint32_t  r,g,b;
513     const uint32_t *bits = pict->bits + y*pict->rowstride;
514     int i;
515     for (i = 0; i < width; ++i) {
516         uint32_t  p = Fetch4(pict, bits, i + x);
517
518         r = ((p & 0x8) * 0xff) << 13;
519         g = ((p & 0x6) * 0x55) << 7;
520         b = ((p & 0x1) * 0xff);
521         *buffer++ = 0xff000000|r|g|b;
522     }
523 }
524
525 static FASTCALL void
526 fbFetch_b1g2r1 (bits_image_t *pict, int x, int y, int width, uint32_t *buffer)
527 {
528     uint32_t  r,g,b;
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         b = ((p & 0x8) * 0xff) >> 3;
535         g = ((p & 0x6) * 0x55) << 7;
536         r = ((p & 0x1) * 0xff) << 16;
537         *buffer++ = 0xff000000|r|g|b;
538     }
539 }
540
541 static FASTCALL void
542 fbFetch_a1r1g1b1 (bits_image_t *pict, int x, int y, int width, uint32_t *buffer)
543 {
544     uint32_t  a,r,g,b;
545     const uint32_t *bits = pict->bits + y*pict->rowstride;
546     int i;
547     for (i = 0; i < width; ++i) {
548         uint32_t  p = Fetch4(pict, bits, i + x);
549
550         a = ((p & 0x8) * 0xff) << 21;
551         r = ((p & 0x4) * 0xff) << 14;
552         g = ((p & 0x2) * 0xff) << 7;
553         b = ((p & 0x1) * 0xff);
554         *buffer++ = a|r|g|b;
555     }
556 }
557
558 static FASTCALL void
559 fbFetch_a1b1g1r1 (bits_image_t *pict, int x, int y, int width, uint32_t *buffer)
560 {
561     uint32_t  a,r,g,b;
562     const uint32_t *bits = pict->bits + y*pict->rowstride;
563     int i;
564     for (i = 0; i < width; ++i) {
565         uint32_t  p = Fetch4(pict, bits, i + x);
566
567         a = ((p & 0x8) * 0xff) << 21;
568         r = ((p & 0x4) * 0xff) >> 3;
569         g = ((p & 0x2) * 0xff) << 7;
570         b = ((p & 0x1) * 0xff) << 16;
571         *buffer++ = a|r|g|b;
572     }
573 }
574
575 static FASTCALL void
576 fbFetch_c4 (bits_image_t *pict, int x, int y, int width, uint32_t *buffer)
577 {
578     const uint32_t *bits = pict->bits + y*pict->rowstride;
579     const pixman_indexed_t * indexed = pict->indexed;
580     int i;
581     for (i = 0; i < width; ++i) {
582         uint32_t  p = Fetch4(pict, bits, i + x);
583
584         *buffer++ = indexed->rgba[p];
585     }
586 }
587
588
589 static FASTCALL void
590 fbFetch_a1 (bits_image_t *pict, int x, int y, int width, uint32_t *buffer)
591 {
592     const uint32_t *bits = pict->bits + y*pict->rowstride;
593     int i;
594     for (i = 0; i < width; ++i) {
595         uint32_t  p = READ(pict, bits + ((i + x) >> 5));
596         uint32_t  a;
597 #if BITMAP_BIT_ORDER == MSBFirst
598         a = p >> (0x1f - ((i+x) & 0x1f));
599 #else
600         a = p >> ((i+x) & 0x1f);
601 #endif
602         a = a & 1;
603         a |= a << 1;
604         a |= a << 2;
605         a |= a << 4;
606         *buffer++ = a << 24;
607     }
608 }
609
610 static FASTCALL void
611 fbFetch_g1 (bits_image_t *pict, int x, int y, int width, uint32_t *buffer)
612 {
613     const uint32_t *bits = pict->bits + y*pict->rowstride;
614     const pixman_indexed_t * indexed = pict->indexed;
615     int i;
616     for (i = 0; i < width; ++i) {
617         uint32_t p = READ(pict, bits + ((i+x) >> 5));
618         uint32_t a;
619 #if BITMAP_BIT_ORDER == MSBFirst
620         a = p >> (0x1f - ((i+x) & 0x1f));
621 #else
622         a = p >> ((i+x) & 0x1f);
623 #endif
624         a = a & 1;
625         *buffer++ = indexed->rgba[a];
626     }
627 }
628
629 static FASTCALL void
630 fbFetch_yuy2 (bits_image_t *pict, int x, int line, int width, uint32_t *buffer)
631 {
632     int16_t y, u, v;
633     int32_t r, g, b;
634     int   i;
635
636     const uint32_t *bits = pict->bits + pict->rowstride * line;
637
638     for (i = 0; i < width; i++)
639     {
640         y = ((uint8_t *) bits)[(x + i) << 1] - 16;
641         u = ((uint8_t *) bits)[(((x + i) << 1) & -4) + 1] - 128;
642         v = ((uint8_t *) bits)[(((x + i) << 1) & -4) + 3] - 128;
643
644         /* R = 1.164(Y - 16) + 1.596(V - 128) */
645         r = 0x012b27 * y + 0x019a2e * v;
646         /* G = 1.164(Y - 16) - 0.813(V - 128) - 0.391(U - 128) */
647         g = 0x012b27 * y - 0x00d0f2 * v - 0x00647e * u;
648         /* B = 1.164(Y - 16) + 2.018(U - 128) */
649         b = 0x012b27 * y + 0x0206a2 * u;
650
651     WRITE(pict, buffer++, 0xff000000 |
652         (r >= 0 ? r < 0x1000000 ? r         & 0xff0000 : 0xff0000 : 0) |
653         (g >= 0 ? g < 0x1000000 ? (g >> 8)  & 0x00ff00 : 0x00ff00 : 0) |
654         (b >= 0 ? b < 0x1000000 ? (b >> 16) & 0x0000ff : 0x0000ff : 0));
655     }
656 }
657
658 static FASTCALL void
659 fbFetch_yv12 (bits_image_t *pict, int x, int line, int width, uint32_t *buffer)
660 {
661     YV12_SETUP(pict);
662     uint8_t *pY = YV12_Y (line);
663     uint8_t *pU = YV12_U (line);
664     uint8_t *pV = YV12_V (line);
665     int16_t y, u, v;
666     int32_t r, g, b;
667     int   i;
668
669     for (i = 0; i < width; i++)
670     {
671         y = pY[x + i] - 16;
672         u = pU[(x + i) >> 1] - 128;
673         v = pV[(x + i) >> 1] - 128;
674
675         /* R = 1.164(Y - 16) + 1.596(V - 128) */
676         r = 0x012b27 * y + 0x019a2e * v;
677         /* G = 1.164(Y - 16) - 0.813(V - 128) - 0.391(U - 128) */
678         g = 0x012b27 * y - 0x00d0f2 * v - 0x00647e * u;
679         /* B = 1.164(Y - 16) + 2.018(U - 128) */
680         b = 0x012b27 * y + 0x0206a2 * u;
681
682         WRITE(pict, buffer++, 0xff000000 |
683             (r >= 0 ? r < 0x1000000 ? r         & 0xff0000 : 0xff0000 : 0) |
684             (g >= 0 ? g < 0x1000000 ? (g >> 8)  & 0x00ff00 : 0x00ff00 : 0) |
685             (b >= 0 ? b < 0x1000000 ? (b >> 16) & 0x0000ff : 0x0000ff : 0));
686     }
687 }
688
689 fetchProc32 ACCESS(pixman_fetchProcForPicture32) (bits_image_t * pict)
690 {
691     switch(pict->format) {
692     case PIXMAN_a8r8g8b8: return fbFetch_a8r8g8b8;
693     case PIXMAN_x8r8g8b8: return fbFetch_x8r8g8b8;
694     case PIXMAN_a8b8g8r8: return fbFetch_a8b8g8r8;
695     case PIXMAN_x8b8g8r8: return fbFetch_x8b8g8r8;
696     /* These two require wide compositing */
697     case PIXMAN_a2b10g10r10: return NULL;
698     case PIXMAN_x2b10g10r10: return NULL;
699
700         /* 24bpp formats */
701     case PIXMAN_r8g8b8: return fbFetch_r8g8b8;
702     case PIXMAN_b8g8r8: return fbFetch_b8g8r8;
703
704         /* 16bpp formats */
705     case PIXMAN_r5g6b5: return fbFetch_r5g6b5;
706     case PIXMAN_b5g6r5: return fbFetch_b5g6r5;
707
708     case PIXMAN_a1r5g5b5: return fbFetch_a1r5g5b5;
709     case PIXMAN_x1r5g5b5: return fbFetch_x1r5g5b5;
710     case PIXMAN_a1b5g5r5: return fbFetch_a1b5g5r5;
711     case PIXMAN_x1b5g5r5: return fbFetch_x1b5g5r5;
712     case PIXMAN_a4r4g4b4: return fbFetch_a4r4g4b4;
713     case PIXMAN_x4r4g4b4: return fbFetch_x4r4g4b4;
714     case PIXMAN_a4b4g4r4: return fbFetch_a4b4g4r4;
715     case PIXMAN_x4b4g4r4: return fbFetch_x4b4g4r4;
716
717         /* 8bpp formats */
718     case PIXMAN_a8: return  fbFetch_a8;
719     case PIXMAN_r3g3b2: return fbFetch_r3g3b2;
720     case PIXMAN_b2g3r3: return fbFetch_b2g3r3;
721     case PIXMAN_a2r2g2b2: return fbFetch_a2r2g2b2;
722     case PIXMAN_a2b2g2r2: return fbFetch_a2b2g2r2;
723     case PIXMAN_c8: return  fbFetch_c8;
724     case PIXMAN_g8: return  fbFetch_c8;
725     case PIXMAN_x4a4: return fbFetch_x4a4;
726
727         /* 4bpp formats */
728     case PIXMAN_a4: return  fbFetch_a4;
729     case PIXMAN_r1g2b1: return fbFetch_r1g2b1;
730     case PIXMAN_b1g2r1: return fbFetch_b1g2r1;
731     case PIXMAN_a1r1g1b1: return fbFetch_a1r1g1b1;
732     case PIXMAN_a1b1g1r1: return fbFetch_a1b1g1r1;
733     case PIXMAN_c4: return  fbFetch_c4;
734     case PIXMAN_g4: return  fbFetch_c4;
735
736         /* 1bpp formats */
737     case PIXMAN_a1: return  fbFetch_a1;
738     case PIXMAN_g1: return  fbFetch_g1;
739
740         /* YUV formats */
741     case PIXMAN_yuy2: return fbFetch_yuy2;
742     case PIXMAN_yv12: return fbFetch_yv12;
743     }
744
745     return NULL;
746 }
747
748 static FASTCALL void
749 fbFetch64_generic (bits_image_t *pict, int x, int y, int width, uint64_t *buffer)
750 {
751     fetchProc32 fetch32 = ACCESS(pixman_fetchProcForPicture32) (pict);
752
753     // Fetch the pixels into the first half of buffer and then expand them in
754     // place.
755     fetch32(pict, x, y, width, (uint32_t*)buffer);
756     pixman_expand(buffer, (uint32_t*)buffer, pict->format, width);
757 }
758
759 fetchProc64 ACCESS(pixman_fetchProcForPicture64) (bits_image_t * pict)
760 {
761     switch(pict->format) {
762     case PIXMAN_a2b10g10r10: return fbFetch_a2b10g10r10;
763     case PIXMAN_x2b10g10r10: return fbFetch_x2b10g10r10;
764     default: return fbFetch64_generic;
765     }
766 }
767
768 /**************************** Pixel wise fetching *****************************/
769
770 static FASTCALL uint64_t
771 fbFetchPixel_a2b10g10r10 (bits_image_t *pict, int offset, int line)
772 {
773     uint32_t *bits = pict->bits + line*pict->rowstride;
774     uint32_t p = READ(pict, bits + offset);
775     uint64_t a = p >> 30;
776     uint64_t b = (p >> 20) & 0x3ff;
777     uint64_t g = (p >> 10) & 0x3ff;
778     uint64_t r = p & 0x3ff;
779
780     r = r << 6 | r >> 4;
781     g = g << 6 | g >> 4;
782     b = b << 6 | b >> 4;
783
784     a <<= 62;
785     a |= a >> 2;
786     a |= a >> 4;
787     a |= a >> 8;
788
789     return a << 48 | r << 32 | g << 16 | b;
790 }
791
792 static FASTCALL uint64_t
793 fbFetchPixel_x2b10g10r10 (bits_image_t *pict, int offset, int line)
794 {
795     uint32_t *bits = pict->bits + line*pict->rowstride;
796     uint32_t p = READ(pict, bits + offset);
797     uint64_t b = (p >> 20) & 0x3ff;
798     uint64_t g = (p >> 10) & 0x3ff;
799     uint64_t r = p & 0x3ff;
800
801     r = r << 6 | r >> 4;
802     g = g << 6 | g >> 4;
803     b = b << 6 | b >> 4;
804
805     return 0xffffULL << 48 | r << 32 | g << 16 | b;
806 }
807
808 static FASTCALL uint32_t
809 fbFetchPixel_a8r8g8b8 (bits_image_t *pict, int offset, int line)
810 {
811     uint32_t *bits = pict->bits + line*pict->rowstride;
812     return READ(pict, (uint32_t *)bits + offset);
813 }
814
815 static FASTCALL uint32_t
816 fbFetchPixel_x8r8g8b8 (bits_image_t *pict, int offset, int line)
817 {
818     uint32_t *bits = pict->bits + line*pict->rowstride;
819     return READ(pict, (uint32_t *)bits + offset) | 0xff000000;
820 }
821
822 static FASTCALL uint32_t
823 fbFetchPixel_a8b8g8r8 (bits_image_t *pict, int offset, int line)
824 {
825     uint32_t *bits = pict->bits + line*pict->rowstride;
826     uint32_t  pixel = READ(pict, (uint32_t *)bits + offset);
827
828     return ((pixel & 0xff000000) |
829             ((pixel >> 16) & 0xff) |
830             (pixel & 0x0000ff00) |
831             ((pixel & 0xff) << 16));
832 }
833
834 static FASTCALL uint32_t
835 fbFetchPixel_x8b8g8r8 (bits_image_t *pict, int offset, int line)
836 {
837     uint32_t *bits = pict->bits + line*pict->rowstride;
838     uint32_t  pixel = READ(pict, (uint32_t *)bits + offset);
839
840     return ((0xff000000) |
841             ((pixel >> 16) & 0xff) |
842             (pixel & 0x0000ff00) |
843             ((pixel & 0xff) << 16));
844 }
845
846 static FASTCALL uint32_t
847 fbFetchPixel_r8g8b8 (bits_image_t *pict, int offset, int line)
848 {
849     uint32_t *bits = pict->bits + line*pict->rowstride;
850     uint8_t   *pixel = ((uint8_t *) bits) + (offset*3);
851 #if IMAGE_BYTE_ORDER == MSBFirst
852     return (0xff000000 |
853             (READ(pict, pixel + 0) << 16) |
854             (READ(pict, pixel + 1) << 8) |
855             (READ(pict, pixel + 2)));
856 #else
857     return (0xff000000 |
858             (READ(pict, pixel + 2) << 16) |
859             (READ(pict, pixel + 1) << 8) |
860             (READ(pict, pixel + 0)));
861 #endif
862 }
863
864 static FASTCALL uint32_t
865 fbFetchPixel_b8g8r8 (bits_image_t *pict, int offset, int line)
866 {
867     uint32_t *bits = pict->bits + line*pict->rowstride;
868     uint8_t   *pixel = ((uint8_t *) bits) + (offset*3);
869 #if IMAGE_BYTE_ORDER == MSBFirst
870     return (0xff000000 |
871             (READ(pict, pixel + 2) << 16) |
872             (READ(pict, pixel + 1) << 8) |
873             (READ(pict, pixel + 0)));
874 #else
875     return (0xff000000 |
876             (READ(pict, pixel + 0) << 16) |
877             (READ(pict, pixel + 1) << 8) |
878             (READ(pict, pixel + 2)));
879 #endif
880 }
881
882 static FASTCALL uint32_t
883 fbFetchPixel_r5g6b5 (bits_image_t *pict, int offset, int line)
884 {
885     uint32_t  r,g,b;
886     uint32_t *bits = pict->bits + line*pict->rowstride;
887     uint32_t  pixel = READ(pict, (uint16_t *) bits + offset);
888
889     r = ((pixel & 0xf800) | ((pixel & 0xe000) >> 5)) << 8;
890     g = ((pixel & 0x07e0) | ((pixel & 0x0600) >> 6)) << 5;
891     b = ((pixel & 0x001c) | ((pixel & 0x001f) << 5)) >> 2;
892     return (0xff000000 | r | g | b);
893 }
894
895 static FASTCALL uint32_t
896 fbFetchPixel_b5g6r5 (bits_image_t *pict, int offset, int line)
897 {
898     uint32_t  r,g,b;
899     uint32_t *bits = pict->bits + line*pict->rowstride;
900     uint32_t  pixel = READ(pict, (uint16_t *) bits + offset);
901
902     b = ((pixel & 0xf800) | ((pixel & 0xe000) >> 5)) >> 8;
903     g = ((pixel & 0x07e0) | ((pixel & 0x0600) >> 6)) << 5;
904     r = ((pixel & 0x001c) | ((pixel & 0x001f) << 5)) << 14;
905     return (0xff000000 | r | g | b);
906 }
907
908 static FASTCALL uint32_t
909 fbFetchPixel_a1r5g5b5 (bits_image_t *pict, int offset, int line)
910 {
911     uint32_t  a,r,g,b;
912     uint32_t *bits = pict->bits + line*pict->rowstride;
913     uint32_t  pixel = READ(pict, (uint16_t *) bits + offset);
914
915     a = (uint32_t) ((uint8_t) (0 - ((pixel & 0x8000) >> 15))) << 24;
916     r = ((pixel & 0x7c00) | ((pixel & 0x7000) >> 5)) << 9;
917     g = ((pixel & 0x03e0) | ((pixel & 0x0380) >> 5)) << 6;
918     b = ((pixel & 0x001c) | ((pixel & 0x001f) << 5)) >> 2;
919     return (a | r | g | b);
920 }
921
922 static FASTCALL uint32_t
923 fbFetchPixel_x1r5g5b5 (bits_image_t *pict, int offset, int line)
924 {
925     uint32_t  r,g,b;
926     uint32_t *bits = pict->bits + line*pict->rowstride;
927     uint32_t  pixel = READ(pict, (uint16_t *) bits + offset);
928
929     r = ((pixel & 0x7c00) | ((pixel & 0x7000) >> 5)) << 9;
930     g = ((pixel & 0x03e0) | ((pixel & 0x0380) >> 5)) << 6;
931     b = ((pixel & 0x001c) | ((pixel & 0x001f) << 5)) >> 2;
932     return (0xff000000 | r | g | b);
933 }
934
935 static FASTCALL uint32_t
936 fbFetchPixel_a1b5g5r5 (bits_image_t *pict, int offset, int line)
937 {
938     uint32_t  a,r,g,b;
939     uint32_t *bits = pict->bits + line*pict->rowstride;
940     uint32_t  pixel = READ(pict, (uint16_t *) bits + offset);
941
942     a = (uint32_t) ((uint8_t) (0 - ((pixel & 0x8000) >> 15))) << 24;
943     b = ((pixel & 0x7c00) | ((pixel & 0x7000) >> 5)) >> 7;
944     g = ((pixel & 0x03e0) | ((pixel & 0x0380) >> 5)) << 6;
945     r = ((pixel & 0x001c) | ((pixel & 0x001f) << 5)) << 14;
946     return (a | r | g | b);
947 }
948
949 static FASTCALL uint32_t
950 fbFetchPixel_x1b5g5r5 (bits_image_t *pict, int offset, int line)
951 {
952     uint32_t  r,g,b;
953     uint32_t *bits = pict->bits + line*pict->rowstride;
954     uint32_t  pixel = READ(pict, (uint16_t *) bits + offset);
955
956     b = ((pixel & 0x7c00) | ((pixel & 0x7000) >> 5)) >> 7;
957     g = ((pixel & 0x03e0) | ((pixel & 0x0380) >> 5)) << 6;
958     r = ((pixel & 0x001c) | ((pixel & 0x001f) << 5)) << 14;
959     return (0xff000000 | r | g | b);
960 }
961
962 static FASTCALL uint32_t
963 fbFetchPixel_a4r4g4b4 (bits_image_t *pict, int offset, int line)
964 {
965     uint32_t  a,r,g,b;
966     uint32_t *bits = pict->bits + line*pict->rowstride;
967     uint32_t  pixel = READ(pict, (uint16_t *) bits + offset);
968
969     a = ((pixel & 0xf000) | ((pixel & 0xf000) >> 4)) << 16;
970     r = ((pixel & 0x0f00) | ((pixel & 0x0f00) >> 4)) << 12;
971     g = ((pixel & 0x00f0) | ((pixel & 0x00f0) >> 4)) << 8;
972     b = ((pixel & 0x000f) | ((pixel & 0x000f) << 4));
973     return (a | r | g | b);
974 }
975
976 static FASTCALL uint32_t
977 fbFetchPixel_x4r4g4b4 (bits_image_t *pict, int offset, int line)
978 {
979     uint32_t  r,g,b;
980     uint32_t *bits = pict->bits + line*pict->rowstride;
981     uint32_t  pixel = READ(pict, (uint16_t *) bits + offset);
982
983     r = ((pixel & 0x0f00) | ((pixel & 0x0f00) >> 4)) << 12;
984     g = ((pixel & 0x00f0) | ((pixel & 0x00f0) >> 4)) << 8;
985     b = ((pixel & 0x000f) | ((pixel & 0x000f) << 4));
986     return (0xff000000 | r | g | b);
987 }
988
989 static FASTCALL uint32_t
990 fbFetchPixel_a4b4g4r4 (bits_image_t *pict, int offset, int line)
991 {
992     uint32_t  a,r,g,b;
993     uint32_t *bits = pict->bits + line*pict->rowstride;
994     uint32_t  pixel = READ(pict, (uint16_t *) bits + offset);
995
996     a = ((pixel & 0xf000) | ((pixel & 0xf000) >> 4)) << 16;
997     b = ((pixel & 0x0f00) | ((pixel & 0x0f00) >> 4)) >> 4;
998     g = ((pixel & 0x00f0) | ((pixel & 0x00f0) >> 4)) << 8;
999     r = ((pixel & 0x000f) | ((pixel & 0x000f) << 4)) << 16;
1000     return (a | r | g | b);
1001 }
1002
1003 static FASTCALL uint32_t
1004 fbFetchPixel_x4b4g4r4 (bits_image_t *pict, int offset, int line)
1005 {
1006     uint32_t  r,g,b;
1007     uint32_t *bits = pict->bits + line*pict->rowstride;
1008     uint32_t  pixel = READ(pict, (uint16_t *) bits + offset);
1009
1010     b = ((pixel & 0x0f00) | ((pixel & 0x0f00) >> 4)) >> 4;
1011     g = ((pixel & 0x00f0) | ((pixel & 0x00f0) >> 4)) << 8;
1012     r = ((pixel & 0x000f) | ((pixel & 0x000f) << 4)) << 16;
1013     return (0xff000000 | r | g | b);
1014 }
1015
1016 static FASTCALL uint32_t
1017 fbFetchPixel_a8 (bits_image_t *pict, int offset, int line)
1018 {
1019     uint32_t *bits = pict->bits + line*pict->rowstride;
1020     uint32_t   pixel = READ(pict, (uint8_t *) bits + offset);
1021
1022     return pixel << 24;
1023 }
1024
1025 static FASTCALL uint32_t
1026 fbFetchPixel_r3g3b2 (bits_image_t *pict, int offset, int line)
1027 {
1028     uint32_t  r,g,b;
1029     uint32_t *bits = pict->bits + line*pict->rowstride;
1030     uint32_t   pixel = READ(pict, (uint8_t *) bits + offset);
1031
1032     r = ((pixel & 0xe0) | ((pixel & 0xe0) >> 3) | ((pixel & 0xc0) >> 6)) << 16;
1033     g = ((pixel & 0x1c) | ((pixel & 0x18) >> 3) | ((pixel & 0x1c) << 3)) << 8;
1034     b = (((pixel & 0x03)     ) |
1035          ((pixel & 0x03) << 2) |
1036          ((pixel & 0x03) << 4) |
1037          ((pixel & 0x03) << 6));
1038     return (0xff000000 | r | g | b);
1039 }
1040
1041 static FASTCALL uint32_t
1042 fbFetchPixel_b2g3r3 (bits_image_t *pict, int offset, int line)
1043 {
1044     uint32_t  r,g,b;
1045     uint32_t *bits = pict->bits + line*pict->rowstride;
1046     uint32_t   pixel = READ(pict, (uint8_t *) bits + offset);
1047
1048     b = (((pixel & 0xc0)     ) |
1049          ((pixel & 0xc0) >> 2) |
1050          ((pixel & 0xc0) >> 4) |
1051          ((pixel & 0xc0) >> 6));
1052     g = ((pixel & 0x38) | ((pixel & 0x38) >> 3) | ((pixel & 0x30) << 2)) << 8;
1053     r = (((pixel & 0x07)     ) |
1054          ((pixel & 0x07) << 3) |
1055          ((pixel & 0x06) << 6)) << 16;
1056     return (0xff000000 | r | g | b);
1057 }
1058
1059 static FASTCALL uint32_t
1060 fbFetchPixel_a2r2g2b2 (bits_image_t *pict, int offset, int line)
1061 {
1062     uint32_t   a,r,g,b;
1063     uint32_t *bits = pict->bits + line*pict->rowstride;
1064     uint32_t   pixel = READ(pict, (uint8_t *) bits + offset);
1065
1066     a = ((pixel & 0xc0) * 0x55) << 18;
1067     r = ((pixel & 0x30) * 0x55) << 12;
1068     g = ((pixel & 0x0c) * 0x55) << 6;
1069     b = ((pixel & 0x03) * 0x55);
1070     return a|r|g|b;
1071 }
1072
1073 static FASTCALL uint32_t
1074 fbFetchPixel_a2b2g2r2 (bits_image_t *pict, int offset, int line)
1075 {
1076     uint32_t   a,r,g,b;
1077     uint32_t *bits = pict->bits + line*pict->rowstride;
1078     uint32_t   pixel = READ(pict, (uint8_t *) bits + offset);
1079
1080     a = ((pixel & 0xc0) * 0x55) << 18;
1081     b = ((pixel & 0x30) * 0x55) >> 6;
1082     g = ((pixel & 0x0c) * 0x55) << 6;
1083     r = ((pixel & 0x03) * 0x55) << 16;
1084     return a|r|g|b;
1085 }
1086
1087 static FASTCALL uint32_t
1088 fbFetchPixel_c8 (bits_image_t *pict, int offset, int line)
1089 {
1090     uint32_t *bits = pict->bits + line*pict->rowstride;
1091     uint32_t   pixel = READ(pict, (uint8_t *) bits + offset);
1092     const pixman_indexed_t * indexed = pict->indexed;
1093     return indexed->rgba[pixel];
1094 }
1095
1096 static FASTCALL uint32_t
1097 fbFetchPixel_x4a4 (bits_image_t *pict, int offset, int line)
1098 {
1099     uint32_t *bits = pict->bits + line*pict->rowstride;
1100     uint32_t   pixel = READ(pict, (uint8_t *) bits + offset);
1101
1102     return ((pixel & 0xf) | ((pixel & 0xf) << 4)) << 24;
1103 }
1104
1105 static FASTCALL uint32_t
1106 fbFetchPixel_a4 (bits_image_t *pict, int offset, int line)
1107 {
1108     uint32_t *bits = pict->bits + line*pict->rowstride;
1109     uint32_t  pixel = Fetch4(pict, bits, offset);
1110
1111     pixel |= pixel << 4;
1112     return pixel << 24;
1113 }
1114
1115 static FASTCALL uint32_t
1116 fbFetchPixel_r1g2b1 (bits_image_t *pict, int offset, int line)
1117 {
1118     uint32_t  r,g,b;
1119     uint32_t *bits = pict->bits + line*pict->rowstride;
1120     uint32_t  pixel = Fetch4(pict, bits, offset);
1121
1122     r = ((pixel & 0x8) * 0xff) << 13;
1123     g = ((pixel & 0x6) * 0x55) << 7;
1124     b = ((pixel & 0x1) * 0xff);
1125     return 0xff000000|r|g|b;
1126 }
1127
1128 static FASTCALL uint32_t
1129 fbFetchPixel_b1g2r1 (bits_image_t *pict, int offset, int line)
1130 {
1131     uint32_t  r,g,b;
1132     uint32_t *bits = pict->bits + line*pict->rowstride;
1133     uint32_t  pixel = Fetch4(pict, bits, offset);
1134
1135     b = ((pixel & 0x8) * 0xff) >> 3;
1136     g = ((pixel & 0x6) * 0x55) << 7;
1137     r = ((pixel & 0x1) * 0xff) << 16;
1138     return 0xff000000|r|g|b;
1139 }
1140
1141 static FASTCALL uint32_t
1142 fbFetchPixel_a1r1g1b1 (bits_image_t *pict, int offset, int line)
1143 {
1144     uint32_t  a,r,g,b;
1145     uint32_t *bits = pict->bits + line*pict->rowstride;
1146     uint32_t  pixel = Fetch4(pict, bits, offset);
1147
1148     a = ((pixel & 0x8) * 0xff) << 21;
1149     r = ((pixel & 0x4) * 0xff) << 14;
1150     g = ((pixel & 0x2) * 0xff) << 7;
1151     b = ((pixel & 0x1) * 0xff);
1152     return a|r|g|b;
1153 }
1154
1155 static FASTCALL uint32_t
1156 fbFetchPixel_a1b1g1r1 (bits_image_t *pict, int offset, int line)
1157 {
1158     uint32_t  a,r,g,b;
1159     uint32_t *bits = pict->bits + line*pict->rowstride;
1160     uint32_t  pixel = Fetch4(pict, bits, offset);
1161
1162     a = ((pixel & 0x8) * 0xff) << 21;
1163     r = ((pixel & 0x4) * 0xff) >> 3;
1164     g = ((pixel & 0x2) * 0xff) << 7;
1165     b = ((pixel & 0x1) * 0xff) << 16;
1166     return a|r|g|b;
1167 }
1168
1169 static FASTCALL uint32_t
1170 fbFetchPixel_c4 (bits_image_t *pict, int offset, int line)
1171 {
1172     uint32_t *bits = pict->bits + line*pict->rowstride;
1173     uint32_t  pixel = Fetch4(pict, bits, offset);
1174     const pixman_indexed_t * indexed = pict->indexed;
1175
1176     return indexed->rgba[pixel];
1177 }
1178
1179
1180 static FASTCALL uint32_t
1181 fbFetchPixel_a1 (bits_image_t *pict, int offset, int line)
1182 {
1183     uint32_t *bits = pict->bits + line*pict->rowstride;
1184     uint32_t  pixel = READ(pict, bits + (offset >> 5));
1185     uint32_t  a;
1186 #if BITMAP_BIT_ORDER == MSBFirst
1187     a = pixel >> (0x1f - (offset & 0x1f));
1188 #else
1189     a = pixel >> (offset & 0x1f);
1190 #endif
1191     a = a & 1;
1192     a |= a << 1;
1193     a |= a << 2;
1194     a |= a << 4;
1195     return a << 24;
1196 }
1197
1198 static FASTCALL uint32_t
1199 fbFetchPixel_g1 (bits_image_t *pict, int offset, int line)
1200 {
1201     uint32_t *bits = pict->bits + line*pict->rowstride;
1202     uint32_t pixel = READ(pict, bits + (offset >> 5));
1203     const pixman_indexed_t * indexed = pict->indexed;
1204     uint32_t a;
1205 #if BITMAP_BIT_ORDER == MSBFirst
1206     a = pixel >> (0x1f - (offset & 0x1f));
1207 #else
1208     a = pixel >> (offset & 0x1f);
1209 #endif
1210     a = a & 1;
1211     return indexed->rgba[a];
1212 }
1213
1214 static FASTCALL uint32_t
1215 fbFetchPixel_yuy2 (bits_image_t *pict, int offset, int line)
1216 {
1217     int16_t y, u, v;
1218     int32_t r, g, b;
1219
1220     const uint32_t *bits = pict->bits + pict->rowstride * line;
1221
1222     y = ((uint8_t *) bits)[offset << 1] - 16;
1223     u = ((uint8_t *) bits)[((offset << 1) & -4) + 1] - 128;
1224     v = ((uint8_t *) bits)[((offset << 1) & -4) + 3] - 128;
1225
1226     /* R = 1.164(Y - 16) + 1.596(V - 128) */
1227     r = 0x012b27 * y + 0x019a2e * v;
1228     /* G = 1.164(Y - 16) - 0.813(V - 128) - 0.391(U - 128) */
1229     g = 0x012b27 * y - 0x00d0f2 * v - 0x00647e * u;
1230     /* B = 1.164(Y - 16) + 2.018(U - 128) */
1231     b = 0x012b27 * y + 0x0206a2 * u;
1232
1233     return 0xff000000 |
1234         (r >= 0 ? r < 0x1000000 ? r         & 0xff0000 : 0xff0000 : 0) |
1235         (g >= 0 ? g < 0x1000000 ? (g >> 8)  & 0x00ff00 : 0x00ff00 : 0) |
1236         (b >= 0 ? b < 0x1000000 ? (b >> 16) & 0x0000ff : 0x0000ff : 0);
1237 }
1238
1239 static FASTCALL uint32_t
1240 fbFetchPixel_yv12 (bits_image_t *pict, int offset, int line)
1241 {
1242     YV12_SETUP(pict);
1243     int16_t y = YV12_Y (line)[offset] - 16;
1244     int16_t u = YV12_U (line)[offset >> 1] - 128;
1245     int16_t v = YV12_V (line)[offset >> 1] - 128;
1246     int32_t r, g, b;
1247
1248     /* R = 1.164(Y - 16) + 1.596(V - 128) */
1249     r = 0x012b27 * y + 0x019a2e * v;
1250     /* G = 1.164(Y - 16) - 0.813(V - 128) - 0.391(U - 128) */
1251     g = 0x012b27 * y - 0x00d0f2 * v - 0x00647e * u;
1252     /* B = 1.164(Y - 16) + 2.018(U - 128) */
1253     b = 0x012b27 * y + 0x0206a2 * u;
1254
1255     return 0xff000000 |
1256         (r >= 0 ? r < 0x1000000 ? r         & 0xff0000 : 0xff0000 : 0) |
1257         (g >= 0 ? g < 0x1000000 ? (g >> 8)  & 0x00ff00 : 0x00ff00 : 0) |
1258         (b >= 0 ? b < 0x1000000 ? (b >> 16) & 0x0000ff : 0x0000ff : 0);
1259 }
1260
1261 /*
1262  * XXX: The transformed fetch path only works at 32-bpp so far.  When all paths
1263  * have wide versions, this can be removed.
1264  *
1265  * WARNING: This function loses precision!
1266  */
1267 static FASTCALL uint32_t
1268 fbFetchPixel32_generic_lossy (bits_image_t *pict, int offset, int line)
1269 {
1270     fetchPixelProc64 fetchPixel64 = ACCESS(pixman_fetchPixelProcForPicture64) (pict);
1271     const uint64_t argb16Pixel = fetchPixel64(pict, offset, line);
1272     uint32_t argb8Pixel;
1273
1274     pixman_contract(&argb8Pixel, &argb16Pixel, 1);
1275
1276     return argb8Pixel;
1277 }
1278
1279 fetchPixelProc32 ACCESS(pixman_fetchPixelProcForPicture32) (bits_image_t * pict)
1280 {
1281     switch(pict->format) {
1282     case PIXMAN_a8r8g8b8: return fbFetchPixel_a8r8g8b8;
1283     case PIXMAN_x8r8g8b8: return fbFetchPixel_x8r8g8b8;
1284     case PIXMAN_a8b8g8r8: return fbFetchPixel_a8b8g8r8;
1285     case PIXMAN_x8b8g8r8: return fbFetchPixel_x8b8g8r8;
1286     /* These two require wide compositing */
1287     case PIXMAN_a2b10g10r10: return fbFetchPixel32_generic_lossy;
1288     case PIXMAN_x2b10g10r10: return fbFetchPixel32_generic_lossy;
1289
1290         /* 24bpp formats */
1291     case PIXMAN_r8g8b8: return fbFetchPixel_r8g8b8;
1292     case PIXMAN_b8g8r8: return fbFetchPixel_b8g8r8;
1293
1294         /* 16bpp formats */
1295     case PIXMAN_r5g6b5: return fbFetchPixel_r5g6b5;
1296     case PIXMAN_b5g6r5: return fbFetchPixel_b5g6r5;
1297
1298     case PIXMAN_a1r5g5b5: return fbFetchPixel_a1r5g5b5;
1299     case PIXMAN_x1r5g5b5: return fbFetchPixel_x1r5g5b5;
1300     case PIXMAN_a1b5g5r5: return fbFetchPixel_a1b5g5r5;
1301     case PIXMAN_x1b5g5r5: return fbFetchPixel_x1b5g5r5;
1302     case PIXMAN_a4r4g4b4: return fbFetchPixel_a4r4g4b4;
1303     case PIXMAN_x4r4g4b4: return fbFetchPixel_x4r4g4b4;
1304     case PIXMAN_a4b4g4r4: return fbFetchPixel_a4b4g4r4;
1305     case PIXMAN_x4b4g4r4: return fbFetchPixel_x4b4g4r4;
1306
1307         /* 8bpp formats */
1308     case PIXMAN_a8: return  fbFetchPixel_a8;
1309     case PIXMAN_r3g3b2: return fbFetchPixel_r3g3b2;
1310     case PIXMAN_b2g3r3: return fbFetchPixel_b2g3r3;
1311     case PIXMAN_a2r2g2b2: return fbFetchPixel_a2r2g2b2;
1312     case PIXMAN_a2b2g2r2: return fbFetchPixel_a2b2g2r2;
1313     case PIXMAN_c8: return  fbFetchPixel_c8;
1314     case PIXMAN_g8: return  fbFetchPixel_c8;
1315     case PIXMAN_x4a4: return fbFetchPixel_x4a4;
1316
1317         /* 4bpp formats */
1318     case PIXMAN_a4: return  fbFetchPixel_a4;
1319     case PIXMAN_r1g2b1: return fbFetchPixel_r1g2b1;
1320     case PIXMAN_b1g2r1: return fbFetchPixel_b1g2r1;
1321     case PIXMAN_a1r1g1b1: return fbFetchPixel_a1r1g1b1;
1322     case PIXMAN_a1b1g1r1: return fbFetchPixel_a1b1g1r1;
1323     case PIXMAN_c4: return  fbFetchPixel_c4;
1324     case PIXMAN_g4: return  fbFetchPixel_c4;
1325
1326         /* 1bpp formats */
1327     case PIXMAN_a1: return  fbFetchPixel_a1;
1328     case PIXMAN_g1: return  fbFetchPixel_g1;
1329
1330         /* YUV formats */
1331     case PIXMAN_yuy2: return fbFetchPixel_yuy2;
1332     case PIXMAN_yv12: return fbFetchPixel_yv12;
1333     }
1334
1335     return NULL;
1336 }
1337
1338 static FASTCALL uint64_t
1339 fbFetchPixel64_generic (bits_image_t *pict, int offset, int line)
1340 {
1341     fetchPixelProc32 fetchPixel32 = ACCESS(pixman_fetchPixelProcForPicture32) (pict);
1342     uint32_t argb8Pixel = fetchPixel32(pict, offset, line);
1343     uint64_t argb16Pixel;
1344
1345     pixman_expand(&argb16Pixel, &argb8Pixel, pict->format, 1);
1346
1347     return argb16Pixel;
1348 }
1349
1350 fetchPixelProc64 ACCESS(pixman_fetchPixelProcForPicture64) (bits_image_t * pict)
1351 {
1352     switch(pict->format) {
1353     case PIXMAN_a2b10g10r10: return fbFetchPixel_a2b10g10r10;
1354     case PIXMAN_x2b10g10r10: return fbFetchPixel_x2b10g10r10;
1355     default: return fbFetchPixel64_generic;
1356     }
1357 }
1358
1359 /*********************************** Store ************************************/
1360
1361 #define Splita(v)       uint32_t        a = ((v) >> 24), r = ((v) >> 16) & 0xff, g = ((v) >> 8) & 0xff, b = (v) & 0xff
1362 #define Split(v)        uint32_t        r = ((v) >> 16) & 0xff, g = ((v) >> 8) & 0xff, b = (v) & 0xff
1363
1364 static FASTCALL void
1365 fbStore_a2b10g10r10 (pixman_image_t *image,
1366                      uint32_t *bits, const uint64_t *values, int x, int width, const pixman_indexed_t * indexed)
1367 {
1368     int i;
1369     uint32_t *pixel = bits + x;
1370     for (i = 0; i < width; ++i) {
1371         WRITE(image, pixel++,
1372             ((values[i] >> 32) & 0xc0000000) | // A
1373             ((values[i] >> 38) & 0x3ff) |      // R
1374             ((values[i] >> 12) & 0xffc00) |    // G
1375             ((values[i] << 14) & 0x3ff00000)); // B
1376     }
1377 }
1378
1379 static FASTCALL void
1380 fbStore_x2b10g10r10 (pixman_image_t *image,
1381                      uint32_t *bits, const uint64_t *values, int x, int width, const pixman_indexed_t * indexed)
1382 {
1383     int i;
1384     uint32_t *pixel = bits + x;
1385     for (i = 0; i < width; ++i) {
1386         WRITE(image, pixel++,
1387             ((values[i] >> 38) & 0x3ff) |      // R
1388             ((values[i] >> 12) & 0xffc00) |    // G
1389             ((values[i] << 14) & 0x3ff00000)); // B
1390     }
1391 }
1392
1393 static FASTCALL void
1394 fbStore_a8r8g8b8 (pixman_image_t *image,
1395                   uint32_t *bits, const uint32_t *values, int x, int width, const pixman_indexed_t * indexed)
1396 {
1397     MEMCPY_WRAPPED(image, ((uint32_t *)bits) + x, values, width*sizeof(uint32_t));
1398 }
1399
1400 static FASTCALL void
1401 fbStore_x8r8g8b8 (pixman_image_t *image,
1402                   uint32_t *bits, const uint32_t *values, int x, int width, const pixman_indexed_t * indexed)
1403 {
1404     int i;
1405     uint32_t *pixel = (uint32_t *)bits + x;
1406     for (i = 0; i < width; ++i)
1407         WRITE(image, pixel++, values[i] & 0xffffff);
1408 }
1409
1410 static FASTCALL void
1411 fbStore_a8b8g8r8 (pixman_image_t *image,
1412                   uint32_t *bits, const uint32_t *values, int x, int width, const pixman_indexed_t * indexed)
1413 {
1414     int i;
1415     uint32_t *pixel = (uint32_t *)bits + x;
1416     for (i = 0; i < width; ++i)
1417         WRITE(image, pixel++, (values[i] & 0xff00ff00) | ((values[i] >> 16) & 0xff) | ((values[i] & 0xff) << 16));
1418 }
1419
1420 static FASTCALL void
1421 fbStore_x8b8g8r8 (pixman_image_t *image,
1422                   uint32_t *bits, const uint32_t *values, int x, int width, const pixman_indexed_t * indexed)
1423 {
1424     int i;
1425     uint32_t *pixel = (uint32_t *)bits + x;
1426     for (i = 0; i < width; ++i)
1427         WRITE(image, pixel++, (values[i] & 0x0000ff00) | ((values[i] >> 16) & 0xff) | ((values[i] & 0xff) << 16));
1428 }
1429
1430 static FASTCALL void
1431 fbStore_r8g8b8 (pixman_image_t *image,
1432                 uint32_t *bits, const uint32_t *values, int x, int width,
1433                 const pixman_indexed_t * indexed)
1434 {
1435     int i;
1436     uint8_t *pixel = ((uint8_t *) bits) + 3*x;
1437     for (i = 0; i < width; ++i) {
1438         Store24(image, pixel, values[i]);
1439         pixel += 3;
1440     }
1441 }
1442
1443 static FASTCALL void
1444 fbStore_b8g8r8 (pixman_image_t *image,
1445                 uint32_t *bits, const uint32_t *values, int x, int width, const pixman_indexed_t * indexed)
1446 {
1447     int i;
1448     uint8_t *pixel = ((uint8_t *) bits) + 3*x;
1449     for (i = 0; i < width; ++i) {
1450         uint32_t val = values[i];
1451 #if IMAGE_BYTE_ORDER == MSBFirst
1452         WRITE(image, pixel++, Blue(val));
1453         WRITE(image, pixel++, Green(val));
1454         WRITE(image, pixel++, Red(val));
1455 #else
1456         WRITE(image, pixel++, Red(val));
1457         WRITE(image, pixel++, Green(val));
1458         WRITE(image, pixel++, Blue(val));
1459 #endif
1460     }
1461 }
1462
1463 static FASTCALL void
1464 fbStore_r5g6b5 (pixman_image_t *image,
1465                 uint32_t *bits, const uint32_t *values, int x, int width, const pixman_indexed_t * indexed)
1466 {
1467     int i;
1468     uint16_t *pixel = ((uint16_t *) bits) + x;
1469     for (i = 0; i < width; ++i) {
1470         uint32_t s = values[i];
1471         WRITE(image, pixel++, ((s >> 3) & 0x001f) |
1472               ((s >> 5) & 0x07e0) |
1473               ((s >> 8) & 0xf800));
1474     }
1475 }
1476
1477 static FASTCALL void
1478 fbStore_b5g6r5 (pixman_image_t *image,
1479                 uint32_t *bits, const uint32_t *values, int x, int width, const pixman_indexed_t * indexed)
1480 {
1481     int i;
1482     uint16_t  *pixel = ((uint16_t *) bits) + x;
1483     for (i = 0; i < width; ++i) {
1484         Split(values[i]);
1485         WRITE(image, pixel++, ((b << 8) & 0xf800) |
1486               ((g << 3) & 0x07e0) |
1487               ((r >> 3)         ));
1488     }
1489 }
1490
1491 static FASTCALL void
1492 fbStore_a1r5g5b5 (pixman_image_t *image,
1493                   uint32_t *bits, const uint32_t *values, int x, int width, const pixman_indexed_t * indexed)
1494 {
1495     int i;
1496     uint16_t  *pixel = ((uint16_t *) bits) + x;
1497     for (i = 0; i < width; ++i) {
1498         Splita(values[i]);
1499         WRITE(image, pixel++, ((a << 8) & 0x8000) |
1500               ((r << 7) & 0x7c00) |
1501               ((g << 2) & 0x03e0) |
1502               ((b >> 3)         ));
1503     }
1504 }
1505
1506 static FASTCALL void
1507 fbStore_x1r5g5b5 (pixman_image_t *image,
1508                   uint32_t *bits, const uint32_t *values, int x, int width, const pixman_indexed_t * indexed)
1509 {
1510     int i;
1511     uint16_t  *pixel = ((uint16_t *) bits) + x;
1512     for (i = 0; i < width; ++i) {
1513         Split(values[i]);
1514         WRITE(image, pixel++, ((r << 7) & 0x7c00) |
1515               ((g << 2) & 0x03e0) |
1516               ((b >> 3)         ));
1517     }
1518 }
1519
1520 static FASTCALL void
1521 fbStore_a1b5g5r5 (pixman_image_t *image,
1522                   uint32_t *bits, const uint32_t *values, int x, int width, const pixman_indexed_t * indexed)
1523 {
1524     int i;
1525     uint16_t  *pixel = ((uint16_t *) bits) + x;
1526     for (i = 0; i < width; ++i) {
1527         Splita(values[i]);
1528         WRITE(image, pixel++, ((a << 8) & 0x8000) |
1529               ((b << 7) & 0x7c00) |
1530               ((g << 2) & 0x03e0) |
1531               ((r >> 3)         ));
1532     }
1533 }
1534
1535 static FASTCALL void
1536 fbStore_x1b5g5r5 (pixman_image_t *image,
1537                   uint32_t *bits, const uint32_t *values, int x, int width, const pixman_indexed_t * indexed)
1538 {
1539     int i;
1540     uint16_t  *pixel = ((uint16_t *) bits) + x;
1541     for (i = 0; i < width; ++i) {
1542         Split(values[i]);
1543         WRITE(image, pixel++, ((b << 7) & 0x7c00) |
1544               ((g << 2) & 0x03e0) |
1545               ((r >> 3)         ));
1546     }
1547 }
1548
1549 static FASTCALL void
1550 fbStore_a4r4g4b4 (pixman_image_t *image,
1551                   uint32_t *bits, const uint32_t *values, int x, int width, const pixman_indexed_t * indexed)
1552 {
1553     int i;
1554     uint16_t  *pixel = ((uint16_t *) bits) + x;
1555     for (i = 0; i < width; ++i) {
1556         Splita(values[i]);
1557         WRITE(image, pixel++, ((a << 8) & 0xf000) |
1558               ((r << 4) & 0x0f00) |
1559               ((g     ) & 0x00f0) |
1560               ((b >> 4)         ));
1561     }
1562 }
1563
1564 static FASTCALL void
1565 fbStore_x4r4g4b4 (pixman_image_t *image,
1566                   uint32_t *bits, const uint32_t *values, int x, int width, const pixman_indexed_t * indexed)
1567 {
1568     int i;
1569     uint16_t  *pixel = ((uint16_t *) bits) + x;
1570     for (i = 0; i < width; ++i) {
1571         Split(values[i]);
1572         WRITE(image, pixel++, ((r << 4) & 0x0f00) |
1573               ((g     ) & 0x00f0) |
1574               ((b >> 4)         ));
1575     }
1576 }
1577
1578 static FASTCALL void
1579 fbStore_a4b4g4r4 (pixman_image_t *image,
1580                   uint32_t *bits, const uint32_t *values, int x, int width, const pixman_indexed_t * indexed)
1581 {
1582     int i;
1583     uint16_t  *pixel = ((uint16_t *) bits) + x;
1584     for (i = 0; i < width; ++i) {
1585         Splita(values[i]);
1586         WRITE(image, pixel++, ((a << 8) & 0xf000) |
1587               ((b << 4) & 0x0f00) |
1588               ((g     ) & 0x00f0) |
1589               ((r >> 4)         ));
1590     }
1591 }
1592
1593 static FASTCALL void
1594 fbStore_x4b4g4r4 (pixman_image_t *image,
1595                   uint32_t *bits, const uint32_t *values, int x, int width, const pixman_indexed_t * indexed)
1596 {
1597     int i;
1598     uint16_t  *pixel = ((uint16_t *) bits) + x;
1599     for (i = 0; i < width; ++i) {
1600         Split(values[i]);
1601         WRITE(image, pixel++, ((b << 4) & 0x0f00) |
1602               ((g     ) & 0x00f0) |
1603               ((r >> 4)         ));
1604     }
1605 }
1606
1607 static FASTCALL void
1608 fbStore_a8 (pixman_image_t *image,
1609             uint32_t *bits, const uint32_t *values, int x, int width, const pixman_indexed_t * indexed)
1610 {
1611     int i;
1612     uint8_t   *pixel = ((uint8_t *) bits) + x;
1613     for (i = 0; i < width; ++i) {
1614         WRITE(image, pixel++, values[i] >> 24);
1615     }
1616 }
1617
1618 static FASTCALL void
1619 fbStore_r3g3b2 (pixman_image_t *image,
1620                 uint32_t *bits, const uint32_t *values, int x, int width, const pixman_indexed_t * indexed)
1621 {
1622     int i;
1623     uint8_t   *pixel = ((uint8_t *) bits) + x;
1624     for (i = 0; i < width; ++i) {
1625         Split(values[i]);
1626         WRITE(image, pixel++,
1627               ((r     ) & 0xe0) |
1628               ((g >> 3) & 0x1c) |
1629               ((b >> 6)       ));
1630     }
1631 }
1632
1633 static FASTCALL void
1634 fbStore_b2g3r3 (pixman_image_t *image,
1635                 uint32_t *bits, const uint32_t *values, int x, int width, const pixman_indexed_t * indexed)
1636 {
1637     int i;
1638     uint8_t   *pixel = ((uint8_t *) bits) + x;
1639     for (i = 0; i < width; ++i) {
1640         Split(values[i]);
1641         WRITE(image, pixel++,
1642               ((b     ) & 0xc0) |
1643               ((g >> 2) & 0x38) |
1644               ((r >> 5)       ));
1645     }
1646 }
1647
1648 static FASTCALL void
1649 fbStore_a2r2g2b2 (pixman_image_t *image,
1650                   uint32_t *bits, const uint32_t *values, int x, int width, const pixman_indexed_t * indexed)
1651 {
1652     int i;
1653     uint8_t   *pixel = ((uint8_t *) bits) + x;
1654     for (i = 0; i < width; ++i) {
1655         Splita(values[i]);
1656         WRITE(image, pixel++, ((a     ) & 0xc0) |
1657               ((r >> 2) & 0x30) |
1658               ((g >> 4) & 0x0c) |
1659               ((b >> 6)       ));
1660     }
1661 }
1662
1663 static FASTCALL void
1664 fbStore_c8 (pixman_image_t *image,
1665             uint32_t *bits, const uint32_t *values, int x, int width, const pixman_indexed_t * indexed)
1666 {
1667     int i;
1668     uint8_t   *pixel = ((uint8_t *) bits) + x;
1669     for (i = 0; i < width; ++i) {
1670         WRITE(image, pixel++, miIndexToEnt24(indexed,values[i]));
1671     }
1672 }
1673
1674 static FASTCALL void
1675 fbStore_x4a4 (pixman_image_t *image,
1676               uint32_t *bits, const uint32_t *values, int x, int width, const pixman_indexed_t * indexed)
1677 {
1678     int i;
1679     uint8_t   *pixel = ((uint8_t *) bits) + x;
1680     for (i = 0; i < width; ++i) {
1681         WRITE(image, pixel++, values[i] >> 28);
1682     }
1683 }
1684
1685 #define Store8(img,l,o,v)  (WRITE(img, (uint8_t *)(l) + ((o) >> 3), (v)))
1686 #if IMAGE_BYTE_ORDER == MSBFirst
1687 #define Store4(img,l,o,v)  Store8(img,l,o,((o) & 4 ?                            \
1688                                    (Fetch8(img,l,o) & 0xf0) | (v) :             \
1689                                    (Fetch8(img,l,o) & 0x0f) | ((v) << 4)))
1690 #else
1691 #define Store4(img,l,o,v)  Store8(img,l,o,((o) & 4 ?                           \
1692                                    (Fetch8(img,l,o) & 0x0f) | ((v) << 4) : \
1693                                    (Fetch8(img,l,o) & 0xf0) | (v)))
1694 #endif
1695
1696 static FASTCALL void
1697 fbStore_a4 (pixman_image_t *image,
1698             uint32_t *bits, const uint32_t *values, int x, int width, const pixman_indexed_t * indexed)
1699 {
1700     int i;
1701     for (i = 0; i < width; ++i) {
1702         Store4(image, bits, i + x, values[i]>>28);
1703     }
1704 }
1705
1706 static FASTCALL void
1707 fbStore_r1g2b1 (pixman_image_t *image,
1708                 uint32_t *bits, const uint32_t *values, int x, int width, const pixman_indexed_t * indexed)
1709 {
1710     int i;
1711     for (i = 0; i < width; ++i) {
1712         uint32_t  pixel;
1713
1714         Split(values[i]);
1715         pixel = (((r >> 4) & 0x8) |
1716                  ((g >> 5) & 0x6) |
1717                  ((b >> 7)      ));
1718         Store4(image, bits, i + x, pixel);
1719     }
1720 }
1721
1722 static FASTCALL void
1723 fbStore_b1g2r1 (pixman_image_t *image,
1724                 uint32_t *bits, const uint32_t *values, int x, int width, const pixman_indexed_t * indexed)
1725 {
1726     int i;
1727     for (i = 0; i < width; ++i) {
1728         uint32_t  pixel;
1729
1730         Split(values[i]);
1731         pixel = (((b >> 4) & 0x8) |
1732                  ((g >> 5) & 0x6) |
1733                  ((r >> 7)      ));
1734         Store4(image, bits, i + x, pixel);
1735     }
1736 }
1737
1738 static FASTCALL void
1739 fbStore_a1r1g1b1 (pixman_image_t *image,
1740                   uint32_t *bits, const uint32_t *values, int x, int width, const pixman_indexed_t * indexed)
1741 {
1742     int i;
1743     for (i = 0; i < width; ++i) {
1744         uint32_t  pixel;
1745         Splita(values[i]);
1746         pixel = (((a >> 4) & 0x8) |
1747                  ((r >> 5) & 0x4) |
1748                  ((g >> 6) & 0x2) |
1749                  ((b >> 7)      ));
1750         Store4(image, bits, i + x, pixel);
1751     }
1752 }
1753
1754 static FASTCALL void
1755 fbStore_a1b1g1r1 (pixman_image_t *image,
1756                   uint32_t *bits, const uint32_t *values, int x, int width, const pixman_indexed_t * indexed)
1757 {
1758     int i;
1759     for (i = 0; i < width; ++i) {
1760         uint32_t  pixel;
1761         Splita(values[i]);
1762         pixel = (((a >> 4) & 0x8) |
1763                  ((b >> 5) & 0x4) |
1764                  ((g >> 6) & 0x2) |
1765                  ((r >> 7)      ));
1766         Store4(image, bits, i + x, pixel);
1767     }
1768 }
1769
1770 static FASTCALL void
1771 fbStore_c4 (pixman_image_t *image,
1772             uint32_t *bits, const uint32_t *values, int x, int width, const pixman_indexed_t * indexed)
1773 {
1774     int i;
1775     for (i = 0; i < width; ++i) {
1776         uint32_t  pixel;
1777
1778         pixel = miIndexToEnt24(indexed, values[i]);
1779         Store4(image, bits, i + x, pixel);
1780     }
1781 }
1782
1783 static FASTCALL void
1784 fbStore_a1 (pixman_image_t *image,
1785             uint32_t *bits, const uint32_t *values, int x, int width, const pixman_indexed_t * indexed)
1786 {
1787     int i;
1788     for (i = 0; i < width; ++i) {
1789         uint32_t  *pixel = ((uint32_t *) bits) + ((i+x) >> 5);
1790         uint32_t  mask = FbStipMask((i+x) & 0x1f, 1);
1791
1792         uint32_t v = values[i] & 0x80000000 ? mask : 0;
1793         WRITE(image, pixel, (READ(image, pixel) & ~mask) | v);
1794     }
1795 }
1796
1797 static FASTCALL void
1798 fbStore_g1 (pixman_image_t *image,
1799             uint32_t *bits, const uint32_t *values, int x, int width, const pixman_indexed_t * indexed)
1800 {
1801     int i;
1802     for (i = 0; i < width; ++i) {
1803         uint32_t  *pixel = ((uint32_t *) bits) + ((i+x) >> 5);
1804         uint32_t  mask = FbStipMask((i+x) & 0x1f, 1);
1805
1806         uint32_t v = miIndexToEntY24(indexed,values[i]) ? mask : 0;
1807         WRITE(image, pixel, (READ(image, pixel) & ~mask) | v);
1808     }
1809 }
1810
1811
1812 storeProc32 ACCESS(pixman_storeProcForPicture32) (bits_image_t * pict)
1813 {
1814     switch(pict->format) {
1815     case PIXMAN_a8r8g8b8: return fbStore_a8r8g8b8;
1816     case PIXMAN_x8r8g8b8: return fbStore_x8r8g8b8;
1817     case PIXMAN_a8b8g8r8: return fbStore_a8b8g8r8;
1818     case PIXMAN_x8b8g8r8: return fbStore_x8b8g8r8;
1819
1820         /* 24bpp formats */
1821     case PIXMAN_r8g8b8: return fbStore_r8g8b8;
1822     case PIXMAN_b8g8r8: return fbStore_b8g8r8;
1823
1824         /* 16bpp formats */
1825     case PIXMAN_r5g6b5: return fbStore_r5g6b5;
1826     case PIXMAN_b5g6r5: return fbStore_b5g6r5;
1827
1828     case PIXMAN_a1r5g5b5: return fbStore_a1r5g5b5;
1829     case PIXMAN_x1r5g5b5: return fbStore_x1r5g5b5;
1830     case PIXMAN_a1b5g5r5: return fbStore_a1b5g5r5;
1831     case PIXMAN_x1b5g5r5: return fbStore_x1b5g5r5;
1832     case PIXMAN_a4r4g4b4: return fbStore_a4r4g4b4;
1833     case PIXMAN_x4r4g4b4: return fbStore_x4r4g4b4;
1834     case PIXMAN_a4b4g4r4: return fbStore_a4b4g4r4;
1835     case PIXMAN_x4b4g4r4: return fbStore_x4b4g4r4;
1836
1837         /* 8bpp formats */
1838     case PIXMAN_a8: return  fbStore_a8;
1839     case PIXMAN_r3g3b2: return fbStore_r3g3b2;
1840     case PIXMAN_b2g3r3: return fbStore_b2g3r3;
1841     case PIXMAN_a2r2g2b2: return fbStore_a2r2g2b2;
1842     case PIXMAN_c8: return  fbStore_c8;
1843     case PIXMAN_g8: return  fbStore_c8;
1844     case PIXMAN_x4a4: return fbStore_x4a4;
1845
1846         /* 4bpp formats */
1847     case PIXMAN_a4: return  fbStore_a4;
1848     case PIXMAN_r1g2b1: return fbStore_r1g2b1;
1849     case PIXMAN_b1g2r1: return fbStore_b1g2r1;
1850     case PIXMAN_a1r1g1b1: return fbStore_a1r1g1b1;
1851     case PIXMAN_a1b1g1r1: return fbStore_a1b1g1r1;
1852     case PIXMAN_c4: return  fbStore_c4;
1853     case PIXMAN_g4: return  fbStore_c4;
1854
1855         /* 1bpp formats */
1856     case PIXMAN_a1: return  fbStore_a1;
1857     case PIXMAN_g1: return  fbStore_g1;
1858     default:
1859         return NULL;
1860     }
1861 }
1862
1863 /*
1864  * Contracts a 64bpp image to 32bpp and then stores it using a regular 32-bit
1865  * store proc.
1866  */
1867 static FASTCALL void
1868 fbStore64_generic (pixman_image_t *image,
1869                    uint32_t *bits, const uint64_t *values, int x, int width, const pixman_indexed_t * indexed)
1870 {
1871     bits_image_t *pict = (bits_image_t*)image;
1872     storeProc32 store32 = ACCESS(pixman_storeProcForPicture32) (pict);
1873     uint32_t *argb8Pixels;
1874
1875     assert(image->common.type == BITS);
1876     assert(store32);
1877
1878     argb8Pixels = pixman_malloc_ab (width, sizeof(uint32_t));
1879     if (!argb8Pixels) return;
1880
1881     // Contract the scanline.  We could do this in place if values weren't
1882     // const.
1883     pixman_contract(argb8Pixels, values, width);
1884     store32(image, bits, argb8Pixels, x, width, indexed);
1885
1886     free(argb8Pixels);
1887 }
1888
1889 storeProc64 ACCESS(pixman_storeProcForPicture64) (bits_image_t * pict)
1890 {
1891     switch(pict->format) {
1892     case PIXMAN_a2b10g10r10: return fbStore_a2b10g10r10;
1893     case PIXMAN_x2b10g10r10: return fbStore_x2b10g10r10;
1894     default: return fbStore64_generic;
1895     }
1896 }
1897
1898 #ifndef PIXMAN_FB_ACCESSORS
1899 /*
1900  * Helper routine to expand a color component from 0 < n <= 8 bits to 16 bits by
1901  * replication.
1902  */
1903 static inline uint64_t expand16(const uint8_t val, int nbits)
1904 {
1905     // Start out with the high bit of val in the high bit of result.
1906     uint16_t result = (uint16_t)val << (16 - nbits);
1907
1908     if (nbits == 0)
1909         return 0;
1910
1911     // Copy the bits in result, doubling the number of bits each time, until we
1912     // fill all 16 bits.
1913     while (nbits < 16) {
1914         result |= result >> nbits;
1915         nbits *= 2;
1916     }
1917
1918     return result;
1919 }
1920
1921 /*
1922  * This function expands images from ARGB8 format to ARGB16.  To preserve
1923  * precision, it needs to know the original source format.  For example, if the
1924  * source was PIXMAN_x1r5g5b5 and the red component contained bits 12345, then
1925  * the expanded value is 12345123.  To correctly expand this to 16 bits, it
1926  * should be 1234512345123451 and not 1234512312345123.
1927  */
1928 void pixman_expand(uint64_t *dst, const uint32_t *src,
1929                    pixman_format_code_t format, int width)
1930 {
1931     /*
1932      * Determine the sizes of each component and the masks and shifts required
1933      * to extract them from the source pixel.
1934      */
1935     const int a_size = PIXMAN_FORMAT_A(format),
1936               r_size = PIXMAN_FORMAT_R(format),
1937               g_size = PIXMAN_FORMAT_G(format),
1938               b_size = PIXMAN_FORMAT_B(format);
1939     const int a_shift = 32 - a_size,
1940               r_shift = 24 - r_size,
1941               g_shift = 16 - g_size,
1942               b_shift =  8 - b_size;
1943     const uint8_t a_mask = ~(~0 << a_size),
1944                   r_mask = ~(~0 << r_size),
1945                   g_mask = ~(~0 << g_size),
1946                   b_mask = ~(~0 << b_size);
1947     int i;
1948
1949     /* Start at the end so that we can do the expansion in place when src == dst */
1950     for (i = width - 1; i >= 0; i--)
1951     {
1952         const uint32_t pixel = src[i];
1953         // Extract the components.
1954         const uint8_t a = (pixel >> a_shift) & a_mask,
1955                       r = (pixel >> r_shift) & r_mask,
1956                       g = (pixel >> g_shift) & g_mask,
1957                       b = (pixel >> b_shift) & b_mask;
1958         const uint64_t a16 = a_size ? expand16(a, a_size) : 0xffff,
1959                        r16 = expand16(r, r_size),
1960                        g16 = expand16(g, g_size),
1961                        b16 = expand16(b, b_size);
1962
1963         dst[i] = a16 << 48 | r16 << 32 | g16 << 16 | b16;
1964     }
1965 }
1966
1967 /*
1968  * Contracting is easier than expanding.  We just need to truncate the
1969  * components.
1970  */
1971 void pixman_contract(uint32_t *dst, const uint64_t *src, int width)
1972 {
1973     int i;
1974
1975     /* Start at the beginning so that we can do the contraction in place when
1976      * src == dst */
1977     for (i = 0; i < width; i++)
1978     {
1979         const uint8_t a = src[i] >> 56,
1980                       r = src[i] >> 40,
1981                       g = src[i] >> 24,
1982                       b = src[i] >> 8;
1983         dst[i] = a << 24 | r << 16 | g << 8 | b;
1984     }
1985 }
1986 #endif // PIXMAN_FB_ACCESSORS