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_to_a8r8g8b8 (pixman_image_t *image,
305 pixman_format_code_t format,
308 if (PIXMAN_FORMAT_TYPE (format) == PIXMAN_TYPE_GRAY ||
309 PIXMAN_FORMAT_TYPE (format) == PIXMAN_TYPE_COLOR)
311 return image->bits.indexed->rgba[pixel];
315 return convert_pixel (format, PIXMAN_a8r8g8b8, pixel);
319 static force_inline uint32_t
320 convert_pixel_from_a8r8g8b8 (pixman_image_t *image,
321 pixman_format_code_t format, uint32_t pixel)
323 if (PIXMAN_FORMAT_TYPE (format) == PIXMAN_TYPE_GRAY)
325 pixel = CONVERT_RGB24_TO_Y15 (pixel);
327 return image->bits.indexed->ent[pixel & 0x7fff];
329 else if (PIXMAN_FORMAT_TYPE (format) == PIXMAN_TYPE_COLOR)
331 pixel = convert_pixel (PIXMAN_a8r8g8b8, PIXMAN_x1r5g5b5, pixel);
333 return image->bits.indexed->ent[pixel & 0x7fff];
337 return convert_pixel (PIXMAN_a8r8g8b8, format, pixel);
341 static force_inline uint32_t
342 fetch_and_convert_pixel (pixman_image_t * image,
343 const uint8_t * bits,
345 pixman_format_code_t format)
349 switch (PIXMAN_FORMAT_BPP (format))
352 pixel = FETCH_1 (image, bits, offset);
356 pixel = FETCH_4 (image, bits, offset);
360 pixel = READ (image, bits + offset);
364 pixel = READ (image, ((uint16_t *)bits + offset));
368 pixel = FETCH_24 (image, bits, offset);
372 pixel = READ (image, ((uint32_t *)bits + offset));
376 pixel = 0xffff00ff; /* As ugly as possible to detect the bug */
380 return convert_pixel_to_a8r8g8b8 (image, format, pixel);
383 static force_inline void
384 convert_and_store_pixel (bits_image_t * image,
387 pixman_format_code_t format,
390 uint32_t converted = convert_pixel_from_a8r8g8b8 (
391 (pixman_image_t *)image, format, pixel);
393 switch (PIXMAN_FORMAT_BPP (format))
396 STORE_1 (image, dest, offset, converted & 0x01);
400 STORE_4 (image, dest, offset, converted & 0xf);
404 WRITE (image, (dest + offset), converted & 0xff);
408 WRITE (image, ((uint16_t *)dest + offset), converted & 0xffff);
412 STORE_24 (image, dest, offset, converted);
416 WRITE (image, ((uint32_t *)dest + offset), converted);
425 #define MAKE_ACCESSORS(format) \
427 fetch_scanline_ ## format (pixman_image_t *image, \
432 const uint32_t *mask) \
435 (uint8_t *)(image->bits.bits + y * image->bits.rowstride); \
438 for (i = 0; i < width; ++i) \
441 fetch_and_convert_pixel (image, bits, x + i, PIXMAN_ ## format); \
446 store_scanline_ ## format (bits_image_t * image, \
450 const uint32_t *values) \
453 (uint8_t *)(image->bits + y * image->rowstride); \
456 for (i = 0; i < width; ++i) \
458 convert_and_store_pixel ( \
459 image, dest, i + x, PIXMAN_ ## format, values[i]); \
464 fetch_pixel_ ## format (bits_image_t *image, \
469 (uint8_t *)(image->bits + line * image->rowstride); \
471 return fetch_and_convert_pixel ((pixman_image_t *)image, \
472 bits, offset, PIXMAN_ ## format); \
475 static const void *const __dummy__ ## format
477 MAKE_ACCESSORS(a8r8g8b8);
478 MAKE_ACCESSORS(x8r8g8b8);
479 MAKE_ACCESSORS(a8b8g8r8);
480 MAKE_ACCESSORS(x8b8g8r8);
481 MAKE_ACCESSORS(x14r6g6b6);
482 MAKE_ACCESSORS(b8g8r8a8);
483 MAKE_ACCESSORS(b8g8r8x8);
484 MAKE_ACCESSORS(r8g8b8x8);
485 MAKE_ACCESSORS(r8g8b8a8);
486 MAKE_ACCESSORS(r8g8b8);
487 MAKE_ACCESSORS(b8g8r8);
488 MAKE_ACCESSORS(r5g6b5);
489 MAKE_ACCESSORS(b5g6r5);
490 MAKE_ACCESSORS(a1r5g5b5);
491 MAKE_ACCESSORS(x1r5g5b5);
492 MAKE_ACCESSORS(a1b5g5r5);
493 MAKE_ACCESSORS(x1b5g5r5);
494 MAKE_ACCESSORS(a4r4g4b4);
495 MAKE_ACCESSORS(x4r4g4b4);
496 MAKE_ACCESSORS(a4b4g4r4);
497 MAKE_ACCESSORS(x4b4g4r4);
501 MAKE_ACCESSORS(r3g3b2);
502 MAKE_ACCESSORS(b2g3r3);
503 MAKE_ACCESSORS(a2r2g2b2);
504 MAKE_ACCESSORS(a2b2g2r2);
505 MAKE_ACCESSORS(x4a4);
509 MAKE_ACCESSORS(r1g2b1);
510 MAKE_ACCESSORS(b1g2r1);
511 MAKE_ACCESSORS(a1r1g1b1);
512 MAKE_ACCESSORS(a1b1g1r1);
516 /********************************** Fetch ************************************/
518 /* Expects a uint64_t buffer */
520 fetch_scanline_a2r10g10b10 (pixman_image_t *image,
525 const uint32_t *mask)
527 const uint32_t *bits = image->bits.bits + y * image->bits.rowstride;
528 const uint32_t *pixel = bits + x;
529 const uint32_t *end = pixel + width;
530 uint64_t *buffer = (uint64_t *)b;
534 uint32_t p = READ (image, pixel++);
535 uint64_t a = p >> 30;
536 uint64_t r = (p >> 20) & 0x3ff;
537 uint64_t g = (p >> 10) & 0x3ff;
538 uint64_t b = p & 0x3ff;
549 *buffer++ = a << 48 | r << 32 | g << 16 | b;
553 /* Expects a uint64_t buffer */
555 fetch_scanline_x2r10g10b10 (pixman_image_t *image,
560 const uint32_t *mask)
562 const uint32_t *bits = image->bits.bits + y * image->bits.rowstride;
563 const uint32_t *pixel = (uint32_t *)bits + x;
564 const uint32_t *end = pixel + width;
565 uint64_t *buffer = (uint64_t *)b;
569 uint32_t p = READ (image, pixel++);
570 uint64_t r = (p >> 20) & 0x3ff;
571 uint64_t g = (p >> 10) & 0x3ff;
572 uint64_t b = p & 0x3ff;
578 *buffer++ = 0xffffULL << 48 | r << 32 | g << 16 | b;
582 /* Expects a uint64_t buffer */
584 fetch_scanline_a2b10g10r10 (pixman_image_t *image,
589 const uint32_t *mask)
591 const uint32_t *bits = image->bits.bits + y * image->bits.rowstride;
592 const uint32_t *pixel = bits + x;
593 const uint32_t *end = pixel + width;
594 uint64_t *buffer = (uint64_t *)b;
598 uint32_t p = READ (image, pixel++);
599 uint64_t a = p >> 30;
600 uint64_t b = (p >> 20) & 0x3ff;
601 uint64_t g = (p >> 10) & 0x3ff;
602 uint64_t r = p & 0x3ff;
613 *buffer++ = a << 48 | r << 32 | g << 16 | b;
617 /* Expects a uint64_t buffer */
619 fetch_scanline_x2b10g10r10 (pixman_image_t *image,
624 const uint32_t *mask)
626 const uint32_t *bits = image->bits.bits + y * image->bits.rowstride;
627 const uint32_t *pixel = (uint32_t *)bits + x;
628 const uint32_t *end = pixel + width;
629 uint64_t *buffer = (uint64_t *)b;
633 uint32_t p = READ (image, pixel++);
634 uint64_t b = (p >> 20) & 0x3ff;
635 uint64_t g = (p >> 10) & 0x3ff;
636 uint64_t r = p & 0x3ff;
642 *buffer++ = 0xffffULL << 48 | r << 32 | g << 16 | b;
647 fetch_scanline_yuy2 (pixman_image_t *image,
652 const uint32_t *mask)
654 const uint32_t *bits = image->bits.bits + image->bits.rowstride * line;
657 for (i = 0; i < width; i++)
662 y = ((uint8_t *) bits)[(x + i) << 1] - 16;
663 u = ((uint8_t *) bits)[(((x + i) << 1) & - 4) + 1] - 128;
664 v = ((uint8_t *) bits)[(((x + i) << 1) & - 4) + 3] - 128;
666 /* R = 1.164(Y - 16) + 1.596(V - 128) */
667 r = 0x012b27 * y + 0x019a2e * v;
668 /* G = 1.164(Y - 16) - 0.813(V - 128) - 0.391(U - 128) */
669 g = 0x012b27 * y - 0x00d0f2 * v - 0x00647e * u;
670 /* B = 1.164(Y - 16) + 2.018(U - 128) */
671 b = 0x012b27 * y + 0x0206a2 * u;
673 *buffer++ = 0xff000000 |
674 (r >= 0 ? r < 0x1000000 ? r & 0xff0000 : 0xff0000 : 0) |
675 (g >= 0 ? g < 0x1000000 ? (g >> 8) & 0x00ff00 : 0x00ff00 : 0) |
676 (b >= 0 ? b < 0x1000000 ? (b >> 16) & 0x0000ff : 0x0000ff : 0);
681 fetch_scanline_yv12 (pixman_image_t *image,
686 const uint32_t *mask)
689 uint8_t *y_line = YV12_Y (line);
690 uint8_t *u_line = YV12_U (line);
691 uint8_t *v_line = YV12_V (line);
694 for (i = 0; i < width; i++)
699 y = y_line[x + i] - 16;
700 u = u_line[(x + i) >> 1] - 128;
701 v = v_line[(x + i) >> 1] - 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);
717 /**************************** Pixel wise fetching *****************************/
719 /* Despite the type, expects a uint64_t buffer */
721 fetch_pixel_a2r10g10b10 (bits_image_t *image,
725 uint32_t *bits = image->bits + line * image->rowstride;
726 uint32_t p = READ (image, bits + offset);
727 uint64_t a = p >> 30;
728 uint64_t r = (p >> 20) & 0x3ff;
729 uint64_t g = (p >> 10) & 0x3ff;
730 uint64_t b = p & 0x3ff;
741 return a << 48 | r << 32 | g << 16 | b;
744 /* Despite the type, this function expects a uint64_t buffer */
746 fetch_pixel_x2r10g10b10 (bits_image_t *image,
750 uint32_t *bits = image->bits + line * image->rowstride;
751 uint32_t p = READ (image, bits + offset);
752 uint64_t r = (p >> 20) & 0x3ff;
753 uint64_t g = (p >> 10) & 0x3ff;
754 uint64_t b = p & 0x3ff;
760 return 0xffffULL << 48 | r << 32 | g << 16 | b;
763 /* Despite the type, expects a uint64_t buffer */
765 fetch_pixel_a2b10g10r10 (bits_image_t *image,
769 uint32_t *bits = image->bits + line * image->rowstride;
770 uint32_t p = READ (image, bits + offset);
771 uint64_t a = p >> 30;
772 uint64_t b = (p >> 20) & 0x3ff;
773 uint64_t g = (p >> 10) & 0x3ff;
774 uint64_t r = p & 0x3ff;
785 return a << 48 | r << 32 | g << 16 | b;
788 /* Despite the type, this function expects a uint64_t buffer */
790 fetch_pixel_x2b10g10r10 (bits_image_t *image,
794 uint32_t *bits = image->bits + line * image->rowstride;
795 uint32_t p = READ (image, bits + offset);
796 uint64_t b = (p >> 20) & 0x3ff;
797 uint64_t g = (p >> 10) & 0x3ff;
798 uint64_t r = p & 0x3ff;
804 return 0xffffULL << 48 | r << 32 | g << 16 | b;
808 fetch_pixel_yuy2 (bits_image_t *image,
812 const uint32_t *bits = image->bits + image->rowstride * line;
817 y = ((uint8_t *) bits)[offset << 1] - 16;
818 u = ((uint8_t *) bits)[((offset << 1) & - 4) + 1] - 128;
819 v = ((uint8_t *) bits)[((offset << 1) & - 4) + 3] - 128;
821 /* R = 1.164(Y - 16) + 1.596(V - 128) */
822 r = 0x012b27 * y + 0x019a2e * v;
824 /* G = 1.164(Y - 16) - 0.813(V - 128) - 0.391(U - 128) */
825 g = 0x012b27 * y - 0x00d0f2 * v - 0x00647e * u;
827 /* B = 1.164(Y - 16) + 2.018(U - 128) */
828 b = 0x012b27 * y + 0x0206a2 * u;
831 (r >= 0 ? r < 0x1000000 ? r & 0xff0000 : 0xff0000 : 0) |
832 (g >= 0 ? g < 0x1000000 ? (g >> 8) & 0x00ff00 : 0x00ff00 : 0) |
833 (b >= 0 ? b < 0x1000000 ? (b >> 16) & 0x0000ff : 0x0000ff : 0);
837 fetch_pixel_yv12 (bits_image_t *image,
842 int16_t y = YV12_Y (line)[offset] - 16;
843 int16_t u = YV12_U (line)[offset >> 1] - 128;
844 int16_t v = YV12_V (line)[offset >> 1] - 128;
847 /* R = 1.164(Y - 16) + 1.596(V - 128) */
848 r = 0x012b27 * y + 0x019a2e * v;
850 /* G = 1.164(Y - 16) - 0.813(V - 128) - 0.391(U - 128) */
851 g = 0x012b27 * y - 0x00d0f2 * v - 0x00647e * u;
853 /* B = 1.164(Y - 16) + 2.018(U - 128) */
854 b = 0x012b27 * y + 0x0206a2 * u;
857 (r >= 0 ? r < 0x1000000 ? r & 0xff0000 : 0xff0000 : 0) |
858 (g >= 0 ? g < 0x1000000 ? (g >> 8) & 0x00ff00 : 0x00ff00 : 0) |
859 (b >= 0 ? b < 0x1000000 ? (b >> 16) & 0x0000ff : 0x0000ff : 0);
862 /*********************************** Store ************************************/
865 store_scanline_a2r10g10b10 (bits_image_t * image,
871 uint32_t *bits = image->bits + image->rowstride * y;
872 uint32_t *pixel = bits + x;
873 uint64_t *values = (uint64_t *)v;
876 for (i = 0; i < width; ++i)
878 WRITE (image, pixel++,
879 ((values[i] >> 32) & 0xc0000000) |
880 ((values[i] >> 18) & 0x3ff00000) |
881 ((values[i] >> 12) & 0xffc00) |
882 ((values[i] >> 6) & 0x3ff));
887 store_scanline_x2r10g10b10 (bits_image_t * image,
893 uint32_t *bits = image->bits + image->rowstride * y;
894 uint64_t *values = (uint64_t *)v;
895 uint32_t *pixel = bits + x;
898 for (i = 0; i < width; ++i)
900 WRITE (image, pixel++,
901 ((values[i] >> 18) & 0x3ff00000) |
902 ((values[i] >> 12) & 0xffc00) |
903 ((values[i] >> 6) & 0x3ff));
908 store_scanline_a2b10g10r10 (bits_image_t * image,
914 uint32_t *bits = image->bits + image->rowstride * y;
915 uint32_t *pixel = bits + x;
916 uint64_t *values = (uint64_t *)v;
919 for (i = 0; i < width; ++i)
921 WRITE (image, pixel++,
922 ((values[i] >> 32) & 0xc0000000) |
923 ((values[i] >> 38) & 0x3ff) |
924 ((values[i] >> 12) & 0xffc00) |
925 ((values[i] << 14) & 0x3ff00000));
930 store_scanline_x2b10g10r10 (bits_image_t * image,
936 uint32_t *bits = image->bits + image->rowstride * y;
937 uint64_t *values = (uint64_t *)v;
938 uint32_t *pixel = bits + x;
941 for (i = 0; i < width; ++i)
943 WRITE (image, pixel++,
944 ((values[i] >> 38) & 0x3ff) |
945 ((values[i] >> 12) & 0xffc00) |
946 ((values[i] << 14) & 0x3ff00000));
951 * Contracts a 64bpp image to 32bpp and then stores it using a regular 32-bit
952 * store proc. Despite the type, this function expects a uint64_t buffer.
955 store_scanline_generic_64 (bits_image_t * image,
959 const uint32_t *values)
961 uint32_t *argb8_pixels;
963 assert (image->common.type == BITS);
965 argb8_pixels = pixman_malloc_ab (width, sizeof(uint32_t));
969 /* Contract the scanline. We could do this in place if values weren't
972 pixman_contract (argb8_pixels, (uint64_t *)values, width);
974 image->store_scanline_32 (image, x, y, width, argb8_pixels);
979 /* Despite the type, this function expects both buffer
980 * and mask to be uint64_t
983 fetch_scanline_generic_64 (pixman_image_t *image,
988 const uint32_t *mask)
990 pixman_format_code_t format;
992 /* Fetch the pixels into the first half of buffer and then expand them in
995 image->bits.fetch_scanline_32 (image, x, y, width, buffer, NULL);
997 format = image->bits.format;
998 if (PIXMAN_FORMAT_TYPE (format) == PIXMAN_TYPE_COLOR ||
999 PIXMAN_FORMAT_TYPE (format) == PIXMAN_TYPE_GRAY)
1001 /* Indexed formats are mapped to a8r8g8b8 with full
1002 * precision, so when expanding we shouldn't correct
1003 * for the width of the channels
1006 format = PIXMAN_a8r8g8b8;
1009 pixman_expand ((uint64_t *)buffer, buffer, format, width);
1012 /* Despite the type, this function expects a uint64_t *buffer */
1014 fetch_pixel_generic_64 (bits_image_t *image,
1018 uint32_t pixel32 = image->fetch_pixel_32 (image, offset, line);
1020 pixman_format_code_t format;
1022 format = image->format;
1023 if (PIXMAN_FORMAT_TYPE (format) == PIXMAN_TYPE_COLOR ||
1024 PIXMAN_FORMAT_TYPE (format) == PIXMAN_TYPE_GRAY)
1026 /* Indexed formats are mapped to a8r8g8b8 with full
1027 * precision, so when expanding we shouldn't correct
1028 * for the width of the channels
1031 format = PIXMAN_a8r8g8b8;
1034 pixman_expand ((uint64_t *)&result, &pixel32, format, 1);
1040 * XXX: The transformed fetch path only works at 32-bpp so far. When all
1041 * paths have wide versions, this can be removed.
1043 * WARNING: This function loses precision!
1046 fetch_pixel_generic_lossy_32 (bits_image_t *image,
1050 uint64_t pixel64 = image->fetch_pixel_64 (image, offset, line);
1053 pixman_contract (&result, &pixel64, 1);
1060 pixman_format_code_t format;
1061 fetch_scanline_t fetch_scanline_32;
1062 fetch_scanline_t fetch_scanline_64;
1063 fetch_pixel_32_t fetch_pixel_32;
1064 fetch_pixel_64_t fetch_pixel_64;
1065 store_scanline_t store_scanline_32;
1066 store_scanline_t store_scanline_64;
1069 #define FORMAT_INFO(format) \
1071 PIXMAN_ ## format, \
1072 fetch_scanline_ ## format, \
1073 fetch_scanline_generic_64, \
1074 fetch_pixel_ ## format, fetch_pixel_generic_64, \
1075 store_scanline_ ## format, store_scanline_generic_64 \
1078 static const format_info_t accessors[] =
1080 /* 32 bpp formats */
1081 FORMAT_INFO (a8r8g8b8),
1082 FORMAT_INFO (x8r8g8b8),
1083 FORMAT_INFO (a8b8g8r8),
1084 FORMAT_INFO (x8b8g8r8),
1085 FORMAT_INFO (b8g8r8a8),
1086 FORMAT_INFO (b8g8r8x8),
1087 FORMAT_INFO (r8g8b8a8),
1088 FORMAT_INFO (r8g8b8x8),
1089 FORMAT_INFO (x14r6g6b6),
1092 FORMAT_INFO (r8g8b8),
1093 FORMAT_INFO (b8g8r8),
1096 FORMAT_INFO (r5g6b5),
1097 FORMAT_INFO (b5g6r5),
1099 FORMAT_INFO (a1r5g5b5),
1100 FORMAT_INFO (x1r5g5b5),
1101 FORMAT_INFO (a1b5g5r5),
1102 FORMAT_INFO (x1b5g5r5),
1103 FORMAT_INFO (a4r4g4b4),
1104 FORMAT_INFO (x4r4g4b4),
1105 FORMAT_INFO (a4b4g4r4),
1106 FORMAT_INFO (x4b4g4r4),
1110 FORMAT_INFO (r3g3b2),
1111 FORMAT_INFO (b2g3r3),
1112 FORMAT_INFO (a2r2g2b2),
1113 FORMAT_INFO (a2b2g2r2),
1119 #define fetch_scanline_x4c4 fetch_scanline_c8
1120 #define fetch_pixel_x4c4 fetch_pixel_c8
1121 #define store_scanline_x4c4 store_scanline_c8
1124 #define fetch_scanline_x4g4 fetch_scanline_g8
1125 #define fetch_pixel_x4g4 fetch_pixel_g8
1126 #define store_scanline_x4g4 store_scanline_g8
1133 FORMAT_INFO (r1g2b1),
1134 FORMAT_INFO (b1g2r1),
1135 FORMAT_INFO (a1r1g1b1),
1136 FORMAT_INFO (a1b1g1r1),
1148 { PIXMAN_a2r10g10b10,
1149 NULL, fetch_scanline_a2r10g10b10,
1150 fetch_pixel_generic_lossy_32, fetch_pixel_a2r10g10b10,
1151 NULL, store_scanline_a2r10g10b10 },
1153 { PIXMAN_x2r10g10b10,
1154 NULL, fetch_scanline_x2r10g10b10,
1155 fetch_pixel_generic_lossy_32, fetch_pixel_x2r10g10b10,
1156 NULL, store_scanline_x2r10g10b10 },
1158 { PIXMAN_a2b10g10r10,
1159 NULL, fetch_scanline_a2b10g10r10,
1160 fetch_pixel_generic_lossy_32, fetch_pixel_a2b10g10r10,
1161 NULL, store_scanline_a2b10g10r10 },
1163 { PIXMAN_x2b10g10r10,
1164 NULL, fetch_scanline_x2b10g10r10,
1165 fetch_pixel_generic_lossy_32, fetch_pixel_x2b10g10r10,
1166 NULL, store_scanline_x2b10g10r10 },
1170 fetch_scanline_yuy2, fetch_scanline_generic_64,
1171 fetch_pixel_yuy2, fetch_pixel_generic_64,
1175 fetch_scanline_yv12, fetch_scanline_generic_64,
1176 fetch_pixel_yv12, fetch_pixel_generic_64,
1183 setup_accessors (bits_image_t *image)
1185 const format_info_t *info = accessors;
1187 while (info->format != PIXMAN_null)
1189 if (info->format == image->format)
1191 image->fetch_scanline_32 = info->fetch_scanline_32;
1192 image->fetch_scanline_64 = info->fetch_scanline_64;
1193 image->fetch_pixel_32 = info->fetch_pixel_32;
1194 image->fetch_pixel_64 = info->fetch_pixel_64;
1195 image->store_scanline_32 = info->store_scanline_32;
1196 image->store_scanline_64 = info->store_scanline_64;
1205 #ifndef PIXMAN_FB_ACCESSORS
1207 _pixman_bits_image_setup_accessors_accessors (bits_image_t *image);
1210 _pixman_bits_image_setup_accessors (bits_image_t *image)
1212 if (image->read_func || image->write_func)
1213 _pixman_bits_image_setup_accessors_accessors (image);
1215 setup_accessors (image);
1221 _pixman_bits_image_setup_accessors_accessors (bits_image_t *image)
1223 setup_accessors (image);