Bug Summary

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