Use MAKE_ACCESSORS() to generate accessors for the a1 format.
[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 #define RGB15_TO_ENTRY(mif,rgb15)                                       \
49     ((mif)->ent[rgb15])
50
51 #define RGB24_TO_ENTRY(mif,rgb24)                                       \
52     RGB15_TO_ENTRY (mif,CONVERT_RGB24_TO_RGB15 (rgb24))
53
54 #define RGB24_TO_ENTRY_Y(mif,rgb24)                                     \
55     ((mif)->ent[CONVERT_RGB24_TO_Y15 (rgb24)])
56
57 /* Fetch macros */
58
59 #ifdef WORDS_BIGENDIAN
60 #define FETCH_1(img,l,o)                                                \
61     (((READ ((img), ((uint32_t *)(l)) + ((o) >> 5))) >> (0x1f - ((o) & 0x1f))) & 0x1)
62 #else
63 #define FETCH_1(img,l,o)                                                \
64     ((((READ ((img), ((uint32_t *)(l)) + ((o) >> 5))) >> ((o) & 0x1f))) & 0x1)
65 #endif
66
67 #define FETCH_8(img,l,o)    (READ (img, (((uint8_t *)(l)) + ((o) >> 3))))
68
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))
72 #else
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))
75 #endif
76
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))
82 #else
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))
87 #endif
88
89 /* Store macros */
90
91 #ifdef WORDS_BIGENDIAN
92 #define STORE_1(img,l,o,v)                                              \
93     do                                                                  \
94     {                                                                   \
95         uint32_t  *__d = ((uint32_t *)(l)) + ((o) >> 5);                \
96         uint32_t __m, __v;                                              \
97                                                                         \
98         __m = 1 << (0x1f - ((o) & 0x1f));                               \
99         __v = (v)? __m : 0;                                             \
100                                                                         \
101         WRITE((img), __d, (READ((img), __d) & ~__m) | __v);             \
102     }                                                                   \
103     while (0)
104 #else
105 #define STORE_1(img,l,o,v)                                              \
106     do                                                                  \
107     {                                                                   \
108         uint32_t  *__d = ((uint32_t *)(l)) + ((o) >> 5);                \
109         uint32_t __m, __v;                                              \
110                                                                         \
111         __m = 1 << ((o) & 0x1f);                                        \
112         __v = (v)? __m : 0;                                             \
113                                                                         \
114         WRITE((img), __d, (READ((img), __d) & ~__m) | __v);             \
115     }                                                                   \
116     while (0)
117 #endif
118
119 #define STORE_8(img,l,o,v)  (WRITE (img, (uint8_t *)(l) + ((o) >> 3), (v)))
120
121 #ifdef WORDS_BIGENDIAN
122 #define STORE_4(img,l,o,v)                                              \
123     do                                                                  \
124     {                                                                   \
125         int bo = 4 * (o);                                               \
126         int v4 = (v) & 0x0f;                                            \
127                                                                         \
128         STORE_8 (img, l, bo, (                                          \
129                      bo & 4 ?                                           \
130                      (FETCH_8 (img, l, bo) & 0xf0) | (v4) :             \
131                      (FETCH_8 (img, l, bo) & 0x0f) | (v4 << 4)));       \
132     } while (0)
133 #else
134 #define STORE_4(img,l,o,v)                                              \
135     do                                                                  \
136     {                                                                   \
137         int bo = 4 * (o);                                               \
138         int v4 = (v) & 0x0f;                                            \
139                                                                         \
140         STORE_8 (img, l, bo, (                                          \
141                      bo & 4 ?                                           \
142                      (FETCH_8 (img, l, bo) & 0x0f) | (v4 << 4) :        \
143                      (FETCH_8 (img, l, bo) & 0xf0) | (v4)));            \
144     } while (0)
145 #endif
146
147 #ifdef WORDS_BIGENDIAN
148 #define STORE_24(img,l,o,v)                                            \
149     do                                                                 \
150     {                                                                  \
151         uint8_t *__tmp = (l) + 3 * (o);                                \
152                                                                        \
153         WRITE ((img), __tmp++, ((v) & 0x00ff0000) >> 16);              \
154         WRITE ((img), __tmp++, ((v) & 0x0000ff00) >>  8);              \
155         WRITE ((img), __tmp++, ((v) & 0x000000ff) >>  0);              \
156     }                                                                  \
157     while (0)
158 #else
159 #define STORE_24(img,l,o,v)                                            \
160     do                                                                 \
161     {                                                                  \
162         uint8_t *__tmp = (l) + 3 * (o);                                \
163                                                                        \
164         WRITE ((img), __tmp++, ((v) & 0x000000ff) >>  0);              \
165         WRITE ((img), __tmp++, ((v) & 0x0000ff00) >>  8);              \
166         WRITE ((img), __tmp++, ((v) & 0x00ff0000) >> 16);              \
167     }                                                                  \
168     while (0)
169 #endif
170
171 /*
172  * YV12 setup and access macros
173  */
174
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)
185
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.
190  */
191
192 #define YV12_Y(line)                                                    \
193     ((uint8_t *) ((bits) + (stride) * (line)))
194
195 #define YV12_U(line)                                                    \
196     ((uint8_t *) ((bits) + offset1 +                                    \
197                   ((stride) >> 1) * ((line) >> 1)))
198
199 #define YV12_V(line)                                                    \
200     ((uint8_t *) ((bits) + offset0 +                                    \
201                   ((stride) >> 1) * ((line) >> 1)))
202
203 /* Misc. helpers */
204
205 static force_inline void
206 get_shifts (pixman_format_code_t  format,
207             int                  *a,
208             int                  *r,
209             int                  *g,
210             int                  *b)
211 {
212     switch (PIXMAN_FORMAT_TYPE (format))
213     {
214     case PIXMAN_TYPE_A:
215         *b = 0;
216         *g = 0;
217         *r = 0;
218         *a = 0;
219         break;
220
221     case PIXMAN_TYPE_ARGB:
222         *b = 0;
223         *g = *b + PIXMAN_FORMAT_B (format);
224         *r = *g + PIXMAN_FORMAT_G (format);
225         *a = *r + PIXMAN_FORMAT_R (format);
226         break;
227
228     case PIXMAN_TYPE_ABGR:
229         *r = 0;
230         *g = *r + PIXMAN_FORMAT_R (format);
231         *b = *g + PIXMAN_FORMAT_G (format);
232         *a = *b + PIXMAN_FORMAT_B (format);
233         break;
234
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);
241         break;
242
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);
249         break;
250
251     default:
252         assert (0);
253         break;
254     }
255 }
256
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)
261 {
262     uint32_t v;
263
264     if (n_from_bits && n_to_bits)
265         v  = unorm_to_unorm (pixel >> from_shift, n_from_bits, n_to_bits);
266     else if (n_to_bits)
267         v = def_value;
268     else
269         v = 0;
270
271     return (v & ((1 << n_to_bits) - 1)) << to_shift;
272 }
273
274 static force_inline uint32_t
275 convert_pixel (pixman_format_code_t from, pixman_format_code_t to, uint32_t pixel)
276 {
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;
279     uint32_t a, r, g, b;
280
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);
283
284     a = convert_channel (pixel, ~0,
285                          PIXMAN_FORMAT_A (from), a_from_shift,
286                          PIXMAN_FORMAT_A (to), a_to_shift);
287
288     r = convert_channel (pixel, 0,
289                          PIXMAN_FORMAT_R (from), r_from_shift,
290                          PIXMAN_FORMAT_R (to), r_to_shift);
291
292     g = convert_channel (pixel, 0,
293                          PIXMAN_FORMAT_G (from), g_from_shift,
294                          PIXMAN_FORMAT_G (to), g_to_shift);
295
296     b = convert_channel (pixel, 0,
297                          PIXMAN_FORMAT_B (from), b_from_shift,
298                          PIXMAN_FORMAT_B (to), b_to_shift);
299
300     return a | r | g | b;
301 }
302
303 static force_inline uint32_t
304 convert_pixel_from_a8r8g8b8 (pixman_format_code_t format, uint32_t pixel)
305 {
306     return convert_pixel (PIXMAN_a8r8g8b8, format, pixel);
307 }
308
309 static force_inline uint32_t
310 convert_pixel_to_a8r8g8b8 (pixman_format_code_t format, uint32_t pixel)
311 {
312     return convert_pixel (format, PIXMAN_a8r8g8b8, pixel);
313 }
314
315 static force_inline uint32_t
316 fetch_and_convert_pixel (pixman_image_t *       image,
317                          const uint8_t *        bits,
318                          int                    offset,
319                          pixman_format_code_t   format)
320 {
321     uint32_t pixel;
322
323     switch (PIXMAN_FORMAT_BPP (format))
324     {
325     case 1:
326         pixel = FETCH_1 (image, bits, offset);
327         break;
328
329     case 4:
330         pixel = FETCH_4 (image, bits, offset);
331         break;
332
333     case 8:
334         pixel = READ (image, bits + offset);
335         break;
336
337     case 16:
338         pixel = READ (image, ((uint16_t *)bits + offset));
339         break;
340
341     case 24:
342         pixel = FETCH_24 (image, bits, offset);
343         break;
344
345     case 32:
346         pixel = READ (image, ((uint32_t *)bits + offset));
347         break;
348
349     default:
350         pixel = 0xffff00ff; /* As ugly as possible to detect the bug */
351         break;
352     }
353
354     return convert_pixel_to_a8r8g8b8 (format, pixel);
355 }
356
357 static force_inline void
358 convert_and_store_pixel (bits_image_t *         image,
359                          uint8_t *              dest,
360                          int                    offset,
361                          pixman_format_code_t   format,
362                          uint32_t               pixel)
363 {
364     uint32_t converted = convert_pixel_from_a8r8g8b8 (format, pixel);
365
366     switch (PIXMAN_FORMAT_BPP (format))
367     {
368     case 1:
369         STORE_1 (image, dest, offset, converted & 0x01);
370         break;
371
372     case 4:
373         STORE_4 (image, dest, offset, converted & 0xf);
374         break;
375
376     case 8:
377         WRITE (image, (dest + offset), converted & 0xff);
378         break;
379
380     case 16:
381         WRITE (image, ((uint16_t *)dest + offset), converted & 0xffff);
382         break;
383
384     case 24:
385         STORE_24 (image, dest, offset, converted);
386         break;
387
388     case 32:
389         WRITE (image, ((uint32_t *)dest + offset), converted);
390         break;
391
392     default:
393         *dest = 0x0;
394         break;
395     }
396 }
397
398 #define MAKE_ACCESSORS(format)                                          \
399     static void                                                         \
400     fetch_scanline_ ## format (pixman_image_t *image,                   \
401                                int             x,                       \
402                                int             y,                       \
403                                int             width,                   \
404                                uint32_t *      buffer,                  \
405                                const uint32_t *mask)                    \
406     {                                                                   \
407         uint8_t *bits =                                                 \
408             (uint8_t *)(image->bits.bits + y * image->bits.rowstride);  \
409         int i;                                                          \
410                                                                         \
411         for (i = 0; i < width; ++i)                                     \
412         {                                                               \
413             *buffer++ =                                                 \
414                 fetch_and_convert_pixel (image, bits, x + i, PIXMAN_ ## format); \
415         }                                                               \
416     }                                                                   \
417                                                                         \
418     static void                                                         \
419     store_scanline_ ## format (bits_image_t *  image,                   \
420                                int             x,                       \
421                                int             y,                       \
422                                int             width,                   \
423                                const uint32_t *values)                  \
424     {                                                                   \
425         uint8_t *dest =                                                 \
426             (uint8_t *)(image->bits + y * image->rowstride);            \
427         int i;                                                          \
428                                                                         \
429         for (i = 0; i < width; ++i)                                     \
430         {                                                               \
431             convert_and_store_pixel (                                   \
432                 image, dest, i + x, PIXMAN_ ## format, values[i]);      \
433         }                                                               \
434     }                                                                   \
435                                                                         \
436     static uint32_t                                                     \
437     fetch_pixel_ ## format (bits_image_t *image,                        \
438                             int         offset,                         \
439                             int         line)                           \
440     {                                                                   \
441         uint8_t *bits =                                                 \
442             (uint8_t *)(image->bits + line * image->rowstride);         \
443                                                                         \
444         return fetch_and_convert_pixel ((pixman_image_t *)image,        \
445                                         bits, offset, PIXMAN_ ## format); \
446     }                                                                   \
447                                                                         \
448     static const void *const __dummy__ ## format
449
450 MAKE_ACCESSORS(a8r8g8b8);
451 MAKE_ACCESSORS(x8r8g8b8);
452 MAKE_ACCESSORS(a8b8g8r8);
453 MAKE_ACCESSORS(x8b8g8r8);
454 MAKE_ACCESSORS(x14r6g6b6);
455 MAKE_ACCESSORS(b8g8r8a8);
456 MAKE_ACCESSORS(b8g8r8x8);
457 MAKE_ACCESSORS(r8g8b8x8);
458 MAKE_ACCESSORS(r8g8b8a8);
459 MAKE_ACCESSORS(r8g8b8);
460 MAKE_ACCESSORS(b8g8r8);
461 MAKE_ACCESSORS(r5g6b5);
462 MAKE_ACCESSORS(b5g6r5);
463 MAKE_ACCESSORS(a1r5g5b5);
464 MAKE_ACCESSORS(x1r5g5b5);
465 MAKE_ACCESSORS(a1b5g5r5);
466 MAKE_ACCESSORS(x1b5g5r5);
467 MAKE_ACCESSORS(a4r4g4b4);
468 MAKE_ACCESSORS(x4r4g4b4);
469 MAKE_ACCESSORS(a4b4g4r4);
470 MAKE_ACCESSORS(x4b4g4r4);
471 MAKE_ACCESSORS(a8);
472 MAKE_ACCESSORS(r3g3b2);
473 MAKE_ACCESSORS(b2g3r3);
474 MAKE_ACCESSORS(a2r2g2b2);
475 MAKE_ACCESSORS(a2b2g2r2);
476 MAKE_ACCESSORS(x4a4);
477 MAKE_ACCESSORS(a4);
478 MAKE_ACCESSORS(r1g2b1);
479 MAKE_ACCESSORS(b1g2r1);
480 MAKE_ACCESSORS(a1r1g1b1);
481 MAKE_ACCESSORS(a1b1g1r1);
482 MAKE_ACCESSORS(a1);
483
484 /********************************** Fetch ************************************/
485
486 /* Expects a uint64_t buffer */
487 static void
488 fetch_scanline_a2r10g10b10 (pixman_image_t *image,
489                             int             x,
490                             int             y,
491                             int             width,
492                             uint32_t *      b,
493                             const uint32_t *mask)
494 {
495     const uint32_t *bits = image->bits.bits + y * image->bits.rowstride;
496     const uint32_t *pixel = bits + x;
497     const uint32_t *end = pixel + width;
498     uint64_t *buffer = (uint64_t *)b;
499
500     while (pixel < end)
501     {
502         uint32_t p = READ (image, pixel++);
503         uint64_t a = p >> 30;
504         uint64_t r = (p >> 20) & 0x3ff;
505         uint64_t g = (p >> 10) & 0x3ff;
506         uint64_t b = p & 0x3ff;
507
508         r = r << 6 | r >> 4;
509         g = g << 6 | g >> 4;
510         b = b << 6 | b >> 4;
511
512         a <<= 14;
513         a |= a >> 2;
514         a |= a >> 4;
515         a |= a >> 8;
516
517         *buffer++ = a << 48 | r << 32 | g << 16 | b;
518     }
519 }
520
521 /* Expects a uint64_t buffer */
522 static void
523 fetch_scanline_x2r10g10b10 (pixman_image_t *image,
524                             int             x,
525                             int             y,
526                             int             width,
527                             uint32_t *      b,
528                             const uint32_t *mask)
529 {
530     const uint32_t *bits = image->bits.bits + y * image->bits.rowstride;
531     const uint32_t *pixel = (uint32_t *)bits + x;
532     const uint32_t *end = pixel + width;
533     uint64_t *buffer = (uint64_t *)b;
534     
535     while (pixel < end)
536     {
537         uint32_t p = READ (image, pixel++);
538         uint64_t r = (p >> 20) & 0x3ff;
539         uint64_t g = (p >> 10) & 0x3ff;
540         uint64_t b = p & 0x3ff;
541         
542         r = r << 6 | r >> 4;
543         g = g << 6 | g >> 4;
544         b = b << 6 | b >> 4;
545         
546         *buffer++ = 0xffffULL << 48 | r << 32 | g << 16 | b;
547     }
548 }
549
550 /* Expects a uint64_t buffer */
551 static void
552 fetch_scanline_a2b10g10r10 (pixman_image_t *image,
553                             int             x,
554                             int             y,
555                             int             width,
556                             uint32_t *      b,
557                             const uint32_t *mask)
558 {
559     const uint32_t *bits = image->bits.bits + y * image->bits.rowstride;
560     const uint32_t *pixel = bits + x;
561     const uint32_t *end = pixel + width;
562     uint64_t *buffer = (uint64_t *)b;
563     
564     while (pixel < end)
565     {
566         uint32_t p = READ (image, pixel++);
567         uint64_t a = p >> 30;
568         uint64_t b = (p >> 20) & 0x3ff;
569         uint64_t g = (p >> 10) & 0x3ff;
570         uint64_t r = p & 0x3ff;
571         
572         r = r << 6 | r >> 4;
573         g = g << 6 | g >> 4;
574         b = b << 6 | b >> 4;
575         
576         a <<= 14;
577         a |= a >> 2;
578         a |= a >> 4;
579         a |= a >> 8;
580
581         *buffer++ = a << 48 | r << 32 | g << 16 | b;
582     }
583 }
584
585 /* Expects a uint64_t buffer */
586 static void
587 fetch_scanline_x2b10g10r10 (pixman_image_t *image,
588                             int             x,
589                             int             y,
590                             int             width,
591                             uint32_t *      b,
592                             const uint32_t *mask)
593 {
594     const uint32_t *bits = image->bits.bits + y * image->bits.rowstride;
595     const uint32_t *pixel = (uint32_t *)bits + x;
596     const uint32_t *end = pixel + width;
597     uint64_t *buffer = (uint64_t *)b;
598     
599     while (pixel < end)
600     {
601         uint32_t p = READ (image, pixel++);
602         uint64_t b = (p >> 20) & 0x3ff;
603         uint64_t g = (p >> 10) & 0x3ff;
604         uint64_t r = p & 0x3ff;
605         
606         r = r << 6 | r >> 4;
607         g = g << 6 | g >> 4;
608         b = b << 6 | b >> 4;
609         
610         *buffer++ = 0xffffULL << 48 | r << 32 | g << 16 | b;
611     }
612 }
613
614 static void
615 fetch_scanline_c8 (pixman_image_t *image,
616                    int             x,
617                    int             y,
618                    int             width,
619                    uint32_t *      buffer,
620                    const uint32_t *mask)
621 {
622     const uint32_t *bits = image->bits.bits + y * image->bits.rowstride;
623     const pixman_indexed_t * indexed = image->bits.indexed;
624     const uint8_t *pixel = (const uint8_t *)bits + x;
625     const uint8_t *end = pixel + width;
626     
627     while (pixel < end)
628     {
629         uint32_t p = READ (image, pixel++);
630         
631         *buffer++ = indexed->rgba[p];
632     }
633 }
634
635 static void
636 fetch_scanline_c4 (pixman_image_t *image,
637                    int             x,
638                    int             y,
639                    int             width,
640                    uint32_t *      buffer,
641                    const uint32_t *mask)
642 {
643     const uint32_t *bits = image->bits.bits + y * image->bits.rowstride;
644     const pixman_indexed_t * indexed = image->bits.indexed;
645     int i;
646     
647     for (i = 0; i < width; ++i)
648     {
649         uint32_t p = FETCH_4 (image, bits, i + x);
650         
651         *buffer++ = indexed->rgba[p];
652     }
653 }
654
655 static void
656 fetch_scanline_g1 (pixman_image_t *image,
657                    int             x,
658                    int             y,
659                    int             width,
660                    uint32_t *      buffer,
661                    const uint32_t *mask)
662 {
663     const uint32_t *bits = image->bits.bits + y * image->bits.rowstride;
664     const pixman_indexed_t * indexed = image->bits.indexed;
665     int i;
666     
667     for (i = 0; i < width; ++i)
668     {
669         uint32_t p = READ (image, bits + ((i + x) >> 5));
670         uint32_t a;
671         
672 #ifdef WORDS_BIGENDIAN
673         a = p >> (0x1f - ((i + x) & 0x1f));
674 #else
675         a = p >> ((i + x) & 0x1f);
676 #endif
677         a = a & 1;
678         
679         *buffer++ = indexed->rgba[a];
680     }
681 }
682
683 static void
684 fetch_scanline_yuy2 (pixman_image_t *image,
685                      int             x,
686                      int             line,
687                      int             width,
688                      uint32_t *      buffer,
689                      const uint32_t *mask)
690 {
691     const uint32_t *bits = image->bits.bits + image->bits.rowstride * line;
692     int i;
693     
694     for (i = 0; i < width; i++)
695     {
696         int16_t y, u, v;
697         int32_t r, g, b;
698         
699         y = ((uint8_t *) bits)[(x + i) << 1] - 16;
700         u = ((uint8_t *) bits)[(((x + i) << 1) & - 4) + 1] - 128;
701         v = ((uint8_t *) bits)[(((x + i) << 1) & - 4) + 3] - 128;
702         
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;
709         
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);
714     }
715 }
716
717 static void
718 fetch_scanline_yv12 (pixman_image_t *image,
719                      int             x,
720                      int             line,
721                      int             width,
722                      uint32_t *      buffer,
723                      const uint32_t *mask)
724 {
725     YV12_SETUP (image);
726     uint8_t *y_line = YV12_Y (line);
727     uint8_t *u_line = YV12_U (line);
728     uint8_t *v_line = YV12_V (line);
729     int i;
730     
731     for (i = 0; i < width; i++)
732     {
733         int16_t y, u, v;
734         int32_t r, g, b;
735
736         y = y_line[x + i] - 16;
737         u = u_line[(x + i) >> 1] - 128;
738         v = v_line[(x + i) >> 1] - 128;
739
740         /* R = 1.164(Y - 16) + 1.596(V - 128) */
741         r = 0x012b27 * y + 0x019a2e * v;
742         /* G = 1.164(Y - 16) - 0.813(V - 128) - 0.391(U - 128) */
743         g = 0x012b27 * y - 0x00d0f2 * v - 0x00647e * u;
744         /* B = 1.164(Y - 16) + 2.018(U - 128) */
745         b = 0x012b27 * y + 0x0206a2 * u;
746
747         *buffer++ = 0xff000000 |
748             (r >= 0 ? r < 0x1000000 ? r         & 0xff0000 : 0xff0000 : 0) |
749             (g >= 0 ? g < 0x1000000 ? (g >> 8)  & 0x00ff00 : 0x00ff00 : 0) |
750             (b >= 0 ? b < 0x1000000 ? (b >> 16) & 0x0000ff : 0x0000ff : 0);
751     }
752 }
753
754 /**************************** Pixel wise fetching *****************************/
755
756 /* Despite the type, expects a uint64_t buffer */
757 static uint64_t
758 fetch_pixel_a2r10g10b10 (bits_image_t *image,
759                          int              offset,
760                          int           line)
761 {
762     uint32_t *bits = image->bits + line * image->rowstride;
763     uint32_t p = READ (image, bits + offset);
764     uint64_t a = p >> 30;
765     uint64_t r = (p >> 20) & 0x3ff;
766     uint64_t g = (p >> 10) & 0x3ff;
767     uint64_t b = p & 0x3ff;
768
769     r = r << 6 | r >> 4;
770     g = g << 6 | g >> 4;
771     b = b << 6 | b >> 4;
772
773     a <<= 14;
774     a |= a >> 2;
775     a |= a >> 4;
776     a |= a >> 8;
777
778     return a << 48 | r << 32 | g << 16 | b;
779 }
780
781 /* Despite the type, this function expects a uint64_t buffer */
782 static uint64_t
783 fetch_pixel_x2r10g10b10 (bits_image_t *image,
784                          int       offset,
785                          int           line)
786 {
787     uint32_t *bits = image->bits + line * image->rowstride;
788     uint32_t p = READ (image, bits + offset);
789     uint64_t r = (p >> 20) & 0x3ff;
790     uint64_t g = (p >> 10) & 0x3ff;
791     uint64_t b = p & 0x3ff;
792     
793     r = r << 6 | r >> 4;
794     g = g << 6 | g >> 4;
795     b = b << 6 | b >> 4;
796     
797     return 0xffffULL << 48 | r << 32 | g << 16 | b;
798 }
799
800 /* Despite the type, expects a uint64_t buffer */
801 static uint64_t
802 fetch_pixel_a2b10g10r10 (bits_image_t *image,
803                          int           offset,
804                          int           line)
805 {
806     uint32_t *bits = image->bits + line * image->rowstride;
807     uint32_t p = READ (image, bits + offset);
808     uint64_t a = p >> 30;
809     uint64_t b = (p >> 20) & 0x3ff;
810     uint64_t g = (p >> 10) & 0x3ff;
811     uint64_t r = p & 0x3ff;
812     
813     r = r << 6 | r >> 4;
814     g = g << 6 | g >> 4;
815     b = b << 6 | b >> 4;
816     
817     a <<= 14;
818     a |= a >> 2;
819     a |= a >> 4;
820     a |= a >> 8;
821     
822     return a << 48 | r << 32 | g << 16 | b;
823 }
824
825 /* Despite the type, this function expects a uint64_t buffer */
826 static uint64_t
827 fetch_pixel_x2b10g10r10 (bits_image_t *image,
828                          int           offset,
829                          int           line)
830 {
831     uint32_t *bits = image->bits + line * image->rowstride;
832     uint32_t p = READ (image, bits + offset);
833     uint64_t b = (p >> 20) & 0x3ff;
834     uint64_t g = (p >> 10) & 0x3ff;
835     uint64_t r = p & 0x3ff;
836     
837     r = r << 6 | r >> 4;
838     g = g << 6 | g >> 4;
839     b = b << 6 | b >> 4;
840     
841     return 0xffffULL << 48 | r << 32 | g << 16 | b;
842 }
843
844 static uint32_t
845 fetch_pixel_c8 (bits_image_t *image,
846                 int           offset,
847                 int           line)
848 {
849     uint32_t *bits = image->bits + line * image->rowstride;
850     uint32_t pixel = READ (image, (uint8_t *) bits + offset);
851     const pixman_indexed_t * indexed = image->indexed;
852     
853     return indexed->rgba[pixel];
854 }
855
856 static uint32_t
857 fetch_pixel_c4 (bits_image_t *image,
858                 int           offset,
859                 int           line)
860 {
861     uint32_t *bits = image->bits + line * image->rowstride;
862     uint32_t pixel = FETCH_4 (image, bits, offset);
863     const pixman_indexed_t * indexed = image->indexed;
864
865     return indexed->rgba[pixel];
866 }
867
868 static uint32_t
869 fetch_pixel_g1 (bits_image_t *image,
870                 int           offset,
871                 int           line)
872 {
873     uint32_t *bits = image->bits + line * image->rowstride;
874     uint32_t pixel = READ (image, bits + (offset >> 5));
875     const pixman_indexed_t * indexed = image->indexed;
876     uint32_t a;
877     
878 #ifdef WORDS_BIGENDIAN
879     a = pixel >> (0x1f - (offset & 0x1f));
880 #else
881     a = pixel >> (offset & 0x1f);
882 #endif
883     a = a & 1;
884     
885     return indexed->rgba[a];
886 }
887
888 static uint32_t
889 fetch_pixel_yuy2 (bits_image_t *image,
890                   int           offset,
891                   int           line)
892 {
893     const uint32_t *bits = image->bits + image->rowstride * line;
894     
895     int16_t y, u, v;
896     int32_t r, g, b;
897     
898     y = ((uint8_t *) bits)[offset << 1] - 16;
899     u = ((uint8_t *) bits)[((offset << 1) & - 4) + 1] - 128;
900     v = ((uint8_t *) bits)[((offset << 1) & - 4) + 3] - 128;
901     
902     /* R = 1.164(Y - 16) + 1.596(V - 128) */
903     r = 0x012b27 * y + 0x019a2e * v;
904     
905     /* G = 1.164(Y - 16) - 0.813(V - 128) - 0.391(U - 128) */
906     g = 0x012b27 * y - 0x00d0f2 * v - 0x00647e * u;
907     
908     /* B = 1.164(Y - 16) + 2.018(U - 128) */
909     b = 0x012b27 * y + 0x0206a2 * u;
910     
911     return 0xff000000 |
912         (r >= 0 ? r < 0x1000000 ? r         & 0xff0000 : 0xff0000 : 0) |
913         (g >= 0 ? g < 0x1000000 ? (g >> 8)  & 0x00ff00 : 0x00ff00 : 0) |
914         (b >= 0 ? b < 0x1000000 ? (b >> 16) & 0x0000ff : 0x0000ff : 0);
915 }
916
917 static uint32_t
918 fetch_pixel_yv12 (bits_image_t *image,
919                   int           offset,
920                   int           line)
921 {
922     YV12_SETUP (image);
923     int16_t y = YV12_Y (line)[offset] - 16;
924     int16_t u = YV12_U (line)[offset >> 1] - 128;
925     int16_t v = YV12_V (line)[offset >> 1] - 128;
926     int32_t r, g, b;
927     
928     /* R = 1.164(Y - 16) + 1.596(V - 128) */
929     r = 0x012b27 * y + 0x019a2e * v;
930     
931     /* G = 1.164(Y - 16) - 0.813(V - 128) - 0.391(U - 128) */
932     g = 0x012b27 * y - 0x00d0f2 * v - 0x00647e * u;
933     
934     /* B = 1.164(Y - 16) + 2.018(U - 128) */
935     b = 0x012b27 * y + 0x0206a2 * u;
936     
937     return 0xff000000 |
938         (r >= 0 ? r < 0x1000000 ? r         & 0xff0000 : 0xff0000 : 0) |
939         (g >= 0 ? g < 0x1000000 ? (g >> 8)  & 0x00ff00 : 0x00ff00 : 0) |
940         (b >= 0 ? b < 0x1000000 ? (b >> 16) & 0x0000ff : 0x0000ff : 0);
941 }
942
943 /*********************************** Store ************************************/
944
945 static void
946 store_scanline_a2r10g10b10 (bits_image_t *  image,
947                             int             x,
948                             int             y,
949                             int             width,
950                             const uint32_t *v)
951 {
952     uint32_t *bits = image->bits + image->rowstride * y;
953     uint32_t *pixel = bits + x;
954     uint64_t *values = (uint64_t *)v;
955     int i;
956     
957     for (i = 0; i < width; ++i)
958     {
959         WRITE (image, pixel++,
960                ((values[i] >> 32) & 0xc0000000) |
961                ((values[i] >> 18) & 0x3ff00000) |
962                ((values[i] >> 12) & 0xffc00) | 
963                ((values[i] >> 6) & 0x3ff));    
964     }
965 }
966
967 static void
968 store_scanline_x2r10g10b10 (bits_image_t *  image,
969                             int             x,
970                             int             y,
971                             int             width,
972                             const uint32_t *v)
973 {
974     uint32_t *bits = image->bits + image->rowstride * y;
975     uint64_t *values = (uint64_t *)v;
976     uint32_t *pixel = bits + x;
977     int i;
978     
979     for (i = 0; i < width; ++i)
980     {
981         WRITE (image, pixel++,
982                ((values[i] >> 18) & 0x3ff00000) | 
983                ((values[i] >> 12) & 0xffc00) |
984                ((values[i] >> 6) & 0x3ff));
985     }
986 }
987
988 static void
989 store_scanline_a2b10g10r10 (bits_image_t *  image,
990                             int             x,
991                             int             y,
992                             int             width,
993                             const uint32_t *v)
994 {
995     uint32_t *bits = image->bits + image->rowstride * y;
996     uint32_t *pixel = bits + x;
997     uint64_t *values = (uint64_t *)v;
998     int i;
999     
1000     for (i = 0; i < width; ++i)
1001     {
1002         WRITE (image, pixel++,
1003                ((values[i] >> 32) & 0xc0000000) |
1004                ((values[i] >> 38) & 0x3ff) |
1005                ((values[i] >> 12) & 0xffc00) |
1006                ((values[i] << 14) & 0x3ff00000));
1007     }
1008 }
1009
1010 static void
1011 store_scanline_x2b10g10r10 (bits_image_t *  image,
1012                             int             x,
1013                             int             y,
1014                             int             width,
1015                             const uint32_t *v)
1016 {
1017     uint32_t *bits = image->bits + image->rowstride * y;
1018     uint64_t *values = (uint64_t *)v;
1019     uint32_t *pixel = bits + x;
1020     int i;
1021     
1022     for (i = 0; i < width; ++i)
1023     {
1024         WRITE (image, pixel++,
1025                ((values[i] >> 38) & 0x3ff) |
1026                ((values[i] >> 12) & 0xffc00) |
1027                ((values[i] << 14) & 0x3ff00000));
1028     }
1029 }
1030
1031 static void
1032 store_scanline_c8 (bits_image_t *  image,
1033                    int             x,
1034                    int             y,
1035                    int             width,
1036                    const uint32_t *values)
1037 {
1038     uint32_t *bits = image->bits + image->rowstride * y;
1039     uint8_t *pixel = ((uint8_t *) bits) + x;
1040     const pixman_indexed_t *indexed = image->indexed;
1041     int i;
1042     
1043     for (i = 0; i < width; ++i)
1044         WRITE (image, pixel++, RGB24_TO_ENTRY (indexed,values[i]));
1045 }
1046
1047 static void
1048 store_scanline_g8 (bits_image_t *  image,
1049                    int             x,
1050                    int             y,
1051                    int             width,
1052                    const uint32_t *values)
1053 {
1054     uint32_t *bits = image->bits + image->rowstride * y;
1055     uint8_t *pixel = ((uint8_t *) bits) + x;
1056     const pixman_indexed_t *indexed = image->indexed;
1057     int i;
1058
1059     for (i = 0; i < width; ++i)
1060         WRITE (image, pixel++, RGB24_TO_ENTRY_Y (indexed,values[i]));
1061 }
1062
1063 static void
1064 store_scanline_c4 (bits_image_t *  image,
1065                    int             x,
1066                    int             y,
1067                    int             width,
1068                    const uint32_t *values)
1069 {
1070     uint32_t *bits = image->bits + image->rowstride * y;
1071     const pixman_indexed_t *indexed = image->indexed;
1072     int i;
1073     
1074     for (i = 0; i < width; ++i)
1075     {
1076         uint32_t pixel;
1077         
1078         pixel = RGB24_TO_ENTRY (indexed, values[i]);
1079         STORE_4 (image, bits, i + x, pixel);
1080     }
1081 }
1082
1083 static void
1084 store_scanline_g4 (bits_image_t *  image,
1085                    int             x,
1086                    int             y,
1087                    int             width,
1088                    const uint32_t *values)
1089 {
1090     uint32_t *bits = image->bits + image->rowstride * y;
1091     const pixman_indexed_t *indexed = image->indexed;
1092     int i;
1093     
1094     for (i = 0; i < width; ++i)
1095     {
1096         uint32_t pixel;
1097         
1098         pixel = RGB24_TO_ENTRY_Y (indexed, values[i]);
1099         STORE_4 (image, bits, i + x, pixel);
1100     }
1101 }
1102
1103 static void
1104 store_scanline_g1 (bits_image_t *  image,
1105                    int             x,
1106                    int             y,
1107                    int             width,
1108                    const uint32_t *values)
1109 {
1110     uint32_t *bits = image->bits + image->rowstride * y;
1111     const pixman_indexed_t *indexed = image->indexed;
1112     int i;
1113     
1114     for (i = 0; i < width; ++i)
1115     {
1116         uint32_t  *pixel = ((uint32_t *) bits) + ((i + x) >> 5);
1117         uint32_t mask, v;
1118         
1119 #ifdef WORDS_BIGENDIAN
1120         mask = 1 << (0x1f - ((i + x) & 0x1f));
1121 #else
1122         mask = 1 << ((i + x) & 0x1f);
1123 #endif
1124         v = RGB24_TO_ENTRY_Y (indexed, values[i]) & 0x1 ? mask : 0;
1125         
1126         WRITE (image, pixel, (READ (image, pixel) & ~mask) | v);
1127     }
1128 }
1129
1130 /*
1131  * Contracts a 64bpp image to 32bpp and then stores it using a regular 32-bit
1132  * store proc. Despite the type, this function expects a uint64_t buffer.
1133  */
1134 static void
1135 store_scanline_generic_64 (bits_image_t *  image,
1136                            int             x,
1137                            int             y,
1138                            int             width,
1139                            const uint32_t *values)
1140 {
1141     uint32_t *argb8_pixels;
1142     
1143     assert (image->common.type == BITS);
1144     
1145     argb8_pixels = pixman_malloc_ab (width, sizeof(uint32_t));
1146     if (!argb8_pixels)
1147         return;
1148     
1149     /* Contract the scanline.  We could do this in place if values weren't
1150      * const.
1151      */
1152     pixman_contract (argb8_pixels, (uint64_t *)values, width);
1153     
1154     image->store_scanline_32 (image, x, y, width, argb8_pixels);
1155     
1156     free (argb8_pixels);
1157 }
1158
1159 /* Despite the type, this function expects both buffer
1160  * and mask to be uint64_t
1161  */
1162 static void
1163 fetch_scanline_generic_64 (pixman_image_t *image,
1164                            int             x,
1165                            int             y,
1166                            int             width,
1167                            uint32_t *      buffer,
1168                            const uint32_t *mask)
1169 {
1170     pixman_format_code_t format;
1171     
1172     /* Fetch the pixels into the first half of buffer and then expand them in
1173      * place.
1174      */
1175     image->bits.fetch_scanline_32 (image, x, y, width, buffer, NULL);
1176
1177     format = image->bits.format;
1178     if (PIXMAN_FORMAT_TYPE (format) == PIXMAN_TYPE_COLOR        ||
1179         PIXMAN_FORMAT_TYPE (format) == PIXMAN_TYPE_GRAY)
1180     {
1181         /* Indexed formats are mapped to a8r8g8b8 with full
1182          * precision, so when expanding we shouldn't correct
1183          * for the width of the channels
1184          */
1185         
1186         format = PIXMAN_a8r8g8b8;
1187     }
1188     
1189     pixman_expand ((uint64_t *)buffer, buffer, format, width);
1190 }
1191
1192 /* Despite the type, this function expects a uint64_t *buffer */
1193 static uint64_t
1194 fetch_pixel_generic_64 (bits_image_t *image,
1195                         int           offset,
1196                         int           line)
1197 {
1198     uint32_t pixel32 = image->fetch_pixel_32 (image, offset, line);
1199     uint64_t result;
1200     pixman_format_code_t format;
1201
1202     format = image->format;
1203     if (PIXMAN_FORMAT_TYPE (format) == PIXMAN_TYPE_COLOR        ||
1204         PIXMAN_FORMAT_TYPE (format) == PIXMAN_TYPE_GRAY)
1205     {
1206         /* Indexed formats are mapped to a8r8g8b8 with full
1207          * precision, so when expanding we shouldn't correct
1208          * for the width of the channels
1209          */
1210         
1211         format = PIXMAN_a8r8g8b8;
1212     }
1213     
1214     pixman_expand ((uint64_t *)&result, &pixel32, format, 1);
1215
1216     return result;
1217 }
1218
1219 /*
1220  * XXX: The transformed fetch path only works at 32-bpp so far.  When all
1221  * paths have wide versions, this can be removed.
1222  *
1223  * WARNING: This function loses precision!
1224  */
1225 static uint32_t
1226 fetch_pixel_generic_lossy_32 (bits_image_t *image,
1227                               int           offset,
1228                               int           line)
1229 {
1230     uint64_t pixel64 = image->fetch_pixel_64 (image, offset, line);
1231     uint32_t result;
1232     
1233     pixman_contract (&result, &pixel64, 1);
1234
1235     return result;
1236 }
1237
1238 typedef struct
1239 {
1240     pixman_format_code_t        format;
1241     fetch_scanline_t            fetch_scanline_32;
1242     fetch_scanline_t            fetch_scanline_64;
1243     fetch_pixel_32_t            fetch_pixel_32;
1244     fetch_pixel_64_t            fetch_pixel_64;
1245     store_scanline_t            store_scanline_32;
1246     store_scanline_t            store_scanline_64;
1247 } format_info_t;
1248
1249 #define FORMAT_INFO(format)                                             \
1250     {                                                                   \
1251         PIXMAN_ ## format,                                              \
1252             fetch_scanline_ ## format,                                  \
1253             fetch_scanline_generic_64,                                  \
1254             fetch_pixel_ ## format, fetch_pixel_generic_64,             \
1255             store_scanline_ ## format, store_scanline_generic_64        \
1256     }
1257
1258 static const format_info_t accessors[] =
1259 {
1260 /* 32 bpp formats */
1261     FORMAT_INFO (a8r8g8b8),
1262     FORMAT_INFO (x8r8g8b8),
1263     FORMAT_INFO (a8b8g8r8),
1264     FORMAT_INFO (x8b8g8r8),
1265     FORMAT_INFO (b8g8r8a8),
1266     FORMAT_INFO (b8g8r8x8),
1267     FORMAT_INFO (r8g8b8a8),
1268     FORMAT_INFO (r8g8b8x8),
1269     FORMAT_INFO (x14r6g6b6),
1270
1271 /* 24bpp formats */
1272     FORMAT_INFO (r8g8b8),
1273     FORMAT_INFO (b8g8r8),
1274     
1275 /* 16bpp formats */
1276     FORMAT_INFO (r5g6b5),
1277     FORMAT_INFO (b5g6r5),
1278     
1279     FORMAT_INFO (a1r5g5b5),
1280     FORMAT_INFO (x1r5g5b5),
1281     FORMAT_INFO (a1b5g5r5),
1282     FORMAT_INFO (x1b5g5r5),
1283     FORMAT_INFO (a4r4g4b4),
1284     FORMAT_INFO (x4r4g4b4),
1285     FORMAT_INFO (a4b4g4r4),
1286     FORMAT_INFO (x4b4g4r4),
1287     
1288 /* 8bpp formats */
1289     FORMAT_INFO (a8),
1290     FORMAT_INFO (r3g3b2),
1291     FORMAT_INFO (b2g3r3),
1292     FORMAT_INFO (a2r2g2b2),
1293     FORMAT_INFO (a2b2g2r2),
1294     
1295     FORMAT_INFO (c8),
1296     
1297 #define fetch_scanline_g8 fetch_scanline_c8
1298 #define fetch_pixel_g8 fetch_pixel_c8
1299     FORMAT_INFO (g8),
1300     
1301 #define fetch_scanline_x4c4 fetch_scanline_c8
1302 #define fetch_pixel_x4c4 fetch_pixel_c8
1303 #define store_scanline_x4c4 store_scanline_c8
1304     FORMAT_INFO (x4c4),
1305     
1306 #define fetch_scanline_x4g4 fetch_scanline_c8
1307 #define fetch_pixel_x4g4 fetch_pixel_c8
1308 #define store_scanline_x4g4 store_scanline_g8
1309     FORMAT_INFO (x4g4),
1310     
1311     FORMAT_INFO (x4a4),
1312     
1313 /* 4bpp formats */
1314     FORMAT_INFO (a4),
1315     FORMAT_INFO (r1g2b1),
1316     FORMAT_INFO (b1g2r1),
1317     FORMAT_INFO (a1r1g1b1),
1318     FORMAT_INFO (a1b1g1r1),
1319     
1320     FORMAT_INFO (c4),
1321     
1322 #define fetch_scanline_g4 fetch_scanline_c4
1323 #define fetch_pixel_g4 fetch_pixel_c4
1324     FORMAT_INFO (g4),
1325     
1326 /* 1bpp formats */
1327     FORMAT_INFO (a1),
1328     FORMAT_INFO (g1),
1329     
1330 /* Wide formats */
1331     
1332     { PIXMAN_a2r10g10b10,
1333       NULL, fetch_scanline_a2r10g10b10,
1334       fetch_pixel_generic_lossy_32, fetch_pixel_a2r10g10b10,
1335       NULL, store_scanline_a2r10g10b10 },
1336     
1337     { PIXMAN_x2r10g10b10,
1338       NULL, fetch_scanline_x2r10g10b10,
1339       fetch_pixel_generic_lossy_32, fetch_pixel_x2r10g10b10,
1340       NULL, store_scanline_x2r10g10b10 },
1341     
1342     { PIXMAN_a2b10g10r10,
1343       NULL, fetch_scanline_a2b10g10r10,
1344       fetch_pixel_generic_lossy_32, fetch_pixel_a2b10g10r10,
1345       NULL, store_scanline_a2b10g10r10 },
1346     
1347     { PIXMAN_x2b10g10r10,
1348       NULL, fetch_scanline_x2b10g10r10,
1349       fetch_pixel_generic_lossy_32, fetch_pixel_x2b10g10r10,
1350       NULL, store_scanline_x2b10g10r10 },
1351     
1352 /* YUV formats */
1353     { PIXMAN_yuy2,
1354       fetch_scanline_yuy2, fetch_scanline_generic_64,
1355       fetch_pixel_yuy2, fetch_pixel_generic_64,
1356       NULL, NULL },
1357     
1358     { PIXMAN_yv12,
1359       fetch_scanline_yv12, fetch_scanline_generic_64,
1360       fetch_pixel_yv12, fetch_pixel_generic_64,
1361       NULL, NULL },
1362     
1363     { PIXMAN_null },
1364 };
1365
1366 static void
1367 setup_accessors (bits_image_t *image)
1368 {
1369     const format_info_t *info = accessors;
1370     
1371     while (info->format != PIXMAN_null)
1372     {
1373         if (info->format == image->format)
1374         {
1375             image->fetch_scanline_32 = info->fetch_scanline_32;
1376             image->fetch_scanline_64 = info->fetch_scanline_64;
1377             image->fetch_pixel_32 = info->fetch_pixel_32;
1378             image->fetch_pixel_64 = info->fetch_pixel_64;
1379             image->store_scanline_32 = info->store_scanline_32;
1380             image->store_scanline_64 = info->store_scanline_64;
1381             
1382             return;
1383         }
1384         
1385         info++;
1386     }
1387 }
1388
1389 #ifndef PIXMAN_FB_ACCESSORS
1390 void
1391 _pixman_bits_image_setup_accessors_accessors (bits_image_t *image);
1392
1393 void
1394 _pixman_bits_image_setup_accessors (bits_image_t *image)
1395 {
1396     if (image->read_func || image->write_func)
1397         _pixman_bits_image_setup_accessors_accessors (image);
1398     else
1399         setup_accessors (image);
1400 }
1401
1402 #else
1403
1404 void
1405 _pixman_bits_image_setup_accessors_accessors (bits_image_t *image)
1406 {
1407     setup_accessors (image);
1408 }
1409
1410 #endif