tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

pixman-access.c (49952B)


      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