3 * Copyright © 2000 Keith Packard, member of The XFree86 Project, Inc.
4 * 2005 Lars Knoll & Zack Rusin, Trolltech
5 * 2008 Aaron Plattner, NVIDIA Corporation
7 * Permission to use, copy, modify, distribute, and sell this software and its
8 * documentation for any purpose is hereby granted without fee, provided that
9 * the above copyright notice appear in all copies and that both that
10 * copyright notice and this permission notice appear in supporting
11 * documentation, and that the name of Keith Packard not be used in
12 * advertising or publicity pertaining to distribution of the software without
13 * specific, written prior permission. Keith Packard makes no
14 * representations about the suitability of this software for any purpose. It
15 * is provided "as is" without express or implied warranty.
17 * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
18 * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
19 * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
20 * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
21 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
22 * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
23 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
35 #include "pixman-private.h"
37 #define Red(x) (((x) >> 16) & 0xff)
38 #define Green(x) (((x) >> 8) & 0xff)
39 #define Blue(x) ((x) & 0xff)
42 * YV12 setup and access macros
45 #define YV12_SETUP(pict) \
46 uint32_t *bits = pict->bits; \
47 int stride = pict->rowstride; \
48 int offset0 = stride < 0 ? \
49 ((-stride) >> 1) * ((pict->height - 1) >> 1) - stride : \
50 stride * pict->height; \
51 int offset1 = stride < 0 ? \
52 offset0 + ((-stride) >> 1) * ((pict->height) >> 1) : \
53 offset0 + (offset0 >> 2)
54 /* Note no trailing semicolon on the above macro; if it's there, then
55 * the typical usage of YV12_SETUP(pict); will have an extra trailing ;
56 * that some compilers will interpret as a statement -- and then any further
57 * variable declarations will cause an error.
60 #define YV12_Y(line) \
61 ((uint8_t *) ((bits) + (stride) * (line)))
63 #define YV12_U(line) \
64 ((uint8_t *) ((bits) + offset1 + \
65 ((stride) >> 1) * ((line) >> 1)))
67 #define YV12_V(line) \
68 ((uint8_t *) ((bits) + offset0 + \
69 ((stride) >> 1) * ((line) >> 1)))
71 /*********************************** Fetch ************************************/
74 fbFetch_a8r8g8b8 (bits_image_t *pict, int x, int y, int width, uint32_t *buffer)
76 const uint32_t *bits = pict->bits + y*pict->rowstride;
78 buffer, (const uint32_t *)bits + x,
79 width*sizeof(uint32_t));
83 fbFetch_x8r8g8b8 (bits_image_t *pict, int x, int y, int width, uint32_t *buffer)
85 const uint32_t *bits = pict->bits + y*pict->rowstride;
86 const uint32_t *pixel = (const uint32_t *)bits + x;
87 const uint32_t *end = pixel + width;
89 *buffer++ = READ(pict, pixel++) | 0xff000000;
94 fbFetch_a8b8g8r8 (bits_image_t *pict, int x, int y, int width, uint32_t *buffer)
96 const uint32_t *bits = pict->bits + y*pict->rowstride;
97 const uint32_t *pixel = (uint32_t *)bits + x;
98 const uint32_t *end = pixel + width;
100 uint32_t p = READ(pict, pixel++);
101 *buffer++ = (p & 0xff00ff00) |
108 fbFetch_x8b8g8r8 (bits_image_t *pict, int x, int y, int width, uint32_t *buffer)
110 const uint32_t *bits = pict->bits + y*pict->rowstride;
111 const uint32_t *pixel = (uint32_t *)bits + x;
112 const uint32_t *end = pixel + width;
113 while (pixel < end) {
114 uint32_t p = READ(pict, pixel++);
115 *buffer++ = 0xff000000 |
123 fbFetch_b8g8r8a8 (bits_image_t *pict, int x, int y, int width, uint32_t *buffer)
125 const uint32_t *bits = pict->bits + y*pict->rowstride;
126 const uint32_t *pixel = (uint32_t *)bits + x;
127 const uint32_t *end = pixel + width;
128 while (pixel < end) {
129 uint32_t p = READ(pict, pixel++);
130 *buffer++ = ((p & 0xff000000) >> 24) |
131 ((p & 0x00ff0000) >> 8) |
132 ((p & 0x0000ff00) << 8) |
133 ((p & 0x000000ff) << 24);
138 fbFetch_b8g8r8x8 (bits_image_t *pict, int x, int y, int width, uint32_t *buffer)
140 const uint32_t *bits = pict->bits + y*pict->rowstride;
141 const uint32_t *pixel = (uint32_t *)bits + x;
142 const uint32_t *end = pixel + width;
143 while (pixel < end) {
144 uint32_t p = READ(pict, pixel++);
145 *buffer++ = 0xff000000 |
146 ((p & 0xff000000) >> 24) |
147 ((p & 0x00ff0000) >> 8) |
148 ((p & 0x0000ff00) << 8);
153 fbFetch_a2b10g10r10 (bits_image_t *pict, int x, int y, int width, uint64_t *buffer)
155 const uint32_t *bits = pict->bits + y*pict->rowstride;
156 const uint32_t *pixel = bits + x;
157 const uint32_t *end = pixel + width;
158 while (pixel < end) {
159 uint32_t p = READ(pict, pixel++);
160 uint64_t a = p >> 30;
161 uint64_t b = (p >> 20) & 0x3ff;
162 uint64_t g = (p >> 10) & 0x3ff;
163 uint64_t r = p & 0x3ff;
174 *buffer++ = a << 48 | r << 32 | g << 16 | b;
179 fbFetch_x2b10g10r10 (bits_image_t *pict, int x, int y, int width, uint64_t *buffer)
181 const uint32_t *bits = pict->bits + y*pict->rowstride;
182 const uint32_t *pixel = (uint32_t *)bits + x;
183 const uint32_t *end = pixel + width;
184 while (pixel < end) {
185 uint32_t p = READ(pict, pixel++);
186 uint64_t b = (p >> 20) & 0x3ff;
187 uint64_t g = (p >> 10) & 0x3ff;
188 uint64_t r = p & 0x3ff;
194 *buffer++ = 0xffffULL << 48 | r << 32 | g << 16 | b;
199 fbFetch_r8g8b8 (bits_image_t *pict, int x, int y, int width, uint32_t *buffer)
201 const uint32_t *bits = pict->bits + y*pict->rowstride;
202 const uint8_t *pixel = (const uint8_t *)bits + 3*x;
203 const uint8_t *end = pixel + 3*width;
204 while (pixel < end) {
205 uint32_t b = Fetch24(pict, pixel) | 0xff000000;
212 fbFetch_b8g8r8 (bits_image_t *pict, int x, int y, int width, uint32_t *buffer)
214 const uint32_t *bits = pict->bits + y*pict->rowstride;
215 const uint8_t *pixel = (const uint8_t *)bits + 3*x;
216 const uint8_t *end = pixel + 3*width;
217 while (pixel < end) {
218 uint32_t b = 0xff000000;
219 #if IMAGE_BYTE_ORDER == MSBFirst
220 b |= (READ(pict, pixel++));
221 b |= (READ(pict, pixel++) << 8);
222 b |= (READ(pict, pixel++) << 16);
224 b |= (READ(pict, pixel++) << 16);
225 b |= (READ(pict, pixel++) << 8);
226 b |= (READ(pict, pixel++));
233 fbFetch_r5g6b5 (bits_image_t *pict, int x, int y, int width, uint32_t *buffer)
235 const uint32_t *bits = pict->bits + y*pict->rowstride;
236 const uint16_t *pixel = (const uint16_t *)bits + x;
237 const uint16_t *end = pixel + width;
238 while (pixel < end) {
239 uint32_t p = READ(pict, pixel++);
240 uint32_t r = (((p) << 3) & 0xf8) |
241 (((p) << 5) & 0xfc00) |
242 (((p) << 8) & 0xf80000);
243 r |= (r >> 5) & 0x70007;
244 r |= (r >> 6) & 0x300;
245 *buffer++ = 0xff000000 | r;
250 fbFetch_b5g6r5 (bits_image_t *pict, int x, int y, int width, uint32_t *buffer)
253 const uint32_t *bits = pict->bits + y*pict->rowstride;
254 const uint16_t *pixel = (const uint16_t *)bits + x;
255 const uint16_t *end = pixel + width;
256 while (pixel < end) {
257 uint32_t p = READ(pict, pixel++);
258 b = ((p & 0xf800) | ((p & 0xe000) >> 5)) >> 8;
259 g = ((p & 0x07e0) | ((p & 0x0600) >> 6)) << 5;
260 r = ((p & 0x001c) | ((p & 0x001f) << 5)) << 14;
261 *buffer++ = 0xff000000 | r | g | b;
266 fbFetch_a1r5g5b5 (bits_image_t *pict, int x, int y, int width, uint32_t *buffer)
269 const uint32_t *bits = pict->bits + y*pict->rowstride;
270 const uint16_t *pixel = (const uint16_t *)bits + x;
271 const uint16_t *end = pixel + width;
272 while (pixel < end) {
273 uint32_t p = READ(pict, pixel++);
275 a = (uint32_t) ((uint8_t) (0 - ((p & 0x8000) >> 15))) << 24;
276 r = ((p & 0x7c00) | ((p & 0x7000) >> 5)) << 9;
277 g = ((p & 0x03e0) | ((p & 0x0380) >> 5)) << 6;
278 b = ((p & 0x001c) | ((p & 0x001f) << 5)) >> 2;
279 *buffer++ = a | r | g | b;
284 fbFetch_x1r5g5b5 (bits_image_t *pict, int x, int y, int width, uint32_t *buffer)
287 const uint32_t *bits = pict->bits + y*pict->rowstride;
288 const uint16_t *pixel = (const uint16_t *)bits + x;
289 const uint16_t *end = pixel + width;
290 while (pixel < end) {
291 uint32_t p = READ(pict, pixel++);
293 r = ((p & 0x7c00) | ((p & 0x7000) >> 5)) << 9;
294 g = ((p & 0x03e0) | ((p & 0x0380) >> 5)) << 6;
295 b = ((p & 0x001c) | ((p & 0x001f) << 5)) >> 2;
296 *buffer++ = 0xff000000 | r | g | b;
301 fbFetch_a1b5g5r5 (bits_image_t *pict, int x, int y, int width, uint32_t *buffer)
304 const uint32_t *bits = pict->bits + y*pict->rowstride;
305 const uint16_t *pixel = (const uint16_t *)bits + x;
306 const uint16_t *end = pixel + width;
307 while (pixel < end) {
308 uint32_t p = READ(pict, pixel++);
310 a = (uint32_t) ((uint8_t) (0 - ((p & 0x8000) >> 15))) << 24;
311 b = ((p & 0x7c00) | ((p & 0x7000) >> 5)) >> 7;
312 g = ((p & 0x03e0) | ((p & 0x0380) >> 5)) << 6;
313 r = ((p & 0x001c) | ((p & 0x001f) << 5)) << 14;
314 *buffer++ = a | r | g | b;
319 fbFetch_x1b5g5r5 (bits_image_t *pict, int x, int y, int width, uint32_t *buffer)
322 const uint32_t *bits = pict->bits + y*pict->rowstride;
323 const uint16_t *pixel = (const uint16_t *)bits + x;
324 const uint16_t *end = pixel + width;
325 while (pixel < end) {
326 uint32_t p = READ(pict, pixel++);
328 b = ((p & 0x7c00) | ((p & 0x7000) >> 5)) >> 7;
329 g = ((p & 0x03e0) | ((p & 0x0380) >> 5)) << 6;
330 r = ((p & 0x001c) | ((p & 0x001f) << 5)) << 14;
331 *buffer++ = 0xff000000 | r | g | b;
336 fbFetch_a4r4g4b4 (bits_image_t *pict, int x, int y, int width, uint32_t *buffer)
339 const uint32_t *bits = pict->bits + y*pict->rowstride;
340 const uint16_t *pixel = (const uint16_t *)bits + x;
341 const uint16_t *end = pixel + width;
342 while (pixel < end) {
343 uint32_t p = READ(pict, pixel++);
345 a = ((p & 0xf000) | ((p & 0xf000) >> 4)) << 16;
346 r = ((p & 0x0f00) | ((p & 0x0f00) >> 4)) << 12;
347 g = ((p & 0x00f0) | ((p & 0x00f0) >> 4)) << 8;
348 b = ((p & 0x000f) | ((p & 0x000f) << 4));
349 *buffer++ = a | r | g | b;
354 fbFetch_x4r4g4b4 (bits_image_t *pict, int x, int y, int width, uint32_t *buffer)
357 const uint32_t *bits = pict->bits + y*pict->rowstride;
358 const uint16_t *pixel = (const uint16_t *)bits + x;
359 const uint16_t *end = pixel + width;
360 while (pixel < end) {
361 uint32_t p = READ(pict, pixel++);
363 r = ((p & 0x0f00) | ((p & 0x0f00) >> 4)) << 12;
364 g = ((p & 0x00f0) | ((p & 0x00f0) >> 4)) << 8;
365 b = ((p & 0x000f) | ((p & 0x000f) << 4));
366 *buffer++ = 0xff000000 | r | g | b;
371 fbFetch_a4b4g4r4 (bits_image_t *pict, int x, int y, int width, uint32_t *buffer)
374 const uint32_t *bits = pict->bits + y*pict->rowstride;
375 const uint16_t *pixel = (const uint16_t *)bits + x;
376 const uint16_t *end = pixel + width;
377 while (pixel < end) {
378 uint32_t p = READ(pict, pixel++);
380 a = ((p & 0xf000) | ((p & 0xf000) >> 4)) << 16;
381 b = ((p & 0x0f00) | ((p & 0x0f00) >> 4)) >> 4;
382 g = ((p & 0x00f0) | ((p & 0x00f0) >> 4)) << 8;
383 r = ((p & 0x000f) | ((p & 0x000f) << 4)) << 16;
384 *buffer++ = a | r | g | b;
389 fbFetch_x4b4g4r4 (bits_image_t *pict, int x, int y, int width, uint32_t *buffer)
392 const uint32_t *bits = pict->bits + y*pict->rowstride;
393 const uint16_t *pixel = (const uint16_t *)bits + x;
394 const uint16_t *end = pixel + width;
395 while (pixel < end) {
396 uint32_t p = READ(pict, pixel++);
398 b = ((p & 0x0f00) | ((p & 0x0f00) >> 4)) >> 4;
399 g = ((p & 0x00f0) | ((p & 0x00f0) >> 4)) << 8;
400 r = ((p & 0x000f) | ((p & 0x000f) << 4)) << 16;
401 *buffer++ = 0xff000000 | r | g | b;
406 fbFetch_a8 (bits_image_t *pict, int x, int y, int width, uint32_t *buffer)
408 const uint32_t *bits = pict->bits + y*pict->rowstride;
409 const uint8_t *pixel = (const uint8_t *)bits + x;
410 const uint8_t *end = pixel + width;
411 while (pixel < end) {
412 *buffer++ = READ(pict, pixel++) << 24;
417 fbFetch_r3g3b2 (bits_image_t *pict, int x, int y, int width, uint32_t *buffer)
420 const uint32_t *bits = pict->bits + y*pict->rowstride;
421 const uint8_t *pixel = (const uint8_t *)bits + x;
422 const uint8_t *end = pixel + width;
423 while (pixel < end) {
424 uint32_t p = READ(pict, pixel++);
426 r = ((p & 0xe0) | ((p & 0xe0) >> 3) | ((p & 0xc0) >> 6)) << 16;
427 g = ((p & 0x1c) | ((p & 0x18) >> 3) | ((p & 0x1c) << 3)) << 8;
432 *buffer++ = 0xff000000 | r | g | b;
437 fbFetch_b2g3r3 (bits_image_t *pict, int x, int y, int width, uint32_t *buffer)
440 const uint32_t *bits = pict->bits + y*pict->rowstride;
441 const uint8_t *pixel = (const uint8_t *)bits + x;
442 const uint8_t *end = pixel + width;
443 while (pixel < end) {
444 uint32_t p = READ(pict, pixel++);
450 g = ((p & 0x38) | ((p & 0x38) >> 3) | ((p & 0x30) << 2)) << 8;
453 ((p & 0x06) << 6)) << 16;
454 *buffer++ = 0xff000000 | r | g | b;
459 fbFetch_a2r2g2b2 (bits_image_t *pict, int x, int y, int width, uint32_t *buffer)
462 const uint32_t *bits = pict->bits + y*pict->rowstride;
463 const uint8_t *pixel = (const uint8_t *)bits + x;
464 const uint8_t *end = pixel + width;
465 while (pixel < end) {
466 uint32_t p = READ(pict, pixel++);
468 a = ((p & 0xc0) * 0x55) << 18;
469 r = ((p & 0x30) * 0x55) << 12;
470 g = ((p & 0x0c) * 0x55) << 6;
471 b = ((p & 0x03) * 0x55);
477 fbFetch_a2b2g2r2 (bits_image_t *pict, int x, int y, int width, uint32_t *buffer)
480 const uint32_t *bits = pict->bits + y*pict->rowstride;
481 const uint8_t *pixel = (const uint8_t *)bits + x;
482 const uint8_t *end = pixel + width;
483 while (pixel < end) {
484 uint32_t p = READ(pict, pixel++);
486 a = ((p & 0xc0) * 0x55) << 18;
487 b = ((p & 0x30) * 0x55) >> 6;
488 g = ((p & 0x0c) * 0x55) << 6;
489 r = ((p & 0x03) * 0x55) << 16;
495 fbFetch_c8 (bits_image_t *pict, int x, int y, int width, uint32_t *buffer)
497 const uint32_t *bits = pict->bits + y*pict->rowstride;
498 const pixman_indexed_t * indexed = pict->indexed;
499 const uint8_t *pixel = (const uint8_t *)bits + x;
500 const uint8_t *end = pixel + width;
501 while (pixel < end) {
502 uint32_t p = READ(pict, pixel++);
503 *buffer++ = indexed->rgba[p];
508 fbFetch_x4a4 (bits_image_t *pict, int x, int y, int width, uint32_t *buffer)
510 const uint32_t *bits = pict->bits + y*pict->rowstride;
511 const uint8_t *pixel = (const uint8_t *)bits + x;
512 const uint8_t *end = pixel + width;
513 while (pixel < end) {
514 uint8_t p = READ(pict, pixel++) & 0xf;
515 *buffer++ = (p | (p << 4)) << 24;
519 #define Fetch8(img,l,o) (READ(img, (uint8_t *)(l) + ((o) >> 2)))
520 #if IMAGE_BYTE_ORDER == MSBFirst
521 #define Fetch4(img,l,o) ((o) & 2 ? Fetch8(img,l,o) & 0xf : Fetch8(img,l,o) >> 4)
523 #define Fetch4(img,l,o) ((o) & 2 ? Fetch8(img,l,o) >> 4 : Fetch8(img,l,o) & 0xf)
527 fbFetch_a4 (bits_image_t *pict, int x, int y, int width, uint32_t *buffer)
529 const uint32_t *bits = pict->bits + y*pict->rowstride;
531 for (i = 0; i < width; ++i) {
532 uint32_t p = Fetch4(pict, bits, i + x);
540 fbFetch_r1g2b1 (bits_image_t *pict, int x, int y, int width, uint32_t *buffer)
543 const uint32_t *bits = pict->bits + y*pict->rowstride;
545 for (i = 0; i < width; ++i) {
546 uint32_t p = Fetch4(pict, bits, i + x);
548 r = ((p & 0x8) * 0xff) << 13;
549 g = ((p & 0x6) * 0x55) << 7;
550 b = ((p & 0x1) * 0xff);
551 *buffer++ = 0xff000000|r|g|b;
556 fbFetch_b1g2r1 (bits_image_t *pict, int x, int y, int width, uint32_t *buffer)
559 const uint32_t *bits = pict->bits + y*pict->rowstride;
561 for (i = 0; i < width; ++i) {
562 uint32_t p = Fetch4(pict, bits, i + x);
564 b = ((p & 0x8) * 0xff) >> 3;
565 g = ((p & 0x6) * 0x55) << 7;
566 r = ((p & 0x1) * 0xff) << 16;
567 *buffer++ = 0xff000000|r|g|b;
572 fbFetch_a1r1g1b1 (bits_image_t *pict, int x, int y, int width, uint32_t *buffer)
575 const uint32_t *bits = pict->bits + y*pict->rowstride;
577 for (i = 0; i < width; ++i) {
578 uint32_t p = Fetch4(pict, bits, i + x);
580 a = ((p & 0x8) * 0xff) << 21;
581 r = ((p & 0x4) * 0xff) << 14;
582 g = ((p & 0x2) * 0xff) << 7;
583 b = ((p & 0x1) * 0xff);
589 fbFetch_a1b1g1r1 (bits_image_t *pict, int x, int y, int width, uint32_t *buffer)
592 const uint32_t *bits = pict->bits + y*pict->rowstride;
594 for (i = 0; i < width; ++i) {
595 uint32_t p = Fetch4(pict, bits, i + x);
597 a = ((p & 0x8) * 0xff) << 21;
598 r = ((p & 0x4) * 0xff) >> 3;
599 g = ((p & 0x2) * 0xff) << 7;
600 b = ((p & 0x1) * 0xff) << 16;
606 fbFetch_c4 (bits_image_t *pict, int x, int y, int width, uint32_t *buffer)
608 const uint32_t *bits = pict->bits + y*pict->rowstride;
609 const pixman_indexed_t * indexed = pict->indexed;
611 for (i = 0; i < width; ++i) {
612 uint32_t p = Fetch4(pict, bits, i + x);
614 *buffer++ = indexed->rgba[p];
620 fbFetch_a1 (bits_image_t *pict, int x, int y, int width, uint32_t *buffer)
622 const uint32_t *bits = pict->bits + y*pict->rowstride;
624 for (i = 0; i < width; ++i) {
625 uint32_t p = READ(pict, bits + ((i + x) >> 5));
627 #if BITMAP_BIT_ORDER == MSBFirst
628 a = p >> (0x1f - ((i+x) & 0x1f));
630 a = p >> ((i+x) & 0x1f);
641 fbFetch_g1 (bits_image_t *pict, int x, int y, int width, uint32_t *buffer)
643 const uint32_t *bits = pict->bits + y*pict->rowstride;
644 const pixman_indexed_t * indexed = pict->indexed;
646 for (i = 0; i < width; ++i) {
647 uint32_t p = READ(pict, bits + ((i+x) >> 5));
649 #if BITMAP_BIT_ORDER == MSBFirst
650 a = p >> (0x1f - ((i+x) & 0x1f));
652 a = p >> ((i+x) & 0x1f);
655 *buffer++ = indexed->rgba[a];
660 fbFetch_yuy2 (bits_image_t *pict, int x, int line, int width, uint32_t *buffer)
666 const uint32_t *bits = pict->bits + pict->rowstride * line;
668 for (i = 0; i < width; i++)
670 y = ((uint8_t *) bits)[(x + i) << 1] - 16;
671 u = ((uint8_t *) bits)[(((x + i) << 1) & -4) + 1] - 128;
672 v = ((uint8_t *) bits)[(((x + i) << 1) & -4) + 3] - 128;
674 /* R = 1.164(Y - 16) + 1.596(V - 128) */
675 r = 0x012b27 * y + 0x019a2e * v;
676 /* G = 1.164(Y - 16) - 0.813(V - 128) - 0.391(U - 128) */
677 g = 0x012b27 * y - 0x00d0f2 * v - 0x00647e * u;
678 /* B = 1.164(Y - 16) + 2.018(U - 128) */
679 b = 0x012b27 * y + 0x0206a2 * u;
681 WRITE(pict, buffer++, 0xff000000 |
682 (r >= 0 ? r < 0x1000000 ? r & 0xff0000 : 0xff0000 : 0) |
683 (g >= 0 ? g < 0x1000000 ? (g >> 8) & 0x00ff00 : 0x00ff00 : 0) |
684 (b >= 0 ? b < 0x1000000 ? (b >> 16) & 0x0000ff : 0x0000ff : 0));
689 fbFetch_yv12 (bits_image_t *pict, int x, int line, int width, uint32_t *buffer)
692 uint8_t *pY = YV12_Y (line);
693 uint8_t *pU = YV12_U (line);
694 uint8_t *pV = YV12_V (line);
699 for (i = 0; i < width; i++)
702 u = pU[(x + i) >> 1] - 128;
703 v = pV[(x + i) >> 1] - 128;
705 /* R = 1.164(Y - 16) + 1.596(V - 128) */
706 r = 0x012b27 * y + 0x019a2e * v;
707 /* G = 1.164(Y - 16) - 0.813(V - 128) - 0.391(U - 128) */
708 g = 0x012b27 * y - 0x00d0f2 * v - 0x00647e * u;
709 /* B = 1.164(Y - 16) + 2.018(U - 128) */
710 b = 0x012b27 * y + 0x0206a2 * u;
712 WRITE(pict, buffer++, 0xff000000 |
713 (r >= 0 ? r < 0x1000000 ? r & 0xff0000 : 0xff0000 : 0) |
714 (g >= 0 ? g < 0x1000000 ? (g >> 8) & 0x00ff00 : 0x00ff00 : 0) |
715 (b >= 0 ? b < 0x1000000 ? (b >> 16) & 0x0000ff : 0x0000ff : 0));
719 fetchProc32 ACCESS(pixman_fetchProcForPicture32) (bits_image_t * pict)
721 switch(pict->format) {
722 case PIXMAN_a8r8g8b8: return fbFetch_a8r8g8b8;
723 case PIXMAN_x8r8g8b8: return fbFetch_x8r8g8b8;
724 case PIXMAN_a8b8g8r8: return fbFetch_a8b8g8r8;
725 case PIXMAN_x8b8g8r8: return fbFetch_x8b8g8r8;
726 case PIXMAN_b8g8r8a8: return fbFetch_b8g8r8a8;
727 case PIXMAN_b8g8r8x8: return fbFetch_b8g8r8x8;
728 /* These two require wide compositing */
729 case PIXMAN_a2b10g10r10: return NULL;
730 case PIXMAN_x2b10g10r10: return NULL;
733 case PIXMAN_r8g8b8: return fbFetch_r8g8b8;
734 case PIXMAN_b8g8r8: return fbFetch_b8g8r8;
737 case PIXMAN_r5g6b5: return fbFetch_r5g6b5;
738 case PIXMAN_b5g6r5: return fbFetch_b5g6r5;
740 case PIXMAN_a1r5g5b5: return fbFetch_a1r5g5b5;
741 case PIXMAN_x1r5g5b5: return fbFetch_x1r5g5b5;
742 case PIXMAN_a1b5g5r5: return fbFetch_a1b5g5r5;
743 case PIXMAN_x1b5g5r5: return fbFetch_x1b5g5r5;
744 case PIXMAN_a4r4g4b4: return fbFetch_a4r4g4b4;
745 case PIXMAN_x4r4g4b4: return fbFetch_x4r4g4b4;
746 case PIXMAN_a4b4g4r4: return fbFetch_a4b4g4r4;
747 case PIXMAN_x4b4g4r4: return fbFetch_x4b4g4r4;
750 case PIXMAN_a8: return fbFetch_a8;
751 case PIXMAN_r3g3b2: return fbFetch_r3g3b2;
752 case PIXMAN_b2g3r3: return fbFetch_b2g3r3;
753 case PIXMAN_a2r2g2b2: return fbFetch_a2r2g2b2;
754 case PIXMAN_a2b2g2r2: return fbFetch_a2b2g2r2;
755 case PIXMAN_c8: return fbFetch_c8;
756 case PIXMAN_g8: return fbFetch_c8;
757 case PIXMAN_x4a4: return fbFetch_x4a4;
760 case PIXMAN_a4: return fbFetch_a4;
761 case PIXMAN_r1g2b1: return fbFetch_r1g2b1;
762 case PIXMAN_b1g2r1: return fbFetch_b1g2r1;
763 case PIXMAN_a1r1g1b1: return fbFetch_a1r1g1b1;
764 case PIXMAN_a1b1g1r1: return fbFetch_a1b1g1r1;
765 case PIXMAN_c4: return fbFetch_c4;
766 case PIXMAN_g4: return fbFetch_c4;
769 case PIXMAN_a1: return fbFetch_a1;
770 case PIXMAN_g1: return fbFetch_g1;
773 case PIXMAN_yuy2: return fbFetch_yuy2;
774 case PIXMAN_yv12: return fbFetch_yv12;
781 fbFetch64_generic (bits_image_t *pict, int x, int y, int width, uint64_t *buffer)
783 fetchProc32 fetch32 = ACCESS(pixman_fetchProcForPicture32) (pict);
785 // Fetch the pixels into the first half of buffer and then expand them in
787 fetch32(pict, x, y, width, (uint32_t*)buffer);
788 pixman_expand(buffer, (uint32_t*)buffer, pict->format, width);
791 fetchProc64 ACCESS(pixman_fetchProcForPicture64) (bits_image_t * pict)
793 switch(pict->format) {
794 case PIXMAN_a2b10g10r10: return fbFetch_a2b10g10r10;
795 case PIXMAN_x2b10g10r10: return fbFetch_x2b10g10r10;
796 default: return fbFetch64_generic;
800 /**************************** Pixel wise fetching *****************************/
802 static FASTCALL uint64_t
803 fbFetchPixel_a2b10g10r10 (bits_image_t *pict, int offset, int line)
805 uint32_t *bits = pict->bits + line*pict->rowstride;
806 uint32_t p = READ(pict, bits + offset);
807 uint64_t a = p >> 30;
808 uint64_t b = (p >> 20) & 0x3ff;
809 uint64_t g = (p >> 10) & 0x3ff;
810 uint64_t r = p & 0x3ff;
821 return a << 48 | r << 32 | g << 16 | b;
824 static FASTCALL uint64_t
825 fbFetchPixel_x2b10g10r10 (bits_image_t *pict, int offset, int line)
827 uint32_t *bits = pict->bits + line*pict->rowstride;
828 uint32_t p = READ(pict, bits + offset);
829 uint64_t b = (p >> 20) & 0x3ff;
830 uint64_t g = (p >> 10) & 0x3ff;
831 uint64_t r = p & 0x3ff;
837 return 0xffffULL << 48 | r << 32 | g << 16 | b;
840 static FASTCALL uint32_t
841 fbFetchPixel_a8r8g8b8 (bits_image_t *pict, int offset, int line)
843 uint32_t *bits = pict->bits + line*pict->rowstride;
844 return READ(pict, (uint32_t *)bits + offset);
847 static FASTCALL uint32_t
848 fbFetchPixel_x8r8g8b8 (bits_image_t *pict, int offset, int line)
850 uint32_t *bits = pict->bits + line*pict->rowstride;
851 return READ(pict, (uint32_t *)bits + offset) | 0xff000000;
854 static FASTCALL uint32_t
855 fbFetchPixel_a8b8g8r8 (bits_image_t *pict, int offset, int line)
857 uint32_t *bits = pict->bits + line*pict->rowstride;
858 uint32_t pixel = READ(pict, (uint32_t *)bits + offset);
860 return ((pixel & 0xff000000) |
861 ((pixel >> 16) & 0xff) |
862 (pixel & 0x0000ff00) |
863 ((pixel & 0xff) << 16));
866 static FASTCALL uint32_t
867 fbFetchPixel_x8b8g8r8 (bits_image_t *pict, int offset, int line)
869 uint32_t *bits = pict->bits + line*pict->rowstride;
870 uint32_t pixel = READ(pict, (uint32_t *)bits + offset);
872 return ((0xff000000) |
873 ((pixel >> 16) & 0xff) |
874 (pixel & 0x0000ff00) |
875 ((pixel & 0xff) << 16));
878 static FASTCALL uint32_t
879 fbFetchPixel_b8g8r8a8 (bits_image_t *pict, int offset, int line)
881 uint32_t *bits = pict->bits + line*pict->rowstride;
882 uint32_t pixel = READ(pict, (uint32_t *)bits + offset);
884 return ((pixel & 0xff000000) >> 24 |
885 (pixel & 0x00ff0000) >> 8 |
886 (pixel & 0x0000ff00) << 8 |
887 (pixel & 0x000000ff) << 24);
890 static FASTCALL uint32_t
891 fbFetchPixel_b8g8r8x8 (bits_image_t *pict, int offset, int line)
893 uint32_t *bits = pict->bits + line*pict->rowstride;
894 uint32_t pixel = READ(pict, (uint32_t *)bits + offset);
896 return ((0xff000000) |
897 (pixel & 0xff000000) >> 24 |
898 (pixel & 0x00ff0000) >> 8 |
899 (pixel & 0x0000ff00) << 8);
902 static FASTCALL uint32_t
903 fbFetchPixel_r8g8b8 (bits_image_t *pict, int offset, int line)
905 uint32_t *bits = pict->bits + line*pict->rowstride;
906 uint8_t *pixel = ((uint8_t *) bits) + (offset*3);
907 #if IMAGE_BYTE_ORDER == MSBFirst
909 (READ(pict, pixel + 0) << 16) |
910 (READ(pict, pixel + 1) << 8) |
911 (READ(pict, pixel + 2)));
914 (READ(pict, pixel + 2) << 16) |
915 (READ(pict, pixel + 1) << 8) |
916 (READ(pict, pixel + 0)));
920 static FASTCALL uint32_t
921 fbFetchPixel_b8g8r8 (bits_image_t *pict, int offset, int line)
923 uint32_t *bits = pict->bits + line*pict->rowstride;
924 uint8_t *pixel = ((uint8_t *) bits) + (offset*3);
925 #if IMAGE_BYTE_ORDER == MSBFirst
927 (READ(pict, pixel + 2) << 16) |
928 (READ(pict, pixel + 1) << 8) |
929 (READ(pict, pixel + 0)));
932 (READ(pict, pixel + 0) << 16) |
933 (READ(pict, pixel + 1) << 8) |
934 (READ(pict, pixel + 2)));
938 static FASTCALL uint32_t
939 fbFetchPixel_r5g6b5 (bits_image_t *pict, int offset, int line)
942 uint32_t *bits = pict->bits + line*pict->rowstride;
943 uint32_t pixel = READ(pict, (uint16_t *) bits + offset);
945 r = ((pixel & 0xf800) | ((pixel & 0xe000) >> 5)) << 8;
946 g = ((pixel & 0x07e0) | ((pixel & 0x0600) >> 6)) << 5;
947 b = ((pixel & 0x001c) | ((pixel & 0x001f) << 5)) >> 2;
948 return (0xff000000 | r | g | b);
951 static FASTCALL uint32_t
952 fbFetchPixel_b5g6r5 (bits_image_t *pict, int offset, int line)
955 uint32_t *bits = pict->bits + line*pict->rowstride;
956 uint32_t pixel = READ(pict, (uint16_t *) bits + offset);
958 b = ((pixel & 0xf800) | ((pixel & 0xe000) >> 5)) >> 8;
959 g = ((pixel & 0x07e0) | ((pixel & 0x0600) >> 6)) << 5;
960 r = ((pixel & 0x001c) | ((pixel & 0x001f) << 5)) << 14;
961 return (0xff000000 | r | g | b);
964 static FASTCALL uint32_t
965 fbFetchPixel_a1r5g5b5 (bits_image_t *pict, int offset, int line)
968 uint32_t *bits = pict->bits + line*pict->rowstride;
969 uint32_t pixel = READ(pict, (uint16_t *) bits + offset);
971 a = (uint32_t) ((uint8_t) (0 - ((pixel & 0x8000) >> 15))) << 24;
972 r = ((pixel & 0x7c00) | ((pixel & 0x7000) >> 5)) << 9;
973 g = ((pixel & 0x03e0) | ((pixel & 0x0380) >> 5)) << 6;
974 b = ((pixel & 0x001c) | ((pixel & 0x001f) << 5)) >> 2;
975 return (a | r | g | b);
978 static FASTCALL uint32_t
979 fbFetchPixel_x1r5g5b5 (bits_image_t *pict, int offset, int line)
982 uint32_t *bits = pict->bits + line*pict->rowstride;
983 uint32_t pixel = READ(pict, (uint16_t *) bits + offset);
985 r = ((pixel & 0x7c00) | ((pixel & 0x7000) >> 5)) << 9;
986 g = ((pixel & 0x03e0) | ((pixel & 0x0380) >> 5)) << 6;
987 b = ((pixel & 0x001c) | ((pixel & 0x001f) << 5)) >> 2;
988 return (0xff000000 | r | g | b);
991 static FASTCALL uint32_t
992 fbFetchPixel_a1b5g5r5 (bits_image_t *pict, int offset, int line)
995 uint32_t *bits = pict->bits + line*pict->rowstride;
996 uint32_t pixel = READ(pict, (uint16_t *) bits + offset);
998 a = (uint32_t) ((uint8_t) (0 - ((pixel & 0x8000) >> 15))) << 24;
999 b = ((pixel & 0x7c00) | ((pixel & 0x7000) >> 5)) >> 7;
1000 g = ((pixel & 0x03e0) | ((pixel & 0x0380) >> 5)) << 6;
1001 r = ((pixel & 0x001c) | ((pixel & 0x001f) << 5)) << 14;
1002 return (a | r | g | b);
1005 static FASTCALL uint32_t
1006 fbFetchPixel_x1b5g5r5 (bits_image_t *pict, int offset, int line)
1009 uint32_t *bits = pict->bits + line*pict->rowstride;
1010 uint32_t pixel = READ(pict, (uint16_t *) bits + offset);
1012 b = ((pixel & 0x7c00) | ((pixel & 0x7000) >> 5)) >> 7;
1013 g = ((pixel & 0x03e0) | ((pixel & 0x0380) >> 5)) << 6;
1014 r = ((pixel & 0x001c) | ((pixel & 0x001f) << 5)) << 14;
1015 return (0xff000000 | r | g | b);
1018 static FASTCALL uint32_t
1019 fbFetchPixel_a4r4g4b4 (bits_image_t *pict, int offset, int line)
1022 uint32_t *bits = pict->bits + line*pict->rowstride;
1023 uint32_t pixel = READ(pict, (uint16_t *) bits + offset);
1025 a = ((pixel & 0xf000) | ((pixel & 0xf000) >> 4)) << 16;
1026 r = ((pixel & 0x0f00) | ((pixel & 0x0f00) >> 4)) << 12;
1027 g = ((pixel & 0x00f0) | ((pixel & 0x00f0) >> 4)) << 8;
1028 b = ((pixel & 0x000f) | ((pixel & 0x000f) << 4));
1029 return (a | r | g | b);
1032 static FASTCALL uint32_t
1033 fbFetchPixel_x4r4g4b4 (bits_image_t *pict, int offset, int line)
1036 uint32_t *bits = pict->bits + line*pict->rowstride;
1037 uint32_t pixel = READ(pict, (uint16_t *) bits + offset);
1039 r = ((pixel & 0x0f00) | ((pixel & 0x0f00) >> 4)) << 12;
1040 g = ((pixel & 0x00f0) | ((pixel & 0x00f0) >> 4)) << 8;
1041 b = ((pixel & 0x000f) | ((pixel & 0x000f) << 4));
1042 return (0xff000000 | r | g | b);
1045 static FASTCALL uint32_t
1046 fbFetchPixel_a4b4g4r4 (bits_image_t *pict, int offset, int line)
1049 uint32_t *bits = pict->bits + line*pict->rowstride;
1050 uint32_t pixel = READ(pict, (uint16_t *) bits + offset);
1052 a = ((pixel & 0xf000) | ((pixel & 0xf000) >> 4)) << 16;
1053 b = ((pixel & 0x0f00) | ((pixel & 0x0f00) >> 4)) >> 4;
1054 g = ((pixel & 0x00f0) | ((pixel & 0x00f0) >> 4)) << 8;
1055 r = ((pixel & 0x000f) | ((pixel & 0x000f) << 4)) << 16;
1056 return (a | r | g | b);
1059 static FASTCALL uint32_t
1060 fbFetchPixel_x4b4g4r4 (bits_image_t *pict, int offset, int line)
1063 uint32_t *bits = pict->bits + line*pict->rowstride;
1064 uint32_t pixel = READ(pict, (uint16_t *) bits + offset);
1066 b = ((pixel & 0x0f00) | ((pixel & 0x0f00) >> 4)) >> 4;
1067 g = ((pixel & 0x00f0) | ((pixel & 0x00f0) >> 4)) << 8;
1068 r = ((pixel & 0x000f) | ((pixel & 0x000f) << 4)) << 16;
1069 return (0xff000000 | r | g | b);
1072 static FASTCALL uint32_t
1073 fbFetchPixel_a8 (bits_image_t *pict, int offset, int line)
1075 uint32_t *bits = pict->bits + line*pict->rowstride;
1076 uint32_t pixel = READ(pict, (uint8_t *) bits + offset);
1081 static FASTCALL uint32_t
1082 fbFetchPixel_r3g3b2 (bits_image_t *pict, int offset, int line)
1085 uint32_t *bits = pict->bits + line*pict->rowstride;
1086 uint32_t pixel = READ(pict, (uint8_t *) bits + offset);
1088 r = ((pixel & 0xe0) | ((pixel & 0xe0) >> 3) | ((pixel & 0xc0) >> 6)) << 16;
1089 g = ((pixel & 0x1c) | ((pixel & 0x18) >> 3) | ((pixel & 0x1c) << 3)) << 8;
1090 b = (((pixel & 0x03) ) |
1091 ((pixel & 0x03) << 2) |
1092 ((pixel & 0x03) << 4) |
1093 ((pixel & 0x03) << 6));
1094 return (0xff000000 | r | g | b);
1097 static FASTCALL uint32_t
1098 fbFetchPixel_b2g3r3 (bits_image_t *pict, int offset, int line)
1101 uint32_t *bits = pict->bits + line*pict->rowstride;
1102 uint32_t pixel = READ(pict, (uint8_t *) bits + offset);
1104 b = (((pixel & 0xc0) ) |
1105 ((pixel & 0xc0) >> 2) |
1106 ((pixel & 0xc0) >> 4) |
1107 ((pixel & 0xc0) >> 6));
1108 g = ((pixel & 0x38) | ((pixel & 0x38) >> 3) | ((pixel & 0x30) << 2)) << 8;
1109 r = (((pixel & 0x07) ) |
1110 ((pixel & 0x07) << 3) |
1111 ((pixel & 0x06) << 6)) << 16;
1112 return (0xff000000 | r | g | b);
1115 static FASTCALL uint32_t
1116 fbFetchPixel_a2r2g2b2 (bits_image_t *pict, int offset, int line)
1119 uint32_t *bits = pict->bits + line*pict->rowstride;
1120 uint32_t pixel = READ(pict, (uint8_t *) bits + offset);
1122 a = ((pixel & 0xc0) * 0x55) << 18;
1123 r = ((pixel & 0x30) * 0x55) << 12;
1124 g = ((pixel & 0x0c) * 0x55) << 6;
1125 b = ((pixel & 0x03) * 0x55);
1129 static FASTCALL uint32_t
1130 fbFetchPixel_a2b2g2r2 (bits_image_t *pict, int offset, int line)
1133 uint32_t *bits = pict->bits + line*pict->rowstride;
1134 uint32_t pixel = READ(pict, (uint8_t *) bits + offset);
1136 a = ((pixel & 0xc0) * 0x55) << 18;
1137 b = ((pixel & 0x30) * 0x55) >> 6;
1138 g = ((pixel & 0x0c) * 0x55) << 6;
1139 r = ((pixel & 0x03) * 0x55) << 16;
1143 static FASTCALL uint32_t
1144 fbFetchPixel_c8 (bits_image_t *pict, int offset, int line)
1146 uint32_t *bits = pict->bits + line*pict->rowstride;
1147 uint32_t pixel = READ(pict, (uint8_t *) bits + offset);
1148 const pixman_indexed_t * indexed = pict->indexed;
1149 return indexed->rgba[pixel];
1152 static FASTCALL uint32_t
1153 fbFetchPixel_x4a4 (bits_image_t *pict, int offset, int line)
1155 uint32_t *bits = pict->bits + line*pict->rowstride;
1156 uint32_t pixel = READ(pict, (uint8_t *) bits + offset);
1158 return ((pixel & 0xf) | ((pixel & 0xf) << 4)) << 24;
1161 static FASTCALL uint32_t
1162 fbFetchPixel_a4 (bits_image_t *pict, int offset, int line)
1164 uint32_t *bits = pict->bits + line*pict->rowstride;
1165 uint32_t pixel = Fetch4(pict, bits, offset);
1167 pixel |= pixel << 4;
1171 static FASTCALL uint32_t
1172 fbFetchPixel_r1g2b1 (bits_image_t *pict, int offset, int line)
1175 uint32_t *bits = pict->bits + line*pict->rowstride;
1176 uint32_t pixel = Fetch4(pict, bits, offset);
1178 r = ((pixel & 0x8) * 0xff) << 13;
1179 g = ((pixel & 0x6) * 0x55) << 7;
1180 b = ((pixel & 0x1) * 0xff);
1181 return 0xff000000|r|g|b;
1184 static FASTCALL uint32_t
1185 fbFetchPixel_b1g2r1 (bits_image_t *pict, int offset, int line)
1188 uint32_t *bits = pict->bits + line*pict->rowstride;
1189 uint32_t pixel = Fetch4(pict, bits, offset);
1191 b = ((pixel & 0x8) * 0xff) >> 3;
1192 g = ((pixel & 0x6) * 0x55) << 7;
1193 r = ((pixel & 0x1) * 0xff) << 16;
1194 return 0xff000000|r|g|b;
1197 static FASTCALL uint32_t
1198 fbFetchPixel_a1r1g1b1 (bits_image_t *pict, int offset, int line)
1201 uint32_t *bits = pict->bits + line*pict->rowstride;
1202 uint32_t pixel = Fetch4(pict, bits, offset);
1204 a = ((pixel & 0x8) * 0xff) << 21;
1205 r = ((pixel & 0x4) * 0xff) << 14;
1206 g = ((pixel & 0x2) * 0xff) << 7;
1207 b = ((pixel & 0x1) * 0xff);
1211 static FASTCALL uint32_t
1212 fbFetchPixel_a1b1g1r1 (bits_image_t *pict, int offset, int line)
1215 uint32_t *bits = pict->bits + line*pict->rowstride;
1216 uint32_t pixel = Fetch4(pict, bits, offset);
1218 a = ((pixel & 0x8) * 0xff) << 21;
1219 r = ((pixel & 0x4) * 0xff) >> 3;
1220 g = ((pixel & 0x2) * 0xff) << 7;
1221 b = ((pixel & 0x1) * 0xff) << 16;
1225 static FASTCALL uint32_t
1226 fbFetchPixel_c4 (bits_image_t *pict, int offset, int line)
1228 uint32_t *bits = pict->bits + line*pict->rowstride;
1229 uint32_t pixel = Fetch4(pict, bits, offset);
1230 const pixman_indexed_t * indexed = pict->indexed;
1232 return indexed->rgba[pixel];
1236 static FASTCALL uint32_t
1237 fbFetchPixel_a1 (bits_image_t *pict, int offset, int line)
1239 uint32_t *bits = pict->bits + line*pict->rowstride;
1240 uint32_t pixel = READ(pict, bits + (offset >> 5));
1242 #if BITMAP_BIT_ORDER == MSBFirst
1243 a = pixel >> (0x1f - (offset & 0x1f));
1245 a = pixel >> (offset & 0x1f);
1254 static FASTCALL uint32_t
1255 fbFetchPixel_g1 (bits_image_t *pict, int offset, int line)
1257 uint32_t *bits = pict->bits + line*pict->rowstride;
1258 uint32_t pixel = READ(pict, bits + (offset >> 5));
1259 const pixman_indexed_t * indexed = pict->indexed;
1261 #if BITMAP_BIT_ORDER == MSBFirst
1262 a = pixel >> (0x1f - (offset & 0x1f));
1264 a = pixel >> (offset & 0x1f);
1267 return indexed->rgba[a];
1270 static FASTCALL uint32_t
1271 fbFetchPixel_yuy2 (bits_image_t *pict, int offset, int line)
1276 const uint32_t *bits = pict->bits + pict->rowstride * line;
1278 y = ((uint8_t *) bits)[offset << 1] - 16;
1279 u = ((uint8_t *) bits)[((offset << 1) & -4) + 1] - 128;
1280 v = ((uint8_t *) bits)[((offset << 1) & -4) + 3] - 128;
1282 /* R = 1.164(Y - 16) + 1.596(V - 128) */
1283 r = 0x012b27 * y + 0x019a2e * v;
1284 /* G = 1.164(Y - 16) - 0.813(V - 128) - 0.391(U - 128) */
1285 g = 0x012b27 * y - 0x00d0f2 * v - 0x00647e * u;
1286 /* B = 1.164(Y - 16) + 2.018(U - 128) */
1287 b = 0x012b27 * y + 0x0206a2 * u;
1290 (r >= 0 ? r < 0x1000000 ? r & 0xff0000 : 0xff0000 : 0) |
1291 (g >= 0 ? g < 0x1000000 ? (g >> 8) & 0x00ff00 : 0x00ff00 : 0) |
1292 (b >= 0 ? b < 0x1000000 ? (b >> 16) & 0x0000ff : 0x0000ff : 0);
1295 static FASTCALL uint32_t
1296 fbFetchPixel_yv12 (bits_image_t *pict, int offset, int line)
1299 int16_t y = YV12_Y (line)[offset] - 16;
1300 int16_t u = YV12_U (line)[offset >> 1] - 128;
1301 int16_t v = YV12_V (line)[offset >> 1] - 128;
1304 /* R = 1.164(Y - 16) + 1.596(V - 128) */
1305 r = 0x012b27 * y + 0x019a2e * v;
1306 /* G = 1.164(Y - 16) - 0.813(V - 128) - 0.391(U - 128) */
1307 g = 0x012b27 * y - 0x00d0f2 * v - 0x00647e * u;
1308 /* B = 1.164(Y - 16) + 2.018(U - 128) */
1309 b = 0x012b27 * y + 0x0206a2 * u;
1312 (r >= 0 ? r < 0x1000000 ? r & 0xff0000 : 0xff0000 : 0) |
1313 (g >= 0 ? g < 0x1000000 ? (g >> 8) & 0x00ff00 : 0x00ff00 : 0) |
1314 (b >= 0 ? b < 0x1000000 ? (b >> 16) & 0x0000ff : 0x0000ff : 0);
1318 * XXX: The transformed fetch path only works at 32-bpp so far. When all paths
1319 * have wide versions, this can be removed.
1321 * WARNING: This function loses precision!
1323 static FASTCALL uint32_t
1324 fbFetchPixel32_generic_lossy (bits_image_t *pict, int offset, int line)
1326 fetchPixelProc64 fetchPixel64 = ACCESS(pixman_fetchPixelProcForPicture64) (pict);
1327 const uint64_t argb16Pixel = fetchPixel64(pict, offset, line);
1328 uint32_t argb8Pixel;
1330 pixman_contract(&argb8Pixel, &argb16Pixel, 1);
1335 fetchPixelProc32 ACCESS(pixman_fetchPixelProcForPicture32) (bits_image_t * pict)
1337 switch(pict->format) {
1338 case PIXMAN_a8r8g8b8: return fbFetchPixel_a8r8g8b8;
1339 case PIXMAN_x8r8g8b8: return fbFetchPixel_x8r8g8b8;
1340 case PIXMAN_a8b8g8r8: return fbFetchPixel_a8b8g8r8;
1341 case PIXMAN_x8b8g8r8: return fbFetchPixel_x8b8g8r8;
1342 case PIXMAN_b8g8r8a8: return fbFetchPixel_b8g8r8a8;
1343 case PIXMAN_b8g8r8x8: return fbFetchPixel_b8g8r8x8;
1344 /* These two require wide compositing */
1345 case PIXMAN_a2b10g10r10: return fbFetchPixel32_generic_lossy;
1346 case PIXMAN_x2b10g10r10: return fbFetchPixel32_generic_lossy;
1349 case PIXMAN_r8g8b8: return fbFetchPixel_r8g8b8;
1350 case PIXMAN_b8g8r8: return fbFetchPixel_b8g8r8;
1353 case PIXMAN_r5g6b5: return fbFetchPixel_r5g6b5;
1354 case PIXMAN_b5g6r5: return fbFetchPixel_b5g6r5;
1356 case PIXMAN_a1r5g5b5: return fbFetchPixel_a1r5g5b5;
1357 case PIXMAN_x1r5g5b5: return fbFetchPixel_x1r5g5b5;
1358 case PIXMAN_a1b5g5r5: return fbFetchPixel_a1b5g5r5;
1359 case PIXMAN_x1b5g5r5: return fbFetchPixel_x1b5g5r5;
1360 case PIXMAN_a4r4g4b4: return fbFetchPixel_a4r4g4b4;
1361 case PIXMAN_x4r4g4b4: return fbFetchPixel_x4r4g4b4;
1362 case PIXMAN_a4b4g4r4: return fbFetchPixel_a4b4g4r4;
1363 case PIXMAN_x4b4g4r4: return fbFetchPixel_x4b4g4r4;
1366 case PIXMAN_a8: return fbFetchPixel_a8;
1367 case PIXMAN_r3g3b2: return fbFetchPixel_r3g3b2;
1368 case PIXMAN_b2g3r3: return fbFetchPixel_b2g3r3;
1369 case PIXMAN_a2r2g2b2: return fbFetchPixel_a2r2g2b2;
1370 case PIXMAN_a2b2g2r2: return fbFetchPixel_a2b2g2r2;
1371 case PIXMAN_c8: return fbFetchPixel_c8;
1372 case PIXMAN_g8: return fbFetchPixel_c8;
1373 case PIXMAN_x4a4: return fbFetchPixel_x4a4;
1376 case PIXMAN_a4: return fbFetchPixel_a4;
1377 case PIXMAN_r1g2b1: return fbFetchPixel_r1g2b1;
1378 case PIXMAN_b1g2r1: return fbFetchPixel_b1g2r1;
1379 case PIXMAN_a1r1g1b1: return fbFetchPixel_a1r1g1b1;
1380 case PIXMAN_a1b1g1r1: return fbFetchPixel_a1b1g1r1;
1381 case PIXMAN_c4: return fbFetchPixel_c4;
1382 case PIXMAN_g4: return fbFetchPixel_c4;
1385 case PIXMAN_a1: return fbFetchPixel_a1;
1386 case PIXMAN_g1: return fbFetchPixel_g1;
1389 case PIXMAN_yuy2: return fbFetchPixel_yuy2;
1390 case PIXMAN_yv12: return fbFetchPixel_yv12;
1396 static FASTCALL uint64_t
1397 fbFetchPixel64_generic (bits_image_t *pict, int offset, int line)
1399 fetchPixelProc32 fetchPixel32 = ACCESS(pixman_fetchPixelProcForPicture32) (pict);
1400 uint32_t argb8Pixel = fetchPixel32(pict, offset, line);
1401 uint64_t argb16Pixel;
1403 pixman_expand(&argb16Pixel, &argb8Pixel, pict->format, 1);
1408 fetchPixelProc64 ACCESS(pixman_fetchPixelProcForPicture64) (bits_image_t * pict)
1410 switch(pict->format) {
1411 case PIXMAN_a2b10g10r10: return fbFetchPixel_a2b10g10r10;
1412 case PIXMAN_x2b10g10r10: return fbFetchPixel_x2b10g10r10;
1413 default: return fbFetchPixel64_generic;
1417 /*********************************** Store ************************************/
1419 #define Splita(v) uint32_t a = ((v) >> 24), r = ((v) >> 16) & 0xff, g = ((v) >> 8) & 0xff, b = (v) & 0xff
1420 #define Split(v) uint32_t r = ((v) >> 16) & 0xff, g = ((v) >> 8) & 0xff, b = (v) & 0xff
1422 static FASTCALL void
1423 fbStore_a2b10g10r10 (pixman_image_t *image,
1424 uint32_t *bits, const uint64_t *values, int x, int width, const pixman_indexed_t * indexed)
1427 uint32_t *pixel = bits + x;
1428 for (i = 0; i < width; ++i) {
1429 WRITE(image, pixel++,
1430 ((values[i] >> 32) & 0xc0000000) | // A
1431 ((values[i] >> 38) & 0x3ff) | // R
1432 ((values[i] >> 12) & 0xffc00) | // G
1433 ((values[i] << 14) & 0x3ff00000)); // B
1437 static FASTCALL void
1438 fbStore_x2b10g10r10 (pixman_image_t *image,
1439 uint32_t *bits, const uint64_t *values, int x, int width, const pixman_indexed_t * indexed)
1442 uint32_t *pixel = bits + x;
1443 for (i = 0; i < width; ++i) {
1444 WRITE(image, pixel++,
1445 ((values[i] >> 38) & 0x3ff) | // R
1446 ((values[i] >> 12) & 0xffc00) | // G
1447 ((values[i] << 14) & 0x3ff00000)); // B
1451 static FASTCALL void
1452 fbStore_a8r8g8b8 (pixman_image_t *image,
1453 uint32_t *bits, const uint32_t *values, int x, int width, const pixman_indexed_t * indexed)
1455 MEMCPY_WRAPPED(image, ((uint32_t *)bits) + x, values, width*sizeof(uint32_t));
1458 static FASTCALL void
1459 fbStore_x8r8g8b8 (pixman_image_t *image,
1460 uint32_t *bits, const uint32_t *values, int x, int width, const pixman_indexed_t * indexed)
1463 uint32_t *pixel = (uint32_t *)bits + x;
1464 for (i = 0; i < width; ++i)
1465 WRITE(image, pixel++, values[i] & 0xffffff);
1468 static FASTCALL void
1469 fbStore_a8b8g8r8 (pixman_image_t *image,
1470 uint32_t *bits, const uint32_t *values, int x, int width, const pixman_indexed_t * indexed)
1473 uint32_t *pixel = (uint32_t *)bits + x;
1474 for (i = 0; i < width; ++i)
1475 WRITE(image, pixel++, (values[i] & 0xff00ff00) | ((values[i] >> 16) & 0xff) | ((values[i] & 0xff) << 16));
1478 static FASTCALL void
1479 fbStore_x8b8g8r8 (pixman_image_t *image,
1480 uint32_t *bits, const uint32_t *values, int x, int width, const pixman_indexed_t * indexed)
1483 uint32_t *pixel = (uint32_t *)bits + x;
1484 for (i = 0; i < width; ++i)
1485 WRITE(image, pixel++, (values[i] & 0x0000ff00) | ((values[i] >> 16) & 0xff) | ((values[i] & 0xff) << 16));
1488 static FASTCALL void
1489 fbStore_b8g8r8a8 (pixman_image_t *image,
1490 uint32_t *bits, const uint32_t *values, int x, int width, const pixman_indexed_t * indexed)
1493 uint32_t *pixel = (uint32_t *)bits + x;
1494 for (i = 0; i < width; ++i)
1495 WRITE(image, pixel++,
1496 ((values[i] >> 24) & 0x000000ff) |
1497 ((values[i] >> 8) & 0x0000ff00) |
1498 ((values[i] << 8) & 0x00ff0000) |
1499 ((values[i] << 24) & 0xff000000));
1502 static FASTCALL void
1503 fbStore_b8g8r8x8 (pixman_image_t *image,
1504 uint32_t *bits, const uint32_t *values, int x, int width, const pixman_indexed_t * indexed)
1507 uint32_t *pixel = (uint32_t *)bits + x;
1508 for (i = 0; i < width; ++i)
1509 WRITE(image, pixel++,
1510 ((values[i] >> 8) & 0x0000ff00) |
1511 ((values[i] << 8) & 0x00ff0000) |
1512 ((values[i] << 24) & 0xff000000));
1515 static FASTCALL void
1516 fbStore_r8g8b8 (pixman_image_t *image,
1517 uint32_t *bits, const uint32_t *values, int x, int width,
1518 const pixman_indexed_t * indexed)
1521 uint8_t *pixel = ((uint8_t *) bits) + 3*x;
1522 for (i = 0; i < width; ++i) {
1523 Store24(image, pixel, values[i]);
1528 static FASTCALL void
1529 fbStore_b8g8r8 (pixman_image_t *image,
1530 uint32_t *bits, const uint32_t *values, int x, int width, const pixman_indexed_t * indexed)
1533 uint8_t *pixel = ((uint8_t *) bits) + 3*x;
1534 for (i = 0; i < width; ++i) {
1535 uint32_t val = values[i];
1536 #if IMAGE_BYTE_ORDER == MSBFirst
1537 WRITE(image, pixel++, Blue(val));
1538 WRITE(image, pixel++, Green(val));
1539 WRITE(image, pixel++, Red(val));
1541 WRITE(image, pixel++, Red(val));
1542 WRITE(image, pixel++, Green(val));
1543 WRITE(image, pixel++, Blue(val));
1548 static FASTCALL void
1549 fbStore_r5g6b5 (pixman_image_t *image,
1550 uint32_t *bits, const uint32_t *values, int x, int width, const pixman_indexed_t * indexed)
1553 uint16_t *pixel = ((uint16_t *) bits) + x;
1554 for (i = 0; i < width; ++i) {
1555 uint32_t s = values[i];
1556 WRITE(image, pixel++, ((s >> 3) & 0x001f) |
1557 ((s >> 5) & 0x07e0) |
1558 ((s >> 8) & 0xf800));
1562 static FASTCALL void
1563 fbStore_b5g6r5 (pixman_image_t *image,
1564 uint32_t *bits, const uint32_t *values, int x, int width, const pixman_indexed_t * indexed)
1567 uint16_t *pixel = ((uint16_t *) bits) + x;
1568 for (i = 0; i < width; ++i) {
1570 WRITE(image, pixel++, ((b << 8) & 0xf800) |
1571 ((g << 3) & 0x07e0) |
1576 static FASTCALL void
1577 fbStore_a1r5g5b5 (pixman_image_t *image,
1578 uint32_t *bits, const uint32_t *values, int x, int width, const pixman_indexed_t * indexed)
1581 uint16_t *pixel = ((uint16_t *) bits) + x;
1582 for (i = 0; i < width; ++i) {
1584 WRITE(image, pixel++, ((a << 8) & 0x8000) |
1585 ((r << 7) & 0x7c00) |
1586 ((g << 2) & 0x03e0) |
1591 static FASTCALL void
1592 fbStore_x1r5g5b5 (pixman_image_t *image,
1593 uint32_t *bits, const uint32_t *values, int x, int width, const pixman_indexed_t * indexed)
1596 uint16_t *pixel = ((uint16_t *) bits) + x;
1597 for (i = 0; i < width; ++i) {
1599 WRITE(image, pixel++, ((r << 7) & 0x7c00) |
1600 ((g << 2) & 0x03e0) |
1605 static FASTCALL void
1606 fbStore_a1b5g5r5 (pixman_image_t *image,
1607 uint32_t *bits, const uint32_t *values, int x, int width, const pixman_indexed_t * indexed)
1610 uint16_t *pixel = ((uint16_t *) bits) + x;
1611 for (i = 0; i < width; ++i) {
1613 WRITE(image, pixel++, ((a << 8) & 0x8000) |
1614 ((b << 7) & 0x7c00) |
1615 ((g << 2) & 0x03e0) |
1620 static FASTCALL void
1621 fbStore_x1b5g5r5 (pixman_image_t *image,
1622 uint32_t *bits, const uint32_t *values, int x, int width, const pixman_indexed_t * indexed)
1625 uint16_t *pixel = ((uint16_t *) bits) + x;
1626 for (i = 0; i < width; ++i) {
1628 WRITE(image, pixel++, ((b << 7) & 0x7c00) |
1629 ((g << 2) & 0x03e0) |
1634 static FASTCALL void
1635 fbStore_a4r4g4b4 (pixman_image_t *image,
1636 uint32_t *bits, const uint32_t *values, int x, int width, const pixman_indexed_t * indexed)
1639 uint16_t *pixel = ((uint16_t *) bits) + x;
1640 for (i = 0; i < width; ++i) {
1642 WRITE(image, pixel++, ((a << 8) & 0xf000) |
1643 ((r << 4) & 0x0f00) |
1649 static FASTCALL void
1650 fbStore_x4r4g4b4 (pixman_image_t *image,
1651 uint32_t *bits, const uint32_t *values, int x, int width, const pixman_indexed_t * indexed)
1654 uint16_t *pixel = ((uint16_t *) bits) + x;
1655 for (i = 0; i < width; ++i) {
1657 WRITE(image, pixel++, ((r << 4) & 0x0f00) |
1663 static FASTCALL void
1664 fbStore_a4b4g4r4 (pixman_image_t *image,
1665 uint32_t *bits, const uint32_t *values, int x, int width, const pixman_indexed_t * indexed)
1668 uint16_t *pixel = ((uint16_t *) bits) + x;
1669 for (i = 0; i < width; ++i) {
1671 WRITE(image, pixel++, ((a << 8) & 0xf000) |
1672 ((b << 4) & 0x0f00) |
1678 static FASTCALL void
1679 fbStore_x4b4g4r4 (pixman_image_t *image,
1680 uint32_t *bits, const uint32_t *values, int x, int width, const pixman_indexed_t * indexed)
1683 uint16_t *pixel = ((uint16_t *) bits) + x;
1684 for (i = 0; i < width; ++i) {
1686 WRITE(image, pixel++, ((b << 4) & 0x0f00) |
1692 static FASTCALL void
1693 fbStore_a8 (pixman_image_t *image,
1694 uint32_t *bits, const uint32_t *values, int x, int width, const pixman_indexed_t * indexed)
1697 uint8_t *pixel = ((uint8_t *) bits) + x;
1698 for (i = 0; i < width; ++i) {
1699 WRITE(image, pixel++, values[i] >> 24);
1703 static FASTCALL void
1704 fbStore_r3g3b2 (pixman_image_t *image,
1705 uint32_t *bits, const uint32_t *values, int x, int width, const pixman_indexed_t * indexed)
1708 uint8_t *pixel = ((uint8_t *) bits) + x;
1709 for (i = 0; i < width; ++i) {
1711 WRITE(image, pixel++,
1718 static FASTCALL void
1719 fbStore_b2g3r3 (pixman_image_t *image,
1720 uint32_t *bits, const uint32_t *values, int x, int width, const pixman_indexed_t * indexed)
1723 uint8_t *pixel = ((uint8_t *) bits) + x;
1724 for (i = 0; i < width; ++i) {
1726 WRITE(image, pixel++,
1733 static FASTCALL void
1734 fbStore_a2r2g2b2 (pixman_image_t *image,
1735 uint32_t *bits, const uint32_t *values, int x, int width, const pixman_indexed_t * indexed)
1738 uint8_t *pixel = ((uint8_t *) bits) + x;
1739 for (i = 0; i < width; ++i) {
1741 WRITE(image, pixel++, ((a ) & 0xc0) |
1748 static FASTCALL void
1749 fbStore_c8 (pixman_image_t *image,
1750 uint32_t *bits, const uint32_t *values, int x, int width, const pixman_indexed_t * indexed)
1753 uint8_t *pixel = ((uint8_t *) bits) + x;
1754 for (i = 0; i < width; ++i) {
1755 WRITE(image, pixel++, miIndexToEnt24(indexed,values[i]));
1759 static FASTCALL void
1760 fbStore_x4a4 (pixman_image_t *image,
1761 uint32_t *bits, const uint32_t *values, int x, int width, const pixman_indexed_t * indexed)
1764 uint8_t *pixel = ((uint8_t *) bits) + x;
1765 for (i = 0; i < width; ++i) {
1766 WRITE(image, pixel++, values[i] >> 28);
1770 #define Store8(img,l,o,v) (WRITE(img, (uint8_t *)(l) + ((o) >> 3), (v)))
1771 #if IMAGE_BYTE_ORDER == MSBFirst
1772 #define Store4(img,l,o,v) Store8(img,l,o,((o) & 4 ? \
1773 (Fetch8(img,l,o) & 0xf0) | (v) : \
1774 (Fetch8(img,l,o) & 0x0f) | ((v) << 4)))
1776 #define Store4(img,l,o,v) Store8(img,l,o,((o) & 4 ? \
1777 (Fetch8(img,l,o) & 0x0f) | ((v) << 4) : \
1778 (Fetch8(img,l,o) & 0xf0) | (v)))
1781 static FASTCALL void
1782 fbStore_a4 (pixman_image_t *image,
1783 uint32_t *bits, const uint32_t *values, int x, int width, const pixman_indexed_t * indexed)
1786 for (i = 0; i < width; ++i) {
1787 Store4(image, bits, i + x, values[i]>>28);
1791 static FASTCALL void
1792 fbStore_r1g2b1 (pixman_image_t *image,
1793 uint32_t *bits, const uint32_t *values, int x, int width, const pixman_indexed_t * indexed)
1796 for (i = 0; i < width; ++i) {
1800 pixel = (((r >> 4) & 0x8) |
1803 Store4(image, bits, i + x, pixel);
1807 static FASTCALL void
1808 fbStore_b1g2r1 (pixman_image_t *image,
1809 uint32_t *bits, const uint32_t *values, int x, int width, const pixman_indexed_t * indexed)
1812 for (i = 0; i < width; ++i) {
1816 pixel = (((b >> 4) & 0x8) |
1819 Store4(image, bits, i + x, pixel);
1823 static FASTCALL void
1824 fbStore_a1r1g1b1 (pixman_image_t *image,
1825 uint32_t *bits, const uint32_t *values, int x, int width, const pixman_indexed_t * indexed)
1828 for (i = 0; i < width; ++i) {
1831 pixel = (((a >> 4) & 0x8) |
1835 Store4(image, bits, i + x, pixel);
1839 static FASTCALL void
1840 fbStore_a1b1g1r1 (pixman_image_t *image,
1841 uint32_t *bits, const uint32_t *values, int x, int width, const pixman_indexed_t * indexed)
1844 for (i = 0; i < width; ++i) {
1847 pixel = (((a >> 4) & 0x8) |
1851 Store4(image, bits, i + x, pixel);
1855 static FASTCALL void
1856 fbStore_c4 (pixman_image_t *image,
1857 uint32_t *bits, const uint32_t *values, int x, int width, const pixman_indexed_t * indexed)
1860 for (i = 0; i < width; ++i) {
1863 pixel = miIndexToEnt24(indexed, values[i]);
1864 Store4(image, bits, i + x, pixel);
1868 static FASTCALL void
1869 fbStore_a1 (pixman_image_t *image,
1870 uint32_t *bits, const uint32_t *values, int x, int width, const pixman_indexed_t * indexed)
1873 for (i = 0; i < width; ++i) {
1874 uint32_t *pixel = ((uint32_t *) bits) + ((i+x) >> 5);
1875 uint32_t mask = FbStipMask((i+x) & 0x1f, 1);
1877 uint32_t v = values[i] & 0x80000000 ? mask : 0;
1878 WRITE(image, pixel, (READ(image, pixel) & ~mask) | v);
1882 static FASTCALL void
1883 fbStore_g1 (pixman_image_t *image,
1884 uint32_t *bits, const uint32_t *values, int x, int width, const pixman_indexed_t * indexed)
1887 for (i = 0; i < width; ++i) {
1888 uint32_t *pixel = ((uint32_t *) bits) + ((i+x) >> 5);
1889 uint32_t mask = FbStipMask((i+x) & 0x1f, 1);
1891 uint32_t v = miIndexToEntY24(indexed,values[i]) ? mask : 0;
1892 WRITE(image, pixel, (READ(image, pixel) & ~mask) | v);
1897 storeProc32 ACCESS(pixman_storeProcForPicture32) (bits_image_t * pict)
1899 switch(pict->format) {
1900 case PIXMAN_a8r8g8b8: return fbStore_a8r8g8b8;
1901 case PIXMAN_x8r8g8b8: return fbStore_x8r8g8b8;
1902 case PIXMAN_a8b8g8r8: return fbStore_a8b8g8r8;
1903 case PIXMAN_x8b8g8r8: return fbStore_x8b8g8r8;
1904 case PIXMAN_b8g8r8a8: return fbStore_b8g8r8a8;
1905 case PIXMAN_b8g8r8x8: return fbStore_b8g8r8x8;
1908 case PIXMAN_r8g8b8: return fbStore_r8g8b8;
1909 case PIXMAN_b8g8r8: return fbStore_b8g8r8;
1912 case PIXMAN_r5g6b5: return fbStore_r5g6b5;
1913 case PIXMAN_b5g6r5: return fbStore_b5g6r5;
1915 case PIXMAN_a1r5g5b5: return fbStore_a1r5g5b5;
1916 case PIXMAN_x1r5g5b5: return fbStore_x1r5g5b5;
1917 case PIXMAN_a1b5g5r5: return fbStore_a1b5g5r5;
1918 case PIXMAN_x1b5g5r5: return fbStore_x1b5g5r5;
1919 case PIXMAN_a4r4g4b4: return fbStore_a4r4g4b4;
1920 case PIXMAN_x4r4g4b4: return fbStore_x4r4g4b4;
1921 case PIXMAN_a4b4g4r4: return fbStore_a4b4g4r4;
1922 case PIXMAN_x4b4g4r4: return fbStore_x4b4g4r4;
1925 case PIXMAN_a8: return fbStore_a8;
1926 case PIXMAN_r3g3b2: return fbStore_r3g3b2;
1927 case PIXMAN_b2g3r3: return fbStore_b2g3r3;
1928 case PIXMAN_a2r2g2b2: return fbStore_a2r2g2b2;
1929 case PIXMAN_c8: return fbStore_c8;
1930 case PIXMAN_g8: return fbStore_c8;
1931 case PIXMAN_x4a4: return fbStore_x4a4;
1934 case PIXMAN_a4: return fbStore_a4;
1935 case PIXMAN_r1g2b1: return fbStore_r1g2b1;
1936 case PIXMAN_b1g2r1: return fbStore_b1g2r1;
1937 case PIXMAN_a1r1g1b1: return fbStore_a1r1g1b1;
1938 case PIXMAN_a1b1g1r1: return fbStore_a1b1g1r1;
1939 case PIXMAN_c4: return fbStore_c4;
1940 case PIXMAN_g4: return fbStore_c4;
1943 case PIXMAN_a1: return fbStore_a1;
1944 case PIXMAN_g1: return fbStore_g1;
1951 * Contracts a 64bpp image to 32bpp and then stores it using a regular 32-bit
1954 static FASTCALL void
1955 fbStore64_generic (pixman_image_t *image,
1956 uint32_t *bits, const uint64_t *values, int x, int width, const pixman_indexed_t * indexed)
1958 bits_image_t *pict = (bits_image_t*)image;
1959 storeProc32 store32 = ACCESS(pixman_storeProcForPicture32) (pict);
1960 uint32_t *argb8Pixels;
1962 assert(image->common.type == BITS);
1965 argb8Pixels = pixman_malloc_ab (width, sizeof(uint32_t));
1966 if (!argb8Pixels) return;
1968 // Contract the scanline. We could do this in place if values weren't
1970 pixman_contract(argb8Pixels, values, width);
1971 store32(image, bits, argb8Pixels, x, width, indexed);
1976 storeProc64 ACCESS(pixman_storeProcForPicture64) (bits_image_t * pict)
1978 switch(pict->format) {
1979 case PIXMAN_a2b10g10r10: return fbStore_a2b10g10r10;
1980 case PIXMAN_x2b10g10r10: return fbStore_x2b10g10r10;
1981 default: return fbStore64_generic;
1985 #ifndef PIXMAN_FB_ACCESSORS
1987 * Helper routine to expand a color component from 0 < n <= 8 bits to 16 bits by
1990 static inline uint64_t expand16(const uint8_t val, int nbits)
1992 // Start out with the high bit of val in the high bit of result.
1993 uint16_t result = (uint16_t)val << (16 - nbits);
1998 // Copy the bits in result, doubling the number of bits each time, until we
1999 // fill all 16 bits.
2000 while (nbits < 16) {
2001 result |= result >> nbits;
2009 * This function expands images from ARGB8 format to ARGB16. To preserve
2010 * precision, it needs to know the original source format. For example, if the
2011 * source was PIXMAN_x1r5g5b5 and the red component contained bits 12345, then
2012 * the expanded value is 12345123. To correctly expand this to 16 bits, it
2013 * should be 1234512345123451 and not 1234512312345123.
2015 void pixman_expand(uint64_t *dst, const uint32_t *src,
2016 pixman_format_code_t format, int width)
2019 * Determine the sizes of each component and the masks and shifts required
2020 * to extract them from the source pixel.
2022 const int a_size = PIXMAN_FORMAT_A(format),
2023 r_size = PIXMAN_FORMAT_R(format),
2024 g_size = PIXMAN_FORMAT_G(format),
2025 b_size = PIXMAN_FORMAT_B(format);
2026 const int a_shift = 32 - a_size,
2027 r_shift = 24 - r_size,
2028 g_shift = 16 - g_size,
2029 b_shift = 8 - b_size;
2030 const uint8_t a_mask = ~(~0 << a_size),
2031 r_mask = ~(~0 << r_size),
2032 g_mask = ~(~0 << g_size),
2033 b_mask = ~(~0 << b_size);
2036 /* Start at the end so that we can do the expansion in place when src == dst */
2037 for (i = width - 1; i >= 0; i--)
2039 const uint32_t pixel = src[i];
2040 // Extract the components.
2041 const uint8_t a = (pixel >> a_shift) & a_mask,
2042 r = (pixel >> r_shift) & r_mask,
2043 g = (pixel >> g_shift) & g_mask,
2044 b = (pixel >> b_shift) & b_mask;
2045 const uint64_t a16 = a_size ? expand16(a, a_size) : 0xffff,
2046 r16 = expand16(r, r_size),
2047 g16 = expand16(g, g_size),
2048 b16 = expand16(b, b_size);
2050 dst[i] = a16 << 48 | r16 << 32 | g16 << 16 | b16;
2055 * Contracting is easier than expanding. We just need to truncate the
2058 void pixman_contract(uint32_t *dst, const uint64_t *src, int width)
2062 /* Start at the beginning so that we can do the contraction in place when
2064 for (i = 0; i < width; i++)
2066 const uint8_t a = src[i] >> 56,
2070 dst[i] = a << 24 | r << 16 | g << 8 | b;
2073 #endif // PIXMAN_FB_ACCESSORS