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))
50 #ifdef WORDS_BIGENDIAN
51 #define FETCH_1(img,l,o) \
52 (((READ ((img), ((uint32_t *)(l)) + ((o) >> 5))) >> (0x1f - ((o) & 0x1f))) & 0x1)
54 #define FETCH_1(img,l,o) \
55 ((((READ ((img), ((uint32_t *)(l)) + ((o) >> 5))) >> ((o) & 0x1f))) & 0x1)
58 #define FETCH_8(img,l,o) (READ (img, (((uint8_t *)(l)) + ((o) >> 3))))
60 #ifdef WORDS_BIGENDIAN
61 #define FETCH_4(img,l,o) \
62 (((4 * (o)) & 4) ? (FETCH_8 (img,l, 4 * (o)) & 0xf) : (FETCH_8 (img,l,(4 * (o))) >> 4))
64 #define FETCH_4(img,l,o) \
65 (((4 * (o)) & 4) ? (FETCH_8 (img, l, 4 * (o)) >> 4) : (FETCH_8 (img, l, (4 * (o))) & 0xf))
68 #ifdef WORDS_BIGENDIAN
69 #define FETCH_24(img,l,o) \
70 ((READ (img, (((uint8_t *)(l)) + ((o) * 3) + 0)) << 16) | \
71 (READ (img, (((uint8_t *)(l)) + ((o) * 3) + 1)) << 8) | \
72 (READ (img, (((uint8_t *)(l)) + ((o) * 3) + 2)) << 0))
74 #define FETCH_24(img,l,o) \
75 ((READ (img, (((uint8_t *)(l)) + ((o) * 3) + 0)) << 0) | \
76 (READ (img, (((uint8_t *)(l)) + ((o) * 3) + 1)) << 8) | \
77 (READ (img, (((uint8_t *)(l)) + ((o) * 3) + 2)) << 16))
82 #ifdef WORDS_BIGENDIAN
83 #define STORE_1(img,l,o,v) \
86 uint32_t *__d = ((uint32_t *)(l)) + ((o) >> 5); \
89 __m = 1 << (0x1f - ((o) & 0x1f)); \
92 WRITE((img), __d, (READ((img), __d) & ~__m) | __v); \
96 #define STORE_1(img,l,o,v) \
99 uint32_t *__d = ((uint32_t *)(l)) + ((o) >> 5); \
102 __m = 1 << ((o) & 0x1f); \
103 __v = (v)? __m : 0; \
105 WRITE((img), __d, (READ((img), __d) & ~__m) | __v); \
110 #define STORE_8(img,l,o,v) (WRITE (img, (uint8_t *)(l) + ((o) >> 3), (v)))
112 #ifdef WORDS_BIGENDIAN
113 #define STORE_4(img,l,o,v) \
117 int v4 = (v) & 0x0f; \
119 STORE_8 (img, l, bo, ( \
121 (FETCH_8 (img, l, bo) & 0xf0) | (v4) : \
122 (FETCH_8 (img, l, bo) & 0x0f) | (v4 << 4))); \
125 #define STORE_4(img,l,o,v) \
129 int v4 = (v) & 0x0f; \
131 STORE_8 (img, l, bo, ( \
133 (FETCH_8 (img, l, bo) & 0x0f) | (v4 << 4) : \
134 (FETCH_8 (img, l, bo) & 0xf0) | (v4))); \
138 #ifdef WORDS_BIGENDIAN
139 #define STORE_24(img,l,o,v) \
142 uint8_t *__tmp = (l) + 3 * (o); \
144 WRITE ((img), __tmp++, ((v) & 0x00ff0000) >> 16); \
145 WRITE ((img), __tmp++, ((v) & 0x0000ff00) >> 8); \
146 WRITE ((img), __tmp++, ((v) & 0x000000ff) >> 0); \
150 #define STORE_24(img,l,o,v) \
153 uint8_t *__tmp = (l) + 3 * (o); \
155 WRITE ((img), __tmp++, ((v) & 0x000000ff) >> 0); \
156 WRITE ((img), __tmp++, ((v) & 0x0000ff00) >> 8); \
157 WRITE ((img), __tmp++, ((v) & 0x00ff0000) >> 16); \
163 * YV12 setup and access macros
166 #define YV12_SETUP(image) \
167 bits_image_t *__bits_image = (bits_image_t *)image; \
168 uint32_t *bits = __bits_image->bits; \
169 int stride = __bits_image->rowstride; \
170 int offset0 = stride < 0 ? \
171 ((-stride) >> 1) * ((__bits_image->height - 1) >> 1) - stride : \
172 stride * __bits_image->height; \
173 int offset1 = stride < 0 ? \
174 offset0 + ((-stride) >> 1) * ((__bits_image->height) >> 1) : \
175 offset0 + (offset0 >> 2)
177 /* Note no trailing semicolon on the above macro; if it's there, then
178 * the typical usage of YV12_SETUP(image); will have an extra trailing ;
179 * that some compilers will interpret as a statement -- and then any further
180 * variable declarations will cause an error.
183 #define YV12_Y(line) \
184 ((uint8_t *) ((bits) + (stride) * (line)))
186 #define YV12_U(line) \
187 ((uint8_t *) ((bits) + offset1 + \
188 ((stride) >> 1) * ((line) >> 1)))
190 #define YV12_V(line) \
191 ((uint8_t *) ((bits) + offset0 + \
192 ((stride) >> 1) * ((line) >> 1)))
196 static force_inline void
197 get_shifts (pixman_format_code_t format,
203 switch (PIXMAN_FORMAT_TYPE (format))
212 case PIXMAN_TYPE_ARGB:
214 *g = *b + PIXMAN_FORMAT_B (format);
215 *r = *g + PIXMAN_FORMAT_G (format);
216 *a = *r + PIXMAN_FORMAT_R (format);
219 case PIXMAN_TYPE_ABGR:
221 *g = *r + PIXMAN_FORMAT_R (format);
222 *b = *g + PIXMAN_FORMAT_G (format);
223 *a = *b + PIXMAN_FORMAT_B (format);
226 case PIXMAN_TYPE_BGRA:
227 /* With BGRA formats we start counting at the high end of the pixel */
228 *b = PIXMAN_FORMAT_BPP (format) - PIXMAN_FORMAT_B (format);
229 *g = *b - PIXMAN_FORMAT_B (format);
230 *r = *g - PIXMAN_FORMAT_G (format);
231 *a = *r - PIXMAN_FORMAT_R (format);
234 case PIXMAN_TYPE_RGBA:
235 /* With BGRA formats we start counting at the high end of the pixel */
236 *r = PIXMAN_FORMAT_BPP (format) - PIXMAN_FORMAT_R (format);
237 *g = *r - PIXMAN_FORMAT_R (format);
238 *b = *g - PIXMAN_FORMAT_G (format);
239 *a = *b - PIXMAN_FORMAT_B (format);
248 static force_inline uint32_t
249 convert_channel (uint32_t pixel, uint32_t def_value,
250 int n_from_bits, int from_shift,
251 int n_to_bits, int to_shift)
255 if (n_from_bits && n_to_bits)
256 v = unorm_to_unorm (pixel >> from_shift, n_from_bits, n_to_bits);
262 return (v & ((1 << n_to_bits) - 1)) << to_shift;
265 static force_inline uint32_t
266 convert_pixel (pixman_format_code_t from, pixman_format_code_t to, uint32_t pixel)
268 int a_from_shift, r_from_shift, g_from_shift, b_from_shift;
269 int a_to_shift, r_to_shift, g_to_shift, b_to_shift;
272 get_shifts (from, &a_from_shift, &r_from_shift, &g_from_shift, &b_from_shift);
273 get_shifts (to, &a_to_shift, &r_to_shift, &g_to_shift, &b_to_shift);
275 a = convert_channel (pixel, ~0,
276 PIXMAN_FORMAT_A (from), a_from_shift,
277 PIXMAN_FORMAT_A (to), a_to_shift);
279 r = convert_channel (pixel, 0,
280 PIXMAN_FORMAT_R (from), r_from_shift,
281 PIXMAN_FORMAT_R (to), r_to_shift);
283 g = convert_channel (pixel, 0,
284 PIXMAN_FORMAT_G (from), g_from_shift,
285 PIXMAN_FORMAT_G (to), g_to_shift);
287 b = convert_channel (pixel, 0,
288 PIXMAN_FORMAT_B (from), b_from_shift,
289 PIXMAN_FORMAT_B (to), b_to_shift);
291 return a | r | g | b;
294 static force_inline uint32_t
295 convert_pixel_to_a8r8g8b8 (pixman_image_t *image,
296 pixman_format_code_t format,
299 if (PIXMAN_FORMAT_TYPE (format) == PIXMAN_TYPE_GRAY ||
300 PIXMAN_FORMAT_TYPE (format) == PIXMAN_TYPE_COLOR)
302 return image->bits.indexed->rgba[pixel];
306 return convert_pixel (format, PIXMAN_a8r8g8b8, pixel);
310 static force_inline uint32_t
311 convert_pixel_from_a8r8g8b8 (pixman_image_t *image,
312 pixman_format_code_t format, uint32_t pixel)
314 if (PIXMAN_FORMAT_TYPE (format) == PIXMAN_TYPE_GRAY)
316 pixel = CONVERT_RGB24_TO_Y15 (pixel);
318 return image->bits.indexed->ent[pixel & 0x7fff];
320 else if (PIXMAN_FORMAT_TYPE (format) == PIXMAN_TYPE_COLOR)
322 pixel = convert_pixel (PIXMAN_a8r8g8b8, PIXMAN_x1r5g5b5, pixel);
324 return image->bits.indexed->ent[pixel & 0x7fff];
328 return convert_pixel (PIXMAN_a8r8g8b8, format, pixel);
332 static force_inline uint32_t
333 fetch_and_convert_pixel (pixman_image_t * image,
334 const uint8_t * bits,
336 pixman_format_code_t format)
340 switch (PIXMAN_FORMAT_BPP (format))
343 pixel = FETCH_1 (image, bits, offset);
347 pixel = FETCH_4 (image, bits, offset);
351 pixel = READ (image, bits + offset);
355 pixel = READ (image, ((uint16_t *)bits + offset));
359 pixel = FETCH_24 (image, bits, offset);
363 pixel = READ (image, ((uint32_t *)bits + offset));
367 pixel = 0xffff00ff; /* As ugly as possible to detect the bug */
371 return convert_pixel_to_a8r8g8b8 (image, format, pixel);
374 static force_inline void
375 convert_and_store_pixel (bits_image_t * image,
378 pixman_format_code_t format,
381 uint32_t converted = convert_pixel_from_a8r8g8b8 (
382 (pixman_image_t *)image, format, pixel);
384 switch (PIXMAN_FORMAT_BPP (format))
387 STORE_1 (image, dest, offset, converted & 0x01);
391 STORE_4 (image, dest, offset, converted & 0xf);
395 WRITE (image, (dest + offset), converted & 0xff);
399 WRITE (image, ((uint16_t *)dest + offset), converted & 0xffff);
403 STORE_24 (image, dest, offset, converted);
407 WRITE (image, ((uint32_t *)dest + offset), converted);
416 #define MAKE_ACCESSORS(format) \
418 fetch_scanline_ ## format (pixman_image_t *image, \
423 const uint32_t *mask) \
426 (uint8_t *)(image->bits.bits + y * image->bits.rowstride); \
429 for (i = 0; i < width; ++i) \
432 fetch_and_convert_pixel (image, bits, x + i, PIXMAN_ ## format); \
437 store_scanline_ ## format (bits_image_t * image, \
441 const uint32_t *values) \
444 (uint8_t *)(image->bits + y * image->rowstride); \
447 for (i = 0; i < width; ++i) \
449 convert_and_store_pixel ( \
450 image, dest, i + x, PIXMAN_ ## format, values[i]); \
455 fetch_pixel_ ## format (bits_image_t *image, \
460 (uint8_t *)(image->bits + line * image->rowstride); \
462 return fetch_and_convert_pixel ((pixman_image_t *)image, \
463 bits, offset, PIXMAN_ ## format); \
466 static const void *const __dummy__ ## format
468 MAKE_ACCESSORS(a8r8g8b8);
469 MAKE_ACCESSORS(x8r8g8b8);
470 MAKE_ACCESSORS(a8b8g8r8);
471 MAKE_ACCESSORS(x8b8g8r8);
472 MAKE_ACCESSORS(x14r6g6b6);
473 MAKE_ACCESSORS(b8g8r8a8);
474 MAKE_ACCESSORS(b8g8r8x8);
475 MAKE_ACCESSORS(r8g8b8x8);
476 MAKE_ACCESSORS(r8g8b8a8);
477 MAKE_ACCESSORS(r8g8b8);
478 MAKE_ACCESSORS(b8g8r8);
479 MAKE_ACCESSORS(r5g6b5);
480 MAKE_ACCESSORS(b5g6r5);
481 MAKE_ACCESSORS(a1r5g5b5);
482 MAKE_ACCESSORS(x1r5g5b5);
483 MAKE_ACCESSORS(a1b5g5r5);
484 MAKE_ACCESSORS(x1b5g5r5);
485 MAKE_ACCESSORS(a4r4g4b4);
486 MAKE_ACCESSORS(x4r4g4b4);
487 MAKE_ACCESSORS(a4b4g4r4);
488 MAKE_ACCESSORS(x4b4g4r4);
492 MAKE_ACCESSORS(r3g3b2);
493 MAKE_ACCESSORS(b2g3r3);
494 MAKE_ACCESSORS(a2r2g2b2);
495 MAKE_ACCESSORS(a2b2g2r2);
496 MAKE_ACCESSORS(x4a4);
500 MAKE_ACCESSORS(r1g2b1);
501 MAKE_ACCESSORS(b1g2r1);
502 MAKE_ACCESSORS(a1r1g1b1);
503 MAKE_ACCESSORS(a1b1g1r1);
507 /********************************** Fetch ************************************/
509 /* Expects a uint64_t buffer */
511 fetch_scanline_a2r10g10b10 (pixman_image_t *image,
516 const uint32_t *mask)
518 const uint32_t *bits = image->bits.bits + y * image->bits.rowstride;
519 const uint32_t *pixel = bits + x;
520 const uint32_t *end = pixel + width;
521 uint64_t *buffer = (uint64_t *)b;
525 uint32_t p = READ (image, pixel++);
526 uint64_t a = p >> 30;
527 uint64_t r = (p >> 20) & 0x3ff;
528 uint64_t g = (p >> 10) & 0x3ff;
529 uint64_t b = p & 0x3ff;
540 *buffer++ = a << 48 | r << 32 | g << 16 | b;
544 /* Expects a uint64_t buffer */
546 fetch_scanline_x2r10g10b10 (pixman_image_t *image,
551 const uint32_t *mask)
553 const uint32_t *bits = image->bits.bits + y * image->bits.rowstride;
554 const uint32_t *pixel = (uint32_t *)bits + x;
555 const uint32_t *end = pixel + width;
556 uint64_t *buffer = (uint64_t *)b;
560 uint32_t p = READ (image, pixel++);
561 uint64_t r = (p >> 20) & 0x3ff;
562 uint64_t g = (p >> 10) & 0x3ff;
563 uint64_t b = p & 0x3ff;
569 *buffer++ = 0xffffULL << 48 | r << 32 | g << 16 | b;
573 /* Expects a uint64_t buffer */
575 fetch_scanline_a2b10g10r10 (pixman_image_t *image,
580 const uint32_t *mask)
582 const uint32_t *bits = image->bits.bits + y * image->bits.rowstride;
583 const uint32_t *pixel = bits + x;
584 const uint32_t *end = pixel + width;
585 uint64_t *buffer = (uint64_t *)b;
589 uint32_t p = READ (image, pixel++);
590 uint64_t a = p >> 30;
591 uint64_t b = (p >> 20) & 0x3ff;
592 uint64_t g = (p >> 10) & 0x3ff;
593 uint64_t r = p & 0x3ff;
604 *buffer++ = a << 48 | r << 32 | g << 16 | b;
608 /* Expects a uint64_t buffer */
610 fetch_scanline_x2b10g10r10 (pixman_image_t *image,
615 const uint32_t *mask)
617 const uint32_t *bits = image->bits.bits + y * image->bits.rowstride;
618 const uint32_t *pixel = (uint32_t *)bits + x;
619 const uint32_t *end = pixel + width;
620 uint64_t *buffer = (uint64_t *)b;
624 uint32_t p = READ (image, pixel++);
625 uint64_t b = (p >> 20) & 0x3ff;
626 uint64_t g = (p >> 10) & 0x3ff;
627 uint64_t r = p & 0x3ff;
633 *buffer++ = 0xffffULL << 48 | r << 32 | g << 16 | b;
638 fetch_scanline_yuy2 (pixman_image_t *image,
643 const uint32_t *mask)
645 const uint32_t *bits = image->bits.bits + image->bits.rowstride * line;
648 for (i = 0; i < width; i++)
653 y = ((uint8_t *) bits)[(x + i) << 1] - 16;
654 u = ((uint8_t *) bits)[(((x + i) << 1) & - 4) + 1] - 128;
655 v = ((uint8_t *) bits)[(((x + i) << 1) & - 4) + 3] - 128;
657 /* R = 1.164(Y - 16) + 1.596(V - 128) */
658 r = 0x012b27 * y + 0x019a2e * v;
659 /* G = 1.164(Y - 16) - 0.813(V - 128) - 0.391(U - 128) */
660 g = 0x012b27 * y - 0x00d0f2 * v - 0x00647e * u;
661 /* B = 1.164(Y - 16) + 2.018(U - 128) */
662 b = 0x012b27 * y + 0x0206a2 * u;
664 *buffer++ = 0xff000000 |
665 (r >= 0 ? r < 0x1000000 ? r & 0xff0000 : 0xff0000 : 0) |
666 (g >= 0 ? g < 0x1000000 ? (g >> 8) & 0x00ff00 : 0x00ff00 : 0) |
667 (b >= 0 ? b < 0x1000000 ? (b >> 16) & 0x0000ff : 0x0000ff : 0);
672 fetch_scanline_yv12 (pixman_image_t *image,
677 const uint32_t *mask)
680 uint8_t *y_line = YV12_Y (line);
681 uint8_t *u_line = YV12_U (line);
682 uint8_t *v_line = YV12_V (line);
685 for (i = 0; i < width; i++)
690 y = y_line[x + i] - 16;
691 u = u_line[(x + i) >> 1] - 128;
692 v = v_line[(x + i) >> 1] - 128;
694 /* R = 1.164(Y - 16) + 1.596(V - 128) */
695 r = 0x012b27 * y + 0x019a2e * v;
696 /* G = 1.164(Y - 16) - 0.813(V - 128) - 0.391(U - 128) */
697 g = 0x012b27 * y - 0x00d0f2 * v - 0x00647e * u;
698 /* B = 1.164(Y - 16) + 2.018(U - 128) */
699 b = 0x012b27 * y + 0x0206a2 * u;
701 *buffer++ = 0xff000000 |
702 (r >= 0 ? r < 0x1000000 ? r & 0xff0000 : 0xff0000 : 0) |
703 (g >= 0 ? g < 0x1000000 ? (g >> 8) & 0x00ff00 : 0x00ff00 : 0) |
704 (b >= 0 ? b < 0x1000000 ? (b >> 16) & 0x0000ff : 0x0000ff : 0);
708 /**************************** Pixel wise fetching *****************************/
710 /* Despite the type, expects a uint64_t buffer */
712 fetch_pixel_a2r10g10b10 (bits_image_t *image,
716 uint32_t *bits = image->bits + line * image->rowstride;
717 uint32_t p = READ (image, bits + offset);
718 uint64_t a = p >> 30;
719 uint64_t r = (p >> 20) & 0x3ff;
720 uint64_t g = (p >> 10) & 0x3ff;
721 uint64_t b = p & 0x3ff;
732 return a << 48 | r << 32 | g << 16 | b;
735 /* Despite the type, this function expects a uint64_t buffer */
737 fetch_pixel_x2r10g10b10 (bits_image_t *image,
741 uint32_t *bits = image->bits + line * image->rowstride;
742 uint32_t p = READ (image, bits + offset);
743 uint64_t r = (p >> 20) & 0x3ff;
744 uint64_t g = (p >> 10) & 0x3ff;
745 uint64_t b = p & 0x3ff;
751 return 0xffffULL << 48 | r << 32 | g << 16 | b;
754 /* Despite the type, expects a uint64_t buffer */
756 fetch_pixel_a2b10g10r10 (bits_image_t *image,
760 uint32_t *bits = image->bits + line * image->rowstride;
761 uint32_t p = READ (image, bits + offset);
762 uint64_t a = p >> 30;
763 uint64_t b = (p >> 20) & 0x3ff;
764 uint64_t g = (p >> 10) & 0x3ff;
765 uint64_t r = p & 0x3ff;
776 return a << 48 | r << 32 | g << 16 | b;
779 /* Despite the type, this function expects a uint64_t buffer */
781 fetch_pixel_x2b10g10r10 (bits_image_t *image,
785 uint32_t *bits = image->bits + line * image->rowstride;
786 uint32_t p = READ (image, bits + offset);
787 uint64_t b = (p >> 20) & 0x3ff;
788 uint64_t g = (p >> 10) & 0x3ff;
789 uint64_t r = p & 0x3ff;
795 return 0xffffULL << 48 | r << 32 | g << 16 | b;
799 fetch_pixel_yuy2 (bits_image_t *image,
803 const uint32_t *bits = image->bits + image->rowstride * line;
808 y = ((uint8_t *) bits)[offset << 1] - 16;
809 u = ((uint8_t *) bits)[((offset << 1) & - 4) + 1] - 128;
810 v = ((uint8_t *) bits)[((offset << 1) & - 4) + 3] - 128;
812 /* R = 1.164(Y - 16) + 1.596(V - 128) */
813 r = 0x012b27 * y + 0x019a2e * v;
815 /* G = 1.164(Y - 16) - 0.813(V - 128) - 0.391(U - 128) */
816 g = 0x012b27 * y - 0x00d0f2 * v - 0x00647e * u;
818 /* B = 1.164(Y - 16) + 2.018(U - 128) */
819 b = 0x012b27 * y + 0x0206a2 * u;
822 (r >= 0 ? r < 0x1000000 ? r & 0xff0000 : 0xff0000 : 0) |
823 (g >= 0 ? g < 0x1000000 ? (g >> 8) & 0x00ff00 : 0x00ff00 : 0) |
824 (b >= 0 ? b < 0x1000000 ? (b >> 16) & 0x0000ff : 0x0000ff : 0);
828 fetch_pixel_yv12 (bits_image_t *image,
833 int16_t y = YV12_Y (line)[offset] - 16;
834 int16_t u = YV12_U (line)[offset >> 1] - 128;
835 int16_t v = YV12_V (line)[offset >> 1] - 128;
838 /* R = 1.164(Y - 16) + 1.596(V - 128) */
839 r = 0x012b27 * y + 0x019a2e * v;
841 /* G = 1.164(Y - 16) - 0.813(V - 128) - 0.391(U - 128) */
842 g = 0x012b27 * y - 0x00d0f2 * v - 0x00647e * u;
844 /* B = 1.164(Y - 16) + 2.018(U - 128) */
845 b = 0x012b27 * y + 0x0206a2 * u;
848 (r >= 0 ? r < 0x1000000 ? r & 0xff0000 : 0xff0000 : 0) |
849 (g >= 0 ? g < 0x1000000 ? (g >> 8) & 0x00ff00 : 0x00ff00 : 0) |
850 (b >= 0 ? b < 0x1000000 ? (b >> 16) & 0x0000ff : 0x0000ff : 0);
853 /*********************************** Store ************************************/
856 store_scanline_a2r10g10b10 (bits_image_t * image,
862 uint32_t *bits = image->bits + image->rowstride * y;
863 uint32_t *pixel = bits + x;
864 uint64_t *values = (uint64_t *)v;
867 for (i = 0; i < width; ++i)
869 WRITE (image, pixel++,
870 ((values[i] >> 32) & 0xc0000000) |
871 ((values[i] >> 18) & 0x3ff00000) |
872 ((values[i] >> 12) & 0xffc00) |
873 ((values[i] >> 6) & 0x3ff));
878 store_scanline_x2r10g10b10 (bits_image_t * image,
884 uint32_t *bits = image->bits + image->rowstride * y;
885 uint64_t *values = (uint64_t *)v;
886 uint32_t *pixel = bits + x;
889 for (i = 0; i < width; ++i)
891 WRITE (image, pixel++,
892 ((values[i] >> 18) & 0x3ff00000) |
893 ((values[i] >> 12) & 0xffc00) |
894 ((values[i] >> 6) & 0x3ff));
899 store_scanline_a2b10g10r10 (bits_image_t * image,
905 uint32_t *bits = image->bits + image->rowstride * y;
906 uint32_t *pixel = bits + x;
907 uint64_t *values = (uint64_t *)v;
910 for (i = 0; i < width; ++i)
912 WRITE (image, pixel++,
913 ((values[i] >> 32) & 0xc0000000) |
914 ((values[i] >> 38) & 0x3ff) |
915 ((values[i] >> 12) & 0xffc00) |
916 ((values[i] << 14) & 0x3ff00000));
921 store_scanline_x2b10g10r10 (bits_image_t * image,
927 uint32_t *bits = image->bits + image->rowstride * y;
928 uint64_t *values = (uint64_t *)v;
929 uint32_t *pixel = bits + x;
932 for (i = 0; i < width; ++i)
934 WRITE (image, pixel++,
935 ((values[i] >> 38) & 0x3ff) |
936 ((values[i] >> 12) & 0xffc00) |
937 ((values[i] << 14) & 0x3ff00000));
942 * Contracts a 64bpp image to 32bpp and then stores it using a regular 32-bit
943 * store proc. Despite the type, this function expects a uint64_t buffer.
946 store_scanline_generic_64 (bits_image_t * image,
950 const uint32_t *values)
952 uint32_t *argb8_pixels;
954 assert (image->common.type == BITS);
956 argb8_pixels = pixman_malloc_ab (width, sizeof(uint32_t));
960 /* Contract the scanline. We could do this in place if values weren't
963 pixman_contract (argb8_pixels, (uint64_t *)values, width);
965 image->store_scanline_32 (image, x, y, width, argb8_pixels);
970 /* Despite the type, this function expects both buffer
971 * and mask to be uint64_t
974 fetch_scanline_generic_64 (pixman_image_t *image,
979 const uint32_t *mask)
981 pixman_format_code_t format;
983 /* Fetch the pixels into the first half of buffer and then expand them in
986 image->bits.fetch_scanline_32 (image, x, y, width, buffer, NULL);
988 format = image->bits.format;
989 if (PIXMAN_FORMAT_TYPE (format) == PIXMAN_TYPE_COLOR ||
990 PIXMAN_FORMAT_TYPE (format) == PIXMAN_TYPE_GRAY)
992 /* Indexed formats are mapped to a8r8g8b8 with full
993 * precision, so when expanding we shouldn't correct
994 * for the width of the channels
997 format = PIXMAN_a8r8g8b8;
1000 pixman_expand ((uint64_t *)buffer, buffer, format, width);
1003 /* Despite the type, this function expects a uint64_t *buffer */
1005 fetch_pixel_generic_64 (bits_image_t *image,
1009 uint32_t pixel32 = image->fetch_pixel_32 (image, offset, line);
1011 pixman_format_code_t format;
1013 format = image->format;
1014 if (PIXMAN_FORMAT_TYPE (format) == PIXMAN_TYPE_COLOR ||
1015 PIXMAN_FORMAT_TYPE (format) == PIXMAN_TYPE_GRAY)
1017 /* Indexed formats are mapped to a8r8g8b8 with full
1018 * precision, so when expanding we shouldn't correct
1019 * for the width of the channels
1022 format = PIXMAN_a8r8g8b8;
1025 pixman_expand ((uint64_t *)&result, &pixel32, format, 1);
1031 * XXX: The transformed fetch path only works at 32-bpp so far. When all
1032 * paths have wide versions, this can be removed.
1034 * WARNING: This function loses precision!
1037 fetch_pixel_generic_lossy_32 (bits_image_t *image,
1041 uint64_t pixel64 = image->fetch_pixel_64 (image, offset, line);
1044 pixman_contract (&result, &pixel64, 1);
1051 pixman_format_code_t format;
1052 fetch_scanline_t fetch_scanline_32;
1053 fetch_scanline_t fetch_scanline_64;
1054 fetch_pixel_32_t fetch_pixel_32;
1055 fetch_pixel_64_t fetch_pixel_64;
1056 store_scanline_t store_scanline_32;
1057 store_scanline_t store_scanline_64;
1060 #define FORMAT_INFO(format) \
1062 PIXMAN_ ## format, \
1063 fetch_scanline_ ## format, \
1064 fetch_scanline_generic_64, \
1065 fetch_pixel_ ## format, fetch_pixel_generic_64, \
1066 store_scanline_ ## format, store_scanline_generic_64 \
1069 static const format_info_t accessors[] =
1071 /* 32 bpp formats */
1072 FORMAT_INFO (a8r8g8b8),
1073 FORMAT_INFO (x8r8g8b8),
1074 FORMAT_INFO (a8b8g8r8),
1075 FORMAT_INFO (x8b8g8r8),
1076 FORMAT_INFO (b8g8r8a8),
1077 FORMAT_INFO (b8g8r8x8),
1078 FORMAT_INFO (r8g8b8a8),
1079 FORMAT_INFO (r8g8b8x8),
1080 FORMAT_INFO (x14r6g6b6),
1083 FORMAT_INFO (r8g8b8),
1084 FORMAT_INFO (b8g8r8),
1087 FORMAT_INFO (r5g6b5),
1088 FORMAT_INFO (b5g6r5),
1090 FORMAT_INFO (a1r5g5b5),
1091 FORMAT_INFO (x1r5g5b5),
1092 FORMAT_INFO (a1b5g5r5),
1093 FORMAT_INFO (x1b5g5r5),
1094 FORMAT_INFO (a4r4g4b4),
1095 FORMAT_INFO (x4r4g4b4),
1096 FORMAT_INFO (a4b4g4r4),
1097 FORMAT_INFO (x4b4g4r4),
1101 FORMAT_INFO (r3g3b2),
1102 FORMAT_INFO (b2g3r3),
1103 FORMAT_INFO (a2r2g2b2),
1104 FORMAT_INFO (a2b2g2r2),
1110 #define fetch_scanline_x4c4 fetch_scanline_c8
1111 #define fetch_pixel_x4c4 fetch_pixel_c8
1112 #define store_scanline_x4c4 store_scanline_c8
1115 #define fetch_scanline_x4g4 fetch_scanline_g8
1116 #define fetch_pixel_x4g4 fetch_pixel_g8
1117 #define store_scanline_x4g4 store_scanline_g8
1124 FORMAT_INFO (r1g2b1),
1125 FORMAT_INFO (b1g2r1),
1126 FORMAT_INFO (a1r1g1b1),
1127 FORMAT_INFO (a1b1g1r1),
1139 { PIXMAN_a2r10g10b10,
1140 NULL, fetch_scanline_a2r10g10b10,
1141 fetch_pixel_generic_lossy_32, fetch_pixel_a2r10g10b10,
1142 NULL, store_scanline_a2r10g10b10 },
1144 { PIXMAN_x2r10g10b10,
1145 NULL, fetch_scanline_x2r10g10b10,
1146 fetch_pixel_generic_lossy_32, fetch_pixel_x2r10g10b10,
1147 NULL, store_scanline_x2r10g10b10 },
1149 { PIXMAN_a2b10g10r10,
1150 NULL, fetch_scanline_a2b10g10r10,
1151 fetch_pixel_generic_lossy_32, fetch_pixel_a2b10g10r10,
1152 NULL, store_scanline_a2b10g10r10 },
1154 { PIXMAN_x2b10g10r10,
1155 NULL, fetch_scanline_x2b10g10r10,
1156 fetch_pixel_generic_lossy_32, fetch_pixel_x2b10g10r10,
1157 NULL, store_scanline_x2b10g10r10 },
1161 fetch_scanline_yuy2, fetch_scanline_generic_64,
1162 fetch_pixel_yuy2, fetch_pixel_generic_64,
1166 fetch_scanline_yv12, fetch_scanline_generic_64,
1167 fetch_pixel_yv12, fetch_pixel_generic_64,
1174 setup_accessors (bits_image_t *image)
1176 const format_info_t *info = accessors;
1178 while (info->format != PIXMAN_null)
1180 if (info->format == image->format)
1182 image->fetch_scanline_32 = info->fetch_scanline_32;
1183 image->fetch_scanline_64 = info->fetch_scanline_64;
1184 image->fetch_pixel_32 = info->fetch_pixel_32;
1185 image->fetch_pixel_64 = info->fetch_pixel_64;
1186 image->store_scanline_32 = info->store_scanline_32;
1187 image->store_scanline_64 = info->store_scanline_64;
1196 #ifndef PIXMAN_FB_ACCESSORS
1198 _pixman_bits_image_setup_accessors_accessors (bits_image_t *image);
1201 _pixman_bits_image_setup_accessors (bits_image_t *image)
1203 if (image->read_func || image->write_func)
1204 _pixman_bits_image_setup_accessors_accessors (image);
1206 setup_accessors (image);
1212 _pixman_bits_image_setup_accessors_accessors (bits_image_t *image)
1214 setup_accessors (image);