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

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

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

mercurial