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 /*
58 * YV12 setup and access macros
59 */
60
61 #define YV12_SETUP(image) \
62 bits_image_t *__bits_image = (bits_image_t *)image; \
63 uint32_t *bits = __bits_image->bits; \
64 int stride = __bits_image->rowstride; \
65 int offset0 = stride < 0 ? \
66 ((-stride) >> 1) * ((__bits_image->height - 1) >> 1) - stride : \
67 stride * __bits_image->height; \
68 int offset1 = stride < 0 ? \
69 offset0 + ((-stride) >> 1) * ((__bits_image->height) >> 1) : \
70 offset0 + (offset0 >> 2)
71
72 /* Note no trailing semicolon on the above macro; if it's there, then
73 * the typical usage of YV12_SETUP(image); will have an extra trailing ;
74 * that some compilers will interpret as a statement -- and then any further
75 * variable declarations will cause an error.
76 */
77
78 #define YV12_Y(line) \
79 ((uint8_t *) ((bits) + (stride) * (line)))
80
81 #define YV12_U(line) \
82 ((uint8_t *) ((bits) + offset1 + \
83 ((stride) >> 1) * ((line) >> 1)))
84
85 #define YV12_V(line) \
86 ((uint8_t *) ((bits) + offset0 + \
87 ((stride) >> 1) * ((line) >> 1)))
88
89 /********************************** Fetch ************************************/
90
91 static void
fetch_scanline_a8r8g8b8(pixman_image_t * image,int x,int y,int width,uint32_t * buffer,const uint32_t * mask,uint32_t mask_bits)92 fetch_scanline_a8r8g8b8 (pixman_image_t *image,
93 int x,
94 int y,
95 int width,
96 uint32_t * buffer,
97 const uint32_t *mask,
98 uint32_t mask_bits)
99 {
100 const uint32_t *bits = image->bits.bits + y * image->bits.rowstride;
101
102 MEMCPY_WRAPPED (image,
103 buffer, (const uint32_t *)bits + x,
104 width * sizeof(uint32_t));
105 }
106
107 static void
fetch_scanline_x8r8g8b8(pixman_image_t * image,int x,int y,int width,uint32_t * buffer,const uint32_t * mask,uint32_t mask_bits)108 fetch_scanline_x8r8g8b8 (pixman_image_t *image,
109 int x,
110 int y,
111 int width,
112 uint32_t * buffer,
113 const uint32_t *mask,
114 uint32_t mask_bits)
115 {
116 const uint32_t *bits = image->bits.bits + y * image->bits.rowstride;
117 const uint32_t *pixel = (const uint32_t *)bits + x;
118 const uint32_t *end = pixel + width;
119
120 while (pixel < end)
121 *buffer++ = READ (image, pixel++) | 0xff000000;
122 }
123
124 static void
fetch_scanline_a8b8g8r8(pixman_image_t * image,int x,int y,int width,uint32_t * buffer,const uint32_t * mask,uint32_t mask_bits)125 fetch_scanline_a8b8g8r8 (pixman_image_t *image,
126 int x,
127 int y,
128 int width,
129 uint32_t * buffer,
130 const uint32_t *mask,
131 uint32_t mask_bits)
132 {
133 const uint32_t *bits = image->bits.bits + y * image->bits.rowstride;
134 const uint32_t *pixel = (uint32_t *)bits + x;
135 const uint32_t *end = pixel + width;
136
137 while (pixel < end)
138 {
139 uint32_t p = READ (image, pixel++);
140
141 *buffer++ = (p & 0xff00ff00) |
142 ((p >> 16) & 0xff) |
143 ((p & 0xff) << 16);
144 }
145 }
146
147 static void
fetch_scanline_x8b8g8r8(pixman_image_t * image,int x,int y,int width,uint32_t * buffer,const uint32_t * mask,uint32_t mask_bits)148 fetch_scanline_x8b8g8r8 (pixman_image_t *image,
149 int x,
150 int y,
151 int width,
152 uint32_t * buffer,
153 const uint32_t *mask,
154 uint32_t mask_bits)
155 {
156 const uint32_t *bits = image->bits.bits + y * image->bits.rowstride;
157 const uint32_t *pixel = (uint32_t *)bits + x;
158 const uint32_t *end = pixel + width;
159
160 while (pixel < end)
161 {
162 uint32_t p = READ (image, pixel++);
163
164 *buffer++ = 0xff000000 |
165 (p & 0x0000ff00) |
166 ((p >> 16) & 0xff) |
167 ((p & 0xff) << 16);
168 }
169 }
170
171 static void
fetch_scanline_b8g8r8a8(pixman_image_t * image,int x,int y,int width,uint32_t * buffer,const uint32_t * mask,uint32_t mask_bits)172 fetch_scanline_b8g8r8a8 (pixman_image_t *image,
173 int x,
174 int y,
175 int width,
176 uint32_t * buffer,
177 const uint32_t *mask,
178 uint32_t mask_bits)
179 {
180 const uint32_t *bits = image->bits.bits + y * image->bits.rowstride;
181 const uint32_t *pixel = (uint32_t *)bits + x;
182 const uint32_t *end = pixel + width;
183
184 while (pixel < end)
185 {
186 uint32_t p = READ (image, pixel++);
187
188 *buffer++ = (((p & 0xff000000) >> 24) |
189 ((p & 0x00ff0000) >> 8) |
190 ((p & 0x0000ff00) << 8) |
191 ((p & 0x000000ff) << 24));
192 }
193 }
194
195 static void
fetch_scanline_b8g8r8x8(pixman_image_t * image,int x,int y,int width,uint32_t * buffer,const uint32_t * mask,uint32_t mask_bits)196 fetch_scanline_b8g8r8x8 (pixman_image_t *image,
197 int x,
198 int y,
199 int width,
200 uint32_t * buffer,
201 const uint32_t *mask,
202 uint32_t mask_bits)
203 {
204 const uint32_t *bits = image->bits.bits + y * image->bits.rowstride;
205 const uint32_t *pixel = (uint32_t *)bits + x;
206 const uint32_t *end = pixel + width;
207
208 while (pixel < end)
209 {
210 uint32_t p = READ (image, pixel++);
211
212 *buffer++ = (0xff000000 |
213 ((p & 0xff000000) >> 24) |
214 ((p & 0x00ff0000) >> 8) |
215 ((p & 0x0000ff00) << 8));
216 }
217 }
218
219 /* Expects a uint64_t buffer */
220 static void
fetch_scanline_a2r10g10b10(pixman_image_t * image,int x,int y,int width,uint32_t * b,const uint32_t * mask,uint32_t mask_bits)221 fetch_scanline_a2r10g10b10 (pixman_image_t *image,
222 int x,
223 int y,
224 int width,
225 uint32_t * b,
226 const uint32_t *mask,
227 uint32_t mask_bits)
228 {
229 const uint32_t *bits = image->bits.bits + y * image->bits.rowstride;
230 const uint32_t *pixel = bits + x;
231 const uint32_t *end = pixel + width;
232 uint64_t *buffer = (uint64_t *)b;
233
234 while (pixel < end)
235 {
236 uint32_t p = READ (image, pixel++);
237 uint64_t a = p >> 30;
238 uint64_t r = (p >> 20) & 0x3ff;
239 uint64_t g = (p >> 10) & 0x3ff;
240 uint64_t b = p & 0x3ff;
241
242 r = r << 6 | r >> 4;
243 g = g << 6 | g >> 4;
244 b = b << 6 | b >> 4;
245
246 a <<= 14;
247 a |= a >> 2;
248 a |= a >> 4;
249 a |= a >> 8;
250
251 *buffer++ = a << 48 | r << 32 | g << 16 | b;
252 }
253 }
254
255 /* Expects a uint64_t buffer */
256 static void
fetch_scanline_x2r10g10b10(pixman_image_t * image,int x,int y,int width,uint32_t * b,const uint32_t * mask,uint32_t mask_bits)257 fetch_scanline_x2r10g10b10 (pixman_image_t *image,
258 int x,
259 int y,
260 int width,
261 uint32_t * b,
262 const uint32_t *mask,
263 uint32_t mask_bits)
264 {
265 const uint32_t *bits = image->bits.bits + y * image->bits.rowstride;
266 const uint32_t *pixel = (uint32_t *)bits + x;
267 const uint32_t *end = pixel + width;
268 uint64_t *buffer = (uint64_t *)b;
269
270 while (pixel < end)
271 {
272 uint32_t p = READ (image, pixel++);
273 uint64_t r = (p >> 20) & 0x3ff;
274 uint64_t g = (p >> 10) & 0x3ff;
275 uint64_t b = p & 0x3ff;
276
277 r = r << 6 | r >> 4;
278 g = g << 6 | g >> 4;
279 b = b << 6 | b >> 4;
280
281 *buffer++ = 0xffffULL << 48 | r << 32 | g << 16 | b;
282 }
283 }
284
285 /* Expects a uint64_t buffer */
286 static void
fetch_scanline_a2b10g10r10(pixman_image_t * image,int x,int y,int width,uint32_t * b,const uint32_t * mask,uint32_t mask_bits)287 fetch_scanline_a2b10g10r10 (pixman_image_t *image,
288 int x,
289 int y,
290 int width,
291 uint32_t * b,
292 const uint32_t *mask,
293 uint32_t mask_bits)
294 {
295 const uint32_t *bits = image->bits.bits + y * image->bits.rowstride;
296 const uint32_t *pixel = bits + x;
297 const uint32_t *end = pixel + width;
298 uint64_t *buffer = (uint64_t *)b;
299
300 while (pixel < end)
301 {
302 uint32_t p = READ (image, pixel++);
303 uint64_t a = p >> 30;
304 uint64_t b = (p >> 20) & 0x3ff;
305 uint64_t g = (p >> 10) & 0x3ff;
306 uint64_t r = p & 0x3ff;
307
308 r = r << 6 | r >> 4;
309 g = g << 6 | g >> 4;
310 b = b << 6 | b >> 4;
311
312 a <<= 14;
313 a |= a >> 2;
314 a |= a >> 4;
315 a |= a >> 8;
316
317 *buffer++ = a << 48 | r << 32 | g << 16 | b;
318 }
319 }
320
321 /* Expects a uint64_t buffer */
322 static void
fetch_scanline_x2b10g10r10(pixman_image_t * image,int x,int y,int width,uint32_t * b,const uint32_t * mask,uint32_t mask_bits)323 fetch_scanline_x2b10g10r10 (pixman_image_t *image,
324 int x,
325 int y,
326 int width,
327 uint32_t * b,
328 const uint32_t *mask,
329 uint32_t mask_bits)
330 {
331 const uint32_t *bits = image->bits.bits + y * image->bits.rowstride;
332 const uint32_t *pixel = (uint32_t *)bits + x;
333 const uint32_t *end = pixel + width;
334 uint64_t *buffer = (uint64_t *)b;
335
336 while (pixel < end)
337 {
338 uint32_t p = READ (image, pixel++);
339 uint64_t b = (p >> 20) & 0x3ff;
340 uint64_t g = (p >> 10) & 0x3ff;
341 uint64_t r = p & 0x3ff;
342
343 r = r << 6 | r >> 4;
344 g = g << 6 | g >> 4;
345 b = b << 6 | b >> 4;
346
347 *buffer++ = 0xffffULL << 48 | r << 32 | g << 16 | b;
348 }
349 }
350
351 static void
fetch_scanline_r8g8b8(pixman_image_t * image,int x,int y,int width,uint32_t * buffer,const uint32_t * mask,uint32_t mask_bits)352 fetch_scanline_r8g8b8 (pixman_image_t *image,
353 int x,
354 int y,
355 int width,
356 uint32_t * buffer,
357 const uint32_t *mask,
358 uint32_t mask_bits)
359 {
360 const uint32_t *bits = image->bits.bits + y * image->bits.rowstride;
361 const uint8_t *pixel = (const uint8_t *)bits + 3 * x;
362 const uint8_t *end = pixel + 3 * width;
363
364 while (pixel < end)
365 {
366 uint32_t b = 0xff000000;
367
368 #ifdef WORDS_BIGENDIAN
369 b |= (READ (image, pixel++) << 16);
370 b |= (READ (image, pixel++) << 8);
371 b |= (READ (image, pixel++));
372 #else
373 b |= (READ (image, pixel++));
374 b |= (READ (image, pixel++) << 8);
375 b |= (READ (image, pixel++) << 16);
376 #endif
377
378 *buffer++ = b;
379 }
380 }
381
382 static void
fetch_scanline_b8g8r8(pixman_image_t * image,int x,int y,int width,uint32_t * buffer,const uint32_t * mask,uint32_t mask_bits)383 fetch_scanline_b8g8r8 (pixman_image_t *image,
384 int x,
385 int y,
386 int width,
387 uint32_t * buffer,
388 const uint32_t *mask,
389 uint32_t mask_bits)
390 {
391 const uint32_t *bits = image->bits.bits + y * image->bits.rowstride;
392 const uint8_t *pixel = (const uint8_t *)bits + 3 * x;
393 const uint8_t *end = pixel + 3 * width;
394
395 while (pixel < end)
396 {
397 uint32_t b = 0xff000000;
398 #ifdef WORDS_BIGENDIAN
399 b |= (READ (image, pixel++));
400 b |= (READ (image, pixel++) << 8);
401 b |= (READ (image, pixel++) << 16);
402 #else
403 b |= (READ (image, pixel++) << 16);
404 b |= (READ (image, pixel++) << 8);
405 b |= (READ (image, pixel++));
406 #endif
407 *buffer++ = b;
408 }
409 }
410
411 static void
fetch_scanline_r5g6b5(pixman_image_t * image,int x,int y,int width,uint32_t * buffer,const uint32_t * mask,uint32_t mask_bits)412 fetch_scanline_r5g6b5 (pixman_image_t *image,
413 int x,
414 int y,
415 int width,
416 uint32_t * buffer,
417 const uint32_t *mask,
418 uint32_t mask_bits)
419 {
420 const uint32_t *bits = image->bits.bits + y * image->bits.rowstride;
421 const uint16_t *pixel = (const uint16_t *)bits + x;
422 const uint16_t *end = pixel + width;
423
424 while (pixel < end)
425 {
426 uint32_t p = READ (image, pixel++);
427 uint32_t r = (((p) << 3) & 0xf8) |
428 (((p) << 5) & 0xfc00) |
429 (((p) << 8) & 0xf80000);
430
431 r |= (r >> 5) & 0x70007;
432 r |= (r >> 6) & 0x300;
433
434 *buffer++ = 0xff000000 | r;
435 }
436 }
437
438 static void
fetch_scanline_b5g6r5(pixman_image_t * image,int x,int y,int width,uint32_t * buffer,const uint32_t * mask,uint32_t mask_bits)439 fetch_scanline_b5g6r5 (pixman_image_t *image,
440 int x,
441 int y,
442 int width,
443 uint32_t * buffer,
444 const uint32_t *mask,
445 uint32_t mask_bits)
446 {
447 const uint32_t *bits = image->bits.bits + y * image->bits.rowstride;
448 const uint16_t *pixel = (const uint16_t *)bits + x;
449 const uint16_t *end = pixel + width;
450
451 while (pixel < end)
452 {
453 uint32_t p = READ (image, pixel++);
454 uint32_t r, g, b;
455
456 b = ((p & 0xf800) | ((p & 0xe000) >> 5)) >> 8;
457 g = ((p & 0x07e0) | ((p & 0x0600) >> 6)) << 5;
458 r = ((p & 0x001c) | ((p & 0x001f) << 5)) << 14;
459
460 *buffer++ = 0xff000000 | r | g | b;
461 }
462 }
463
464 static void
fetch_scanline_a1r5g5b5(pixman_image_t * image,int x,int y,int width,uint32_t * buffer,const uint32_t * mask,uint32_t mask_bits)465 fetch_scanline_a1r5g5b5 (pixman_image_t *image,
466 int x,
467 int y,
468 int width,
469 uint32_t * buffer,
470 const uint32_t *mask,
471 uint32_t mask_bits)
472 {
473 const uint32_t *bits = image->bits.bits + y * image->bits.rowstride;
474 const uint16_t *pixel = (const uint16_t *)bits + x;
475 const uint16_t *end = pixel + width;
476
477 while (pixel < end)
478 {
479 uint32_t p = READ (image, pixel++);
480 uint32_t r, g, b, a;
481
482 a = (uint32_t) ((uint8_t) (0 - ((p & 0x8000) >> 15))) << 24;
483 r = ((p & 0x7c00) | ((p & 0x7000) >> 5)) << 9;
484 g = ((p & 0x03e0) | ((p & 0x0380) >> 5)) << 6;
485 b = ((p & 0x001c) | ((p & 0x001f) << 5)) >> 2;
486
487 *buffer++ = a | r | g | b;
488 }
489 }
490
491 static void
fetch_scanline_x1r5g5b5(pixman_image_t * image,int x,int y,int width,uint32_t * buffer,const uint32_t * mask,uint32_t mask_bits)492 fetch_scanline_x1r5g5b5 (pixman_image_t *image,
493 int x,
494 int y,
495 int width,
496 uint32_t * buffer,
497 const uint32_t *mask,
498 uint32_t mask_bits)
499 {
500 const uint32_t *bits = image->bits.bits + y * image->bits.rowstride;
501 const uint16_t *pixel = (const uint16_t *)bits + x;
502 const uint16_t *end = pixel + width;
503
504 while (pixel < end)
505 {
506 uint32_t p = READ (image, pixel++);
507 uint32_t r, g, b;
508
509 r = ((p & 0x7c00) | ((p & 0x7000) >> 5)) << 9;
510 g = ((p & 0x03e0) | ((p & 0x0380) >> 5)) << 6;
511 b = ((p & 0x001c) | ((p & 0x001f) << 5)) >> 2;
512
513 *buffer++ = 0xff000000 | r | g | b;
514 }
515 }
516
517 static void
fetch_scanline_a1b5g5r5(pixman_image_t * image,int x,int y,int width,uint32_t * buffer,const uint32_t * mask,uint32_t mask_bits)518 fetch_scanline_a1b5g5r5 (pixman_image_t *image,
519 int x,
520 int y,
521 int width,
522 uint32_t * buffer,
523 const uint32_t *mask,
524 uint32_t mask_bits)
525 {
526 const uint32_t *bits = image->bits.bits + y * image->bits.rowstride;
527 const uint16_t *pixel = (const uint16_t *)bits + x;
528 const uint16_t *end = pixel + width;
529 uint32_t r, g, b, a;
530
531 while (pixel < end)
532 {
533 uint32_t p = READ (image, pixel++);
534
535 a = (uint32_t) ((uint8_t) (0 - ((p & 0x8000) >> 15))) << 24;
536 b = ((p & 0x7c00) | ((p & 0x7000) >> 5)) >> 7;
537 g = ((p & 0x03e0) | ((p & 0x0380) >> 5)) << 6;
538 r = ((p & 0x001c) | ((p & 0x001f) << 5)) << 14;
539
540 *buffer++ = a | r | g | b;
541 }
542 }
543
544 static void
fetch_scanline_x1b5g5r5(pixman_image_t * image,int x,int y,int width,uint32_t * buffer,const uint32_t * mask,uint32_t mask_bits)545 fetch_scanline_x1b5g5r5 (pixman_image_t *image,
546 int x,
547 int y,
548 int width,
549 uint32_t * buffer,
550 const uint32_t *mask,
551 uint32_t mask_bits)
552 {
553 const uint32_t *bits = image->bits.bits + y * image->bits.rowstride;
554 const uint16_t *pixel = (const uint16_t *)bits + x;
555 const uint16_t *end = pixel + width;
556
557 while (pixel < end)
558 {
559 uint32_t p = READ (image, pixel++);
560 uint32_t r, g, b;
561
562 b = ((p & 0x7c00) | ((p & 0x7000) >> 5)) >> 7;
563 g = ((p & 0x03e0) | ((p & 0x0380) >> 5)) << 6;
564 r = ((p & 0x001c) | ((p & 0x001f) << 5)) << 14;
565
566 *buffer++ = 0xff000000 | r | g | b;
567 }
568 }
569
570 static void
fetch_scanline_a4r4g4b4(pixman_image_t * image,int x,int y,int width,uint32_t * buffer,const uint32_t * mask,uint32_t mask_bits)571 fetch_scanline_a4r4g4b4 (pixman_image_t *image,
572 int x,
573 int y,
574 int width,
575 uint32_t * buffer,
576 const uint32_t *mask,
577 uint32_t mask_bits)
578 {
579 const uint32_t *bits = image->bits.bits + y * image->bits.rowstride;
580 const uint16_t *pixel = (const uint16_t *)bits + x;
581 const uint16_t *end = pixel + width;
582
583 while (pixel < end)
584 {
585 uint32_t p = READ (image, pixel++);
586 uint32_t r, g, b, a;
587
588 a = ((p & 0xf000) | ((p & 0xf000) >> 4)) << 16;
589 r = ((p & 0x0f00) | ((p & 0x0f00) >> 4)) << 12;
590 g = ((p & 0x00f0) | ((p & 0x00f0) >> 4)) << 8;
591 b = ((p & 0x000f) | ((p & 0x000f) << 4));
592
593 *buffer++ = a | r | g | b;
594 }
595 }
596
597 static void
fetch_scanline_x4r4g4b4(pixman_image_t * image,int x,int y,int width,uint32_t * buffer,const uint32_t * mask,uint32_t mask_bits)598 fetch_scanline_x4r4g4b4 (pixman_image_t *image,
599 int x,
600 int y,
601 int width,
602 uint32_t * buffer,
603 const uint32_t *mask,
604 uint32_t mask_bits)
605 {
606 const uint32_t *bits = image->bits.bits + y * image->bits.rowstride;
607 const uint16_t *pixel = (const uint16_t *)bits + x;
608 const uint16_t *end = pixel + width;
609
610 while (pixel < end)
611 {
612 uint32_t p = READ (image, pixel++);
613 uint32_t r, g, b;
614
615 r = ((p & 0x0f00) | ((p & 0x0f00) >> 4)) << 12;
616 g = ((p & 0x00f0) | ((p & 0x00f0) >> 4)) << 8;
617 b = ((p & 0x000f) | ((p & 0x000f) << 4));
618
619 *buffer++ = 0xff000000 | r | g | b;
620 }
621 }
622
623 static void
fetch_scanline_a4b4g4r4(pixman_image_t * image,int x,int y,int width,uint32_t * buffer,const uint32_t * mask,uint32_t mask_bits)624 fetch_scanline_a4b4g4r4 (pixman_image_t *image,
625 int x,
626 int y,
627 int width,
628 uint32_t * buffer,
629 const uint32_t *mask,
630 uint32_t mask_bits)
631 {
632 const uint32_t *bits = image->bits.bits + y * image->bits.rowstride;
633 const uint16_t *pixel = (const uint16_t *)bits + x;
634 const uint16_t *end = pixel + width;
635
636 while (pixel < end)
637 {
638 uint32_t p = READ (image, pixel++);
639 uint32_t r, g, b, a;
640
641 a = ((p & 0xf000) | ((p & 0xf000) >> 4)) << 16;
642 b = ((p & 0x0f00) | ((p & 0x0f00) >> 4)) >> 4;
643 g = ((p & 0x00f0) | ((p & 0x00f0) >> 4)) << 8;
644 r = ((p & 0x000f) | ((p & 0x000f) << 4)) << 16;
645
646 *buffer++ = a | r | g | b;
647 }
648 }
649
650 static void
fetch_scanline_x4b4g4r4(pixman_image_t * image,int x,int y,int width,uint32_t * buffer,const uint32_t * mask,uint32_t mask_bits)651 fetch_scanline_x4b4g4r4 (pixman_image_t *image,
652 int x,
653 int y,
654 int width,
655 uint32_t * buffer,
656 const uint32_t *mask,
657 uint32_t mask_bits)
658 {
659 const uint32_t *bits = image->bits.bits + y * image->bits.rowstride;
660 const uint16_t *pixel = (const uint16_t *)bits + x;
661 const uint16_t *end = pixel + width;
662
663 while (pixel < end)
664 {
665 uint32_t p = READ (image, pixel++);
666 uint32_t r, g, b;
667
668 b = ((p & 0x0f00) | ((p & 0x0f00) >> 4)) >> 4;
669 g = ((p & 0x00f0) | ((p & 0x00f0) >> 4)) << 8;
670 r = ((p & 0x000f) | ((p & 0x000f) << 4)) << 16;
671
672 *buffer++ = 0xff000000 | r | g | b;
673 }
674 }
675
676 static void
fetch_scanline_a8(pixman_image_t * image,int x,int y,int width,uint32_t * buffer,const uint32_t * mask,uint32_t mask_bits)677 fetch_scanline_a8 (pixman_image_t *image,
678 int x,
679 int y,
680 int width,
681 uint32_t * buffer,
682 const uint32_t *mask,
683 uint32_t mask_bits)
684 {
685 const uint32_t *bits = image->bits.bits + y * image->bits.rowstride;
686 const uint8_t *pixel = (const uint8_t *)bits + x;
687 const uint8_t *end = pixel + width;
688
689 while (pixel < end)
690 *buffer++ = READ (image, pixel++) << 24;
691 }
692
693 static void
fetch_scanline_r3g3b2(pixman_image_t * image,int x,int y,int width,uint32_t * buffer,const uint32_t * mask,uint32_t mask_bits)694 fetch_scanline_r3g3b2 (pixman_image_t *image,
695 int x,
696 int y,
697 int width,
698 uint32_t * buffer,
699 const uint32_t *mask,
700 uint32_t mask_bits)
701 {
702 const uint32_t *bits = image->bits.bits + y * image->bits.rowstride;
703 const uint8_t *pixel = (const uint8_t *)bits + x;
704 const uint8_t *end = pixel + width;
705
706 while (pixel < end)
707 {
708 uint32_t p = READ (image, pixel++);
709 uint32_t r, g, b;
710
711 r = ((p & 0xe0) | ((p & 0xe0) >> 3) | ((p & 0xc0) >> 6)) << 16;
712 g = ((p & 0x1c) | ((p & 0x18) >> 3) | ((p & 0x1c) << 3)) << 8;
713 b = (((p & 0x03) ) |
714 ((p & 0x03) << 2) |
715 ((p & 0x03) << 4) |
716 ((p & 0x03) << 6));
717
718 *buffer++ = 0xff000000 | r | g | b;
719 }
720 }
721
722 static void
fetch_scanline_b2g3r3(pixman_image_t * image,int x,int y,int width,uint32_t * buffer,const uint32_t * mask,uint32_t mask_bits)723 fetch_scanline_b2g3r3 (pixman_image_t *image,
724 int x,
725 int y,
726 int width,
727 uint32_t * buffer,
728 const uint32_t *mask,
729 uint32_t mask_bits)
730 {
731 const uint32_t *bits = image->bits.bits + y * image->bits.rowstride;
732 const uint8_t *pixel = (const uint8_t *)bits + x;
733 const uint8_t *end = pixel + width;
734
735 while (pixel < end)
736 {
737 uint32_t p = READ (image, pixel++);
738 uint32_t r, g, b;
739
740 b = p & 0xc0;
741 b |= b >> 2;
742 b |= b >> 4;
743 b &= 0xff;
744
745 g = (p & 0x38) << 10;
746 g |= g >> 3;
747 g |= g >> 6;
748 g &= 0xff00;
749
750 r = (p & 0x7) << 21;
751 r |= r >> 3;
752 r |= r >> 6;
753 r &= 0xff0000;
754
755 *buffer++ = 0xff000000 | r | g | b;
756 }
757 }
758
759 static void
fetch_scanline_a2r2g2b2(pixman_image_t * image,int x,int y,int width,uint32_t * buffer,const uint32_t * mask,uint32_t mask_bits)760 fetch_scanline_a2r2g2b2 (pixman_image_t *image,
761 int x,
762 int y,
763 int width,
764 uint32_t * buffer,
765 const uint32_t *mask,
766 uint32_t mask_bits)
767 {
768 const uint32_t *bits = image->bits.bits + y * image->bits.rowstride;
769 const uint8_t *pixel = (const uint8_t *)bits + x;
770 const uint8_t *end = pixel + width;
771
772 while (pixel < end)
773 {
774 uint32_t p = READ (image, pixel++);
775 uint32_t a, r, g, b;
776
777 a = ((p & 0xc0) * 0x55) << 18;
778 r = ((p & 0x30) * 0x55) << 12;
779 g = ((p & 0x0c) * 0x55) << 6;
780 b = ((p & 0x03) * 0x55);
781
782 *buffer++ = a | r | g | b;
783 }
784 }
785
786 static void
fetch_scanline_a2b2g2r2(pixman_image_t * image,int x,int y,int width,uint32_t * buffer,const uint32_t * mask,uint32_t mask_bits)787 fetch_scanline_a2b2g2r2 (pixman_image_t *image,
788 int x,
789 int y,
790 int width,
791 uint32_t * buffer,
792 const uint32_t *mask,
793 uint32_t mask_bits)
794 {
795 const uint32_t *bits = image->bits.bits + y * image->bits.rowstride;
796 const uint8_t *pixel = (const uint8_t *)bits + x;
797 const uint8_t *end = pixel + width;
798
799 while (pixel < end)
800 {
801 uint32_t p = READ (image, pixel++);
802 uint32_t a, r, g, b;
803
804 a = ((p & 0xc0) * 0x55) << 18;
805 b = ((p & 0x30) * 0x55) >> 4;
806 g = ((p & 0x0c) * 0x55) << 6;
807 r = ((p & 0x03) * 0x55) << 16;
808
809 *buffer++ = a | r | g | b;
810 }
811 }
812
813 static void
fetch_scanline_c8(pixman_image_t * image,int x,int y,int width,uint32_t * buffer,const uint32_t * mask,uint32_t mask_bits)814 fetch_scanline_c8 (pixman_image_t *image,
815 int x,
816 int y,
817 int width,
818 uint32_t * buffer,
819 const uint32_t *mask,
820 uint32_t mask_bits)
821 {
822 const uint32_t *bits = image->bits.bits + y * image->bits.rowstride;
823 const pixman_indexed_t * indexed = image->bits.indexed;
824 const uint8_t *pixel = (const uint8_t *)bits + x;
825 const uint8_t *end = pixel + width;
826
827 while (pixel < end)
828 {
829 uint32_t p = READ (image, pixel++);
830
831 *buffer++ = indexed->rgba[p];
832 }
833 }
834
835 static void
fetch_scanline_x4a4(pixman_image_t * image,int x,int y,int width,uint32_t * buffer,const uint32_t * mask,uint32_t mask_bits)836 fetch_scanline_x4a4 (pixman_image_t *image,
837 int x,
838 int y,
839 int width,
840 uint32_t * buffer,
841 const uint32_t *mask,
842 uint32_t mask_bits)
843 {
844 const uint32_t *bits = image->bits.bits + y * image->bits.rowstride;
845 const uint8_t *pixel = (const uint8_t *)bits + x;
846 const uint8_t *end = pixel + width;
847
848 while (pixel < end)
849 {
850 uint8_t p = READ (image, pixel++) & 0xf;
851
852 *buffer++ = (p | (p << 4)) << 24;
853 }
854 }
855
856 #define FETCH_8(img,l,o) (READ (img, (((uint8_t *)(l)) + ((o) >> 3))))
857 #ifdef WORDS_BIGENDIAN
858 #define FETCH_4(img,l,o) \
859 (((4 * (o)) & 4) ? (FETCH_8 (img,l, 4 * (o)) & 0xf) : (FETCH_8 (img,l,(4 * (o))) >> 4))
860 #else
861 #define FETCH_4(img,l,o) \
862 (((4 * (o)) & 4) ? (FETCH_8 (img, l, 4 * (o)) >> 4) : (FETCH_8 (img, l, (4 * (o))) & 0xf))
863 #endif
864
865 static void
fetch_scanline_a4(pixman_image_t * image,int x,int y,int width,uint32_t * buffer,const uint32_t * mask,uint32_t mask_bits)866 fetch_scanline_a4 (pixman_image_t *image,
867 int x,
868 int y,
869 int width,
870 uint32_t * buffer,
871 const uint32_t *mask,
872 uint32_t mask_bits)
873 {
874 const uint32_t *bits = image->bits.bits + y * image->bits.rowstride;
875 int i;
876
877 for (i = 0; i < width; ++i)
878 {
879 uint32_t p = FETCH_4 (image, bits, i + x);
880
881 p |= p << 4;
882
883 *buffer++ = p << 24;
884 }
885 }
886
887 static void
fetch_scanline_r1g2b1(pixman_image_t * image,int x,int y,int width,uint32_t * buffer,const uint32_t * mask,uint32_t mask_bits)888 fetch_scanline_r1g2b1 (pixman_image_t *image,
889 int x,
890 int y,
891 int width,
892 uint32_t * buffer,
893 const uint32_t *mask,
894 uint32_t mask_bits)
895 {
896 const uint32_t *bits = image->bits.bits + y * image->bits.rowstride;
897 int i;
898
899 for (i = 0; i < width; ++i)
900 {
901 uint32_t p = FETCH_4 (image, bits, i + x);
902 uint32_t r, g, b;
903
904 r = ((p & 0x8) * 0xff) << 13;
905 g = ((p & 0x6) * 0x55) << 7;
906 b = ((p & 0x1) * 0xff);
907
908 *buffer++ = 0xff000000 | r | g | b;
909 }
910 }
911
912 static void
fetch_scanline_b1g2r1(pixman_image_t * image,int x,int y,int width,uint32_t * buffer,const uint32_t * mask,uint32_t mask_bits)913 fetch_scanline_b1g2r1 (pixman_image_t *image,
914 int x,
915 int y,
916 int width,
917 uint32_t * buffer,
918 const uint32_t *mask,
919 uint32_t mask_bits)
920 {
921 const uint32_t *bits = image->bits.bits + y * image->bits.rowstride;
922 int i;
923
924 for (i = 0; i < width; ++i)
925 {
926 uint32_t p = FETCH_4 (image, bits, i + x);
927 uint32_t r, g, b;
928
929 b = ((p & 0x8) * 0xff) >> 3;
930 g = ((p & 0x6) * 0x55) << 7;
931 r = ((p & 0x1) * 0xff) << 16;
932
933 *buffer++ = 0xff000000 | r | g | b;
934 }
935 }
936
937 static void
fetch_scanline_a1r1g1b1(pixman_image_t * image,int x,int y,int width,uint32_t * buffer,const uint32_t * mask,uint32_t mask_bits)938 fetch_scanline_a1r1g1b1 (pixman_image_t *image,
939 int x,
940 int y,
941 int width,
942 uint32_t * buffer,
943 const uint32_t *mask,
944 uint32_t mask_bits)
945 {
946 uint32_t a, r, g, b;
947 const uint32_t *bits = image->bits.bits + y * image->bits.rowstride;
948 int i;
949
950 for (i = 0; i < width; ++i)
951 {
952 uint32_t p = FETCH_4 (image, bits, i + x);
953
954 a = ((p & 0x8) * 0xff) << 21;
955 r = ((p & 0x4) * 0xff) << 14;
956 g = ((p & 0x2) * 0xff) << 7;
957 b = ((p & 0x1) * 0xff);
958
959 *buffer++ = a | r | g | b;
960 }
961 }
962
963 static void
fetch_scanline_a1b1g1r1(pixman_image_t * image,int x,int y,int width,uint32_t * buffer,const uint32_t * mask,uint32_t mask_bits)964 fetch_scanline_a1b1g1r1 (pixman_image_t *image,
965 int x,
966 int y,
967 int width,
968 uint32_t * buffer,
969 const uint32_t *mask,
970 uint32_t mask_bits)
971 {
972 const uint32_t *bits = image->bits.bits + y * image->bits.rowstride;
973 int i;
974
975 for (i = 0; i < width; ++i)
976 {
977 uint32_t p = FETCH_4 (image, bits, i + x);
978 uint32_t a, r, g, b;
979
980 a = ((p & 0x8) * 0xff) << 21;
981 b = ((p & 0x4) * 0xff) >> 2;
982 g = ((p & 0x2) * 0xff) << 7;
983 r = ((p & 0x1) * 0xff) << 16;
984
985 *buffer++ = a | r | g | b;
986 }
987 }
988
989 static void
fetch_scanline_c4(pixman_image_t * image,int x,int y,int width,uint32_t * buffer,const uint32_t * mask,uint32_t mask_bits)990 fetch_scanline_c4 (pixman_image_t *image,
991 int x,
992 int y,
993 int width,
994 uint32_t * buffer,
995 const uint32_t *mask,
996 uint32_t mask_bits)
997 {
998 const uint32_t *bits = image->bits.bits + y * image->bits.rowstride;
999 const pixman_indexed_t * indexed = image->bits.indexed;
1000 int i;
1001
1002 for (i = 0; i < width; ++i)
1003 {
1004 uint32_t p = FETCH_4 (image, bits, i + x);
1005
1006 *buffer++ = indexed->rgba[p];
1007 }
1008 }
1009
1010 static void
fetch_scanline_a1(pixman_image_t * image,int x,int y,int width,uint32_t * buffer,const uint32_t * mask,uint32_t mask_bits)1011 fetch_scanline_a1 (pixman_image_t *image,
1012 int x,
1013 int y,
1014 int width,
1015 uint32_t * buffer,
1016 const uint32_t *mask,
1017 uint32_t mask_bits)
1018 {
1019 const uint32_t *bits = image->bits.bits + y * image->bits.rowstride;
1020 int i;
1021
1022 for (i = 0; i < width; ++i)
1023 {
1024 uint32_t p = READ (image, bits + ((i + x) >> 5));
1025 uint32_t a;
1026
1027 #ifdef WORDS_BIGENDIAN
1028 a = p >> (0x1f - ((i + x) & 0x1f));
1029 #else
1030 a = p >> ((i + x) & 0x1f);
1031 #endif
1032 a = a & 1;
1033 a |= a << 1;
1034 a |= a << 2;
1035 a |= a << 4;
1036
1037 *buffer++ = a << 24;
1038 }
1039 }
1040
1041 static void
fetch_scanline_g1(pixman_image_t * image,int x,int y,int width,uint32_t * buffer,const uint32_t * mask,uint32_t mask_bits)1042 fetch_scanline_g1 (pixman_image_t *image,
1043 int x,
1044 int y,
1045 int width,
1046 uint32_t * buffer,
1047 const uint32_t *mask,
1048 uint32_t mask_bits)
1049 {
1050 const uint32_t *bits = image->bits.bits + y * image->bits.rowstride;
1051 const pixman_indexed_t * indexed = image->bits.indexed;
1052 int i;
1053
1054 for (i = 0; i < width; ++i)
1055 {
1056 uint32_t p = READ (image, bits + ((i + x) >> 5));
1057 uint32_t a;
1058
1059 #ifdef WORDS_BIGENDIAN
1060 a = p >> (0x1f - ((i + x) & 0x1f));
1061 #else
1062 a = p >> ((i + x) & 0x1f);
1063 #endif
1064 a = a & 1;
1065
1066 *buffer++ = indexed->rgba[a];
1067 }
1068 }
1069
1070 static void
fetch_scanline_yuy2(pixman_image_t * image,int x,int line,int width,uint32_t * buffer,const uint32_t * mask,uint32_t mask_bits)1071 fetch_scanline_yuy2 (pixman_image_t *image,
1072 int x,
1073 int line,
1074 int width,
1075 uint32_t * buffer,
1076 const uint32_t *mask,
1077 uint32_t mask_bits)
1078 {
1079 const uint32_t *bits = image->bits.bits + image->bits.rowstride * line;
1080 int i;
1081
1082 for (i = 0; i < width; i++)
1083 {
1084 int16_t y, u, v;
1085 int32_t r, g, b;
1086
1087 y = ((uint8_t *) bits)[(x + i) << 1] - 16;
1088 u = ((uint8_t *) bits)[(((x + i) << 1) & - 4) + 1] - 128;
1089 v = ((uint8_t *) bits)[(((x + i) << 1) & - 4) + 3] - 128;
1090
1091 /* R = 1.164(Y - 16) + 1.596(V - 128) */
1092 r = 0x012b27 * y + 0x019a2e * v;
1093 /* G = 1.164(Y - 16) - 0.813(V - 128) - 0.391(U - 128) */
1094 g = 0x012b27 * y - 0x00d0f2 * v - 0x00647e * u;
1095 /* B = 1.164(Y - 16) + 2.018(U - 128) */
1096 b = 0x012b27 * y + 0x0206a2 * u;
1097
1098 *buffer++ = 0xff000000 |
1099 (r >= 0 ? r < 0x1000000 ? r & 0xff0000 : 0xff0000 : 0) |
1100 (g >= 0 ? g < 0x1000000 ? (g >> 8) & 0x00ff00 : 0x00ff00 : 0) |
1101 (b >= 0 ? b < 0x1000000 ? (b >> 16) & 0x0000ff : 0x0000ff : 0);
1102 }
1103 }
1104
1105 static void
fetch_scanline_yv12(pixman_image_t * image,int x,int line,int width,uint32_t * buffer,const uint32_t * mask,uint32_t mask_bits)1106 fetch_scanline_yv12 (pixman_image_t *image,
1107 int x,
1108 int line,
1109 int width,
1110 uint32_t * buffer,
1111 const uint32_t *mask,
1112 uint32_t mask_bits)
1113 {
1114 YV12_SETUP (image);
1115 uint8_t *y_line = YV12_Y (line);
1116 uint8_t *u_line = YV12_U (line);
1117 uint8_t *v_line = YV12_V (line);
1118 int i;
1119
1120 for (i = 0; i < width; i++)
1121 {
1122 int16_t y, u, v;
1123 int32_t r, g, b;
1124
1125 y = y_line[x + i] - 16;
1126 u = u_line[(x + i) >> 1] - 128;
1127 v = v_line[(x + i) >> 1] - 128;
1128
1129 /* R = 1.164(Y - 16) + 1.596(V - 128) */
1130 r = 0x012b27 * y + 0x019a2e * v;
1131 /* G = 1.164(Y - 16) - 0.813(V - 128) - 0.391(U - 128) */
1132 g = 0x012b27 * y - 0x00d0f2 * v - 0x00647e * u;
1133 /* B = 1.164(Y - 16) + 2.018(U - 128) */
1134 b = 0x012b27 * y + 0x0206a2 * u;
1135
1136 *buffer++ = 0xff000000 |
1137 (r >= 0 ? r < 0x1000000 ? r & 0xff0000 : 0xff0000 : 0) |
1138 (g >= 0 ? g < 0x1000000 ? (g >> 8) & 0x00ff00 : 0x00ff00 : 0) |
1139 (b >= 0 ? b < 0x1000000 ? (b >> 16) & 0x0000ff : 0x0000ff : 0);
1140 }
1141 }
1142
1143 /**************************** Pixel wise fetching *****************************/
1144
1145 /* Despite the type, expects a uint64_t buffer */
1146 static uint64_t
fetch_pixel_a2r10g10b10(bits_image_t * image,int offset,int line)1147 fetch_pixel_a2r10g10b10 (bits_image_t *image,
1148 int offset,
1149 int line)
1150 {
1151 uint32_t *bits = image->bits + line * image->rowstride;
1152 uint32_t p = READ (image, bits + offset);
1153 uint64_t a = p >> 30;
1154 uint64_t r = (p >> 20) & 0x3ff;
1155 uint64_t g = (p >> 10) & 0x3ff;
1156 uint64_t b = p & 0x3ff;
1157
1158 r = r << 6 | r >> 4;
1159 g = g << 6 | g >> 4;
1160 b = b << 6 | b >> 4;
1161
1162 a <<= 14;
1163 a |= a >> 2;
1164 a |= a >> 4;
1165 a |= a >> 8;
1166
1167 return a << 48 | r << 32 | g << 16 | b;
1168 }
1169
1170 /* Despite the type, this function expects a uint64_t buffer */
1171 static uint64_t
fetch_pixel_x2r10g10b10(bits_image_t * image,int offset,int line)1172 fetch_pixel_x2r10g10b10 (bits_image_t *image,
1173 int offset,
1174 int line)
1175 {
1176 uint32_t *bits = image->bits + line * image->rowstride;
1177 uint32_t p = READ (image, bits + offset);
1178 uint64_t r = (p >> 20) & 0x3ff;
1179 uint64_t g = (p >> 10) & 0x3ff;
1180 uint64_t b = p & 0x3ff;
1181
1182 r = r << 6 | r >> 4;
1183 g = g << 6 | g >> 4;
1184 b = b << 6 | b >> 4;
1185
1186 return 0xffffULL << 48 | r << 32 | g << 16 | b;
1187 }
1188
1189 /* Despite the type, expects a uint64_t buffer */
1190 static uint64_t
fetch_pixel_a2b10g10r10(bits_image_t * image,int offset,int line)1191 fetch_pixel_a2b10g10r10 (bits_image_t *image,
1192 int offset,
1193 int line)
1194 {
1195 uint32_t *bits = image->bits + line * image->rowstride;
1196 uint32_t p = READ (image, bits + offset);
1197 uint64_t a = p >> 30;
1198 uint64_t b = (p >> 20) & 0x3ff;
1199 uint64_t g = (p >> 10) & 0x3ff;
1200 uint64_t r = p & 0x3ff;
1201
1202 r = r << 6 | r >> 4;
1203 g = g << 6 | g >> 4;
1204 b = b << 6 | b >> 4;
1205
1206 a <<= 14;
1207 a |= a >> 2;
1208 a |= a >> 4;
1209 a |= a >> 8;
1210
1211 return a << 48 | r << 32 | g << 16 | b;
1212 }
1213
1214 /* Despite the type, this function expects a uint64_t buffer */
1215 static uint64_t
fetch_pixel_x2b10g10r10(bits_image_t * image,int offset,int line)1216 fetch_pixel_x2b10g10r10 (bits_image_t *image,
1217 int offset,
1218 int line)
1219 {
1220 uint32_t *bits = image->bits + line * image->rowstride;
1221 uint32_t p = READ (image, bits + offset);
1222 uint64_t b = (p >> 20) & 0x3ff;
1223 uint64_t g = (p >> 10) & 0x3ff;
1224 uint64_t r = p & 0x3ff;
1225
1226 r = r << 6 | r >> 4;
1227 g = g << 6 | g >> 4;
1228 b = b << 6 | b >> 4;
1229
1230 return 0xffffULL << 48 | r << 32 | g << 16 | b;
1231 }
1232
1233 static uint32_t
fetch_pixel_a8r8g8b8(bits_image_t * image,int offset,int line)1234 fetch_pixel_a8r8g8b8 (bits_image_t *image,
1235 int offset,
1236 int line)
1237 {
1238 uint32_t *bits = image->bits + line * image->rowstride;
1239 return READ (image, (uint32_t *)bits + offset);
1240 }
1241
1242 static uint32_t
fetch_pixel_x8r8g8b8(bits_image_t * image,int offset,int line)1243 fetch_pixel_x8r8g8b8 (bits_image_t *image,
1244 int offset,
1245 int line)
1246 {
1247 uint32_t *bits = image->bits + line * image->rowstride;
1248
1249 return READ (image, (uint32_t *)bits + offset) | 0xff000000;
1250 }
1251
1252 static uint32_t
fetch_pixel_a8b8g8r8(bits_image_t * image,int offset,int line)1253 fetch_pixel_a8b8g8r8 (bits_image_t *image,
1254 int offset,
1255 int line)
1256 {
1257 uint32_t *bits = image->bits + line * image->rowstride;
1258 uint32_t pixel = READ (image, (uint32_t *)bits + offset);
1259
1260 return ((pixel & 0xff000000) |
1261 ((pixel >> 16) & 0xff) |
1262 (pixel & 0x0000ff00) |
1263 ((pixel & 0xff) << 16));
1264 }
1265
1266 static uint32_t
fetch_pixel_x8b8g8r8(bits_image_t * image,int offset,int line)1267 fetch_pixel_x8b8g8r8 (bits_image_t *image,
1268 int offset,
1269 int line)
1270 {
1271 uint32_t *bits = image->bits + line * image->rowstride;
1272 uint32_t pixel = READ (image, (uint32_t *)bits + offset);
1273
1274 return ((0xff000000) |
1275 ((pixel >> 16) & 0xff) |
1276 (pixel & 0x0000ff00) |
1277 ((pixel & 0xff) << 16));
1278 }
1279
1280 static uint32_t
fetch_pixel_b8g8r8a8(bits_image_t * image,int offset,int line)1281 fetch_pixel_b8g8r8a8 (bits_image_t *image,
1282 int offset,
1283 int line)
1284 {
1285 uint32_t *bits = image->bits + line * image->rowstride;
1286 uint32_t pixel = READ (image, (uint32_t *)bits + offset);
1287
1288 return ((pixel & 0xff000000) >> 24 |
1289 (pixel & 0x00ff0000) >> 8 |
1290 (pixel & 0x0000ff00) << 8 |
1291 (pixel & 0x000000ff) << 24);
1292 }
1293
1294 static uint32_t
fetch_pixel_b8g8r8x8(bits_image_t * image,int offset,int line)1295 fetch_pixel_b8g8r8x8 (bits_image_t *image,
1296 int offset,
1297 int line)
1298 {
1299 uint32_t *bits = image->bits + line * image->rowstride;
1300 uint32_t pixel = READ (image, (uint32_t *)bits + offset);
1301
1302 return ((0xff000000) |
1303 (pixel & 0xff000000) >> 24 |
1304 (pixel & 0x00ff0000) >> 8 |
1305 (pixel & 0x0000ff00) << 8);
1306 }
1307
1308 static uint32_t
fetch_pixel_r8g8b8(bits_image_t * image,int offset,int line)1309 fetch_pixel_r8g8b8 (bits_image_t *image,
1310 int offset,
1311 int line)
1312 {
1313 uint32_t *bits = image->bits + line * image->rowstride;
1314 uint8_t *pixel = ((uint8_t *) bits) + (offset * 3);
1315
1316 #ifdef WORDS_BIGENDIAN
1317 return (0xff000000 |
1318 (READ (image, pixel + 0) << 16) |
1319 (READ (image, pixel + 1) << 8) |
1320 (READ (image, pixel + 2)));
1321 #else
1322 return (0xff000000 |
1323 (READ (image, pixel + 2) << 16) |
1324 (READ (image, pixel + 1) << 8) |
1325 (READ (image, pixel + 0)));
1326 #endif
1327 }
1328
1329 static uint32_t
fetch_pixel_b8g8r8(bits_image_t * image,int offset,int line)1330 fetch_pixel_b8g8r8 (bits_image_t *image,
1331 int offset,
1332 int line)
1333 {
1334 uint32_t *bits = image->bits + line * image->rowstride;
1335 uint8_t *pixel = ((uint8_t *) bits) + (offset * 3);
1336 #ifdef WORDS_BIGENDIAN
1337 return (0xff000000 |
1338 (READ (image, pixel + 2) << 16) |
1339 (READ (image, pixel + 1) << 8) |
1340 (READ (image, pixel + 0)));
1341 #else
1342 return (0xff000000 |
1343 (READ (image, pixel + 0) << 16) |
1344 (READ (image, pixel + 1) << 8) |
1345 (READ (image, pixel + 2)));
1346 #endif
1347 }
1348
1349 static uint32_t
fetch_pixel_r5g6b5(bits_image_t * image,int offset,int line)1350 fetch_pixel_r5g6b5 (bits_image_t *image,
1351 int offset,
1352 int line)
1353 {
1354 uint32_t *bits = image->bits + line * image->rowstride;
1355 uint32_t pixel = READ (image, (uint16_t *) bits + offset);
1356 uint32_t r, g, b;
1357
1358 r = ((pixel & 0xf800) | ((pixel & 0xe000) >> 5)) << 8;
1359 g = ((pixel & 0x07e0) | ((pixel & 0x0600) >> 6)) << 5;
1360 b = ((pixel & 0x001c) | ((pixel & 0x001f) << 5)) >> 2;
1361
1362 return (0xff000000 | r | g | b);
1363 }
1364
1365 static uint32_t
fetch_pixel_b5g6r5(bits_image_t * image,int offset,int line)1366 fetch_pixel_b5g6r5 (bits_image_t *image,
1367 int offset,
1368 int line)
1369 {
1370 uint32_t r, g, b;
1371 uint32_t *bits = image->bits + line * image->rowstride;
1372 uint32_t pixel = READ (image, (uint16_t *) bits + offset);
1373
1374 b = ((pixel & 0xf800) | ((pixel & 0xe000) >> 5)) >> 8;
1375 g = ((pixel & 0x07e0) | ((pixel & 0x0600) >> 6)) << 5;
1376 r = ((pixel & 0x001c) | ((pixel & 0x001f) << 5)) << 14;
1377
1378 return (0xff000000 | r | g | b);
1379 }
1380
1381 static uint32_t
fetch_pixel_a1r5g5b5(bits_image_t * image,int offset,int line)1382 fetch_pixel_a1r5g5b5 (bits_image_t *image,
1383 int offset,
1384 int line)
1385 {
1386 uint32_t *bits = image->bits + line * image->rowstride;
1387 uint32_t pixel = READ (image, (uint16_t *) bits + offset);
1388 uint32_t a, r, g, b;
1389
1390 a = (uint32_t) ((uint8_t) (0 - ((pixel & 0x8000) >> 15))) << 24;
1391 r = ((pixel & 0x7c00) | ((pixel & 0x7000) >> 5)) << 9;
1392 g = ((pixel & 0x03e0) | ((pixel & 0x0380) >> 5)) << 6;
1393 b = ((pixel & 0x001c) | ((pixel & 0x001f) << 5)) >> 2;
1394
1395 return (a | r | g | b);
1396 }
1397
1398 static uint32_t
fetch_pixel_x1r5g5b5(bits_image_t * image,int offset,int line)1399 fetch_pixel_x1r5g5b5 (bits_image_t *image,
1400 int offset,
1401 int line)
1402 {
1403 uint32_t *bits = image->bits + line * image->rowstride;
1404 uint32_t pixel = READ (image, (uint16_t *) bits + offset);
1405 uint32_t r, g, b;
1406
1407 r = ((pixel & 0x7c00) | ((pixel & 0x7000) >> 5)) << 9;
1408 g = ((pixel & 0x03e0) | ((pixel & 0x0380) >> 5)) << 6;
1409 b = ((pixel & 0x001c) | ((pixel & 0x001f) << 5)) >> 2;
1410
1411 return (0xff000000 | r | g | b);
1412 }
1413
1414 static uint32_t
fetch_pixel_a1b5g5r5(bits_image_t * image,int offset,int line)1415 fetch_pixel_a1b5g5r5 (bits_image_t *image,
1416 int offset,
1417 int line)
1418 {
1419 uint32_t *bits = image->bits + line * image->rowstride;
1420 uint32_t pixel = READ (image, (uint16_t *) bits + offset);
1421 uint32_t a, r, g, b;
1422
1423 a = (uint32_t) ((uint8_t) (0 - ((pixel & 0x8000) >> 15))) << 24;
1424 b = ((pixel & 0x7c00) | ((pixel & 0x7000) >> 5)) >> 7;
1425 g = ((pixel & 0x03e0) | ((pixel & 0x0380) >> 5)) << 6;
1426 r = ((pixel & 0x001c) | ((pixel & 0x001f) << 5)) << 14;
1427
1428 return (a | r | g | b);
1429 }
1430
1431 static uint32_t
fetch_pixel_x1b5g5r5(bits_image_t * image,int offset,int line)1432 fetch_pixel_x1b5g5r5 (bits_image_t *image,
1433 int offset,
1434 int line)
1435 {
1436 uint32_t *bits = image->bits + line * image->rowstride;
1437 uint32_t pixel = READ (image, (uint16_t *) bits + offset);
1438 uint32_t r, g, b;
1439
1440 b = ((pixel & 0x7c00) | ((pixel & 0x7000) >> 5)) >> 7;
1441 g = ((pixel & 0x03e0) | ((pixel & 0x0380) >> 5)) << 6;
1442 r = ((pixel & 0x001c) | ((pixel & 0x001f) << 5)) << 14;
1443
1444 return (0xff000000 | r | g | b);
1445 }
1446
1447 static uint32_t
fetch_pixel_a4r4g4b4(bits_image_t * image,int offset,int line)1448 fetch_pixel_a4r4g4b4 (bits_image_t *image,
1449 int offset,
1450 int line)
1451 {
1452 uint32_t *bits = image->bits + line * image->rowstride;
1453 uint32_t pixel = READ (image, (uint16_t *) bits + offset);
1454 uint32_t a, r, g, b;
1455
1456 a = ((pixel & 0xf000) | ((pixel & 0xf000) >> 4)) << 16;
1457 r = ((pixel & 0x0f00) | ((pixel & 0x0f00) >> 4)) << 12;
1458 g = ((pixel & 0x00f0) | ((pixel & 0x00f0) >> 4)) << 8;
1459 b = ((pixel & 0x000f) | ((pixel & 0x000f) << 4));
1460
1461 return (a | r | g | b);
1462 }
1463
1464 static uint32_t
fetch_pixel_x4r4g4b4(bits_image_t * image,int offset,int line)1465 fetch_pixel_x4r4g4b4 (bits_image_t *image,
1466 int offset,
1467 int line)
1468 {
1469 uint32_t *bits = image->bits + line * image->rowstride;
1470 uint32_t pixel = READ (image, (uint16_t *) bits + offset);
1471 uint32_t r, g, b;
1472
1473 r = ((pixel & 0x0f00) | ((pixel & 0x0f00) >> 4)) << 12;
1474 g = ((pixel & 0x00f0) | ((pixel & 0x00f0) >> 4)) << 8;
1475 b = ((pixel & 0x000f) | ((pixel & 0x000f) << 4));
1476
1477 return (0xff000000 | r | g | b);
1478 }
1479
1480 static uint32_t
fetch_pixel_a4b4g4r4(bits_image_t * image,int offset,int line)1481 fetch_pixel_a4b4g4r4 (bits_image_t *image,
1482 int offset,
1483 int line)
1484 {
1485 uint32_t *bits = image->bits + line * image->rowstride;
1486 uint32_t pixel = READ (image, (uint16_t *) bits + offset);
1487 uint32_t a, r, g, b;
1488
1489 a = ((pixel & 0xf000) | ((pixel & 0xf000) >> 4)) << 16;
1490 b = ((pixel & 0x0f00) | ((pixel & 0x0f00) >> 4)) >> 4;
1491 g = ((pixel & 0x00f0) | ((pixel & 0x00f0) >> 4)) << 8;
1492 r = ((pixel & 0x000f) | ((pixel & 0x000f) << 4)) << 16;
1493
1494 return (a | r | g | b);
1495 }
1496
1497 static uint32_t
fetch_pixel_x4b4g4r4(bits_image_t * image,int offset,int line)1498 fetch_pixel_x4b4g4r4 (bits_image_t *image,
1499 int offset,
1500 int line)
1501 {
1502 uint32_t *bits = image->bits + line * image->rowstride;
1503 uint32_t pixel = READ (image, (uint16_t *) bits + offset);
1504 uint32_t r, g, b;
1505
1506 b = ((pixel & 0x0f00) | ((pixel & 0x0f00) >> 4)) >> 4;
1507 g = ((pixel & 0x00f0) | ((pixel & 0x00f0) >> 4)) << 8;
1508 r = ((pixel & 0x000f) | ((pixel & 0x000f) << 4)) << 16;
1509
1510 return (0xff000000 | r | g | b);
1511 }
1512
1513 static uint32_t
fetch_pixel_a8(bits_image_t * image,int offset,int line)1514 fetch_pixel_a8 (bits_image_t *image,
1515 int offset,
1516 int line)
1517 {
1518 uint32_t *bits = image->bits + line * image->rowstride;
1519 uint32_t pixel = READ (image, (uint8_t *) bits + offset);
1520
1521 return pixel << 24;
1522 }
1523
1524 static uint32_t
fetch_pixel_r3g3b2(bits_image_t * image,int offset,int line)1525 fetch_pixel_r3g3b2 (bits_image_t *image,
1526 int offset,
1527 int line)
1528 {
1529 uint32_t *bits = image->bits + line * image->rowstride;
1530 uint32_t pixel = READ (image, (uint8_t *) bits + offset);
1531 uint32_t r, g, b;
1532
1533 r = ((pixel & 0xe0) |
1534 ((pixel & 0xe0) >> 3) |
1535 ((pixel & 0xc0) >> 6)) << 16;
1536
1537 g = ((pixel & 0x1c) |
1538 ((pixel & 0x18) >> 3) |
1539 ((pixel & 0x1c) << 3)) << 8;
1540
1541 b = (((pixel & 0x03) ) |
1542 ((pixel & 0x03) << 2) |
1543 ((pixel & 0x03) << 4) |
1544 ((pixel & 0x03) << 6));
1545
1546 return (0xff000000 | r | g | b);
1547 }
1548
1549 static uint32_t
fetch_pixel_b2g3r3(bits_image_t * image,int offset,int line)1550 fetch_pixel_b2g3r3 (bits_image_t *image,
1551 int offset,
1552 int line)
1553 {
1554 uint32_t *bits = image->bits + line * image->rowstride;
1555 uint32_t p = READ (image, (uint8_t *) bits + offset);
1556 uint32_t r, g, b;
1557
1558 b = p & 0xc0;
1559 b |= b >> 2;
1560 b |= b >> 4;
1561 b &= 0xff;
1562
1563 g = (p & 0x38) << 10;
1564 g |= g >> 3;
1565 g |= g >> 6;
1566 g &= 0xff00;
1567
1568 r = (p & 0x7) << 21;
1569 r |= r >> 3;
1570 r |= r >> 6;
1571 r &= 0xff0000;
1572
1573 return 0xff000000 | r | g | b;
1574 }
1575
1576 static uint32_t
fetch_pixel_a2r2g2b2(bits_image_t * image,int offset,int line)1577 fetch_pixel_a2r2g2b2 (bits_image_t *image,
1578 int offset,
1579 int line)
1580 {
1581 uint32_t *bits = image->bits + line * image->rowstride;
1582 uint32_t pixel = READ (image, (uint8_t *) bits + offset);
1583 uint32_t a, r, g, b;
1584
1585 a = ((pixel & 0xc0) * 0x55) << 18;
1586 r = ((pixel & 0x30) * 0x55) << 12;
1587 g = ((pixel & 0x0c) * 0x55) << 6;
1588 b = ((pixel & 0x03) * 0x55);
1589
1590 return a | r | g | b;
1591 }
1592
1593 static uint32_t
fetch_pixel_a2b2g2r2(bits_image_t * image,int offset,int line)1594 fetch_pixel_a2b2g2r2 (bits_image_t *image,
1595 int offset,
1596 int line)
1597 {
1598 uint32_t *bits = image->bits + line * image->rowstride;
1599 uint32_t pixel = READ (image, (uint8_t *) bits + offset);
1600 uint32_t a, r, g, b;
1601
1602 a = ((pixel & 0xc0) * 0x55) << 18;
1603 b = ((pixel & 0x30) * 0x55) >> 4;
1604 g = ((pixel & 0x0c) * 0x55) << 6;
1605 r = ((pixel & 0x03) * 0x55) << 16;
1606
1607 return a | r | g | b;
1608 }
1609
1610 static uint32_t
fetch_pixel_c8(bits_image_t * image,int offset,int line)1611 fetch_pixel_c8 (bits_image_t *image,
1612 int offset,
1613 int line)
1614 {
1615 uint32_t *bits = image->bits + line * image->rowstride;
1616 uint32_t pixel = READ (image, (uint8_t *) bits + offset);
1617 const pixman_indexed_t * indexed = image->indexed;
1618
1619 return indexed->rgba[pixel];
1620 }
1621
1622 static uint32_t
fetch_pixel_x4a4(bits_image_t * image,int offset,int line)1623 fetch_pixel_x4a4 (bits_image_t *image,
1624 int offset,
1625 int line)
1626 {
1627 uint32_t *bits = image->bits + line * image->rowstride;
1628 uint32_t pixel = READ (image, (uint8_t *) bits + offset);
1629
1630 return ((pixel & 0xf) | ((pixel & 0xf) << 4)) << 24;
1631 }
1632
1633 static uint32_t
fetch_pixel_a4(bits_image_t * image,int offset,int line)1634 fetch_pixel_a4 (bits_image_t *image,
1635 int offset,
1636 int line)
1637 {
1638 uint32_t *bits = image->bits + line * image->rowstride;
1639 uint32_t pixel = FETCH_4 (image, bits, offset);
1640
1641 pixel |= pixel << 4;
1642 return pixel << 24;
1643 }
1644
1645 static uint32_t
fetch_pixel_r1g2b1(bits_image_t * image,int offset,int line)1646 fetch_pixel_r1g2b1 (bits_image_t *image,
1647 int offset,
1648 int line)
1649 {
1650 uint32_t *bits = image->bits + line * image->rowstride;
1651 uint32_t pixel = FETCH_4 (image, bits, offset);
1652 uint32_t r, g, b;
1653
1654 r = ((pixel & 0x8) * 0xff) << 13;
1655 g = ((pixel & 0x6) * 0x55) << 7;
1656 b = ((pixel & 0x1) * 0xff);
1657
1658 return 0xff000000 | r | g | b;
1659 }
1660
1661 static uint32_t
fetch_pixel_b1g2r1(bits_image_t * image,int offset,int line)1662 fetch_pixel_b1g2r1 (bits_image_t *image,
1663 int offset,
1664 int line)
1665 {
1666 uint32_t *bits = image->bits + line * image->rowstride;
1667 uint32_t pixel = FETCH_4 (image, bits, offset);
1668 uint32_t r, g, b;
1669
1670 b = ((pixel & 0x8) * 0xff) >> 3;
1671 g = ((pixel & 0x6) * 0x55) << 7;
1672 r = ((pixel & 0x1) * 0xff) << 16;
1673
1674 return 0xff000000 | r | g | b;
1675 }
1676
1677 static uint32_t
fetch_pixel_a1r1g1b1(bits_image_t * image,int offset,int line)1678 fetch_pixel_a1r1g1b1 (bits_image_t *image,
1679 int offset,
1680 int line)
1681 {
1682 uint32_t *bits = image->bits + line * image->rowstride;
1683 uint32_t pixel = FETCH_4 (image, bits, offset);
1684 uint32_t a, r, g, b;
1685
1686 a = ((pixel & 0x8) * 0xff) << 21;
1687 r = ((pixel & 0x4) * 0xff) << 14;
1688 g = ((pixel & 0x2) * 0xff) << 7;
1689 b = ((pixel & 0x1) * 0xff);
1690
1691 return a | r | g | b;
1692 }
1693
1694 static uint32_t
fetch_pixel_a1b1g1r1(bits_image_t * image,int offset,int line)1695 fetch_pixel_a1b1g1r1 (bits_image_t *image,
1696 int offset,
1697 int line)
1698 {
1699 uint32_t *bits = image->bits + line * image->rowstride;
1700 uint32_t pixel = FETCH_4 (image, bits, offset);
1701 uint32_t a, r, g, b;
1702
1703 a = ((pixel & 0x8) * 0xff) << 21;
1704 b = ((pixel & 0x4) * 0xff) >> 2;
1705 g = ((pixel & 0x2) * 0xff) << 7;
1706 r = ((pixel & 0x1) * 0xff) << 16;
1707
1708 return a | r | g | b;
1709 }
1710
1711 static uint32_t
fetch_pixel_c4(bits_image_t * image,int offset,int line)1712 fetch_pixel_c4 (bits_image_t *image,
1713 int offset,
1714 int line)
1715 {
1716 uint32_t *bits = image->bits + line * image->rowstride;
1717 uint32_t pixel = FETCH_4 (image, bits, offset);
1718 const pixman_indexed_t * indexed = image->indexed;
1719
1720 return indexed->rgba[pixel];
1721 }
1722
1723 static uint32_t
fetch_pixel_a1(bits_image_t * image,int offset,int line)1724 fetch_pixel_a1 (bits_image_t *image,
1725 int offset,
1726 int line)
1727 {
1728 uint32_t *bits = image->bits + line * image->rowstride;
1729 uint32_t pixel = READ (image, bits + (offset >> 5));
1730 uint32_t a;
1731
1732 #ifdef WORDS_BIGENDIAN
1733 a = pixel >> (0x1f - (offset & 0x1f));
1734 #else
1735 a = pixel >> (offset & 0x1f);
1736 #endif
1737 a = a & 1;
1738 a |= a << 1;
1739 a |= a << 2;
1740 a |= a << 4;
1741
1742 return a << 24;
1743 }
1744
1745 static uint32_t
fetch_pixel_g1(bits_image_t * image,int offset,int line)1746 fetch_pixel_g1 (bits_image_t *image,
1747 int offset,
1748 int line)
1749 {
1750 uint32_t *bits = image->bits + line * image->rowstride;
1751 uint32_t pixel = READ (image, bits + (offset >> 5));
1752 const pixman_indexed_t * indexed = image->indexed;
1753 uint32_t a;
1754
1755 #ifdef WORDS_BIGENDIAN
1756 a = pixel >> (0x1f - (offset & 0x1f));
1757 #else
1758 a = pixel >> (offset & 0x1f);
1759 #endif
1760 a = a & 1;
1761
1762 return indexed->rgba[a];
1763 }
1764
1765 static uint32_t
fetch_pixel_yuy2(bits_image_t * image,int offset,int line)1766 fetch_pixel_yuy2 (bits_image_t *image,
1767 int offset,
1768 int line)
1769 {
1770 const uint32_t *bits = image->bits + image->rowstride * line;
1771
1772 int16_t y, u, v;
1773 int32_t r, g, b;
1774
1775 y = ((uint8_t *) bits)[offset << 1] - 16;
1776 u = ((uint8_t *) bits)[((offset << 1) & - 4) + 1] - 128;
1777 v = ((uint8_t *) bits)[((offset << 1) & - 4) + 3] - 128;
1778
1779 /* R = 1.164(Y - 16) + 1.596(V - 128) */
1780 r = 0x012b27 * y + 0x019a2e * v;
1781
1782 /* G = 1.164(Y - 16) - 0.813(V - 128) - 0.391(U - 128) */
1783 g = 0x012b27 * y - 0x00d0f2 * v - 0x00647e * u;
1784
1785 /* B = 1.164(Y - 16) + 2.018(U - 128) */
1786 b = 0x012b27 * y + 0x0206a2 * u;
1787
1788 return 0xff000000 |
1789 (r >= 0 ? r < 0x1000000 ? r & 0xff0000 : 0xff0000 : 0) |
1790 (g >= 0 ? g < 0x1000000 ? (g >> 8) & 0x00ff00 : 0x00ff00 : 0) |
1791 (b >= 0 ? b < 0x1000000 ? (b >> 16) & 0x0000ff : 0x0000ff : 0);
1792 }
1793
1794 static uint32_t
fetch_pixel_yv12(bits_image_t * image,int offset,int line)1795 fetch_pixel_yv12 (bits_image_t *image,
1796 int offset,
1797 int line)
1798 {
1799 YV12_SETUP (image);
1800 int16_t y = YV12_Y (line)[offset] - 16;
1801 int16_t u = YV12_U (line)[offset >> 1] - 128;
1802 int16_t v = YV12_V (line)[offset >> 1] - 128;
1803 int32_t r, g, b;
1804
1805 /* R = 1.164(Y - 16) + 1.596(V - 128) */
1806 r = 0x012b27 * y + 0x019a2e * v;
1807
1808 /* G = 1.164(Y - 16) - 0.813(V - 128) - 0.391(U - 128) */
1809 g = 0x012b27 * y - 0x00d0f2 * v - 0x00647e * u;
1810
1811 /* B = 1.164(Y - 16) + 2.018(U - 128) */
1812 b = 0x012b27 * y + 0x0206a2 * u;
1813
1814 return 0xff000000 |
1815 (r >= 0 ? r < 0x1000000 ? r & 0xff0000 : 0xff0000 : 0) |
1816 (g >= 0 ? g < 0x1000000 ? (g >> 8) & 0x00ff00 : 0x00ff00 : 0) |
1817 (b >= 0 ? b < 0x1000000 ? (b >> 16) & 0x0000ff : 0x0000ff : 0);
1818 }
1819
1820 /*********************************** Store ************************************/
1821
1822 #define SPLIT_A(v) \
1823 uint32_t a = ((v) >> 24), \
1824 r = ((v) >> 16) & 0xff, \
1825 g = ((v) >> 8) & 0xff, \
1826 b = (v) & 0xff
1827
1828 #define SPLIT(v) \
1829 uint32_t r = ((v) >> 16) & 0xff, \
1830 g = ((v) >> 8) & 0xff, \
1831 b = (v) & 0xff
1832
1833 static void
store_scanline_a2r10g10b10(bits_image_t * image,int x,int y,int width,const uint32_t * v)1834 store_scanline_a2r10g10b10 (bits_image_t * image,
1835 int x,
1836 int y,
1837 int width,
1838 const uint32_t *v)
1839 {
1840 uint32_t *bits = image->bits + image->rowstride * y;
1841 uint32_t *pixel = bits + x;
1842 uint64_t *values = (uint64_t *)v;
1843 int i;
1844
1845 for (i = 0; i < width; ++i)
1846 {
1847 WRITE (image, pixel++,
1848 ((values[i] >> 32) & 0xc0000000) |
1849 ((values[i] >> 18) & 0x3ff00000) |
1850 ((values[i] >> 12) & 0xffc00) |
1851 ((values[i] >> 6) & 0x3ff));
1852 }
1853 }
1854
1855 static void
store_scanline_x2r10g10b10(bits_image_t * image,int x,int y,int width,const uint32_t * v)1856 store_scanline_x2r10g10b10 (bits_image_t * image,
1857 int x,
1858 int y,
1859 int width,
1860 const uint32_t *v)
1861 {
1862 uint32_t *bits = image->bits + image->rowstride * y;
1863 uint64_t *values = (uint64_t *)v;
1864 uint32_t *pixel = bits + x;
1865 int i;
1866
1867 for (i = 0; i < width; ++i)
1868 {
1869 WRITE (image, pixel++,
1870 ((values[i] >> 18) & 0x3ff00000) |
1871 ((values[i] >> 12) & 0xffc00) |
1872 ((values[i] >> 6) & 0x3ff));
1873 }
1874 }
1875
1876 static void
store_scanline_a2b10g10r10(bits_image_t * image,int x,int y,int width,const uint32_t * v)1877 store_scanline_a2b10g10r10 (bits_image_t * image,
1878 int x,
1879 int y,
1880 int width,
1881 const uint32_t *v)
1882 {
1883 uint32_t *bits = image->bits + image->rowstride * y;
1884 uint32_t *pixel = bits + x;
1885 uint64_t *values = (uint64_t *)v;
1886 int i;
1887
1888 for (i = 0; i < width; ++i)
1889 {
1890 WRITE (image, pixel++,
1891 ((values[i] >> 32) & 0xc0000000) |
1892 ((values[i] >> 38) & 0x3ff) |
1893 ((values[i] >> 12) & 0xffc00) |
1894 ((values[i] << 14) & 0x3ff00000));
1895 }
1896 }
1897
1898 static void
store_scanline_x2b10g10r10(bits_image_t * image,int x,int y,int width,const uint32_t * v)1899 store_scanline_x2b10g10r10 (bits_image_t * image,
1900 int x,
1901 int y,
1902 int width,
1903 const uint32_t *v)
1904 {
1905 uint32_t *bits = image->bits + image->rowstride * y;
1906 uint64_t *values = (uint64_t *)v;
1907 uint32_t *pixel = bits + x;
1908 int i;
1909
1910 for (i = 0; i < width; ++i)
1911 {
1912 WRITE (image, pixel++,
1913 ((values[i] >> 38) & 0x3ff) |
1914 ((values[i] >> 12) & 0xffc00) |
1915 ((values[i] << 14) & 0x3ff00000));
1916 }
1917 }
1918
1919 static void
store_scanline_a8r8g8b8(bits_image_t * image,int x,int y,int width,const uint32_t * values)1920 store_scanline_a8r8g8b8 (bits_image_t * image,
1921 int x,
1922 int y,
1923 int width,
1924 const uint32_t *values)
1925 {
1926 uint32_t *bits = image->bits + image->rowstride * y;
1927
1928 MEMCPY_WRAPPED (image, ((uint32_t *)bits) + x, values,
1929 width * sizeof(uint32_t));
1930 }
1931
1932 static void
store_scanline_x8r8g8b8(bits_image_t * image,int x,int y,int width,const uint32_t * values)1933 store_scanline_x8r8g8b8 (bits_image_t * image,
1934 int x,
1935 int y,
1936 int width,
1937 const uint32_t *values)
1938 {
1939 uint32_t *bits = image->bits + image->rowstride * y;
1940 uint32_t *pixel = (uint32_t *)bits + x;
1941 int i;
1942
1943 for (i = 0; i < width; ++i)
1944 WRITE (image, pixel++, values[i] & 0xffffff);
1945 }
1946
1947 static void
store_scanline_a8b8g8r8(bits_image_t * image,int x,int y,int width,const uint32_t * values)1948 store_scanline_a8b8g8r8 (bits_image_t * image,
1949 int x,
1950 int y,
1951 int width,
1952 const uint32_t *values)
1953 {
1954 uint32_t *bits = image->bits + image->rowstride * y;
1955 uint32_t *pixel = (uint32_t *)bits + x;
1956 int i;
1957
1958 for (i = 0; i < width; ++i)
1959 {
1960 WRITE (image, pixel++,
1961 (values[i] & 0xff00ff00) |
1962 ((values[i] >> 16) & 0xff) |
1963 ((values[i] & 0xff) << 16));
1964 }
1965 }
1966
1967 static void
store_scanline_x8b8g8r8(bits_image_t * image,int x,int y,int width,const uint32_t * values)1968 store_scanline_x8b8g8r8 (bits_image_t * image,
1969 int x,
1970 int y,
1971 int width,
1972 const uint32_t *values)
1973 {
1974 uint32_t *bits = image->bits + image->rowstride * y;
1975 uint32_t *pixel = (uint32_t *)bits + x;
1976 int i;
1977
1978 for (i = 0; i < width; ++i)
1979 {
1980 WRITE (image, pixel++,
1981 (values[i] & 0x0000ff00) |
1982 ((values[i] >> 16) & 0xff) |
1983 ((values[i] & 0xff) << 16));
1984 }
1985 }
1986
1987 static void
store_scanline_b8g8r8a8(bits_image_t * image,int x,int y,int width,const uint32_t * values)1988 store_scanline_b8g8r8a8 (bits_image_t * image,
1989 int x,
1990 int y,
1991 int width,
1992 const uint32_t *values)
1993 {
1994 uint32_t *bits = image->bits + image->rowstride * y;
1995 uint32_t *pixel = (uint32_t *)bits + x;
1996 int i;
1997
1998 for (i = 0; i < width; ++i)
1999 {
2000 WRITE (image, pixel++,
2001 ((values[i] >> 24) & 0x000000ff) |
2002 ((values[i] >> 8) & 0x0000ff00) |
2003 ((values[i] << 8) & 0x00ff0000) |
2004 ((values[i] << 24) & 0xff000000));
2005 }
2006 }
2007
2008 static void
store_scanline_b8g8r8x8(bits_image_t * image,int x,int y,int width,const uint32_t * values)2009 store_scanline_b8g8r8x8 (bits_image_t * image,
2010 int x,
2011 int y,
2012 int width,
2013 const uint32_t *values)
2014 {
2015 uint32_t *bits = image->bits + image->rowstride * y;
2016 uint32_t *pixel = (uint32_t *)bits + x;
2017 int i;
2018
2019 for (i = 0; i < width; ++i)
2020 {
2021 WRITE (image, pixel++,
2022 ((values[i] >> 8) & 0x0000ff00) |
2023 ((values[i] << 8) & 0x00ff0000) |
2024 ((values[i] << 24) & 0xff000000));
2025 }
2026 }
2027
2028 static void
store_scanline_r8g8b8(bits_image_t * image,int x,int y,int width,const uint32_t * values)2029 store_scanline_r8g8b8 (bits_image_t * image,
2030 int x,
2031 int y,
2032 int width,
2033 const uint32_t *values)
2034 {
2035 uint32_t *bits = image->bits + image->rowstride * y;
2036 uint8_t *pixel = ((uint8_t *) bits) + 3 * x;
2037 int i;
2038
2039 for (i = 0; i < width; ++i)
2040 {
2041 uint32_t val = values[i];
2042
2043 #ifdef WORDS_BIGENDIAN
2044 WRITE (image, pixel++, (val & 0x00ff0000) >> 16);
2045 WRITE (image, pixel++, (val & 0x0000ff00) >> 8);
2046 WRITE (image, pixel++, (val & 0x000000ff) >> 0);
2047 #else
2048 WRITE (image, pixel++, (val & 0x000000ff) >> 0);
2049 WRITE (image, pixel++, (val & 0x0000ff00) >> 8);
2050 WRITE (image, pixel++, (val & 0x00ff0000) >> 16);
2051 #endif
2052 }
2053 }
2054
2055 static void
store_scanline_b8g8r8(bits_image_t * image,int x,int y,int width,const uint32_t * values)2056 store_scanline_b8g8r8 (bits_image_t * image,
2057 int x,
2058 int y,
2059 int width,
2060 const uint32_t *values)
2061 {
2062 uint32_t *bits = image->bits + image->rowstride * y;
2063 uint8_t *pixel = ((uint8_t *) bits) + 3 * x;
2064 int i;
2065
2066 for (i = 0; i < width; ++i)
2067 {
2068 uint32_t val = values[i];
2069
2070 #ifdef WORDS_BIGENDIAN
2071 WRITE (image, pixel++, (val & 0x000000ff) >> 0);
2072 WRITE (image, pixel++, (val & 0x0000ff00) >> 8);
2073 WRITE (image, pixel++, (val & 0x00ff0000) >> 16);
2074 #else
2075 WRITE (image, pixel++, (val & 0x00ff0000) >> 16);
2076 WRITE (image, pixel++, (val & 0x0000ff00) >> 8);
2077 WRITE (image, pixel++, (val & 0x000000ff) >> 0);
2078 #endif
2079 }
2080 }
2081
2082 static void
store_scanline_r5g6b5(bits_image_t * image,int x,int y,int width,const uint32_t * values)2083 store_scanline_r5g6b5 (bits_image_t * image,
2084 int x,
2085 int y,
2086 int width,
2087 const uint32_t *values)
2088 {
2089 uint32_t *bits = image->bits + image->rowstride * y;
2090 uint16_t *pixel = ((uint16_t *) bits) + x;
2091 int i;
2092
2093 for (i = 0; i < width; ++i)
2094 {
2095 uint32_t s = values[i];
2096
2097 WRITE (image, pixel++,
2098 ((s >> 3) & 0x001f) |
2099 ((s >> 5) & 0x07e0) |
2100 ((s >> 8) & 0xf800));
2101 }
2102 }
2103
2104 static void
store_scanline_b5g6r5(bits_image_t * image,int x,int y,int width,const uint32_t * values)2105 store_scanline_b5g6r5 (bits_image_t * image,
2106 int x,
2107 int y,
2108 int width,
2109 const uint32_t *values)
2110 {
2111 uint32_t *bits = image->bits + image->rowstride * y;
2112 uint16_t *pixel = ((uint16_t *) bits) + x;
2113 int i;
2114
2115 for (i = 0; i < width; ++i)
2116 {
2117 SPLIT (values[i]);
2118
2119 WRITE (image, pixel++,
2120 ((b << 8) & 0xf800) |
2121 ((g << 3) & 0x07e0) |
2122 ((r >> 3) ));
2123 }
2124 }
2125
2126 static void
store_scanline_a1r5g5b5(bits_image_t * image,int x,int y,int width,const uint32_t * values)2127 store_scanline_a1r5g5b5 (bits_image_t * image,
2128 int x,
2129 int y,
2130 int width,
2131 const uint32_t *values)
2132 {
2133 uint32_t *bits = image->bits + image->rowstride * y;
2134 uint16_t *pixel = ((uint16_t *) bits) + x;
2135 int i;
2136
2137 for (i = 0; i < width; ++i)
2138 {
2139 SPLIT_A (values[i]);
2140
2141 WRITE (image, pixel++,
2142 ((a << 8) & 0x8000) |
2143 ((r << 7) & 0x7c00) |
2144 ((g << 2) & 0x03e0) |
2145 ((b >> 3) ));
2146 }
2147 }
2148
2149 static void
store_scanline_x1r5g5b5(bits_image_t * image,int x,int y,int width,const uint32_t * values)2150 store_scanline_x1r5g5b5 (bits_image_t * image,
2151 int x,
2152 int y,
2153 int width,
2154 const uint32_t *values)
2155 {
2156 uint32_t *bits = image->bits + image->rowstride * y;
2157 uint16_t *pixel = ((uint16_t *) bits) + x;
2158 int i;
2159
2160 for (i = 0; i < width; ++i)
2161 {
2162 SPLIT (values[i]);
2163
2164 WRITE (image, pixel++,
2165 ((r << 7) & 0x7c00) |
2166 ((g << 2) & 0x03e0) |
2167 ((b >> 3) ));
2168 }
2169 }
2170
2171 static void
store_scanline_a1b5g5r5(bits_image_t * image,int x,int y,int width,const uint32_t * values)2172 store_scanline_a1b5g5r5 (bits_image_t * image,
2173 int x,
2174 int y,
2175 int width,
2176 const uint32_t *values)
2177 {
2178 uint32_t *bits = image->bits + image->rowstride * y;
2179 uint16_t *pixel = ((uint16_t *) bits) + x;
2180 int i;
2181
2182 for (i = 0; i < width; ++i)
2183 {
2184 SPLIT_A (values[i]);
2185
2186 WRITE (image, pixel++,
2187 ((a << 8) & 0x8000) |
2188 ((b << 7) & 0x7c00) |
2189 ((g << 2) & 0x03e0) |
2190 ((r >> 3) ));
2191 }
2192 }
2193
2194 static void
store_scanline_x1b5g5r5(bits_image_t * image,int x,int y,int width,const uint32_t * values)2195 store_scanline_x1b5g5r5 (bits_image_t * image,
2196 int x,
2197 int y,
2198 int width,
2199 const uint32_t *values)
2200 {
2201 uint32_t *bits = image->bits + image->rowstride * y;
2202 uint16_t *pixel = ((uint16_t *) bits) + x;
2203 int i;
2204
2205 for (i = 0; i < width; ++i)
2206 {
2207 SPLIT (values[i]);
2208
2209 WRITE (image, pixel++, ((b << 7) & 0x7c00) |
2210 ((g << 2) & 0x03e0) |
2211 ((r >> 3) ));
2212 }
2213 }
2214
2215 static void
store_scanline_a4r4g4b4(bits_image_t * image,int x,int y,int width,const uint32_t * values)2216 store_scanline_a4r4g4b4 (bits_image_t * image,
2217 int x,
2218 int y,
2219 int width,
2220 const uint32_t *values)
2221 {
2222 uint32_t *bits = image->bits + image->rowstride * y;
2223 uint16_t *pixel = ((uint16_t *) bits) + x;
2224 int i;
2225
2226 for (i = 0; i < width; ++i)
2227 {
2228 SPLIT_A (values[i]);
2229
2230 WRITE (image, pixel++,
2231 ((a << 8) & 0xf000) |
2232 ((r << 4) & 0x0f00) |
2233 ((g ) & 0x00f0) |
2234 ((b >> 4) ));
2235 }
2236 }
2237
2238 static void
store_scanline_x4r4g4b4(bits_image_t * image,int x,int y,int width,const uint32_t * values)2239 store_scanline_x4r4g4b4 (bits_image_t * image,
2240 int x,
2241 int y,
2242 int width,
2243 const uint32_t *values)
2244 {
2245 uint32_t *bits = image->bits + image->rowstride * y;
2246 uint16_t *pixel = ((uint16_t *) bits) + x;
2247 int i;
2248
2249 for (i = 0; i < width; ++i)
2250 {
2251 SPLIT (values[i]);
2252
2253 WRITE (image, pixel++,
2254 ((r << 4) & 0x0f00) |
2255 ((g ) & 0x00f0) |
2256 ((b >> 4) ));
2257 }
2258 }
2259
2260 static void
store_scanline_a4b4g4r4(bits_image_t * image,int x,int y,int width,const uint32_t * values)2261 store_scanline_a4b4g4r4 (bits_image_t * image,
2262 int x,
2263 int y,
2264 int width,
2265 const uint32_t *values)
2266 {
2267 uint32_t *bits = image->bits + image->rowstride * y;
2268 uint16_t *pixel = ((uint16_t *) bits) + x;
2269 int i;
2270
2271 for (i = 0; i < width; ++i)
2272 {
2273 SPLIT_A (values[i]);
2274 WRITE (image, pixel++, ((a << 8) & 0xf000) |
2275 ((b << 4) & 0x0f00) |
2276 ((g ) & 0x00f0) |
2277 ((r >> 4) ));
2278 }
2279 }
2280
2281 static void
store_scanline_x4b4g4r4(bits_image_t * image,int x,int y,int width,const uint32_t * values)2282 store_scanline_x4b4g4r4 (bits_image_t * image,
2283 int x,
2284 int y,
2285 int width,
2286 const uint32_t *values)
2287 {
2288 uint32_t *bits = image->bits + image->rowstride * y;
2289 uint16_t *pixel = ((uint16_t *) bits) + x;
2290 int i;
2291
2292 for (i = 0; i < width; ++i)
2293 {
2294 SPLIT (values[i]);
2295
2296 WRITE (image, pixel++,
2297 ((b << 4) & 0x0f00) |
2298 ((g ) & 0x00f0) |
2299 ((r >> 4) ));
2300 }
2301 }
2302
2303 static void
store_scanline_a8(bits_image_t * image,int x,int y,int width,const uint32_t * values)2304 store_scanline_a8 (bits_image_t * image,
2305 int x,
2306 int y,
2307 int width,
2308 const uint32_t *values)
2309 {
2310 uint32_t *bits = image->bits + image->rowstride * y;
2311 uint8_t *pixel = ((uint8_t *) bits) + x;
2312 int i;
2313
2314 for (i = 0; i < width; ++i)
2315 {
2316 WRITE (image, pixel++, values[i] >> 24);
2317 }
2318 }
2319
2320 static void
store_scanline_r3g3b2(bits_image_t * image,int x,int y,int width,const uint32_t * values)2321 store_scanline_r3g3b2 (bits_image_t * image,
2322 int x,
2323 int y,
2324 int width,
2325 const uint32_t *values)
2326 {
2327 uint32_t *bits = image->bits + image->rowstride * y;
2328 uint8_t *pixel = ((uint8_t *) bits) + x;
2329 int i;
2330
2331 for (i = 0; i < width; ++i)
2332 {
2333 SPLIT (values[i]);
2334
2335 WRITE (image, pixel++,
2336 ((r ) & 0xe0) |
2337 ((g >> 3) & 0x1c) |
2338 ((b >> 6) ));
2339 }
2340 }
2341
2342 static void
store_scanline_b2g3r3(bits_image_t * image,int x,int y,int width,const uint32_t * values)2343 store_scanline_b2g3r3 (bits_image_t * image,
2344 int x,
2345 int y,
2346 int width,
2347 const uint32_t *values)
2348 {
2349 uint32_t *bits = image->bits + image->rowstride * y;
2350 uint8_t *pixel = ((uint8_t *) bits) + x;
2351 int i;
2352
2353 for (i = 0; i < width; ++i)
2354 {
2355 SPLIT (values[i]);
2356
2357 WRITE (image, pixel++,
2358 ((b ) & 0xc0) |
2359 ((g >> 2) & 0x38) |
2360 ((r >> 5) ));
2361 }
2362 }
2363
2364 static void
store_scanline_a2r2g2b2(bits_image_t * image,int x,int y,int width,const uint32_t * values)2365 store_scanline_a2r2g2b2 (bits_image_t * image,
2366 int x,
2367 int y,
2368 int width,
2369 const uint32_t *values)
2370 {
2371 uint32_t *bits = image->bits + image->rowstride * y;
2372 uint8_t *pixel = ((uint8_t *) bits) + x;
2373 int i;
2374
2375 for (i = 0; i < width; ++i)
2376 {
2377 SPLIT_A (values[i]);
2378
2379 WRITE (image, pixel++,
2380 ((a ) & 0xc0) |
2381 ((r >> 2) & 0x30) |
2382 ((g >> 4) & 0x0c) |
2383 ((b >> 6) ));
2384 }
2385 }
2386
2387 static void
store_scanline_a2b2g2r2(bits_image_t * image,int x,int y,int width,const uint32_t * values)2388 store_scanline_a2b2g2r2 (bits_image_t * image,
2389 int x,
2390 int y,
2391 int width,
2392 const uint32_t *values)
2393 {
2394 uint32_t *bits = image->bits + image->rowstride * y;
2395 uint8_t *pixel = ((uint8_t *) bits) + x;
2396 int i;
2397
2398 for (i = 0; i < width; ++i)
2399 {
2400 SPLIT_A (values[i]);
2401
2402 *(pixel++) =
2403 ((a ) & 0xc0) |
2404 ((b >> 2) & 0x30) |
2405 ((g >> 4) & 0x0c) |
2406 ((r >> 6) );
2407 }
2408 }
2409
2410 static void
store_scanline_c8(bits_image_t * image,int x,int y,int width,const uint32_t * values)2411 store_scanline_c8 (bits_image_t * image,
2412 int x,
2413 int y,
2414 int width,
2415 const uint32_t *values)
2416 {
2417 uint32_t *bits = image->bits + image->rowstride * y;
2418 uint8_t *pixel = ((uint8_t *) bits) + x;
2419 const pixman_indexed_t *indexed = image->indexed;
2420 int i;
2421
2422 for (i = 0; i < width; ++i)
2423 WRITE (image, pixel++, RGB24_TO_ENTRY (indexed,values[i]));
2424 }
2425
2426 static void
store_scanline_x4a4(bits_image_t * image,int x,int y,int width,const uint32_t * values)2427 store_scanline_x4a4 (bits_image_t * image,
2428 int x,
2429 int y,
2430 int width,
2431 const uint32_t *values)
2432 {
2433 uint32_t *bits = image->bits + image->rowstride * y;
2434 uint8_t *pixel = ((uint8_t *) bits) + x;
2435 int i;
2436
2437 for (i = 0; i < width; ++i)
2438 WRITE (image, pixel++, values[i] >> 28);
2439 }
2440
2441 #define STORE_8(img,l,o,v) (WRITE (img, (uint8_t *)(l) + ((o) >> 3), (v)))
2442 #ifdef WORDS_BIGENDIAN
2443
2444 #define STORE_4(img,l,o,v) \
2445 do \
2446 { \
2447 int bo = 4 * (o); \
2448 int v4 = (v) & 0x0f; \
2449 \
2450 STORE_8 (img, l, bo, ( \
2451 bo & 4 ? \
2452 (FETCH_8 (img, l, bo) & 0xf0) | (v4) : \
2453 (FETCH_8 (img, l, bo) & 0x0f) | (v4 << 4))); \
2454 } while (0)
2455 #else
2456
2457 #define STORE_4(img,l,o,v) \
2458 do \
2459 { \
2460 int bo = 4 * (o); \
2461 int v4 = (v) & 0x0f; \
2462 \
2463 STORE_8 (img, l, bo, ( \
2464 bo & 4 ? \
2465 (FETCH_8 (img, l, bo) & 0x0f) | (v4 << 4) : \
2466 (FETCH_8 (img, l, bo) & 0xf0) | (v4))); \
2467 } while (0)
2468 #endif
2469
2470 static void
store_scanline_a4(bits_image_t * image,int x,int y,int width,const uint32_t * values)2471 store_scanline_a4 (bits_image_t * image,
2472 int x,
2473 int y,
2474 int width,
2475 const uint32_t *values)
2476 {
2477 uint32_t *bits = image->bits + image->rowstride * y;
2478 int i;
2479
2480 for (i = 0; i < width; ++i)
2481 STORE_4 (image, bits, i + x, values[i] >> 28);
2482 }
2483
2484 static void
store_scanline_r1g2b1(bits_image_t * image,int x,int y,int width,const uint32_t * values)2485 store_scanline_r1g2b1 (bits_image_t * image,
2486 int x,
2487 int y,
2488 int width,
2489 const uint32_t *values)
2490 {
2491 uint32_t *bits = image->bits + image->rowstride * y;
2492 int i;
2493
2494 for (i = 0; i < width; ++i)
2495 {
2496 uint32_t pixel;
2497
2498 SPLIT (values[i]);
2499 pixel = (((r >> 4) & 0x8) |
2500 ((g >> 5) & 0x6) |
2501 ((b >> 7) ));
2502 STORE_4 (image, bits, i + x, pixel);
2503 }
2504 }
2505
2506 static void
store_scanline_b1g2r1(bits_image_t * image,int x,int y,int width,const uint32_t * values)2507 store_scanline_b1g2r1 (bits_image_t * image,
2508 int x,
2509 int y,
2510 int width,
2511 const uint32_t *values)
2512 {
2513 uint32_t *bits = image->bits + image->rowstride * y;
2514 int i;
2515
2516 for (i = 0; i < width; ++i)
2517 {
2518 uint32_t pixel;
2519
2520 SPLIT (values[i]);
2521 pixel = (((b >> 4) & 0x8) |
2522 ((g >> 5) & 0x6) |
2523 ((r >> 7) ));
2524 STORE_4 (image, bits, i + x, pixel);
2525 }
2526 }
2527
2528 static void
store_scanline_a1r1g1b1(bits_image_t * image,int x,int y,int width,const uint32_t * values)2529 store_scanline_a1r1g1b1 (bits_image_t * image,
2530 int x,
2531 int y,
2532 int width,
2533 const uint32_t *values)
2534 {
2535 uint32_t *bits = image->bits + image->rowstride * y;
2536 int i;
2537
2538 for (i = 0; i < width; ++i)
2539 {
2540 uint32_t pixel;
2541
2542 SPLIT_A (values[i]);
2543 pixel = (((a >> 4) & 0x8) |
2544 ((r >> 5) & 0x4) |
2545 ((g >> 6) & 0x2) |
2546 ((b >> 7) ));
2547
2548 STORE_4 (image, bits, i + x, pixel);
2549 }
2550 }
2551
2552 static void
store_scanline_a1b1g1r1(bits_image_t * image,int x,int y,int width,const uint32_t * values)2553 store_scanline_a1b1g1r1 (bits_image_t * image,
2554 int x,
2555 int y,
2556 int width,
2557 const uint32_t *values)
2558 {
2559 uint32_t *bits = image->bits + image->rowstride * y;
2560 int i;
2561
2562 for (i = 0; i < width; ++i)
2563 {
2564 uint32_t pixel;
2565
2566 SPLIT_A (values[i]);
2567 pixel = (((a >> 4) & 0x8) |
2568 ((b >> 5) & 0x4) |
2569 ((g >> 6) & 0x2) |
2570 ((r >> 7) ));
2571
2572 STORE_4 (image, bits, i + x, pixel);
2573 }
2574 }
2575
2576 static void
store_scanline_c4(bits_image_t * image,int x,int y,int width,const uint32_t * values)2577 store_scanline_c4 (bits_image_t * image,
2578 int x,
2579 int y,
2580 int width,
2581 const uint32_t *values)
2582 {
2583 uint32_t *bits = image->bits + image->rowstride * y;
2584 const pixman_indexed_t *indexed = image->indexed;
2585 int i;
2586
2587 for (i = 0; i < width; ++i)
2588 {
2589 uint32_t pixel;
2590
2591 pixel = RGB24_TO_ENTRY (indexed, values[i]);
2592 STORE_4 (image, bits, i + x, pixel);
2593 }
2594 }
2595
2596 static void
store_scanline_a1(bits_image_t * image,int x,int y,int width,const uint32_t * values)2597 store_scanline_a1 (bits_image_t * image,
2598 int x,
2599 int y,
2600 int width,
2601 const uint32_t *values)
2602 {
2603 uint32_t *bits = image->bits + image->rowstride * y;
2604 int i;
2605
2606 for (i = 0; i < width; ++i)
2607 {
2608 uint32_t *pixel = ((uint32_t *) bits) + ((i + x) >> 5);
2609 uint32_t mask, v;
2610
2611 #ifdef WORDS_BIGENDIAN
2612 mask = 1 << (0x1f - ((i + x) & 0x1f));
2613 #else
2614 mask = 1 << ((i + x) & 0x1f);
2615 #endif
2616 v = values[i] & 0x80000000 ? mask : 0;
2617
2618 WRITE (image, pixel, (READ (image, pixel) & ~mask) | v);
2619 }
2620 }
2621
2622 static void
store_scanline_g1(bits_image_t * image,int x,int y,int width,const uint32_t * values)2623 store_scanline_g1 (bits_image_t * image,
2624 int x,
2625 int y,
2626 int width,
2627 const uint32_t *values)
2628 {
2629 uint32_t *bits = image->bits + image->rowstride * y;
2630 const pixman_indexed_t *indexed = image->indexed;
2631 int i;
2632
2633 for (i = 0; i < width; ++i)
2634 {
2635 uint32_t *pixel = ((uint32_t *) bits) + ((i + x) >> 5);
2636 uint32_t mask, v;
2637
2638 #ifdef WORDS_BIGENDIAN
2639 mask = 1 << (0x1f - ((i + x) & 0x1f));
2640 #else
2641 mask = 1 << ((i + x) & 0x1f);
2642 #endif
2643 v = RGB24_TO_ENTRY_Y (indexed, values[i]) & 0x1 ? mask : 0;
2644
2645 WRITE (image, pixel, (READ (image, pixel) & ~mask) | v);
2646 }
2647 }
2648
2649 /*
2650 * Contracts a 64bpp image to 32bpp and then stores it using a regular 32-bit
2651 * store proc. Despite the type, this function expects a uint64_t buffer.
2652 */
2653 static void
store_scanline_generic_64(bits_image_t * image,int x,int y,int width,const uint32_t * values)2654 store_scanline_generic_64 (bits_image_t * image,
2655 int x,
2656 int y,
2657 int width,
2658 const uint32_t *values)
2659 {
2660 uint32_t *argb8_pixels;
2661
2662 assert (image->common.type == BITS);
2663
2664 argb8_pixels = pixman_malloc_ab (width, sizeof(uint32_t));
2665 if (!argb8_pixels)
2666 return;
2667
2668 /* Contract the scanline. We could do this in place if values weren't
2669 * const.
2670 */
2671 pixman_contract (argb8_pixels, (uint64_t *)values, width);
2672
2673 image->store_scanline_raw_32 (image, x, y, width, argb8_pixels);
2674
2675 free (argb8_pixels);
2676 }
2677
2678 /* Despite the type, this function expects both buffer
2679 * and mask to be uint64_t
2680 */
2681 static void
fetch_scanline_generic_64(pixman_image_t * image,int x,int y,int width,uint32_t * buffer,const uint32_t * mask,uint32_t mask_bits)2682 fetch_scanline_generic_64 (pixman_image_t *image,
2683 int x,
2684 int y,
2685 int width,
2686 uint32_t * buffer,
2687 const uint32_t *mask,
2688 uint32_t mask_bits)
2689 {
2690 /* Fetch the pixels into the first half of buffer and then expand them in
2691 * place.
2692 */
2693 image->bits.fetch_scanline_raw_32 (image, x, y, width, buffer, NULL, 0);
2694
2695 pixman_expand ((uint64_t *)buffer, buffer, image->bits.format, width);
2696 }
2697
2698 /* Despite the type, this function expects a uint64_t *buffer */
2699 static uint64_t
fetch_pixel_generic_64(bits_image_t * image,int offset,int line)2700 fetch_pixel_generic_64 (bits_image_t *image,
2701 int offset,
2702 int line)
2703 {
2704 uint32_t pixel32 = image->fetch_pixel_raw_32 (image, offset, line);
2705 uint64_t result;
2706
2707 pixman_expand ((uint64_t *)&result, &pixel32, image->format, 1);
2708
2709 return result;
2710 }
2711
2712 /*
2713 * XXX: The transformed fetch path only works at 32-bpp so far. When all
2714 * paths have wide versions, this can be removed.
2715 *
2716 * WARNING: This function loses precision!
2717 */
2718 static uint32_t
fetch_pixel_generic_lossy_32(bits_image_t * image,int offset,int line)2719 fetch_pixel_generic_lossy_32 (bits_image_t *image,
2720 int offset,
2721 int line)
2722 {
2723 uint64_t pixel64 = image->fetch_pixel_raw_64 (image, offset, line);
2724 uint32_t result;
2725
2726 pixman_contract (&result, &pixel64, 1);
2727
2728 return result;
2729 }
2730
2731 typedef struct
2732 {
2733 pixman_format_code_t format;
2734 fetch_scanline_t fetch_scanline_raw_32;
2735 fetch_scanline_t fetch_scanline_raw_64;
2736 fetch_pixel_32_t fetch_pixel_raw_32;
2737 fetch_pixel_64_t fetch_pixel_raw_64;
2738 store_scanline_t store_scanline_raw_32;
2739 store_scanline_t store_scanline_raw_64;
2740 } format_info_t;
2741
2742 #define FORMAT_INFO(format) \
2743 { \
2744 PIXMAN_ ## format, \
2745 fetch_scanline_ ## format, \
2746 fetch_scanline_generic_64, \
2747 fetch_pixel_ ## format, fetch_pixel_generic_64, \
2748 store_scanline_ ## format, store_scanline_generic_64 \
2749 }
2750
2751 static const format_info_t accessors[] =
2752 {
2753 /* 32 bpp formats */
2754 FORMAT_INFO (a8r8g8b8),
2755 FORMAT_INFO (x8r8g8b8),
2756 FORMAT_INFO (a8b8g8r8),
2757 FORMAT_INFO (x8b8g8r8),
2758 FORMAT_INFO (b8g8r8a8),
2759 FORMAT_INFO (b8g8r8x8),
2760
2761 /* 24bpp formats */
2762 FORMAT_INFO (r8g8b8),
2763 FORMAT_INFO (b8g8r8),
2764
2765 /* 16bpp formats */
2766 FORMAT_INFO (r5g6b5),
2767 FORMAT_INFO (b5g6r5),
2768
2769 FORMAT_INFO (a1r5g5b5),
2770 FORMAT_INFO (x1r5g5b5),
2771 FORMAT_INFO (a1b5g5r5),
2772 FORMAT_INFO (x1b5g5r5),
2773 FORMAT_INFO (a4r4g4b4),
2774 FORMAT_INFO (x4r4g4b4),
2775 FORMAT_INFO (a4b4g4r4),
2776 FORMAT_INFO (x4b4g4r4),
2777
2778 /* 8bpp formats */
2779 FORMAT_INFO (a8),
2780 FORMAT_INFO (r3g3b2),
2781 FORMAT_INFO (b2g3r3),
2782 FORMAT_INFO (a2r2g2b2),
2783 FORMAT_INFO (a2b2g2r2),
2784
2785 FORMAT_INFO (c8),
2786
2787 #define fetch_scanline_g8 fetch_scanline_c8
2788 #define fetch_pixel_g8 fetch_pixel_c8
2789 #define store_scanline_g8 store_scanline_c8
2790 FORMAT_INFO (g8),
2791
2792 #define fetch_scanline_x4c4 fetch_scanline_c8
2793 #define fetch_pixel_x4c4 fetch_pixel_c8
2794 #define store_scanline_x4c4 store_scanline_c8
2795 FORMAT_INFO (x4c4),
2796
2797 #define fetch_scanline_x4g4 fetch_scanline_c8
2798 #define fetch_pixel_x4g4 fetch_pixel_c8
2799 #define store_scanline_x4g4 store_scanline_c8
2800 FORMAT_INFO (x4g4),
2801
2802 FORMAT_INFO (x4a4),
2803
2804 /* 4bpp formats */
2805 FORMAT_INFO (a4),
2806 FORMAT_INFO (r1g2b1),
2807 FORMAT_INFO (b1g2r1),
2808 FORMAT_INFO (a1r1g1b1),
2809 FORMAT_INFO (a1b1g1r1),
2810
2811 FORMAT_INFO (c4),
2812
2813 #define fetch_scanline_g4 fetch_scanline_c4
2814 #define fetch_pixel_g4 fetch_pixel_c4
2815 #define store_scanline_g4 store_scanline_c4
2816 FORMAT_INFO (g4),
2817
2818 /* 1bpp formats */
2819 FORMAT_INFO (a1),
2820 FORMAT_INFO (g1),
2821
2822 /* Wide formats */
2823
2824 { PIXMAN_a2r10g10b10,
2825 NULL, fetch_scanline_a2r10g10b10,
2826 fetch_pixel_generic_lossy_32, fetch_pixel_a2r10g10b10,
2827 NULL, store_scanline_a2r10g10b10 },
2828
2829 { PIXMAN_x2r10g10b10,
2830 NULL, fetch_scanline_x2r10g10b10,
2831 fetch_pixel_generic_lossy_32, fetch_pixel_x2r10g10b10,
2832 NULL, store_scanline_x2r10g10b10 },
2833
2834 { PIXMAN_a2b10g10r10,
2835 NULL, fetch_scanline_a2b10g10r10,
2836 fetch_pixel_generic_lossy_32, fetch_pixel_a2b10g10r10,
2837 NULL, store_scanline_a2b10g10r10 },
2838
2839 { PIXMAN_x2b10g10r10,
2840 NULL, fetch_scanline_x2b10g10r10,
2841 fetch_pixel_generic_lossy_32, fetch_pixel_x2b10g10r10,
2842 NULL, store_scanline_x2b10g10r10 },
2843
2844 /* YUV formats */
2845 { PIXMAN_yuy2,
2846 fetch_scanline_yuy2, fetch_scanline_generic_64,
2847 fetch_pixel_yuy2, fetch_pixel_generic_64,
2848 NULL, NULL },
2849
2850 { PIXMAN_yv12,
2851 fetch_scanline_yv12, fetch_scanline_generic_64,
2852 fetch_pixel_yv12, fetch_pixel_generic_64,
2853 NULL, NULL },
2854
2855 { PIXMAN_null },
2856 };
2857
2858 static void
setup_accessors(bits_image_t * image)2859 setup_accessors (bits_image_t *image)
2860 {
2861 const format_info_t *info = accessors;
2862
2863 while (info->format != PIXMAN_null)
2864 {
2865 if (info->format == image->format)
2866 {
2867 image->fetch_scanline_raw_32 = info->fetch_scanline_raw_32;
2868 image->fetch_scanline_raw_64 = info->fetch_scanline_raw_64;
2869 image->fetch_pixel_raw_32 = info->fetch_pixel_raw_32;
2870 image->fetch_pixel_raw_64 = info->fetch_pixel_raw_64;
2871 image->store_scanline_raw_32 = info->store_scanline_raw_32;
2872 image->store_scanline_raw_64 = info->store_scanline_raw_64;
2873
2874 return;
2875 }
2876
2877 info++;
2878 }
2879 }
2880
2881 #ifndef PIXMAN_FB_ACCESSORS
2882 void
2883 _pixman_bits_image_setup_raw_accessors_accessors (bits_image_t *image);
2884
2885 void
_pixman_bits_image_setup_raw_accessors(bits_image_t * image)2886 _pixman_bits_image_setup_raw_accessors (bits_image_t *image)
2887 {
2888 if (image->read_func || image->write_func)
2889 _pixman_bits_image_setup_raw_accessors_accessors (image);
2890 else
2891 setup_accessors (image);
2892 }
2893
2894 #else
2895
2896 void
_pixman_bits_image_setup_raw_accessors_accessors(bits_image_t * image)2897 _pixman_bits_image_setup_raw_accessors_accessors (bits_image_t *image)
2898 {
2899 setup_accessors (image);
2900 }
2901
2902 #endif
2903