Add qemu 2.4.0
[kvmfornfv.git] / qemu / pixman / 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 #include <math.h>
35
36 #include "pixman-accessor.h"
37 #include "pixman-private.h"
38
39 #define CONVERT_RGB24_TO_Y15(s)                                         \
40     (((((s) >> 16) & 0xff) * 153 +                                      \
41       (((s) >>  8) & 0xff) * 301 +                                      \
42       (((s)      ) & 0xff) * 58) >> 2)
43
44 #define CONVERT_RGB24_TO_RGB15(s)                                       \
45     ((((s) >> 3) & 0x001f) |                                            \
46      (((s) >> 6) & 0x03e0) |                                            \
47      (((s) >> 9) & 0x7c00))
48
49 /* Fetch macros */
50
51 #ifdef WORDS_BIGENDIAN
52 #define FETCH_1(img,l,o)                                                \
53     (((READ ((img), ((uint32_t *)(l)) + ((o) >> 5))) >> (0x1f - ((o) & 0x1f))) & 0x1)
54 #else
55 #define FETCH_1(img,l,o)                                                \
56     ((((READ ((img), ((uint32_t *)(l)) + ((o) >> 5))) >> ((o) & 0x1f))) & 0x1)
57 #endif
58
59 #define FETCH_8(img,l,o)    (READ (img, (((uint8_t *)(l)) + ((o) >> 3))))
60
61 #ifdef WORDS_BIGENDIAN
62 #define FETCH_4(img,l,o)                                                \
63     (((4 * (o)) & 4) ? (FETCH_8 (img,l, 4 * (o)) & 0xf) : (FETCH_8 (img,l,(4 * (o))) >> 4))
64 #else
65 #define FETCH_4(img,l,o)                                                \
66     (((4 * (o)) & 4) ? (FETCH_8 (img, l, 4 * (o)) >> 4) : (FETCH_8 (img, l, (4 * (o))) & 0xf))
67 #endif
68
69 #ifdef WORDS_BIGENDIAN
70 #define FETCH_24(img,l,o)                                              \
71     ((READ (img, (((uint8_t *)(l)) + ((o) * 3) + 0)) << 16)    |       \
72      (READ (img, (((uint8_t *)(l)) + ((o) * 3) + 1)) << 8)     |       \
73      (READ (img, (((uint8_t *)(l)) + ((o) * 3) + 2)) << 0))
74 #else
75 #define FETCH_24(img,l,o)                                               \
76     ((READ (img, (((uint8_t *)(l)) + ((o) * 3) + 0)) << 0)      |       \
77      (READ (img, (((uint8_t *)(l)) + ((o) * 3) + 1)) << 8)      |       \
78      (READ (img, (((uint8_t *)(l)) + ((o) * 3) + 2)) << 16))
79 #endif
80
81 /* Store macros */
82
83 #ifdef WORDS_BIGENDIAN
84 #define STORE_1(img,l,o,v)                                              \
85     do                                                                  \
86     {                                                                   \
87         uint32_t  *__d = ((uint32_t *)(l)) + ((o) >> 5);                \
88         uint32_t __m, __v;                                              \
89                                                                         \
90         __m = 1 << (0x1f - ((o) & 0x1f));                               \
91         __v = (v)? __m : 0;                                             \
92                                                                         \
93         WRITE((img), __d, (READ((img), __d) & ~__m) | __v);             \
94     }                                                                   \
95     while (0)
96 #else
97 #define STORE_1(img,l,o,v)                                              \
98     do                                                                  \
99     {                                                                   \
100         uint32_t  *__d = ((uint32_t *)(l)) + ((o) >> 5);                \
101         uint32_t __m, __v;                                              \
102                                                                         \
103         __m = 1 << ((o) & 0x1f);                                        \
104         __v = (v)? __m : 0;                                             \
105                                                                         \
106         WRITE((img), __d, (READ((img), __d) & ~__m) | __v);             \
107     }                                                                   \
108     while (0)
109 #endif
110
111 #define STORE_8(img,l,o,v)  (WRITE (img, (uint8_t *)(l) + ((o) >> 3), (v)))
112
113 #ifdef WORDS_BIGENDIAN
114 #define STORE_4(img,l,o,v)                                              \
115     do                                                                  \
116     {                                                                   \
117         int bo = 4 * (o);                                               \
118         int v4 = (v) & 0x0f;                                            \
119                                                                         \
120         STORE_8 (img, l, bo, (                                          \
121                      bo & 4 ?                                           \
122                      (FETCH_8 (img, l, bo) & 0xf0) | (v4) :             \
123                      (FETCH_8 (img, l, bo) & 0x0f) | (v4 << 4)));       \
124     } while (0)
125 #else
126 #define STORE_4(img,l,o,v)                                              \
127     do                                                                  \
128     {                                                                   \
129         int bo = 4 * (o);                                               \
130         int v4 = (v) & 0x0f;                                            \
131                                                                         \
132         STORE_8 (img, l, bo, (                                          \
133                      bo & 4 ?                                           \
134                      (FETCH_8 (img, l, bo) & 0x0f) | (v4 << 4) :        \
135                      (FETCH_8 (img, l, bo) & 0xf0) | (v4)));            \
136     } while (0)
137 #endif
138
139 #ifdef WORDS_BIGENDIAN
140 #define STORE_24(img,l,o,v)                                            \
141     do                                                                 \
142     {                                                                  \
143         uint8_t *__tmp = (l) + 3 * (o);                                \
144                                                                        \
145         WRITE ((img), __tmp++, ((v) & 0x00ff0000) >> 16);              \
146         WRITE ((img), __tmp++, ((v) & 0x0000ff00) >>  8);              \
147         WRITE ((img), __tmp++, ((v) & 0x000000ff) >>  0);              \
148     }                                                                  \
149     while (0)
150 #else
151 #define STORE_24(img,l,o,v)                                            \
152     do                                                                 \
153     {                                                                  \
154         uint8_t *__tmp = (l) + 3 * (o);                                \
155                                                                        \
156         WRITE ((img), __tmp++, ((v) & 0x000000ff) >>  0);              \
157         WRITE ((img), __tmp++, ((v) & 0x0000ff00) >>  8);              \
158         WRITE ((img), __tmp++, ((v) & 0x00ff0000) >> 16);              \
159     }                                                                  \
160     while (0)
161 #endif
162
163 /*
164  * YV12 setup and access macros
165  */
166
167 #define YV12_SETUP(image)                                               \
168     bits_image_t *__bits_image = (bits_image_t *)image;                 \
169     uint32_t *bits = __bits_image->bits;                                \
170     int stride = __bits_image->rowstride;                               \
171     int offset0 = stride < 0 ?                                          \
172     ((-stride) >> 1) * ((__bits_image->height - 1) >> 1) - stride :     \
173     stride * __bits_image->height;                                      \
174     int offset1 = stride < 0 ?                                          \
175     offset0 + ((-stride) >> 1) * ((__bits_image->height) >> 1) :        \
176         offset0 + (offset0 >> 2)
177
178 /* Note no trailing semicolon on the above macro; if it's there, then
179  * the typical usage of YV12_SETUP(image); will have an extra trailing ;
180  * that some compilers will interpret as a statement -- and then any further
181  * variable declarations will cause an error.
182  */
183
184 #define YV12_Y(line)                                                    \
185     ((uint8_t *) ((bits) + (stride) * (line)))
186
187 #define YV12_U(line)                                                    \
188     ((uint8_t *) ((bits) + offset1 +                                    \
189                   ((stride) >> 1) * ((line) >> 1)))
190
191 #define YV12_V(line)                                                    \
192     ((uint8_t *) ((bits) + offset0 +                                    \
193                   ((stride) >> 1) * ((line) >> 1)))
194
195 /* Misc. helpers */
196
197 static force_inline void
198 get_shifts (pixman_format_code_t  format,
199             int                  *a,
200             int                  *r,
201             int                  *g,
202             int                  *b)
203 {
204     switch (PIXMAN_FORMAT_TYPE (format))
205     {
206     case PIXMAN_TYPE_A:
207         *b = 0;
208         *g = 0;
209         *r = 0;
210         *a = 0;
211         break;
212
213     case PIXMAN_TYPE_ARGB:
214     case PIXMAN_TYPE_ARGB_SRGB:
215         *b = 0;
216         *g = *b + PIXMAN_FORMAT_B (format);
217         *r = *g + PIXMAN_FORMAT_G (format);
218         *a = *r + PIXMAN_FORMAT_R (format);
219         break;
220
221     case PIXMAN_TYPE_ABGR:
222         *r = 0;
223         *g = *r + PIXMAN_FORMAT_R (format);
224         *b = *g + PIXMAN_FORMAT_G (format);
225         *a = *b + PIXMAN_FORMAT_B (format);
226         break;
227
228     case PIXMAN_TYPE_BGRA:
229         /* With BGRA formats we start counting at the high end of the pixel */
230         *b = PIXMAN_FORMAT_BPP (format) - PIXMAN_FORMAT_B (format);
231         *g = *b - PIXMAN_FORMAT_B (format);
232         *r = *g - PIXMAN_FORMAT_G (format);
233         *a = *r - PIXMAN_FORMAT_R (format);
234         break;
235
236     case PIXMAN_TYPE_RGBA:
237         /* With BGRA formats we start counting at the high end of the pixel */
238         *r = PIXMAN_FORMAT_BPP (format) - PIXMAN_FORMAT_R (format);
239         *g = *r - PIXMAN_FORMAT_R (format);
240         *b = *g - PIXMAN_FORMAT_G (format);
241         *a = *b - PIXMAN_FORMAT_B (format);
242         break;
243
244     default:
245         assert (0);
246         break;
247     }
248 }
249
250 static force_inline uint32_t
251 convert_channel (uint32_t pixel, uint32_t def_value,
252                  int n_from_bits, int from_shift,
253                  int n_to_bits, int to_shift)
254 {
255     uint32_t v;
256
257     if (n_from_bits && n_to_bits)
258         v  = unorm_to_unorm (pixel >> from_shift, n_from_bits, n_to_bits);
259     else if (n_to_bits)
260         v = def_value;
261     else
262         v = 0;
263
264     return (v & ((1 << n_to_bits) - 1)) << to_shift;
265 }
266
267 static force_inline uint32_t
268 convert_pixel (pixman_format_code_t from, pixman_format_code_t to, uint32_t pixel)
269 {
270     int a_from_shift, r_from_shift, g_from_shift, b_from_shift;
271     int a_to_shift, r_to_shift, g_to_shift, b_to_shift;
272     uint32_t a, r, g, b;
273
274     get_shifts (from, &a_from_shift, &r_from_shift, &g_from_shift, &b_from_shift);
275     get_shifts (to, &a_to_shift, &r_to_shift, &g_to_shift, &b_to_shift);
276
277     a = convert_channel (pixel, ~0,
278                          PIXMAN_FORMAT_A (from), a_from_shift,
279                          PIXMAN_FORMAT_A (to), a_to_shift);
280
281     r = convert_channel (pixel, 0,
282                          PIXMAN_FORMAT_R (from), r_from_shift,
283                          PIXMAN_FORMAT_R (to), r_to_shift);
284
285     g = convert_channel (pixel, 0,
286                          PIXMAN_FORMAT_G (from), g_from_shift,
287                          PIXMAN_FORMAT_G (to), g_to_shift);
288
289     b = convert_channel (pixel, 0,
290                          PIXMAN_FORMAT_B (from), b_from_shift,
291                          PIXMAN_FORMAT_B (to), b_to_shift);
292
293     return a | r | g | b;
294 }
295
296 static force_inline uint32_t
297 convert_pixel_to_a8r8g8b8 (bits_image_t *image,
298                            pixman_format_code_t format,
299                            uint32_t pixel)
300 {
301     if (PIXMAN_FORMAT_TYPE (format) == PIXMAN_TYPE_GRAY         ||
302         PIXMAN_FORMAT_TYPE (format) == PIXMAN_TYPE_COLOR)
303     {
304         return image->indexed->rgba[pixel];
305     }
306     else
307     {
308         return convert_pixel (format, PIXMAN_a8r8g8b8, pixel);
309     }
310 }
311
312 static force_inline uint32_t
313 convert_pixel_from_a8r8g8b8 (pixman_image_t *image,
314                              pixman_format_code_t format, uint32_t pixel)
315 {
316     if (PIXMAN_FORMAT_TYPE (format) == PIXMAN_TYPE_GRAY)
317     {
318         pixel = CONVERT_RGB24_TO_Y15 (pixel);
319
320         return image->bits.indexed->ent[pixel & 0x7fff];
321     }
322     else if (PIXMAN_FORMAT_TYPE (format) == PIXMAN_TYPE_COLOR)
323     {
324         pixel = convert_pixel (PIXMAN_a8r8g8b8, PIXMAN_x1r5g5b5, pixel);
325
326         return image->bits.indexed->ent[pixel & 0x7fff];
327     }
328     else
329     {
330         return convert_pixel (PIXMAN_a8r8g8b8, format, pixel);
331     }
332 }
333
334 static force_inline uint32_t
335 fetch_and_convert_pixel (bits_image_t *         image,
336                          const uint8_t *        bits,
337                          int                    offset,
338                          pixman_format_code_t   format)
339 {
340     uint32_t pixel;
341
342     switch (PIXMAN_FORMAT_BPP (format))
343     {
344     case 1:
345         pixel = FETCH_1 (image, bits, offset);
346         break;
347
348     case 4:
349         pixel = FETCH_4 (image, bits, offset);
350         break;
351
352     case 8:
353         pixel = READ (image, bits + offset);
354         break;
355
356     case 16:
357         pixel = READ (image, ((uint16_t *)bits + offset));
358         break;
359
360     case 24:
361         pixel = FETCH_24 (image, bits, offset);
362         break;
363
364     case 32:
365         pixel = READ (image, ((uint32_t *)bits + offset));
366         break;
367
368     default:
369         pixel = 0xffff00ff; /* As ugly as possible to detect the bug */
370         break;
371     }
372
373     return convert_pixel_to_a8r8g8b8 (image, format, pixel);
374 }
375
376 static force_inline void
377 convert_and_store_pixel (bits_image_t *         image,
378                          uint8_t *              dest,
379                          int                    offset,
380                          pixman_format_code_t   format,
381                          uint32_t               pixel)
382 {
383     uint32_t converted = convert_pixel_from_a8r8g8b8 (
384         (pixman_image_t *)image, format, pixel);
385
386     switch (PIXMAN_FORMAT_BPP (format))
387     {
388     case 1:
389         STORE_1 (image, dest, offset, converted & 0x01);
390         break;
391
392     case 4:
393         STORE_4 (image, dest, offset, converted & 0xf);
394         break;
395
396     case 8:
397         WRITE (image, (dest + offset), converted & 0xff);
398         break;
399
400     case 16:
401         WRITE (image, ((uint16_t *)dest + offset), converted & 0xffff);
402         break;
403
404     case 24:
405         STORE_24 (image, dest, offset, converted);
406         break;
407
408     case 32:
409         WRITE (image, ((uint32_t *)dest + offset), converted);
410         break;
411
412     default:
413         *dest = 0x0;
414         break;
415     }
416 }
417
418 #define MAKE_ACCESSORS(format)                                          \
419     static void                                                         \
420     fetch_scanline_ ## format (bits_image_t *image,                     \
421                                int             x,                       \
422                                int             y,                       \
423                                int             width,                   \
424                                uint32_t *      buffer,                  \
425                                const uint32_t *mask)                    \
426     {                                                                   \
427         uint8_t *bits =                                                 \
428             (uint8_t *)(image->bits + y * image->rowstride);            \
429         int i;                                                          \
430                                                                         \
431         for (i = 0; i < width; ++i)                                     \
432         {                                                               \
433             *buffer++ =                                                 \
434                 fetch_and_convert_pixel (image, bits, x + i, PIXMAN_ ## format); \
435         }                                                               \
436     }                                                                   \
437                                                                         \
438     static void                                                         \
439     store_scanline_ ## format (bits_image_t *  image,                   \
440                                int             x,                       \
441                                int             y,                       \
442                                int             width,                   \
443                                const uint32_t *values)                  \
444     {                                                                   \
445         uint8_t *dest =                                                 \
446             (uint8_t *)(image->bits + y * image->rowstride);            \
447         int i;                                                          \
448                                                                         \
449         for (i = 0; i < width; ++i)                                     \
450         {                                                               \
451             convert_and_store_pixel (                                   \
452                 image, dest, i + x, PIXMAN_ ## format, values[i]);      \
453         }                                                               \
454     }                                                                   \
455                                                                         \
456     static uint32_t                                                     \
457     fetch_pixel_ ## format (bits_image_t *image,                        \
458                             int         offset,                         \
459                             int         line)                           \
460     {                                                                   \
461         uint8_t *bits =                                                 \
462             (uint8_t *)(image->bits + line * image->rowstride);         \
463                                                                         \
464         return fetch_and_convert_pixel (                                \
465             image, bits, offset, PIXMAN_ ## format);                    \
466     }                                                                   \
467                                                                         \
468     static const void *const __dummy__ ## format
469
470 MAKE_ACCESSORS(a8r8g8b8);
471 MAKE_ACCESSORS(x8r8g8b8);
472 MAKE_ACCESSORS(a8b8g8r8);
473 MAKE_ACCESSORS(x8b8g8r8);
474 MAKE_ACCESSORS(x14r6g6b6);
475 MAKE_ACCESSORS(b8g8r8a8);
476 MAKE_ACCESSORS(b8g8r8x8);
477 MAKE_ACCESSORS(r8g8b8x8);
478 MAKE_ACCESSORS(r8g8b8a8);
479 MAKE_ACCESSORS(r8g8b8);
480 MAKE_ACCESSORS(b8g8r8);
481 MAKE_ACCESSORS(r5g6b5);
482 MAKE_ACCESSORS(b5g6r5);
483 MAKE_ACCESSORS(a1r5g5b5);
484 MAKE_ACCESSORS(x1r5g5b5);
485 MAKE_ACCESSORS(a1b5g5r5);
486 MAKE_ACCESSORS(x1b5g5r5);
487 MAKE_ACCESSORS(a4r4g4b4);
488 MAKE_ACCESSORS(x4r4g4b4);
489 MAKE_ACCESSORS(a4b4g4r4);
490 MAKE_ACCESSORS(x4b4g4r4);
491 MAKE_ACCESSORS(a8);
492 MAKE_ACCESSORS(c8);
493 MAKE_ACCESSORS(g8);
494 MAKE_ACCESSORS(r3g3b2);
495 MAKE_ACCESSORS(b2g3r3);
496 MAKE_ACCESSORS(a2r2g2b2);
497 MAKE_ACCESSORS(a2b2g2r2);
498 MAKE_ACCESSORS(x4a4);
499 MAKE_ACCESSORS(a4);
500 MAKE_ACCESSORS(g4);
501 MAKE_ACCESSORS(c4);
502 MAKE_ACCESSORS(r1g2b1);
503 MAKE_ACCESSORS(b1g2r1);
504 MAKE_ACCESSORS(a1r1g1b1);
505 MAKE_ACCESSORS(a1b1g1r1);
506 MAKE_ACCESSORS(a1);
507 MAKE_ACCESSORS(g1);
508
509 /********************************** Fetch ************************************/
510 /* Table mapping sRGB-encoded 8 bit numbers to linearly encoded
511  * floating point numbers. We assume that single precision
512  * floating point follows the IEEE 754 format.
513  */
514 static const uint32_t to_linear_u[256] =
515 {
516     0x00000000, 0x399f22b4, 0x3a1f22b4, 0x3a6eb40e, 0x3a9f22b4, 0x3ac6eb61,
517     0x3aeeb40e, 0x3b0b3e5d, 0x3b1f22b4, 0x3b33070b, 0x3b46eb61, 0x3b5b518a,
518     0x3b70f18a, 0x3b83e1c5, 0x3b8fe614, 0x3b9c87fb, 0x3ba9c9b5, 0x3bb7ad6d,
519     0x3bc63547, 0x3bd5635f, 0x3be539bd, 0x3bf5ba70, 0x3c0373b5, 0x3c0c6152,
520     0x3c15a703, 0x3c1f45bc, 0x3c293e68, 0x3c3391f4, 0x3c3e4149, 0x3c494d43,
521     0x3c54b6c7, 0x3c607eb1, 0x3c6ca5df, 0x3c792d22, 0x3c830aa8, 0x3c89af9e,
522     0x3c9085db, 0x3c978dc5, 0x3c9ec7c0, 0x3ca63432, 0x3cadd37d, 0x3cb5a601,
523     0x3cbdac20, 0x3cc5e639, 0x3cce54ab, 0x3cd6f7d2, 0x3cdfd00e, 0x3ce8ddb9,
524     0x3cf2212c, 0x3cfb9ac1, 0x3d02a569, 0x3d0798dc, 0x3d0ca7e4, 0x3d11d2ae,
525     0x3d171963, 0x3d1c7c2e, 0x3d21fb3a, 0x3d2796af, 0x3d2d4ebb, 0x3d332380,
526     0x3d39152b, 0x3d3f23e3, 0x3d454fd0, 0x3d4b991c, 0x3d51ffeb, 0x3d588466,
527     0x3d5f26b7, 0x3d65e6fe, 0x3d6cc564, 0x3d73c210, 0x3d7add25, 0x3d810b65,
528     0x3d84b793, 0x3d88732e, 0x3d8c3e48, 0x3d9018f4, 0x3d940343, 0x3d97fd48,
529     0x3d9c0714, 0x3da020b9, 0x3da44a48, 0x3da883d6, 0x3daccd70, 0x3db12728,
530     0x3db59110, 0x3dba0b38, 0x3dbe95b2, 0x3dc3308f, 0x3dc7dbe0, 0x3dcc97b4,
531     0x3dd1641c, 0x3dd6412a, 0x3ddb2eec, 0x3de02d75, 0x3de53cd3, 0x3dea5d16,
532     0x3def8e52, 0x3df4d091, 0x3dfa23e5, 0x3dff885e, 0x3e027f06, 0x3e05427f,
533     0x3e080ea2, 0x3e0ae376, 0x3e0dc104, 0x3e10a752, 0x3e139669, 0x3e168e50,
534     0x3e198f0e, 0x3e1c98ab, 0x3e1fab2e, 0x3e22c6a0, 0x3e25eb08, 0x3e29186a,
535     0x3e2c4ed0, 0x3e2f8e42, 0x3e32d6c4, 0x3e362861, 0x3e39831e, 0x3e3ce702,
536     0x3e405416, 0x3e43ca5e, 0x3e4749e4, 0x3e4ad2ae, 0x3e4e64c2, 0x3e520027,
537     0x3e55a4e6, 0x3e595303, 0x3e5d0a8a, 0x3e60cb7c, 0x3e6495e0, 0x3e6869bf,
538     0x3e6c4720, 0x3e702e08, 0x3e741e7f, 0x3e78188c, 0x3e7c1c34, 0x3e8014c0,
539     0x3e822039, 0x3e84308b, 0x3e8645b8, 0x3e885fc3, 0x3e8a7eb0, 0x3e8ca281,
540     0x3e8ecb3a, 0x3e90f8df, 0x3e932b72, 0x3e9562f6, 0x3e979f6f, 0x3e99e0e0,
541     0x3e9c274e, 0x3e9e72b8, 0x3ea0c322, 0x3ea31892, 0x3ea57308, 0x3ea7d28a,
542     0x3eaa3718, 0x3eaca0b7, 0x3eaf0f69, 0x3eb18332, 0x3eb3fc16, 0x3eb67a15,
543     0x3eb8fd34, 0x3ebb8576, 0x3ebe12de, 0x3ec0a56e, 0x3ec33d2a, 0x3ec5da14,
544     0x3ec87c30, 0x3ecb2380, 0x3ecdd008, 0x3ed081ca, 0x3ed338c9, 0x3ed5f508,
545     0x3ed8b68a, 0x3edb7d52, 0x3ede4962, 0x3ee11abe, 0x3ee3f168, 0x3ee6cd64,
546     0x3ee9aeb6, 0x3eec955d, 0x3eef815d, 0x3ef272ba, 0x3ef56976, 0x3ef86594,
547     0x3efb6717, 0x3efe6e02, 0x3f00bd2b, 0x3f02460c, 0x3f03d1a5, 0x3f055ff8,
548     0x3f06f105, 0x3f0884ce, 0x3f0a1b54, 0x3f0bb499, 0x3f0d509f, 0x3f0eef65,
549     0x3f1090ef, 0x3f12353c, 0x3f13dc50, 0x3f15862a, 0x3f1732cc, 0x3f18e237,
550     0x3f1a946d, 0x3f1c4970, 0x3f1e013f, 0x3f1fbbde, 0x3f21794c, 0x3f23398c,
551     0x3f24fca0, 0x3f26c286, 0x3f288b42, 0x3f2a56d3, 0x3f2c253d, 0x3f2df680,
552     0x3f2fca9d, 0x3f31a195, 0x3f337b6a, 0x3f35581e, 0x3f3737b1, 0x3f391a24,
553     0x3f3aff7a, 0x3f3ce7b2, 0x3f3ed2d0, 0x3f40c0d2, 0x3f42b1bc, 0x3f44a58e,
554     0x3f469c49, 0x3f4895ee, 0x3f4a9280, 0x3f4c91ff, 0x3f4e946c, 0x3f5099c8,
555     0x3f52a216, 0x3f54ad55, 0x3f56bb88, 0x3f58ccae, 0x3f5ae0cb, 0x3f5cf7de,
556     0x3f5f11ec, 0x3f612ef0, 0x3f634eef, 0x3f6571ea, 0x3f6797e1, 0x3f69c0d6,
557     0x3f6beccb, 0x3f6e1bc0, 0x3f704db6, 0x3f7282af, 0x3f74baac, 0x3f76f5ae,
558     0x3f7933b6, 0x3f7b74c6, 0x3f7db8de, 0x3f800000
559 };
560
561 static const float * const to_linear = (const float *)to_linear_u;
562
563 static uint8_t
564 to_srgb (float f)
565 {
566     uint8_t low = 0;
567     uint8_t high = 255;
568
569     while (high - low > 1)
570     {
571         uint8_t mid = (low + high) / 2;
572
573         if (to_linear[mid] > f)
574             high = mid;
575         else
576             low = mid;
577     }
578
579     if (to_linear[high] - f < f - to_linear[low])
580         return high;
581     else
582         return low;
583 }
584
585 static void
586 fetch_scanline_a8r8g8b8_sRGB_float (bits_image_t *  image,
587                                     int             x,
588                                     int             y,
589                                     int             width,
590                                     uint32_t *      b,
591                                     const uint32_t *mask)
592 {
593     const uint32_t *bits = image->bits + y * image->rowstride;
594     const uint32_t *pixel = bits + x;
595     const uint32_t *end = pixel + width;
596     argb_t *buffer = (argb_t *)b;
597
598     while (pixel < end)
599     {
600         uint32_t p = READ (image, pixel++);
601         argb_t *argb = buffer;
602
603         argb->a = pixman_unorm_to_float ((p >> 24) & 0xff, 8);
604
605         argb->r = to_linear [(p >> 16) & 0xff];
606         argb->g = to_linear [(p >>  8) & 0xff];
607         argb->b = to_linear [(p >>  0) & 0xff];
608
609         buffer++;
610     }
611 }
612
613 /* Expects a float buffer */
614 static void
615 fetch_scanline_a2r10g10b10_float (bits_image_t *  image,
616                                   int             x,
617                                   int             y,
618                                   int             width,
619                                   uint32_t *      b,
620                                   const uint32_t *mask)
621 {
622     const uint32_t *bits = image->bits + y * image->rowstride;
623     const uint32_t *pixel = bits + x;
624     const uint32_t *end = pixel + width;
625     argb_t *buffer = (argb_t *)b;
626
627     while (pixel < end)
628     {
629         uint32_t p = READ (image, pixel++);
630         uint64_t a = p >> 30;
631         uint64_t r = (p >> 20) & 0x3ff;
632         uint64_t g = (p >> 10) & 0x3ff;
633         uint64_t b = p & 0x3ff;
634
635         buffer->a = pixman_unorm_to_float (a, 2);
636         buffer->r = pixman_unorm_to_float (r, 10);
637         buffer->g = pixman_unorm_to_float (g, 10);
638         buffer->b = pixman_unorm_to_float (b, 10);
639
640         buffer++;
641     }
642 }
643
644 /* Expects a float buffer */
645 static void
646 fetch_scanline_x2r10g10b10_float (bits_image_t   *image,
647                                   int             x,
648                                   int             y,
649                                   int             width,
650                                   uint32_t *      b,
651                                   const uint32_t *mask)
652 {
653     const uint32_t *bits = image->bits + y * image->rowstride;
654     const uint32_t *pixel = (uint32_t *)bits + x;
655     const uint32_t *end = pixel + width;
656     argb_t *buffer = (argb_t *)b;
657
658     while (pixel < end)
659     {
660         uint32_t p = READ (image, pixel++);
661         uint64_t r = (p >> 20) & 0x3ff;
662         uint64_t g = (p >> 10) & 0x3ff;
663         uint64_t b = p & 0x3ff;
664
665         buffer->a = 1.0;
666         buffer->r = pixman_unorm_to_float (r, 10);
667         buffer->g = pixman_unorm_to_float (g, 10);
668         buffer->b = pixman_unorm_to_float (b, 10);
669
670         buffer++;
671     }
672 }
673
674 /* Expects a float buffer */
675 static void
676 fetch_scanline_a2b10g10r10_float (bits_image_t   *image,
677                                   int             x,
678                                   int             y,
679                                   int             width,
680                                   uint32_t *      b,
681                                   const uint32_t *mask)
682 {
683     const uint32_t *bits = image->bits + y * image->rowstride;
684     const uint32_t *pixel = bits + x;
685     const uint32_t *end = pixel + width;
686     argb_t *buffer = (argb_t *)b;
687
688     while (pixel < end)
689     {
690         uint32_t p = READ (image, pixel++);
691         uint64_t a = p >> 30;
692         uint64_t b = (p >> 20) & 0x3ff;
693         uint64_t g = (p >> 10) & 0x3ff;
694         uint64_t r = p & 0x3ff;
695
696         buffer->a = pixman_unorm_to_float (a, 2);
697         buffer->r = pixman_unorm_to_float (r, 10);
698         buffer->g = pixman_unorm_to_float (g, 10);
699         buffer->b = pixman_unorm_to_float (b, 10);
700
701         buffer++;
702     }
703 }
704
705 /* Expects a float buffer */
706 static void
707 fetch_scanline_x2b10g10r10_float (bits_image_t   *image,
708                                   int             x,
709                                   int             y,
710                                   int             width,
711                                   uint32_t *      b,
712                                   const uint32_t *mask)
713 {
714     const uint32_t *bits = image->bits + y * image->rowstride;
715     const uint32_t *pixel = (uint32_t *)bits + x;
716     const uint32_t *end = pixel + width;
717     argb_t *buffer = (argb_t *)b;
718
719     while (pixel < end)
720     {
721         uint32_t p = READ (image, pixel++);
722         uint64_t b = (p >> 20) & 0x3ff;
723         uint64_t g = (p >> 10) & 0x3ff;
724         uint64_t r = p & 0x3ff;
725
726         buffer->a = 1.0;
727         buffer->r = pixman_unorm_to_float (r, 10);
728         buffer->g = pixman_unorm_to_float (g, 10);
729         buffer->b = pixman_unorm_to_float (b, 10);
730
731         buffer++;
732     }
733 }
734
735 static void
736 fetch_scanline_yuy2 (bits_image_t   *image,
737                      int             x,
738                      int             line,
739                      int             width,
740                      uint32_t *      buffer,
741                      const uint32_t *mask)
742 {
743     const uint32_t *bits = image->bits + image->rowstride * line;
744     int i;
745     
746     for (i = 0; i < width; i++)
747     {
748         int16_t y, u, v;
749         int32_t r, g, b;
750         
751         y = ((uint8_t *) bits)[(x + i) << 1] - 16;
752         u = ((uint8_t *) bits)[(((x + i) << 1) & - 4) + 1] - 128;
753         v = ((uint8_t *) bits)[(((x + i) << 1) & - 4) + 3] - 128;
754         
755         /* R = 1.164(Y - 16) + 1.596(V - 128) */
756         r = 0x012b27 * y + 0x019a2e * v;
757         /* G = 1.164(Y - 16) - 0.813(V - 128) - 0.391(U - 128) */
758         g = 0x012b27 * y - 0x00d0f2 * v - 0x00647e * u;
759         /* B = 1.164(Y - 16) + 2.018(U - 128) */
760         b = 0x012b27 * y + 0x0206a2 * u;
761         
762         *buffer++ = 0xff000000 |
763             (r >= 0 ? r < 0x1000000 ? r         & 0xff0000 : 0xff0000 : 0) |
764             (g >= 0 ? g < 0x1000000 ? (g >> 8)  & 0x00ff00 : 0x00ff00 : 0) |
765             (b >= 0 ? b < 0x1000000 ? (b >> 16) & 0x0000ff : 0x0000ff : 0);
766     }
767 }
768
769 static void
770 fetch_scanline_yv12 (bits_image_t   *image,
771                      int             x,
772                      int             line,
773                      int             width,
774                      uint32_t *      buffer,
775                      const uint32_t *mask)
776 {
777     YV12_SETUP (image);
778     uint8_t *y_line = YV12_Y (line);
779     uint8_t *u_line = YV12_U (line);
780     uint8_t *v_line = YV12_V (line);
781     int i;
782     
783     for (i = 0; i < width; i++)
784     {
785         int16_t y, u, v;
786         int32_t r, g, b;
787
788         y = y_line[x + i] - 16;
789         u = u_line[(x + i) >> 1] - 128;
790         v = v_line[(x + i) >> 1] - 128;
791
792         /* R = 1.164(Y - 16) + 1.596(V - 128) */
793         r = 0x012b27 * y + 0x019a2e * v;
794         /* G = 1.164(Y - 16) - 0.813(V - 128) - 0.391(U - 128) */
795         g = 0x012b27 * y - 0x00d0f2 * v - 0x00647e * u;
796         /* B = 1.164(Y - 16) + 2.018(U - 128) */
797         b = 0x012b27 * y + 0x0206a2 * u;
798
799         *buffer++ = 0xff000000 |
800             (r >= 0 ? r < 0x1000000 ? r         & 0xff0000 : 0xff0000 : 0) |
801             (g >= 0 ? g < 0x1000000 ? (g >> 8)  & 0x00ff00 : 0x00ff00 : 0) |
802             (b >= 0 ? b < 0x1000000 ? (b >> 16) & 0x0000ff : 0x0000ff : 0);
803     }
804 }
805
806 /**************************** Pixel wise fetching *****************************/
807
808 static argb_t
809 fetch_pixel_x2r10g10b10_float (bits_image_t *image,
810                                int         offset,
811                                int           line)
812 {
813     uint32_t *bits = image->bits + line * image->rowstride;
814     uint32_t p = READ (image, bits + offset);
815     uint64_t r = (p >> 20) & 0x3ff;
816     uint64_t g = (p >> 10) & 0x3ff;
817     uint64_t b = p & 0x3ff;
818     argb_t argb;
819
820     argb.a = 1.0;
821     argb.r = pixman_unorm_to_float (r, 10);
822     argb.g = pixman_unorm_to_float (g, 10);
823     argb.b = pixman_unorm_to_float (b, 10);
824
825     return argb;
826 }
827
828 static argb_t
829 fetch_pixel_a2r10g10b10_float (bits_image_t *image,
830                                int           offset,
831                                int           line)
832 {
833     uint32_t *bits = image->bits + line * image->rowstride;
834     uint32_t p = READ (image, bits + offset);
835     uint64_t a = p >> 30;
836     uint64_t r = (p >> 20) & 0x3ff;
837     uint64_t g = (p >> 10) & 0x3ff;
838     uint64_t b = p & 0x3ff;
839     argb_t argb;
840
841     argb.a = pixman_unorm_to_float (a, 2);
842     argb.r = pixman_unorm_to_float (r, 10);
843     argb.g = pixman_unorm_to_float (g, 10);
844     argb.b = pixman_unorm_to_float (b, 10);
845
846     return argb;
847 }
848
849 static argb_t
850 fetch_pixel_a2b10g10r10_float (bits_image_t *image,
851                                int           offset,
852                                int           line)
853 {
854     uint32_t *bits = image->bits + line * image->rowstride;
855     uint32_t p = READ (image, bits + offset);
856     uint64_t a = p >> 30;
857     uint64_t b = (p >> 20) & 0x3ff;
858     uint64_t g = (p >> 10) & 0x3ff;
859     uint64_t r = p & 0x3ff;
860     argb_t argb;
861
862     argb.a = pixman_unorm_to_float (a, 2);
863     argb.r = pixman_unorm_to_float (r, 10);
864     argb.g = pixman_unorm_to_float (g, 10);
865     argb.b = pixman_unorm_to_float (b, 10);
866
867     return argb;
868 }
869
870 static argb_t
871 fetch_pixel_x2b10g10r10_float (bits_image_t *image,
872                                int           offset,
873                                int           line)
874 {
875     uint32_t *bits = image->bits + line * image->rowstride;
876     uint32_t p = READ (image, bits + offset);
877     uint64_t b = (p >> 20) & 0x3ff;
878     uint64_t g = (p >> 10) & 0x3ff;
879     uint64_t r = p & 0x3ff;
880     argb_t argb;
881
882     argb.a = 1.0;
883     argb.r = pixman_unorm_to_float (r, 10);
884     argb.g = pixman_unorm_to_float (g, 10);
885     argb.b = pixman_unorm_to_float (b, 10);
886
887     return argb;
888 }
889
890 static argb_t
891 fetch_pixel_a8r8g8b8_sRGB_float (bits_image_t *image,
892                                  int           offset,
893                                  int           line)
894 {
895     uint32_t *bits = image->bits + line * image->rowstride;
896     uint32_t p = READ (image, bits + offset);
897     argb_t argb;
898
899     argb.a = pixman_unorm_to_float ((p >> 24) & 0xff, 8);
900
901     argb.r = to_linear [(p >> 16) & 0xff];
902     argb.g = to_linear [(p >>  8) & 0xff];
903     argb.b = to_linear [(p >>  0) & 0xff];
904
905     return argb;
906 }
907
908 static uint32_t
909 fetch_pixel_yuy2 (bits_image_t *image,
910                   int           offset,
911                   int           line)
912 {
913     const uint32_t *bits = image->bits + image->rowstride * line;
914     
915     int16_t y, u, v;
916     int32_t r, g, b;
917     
918     y = ((uint8_t *) bits)[offset << 1] - 16;
919     u = ((uint8_t *) bits)[((offset << 1) & - 4) + 1] - 128;
920     v = ((uint8_t *) bits)[((offset << 1) & - 4) + 3] - 128;
921     
922     /* R = 1.164(Y - 16) + 1.596(V - 128) */
923     r = 0x012b27 * y + 0x019a2e * v;
924     
925     /* G = 1.164(Y - 16) - 0.813(V - 128) - 0.391(U - 128) */
926     g = 0x012b27 * y - 0x00d0f2 * v - 0x00647e * u;
927     
928     /* B = 1.164(Y - 16) + 2.018(U - 128) */
929     b = 0x012b27 * y + 0x0206a2 * u;
930     
931     return 0xff000000 |
932         (r >= 0 ? r < 0x1000000 ? r         & 0xff0000 : 0xff0000 : 0) |
933         (g >= 0 ? g < 0x1000000 ? (g >> 8)  & 0x00ff00 : 0x00ff00 : 0) |
934         (b >= 0 ? b < 0x1000000 ? (b >> 16) & 0x0000ff : 0x0000ff : 0);
935 }
936
937 static uint32_t
938 fetch_pixel_yv12 (bits_image_t *image,
939                   int           offset,
940                   int           line)
941 {
942     YV12_SETUP (image);
943     int16_t y = YV12_Y (line)[offset] - 16;
944     int16_t u = YV12_U (line)[offset >> 1] - 128;
945     int16_t v = YV12_V (line)[offset >> 1] - 128;
946     int32_t r, g, b;
947     
948     /* R = 1.164(Y - 16) + 1.596(V - 128) */
949     r = 0x012b27 * y + 0x019a2e * v;
950     
951     /* G = 1.164(Y - 16) - 0.813(V - 128) - 0.391(U - 128) */
952     g = 0x012b27 * y - 0x00d0f2 * v - 0x00647e * u;
953     
954     /* B = 1.164(Y - 16) + 2.018(U - 128) */
955     b = 0x012b27 * y + 0x0206a2 * u;
956     
957     return 0xff000000 |
958         (r >= 0 ? r < 0x1000000 ? r         & 0xff0000 : 0xff0000 : 0) |
959         (g >= 0 ? g < 0x1000000 ? (g >> 8)  & 0x00ff00 : 0x00ff00 : 0) |
960         (b >= 0 ? b < 0x1000000 ? (b >> 16) & 0x0000ff : 0x0000ff : 0);
961 }
962
963 /*********************************** Store ************************************/
964
965 static void
966 store_scanline_a2r10g10b10_float (bits_image_t *  image,
967                                   int             x,
968                                   int             y,
969                                   int             width,
970                                   const uint32_t *v)
971 {
972     uint32_t *bits = image->bits + image->rowstride * y;
973     uint32_t *pixel = bits + x;
974     argb_t *values = (argb_t *)v;
975     int i;
976
977     for (i = 0; i < width; ++i)
978     {
979         uint16_t a, r, g, b;
980
981         a = pixman_float_to_unorm (values[i].a, 2);
982         r = pixman_float_to_unorm (values[i].r, 10);
983         g = pixman_float_to_unorm (values[i].g, 10);
984         b = pixman_float_to_unorm (values[i].b, 10);
985
986         WRITE (image, pixel++,
987                (a << 30) | (r << 20) | (g << 10) | b);
988     }
989 }
990
991 static void
992 store_scanline_x2r10g10b10_float (bits_image_t *  image,
993                                   int             x,
994                                   int             y,
995                                   int             width,
996                                   const uint32_t *v)
997 {
998     uint32_t *bits = image->bits + image->rowstride * y;
999     uint32_t *pixel = bits + x;
1000     argb_t *values = (argb_t *)v;
1001     int i;
1002
1003     for (i = 0; i < width; ++i)
1004     {
1005         uint16_t r, g, b;
1006
1007         r = pixman_float_to_unorm (values[i].r, 10);
1008         g = pixman_float_to_unorm (values[i].g, 10);
1009         b = pixman_float_to_unorm (values[i].b, 10);
1010
1011         WRITE (image, pixel++,
1012                (r << 20) | (g << 10) | b);
1013     }
1014 }
1015
1016 static void
1017 store_scanline_a2b10g10r10_float (bits_image_t *  image,
1018                                   int             x,
1019                                   int             y,
1020                                   int             width,
1021                                   const uint32_t *v)
1022 {
1023     uint32_t *bits = image->bits + image->rowstride * y;
1024     uint32_t *pixel = bits + x;
1025     argb_t *values = (argb_t *)v;
1026     int i;
1027
1028     for (i = 0; i < width; ++i)
1029     {
1030         uint16_t a, r, g, b;
1031
1032         a = pixman_float_to_unorm (values[i].a, 2);
1033         r = pixman_float_to_unorm (values[i].r, 10);
1034         g = pixman_float_to_unorm (values[i].g, 10);
1035         b = pixman_float_to_unorm (values[i].b, 10);
1036
1037         WRITE (image, pixel++,
1038                (a << 30) | (b << 20) | (g << 10) | r);
1039     }
1040 }
1041
1042 static void
1043 store_scanline_x2b10g10r10_float (bits_image_t *  image,
1044                                   int             x,
1045                                   int             y,
1046                                   int             width,
1047                                   const uint32_t *v)
1048 {
1049     uint32_t *bits = image->bits + image->rowstride * y;
1050     uint32_t *pixel = bits + x;
1051     argb_t *values = (argb_t *)v;
1052     int i;
1053
1054     for (i = 0; i < width; ++i)
1055     {
1056         uint16_t r, g, b;
1057
1058         r = pixman_float_to_unorm (values[i].r, 10);
1059         g = pixman_float_to_unorm (values[i].g, 10);
1060         b = pixman_float_to_unorm (values[i].b, 10);
1061
1062         WRITE (image, pixel++,
1063                (b << 20) | (g << 10) | r);
1064     }
1065 }
1066
1067 static void
1068 store_scanline_a8r8g8b8_sRGB_float (bits_image_t *  image,
1069                                     int             x,
1070                                     int             y,
1071                                     int             width,
1072                                     const uint32_t *v)
1073 {
1074     uint32_t *bits = image->bits + image->rowstride * y;
1075     uint32_t *pixel = bits + x;
1076     argb_t *values = (argb_t *)v;
1077     int i;
1078
1079     for (i = 0; i < width; ++i)
1080     {
1081         uint8_t a, r, g, b;
1082
1083         a = pixman_float_to_unorm (values[i].a, 8);
1084         r = to_srgb (values[i].r);
1085         g = to_srgb (values[i].g);
1086         b = to_srgb (values[i].b);
1087
1088         WRITE (image, pixel++,
1089                (a << 24) | (r << 16) | (g << 8) | b);
1090     }
1091 }
1092
1093 /*
1094  * Contracts a floating point image to 32bpp and then stores it using a
1095  * regular 32-bit store proc. Despite the type, this function expects an
1096  * argb_t buffer.
1097  */
1098 static void
1099 store_scanline_generic_float (bits_image_t *  image,
1100                               int             x,
1101                               int             y,
1102                               int             width,
1103                               const uint32_t *values)
1104 {
1105     uint32_t *argb8_pixels;
1106
1107     assert (image->common.type == BITS);
1108
1109     argb8_pixels = pixman_malloc_ab (width, sizeof(uint32_t));
1110     if (!argb8_pixels)
1111         return;
1112
1113     /* Contract the scanline.  We could do this in place if values weren't
1114      * const.
1115      */
1116     pixman_contract_from_float (argb8_pixels, (argb_t *)values, width);
1117
1118     image->store_scanline_32 (image, x, y, width, argb8_pixels);
1119
1120     free (argb8_pixels);
1121 }
1122
1123 static void
1124 fetch_scanline_generic_float (bits_image_t *  image,
1125                               int             x,
1126                               int             y,
1127                               int             width,
1128                               uint32_t *      buffer,
1129                               const uint32_t *mask)
1130 {
1131     image->fetch_scanline_32 (image, x, y, width, buffer, NULL);
1132
1133     pixman_expand_to_float ((argb_t *)buffer, buffer, image->format, width);
1134 }
1135
1136 /* The 32_sRGB paths should be deleted after narrow processing
1137  * is no longer invoked for formats that are considered wide.
1138  * (Also see fetch_pixel_generic_lossy_32) */
1139 static void
1140 fetch_scanline_a8r8g8b8_32_sRGB (bits_image_t   *image,
1141                                  int             x,
1142                                  int             y,
1143                                  int             width,
1144                                  uint32_t       *buffer,
1145                                  const uint32_t *mask)
1146 {
1147     const uint32_t *bits = image->bits + y * image->rowstride;
1148     const uint32_t *pixel = (uint32_t *)bits + x;
1149     const uint32_t *end = pixel + width;
1150     uint32_t tmp;
1151     
1152     while (pixel < end)
1153     {
1154         uint8_t a, r, g, b;
1155
1156         tmp = READ (image, pixel++);
1157
1158         a = (tmp >> 24) & 0xff;
1159         r = (tmp >> 16) & 0xff;
1160         g = (tmp >> 8) & 0xff;
1161         b = (tmp >> 0) & 0xff;
1162
1163         r = to_linear[r] * 255.0f + 0.5f;
1164         g = to_linear[g] * 255.0f + 0.5f;
1165         b = to_linear[b] * 255.0f + 0.5f;
1166
1167         *buffer++ = (a << 24) | (r << 16) | (g << 8) | (b << 0);
1168     }
1169 }
1170
1171 static uint32_t
1172 fetch_pixel_a8r8g8b8_32_sRGB (bits_image_t *image,
1173                               int           offset,
1174                               int           line)
1175 {
1176     uint32_t *bits = image->bits + line * image->rowstride;
1177     uint32_t tmp = READ (image, bits + offset);
1178     uint8_t a, r, g, b;
1179
1180     a = (tmp >> 24) & 0xff;
1181     r = (tmp >> 16) & 0xff;
1182     g = (tmp >> 8) & 0xff;
1183     b = (tmp >> 0) & 0xff;
1184
1185     r = to_linear[r] * 255.0f + 0.5f;
1186     g = to_linear[g] * 255.0f + 0.5f;
1187     b = to_linear[b] * 255.0f + 0.5f;
1188
1189     return (a << 24) | (r << 16) | (g << 8) | (b << 0);
1190 }
1191
1192 static void
1193 store_scanline_a8r8g8b8_32_sRGB (bits_image_t   *image,
1194                                  int             x,
1195                                  int             y,
1196                                  int             width,
1197                                  const uint32_t *v)
1198 {
1199     uint32_t *bits = image->bits + image->rowstride * y;
1200     uint64_t *values = (uint64_t *)v;
1201     uint32_t *pixel = bits + x;
1202     uint64_t tmp;
1203     int i;
1204     
1205     for (i = 0; i < width; ++i)
1206     {
1207         uint8_t a, r, g, b;
1208
1209         tmp = values[i];
1210
1211         a = (tmp >> 24) & 0xff;
1212         r = (tmp >> 16) & 0xff;
1213         g = (tmp >> 8) & 0xff;
1214         b = (tmp >> 0) & 0xff;
1215
1216         r = to_srgb (r * (1/255.0f));
1217         g = to_srgb (g * (1/255.0f));
1218         b = to_srgb (b * (1/255.0f));
1219         
1220         WRITE (image, pixel++, a | (r << 16) | (g << 8) | (b << 0));
1221     }
1222 }
1223
1224 static argb_t
1225 fetch_pixel_generic_float (bits_image_t *image,
1226                            int           offset,
1227                            int           line)
1228 {
1229     uint32_t pixel32 = image->fetch_pixel_32 (image, offset, line);
1230     argb_t f;
1231
1232     pixman_expand_to_float (&f, &pixel32, image->format, 1);
1233
1234     return f;
1235 }
1236
1237 /*
1238  * XXX: The transformed fetch path only works at 32-bpp so far.  When all
1239  * paths have wide versions, this can be removed.
1240  *
1241  * WARNING: This function loses precision!
1242  */
1243 static uint32_t
1244 fetch_pixel_generic_lossy_32 (bits_image_t *image,
1245                               int           offset,
1246                               int           line)
1247 {
1248     argb_t pixel64 = image->fetch_pixel_float (image, offset, line);
1249     uint32_t result;
1250
1251     pixman_contract_from_float (&result, &pixel64, 1);
1252
1253     return result;
1254 }
1255
1256 typedef struct
1257 {
1258     pixman_format_code_t        format;
1259     fetch_scanline_t            fetch_scanline_32;
1260     fetch_scanline_t            fetch_scanline_float;
1261     fetch_pixel_32_t            fetch_pixel_32;
1262     fetch_pixel_float_t         fetch_pixel_float;
1263     store_scanline_t            store_scanline_32;
1264     store_scanline_t            store_scanline_float;
1265 } format_info_t;
1266
1267 #define FORMAT_INFO(format)                                             \
1268     {                                                                   \
1269         PIXMAN_ ## format,                                              \
1270             fetch_scanline_ ## format,                                  \
1271             fetch_scanline_generic_float,                               \
1272             fetch_pixel_ ## format,                                     \
1273             fetch_pixel_generic_float,                                  \
1274             store_scanline_ ## format,                                  \
1275             store_scanline_generic_float                                \
1276     }
1277
1278 static const format_info_t accessors[] =
1279 {
1280 /* 32 bpp formats */
1281     FORMAT_INFO (a8r8g8b8),
1282     FORMAT_INFO (x8r8g8b8),
1283     FORMAT_INFO (a8b8g8r8),
1284     FORMAT_INFO (x8b8g8r8),
1285     FORMAT_INFO (b8g8r8a8),
1286     FORMAT_INFO (b8g8r8x8),
1287     FORMAT_INFO (r8g8b8a8),
1288     FORMAT_INFO (r8g8b8x8),
1289     FORMAT_INFO (x14r6g6b6),
1290
1291 /* sRGB formats */
1292   { PIXMAN_a8r8g8b8_sRGB,
1293     fetch_scanline_a8r8g8b8_32_sRGB, fetch_scanline_a8r8g8b8_sRGB_float,
1294     fetch_pixel_a8r8g8b8_32_sRGB, fetch_pixel_a8r8g8b8_sRGB_float,
1295     store_scanline_a8r8g8b8_32_sRGB, store_scanline_a8r8g8b8_sRGB_float,
1296   },
1297
1298 /* 24bpp formats */
1299     FORMAT_INFO (r8g8b8),
1300     FORMAT_INFO (b8g8r8),
1301     
1302 /* 16bpp formats */
1303     FORMAT_INFO (r5g6b5),
1304     FORMAT_INFO (b5g6r5),
1305     
1306     FORMAT_INFO (a1r5g5b5),
1307     FORMAT_INFO (x1r5g5b5),
1308     FORMAT_INFO (a1b5g5r5),
1309     FORMAT_INFO (x1b5g5r5),
1310     FORMAT_INFO (a4r4g4b4),
1311     FORMAT_INFO (x4r4g4b4),
1312     FORMAT_INFO (a4b4g4r4),
1313     FORMAT_INFO (x4b4g4r4),
1314     
1315 /* 8bpp formats */
1316     FORMAT_INFO (a8),
1317     FORMAT_INFO (r3g3b2),
1318     FORMAT_INFO (b2g3r3),
1319     FORMAT_INFO (a2r2g2b2),
1320     FORMAT_INFO (a2b2g2r2),
1321     
1322     FORMAT_INFO (c8),
1323     
1324     FORMAT_INFO (g8),
1325     
1326 #define fetch_scanline_x4c4 fetch_scanline_c8
1327 #define fetch_pixel_x4c4 fetch_pixel_c8
1328 #define store_scanline_x4c4 store_scanline_c8
1329     FORMAT_INFO (x4c4),
1330     
1331 #define fetch_scanline_x4g4 fetch_scanline_g8
1332 #define fetch_pixel_x4g4 fetch_pixel_g8
1333 #define store_scanline_x4g4 store_scanline_g8
1334     FORMAT_INFO (x4g4),
1335     
1336     FORMAT_INFO (x4a4),
1337     
1338 /* 4bpp formats */
1339     FORMAT_INFO (a4),
1340     FORMAT_INFO (r1g2b1),
1341     FORMAT_INFO (b1g2r1),
1342     FORMAT_INFO (a1r1g1b1),
1343     FORMAT_INFO (a1b1g1r1),
1344     
1345     FORMAT_INFO (c4),
1346     
1347     FORMAT_INFO (g4),
1348     
1349 /* 1bpp formats */
1350     FORMAT_INFO (a1),
1351     FORMAT_INFO (g1),
1352     
1353 /* Wide formats */
1354     
1355     { PIXMAN_a2r10g10b10,
1356       NULL, fetch_scanline_a2r10g10b10_float,
1357       fetch_pixel_generic_lossy_32, fetch_pixel_a2r10g10b10_float,
1358       NULL, store_scanline_a2r10g10b10_float },
1359
1360     { PIXMAN_x2r10g10b10,
1361       NULL, fetch_scanline_x2r10g10b10_float,
1362       fetch_pixel_generic_lossy_32, fetch_pixel_x2r10g10b10_float,
1363       NULL, store_scanline_x2r10g10b10_float },
1364
1365     { PIXMAN_a2b10g10r10,
1366       NULL, fetch_scanline_a2b10g10r10_float,
1367       fetch_pixel_generic_lossy_32, fetch_pixel_a2b10g10r10_float,
1368       NULL, store_scanline_a2b10g10r10_float },
1369
1370     { PIXMAN_x2b10g10r10,
1371       NULL, fetch_scanline_x2b10g10r10_float,
1372       fetch_pixel_generic_lossy_32, fetch_pixel_x2b10g10r10_float,
1373       NULL, store_scanline_x2b10g10r10_float },
1374
1375 /* YUV formats */
1376     { PIXMAN_yuy2,
1377       fetch_scanline_yuy2, fetch_scanline_generic_float,
1378       fetch_pixel_yuy2, fetch_pixel_generic_float,
1379       NULL, NULL },
1380
1381     { PIXMAN_yv12,
1382       fetch_scanline_yv12, fetch_scanline_generic_float,
1383       fetch_pixel_yv12, fetch_pixel_generic_float,
1384       NULL, NULL },
1385     
1386     { PIXMAN_null },
1387 };
1388
1389 static void
1390 setup_accessors (bits_image_t *image)
1391 {
1392     const format_info_t *info = accessors;
1393     
1394     while (info->format != PIXMAN_null)
1395     {
1396         if (info->format == image->format)
1397         {
1398             image->fetch_scanline_32 = info->fetch_scanline_32;
1399             image->fetch_scanline_float = info->fetch_scanline_float;
1400             image->fetch_pixel_32 = info->fetch_pixel_32;
1401             image->fetch_pixel_float = info->fetch_pixel_float;
1402             image->store_scanline_32 = info->store_scanline_32;
1403             image->store_scanline_float = info->store_scanline_float;
1404             
1405             return;
1406         }
1407         
1408         info++;
1409     }
1410 }
1411
1412 #ifndef PIXMAN_FB_ACCESSORS
1413 void
1414 _pixman_bits_image_setup_accessors_accessors (bits_image_t *image);
1415
1416 void
1417 _pixman_bits_image_setup_accessors (bits_image_t *image)
1418 {
1419     if (image->read_func || image->write_func)
1420         _pixman_bits_image_setup_accessors_accessors (image);
1421     else
1422         setup_accessors (image);
1423 }
1424
1425 #else
1426
1427 void
1428 _pixman_bits_image_setup_accessors_accessors (bits_image_t *image)
1429 {
1430     setup_accessors (image);
1431 }
1432
1433 #endif