Make expansion and contraction loops clearer.
[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 n 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 fetchPixelProc32 ACCESS(pixman_fetchPixelProcForPicture32) (bits_image_t * pict)
1262 {
1263     switch(pict->format) {
1264     case PIXMAN_a8r8g8b8: return fbFetchPixel_a8r8g8b8;
1265     case PIXMAN_x8r8g8b8: return fbFetchPixel_x8r8g8b8;
1266     case PIXMAN_a8b8g8r8: return fbFetchPixel_a8b8g8r8;
1267     case PIXMAN_x8b8g8r8: return fbFetchPixel_x8b8g8r8;
1268     /* These two require wide compositing */
1269     case PIXMAN_a2b10g10r10: return NULL;
1270     case PIXMAN_x2b10g10r10: return NULL;
1271
1272         /* 24bpp formats */
1273     case PIXMAN_r8g8b8: return fbFetchPixel_r8g8b8;
1274     case PIXMAN_b8g8r8: return fbFetchPixel_b8g8r8;
1275
1276         /* 16bpp formats */
1277     case PIXMAN_r5g6b5: return fbFetchPixel_r5g6b5;
1278     case PIXMAN_b5g6r5: return fbFetchPixel_b5g6r5;
1279
1280     case PIXMAN_a1r5g5b5: return fbFetchPixel_a1r5g5b5;
1281     case PIXMAN_x1r5g5b5: return fbFetchPixel_x1r5g5b5;
1282     case PIXMAN_a1b5g5r5: return fbFetchPixel_a1b5g5r5;
1283     case PIXMAN_x1b5g5r5: return fbFetchPixel_x1b5g5r5;
1284     case PIXMAN_a4r4g4b4: return fbFetchPixel_a4r4g4b4;
1285     case PIXMAN_x4r4g4b4: return fbFetchPixel_x4r4g4b4;
1286     case PIXMAN_a4b4g4r4: return fbFetchPixel_a4b4g4r4;
1287     case PIXMAN_x4b4g4r4: return fbFetchPixel_x4b4g4r4;
1288
1289         /* 8bpp formats */
1290     case PIXMAN_a8: return  fbFetchPixel_a8;
1291     case PIXMAN_r3g3b2: return fbFetchPixel_r3g3b2;
1292     case PIXMAN_b2g3r3: return fbFetchPixel_b2g3r3;
1293     case PIXMAN_a2r2g2b2: return fbFetchPixel_a2r2g2b2;
1294     case PIXMAN_a2b2g2r2: return fbFetchPixel_a2b2g2r2;
1295     case PIXMAN_c8: return  fbFetchPixel_c8;
1296     case PIXMAN_g8: return  fbFetchPixel_c8;
1297     case PIXMAN_x4a4: return fbFetchPixel_x4a4;
1298
1299         /* 4bpp formats */
1300     case PIXMAN_a4: return  fbFetchPixel_a4;
1301     case PIXMAN_r1g2b1: return fbFetchPixel_r1g2b1;
1302     case PIXMAN_b1g2r1: return fbFetchPixel_b1g2r1;
1303     case PIXMAN_a1r1g1b1: return fbFetchPixel_a1r1g1b1;
1304     case PIXMAN_a1b1g1r1: return fbFetchPixel_a1b1g1r1;
1305     case PIXMAN_c4: return  fbFetchPixel_c4;
1306     case PIXMAN_g4: return  fbFetchPixel_c4;
1307
1308         /* 1bpp formats */
1309     case PIXMAN_a1: return  fbFetchPixel_a1;
1310     case PIXMAN_g1: return  fbFetchPixel_g1;
1311
1312         /* YUV formats */
1313     case PIXMAN_yuy2: return fbFetchPixel_yuy2;
1314     case PIXMAN_yv12: return fbFetchPixel_yv12;
1315     }
1316
1317     return NULL;
1318 }
1319
1320 static FASTCALL uint64_t
1321 fbFetchPixel64_generic (bits_image_t *pict, int offset, int line)
1322 {
1323     fetchPixelProc32 fetchPixel32 = ACCESS(pixman_fetchPixelProcForPicture32) (pict);
1324     uint32_t argb8Pixel = fetchPixel32(pict, offset, line);
1325     uint64_t argb16Pixel;
1326
1327     pixman_expand(&argb16Pixel, &argb8Pixel, pict->format, 1);
1328
1329     return argb16Pixel;
1330 }
1331
1332 fetchPixelProc64 ACCESS(pixman_fetchPixelProcForPicture64) (bits_image_t * pict)
1333 {
1334     switch(pict->format) {
1335     case PIXMAN_a2b10g10r10: return fbFetchPixel_a2b10g10r10;
1336     case PIXMAN_x2b10g10r10: return fbFetchPixel_x2b10g10r10;
1337     default: return fbFetchPixel64_generic;
1338     }
1339 }
1340
1341 /*********************************** Store ************************************/
1342
1343 #define Splita(v)       uint32_t        a = ((v) >> 24), r = ((v) >> 16) & 0xff, g = ((v) >> 8) & 0xff, b = (v) & 0xff
1344 #define Split(v)        uint32_t        r = ((v) >> 16) & 0xff, g = ((v) >> 8) & 0xff, b = (v) & 0xff
1345
1346 static FASTCALL void
1347 fbStore_a2b10g10r10 (pixman_image_t *image,
1348                      uint32_t *bits, const uint64_t *values, int x, int width, const pixman_indexed_t * indexed)
1349 {
1350     int i;
1351     uint32_t *pixel = bits + x;
1352     for (i = 0; i < width; ++i) {
1353         WRITE(image, pixel++,
1354             ((values[i] >> 32) & 0xc0000000) | // A
1355             ((values[i] >> 38) & 0x3ff) |      // R
1356             ((values[i] >> 12) & 0xffc00) |    // G
1357             ((values[i] << 14) & 0x3ff00000)); // B
1358     }
1359 }
1360
1361 static FASTCALL void
1362 fbStore_x2b10g10r10 (pixman_image_t *image,
1363                      uint32_t *bits, const uint64_t *values, int x, int width, const pixman_indexed_t * indexed)
1364 {
1365     int i;
1366     uint32_t *pixel = bits + x;
1367     for (i = 0; i < width; ++i) {
1368         WRITE(image, pixel++,
1369             ((values[i] >> 38) & 0x3ff) |      // R
1370             ((values[i] >> 12) & 0xffc00) |    // G
1371             ((values[i] << 14) & 0x3ff00000)); // B
1372     }
1373 }
1374
1375 static FASTCALL void
1376 fbStore_a8r8g8b8 (pixman_image_t *image,
1377                   uint32_t *bits, const uint32_t *values, int x, int width, const pixman_indexed_t * indexed)
1378 {
1379     MEMCPY_WRAPPED(image, ((uint32_t *)bits) + x, values, width*sizeof(uint32_t));
1380 }
1381
1382 static FASTCALL void
1383 fbStore_x8r8g8b8 (pixman_image_t *image,
1384                   uint32_t *bits, const uint32_t *values, int x, int width, const pixman_indexed_t * indexed)
1385 {
1386     int i;
1387     uint32_t *pixel = (uint32_t *)bits + x;
1388     for (i = 0; i < width; ++i)
1389         WRITE(image, pixel++, values[i] & 0xffffff);
1390 }
1391
1392 static FASTCALL void
1393 fbStore_a8b8g8r8 (pixman_image_t *image,
1394                   uint32_t *bits, const uint32_t *values, int x, int width, const pixman_indexed_t * indexed)
1395 {
1396     int i;
1397     uint32_t *pixel = (uint32_t *)bits + x;
1398     for (i = 0; i < width; ++i)
1399         WRITE(image, pixel++, (values[i] & 0xff00ff00) | ((values[i] >> 16) & 0xff) | ((values[i] & 0xff) << 16));
1400 }
1401
1402 static FASTCALL void
1403 fbStore_x8b8g8r8 (pixman_image_t *image,
1404                   uint32_t *bits, const uint32_t *values, int x, int width, const pixman_indexed_t * indexed)
1405 {
1406     int i;
1407     uint32_t *pixel = (uint32_t *)bits + x;
1408     for (i = 0; i < width; ++i)
1409         WRITE(image, pixel++, (values[i] & 0x0000ff00) | ((values[i] >> 16) & 0xff) | ((values[i] & 0xff) << 16));
1410 }
1411
1412 static FASTCALL void
1413 fbStore_r8g8b8 (pixman_image_t *image,
1414                 uint32_t *bits, const uint32_t *values, int x, int width,
1415                 const pixman_indexed_t * indexed)
1416 {
1417     int i;
1418     uint8_t *pixel = ((uint8_t *) bits) + 3*x;
1419     for (i = 0; i < width; ++i) {
1420         Store24(image, pixel, values[i]);
1421         pixel += 3;
1422     }
1423 }
1424
1425 static FASTCALL void
1426 fbStore_b8g8r8 (pixman_image_t *image,
1427                 uint32_t *bits, const uint32_t *values, int x, int width, const pixman_indexed_t * indexed)
1428 {
1429     int i;
1430     uint8_t *pixel = ((uint8_t *) bits) + 3*x;
1431     for (i = 0; i < width; ++i) {
1432         uint32_t val = values[i];
1433 #if IMAGE_BYTE_ORDER == MSBFirst
1434         WRITE(image, pixel++, Blue(val));
1435         WRITE(image, pixel++, Green(val));
1436         WRITE(image, pixel++, Red(val));
1437 #else
1438         WRITE(image, pixel++, Red(val));
1439         WRITE(image, pixel++, Green(val));
1440         WRITE(image, pixel++, Blue(val));
1441 #endif
1442     }
1443 }
1444
1445 static FASTCALL void
1446 fbStore_r5g6b5 (pixman_image_t *image,
1447                 uint32_t *bits, const uint32_t *values, int x, int width, const pixman_indexed_t * indexed)
1448 {
1449     int i;
1450     uint16_t *pixel = ((uint16_t *) bits) + x;
1451     for (i = 0; i < width; ++i) {
1452         uint32_t s = values[i];
1453         WRITE(image, pixel++, ((s >> 3) & 0x001f) |
1454               ((s >> 5) & 0x07e0) |
1455               ((s >> 8) & 0xf800));
1456     }
1457 }
1458
1459 static FASTCALL void
1460 fbStore_b5g6r5 (pixman_image_t *image,
1461                 uint32_t *bits, const uint32_t *values, int x, int width, const pixman_indexed_t * indexed)
1462 {
1463     int i;
1464     uint16_t  *pixel = ((uint16_t *) bits) + x;
1465     for (i = 0; i < width; ++i) {
1466         Split(values[i]);
1467         WRITE(image, pixel++, ((b << 8) & 0xf800) |
1468               ((g << 3) & 0x07e0) |
1469               ((r >> 3)         ));
1470     }
1471 }
1472
1473 static FASTCALL void
1474 fbStore_a1r5g5b5 (pixman_image_t *image,
1475                   uint32_t *bits, const uint32_t *values, int x, int width, const pixman_indexed_t * indexed)
1476 {
1477     int i;
1478     uint16_t  *pixel = ((uint16_t *) bits) + x;
1479     for (i = 0; i < width; ++i) {
1480         Splita(values[i]);
1481         WRITE(image, pixel++, ((a << 8) & 0x8000) |
1482               ((r << 7) & 0x7c00) |
1483               ((g << 2) & 0x03e0) |
1484               ((b >> 3)         ));
1485     }
1486 }
1487
1488 static FASTCALL void
1489 fbStore_x1r5g5b5 (pixman_image_t *image,
1490                   uint32_t *bits, const uint32_t *values, int x, int width, const pixman_indexed_t * indexed)
1491 {
1492     int i;
1493     uint16_t  *pixel = ((uint16_t *) bits) + x;
1494     for (i = 0; i < width; ++i) {
1495         Split(values[i]);
1496         WRITE(image, pixel++, ((r << 7) & 0x7c00) |
1497               ((g << 2) & 0x03e0) |
1498               ((b >> 3)         ));
1499     }
1500 }
1501
1502 static FASTCALL void
1503 fbStore_a1b5g5r5 (pixman_image_t *image,
1504                   uint32_t *bits, const uint32_t *values, int x, int width, const pixman_indexed_t * indexed)
1505 {
1506     int i;
1507     uint16_t  *pixel = ((uint16_t *) bits) + x;
1508     for (i = 0; i < width; ++i) {
1509         Splita(values[i]);
1510         WRITE(image, pixel++, ((a << 8) & 0x8000) |
1511               ((b << 7) & 0x7c00) |
1512               ((g << 2) & 0x03e0) |
1513               ((r >> 3)         ));
1514     }
1515 }
1516
1517 static FASTCALL void
1518 fbStore_x1b5g5r5 (pixman_image_t *image,
1519                   uint32_t *bits, const uint32_t *values, int x, int width, const pixman_indexed_t * indexed)
1520 {
1521     int i;
1522     uint16_t  *pixel = ((uint16_t *) bits) + x;
1523     for (i = 0; i < width; ++i) {
1524         Split(values[i]);
1525         WRITE(image, pixel++, ((b << 7) & 0x7c00) |
1526               ((g << 2) & 0x03e0) |
1527               ((r >> 3)         ));
1528     }
1529 }
1530
1531 static FASTCALL void
1532 fbStore_a4r4g4b4 (pixman_image_t *image,
1533                   uint32_t *bits, const uint32_t *values, int x, int width, const pixman_indexed_t * indexed)
1534 {
1535     int i;
1536     uint16_t  *pixel = ((uint16_t *) bits) + x;
1537     for (i = 0; i < width; ++i) {
1538         Splita(values[i]);
1539         WRITE(image, pixel++, ((a << 8) & 0xf000) |
1540               ((r << 4) & 0x0f00) |
1541               ((g     ) & 0x00f0) |
1542               ((b >> 4)         ));
1543     }
1544 }
1545
1546 static FASTCALL void
1547 fbStore_x4r4g4b4 (pixman_image_t *image,
1548                   uint32_t *bits, const uint32_t *values, int x, int width, const pixman_indexed_t * indexed)
1549 {
1550     int i;
1551     uint16_t  *pixel = ((uint16_t *) bits) + x;
1552     for (i = 0; i < width; ++i) {
1553         Split(values[i]);
1554         WRITE(image, pixel++, ((r << 4) & 0x0f00) |
1555               ((g     ) & 0x00f0) |
1556               ((b >> 4)         ));
1557     }
1558 }
1559
1560 static FASTCALL void
1561 fbStore_a4b4g4r4 (pixman_image_t *image,
1562                   uint32_t *bits, const uint32_t *values, int x, int width, const pixman_indexed_t * indexed)
1563 {
1564     int i;
1565     uint16_t  *pixel = ((uint16_t *) bits) + x;
1566     for (i = 0; i < width; ++i) {
1567         Splita(values[i]);
1568         WRITE(image, pixel++, ((a << 8) & 0xf000) |
1569               ((b << 4) & 0x0f00) |
1570               ((g     ) & 0x00f0) |
1571               ((r >> 4)         ));
1572     }
1573 }
1574
1575 static FASTCALL void
1576 fbStore_x4b4g4r4 (pixman_image_t *image,
1577                   uint32_t *bits, const uint32_t *values, int x, int width, const pixman_indexed_t * indexed)
1578 {
1579     int i;
1580     uint16_t  *pixel = ((uint16_t *) bits) + x;
1581     for (i = 0; i < width; ++i) {
1582         Split(values[i]);
1583         WRITE(image, pixel++, ((b << 4) & 0x0f00) |
1584               ((g     ) & 0x00f0) |
1585               ((r >> 4)         ));
1586     }
1587 }
1588
1589 static FASTCALL void
1590 fbStore_a8 (pixman_image_t *image,
1591             uint32_t *bits, const uint32_t *values, int x, int width, const pixman_indexed_t * indexed)
1592 {
1593     int i;
1594     uint8_t   *pixel = ((uint8_t *) bits) + x;
1595     for (i = 0; i < width; ++i) {
1596         WRITE(image, pixel++, values[i] >> 24);
1597     }
1598 }
1599
1600 static FASTCALL void
1601 fbStore_r3g3b2 (pixman_image_t *image,
1602                 uint32_t *bits, const uint32_t *values, int x, int width, const pixman_indexed_t * indexed)
1603 {
1604     int i;
1605     uint8_t   *pixel = ((uint8_t *) bits) + x;
1606     for (i = 0; i < width; ++i) {
1607         Split(values[i]);
1608         WRITE(image, pixel++,
1609               ((r     ) & 0xe0) |
1610               ((g >> 3) & 0x1c) |
1611               ((b >> 6)       ));
1612     }
1613 }
1614
1615 static FASTCALL void
1616 fbStore_b2g3r3 (pixman_image_t *image,
1617                 uint32_t *bits, const uint32_t *values, int x, int width, const pixman_indexed_t * indexed)
1618 {
1619     int i;
1620     uint8_t   *pixel = ((uint8_t *) bits) + x;
1621     for (i = 0; i < width; ++i) {
1622         Split(values[i]);
1623         WRITE(image, pixel++,
1624               ((b     ) & 0xc0) |
1625               ((g >> 2) & 0x38) |
1626               ((r >> 5)       ));
1627     }
1628 }
1629
1630 static FASTCALL void
1631 fbStore_a2r2g2b2 (pixman_image_t *image,
1632                   uint32_t *bits, const uint32_t *values, int x, int width, const pixman_indexed_t * indexed)
1633 {
1634     int i;
1635     uint8_t   *pixel = ((uint8_t *) bits) + x;
1636     for (i = 0; i < width; ++i) {
1637         Splita(values[i]);
1638         WRITE(image, pixel++, ((a     ) & 0xc0) |
1639               ((r >> 2) & 0x30) |
1640               ((g >> 4) & 0x0c) |
1641               ((b >> 6)       ));
1642     }
1643 }
1644
1645 static FASTCALL void
1646 fbStore_c8 (pixman_image_t *image,
1647             uint32_t *bits, const uint32_t *values, int x, int width, const pixman_indexed_t * indexed)
1648 {
1649     int i;
1650     uint8_t   *pixel = ((uint8_t *) bits) + x;
1651     for (i = 0; i < width; ++i) {
1652         WRITE(image, pixel++, miIndexToEnt24(indexed,values[i]));
1653     }
1654 }
1655
1656 static FASTCALL void
1657 fbStore_x4a4 (pixman_image_t *image,
1658               uint32_t *bits, const uint32_t *values, int x, int width, const pixman_indexed_t * indexed)
1659 {
1660     int i;
1661     uint8_t   *pixel = ((uint8_t *) bits) + x;
1662     for (i = 0; i < width; ++i) {
1663         WRITE(image, pixel++, values[i] >> 28);
1664     }
1665 }
1666
1667 #define Store8(img,l,o,v)  (WRITE(img, (uint8_t *)(l) + ((o) >> 3), (v)))
1668 #if IMAGE_BYTE_ORDER == MSBFirst
1669 #define Store4(img,l,o,v)  Store8(img,l,o,((o) & 4 ?                            \
1670                                    (Fetch8(img,l,o) & 0xf0) | (v) :             \
1671                                    (Fetch8(img,l,o) & 0x0f) | ((v) << 4)))
1672 #else
1673 #define Store4(img,l,o,v)  Store8(img,l,o,((o) & 4 ?                           \
1674                                    (Fetch8(img,l,o) & 0x0f) | ((v) << 4) : \
1675                                    (Fetch8(img,l,o) & 0xf0) | (v)))
1676 #endif
1677
1678 static FASTCALL void
1679 fbStore_a4 (pixman_image_t *image,
1680             uint32_t *bits, const uint32_t *values, int x, int width, const pixman_indexed_t * indexed)
1681 {
1682     int i;
1683     for (i = 0; i < width; ++i) {
1684         Store4(image, bits, i + x, values[i]>>28);
1685     }
1686 }
1687
1688 static FASTCALL void
1689 fbStore_r1g2b1 (pixman_image_t *image,
1690                 uint32_t *bits, const uint32_t *values, int x, int width, const pixman_indexed_t * indexed)
1691 {
1692     int i;
1693     for (i = 0; i < width; ++i) {
1694         uint32_t  pixel;
1695
1696         Split(values[i]);
1697         pixel = (((r >> 4) & 0x8) |
1698                  ((g >> 5) & 0x6) |
1699                  ((b >> 7)      ));
1700         Store4(image, bits, i + x, pixel);
1701     }
1702 }
1703
1704 static FASTCALL void
1705 fbStore_b1g2r1 (pixman_image_t *image,
1706                 uint32_t *bits, const uint32_t *values, int x, int width, const pixman_indexed_t * indexed)
1707 {
1708     int i;
1709     for (i = 0; i < width; ++i) {
1710         uint32_t  pixel;
1711
1712         Split(values[i]);
1713         pixel = (((b >> 4) & 0x8) |
1714                  ((g >> 5) & 0x6) |
1715                  ((r >> 7)      ));
1716         Store4(image, bits, i + x, pixel);
1717     }
1718 }
1719
1720 static FASTCALL void
1721 fbStore_a1r1g1b1 (pixman_image_t *image,
1722                   uint32_t *bits, const uint32_t *values, int x, int width, const pixman_indexed_t * indexed)
1723 {
1724     int i;
1725     for (i = 0; i < width; ++i) {
1726         uint32_t  pixel;
1727         Splita(values[i]);
1728         pixel = (((a >> 4) & 0x8) |
1729                  ((r >> 5) & 0x4) |
1730                  ((g >> 6) & 0x2) |
1731                  ((b >> 7)      ));
1732         Store4(image, bits, i + x, pixel);
1733     }
1734 }
1735
1736 static FASTCALL void
1737 fbStore_a1b1g1r1 (pixman_image_t *image,
1738                   uint32_t *bits, const uint32_t *values, int x, int width, const pixman_indexed_t * indexed)
1739 {
1740     int i;
1741     for (i = 0; i < width; ++i) {
1742         uint32_t  pixel;
1743         Splita(values[i]);
1744         pixel = (((a >> 4) & 0x8) |
1745                  ((b >> 5) & 0x4) |
1746                  ((g >> 6) & 0x2) |
1747                  ((r >> 7)      ));
1748         Store4(image, bits, i + x, pixel);
1749     }
1750 }
1751
1752 static FASTCALL void
1753 fbStore_c4 (pixman_image_t *image,
1754             uint32_t *bits, const uint32_t *values, int x, int width, const pixman_indexed_t * indexed)
1755 {
1756     int i;
1757     for (i = 0; i < width; ++i) {
1758         uint32_t  pixel;
1759
1760         pixel = miIndexToEnt24(indexed, values[i]);
1761         Store4(image, bits, i + x, pixel);
1762     }
1763 }
1764
1765 static FASTCALL void
1766 fbStore_a1 (pixman_image_t *image,
1767             uint32_t *bits, const uint32_t *values, int x, int width, const pixman_indexed_t * indexed)
1768 {
1769     int i;
1770     for (i = 0; i < width; ++i) {
1771         uint32_t  *pixel = ((uint32_t *) bits) + ((i+x) >> 5);
1772         uint32_t  mask = FbStipMask((i+x) & 0x1f, 1);
1773
1774         uint32_t v = values[i] & 0x80000000 ? mask : 0;
1775         WRITE(image, pixel, (READ(image, pixel) & ~mask) | v);
1776     }
1777 }
1778
1779 static FASTCALL void
1780 fbStore_g1 (pixman_image_t *image,
1781             uint32_t *bits, const uint32_t *values, int x, int width, const pixman_indexed_t * indexed)
1782 {
1783     int i;
1784     for (i = 0; i < width; ++i) {
1785         uint32_t  *pixel = ((uint32_t *) bits) + ((i+x) >> 5);
1786         uint32_t  mask = FbStipMask((i+x) & 0x1f, 1);
1787
1788         uint32_t v = miIndexToEntY24(indexed,values[i]) ? mask : 0;
1789         WRITE(image, pixel, (READ(image, pixel) & ~mask) | v);
1790     }
1791 }
1792
1793
1794 storeProc32 ACCESS(pixman_storeProcForPicture32) (bits_image_t * pict)
1795 {
1796     switch(pict->format) {
1797     case PIXMAN_a8r8g8b8: return fbStore_a8r8g8b8;
1798     case PIXMAN_x8r8g8b8: return fbStore_x8r8g8b8;
1799     case PIXMAN_a8b8g8r8: return fbStore_a8b8g8r8;
1800     case PIXMAN_x8b8g8r8: return fbStore_x8b8g8r8;
1801
1802         /* 24bpp formats */
1803     case PIXMAN_r8g8b8: return fbStore_r8g8b8;
1804     case PIXMAN_b8g8r8: return fbStore_b8g8r8;
1805
1806         /* 16bpp formats */
1807     case PIXMAN_r5g6b5: return fbStore_r5g6b5;
1808     case PIXMAN_b5g6r5: return fbStore_b5g6r5;
1809
1810     case PIXMAN_a1r5g5b5: return fbStore_a1r5g5b5;
1811     case PIXMAN_x1r5g5b5: return fbStore_x1r5g5b5;
1812     case PIXMAN_a1b5g5r5: return fbStore_a1b5g5r5;
1813     case PIXMAN_x1b5g5r5: return fbStore_x1b5g5r5;
1814     case PIXMAN_a4r4g4b4: return fbStore_a4r4g4b4;
1815     case PIXMAN_x4r4g4b4: return fbStore_x4r4g4b4;
1816     case PIXMAN_a4b4g4r4: return fbStore_a4b4g4r4;
1817     case PIXMAN_x4b4g4r4: return fbStore_x4b4g4r4;
1818
1819         /* 8bpp formats */
1820     case PIXMAN_a8: return  fbStore_a8;
1821     case PIXMAN_r3g3b2: return fbStore_r3g3b2;
1822     case PIXMAN_b2g3r3: return fbStore_b2g3r3;
1823     case PIXMAN_a2r2g2b2: return fbStore_a2r2g2b2;
1824     case PIXMAN_c8: return  fbStore_c8;
1825     case PIXMAN_g8: return  fbStore_c8;
1826     case PIXMAN_x4a4: return fbStore_x4a4;
1827
1828         /* 4bpp formats */
1829     case PIXMAN_a4: return  fbStore_a4;
1830     case PIXMAN_r1g2b1: return fbStore_r1g2b1;
1831     case PIXMAN_b1g2r1: return fbStore_b1g2r1;
1832     case PIXMAN_a1r1g1b1: return fbStore_a1r1g1b1;
1833     case PIXMAN_a1b1g1r1: return fbStore_a1b1g1r1;
1834     case PIXMAN_c4: return  fbStore_c4;
1835     case PIXMAN_g4: return  fbStore_c4;
1836
1837         /* 1bpp formats */
1838     case PIXMAN_a1: return  fbStore_a1;
1839     case PIXMAN_g1: return  fbStore_g1;
1840     default:
1841         return NULL;
1842     }
1843 }
1844
1845 /*
1846  * Contracts a 64bpp image to 32bpp and then stores it using a regular 32-bit
1847  * store proc.
1848  */
1849 static FASTCALL void
1850 fbStore64_generic (pixman_image_t *image,
1851                    uint32_t *bits, const uint64_t *values, int x, int width, const pixman_indexed_t * indexed)
1852 {
1853     bits_image_t *pict = (bits_image_t*)image;
1854     storeProc32 store32 = ACCESS(pixman_storeProcForPicture32) (pict);
1855     uint32_t *argb8Pixels;
1856
1857     assert(image->common.type == BITS);
1858     assert(store32);
1859
1860     argb8Pixels = malloc(sizeof(uint32_t) * width);
1861     if (!argb8Pixels) return;
1862
1863     // Contract the scanline.  We could do this in place if values weren't
1864     // const.
1865     pixman_contract(argb8Pixels, values, width);
1866     store32(image, bits, argb8Pixels, x, width, indexed);
1867
1868     free(argb8Pixels);
1869 }
1870
1871 storeProc64 ACCESS(pixman_storeProcForPicture64) (bits_image_t * pict)
1872 {
1873     switch(pict->format) {
1874     case PIXMAN_a2b10g10r10: return fbStore_a2b10g10r10;
1875     case PIXMAN_x2b10g10r10: return fbStore_x2b10g10r10;
1876     default: return fbStore64_generic;
1877     }
1878 }
1879
1880 #ifndef PIXMAN_FB_ACCESSORS
1881 /*
1882  * This function expands images from ARGB8 format to ARGB16.  To preserve
1883  * precision, it needs to know the original source format.  For example, if the
1884  * source was PIXMAN_x1r5g5b5 and the red component contained bits 12345, then
1885  * the expanded value is 12345123.  To correctly expand this to 16 bits, it
1886  * should be 1234512345123451 and not 1234512312345123.
1887  *
1888  * XXX[AGP]: For now, this just does naïve byte replication.
1889  */
1890 void pixman_expand(uint64_t *dst, const uint32_t *src,
1891                    pixman_format_code_t format, int width)
1892 {
1893     int i;
1894
1895     /* Start at the end so that we can do the expansion in place when src == dst */
1896     for (i = width - 1; i >= 0; i--)
1897     {
1898         const uint8_t a = src[i] >> 24,
1899                       r = src[i] >> 16,
1900                       g = src[i] >> 8,
1901                       b = src[i];
1902         dst[i] = (uint64_t)a << 56 | (uint64_t) a << 48 |
1903                  (uint64_t)r << 40 | (uint64_t) r << 32 |
1904                  (uint64_t)g << 24 | (uint64_t) g << 16 |
1905                  (uint64_t)b << 8 | (uint64_t)b;
1906     }
1907 }
1908
1909 /*
1910  * Contracting is easier than expanding.  We just need to truncate the
1911  * components.
1912  */
1913 void pixman_contract(uint32_t *dst, const uint64_t *src, int width)
1914 {
1915     int i;
1916
1917     /* Start at the beginning so that we can do the contraction in place when
1918      * src == dst */
1919     for (i = 0; i < width; i++)
1920     {
1921         const uint8_t a = src[i] >> 56,
1922                       r = src[i] >> 40,
1923                       g = src[i] >> 24,
1924                       b = src[i] >> 8;
1925         dst[i] = a << 24 | r << 16 | g << 8 | b;
1926     }
1927 }
1928 #endif // PIXMAN_FB_ACCESSORS