gfx/cairo/libpixman/src/pixman-access.c

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/gfx/cairo/libpixman/src/pixman-access.c	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,1492 @@
     1.4 +/*
     1.5 + *
     1.6 + * Copyright © 2000 Keith Packard, member of The XFree86 Project, Inc.
     1.7 + *             2005 Lars Knoll & Zack Rusin, Trolltech
     1.8 + *             2008 Aaron Plattner, NVIDIA Corporation
     1.9 + *
    1.10 + * Permission to use, copy, modify, distribute, and sell this software and its
    1.11 + * documentation for any purpose is hereby granted without fee, provided that
    1.12 + * the above copyright notice appear in all copies and that both that
    1.13 + * copyright notice and this permission notice appear in supporting
    1.14 + * documentation, and that the name of Keith Packard not be used in
    1.15 + * advertising or publicity pertaining to distribution of the software without
    1.16 + * specific, written prior permission.  Keith Packard makes no
    1.17 + * representations about the suitability of this software for any purpose.  It
    1.18 + * is provided "as is" without express or implied warranty.
    1.19 + *
    1.20 + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
    1.21 + * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
    1.22 + * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
    1.23 + * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
    1.24 + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
    1.25 + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
    1.26 + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
    1.27 + * SOFTWARE.
    1.28 + */
    1.29 +
    1.30 +#ifdef HAVE_CONFIG_H
    1.31 +#include <config.h>
    1.32 +#endif
    1.33 +
    1.34 +#include <stdlib.h>
    1.35 +#include <string.h>
    1.36 +#include <assert.h>
    1.37 +#include <math.h>
    1.38 +
    1.39 +#include "pixman-accessor.h"
    1.40 +#include "pixman-private.h"
    1.41 +
    1.42 +#define CONVERT_RGB24_TO_Y15(s)						\
    1.43 +    (((((s) >> 16) & 0xff) * 153 +					\
    1.44 +      (((s) >>  8) & 0xff) * 301 +					\
    1.45 +      (((s)      ) & 0xff) * 58) >> 2)
    1.46 +
    1.47 +#define CONVERT_RGB24_TO_RGB15(s)                                       \
    1.48 +    ((((s) >> 3) & 0x001f) |                                            \
    1.49 +     (((s) >> 6) & 0x03e0) |                                            \
    1.50 +     (((s) >> 9) & 0x7c00))
    1.51 +
    1.52 +/* Fetch macros */
    1.53 +
    1.54 +#ifdef WORDS_BIGENDIAN
    1.55 +#define FETCH_1(img,l,o)						\
    1.56 +    (((READ ((img), ((uint32_t *)(l)) + ((o) >> 5))) >> (0x1f - ((o) & 0x1f))) & 0x1)
    1.57 +#else
    1.58 +#define FETCH_1(img,l,o)						\
    1.59 +    ((((READ ((img), ((uint32_t *)(l)) + ((o) >> 5))) >> ((o) & 0x1f))) & 0x1)
    1.60 +#endif
    1.61 +
    1.62 +#define FETCH_8(img,l,o)    (READ (img, (((uint8_t *)(l)) + ((o) >> 3))))
    1.63 +
    1.64 +#ifdef WORDS_BIGENDIAN
    1.65 +#define FETCH_4(img,l,o)						\
    1.66 +    (((4 * (o)) & 4) ? (FETCH_8 (img,l, 4 * (o)) & 0xf) : (FETCH_8 (img,l,(4 * (o))) >> 4))
    1.67 +#else
    1.68 +#define FETCH_4(img,l,o)						\
    1.69 +    (((4 * (o)) & 4) ? (FETCH_8 (img, l, 4 * (o)) >> 4) : (FETCH_8 (img, l, (4 * (o))) & 0xf))
    1.70 +#endif
    1.71 +
    1.72 +#ifdef WORDS_BIGENDIAN
    1.73 +#define FETCH_24(img,l,o)                                              \
    1.74 +    ((READ (img, (((uint8_t *)(l)) + ((o) * 3) + 0)) << 16)    |       \
    1.75 +     (READ (img, (((uint8_t *)(l)) + ((o) * 3) + 1)) << 8)     |       \
    1.76 +     (READ (img, (((uint8_t *)(l)) + ((o) * 3) + 2)) << 0))
    1.77 +#else
    1.78 +#define FETCH_24(img,l,o)						\
    1.79 +    ((READ (img, (((uint8_t *)(l)) + ((o) * 3) + 0)) << 0)	|	\
    1.80 +     (READ (img, (((uint8_t *)(l)) + ((o) * 3) + 1)) << 8)	|	\
    1.81 +     (READ (img, (((uint8_t *)(l)) + ((o) * 3) + 2)) << 16))
    1.82 +#endif
    1.83 +
    1.84 +/* Store macros */
    1.85 +
    1.86 +#ifdef WORDS_BIGENDIAN
    1.87 +#define STORE_1(img,l,o,v)						\
    1.88 +    do									\
    1.89 +    {									\
    1.90 +	uint32_t  *__d = ((uint32_t *)(l)) + ((o) >> 5);		\
    1.91 +	uint32_t __m, __v;						\
    1.92 +									\
    1.93 +	__m = 1 << (0x1f - ((o) & 0x1f));				\
    1.94 +	__v = (v)? __m : 0;						\
    1.95 +									\
    1.96 +	WRITE((img), __d, (READ((img), __d) & ~__m) | __v);		\
    1.97 +    }									\
    1.98 +    while (0)
    1.99 +#else
   1.100 +#define STORE_1(img,l,o,v)						\
   1.101 +    do									\
   1.102 +    {									\
   1.103 +	uint32_t  *__d = ((uint32_t *)(l)) + ((o) >> 5);		\
   1.104 +	uint32_t __m, __v;						\
   1.105 +									\
   1.106 +	__m = 1 << ((o) & 0x1f);					\
   1.107 +	__v = (v)? __m : 0;						\
   1.108 +									\
   1.109 +	WRITE((img), __d, (READ((img), __d) & ~__m) | __v);		\
   1.110 +    }									\
   1.111 +    while (0)
   1.112 +#endif
   1.113 +
   1.114 +#define STORE_8(img,l,o,v)  (WRITE (img, (uint8_t *)(l) + ((o) >> 3), (v)))
   1.115 +
   1.116 +#ifdef WORDS_BIGENDIAN
   1.117 +#define STORE_4(img,l,o,v)						\
   1.118 +    do									\
   1.119 +    {									\
   1.120 +	int bo = 4 * (o);						\
   1.121 +	int v4 = (v) & 0x0f;						\
   1.122 +									\
   1.123 +	STORE_8 (img, l, bo, (						\
   1.124 +		     bo & 4 ?						\
   1.125 +		     (FETCH_8 (img, l, bo) & 0xf0) | (v4) :		\
   1.126 +		     (FETCH_8 (img, l, bo) & 0x0f) | (v4 << 4)));	\
   1.127 +    } while (0)
   1.128 +#else
   1.129 +#define STORE_4(img,l,o,v)						\
   1.130 +    do									\
   1.131 +    {									\
   1.132 +	int bo = 4 * (o);						\
   1.133 +	int v4 = (v) & 0x0f;						\
   1.134 +									\
   1.135 +	STORE_8 (img, l, bo, (						\
   1.136 +		     bo & 4 ?						\
   1.137 +		     (FETCH_8 (img, l, bo) & 0x0f) | (v4 << 4) :	\
   1.138 +		     (FETCH_8 (img, l, bo) & 0xf0) | (v4)));		\
   1.139 +    } while (0)
   1.140 +#endif
   1.141 +
   1.142 +#ifdef WORDS_BIGENDIAN
   1.143 +#define STORE_24(img,l,o,v)                                            \
   1.144 +    do                                                                 \
   1.145 +    {                                                                  \
   1.146 +	uint8_t *__tmp = (l) + 3 * (o);				       \
   1.147 +        							       \
   1.148 +	WRITE ((img), __tmp++, ((v) & 0x00ff0000) >> 16);	       \
   1.149 +	WRITE ((img), __tmp++, ((v) & 0x0000ff00) >>  8);	       \
   1.150 +	WRITE ((img), __tmp++, ((v) & 0x000000ff) >>  0);	       \
   1.151 +    }                                                                  \
   1.152 +    while (0)
   1.153 +#else
   1.154 +#define STORE_24(img,l,o,v)                                            \
   1.155 +    do                                                                 \
   1.156 +    {                                                                  \
   1.157 +	uint8_t *__tmp = (l) + 3 * (o);				       \
   1.158 +        							       \
   1.159 +	WRITE ((img), __tmp++, ((v) & 0x000000ff) >>  0);	       \
   1.160 +	WRITE ((img), __tmp++, ((v) & 0x0000ff00) >>  8);	       \
   1.161 +	WRITE ((img), __tmp++, ((v) & 0x00ff0000) >> 16);	       \
   1.162 +    }								       \
   1.163 +    while (0)
   1.164 +#endif
   1.165 +
   1.166 +/*
   1.167 + * YV12 setup and access macros
   1.168 + */
   1.169 +
   1.170 +#define YV12_SETUP(image)                                               \
   1.171 +    bits_image_t *__bits_image = (bits_image_t *)image;                 \
   1.172 +    uint32_t *bits = __bits_image->bits;                                \
   1.173 +    int stride = __bits_image->rowstride;                               \
   1.174 +    int offset0 = stride < 0 ?                                          \
   1.175 +    ((-stride) >> 1) * ((__bits_image->height - 1) >> 1) - stride :	\
   1.176 +    stride * __bits_image->height;					\
   1.177 +    int offset1 = stride < 0 ?                                          \
   1.178 +    offset0 + ((-stride) >> 1) * ((__bits_image->height) >> 1) :	\
   1.179 +	offset0 + (offset0 >> 2)
   1.180 +
   1.181 +/* Note no trailing semicolon on the above macro; if it's there, then
   1.182 + * the typical usage of YV12_SETUP(image); will have an extra trailing ;
   1.183 + * that some compilers will interpret as a statement -- and then any further
   1.184 + * variable declarations will cause an error.
   1.185 + */
   1.186 +
   1.187 +#define YV12_Y(line)                                                    \
   1.188 +    ((uint8_t *) ((bits) + (stride) * (line)))
   1.189 +
   1.190 +#define YV12_U(line)                                                    \
   1.191 +    ((uint8_t *) ((bits) + offset1 +                                    \
   1.192 +                  ((stride) >> 1) * ((line) >> 1)))
   1.193 +
   1.194 +#define YV12_V(line)                                                    \
   1.195 +    ((uint8_t *) ((bits) + offset0 +                                    \
   1.196 +                  ((stride) >> 1) * ((line) >> 1)))
   1.197 +
   1.198 +/* Misc. helpers */
   1.199 +
   1.200 +static force_inline void
   1.201 +get_shifts (pixman_format_code_t  format,
   1.202 +	    int			 *a,
   1.203 +	    int			 *r,
   1.204 +	    int                  *g,
   1.205 +	    int                  *b)
   1.206 +{
   1.207 +    switch (PIXMAN_FORMAT_TYPE (format))
   1.208 +    {
   1.209 +    case PIXMAN_TYPE_A:
   1.210 +	*b = 0;
   1.211 +	*g = 0;
   1.212 +	*r = 0;
   1.213 +	*a = 0;
   1.214 +	break;
   1.215 +
   1.216 +    case PIXMAN_TYPE_ARGB:
   1.217 +    case PIXMAN_TYPE_ARGB_SRGB:
   1.218 +	*b = 0;
   1.219 +	*g = *b + PIXMAN_FORMAT_B (format);
   1.220 +	*r = *g + PIXMAN_FORMAT_G (format);
   1.221 +	*a = *r + PIXMAN_FORMAT_R (format);
   1.222 +	break;
   1.223 +
   1.224 +    case PIXMAN_TYPE_ABGR:
   1.225 +	*r = 0;
   1.226 +	*g = *r + PIXMAN_FORMAT_R (format);
   1.227 +	*b = *g + PIXMAN_FORMAT_G (format);
   1.228 +	*a = *b + PIXMAN_FORMAT_B (format);
   1.229 +	break;
   1.230 +
   1.231 +    case PIXMAN_TYPE_BGRA:
   1.232 +	/* With BGRA formats we start counting at the high end of the pixel */
   1.233 +	*b = PIXMAN_FORMAT_BPP (format) - PIXMAN_FORMAT_B (format);
   1.234 +	*g = *b - PIXMAN_FORMAT_B (format);
   1.235 +	*r = *g - PIXMAN_FORMAT_G (format);
   1.236 +	*a = *r - PIXMAN_FORMAT_R (format);
   1.237 +	break;
   1.238 +
   1.239 +    case PIXMAN_TYPE_RGBA:
   1.240 +	/* With BGRA formats we start counting at the high end of the pixel */
   1.241 +	*r = PIXMAN_FORMAT_BPP (format) - PIXMAN_FORMAT_R (format);
   1.242 +	*g = *r - PIXMAN_FORMAT_R (format);
   1.243 +	*b = *g - PIXMAN_FORMAT_G (format);
   1.244 +	*a = *b - PIXMAN_FORMAT_B (format);
   1.245 +	break;
   1.246 +
   1.247 +    default:
   1.248 +	assert (0);
   1.249 +	break;
   1.250 +    }
   1.251 +}
   1.252 +
   1.253 +static force_inline uint32_t
   1.254 +convert_channel (uint32_t pixel, uint32_t def_value,
   1.255 +		 int n_from_bits, int from_shift,
   1.256 +		 int n_to_bits, int to_shift)
   1.257 +{
   1.258 +    uint32_t v;
   1.259 +
   1.260 +    if (n_from_bits && n_to_bits)
   1.261 +	v  = unorm_to_unorm (pixel >> from_shift, n_from_bits, n_to_bits);
   1.262 +    else if (n_to_bits)
   1.263 +	v = def_value;
   1.264 +    else
   1.265 +	v = 0;
   1.266 +
   1.267 +    return (v & ((1 << n_to_bits) - 1)) << to_shift;
   1.268 +}
   1.269 +
   1.270 +static force_inline uint32_t
   1.271 +convert_pixel (pixman_format_code_t from, pixman_format_code_t to, uint32_t pixel)
   1.272 +{
   1.273 +    int a_from_shift, r_from_shift, g_from_shift, b_from_shift;
   1.274 +    int a_to_shift, r_to_shift, g_to_shift, b_to_shift;
   1.275 +    uint32_t a, r, g, b;
   1.276 +
   1.277 +    get_shifts (from, &a_from_shift, &r_from_shift, &g_from_shift, &b_from_shift);
   1.278 +    get_shifts (to, &a_to_shift, &r_to_shift, &g_to_shift, &b_to_shift);
   1.279 +
   1.280 +    a = convert_channel (pixel, ~0,
   1.281 +			 PIXMAN_FORMAT_A (from), a_from_shift,
   1.282 +			 PIXMAN_FORMAT_A (to), a_to_shift);
   1.283 +
   1.284 +    r = convert_channel (pixel, 0,
   1.285 +			 PIXMAN_FORMAT_R (from), r_from_shift,
   1.286 +			 PIXMAN_FORMAT_R (to), r_to_shift);
   1.287 +
   1.288 +    g = convert_channel (pixel, 0,
   1.289 +			 PIXMAN_FORMAT_G (from), g_from_shift,
   1.290 +			 PIXMAN_FORMAT_G (to), g_to_shift);
   1.291 +
   1.292 +    b = convert_channel (pixel, 0,
   1.293 +			 PIXMAN_FORMAT_B (from), b_from_shift,
   1.294 +			 PIXMAN_FORMAT_B (to), b_to_shift);
   1.295 +
   1.296 +    return a | r | g | b;
   1.297 +}
   1.298 +
   1.299 +static force_inline uint32_t
   1.300 +convert_pixel_to_a8r8g8b8 (pixman_image_t *image,
   1.301 +			   pixman_format_code_t format,
   1.302 +			   uint32_t pixel)
   1.303 +{
   1.304 +    if (PIXMAN_FORMAT_TYPE (format) == PIXMAN_TYPE_GRAY		||
   1.305 +	PIXMAN_FORMAT_TYPE (format) == PIXMAN_TYPE_COLOR)
   1.306 +    {
   1.307 +	return image->bits.indexed->rgba[pixel];
   1.308 +    }
   1.309 +    else
   1.310 +    {
   1.311 +	return convert_pixel (format, PIXMAN_a8r8g8b8, pixel);
   1.312 +    }
   1.313 +}
   1.314 +
   1.315 +static force_inline uint32_t
   1.316 +convert_pixel_from_a8r8g8b8 (pixman_image_t *image,
   1.317 +			     pixman_format_code_t format, uint32_t pixel)
   1.318 +{
   1.319 +    if (PIXMAN_FORMAT_TYPE (format) == PIXMAN_TYPE_GRAY)
   1.320 +    {
   1.321 +	pixel = CONVERT_RGB24_TO_Y15 (pixel);
   1.322 +
   1.323 +	return image->bits.indexed->ent[pixel & 0x7fff];
   1.324 +    }
   1.325 +    else if (PIXMAN_FORMAT_TYPE (format) == PIXMAN_TYPE_COLOR)
   1.326 +    {
   1.327 +	pixel = convert_pixel (PIXMAN_a8r8g8b8, PIXMAN_x1r5g5b5, pixel);
   1.328 +
   1.329 +	return image->bits.indexed->ent[pixel & 0x7fff];
   1.330 +    }
   1.331 +    else
   1.332 +    {
   1.333 +	return convert_pixel (PIXMAN_a8r8g8b8, format, pixel);
   1.334 +    }
   1.335 +}
   1.336 +
   1.337 +static force_inline uint32_t
   1.338 +fetch_and_convert_pixel (pixman_image_t	*	image,
   1.339 +			 const uint8_t *	bits,
   1.340 +			 int			offset,
   1.341 +			 pixman_format_code_t	format)
   1.342 +{
   1.343 +    uint32_t pixel;
   1.344 +
   1.345 +    switch (PIXMAN_FORMAT_BPP (format))
   1.346 +    {
   1.347 +    case 1:
   1.348 +	pixel = FETCH_1 (image, bits, offset);
   1.349 +	break;
   1.350 +
   1.351 +    case 4:
   1.352 +	pixel = FETCH_4 (image, bits, offset);
   1.353 +	break;
   1.354 +
   1.355 +    case 8:
   1.356 +	pixel = READ (image, bits + offset);
   1.357 +	break;
   1.358 +
   1.359 +    case 16:
   1.360 +	pixel = READ (image, ((uint16_t *)bits + offset));
   1.361 +	break;
   1.362 +
   1.363 +    case 24:
   1.364 +	pixel = FETCH_24 (image, bits, offset);
   1.365 +	break;
   1.366 +
   1.367 +    case 32:
   1.368 +	pixel = READ (image, ((uint32_t *)bits + offset));
   1.369 +	break;
   1.370 +
   1.371 +    default:
   1.372 +	pixel = 0xffff00ff; /* As ugly as possible to detect the bug */
   1.373 +	break;
   1.374 +    }
   1.375 +
   1.376 +    return convert_pixel_to_a8r8g8b8 (image, format, pixel);
   1.377 +}
   1.378 +
   1.379 +static force_inline void
   1.380 +convert_and_store_pixel (bits_image_t *		image,
   1.381 +			 uint8_t *		dest,
   1.382 +			 int                    offset,
   1.383 +			 pixman_format_code_t	format,
   1.384 +			 uint32_t		pixel)
   1.385 +{
   1.386 +    uint32_t converted = convert_pixel_from_a8r8g8b8 (
   1.387 +	(pixman_image_t *)image, format, pixel);
   1.388 +
   1.389 +    switch (PIXMAN_FORMAT_BPP (format))
   1.390 +    {
   1.391 +    case 1:
   1.392 +	STORE_1 (image, dest, offset, converted & 0x01);
   1.393 +	break;
   1.394 +
   1.395 +    case 4:
   1.396 +	STORE_4 (image, dest, offset, converted & 0xf);
   1.397 +	break;
   1.398 +
   1.399 +    case 8:
   1.400 +	WRITE (image, (dest + offset), converted & 0xff);
   1.401 +	break;
   1.402 +
   1.403 +    case 16:
   1.404 +	WRITE (image, ((uint16_t *)dest + offset), converted & 0xffff);
   1.405 +	break;
   1.406 +
   1.407 +    case 24:
   1.408 +	STORE_24 (image, dest, offset, converted);
   1.409 +	break;
   1.410 +
   1.411 +    case 32:
   1.412 +	WRITE (image, ((uint32_t *)dest + offset), converted);
   1.413 +	break;
   1.414 +
   1.415 +    default:
   1.416 +	*dest = 0x0;
   1.417 +	break;
   1.418 +    }
   1.419 +}
   1.420 +
   1.421 +#define MAKE_ACCESSORS(format)						\
   1.422 +    static void								\
   1.423 +    fetch_scanline_ ## format (pixman_image_t *image,			\
   1.424 +			       int	       x,			\
   1.425 +			       int             y,			\
   1.426 +			       int             width,			\
   1.427 +			       uint32_t *      buffer,			\
   1.428 +			       const uint32_t *mask)			\
   1.429 +    {									\
   1.430 +	uint8_t *bits =							\
   1.431 +	    (uint8_t *)(image->bits.bits + y * image->bits.rowstride);	\
   1.432 +	int i;								\
   1.433 +									\
   1.434 +	for (i = 0; i < width; ++i)					\
   1.435 +	{								\
   1.436 +	    *buffer++ =							\
   1.437 +		fetch_and_convert_pixel (image, bits, x + i, PIXMAN_ ## format); \
   1.438 +	}								\
   1.439 +    }									\
   1.440 +									\
   1.441 +    static void								\
   1.442 +    store_scanline_ ## format (bits_image_t *  image,			\
   1.443 +			       int             x,			\
   1.444 +			       int             y,			\
   1.445 +			       int             width,			\
   1.446 +			       const uint32_t *values)			\
   1.447 +    {									\
   1.448 +	uint8_t *dest =							\
   1.449 +	    (uint8_t *)(image->bits + y * image->rowstride);		\
   1.450 +	int i;								\
   1.451 +									\
   1.452 +	for (i = 0; i < width; ++i)					\
   1.453 +	{								\
   1.454 +	    convert_and_store_pixel (					\
   1.455 +		image, dest, i + x, PIXMAN_ ## format, values[i]);	\
   1.456 +	}								\
   1.457 +    }									\
   1.458 +									\
   1.459 +    static uint32_t							\
   1.460 +    fetch_pixel_ ## format (bits_image_t *image,			\
   1.461 +			    int		offset,				\
   1.462 +			    int		line)				\
   1.463 +    {									\
   1.464 +	uint8_t *bits =							\
   1.465 +	    (uint8_t *)(image->bits + line * image->rowstride);		\
   1.466 +									\
   1.467 +	return fetch_and_convert_pixel ((pixman_image_t *)image,	\
   1.468 +					bits, offset, PIXMAN_ ## format); \
   1.469 +    }									\
   1.470 +									\
   1.471 +    static const void *const __dummy__ ## format
   1.472 +
   1.473 +MAKE_ACCESSORS(a8r8g8b8);
   1.474 +MAKE_ACCESSORS(x8r8g8b8);
   1.475 +MAKE_ACCESSORS(a8b8g8r8);
   1.476 +MAKE_ACCESSORS(x8b8g8r8);
   1.477 +MAKE_ACCESSORS(x14r6g6b6);
   1.478 +MAKE_ACCESSORS(b8g8r8a8);
   1.479 +MAKE_ACCESSORS(b8g8r8x8);
   1.480 +MAKE_ACCESSORS(r8g8b8x8);
   1.481 +MAKE_ACCESSORS(r8g8b8a8);
   1.482 +MAKE_ACCESSORS(r8g8b8);
   1.483 +MAKE_ACCESSORS(b8g8r8);
   1.484 +MAKE_ACCESSORS(r5g6b5);
   1.485 +MAKE_ACCESSORS(b5g6r5);
   1.486 +MAKE_ACCESSORS(a1r5g5b5);
   1.487 +MAKE_ACCESSORS(x1r5g5b5);
   1.488 +MAKE_ACCESSORS(a1b5g5r5);
   1.489 +MAKE_ACCESSORS(x1b5g5r5);
   1.490 +MAKE_ACCESSORS(a4r4g4b4);
   1.491 +MAKE_ACCESSORS(x4r4g4b4);
   1.492 +MAKE_ACCESSORS(a4b4g4r4);
   1.493 +MAKE_ACCESSORS(x4b4g4r4);
   1.494 +MAKE_ACCESSORS(a8);
   1.495 +MAKE_ACCESSORS(c8);
   1.496 +MAKE_ACCESSORS(g8);
   1.497 +MAKE_ACCESSORS(r3g3b2);
   1.498 +MAKE_ACCESSORS(b2g3r3);
   1.499 +MAKE_ACCESSORS(a2r2g2b2);
   1.500 +MAKE_ACCESSORS(a2b2g2r2);
   1.501 +MAKE_ACCESSORS(x4a4);
   1.502 +MAKE_ACCESSORS(a4);
   1.503 +MAKE_ACCESSORS(g4);
   1.504 +MAKE_ACCESSORS(c4);
   1.505 +MAKE_ACCESSORS(r1g2b1);
   1.506 +MAKE_ACCESSORS(b1g2r1);
   1.507 +MAKE_ACCESSORS(a1r1g1b1);
   1.508 +MAKE_ACCESSORS(a1b1g1r1);
   1.509 +MAKE_ACCESSORS(a1);
   1.510 +MAKE_ACCESSORS(g1);
   1.511 +
   1.512 +/********************************** Fetch ************************************/
   1.513 +/* Table mapping sRGB-encoded 8 bit numbers to linearly encoded
   1.514 + * floating point numbers. We assume that single precision
   1.515 + * floating point follows the IEEE 754 format.
   1.516 + */
   1.517 +static const uint32_t to_linear_u[256] =
   1.518 +{
   1.519 +    0x00000000, 0x399f22b4, 0x3a1f22b4, 0x3a6eb40e, 0x3a9f22b4, 0x3ac6eb61,
   1.520 +    0x3aeeb40e, 0x3b0b3e5d, 0x3b1f22b4, 0x3b33070b, 0x3b46eb61, 0x3b5b518a,
   1.521 +    0x3b70f18a, 0x3b83e1c5, 0x3b8fe614, 0x3b9c87fb, 0x3ba9c9b5, 0x3bb7ad6d,
   1.522 +    0x3bc63547, 0x3bd5635f, 0x3be539bd, 0x3bf5ba70, 0x3c0373b5, 0x3c0c6152,
   1.523 +    0x3c15a703, 0x3c1f45bc, 0x3c293e68, 0x3c3391f4, 0x3c3e4149, 0x3c494d43,
   1.524 +    0x3c54b6c7, 0x3c607eb1, 0x3c6ca5df, 0x3c792d22, 0x3c830aa8, 0x3c89af9e,
   1.525 +    0x3c9085db, 0x3c978dc5, 0x3c9ec7c0, 0x3ca63432, 0x3cadd37d, 0x3cb5a601,
   1.526 +    0x3cbdac20, 0x3cc5e639, 0x3cce54ab, 0x3cd6f7d2, 0x3cdfd00e, 0x3ce8ddb9,
   1.527 +    0x3cf2212c, 0x3cfb9ac1, 0x3d02a569, 0x3d0798dc, 0x3d0ca7e4, 0x3d11d2ae,
   1.528 +    0x3d171963, 0x3d1c7c2e, 0x3d21fb3a, 0x3d2796af, 0x3d2d4ebb, 0x3d332380,
   1.529 +    0x3d39152b, 0x3d3f23e3, 0x3d454fd0, 0x3d4b991c, 0x3d51ffeb, 0x3d588466,
   1.530 +    0x3d5f26b7, 0x3d65e6fe, 0x3d6cc564, 0x3d73c210, 0x3d7add25, 0x3d810b65,
   1.531 +    0x3d84b793, 0x3d88732e, 0x3d8c3e48, 0x3d9018f4, 0x3d940343, 0x3d97fd48,
   1.532 +    0x3d9c0714, 0x3da020b9, 0x3da44a48, 0x3da883d6, 0x3daccd70, 0x3db12728,
   1.533 +    0x3db59110, 0x3dba0b38, 0x3dbe95b2, 0x3dc3308f, 0x3dc7dbe0, 0x3dcc97b4,
   1.534 +    0x3dd1641c, 0x3dd6412a, 0x3ddb2eec, 0x3de02d75, 0x3de53cd3, 0x3dea5d16,
   1.535 +    0x3def8e52, 0x3df4d091, 0x3dfa23e5, 0x3dff885e, 0x3e027f06, 0x3e05427f,
   1.536 +    0x3e080ea2, 0x3e0ae376, 0x3e0dc104, 0x3e10a752, 0x3e139669, 0x3e168e50,
   1.537 +    0x3e198f0e, 0x3e1c98ab, 0x3e1fab2e, 0x3e22c6a0, 0x3e25eb08, 0x3e29186a,
   1.538 +    0x3e2c4ed0, 0x3e2f8e42, 0x3e32d6c4, 0x3e362861, 0x3e39831e, 0x3e3ce702,
   1.539 +    0x3e405416, 0x3e43ca5e, 0x3e4749e4, 0x3e4ad2ae, 0x3e4e64c2, 0x3e520027,
   1.540 +    0x3e55a4e6, 0x3e595303, 0x3e5d0a8a, 0x3e60cb7c, 0x3e6495e0, 0x3e6869bf,
   1.541 +    0x3e6c4720, 0x3e702e08, 0x3e741e7f, 0x3e78188c, 0x3e7c1c34, 0x3e8014c0,
   1.542 +    0x3e822039, 0x3e84308b, 0x3e8645b8, 0x3e885fc3, 0x3e8a7eb0, 0x3e8ca281,
   1.543 +    0x3e8ecb3a, 0x3e90f8df, 0x3e932b72, 0x3e9562f6, 0x3e979f6f, 0x3e99e0e0,
   1.544 +    0x3e9c274e, 0x3e9e72b8, 0x3ea0c322, 0x3ea31892, 0x3ea57308, 0x3ea7d28a,
   1.545 +    0x3eaa3718, 0x3eaca0b7, 0x3eaf0f69, 0x3eb18332, 0x3eb3fc16, 0x3eb67a15,
   1.546 +    0x3eb8fd34, 0x3ebb8576, 0x3ebe12de, 0x3ec0a56e, 0x3ec33d2a, 0x3ec5da14,
   1.547 +    0x3ec87c30, 0x3ecb2380, 0x3ecdd008, 0x3ed081ca, 0x3ed338c9, 0x3ed5f508,
   1.548 +    0x3ed8b68a, 0x3edb7d52, 0x3ede4962, 0x3ee11abe, 0x3ee3f168, 0x3ee6cd64,
   1.549 +    0x3ee9aeb6, 0x3eec955d, 0x3eef815d, 0x3ef272ba, 0x3ef56976, 0x3ef86594,
   1.550 +    0x3efb6717, 0x3efe6e02, 0x3f00bd2b, 0x3f02460c, 0x3f03d1a5, 0x3f055ff8,
   1.551 +    0x3f06f105, 0x3f0884ce, 0x3f0a1b54, 0x3f0bb499, 0x3f0d509f, 0x3f0eef65,
   1.552 +    0x3f1090ef, 0x3f12353c, 0x3f13dc50, 0x3f15862a, 0x3f1732cc, 0x3f18e237,
   1.553 +    0x3f1a946d, 0x3f1c4970, 0x3f1e013f, 0x3f1fbbde, 0x3f21794c, 0x3f23398c,
   1.554 +    0x3f24fca0, 0x3f26c286, 0x3f288b42, 0x3f2a56d3, 0x3f2c253d, 0x3f2df680,
   1.555 +    0x3f2fca9d, 0x3f31a195, 0x3f337b6a, 0x3f35581e, 0x3f3737b1, 0x3f391a24,
   1.556 +    0x3f3aff7a, 0x3f3ce7b2, 0x3f3ed2d0, 0x3f40c0d2, 0x3f42b1bc, 0x3f44a58e,
   1.557 +    0x3f469c49, 0x3f4895ee, 0x3f4a9280, 0x3f4c91ff, 0x3f4e946c, 0x3f5099c8,
   1.558 +    0x3f52a216, 0x3f54ad55, 0x3f56bb88, 0x3f58ccae, 0x3f5ae0cb, 0x3f5cf7de,
   1.559 +    0x3f5f11ec, 0x3f612ef0, 0x3f634eef, 0x3f6571ea, 0x3f6797e1, 0x3f69c0d6,
   1.560 +    0x3f6beccb, 0x3f6e1bc0, 0x3f704db6, 0x3f7282af, 0x3f74baac, 0x3f76f5ae,
   1.561 +    0x3f7933b6, 0x3f7b74c6, 0x3f7db8de, 0x3f800000
   1.562 +};
   1.563 +
   1.564 +static const float * const to_linear = (const float *)to_linear_u;
   1.565 +
   1.566 +static uint8_t
   1.567 +to_srgb (float f)
   1.568 +{
   1.569 +    uint8_t low = 0;
   1.570 +    uint8_t high = 255;
   1.571 +
   1.572 +    while (high - low > 1)
   1.573 +    {
   1.574 +	uint8_t mid = (low + high) / 2;
   1.575 +
   1.576 +	if (to_linear[mid] > f)
   1.577 +	    high = mid;
   1.578 +	else
   1.579 +	    low = mid;
   1.580 +    }
   1.581 +
   1.582 +    if (to_linear[high] - f < f - to_linear[low])
   1.583 +	return high;
   1.584 +    else
   1.585 +	return low;
   1.586 +}
   1.587 +
   1.588 +static void
   1.589 +fetch_scanline_a8r8g8b8_sRGB_float (pixman_image_t *image,
   1.590 +				    int             x,
   1.591 +				    int             y,
   1.592 +				    int             width,
   1.593 +				    uint32_t *      b,
   1.594 +				    const uint32_t *mask)
   1.595 +{
   1.596 +    const uint32_t *bits = image->bits.bits + y * image->bits.rowstride;
   1.597 +    const uint32_t *pixel = bits + x;
   1.598 +    const uint32_t *end = pixel + width;
   1.599 +    argb_t *buffer = (argb_t *)b;
   1.600 +
   1.601 +    while (pixel < end)
   1.602 +    {
   1.603 +	uint32_t p = READ (image, pixel++);
   1.604 +	argb_t *argb = buffer;
   1.605 +
   1.606 +	argb->a = pixman_unorm_to_float ((p >> 24) & 0xff, 8);
   1.607 +
   1.608 +	argb->r = to_linear [(p >> 16) & 0xff];
   1.609 +	argb->g = to_linear [(p >>  8) & 0xff];
   1.610 +	argb->b = to_linear [(p >>  0) & 0xff];
   1.611 +
   1.612 +	buffer++;
   1.613 +    }
   1.614 +}
   1.615 +
   1.616 +/* Expects a float buffer */
   1.617 +static void
   1.618 +fetch_scanline_a2r10g10b10_float (pixman_image_t *image,
   1.619 +				  int             x,
   1.620 +				  int             y,
   1.621 +				  int             width,
   1.622 +				  uint32_t *      b,
   1.623 +				  const uint32_t *mask)
   1.624 +{
   1.625 +    const uint32_t *bits = image->bits.bits + y * image->bits.rowstride;
   1.626 +    const uint32_t *pixel = bits + x;
   1.627 +    const uint32_t *end = pixel + width;
   1.628 +    argb_t *buffer = (argb_t *)b;
   1.629 +
   1.630 +    while (pixel < end)
   1.631 +    {
   1.632 +	uint32_t p = READ (image, pixel++);
   1.633 +	uint64_t a = p >> 30;
   1.634 +	uint64_t r = (p >> 20) & 0x3ff;
   1.635 +	uint64_t g = (p >> 10) & 0x3ff;
   1.636 +	uint64_t b = p & 0x3ff;
   1.637 +
   1.638 +	buffer->a = pixman_unorm_to_float (a, 2);
   1.639 +	buffer->r = pixman_unorm_to_float (r, 10);
   1.640 +	buffer->g = pixman_unorm_to_float (g, 10);
   1.641 +	buffer->b = pixman_unorm_to_float (b, 10);
   1.642 +
   1.643 +	buffer++;
   1.644 +    }
   1.645 +}
   1.646 +
   1.647 +/* Expects a float buffer */
   1.648 +static void
   1.649 +fetch_scanline_x2r10g10b10_float (pixman_image_t *image,
   1.650 +				  int             x,
   1.651 +				  int             y,
   1.652 +				  int             width,
   1.653 +				  uint32_t *      b,
   1.654 +				  const uint32_t *mask)
   1.655 +{
   1.656 +    const uint32_t *bits = image->bits.bits + y * image->bits.rowstride;
   1.657 +    const uint32_t *pixel = (uint32_t *)bits + x;
   1.658 +    const uint32_t *end = pixel + width;
   1.659 +    argb_t *buffer = (argb_t *)b;
   1.660 +
   1.661 +    while (pixel < end)
   1.662 +    {
   1.663 +	uint32_t p = READ (image, pixel++);
   1.664 +	uint64_t r = (p >> 20) & 0x3ff;
   1.665 +	uint64_t g = (p >> 10) & 0x3ff;
   1.666 +	uint64_t b = p & 0x3ff;
   1.667 +
   1.668 +	buffer->a = 1.0;
   1.669 +	buffer->r = pixman_unorm_to_float (r, 10);
   1.670 +	buffer->g = pixman_unorm_to_float (g, 10);
   1.671 +	buffer->b = pixman_unorm_to_float (b, 10);
   1.672 +
   1.673 +	buffer++;
   1.674 +    }
   1.675 +}
   1.676 +
   1.677 +/* Expects a float buffer */
   1.678 +static void
   1.679 +fetch_scanline_a2b10g10r10_float (pixman_image_t *image,
   1.680 +				  int             x,
   1.681 +				  int             y,
   1.682 +				  int             width,
   1.683 +				  uint32_t *      b,
   1.684 +				  const uint32_t *mask)
   1.685 +{
   1.686 +    const uint32_t *bits = image->bits.bits + y * image->bits.rowstride;
   1.687 +    const uint32_t *pixel = bits + x;
   1.688 +    const uint32_t *end = pixel + width;
   1.689 +    argb_t *buffer = (argb_t *)b;
   1.690 +
   1.691 +    while (pixel < end)
   1.692 +    {
   1.693 +	uint32_t p = READ (image, pixel++);
   1.694 +	uint64_t a = p >> 30;
   1.695 +	uint64_t b = (p >> 20) & 0x3ff;
   1.696 +	uint64_t g = (p >> 10) & 0x3ff;
   1.697 +	uint64_t r = p & 0x3ff;
   1.698 +
   1.699 +	buffer->a = pixman_unorm_to_float (a, 2);
   1.700 +	buffer->r = pixman_unorm_to_float (r, 10);
   1.701 +	buffer->g = pixman_unorm_to_float (g, 10);
   1.702 +	buffer->b = pixman_unorm_to_float (b, 10);
   1.703 +
   1.704 +	buffer++;
   1.705 +    }
   1.706 +}
   1.707 +
   1.708 +/* Expects a float buffer */
   1.709 +static void
   1.710 +fetch_scanline_x2b10g10r10_float (pixman_image_t *image,
   1.711 +				  int             x,
   1.712 +				  int             y,
   1.713 +				  int             width,
   1.714 +				  uint32_t *      b,
   1.715 +				  const uint32_t *mask)
   1.716 +{
   1.717 +    const uint32_t *bits = image->bits.bits + y * image->bits.rowstride;
   1.718 +    const uint32_t *pixel = (uint32_t *)bits + x;
   1.719 +    const uint32_t *end = pixel + width;
   1.720 +    argb_t *buffer = (argb_t *)b;
   1.721 +
   1.722 +    while (pixel < end)
   1.723 +    {
   1.724 +	uint32_t p = READ (image, pixel++);
   1.725 +	uint64_t b = (p >> 20) & 0x3ff;
   1.726 +	uint64_t g = (p >> 10) & 0x3ff;
   1.727 +	uint64_t r = p & 0x3ff;
   1.728 +
   1.729 +	buffer->a = 1.0;
   1.730 +	buffer->r = pixman_unorm_to_float (r, 10);
   1.731 +	buffer->g = pixman_unorm_to_float (g, 10);
   1.732 +	buffer->b = pixman_unorm_to_float (b, 10);
   1.733 +
   1.734 +	buffer++;
   1.735 +    }
   1.736 +}
   1.737 +
   1.738 +static void
   1.739 +fetch_scanline_yuy2 (pixman_image_t *image,
   1.740 +                     int             x,
   1.741 +                     int             line,
   1.742 +                     int             width,
   1.743 +                     uint32_t *      buffer,
   1.744 +                     const uint32_t *mask)
   1.745 +{
   1.746 +    const uint32_t *bits = image->bits.bits + image->bits.rowstride * line;
   1.747 +    int i;
   1.748 +    
   1.749 +    for (i = 0; i < width; i++)
   1.750 +    {
   1.751 +	int16_t y, u, v;
   1.752 +	int32_t r, g, b;
   1.753 +	
   1.754 +	y = ((uint8_t *) bits)[(x + i) << 1] - 16;
   1.755 +	u = ((uint8_t *) bits)[(((x + i) << 1) & - 4) + 1] - 128;
   1.756 +	v = ((uint8_t *) bits)[(((x + i) << 1) & - 4) + 3] - 128;
   1.757 +	
   1.758 +	/* R = 1.164(Y - 16) + 1.596(V - 128) */
   1.759 +	r = 0x012b27 * y + 0x019a2e * v;
   1.760 +	/* G = 1.164(Y - 16) - 0.813(V - 128) - 0.391(U - 128) */
   1.761 +	g = 0x012b27 * y - 0x00d0f2 * v - 0x00647e * u;
   1.762 +	/* B = 1.164(Y - 16) + 2.018(U - 128) */
   1.763 +	b = 0x012b27 * y + 0x0206a2 * u;
   1.764 +	
   1.765 +	*buffer++ = 0xff000000 |
   1.766 +	    (r >= 0 ? r < 0x1000000 ? r         & 0xff0000 : 0xff0000 : 0) |
   1.767 +	    (g >= 0 ? g < 0x1000000 ? (g >> 8)  & 0x00ff00 : 0x00ff00 : 0) |
   1.768 +	    (b >= 0 ? b < 0x1000000 ? (b >> 16) & 0x0000ff : 0x0000ff : 0);
   1.769 +    }
   1.770 +}
   1.771 +
   1.772 +static void
   1.773 +fetch_scanline_yv12 (pixman_image_t *image,
   1.774 +                     int             x,
   1.775 +                     int             line,
   1.776 +                     int             width,
   1.777 +                     uint32_t *      buffer,
   1.778 +                     const uint32_t *mask)
   1.779 +{
   1.780 +    YV12_SETUP (image);
   1.781 +    uint8_t *y_line = YV12_Y (line);
   1.782 +    uint8_t *u_line = YV12_U (line);
   1.783 +    uint8_t *v_line = YV12_V (line);
   1.784 +    int i;
   1.785 +    
   1.786 +    for (i = 0; i < width; i++)
   1.787 +    {
   1.788 +	int16_t y, u, v;
   1.789 +	int32_t r, g, b;
   1.790 +
   1.791 +	y = y_line[x + i] - 16;
   1.792 +	u = u_line[(x + i) >> 1] - 128;
   1.793 +	v = v_line[(x + i) >> 1] - 128;
   1.794 +
   1.795 +	/* R = 1.164(Y - 16) + 1.596(V - 128) */
   1.796 +	r = 0x012b27 * y + 0x019a2e * v;
   1.797 +	/* G = 1.164(Y - 16) - 0.813(V - 128) - 0.391(U - 128) */
   1.798 +	g = 0x012b27 * y - 0x00d0f2 * v - 0x00647e * u;
   1.799 +	/* B = 1.164(Y - 16) + 2.018(U - 128) */
   1.800 +	b = 0x012b27 * y + 0x0206a2 * u;
   1.801 +
   1.802 +	*buffer++ = 0xff000000 |
   1.803 +	    (r >= 0 ? r < 0x1000000 ? r         & 0xff0000 : 0xff0000 : 0) |
   1.804 +	    (g >= 0 ? g < 0x1000000 ? (g >> 8)  & 0x00ff00 : 0x00ff00 : 0) |
   1.805 +	    (b >= 0 ? b < 0x1000000 ? (b >> 16) & 0x0000ff : 0x0000ff : 0);
   1.806 +    }
   1.807 +}
   1.808 +
   1.809 +/**************************** Pixel wise fetching *****************************/
   1.810 +
   1.811 +static argb_t
   1.812 +fetch_pixel_x2r10g10b10_float (bits_image_t *image,
   1.813 +			       int	   offset,
   1.814 +			       int           line)
   1.815 +{
   1.816 +    uint32_t *bits = image->bits + line * image->rowstride;
   1.817 +    uint32_t p = READ (image, bits + offset);
   1.818 +    uint64_t r = (p >> 20) & 0x3ff;
   1.819 +    uint64_t g = (p >> 10) & 0x3ff;
   1.820 +    uint64_t b = p & 0x3ff;
   1.821 +    argb_t argb;
   1.822 +
   1.823 +    argb.a = 1.0;
   1.824 +    argb.r = pixman_unorm_to_float (r, 10);
   1.825 +    argb.g = pixman_unorm_to_float (g, 10);
   1.826 +    argb.b = pixman_unorm_to_float (b, 10);
   1.827 +
   1.828 +    return argb;
   1.829 +}
   1.830 +
   1.831 +static argb_t
   1.832 +fetch_pixel_a2r10g10b10_float (bits_image_t *image,
   1.833 +			       int	     offset,
   1.834 +			       int           line)
   1.835 +{
   1.836 +    uint32_t *bits = image->bits + line * image->rowstride;
   1.837 +    uint32_t p = READ (image, bits + offset);
   1.838 +    uint64_t a = p >> 30;
   1.839 +    uint64_t r = (p >> 20) & 0x3ff;
   1.840 +    uint64_t g = (p >> 10) & 0x3ff;
   1.841 +    uint64_t b = p & 0x3ff;
   1.842 +    argb_t argb;
   1.843 +
   1.844 +    argb.a = pixman_unorm_to_float (a, 2);
   1.845 +    argb.r = pixman_unorm_to_float (r, 10);
   1.846 +    argb.g = pixman_unorm_to_float (g, 10);
   1.847 +    argb.b = pixman_unorm_to_float (b, 10);
   1.848 +
   1.849 +    return argb;
   1.850 +}
   1.851 +
   1.852 +static argb_t
   1.853 +fetch_pixel_a2b10g10r10_float (bits_image_t *image,
   1.854 +			       int           offset,
   1.855 +			       int           line)
   1.856 +{
   1.857 +    uint32_t *bits = image->bits + line * image->rowstride;
   1.858 +    uint32_t p = READ (image, bits + offset);
   1.859 +    uint64_t a = p >> 30;
   1.860 +    uint64_t b = (p >> 20) & 0x3ff;
   1.861 +    uint64_t g = (p >> 10) & 0x3ff;
   1.862 +    uint64_t r = p & 0x3ff;
   1.863 +    argb_t argb;
   1.864 +
   1.865 +    argb.a = pixman_unorm_to_float (a, 2);
   1.866 +    argb.r = pixman_unorm_to_float (r, 10);
   1.867 +    argb.g = pixman_unorm_to_float (g, 10);
   1.868 +    argb.b = pixman_unorm_to_float (b, 10);
   1.869 +
   1.870 +    return argb;
   1.871 +}
   1.872 +
   1.873 +static argb_t
   1.874 +fetch_pixel_x2b10g10r10_float (bits_image_t *image,
   1.875 +			       int           offset,
   1.876 +			       int           line)
   1.877 +{
   1.878 +    uint32_t *bits = image->bits + line * image->rowstride;
   1.879 +    uint32_t p = READ (image, bits + offset);
   1.880 +    uint64_t b = (p >> 20) & 0x3ff;
   1.881 +    uint64_t g = (p >> 10) & 0x3ff;
   1.882 +    uint64_t r = p & 0x3ff;
   1.883 +    argb_t argb;
   1.884 +
   1.885 +    argb.a = 1.0;
   1.886 +    argb.r = pixman_unorm_to_float (r, 10);
   1.887 +    argb.g = pixman_unorm_to_float (g, 10);
   1.888 +    argb.b = pixman_unorm_to_float (b, 10);
   1.889 +
   1.890 +    return argb;
   1.891 +}
   1.892 +
   1.893 +static argb_t
   1.894 +fetch_pixel_a8r8g8b8_sRGB_float (bits_image_t *image,
   1.895 +				 int	       offset,
   1.896 +				 int           line)
   1.897 +{
   1.898 +    uint32_t *bits = image->bits + line * image->rowstride;
   1.899 +    uint32_t p = READ (image, bits + offset);
   1.900 +    argb_t argb;
   1.901 +
   1.902 +    argb.a = pixman_unorm_to_float ((p >> 24) & 0xff, 8);
   1.903 +
   1.904 +    argb.r = to_linear [(p >> 16) & 0xff];
   1.905 +    argb.g = to_linear [(p >>  8) & 0xff];
   1.906 +    argb.b = to_linear [(p >>  0) & 0xff];
   1.907 +
   1.908 +    return argb;
   1.909 +}
   1.910 +
   1.911 +static uint32_t
   1.912 +fetch_pixel_yuy2 (bits_image_t *image,
   1.913 +		  int           offset,
   1.914 +		  int           line)
   1.915 +{
   1.916 +    const uint32_t *bits = image->bits + image->rowstride * line;
   1.917 +    
   1.918 +    int16_t y, u, v;
   1.919 +    int32_t r, g, b;
   1.920 +    
   1.921 +    y = ((uint8_t *) bits)[offset << 1] - 16;
   1.922 +    u = ((uint8_t *) bits)[((offset << 1) & - 4) + 1] - 128;
   1.923 +    v = ((uint8_t *) bits)[((offset << 1) & - 4) + 3] - 128;
   1.924 +    
   1.925 +    /* R = 1.164(Y - 16) + 1.596(V - 128) */
   1.926 +    r = 0x012b27 * y + 0x019a2e * v;
   1.927 +    
   1.928 +    /* G = 1.164(Y - 16) - 0.813(V - 128) - 0.391(U - 128) */
   1.929 +    g = 0x012b27 * y - 0x00d0f2 * v - 0x00647e * u;
   1.930 +    
   1.931 +    /* B = 1.164(Y - 16) + 2.018(U - 128) */
   1.932 +    b = 0x012b27 * y + 0x0206a2 * u;
   1.933 +    
   1.934 +    return 0xff000000 |
   1.935 +	(r >= 0 ? r < 0x1000000 ? r         & 0xff0000 : 0xff0000 : 0) |
   1.936 +	(g >= 0 ? g < 0x1000000 ? (g >> 8)  & 0x00ff00 : 0x00ff00 : 0) |
   1.937 +	(b >= 0 ? b < 0x1000000 ? (b >> 16) & 0x0000ff : 0x0000ff : 0);
   1.938 +}
   1.939 +
   1.940 +static uint32_t
   1.941 +fetch_pixel_yv12 (bits_image_t *image,
   1.942 +		  int           offset,
   1.943 +		  int           line)
   1.944 +{
   1.945 +    YV12_SETUP (image);
   1.946 +    int16_t y = YV12_Y (line)[offset] - 16;
   1.947 +    int16_t u = YV12_U (line)[offset >> 1] - 128;
   1.948 +    int16_t v = YV12_V (line)[offset >> 1] - 128;
   1.949 +    int32_t r, g, b;
   1.950 +    
   1.951 +    /* R = 1.164(Y - 16) + 1.596(V - 128) */
   1.952 +    r = 0x012b27 * y + 0x019a2e * v;
   1.953 +    
   1.954 +    /* G = 1.164(Y - 16) - 0.813(V - 128) - 0.391(U - 128) */
   1.955 +    g = 0x012b27 * y - 0x00d0f2 * v - 0x00647e * u;
   1.956 +    
   1.957 +    /* B = 1.164(Y - 16) + 2.018(U - 128) */
   1.958 +    b = 0x012b27 * y + 0x0206a2 * u;
   1.959 +    
   1.960 +    return 0xff000000 |
   1.961 +	(r >= 0 ? r < 0x1000000 ? r         & 0xff0000 : 0xff0000 : 0) |
   1.962 +	(g >= 0 ? g < 0x1000000 ? (g >> 8)  & 0x00ff00 : 0x00ff00 : 0) |
   1.963 +	(b >= 0 ? b < 0x1000000 ? (b >> 16) & 0x0000ff : 0x0000ff : 0);
   1.964 +}
   1.965 +
   1.966 +/*********************************** Store ************************************/
   1.967 +
   1.968 +static void
   1.969 +store_scanline_a2r10g10b10_float (bits_image_t *  image,
   1.970 +				  int             x,
   1.971 +				  int             y,
   1.972 +				  int             width,
   1.973 +				  const uint32_t *v)
   1.974 +{
   1.975 +    uint32_t *bits = image->bits + image->rowstride * y;
   1.976 +    uint32_t *pixel = bits + x;
   1.977 +    argb_t *values = (argb_t *)v;
   1.978 +    int i;
   1.979 +
   1.980 +    for (i = 0; i < width; ++i)
   1.981 +    {
   1.982 +	uint16_t a, r, g, b;
   1.983 +
   1.984 +	a = pixman_float_to_unorm (values[i].a, 2);
   1.985 +	r = pixman_float_to_unorm (values[i].r, 10);
   1.986 +	g = pixman_float_to_unorm (values[i].g, 10);
   1.987 +	b = pixman_float_to_unorm (values[i].b, 10);
   1.988 +
   1.989 +	WRITE (image, pixel++,
   1.990 +	       (a << 30) | (r << 20) | (g << 10) | b);
   1.991 +    }
   1.992 +}
   1.993 +
   1.994 +static void
   1.995 +store_scanline_x2r10g10b10_float (bits_image_t *  image,
   1.996 +				  int             x,
   1.997 +				  int             y,
   1.998 +				  int             width,
   1.999 +				  const uint32_t *v)
  1.1000 +{
  1.1001 +    uint32_t *bits = image->bits + image->rowstride * y;
  1.1002 +    uint32_t *pixel = bits + x;
  1.1003 +    argb_t *values = (argb_t *)v;
  1.1004 +    int i;
  1.1005 +
  1.1006 +    for (i = 0; i < width; ++i)
  1.1007 +    {
  1.1008 +	uint16_t r, g, b;
  1.1009 +
  1.1010 +	r = pixman_float_to_unorm (values[i].r, 10);
  1.1011 +	g = pixman_float_to_unorm (values[i].g, 10);
  1.1012 +	b = pixman_float_to_unorm (values[i].b, 10);
  1.1013 +
  1.1014 +	WRITE (image, pixel++,
  1.1015 +	       (r << 20) | (g << 10) | b);
  1.1016 +    }
  1.1017 +}
  1.1018 +
  1.1019 +static void
  1.1020 +store_scanline_a2b10g10r10_float (bits_image_t *  image,
  1.1021 +				  int             x,
  1.1022 +				  int             y,
  1.1023 +				  int             width,
  1.1024 +				  const uint32_t *v)
  1.1025 +{
  1.1026 +    uint32_t *bits = image->bits + image->rowstride * y;
  1.1027 +    uint32_t *pixel = bits + x;
  1.1028 +    argb_t *values = (argb_t *)v;
  1.1029 +    int i;
  1.1030 +
  1.1031 +    for (i = 0; i < width; ++i)
  1.1032 +    {
  1.1033 +	uint16_t a, r, g, b;
  1.1034 +
  1.1035 +	a = pixman_float_to_unorm (values[i].a, 2);
  1.1036 +	r = pixman_float_to_unorm (values[i].r, 10);
  1.1037 +	g = pixman_float_to_unorm (values[i].g, 10);
  1.1038 +	b = pixman_float_to_unorm (values[i].b, 10);
  1.1039 +
  1.1040 +	WRITE (image, pixel++,
  1.1041 +	       (a << 30) | (b << 20) | (g << 10) | r);
  1.1042 +    }
  1.1043 +}
  1.1044 +
  1.1045 +static void
  1.1046 +store_scanline_x2b10g10r10_float (bits_image_t *  image,
  1.1047 +				  int             x,
  1.1048 +				  int             y,
  1.1049 +				  int             width,
  1.1050 +				  const uint32_t *v)
  1.1051 +{
  1.1052 +    uint32_t *bits = image->bits + image->rowstride * y;
  1.1053 +    uint32_t *pixel = bits + x;
  1.1054 +    argb_t *values = (argb_t *)v;
  1.1055 +    int i;
  1.1056 +
  1.1057 +    for (i = 0; i < width; ++i)
  1.1058 +    {
  1.1059 +	uint16_t r, g, b;
  1.1060 +
  1.1061 +	r = pixman_float_to_unorm (values[i].r, 10);
  1.1062 +	g = pixman_float_to_unorm (values[i].g, 10);
  1.1063 +	b = pixman_float_to_unorm (values[i].b, 10);
  1.1064 +
  1.1065 +	WRITE (image, pixel++,
  1.1066 +	       (b << 20) | (g << 10) | r);
  1.1067 +    }
  1.1068 +}
  1.1069 +
  1.1070 +static void
  1.1071 +store_scanline_a8r8g8b8_sRGB_float (bits_image_t *  image,
  1.1072 +				    int             x,
  1.1073 +				    int             y,
  1.1074 +				    int             width,
  1.1075 +				    const uint32_t *v)
  1.1076 +{
  1.1077 +    uint32_t *bits = image->bits + image->rowstride * y;
  1.1078 +    uint32_t *pixel = bits + x;
  1.1079 +    argb_t *values = (argb_t *)v;
  1.1080 +    int i;
  1.1081 +
  1.1082 +    for (i = 0; i < width; ++i)
  1.1083 +    {
  1.1084 +	uint8_t a, r, g, b;
  1.1085 +
  1.1086 +	a = pixman_float_to_unorm (values[i].a, 8);
  1.1087 +	r = to_srgb (values[i].r);
  1.1088 +	g = to_srgb (values[i].g);
  1.1089 +	b = to_srgb (values[i].b);
  1.1090 +
  1.1091 +	WRITE (image, pixel++,
  1.1092 +	       (a << 24) | (r << 16) | (g << 8) | b);
  1.1093 +    }
  1.1094 +}
  1.1095 +
  1.1096 +static void
  1.1097 +store_scanline_16 (bits_image_t *  image,
  1.1098 +		   int             x,
  1.1099 +		   int             y,
  1.1100 +		   int             width,
  1.1101 +		   const uint32_t *v)
  1.1102 +{
  1.1103 +    uint16_t *bits = (uint16_t*)(image->bits + image->rowstride * y);
  1.1104 +    uint16_t *values = (uint16_t *)v;
  1.1105 +    uint16_t *pixel = bits + x;
  1.1106 +    int i;
  1.1107 +
  1.1108 +    for (i = 0; i < width; ++i)
  1.1109 +    {
  1.1110 +	WRITE (image, pixel++, values[i]);
  1.1111 +    }
  1.1112 +}
  1.1113 +
  1.1114 +static void
  1.1115 +fetch_scanline_16 (pixman_image_t *image,
  1.1116 +                            int             x,
  1.1117 +                            int             y,
  1.1118 +                            int             width,
  1.1119 +                            uint32_t *      b,
  1.1120 +                            const uint32_t *mask)
  1.1121 +{
  1.1122 +    const uint16_t *bits = (uint16_t*)(image->bits.bits + y * image->bits.rowstride);
  1.1123 +    const uint16_t *pixel = bits + x;
  1.1124 +    int i;
  1.1125 +    uint16_t *buffer = (uint16_t *)b;
  1.1126 +
  1.1127 +    for (i = 0; i < width; ++i)
  1.1128 +    {
  1.1129 +	*buffer++ = READ (image, pixel++);
  1.1130 +    }
  1.1131 +}
  1.1132 +
  1.1133 +
  1.1134 +/*
  1.1135 + * Contracts a floating point image to 32bpp and then stores it using a
  1.1136 + * regular 32-bit store proc. Despite the type, this function expects an
  1.1137 + * argb_t buffer.
  1.1138 + */
  1.1139 +static void
  1.1140 +store_scanline_generic_float (bits_image_t *  image,
  1.1141 +			      int             x,
  1.1142 +			      int             y,
  1.1143 +			      int             width,
  1.1144 +			      const uint32_t *values)
  1.1145 +{
  1.1146 +    uint32_t *argb8_pixels;
  1.1147 +
  1.1148 +    assert (image->common.type == BITS);
  1.1149 +
  1.1150 +    argb8_pixels = pixman_malloc_ab (width, sizeof(uint32_t));
  1.1151 +    if (!argb8_pixels)
  1.1152 +	return;
  1.1153 +
  1.1154 +    /* Contract the scanline.  We could do this in place if values weren't
  1.1155 +     * const.
  1.1156 +     */
  1.1157 +    pixman_contract_from_float (argb8_pixels, (argb_t *)values, width);
  1.1158 +
  1.1159 +    image->store_scanline_32 (image, x, y, width, argb8_pixels);
  1.1160 +
  1.1161 +    free (argb8_pixels);
  1.1162 +}
  1.1163 +
  1.1164 +static void
  1.1165 +fetch_scanline_generic_float (pixman_image_t *image,
  1.1166 +			      int	      x,
  1.1167 +			      int	      y,
  1.1168 +			      int	      width,
  1.1169 +			      uint32_t *      buffer,
  1.1170 +			      const uint32_t *mask)
  1.1171 +{
  1.1172 +    image->bits.fetch_scanline_32 (image, x, y, width, buffer, NULL);
  1.1173 +
  1.1174 +    pixman_expand_to_float ((argb_t *)buffer, buffer, image->bits.format, width);
  1.1175 +}
  1.1176 +
  1.1177 +/* The 32_sRGB paths should be deleted after narrow processing
  1.1178 + * is no longer invoked for formats that are considered wide.
  1.1179 + * (Also see fetch_pixel_generic_lossy_32) */
  1.1180 +static void
  1.1181 +fetch_scanline_a8r8g8b8_32_sRGB (pixman_image_t *image,
  1.1182 +                                 int             x,
  1.1183 +                                 int             y,
  1.1184 +                                 int             width,
  1.1185 +                                 uint32_t       *buffer,
  1.1186 +                                 const uint32_t *mask)
  1.1187 +{
  1.1188 +    const uint32_t *bits = image->bits.bits + y * image->bits.rowstride;
  1.1189 +    const uint32_t *pixel = (uint32_t *)bits + x;
  1.1190 +    const uint32_t *end = pixel + width;
  1.1191 +    uint32_t tmp;
  1.1192 +    
  1.1193 +    while (pixel < end)
  1.1194 +    {
  1.1195 +	uint8_t a, r, g, b;
  1.1196 +
  1.1197 +	tmp = READ (image, pixel++);
  1.1198 +
  1.1199 +	a = (tmp >> 24) & 0xff;
  1.1200 +	r = (tmp >> 16) & 0xff;
  1.1201 +	g = (tmp >> 8) & 0xff;
  1.1202 +	b = (tmp >> 0) & 0xff;
  1.1203 +
  1.1204 +	r = to_linear[r] * 255.0f + 0.5f;
  1.1205 +	g = to_linear[g] * 255.0f + 0.5f;
  1.1206 +	b = to_linear[b] * 255.0f + 0.5f;
  1.1207 +
  1.1208 +	*buffer++ = (a << 24) | (r << 16) | (g << 8) | (b << 0);
  1.1209 +    }
  1.1210 +}
  1.1211 +
  1.1212 +static uint32_t
  1.1213 +fetch_pixel_a8r8g8b8_32_sRGB (bits_image_t *image,
  1.1214 +			      int           offset,
  1.1215 +			      int           line)
  1.1216 +{
  1.1217 +    uint32_t *bits = image->bits + line * image->rowstride;
  1.1218 +    uint32_t tmp = READ (image, bits + offset);
  1.1219 +    uint8_t a, r, g, b;
  1.1220 +
  1.1221 +    a = (tmp >> 24) & 0xff;
  1.1222 +    r = (tmp >> 16) & 0xff;
  1.1223 +    g = (tmp >> 8) & 0xff;
  1.1224 +    b = (tmp >> 0) & 0xff;
  1.1225 +
  1.1226 +    r = to_linear[r] * 255.0f + 0.5f;
  1.1227 +    g = to_linear[g] * 255.0f + 0.5f;
  1.1228 +    b = to_linear[b] * 255.0f + 0.5f;
  1.1229 +
  1.1230 +    return (a << 24) | (r << 16) | (g << 8) | (b << 0);
  1.1231 +}
  1.1232 +
  1.1233 +static void
  1.1234 +store_scanline_a8r8g8b8_32_sRGB (bits_image_t   *image,
  1.1235 +                                 int             x,
  1.1236 +                                 int             y,
  1.1237 +                                 int             width,
  1.1238 +                                 const uint32_t *v)
  1.1239 +{
  1.1240 +    uint32_t *bits = image->bits + image->rowstride * y;
  1.1241 +    uint64_t *values = (uint64_t *)v;
  1.1242 +    uint32_t *pixel = bits + x;
  1.1243 +    uint64_t tmp;
  1.1244 +    int i;
  1.1245 +    
  1.1246 +    for (i = 0; i < width; ++i)
  1.1247 +    {
  1.1248 +	uint8_t a, r, g, b;
  1.1249 +
  1.1250 +	tmp = values[i];
  1.1251 +
  1.1252 +	a = (tmp >> 24) & 0xff;
  1.1253 +	r = (tmp >> 16) & 0xff;
  1.1254 +	g = (tmp >> 8) & 0xff;
  1.1255 +	b = (tmp >> 0) & 0xff;
  1.1256 +
  1.1257 +	r = to_srgb (r * (1/255.0f));
  1.1258 +	g = to_srgb (g * (1/255.0f));
  1.1259 +	b = to_srgb (b * (1/255.0f));
  1.1260 +	
  1.1261 +	WRITE (image, pixel++, a | (r << 16) | (g << 8) | (b << 0));
  1.1262 +    }
  1.1263 +}
  1.1264 +
  1.1265 +static argb_t
  1.1266 +fetch_pixel_generic_float (bits_image_t *image,
  1.1267 +			   int		 offset,
  1.1268 +			   int           line)
  1.1269 +{
  1.1270 +    uint32_t pixel32 = image->fetch_pixel_32 (image, offset, line);
  1.1271 +    argb_t f;
  1.1272 +
  1.1273 +    pixman_expand_to_float (&f, &pixel32, image->format, 1);
  1.1274 +
  1.1275 +    return f;
  1.1276 +}
  1.1277 +
  1.1278 +/*
  1.1279 + * XXX: The transformed fetch path only works at 32-bpp so far.  When all
  1.1280 + * paths have wide versions, this can be removed.
  1.1281 + *
  1.1282 + * WARNING: This function loses precision!
  1.1283 + */
  1.1284 +static uint32_t
  1.1285 +fetch_pixel_generic_lossy_32 (bits_image_t *image,
  1.1286 +			      int           offset,
  1.1287 +			      int           line)
  1.1288 +{
  1.1289 +    argb_t pixel64 = image->fetch_pixel_float (image, offset, line);
  1.1290 +    uint32_t result;
  1.1291 +
  1.1292 +    pixman_contract_from_float (&result, &pixel64, 1);
  1.1293 +
  1.1294 +    return result;
  1.1295 +}
  1.1296 +
  1.1297 +typedef struct
  1.1298 +{
  1.1299 +    pixman_format_code_t	format;
  1.1300 +    fetch_scanline_t		fetch_scanline_16;
  1.1301 +    fetch_scanline_t		fetch_scanline_32;
  1.1302 +    fetch_scanline_t		fetch_scanline_float;
  1.1303 +    fetch_pixel_32_t		fetch_pixel_32;
  1.1304 +    fetch_pixel_float_t		fetch_pixel_float;
  1.1305 +    store_scanline_t		store_scanline_16;
  1.1306 +    store_scanline_t		store_scanline_32;
  1.1307 +    store_scanline_t		store_scanline_float;
  1.1308 +} format_info_t;
  1.1309 +
  1.1310 +#define FORMAT_INFO(format) 						\
  1.1311 +    {									\
  1.1312 +	PIXMAN_ ## format,						\
  1.1313 +	    NULL,							\
  1.1314 +	    fetch_scanline_ ## format,					\
  1.1315 +	    fetch_scanline_generic_float,				\
  1.1316 +	    fetch_pixel_ ## format,					\
  1.1317 +	    fetch_pixel_generic_float,					\
  1.1318 +	    NULL,							\
  1.1319 +	    store_scanline_ ## format,					\
  1.1320 +	    store_scanline_generic_float				\
  1.1321 +    }
  1.1322 +#define FORMAT_INFO16(format) 						\
  1.1323 +    {									\
  1.1324 +	PIXMAN_ ## format,						\
  1.1325 +	    fetch_scanline_16,						\
  1.1326 +	    fetch_scanline_ ## format,					\
  1.1327 +	    fetch_scanline_generic_float,				\
  1.1328 +	    fetch_pixel_ ## format,					\
  1.1329 +	    fetch_pixel_generic_float,					\
  1.1330 +	    store_scanline_16,						\
  1.1331 +	    store_scanline_ ## format,					\
  1.1332 +	    store_scanline_generic_float				\
  1.1333 +    }
  1.1334 +
  1.1335 +
  1.1336 +static const format_info_t accessors[] =
  1.1337 +{
  1.1338 +/* 32 bpp formats */
  1.1339 +    FORMAT_INFO (a8r8g8b8),
  1.1340 +    FORMAT_INFO (x8r8g8b8),
  1.1341 +    FORMAT_INFO (a8b8g8r8),
  1.1342 +    FORMAT_INFO (x8b8g8r8),
  1.1343 +    FORMAT_INFO (b8g8r8a8),
  1.1344 +    FORMAT_INFO (b8g8r8x8),
  1.1345 +    FORMAT_INFO (r8g8b8a8),
  1.1346 +    FORMAT_INFO (r8g8b8x8),
  1.1347 +    FORMAT_INFO (x14r6g6b6),
  1.1348 +
  1.1349 +/* sRGB formats */
  1.1350 +  { PIXMAN_a8r8g8b8_sRGB,
  1.1351 +    NULL,
  1.1352 +    fetch_scanline_a8r8g8b8_32_sRGB, fetch_scanline_a8r8g8b8_sRGB_float,
  1.1353 +    fetch_pixel_a8r8g8b8_32_sRGB, fetch_pixel_a8r8g8b8_sRGB_float,
  1.1354 +    NULL,
  1.1355 +    store_scanline_a8r8g8b8_32_sRGB, store_scanline_a8r8g8b8_sRGB_float,
  1.1356 +  },
  1.1357 +
  1.1358 +/* 24bpp formats */
  1.1359 +    FORMAT_INFO (r8g8b8),
  1.1360 +    FORMAT_INFO (b8g8r8),
  1.1361 +    
  1.1362 +/* 16bpp formats */
  1.1363 +    FORMAT_INFO16 (r5g6b5),
  1.1364 +    FORMAT_INFO16 (b5g6r5),
  1.1365 +    
  1.1366 +    FORMAT_INFO (a1r5g5b5),
  1.1367 +    FORMAT_INFO (x1r5g5b5),
  1.1368 +    FORMAT_INFO (a1b5g5r5),
  1.1369 +    FORMAT_INFO (x1b5g5r5),
  1.1370 +    FORMAT_INFO (a4r4g4b4),
  1.1371 +    FORMAT_INFO (x4r4g4b4),
  1.1372 +    FORMAT_INFO (a4b4g4r4),
  1.1373 +    FORMAT_INFO (x4b4g4r4),
  1.1374 +    
  1.1375 +/* 8bpp formats */
  1.1376 +    FORMAT_INFO (a8),
  1.1377 +    FORMAT_INFO (r3g3b2),
  1.1378 +    FORMAT_INFO (b2g3r3),
  1.1379 +    FORMAT_INFO (a2r2g2b2),
  1.1380 +    FORMAT_INFO (a2b2g2r2),
  1.1381 +    
  1.1382 +    FORMAT_INFO (c8),
  1.1383 +    
  1.1384 +    FORMAT_INFO (g8),
  1.1385 +    
  1.1386 +#define fetch_scanline_x4c4 fetch_scanline_c8
  1.1387 +#define fetch_pixel_x4c4 fetch_pixel_c8
  1.1388 +#define store_scanline_x4c4 store_scanline_c8
  1.1389 +    FORMAT_INFO (x4c4),
  1.1390 +    
  1.1391 +#define fetch_scanline_x4g4 fetch_scanline_g8
  1.1392 +#define fetch_pixel_x4g4 fetch_pixel_g8
  1.1393 +#define store_scanline_x4g4 store_scanline_g8
  1.1394 +    FORMAT_INFO (x4g4),
  1.1395 +    
  1.1396 +    FORMAT_INFO (x4a4),
  1.1397 +    
  1.1398 +/* 4bpp formats */
  1.1399 +    FORMAT_INFO (a4),
  1.1400 +    FORMAT_INFO (r1g2b1),
  1.1401 +    FORMAT_INFO (b1g2r1),
  1.1402 +    FORMAT_INFO (a1r1g1b1),
  1.1403 +    FORMAT_INFO (a1b1g1r1),
  1.1404 +    
  1.1405 +    FORMAT_INFO (c4),
  1.1406 +    
  1.1407 +    FORMAT_INFO (g4),
  1.1408 +    
  1.1409 +/* 1bpp formats */
  1.1410 +    FORMAT_INFO (a1),
  1.1411 +    FORMAT_INFO (g1),
  1.1412 +    
  1.1413 +/* Wide formats */
  1.1414 +    
  1.1415 +    { PIXMAN_a2r10g10b10,
  1.1416 +      NULL, NULL, fetch_scanline_a2r10g10b10_float,
  1.1417 +      fetch_pixel_generic_lossy_32, fetch_pixel_a2r10g10b10_float,
  1.1418 +      NULL, NULL, store_scanline_a2r10g10b10_float },
  1.1419 +
  1.1420 +    { PIXMAN_x2r10g10b10,
  1.1421 +      NULL, NULL, fetch_scanline_x2r10g10b10_float,
  1.1422 +      fetch_pixel_generic_lossy_32, fetch_pixel_x2r10g10b10_float,
  1.1423 +      NULL, NULL, store_scanline_x2r10g10b10_float },
  1.1424 +
  1.1425 +    { PIXMAN_a2b10g10r10,
  1.1426 +      NULL, NULL, fetch_scanline_a2b10g10r10_float,
  1.1427 +      fetch_pixel_generic_lossy_32, fetch_pixel_a2b10g10r10_float,
  1.1428 +      NULL, NULL, store_scanline_a2b10g10r10_float },
  1.1429 +
  1.1430 +    { PIXMAN_x2b10g10r10,
  1.1431 +      NULL, NULL, fetch_scanline_x2b10g10r10_float,
  1.1432 +      fetch_pixel_generic_lossy_32, fetch_pixel_x2b10g10r10_float,
  1.1433 +      NULL, NULL, store_scanline_x2b10g10r10_float },
  1.1434 +
  1.1435 +/* YUV formats */
  1.1436 +    { PIXMAN_yuy2,
  1.1437 +      NULL, fetch_scanline_yuy2, fetch_scanline_generic_float,
  1.1438 +      fetch_pixel_yuy2, fetch_pixel_generic_float,
  1.1439 +      NULL, NULL, NULL },
  1.1440 +
  1.1441 +    { PIXMAN_yv12,
  1.1442 +      NULL, fetch_scanline_yv12, fetch_scanline_generic_float,
  1.1443 +      fetch_pixel_yv12, fetch_pixel_generic_float,
  1.1444 +      NULL, NULL, NULL },
  1.1445 +    
  1.1446 +    { PIXMAN_null },
  1.1447 +};
  1.1448 +
  1.1449 +static void
  1.1450 +setup_accessors (bits_image_t *image)
  1.1451 +{
  1.1452 +    const format_info_t *info = accessors;
  1.1453 +    
  1.1454 +    while (info->format != PIXMAN_null)
  1.1455 +    {
  1.1456 +	if (info->format == image->format)
  1.1457 +	{
  1.1458 +	    image->fetch_scanline_16 = info->fetch_scanline_16;
  1.1459 +	    image->fetch_scanline_32 = info->fetch_scanline_32;
  1.1460 +	    image->fetch_scanline_float = info->fetch_scanline_float;
  1.1461 +	    image->fetch_pixel_32 = info->fetch_pixel_32;
  1.1462 +	    image->fetch_pixel_float = info->fetch_pixel_float;
  1.1463 +	    image->store_scanline_16 = info->store_scanline_16;
  1.1464 +	    image->store_scanline_32 = info->store_scanline_32;
  1.1465 +	    image->store_scanline_float = info->store_scanline_float;
  1.1466 +	    
  1.1467 +	    return;
  1.1468 +	}
  1.1469 +	
  1.1470 +	info++;
  1.1471 +    }
  1.1472 +}
  1.1473 +
  1.1474 +#ifndef PIXMAN_FB_ACCESSORS
  1.1475 +void
  1.1476 +_pixman_bits_image_setup_accessors_accessors (bits_image_t *image);
  1.1477 +
  1.1478 +void
  1.1479 +_pixman_bits_image_setup_accessors (bits_image_t *image)
  1.1480 +{
  1.1481 +    if (image->read_func || image->write_func)
  1.1482 +	_pixman_bits_image_setup_accessors_accessors (image);
  1.1483 +    else
  1.1484 +	setup_accessors (image);
  1.1485 +}
  1.1486 +
  1.1487 +#else
  1.1488 +
  1.1489 +void
  1.1490 +_pixman_bits_image_setup_accessors_accessors (bits_image_t *image)
  1.1491 +{
  1.1492 +    setup_accessors (image);
  1.1493 +}
  1.1494 +
  1.1495 +#endif

mercurial