Home | History | Annotate | Line # | Download | only in pixman
      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 <pixman-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     ((uint32_t)(READ (img, (((uint8_t *)(l)) + ((o) * 3) + 0)) << 16)    |       \
     72      (uint32_t)(READ (img, (((uint8_t *)(l)) + ((o) * 3) + 1)) << 8)     |       \
     73      (uint32_t)(READ (img, (((uint8_t *)(l)) + ((o) * 3) + 2)) << 0))
     74 #else
     75 #define FETCH_24(img,l,o)						\
     76     ((uint32_t)(READ (img, (((uint8_t *)(l)) + ((o) * 3) + 0)) << 0)	|	\
     77      (uint32_t)(READ (img, (((uint8_t *)(l)) + ((o) * 3) + 1)) << 8)	|	\
     78      (uint32_t)(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 = 1U << (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 = 1U << ((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 MAYBE_UNUSED
    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 static void
    614 fetch_scanline_r8g8b8_sRGB_float (bits_image_t *  image,
    615 				  int             x,
    616 				  int             y,
    617 				  int             width,
    618 				  uint32_t *      b,
    619 				  const uint32_t *mask)
    620 {
    621     const uint8_t *bits = (uint8_t *)(image->bits + y * image->rowstride);
    622     argb_t *buffer = (argb_t *)b;
    623     int i;
    624     for (i = x; i < width; ++i)
    625     {
    626 	uint32_t p = FETCH_24 (image, bits, i);
    627 	argb_t *argb = buffer;
    628 
    629 	argb->a = 1.0f;
    630 
    631 	argb->r = to_linear[(p >> 16) & 0xff];
    632 	argb->g = to_linear[(p >>  8) & 0xff];
    633 	argb->b = to_linear[(p >>  0) & 0xff];
    634 
    635 	buffer++;
    636     }
    637 }
    638 
    639 /* Expects a float buffer */
    640 static void
    641 fetch_scanline_a2r10g10b10_float (bits_image_t *  image,
    642 				  int             x,
    643 				  int             y,
    644 				  int             width,
    645 				  uint32_t *      b,
    646 				  const uint32_t *mask)
    647 {
    648     const uint32_t *bits = image->bits + y * image->rowstride;
    649     const uint32_t *pixel = bits + x;
    650     const uint32_t *end = pixel + width;
    651     argb_t *buffer = (argb_t *)b;
    652 
    653     while (pixel < end)
    654     {
    655 	uint32_t p = READ (image, pixel++);
    656 	uint64_t a = p >> 30;
    657 	uint64_t r = (p >> 20) & 0x3ff;
    658 	uint64_t g = (p >> 10) & 0x3ff;
    659 	uint64_t b = p & 0x3ff;
    660 
    661 	buffer->a = pixman_unorm_to_float (a, 2);
    662 	buffer->r = pixman_unorm_to_float (r, 10);
    663 	buffer->g = pixman_unorm_to_float (g, 10);
    664 	buffer->b = pixman_unorm_to_float (b, 10);
    665 
    666 	buffer++;
    667     }
    668 }
    669 
    670 /* Expects a float buffer */
    671 #ifndef PIXMAN_FB_ACCESSORS
    672 static void
    673 fetch_scanline_rgbf_float (bits_image_t   *image,
    674 			   int             x,
    675 			   int             y,
    676 			   int             width,
    677 			   uint32_t *      b,
    678 			   const uint32_t *mask)
    679 {
    680     const float *bits = (float *)image->bits + y * image->rowstride;
    681     const float *pixel = bits + x * 3;
    682     argb_t *buffer = (argb_t *)b;
    683 
    684     for (; width--; buffer++) {
    685 	buffer->r = *pixel++;
    686 	buffer->g = *pixel++;
    687 	buffer->b = *pixel++;
    688 	buffer->a = 1.f;
    689     }
    690 }
    691 
    692 static void
    693 fetch_scanline_rgbaf_float (bits_image_t   *image,
    694 			    int             x,
    695 			    int             y,
    696 			    int             width,
    697 			    uint32_t *      b,
    698 			    const uint32_t *mask)
    699 {
    700     const float *bits = (float *)image->bits + y * image->rowstride;
    701     const float *pixel = bits + x * 4;
    702     argb_t *buffer = (argb_t *)b;
    703 
    704     for (; width--; buffer++) {
    705 	buffer->r = *pixel++;
    706 	buffer->g = *pixel++;
    707 	buffer->b = *pixel++;
    708 	buffer->a = *pixel++;
    709     }
    710 }
    711 #endif
    712 
    713 static void
    714 fetch_scanline_a16b16g16r16_float (bits_image_t *  image,
    715 				   int             x,
    716 				   int             y,
    717 				   int             width,
    718 				   uint32_t *      b,
    719 				   const uint32_t *mask)
    720 {
    721     const uint64_t *bits = (uint64_t *)(image->bits + y * image->rowstride);
    722     const uint64_t *pixel = bits + x;
    723     const uint64_t *end = pixel + width;
    724     argb_t *buffer = (argb_t *)b;
    725 
    726     while (pixel < end)
    727     {
    728 	uint64_t p = READ (image, pixel++);
    729 	uint64_t a = (p >> 48) & 0xffff;
    730 	uint64_t b = (p >> 32) & 0xffff;
    731 	uint64_t g = (p >> 16) & 0xffff;
    732 	uint64_t r = (p >> 0) & 0xffff;
    733 
    734 	buffer->a = pixman_unorm_to_float (a, 16);
    735 	buffer->r = pixman_unorm_to_float (r, 16);
    736 	buffer->g = pixman_unorm_to_float (g, 16);
    737 	buffer->b = pixman_unorm_to_float (b, 16);
    738 
    739 	buffer++;
    740     }
    741 }
    742 
    743 static void
    744 fetch_scanline_x2r10g10b10_float (bits_image_t   *image,
    745 				  int             x,
    746 				  int             y,
    747 				  int             width,
    748 				  uint32_t *      b,
    749 				  const uint32_t *mask)
    750 {
    751     const uint32_t *bits = image->bits + y * image->rowstride;
    752     const uint32_t *pixel = (uint32_t *)bits + x;
    753     const uint32_t *end = pixel + width;
    754     argb_t *buffer = (argb_t *)b;
    755 
    756     while (pixel < end)
    757     {
    758 	uint32_t p = READ (image, pixel++);
    759 	uint64_t r = (p >> 20) & 0x3ff;
    760 	uint64_t g = (p >> 10) & 0x3ff;
    761 	uint64_t b = p & 0x3ff;
    762 
    763 	buffer->a = 1.0;
    764 	buffer->r = pixman_unorm_to_float (r, 10);
    765 	buffer->g = pixman_unorm_to_float (g, 10);
    766 	buffer->b = pixman_unorm_to_float (b, 10);
    767 
    768 	buffer++;
    769     }
    770 }
    771 
    772 /* Expects a float buffer */
    773 static void
    774 fetch_scanline_a2b10g10r10_float (bits_image_t   *image,
    775 				  int             x,
    776 				  int             y,
    777 				  int             width,
    778 				  uint32_t *      b,
    779 				  const uint32_t *mask)
    780 {
    781     const uint32_t *bits = image->bits + y * image->rowstride;
    782     const uint32_t *pixel = bits + x;
    783     const uint32_t *end = pixel + width;
    784     argb_t *buffer = (argb_t *)b;
    785 
    786     while (pixel < end)
    787     {
    788 	uint32_t p = READ (image, pixel++);
    789 	uint64_t a = p >> 30;
    790 	uint64_t b = (p >> 20) & 0x3ff;
    791 	uint64_t g = (p >> 10) & 0x3ff;
    792 	uint64_t r = p & 0x3ff;
    793 
    794 	buffer->a = pixman_unorm_to_float (a, 2);
    795 	buffer->r = pixman_unorm_to_float (r, 10);
    796 	buffer->g = pixman_unorm_to_float (g, 10);
    797 	buffer->b = pixman_unorm_to_float (b, 10);
    798 
    799 	buffer++;
    800     }
    801 }
    802 
    803 /* Expects a float buffer */
    804 static void
    805 fetch_scanline_x2b10g10r10_float (bits_image_t   *image,
    806 				  int             x,
    807 				  int             y,
    808 				  int             width,
    809 				  uint32_t *      b,
    810 				  const uint32_t *mask)
    811 {
    812     const uint32_t *bits = image->bits + y * image->rowstride;
    813     const uint32_t *pixel = (uint32_t *)bits + x;
    814     const uint32_t *end = pixel + width;
    815     argb_t *buffer = (argb_t *)b;
    816 
    817     while (pixel < end)
    818     {
    819 	uint32_t p = READ (image, pixel++);
    820 	uint64_t b = (p >> 20) & 0x3ff;
    821 	uint64_t g = (p >> 10) & 0x3ff;
    822 	uint64_t r = p & 0x3ff;
    823 
    824 	buffer->a = 1.0;
    825 	buffer->r = pixman_unorm_to_float (r, 10);
    826 	buffer->g = pixman_unorm_to_float (g, 10);
    827 	buffer->b = pixman_unorm_to_float (b, 10);
    828 
    829 	buffer++;
    830     }
    831 }
    832 
    833 static void
    834 fetch_scanline_yuy2 (bits_image_t   *image,
    835                      int             x,
    836                      int             line,
    837                      int             width,
    838                      uint32_t *      buffer,
    839                      const uint32_t *mask)
    840 {
    841     const uint32_t *bits = image->bits + image->rowstride * line;
    842     int i;
    843 
    844     for (i = 0; i < width; i++)
    845     {
    846 	int16_t y, u, v;
    847 	int32_t r, g, b;
    848 
    849 	y = ((uint8_t *) bits)[(x + i) << 1] - 16;
    850 	u = ((uint8_t *) bits)[(((x + i) << 1) & - 4) + 1] - 128;
    851 	v = ((uint8_t *) bits)[(((x + i) << 1) & - 4) + 3] - 128;
    852 
    853 	/* R = 1.164(Y - 16) + 1.596(V - 128) */
    854 	r = 0x012b27 * y + 0x019a2e * v;
    855 	/* G = 1.164(Y - 16) - 0.813(V - 128) - 0.391(U - 128) */
    856 	g = 0x012b27 * y - 0x00d0f2 * v - 0x00647e * u;
    857 	/* B = 1.164(Y - 16) + 2.018(U - 128) */
    858 	b = 0x012b27 * y + 0x0206a2 * u;
    859 
    860 	*buffer++ = 0xff000000 |
    861 	    (r >= 0 ? r < 0x1000000 ? r         & 0xff0000 : 0xff0000 : 0) |
    862 	    (g >= 0 ? g < 0x1000000 ? (g >> 8)  & 0x00ff00 : 0x00ff00 : 0) |
    863 	    (b >= 0 ? b < 0x1000000 ? (b >> 16) & 0x0000ff : 0x0000ff : 0);
    864     }
    865 }
    866 
    867 static void
    868 fetch_scanline_yv12 (bits_image_t   *image,
    869                      int             x,
    870                      int             line,
    871                      int             width,
    872                      uint32_t *      buffer,
    873                      const uint32_t *mask)
    874 {
    875     YV12_SETUP (image);
    876     uint8_t *y_line = YV12_Y (line);
    877     uint8_t *u_line = YV12_U (line);
    878     uint8_t *v_line = YV12_V (line);
    879     int i;
    880 
    881     for (i = 0; i < width; i++)
    882     {
    883 	int16_t y, u, v;
    884 	int32_t r, g, b;
    885 
    886 	y = y_line[x + i] - 16;
    887 	u = u_line[(x + i) >> 1] - 128;
    888 	v = v_line[(x + i) >> 1] - 128;
    889 
    890 	/* R = 1.164(Y - 16) + 1.596(V - 128) */
    891 	r = 0x012b27 * y + 0x019a2e * v;
    892 	/* G = 1.164(Y - 16) - 0.813(V - 128) - 0.391(U - 128) */
    893 	g = 0x012b27 * y - 0x00d0f2 * v - 0x00647e * u;
    894 	/* B = 1.164(Y - 16) + 2.018(U - 128) */
    895 	b = 0x012b27 * y + 0x0206a2 * u;
    896 
    897 	*buffer++ = 0xff000000 |
    898 	    (r >= 0 ? r < 0x1000000 ? r         & 0xff0000 : 0xff0000 : 0) |
    899 	    (g >= 0 ? g < 0x1000000 ? (g >> 8)  & 0x00ff00 : 0x00ff00 : 0) |
    900 	    (b >= 0 ? b < 0x1000000 ? (b >> 16) & 0x0000ff : 0x0000ff : 0);
    901     }
    902 }
    903 
    904 /**************************** Pixel wise fetching *****************************/
    905 
    906 #ifndef PIXMAN_FB_ACCESSORS
    907 static argb_t
    908 fetch_pixel_rgbf_float (bits_image_t *image,
    909 			int	    offset,
    910 			int	    line)
    911 {
    912     float *bits = (float *)image->bits + line * image->rowstride;
    913     argb_t argb;
    914 
    915     argb.r = bits[offset * 3];
    916     argb.g = bits[offset * 3 + 1];
    917     argb.b = bits[offset * 3 + 2];
    918     argb.a = 1.f;
    919 
    920     return argb;
    921 }
    922 
    923 static argb_t
    924 fetch_pixel_rgbaf_float (bits_image_t *image,
    925 			 int	    offset,
    926 			 int	    line)
    927 {
    928     float *bits = (float *)image->bits + line * image->rowstride;
    929     argb_t argb;
    930 
    931     argb.r = bits[offset * 4];
    932     argb.g = bits[offset * 4 + 1];
    933     argb.b = bits[offset * 4 + 2];
    934     argb.a = bits[offset * 4 + 3];
    935 
    936     return argb;
    937 }
    938 #endif
    939 
    940 static argb_t
    941 fetch_pixel_a16b16g16r16_float (bits_image_t *image,
    942 				int           offset,
    943 				int           line)
    944 {
    945     uint64_t *bits = (uint64_t *)(image->bits + line * image->rowstride);
    946     uint64_t p = READ (image, bits + offset);
    947     uint64_t a = (p >> 48) & 0xffff;
    948     uint64_t b = (p >> 32) & 0xffff;
    949     uint64_t g = (p >> 16) & 0xffff;
    950     uint64_t r = (p >> 0)  & 0xffff;
    951     argb_t argb;
    952 
    953     argb.a = pixman_unorm_to_float (a, 16);
    954     argb.r = pixman_unorm_to_float (r, 16);
    955     argb.g = pixman_unorm_to_float (g, 16);
    956     argb.b = pixman_unorm_to_float (b, 16);
    957 
    958     return argb;
    959 }
    960 
    961 static argb_t
    962 fetch_pixel_x2r10g10b10_float (bits_image_t *image,
    963 			       int	   offset,
    964 			       int           line)
    965 {
    966     uint32_t *bits = image->bits + line * image->rowstride;
    967     uint32_t p = READ (image, bits + offset);
    968     uint64_t r = (p >> 20) & 0x3ff;
    969     uint64_t g = (p >> 10) & 0x3ff;
    970     uint64_t b = p & 0x3ff;
    971     argb_t argb;
    972 
    973     argb.a = 1.0;
    974     argb.r = pixman_unorm_to_float (r, 10);
    975     argb.g = pixman_unorm_to_float (g, 10);
    976     argb.b = pixman_unorm_to_float (b, 10);
    977 
    978     return argb;
    979 }
    980 
    981 static argb_t
    982 fetch_pixel_a2r10g10b10_float (bits_image_t *image,
    983 			       int	     offset,
    984 			       int           line)
    985 {
    986     uint32_t *bits = image->bits + line * image->rowstride;
    987     uint32_t p = READ (image, bits + offset);
    988     uint64_t a = p >> 30;
    989     uint64_t r = (p >> 20) & 0x3ff;
    990     uint64_t g = (p >> 10) & 0x3ff;
    991     uint64_t b = p & 0x3ff;
    992     argb_t argb;
    993 
    994     argb.a = pixman_unorm_to_float (a, 2);
    995     argb.r = pixman_unorm_to_float (r, 10);
    996     argb.g = pixman_unorm_to_float (g, 10);
    997     argb.b = pixman_unorm_to_float (b, 10);
    998 
    999     return argb;
   1000 }
   1001 
   1002 static argb_t
   1003 fetch_pixel_a2b10g10r10_float (bits_image_t *image,
   1004 			       int           offset,
   1005 			       int           line)
   1006 {
   1007     uint32_t *bits = image->bits + line * image->rowstride;
   1008     uint32_t p = READ (image, bits + offset);
   1009     uint64_t a = p >> 30;
   1010     uint64_t b = (p >> 20) & 0x3ff;
   1011     uint64_t g = (p >> 10) & 0x3ff;
   1012     uint64_t r = p & 0x3ff;
   1013     argb_t argb;
   1014 
   1015     argb.a = pixman_unorm_to_float (a, 2);
   1016     argb.r = pixman_unorm_to_float (r, 10);
   1017     argb.g = pixman_unorm_to_float (g, 10);
   1018     argb.b = pixman_unorm_to_float (b, 10);
   1019 
   1020     return argb;
   1021 }
   1022 
   1023 static argb_t
   1024 fetch_pixel_x2b10g10r10_float (bits_image_t *image,
   1025 			       int           offset,
   1026 			       int           line)
   1027 {
   1028     uint32_t *bits = image->bits + line * image->rowstride;
   1029     uint32_t p = READ (image, bits + offset);
   1030     uint64_t b = (p >> 20) & 0x3ff;
   1031     uint64_t g = (p >> 10) & 0x3ff;
   1032     uint64_t r = p & 0x3ff;
   1033     argb_t argb;
   1034 
   1035     argb.a = 1.0;
   1036     argb.r = pixman_unorm_to_float (r, 10);
   1037     argb.g = pixman_unorm_to_float (g, 10);
   1038     argb.b = pixman_unorm_to_float (b, 10);
   1039 
   1040     return argb;
   1041 }
   1042 
   1043 static argb_t
   1044 fetch_pixel_a8r8g8b8_sRGB_float (bits_image_t *image,
   1045 				 int	       offset,
   1046 				 int           line)
   1047 {
   1048     uint32_t *bits = image->bits + line * image->rowstride;
   1049     uint32_t p = READ (image, bits + offset);
   1050     argb_t argb;
   1051 
   1052     argb.a = pixman_unorm_to_float ((p >> 24) & 0xff, 8);
   1053 
   1054     argb.r = to_linear [(p >> 16) & 0xff];
   1055     argb.g = to_linear [(p >>  8) & 0xff];
   1056     argb.b = to_linear [(p >>  0) & 0xff];
   1057 
   1058     return argb;
   1059 }
   1060 
   1061 static argb_t
   1062 fetch_pixel_r8g8b8_sRGB_float (bits_image_t *image,
   1063 			       int	     offset,
   1064 			       int           line)
   1065 {
   1066     uint8_t *bits = (uint8_t *)(image->bits + line * image->rowstride);
   1067     uint32_t p = FETCH_24 (image, bits, offset);
   1068     argb_t argb;
   1069 
   1070     argb.a = 1.0f;
   1071 
   1072     argb.r = to_linear[(p >> 16) & 0xff];
   1073     argb.g = to_linear[(p >>  8) & 0xff];
   1074     argb.b = to_linear[(p >>  0) & 0xff];
   1075 
   1076     return argb;
   1077 }
   1078 
   1079 static uint32_t
   1080 fetch_pixel_yuy2 (bits_image_t *image,
   1081 		  int           offset,
   1082 		  int           line)
   1083 {
   1084     const uint32_t *bits = image->bits + image->rowstride * line;
   1085 
   1086     int16_t y, u, v;
   1087     int32_t r, g, b;
   1088 
   1089     y = ((uint8_t *) bits)[offset << 1] - 16;
   1090     u = ((uint8_t *) bits)[((offset << 1) & - 4) + 1] - 128;
   1091     v = ((uint8_t *) bits)[((offset << 1) & - 4) + 3] - 128;
   1092 
   1093     /* R = 1.164(Y - 16) + 1.596(V - 128) */
   1094     r = 0x012b27 * y + 0x019a2e * v;
   1095 
   1096     /* G = 1.164(Y - 16) - 0.813(V - 128) - 0.391(U - 128) */
   1097     g = 0x012b27 * y - 0x00d0f2 * v - 0x00647e * u;
   1098 
   1099     /* B = 1.164(Y - 16) + 2.018(U - 128) */
   1100     b = 0x012b27 * y + 0x0206a2 * u;
   1101 
   1102     return 0xff000000 |
   1103 	(r >= 0 ? r < 0x1000000 ? r         & 0xff0000 : 0xff0000 : 0) |
   1104 	(g >= 0 ? g < 0x1000000 ? (g >> 8)  & 0x00ff00 : 0x00ff00 : 0) |
   1105 	(b >= 0 ? b < 0x1000000 ? (b >> 16) & 0x0000ff : 0x0000ff : 0);
   1106 }
   1107 
   1108 static uint32_t
   1109 fetch_pixel_yv12 (bits_image_t *image,
   1110 		  int           offset,
   1111 		  int           line)
   1112 {
   1113     YV12_SETUP (image);
   1114     int16_t y = YV12_Y (line)[offset] - 16;
   1115     int16_t u = YV12_U (line)[offset >> 1] - 128;
   1116     int16_t v = YV12_V (line)[offset >> 1] - 128;
   1117     int32_t r, g, b;
   1118 
   1119     /* R = 1.164(Y - 16) + 1.596(V - 128) */
   1120     r = 0x012b27 * y + 0x019a2e * v;
   1121 
   1122     /* G = 1.164(Y - 16) - 0.813(V - 128) - 0.391(U - 128) */
   1123     g = 0x012b27 * y - 0x00d0f2 * v - 0x00647e * u;
   1124 
   1125     /* B = 1.164(Y - 16) + 2.018(U - 128) */
   1126     b = 0x012b27 * y + 0x0206a2 * u;
   1127 
   1128     return 0xff000000 |
   1129 	(r >= 0 ? r < 0x1000000 ? r         & 0xff0000 : 0xff0000 : 0) |
   1130 	(g >= 0 ? g < 0x1000000 ? (g >> 8)  & 0x00ff00 : 0x00ff00 : 0) |
   1131 	(b >= 0 ? b < 0x1000000 ? (b >> 16) & 0x0000ff : 0x0000ff : 0);
   1132 }
   1133 
   1134 /*********************************** Store ************************************/
   1135 
   1136 #ifndef PIXMAN_FB_ACCESSORS
   1137 static void
   1138 store_scanline_rgbaf_float (bits_image_t *  image,
   1139 			    int             x,
   1140 			    int             y,
   1141 			    int             width,
   1142 			    const uint32_t *v)
   1143 {
   1144     float *bits = (float *)image->bits + image->rowstride * y + 4 * x;
   1145     const argb_t *values = (argb_t *)v;
   1146 
   1147     for (; width; width--, values++)
   1148     {
   1149 	*bits++ = values->r;
   1150 	*bits++ = values->g;
   1151 	*bits++ = values->b;
   1152 	*bits++ = values->a;
   1153     }
   1154 }
   1155 
   1156 static void
   1157 store_scanline_rgbf_float (bits_image_t *  image,
   1158 			   int             x,
   1159 			   int             y,
   1160 			   int             width,
   1161 			   const uint32_t *v)
   1162 {
   1163     float *bits = (float *)image->bits + image->rowstride * y + 3 * x;
   1164     const argb_t *values = (argb_t *)v;
   1165 
   1166     for (; width; width--, values++)
   1167     {
   1168 	*bits++ = values->r;
   1169 	*bits++ = values->g;
   1170 	*bits++ = values->b;
   1171     }
   1172 }
   1173 #endif
   1174 
   1175 static void
   1176 store_scanline_a16b16g16r16_float (bits_image_t *  image,
   1177 				   int             x,
   1178 				   int             y,
   1179 				   int             width,
   1180 				   const uint32_t *v)
   1181 {
   1182     uint64_t *bits = (uint64_t *)(image->bits + image->rowstride * y);
   1183     uint64_t *pixel = bits + x;
   1184     argb_t *values = (argb_t *)v;
   1185     int i;
   1186 
   1187     for (i = 0; i < width; ++i)
   1188     {
   1189 	uint64_t a, r, g, b;
   1190 
   1191 	a = pixman_float_to_unorm (values[i].a, 16);
   1192 	r = pixman_float_to_unorm (values[i].r, 16);
   1193 	g = pixman_float_to_unorm (values[i].g, 16);
   1194 	b = pixman_float_to_unorm (values[i].b, 16);
   1195 
   1196 	WRITE (image, pixel++,
   1197 	       (a << 48) | (b << 32) | (g << 16) | (r << 0));
   1198     }
   1199 }
   1200 
   1201 static void
   1202 store_scanline_a2r10g10b10_float (bits_image_t *  image,
   1203 				  int             x,
   1204 				  int             y,
   1205 				  int             width,
   1206 				  const uint32_t *v)
   1207 {
   1208     uint32_t *bits = image->bits + image->rowstride * y;
   1209     uint32_t *pixel = bits + x;
   1210     argb_t *values = (argb_t *)v;
   1211     int i;
   1212 
   1213     for (i = 0; i < width; ++i)
   1214     {
   1215 	uint32_t a, r, g, b;
   1216 
   1217 	a = pixman_float_to_unorm (values[i].a, 2);
   1218 	r = pixman_float_to_unorm (values[i].r, 10);
   1219 	g = pixman_float_to_unorm (values[i].g, 10);
   1220 	b = pixman_float_to_unorm (values[i].b, 10);
   1221 
   1222 	WRITE (image, pixel++,
   1223 	       (a << 30) | (r << 20) | (g << 10) | b);
   1224     }
   1225 }
   1226 
   1227 static void
   1228 store_scanline_x2r10g10b10_float (bits_image_t *  image,
   1229 				  int             x,
   1230 				  int             y,
   1231 				  int             width,
   1232 				  const uint32_t *v)
   1233 {
   1234     uint32_t *bits = image->bits + image->rowstride * y;
   1235     uint32_t *pixel = bits + x;
   1236     argb_t *values = (argb_t *)v;
   1237     int i;
   1238 
   1239     for (i = 0; i < width; ++i)
   1240     {
   1241 	uint32_t r, g, b;
   1242 
   1243 	r = pixman_float_to_unorm (values[i].r, 10);
   1244 	g = pixman_float_to_unorm (values[i].g, 10);
   1245 	b = pixman_float_to_unorm (values[i].b, 10);
   1246 
   1247 	WRITE (image, pixel++,
   1248 	       (r << 20) | (g << 10) | b);
   1249     }
   1250 }
   1251 
   1252 static void
   1253 store_scanline_a2b10g10r10_float (bits_image_t *  image,
   1254 				  int             x,
   1255 				  int             y,
   1256 				  int             width,
   1257 				  const uint32_t *v)
   1258 {
   1259     uint32_t *bits = image->bits + image->rowstride * y;
   1260     uint32_t *pixel = bits + x;
   1261     argb_t *values = (argb_t *)v;
   1262     int i;
   1263 
   1264     for (i = 0; i < width; ++i)
   1265     {
   1266 	uint32_t a, r, g, b;
   1267 
   1268 	a = pixman_float_to_unorm (values[i].a, 2);
   1269 	r = pixman_float_to_unorm (values[i].r, 10);
   1270 	g = pixman_float_to_unorm (values[i].g, 10);
   1271 	b = pixman_float_to_unorm (values[i].b, 10);
   1272 
   1273 	WRITE (image, pixel++,
   1274 	       (a << 30) | (b << 20) | (g << 10) | r);
   1275     }
   1276 }
   1277 
   1278 static void
   1279 store_scanline_x2b10g10r10_float (bits_image_t *  image,
   1280 				  int             x,
   1281 				  int             y,
   1282 				  int             width,
   1283 				  const uint32_t *v)
   1284 {
   1285     uint32_t *bits = image->bits + image->rowstride * y;
   1286     uint32_t *pixel = bits + x;
   1287     argb_t *values = (argb_t *)v;
   1288     int i;
   1289 
   1290     for (i = 0; i < width; ++i)
   1291     {
   1292 	uint32_t r, g, b;
   1293 
   1294 	r = pixman_float_to_unorm (values[i].r, 10);
   1295 	g = pixman_float_to_unorm (values[i].g, 10);
   1296 	b = pixman_float_to_unorm (values[i].b, 10);
   1297 
   1298 	WRITE (image, pixel++,
   1299 	       (b << 20) | (g << 10) | r);
   1300     }
   1301 }
   1302 
   1303 static void
   1304 store_scanline_a8r8g8b8_sRGB_float (bits_image_t *  image,
   1305 				    int             x,
   1306 				    int             y,
   1307 				    int             width,
   1308 				    const uint32_t *v)
   1309 {
   1310     uint32_t *bits = image->bits + image->rowstride * y;
   1311     uint32_t *pixel = bits + x;
   1312     argb_t *values = (argb_t *)v;
   1313     int i;
   1314 
   1315     for (i = 0; i < width; ++i)
   1316     {
   1317 	uint32_t a, r, g, b;
   1318 
   1319 	a = pixman_float_to_unorm (values[i].a, 8);
   1320 	r = to_srgb (values[i].r);
   1321 	g = to_srgb (values[i].g);
   1322 	b = to_srgb (values[i].b);
   1323 
   1324 	WRITE (image, pixel++,
   1325 	       (a << 24) | (r << 16) | (g << 8) | b);
   1326     }
   1327 }
   1328 
   1329 static void
   1330 store_scanline_r8g8b8_sRGB_float (bits_image_t *  image,
   1331 				  int             x,
   1332 				  int             y,
   1333 				  int             width,
   1334 				  const uint32_t *v)
   1335 {
   1336     uint8_t *bits = (uint8_t *)(image->bits + image->rowstride * y) + 3 * x;
   1337     argb_t *values = (argb_t *)v;
   1338     int i;
   1339 
   1340     for (i = 0; i < width; ++i)
   1341     {
   1342 	uint32_t r, g, b, rgb;
   1343 
   1344 	r = to_srgb (values[i].r);
   1345 	g = to_srgb (values[i].g);
   1346 	b = to_srgb (values[i].b);
   1347 
   1348 	rgb = (r << 16) | (g << 8) | b;
   1349 
   1350 	STORE_24 (image, bits, i, rgb);
   1351     }
   1352 }
   1353 
   1354 /*
   1355  * Contracts a floating point image to 32bpp and then stores it using a
   1356  * regular 32-bit store proc. Despite the type, this function expects an
   1357  * argb_t buffer.
   1358  */
   1359 static void
   1360 store_scanline_generic_float (bits_image_t *  image,
   1361 			      int             x,
   1362 			      int             y,
   1363 			      int             width,
   1364 			      const uint32_t *values)
   1365 {
   1366     uint32_t *argb8_pixels;
   1367 
   1368     assert (image->common.type == BITS);
   1369 
   1370     argb8_pixels = pixman_malloc_ab (width, sizeof(uint32_t));
   1371     if (!argb8_pixels)
   1372 	return;
   1373 
   1374     /* Contract the scanline.  We could do this in place if values weren't
   1375      * const.
   1376      */
   1377     pixman_contract_from_float (argb8_pixels, (argb_t *)values, width);
   1378 
   1379     image->store_scanline_32 (image, x, y, width, argb8_pixels);
   1380 
   1381     free (argb8_pixels);
   1382 }
   1383 
   1384 static void
   1385 fetch_scanline_generic_float (bits_image_t *  image,
   1386 			      int	      x,
   1387 			      int	      y,
   1388 			      int	      width,
   1389 			      uint32_t *      buffer,
   1390 			      const uint32_t *mask)
   1391 {
   1392     image->fetch_scanline_32 (image, x, y, width, buffer, NULL);
   1393 
   1394     pixman_expand_to_float ((argb_t *)buffer, buffer, image->format, width);
   1395 }
   1396 
   1397 /* The 32_sRGB paths should be deleted after narrow processing
   1398  * is no longer invoked for formats that are considered wide.
   1399  * (Also see fetch_pixel_generic_lossy_32) */
   1400 static void
   1401 fetch_scanline_a8r8g8b8_32_sRGB (bits_image_t   *image,
   1402                                  int             x,
   1403                                  int             y,
   1404                                  int             width,
   1405                                  uint32_t       *buffer,
   1406                                  const uint32_t *mask)
   1407 {
   1408     const uint32_t *bits = image->bits + y * image->rowstride;
   1409     const uint32_t *pixel = (uint32_t *)bits + x;
   1410     const uint32_t *end = pixel + width;
   1411     uint32_t tmp;
   1412 
   1413     while (pixel < end)
   1414     {
   1415 	uint32_t a, r, g, b;
   1416 
   1417 	tmp = READ (image, pixel++);
   1418 
   1419 	a = (tmp >> 24) & 0xff;
   1420 	r = (tmp >> 16) & 0xff;
   1421 	g = (tmp >> 8) & 0xff;
   1422 	b = (tmp >> 0) & 0xff;
   1423 
   1424 	r = to_linear[r] * 255.0f + 0.5f;
   1425 	g = to_linear[g] * 255.0f + 0.5f;
   1426 	b = to_linear[b] * 255.0f + 0.5f;
   1427 
   1428 	*buffer++ = (a << 24) | (r << 16) | (g << 8) | (b << 0);
   1429     }
   1430 }
   1431 
   1432 static void
   1433 fetch_scanline_r8g8b8_32_sRGB (bits_image_t   *image,
   1434                                int             x,
   1435                                int             y,
   1436                                int             width,
   1437                                uint32_t       *buffer,
   1438                                const uint32_t *mask)
   1439 {
   1440     const uint8_t *bits = (uint8_t *)(image->bits + y * image->rowstride) + 3 * x;
   1441     uint32_t tmp;
   1442     int i;
   1443 
   1444     for (i = 0; i < width; ++i)
   1445     {
   1446 	uint32_t a, r, g, b;
   1447 
   1448 	tmp = FETCH_24 (image, bits, i);
   1449 
   1450 	a = 0xff;
   1451 	r = (tmp >> 16) & 0xff;
   1452 	g = (tmp >> 8) & 0xff;
   1453 	b = (tmp >> 0) & 0xff;
   1454 
   1455 	r = to_linear[r] * 255.0f + 0.5f;
   1456 	g = to_linear[g] * 255.0f + 0.5f;
   1457 	b = to_linear[b] * 255.0f + 0.5f;
   1458 
   1459 	*buffer++ = (a << 24) | (r << 16) | (g << 8) | (b << 0);
   1460     }
   1461 }
   1462 
   1463 static uint32_t
   1464 fetch_pixel_a8r8g8b8_32_sRGB (bits_image_t *image,
   1465 			      int           offset,
   1466 			      int           line)
   1467 {
   1468     uint32_t *bits = image->bits + line * image->rowstride;
   1469     uint32_t tmp = READ (image, bits + offset);
   1470     uint32_t a, r, g, b;
   1471 
   1472     a = (tmp >> 24) & 0xff;
   1473     r = (tmp >> 16) & 0xff;
   1474     g = (tmp >> 8) & 0xff;
   1475     b = (tmp >> 0) & 0xff;
   1476 
   1477     r = to_linear[r] * 255.0f + 0.5f;
   1478     g = to_linear[g] * 255.0f + 0.5f;
   1479     b = to_linear[b] * 255.0f + 0.5f;
   1480 
   1481     return (a << 24) | (r << 16) | (g << 8) | (b << 0);
   1482 }
   1483 
   1484 static uint32_t
   1485 fetch_pixel_r8g8b8_32_sRGB (bits_image_t *image,
   1486 			    int           offset,
   1487 			    int           line)
   1488 {
   1489     uint8_t *bits = (uint8_t *)(image->bits + line * image->rowstride);
   1490     uint32_t tmp = FETCH_24 (image, bits, offset);
   1491     uint32_t a, r, g, b;
   1492 
   1493     a = 0xff;
   1494     r = (tmp >> 16) & 0xff;
   1495     g = (tmp >> 8) & 0xff;
   1496     b = (tmp >> 0) & 0xff;
   1497 
   1498     r = to_linear[r] * 255.0f + 0.5f;
   1499     g = to_linear[g] * 255.0f + 0.5f;
   1500     b = to_linear[b] * 255.0f + 0.5f;
   1501 
   1502     return (a << 24) | (r << 16) | (g << 8) | (b << 0);
   1503 }
   1504 
   1505 static void
   1506 store_scanline_a8r8g8b8_32_sRGB (bits_image_t   *image,
   1507                                  int             x,
   1508                                  int             y,
   1509                                  int             width,
   1510                                  const uint32_t *v)
   1511 {
   1512     uint32_t *bits = image->bits + image->rowstride * y;
   1513     uint64_t *values = (uint64_t *)v;
   1514     uint32_t *pixel = bits + x;
   1515     uint64_t tmp;
   1516     int i;
   1517 
   1518     for (i = 0; i < width; ++i)
   1519     {
   1520 	uint32_t a, r, g, b;
   1521 
   1522 	tmp = values[i];
   1523 
   1524 	a = (tmp >> 24) & 0xff;
   1525 	r = (tmp >> 16) & 0xff;
   1526 	g = (tmp >> 8) & 0xff;
   1527 	b = (tmp >> 0) & 0xff;
   1528 
   1529 	r = to_srgb (r * (1/255.0f));
   1530 	g = to_srgb (g * (1/255.0f));
   1531 	b = to_srgb (b * (1/255.0f));
   1532 
   1533 	WRITE (image, pixel++, a | (r << 16) | (g << 8) | (b << 0));
   1534     }
   1535 }
   1536 
   1537 static void
   1538 store_scanline_r8g8b8_32_sRGB (bits_image_t   *image,
   1539 			       int             x,
   1540                                int             y,
   1541                                int             width,
   1542                                const uint32_t *v)
   1543 {
   1544     uint8_t *bits = (uint8_t *)(image->bits + image->rowstride * y) + 3 * x;
   1545     uint64_t *values = (uint64_t *)v;
   1546     uint64_t tmp;
   1547     int i;
   1548 
   1549     for (i = 0; i < width; ++i)
   1550     {
   1551 	uint32_t r, g, b;
   1552 
   1553 	tmp = values[i];
   1554 
   1555 	r = (tmp >> 16) & 0xff;
   1556 	g = (tmp >> 8) & 0xff;
   1557 	b = (tmp >> 0) & 0xff;
   1558 
   1559 	r = to_srgb (r * (1/255.0f));
   1560 	g = to_srgb (g * (1/255.0f));
   1561 	b = to_srgb (b * (1/255.0f));
   1562 
   1563 	STORE_24 (image, bits, i, (r << 16) | (g << 8) | (b << 0));
   1564     }
   1565 }
   1566 
   1567 static argb_t
   1568 fetch_pixel_generic_float (bits_image_t *image,
   1569 			   int		 offset,
   1570 			   int           line)
   1571 {
   1572     uint32_t pixel32 = image->fetch_pixel_32 (image, offset, line);
   1573     argb_t f;
   1574 
   1575     pixman_expand_to_float (&f, &pixel32, image->format, 1);
   1576 
   1577     return f;
   1578 }
   1579 
   1580 /*
   1581  * XXX: The transformed fetch path only works at 32-bpp so far.  When all
   1582  * paths have wide versions, this can be removed.
   1583  *
   1584  * WARNING: This function loses precision!
   1585  */
   1586 static uint32_t
   1587 fetch_pixel_generic_lossy_32 (bits_image_t *image,
   1588 			      int           offset,
   1589 			      int           line)
   1590 {
   1591     argb_t pixel64 = image->fetch_pixel_float (image, offset, line);
   1592     uint32_t result;
   1593 
   1594     pixman_contract_from_float (&result, &pixel64, 1);
   1595 
   1596     return result;
   1597 }
   1598 
   1599 typedef struct
   1600 {
   1601     pixman_format_code_t	format;
   1602     fetch_scanline_t		fetch_scanline_32;
   1603     fetch_scanline_t		fetch_scanline_float;
   1604     fetch_pixel_32_t		fetch_pixel_32;
   1605     fetch_pixel_float_t		fetch_pixel_float;
   1606     store_scanline_t		store_scanline_32;
   1607     store_scanline_t		store_scanline_float;
   1608 } format_info_t;
   1609 
   1610 #define FORMAT_INFO(format) 						\
   1611     {									\
   1612 	PIXMAN_ ## format,						\
   1613 	    fetch_scanline_ ## format,					\
   1614 	    fetch_scanline_generic_float,				\
   1615 	    fetch_pixel_ ## format,					\
   1616 	    fetch_pixel_generic_float,					\
   1617 	    store_scanline_ ## format,					\
   1618 	    store_scanline_generic_float				\
   1619     }
   1620 
   1621 static const format_info_t accessors[] =
   1622 {
   1623 /* 32 bpp formats */
   1624     FORMAT_INFO (a8r8g8b8),
   1625     FORMAT_INFO (x8r8g8b8),
   1626     FORMAT_INFO (a8b8g8r8),
   1627     FORMAT_INFO (x8b8g8r8),
   1628     FORMAT_INFO (b8g8r8a8),
   1629     FORMAT_INFO (b8g8r8x8),
   1630     FORMAT_INFO (r8g8b8a8),
   1631     FORMAT_INFO (r8g8b8x8),
   1632     FORMAT_INFO (x14r6g6b6),
   1633 
   1634 /* sRGB formats */
   1635   { PIXMAN_a8r8g8b8_sRGB,
   1636     fetch_scanline_a8r8g8b8_32_sRGB, fetch_scanline_a8r8g8b8_sRGB_float,
   1637     fetch_pixel_a8r8g8b8_32_sRGB, fetch_pixel_a8r8g8b8_sRGB_float,
   1638     store_scanline_a8r8g8b8_32_sRGB, store_scanline_a8r8g8b8_sRGB_float,
   1639   },
   1640   { PIXMAN_r8g8b8_sRGB,
   1641     fetch_scanline_r8g8b8_32_sRGB, fetch_scanline_r8g8b8_sRGB_float,
   1642     fetch_pixel_r8g8b8_32_sRGB, fetch_pixel_r8g8b8_sRGB_float,
   1643     store_scanline_r8g8b8_32_sRGB, store_scanline_r8g8b8_sRGB_float,
   1644   },
   1645 
   1646 /* 24bpp formats */
   1647     FORMAT_INFO (r8g8b8),
   1648     FORMAT_INFO (b8g8r8),
   1649 
   1650 /* 16bpp formats */
   1651     FORMAT_INFO (r5g6b5),
   1652     FORMAT_INFO (b5g6r5),
   1653 
   1654     FORMAT_INFO (a1r5g5b5),
   1655     FORMAT_INFO (x1r5g5b5),
   1656     FORMAT_INFO (a1b5g5r5),
   1657     FORMAT_INFO (x1b5g5r5),
   1658     FORMAT_INFO (a4r4g4b4),
   1659     FORMAT_INFO (x4r4g4b4),
   1660     FORMAT_INFO (a4b4g4r4),
   1661     FORMAT_INFO (x4b4g4r4),
   1662 
   1663 /* 8bpp formats */
   1664     FORMAT_INFO (a8),
   1665     FORMAT_INFO (r3g3b2),
   1666     FORMAT_INFO (b2g3r3),
   1667     FORMAT_INFO (a2r2g2b2),
   1668     FORMAT_INFO (a2b2g2r2),
   1669 
   1670     FORMAT_INFO (c8),
   1671 
   1672     FORMAT_INFO (g8),
   1673 
   1674 #define fetch_scanline_x4c4 fetch_scanline_c8
   1675 #define fetch_pixel_x4c4 fetch_pixel_c8
   1676 #define store_scanline_x4c4 store_scanline_c8
   1677     FORMAT_INFO (x4c4),
   1678 
   1679 #define fetch_scanline_x4g4 fetch_scanline_g8
   1680 #define fetch_pixel_x4g4 fetch_pixel_g8
   1681 #define store_scanline_x4g4 store_scanline_g8
   1682     FORMAT_INFO (x4g4),
   1683 
   1684     FORMAT_INFO (x4a4),
   1685 
   1686 /* 4bpp formats */
   1687     FORMAT_INFO (a4),
   1688     FORMAT_INFO (r1g2b1),
   1689     FORMAT_INFO (b1g2r1),
   1690     FORMAT_INFO (a1r1g1b1),
   1691     FORMAT_INFO (a1b1g1r1),
   1692 
   1693     FORMAT_INFO (c4),
   1694 
   1695     FORMAT_INFO (g4),
   1696 
   1697 /* 1bpp formats */
   1698     FORMAT_INFO (a1),
   1699     FORMAT_INFO (g1),
   1700 
   1701 /* Wide formats */
   1702 #ifndef PIXMAN_FB_ACCESSORS
   1703     { PIXMAN_rgba_float,
   1704       NULL, fetch_scanline_rgbaf_float,
   1705       fetch_pixel_generic_lossy_32, fetch_pixel_rgbaf_float,
   1706       NULL, store_scanline_rgbaf_float },
   1707 
   1708     { PIXMAN_rgb_float,
   1709       NULL, fetch_scanline_rgbf_float,
   1710       fetch_pixel_generic_lossy_32, fetch_pixel_rgbf_float,
   1711       NULL, store_scanline_rgbf_float },
   1712 #endif
   1713     { PIXMAN_a16b16g16r16,
   1714       NULL, fetch_scanline_a16b16g16r16_float,
   1715       fetch_pixel_generic_lossy_32, fetch_pixel_a16b16g16r16_float,
   1716       NULL, store_scanline_a16b16g16r16_float },
   1717 
   1718     { PIXMAN_a2r10g10b10,
   1719       NULL, fetch_scanline_a2r10g10b10_float,
   1720       fetch_pixel_generic_lossy_32, fetch_pixel_a2r10g10b10_float,
   1721       NULL, store_scanline_a2r10g10b10_float },
   1722 
   1723     { PIXMAN_x2r10g10b10,
   1724       NULL, fetch_scanline_x2r10g10b10_float,
   1725       fetch_pixel_generic_lossy_32, fetch_pixel_x2r10g10b10_float,
   1726       NULL, store_scanline_x2r10g10b10_float },
   1727 
   1728     { PIXMAN_a2b10g10r10,
   1729       NULL, fetch_scanline_a2b10g10r10_float,
   1730       fetch_pixel_generic_lossy_32, fetch_pixel_a2b10g10r10_float,
   1731       NULL, store_scanline_a2b10g10r10_float },
   1732 
   1733     { PIXMAN_x2b10g10r10,
   1734       NULL, fetch_scanline_x2b10g10r10_float,
   1735       fetch_pixel_generic_lossy_32, fetch_pixel_x2b10g10r10_float,
   1736       NULL, store_scanline_x2b10g10r10_float },
   1737 
   1738 /* YUV formats */
   1739     { PIXMAN_yuy2,
   1740       fetch_scanline_yuy2, fetch_scanline_generic_float,
   1741       fetch_pixel_yuy2, fetch_pixel_generic_float,
   1742       NULL, NULL },
   1743 
   1744     { PIXMAN_yv12,
   1745       fetch_scanline_yv12, fetch_scanline_generic_float,
   1746       fetch_pixel_yv12, fetch_pixel_generic_float,
   1747       NULL, NULL },
   1748 
   1749     { PIXMAN_null },
   1750 };
   1751 
   1752 static void
   1753 setup_accessors (bits_image_t *image)
   1754 {
   1755     const format_info_t *info = accessors;
   1756 
   1757     while (info->format != PIXMAN_null)
   1758     {
   1759 	if (info->format == image->format)
   1760 	{
   1761 	    image->fetch_scanline_32 = info->fetch_scanline_32;
   1762 	    image->fetch_scanline_float = info->fetch_scanline_float;
   1763 	    image->fetch_pixel_32 = info->fetch_pixel_32;
   1764 	    image->fetch_pixel_float = info->fetch_pixel_float;
   1765 	    image->store_scanline_32 = info->store_scanline_32;
   1766 	    image->store_scanline_float = info->store_scanline_float;
   1767 
   1768 	    return;
   1769 	}
   1770 
   1771 	info++;
   1772     }
   1773 }
   1774 
   1775 #ifndef PIXMAN_FB_ACCESSORS
   1776 void
   1777 _pixman_bits_image_setup_accessors_accessors (bits_image_t *image);
   1778 
   1779 void
   1780 _pixman_bits_image_setup_accessors (bits_image_t *image)
   1781 {
   1782     if (image->read_func || image->write_func)
   1783 	_pixman_bits_image_setup_accessors_accessors (image);
   1784     else
   1785 	setup_accessors (image);
   1786 }
   1787 
   1788 #else
   1789 
   1790 void
   1791 _pixman_bits_image_setup_accessors_accessors (bits_image_t *image)
   1792 {
   1793     setup_accessors (image);
   1794 }
   1795 
   1796 #endif
   1797