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