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"
36 #include "pixman-accessor.h"
38 #define CONVERT_RGB24_TO_Y15(s) \
39 (((((s) >> 16) & 0xff) * 153 + \
40 (((s) >> 8) & 0xff) * 301 + \
41 (((s) ) & 0xff) * 58) >> 2)
43 #define CONVERT_RGB24_TO_RGB15(s) \
44 ((((s) >> 3) & 0x001f) | \
45 (((s) >> 6) & 0x03e0) | \
46 (((s) >> 9) & 0x7c00))
48 #define RGB15_TO_ENTRY(mif,rgb15) \
51 #define RGB24_TO_ENTRY(mif,rgb24) \
52 RGB15_TO_ENTRY (mif,CONVERT_RGB24_TO_RGB15 (rgb24))
54 #define RGB24_TO_ENTRY_Y(mif,rgb24) \
55 ((mif)->ent[CONVERT_RGB24_TO_Y15 (rgb24)])
59 #ifdef WORDS_BIGENDIAN
60 #define FETCH_1(img,l,o) \
61 (((READ ((img), ((uint32_t *)(l)) + ((o) >> 5))) >> (0x1f - ((o) & 0x1f))) & 0x1)
63 #define FETCH_1(img,l,o) \
64 ((((READ ((img), ((uint32_t *)(l)) + ((o) >> 5))) >> ((o) & 0x1f))) & 0x1)
67 #define FETCH_8(img,l,o) (READ (img, (((uint8_t *)(l)) + ((o) >> 3))))
69 #ifdef WORDS_BIGENDIAN
70 #define FETCH_4(img,l,o) \
71 (((4 * (o)) & 4) ? (FETCH_8 (img,l, 4 * (o)) & 0xf) : (FETCH_8 (img,l,(4 * (o))) >> 4))
73 #define FETCH_4(img,l,o) \
74 (((4 * (o)) & 4) ? (FETCH_8 (img, l, 4 * (o)) >> 4) : (FETCH_8 (img, l, (4 * (o))) & 0xf))
77 #ifdef WORDS_BIGENDIAN
78 #define FETCH_24(img,l,o) \
79 ((READ (img, (((uint8_t *)(l)) + ((o) * 3) + 0)) << 16) | \
80 (READ (img, (((uint8_t *)(l)) + ((o) * 3) + 1)) << 8) | \
81 (READ (img, (((uint8_t *)(l)) + ((o) * 3) + 2)) << 0))
83 #define FETCH_24(img,l,o) \
84 ((READ (img, (((uint8_t *)(l)) + ((o) * 3) + 0)) << 0) | \
85 (READ (img, (((uint8_t *)(l)) + ((o) * 3) + 1)) << 8) | \
86 (READ (img, (((uint8_t *)(l)) + ((o) * 3) + 2)) << 16))
91 #ifdef WORDS_BIGENDIAN
92 #define STORE_1(img,l,o,v) \
95 uint32_t *__d = ((uint32_t *)(l)) + ((o) >> 5); \
98 __m = 1 << (0x1f - ((o) & 0x1f)); \
101 WRITE((img), __d, (READ((img), __d) & ~__m) | __v); \
105 #define STORE_1(img,l,o,v) \
108 uint32_t *__d = ((uint32_t *)(l)) + ((o) >> 5); \
111 __m = 1 << ((o) & 0x1f); \
112 __v = (v)? __m : 0; \
114 WRITE((img), __d, (READ((img), __d) & ~__m) | __v); \
119 #define STORE_8(img,l,o,v) (WRITE (img, (uint8_t *)(l) + ((o) >> 3), (v)))
121 #ifdef WORDS_BIGENDIAN
122 #define STORE_4(img,l,o,v) \
126 int v4 = (v) & 0x0f; \
128 STORE_8 (img, l, bo, ( \
130 (FETCH_8 (img, l, bo) & 0xf0) | (v4) : \
131 (FETCH_8 (img, l, bo) & 0x0f) | (v4 << 4))); \
134 #define STORE_4(img,l,o,v) \
138 int v4 = (v) & 0x0f; \
140 STORE_8 (img, l, bo, ( \
142 (FETCH_8 (img, l, bo) & 0x0f) | (v4 << 4) : \
143 (FETCH_8 (img, l, bo) & 0xf0) | (v4))); \
147 #ifdef WORDS_BIGENDIAN
148 #define STORE_24(img,l,o,v) \
151 uint8_t *__tmp = (l) + 3 * (o); \
153 WRITE ((img), __tmp++, ((v) & 0x00ff0000) >> 16); \
154 WRITE ((img), __tmp++, ((v) & 0x0000ff00) >> 8); \
155 WRITE ((img), __tmp++, ((v) & 0x000000ff) >> 0); \
159 #define STORE_24(img,l,o,v) \
162 uint8_t *__tmp = (l) + 3 * (o); \
164 WRITE ((img), __tmp++, ((v) & 0x000000ff) >> 0); \
165 WRITE ((img), __tmp++, ((v) & 0x0000ff00) >> 8); \
166 WRITE ((img), __tmp++, ((v) & 0x00ff0000) >> 16); \
172 * YV12 setup and access macros
175 #define YV12_SETUP(image) \
176 bits_image_t *__bits_image = (bits_image_t *)image; \
177 uint32_t *bits = __bits_image->bits; \
178 int stride = __bits_image->rowstride; \
179 int offset0 = stride < 0 ? \
180 ((-stride) >> 1) * ((__bits_image->height - 1) >> 1) - stride : \
181 stride * __bits_image->height; \
182 int offset1 = stride < 0 ? \
183 offset0 + ((-stride) >> 1) * ((__bits_image->height) >> 1) : \
184 offset0 + (offset0 >> 2)
186 /* Note no trailing semicolon on the above macro; if it's there, then
187 * the typical usage of YV12_SETUP(image); will have an extra trailing ;
188 * that some compilers will interpret as a statement -- and then any further
189 * variable declarations will cause an error.
192 #define YV12_Y(line) \
193 ((uint8_t *) ((bits) + (stride) * (line)))
195 #define YV12_U(line) \
196 ((uint8_t *) ((bits) + offset1 + \
197 ((stride) >> 1) * ((line) >> 1)))
199 #define YV12_V(line) \
200 ((uint8_t *) ((bits) + offset0 + \
201 ((stride) >> 1) * ((line) >> 1)))
205 static force_inline void
206 get_shifts (pixman_format_code_t format,
212 switch (PIXMAN_FORMAT_TYPE (format))
221 case PIXMAN_TYPE_ARGB:
223 *g = *b + PIXMAN_FORMAT_B (format);
224 *r = *g + PIXMAN_FORMAT_G (format);
225 *a = *r + PIXMAN_FORMAT_R (format);
228 case PIXMAN_TYPE_ABGR:
230 *g = *r + PIXMAN_FORMAT_R (format);
231 *b = *g + PIXMAN_FORMAT_G (format);
232 *a = *b + PIXMAN_FORMAT_B (format);
235 case PIXMAN_TYPE_BGRA:
236 /* With BGRA formats we start counting at the high end of the pixel */
237 *b = PIXMAN_FORMAT_BPP (format) - PIXMAN_FORMAT_B (format);
238 *g = *b - PIXMAN_FORMAT_B (format);
239 *r = *g - PIXMAN_FORMAT_G (format);
240 *a = *r - PIXMAN_FORMAT_R (format);
243 case PIXMAN_TYPE_RGBA:
244 /* With BGRA formats we start counting at the high end of the pixel */
245 *r = PIXMAN_FORMAT_BPP (format) - PIXMAN_FORMAT_R (format);
246 *g = *r - PIXMAN_FORMAT_R (format);
247 *b = *g - PIXMAN_FORMAT_G (format);
248 *a = *b - PIXMAN_FORMAT_B (format);
257 static force_inline uint32_t
258 convert_channel (uint32_t pixel, uint32_t def_value,
259 int n_from_bits, int from_shift,
260 int n_to_bits, int to_shift)
264 if (n_from_bits && n_to_bits)
265 v = unorm_to_unorm (pixel >> from_shift, n_from_bits, n_to_bits);
271 return (v & ((1 << n_to_bits) - 1)) << to_shift;
274 static force_inline uint32_t
275 convert_pixel (pixman_format_code_t from, pixman_format_code_t to, uint32_t pixel)
277 int a_from_shift, r_from_shift, g_from_shift, b_from_shift;
278 int a_to_shift, r_to_shift, g_to_shift, b_to_shift;
281 get_shifts (from, &a_from_shift, &r_from_shift, &g_from_shift, &b_from_shift);
282 get_shifts (to, &a_to_shift, &r_to_shift, &g_to_shift, &b_to_shift);
284 a = convert_channel (pixel, ~0,
285 PIXMAN_FORMAT_A (from), a_from_shift,
286 PIXMAN_FORMAT_A (to), a_to_shift);
288 r = convert_channel (pixel, 0,
289 PIXMAN_FORMAT_R (from), r_from_shift,
290 PIXMAN_FORMAT_R (to), r_to_shift);
292 g = convert_channel (pixel, 0,
293 PIXMAN_FORMAT_G (from), g_from_shift,
294 PIXMAN_FORMAT_G (to), g_to_shift);
296 b = convert_channel (pixel, 0,
297 PIXMAN_FORMAT_B (from), b_from_shift,
298 PIXMAN_FORMAT_B (to), b_to_shift);
300 return a | r | g | b;
303 static force_inline uint32_t
304 convert_pixel_from_a8r8g8b8 (pixman_format_code_t format, uint32_t pixel)
306 return convert_pixel (PIXMAN_a8r8g8b8, format, pixel);
309 static force_inline uint32_t
310 convert_pixel_to_a8r8g8b8 (pixman_format_code_t format, uint32_t pixel)
312 return convert_pixel (format, PIXMAN_a8r8g8b8, pixel);
315 static force_inline uint32_t
316 fetch_and_convert_pixel (pixman_image_t * image,
317 const uint8_t * bits,
319 pixman_format_code_t format)
323 switch (PIXMAN_FORMAT_BPP (format))
326 pixel = FETCH_1 (image, bits, offset);
330 pixel = FETCH_4 (image, bits, offset);
334 pixel = READ (image, bits + offset);
338 pixel = READ (image, ((uint16_t *)bits + offset));
342 pixel = FETCH_24 (image, bits, offset);
346 pixel = READ (image, ((uint32_t *)bits + offset));
350 pixel = 0xffff00ff; /* As ugly as possible to detect the bug */
354 return convert_pixel_to_a8r8g8b8 (format, pixel);
357 static force_inline void
358 convert_and_store_pixel (bits_image_t * image,
361 pixman_format_code_t format,
364 uint32_t converted = convert_pixel_from_a8r8g8b8 (format, pixel);
366 switch (PIXMAN_FORMAT_BPP (format))
369 STORE_1 (image, dest, offset, converted & 0x01);
373 STORE_4 (image, dest, offset, converted & 0xf);
377 WRITE (image, (dest + offset), converted & 0xff);
381 WRITE (image, ((uint16_t *)dest + offset), converted & 0xffff);
385 STORE_24 (image, dest, offset, converted);
389 WRITE (image, ((uint32_t *)dest + offset), converted);
398 #define MAKE_ACCESSORS(format) \
400 fetch_scanline_ ## format (pixman_image_t *image, \
405 const uint32_t *mask) \
408 (uint8_t *)(image->bits.bits + y * image->bits.rowstride); \
411 for (i = 0; i < width; ++i) \
414 fetch_and_convert_pixel (image, bits, x + i, PIXMAN_ ## format); \
419 store_scanline_ ## format (bits_image_t * image, \
423 const uint32_t *values) \
426 (uint8_t *)(image->bits + y * image->rowstride); \
429 for (i = 0; i < width; ++i) \
431 convert_and_store_pixel ( \
432 image, dest, i + x, PIXMAN_ ## format, values[i]); \
437 fetch_pixel_ ## format (bits_image_t *image, \
442 (uint8_t *)(image->bits + line * image->rowstride); \
444 return fetch_and_convert_pixel ((pixman_image_t *)image, \
445 bits, offset, PIXMAN_ ## format); \
448 static const void *const __dummy__ ## format
450 MAKE_ACCESSORS(a8r8g8b8);
451 MAKE_ACCESSORS(x8r8g8b8);
452 MAKE_ACCESSORS(a8b8g8r8);
453 MAKE_ACCESSORS(x8b8g8r8);
454 MAKE_ACCESSORS(x14r6g6b6);
455 MAKE_ACCESSORS(b8g8r8a8);
456 MAKE_ACCESSORS(b8g8r8x8);
457 MAKE_ACCESSORS(r8g8b8x8);
458 MAKE_ACCESSORS(r8g8b8a8);
459 MAKE_ACCESSORS(r8g8b8);
460 MAKE_ACCESSORS(b8g8r8);
461 MAKE_ACCESSORS(r5g6b5);
462 MAKE_ACCESSORS(b5g6r5);
463 MAKE_ACCESSORS(a1r5g5b5);
464 MAKE_ACCESSORS(x1r5g5b5);
465 MAKE_ACCESSORS(a1b5g5r5);
466 MAKE_ACCESSORS(x1b5g5r5);
467 MAKE_ACCESSORS(a4r4g4b4);
468 MAKE_ACCESSORS(x4r4g4b4);
469 MAKE_ACCESSORS(a4b4g4r4);
470 MAKE_ACCESSORS(x4b4g4r4);
472 MAKE_ACCESSORS(r3g3b2);
473 MAKE_ACCESSORS(b2g3r3);
474 MAKE_ACCESSORS(a2r2g2b2);
475 MAKE_ACCESSORS(a2b2g2r2);
476 MAKE_ACCESSORS(x4a4);
478 MAKE_ACCESSORS(r1g2b1);
479 MAKE_ACCESSORS(b1g2r1);
480 MAKE_ACCESSORS(a1r1g1b1);
481 MAKE_ACCESSORS(a1b1g1r1);
484 /********************************** Fetch ************************************/
486 /* Expects a uint64_t buffer */
488 fetch_scanline_a2r10g10b10 (pixman_image_t *image,
493 const uint32_t *mask)
495 const uint32_t *bits = image->bits.bits + y * image->bits.rowstride;
496 const uint32_t *pixel = bits + x;
497 const uint32_t *end = pixel + width;
498 uint64_t *buffer = (uint64_t *)b;
502 uint32_t p = READ (image, pixel++);
503 uint64_t a = p >> 30;
504 uint64_t r = (p >> 20) & 0x3ff;
505 uint64_t g = (p >> 10) & 0x3ff;
506 uint64_t b = p & 0x3ff;
517 *buffer++ = a << 48 | r << 32 | g << 16 | b;
521 /* Expects a uint64_t buffer */
523 fetch_scanline_x2r10g10b10 (pixman_image_t *image,
528 const uint32_t *mask)
530 const uint32_t *bits = image->bits.bits + y * image->bits.rowstride;
531 const uint32_t *pixel = (uint32_t *)bits + x;
532 const uint32_t *end = pixel + width;
533 uint64_t *buffer = (uint64_t *)b;
537 uint32_t p = READ (image, pixel++);
538 uint64_t r = (p >> 20) & 0x3ff;
539 uint64_t g = (p >> 10) & 0x3ff;
540 uint64_t b = p & 0x3ff;
546 *buffer++ = 0xffffULL << 48 | r << 32 | g << 16 | b;
550 /* Expects a uint64_t buffer */
552 fetch_scanline_a2b10g10r10 (pixman_image_t *image,
557 const uint32_t *mask)
559 const uint32_t *bits = image->bits.bits + y * image->bits.rowstride;
560 const uint32_t *pixel = bits + x;
561 const uint32_t *end = pixel + width;
562 uint64_t *buffer = (uint64_t *)b;
566 uint32_t p = READ (image, pixel++);
567 uint64_t a = p >> 30;
568 uint64_t b = (p >> 20) & 0x3ff;
569 uint64_t g = (p >> 10) & 0x3ff;
570 uint64_t r = p & 0x3ff;
581 *buffer++ = a << 48 | r << 32 | g << 16 | b;
585 /* Expects a uint64_t buffer */
587 fetch_scanline_x2b10g10r10 (pixman_image_t *image,
592 const uint32_t *mask)
594 const uint32_t *bits = image->bits.bits + y * image->bits.rowstride;
595 const uint32_t *pixel = (uint32_t *)bits + x;
596 const uint32_t *end = pixel + width;
597 uint64_t *buffer = (uint64_t *)b;
601 uint32_t p = READ (image, pixel++);
602 uint64_t b = (p >> 20) & 0x3ff;
603 uint64_t g = (p >> 10) & 0x3ff;
604 uint64_t r = p & 0x3ff;
610 *buffer++ = 0xffffULL << 48 | r << 32 | g << 16 | b;
615 fetch_scanline_c8 (pixman_image_t *image,
620 const uint32_t *mask)
622 const uint32_t *bits = image->bits.bits + y * image->bits.rowstride;
623 const pixman_indexed_t * indexed = image->bits.indexed;
624 const uint8_t *pixel = (const uint8_t *)bits + x;
625 const uint8_t *end = pixel + width;
629 uint32_t p = READ (image, pixel++);
631 *buffer++ = indexed->rgba[p];
636 fetch_scanline_c4 (pixman_image_t *image,
641 const uint32_t *mask)
643 const uint32_t *bits = image->bits.bits + y * image->bits.rowstride;
644 const pixman_indexed_t * indexed = image->bits.indexed;
647 for (i = 0; i < width; ++i)
649 uint32_t p = FETCH_4 (image, bits, i + x);
651 *buffer++ = indexed->rgba[p];
656 fetch_scanline_g1 (pixman_image_t *image,
661 const uint32_t *mask)
663 const uint32_t *bits = image->bits.bits + y * image->bits.rowstride;
664 const pixman_indexed_t * indexed = image->bits.indexed;
667 for (i = 0; i < width; ++i)
669 uint32_t p = READ (image, bits + ((i + x) >> 5));
672 #ifdef WORDS_BIGENDIAN
673 a = p >> (0x1f - ((i + x) & 0x1f));
675 a = p >> ((i + x) & 0x1f);
679 *buffer++ = indexed->rgba[a];
684 fetch_scanline_yuy2 (pixman_image_t *image,
689 const uint32_t *mask)
691 const uint32_t *bits = image->bits.bits + image->bits.rowstride * line;
694 for (i = 0; i < width; i++)
699 y = ((uint8_t *) bits)[(x + i) << 1] - 16;
700 u = ((uint8_t *) bits)[(((x + i) << 1) & - 4) + 1] - 128;
701 v = ((uint8_t *) bits)[(((x + i) << 1) & - 4) + 3] - 128;
703 /* R = 1.164(Y - 16) + 1.596(V - 128) */
704 r = 0x012b27 * y + 0x019a2e * v;
705 /* G = 1.164(Y - 16) - 0.813(V - 128) - 0.391(U - 128) */
706 g = 0x012b27 * y - 0x00d0f2 * v - 0x00647e * u;
707 /* B = 1.164(Y - 16) + 2.018(U - 128) */
708 b = 0x012b27 * y + 0x0206a2 * u;
710 *buffer++ = 0xff000000 |
711 (r >= 0 ? r < 0x1000000 ? r & 0xff0000 : 0xff0000 : 0) |
712 (g >= 0 ? g < 0x1000000 ? (g >> 8) & 0x00ff00 : 0x00ff00 : 0) |
713 (b >= 0 ? b < 0x1000000 ? (b >> 16) & 0x0000ff : 0x0000ff : 0);
718 fetch_scanline_yv12 (pixman_image_t *image,
723 const uint32_t *mask)
726 uint8_t *y_line = YV12_Y (line);
727 uint8_t *u_line = YV12_U (line);
728 uint8_t *v_line = YV12_V (line);
731 for (i = 0; i < width; i++)
736 y = y_line[x + i] - 16;
737 u = u_line[(x + i) >> 1] - 128;
738 v = v_line[(x + i) >> 1] - 128;
740 /* R = 1.164(Y - 16) + 1.596(V - 128) */
741 r = 0x012b27 * y + 0x019a2e * v;
742 /* G = 1.164(Y - 16) - 0.813(V - 128) - 0.391(U - 128) */
743 g = 0x012b27 * y - 0x00d0f2 * v - 0x00647e * u;
744 /* B = 1.164(Y - 16) + 2.018(U - 128) */
745 b = 0x012b27 * y + 0x0206a2 * u;
747 *buffer++ = 0xff000000 |
748 (r >= 0 ? r < 0x1000000 ? r & 0xff0000 : 0xff0000 : 0) |
749 (g >= 0 ? g < 0x1000000 ? (g >> 8) & 0x00ff00 : 0x00ff00 : 0) |
750 (b >= 0 ? b < 0x1000000 ? (b >> 16) & 0x0000ff : 0x0000ff : 0);
754 /**************************** Pixel wise fetching *****************************/
756 /* Despite the type, expects a uint64_t buffer */
758 fetch_pixel_a2r10g10b10 (bits_image_t *image,
762 uint32_t *bits = image->bits + line * image->rowstride;
763 uint32_t p = READ (image, bits + offset);
764 uint64_t a = p >> 30;
765 uint64_t r = (p >> 20) & 0x3ff;
766 uint64_t g = (p >> 10) & 0x3ff;
767 uint64_t b = p & 0x3ff;
778 return a << 48 | r << 32 | g << 16 | b;
781 /* Despite the type, this function expects a uint64_t buffer */
783 fetch_pixel_x2r10g10b10 (bits_image_t *image,
787 uint32_t *bits = image->bits + line * image->rowstride;
788 uint32_t p = READ (image, bits + offset);
789 uint64_t r = (p >> 20) & 0x3ff;
790 uint64_t g = (p >> 10) & 0x3ff;
791 uint64_t b = p & 0x3ff;
797 return 0xffffULL << 48 | r << 32 | g << 16 | b;
800 /* Despite the type, expects a uint64_t buffer */
802 fetch_pixel_a2b10g10r10 (bits_image_t *image,
806 uint32_t *bits = image->bits + line * image->rowstride;
807 uint32_t p = READ (image, bits + offset);
808 uint64_t a = p >> 30;
809 uint64_t b = (p >> 20) & 0x3ff;
810 uint64_t g = (p >> 10) & 0x3ff;
811 uint64_t r = p & 0x3ff;
822 return a << 48 | r << 32 | g << 16 | b;
825 /* Despite the type, this function expects a uint64_t buffer */
827 fetch_pixel_x2b10g10r10 (bits_image_t *image,
831 uint32_t *bits = image->bits + line * image->rowstride;
832 uint32_t p = READ (image, bits + offset);
833 uint64_t b = (p >> 20) & 0x3ff;
834 uint64_t g = (p >> 10) & 0x3ff;
835 uint64_t r = p & 0x3ff;
841 return 0xffffULL << 48 | r << 32 | g << 16 | b;
845 fetch_pixel_c8 (bits_image_t *image,
849 uint32_t *bits = image->bits + line * image->rowstride;
850 uint32_t pixel = READ (image, (uint8_t *) bits + offset);
851 const pixman_indexed_t * indexed = image->indexed;
853 return indexed->rgba[pixel];
857 fetch_pixel_c4 (bits_image_t *image,
861 uint32_t *bits = image->bits + line * image->rowstride;
862 uint32_t pixel = FETCH_4 (image, bits, offset);
863 const pixman_indexed_t * indexed = image->indexed;
865 return indexed->rgba[pixel];
869 fetch_pixel_g1 (bits_image_t *image,
873 uint32_t *bits = image->bits + line * image->rowstride;
874 uint32_t pixel = READ (image, bits + (offset >> 5));
875 const pixman_indexed_t * indexed = image->indexed;
878 #ifdef WORDS_BIGENDIAN
879 a = pixel >> (0x1f - (offset & 0x1f));
881 a = pixel >> (offset & 0x1f);
885 return indexed->rgba[a];
889 fetch_pixel_yuy2 (bits_image_t *image,
893 const uint32_t *bits = image->bits + image->rowstride * line;
898 y = ((uint8_t *) bits)[offset << 1] - 16;
899 u = ((uint8_t *) bits)[((offset << 1) & - 4) + 1] - 128;
900 v = ((uint8_t *) bits)[((offset << 1) & - 4) + 3] - 128;
902 /* R = 1.164(Y - 16) + 1.596(V - 128) */
903 r = 0x012b27 * y + 0x019a2e * v;
905 /* G = 1.164(Y - 16) - 0.813(V - 128) - 0.391(U - 128) */
906 g = 0x012b27 * y - 0x00d0f2 * v - 0x00647e * u;
908 /* B = 1.164(Y - 16) + 2.018(U - 128) */
909 b = 0x012b27 * y + 0x0206a2 * u;
912 (r >= 0 ? r < 0x1000000 ? r & 0xff0000 : 0xff0000 : 0) |
913 (g >= 0 ? g < 0x1000000 ? (g >> 8) & 0x00ff00 : 0x00ff00 : 0) |
914 (b >= 0 ? b < 0x1000000 ? (b >> 16) & 0x0000ff : 0x0000ff : 0);
918 fetch_pixel_yv12 (bits_image_t *image,
923 int16_t y = YV12_Y (line)[offset] - 16;
924 int16_t u = YV12_U (line)[offset >> 1] - 128;
925 int16_t v = YV12_V (line)[offset >> 1] - 128;
928 /* R = 1.164(Y - 16) + 1.596(V - 128) */
929 r = 0x012b27 * y + 0x019a2e * v;
931 /* G = 1.164(Y - 16) - 0.813(V - 128) - 0.391(U - 128) */
932 g = 0x012b27 * y - 0x00d0f2 * v - 0x00647e * u;
934 /* B = 1.164(Y - 16) + 2.018(U - 128) */
935 b = 0x012b27 * y + 0x0206a2 * u;
938 (r >= 0 ? r < 0x1000000 ? r & 0xff0000 : 0xff0000 : 0) |
939 (g >= 0 ? g < 0x1000000 ? (g >> 8) & 0x00ff00 : 0x00ff00 : 0) |
940 (b >= 0 ? b < 0x1000000 ? (b >> 16) & 0x0000ff : 0x0000ff : 0);
943 /*********************************** Store ************************************/
946 store_scanline_a2r10g10b10 (bits_image_t * image,
952 uint32_t *bits = image->bits + image->rowstride * y;
953 uint32_t *pixel = bits + x;
954 uint64_t *values = (uint64_t *)v;
957 for (i = 0; i < width; ++i)
959 WRITE (image, pixel++,
960 ((values[i] >> 32) & 0xc0000000) |
961 ((values[i] >> 18) & 0x3ff00000) |
962 ((values[i] >> 12) & 0xffc00) |
963 ((values[i] >> 6) & 0x3ff));
968 store_scanline_x2r10g10b10 (bits_image_t * image,
974 uint32_t *bits = image->bits + image->rowstride * y;
975 uint64_t *values = (uint64_t *)v;
976 uint32_t *pixel = bits + x;
979 for (i = 0; i < width; ++i)
981 WRITE (image, pixel++,
982 ((values[i] >> 18) & 0x3ff00000) |
983 ((values[i] >> 12) & 0xffc00) |
984 ((values[i] >> 6) & 0x3ff));
989 store_scanline_a2b10g10r10 (bits_image_t * image,
995 uint32_t *bits = image->bits + image->rowstride * y;
996 uint32_t *pixel = bits + x;
997 uint64_t *values = (uint64_t *)v;
1000 for (i = 0; i < width; ++i)
1002 WRITE (image, pixel++,
1003 ((values[i] >> 32) & 0xc0000000) |
1004 ((values[i] >> 38) & 0x3ff) |
1005 ((values[i] >> 12) & 0xffc00) |
1006 ((values[i] << 14) & 0x3ff00000));
1011 store_scanline_x2b10g10r10 (bits_image_t * image,
1017 uint32_t *bits = image->bits + image->rowstride * y;
1018 uint64_t *values = (uint64_t *)v;
1019 uint32_t *pixel = bits + x;
1022 for (i = 0; i < width; ++i)
1024 WRITE (image, pixel++,
1025 ((values[i] >> 38) & 0x3ff) |
1026 ((values[i] >> 12) & 0xffc00) |
1027 ((values[i] << 14) & 0x3ff00000));
1032 store_scanline_c8 (bits_image_t * image,
1036 const uint32_t *values)
1038 uint32_t *bits = image->bits + image->rowstride * y;
1039 uint8_t *pixel = ((uint8_t *) bits) + x;
1040 const pixman_indexed_t *indexed = image->indexed;
1043 for (i = 0; i < width; ++i)
1044 WRITE (image, pixel++, RGB24_TO_ENTRY (indexed,values[i]));
1048 store_scanline_g8 (bits_image_t * image,
1052 const uint32_t *values)
1054 uint32_t *bits = image->bits + image->rowstride * y;
1055 uint8_t *pixel = ((uint8_t *) bits) + x;
1056 const pixman_indexed_t *indexed = image->indexed;
1059 for (i = 0; i < width; ++i)
1060 WRITE (image, pixel++, RGB24_TO_ENTRY_Y (indexed,values[i]));
1064 store_scanline_c4 (bits_image_t * image,
1068 const uint32_t *values)
1070 uint32_t *bits = image->bits + image->rowstride * y;
1071 const pixman_indexed_t *indexed = image->indexed;
1074 for (i = 0; i < width; ++i)
1078 pixel = RGB24_TO_ENTRY (indexed, values[i]);
1079 STORE_4 (image, bits, i + x, pixel);
1084 store_scanline_g4 (bits_image_t * image,
1088 const uint32_t *values)
1090 uint32_t *bits = image->bits + image->rowstride * y;
1091 const pixman_indexed_t *indexed = image->indexed;
1094 for (i = 0; i < width; ++i)
1098 pixel = RGB24_TO_ENTRY_Y (indexed, values[i]);
1099 STORE_4 (image, bits, i + x, pixel);
1104 store_scanline_g1 (bits_image_t * image,
1108 const uint32_t *values)
1110 uint32_t *bits = image->bits + image->rowstride * y;
1111 const pixman_indexed_t *indexed = image->indexed;
1114 for (i = 0; i < width; ++i)
1116 uint32_t *pixel = ((uint32_t *) bits) + ((i + x) >> 5);
1119 #ifdef WORDS_BIGENDIAN
1120 mask = 1 << (0x1f - ((i + x) & 0x1f));
1122 mask = 1 << ((i + x) & 0x1f);
1124 v = RGB24_TO_ENTRY_Y (indexed, values[i]) & 0x1 ? mask : 0;
1126 WRITE (image, pixel, (READ (image, pixel) & ~mask) | v);
1131 * Contracts a 64bpp image to 32bpp and then stores it using a regular 32-bit
1132 * store proc. Despite the type, this function expects a uint64_t buffer.
1135 store_scanline_generic_64 (bits_image_t * image,
1139 const uint32_t *values)
1141 uint32_t *argb8_pixels;
1143 assert (image->common.type == BITS);
1145 argb8_pixels = pixman_malloc_ab (width, sizeof(uint32_t));
1149 /* Contract the scanline. We could do this in place if values weren't
1152 pixman_contract (argb8_pixels, (uint64_t *)values, width);
1154 image->store_scanline_32 (image, x, y, width, argb8_pixels);
1156 free (argb8_pixels);
1159 /* Despite the type, this function expects both buffer
1160 * and mask to be uint64_t
1163 fetch_scanline_generic_64 (pixman_image_t *image,
1168 const uint32_t *mask)
1170 pixman_format_code_t format;
1172 /* Fetch the pixels into the first half of buffer and then expand them in
1175 image->bits.fetch_scanline_32 (image, x, y, width, buffer, NULL);
1177 format = image->bits.format;
1178 if (PIXMAN_FORMAT_TYPE (format) == PIXMAN_TYPE_COLOR ||
1179 PIXMAN_FORMAT_TYPE (format) == PIXMAN_TYPE_GRAY)
1181 /* Indexed formats are mapped to a8r8g8b8 with full
1182 * precision, so when expanding we shouldn't correct
1183 * for the width of the channels
1186 format = PIXMAN_a8r8g8b8;
1189 pixman_expand ((uint64_t *)buffer, buffer, format, width);
1192 /* Despite the type, this function expects a uint64_t *buffer */
1194 fetch_pixel_generic_64 (bits_image_t *image,
1198 uint32_t pixel32 = image->fetch_pixel_32 (image, offset, line);
1200 pixman_format_code_t format;
1202 format = image->format;
1203 if (PIXMAN_FORMAT_TYPE (format) == PIXMAN_TYPE_COLOR ||
1204 PIXMAN_FORMAT_TYPE (format) == PIXMAN_TYPE_GRAY)
1206 /* Indexed formats are mapped to a8r8g8b8 with full
1207 * precision, so when expanding we shouldn't correct
1208 * for the width of the channels
1211 format = PIXMAN_a8r8g8b8;
1214 pixman_expand ((uint64_t *)&result, &pixel32, format, 1);
1220 * XXX: The transformed fetch path only works at 32-bpp so far. When all
1221 * paths have wide versions, this can be removed.
1223 * WARNING: This function loses precision!
1226 fetch_pixel_generic_lossy_32 (bits_image_t *image,
1230 uint64_t pixel64 = image->fetch_pixel_64 (image, offset, line);
1233 pixman_contract (&result, &pixel64, 1);
1240 pixman_format_code_t format;
1241 fetch_scanline_t fetch_scanline_32;
1242 fetch_scanline_t fetch_scanline_64;
1243 fetch_pixel_32_t fetch_pixel_32;
1244 fetch_pixel_64_t fetch_pixel_64;
1245 store_scanline_t store_scanline_32;
1246 store_scanline_t store_scanline_64;
1249 #define FORMAT_INFO(format) \
1251 PIXMAN_ ## format, \
1252 fetch_scanline_ ## format, \
1253 fetch_scanline_generic_64, \
1254 fetch_pixel_ ## format, fetch_pixel_generic_64, \
1255 store_scanline_ ## format, store_scanline_generic_64 \
1258 static const format_info_t accessors[] =
1260 /* 32 bpp formats */
1261 FORMAT_INFO (a8r8g8b8),
1262 FORMAT_INFO (x8r8g8b8),
1263 FORMAT_INFO (a8b8g8r8),
1264 FORMAT_INFO (x8b8g8r8),
1265 FORMAT_INFO (b8g8r8a8),
1266 FORMAT_INFO (b8g8r8x8),
1267 FORMAT_INFO (r8g8b8a8),
1268 FORMAT_INFO (r8g8b8x8),
1269 FORMAT_INFO (x14r6g6b6),
1272 FORMAT_INFO (r8g8b8),
1273 FORMAT_INFO (b8g8r8),
1276 FORMAT_INFO (r5g6b5),
1277 FORMAT_INFO (b5g6r5),
1279 FORMAT_INFO (a1r5g5b5),
1280 FORMAT_INFO (x1r5g5b5),
1281 FORMAT_INFO (a1b5g5r5),
1282 FORMAT_INFO (x1b5g5r5),
1283 FORMAT_INFO (a4r4g4b4),
1284 FORMAT_INFO (x4r4g4b4),
1285 FORMAT_INFO (a4b4g4r4),
1286 FORMAT_INFO (x4b4g4r4),
1290 FORMAT_INFO (r3g3b2),
1291 FORMAT_INFO (b2g3r3),
1292 FORMAT_INFO (a2r2g2b2),
1293 FORMAT_INFO (a2b2g2r2),
1297 #define fetch_scanline_g8 fetch_scanline_c8
1298 #define fetch_pixel_g8 fetch_pixel_c8
1301 #define fetch_scanline_x4c4 fetch_scanline_c8
1302 #define fetch_pixel_x4c4 fetch_pixel_c8
1303 #define store_scanline_x4c4 store_scanline_c8
1306 #define fetch_scanline_x4g4 fetch_scanline_c8
1307 #define fetch_pixel_x4g4 fetch_pixel_c8
1308 #define store_scanline_x4g4 store_scanline_g8
1315 FORMAT_INFO (r1g2b1),
1316 FORMAT_INFO (b1g2r1),
1317 FORMAT_INFO (a1r1g1b1),
1318 FORMAT_INFO (a1b1g1r1),
1322 #define fetch_scanline_g4 fetch_scanline_c4
1323 #define fetch_pixel_g4 fetch_pixel_c4
1332 { PIXMAN_a2r10g10b10,
1333 NULL, fetch_scanline_a2r10g10b10,
1334 fetch_pixel_generic_lossy_32, fetch_pixel_a2r10g10b10,
1335 NULL, store_scanline_a2r10g10b10 },
1337 { PIXMAN_x2r10g10b10,
1338 NULL, fetch_scanline_x2r10g10b10,
1339 fetch_pixel_generic_lossy_32, fetch_pixel_x2r10g10b10,
1340 NULL, store_scanline_x2r10g10b10 },
1342 { PIXMAN_a2b10g10r10,
1343 NULL, fetch_scanline_a2b10g10r10,
1344 fetch_pixel_generic_lossy_32, fetch_pixel_a2b10g10r10,
1345 NULL, store_scanline_a2b10g10r10 },
1347 { PIXMAN_x2b10g10r10,
1348 NULL, fetch_scanline_x2b10g10r10,
1349 fetch_pixel_generic_lossy_32, fetch_pixel_x2b10g10r10,
1350 NULL, store_scanline_x2b10g10r10 },
1354 fetch_scanline_yuy2, fetch_scanline_generic_64,
1355 fetch_pixel_yuy2, fetch_pixel_generic_64,
1359 fetch_scanline_yv12, fetch_scanline_generic_64,
1360 fetch_pixel_yv12, fetch_pixel_generic_64,
1367 setup_accessors (bits_image_t *image)
1369 const format_info_t *info = accessors;
1371 while (info->format != PIXMAN_null)
1373 if (info->format == image->format)
1375 image->fetch_scanline_32 = info->fetch_scanline_32;
1376 image->fetch_scanline_64 = info->fetch_scanline_64;
1377 image->fetch_pixel_32 = info->fetch_pixel_32;
1378 image->fetch_pixel_64 = info->fetch_pixel_64;
1379 image->store_scanline_32 = info->store_scanline_32;
1380 image->store_scanline_64 = info->store_scanline_64;
1389 #ifndef PIXMAN_FB_ACCESSORS
1391 _pixman_bits_image_setup_accessors_accessors (bits_image_t *image);
1394 _pixman_bits_image_setup_accessors (bits_image_t *image)
1396 if (image->read_func || image->write_func)
1397 _pixman_bits_image_setup_accessors_accessors (image);
1399 setup_accessors (image);
1405 _pixman_bits_image_setup_accessors_accessors (bits_image_t *image)
1407 setup_accessors (image);