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 n 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_a2b10g10r10 (bits_image_t *pict, int x, int y, int width, uint64_t *buffer)
125 const uint32_t *bits = pict->bits + y*pict->rowstride;
126 const uint32_t *pixel = bits + x;
127 const uint32_t *end = pixel + width;
128 while (pixel < end) {
129 uint32_t p = READ(pict, pixel++);
130 uint64_t a = p >> 30;
131 uint64_t b = (p >> 20) & 0x3ff;
132 uint64_t g = (p >> 10) & 0x3ff;
133 uint64_t r = p & 0x3ff;
144 *buffer++ = a << 48 | r << 32 | g << 16 | b;
149 fbFetch_x2b10g10r10 (bits_image_t *pict, int x, int y, int width, uint64_t *buffer)
151 const uint32_t *bits = pict->bits + y*pict->rowstride;
152 const uint32_t *pixel = (uint32_t *)bits + x;
153 const uint32_t *end = pixel + width;
154 while (pixel < end) {
155 uint32_t p = READ(pict, pixel++);
156 uint64_t b = (p >> 20) & 0x3ff;
157 uint64_t g = (p >> 10) & 0x3ff;
158 uint64_t r = p & 0x3ff;
164 *buffer++ = 0xffffULL << 48 | r << 32 | g << 16 | b;
169 fbFetch_r8g8b8 (bits_image_t *pict, int x, int y, int width, uint32_t *buffer)
171 const uint32_t *bits = pict->bits + y*pict->rowstride;
172 const uint8_t *pixel = (const uint8_t *)bits + 3*x;
173 const uint8_t *end = pixel + 3*width;
174 while (pixel < end) {
175 uint32_t b = Fetch24(pict, pixel) | 0xff000000;
182 fbFetch_b8g8r8 (bits_image_t *pict, int x, int y, int width, uint32_t *buffer)
184 const uint32_t *bits = pict->bits + y*pict->rowstride;
185 const uint8_t *pixel = (const uint8_t *)bits + 3*x;
186 const uint8_t *end = pixel + 3*width;
187 while (pixel < end) {
188 uint32_t b = 0xff000000;
189 #if IMAGE_BYTE_ORDER == MSBFirst
190 b |= (READ(pict, pixel++));
191 b |= (READ(pict, pixel++) << 8);
192 b |= (READ(pict, pixel++) << 16);
194 b |= (READ(pict, pixel++) << 16);
195 b |= (READ(pict, pixel++) << 8);
196 b |= (READ(pict, pixel++));
203 fbFetch_r5g6b5 (bits_image_t *pict, int x, int y, int width, uint32_t *buffer)
205 const uint32_t *bits = pict->bits + y*pict->rowstride;
206 const uint16_t *pixel = (const uint16_t *)bits + x;
207 const uint16_t *end = pixel + width;
208 while (pixel < end) {
209 uint32_t p = READ(pict, pixel++);
210 uint32_t r = (((p) << 3) & 0xf8) |
211 (((p) << 5) & 0xfc00) |
212 (((p) << 8) & 0xf80000);
213 r |= (r >> 5) & 0x70007;
214 r |= (r >> 6) & 0x300;
215 *buffer++ = 0xff000000 | r;
220 fbFetch_b5g6r5 (bits_image_t *pict, int x, int y, int width, uint32_t *buffer)
223 const uint32_t *bits = pict->bits + y*pict->rowstride;
224 const uint16_t *pixel = (const uint16_t *)bits + x;
225 const uint16_t *end = pixel + width;
226 while (pixel < end) {
227 uint32_t p = READ(pict, pixel++);
228 b = ((p & 0xf800) | ((p & 0xe000) >> 5)) >> 8;
229 g = ((p & 0x07e0) | ((p & 0x0600) >> 6)) << 5;
230 r = ((p & 0x001c) | ((p & 0x001f) << 5)) << 14;
231 *buffer++ = 0xff000000 | r | g | b;
236 fbFetch_a1r5g5b5 (bits_image_t *pict, int x, int y, int width, uint32_t *buffer)
239 const uint32_t *bits = pict->bits + y*pict->rowstride;
240 const uint16_t *pixel = (const uint16_t *)bits + x;
241 const uint16_t *end = pixel + width;
242 while (pixel < end) {
243 uint32_t p = READ(pict, pixel++);
245 a = (uint32_t) ((uint8_t) (0 - ((p & 0x8000) >> 15))) << 24;
246 r = ((p & 0x7c00) | ((p & 0x7000) >> 5)) << 9;
247 g = ((p & 0x03e0) | ((p & 0x0380) >> 5)) << 6;
248 b = ((p & 0x001c) | ((p & 0x001f) << 5)) >> 2;
249 *buffer++ = a | r | g | b;
254 fbFetch_x1r5g5b5 (bits_image_t *pict, int x, int y, int width, uint32_t *buffer)
257 const uint32_t *bits = pict->bits + y*pict->rowstride;
258 const uint16_t *pixel = (const uint16_t *)bits + x;
259 const uint16_t *end = pixel + width;
260 while (pixel < end) {
261 uint32_t p = READ(pict, pixel++);
263 r = ((p & 0x7c00) | ((p & 0x7000) >> 5)) << 9;
264 g = ((p & 0x03e0) | ((p & 0x0380) >> 5)) << 6;
265 b = ((p & 0x001c) | ((p & 0x001f) << 5)) >> 2;
266 *buffer++ = 0xff000000 | r | g | b;
271 fbFetch_a1b5g5r5 (bits_image_t *pict, int x, int y, int width, uint32_t *buffer)
274 const uint32_t *bits = pict->bits + y*pict->rowstride;
275 const uint16_t *pixel = (const uint16_t *)bits + x;
276 const uint16_t *end = pixel + width;
277 while (pixel < end) {
278 uint32_t p = READ(pict, pixel++);
280 a = (uint32_t) ((uint8_t) (0 - ((p & 0x8000) >> 15))) << 24;
281 b = ((p & 0x7c00) | ((p & 0x7000) >> 5)) >> 7;
282 g = ((p & 0x03e0) | ((p & 0x0380) >> 5)) << 6;
283 r = ((p & 0x001c) | ((p & 0x001f) << 5)) << 14;
284 *buffer++ = a | r | g | b;
289 fbFetch_x1b5g5r5 (bits_image_t *pict, int x, int y, int width, uint32_t *buffer)
292 const uint32_t *bits = pict->bits + y*pict->rowstride;
293 const uint16_t *pixel = (const uint16_t *)bits + x;
294 const uint16_t *end = pixel + width;
295 while (pixel < end) {
296 uint32_t p = READ(pict, pixel++);
298 b = ((p & 0x7c00) | ((p & 0x7000) >> 5)) >> 7;
299 g = ((p & 0x03e0) | ((p & 0x0380) >> 5)) << 6;
300 r = ((p & 0x001c) | ((p & 0x001f) << 5)) << 14;
301 *buffer++ = 0xff000000 | r | g | b;
306 fbFetch_a4r4g4b4 (bits_image_t *pict, int x, int y, int width, uint32_t *buffer)
309 const uint32_t *bits = pict->bits + y*pict->rowstride;
310 const uint16_t *pixel = (const uint16_t *)bits + x;
311 const uint16_t *end = pixel + width;
312 while (pixel < end) {
313 uint32_t p = READ(pict, pixel++);
315 a = ((p & 0xf000) | ((p & 0xf000) >> 4)) << 16;
316 r = ((p & 0x0f00) | ((p & 0x0f00) >> 4)) << 12;
317 g = ((p & 0x00f0) | ((p & 0x00f0) >> 4)) << 8;
318 b = ((p & 0x000f) | ((p & 0x000f) << 4));
319 *buffer++ = a | r | g | b;
324 fbFetch_x4r4g4b4 (bits_image_t *pict, int x, int y, int width, uint32_t *buffer)
327 const uint32_t *bits = pict->bits + y*pict->rowstride;
328 const uint16_t *pixel = (const uint16_t *)bits + x;
329 const uint16_t *end = pixel + width;
330 while (pixel < end) {
331 uint32_t p = READ(pict, pixel++);
333 r = ((p & 0x0f00) | ((p & 0x0f00) >> 4)) << 12;
334 g = ((p & 0x00f0) | ((p & 0x00f0) >> 4)) << 8;
335 b = ((p & 0x000f) | ((p & 0x000f) << 4));
336 *buffer++ = 0xff000000 | r | g | b;
341 fbFetch_a4b4g4r4 (bits_image_t *pict, int x, int y, int width, uint32_t *buffer)
344 const uint32_t *bits = pict->bits + y*pict->rowstride;
345 const uint16_t *pixel = (const uint16_t *)bits + x;
346 const uint16_t *end = pixel + width;
347 while (pixel < end) {
348 uint32_t p = READ(pict, pixel++);
350 a = ((p & 0xf000) | ((p & 0xf000) >> 4)) << 16;
351 b = ((p & 0x0f00) | ((p & 0x0f00) >> 4)) >> 4;
352 g = ((p & 0x00f0) | ((p & 0x00f0) >> 4)) << 8;
353 r = ((p & 0x000f) | ((p & 0x000f) << 4)) << 16;
354 *buffer++ = a | r | g | b;
359 fbFetch_x4b4g4r4 (bits_image_t *pict, int x, int y, int width, uint32_t *buffer)
362 const uint32_t *bits = pict->bits + y*pict->rowstride;
363 const uint16_t *pixel = (const uint16_t *)bits + x;
364 const uint16_t *end = pixel + width;
365 while (pixel < end) {
366 uint32_t p = READ(pict, pixel++);
368 b = ((p & 0x0f00) | ((p & 0x0f00) >> 4)) >> 4;
369 g = ((p & 0x00f0) | ((p & 0x00f0) >> 4)) << 8;
370 r = ((p & 0x000f) | ((p & 0x000f) << 4)) << 16;
371 *buffer++ = 0xff000000 | r | g | b;
376 fbFetch_a8 (bits_image_t *pict, int x, int y, int width, uint32_t *buffer)
378 const uint32_t *bits = pict->bits + y*pict->rowstride;
379 const uint8_t *pixel = (const uint8_t *)bits + x;
380 const uint8_t *end = pixel + width;
381 while (pixel < end) {
382 *buffer++ = READ(pict, pixel++) << 24;
387 fbFetch_r3g3b2 (bits_image_t *pict, int x, int y, int width, uint32_t *buffer)
390 const uint32_t *bits = pict->bits + y*pict->rowstride;
391 const uint8_t *pixel = (const uint8_t *)bits + x;
392 const uint8_t *end = pixel + width;
393 while (pixel < end) {
394 uint32_t p = READ(pict, pixel++);
396 r = ((p & 0xe0) | ((p & 0xe0) >> 3) | ((p & 0xc0) >> 6)) << 16;
397 g = ((p & 0x1c) | ((p & 0x18) >> 3) | ((p & 0x1c) << 3)) << 8;
402 *buffer++ = 0xff000000 | r | g | b;
407 fbFetch_b2g3r3 (bits_image_t *pict, int x, int y, int width, uint32_t *buffer)
410 const uint32_t *bits = pict->bits + y*pict->rowstride;
411 const uint8_t *pixel = (const uint8_t *)bits + x;
412 const uint8_t *end = pixel + width;
413 while (pixel < end) {
414 uint32_t p = READ(pict, pixel++);
420 g = ((p & 0x38) | ((p & 0x38) >> 3) | ((p & 0x30) << 2)) << 8;
423 ((p & 0x06) << 6)) << 16;
424 *buffer++ = 0xff000000 | r | g | b;
429 fbFetch_a2r2g2b2 (bits_image_t *pict, int x, int y, int width, uint32_t *buffer)
432 const uint32_t *bits = pict->bits + y*pict->rowstride;
433 const uint8_t *pixel = (const uint8_t *)bits + x;
434 const uint8_t *end = pixel + width;
435 while (pixel < end) {
436 uint32_t p = READ(pict, pixel++);
438 a = ((p & 0xc0) * 0x55) << 18;
439 r = ((p & 0x30) * 0x55) << 12;
440 g = ((p & 0x0c) * 0x55) << 6;
441 b = ((p & 0x03) * 0x55);
447 fbFetch_a2b2g2r2 (bits_image_t *pict, int x, int y, int width, uint32_t *buffer)
450 const uint32_t *bits = pict->bits + y*pict->rowstride;
451 const uint8_t *pixel = (const uint8_t *)bits + x;
452 const uint8_t *end = pixel + width;
453 while (pixel < end) {
454 uint32_t p = READ(pict, pixel++);
456 a = ((p & 0xc0) * 0x55) << 18;
457 b = ((p & 0x30) * 0x55) >> 6;
458 g = ((p & 0x0c) * 0x55) << 6;
459 r = ((p & 0x03) * 0x55) << 16;
465 fbFetch_c8 (bits_image_t *pict, int x, int y, int width, uint32_t *buffer)
467 const uint32_t *bits = pict->bits + y*pict->rowstride;
468 const pixman_indexed_t * indexed = pict->indexed;
469 const uint8_t *pixel = (const uint8_t *)bits + x;
470 const uint8_t *end = pixel + width;
471 while (pixel < end) {
472 uint32_t p = READ(pict, pixel++);
473 *buffer++ = indexed->rgba[p];
478 fbFetch_x4a4 (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 uint8_t p = READ(pict, pixel++) & 0xf;
485 *buffer++ = (p | (p << 4)) << 24;
489 #define Fetch8(img,l,o) (READ(img, (uint8_t *)(l) + ((o) >> 2)))
490 #if IMAGE_BYTE_ORDER == MSBFirst
491 #define Fetch4(img,l,o) ((o) & 2 ? Fetch8(img,l,o) & 0xf : Fetch8(img,l,o) >> 4)
493 #define Fetch4(img,l,o) ((o) & 2 ? Fetch8(img,l,o) >> 4 : Fetch8(img,l,o) & 0xf)
497 fbFetch_a4 (bits_image_t *pict, int x, int y, int width, uint32_t *buffer)
499 const uint32_t *bits = pict->bits + y*pict->rowstride;
501 for (i = 0; i < width; ++i) {
502 uint32_t p = Fetch4(pict, bits, i + x);
510 fbFetch_r1g2b1 (bits_image_t *pict, int x, int y, int width, uint32_t *buffer)
513 const uint32_t *bits = pict->bits + y*pict->rowstride;
515 for (i = 0; i < width; ++i) {
516 uint32_t p = Fetch4(pict, bits, i + x);
518 r = ((p & 0x8) * 0xff) << 13;
519 g = ((p & 0x6) * 0x55) << 7;
520 b = ((p & 0x1) * 0xff);
521 *buffer++ = 0xff000000|r|g|b;
526 fbFetch_b1g2r1 (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);
534 b = ((p & 0x8) * 0xff) >> 3;
535 g = ((p & 0x6) * 0x55) << 7;
536 r = ((p & 0x1) * 0xff) << 16;
537 *buffer++ = 0xff000000|r|g|b;
542 fbFetch_a1r1g1b1 (bits_image_t *pict, int x, int y, int width, uint32_t *buffer)
545 const uint32_t *bits = pict->bits + y*pict->rowstride;
547 for (i = 0; i < width; ++i) {
548 uint32_t p = Fetch4(pict, bits, i + x);
550 a = ((p & 0x8) * 0xff) << 21;
551 r = ((p & 0x4) * 0xff) << 14;
552 g = ((p & 0x2) * 0xff) << 7;
553 b = ((p & 0x1) * 0xff);
559 fbFetch_a1b1g1r1 (bits_image_t *pict, int x, int y, int width, uint32_t *buffer)
562 const uint32_t *bits = pict->bits + y*pict->rowstride;
564 for (i = 0; i < width; ++i) {
565 uint32_t p = Fetch4(pict, bits, i + x);
567 a = ((p & 0x8) * 0xff) << 21;
568 r = ((p & 0x4) * 0xff) >> 3;
569 g = ((p & 0x2) * 0xff) << 7;
570 b = ((p & 0x1) * 0xff) << 16;
576 fbFetch_c4 (bits_image_t *pict, int x, int y, int width, uint32_t *buffer)
578 const uint32_t *bits = pict->bits + y*pict->rowstride;
579 const pixman_indexed_t * indexed = pict->indexed;
581 for (i = 0; i < width; ++i) {
582 uint32_t p = Fetch4(pict, bits, i + x);
584 *buffer++ = indexed->rgba[p];
590 fbFetch_a1 (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 = READ(pict, bits + ((i + x) >> 5));
597 #if BITMAP_BIT_ORDER == MSBFirst
598 a = p >> (0x1f - ((i+x) & 0x1f));
600 a = p >> ((i+x) & 0x1f);
611 fbFetch_g1 (bits_image_t *pict, int x, int y, int width, uint32_t *buffer)
613 const uint32_t *bits = pict->bits + y*pict->rowstride;
614 const pixman_indexed_t * indexed = pict->indexed;
616 for (i = 0; i < width; ++i) {
617 uint32_t p = READ(pict, bits + ((i+x) >> 5));
619 #if BITMAP_BIT_ORDER == MSBFirst
620 a = p >> (0x1f - ((i+x) & 0x1f));
622 a = p >> ((i+x) & 0x1f);
625 *buffer++ = indexed->rgba[a];
630 fbFetch_yuy2 (bits_image_t *pict, int x, int line, int width, uint32_t *buffer)
636 const uint32_t *bits = pict->bits + pict->rowstride * line;
638 for (i = 0; i < width; i++)
640 y = ((uint8_t *) bits)[(x + i) << 1] - 16;
641 u = ((uint8_t *) bits)[(((x + i) << 1) & -4) + 1] - 128;
642 v = ((uint8_t *) bits)[(((x + i) << 1) & -4) + 3] - 128;
644 /* R = 1.164(Y - 16) + 1.596(V - 128) */
645 r = 0x012b27 * y + 0x019a2e * v;
646 /* G = 1.164(Y - 16) - 0.813(V - 128) - 0.391(U - 128) */
647 g = 0x012b27 * y - 0x00d0f2 * v - 0x00647e * u;
648 /* B = 1.164(Y - 16) + 2.018(U - 128) */
649 b = 0x012b27 * y + 0x0206a2 * u;
651 WRITE(pict, buffer++, 0xff000000 |
652 (r >= 0 ? r < 0x1000000 ? r & 0xff0000 : 0xff0000 : 0) |
653 (g >= 0 ? g < 0x1000000 ? (g >> 8) & 0x00ff00 : 0x00ff00 : 0) |
654 (b >= 0 ? b < 0x1000000 ? (b >> 16) & 0x0000ff : 0x0000ff : 0));
659 fbFetch_yv12 (bits_image_t *pict, int x, int line, int width, uint32_t *buffer)
662 uint8_t *pY = YV12_Y (line);
663 uint8_t *pU = YV12_U (line);
664 uint8_t *pV = YV12_V (line);
669 for (i = 0; i < width; i++)
672 u = pU[(x + i) >> 1] - 128;
673 v = pV[(x + i) >> 1] - 128;
675 /* R = 1.164(Y - 16) + 1.596(V - 128) */
676 r = 0x012b27 * y + 0x019a2e * v;
677 /* G = 1.164(Y - 16) - 0.813(V - 128) - 0.391(U - 128) */
678 g = 0x012b27 * y - 0x00d0f2 * v - 0x00647e * u;
679 /* B = 1.164(Y - 16) + 2.018(U - 128) */
680 b = 0x012b27 * y + 0x0206a2 * u;
682 WRITE(pict, buffer++, 0xff000000 |
683 (r >= 0 ? r < 0x1000000 ? r & 0xff0000 : 0xff0000 : 0) |
684 (g >= 0 ? g < 0x1000000 ? (g >> 8) & 0x00ff00 : 0x00ff00 : 0) |
685 (b >= 0 ? b < 0x1000000 ? (b >> 16) & 0x0000ff : 0x0000ff : 0));
689 fetchProc32 ACCESS(pixman_fetchProcForPicture32) (bits_image_t * pict)
691 switch(pict->format) {
692 case PIXMAN_a8r8g8b8: return fbFetch_a8r8g8b8;
693 case PIXMAN_x8r8g8b8: return fbFetch_x8r8g8b8;
694 case PIXMAN_a8b8g8r8: return fbFetch_a8b8g8r8;
695 case PIXMAN_x8b8g8r8: return fbFetch_x8b8g8r8;
696 /* These two require wide compositing */
697 case PIXMAN_a2b10g10r10: return NULL;
698 case PIXMAN_x2b10g10r10: return NULL;
701 case PIXMAN_r8g8b8: return fbFetch_r8g8b8;
702 case PIXMAN_b8g8r8: return fbFetch_b8g8r8;
705 case PIXMAN_r5g6b5: return fbFetch_r5g6b5;
706 case PIXMAN_b5g6r5: return fbFetch_b5g6r5;
708 case PIXMAN_a1r5g5b5: return fbFetch_a1r5g5b5;
709 case PIXMAN_x1r5g5b5: return fbFetch_x1r5g5b5;
710 case PIXMAN_a1b5g5r5: return fbFetch_a1b5g5r5;
711 case PIXMAN_x1b5g5r5: return fbFetch_x1b5g5r5;
712 case PIXMAN_a4r4g4b4: return fbFetch_a4r4g4b4;
713 case PIXMAN_x4r4g4b4: return fbFetch_x4r4g4b4;
714 case PIXMAN_a4b4g4r4: return fbFetch_a4b4g4r4;
715 case PIXMAN_x4b4g4r4: return fbFetch_x4b4g4r4;
718 case PIXMAN_a8: return fbFetch_a8;
719 case PIXMAN_r3g3b2: return fbFetch_r3g3b2;
720 case PIXMAN_b2g3r3: return fbFetch_b2g3r3;
721 case PIXMAN_a2r2g2b2: return fbFetch_a2r2g2b2;
722 case PIXMAN_a2b2g2r2: return fbFetch_a2b2g2r2;
723 case PIXMAN_c8: return fbFetch_c8;
724 case PIXMAN_g8: return fbFetch_c8;
725 case PIXMAN_x4a4: return fbFetch_x4a4;
728 case PIXMAN_a4: return fbFetch_a4;
729 case PIXMAN_r1g2b1: return fbFetch_r1g2b1;
730 case PIXMAN_b1g2r1: return fbFetch_b1g2r1;
731 case PIXMAN_a1r1g1b1: return fbFetch_a1r1g1b1;
732 case PIXMAN_a1b1g1r1: return fbFetch_a1b1g1r1;
733 case PIXMAN_c4: return fbFetch_c4;
734 case PIXMAN_g4: return fbFetch_c4;
737 case PIXMAN_a1: return fbFetch_a1;
738 case PIXMAN_g1: return fbFetch_g1;
741 case PIXMAN_yuy2: return fbFetch_yuy2;
742 case PIXMAN_yv12: return fbFetch_yv12;
749 fbFetch64_generic (bits_image_t *pict, int x, int y, int width, uint64_t *buffer)
751 fetchProc32 fetch32 = ACCESS(pixman_fetchProcForPicture32) (pict);
753 // Fetch the pixels into the first half of buffer and then expand them in
755 fetch32(pict, x, y, width, (uint32_t*)buffer);
756 pixman_expand(buffer, (uint32_t*)buffer, pict->format, width);
759 fetchProc64 ACCESS(pixman_fetchProcForPicture64) (bits_image_t * pict)
761 switch(pict->format) {
762 case PIXMAN_a2b10g10r10: return fbFetch_a2b10g10r10;
763 case PIXMAN_x2b10g10r10: return fbFetch_x2b10g10r10;
764 default: return fbFetch64_generic;
768 /**************************** Pixel wise fetching *****************************/
770 static FASTCALL uint64_t
771 fbFetchPixel_a2b10g10r10 (bits_image_t *pict, int offset, int line)
773 uint32_t *bits = pict->bits + line*pict->rowstride;
774 uint32_t p = READ(pict, bits + offset);
775 uint64_t a = p >> 30;
776 uint64_t b = (p >> 20) & 0x3ff;
777 uint64_t g = (p >> 10) & 0x3ff;
778 uint64_t r = p & 0x3ff;
789 return a << 48 | r << 32 | g << 16 | b;
792 static FASTCALL uint64_t
793 fbFetchPixel_x2b10g10r10 (bits_image_t *pict, int offset, int line)
795 uint32_t *bits = pict->bits + line*pict->rowstride;
796 uint32_t p = READ(pict, bits + offset);
797 uint64_t b = (p >> 20) & 0x3ff;
798 uint64_t g = (p >> 10) & 0x3ff;
799 uint64_t r = p & 0x3ff;
805 return 0xffffULL << 48 | r << 32 | g << 16 | b;
808 static FASTCALL uint32_t
809 fbFetchPixel_a8r8g8b8 (bits_image_t *pict, int offset, int line)
811 uint32_t *bits = pict->bits + line*pict->rowstride;
812 return READ(pict, (uint32_t *)bits + offset);
815 static FASTCALL uint32_t
816 fbFetchPixel_x8r8g8b8 (bits_image_t *pict, int offset, int line)
818 uint32_t *bits = pict->bits + line*pict->rowstride;
819 return READ(pict, (uint32_t *)bits + offset) | 0xff000000;
822 static FASTCALL uint32_t
823 fbFetchPixel_a8b8g8r8 (bits_image_t *pict, int offset, int line)
825 uint32_t *bits = pict->bits + line*pict->rowstride;
826 uint32_t pixel = READ(pict, (uint32_t *)bits + offset);
828 return ((pixel & 0xff000000) |
829 ((pixel >> 16) & 0xff) |
830 (pixel & 0x0000ff00) |
831 ((pixel & 0xff) << 16));
834 static FASTCALL uint32_t
835 fbFetchPixel_x8b8g8r8 (bits_image_t *pict, int offset, int line)
837 uint32_t *bits = pict->bits + line*pict->rowstride;
838 uint32_t pixel = READ(pict, (uint32_t *)bits + offset);
840 return ((0xff000000) |
841 ((pixel >> 16) & 0xff) |
842 (pixel & 0x0000ff00) |
843 ((pixel & 0xff) << 16));
846 static FASTCALL uint32_t
847 fbFetchPixel_r8g8b8 (bits_image_t *pict, int offset, int line)
849 uint32_t *bits = pict->bits + line*pict->rowstride;
850 uint8_t *pixel = ((uint8_t *) bits) + (offset*3);
851 #if IMAGE_BYTE_ORDER == MSBFirst
853 (READ(pict, pixel + 0) << 16) |
854 (READ(pict, pixel + 1) << 8) |
855 (READ(pict, pixel + 2)));
858 (READ(pict, pixel + 2) << 16) |
859 (READ(pict, pixel + 1) << 8) |
860 (READ(pict, pixel + 0)));
864 static FASTCALL uint32_t
865 fbFetchPixel_b8g8r8 (bits_image_t *pict, int offset, int line)
867 uint32_t *bits = pict->bits + line*pict->rowstride;
868 uint8_t *pixel = ((uint8_t *) bits) + (offset*3);
869 #if IMAGE_BYTE_ORDER == MSBFirst
871 (READ(pict, pixel + 2) << 16) |
872 (READ(pict, pixel + 1) << 8) |
873 (READ(pict, pixel + 0)));
876 (READ(pict, pixel + 0) << 16) |
877 (READ(pict, pixel + 1) << 8) |
878 (READ(pict, pixel + 2)));
882 static FASTCALL uint32_t
883 fbFetchPixel_r5g6b5 (bits_image_t *pict, int offset, int line)
886 uint32_t *bits = pict->bits + line*pict->rowstride;
887 uint32_t pixel = READ(pict, (uint16_t *) bits + offset);
889 r = ((pixel & 0xf800) | ((pixel & 0xe000) >> 5)) << 8;
890 g = ((pixel & 0x07e0) | ((pixel & 0x0600) >> 6)) << 5;
891 b = ((pixel & 0x001c) | ((pixel & 0x001f) << 5)) >> 2;
892 return (0xff000000 | r | g | b);
895 static FASTCALL uint32_t
896 fbFetchPixel_b5g6r5 (bits_image_t *pict, int offset, int line)
899 uint32_t *bits = pict->bits + line*pict->rowstride;
900 uint32_t pixel = READ(pict, (uint16_t *) bits + offset);
902 b = ((pixel & 0xf800) | ((pixel & 0xe000) >> 5)) >> 8;
903 g = ((pixel & 0x07e0) | ((pixel & 0x0600) >> 6)) << 5;
904 r = ((pixel & 0x001c) | ((pixel & 0x001f) << 5)) << 14;
905 return (0xff000000 | r | g | b);
908 static FASTCALL uint32_t
909 fbFetchPixel_a1r5g5b5 (bits_image_t *pict, int offset, int line)
912 uint32_t *bits = pict->bits + line*pict->rowstride;
913 uint32_t pixel = READ(pict, (uint16_t *) bits + offset);
915 a = (uint32_t) ((uint8_t) (0 - ((pixel & 0x8000) >> 15))) << 24;
916 r = ((pixel & 0x7c00) | ((pixel & 0x7000) >> 5)) << 9;
917 g = ((pixel & 0x03e0) | ((pixel & 0x0380) >> 5)) << 6;
918 b = ((pixel & 0x001c) | ((pixel & 0x001f) << 5)) >> 2;
919 return (a | r | g | b);
922 static FASTCALL uint32_t
923 fbFetchPixel_x1r5g5b5 (bits_image_t *pict, int offset, int line)
926 uint32_t *bits = pict->bits + line*pict->rowstride;
927 uint32_t pixel = READ(pict, (uint16_t *) bits + offset);
929 r = ((pixel & 0x7c00) | ((pixel & 0x7000) >> 5)) << 9;
930 g = ((pixel & 0x03e0) | ((pixel & 0x0380) >> 5)) << 6;
931 b = ((pixel & 0x001c) | ((pixel & 0x001f) << 5)) >> 2;
932 return (0xff000000 | r | g | b);
935 static FASTCALL uint32_t
936 fbFetchPixel_a1b5g5r5 (bits_image_t *pict, int offset, int line)
939 uint32_t *bits = pict->bits + line*pict->rowstride;
940 uint32_t pixel = READ(pict, (uint16_t *) bits + offset);
942 a = (uint32_t) ((uint8_t) (0 - ((pixel & 0x8000) >> 15))) << 24;
943 b = ((pixel & 0x7c00) | ((pixel & 0x7000) >> 5)) >> 7;
944 g = ((pixel & 0x03e0) | ((pixel & 0x0380) >> 5)) << 6;
945 r = ((pixel & 0x001c) | ((pixel & 0x001f) << 5)) << 14;
946 return (a | r | g | b);
949 static FASTCALL uint32_t
950 fbFetchPixel_x1b5g5r5 (bits_image_t *pict, int offset, int line)
953 uint32_t *bits = pict->bits + line*pict->rowstride;
954 uint32_t pixel = READ(pict, (uint16_t *) bits + offset);
956 b = ((pixel & 0x7c00) | ((pixel & 0x7000) >> 5)) >> 7;
957 g = ((pixel & 0x03e0) | ((pixel & 0x0380) >> 5)) << 6;
958 r = ((pixel & 0x001c) | ((pixel & 0x001f) << 5)) << 14;
959 return (0xff000000 | r | g | b);
962 static FASTCALL uint32_t
963 fbFetchPixel_a4r4g4b4 (bits_image_t *pict, int offset, int line)
966 uint32_t *bits = pict->bits + line*pict->rowstride;
967 uint32_t pixel = READ(pict, (uint16_t *) bits + offset);
969 a = ((pixel & 0xf000) | ((pixel & 0xf000) >> 4)) << 16;
970 r = ((pixel & 0x0f00) | ((pixel & 0x0f00) >> 4)) << 12;
971 g = ((pixel & 0x00f0) | ((pixel & 0x00f0) >> 4)) << 8;
972 b = ((pixel & 0x000f) | ((pixel & 0x000f) << 4));
973 return (a | r | g | b);
976 static FASTCALL uint32_t
977 fbFetchPixel_x4r4g4b4 (bits_image_t *pict, int offset, int line)
980 uint32_t *bits = pict->bits + line*pict->rowstride;
981 uint32_t pixel = READ(pict, (uint16_t *) bits + offset);
983 r = ((pixel & 0x0f00) | ((pixel & 0x0f00) >> 4)) << 12;
984 g = ((pixel & 0x00f0) | ((pixel & 0x00f0) >> 4)) << 8;
985 b = ((pixel & 0x000f) | ((pixel & 0x000f) << 4));
986 return (0xff000000 | r | g | b);
989 static FASTCALL uint32_t
990 fbFetchPixel_a4b4g4r4 (bits_image_t *pict, int offset, int line)
993 uint32_t *bits = pict->bits + line*pict->rowstride;
994 uint32_t pixel = READ(pict, (uint16_t *) bits + offset);
996 a = ((pixel & 0xf000) | ((pixel & 0xf000) >> 4)) << 16;
997 b = ((pixel & 0x0f00) | ((pixel & 0x0f00) >> 4)) >> 4;
998 g = ((pixel & 0x00f0) | ((pixel & 0x00f0) >> 4)) << 8;
999 r = ((pixel & 0x000f) | ((pixel & 0x000f) << 4)) << 16;
1000 return (a | r | g | b);
1003 static FASTCALL uint32_t
1004 fbFetchPixel_x4b4g4r4 (bits_image_t *pict, int offset, int line)
1007 uint32_t *bits = pict->bits + line*pict->rowstride;
1008 uint32_t pixel = READ(pict, (uint16_t *) bits + offset);
1010 b = ((pixel & 0x0f00) | ((pixel & 0x0f00) >> 4)) >> 4;
1011 g = ((pixel & 0x00f0) | ((pixel & 0x00f0) >> 4)) << 8;
1012 r = ((pixel & 0x000f) | ((pixel & 0x000f) << 4)) << 16;
1013 return (0xff000000 | r | g | b);
1016 static FASTCALL uint32_t
1017 fbFetchPixel_a8 (bits_image_t *pict, int offset, int line)
1019 uint32_t *bits = pict->bits + line*pict->rowstride;
1020 uint32_t pixel = READ(pict, (uint8_t *) bits + offset);
1025 static FASTCALL uint32_t
1026 fbFetchPixel_r3g3b2 (bits_image_t *pict, int offset, int line)
1029 uint32_t *bits = pict->bits + line*pict->rowstride;
1030 uint32_t pixel = READ(pict, (uint8_t *) bits + offset);
1032 r = ((pixel & 0xe0) | ((pixel & 0xe0) >> 3) | ((pixel & 0xc0) >> 6)) << 16;
1033 g = ((pixel & 0x1c) | ((pixel & 0x18) >> 3) | ((pixel & 0x1c) << 3)) << 8;
1034 b = (((pixel & 0x03) ) |
1035 ((pixel & 0x03) << 2) |
1036 ((pixel & 0x03) << 4) |
1037 ((pixel & 0x03) << 6));
1038 return (0xff000000 | r | g | b);
1041 static FASTCALL uint32_t
1042 fbFetchPixel_b2g3r3 (bits_image_t *pict, int offset, int line)
1045 uint32_t *bits = pict->bits + line*pict->rowstride;
1046 uint32_t pixel = READ(pict, (uint8_t *) bits + offset);
1048 b = (((pixel & 0xc0) ) |
1049 ((pixel & 0xc0) >> 2) |
1050 ((pixel & 0xc0) >> 4) |
1051 ((pixel & 0xc0) >> 6));
1052 g = ((pixel & 0x38) | ((pixel & 0x38) >> 3) | ((pixel & 0x30) << 2)) << 8;
1053 r = (((pixel & 0x07) ) |
1054 ((pixel & 0x07) << 3) |
1055 ((pixel & 0x06) << 6)) << 16;
1056 return (0xff000000 | r | g | b);
1059 static FASTCALL uint32_t
1060 fbFetchPixel_a2r2g2b2 (bits_image_t *pict, int offset, int line)
1063 uint32_t *bits = pict->bits + line*pict->rowstride;
1064 uint32_t pixel = READ(pict, (uint8_t *) bits + offset);
1066 a = ((pixel & 0xc0) * 0x55) << 18;
1067 r = ((pixel & 0x30) * 0x55) << 12;
1068 g = ((pixel & 0x0c) * 0x55) << 6;
1069 b = ((pixel & 0x03) * 0x55);
1073 static FASTCALL uint32_t
1074 fbFetchPixel_a2b2g2r2 (bits_image_t *pict, int offset, int line)
1077 uint32_t *bits = pict->bits + line*pict->rowstride;
1078 uint32_t pixel = READ(pict, (uint8_t *) bits + offset);
1080 a = ((pixel & 0xc0) * 0x55) << 18;
1081 b = ((pixel & 0x30) * 0x55) >> 6;
1082 g = ((pixel & 0x0c) * 0x55) << 6;
1083 r = ((pixel & 0x03) * 0x55) << 16;
1087 static FASTCALL uint32_t
1088 fbFetchPixel_c8 (bits_image_t *pict, int offset, int line)
1090 uint32_t *bits = pict->bits + line*pict->rowstride;
1091 uint32_t pixel = READ(pict, (uint8_t *) bits + offset);
1092 const pixman_indexed_t * indexed = pict->indexed;
1093 return indexed->rgba[pixel];
1096 static FASTCALL uint32_t
1097 fbFetchPixel_x4a4 (bits_image_t *pict, int offset, int line)
1099 uint32_t *bits = pict->bits + line*pict->rowstride;
1100 uint32_t pixel = READ(pict, (uint8_t *) bits + offset);
1102 return ((pixel & 0xf) | ((pixel & 0xf) << 4)) << 24;
1105 static FASTCALL uint32_t
1106 fbFetchPixel_a4 (bits_image_t *pict, int offset, int line)
1108 uint32_t *bits = pict->bits + line*pict->rowstride;
1109 uint32_t pixel = Fetch4(pict, bits, offset);
1111 pixel |= pixel << 4;
1115 static FASTCALL uint32_t
1116 fbFetchPixel_r1g2b1 (bits_image_t *pict, int offset, int line)
1119 uint32_t *bits = pict->bits + line*pict->rowstride;
1120 uint32_t pixel = Fetch4(pict, bits, offset);
1122 r = ((pixel & 0x8) * 0xff) << 13;
1123 g = ((pixel & 0x6) * 0x55) << 7;
1124 b = ((pixel & 0x1) * 0xff);
1125 return 0xff000000|r|g|b;
1128 static FASTCALL uint32_t
1129 fbFetchPixel_b1g2r1 (bits_image_t *pict, int offset, int line)
1132 uint32_t *bits = pict->bits + line*pict->rowstride;
1133 uint32_t pixel = Fetch4(pict, bits, offset);
1135 b = ((pixel & 0x8) * 0xff) >> 3;
1136 g = ((pixel & 0x6) * 0x55) << 7;
1137 r = ((pixel & 0x1) * 0xff) << 16;
1138 return 0xff000000|r|g|b;
1141 static FASTCALL uint32_t
1142 fbFetchPixel_a1r1g1b1 (bits_image_t *pict, int offset, int line)
1145 uint32_t *bits = pict->bits + line*pict->rowstride;
1146 uint32_t pixel = Fetch4(pict, bits, offset);
1148 a = ((pixel & 0x8) * 0xff) << 21;
1149 r = ((pixel & 0x4) * 0xff) << 14;
1150 g = ((pixel & 0x2) * 0xff) << 7;
1151 b = ((pixel & 0x1) * 0xff);
1155 static FASTCALL uint32_t
1156 fbFetchPixel_a1b1g1r1 (bits_image_t *pict, int offset, int line)
1159 uint32_t *bits = pict->bits + line*pict->rowstride;
1160 uint32_t pixel = Fetch4(pict, bits, offset);
1162 a = ((pixel & 0x8) * 0xff) << 21;
1163 r = ((pixel & 0x4) * 0xff) >> 3;
1164 g = ((pixel & 0x2) * 0xff) << 7;
1165 b = ((pixel & 0x1) * 0xff) << 16;
1169 static FASTCALL uint32_t
1170 fbFetchPixel_c4 (bits_image_t *pict, int offset, int line)
1172 uint32_t *bits = pict->bits + line*pict->rowstride;
1173 uint32_t pixel = Fetch4(pict, bits, offset);
1174 const pixman_indexed_t * indexed = pict->indexed;
1176 return indexed->rgba[pixel];
1180 static FASTCALL uint32_t
1181 fbFetchPixel_a1 (bits_image_t *pict, int offset, int line)
1183 uint32_t *bits = pict->bits + line*pict->rowstride;
1184 uint32_t pixel = READ(pict, bits + (offset >> 5));
1186 #if BITMAP_BIT_ORDER == MSBFirst
1187 a = pixel >> (0x1f - (offset & 0x1f));
1189 a = pixel >> (offset & 0x1f);
1198 static FASTCALL uint32_t
1199 fbFetchPixel_g1 (bits_image_t *pict, int offset, int line)
1201 uint32_t *bits = pict->bits + line*pict->rowstride;
1202 uint32_t pixel = READ(pict, bits + (offset >> 5));
1203 const pixman_indexed_t * indexed = pict->indexed;
1205 #if BITMAP_BIT_ORDER == MSBFirst
1206 a = pixel >> (0x1f - (offset & 0x1f));
1208 a = pixel >> (offset & 0x1f);
1211 return indexed->rgba[a];
1214 static FASTCALL uint32_t
1215 fbFetchPixel_yuy2 (bits_image_t *pict, int offset, int line)
1220 const uint32_t *bits = pict->bits + pict->rowstride * line;
1222 y = ((uint8_t *) bits)[offset << 1] - 16;
1223 u = ((uint8_t *) bits)[((offset << 1) & -4) + 1] - 128;
1224 v = ((uint8_t *) bits)[((offset << 1) & -4) + 3] - 128;
1226 /* R = 1.164(Y - 16) + 1.596(V - 128) */
1227 r = 0x012b27 * y + 0x019a2e * v;
1228 /* G = 1.164(Y - 16) - 0.813(V - 128) - 0.391(U - 128) */
1229 g = 0x012b27 * y - 0x00d0f2 * v - 0x00647e * u;
1230 /* B = 1.164(Y - 16) + 2.018(U - 128) */
1231 b = 0x012b27 * y + 0x0206a2 * u;
1234 (r >= 0 ? r < 0x1000000 ? r & 0xff0000 : 0xff0000 : 0) |
1235 (g >= 0 ? g < 0x1000000 ? (g >> 8) & 0x00ff00 : 0x00ff00 : 0) |
1236 (b >= 0 ? b < 0x1000000 ? (b >> 16) & 0x0000ff : 0x0000ff : 0);
1239 static FASTCALL uint32_t
1240 fbFetchPixel_yv12 (bits_image_t *pict, int offset, int line)
1243 int16_t y = YV12_Y (line)[offset] - 16;
1244 int16_t u = YV12_U (line)[offset >> 1] - 128;
1245 int16_t v = YV12_V (line)[offset >> 1] - 128;
1248 /* R = 1.164(Y - 16) + 1.596(V - 128) */
1249 r = 0x012b27 * y + 0x019a2e * v;
1250 /* G = 1.164(Y - 16) - 0.813(V - 128) - 0.391(U - 128) */
1251 g = 0x012b27 * y - 0x00d0f2 * v - 0x00647e * u;
1252 /* B = 1.164(Y - 16) + 2.018(U - 128) */
1253 b = 0x012b27 * y + 0x0206a2 * u;
1256 (r >= 0 ? r < 0x1000000 ? r & 0xff0000 : 0xff0000 : 0) |
1257 (g >= 0 ? g < 0x1000000 ? (g >> 8) & 0x00ff00 : 0x00ff00 : 0) |
1258 (b >= 0 ? b < 0x1000000 ? (b >> 16) & 0x0000ff : 0x0000ff : 0);
1261 fetchPixelProc32 ACCESS(pixman_fetchPixelProcForPicture32) (bits_image_t * pict)
1263 switch(pict->format) {
1264 case PIXMAN_a8r8g8b8: return fbFetchPixel_a8r8g8b8;
1265 case PIXMAN_x8r8g8b8: return fbFetchPixel_x8r8g8b8;
1266 case PIXMAN_a8b8g8r8: return fbFetchPixel_a8b8g8r8;
1267 case PIXMAN_x8b8g8r8: return fbFetchPixel_x8b8g8r8;
1268 /* These two require wide compositing */
1269 case PIXMAN_a2b10g10r10: return NULL;
1270 case PIXMAN_x2b10g10r10: return NULL;
1273 case PIXMAN_r8g8b8: return fbFetchPixel_r8g8b8;
1274 case PIXMAN_b8g8r8: return fbFetchPixel_b8g8r8;
1277 case PIXMAN_r5g6b5: return fbFetchPixel_r5g6b5;
1278 case PIXMAN_b5g6r5: return fbFetchPixel_b5g6r5;
1280 case PIXMAN_a1r5g5b5: return fbFetchPixel_a1r5g5b5;
1281 case PIXMAN_x1r5g5b5: return fbFetchPixel_x1r5g5b5;
1282 case PIXMAN_a1b5g5r5: return fbFetchPixel_a1b5g5r5;
1283 case PIXMAN_x1b5g5r5: return fbFetchPixel_x1b5g5r5;
1284 case PIXMAN_a4r4g4b4: return fbFetchPixel_a4r4g4b4;
1285 case PIXMAN_x4r4g4b4: return fbFetchPixel_x4r4g4b4;
1286 case PIXMAN_a4b4g4r4: return fbFetchPixel_a4b4g4r4;
1287 case PIXMAN_x4b4g4r4: return fbFetchPixel_x4b4g4r4;
1290 case PIXMAN_a8: return fbFetchPixel_a8;
1291 case PIXMAN_r3g3b2: return fbFetchPixel_r3g3b2;
1292 case PIXMAN_b2g3r3: return fbFetchPixel_b2g3r3;
1293 case PIXMAN_a2r2g2b2: return fbFetchPixel_a2r2g2b2;
1294 case PIXMAN_a2b2g2r2: return fbFetchPixel_a2b2g2r2;
1295 case PIXMAN_c8: return fbFetchPixel_c8;
1296 case PIXMAN_g8: return fbFetchPixel_c8;
1297 case PIXMAN_x4a4: return fbFetchPixel_x4a4;
1300 case PIXMAN_a4: return fbFetchPixel_a4;
1301 case PIXMAN_r1g2b1: return fbFetchPixel_r1g2b1;
1302 case PIXMAN_b1g2r1: return fbFetchPixel_b1g2r1;
1303 case PIXMAN_a1r1g1b1: return fbFetchPixel_a1r1g1b1;
1304 case PIXMAN_a1b1g1r1: return fbFetchPixel_a1b1g1r1;
1305 case PIXMAN_c4: return fbFetchPixel_c4;
1306 case PIXMAN_g4: return fbFetchPixel_c4;
1309 case PIXMAN_a1: return fbFetchPixel_a1;
1310 case PIXMAN_g1: return fbFetchPixel_g1;
1313 case PIXMAN_yuy2: return fbFetchPixel_yuy2;
1314 case PIXMAN_yv12: return fbFetchPixel_yv12;
1320 static FASTCALL uint64_t
1321 fbFetchPixel64_generic (bits_image_t *pict, int offset, int line)
1323 fetchPixelProc32 fetchPixel32 = ACCESS(pixman_fetchPixelProcForPicture32) (pict);
1324 uint32_t argb8Pixel = fetchPixel32(pict, offset, line);
1325 uint64_t argb16Pixel;
1327 pixman_expand(&argb16Pixel, &argb8Pixel, pict->format, 1);
1332 fetchPixelProc64 ACCESS(pixman_fetchPixelProcForPicture64) (bits_image_t * pict)
1334 switch(pict->format) {
1335 case PIXMAN_a2b10g10r10: return fbFetchPixel_a2b10g10r10;
1336 case PIXMAN_x2b10g10r10: return fbFetchPixel_x2b10g10r10;
1337 default: return fbFetchPixel64_generic;
1341 /*********************************** Store ************************************/
1343 #define Splita(v) uint32_t a = ((v) >> 24), r = ((v) >> 16) & 0xff, g = ((v) >> 8) & 0xff, b = (v) & 0xff
1344 #define Split(v) uint32_t r = ((v) >> 16) & 0xff, g = ((v) >> 8) & 0xff, b = (v) & 0xff
1346 static FASTCALL void
1347 fbStore_a2b10g10r10 (pixman_image_t *image,
1348 uint32_t *bits, const uint64_t *values, int x, int width, const pixman_indexed_t * indexed)
1351 uint32_t *pixel = bits + x;
1352 for (i = 0; i < width; ++i) {
1353 WRITE(image, pixel++,
1354 ((values[i] >> 32) & 0xc0000000) | // A
1355 ((values[i] >> 38) & 0x3ff) | // R
1356 ((values[i] >> 12) & 0xffc00) | // G
1357 ((values[i] << 14) & 0x3ff00000)); // B
1361 static FASTCALL void
1362 fbStore_x2b10g10r10 (pixman_image_t *image,
1363 uint32_t *bits, const uint64_t *values, int x, int width, const pixman_indexed_t * indexed)
1366 uint32_t *pixel = bits + x;
1367 for (i = 0; i < width; ++i) {
1368 WRITE(image, pixel++,
1369 ((values[i] >> 38) & 0x3ff) | // R
1370 ((values[i] >> 12) & 0xffc00) | // G
1371 ((values[i] << 14) & 0x3ff00000)); // B
1375 static FASTCALL void
1376 fbStore_a8r8g8b8 (pixman_image_t *image,
1377 uint32_t *bits, const uint32_t *values, int x, int width, const pixman_indexed_t * indexed)
1379 MEMCPY_WRAPPED(image, ((uint32_t *)bits) + x, values, width*sizeof(uint32_t));
1382 static FASTCALL void
1383 fbStore_x8r8g8b8 (pixman_image_t *image,
1384 uint32_t *bits, const uint32_t *values, int x, int width, const pixman_indexed_t * indexed)
1387 uint32_t *pixel = (uint32_t *)bits + x;
1388 for (i = 0; i < width; ++i)
1389 WRITE(image, pixel++, values[i] & 0xffffff);
1392 static FASTCALL void
1393 fbStore_a8b8g8r8 (pixman_image_t *image,
1394 uint32_t *bits, const uint32_t *values, int x, int width, const pixman_indexed_t * indexed)
1397 uint32_t *pixel = (uint32_t *)bits + x;
1398 for (i = 0; i < width; ++i)
1399 WRITE(image, pixel++, (values[i] & 0xff00ff00) | ((values[i] >> 16) & 0xff) | ((values[i] & 0xff) << 16));
1402 static FASTCALL void
1403 fbStore_x8b8g8r8 (pixman_image_t *image,
1404 uint32_t *bits, const uint32_t *values, int x, int width, const pixman_indexed_t * indexed)
1407 uint32_t *pixel = (uint32_t *)bits + x;
1408 for (i = 0; i < width; ++i)
1409 WRITE(image, pixel++, (values[i] & 0x0000ff00) | ((values[i] >> 16) & 0xff) | ((values[i] & 0xff) << 16));
1412 static FASTCALL void
1413 fbStore_r8g8b8 (pixman_image_t *image,
1414 uint32_t *bits, const uint32_t *values, int x, int width,
1415 const pixman_indexed_t * indexed)
1418 uint8_t *pixel = ((uint8_t *) bits) + 3*x;
1419 for (i = 0; i < width; ++i) {
1420 Store24(image, pixel, values[i]);
1425 static FASTCALL void
1426 fbStore_b8g8r8 (pixman_image_t *image,
1427 uint32_t *bits, const uint32_t *values, int x, int width, const pixman_indexed_t * indexed)
1430 uint8_t *pixel = ((uint8_t *) bits) + 3*x;
1431 for (i = 0; i < width; ++i) {
1432 uint32_t val = values[i];
1433 #if IMAGE_BYTE_ORDER == MSBFirst
1434 WRITE(image, pixel++, Blue(val));
1435 WRITE(image, pixel++, Green(val));
1436 WRITE(image, pixel++, Red(val));
1438 WRITE(image, pixel++, Red(val));
1439 WRITE(image, pixel++, Green(val));
1440 WRITE(image, pixel++, Blue(val));
1445 static FASTCALL void
1446 fbStore_r5g6b5 (pixman_image_t *image,
1447 uint32_t *bits, const uint32_t *values, int x, int width, const pixman_indexed_t * indexed)
1450 uint16_t *pixel = ((uint16_t *) bits) + x;
1451 for (i = 0; i < width; ++i) {
1452 uint32_t s = values[i];
1453 WRITE(image, pixel++, ((s >> 3) & 0x001f) |
1454 ((s >> 5) & 0x07e0) |
1455 ((s >> 8) & 0xf800));
1459 static FASTCALL void
1460 fbStore_b5g6r5 (pixman_image_t *image,
1461 uint32_t *bits, const uint32_t *values, int x, int width, const pixman_indexed_t * indexed)
1464 uint16_t *pixel = ((uint16_t *) bits) + x;
1465 for (i = 0; i < width; ++i) {
1467 WRITE(image, pixel++, ((b << 8) & 0xf800) |
1468 ((g << 3) & 0x07e0) |
1473 static FASTCALL void
1474 fbStore_a1r5g5b5 (pixman_image_t *image,
1475 uint32_t *bits, const uint32_t *values, int x, int width, const pixman_indexed_t * indexed)
1478 uint16_t *pixel = ((uint16_t *) bits) + x;
1479 for (i = 0; i < width; ++i) {
1481 WRITE(image, pixel++, ((a << 8) & 0x8000) |
1482 ((r << 7) & 0x7c00) |
1483 ((g << 2) & 0x03e0) |
1488 static FASTCALL void
1489 fbStore_x1r5g5b5 (pixman_image_t *image,
1490 uint32_t *bits, const uint32_t *values, int x, int width, const pixman_indexed_t * indexed)
1493 uint16_t *pixel = ((uint16_t *) bits) + x;
1494 for (i = 0; i < width; ++i) {
1496 WRITE(image, pixel++, ((r << 7) & 0x7c00) |
1497 ((g << 2) & 0x03e0) |
1502 static FASTCALL void
1503 fbStore_a1b5g5r5 (pixman_image_t *image,
1504 uint32_t *bits, const uint32_t *values, int x, int width, const pixman_indexed_t * indexed)
1507 uint16_t *pixel = ((uint16_t *) bits) + x;
1508 for (i = 0; i < width; ++i) {
1510 WRITE(image, pixel++, ((a << 8) & 0x8000) |
1511 ((b << 7) & 0x7c00) |
1512 ((g << 2) & 0x03e0) |
1517 static FASTCALL void
1518 fbStore_x1b5g5r5 (pixman_image_t *image,
1519 uint32_t *bits, const uint32_t *values, int x, int width, const pixman_indexed_t * indexed)
1522 uint16_t *pixel = ((uint16_t *) bits) + x;
1523 for (i = 0; i < width; ++i) {
1525 WRITE(image, pixel++, ((b << 7) & 0x7c00) |
1526 ((g << 2) & 0x03e0) |
1531 static FASTCALL void
1532 fbStore_a4r4g4b4 (pixman_image_t *image,
1533 uint32_t *bits, const uint32_t *values, int x, int width, const pixman_indexed_t * indexed)
1536 uint16_t *pixel = ((uint16_t *) bits) + x;
1537 for (i = 0; i < width; ++i) {
1539 WRITE(image, pixel++, ((a << 8) & 0xf000) |
1540 ((r << 4) & 0x0f00) |
1546 static FASTCALL void
1547 fbStore_x4r4g4b4 (pixman_image_t *image,
1548 uint32_t *bits, const uint32_t *values, int x, int width, const pixman_indexed_t * indexed)
1551 uint16_t *pixel = ((uint16_t *) bits) + x;
1552 for (i = 0; i < width; ++i) {
1554 WRITE(image, pixel++, ((r << 4) & 0x0f00) |
1560 static FASTCALL void
1561 fbStore_a4b4g4r4 (pixman_image_t *image,
1562 uint32_t *bits, const uint32_t *values, int x, int width, const pixman_indexed_t * indexed)
1565 uint16_t *pixel = ((uint16_t *) bits) + x;
1566 for (i = 0; i < width; ++i) {
1568 WRITE(image, pixel++, ((a << 8) & 0xf000) |
1569 ((b << 4) & 0x0f00) |
1575 static FASTCALL void
1576 fbStore_x4b4g4r4 (pixman_image_t *image,
1577 uint32_t *bits, const uint32_t *values, int x, int width, const pixman_indexed_t * indexed)
1580 uint16_t *pixel = ((uint16_t *) bits) + x;
1581 for (i = 0; i < width; ++i) {
1583 WRITE(image, pixel++, ((b << 4) & 0x0f00) |
1589 static FASTCALL void
1590 fbStore_a8 (pixman_image_t *image,
1591 uint32_t *bits, const uint32_t *values, int x, int width, const pixman_indexed_t * indexed)
1594 uint8_t *pixel = ((uint8_t *) bits) + x;
1595 for (i = 0; i < width; ++i) {
1596 WRITE(image, pixel++, values[i] >> 24);
1600 static FASTCALL void
1601 fbStore_r3g3b2 (pixman_image_t *image,
1602 uint32_t *bits, const uint32_t *values, int x, int width, const pixman_indexed_t * indexed)
1605 uint8_t *pixel = ((uint8_t *) bits) + x;
1606 for (i = 0; i < width; ++i) {
1608 WRITE(image, pixel++,
1615 static FASTCALL void
1616 fbStore_b2g3r3 (pixman_image_t *image,
1617 uint32_t *bits, const uint32_t *values, int x, int width, const pixman_indexed_t * indexed)
1620 uint8_t *pixel = ((uint8_t *) bits) + x;
1621 for (i = 0; i < width; ++i) {
1623 WRITE(image, pixel++,
1630 static FASTCALL void
1631 fbStore_a2r2g2b2 (pixman_image_t *image,
1632 uint32_t *bits, const uint32_t *values, int x, int width, const pixman_indexed_t * indexed)
1635 uint8_t *pixel = ((uint8_t *) bits) + x;
1636 for (i = 0; i < width; ++i) {
1638 WRITE(image, pixel++, ((a ) & 0xc0) |
1645 static FASTCALL void
1646 fbStore_c8 (pixman_image_t *image,
1647 uint32_t *bits, const uint32_t *values, int x, int width, const pixman_indexed_t * indexed)
1650 uint8_t *pixel = ((uint8_t *) bits) + x;
1651 for (i = 0; i < width; ++i) {
1652 WRITE(image, pixel++, miIndexToEnt24(indexed,values[i]));
1656 static FASTCALL void
1657 fbStore_x4a4 (pixman_image_t *image,
1658 uint32_t *bits, const uint32_t *values, int x, int width, const pixman_indexed_t * indexed)
1661 uint8_t *pixel = ((uint8_t *) bits) + x;
1662 for (i = 0; i < width; ++i) {
1663 WRITE(image, pixel++, values[i] >> 28);
1667 #define Store8(img,l,o,v) (WRITE(img, (uint8_t *)(l) + ((o) >> 3), (v)))
1668 #if IMAGE_BYTE_ORDER == MSBFirst
1669 #define Store4(img,l,o,v) Store8(img,l,o,((o) & 4 ? \
1670 (Fetch8(img,l,o) & 0xf0) | (v) : \
1671 (Fetch8(img,l,o) & 0x0f) | ((v) << 4)))
1673 #define Store4(img,l,o,v) Store8(img,l,o,((o) & 4 ? \
1674 (Fetch8(img,l,o) & 0x0f) | ((v) << 4) : \
1675 (Fetch8(img,l,o) & 0xf0) | (v)))
1678 static FASTCALL void
1679 fbStore_a4 (pixman_image_t *image,
1680 uint32_t *bits, const uint32_t *values, int x, int width, const pixman_indexed_t * indexed)
1683 for (i = 0; i < width; ++i) {
1684 Store4(image, bits, i + x, values[i]>>28);
1688 static FASTCALL void
1689 fbStore_r1g2b1 (pixman_image_t *image,
1690 uint32_t *bits, const uint32_t *values, int x, int width, const pixman_indexed_t * indexed)
1693 for (i = 0; i < width; ++i) {
1697 pixel = (((r >> 4) & 0x8) |
1700 Store4(image, bits, i + x, pixel);
1704 static FASTCALL void
1705 fbStore_b1g2r1 (pixman_image_t *image,
1706 uint32_t *bits, const uint32_t *values, int x, int width, const pixman_indexed_t * indexed)
1709 for (i = 0; i < width; ++i) {
1713 pixel = (((b >> 4) & 0x8) |
1716 Store4(image, bits, i + x, pixel);
1720 static FASTCALL void
1721 fbStore_a1r1g1b1 (pixman_image_t *image,
1722 uint32_t *bits, const uint32_t *values, int x, int width, const pixman_indexed_t * indexed)
1725 for (i = 0; i < width; ++i) {
1728 pixel = (((a >> 4) & 0x8) |
1732 Store4(image, bits, i + x, pixel);
1736 static FASTCALL void
1737 fbStore_a1b1g1r1 (pixman_image_t *image,
1738 uint32_t *bits, const uint32_t *values, int x, int width, const pixman_indexed_t * indexed)
1741 for (i = 0; i < width; ++i) {
1744 pixel = (((a >> 4) & 0x8) |
1748 Store4(image, bits, i + x, pixel);
1752 static FASTCALL void
1753 fbStore_c4 (pixman_image_t *image,
1754 uint32_t *bits, const uint32_t *values, int x, int width, const pixman_indexed_t * indexed)
1757 for (i = 0; i < width; ++i) {
1760 pixel = miIndexToEnt24(indexed, values[i]);
1761 Store4(image, bits, i + x, pixel);
1765 static FASTCALL void
1766 fbStore_a1 (pixman_image_t *image,
1767 uint32_t *bits, const uint32_t *values, int x, int width, const pixman_indexed_t * indexed)
1770 for (i = 0; i < width; ++i) {
1771 uint32_t *pixel = ((uint32_t *) bits) + ((i+x) >> 5);
1772 uint32_t mask = FbStipMask((i+x) & 0x1f, 1);
1774 uint32_t v = values[i] & 0x80000000 ? mask : 0;
1775 WRITE(image, pixel, (READ(image, pixel) & ~mask) | v);
1779 static FASTCALL void
1780 fbStore_g1 (pixman_image_t *image,
1781 uint32_t *bits, const uint32_t *values, int x, int width, const pixman_indexed_t * indexed)
1784 for (i = 0; i < width; ++i) {
1785 uint32_t *pixel = ((uint32_t *) bits) + ((i+x) >> 5);
1786 uint32_t mask = FbStipMask((i+x) & 0x1f, 1);
1788 uint32_t v = miIndexToEntY24(indexed,values[i]) ? mask : 0;
1789 WRITE(image, pixel, (READ(image, pixel) & ~mask) | v);
1794 storeProc32 ACCESS(pixman_storeProcForPicture32) (bits_image_t * pict)
1796 switch(pict->format) {
1797 case PIXMAN_a8r8g8b8: return fbStore_a8r8g8b8;
1798 case PIXMAN_x8r8g8b8: return fbStore_x8r8g8b8;
1799 case PIXMAN_a8b8g8r8: return fbStore_a8b8g8r8;
1800 case PIXMAN_x8b8g8r8: return fbStore_x8b8g8r8;
1803 case PIXMAN_r8g8b8: return fbStore_r8g8b8;
1804 case PIXMAN_b8g8r8: return fbStore_b8g8r8;
1807 case PIXMAN_r5g6b5: return fbStore_r5g6b5;
1808 case PIXMAN_b5g6r5: return fbStore_b5g6r5;
1810 case PIXMAN_a1r5g5b5: return fbStore_a1r5g5b5;
1811 case PIXMAN_x1r5g5b5: return fbStore_x1r5g5b5;
1812 case PIXMAN_a1b5g5r5: return fbStore_a1b5g5r5;
1813 case PIXMAN_x1b5g5r5: return fbStore_x1b5g5r5;
1814 case PIXMAN_a4r4g4b4: return fbStore_a4r4g4b4;
1815 case PIXMAN_x4r4g4b4: return fbStore_x4r4g4b4;
1816 case PIXMAN_a4b4g4r4: return fbStore_a4b4g4r4;
1817 case PIXMAN_x4b4g4r4: return fbStore_x4b4g4r4;
1820 case PIXMAN_a8: return fbStore_a8;
1821 case PIXMAN_r3g3b2: return fbStore_r3g3b2;
1822 case PIXMAN_b2g3r3: return fbStore_b2g3r3;
1823 case PIXMAN_a2r2g2b2: return fbStore_a2r2g2b2;
1824 case PIXMAN_c8: return fbStore_c8;
1825 case PIXMAN_g8: return fbStore_c8;
1826 case PIXMAN_x4a4: return fbStore_x4a4;
1829 case PIXMAN_a4: return fbStore_a4;
1830 case PIXMAN_r1g2b1: return fbStore_r1g2b1;
1831 case PIXMAN_b1g2r1: return fbStore_b1g2r1;
1832 case PIXMAN_a1r1g1b1: return fbStore_a1r1g1b1;
1833 case PIXMAN_a1b1g1r1: return fbStore_a1b1g1r1;
1834 case PIXMAN_c4: return fbStore_c4;
1835 case PIXMAN_g4: return fbStore_c4;
1838 case PIXMAN_a1: return fbStore_a1;
1839 case PIXMAN_g1: return fbStore_g1;
1846 * Contracts a 64bpp image to 32bpp and then stores it using a regular 32-bit
1849 static FASTCALL void
1850 fbStore64_generic (pixman_image_t *image,
1851 uint32_t *bits, const uint64_t *values, int x, int width, const pixman_indexed_t * indexed)
1853 bits_image_t *pict = (bits_image_t*)image;
1854 storeProc32 store32 = ACCESS(pixman_storeProcForPicture32) (pict);
1855 uint32_t *argb8Pixels;
1857 assert(image->common.type == BITS);
1860 argb8Pixels = malloc(sizeof(uint32_t) * width);
1861 if (!argb8Pixels) return;
1863 // Contract the scanline. We could do this in place if values weren't
1865 pixman_contract(argb8Pixels, values, width);
1866 store32(image, bits, argb8Pixels, x, width, indexed);
1871 storeProc64 ACCESS(pixman_storeProcForPicture64) (bits_image_t * pict)
1873 switch(pict->format) {
1874 case PIXMAN_a2b10g10r10: return fbStore_a2b10g10r10;
1875 case PIXMAN_x2b10g10r10: return fbStore_x2b10g10r10;
1876 default: return fbStore64_generic;
1880 #ifndef PIXMAN_FB_ACCESSORS
1882 * This function expands images from ARGB8 format to ARGB16. To preserve
1883 * precision, it needs to know the original source format. For example, if the
1884 * source was PIXMAN_x1r5g5b5 and the red component contained bits 12345, then
1885 * the expanded value is 12345123. To correctly expand this to 16 bits, it
1886 * should be 1234512345123451 and not 1234512312345123.
1888 * XXX[AGP]: For now, this just does naïve byte replication.
1890 void pixman_expand(uint64_t *dst, const uint32_t *src,
1891 pixman_format_code_t format, int width)
1895 /* Start at the end so that we can do the expansion in place when src == dst */
1896 for (i = width - 1; i >= 0; i--)
1898 const uint8_t a = src[i] >> 24,
1902 dst[i] = (uint64_t)a << 56 | (uint64_t) a << 48 |
1903 (uint64_t)r << 40 | (uint64_t) r << 32 |
1904 (uint64_t)g << 24 | (uint64_t) g << 16 |
1905 (uint64_t)b << 8 | (uint64_t)b;
1910 * Contracting is easier than expanding. We just need to truncate the
1913 void pixman_contract(uint32_t *dst, const uint64_t *src, int width)
1917 /* Start at the beginning so that we can do the contraction in place when
1919 for (i = 0; i < width; i++)
1921 const uint8_t a = src[i] >> 56,
1925 dst[i] = a << 24 | r << 16 | g << 8 | b;
1928 #endif // PIXMAN_FB_ACCESSORS