Bug Summary

File:pixman/pixman-bits-image.c
Location:line 1023, column 2
Description:Value stored to 'x' is never read

Annotated Source Code

1/*
2 * Copyright © 2000 Keith Packard, member of The XFree86 Project, Inc.
3 * 2005 Lars Knoll & Zack Rusin, Trolltech
4 * 2008 Aaron Plattner, NVIDIA Corporation
5 * Copyright © 2000 SuSE, Inc.
6 * Copyright © 2007, 2009 Red Hat, Inc.
7 * Copyright © 2008 André Tupinambá <andrelrt@gmail.com>
8 *
9 * Permission to use, copy, modify, distribute, and sell this software and its
10 * documentation for any purpose is hereby granted without fee, provided that
11 * the above copyright notice appear in all copies and that both that
12 * copyright notice and this permission notice appear in supporting
13 * documentation, and that the name of Keith Packard not be used in
14 * advertising or publicity pertaining to distribution of the software without
15 * specific, written prior permission. Keith Packard makes no
16 * representations about the suitability of this software for any purpose. It
17 * is provided "as is" without express or implied warranty.
18 *
19 * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
20 * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
21 * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
22 * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
23 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
24 * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
25 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
26 * SOFTWARE.
27 */
28
29#ifdef HAVE_CONFIG_H1
30#include <config.h>
31#endif
32#include <stdio.h>
33#include <stdlib.h>
34#include <string.h>
35#include "pixman-private.h"
36#include "pixman-combine32.h"
37#include "pixman-inlines.h"
38
39/*
40 * By default, just evaluate the image at 32bpp and expand. Individual image
41 * types can plug in a better scanline getter if they want to. For example
42 * we could produce smoother gradients by evaluating them at higher color
43 * depth, but that's a project for the future.
44 */
45static uint32_t *
46_pixman_image_get_scanline_generic_64 (pixman_iter_t * iter,
47 const uint32_t *mask)
48{
49 int width = iter->width;
50 uint32_t * buffer = iter->buffer;
51
52 pixman_iter_get_scanline_t fetch_32 = iter->data;
53 uint32_t *mask8 = NULL((void*)0);
54
55 /* Contract the mask image, if one exists, so that the 32-bit fetch
56 * function can use it.
57 */
58 if (mask)
59 {
60 mask8 = pixman_malloc_ab (width, sizeof(uint32_t));
61 if (!mask8)
62 return buffer;
63
64 pixman_contract (mask8, (uint64_t *)mask, width);
65 }
66
67 /* Fetch the source image into the first half of buffer. */
68 fetch_32 (iter, mask8);
69
70 /* Expand from 32bpp to 64bpp in place. */
71 pixman_expand ((uint64_t *)buffer, buffer, PIXMAN_a8r8g8b8, width);
72
73 free (mask8);
74
75 return buffer;
76}
77
78/* Fetch functions */
79
80static force_inline__inline__ __attribute__ ((__always_inline__)) uint32_t
81fetch_pixel_no_alpha (bits_image_t *image,
82 int x, int y, pixman_bool_t check_bounds)
83{
84 if (check_bounds &&
85 (x < 0 || x >= image->width || y < 0 || y >= image->height))
86 {
87 return 0;
88 }
89
90 return image->fetch_pixel_32 (image, x, y);
91}
92
93typedef uint32_t (* get_pixel_t) (bits_image_t *image,
94 int x, int y, pixman_bool_t check_bounds);
95
96static force_inline__inline__ __attribute__ ((__always_inline__)) uint32_t
97bits_image_fetch_pixel_nearest (bits_image_t *image,
98 pixman_fixed_t x,
99 pixman_fixed_t y,
100 get_pixel_t get_pixel)
101{
102 int x0 = pixman_fixed_to_int (x - pixman_fixed_e)((int) ((x - ((pixman_fixed_t) 1)) >> 16));
103 int y0 = pixman_fixed_to_int (y - pixman_fixed_e)((int) ((y - ((pixman_fixed_t) 1)) >> 16));
104
105 if (image->common.repeat != PIXMAN_REPEAT_NONE)
106 {
107 repeat (image->common.repeat, &x0, image->width);
108 repeat (image->common.repeat, &y0, image->height);
109
110 return get_pixel (image, x0, y0, FALSE0);
111 }
112 else
113 {
114 return get_pixel (image, x0, y0, TRUE1);
115 }
116}
117
118static force_inline__inline__ __attribute__ ((__always_inline__)) uint32_t
119bits_image_fetch_pixel_bilinear (bits_image_t *image,
120 pixman_fixed_t x,
121 pixman_fixed_t y,
122 get_pixel_t get_pixel)
123{
124 pixman_repeat_t repeat_mode = image->common.repeat;
125 int width = image->width;
126 int height = image->height;
127 int x1, y1, x2, y2;
128 uint32_t tl, tr, bl, br;
129 int32_t distx, disty;
130
131 x1 = x - pixman_fixed_1(((pixman_fixed_t) ((1) << 16))) / 2;
132 y1 = y - pixman_fixed_1(((pixman_fixed_t) ((1) << 16))) / 2;
133
134 distx = pixman_fixed_to_bilinear_weight (x1);
135 disty = pixman_fixed_to_bilinear_weight (y1);
136
137 x1 = pixman_fixed_to_int (x1)((int) ((x1) >> 16));
138 y1 = pixman_fixed_to_int (y1)((int) ((y1) >> 16));
139 x2 = x1 + 1;
140 y2 = y1 + 1;
141
142 if (repeat_mode != PIXMAN_REPEAT_NONE)
143 {
144 repeat (repeat_mode, &x1, width);
145 repeat (repeat_mode, &y1, height);
146 repeat (repeat_mode, &x2, width);
147 repeat (repeat_mode, &y2, height);
148
149 tl = get_pixel (image, x1, y1, FALSE0);
150 bl = get_pixel (image, x1, y2, FALSE0);
151 tr = get_pixel (image, x2, y1, FALSE0);
152 br = get_pixel (image, x2, y2, FALSE0);
153 }
154 else
155 {
156 tl = get_pixel (image, x1, y1, TRUE1);
157 tr = get_pixel (image, x2, y1, TRUE1);
158 bl = get_pixel (image, x1, y2, TRUE1);
159 br = get_pixel (image, x2, y2, TRUE1);
160 }
161
162 return bilinear_interpolation (tl, tr, bl, br, distx, disty);
163}
164
165static uint32_t *
166bits_image_fetch_bilinear_no_repeat_8888 (pixman_iter_t *iter,
167 const uint32_t *mask)
168{
169
170 pixman_image_t * ima = iter->image;
171 int offset = iter->x;
172 int line = iter->y++;
173 int width = iter->width;
174 uint32_t * buffer = iter->buffer;
175
176 bits_image_t *bits = &ima->bits;
177 pixman_fixed_t x_top, x_bottom, x;
178 pixman_fixed_t ux_top, ux_bottom, ux;
179 pixman_vector_t v;
180 uint32_t top_mask, bottom_mask;
181 uint32_t *top_row;
182 uint32_t *bottom_row;
183 uint32_t *end;
184 uint32_t zero[2] = { 0, 0 };
185 uint32_t one = 1;
186 int y, y1, y2;
187 int disty;
188 int mask_inc;
189 int w;
190
191 /* reference point is the center of the pixel */
192 v.vector[0] = pixman_int_to_fixed (offset)((pixman_fixed_t) ((offset) << 16)) + pixman_fixed_1(((pixman_fixed_t) ((1) << 16))) / 2;
193 v.vector[1] = pixman_int_to_fixed (line)((pixman_fixed_t) ((line) << 16)) + pixman_fixed_1(((pixman_fixed_t) ((1) << 16))) / 2;
194 v.vector[2] = pixman_fixed_1(((pixman_fixed_t) ((1) << 16)));
195
196 if (!pixman_transform_point_3d (bits->common.transform, &v))
197 return iter->buffer;
198
199 ux = ux_top = ux_bottom = bits->common.transform->matrix[0][0];
200 x = x_top = x_bottom = v.vector[0] - pixman_fixed_1(((pixman_fixed_t) ((1) << 16)))/2;
201
202 y = v.vector[1] - pixman_fixed_1(((pixman_fixed_t) ((1) << 16)))/2;
203 disty = pixman_fixed_to_bilinear_weight (y);
204
205 /* Load the pointers to the first and second lines from the source
206 * image that bilinear code must read.
207 *
208 * The main trick in this code is about the check if any line are
209 * outside of the image;
210 *
211 * When I realize that a line (any one) is outside, I change
212 * the pointer to a dummy area with zeros. Once I change this, I
213 * must be sure the pointer will not change, so I set the
214 * variables to each pointer increments inside the loop.
215 */
216 y1 = pixman_fixed_to_int (y)((int) ((y) >> 16));
217 y2 = y1 + 1;
218
219 if (y1 < 0 || y1 >= bits->height)
220 {
221 top_row = zero;
222 x_top = 0;
223 ux_top = 0;
224 }
225 else
226 {
227 top_row = bits->bits + y1 * bits->rowstride;
228 x_top = x;
229 ux_top = ux;
230 }
231
232 if (y2 < 0 || y2 >= bits->height)
233 {
234 bottom_row = zero;
235 x_bottom = 0;
236 ux_bottom = 0;
237 }
238 else
239 {
240 bottom_row = bits->bits + y2 * bits->rowstride;
241 x_bottom = x;
242 ux_bottom = ux;
243 }
244
245 /* Instead of checking whether the operation uses the mast in
246 * each loop iteration, verify this only once and prepare the
247 * variables to make the code smaller inside the loop.
248 */
249 if (!mask)
250 {
251 mask_inc = 0;
252 mask = &one;
253 }
254 else
255 {
256 /* If have a mask, prepare the variables to check it */
257 mask_inc = 1;
258 }
259
260 /* If both are zero, then the whole thing is zero */
261 if (top_row == zero && bottom_row == zero)
262 {
263 memset (buffer, 0, width * sizeof (uint32_t));
264 return iter->buffer;
265 }
266 else if (bits->format == PIXMAN_x8r8g8b8)
267 {
268 if (top_row == zero)
269 {
270 top_mask = 0;
271 bottom_mask = 0xff000000;
272 }
273 else if (bottom_row == zero)
274 {
275 top_mask = 0xff000000;
276 bottom_mask = 0;
277 }
278 else
279 {
280 top_mask = 0xff000000;
281 bottom_mask = 0xff000000;
282 }
283 }
284 else
285 {
286 top_mask = 0;
287 bottom_mask = 0;
288 }
289
290 end = buffer + width;
291
292 /* Zero fill to the left of the image */
293 while (buffer < end && x < pixman_fixed_minus_1(((pixman_fixed_t) ((-1) << 16))))
294 {
295 *buffer++ = 0;
296 x += ux;
297 x_top += ux_top;
298 x_bottom += ux_bottom;
299 mask += mask_inc;
300 }
301
302 /* Left edge
303 */
304 while (buffer < end && x < 0)
305 {
306 uint32_t tr, br;
307 int32_t distx;
308
309 tr = top_row[pixman_fixed_to_int (x_top)((int) ((x_top) >> 16)) + 1] | top_mask;
310 br = bottom_row[pixman_fixed_to_int (x_bottom)((int) ((x_bottom) >> 16)) + 1] | bottom_mask;
311
312 distx = pixman_fixed_to_bilinear_weight (x);
313
314 *buffer++ = bilinear_interpolation (0, tr, 0, br, distx, disty);
315
316 x += ux;
317 x_top += ux_top;
318 x_bottom += ux_bottom;
319 mask += mask_inc;
320 }
321
322 /* Main part */
323 w = pixman_int_to_fixed (bits->width - 1)((pixman_fixed_t) ((bits->width - 1) << 16));
324
325 while (buffer < end && x < w)
326 {
327 if (*mask)
328 {
329 uint32_t tl, tr, bl, br;
330 int32_t distx;
331
332 tl = top_row [pixman_fixed_to_int (x_top)((int) ((x_top) >> 16))] | top_mask;
333 tr = top_row [pixman_fixed_to_int (x_top)((int) ((x_top) >> 16)) + 1] | top_mask;
334 bl = bottom_row [pixman_fixed_to_int (x_bottom)((int) ((x_bottom) >> 16))] | bottom_mask;
335 br = bottom_row [pixman_fixed_to_int (x_bottom)((int) ((x_bottom) >> 16)) + 1] | bottom_mask;
336
337 distx = pixman_fixed_to_bilinear_weight (x);
338
339 *buffer = bilinear_interpolation (tl, tr, bl, br, distx, disty);
340 }
341
342 buffer++;
343 x += ux;
344 x_top += ux_top;
345 x_bottom += ux_bottom;
346 mask += mask_inc;
347 }
348
349 /* Right Edge */
350 w = pixman_int_to_fixed (bits->width)((pixman_fixed_t) ((bits->width) << 16));
351 while (buffer < end && x < w)
352 {
353 if (*mask)
354 {
355 uint32_t tl, bl;
356 int32_t distx;
357
358 tl = top_row [pixman_fixed_to_int (x_top)((int) ((x_top) >> 16))] | top_mask;
359 bl = bottom_row [pixman_fixed_to_int (x_bottom)((int) ((x_bottom) >> 16))] | bottom_mask;
360
361 distx = pixman_fixed_to_bilinear_weight (x);
362
363 *buffer = bilinear_interpolation (tl, 0, bl, 0, distx, disty);
364 }
365
366 buffer++;
367 x += ux;
368 x_top += ux_top;
369 x_bottom += ux_bottom;
370 mask += mask_inc;
371 }
372
373 /* Zero fill to the left of the image */
374 while (buffer < end)
375 *buffer++ = 0;
376
377 return iter->buffer;
378}
379
380static force_inline__inline__ __attribute__ ((__always_inline__)) uint32_t
381bits_image_fetch_pixel_convolution (bits_image_t *image,
382 pixman_fixed_t x,
383 pixman_fixed_t y,
384 get_pixel_t get_pixel)
385{
386 pixman_fixed_t *params = image->common.filter_params;
387 int x_off = (params[0] - pixman_fixed_1(((pixman_fixed_t) ((1) << 16)))) >> 1;
388 int y_off = (params[1] - pixman_fixed_1(((pixman_fixed_t) ((1) << 16)))) >> 1;
389 int32_t cwidth = pixman_fixed_to_int (params[0])((int) ((params[0]) >> 16));
390 int32_t cheight = pixman_fixed_to_int (params[1])((int) ((params[1]) >> 16));
391 int32_t i, j, x1, x2, y1, y2;
392 pixman_repeat_t repeat_mode = image->common.repeat;
393 int width = image->width;
394 int height = image->height;
395 int srtot, sgtot, sbtot, satot;
396
397 params += 2;
398
399 x1 = pixman_fixed_to_int (x - pixman_fixed_e - x_off)((int) ((x - ((pixman_fixed_t) 1) - x_off) >> 16));
400 y1 = pixman_fixed_to_int (y - pixman_fixed_e - y_off)((int) ((y - ((pixman_fixed_t) 1) - y_off) >> 16));
401 x2 = x1 + cwidth;
402 y2 = y1 + cheight;
403
404 srtot = sgtot = sbtot = satot = 0;
405
406 for (i = y1; i < y2; ++i)
407 {
408 for (j = x1; j < x2; ++j)
409 {
410 int rx = j;
411 int ry = i;
412
413 pixman_fixed_t f = *params;
414
415 if (f)
416 {
417 uint32_t pixel;
418
419 if (repeat_mode != PIXMAN_REPEAT_NONE)
420 {
421 repeat (repeat_mode, &rx, width);
422 repeat (repeat_mode, &ry, height);
423
424 pixel = get_pixel (image, rx, ry, FALSE0);
425 }
426 else
427 {
428 pixel = get_pixel (image, rx, ry, TRUE1);
429 }
430
431 srtot += (int)RED_8 (pixel)(((pixel) >> 8 * 2) & 0xff) * f;
432 sgtot += (int)GREEN_8 (pixel)(((pixel) >> 8) & 0xff) * f;
433 sbtot += (int)BLUE_8 (pixel)((pixel) & 0xff) * f;
434 satot += (int)ALPHA_8 (pixel)((pixel) >> 8 * 3) * f;
435 }
436
437 params++;
438 }
439 }
440
441 satot >>= 16;
442 srtot >>= 16;
443 sgtot >>= 16;
444 sbtot >>= 16;
445
446 satot = CLIP (satot, 0, 0xff)((satot) < (0) ? (0) : ((satot) > (0xff) ? (0xff) : (satot
)))
;
447 srtot = CLIP (srtot, 0, 0xff)((srtot) < (0) ? (0) : ((srtot) > (0xff) ? (0xff) : (srtot
)))
;
448 sgtot = CLIP (sgtot, 0, 0xff)((sgtot) < (0) ? (0) : ((sgtot) > (0xff) ? (0xff) : (sgtot
)))
;
449 sbtot = CLIP (sbtot, 0, 0xff)((sbtot) < (0) ? (0) : ((sbtot) > (0xff) ? (0xff) : (sbtot
)))
;
450
451 return ((satot << 24) | (srtot << 16) | (sgtot << 8) | (sbtot));
452}
453
454static force_inline__inline__ __attribute__ ((__always_inline__)) uint32_t
455bits_image_fetch_pixel_filtered (bits_image_t *image,
456 pixman_fixed_t x,
457 pixman_fixed_t y,
458 get_pixel_t get_pixel)
459{
460 switch (image->common.filter)
461 {
462 case PIXMAN_FILTER_NEAREST:
463 case PIXMAN_FILTER_FAST:
464 return bits_image_fetch_pixel_nearest (image, x, y, get_pixel);
465 break;
466
467 case PIXMAN_FILTER_BILINEAR:
468 case PIXMAN_FILTER_GOOD:
469 case PIXMAN_FILTER_BEST:
470 return bits_image_fetch_pixel_bilinear (image, x, y, get_pixel);
471 break;
472
473 case PIXMAN_FILTER_CONVOLUTION:
474 return bits_image_fetch_pixel_convolution (image, x, y, get_pixel);
475 break;
476
477 default:
478 break;
479 }
480
481 return 0;
482}
483
484static uint32_t *
485bits_image_fetch_affine_no_alpha (pixman_iter_t * iter,
486 const uint32_t * mask)
487{
488 pixman_image_t *image = iter->image;
489 int offset = iter->x;
490 int line = iter->y++;
491 int width = iter->width;
492 uint32_t * buffer = iter->buffer;
493
494 pixman_fixed_t x, y;
495 pixman_fixed_t ux, uy;
496 pixman_vector_t v;
497 int i;
498
499 /* reference point is the center of the pixel */
500 v.vector[0] = pixman_int_to_fixed (offset)((pixman_fixed_t) ((offset) << 16)) + pixman_fixed_1(((pixman_fixed_t) ((1) << 16))) / 2;
501 v.vector[1] = pixman_int_to_fixed (line)((pixman_fixed_t) ((line) << 16)) + pixman_fixed_1(((pixman_fixed_t) ((1) << 16))) / 2;
502 v.vector[2] = pixman_fixed_1(((pixman_fixed_t) ((1) << 16)));
503
504 if (image->common.transform)
505 {
506 if (!pixman_transform_point_3d (image->common.transform, &v))
507 return iter->buffer;
508
509 ux = image->common.transform->matrix[0][0];
510 uy = image->common.transform->matrix[1][0];
511 }
512 else
513 {
514 ux = pixman_fixed_1(((pixman_fixed_t) ((1) << 16)));
515 uy = 0;
516 }
517
518 x = v.vector[0];
519 y = v.vector[1];
520
521 for (i = 0; i < width; ++i)
522 {
523 if (!mask || mask[i])
524 {
525 buffer[i] = bits_image_fetch_pixel_filtered (
526 &image->bits, x, y, fetch_pixel_no_alpha);
527 }
528
529 x += ux;
530 y += uy;
531 }
532
533 return buffer;
534}
535
536/* General fetcher */
537static force_inline__inline__ __attribute__ ((__always_inline__)) uint32_t
538fetch_pixel_general (bits_image_t *image, int x, int y, pixman_bool_t check_bounds)
539{
540 uint32_t pixel;
541
542 if (check_bounds &&
543 (x < 0 || x >= image->width || y < 0 || y >= image->height))
544 {
545 return 0;
546 }
547
548 pixel = image->fetch_pixel_32 (image, x, y);
549
550 if (image->common.alpha_map)
551 {
552 uint32_t pixel_a;
553
554 x -= image->common.alpha_origin_x;
555 y -= image->common.alpha_origin_y;
556
557 if (x < 0 || x >= image->common.alpha_map->width ||
558 y < 0 || y >= image->common.alpha_map->height)
559 {
560 pixel_a = 0;
561 }
562 else
563 {
564 pixel_a = image->common.alpha_map->fetch_pixel_32 (
565 image->common.alpha_map, x, y);
566
567 pixel_a = ALPHA_8 (pixel_a)((pixel_a) >> 8 * 3);
568 }
569
570 pixel &= 0x00ffffff;
571 pixel |= (pixel_a << 24);
572 }
573
574 return pixel;
575}
576
577static uint32_t *
578bits_image_fetch_general (pixman_iter_t *iter,
579 const uint32_t *mask)
580{
581 pixman_image_t *image = iter->image;
582 int offset = iter->x;
583 int line = iter->y++;
584 int width = iter->width;
585 uint32_t * buffer = iter->buffer;
586
587 pixman_fixed_t x, y, w;
588 pixman_fixed_t ux, uy, uw;
589 pixman_vector_t v;
590 int i;
591
592 /* reference point is the center of the pixel */
593 v.vector[0] = pixman_int_to_fixed (offset)((pixman_fixed_t) ((offset) << 16)) + pixman_fixed_1(((pixman_fixed_t) ((1) << 16))) / 2;
594 v.vector[1] = pixman_int_to_fixed (line)((pixman_fixed_t) ((line) << 16)) + pixman_fixed_1(((pixman_fixed_t) ((1) << 16))) / 2;
595 v.vector[2] = pixman_fixed_1(((pixman_fixed_t) ((1) << 16)));
596
597 if (image->common.transform)
598 {
599 if (!pixman_transform_point_3d (image->common.transform, &v))
600 return buffer;
601
602 ux = image->common.transform->matrix[0][0];
603 uy = image->common.transform->matrix[1][0];
604 uw = image->common.transform->matrix[2][0];
605 }
606 else
607 {
608 ux = pixman_fixed_1(((pixman_fixed_t) ((1) << 16)));
609 uy = 0;
610 uw = 0;
611 }
612
613 x = v.vector[0];
614 y = v.vector[1];
615 w = v.vector[2];
616
617 for (i = 0; i < width; ++i)
618 {
619 pixman_fixed_t x0, y0;
620
621 if (!mask || mask[i])
622 {
623 if (w != 0)
624 {
625 x0 = ((pixman_fixed_48_16_t)x << 16) / w;
626 y0 = ((pixman_fixed_48_16_t)y << 16) / w;
627 }
628 else
629 {
630 x0 = 0;
631 y0 = 0;
632 }
633
634 buffer[i] = bits_image_fetch_pixel_filtered (
635 &image->bits, x0, y0, fetch_pixel_general);
636 }
637
638 x += ux;
639 y += uy;
640 w += uw;
641 }
642
643 return buffer;
644}
645
646static const uint8_t zero[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
647
648typedef uint32_t (* convert_pixel_t) (const uint8_t *row, int x);
649
650static force_inline__inline__ __attribute__ ((__always_inline__)) void
651bits_image_fetch_bilinear_affine (pixman_image_t * image,
652 int offset,
653 int line,
654 int width,
655 uint32_t * buffer,
656 const uint32_t * mask,
657
658 convert_pixel_t convert_pixel,
659 pixman_format_code_t format,
660 pixman_repeat_t repeat_mode)
661{
662 pixman_fixed_t x, y;
663 pixman_fixed_t ux, uy;
664 pixman_vector_t v;
665 bits_image_t *bits = &image->bits;
666 int i;
667
668 /* reference point is the center of the pixel */
669 v.vector[0] = pixman_int_to_fixed (offset)((pixman_fixed_t) ((offset) << 16)) + pixman_fixed_1(((pixman_fixed_t) ((1) << 16))) / 2;
670 v.vector[1] = pixman_int_to_fixed (line)((pixman_fixed_t) ((line) << 16)) + pixman_fixed_1(((pixman_fixed_t) ((1) << 16))) / 2;
671 v.vector[2] = pixman_fixed_1(((pixman_fixed_t) ((1) << 16)));
672
673 if (!pixman_transform_point_3d (image->common.transform, &v))
674 return;
675
676 ux = image->common.transform->matrix[0][0];
677 uy = image->common.transform->matrix[1][0];
678
679 x = v.vector[0];
680 y = v.vector[1];
681
682 for (i = 0; i < width; ++i)
683 {
684 int x1, y1, x2, y2;
685 uint32_t tl, tr, bl, br;
686 int32_t distx, disty;
687 int width = image->bits.width;
688 int height = image->bits.height;
689 const uint8_t *row1;
690 const uint8_t *row2;
691
692 if (mask && !mask[i])
693 goto next;
694
695 x1 = x - pixman_fixed_1(((pixman_fixed_t) ((1) << 16))) / 2;
696 y1 = y - pixman_fixed_1(((pixman_fixed_t) ((1) << 16))) / 2;
697
698 distx = pixman_fixed_to_bilinear_weight (x1);
699 disty = pixman_fixed_to_bilinear_weight (y1);
700
701 y1 = pixman_fixed_to_int (y1)((int) ((y1) >> 16));
702 y2 = y1 + 1;
703 x1 = pixman_fixed_to_int (x1)((int) ((x1) >> 16));
704 x2 = x1 + 1;
705
706 if (repeat_mode != PIXMAN_REPEAT_NONE)
707 {
708 uint32_t mask;
709
710 mask = PIXMAN_FORMAT_A (format)(((format) >> 12) & 0x0f)? 0 : 0xff000000;
711
712 repeat (repeat_mode, &x1, width);
713 repeat (repeat_mode, &y1, height);
714 repeat (repeat_mode, &x2, width);
715 repeat (repeat_mode, &y2, height);
716
717 row1 = (uint8_t *)bits->bits + bits->rowstride * 4 * y1;
718 row2 = (uint8_t *)bits->bits + bits->rowstride * 4 * y2;
719
720 tl = convert_pixel (row1, x1) | mask;
721 tr = convert_pixel (row1, x2) | mask;
722 bl = convert_pixel (row2, x1) | mask;
723 br = convert_pixel (row2, x2) | mask;
724 }
725 else
726 {
727 uint32_t mask1, mask2;
728 int bpp;
729
730 /* Note: PIXMAN_FORMAT_BPP() returns an unsigned value,
731 * which means if you use it in expressions, those
732 * expressions become unsigned themselves. Since
733 * the variables below can be negative in some cases,
734 * that will lead to crashes on 64 bit architectures.
735 *
736 * So this line makes sure bpp is signed
737 */
738 bpp = PIXMAN_FORMAT_BPP (format)(((format) >> 24) );
739
740 if (x1 >= width || x2 < 0 || y1 >= height || y2 < 0)
741 {
742 buffer[i] = 0;
743 goto next;
744 }
745
746 if (y2 == 0)
747 {
748 row1 = zero;
749 mask1 = 0;
750 }
751 else
752 {
753 row1 = (uint8_t *)bits->bits + bits->rowstride * 4 * y1;
754 row1 += bpp / 8 * x1;
755
756 mask1 = PIXMAN_FORMAT_A (format)(((format) >> 12) & 0x0f)? 0 : 0xff000000;
757 }
758
759 if (y1 == height - 1)
760 {
761 row2 = zero;
762 mask2 = 0;
763 }
764 else
765 {
766 row2 = (uint8_t *)bits->bits + bits->rowstride * 4 * y2;
767 row2 += bpp / 8 * x1;
768
769 mask2 = PIXMAN_FORMAT_A (format)(((format) >> 12) & 0x0f)? 0 : 0xff000000;
770 }
771
772 if (x2 == 0)
773 {
774 tl = 0;
775 bl = 0;
776 }
777 else
778 {
779 tl = convert_pixel (row1, 0) | mask1;
780 bl = convert_pixel (row2, 0) | mask2;
781 }
782
783 if (x1 == width - 1)
784 {
785 tr = 0;
786 br = 0;
787 }
788 else
789 {
790 tr = convert_pixel (row1, 1) | mask1;
791 br = convert_pixel (row2, 1) | mask2;
792 }
793 }
794
795 buffer[i] = bilinear_interpolation (
796 tl, tr, bl, br, distx, disty);
797
798 next:
799 x += ux;
800 y += uy;
801 }
802}
803
804static force_inline__inline__ __attribute__ ((__always_inline__)) void
805bits_image_fetch_nearest_affine (pixman_image_t * image,
806 int offset,
807 int line,
808 int width,
809 uint32_t * buffer,
810 const uint32_t * mask,
811
812 convert_pixel_t convert_pixel,
813 pixman_format_code_t format,
814 pixman_repeat_t repeat_mode)
815{
816 pixman_fixed_t x, y;
817 pixman_fixed_t ux, uy;
818 pixman_vector_t v;
819 bits_image_t *bits = &image->bits;
820 int i;
821
822 /* reference point is the center of the pixel */
823 v.vector[0] = pixman_int_to_fixed (offset)((pixman_fixed_t) ((offset) << 16)) + pixman_fixed_1(((pixman_fixed_t) ((1) << 16))) / 2;
824 v.vector[1] = pixman_int_to_fixed (line)((pixman_fixed_t) ((line) << 16)) + pixman_fixed_1(((pixman_fixed_t) ((1) << 16))) / 2;
825 v.vector[2] = pixman_fixed_1(((pixman_fixed_t) ((1) << 16)));
826
827 if (!pixman_transform_point_3d (image->common.transform, &v))
828 return;
829
830 ux = image->common.transform->matrix[0][0];
831 uy = image->common.transform->matrix[1][0];
832
833 x = v.vector[0];
834 y = v.vector[1];
835
836 for (i = 0; i < width; ++i)
837 {
838 int width, height, x0, y0;
839 const uint8_t *row;
840
841 if (mask && !mask[i])
842 goto next;
843
844 width = image->bits.width;
845 height = image->bits.height;
846 x0 = pixman_fixed_to_int (x - pixman_fixed_e)((int) ((x - ((pixman_fixed_t) 1)) >> 16));
847 y0 = pixman_fixed_to_int (y - pixman_fixed_e)((int) ((y - ((pixman_fixed_t) 1)) >> 16));
848
849 if (repeat_mode == PIXMAN_REPEAT_NONE &&
850 (y0 < 0 || y0 >= height || x0 < 0 || x0 >= width))
851 {
852 buffer[i] = 0;
853 }
854 else
855 {
856 uint32_t mask = PIXMAN_FORMAT_A (format)(((format) >> 12) & 0x0f)? 0 : 0xff000000;
857
858 if (repeat_mode != PIXMAN_REPEAT_NONE)
859 {
860 repeat (repeat_mode, &x0, width);
861 repeat (repeat_mode, &y0, height);
862 }
863
864 row = (uint8_t *)bits->bits + bits->rowstride * 4 * y0;
865
866 buffer[i] = convert_pixel (row, x0) | mask;
867 }
868
869 next:
870 x += ux;
871 y += uy;
872 }
873}
874
875static force_inline__inline__ __attribute__ ((__always_inline__)) uint32_t
876convert_a8r8g8b8 (const uint8_t *row, int x)
877{
878 return *(((uint32_t *)row) + x);
879}
880
881static force_inline__inline__ __attribute__ ((__always_inline__)) uint32_t
882convert_x8r8g8b8 (const uint8_t *row, int x)
883{
884 return *(((uint32_t *)row) + x);
885}
886
887static force_inline__inline__ __attribute__ ((__always_inline__)) uint32_t
888convert_a8 (const uint8_t *row, int x)
889{
890 return *(row + x) << 24;
891}
892
893static force_inline__inline__ __attribute__ ((__always_inline__)) uint32_t
894convert_r5g6b5 (const uint8_t *row, int x)
895{
896 return CONVERT_0565_TO_0888 (*((uint16_t *)row + x))(((((*((uint16_t *)row + x)) << 3) & 0xf8) | (((*((
uint16_t *)row + x)) >> 2) & 0x7)) | ((((*((uint16_t
*)row + x)) << 5) & 0xfc00) | (((*((uint16_t *)row
+ x)) >> 1) & 0x300)) | ((((*((uint16_t *)row + x)
) << 8) & 0xf80000) | (((*((uint16_t *)row + x)) <<
3) & 0x70000)))
;
897}
898
899#define MAKE_BILINEAR_FETCHER(name, format, repeat_mode)static uint32_t * bits_image_fetch_bilinear_affine_name (pixman_iter_t
*iter, const uint32_t * mask) { bits_image_fetch_bilinear_affine
(iter->image, iter->x, iter->y++, iter->width, iter
->buffer, mask, convert_format, PIXMAN_format, repeat_mode
); return iter->buffer; }
\
900 static uint32_t * \
901 bits_image_fetch_bilinear_affine_ ## name (pixman_iter_t *iter, \
902 const uint32_t * mask) \
903 { \
904 bits_image_fetch_bilinear_affine (iter->image, \
905 iter->x, iter->y++, \
906 iter->width, \
907 iter->buffer, mask, \
908 convert_ ## format, \
909 PIXMAN_ ## format, \
910 repeat_mode); \
911 return iter->buffer; \
912 }
913
914#define MAKE_NEAREST_FETCHER(name, format, repeat_mode)static uint32_t * bits_image_fetch_nearest_affine_name (pixman_iter_t
*iter, const uint32_t * mask) { bits_image_fetch_nearest_affine
(iter->image, iter->x, iter->y++, iter->width, iter
->buffer, mask, convert_format, PIXMAN_format, repeat_mode
); return iter->buffer; }
\
915 static uint32_t * \
916 bits_image_fetch_nearest_affine_ ## name (pixman_iter_t *iter, \
917 const uint32_t * mask) \
918 { \
919 bits_image_fetch_nearest_affine (iter->image, \
920 iter->x, iter->y++, \
921 iter->width, \
922 iter->buffer, mask, \
923 convert_ ## format, \
924 PIXMAN_ ## format, \
925 repeat_mode); \
926 return iter->buffer; \
927 }
928
929#define MAKE_FETCHERS(name, format, repeat_mode)static uint32_t * bits_image_fetch_nearest_affine_name (pixman_iter_t
*iter, const uint32_t * mask) { bits_image_fetch_nearest_affine
(iter->image, iter->x, iter->y++, iter->width, iter
->buffer, mask, convert_format, PIXMAN_format, repeat_mode
); return iter->buffer; } static uint32_t * bits_image_fetch_bilinear_affine_name
(pixman_iter_t *iter, const uint32_t * mask) { bits_image_fetch_bilinear_affine
(iter->image, iter->x, iter->y++, iter->width, iter
->buffer, mask, convert_format, PIXMAN_format, repeat_mode
); return iter->buffer; }
\
930 MAKE_NEAREST_FETCHER (name, format, repeat_mode)static uint32_t * bits_image_fetch_nearest_affine_name (pixman_iter_t
*iter, const uint32_t * mask) { bits_image_fetch_nearest_affine
(iter->image, iter->x, iter->y++, iter->width, iter
->buffer, mask, convert_format, PIXMAN_format, repeat_mode
); return iter->buffer; }
\
931 MAKE_BILINEAR_FETCHER (name, format, repeat_mode)static uint32_t * bits_image_fetch_bilinear_affine_name (pixman_iter_t
*iter, const uint32_t * mask) { bits_image_fetch_bilinear_affine
(iter->image, iter->x, iter->y++, iter->width, iter
->buffer, mask, convert_format, PIXMAN_format, repeat_mode
); return iter->buffer; }
932
933MAKE_FETCHERS (pad_a8r8g8b8, a8r8g8b8, PIXMAN_REPEAT_PAD)static uint32_t * bits_image_fetch_nearest_affine_pad_a8r8g8b8
(pixman_iter_t *iter, const uint32_t * mask) { bits_image_fetch_nearest_affine
(iter->image, iter->x, iter->y++, iter->width, iter
->buffer, mask, convert_a8r8g8b8, PIXMAN_a8r8g8b8, PIXMAN_REPEAT_PAD
); return iter->buffer; } static uint32_t * bits_image_fetch_bilinear_affine_pad_a8r8g8b8
(pixman_iter_t *iter, const uint32_t * mask) { bits_image_fetch_bilinear_affine
(iter->image, iter->x, iter->y++, iter->width, iter
->buffer, mask, convert_a8r8g8b8, PIXMAN_a8r8g8b8, PIXMAN_REPEAT_PAD
); return iter->buffer; }
934MAKE_FETCHERS (none_a8r8g8b8, a8r8g8b8, PIXMAN_REPEAT_NONE)static uint32_t * bits_image_fetch_nearest_affine_none_a8r8g8b8
(pixman_iter_t *iter, const uint32_t * mask) { bits_image_fetch_nearest_affine
(iter->image, iter->x, iter->y++, iter->width, iter
->buffer, mask, convert_a8r8g8b8, PIXMAN_a8r8g8b8, PIXMAN_REPEAT_NONE
); return iter->buffer; } static uint32_t * bits_image_fetch_bilinear_affine_none_a8r8g8b8
(pixman_iter_t *iter, const uint32_t * mask) { bits_image_fetch_bilinear_affine
(iter->image, iter->x, iter->y++, iter->width, iter
->buffer, mask, convert_a8r8g8b8, PIXMAN_a8r8g8b8, PIXMAN_REPEAT_NONE
); return iter->buffer; }
935MAKE_FETCHERS (reflect_a8r8g8b8, a8r8g8b8, PIXMAN_REPEAT_REFLECT)static uint32_t * bits_image_fetch_nearest_affine_reflect_a8r8g8b8
(pixman_iter_t *iter, const uint32_t * mask) { bits_image_fetch_nearest_affine
(iter->image, iter->x, iter->y++, iter->width, iter
->buffer, mask, convert_a8r8g8b8, PIXMAN_a8r8g8b8, PIXMAN_REPEAT_REFLECT
); return iter->buffer; } static uint32_t * bits_image_fetch_bilinear_affine_reflect_a8r8g8b8
(pixman_iter_t *iter, const uint32_t * mask) { bits_image_fetch_bilinear_affine
(iter->image, iter->x, iter->y++, iter->width, iter
->buffer, mask, convert_a8r8g8b8, PIXMAN_a8r8g8b8, PIXMAN_REPEAT_REFLECT
); return iter->buffer; }
936MAKE_FETCHERS (normal_a8r8g8b8, a8r8g8b8, PIXMAN_REPEAT_NORMAL)static uint32_t * bits_image_fetch_nearest_affine_normal_a8r8g8b8
(pixman_iter_t *iter, const uint32_t * mask) { bits_image_fetch_nearest_affine
(iter->image, iter->x, iter->y++, iter->width, iter
->buffer, mask, convert_a8r8g8b8, PIXMAN_a8r8g8b8, PIXMAN_REPEAT_NORMAL
); return iter->buffer; } static uint32_t * bits_image_fetch_bilinear_affine_normal_a8r8g8b8
(pixman_iter_t *iter, const uint32_t * mask) { bits_image_fetch_bilinear_affine
(iter->image, iter->x, iter->y++, iter->width, iter
->buffer, mask, convert_a8r8g8b8, PIXMAN_a8r8g8b8, PIXMAN_REPEAT_NORMAL
); return iter->buffer; }
937MAKE_FETCHERS (pad_x8r8g8b8, x8r8g8b8, PIXMAN_REPEAT_PAD)static uint32_t * bits_image_fetch_nearest_affine_pad_x8r8g8b8
(pixman_iter_t *iter, const uint32_t * mask) { bits_image_fetch_nearest_affine
(iter->image, iter->x, iter->y++, iter->width, iter
->buffer, mask, convert_x8r8g8b8, PIXMAN_x8r8g8b8, PIXMAN_REPEAT_PAD
); return iter->buffer; } static uint32_t * bits_image_fetch_bilinear_affine_pad_x8r8g8b8
(pixman_iter_t *iter, const uint32_t * mask) { bits_image_fetch_bilinear_affine
(iter->image, iter->x, iter->y++, iter->width, iter
->buffer, mask, convert_x8r8g8b8, PIXMAN_x8r8g8b8, PIXMAN_REPEAT_PAD
); return iter->buffer; }
938MAKE_FETCHERS (none_x8r8g8b8, x8r8g8b8, PIXMAN_REPEAT_NONE)static uint32_t * bits_image_fetch_nearest_affine_none_x8r8g8b8
(pixman_iter_t *iter, const uint32_t * mask) { bits_image_fetch_nearest_affine
(iter->image, iter->x, iter->y++, iter->width, iter
->buffer, mask, convert_x8r8g8b8, PIXMAN_x8r8g8b8, PIXMAN_REPEAT_NONE
); return iter->buffer; } static uint32_t * bits_image_fetch_bilinear_affine_none_x8r8g8b8
(pixman_iter_t *iter, const uint32_t * mask) { bits_image_fetch_bilinear_affine
(iter->image, iter->x, iter->y++, iter->width, iter
->buffer, mask, convert_x8r8g8b8, PIXMAN_x8r8g8b8, PIXMAN_REPEAT_NONE
); return iter->buffer; }
939MAKE_FETCHERS (reflect_x8r8g8b8, x8r8g8b8, PIXMAN_REPEAT_REFLECT)static uint32_t * bits_image_fetch_nearest_affine_reflect_x8r8g8b8
(pixman_iter_t *iter, const uint32_t * mask) { bits_image_fetch_nearest_affine
(iter->image, iter->x, iter->y++, iter->width, iter
->buffer, mask, convert_x8r8g8b8, PIXMAN_x8r8g8b8, PIXMAN_REPEAT_REFLECT
); return iter->buffer; } static uint32_t * bits_image_fetch_bilinear_affine_reflect_x8r8g8b8
(pixman_iter_t *iter, const uint32_t * mask) { bits_image_fetch_bilinear_affine
(iter->image, iter->x, iter->y++, iter->width, iter
->buffer, mask, convert_x8r8g8b8, PIXMAN_x8r8g8b8, PIXMAN_REPEAT_REFLECT
); return iter->buffer; }
940MAKE_FETCHERS (normal_x8r8g8b8, x8r8g8b8, PIXMAN_REPEAT_NORMAL)static uint32_t * bits_image_fetch_nearest_affine_normal_x8r8g8b8
(pixman_iter_t *iter, const uint32_t * mask) { bits_image_fetch_nearest_affine
(iter->image, iter->x, iter->y++, iter->width, iter
->buffer, mask, convert_x8r8g8b8, PIXMAN_x8r8g8b8, PIXMAN_REPEAT_NORMAL
); return iter->buffer; } static uint32_t * bits_image_fetch_bilinear_affine_normal_x8r8g8b8
(pixman_iter_t *iter, const uint32_t * mask) { bits_image_fetch_bilinear_affine
(iter->image, iter->x, iter->y++, iter->width, iter
->buffer, mask, convert_x8r8g8b8, PIXMAN_x8r8g8b8, PIXMAN_REPEAT_NORMAL
); return iter->buffer; }
941MAKE_FETCHERS (pad_a8, a8, PIXMAN_REPEAT_PAD)static uint32_t * bits_image_fetch_nearest_affine_pad_a8 (pixman_iter_t
*iter, const uint32_t * mask) { bits_image_fetch_nearest_affine
(iter->image, iter->x, iter->y++, iter->width, iter
->buffer, mask, convert_a8, PIXMAN_a8, PIXMAN_REPEAT_PAD);
return iter->buffer; } static uint32_t * bits_image_fetch_bilinear_affine_pad_a8
(pixman_iter_t *iter, const uint32_t * mask) { bits_image_fetch_bilinear_affine
(iter->image, iter->x, iter->y++, iter->width, iter
->buffer, mask, convert_a8, PIXMAN_a8, PIXMAN_REPEAT_PAD);
return iter->buffer; }
942MAKE_FETCHERS (none_a8, a8, PIXMAN_REPEAT_NONE)static uint32_t * bits_image_fetch_nearest_affine_none_a8 (pixman_iter_t
*iter, const uint32_t * mask) { bits_image_fetch_nearest_affine
(iter->image, iter->x, iter->y++, iter->width, iter
->buffer, mask, convert_a8, PIXMAN_a8, PIXMAN_REPEAT_NONE)
; return iter->buffer; } static uint32_t * bits_image_fetch_bilinear_affine_none_a8
(pixman_iter_t *iter, const uint32_t * mask) { bits_image_fetch_bilinear_affine
(iter->image, iter->x, iter->y++, iter->width, iter
->buffer, mask, convert_a8, PIXMAN_a8, PIXMAN_REPEAT_NONE)
; return iter->buffer; }
943MAKE_FETCHERS (reflect_a8, a8, PIXMAN_REPEAT_REFLECT)static uint32_t * bits_image_fetch_nearest_affine_reflect_a8 (
pixman_iter_t *iter, const uint32_t * mask) { bits_image_fetch_nearest_affine
(iter->image, iter->x, iter->y++, iter->width, iter
->buffer, mask, convert_a8, PIXMAN_a8, PIXMAN_REPEAT_REFLECT
); return iter->buffer; } static uint32_t * bits_image_fetch_bilinear_affine_reflect_a8
(pixman_iter_t *iter, const uint32_t * mask) { bits_image_fetch_bilinear_affine
(iter->image, iter->x, iter->y++, iter->width, iter
->buffer, mask, convert_a8, PIXMAN_a8, PIXMAN_REPEAT_REFLECT
); return iter->buffer; }
944MAKE_FETCHERS (normal_a8, a8, PIXMAN_REPEAT_NORMAL)static uint32_t * bits_image_fetch_nearest_affine_normal_a8 (
pixman_iter_t *iter, const uint32_t * mask) { bits_image_fetch_nearest_affine
(iter->image, iter->x, iter->y++, iter->width, iter
->buffer, mask, convert_a8, PIXMAN_a8, PIXMAN_REPEAT_NORMAL
); return iter->buffer; } static uint32_t * bits_image_fetch_bilinear_affine_normal_a8
(pixman_iter_t *iter, const uint32_t * mask) { bits_image_fetch_bilinear_affine
(iter->image, iter->x, iter->y++, iter->width, iter
->buffer, mask, convert_a8, PIXMAN_a8, PIXMAN_REPEAT_NORMAL
); return iter->buffer; }
945MAKE_FETCHERS (pad_r5g6b5, r5g6b5, PIXMAN_REPEAT_PAD)static uint32_t * bits_image_fetch_nearest_affine_pad_r5g6b5 (
pixman_iter_t *iter, const uint32_t * mask) { bits_image_fetch_nearest_affine
(iter->image, iter->x, iter->y++, iter->width, iter
->buffer, mask, convert_r5g6b5, PIXMAN_r5g6b5, PIXMAN_REPEAT_PAD
); return iter->buffer; } static uint32_t * bits_image_fetch_bilinear_affine_pad_r5g6b5
(pixman_iter_t *iter, const uint32_t * mask) { bits_image_fetch_bilinear_affine
(iter->image, iter->x, iter->y++, iter->width, iter
->buffer, mask, convert_r5g6b5, PIXMAN_r5g6b5, PIXMAN_REPEAT_PAD
); return iter->buffer; }
946MAKE_FETCHERS (none_r5g6b5, r5g6b5, PIXMAN_REPEAT_NONE)static uint32_t * bits_image_fetch_nearest_affine_none_r5g6b5
(pixman_iter_t *iter, const uint32_t * mask) { bits_image_fetch_nearest_affine
(iter->image, iter->x, iter->y++, iter->width, iter
->buffer, mask, convert_r5g6b5, PIXMAN_r5g6b5, PIXMAN_REPEAT_NONE
); return iter->buffer; } static uint32_t * bits_image_fetch_bilinear_affine_none_r5g6b5
(pixman_iter_t *iter, const uint32_t * mask) { bits_image_fetch_bilinear_affine
(iter->image, iter->x, iter->y++, iter->width, iter
->buffer, mask, convert_r5g6b5, PIXMAN_r5g6b5, PIXMAN_REPEAT_NONE
); return iter->buffer; }
947MAKE_FETCHERS (reflect_r5g6b5, r5g6b5, PIXMAN_REPEAT_REFLECT)static uint32_t * bits_image_fetch_nearest_affine_reflect_r5g6b5
(pixman_iter_t *iter, const uint32_t * mask) { bits_image_fetch_nearest_affine
(iter->image, iter->x, iter->y++, iter->width, iter
->buffer, mask, convert_r5g6b5, PIXMAN_r5g6b5, PIXMAN_REPEAT_REFLECT
); return iter->buffer; } static uint32_t * bits_image_fetch_bilinear_affine_reflect_r5g6b5
(pixman_iter_t *iter, const uint32_t * mask) { bits_image_fetch_bilinear_affine
(iter->image, iter->x, iter->y++, iter->width, iter
->buffer, mask, convert_r5g6b5, PIXMAN_r5g6b5, PIXMAN_REPEAT_REFLECT
); return iter->buffer; }
948MAKE_FETCHERS (normal_r5g6b5, r5g6b5, PIXMAN_REPEAT_NORMAL)static uint32_t * bits_image_fetch_nearest_affine_normal_r5g6b5
(pixman_iter_t *iter, const uint32_t * mask) { bits_image_fetch_nearest_affine
(iter->image, iter->x, iter->y++, iter->width, iter
->buffer, mask, convert_r5g6b5, PIXMAN_r5g6b5, PIXMAN_REPEAT_NORMAL
); return iter->buffer; } static uint32_t * bits_image_fetch_bilinear_affine_normal_r5g6b5
(pixman_iter_t *iter, const uint32_t * mask) { bits_image_fetch_bilinear_affine
(iter->image, iter->x, iter->y++, iter->width, iter
->buffer, mask, convert_r5g6b5, PIXMAN_r5g6b5, PIXMAN_REPEAT_NORMAL
); return iter->buffer; }
949
950static void
951replicate_pixel_32 (bits_image_t * bits,
952 int x,
953 int y,
954 int width,
955 uint32_t * buffer)
956{
957 uint32_t color;
958 uint32_t *end;
959
960 color = bits->fetch_pixel_32 (bits, x, y);
961
962 end = buffer + width;
963 while (buffer < end)
964 *(buffer++) = color;
965}
966
967static void
968replicate_pixel_64 (bits_image_t * bits,
969 int x,
970 int y,
971 int width,
972 uint32_t * b)
973{
974 uint64_t color;
975 uint64_t *buffer = (uint64_t *)b;
976 uint64_t *end;
977
978 color = bits->fetch_pixel_64 (bits, x, y);
979
980 end = buffer + width;
981 while (buffer < end)
982 *(buffer++) = color;
983}
984
985static void
986bits_image_fetch_untransformed_repeat_none (bits_image_t *image,
987 pixman_bool_t wide,
988 int x,
989 int y,
990 int width,
991 uint32_t * buffer)
992{
993 uint32_t w;
994
995 if (y < 0 || y >= image->height)
996 {
997 memset (buffer, 0, width * (wide? 8 : 4));
998 return;
999 }
1000
1001 if (x < 0)
1002 {
1003 w = MIN (width, -x)((width < -x) ? width : -x);
1004
1005 memset (buffer, 0, w * (wide ? 8 : 4));
1006
1007 width -= w;
1008 buffer += w * (wide? 2 : 1);
1009 x += w;
1010 }
1011
1012 if (x < image->width)
1013 {
1014 w = MIN (width, image->width - x)((width < image->width - x) ? width : image->width -
x)
;
1015
1016 if (wide)
1017 image->fetch_scanline_64 ((pixman_image_t *)image, x, y, w, buffer, NULL((void*)0));
1018 else
1019 image->fetch_scanline_32 ((pixman_image_t *)image, x, y, w, buffer, NULL((void*)0));
1020
1021 width -= w;
1022 buffer += w * (wide? 2 : 1);
1023 x += w;
Value stored to 'x' is never read
1024 }
1025
1026 memset (buffer, 0, width * (wide ? 8 : 4));
1027}
1028
1029static void
1030bits_image_fetch_untransformed_repeat_normal (bits_image_t *image,
1031 pixman_bool_t wide,
1032 int x,
1033 int y,
1034 int width,
1035 uint32_t * buffer)
1036{
1037 uint32_t w;
1038
1039 while (y < 0)
1040 y += image->height;
1041
1042 while (y >= image->height)
1043 y -= image->height;
1044
1045 if (image->width == 1)
1046 {
1047 if (wide)
1048 replicate_pixel_64 (image, 0, y, width, buffer);
1049 else
1050 replicate_pixel_32 (image, 0, y, width, buffer);
1051
1052 return;
1053 }
1054
1055 while (width)
1056 {
1057 while (x < 0)
1058 x += image->width;
1059 while (x >= image->width)
1060 x -= image->width;
1061
1062 w = MIN (width, image->width - x)((width < image->width - x) ? width : image->width -
x)
;
1063
1064 if (wide)
1065 image->fetch_scanline_64 ((pixman_image_t *)image, x, y, w, buffer, NULL((void*)0));
1066 else
1067 image->fetch_scanline_32 ((pixman_image_t *)image, x, y, w, buffer, NULL((void*)0));
1068
1069 buffer += w * (wide? 2 : 1);
1070 x += w;
1071 width -= w;
1072 }
1073}
1074
1075static uint32_t *
1076bits_image_fetch_untransformed_32 (pixman_iter_t * iter,
1077 const uint32_t *mask)
1078{
1079 pixman_image_t *image = iter->image;
1080 int x = iter->x;
1081 int y = iter->y;
1082 int width = iter->width;
1083 uint32_t * buffer = iter->buffer;
1084
1085 if (image->common.repeat == PIXMAN_REPEAT_NONE)
1086 {
1087 bits_image_fetch_untransformed_repeat_none (
1088 &image->bits, FALSE0, x, y, width, buffer);
1089 }
1090 else
1091 {
1092 bits_image_fetch_untransformed_repeat_normal (
1093 &image->bits, FALSE0, x, y, width, buffer);
1094 }
1095
1096 iter->y++;
1097 return buffer;
1098}
1099
1100static uint32_t *
1101bits_image_fetch_untransformed_64 (pixman_iter_t * iter,
1102 const uint32_t *mask)
1103
1104{
1105 pixman_image_t *image = iter->image;
1106 int x = iter->x;
1107 int y = iter->y;
1108 int width = iter->width;
1109 uint32_t * buffer = iter->buffer;
1110
1111 if (image->common.repeat == PIXMAN_REPEAT_NONE)
1112 {
1113 bits_image_fetch_untransformed_repeat_none (
1114 &image->bits, TRUE1, x, y, width, buffer);
1115 }
1116 else
1117 {
1118 bits_image_fetch_untransformed_repeat_normal (
1119 &image->bits, TRUE1, x, y, width, buffer);
1120 }
1121
1122 iter->y++;
1123 return buffer;
1124}
1125
1126static uint32_t *
1127_pixman_image_get_scanline_generic_64 (pixman_iter_t *iter,
1128 const uint32_t * mask);
1129
1130typedef struct
1131{
1132 pixman_format_code_t format;
1133 uint32_t flags;
1134 pixman_iter_get_scanline_t get_scanline_32;
1135 pixman_iter_get_scanline_t get_scanline_64;
1136} fetcher_info_t;
1137
1138static const fetcher_info_t fetcher_info[] =
1139{
1140 { PIXMAN_any(((0) << 24) | ((5) << 16) | ((0) << 12) | (
(0) << 8) | ((0) << 4) | ((0)))
,
1141 (FAST_PATH_NO_ALPHA_MAP(1 << 1) |
1142 FAST_PATH_ID_TRANSFORM(1 << 0) |
1143 FAST_PATH_NO_CONVOLUTION_FILTER(1 << 2) |
1144 FAST_PATH_NO_PAD_REPEAT(1 << 3) |
1145 FAST_PATH_NO_REFLECT_REPEAT(1 << 4)),
1146 bits_image_fetch_untransformed_32,
1147 bits_image_fetch_untransformed_64
1148 },
1149
1150#define FAST_BILINEAR_FLAGS((1 << 1) | (1 << 5) | (1 << 12) | (1 <<
17) | (1 << 16) | (1 << 18) | ((1 << 14) |
(1 << 3) | (1 << 4)) | (1 << 19))
\
1151 (FAST_PATH_NO_ALPHA_MAP(1 << 1) | \
1152 FAST_PATH_NO_ACCESSORS(1 << 5) | \
1153 FAST_PATH_HAS_TRANSFORM(1 << 12) | \
1154 FAST_PATH_AFFINE_TRANSFORM(1 << 17) | \
1155 FAST_PATH_X_UNIT_POSITIVE(1 << 16) | \
1156 FAST_PATH_Y_UNIT_ZERO(1 << 18) | \
1157 FAST_PATH_NONE_REPEAT((1 << 14) | (1 << 3) | (1 << 4)) | \
1158 FAST_PATH_BILINEAR_FILTER(1 << 19))
1159
1160 { PIXMAN_a8r8g8b8,
1161 FAST_BILINEAR_FLAGS((1 << 1) | (1 << 5) | (1 << 12) | (1 <<
17) | (1 << 16) | (1 << 18) | ((1 << 14) |
(1 << 3) | (1 << 4)) | (1 << 19))
,
1162 bits_image_fetch_bilinear_no_repeat_8888,
1163 _pixman_image_get_scanline_generic_64
1164 },
1165
1166 { PIXMAN_x8r8g8b8,
1167 FAST_BILINEAR_FLAGS((1 << 1) | (1 << 5) | (1 << 12) | (1 <<
17) | (1 << 16) | (1 << 18) | ((1 << 14) |
(1 << 3) | (1 << 4)) | (1 << 19))
,
1168 bits_image_fetch_bilinear_no_repeat_8888,
1169 _pixman_image_get_scanline_generic_64
1170 },
1171
1172#define GENERAL_BILINEAR_FLAGS((1 << 1) | (1 << 5) | (1 << 12) | (1 <<
17) | (1 << 19))
\
1173 (FAST_PATH_NO_ALPHA_MAP(1 << 1) | \
1174 FAST_PATH_NO_ACCESSORS(1 << 5) | \
1175 FAST_PATH_HAS_TRANSFORM(1 << 12) | \
1176 FAST_PATH_AFFINE_TRANSFORM(1 << 17) | \
1177 FAST_PATH_BILINEAR_FILTER(1 << 19))
1178
1179#define GENERAL_NEAREST_FLAGS((1 << 1) | (1 << 5) | (1 << 12) | (1 <<
17) | (1 << 11))
\
1180 (FAST_PATH_NO_ALPHA_MAP(1 << 1) | \
1181 FAST_PATH_NO_ACCESSORS(1 << 5) | \
1182 FAST_PATH_HAS_TRANSFORM(1 << 12) | \
1183 FAST_PATH_AFFINE_TRANSFORM(1 << 17) | \
1184 FAST_PATH_NEAREST_FILTER(1 << 11))
1185
1186#define BILINEAR_AFFINE_FAST_PATH(name, format, repeat){ PIXMAN_format, ((1 << 1) | (1 << 5) | (1 <<
12) | (1 << 17) | (1 << 19)) | FAST_PATH_repeat_REPEAT
, bits_image_fetch_bilinear_affine_name, _pixman_image_get_scanline_generic_64
},
\
1187 { PIXMAN_ ## format, \
1188 GENERAL_BILINEAR_FLAGS((1 << 1) | (1 << 5) | (1 << 12) | (1 <<
17) | (1 << 19))
| FAST_PATH_ ## repeat ## _REPEAT, \
1189 bits_image_fetch_bilinear_affine_ ## name, \
1190 _pixman_image_get_scanline_generic_64 \
1191 },
1192
1193#define NEAREST_AFFINE_FAST_PATH(name, format, repeat){ PIXMAN_format, ((1 << 1) | (1 << 5) | (1 <<
12) | (1 << 17) | (1 << 11)) | FAST_PATH_repeat_REPEAT
, bits_image_fetch_nearest_affine_name, _pixman_image_get_scanline_generic_64
},
\
1194 { PIXMAN_ ## format, \
1195 GENERAL_NEAREST_FLAGS((1 << 1) | (1 << 5) | (1 << 12) | (1 <<
17) | (1 << 11))
| FAST_PATH_ ## repeat ## _REPEAT, \
1196 bits_image_fetch_nearest_affine_ ## name, \
1197 _pixman_image_get_scanline_generic_64 \
1198 },
1199
1200#define AFFINE_FAST_PATHS(name, format, repeat){ PIXMAN_format, ((1 << 1) | (1 << 5) | (1 <<
12) | (1 << 17) | (1 << 19)) | FAST_PATH_repeat_REPEAT
, bits_image_fetch_bilinear_affine_name, _pixman_image_get_scanline_generic_64
}, { PIXMAN_format, ((1 << 1) | (1 << 5) | (1 <<
12) | (1 << 17) | (1 << 11)) | FAST_PATH_repeat_REPEAT
, bits_image_fetch_nearest_affine_name, _pixman_image_get_scanline_generic_64
},
\
1201 BILINEAR_AFFINE_FAST_PATH(name, format, repeat){ PIXMAN_format, ((1 << 1) | (1 << 5) | (1 <<
12) | (1 << 17) | (1 << 19)) | FAST_PATH_repeat_REPEAT
, bits_image_fetch_bilinear_affine_name, _pixman_image_get_scanline_generic_64
},
\
1202 NEAREST_AFFINE_FAST_PATH(name, format, repeat){ PIXMAN_format, ((1 << 1) | (1 << 5) | (1 <<
12) | (1 << 17) | (1 << 11)) | FAST_PATH_repeat_REPEAT
, bits_image_fetch_nearest_affine_name, _pixman_image_get_scanline_generic_64
},
1203
1204 AFFINE_FAST_PATHS (pad_a8r8g8b8, a8r8g8b8, PAD){ PIXMAN_a8r8g8b8, ((1 << 1) | (1 << 5) | (1 <<
12) | (1 << 17) | (1 << 19)) | ((1 << 15) |
(1 << 14) | (1 << 4)), bits_image_fetch_bilinear_affine_pad_a8r8g8b8
, _pixman_image_get_scanline_generic_64 }, { PIXMAN_a8r8g8b8,
((1 << 1) | (1 << 5) | (1 << 12) | (1 <<
17) | (1 << 11)) | ((1 << 15) | (1 << 14) |
(1 << 4)), bits_image_fetch_nearest_affine_pad_a8r8g8b8
, _pixman_image_get_scanline_generic_64 },
1205 AFFINE_FAST_PATHS (none_a8r8g8b8, a8r8g8b8, NONE){ PIXMAN_a8r8g8b8, ((1 << 1) | (1 << 5) | (1 <<
12) | (1 << 17) | (1 << 19)) | ((1 << 14) |
(1 << 3) | (1 << 4)), bits_image_fetch_bilinear_affine_none_a8r8g8b8
, _pixman_image_get_scanline_generic_64 }, { PIXMAN_a8r8g8b8,
((1 << 1) | (1 << 5) | (1 << 12) | (1 <<
17) | (1 << 11)) | ((1 << 14) | (1 << 3) |
(1 << 4)), bits_image_fetch_nearest_affine_none_a8r8g8b8
, _pixman_image_get_scanline_generic_64 },
1206 AFFINE_FAST_PATHS (reflect_a8r8g8b8, a8r8g8b8, REFLECT){ PIXMAN_a8r8g8b8, ((1 << 1) | (1 << 5) | (1 <<
12) | (1 << 17) | (1 << 19)) | ((1 << 15) |
(1 << 14) | (1 << 3)), bits_image_fetch_bilinear_affine_reflect_a8r8g8b8
, _pixman_image_get_scanline_generic_64 }, { PIXMAN_a8r8g8b8,
((1 << 1) | (1 << 5) | (1 << 12) | (1 <<
17) | (1 << 11)) | ((1 << 15) | (1 << 14) |
(1 << 3)), bits_image_fetch_nearest_affine_reflect_a8r8g8b8
, _pixman_image_get_scanline_generic_64 },
1207 AFFINE_FAST_PATHS (normal_a8r8g8b8, a8r8g8b8, NORMAL){ PIXMAN_a8r8g8b8, ((1 << 1) | (1 << 5) | (1 <<
12) | (1 << 17) | (1 << 19)) | ((1 << 15) |
(1 << 3) | (1 << 4)), bits_image_fetch_bilinear_affine_normal_a8r8g8b8
, _pixman_image_get_scanline_generic_64 }, { PIXMAN_a8r8g8b8,
((1 << 1) | (1 << 5) | (1 << 12) | (1 <<
17) | (1 << 11)) | ((1 << 15) | (1 << 3) |
(1 << 4)), bits_image_fetch_nearest_affine_normal_a8r8g8b8
, _pixman_image_get_scanline_generic_64 },
1208 AFFINE_FAST_PATHS (pad_x8r8g8b8, x8r8g8b8, PAD){ PIXMAN_x8r8g8b8, ((1 << 1) | (1 << 5) | (1 <<
12) | (1 << 17) | (1 << 19)) | ((1 << 15) |
(1 << 14) | (1 << 4)), bits_image_fetch_bilinear_affine_pad_x8r8g8b8
, _pixman_image_get_scanline_generic_64 }, { PIXMAN_x8r8g8b8,
((1 << 1) | (1 << 5) | (1 << 12) | (1 <<
17) | (1 << 11)) | ((1 << 15) | (1 << 14) |
(1 << 4)), bits_image_fetch_nearest_affine_pad_x8r8g8b8
, _pixman_image_get_scanline_generic_64 },
1209 AFFINE_FAST_PATHS (none_x8r8g8b8, x8r8g8b8, NONE){ PIXMAN_x8r8g8b8, ((1 << 1) | (1 << 5) | (1 <<
12) | (1 << 17) | (1 << 19)) | ((1 << 14) |
(1 << 3) | (1 << 4)), bits_image_fetch_bilinear_affine_none_x8r8g8b8
, _pixman_image_get_scanline_generic_64 }, { PIXMAN_x8r8g8b8,
((1 << 1) | (1 << 5) | (1 << 12) | (1 <<
17) | (1 << 11)) | ((1 << 14) | (1 << 3) |
(1 << 4)), bits_image_fetch_nearest_affine_none_x8r8g8b8
, _pixman_image_get_scanline_generic_64 },
1210 AFFINE_FAST_PATHS (reflect_x8r8g8b8, x8r8g8b8, REFLECT){ PIXMAN_x8r8g8b8, ((1 << 1) | (1 << 5) | (1 <<
12) | (1 << 17) | (1 << 19)) | ((1 << 15) |
(1 << 14) | (1 << 3)), bits_image_fetch_bilinear_affine_reflect_x8r8g8b8
, _pixman_image_get_scanline_generic_64 }, { PIXMAN_x8r8g8b8,
((1 << 1) | (1 << 5) | (1 << 12) | (1 <<
17) | (1 << 11)) | ((1 << 15) | (1 << 14) |
(1 << 3)), bits_image_fetch_nearest_affine_reflect_x8r8g8b8
, _pixman_image_get_scanline_generic_64 },
1211 AFFINE_FAST_PATHS (normal_x8r8g8b8, x8r8g8b8, NORMAL){ PIXMAN_x8r8g8b8, ((1 << 1) | (1 << 5) | (1 <<
12) | (1 << 17) | (1 << 19)) | ((1 << 15) |
(1 << 3) | (1 << 4)), bits_image_fetch_bilinear_affine_normal_x8r8g8b8
, _pixman_image_get_scanline_generic_64 }, { PIXMAN_x8r8g8b8,
((1 << 1) | (1 << 5) | (1 << 12) | (1 <<
17) | (1 << 11)) | ((1 << 15) | (1 << 3) |
(1 << 4)), bits_image_fetch_nearest_affine_normal_x8r8g8b8
, _pixman_image_get_scanline_generic_64 },
1212 AFFINE_FAST_PATHS (pad_a8, a8, PAD){ PIXMAN_a8, ((1 << 1) | (1 << 5) | (1 << 12
) | (1 << 17) | (1 << 19)) | ((1 << 15) | (
1 << 14) | (1 << 4)), bits_image_fetch_bilinear_affine_pad_a8
, _pixman_image_get_scanline_generic_64 }, { PIXMAN_a8, ((1 <<
1) | (1 << 5) | (1 << 12) | (1 << 17) | (1
<< 11)) | ((1 << 15) | (1 << 14) | (1 <<
4)), bits_image_fetch_nearest_affine_pad_a8, _pixman_image_get_scanline_generic_64
},
1213 AFFINE_FAST_PATHS (none_a8, a8, NONE){ PIXMAN_a8, ((1 << 1) | (1 << 5) | (1 << 12
) | (1 << 17) | (1 << 19)) | ((1 << 14) | (
1 << 3) | (1 << 4)), bits_image_fetch_bilinear_affine_none_a8
, _pixman_image_get_scanline_generic_64 }, { PIXMAN_a8, ((1 <<
1) | (1 << 5) | (1 << 12) | (1 << 17) | (1
<< 11)) | ((1 << 14) | (1 << 3) | (1 <<
4)), bits_image_fetch_nearest_affine_none_a8, _pixman_image_get_scanline_generic_64
},
1214 AFFINE_FAST_PATHS (reflect_a8, a8, REFLECT){ PIXMAN_a8, ((1 << 1) | (1 << 5) | (1 << 12
) | (1 << 17) | (1 << 19)) | ((1 << 15) | (
1 << 14) | (1 << 3)), bits_image_fetch_bilinear_affine_reflect_a8
, _pixman_image_get_scanline_generic_64 }, { PIXMAN_a8, ((1 <<
1) | (1 << 5) | (1 << 12) | (1 << 17) | (1
<< 11)) | ((1 << 15) | (1 << 14) | (1 <<
3)), bits_image_fetch_nearest_affine_reflect_a8, _pixman_image_get_scanline_generic_64
},
1215 AFFINE_FAST_PATHS (normal_a8, a8, NORMAL){ PIXMAN_a8, ((1 << 1) | (1 << 5) | (1 << 12
) | (1 << 17) | (1 << 19)) | ((1 << 15) | (
1 << 3) | (1 << 4)), bits_image_fetch_bilinear_affine_normal_a8
, _pixman_image_get_scanline_generic_64 }, { PIXMAN_a8, ((1 <<
1) | (1 << 5) | (1 << 12) | (1 << 17) | (1
<< 11)) | ((1 << 15) | (1 << 3) | (1 <<
4)), bits_image_fetch_nearest_affine_normal_a8, _pixman_image_get_scanline_generic_64
},
1216 AFFINE_FAST_PATHS (pad_r5g6b5, r5g6b5, PAD){ PIXMAN_r5g6b5, ((1 << 1) | (1 << 5) | (1 <<
12) | (1 << 17) | (1 << 19)) | ((1 << 15) |
(1 << 14) | (1 << 4)), bits_image_fetch_bilinear_affine_pad_r5g6b5
, _pixman_image_get_scanline_generic_64 }, { PIXMAN_r5g6b5, (
(1 << 1) | (1 << 5) | (1 << 12) | (1 <<
17) | (1 << 11)) | ((1 << 15) | (1 << 14) |
(1 << 4)), bits_image_fetch_nearest_affine_pad_r5g6b5,
_pixman_image_get_scanline_generic_64 },
1217 AFFINE_FAST_PATHS (none_r5g6b5, r5g6b5, NONE){ PIXMAN_r5g6b5, ((1 << 1) | (1 << 5) | (1 <<
12) | (1 << 17) | (1 << 19)) | ((1 << 14) |
(1 << 3) | (1 << 4)), bits_image_fetch_bilinear_affine_none_r5g6b5
, _pixman_image_get_scanline_generic_64 }, { PIXMAN_r5g6b5, (
(1 << 1) | (1 << 5) | (1 << 12) | (1 <<
17) | (1 << 11)) | ((1 << 14) | (1 << 3) |
(1 << 4)), bits_image_fetch_nearest_affine_none_r5g6b5
, _pixman_image_get_scanline_generic_64 },
1218 AFFINE_FAST_PATHS (reflect_r5g6b5, r5g6b5, REFLECT){ PIXMAN_r5g6b5, ((1 << 1) | (1 << 5) | (1 <<
12) | (1 << 17) | (1 << 19)) | ((1 << 15) |
(1 << 14) | (1 << 3)), bits_image_fetch_bilinear_affine_reflect_r5g6b5
, _pixman_image_get_scanline_generic_64 }, { PIXMAN_r5g6b5, (
(1 << 1) | (1 << 5) | (1 << 12) | (1 <<
17) | (1 << 11)) | ((1 << 15) | (1 << 14) |
(1 << 3)), bits_image_fetch_nearest_affine_reflect_r5g6b5
, _pixman_image_get_scanline_generic_64 },
1219 AFFINE_FAST_PATHS (normal_r5g6b5, r5g6b5, NORMAL){ PIXMAN_r5g6b5, ((1 << 1) | (1 << 5) | (1 <<
12) | (1 << 17) | (1 << 19)) | ((1 << 15) |
(1 << 3) | (1 << 4)), bits_image_fetch_bilinear_affine_normal_r5g6b5
, _pixman_image_get_scanline_generic_64 }, { PIXMAN_r5g6b5, (
(1 << 1) | (1 << 5) | (1 << 12) | (1 <<
17) | (1 << 11)) | ((1 << 15) | (1 << 3) |
(1 << 4)), bits_image_fetch_nearest_affine_normal_r5g6b5
, _pixman_image_get_scanline_generic_64 },
1220
1221 /* Affine, no alpha */
1222 { PIXMAN_any(((0) << 24) | ((5) << 16) | ((0) << 12) | (
(0) << 8) | ((0) << 4) | ((0)))
,
1223 (FAST_PATH_NO_ALPHA_MAP(1 << 1) | FAST_PATH_HAS_TRANSFORM(1 << 12) | FAST_PATH_AFFINE_TRANSFORM(1 << 17)),
1224 bits_image_fetch_affine_no_alpha,
1225 _pixman_image_get_scanline_generic_64
1226 },
1227
1228 /* General */
1229 { PIXMAN_any(((0) << 24) | ((5) << 16) | ((0) << 12) | (
(0) << 8) | ((0) << 4) | ((0)))
, 0, bits_image_fetch_general, _pixman_image_get_scanline_generic_64 },
1230
1231 { PIXMAN_null(((0) << 24) | ((0) << 16) | ((0) << 12) | (
(0) << 8) | ((0) << 4) | ((0)))
},
1232};
1233
1234static void
1235bits_image_property_changed (pixman_image_t *image)
1236{
1237 _pixman_bits_image_setup_accessors (&image->bits);
1238}
1239
1240void
1241_pixman_bits_image_src_iter_init (pixman_image_t *image, pixman_iter_t *iter)
1242{
1243 pixman_format_code_t format = image->common.extended_format_code;
1244 uint32_t flags = image->common.flags;
1245 const fetcher_info_t *info;
1246
1247 for (info = fetcher_info; info->format != PIXMAN_null(((0) << 24) | ((0) << 16) | ((0) << 12) | (
(0) << 8) | ((0) << 4) | ((0)))
; ++info)
1248 {
1249 if ((info->format == format || info->format == PIXMAN_any(((0) << 24) | ((5) << 16) | ((0) << 12) | (
(0) << 8) | ((0) << 4) | ((0)))
) &&
1250 (info->flags & flags) == info->flags)
1251 {
1252 if (iter->iter_flags & ITER_NARROW)
1253 {
1254 iter->get_scanline = info->get_scanline_32;
1255 }
1256 else
1257 {
1258 iter->data = info->get_scanline_32;
1259 iter->get_scanline = info->get_scanline_64;
1260 }
1261 return;
1262 }
1263 }
1264
1265 /* Just in case we somehow didn't find a scanline function */
1266 iter->get_scanline = _pixman_iter_get_scanline_noop;
1267}
1268
1269static uint32_t *
1270dest_get_scanline_narrow (pixman_iter_t *iter, const uint32_t *mask)
1271{
1272 pixman_image_t *image = iter->image;
1273 int x = iter->x;
1274 int y = iter->y;
1275 int width = iter->width;
1276 uint32_t * buffer = iter->buffer;
1277
1278 image->bits.fetch_scanline_32 (image, x, y, width, buffer, mask);
1279 if (image->common.alpha_map)
1280 {
1281 uint32_t *alpha;
1282
1283 if ((alpha = malloc (width * sizeof (uint32_t))))
1284 {
1285 int i;
1286
1287 x -= image->common.alpha_origin_x;
1288 y -= image->common.alpha_origin_y;
1289
1290 image->common.alpha_map->fetch_scanline_32 (
1291 (pixman_image_t *)image->common.alpha_map,
1292 x, y, width, alpha, mask);
1293
1294 for (i = 0; i < width; ++i)
1295 {
1296 buffer[i] &= ~0xff000000;
1297 buffer[i] |= (alpha[i] & 0xff000000);
1298 }
1299
1300 free (alpha);
1301 }
1302 }
1303
1304 return iter->buffer;
1305}
1306
1307static uint32_t *
1308dest_get_scanline_wide (pixman_iter_t *iter, const uint32_t *mask)
1309{
1310 bits_image_t * image = &iter->image->bits;
1311 int x = iter->x;
1312 int y = iter->y;
1313 int width = iter->width;
1314 uint64_t * buffer = (uint64_t *)iter->buffer;
1315
1316 image->fetch_scanline_64 (
1317 (pixman_image_t *)image, x, y, width, (uint32_t *)buffer, mask);
1318 if (image->common.alpha_map)
1319 {
1320 uint64_t *alpha;
1321
1322 if ((alpha = malloc (width * sizeof (uint64_t))))
1323 {
1324 int i;
1325
1326 x -= image->common.alpha_origin_x;
1327 y -= image->common.alpha_origin_y;
1328
1329 image->common.alpha_map->fetch_scanline_64 (
1330 (pixman_image_t *)image->common.alpha_map,
1331 x, y, width, (uint32_t *)alpha, mask);
1332
1333 for (i = 0; i < width; ++i)
1334 {
1335 buffer[i] &= ~0xffff000000000000ULL;
1336 buffer[i] |= (alpha[i] & 0xffff000000000000ULL);
1337 }
1338
1339 free (alpha);
1340 }
1341 }
1342
1343 return iter->buffer;
1344}
1345
1346static void
1347dest_write_back_narrow (pixman_iter_t *iter)
1348{
1349 bits_image_t * image = &iter->image->bits;
1350 int x = iter->x;
1351 int y = iter->y;
1352 int width = iter->width;
1353 const uint32_t *buffer = iter->buffer;
1354
1355 image->store_scanline_32 (image, x, y, width, buffer);
1356
1357 if (image->common.alpha_map)
1358 {
1359 x -= image->common.alpha_origin_x;
1360 y -= image->common.alpha_origin_y;
1361
1362 image->common.alpha_map->store_scanline_32 (
1363 image->common.alpha_map, x, y, width, buffer);
1364 }
1365
1366 iter->y++;
1367}
1368
1369static void
1370dest_write_back_wide (pixman_iter_t *iter)
1371{
1372 bits_image_t * image = &iter->image->bits;
1373 int x = iter->x;
1374 int y = iter->y;
1375 int width = iter->width;
1376 const uint32_t *buffer = iter->buffer;
1377
1378 image->store_scanline_64 (image, x, y, width, buffer);
1379
1380 if (image->common.alpha_map)
1381 {
1382 x -= image->common.alpha_origin_x;
1383 y -= image->common.alpha_origin_y;
1384
1385 image->common.alpha_map->store_scanline_64 (
1386 image->common.alpha_map, x, y, width, buffer);
1387 }
1388
1389 iter->y++;
1390}
1391
1392void
1393_pixman_bits_image_dest_iter_init (pixman_image_t *image, pixman_iter_t *iter)
1394{
1395 if (iter->iter_flags & ITER_NARROW)
1396 {
1397 if ((iter->iter_flags & (ITER_IGNORE_RGB | ITER_IGNORE_ALPHA)) ==
1398 (ITER_IGNORE_RGB | ITER_IGNORE_ALPHA))
1399 {
1400 iter->get_scanline = _pixman_iter_get_scanline_noop;
1401 }
1402 else
1403 {
1404 iter->get_scanline = dest_get_scanline_narrow;
1405 }
1406
1407 iter->write_back = dest_write_back_narrow;
1408 }
1409 else
1410 {
1411 iter->get_scanline = dest_get_scanline_wide;
1412 iter->write_back = dest_write_back_wide;
1413 }
1414}
1415
1416static uint32_t *
1417create_bits (pixman_format_code_t format,
1418 int width,
1419 int height,
1420 int * rowstride_bytes)
1421{
1422 int stride;
1423 size_t buf_size;
1424 int bpp;
1425
1426 /* what follows is a long-winded way, avoiding any possibility of integer
1427 * overflows, of saying:
1428 * stride = ((width * bpp + 0x1f) >> 5) * sizeof (uint32_t);
1429 */
1430
1431 bpp = PIXMAN_FORMAT_BPP (format)(((format) >> 24) );
1432 if (_pixman_multiply_overflows_int (width, bpp))
1433 return NULL((void*)0);
1434
1435 stride = width * bpp;
1436 if (_pixman_addition_overflows_int (stride, 0x1f))
1437 return NULL((void*)0);
1438
1439 stride += 0x1f;
1440 stride >>= 5;
1441
1442 stride *= sizeof (uint32_t);
1443
1444 if (_pixman_multiply_overflows_size (height, stride))
1445 return NULL((void*)0);
1446
1447 buf_size = height * stride;
1448
1449 if (rowstride_bytes)
1450 *rowstride_bytes = stride;
1451
1452 return calloc (buf_size, 1);
1453}
1454
1455pixman_bool_t
1456_pixman_bits_image_init (pixman_image_t * image,
1457 pixman_format_code_t format,
1458 int width,
1459 int height,
1460 uint32_t * bits,
1461 int rowstride)
1462{
1463 uint32_t *free_me = NULL((void*)0);
1464
1465 if (!bits && width && height)
1466 {
1467 int rowstride_bytes;
1468
1469 free_me = bits = create_bits (format, width, height, &rowstride_bytes);
1470
1471 if (!bits)
1472 return FALSE0;
1473
1474 rowstride = rowstride_bytes / (int) sizeof (uint32_t);
1475 }
1476
1477 _pixman_image_init (image);
1478
1479 image->type = BITS;
1480 image->bits.format = format;
1481 image->bits.width = width;
1482 image->bits.height = height;
1483 image->bits.bits = bits;
1484 image->bits.free_me = free_me;
1485 image->bits.read_func = NULL((void*)0);
1486 image->bits.write_func = NULL((void*)0);
1487 image->bits.rowstride = rowstride;
1488 image->bits.indexed = NULL((void*)0);
1489
1490 image->common.property_changed = bits_image_property_changed;
1491
1492 _pixman_image_reset_clip_region (image);
1493
1494 return TRUE1;
1495}
1496
1497PIXMAN_EXPORT__attribute__ ((visibility("default"))) pixman_image_t *
1498pixman_image_create_bits (pixman_format_code_t format,
1499 int width,
1500 int height,
1501 uint32_t * bits,
1502 int rowstride_bytes)
1503{
1504 pixman_image_t *image;
1505
1506 /* must be a whole number of uint32_t's
1507 */
1508 return_val_if_fail (do { if (!(bits == ((void*)0) || (rowstride_bytes % sizeof (uint32_t
)) == 0)) return (((void*)0)); } while (0)
1509 bits == NULL || (rowstride_bytes % sizeof (uint32_t)) == 0, NULL)do { if (!(bits == ((void*)0) || (rowstride_bytes % sizeof (uint32_t
)) == 0)) return (((void*)0)); } while (0)
;
1510
1511 return_val_if_fail (PIXMAN_FORMAT_BPP (format) >= PIXMAN_FORMAT_DEPTH (format), NULL)do { if (!((((format) >> 24) ) >= ((((format) >>
12) & 0x0f) + (((format) >> 8) & 0x0f) + (((format
) >> 4) & 0x0f) + (((format) ) & 0x0f)))) return
(((void*)0)); } while (0)
;
1512
1513 image = _pixman_image_allocate ();
1514
1515 if (!image)
1516 return NULL((void*)0);
1517
1518 if (!_pixman_bits_image_init (image, format, width, height, bits,
1519 rowstride_bytes / (int) sizeof (uint32_t)))
1520 {
1521 free (image);
1522 return NULL((void*)0);
1523 }
1524
1525 return image;
1526}