Add packaging files for Tizen
[profile/ivi/pixman.git] / pixman / pixman-access.c
1 /*
2  *
3  * Copyright © 2000 Keith Packard, member of The XFree86 Project, Inc.
4  *             2005 Lars Knoll & Zack Rusin, Trolltech
5  *             2008 Aaron Plattner, NVIDIA Corporation
6  *
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.
16  *
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
24  * SOFTWARE.
25  */
26
27 #ifdef HAVE_CONFIG_H
28 #include <config.h>
29 #endif
30
31 #include <stdlib.h>
32 #include <string.h>
33 #include <assert.h>
34
35 #include "pixman-private.h"
36 #include "pixman-accessor.h"
37
38 #define CONVERT_RGB24_TO_Y15(s)                                         \
39     (((((s) >> 16) & 0xff) * 153 +                                      \
40       (((s) >>  8) & 0xff) * 301 +                                      \
41       (((s)      ) & 0xff) * 58) >> 2)
42
43 #define CONVERT_RGB24_TO_RGB15(s)                                       \
44     ((((s) >> 3) & 0x001f) |                                            \
45      (((s) >> 6) & 0x03e0) |                                            \
46      (((s) >> 9) & 0x7c00))
47
48 /* Fetch macros */
49
50 #ifdef WORDS_BIGENDIAN
51 #define FETCH_1(img,l,o)                                                \
52     (((READ ((img), ((uint32_t *)(l)) + ((o) >> 5))) >> (0x1f - ((o) & 0x1f))) & 0x1)
53 #else
54 #define FETCH_1(img,l,o)                                                \
55     ((((READ ((img), ((uint32_t *)(l)) + ((o) >> 5))) >> ((o) & 0x1f))) & 0x1)
56 #endif
57
58 #define FETCH_8(img,l,o)    (READ (img, (((uint8_t *)(l)) + ((o) >> 3))))
59
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))
63 #else
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))
66 #endif
67
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))
73 #else
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))
78 #endif
79
80 /* Store macros */
81
82 #ifdef WORDS_BIGENDIAN
83 #define STORE_1(img,l,o,v)                                              \
84     do                                                                  \
85     {                                                                   \
86         uint32_t  *__d = ((uint32_t *)(l)) + ((o) >> 5);                \
87         uint32_t __m, __v;                                              \
88                                                                         \
89         __m = 1 << (0x1f - ((o) & 0x1f));                               \
90         __v = (v)? __m : 0;                                             \
91                                                                         \
92         WRITE((img), __d, (READ((img), __d) & ~__m) | __v);             \
93     }                                                                   \
94     while (0)
95 #else
96 #define STORE_1(img,l,o,v)                                              \
97     do                                                                  \
98     {                                                                   \
99         uint32_t  *__d = ((uint32_t *)(l)) + ((o) >> 5);                \
100         uint32_t __m, __v;                                              \
101                                                                         \
102         __m = 1 << ((o) & 0x1f);                                        \
103         __v = (v)? __m : 0;                                             \
104                                                                         \
105         WRITE((img), __d, (READ((img), __d) & ~__m) | __v);             \
106     }                                                                   \
107     while (0)
108 #endif
109
110 #define STORE_8(img,l,o,v)  (WRITE (img, (uint8_t *)(l) + ((o) >> 3), (v)))
111
112 #ifdef WORDS_BIGENDIAN
113 #define STORE_4(img,l,o,v)                                              \
114     do                                                                  \
115     {                                                                   \
116         int bo = 4 * (o);                                               \
117         int v4 = (v) & 0x0f;                                            \
118                                                                         \
119         STORE_8 (img, l, bo, (                                          \
120                      bo & 4 ?                                           \
121                      (FETCH_8 (img, l, bo) & 0xf0) | (v4) :             \
122                      (FETCH_8 (img, l, bo) & 0x0f) | (v4 << 4)));       \
123     } while (0)
124 #else
125 #define STORE_4(img,l,o,v)                                              \
126     do                                                                  \
127     {                                                                   \
128         int bo = 4 * (o);                                               \
129         int v4 = (v) & 0x0f;                                            \
130                                                                         \
131         STORE_8 (img, l, bo, (                                          \
132                      bo & 4 ?                                           \
133                      (FETCH_8 (img, l, bo) & 0x0f) | (v4 << 4) :        \
134                      (FETCH_8 (img, l, bo) & 0xf0) | (v4)));            \
135     } while (0)
136 #endif
137
138 #ifdef WORDS_BIGENDIAN
139 #define STORE_24(img,l,o,v)                                            \
140     do                                                                 \
141     {                                                                  \
142         uint8_t *__tmp = (l) + 3 * (o);                                \
143                                                                        \
144         WRITE ((img), __tmp++, ((v) & 0x00ff0000) >> 16);              \
145         WRITE ((img), __tmp++, ((v) & 0x0000ff00) >>  8);              \
146         WRITE ((img), __tmp++, ((v) & 0x000000ff) >>  0);              \
147     }                                                                  \
148     while (0)
149 #else
150 #define STORE_24(img,l,o,v)                                            \
151     do                                                                 \
152     {                                                                  \
153         uint8_t *__tmp = (l) + 3 * (o);                                \
154                                                                        \
155         WRITE ((img), __tmp++, ((v) & 0x000000ff) >>  0);              \
156         WRITE ((img), __tmp++, ((v) & 0x0000ff00) >>  8);              \
157         WRITE ((img), __tmp++, ((v) & 0x00ff0000) >> 16);              \
158     }                                                                  \
159     while (0)
160 #endif
161
162 /*
163  * YV12 setup and access macros
164  */
165
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)
176
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.
181  */
182
183 #define YV12_Y(line)                                                    \
184     ((uint8_t *) ((bits) + (stride) * (line)))
185
186 #define YV12_U(line)                                                    \
187     ((uint8_t *) ((bits) + offset1 +                                    \
188                   ((stride) >> 1) * ((line) >> 1)))
189
190 #define YV12_V(line)                                                    \
191     ((uint8_t *) ((bits) + offset0 +                                    \
192                   ((stride) >> 1) * ((line) >> 1)))
193
194 /* Misc. helpers */
195
196 static force_inline void
197 get_shifts (pixman_format_code_t  format,
198             int                  *a,
199             int                  *r,
200             int                  *g,
201             int                  *b)
202 {
203     switch (PIXMAN_FORMAT_TYPE (format))
204     {
205     case PIXMAN_TYPE_A:
206         *b = 0;
207         *g = 0;
208         *r = 0;
209         *a = 0;
210         break;
211
212     case PIXMAN_TYPE_ARGB:
213         *b = 0;
214         *g = *b + PIXMAN_FORMAT_B (format);
215         *r = *g + PIXMAN_FORMAT_G (format);
216         *a = *r + PIXMAN_FORMAT_R (format);
217         break;
218
219     case PIXMAN_TYPE_ABGR:
220         *r = 0;
221         *g = *r + PIXMAN_FORMAT_R (format);
222         *b = *g + PIXMAN_FORMAT_G (format);
223         *a = *b + PIXMAN_FORMAT_B (format);
224         break;
225
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);
232         break;
233
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);
240         break;
241
242     default:
243         assert (0);
244         break;
245     }
246 }
247
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)
252 {
253     uint32_t v;
254
255     if (n_from_bits && n_to_bits)
256         v  = unorm_to_unorm (pixel >> from_shift, n_from_bits, n_to_bits);
257     else if (n_to_bits)
258         v = def_value;
259     else
260         v = 0;
261
262     return (v & ((1 << n_to_bits) - 1)) << to_shift;
263 }
264
265 static force_inline uint32_t
266 convert_pixel (pixman_format_code_t from, pixman_format_code_t to, uint32_t pixel)
267 {
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;
270     uint32_t a, r, g, b;
271
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);
274
275     a = convert_channel (pixel, ~0,
276                          PIXMAN_FORMAT_A (from), a_from_shift,
277                          PIXMAN_FORMAT_A (to), a_to_shift);
278
279     r = convert_channel (pixel, 0,
280                          PIXMAN_FORMAT_R (from), r_from_shift,
281                          PIXMAN_FORMAT_R (to), r_to_shift);
282
283     g = convert_channel (pixel, 0,
284                          PIXMAN_FORMAT_G (from), g_from_shift,
285                          PIXMAN_FORMAT_G (to), g_to_shift);
286
287     b = convert_channel (pixel, 0,
288                          PIXMAN_FORMAT_B (from), b_from_shift,
289                          PIXMAN_FORMAT_B (to), b_to_shift);
290
291     return a | r | g | b;
292 }
293
294 static force_inline uint32_t
295 convert_pixel_to_a8r8g8b8 (pixman_image_t *image,
296                            pixman_format_code_t format,
297                            uint32_t pixel)
298 {
299     if (PIXMAN_FORMAT_TYPE (format) == PIXMAN_TYPE_GRAY         ||
300         PIXMAN_FORMAT_TYPE (format) == PIXMAN_TYPE_COLOR)
301     {
302         return image->bits.indexed->rgba[pixel];
303     }
304     else
305     {
306         return convert_pixel (format, PIXMAN_a8r8g8b8, pixel);
307     }
308 }
309
310 static force_inline uint32_t
311 convert_pixel_from_a8r8g8b8 (pixman_image_t *image,
312                              pixman_format_code_t format, uint32_t pixel)
313 {
314     if (PIXMAN_FORMAT_TYPE (format) == PIXMAN_TYPE_GRAY)
315     {
316         pixel = CONVERT_RGB24_TO_Y15 (pixel);
317
318         return image->bits.indexed->ent[pixel & 0x7fff];
319     }
320     else if (PIXMAN_FORMAT_TYPE (format) == PIXMAN_TYPE_COLOR)
321     {
322         pixel = convert_pixel (PIXMAN_a8r8g8b8, PIXMAN_x1r5g5b5, pixel);
323
324         return image->bits.indexed->ent[pixel & 0x7fff];
325     }
326     else
327     {
328         return convert_pixel (PIXMAN_a8r8g8b8, format, pixel);
329     }
330 }
331
332 static force_inline uint32_t
333 fetch_and_convert_pixel (pixman_image_t *       image,
334                          const uint8_t *        bits,
335                          int                    offset,
336                          pixman_format_code_t   format)
337 {
338     uint32_t pixel;
339
340     switch (PIXMAN_FORMAT_BPP (format))
341     {
342     case 1:
343         pixel = FETCH_1 (image, bits, offset);
344         break;
345
346     case 4:
347         pixel = FETCH_4 (image, bits, offset);
348         break;
349
350     case 8:
351         pixel = READ (image, bits + offset);
352         break;
353
354     case 16:
355         pixel = READ (image, ((uint16_t *)bits + offset));
356         break;
357
358     case 24:
359         pixel = FETCH_24 (image, bits, offset);
360         break;
361
362     case 32:
363         pixel = READ (image, ((uint32_t *)bits + offset));
364         break;
365
366     default:
367         pixel = 0xffff00ff; /* As ugly as possible to detect the bug */
368         break;
369     }
370
371     return convert_pixel_to_a8r8g8b8 (image, format, pixel);
372 }
373
374 static force_inline void
375 convert_and_store_pixel (bits_image_t *         image,
376                          uint8_t *              dest,
377                          int                    offset,
378                          pixman_format_code_t   format,
379                          uint32_t               pixel)
380 {
381     uint32_t converted = convert_pixel_from_a8r8g8b8 (
382         (pixman_image_t *)image, format, pixel);
383
384     switch (PIXMAN_FORMAT_BPP (format))
385     {
386     case 1:
387         STORE_1 (image, dest, offset, converted & 0x01);
388         break;
389
390     case 4:
391         STORE_4 (image, dest, offset, converted & 0xf);
392         break;
393
394     case 8:
395         WRITE (image, (dest + offset), converted & 0xff);
396         break;
397
398     case 16:
399         WRITE (image, ((uint16_t *)dest + offset), converted & 0xffff);
400         break;
401
402     case 24:
403         STORE_24 (image, dest, offset, converted);
404         break;
405
406     case 32:
407         WRITE (image, ((uint32_t *)dest + offset), converted);
408         break;
409
410     default:
411         *dest = 0x0;
412         break;
413     }
414 }
415
416 #define MAKE_ACCESSORS(format)                                          \
417     static void                                                         \
418     fetch_scanline_ ## format (pixman_image_t *image,                   \
419                                int             x,                       \
420                                int             y,                       \
421                                int             width,                   \
422                                uint32_t *      buffer,                  \
423                                const uint32_t *mask)                    \
424     {                                                                   \
425         uint8_t *bits =                                                 \
426             (uint8_t *)(image->bits.bits + y * image->bits.rowstride);  \
427         int i;                                                          \
428                                                                         \
429         for (i = 0; i < width; ++i)                                     \
430         {                                                               \
431             *buffer++ =                                                 \
432                 fetch_and_convert_pixel (image, bits, x + i, PIXMAN_ ## format); \
433         }                                                               \
434     }                                                                   \
435                                                                         \
436     static void                                                         \
437     store_scanline_ ## format (bits_image_t *  image,                   \
438                                int             x,                       \
439                                int             y,                       \
440                                int             width,                   \
441                                const uint32_t *values)                  \
442     {                                                                   \
443         uint8_t *dest =                                                 \
444             (uint8_t *)(image->bits + y * image->rowstride);            \
445         int i;                                                          \
446                                                                         \
447         for (i = 0; i < width; ++i)                                     \
448         {                                                               \
449             convert_and_store_pixel (                                   \
450                 image, dest, i + x, PIXMAN_ ## format, values[i]);      \
451         }                                                               \
452     }                                                                   \
453                                                                         \
454     static uint32_t                                                     \
455     fetch_pixel_ ## format (bits_image_t *image,                        \
456                             int         offset,                         \
457                             int         line)                           \
458     {                                                                   \
459         uint8_t *bits =                                                 \
460             (uint8_t *)(image->bits + line * image->rowstride);         \
461                                                                         \
462         return fetch_and_convert_pixel ((pixman_image_t *)image,        \
463                                         bits, offset, PIXMAN_ ## format); \
464     }                                                                   \
465                                                                         \
466     static const void *const __dummy__ ## format
467
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);
489 MAKE_ACCESSORS(a8);
490 MAKE_ACCESSORS(c8);
491 MAKE_ACCESSORS(g8);
492 MAKE_ACCESSORS(r3g3b2);
493 MAKE_ACCESSORS(b2g3r3);
494 MAKE_ACCESSORS(a2r2g2b2);
495 MAKE_ACCESSORS(a2b2g2r2);
496 MAKE_ACCESSORS(x4a4);
497 MAKE_ACCESSORS(a4);
498 MAKE_ACCESSORS(g4);
499 MAKE_ACCESSORS(c4);
500 MAKE_ACCESSORS(r1g2b1);
501 MAKE_ACCESSORS(b1g2r1);
502 MAKE_ACCESSORS(a1r1g1b1);
503 MAKE_ACCESSORS(a1b1g1r1);
504 MAKE_ACCESSORS(a1);
505 MAKE_ACCESSORS(g1);
506
507 /********************************** Fetch ************************************/
508
509 /* Expects a uint64_t buffer */
510 static void
511 fetch_scanline_a2r10g10b10 (pixman_image_t *image,
512                             int             x,
513                             int             y,
514                             int             width,
515                             uint32_t *      b,
516                             const uint32_t *mask)
517 {
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;
522
523     while (pixel < end)
524     {
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;
530
531         r = r << 6 | r >> 4;
532         g = g << 6 | g >> 4;
533         b = b << 6 | b >> 4;
534
535         a <<= 14;
536         a |= a >> 2;
537         a |= a >> 4;
538         a |= a >> 8;
539
540         *buffer++ = a << 48 | r << 32 | g << 16 | b;
541     }
542 }
543
544 /* Expects a uint64_t buffer */
545 static void
546 fetch_scanline_x2r10g10b10 (pixman_image_t *image,
547                             int             x,
548                             int             y,
549                             int             width,
550                             uint32_t *      b,
551                             const uint32_t *mask)
552 {
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;
557     
558     while (pixel < end)
559     {
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;
564         
565         r = r << 6 | r >> 4;
566         g = g << 6 | g >> 4;
567         b = b << 6 | b >> 4;
568         
569         *buffer++ = 0xffffULL << 48 | r << 32 | g << 16 | b;
570     }
571 }
572
573 /* Expects a uint64_t buffer */
574 static void
575 fetch_scanline_a2b10g10r10 (pixman_image_t *image,
576                             int             x,
577                             int             y,
578                             int             width,
579                             uint32_t *      b,
580                             const uint32_t *mask)
581 {
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;
586     
587     while (pixel < end)
588     {
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;
594         
595         r = r << 6 | r >> 4;
596         g = g << 6 | g >> 4;
597         b = b << 6 | b >> 4;
598         
599         a <<= 14;
600         a |= a >> 2;
601         a |= a >> 4;
602         a |= a >> 8;
603
604         *buffer++ = a << 48 | r << 32 | g << 16 | b;
605     }
606 }
607
608 /* Expects a uint64_t buffer */
609 static void
610 fetch_scanline_x2b10g10r10 (pixman_image_t *image,
611                             int             x,
612                             int             y,
613                             int             width,
614                             uint32_t *      b,
615                             const uint32_t *mask)
616 {
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;
621     
622     while (pixel < end)
623     {
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;
628         
629         r = r << 6 | r >> 4;
630         g = g << 6 | g >> 4;
631         b = b << 6 | b >> 4;
632         
633         *buffer++ = 0xffffULL << 48 | r << 32 | g << 16 | b;
634     }
635 }
636
637 static void
638 fetch_scanline_yuy2 (pixman_image_t *image,
639                      int             x,
640                      int             line,
641                      int             width,
642                      uint32_t *      buffer,
643                      const uint32_t *mask)
644 {
645     const uint32_t *bits = image->bits.bits + image->bits.rowstride * line;
646     int i;
647     
648     for (i = 0; i < width; i++)
649     {
650         int16_t y, u, v;
651         int32_t r, g, b;
652         
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;
656         
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;
663         
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);
668     }
669 }
670
671 static void
672 fetch_scanline_yv12 (pixman_image_t *image,
673                      int             x,
674                      int             line,
675                      int             width,
676                      uint32_t *      buffer,
677                      const uint32_t *mask)
678 {
679     YV12_SETUP (image);
680     uint8_t *y_line = YV12_Y (line);
681     uint8_t *u_line = YV12_U (line);
682     uint8_t *v_line = YV12_V (line);
683     int i;
684     
685     for (i = 0; i < width; i++)
686     {
687         int16_t y, u, v;
688         int32_t r, g, b;
689
690         y = y_line[x + i] - 16;
691         u = u_line[(x + i) >> 1] - 128;
692         v = v_line[(x + i) >> 1] - 128;
693
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;
700
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);
705     }
706 }
707
708 /**************************** Pixel wise fetching *****************************/
709
710 /* Despite the type, expects a uint64_t buffer */
711 static uint64_t
712 fetch_pixel_a2r10g10b10 (bits_image_t *image,
713                          int              offset,
714                          int           line)
715 {
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;
722
723     r = r << 6 | r >> 4;
724     g = g << 6 | g >> 4;
725     b = b << 6 | b >> 4;
726
727     a <<= 14;
728     a |= a >> 2;
729     a |= a >> 4;
730     a |= a >> 8;
731
732     return a << 48 | r << 32 | g << 16 | b;
733 }
734
735 /* Despite the type, this function expects a uint64_t buffer */
736 static uint64_t
737 fetch_pixel_x2r10g10b10 (bits_image_t *image,
738                          int       offset,
739                          int           line)
740 {
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;
746     
747     r = r << 6 | r >> 4;
748     g = g << 6 | g >> 4;
749     b = b << 6 | b >> 4;
750     
751     return 0xffffULL << 48 | r << 32 | g << 16 | b;
752 }
753
754 /* Despite the type, expects a uint64_t buffer */
755 static uint64_t
756 fetch_pixel_a2b10g10r10 (bits_image_t *image,
757                          int           offset,
758                          int           line)
759 {
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;
766     
767     r = r << 6 | r >> 4;
768     g = g << 6 | g >> 4;
769     b = b << 6 | b >> 4;
770     
771     a <<= 14;
772     a |= a >> 2;
773     a |= a >> 4;
774     a |= a >> 8;
775     
776     return a << 48 | r << 32 | g << 16 | b;
777 }
778
779 /* Despite the type, this function expects a uint64_t buffer */
780 static uint64_t
781 fetch_pixel_x2b10g10r10 (bits_image_t *image,
782                          int           offset,
783                          int           line)
784 {
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;
790     
791     r = r << 6 | r >> 4;
792     g = g << 6 | g >> 4;
793     b = b << 6 | b >> 4;
794     
795     return 0xffffULL << 48 | r << 32 | g << 16 | b;
796 }
797
798 static uint32_t
799 fetch_pixel_yuy2 (bits_image_t *image,
800                   int           offset,
801                   int           line)
802 {
803     const uint32_t *bits = image->bits + image->rowstride * line;
804     
805     int16_t y, u, v;
806     int32_t r, g, b;
807     
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;
811     
812     /* R = 1.164(Y - 16) + 1.596(V - 128) */
813     r = 0x012b27 * y + 0x019a2e * v;
814     
815     /* G = 1.164(Y - 16) - 0.813(V - 128) - 0.391(U - 128) */
816     g = 0x012b27 * y - 0x00d0f2 * v - 0x00647e * u;
817     
818     /* B = 1.164(Y - 16) + 2.018(U - 128) */
819     b = 0x012b27 * y + 0x0206a2 * u;
820     
821     return 0xff000000 |
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);
825 }
826
827 static uint32_t
828 fetch_pixel_yv12 (bits_image_t *image,
829                   int           offset,
830                   int           line)
831 {
832     YV12_SETUP (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;
836     int32_t r, g, b;
837     
838     /* R = 1.164(Y - 16) + 1.596(V - 128) */
839     r = 0x012b27 * y + 0x019a2e * v;
840     
841     /* G = 1.164(Y - 16) - 0.813(V - 128) - 0.391(U - 128) */
842     g = 0x012b27 * y - 0x00d0f2 * v - 0x00647e * u;
843     
844     /* B = 1.164(Y - 16) + 2.018(U - 128) */
845     b = 0x012b27 * y + 0x0206a2 * u;
846     
847     return 0xff000000 |
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);
851 }
852
853 /*********************************** Store ************************************/
854
855 static void
856 store_scanline_a2r10g10b10 (bits_image_t *  image,
857                             int             x,
858                             int             y,
859                             int             width,
860                             const uint32_t *v)
861 {
862     uint32_t *bits = image->bits + image->rowstride * y;
863     uint32_t *pixel = bits + x;
864     uint64_t *values = (uint64_t *)v;
865     int i;
866     
867     for (i = 0; i < width; ++i)
868     {
869         WRITE (image, pixel++,
870                ((values[i] >> 32) & 0xc0000000) |
871                ((values[i] >> 18) & 0x3ff00000) |
872                ((values[i] >> 12) & 0xffc00) | 
873                ((values[i] >> 6) & 0x3ff));    
874     }
875 }
876
877 static void
878 store_scanline_x2r10g10b10 (bits_image_t *  image,
879                             int             x,
880                             int             y,
881                             int             width,
882                             const uint32_t *v)
883 {
884     uint32_t *bits = image->bits + image->rowstride * y;
885     uint64_t *values = (uint64_t *)v;
886     uint32_t *pixel = bits + x;
887     int i;
888     
889     for (i = 0; i < width; ++i)
890     {
891         WRITE (image, pixel++,
892                ((values[i] >> 18) & 0x3ff00000) | 
893                ((values[i] >> 12) & 0xffc00) |
894                ((values[i] >> 6) & 0x3ff));
895     }
896 }
897
898 static void
899 store_scanline_a2b10g10r10 (bits_image_t *  image,
900                             int             x,
901                             int             y,
902                             int             width,
903                             const uint32_t *v)
904 {
905     uint32_t *bits = image->bits + image->rowstride * y;
906     uint32_t *pixel = bits + x;
907     uint64_t *values = (uint64_t *)v;
908     int i;
909     
910     for (i = 0; i < width; ++i)
911     {
912         WRITE (image, pixel++,
913                ((values[i] >> 32) & 0xc0000000) |
914                ((values[i] >> 38) & 0x3ff) |
915                ((values[i] >> 12) & 0xffc00) |
916                ((values[i] << 14) & 0x3ff00000));
917     }
918 }
919
920 static void
921 store_scanline_x2b10g10r10 (bits_image_t *  image,
922                             int             x,
923                             int             y,
924                             int             width,
925                             const uint32_t *v)
926 {
927     uint32_t *bits = image->bits + image->rowstride * y;
928     uint64_t *values = (uint64_t *)v;
929     uint32_t *pixel = bits + x;
930     int i;
931     
932     for (i = 0; i < width; ++i)
933     {
934         WRITE (image, pixel++,
935                ((values[i] >> 38) & 0x3ff) |
936                ((values[i] >> 12) & 0xffc00) |
937                ((values[i] << 14) & 0x3ff00000));
938     }
939 }
940
941 /*
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.
944  */
945 static void
946 store_scanline_generic_64 (bits_image_t *  image,
947                            int             x,
948                            int             y,
949                            int             width,
950                            const uint32_t *values)
951 {
952     uint32_t *argb8_pixels;
953     
954     assert (image->common.type == BITS);
955     
956     argb8_pixels = pixman_malloc_ab (width, sizeof(uint32_t));
957     if (!argb8_pixels)
958         return;
959     
960     /* Contract the scanline.  We could do this in place if values weren't
961      * const.
962      */
963     pixman_contract (argb8_pixels, (uint64_t *)values, width);
964     
965     image->store_scanline_32 (image, x, y, width, argb8_pixels);
966     
967     free (argb8_pixels);
968 }
969
970 /* Despite the type, this function expects both buffer
971  * and mask to be uint64_t
972  */
973 static void
974 fetch_scanline_generic_64 (pixman_image_t *image,
975                            int             x,
976                            int             y,
977                            int             width,
978                            uint32_t *      buffer,
979                            const uint32_t *mask)
980 {
981     pixman_format_code_t format;
982
983     /* Fetch the pixels into the first half of buffer and then expand them in
984      * place.
985      */
986     image->bits.fetch_scanline_32 (image, x, y, width, buffer, NULL);
987
988     format = image->bits.format;
989     if (PIXMAN_FORMAT_TYPE (format) == PIXMAN_TYPE_COLOR        ||
990         PIXMAN_FORMAT_TYPE (format) == PIXMAN_TYPE_GRAY)
991     {
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
995          */
996
997         format = PIXMAN_a8r8g8b8;
998     }
999
1000     pixman_expand ((uint64_t *)buffer, buffer, format, width);
1001 }
1002
1003 /* Despite the type, this function expects a uint64_t *buffer */
1004 static uint64_t
1005 fetch_pixel_generic_64 (bits_image_t *image,
1006                         int           offset,
1007                         int           line)
1008 {
1009     uint32_t pixel32 = image->fetch_pixel_32 (image, offset, line);
1010     uint64_t result;
1011     pixman_format_code_t format;
1012
1013     format = image->format;
1014     if (PIXMAN_FORMAT_TYPE (format) == PIXMAN_TYPE_COLOR        ||
1015         PIXMAN_FORMAT_TYPE (format) == PIXMAN_TYPE_GRAY)
1016     {
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
1020          */
1021
1022         format = PIXMAN_a8r8g8b8;
1023     }
1024
1025     pixman_expand ((uint64_t *)&result, &pixel32, format, 1);
1026
1027     return result;
1028 }
1029
1030 /*
1031  * XXX: The transformed fetch path only works at 32-bpp so far.  When all
1032  * paths have wide versions, this can be removed.
1033  *
1034  * WARNING: This function loses precision!
1035  */
1036 static uint32_t
1037 fetch_pixel_generic_lossy_32 (bits_image_t *image,
1038                               int           offset,
1039                               int           line)
1040 {
1041     uint64_t pixel64 = image->fetch_pixel_64 (image, offset, line);
1042     uint32_t result;
1043
1044     pixman_contract (&result, &pixel64, 1);
1045
1046     return result;
1047 }
1048
1049 typedef struct
1050 {
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;
1058 } format_info_t;
1059
1060 #define FORMAT_INFO(format)                                             \
1061     {                                                                   \
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        \
1067     }
1068
1069 static const format_info_t accessors[] =
1070 {
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),
1081
1082 /* 24bpp formats */
1083     FORMAT_INFO (r8g8b8),
1084     FORMAT_INFO (b8g8r8),
1085     
1086 /* 16bpp formats */
1087     FORMAT_INFO (r5g6b5),
1088     FORMAT_INFO (b5g6r5),
1089     
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),
1098     
1099 /* 8bpp formats */
1100     FORMAT_INFO (a8),
1101     FORMAT_INFO (r3g3b2),
1102     FORMAT_INFO (b2g3r3),
1103     FORMAT_INFO (a2r2g2b2),
1104     FORMAT_INFO (a2b2g2r2),
1105     
1106     FORMAT_INFO (c8),
1107     
1108     FORMAT_INFO (g8),
1109     
1110 #define fetch_scanline_x4c4 fetch_scanline_c8
1111 #define fetch_pixel_x4c4 fetch_pixel_c8
1112 #define store_scanline_x4c4 store_scanline_c8
1113     FORMAT_INFO (x4c4),
1114     
1115 #define fetch_scanline_x4g4 fetch_scanline_g8
1116 #define fetch_pixel_x4g4 fetch_pixel_g8
1117 #define store_scanline_x4g4 store_scanline_g8
1118     FORMAT_INFO (x4g4),
1119     
1120     FORMAT_INFO (x4a4),
1121     
1122 /* 4bpp formats */
1123     FORMAT_INFO (a4),
1124     FORMAT_INFO (r1g2b1),
1125     FORMAT_INFO (b1g2r1),
1126     FORMAT_INFO (a1r1g1b1),
1127     FORMAT_INFO (a1b1g1r1),
1128     
1129     FORMAT_INFO (c4),
1130     
1131     FORMAT_INFO (g4),
1132     
1133 /* 1bpp formats */
1134     FORMAT_INFO (a1),
1135     FORMAT_INFO (g1),
1136     
1137 /* Wide formats */
1138     
1139     { PIXMAN_a2r10g10b10,
1140       NULL, fetch_scanline_a2r10g10b10,
1141       fetch_pixel_generic_lossy_32, fetch_pixel_a2r10g10b10,
1142       NULL, store_scanline_a2r10g10b10 },
1143     
1144     { PIXMAN_x2r10g10b10,
1145       NULL, fetch_scanline_x2r10g10b10,
1146       fetch_pixel_generic_lossy_32, fetch_pixel_x2r10g10b10,
1147       NULL, store_scanline_x2r10g10b10 },
1148     
1149     { PIXMAN_a2b10g10r10,
1150       NULL, fetch_scanline_a2b10g10r10,
1151       fetch_pixel_generic_lossy_32, fetch_pixel_a2b10g10r10,
1152       NULL, store_scanline_a2b10g10r10 },
1153     
1154     { PIXMAN_x2b10g10r10,
1155       NULL, fetch_scanline_x2b10g10r10,
1156       fetch_pixel_generic_lossy_32, fetch_pixel_x2b10g10r10,
1157       NULL, store_scanline_x2b10g10r10 },
1158     
1159 /* YUV formats */
1160     { PIXMAN_yuy2,
1161       fetch_scanline_yuy2, fetch_scanline_generic_64,
1162       fetch_pixel_yuy2, fetch_pixel_generic_64,
1163       NULL, NULL },
1164     
1165     { PIXMAN_yv12,
1166       fetch_scanline_yv12, fetch_scanline_generic_64,
1167       fetch_pixel_yv12, fetch_pixel_generic_64,
1168       NULL, NULL },
1169     
1170     { PIXMAN_null },
1171 };
1172
1173 static void
1174 setup_accessors (bits_image_t *image)
1175 {
1176     const format_info_t *info = accessors;
1177     
1178     while (info->format != PIXMAN_null)
1179     {
1180         if (info->format == image->format)
1181         {
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;
1188             
1189             return;
1190         }
1191         
1192         info++;
1193     }
1194 }
1195
1196 #ifndef PIXMAN_FB_ACCESSORS
1197 void
1198 _pixman_bits_image_setup_accessors_accessors (bits_image_t *image);
1199
1200 void
1201 _pixman_bits_image_setup_accessors (bits_image_t *image)
1202 {
1203     if (image->read_func || image->write_func)
1204         _pixman_bits_image_setup_accessors_accessors (image);
1205     else
1206         setup_accessors (image);
1207 }
1208
1209 #else
1210
1211 void
1212 _pixman_bits_image_setup_accessors_accessors (bits_image_t *image)
1213 {
1214     setup_accessors (image);
1215 }
1216
1217 #endif