File: | pixman/pixman-bits-image.c |
Location: | line 581, 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 | #include "pixman-inlines.h" |
38 | |
39 | static uint32_t * |
40 | _pixman_image_get_scanline_generic_float (pixman_iter_t * iter, |
41 | const uint32_t *mask) |
42 | { |
43 | pixman_iter_get_scanline_t fetch_32 = iter->data; |
44 | uint32_t *buffer = iter->buffer; |
45 | |
46 | fetch_32 (iter, NULL((void*)0)); |
47 | |
48 | pixman_expand_to_float ((argb_t *)buffer, buffer, PIXMAN_a8r8g8b8, iter->width); |
49 | |
50 | return iter->buffer; |
51 | } |
52 | |
53 | /* Fetch functions */ |
54 | |
55 | static force_inline__inline__ __attribute__ ((__always_inline__)) uint32_t |
56 | fetch_pixel_no_alpha (bits_image_t *image, |
57 | int x, int y, pixman_bool_t check_bounds) |
58 | { |
59 | if (check_bounds && |
60 | (x < 0 || x >= image->width || y < 0 || y >= image->height)) |
61 | { |
62 | return 0; |
63 | } |
64 | |
65 | return image->fetch_pixel_32 (image, x, y); |
66 | } |
67 | |
68 | typedef uint32_t (* get_pixel_t) (bits_image_t *image, |
69 | int x, int y, pixman_bool_t check_bounds); |
70 | |
71 | static force_inline__inline__ __attribute__ ((__always_inline__)) uint32_t |
72 | bits_image_fetch_pixel_nearest (bits_image_t *image, |
73 | pixman_fixed_t x, |
74 | pixman_fixed_t y, |
75 | get_pixel_t get_pixel) |
76 | { |
77 | int x0 = pixman_fixed_to_int (x - pixman_fixed_e)((int) ((x - ((pixman_fixed_t) 1)) >> 16)); |
78 | int y0 = pixman_fixed_to_int (y - pixman_fixed_e)((int) ((y - ((pixman_fixed_t) 1)) >> 16)); |
79 | |
80 | if (image->common.repeat != PIXMAN_REPEAT_NONE) |
81 | { |
82 | repeat (image->common.repeat, &x0, image->width); |
83 | repeat (image->common.repeat, &y0, image->height); |
84 | |
85 | return get_pixel (image, x0, y0, FALSE0); |
86 | } |
87 | else |
88 | { |
89 | return get_pixel (image, x0, y0, TRUE1); |
90 | } |
91 | } |
92 | |
93 | static force_inline__inline__ __attribute__ ((__always_inline__)) uint32_t |
94 | bits_image_fetch_pixel_bilinear (bits_image_t *image, |
95 | pixman_fixed_t x, |
96 | pixman_fixed_t y, |
97 | get_pixel_t get_pixel) |
98 | { |
99 | pixman_repeat_t repeat_mode = image->common.repeat; |
100 | int width = image->width; |
101 | int height = image->height; |
102 | int x1, y1, x2, y2; |
103 | uint32_t tl, tr, bl, br; |
104 | int32_t distx, disty; |
105 | |
106 | x1 = x - pixman_fixed_1(((pixman_fixed_t) ((1) << 16))) / 2; |
107 | y1 = y - pixman_fixed_1(((pixman_fixed_t) ((1) << 16))) / 2; |
108 | |
109 | distx = pixman_fixed_to_bilinear_weight (x1); |
110 | disty = pixman_fixed_to_bilinear_weight (y1); |
111 | |
112 | x1 = pixman_fixed_to_int (x1)((int) ((x1) >> 16)); |
113 | y1 = pixman_fixed_to_int (y1)((int) ((y1) >> 16)); |
114 | x2 = x1 + 1; |
115 | y2 = y1 + 1; |
116 | |
117 | if (repeat_mode != PIXMAN_REPEAT_NONE) |
118 | { |
119 | repeat (repeat_mode, &x1, width); |
120 | repeat (repeat_mode, &y1, height); |
121 | repeat (repeat_mode, &x2, width); |
122 | repeat (repeat_mode, &y2, height); |
123 | |
124 | tl = get_pixel (image, x1, y1, FALSE0); |
125 | bl = get_pixel (image, x1, y2, FALSE0); |
126 | tr = get_pixel (image, x2, y1, FALSE0); |
127 | br = get_pixel (image, x2, y2, FALSE0); |
128 | } |
129 | else |
130 | { |
131 | tl = get_pixel (image, x1, y1, TRUE1); |
132 | tr = get_pixel (image, x2, y1, TRUE1); |
133 | bl = get_pixel (image, x1, y2, TRUE1); |
134 | br = get_pixel (image, x2, y2, TRUE1); |
135 | } |
136 | |
137 | return bilinear_interpolation (tl, tr, bl, br, distx, disty); |
138 | } |
139 | |
140 | static force_inline__inline__ __attribute__ ((__always_inline__)) uint32_t |
141 | bits_image_fetch_pixel_convolution (bits_image_t *image, |
142 | pixman_fixed_t x, |
143 | pixman_fixed_t y, |
144 | get_pixel_t get_pixel) |
145 | { |
146 | pixman_fixed_t *params = image->common.filter_params; |
147 | int x_off = (params[0] - pixman_fixed_1(((pixman_fixed_t) ((1) << 16)))) >> 1; |
148 | int y_off = (params[1] - pixman_fixed_1(((pixman_fixed_t) ((1) << 16)))) >> 1; |
149 | int32_t cwidth = pixman_fixed_to_int (params[0])((int) ((params[0]) >> 16)); |
150 | int32_t cheight = pixman_fixed_to_int (params[1])((int) ((params[1]) >> 16)); |
151 | int32_t i, j, x1, x2, y1, y2; |
152 | pixman_repeat_t repeat_mode = image->common.repeat; |
153 | int width = image->width; |
154 | int height = image->height; |
155 | int srtot, sgtot, sbtot, satot; |
156 | |
157 | params += 2; |
158 | |
159 | x1 = pixman_fixed_to_int (x - pixman_fixed_e - x_off)((int) ((x - ((pixman_fixed_t) 1) - x_off) >> 16)); |
160 | y1 = pixman_fixed_to_int (y - pixman_fixed_e - y_off)((int) ((y - ((pixman_fixed_t) 1) - y_off) >> 16)); |
161 | x2 = x1 + cwidth; |
162 | y2 = y1 + cheight; |
163 | |
164 | srtot = sgtot = sbtot = satot = 0; |
165 | |
166 | for (i = y1; i < y2; ++i) |
167 | { |
168 | for (j = x1; j < x2; ++j) |
169 | { |
170 | int rx = j; |
171 | int ry = i; |
172 | |
173 | pixman_fixed_t f = *params; |
174 | |
175 | if (f) |
176 | { |
177 | uint32_t pixel; |
178 | |
179 | if (repeat_mode != PIXMAN_REPEAT_NONE) |
180 | { |
181 | repeat (repeat_mode, &rx, width); |
182 | repeat (repeat_mode, &ry, height); |
183 | |
184 | pixel = get_pixel (image, rx, ry, FALSE0); |
185 | } |
186 | else |
187 | { |
188 | pixel = get_pixel (image, rx, ry, TRUE1); |
189 | } |
190 | |
191 | srtot += (int)RED_8 (pixel)(((pixel) >> 8 * 2) & 0xff) * f; |
192 | sgtot += (int)GREEN_8 (pixel)(((pixel) >> 8) & 0xff) * f; |
193 | sbtot += (int)BLUE_8 (pixel)((pixel) & 0xff) * f; |
194 | satot += (int)ALPHA_8 (pixel)((pixel) >> 8 * 3) * f; |
195 | } |
196 | |
197 | params++; |
198 | } |
199 | } |
200 | |
201 | satot = (satot + 0x8000) >> 16; |
202 | srtot = (srtot + 0x8000) >> 16; |
203 | sgtot = (sgtot + 0x8000) >> 16; |
204 | sbtot = (sbtot + 0x8000) >> 16; |
205 | |
206 | satot = CLIP (satot, 0, 0xff)((satot) < (0) ? (0) : ((satot) > (0xff) ? (0xff) : (satot ))); |
207 | srtot = CLIP (srtot, 0, 0xff)((srtot) < (0) ? (0) : ((srtot) > (0xff) ? (0xff) : (srtot ))); |
208 | sgtot = CLIP (sgtot, 0, 0xff)((sgtot) < (0) ? (0) : ((sgtot) > (0xff) ? (0xff) : (sgtot ))); |
209 | sbtot = CLIP (sbtot, 0, 0xff)((sbtot) < (0) ? (0) : ((sbtot) > (0xff) ? (0xff) : (sbtot ))); |
210 | |
211 | return ((satot << 24) | (srtot << 16) | (sgtot << 8) | (sbtot)); |
212 | } |
213 | |
214 | static uint32_t |
215 | bits_image_fetch_pixel_separable_convolution (bits_image_t *image, |
216 | pixman_fixed_t x, |
217 | pixman_fixed_t y, |
218 | get_pixel_t get_pixel) |
219 | { |
220 | pixman_fixed_t *params = image->common.filter_params; |
221 | pixman_repeat_t repeat_mode = image->common.repeat; |
222 | int width = image->width; |
223 | int height = image->height; |
224 | int cwidth = pixman_fixed_to_int (params[0])((int) ((params[0]) >> 16)); |
225 | int cheight = pixman_fixed_to_int (params[1])((int) ((params[1]) >> 16)); |
226 | int x_phase_bits = pixman_fixed_to_int (params[2])((int) ((params[2]) >> 16)); |
227 | int y_phase_bits = pixman_fixed_to_int (params[3])((int) ((params[3]) >> 16)); |
228 | int x_phase_shift = 16 - x_phase_bits; |
229 | int y_phase_shift = 16 - y_phase_bits; |
230 | int x_off = ((cwidth << 16) - pixman_fixed_1(((pixman_fixed_t) ((1) << 16)))) >> 1; |
231 | int y_off = ((cheight << 16) - pixman_fixed_1(((pixman_fixed_t) ((1) << 16)))) >> 1; |
232 | pixman_fixed_t *y_params; |
233 | int srtot, sgtot, sbtot, satot; |
234 | int32_t x1, x2, y1, y2; |
235 | int32_t px, py; |
236 | int i, j; |
237 | |
238 | /* Round x and y to the middle of the closest phase before continuing. This |
239 | * ensures that the convolution matrix is aligned right, since it was |
240 | * positioned relative to a particular phase (and not relative to whatever |
241 | * exact fraction we happen to get here). |
242 | */ |
243 | x = ((x >> x_phase_shift) << x_phase_shift) + ((1 << x_phase_shift) >> 1); |
244 | y = ((y >> y_phase_shift) << y_phase_shift) + ((1 << y_phase_shift) >> 1); |
245 | |
246 | px = (x & 0xffff) >> x_phase_shift; |
247 | py = (y & 0xffff) >> y_phase_shift; |
248 | |
249 | y_params = params + 4 + (1 << x_phase_bits) * cwidth + py * cheight; |
250 | |
251 | x1 = pixman_fixed_to_int (x - pixman_fixed_e - x_off)((int) ((x - ((pixman_fixed_t) 1) - x_off) >> 16)); |
252 | y1 = pixman_fixed_to_int (y - pixman_fixed_e - y_off)((int) ((y - ((pixman_fixed_t) 1) - y_off) >> 16)); |
253 | x2 = x1 + cwidth; |
254 | y2 = y1 + cheight; |
255 | |
256 | srtot = sgtot = sbtot = satot = 0; |
257 | |
258 | for (i = y1; i < y2; ++i) |
259 | { |
260 | pixman_fixed_48_16_t fy = *y_params++; |
261 | pixman_fixed_t *x_params = params + 4 + px * cwidth; |
262 | |
263 | if (fy) |
264 | { |
265 | for (j = x1; j < x2; ++j) |
266 | { |
267 | pixman_fixed_t fx = *x_params++; |
268 | int rx = j; |
269 | int ry = i; |
270 | |
271 | if (fx) |
272 | { |
273 | pixman_fixed_t f; |
274 | uint32_t pixel; |
275 | |
276 | if (repeat_mode != PIXMAN_REPEAT_NONE) |
277 | { |
278 | repeat (repeat_mode, &rx, width); |
279 | repeat (repeat_mode, &ry, height); |
280 | |
281 | pixel = get_pixel (image, rx, ry, FALSE0); |
282 | } |
283 | else |
284 | { |
285 | pixel = get_pixel (image, rx, ry, TRUE1); |
286 | } |
287 | |
288 | f = (fy * fx + 0x8000) >> 16; |
289 | |
290 | srtot += (int)RED_8 (pixel)(((pixel) >> 8 * 2) & 0xff) * f; |
291 | sgtot += (int)GREEN_8 (pixel)(((pixel) >> 8) & 0xff) * f; |
292 | sbtot += (int)BLUE_8 (pixel)((pixel) & 0xff) * f; |
293 | satot += (int)ALPHA_8 (pixel)((pixel) >> 8 * 3) * f; |
294 | } |
295 | } |
296 | } |
297 | } |
298 | |
299 | satot = (satot + 0x8000) >> 16; |
300 | srtot = (srtot + 0x8000) >> 16; |
301 | sgtot = (sgtot + 0x8000) >> 16; |
302 | sbtot = (sbtot + 0x8000) >> 16; |
303 | |
304 | satot = CLIP (satot, 0, 0xff)((satot) < (0) ? (0) : ((satot) > (0xff) ? (0xff) : (satot ))); |
305 | srtot = CLIP (srtot, 0, 0xff)((srtot) < (0) ? (0) : ((srtot) > (0xff) ? (0xff) : (srtot ))); |
306 | sgtot = CLIP (sgtot, 0, 0xff)((sgtot) < (0) ? (0) : ((sgtot) > (0xff) ? (0xff) : (sgtot ))); |
307 | sbtot = CLIP (sbtot, 0, 0xff)((sbtot) < (0) ? (0) : ((sbtot) > (0xff) ? (0xff) : (sbtot ))); |
308 | |
309 | return ((satot << 24) | (srtot << 16) | (sgtot << 8) | (sbtot)); |
310 | } |
311 | |
312 | static force_inline__inline__ __attribute__ ((__always_inline__)) uint32_t |
313 | bits_image_fetch_pixel_filtered (bits_image_t *image, |
314 | pixman_fixed_t x, |
315 | pixman_fixed_t y, |
316 | get_pixel_t get_pixel) |
317 | { |
318 | switch (image->common.filter) |
319 | { |
320 | case PIXMAN_FILTER_NEAREST: |
321 | case PIXMAN_FILTER_FAST: |
322 | return bits_image_fetch_pixel_nearest (image, x, y, get_pixel); |
323 | break; |
324 | |
325 | case PIXMAN_FILTER_BILINEAR: |
326 | case PIXMAN_FILTER_GOOD: |
327 | case PIXMAN_FILTER_BEST: |
328 | return bits_image_fetch_pixel_bilinear (image, x, y, get_pixel); |
329 | break; |
330 | |
331 | case PIXMAN_FILTER_CONVOLUTION: |
332 | return bits_image_fetch_pixel_convolution (image, x, y, get_pixel); |
333 | break; |
334 | |
335 | case PIXMAN_FILTER_SEPARABLE_CONVOLUTION: |
336 | return bits_image_fetch_pixel_separable_convolution (image, x, y, get_pixel); |
337 | break; |
338 | |
339 | default: |
340 | break; |
341 | } |
342 | |
343 | return 0; |
344 | } |
345 | |
346 | static uint32_t * |
347 | bits_image_fetch_affine_no_alpha (pixman_iter_t * iter, |
348 | const uint32_t * mask) |
349 | { |
350 | pixman_image_t *image = iter->image; |
351 | int offset = iter->x; |
352 | int line = iter->y++; |
353 | int width = iter->width; |
354 | uint32_t * buffer = iter->buffer; |
355 | |
356 | pixman_fixed_t x, y; |
357 | pixman_fixed_t ux, uy; |
358 | pixman_vector_t v; |
359 | int i; |
360 | |
361 | /* reference point is the center of the pixel */ |
362 | v.vector[0] = pixman_int_to_fixed (offset)((pixman_fixed_t) ((offset) << 16)) + pixman_fixed_1(((pixman_fixed_t) ((1) << 16))) / 2; |
363 | v.vector[1] = pixman_int_to_fixed (line)((pixman_fixed_t) ((line) << 16)) + pixman_fixed_1(((pixman_fixed_t) ((1) << 16))) / 2; |
364 | v.vector[2] = pixman_fixed_1(((pixman_fixed_t) ((1) << 16))); |
365 | |
366 | if (image->common.transform) |
367 | { |
368 | if (!pixman_transform_point_3d (image->common.transform, &v)) |
369 | return iter->buffer; |
370 | |
371 | ux = image->common.transform->matrix[0][0]; |
372 | uy = image->common.transform->matrix[1][0]; |
373 | } |
374 | else |
375 | { |
376 | ux = pixman_fixed_1(((pixman_fixed_t) ((1) << 16))); |
377 | uy = 0; |
378 | } |
379 | |
380 | x = v.vector[0]; |
381 | y = v.vector[1]; |
382 | |
383 | for (i = 0; i < width; ++i) |
384 | { |
385 | if (!mask || mask[i]) |
386 | { |
387 | buffer[i] = bits_image_fetch_pixel_filtered ( |
388 | &image->bits, x, y, fetch_pixel_no_alpha); |
389 | } |
390 | |
391 | x += ux; |
392 | y += uy; |
393 | } |
394 | |
395 | return buffer; |
396 | } |
397 | |
398 | /* General fetcher */ |
399 | static force_inline__inline__ __attribute__ ((__always_inline__)) uint32_t |
400 | fetch_pixel_general (bits_image_t *image, int x, int y, pixman_bool_t check_bounds) |
401 | { |
402 | uint32_t pixel; |
403 | |
404 | if (check_bounds && |
405 | (x < 0 || x >= image->width || y < 0 || y >= image->height)) |
406 | { |
407 | return 0; |
408 | } |
409 | |
410 | pixel = image->fetch_pixel_32 (image, x, y); |
411 | |
412 | if (image->common.alpha_map) |
413 | { |
414 | uint32_t pixel_a; |
415 | |
416 | x -= image->common.alpha_origin_x; |
417 | y -= image->common.alpha_origin_y; |
418 | |
419 | if (x < 0 || x >= image->common.alpha_map->width || |
420 | y < 0 || y >= image->common.alpha_map->height) |
421 | { |
422 | pixel_a = 0; |
423 | } |
424 | else |
425 | { |
426 | pixel_a = image->common.alpha_map->fetch_pixel_32 ( |
427 | image->common.alpha_map, x, y); |
428 | |
429 | pixel_a = ALPHA_8 (pixel_a)((pixel_a) >> 8 * 3); |
430 | } |
431 | |
432 | pixel &= 0x00ffffff; |
433 | pixel |= (pixel_a << 24); |
434 | } |
435 | |
436 | return pixel; |
437 | } |
438 | |
439 | static uint32_t * |
440 | bits_image_fetch_general (pixman_iter_t *iter, |
441 | const uint32_t *mask) |
442 | { |
443 | pixman_image_t *image = iter->image; |
444 | int offset = iter->x; |
445 | int line = iter->y++; |
446 | int width = iter->width; |
447 | uint32_t * buffer = iter->buffer; |
448 | |
449 | pixman_fixed_t x, y, w; |
450 | pixman_fixed_t ux, uy, uw; |
451 | pixman_vector_t v; |
452 | int i; |
453 | |
454 | /* reference point is the center of the pixel */ |
455 | v.vector[0] = pixman_int_to_fixed (offset)((pixman_fixed_t) ((offset) << 16)) + pixman_fixed_1(((pixman_fixed_t) ((1) << 16))) / 2; |
456 | v.vector[1] = pixman_int_to_fixed (line)((pixman_fixed_t) ((line) << 16)) + pixman_fixed_1(((pixman_fixed_t) ((1) << 16))) / 2; |
457 | v.vector[2] = pixman_fixed_1(((pixman_fixed_t) ((1) << 16))); |
458 | |
459 | if (image->common.transform) |
460 | { |
461 | if (!pixman_transform_point_3d (image->common.transform, &v)) |
462 | return buffer; |
463 | |
464 | ux = image->common.transform->matrix[0][0]; |
465 | uy = image->common.transform->matrix[1][0]; |
466 | uw = image->common.transform->matrix[2][0]; |
467 | } |
468 | else |
469 | { |
470 | ux = pixman_fixed_1(((pixman_fixed_t) ((1) << 16))); |
471 | uy = 0; |
472 | uw = 0; |
473 | } |
474 | |
475 | x = v.vector[0]; |
476 | y = v.vector[1]; |
477 | w = v.vector[2]; |
478 | |
479 | for (i = 0; i < width; ++i) |
480 | { |
481 | pixman_fixed_t x0, y0; |
482 | |
483 | if (!mask || mask[i]) |
484 | { |
485 | if (w != 0) |
486 | { |
487 | x0 = ((pixman_fixed_48_16_t)x << 16) / w; |
488 | y0 = ((pixman_fixed_48_16_t)y << 16) / w; |
489 | } |
490 | else |
491 | { |
492 | x0 = 0; |
493 | y0 = 0; |
494 | } |
495 | |
496 | buffer[i] = bits_image_fetch_pixel_filtered ( |
497 | &image->bits, x0, y0, fetch_pixel_general); |
498 | } |
499 | |
500 | x += ux; |
501 | y += uy; |
502 | w += uw; |
503 | } |
504 | |
505 | return buffer; |
506 | } |
507 | |
508 | static void |
509 | replicate_pixel_32 (bits_image_t * bits, |
510 | int x, |
511 | int y, |
512 | int width, |
513 | uint32_t * buffer) |
514 | { |
515 | uint32_t color; |
516 | uint32_t *end; |
517 | |
518 | color = bits->fetch_pixel_32 (bits, x, y); |
519 | |
520 | end = buffer + width; |
521 | while (buffer < end) |
522 | *(buffer++) = color; |
523 | } |
524 | |
525 | static void |
526 | replicate_pixel_float (bits_image_t * bits, |
527 | int x, |
528 | int y, |
529 | int width, |
530 | uint32_t * b) |
531 | { |
532 | argb_t color; |
533 | argb_t *buffer = (argb_t *)b; |
534 | argb_t *end; |
535 | |
536 | color = bits->fetch_pixel_float (bits, x, y); |
537 | |
538 | end = buffer + width; |
539 | while (buffer < end) |
540 | *(buffer++) = color; |
541 | } |
542 | |
543 | static void |
544 | bits_image_fetch_untransformed_repeat_none (bits_image_t *image, |
545 | pixman_bool_t wide, |
546 | int x, |
547 | int y, |
548 | int width, |
549 | uint32_t * buffer) |
550 | { |
551 | uint32_t w; |
552 | |
553 | if (y < 0 || y >= image->height) |
554 | { |
555 | memset (buffer, 0, width * (wide? sizeof (argb_t) : 4))__builtin___memset_chk (buffer, 0, width * (wide? sizeof (argb_t ) : 4), __builtin_object_size (buffer, 0)); |
556 | return; |
557 | } |
558 | |
559 | if (x < 0) |
560 | { |
561 | w = MIN (width, -x)((width < -x) ? width : -x); |
562 | |
563 | memset (buffer, 0, w * (wide ? sizeof (argb_t) : 4))__builtin___memset_chk (buffer, 0, w * (wide ? sizeof (argb_t ) : 4), __builtin_object_size (buffer, 0)); |
564 | |
565 | width -= w; |
566 | buffer += w * (wide? 4 : 1); |
567 | x += w; |
568 | } |
569 | |
570 | if (x < image->width) |
571 | { |
572 | w = MIN (width, image->width - x)((width < image->width - x) ? width : image->width - x); |
573 | |
574 | if (wide) |
575 | image->fetch_scanline_float (image, x, y, w, buffer, NULL((void*)0)); |
576 | else |
577 | image->fetch_scanline_32 (image, x, y, w, buffer, NULL((void*)0)); |
578 | |
579 | width -= w; |
580 | buffer += w * (wide? 4 : 1); |
581 | x += w; |
Value stored to 'x' is never read | |
582 | } |
583 | |
584 | memset (buffer, 0, width * (wide ? sizeof (argb_t) : 4))__builtin___memset_chk (buffer, 0, width * (wide ? sizeof (argb_t ) : 4), __builtin_object_size (buffer, 0)); |
585 | } |
586 | |
587 | static void |
588 | bits_image_fetch_untransformed_repeat_normal (bits_image_t *image, |
589 | pixman_bool_t wide, |
590 | int x, |
591 | int y, |
592 | int width, |
593 | uint32_t * buffer) |
594 | { |
595 | uint32_t w; |
596 | |
597 | while (y < 0) |
598 | y += image->height; |
599 | |
600 | while (y >= image->height) |
601 | y -= image->height; |
602 | |
603 | if (image->width == 1) |
604 | { |
605 | if (wide) |
606 | replicate_pixel_float (image, 0, y, width, buffer); |
607 | else |
608 | replicate_pixel_32 (image, 0, y, width, buffer); |
609 | |
610 | return; |
611 | } |
612 | |
613 | while (width) |
614 | { |
615 | while (x < 0) |
616 | x += image->width; |
617 | while (x >= image->width) |
618 | x -= image->width; |
619 | |
620 | w = MIN (width, image->width - x)((width < image->width - x) ? width : image->width - x); |
621 | |
622 | if (wide) |
623 | image->fetch_scanline_float (image, x, y, w, buffer, NULL((void*)0)); |
624 | else |
625 | image->fetch_scanline_32 (image, x, y, w, buffer, NULL((void*)0)); |
626 | |
627 | buffer += w * (wide? 4 : 1); |
628 | x += w; |
629 | width -= w; |
630 | } |
631 | } |
632 | |
633 | static uint32_t * |
634 | bits_image_fetch_untransformed_32 (pixman_iter_t * iter, |
635 | const uint32_t *mask) |
636 | { |
637 | pixman_image_t *image = iter->image; |
638 | int x = iter->x; |
639 | int y = iter->y; |
640 | int width = iter->width; |
641 | uint32_t * buffer = iter->buffer; |
642 | |
643 | if (image->common.repeat == PIXMAN_REPEAT_NONE) |
644 | { |
645 | bits_image_fetch_untransformed_repeat_none ( |
646 | &image->bits, FALSE0, x, y, width, buffer); |
647 | } |
648 | else |
649 | { |
650 | bits_image_fetch_untransformed_repeat_normal ( |
651 | &image->bits, FALSE0, x, y, width, buffer); |
652 | } |
653 | |
654 | iter->y++; |
655 | return buffer; |
656 | } |
657 | |
658 | static uint32_t * |
659 | bits_image_fetch_untransformed_float (pixman_iter_t * iter, |
660 | const uint32_t *mask) |
661 | { |
662 | pixman_image_t *image = iter->image; |
663 | int x = iter->x; |
664 | int y = iter->y; |
665 | int width = iter->width; |
666 | uint32_t * buffer = iter->buffer; |
667 | |
668 | if (image->common.repeat == PIXMAN_REPEAT_NONE) |
669 | { |
670 | bits_image_fetch_untransformed_repeat_none ( |
671 | &image->bits, TRUE1, x, y, width, buffer); |
672 | } |
673 | else |
674 | { |
675 | bits_image_fetch_untransformed_repeat_normal ( |
676 | &image->bits, TRUE1, x, y, width, buffer); |
677 | } |
678 | |
679 | iter->y++; |
680 | return buffer; |
681 | } |
682 | |
683 | typedef struct |
684 | { |
685 | pixman_format_code_t format; |
686 | uint32_t flags; |
687 | pixman_iter_get_scanline_t get_scanline_32; |
688 | pixman_iter_get_scanline_t get_scanline_float; |
689 | } fetcher_info_t; |
690 | |
691 | static const fetcher_info_t fetcher_info[] = |
692 | { |
693 | { PIXMAN_any(((0) << 24) | ((5) << 16) | ((0) << 12) | ( (0) << 8) | ((0) << 4) | ((0))), |
694 | (FAST_PATH_NO_ALPHA_MAP(1 << 1) | |
695 | FAST_PATH_ID_TRANSFORM(1 << 0) | |
696 | FAST_PATH_NO_CONVOLUTION_FILTER(1 << 2) | |
697 | FAST_PATH_NO_PAD_REPEAT(1 << 3) | |
698 | FAST_PATH_NO_REFLECT_REPEAT(1 << 4)), |
699 | bits_image_fetch_untransformed_32, |
700 | bits_image_fetch_untransformed_float |
701 | }, |
702 | |
703 | /* Affine, no alpha */ |
704 | { PIXMAN_any(((0) << 24) | ((5) << 16) | ((0) << 12) | ( (0) << 8) | ((0) << 4) | ((0))), |
705 | (FAST_PATH_NO_ALPHA_MAP(1 << 1) | FAST_PATH_HAS_TRANSFORM(1 << 12) | FAST_PATH_AFFINE_TRANSFORM(1 << 17)), |
706 | bits_image_fetch_affine_no_alpha, |
707 | _pixman_image_get_scanline_generic_float |
708 | }, |
709 | |
710 | /* General */ |
711 | { PIXMAN_any(((0) << 24) | ((5) << 16) | ((0) << 12) | ( (0) << 8) | ((0) << 4) | ((0))), |
712 | 0, |
713 | bits_image_fetch_general, |
714 | _pixman_image_get_scanline_generic_float |
715 | }, |
716 | |
717 | { PIXMAN_null(((0) << 24) | ((0) << 16) | ((0) << 12) | ( (0) << 8) | ((0) << 4) | ((0))) }, |
718 | }; |
719 | |
720 | static void |
721 | bits_image_property_changed (pixman_image_t *image) |
722 | { |
723 | _pixman_bits_image_setup_accessors (&image->bits); |
724 | } |
725 | |
726 | void |
727 | _pixman_bits_image_src_iter_init (pixman_image_t *image, pixman_iter_t *iter) |
728 | { |
729 | pixman_format_code_t format = image->common.extended_format_code; |
730 | uint32_t flags = image->common.flags; |
731 | const fetcher_info_t *info; |
732 | |
733 | for (info = fetcher_info; info->format != PIXMAN_null(((0) << 24) | ((0) << 16) | ((0) << 12) | ( (0) << 8) | ((0) << 4) | ((0))); ++info) |
734 | { |
735 | if ((info->format == format || info->format == PIXMAN_any(((0) << 24) | ((5) << 16) | ((0) << 12) | ( (0) << 8) | ((0) << 4) | ((0)))) && |
736 | (info->flags & flags) == info->flags) |
737 | { |
738 | if (iter->iter_flags & ITER_NARROW) |
739 | { |
740 | iter->get_scanline = info->get_scanline_32; |
741 | } |
742 | else |
743 | { |
744 | iter->data = info->get_scanline_32; |
745 | iter->get_scanline = info->get_scanline_float; |
746 | } |
747 | return; |
748 | } |
749 | } |
750 | |
751 | /* Just in case we somehow didn't find a scanline function */ |
752 | iter->get_scanline = _pixman_iter_get_scanline_noop; |
753 | } |
754 | |
755 | static uint32_t * |
756 | dest_get_scanline_narrow (pixman_iter_t *iter, const uint32_t *mask) |
757 | { |
758 | pixman_image_t *image = iter->image; |
759 | int x = iter->x; |
760 | int y = iter->y; |
761 | int width = iter->width; |
762 | uint32_t * buffer = iter->buffer; |
763 | |
764 | image->bits.fetch_scanline_32 (&image->bits, x, y, width, buffer, mask); |
765 | if (image->common.alpha_map) |
766 | { |
767 | uint32_t *alpha; |
768 | |
769 | if ((alpha = malloc (width * sizeof (uint32_t)))) |
770 | { |
771 | int i; |
772 | |
773 | x -= image->common.alpha_origin_x; |
774 | y -= image->common.alpha_origin_y; |
775 | |
776 | image->common.alpha_map->fetch_scanline_32 ( |
777 | image->common.alpha_map, x, y, width, alpha, mask); |
778 | |
779 | for (i = 0; i < width; ++i) |
780 | { |
781 | buffer[i] &= ~0xff000000; |
782 | buffer[i] |= (alpha[i] & 0xff000000); |
783 | } |
784 | |
785 | free (alpha); |
786 | } |
787 | } |
788 | |
789 | return iter->buffer; |
790 | } |
791 | |
792 | static uint32_t * |
793 | dest_get_scanline_wide (pixman_iter_t *iter, const uint32_t *mask) |
794 | { |
795 | bits_image_t * image = &iter->image->bits; |
796 | int x = iter->x; |
797 | int y = iter->y; |
798 | int width = iter->width; |
799 | argb_t * buffer = (argb_t *)iter->buffer; |
800 | |
801 | image->fetch_scanline_float ( |
802 | image, x, y, width, (uint32_t *)buffer, mask); |
803 | if (image->common.alpha_map) |
804 | { |
805 | argb_t *alpha; |
806 | |
807 | if ((alpha = malloc (width * sizeof (argb_t)))) |
808 | { |
809 | int i; |
810 | |
811 | x -= image->common.alpha_origin_x; |
812 | y -= image->common.alpha_origin_y; |
813 | |
814 | image->common.alpha_map->fetch_scanline_float ( |
815 | image->common.alpha_map, x, y, width, (uint32_t *)alpha, mask); |
816 | |
817 | for (i = 0; i < width; ++i) |
818 | buffer[i].a = alpha[i].a; |
819 | |
820 | free (alpha); |
821 | } |
822 | } |
823 | |
824 | return iter->buffer; |
825 | } |
826 | |
827 | static void |
828 | dest_write_back_narrow (pixman_iter_t *iter) |
829 | { |
830 | bits_image_t * image = &iter->image->bits; |
831 | int x = iter->x; |
832 | int y = iter->y; |
833 | int width = iter->width; |
834 | const uint32_t *buffer = iter->buffer; |
835 | |
836 | image->store_scanline_32 (image, x, y, width, buffer); |
837 | |
838 | if (image->common.alpha_map) |
839 | { |
840 | x -= image->common.alpha_origin_x; |
841 | y -= image->common.alpha_origin_y; |
842 | |
843 | image->common.alpha_map->store_scanline_32 ( |
844 | image->common.alpha_map, x, y, width, buffer); |
845 | } |
846 | |
847 | iter->y++; |
848 | } |
849 | |
850 | static void |
851 | dest_write_back_wide (pixman_iter_t *iter) |
852 | { |
853 | bits_image_t * image = &iter->image->bits; |
854 | int x = iter->x; |
855 | int y = iter->y; |
856 | int width = iter->width; |
857 | const uint32_t *buffer = iter->buffer; |
858 | |
859 | image->store_scanline_float (image, x, y, width, buffer); |
860 | |
861 | if (image->common.alpha_map) |
862 | { |
863 | x -= image->common.alpha_origin_x; |
864 | y -= image->common.alpha_origin_y; |
865 | |
866 | image->common.alpha_map->store_scanline_float ( |
867 | image->common.alpha_map, x, y, width, buffer); |
868 | } |
869 | |
870 | iter->y++; |
871 | } |
872 | |
873 | void |
874 | _pixman_bits_image_dest_iter_init (pixman_image_t *image, pixman_iter_t *iter) |
875 | { |
876 | if (iter->iter_flags & ITER_NARROW) |
877 | { |
878 | if ((iter->iter_flags & (ITER_IGNORE_RGB | ITER_IGNORE_ALPHA)) == |
879 | (ITER_IGNORE_RGB | ITER_IGNORE_ALPHA)) |
880 | { |
881 | iter->get_scanline = _pixman_iter_get_scanline_noop; |
882 | } |
883 | else |
884 | { |
885 | iter->get_scanline = dest_get_scanline_narrow; |
886 | } |
887 | |
888 | iter->write_back = dest_write_back_narrow; |
889 | } |
890 | else |
891 | { |
892 | iter->get_scanline = dest_get_scanline_wide; |
893 | iter->write_back = dest_write_back_wide; |
894 | } |
895 | } |
896 | |
897 | static uint32_t * |
898 | create_bits (pixman_format_code_t format, |
899 | int width, |
900 | int height, |
901 | int * rowstride_bytes, |
902 | pixman_bool_t clear) |
903 | { |
904 | int stride; |
905 | size_t buf_size; |
906 | int bpp; |
907 | |
908 | /* what follows is a long-winded way, avoiding any possibility of integer |
909 | * overflows, of saying: |
910 | * stride = ((width * bpp + 0x1f) >> 5) * sizeof (uint32_t); |
911 | */ |
912 | |
913 | bpp = PIXMAN_FORMAT_BPP (format)(((format) >> 24) ); |
914 | if (_pixman_multiply_overflows_int (width, bpp)) |
915 | return NULL((void*)0); |
916 | |
917 | stride = width * bpp; |
918 | if (_pixman_addition_overflows_int (stride, 0x1f)) |
919 | return NULL((void*)0); |
920 | |
921 | stride += 0x1f; |
922 | stride >>= 5; |
923 | |
924 | stride *= sizeof (uint32_t); |
925 | |
926 | if (_pixman_multiply_overflows_size (height, stride)) |
927 | return NULL((void*)0); |
928 | |
929 | buf_size = (size_t)height * stride; |
930 | |
931 | if (rowstride_bytes) |
932 | *rowstride_bytes = stride; |
933 | |
934 | if (clear) |
935 | return calloc (buf_size, 1); |
936 | else |
937 | return malloc (buf_size); |
938 | } |
939 | |
940 | pixman_bool_t |
941 | _pixman_bits_image_init (pixman_image_t * image, |
942 | pixman_format_code_t format, |
943 | int width, |
944 | int height, |
945 | uint32_t * bits, |
946 | int rowstride, |
947 | pixman_bool_t clear) |
948 | { |
949 | uint32_t *free_me = NULL((void*)0); |
950 | |
951 | if (!bits && width && height) |
952 | { |
953 | int rowstride_bytes; |
954 | |
955 | free_me = bits = create_bits (format, width, height, &rowstride_bytes, clear); |
956 | |
957 | if (!bits) |
958 | return FALSE0; |
959 | |
960 | rowstride = rowstride_bytes / (int) sizeof (uint32_t); |
961 | } |
962 | |
963 | _pixman_image_init (image); |
964 | |
965 | image->type = BITS; |
966 | image->bits.format = format; |
967 | image->bits.width = width; |
968 | image->bits.height = height; |
969 | image->bits.bits = bits; |
970 | image->bits.free_me = free_me; |
971 | image->bits.read_func = NULL((void*)0); |
972 | image->bits.write_func = NULL((void*)0); |
973 | image->bits.rowstride = rowstride; |
974 | image->bits.indexed = NULL((void*)0); |
975 | |
976 | image->common.property_changed = bits_image_property_changed; |
977 | |
978 | _pixman_image_reset_clip_region (image); |
979 | |
980 | return TRUE1; |
981 | } |
982 | |
983 | static pixman_image_t * |
984 | create_bits_image_internal (pixman_format_code_t format, |
985 | int width, |
986 | int height, |
987 | uint32_t * bits, |
988 | int rowstride_bytes, |
989 | pixman_bool_t clear) |
990 | { |
991 | pixman_image_t *image; |
992 | |
993 | /* must be a whole number of uint32_t's |
994 | */ |
995 | return_val_if_fail (do { if (__builtin_expect ((!(bits == ((void*)0) || (rowstride_bytes % sizeof (uint32_t)) == 0)), 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) |
996 | bits == NULL || (rowstride_bytes % sizeof (uint32_t)) == 0, NULL)do { if (__builtin_expect ((!(bits == ((void*)0) || (rowstride_bytes % sizeof (uint32_t)) == 0)), 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); |
997 | |
998 | return_val_if_fail (PIXMAN_FORMAT_BPP (format) >= PIXMAN_FORMAT_DEPTH (format), NULL)do { if (__builtin_expect ((!((((format) >> 24) ) >= ((((format) >> 12) & 0x0f) + (((format) >> 8 ) & 0x0f) + (((format) >> 4) & 0x0f) + (((format ) ) & 0x0f)))), 0)) { _pixman_log_error (((const char*) ( __PRETTY_FUNCTION__)), "The expression " "PIXMAN_FORMAT_BPP (format) >= PIXMAN_FORMAT_DEPTH (format)" " was false"); return (((void*)0)); } } while (0); |
999 | |
1000 | image = _pixman_image_allocate (); |
1001 | |
1002 | if (!image) |
1003 | return NULL((void*)0); |
1004 | |
1005 | if (!_pixman_bits_image_init (image, format, width, height, bits, |
1006 | rowstride_bytes / (int) sizeof (uint32_t), |
1007 | clear)) |
1008 | { |
1009 | free (image); |
1010 | return NULL((void*)0); |
1011 | } |
1012 | |
1013 | return image; |
1014 | } |
1015 | |
1016 | /* If bits is NULL, a buffer will be allocated and initialized to 0 */ |
1017 | PIXMAN_EXPORT__attribute__ ((visibility("default"))) pixman_image_t * |
1018 | pixman_image_create_bits (pixman_format_code_t format, |
1019 | int width, |
1020 | int height, |
1021 | uint32_t * bits, |
1022 | int rowstride_bytes) |
1023 | { |
1024 | return create_bits_image_internal ( |
1025 | format, width, height, bits, rowstride_bytes, TRUE1); |
1026 | } |
1027 | |
1028 | |
1029 | /* If bits is NULL, a buffer will be allocated and _not_ initialized */ |
1030 | PIXMAN_EXPORT__attribute__ ((visibility("default"))) pixman_image_t * |
1031 | pixman_image_create_bits_no_clear (pixman_format_code_t format, |
1032 | int width, |
1033 | int height, |
1034 | uint32_t * bits, |
1035 | int rowstride_bytes) |
1036 | { |
1037 | return create_bits_image_internal ( |
1038 | format, width, height, bits, rowstride_bytes, FALSE0); |
1039 | } |