File: | pixman/pixman-bits-image.c |
Location: | line 1130, column 2 |
Description: | Value stored to 'x' is never read |
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 | */ |
44 | static 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 | |
77 | static force_inline__inline__ __attribute__ ((__always_inline__)) uint32_t |
78 | fetch_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 | |
90 | typedef uint32_t (* get_pixel_t) (bits_image_t *image, |
91 | int x, int y, pixman_bool_t check_bounds); |
92 | |
93 | static force_inline__inline__ __attribute__ ((__always_inline__)) void |
94 | repeat (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 | |
121 | static force_inline__inline__ __attribute__ ((__always_inline__)) uint32_t |
122 | bits_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 | |
145 | static force_inline__inline__ __attribute__ ((__always_inline__)) uint32_t |
146 | bilinear_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 | |
189 | static force_inline__inline__ __attribute__ ((__always_inline__)) uint32_t |
190 | bilinear_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 | |
234 | static force_inline__inline__ __attribute__ ((__always_inline__)) uint32_t |
235 | bits_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 | |
281 | static void |
282 | bits_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 | |
491 | static force_inline__inline__ __attribute__ ((__always_inline__)) uint32_t |
492 | bits_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 | |
565 | static force_inline__inline__ __attribute__ ((__always_inline__)) uint32_t |
566 | bits_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 | |
595 | static void |
596 | bits_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 */ |
644 | static force_inline__inline__ __attribute__ ((__always_inline__)) uint32_t |
645 | fetch_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 | |
684 | static void |
685 | bits_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 | |
749 | static const uint8_t zero[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; |
750 | |
751 | typedef uint32_t (* convert_pixel_t) (const uint8_t *row, int x); |
752 | |
753 | static force_inline__inline__ __attribute__ ((__always_inline__)) void |
754 | bits_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 | |
907 | static force_inline__inline__ __attribute__ ((__always_inline__)) void |
908 | bits_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 | |
978 | static force_inline__inline__ __attribute__ ((__always_inline__)) uint32_t |
979 | convert_a8r8g8b8 (const uint8_t *row, int x) |
980 | { |
981 | return *(((uint32_t *)row) + x); |
982 | } |
983 | |
984 | static force_inline__inline__ __attribute__ ((__always_inline__)) uint32_t |
985 | convert_x8r8g8b8 (const uint8_t *row, int x) |
986 | { |
987 | return *(((uint32_t *)row) + x); |
988 | } |
989 | |
990 | static force_inline__inline__ __attribute__ ((__always_inline__)) uint32_t |
991 | convert_a8 (const uint8_t *row, int x) |
992 | { |
993 | return *(row + x) << 24; |
994 | } |
995 | |
996 | static force_inline__inline__ __attribute__ ((__always_inline__)) uint32_t |
997 | convert_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 | |
1038 | MAKE_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); } |
1039 | MAKE_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); } |
1040 | MAKE_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); } |
1041 | MAKE_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); } |
1042 | MAKE_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); } |
1043 | MAKE_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); } |
1044 | MAKE_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); } |
1045 | MAKE_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); } |
1046 | MAKE_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 ); } |
1047 | MAKE_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 ); } |
1048 | MAKE_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); } |
1049 | MAKE_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); } |
1050 | MAKE_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); } |
1051 | MAKE_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); } |
1052 | MAKE_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); } |
1053 | MAKE_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 | |
1055 | static void |
1056 | bits_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 | |
1073 | static void |
1074 | bits_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 | |
1092 | static void |
1093 | bits_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 | |
1136 | static void |
1137 | bits_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 | |
1172 | static void |
1173 | bits_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 | |
1192 | static void |
1193 | bits_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 | |
1212 | typedef 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 | |
1220 | static 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 | |
1322 | static void |
1323 | bits_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 | |
1346 | static uint32_t * |
1347 | src_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 | |
1355 | static uint32_t * |
1356 | src_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 | |
1364 | void |
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 | |
1376 | static uint32_t * |
1377 | dest_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 | |
1399 | static uint32_t * |
1400 | dest_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 | |
1422 | static void |
1423 | dest_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 | |
1445 | static void |
1446 | dest_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 | |
1468 | static void |
1469 | dest_write_back_direct (pixman_iter_t *iter) |
1470 | { |
1471 | iter->buffer += iter->image->bits.rowstride; |
1472 | } |
1473 | |
1474 | void |
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 | |
1516 | static uint32_t * |
1517 | create_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 | |
1555 | PIXMAN_EXPORT__attribute__ ((visibility("default"))) pixman_image_t * |
1556 | pixman_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 | } |