Bug Summary

File:root/firefox-clang/gfx/cairo/libpixman/src/pixman-bits-image.c
Warning:line 790, column 2
Value stored to 'x' is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name pixman-bits-image.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -analyzer-config-compatibility-mode=true -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -mframe-pointer=all -relaxed-aliasing -ffp-contract=off -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/root/firefox-clang/obj-x86_64-pc-linux-gnu/gfx/cairo/libpixman/src -fcoverage-compilation-dir=/root/firefox-clang/obj-x86_64-pc-linux-gnu/gfx/cairo/libpixman/src -resource-dir /usr/lib/llvm-21/lib/clang/21 -include /root/firefox-clang/config/gcc_hidden.h -include /root/firefox-clang/obj-x86_64-pc-linux-gnu/mozilla-config.h -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/system_wrappers -U _FORTIFY_SOURCE -D _FORTIFY_SOURCE=2 -D _GLIBCXX_ASSERTIONS -D DEBUG=1 -D HAVE_PTHREADS -D PACKAGE=mozpixman -D USE_X86_MMX -D USE_SSE2 -D USE_SSSE3 -D MOZ_HAS_MOZGLUE -D MOZILLA_INTERNAL_API -D IMPL_LIBXUL -D MOZ_SUPPORT_LEAKCHECKING -D STATIC_EXPORTABLE_JS_API -I /root/firefox-clang/gfx/cairo/libpixman/src -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/gfx/cairo/libpixman/src -I /root/firefox-clang/gfx/cairo/cairo/src -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/include -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/include/nspr -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/include/nss -D MOZILLA_CLIENT -internal-isystem /usr/lib/llvm-21/lib/clang/21/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-error=tautological-type-limit-compare -Wno-range-loop-analysis -Wno-error=deprecated-declarations -Wno-error=array-bounds -Wno-error=free-nonheap-object -Wno-error=atomic-alignment -Wno-error=deprecated-builtins -Wno-psabi -Wno-error=builtin-macro-redefined -Wno-unknown-warning-option -Wno-address -Wno-braced-scalar-init -Wno-missing-field-initializers -Wno-sign-compare -Wno-incompatible-pointer-types -Wno-unused -Wno-incompatible-pointer-types -Wno-tautological-compare -Wno-tautological-constant-out-of-range-compare -ferror-limit 19 -fstrict-flex-arrays=1 -stack-protector 2 -fstack-clash-protection -ftrivial-auto-var-init=pattern -fgnuc-version=4.2.1 -fskip-odr-check-in-gmf -vectorize-loops -vectorize-slp -analyzer-checker optin.performance.Padding -analyzer-output=html -analyzer-config stable-report-filename=true -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /tmp/scan-build-2025-06-26-231904-1820671-1 -x c /root/firefox-clang/gfx/cairo/libpixman/src/pixman-bits-image.c
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_H
30#include <pixman-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#include "dither/blue-noise-64x64.h"
39
40/* Fetch functions */
41
42static force_inline__inline__ __attribute__ ((__always_inline__)) void
43fetch_pixel_no_alpha_32 (bits_image_t *image,
44 int x, int y, pixman_bool_t check_bounds,
45 void *out)
46{
47 uint32_t *ret = out;
48
49 if (check_bounds &&
50 (x < 0 || x >= image->width || y < 0 || y >= image->height))
51 *ret = 0;
52 else
53 *ret = image->fetch_pixel_32 (image, x, y);
54}
55
56static force_inline__inline__ __attribute__ ((__always_inline__)) void
57fetch_pixel_no_alpha_float (bits_image_t *image,
58 int x, int y, pixman_bool_t check_bounds,
59 void *out)
60{
61 argb_t *ret = out;
62
63 if (check_bounds &&
64 (x < 0 || x >= image->width || y < 0 || y >= image->height))
65 ret->a = ret->r = ret->g = ret->b = 0.f;
66 else
67 *ret = image->fetch_pixel_float (image, x, y);
68}
69
70typedef void (* get_pixel_t) (bits_image_t *image,
71 int x, int y, pixman_bool_t check_bounds, void *out);
72
73static force_inline__inline__ __attribute__ ((__always_inline__)) void
74bits_image_fetch_pixel_nearest (bits_image_t *image,
75 pixman_fixed_t x,
76 pixman_fixed_t y,
77 get_pixel_t get_pixel,
78 void *out)
79{
80 int x0 = pixman_fixed_to_int (x - pixman_fixed_e)((int) ((x - ((pixman_fixed_t) 1)) >> 16));
81 int y0 = pixman_fixed_to_int (y - pixman_fixed_e)((int) ((y - ((pixman_fixed_t) 1)) >> 16));
82
83 if (image->common.repeat != PIXMAN_REPEAT_NONE)
84 {
85 repeat (image->common.repeat, &x0, image->width);
86 repeat (image->common.repeat, &y0, image->height);
87
88 get_pixel (image, x0, y0, FALSE0, out);
89 }
90 else
91 {
92 get_pixel (image, x0, y0, TRUE1, out);
93 }
94}
95
96static force_inline__inline__ __attribute__ ((__always_inline__)) void
97bits_image_fetch_pixel_bilinear_32 (bits_image_t *image,
98 pixman_fixed_t x,
99 pixman_fixed_t y,
100 get_pixel_t get_pixel,
101 void *out)
102{
103 pixman_repeat_t repeat_mode = image->common.repeat;
104 int width = image->width;
105 int height = image->height;
106 int x1, y1, x2, y2;
107 uint32_t tl, tr, bl, br;
108 int32_t distx, disty;
109 uint32_t *ret = out;
110
111 x1 = x - pixman_fixed_1(((pixman_fixed_t) ((uint32_t) (1) << 16))) / 2;
112 y1 = y - pixman_fixed_1(((pixman_fixed_t) ((uint32_t) (1) << 16))) / 2;
113
114 distx = pixman_fixed_to_bilinear_weight (x1);
115 disty = pixman_fixed_to_bilinear_weight (y1);
116
117 x1 = pixman_fixed_to_int (x1)((int) ((x1) >> 16));
118 y1 = pixman_fixed_to_int (y1)((int) ((y1) >> 16));
119 x2 = x1 + 1;
120 y2 = y1 + 1;
121
122 if (repeat_mode != PIXMAN_REPEAT_NONE)
123 {
124 repeat (repeat_mode, &x1, width);
125 repeat (repeat_mode, &y1, height);
126 repeat (repeat_mode, &x2, width);
127 repeat (repeat_mode, &y2, height);
128
129 get_pixel (image, x1, y1, FALSE0, &tl);
130 get_pixel (image, x2, y1, FALSE0, &tr);
131 get_pixel (image, x1, y2, FALSE0, &bl);
132 get_pixel (image, x2, y2, FALSE0, &br);
133 }
134 else
135 {
136 get_pixel (image, x1, y1, TRUE1, &tl);
137 get_pixel (image, x2, y1, TRUE1, &tr);
138 get_pixel (image, x1, y2, TRUE1, &bl);
139 get_pixel (image, x2, y2, TRUE1, &br);
140 }
141
142 *ret = bilinear_interpolation (tl, tr, bl, br, distx, disty);
143}
144
145static force_inline__inline__ __attribute__ ((__always_inline__)) void
146bits_image_fetch_pixel_bilinear_float (bits_image_t *image,
147 pixman_fixed_t x,
148 pixman_fixed_t y,
149 get_pixel_t get_pixel,
150 void *out)
151{
152 pixman_repeat_t repeat_mode = image->common.repeat;
153 int width = image->width;
154 int height = image->height;
155 int x1, y1, x2, y2;
156 argb_t tl, tr, bl, br;
157 float distx, disty;
158 argb_t *ret = out;
159
160 x1 = x - pixman_fixed_1(((pixman_fixed_t) ((uint32_t) (1) << 16))) / 2;
161 y1 = y - pixman_fixed_1(((pixman_fixed_t) ((uint32_t) (1) << 16))) / 2;
162
163 distx = ((float)pixman_fixed_fraction(x1)((x1) & ((((pixman_fixed_t) ((uint32_t) (1) << 16))
) - ((pixman_fixed_t) 1)))
) / 65536.f;
164 disty = ((float)pixman_fixed_fraction(y1)((y1) & ((((pixman_fixed_t) ((uint32_t) (1) << 16))
) - ((pixman_fixed_t) 1)))
) / 65536.f;
165
166 x1 = pixman_fixed_to_int (x1)((int) ((x1) >> 16));
167 y1 = pixman_fixed_to_int (y1)((int) ((y1) >> 16));
168 x2 = x1 + 1;
169 y2 = y1 + 1;
170
171 if (repeat_mode != PIXMAN_REPEAT_NONE)
172 {
173 repeat (repeat_mode, &x1, width);
174 repeat (repeat_mode, &y1, height);
175 repeat (repeat_mode, &x2, width);
176 repeat (repeat_mode, &y2, height);
177
178 get_pixel (image, x1, y1, FALSE0, &tl);
179 get_pixel (image, x2, y1, FALSE0, &tr);
180 get_pixel (image, x1, y2, FALSE0, &bl);
181 get_pixel (image, x2, y2, FALSE0, &br);
182 }
183 else
184 {
185 get_pixel (image, x1, y1, TRUE1, &tl);
186 get_pixel (image, x2, y1, TRUE1, &tr);
187 get_pixel (image, x1, y2, TRUE1, &bl);
188 get_pixel (image, x2, y2, TRUE1, &br);
189 }
190
191 *ret = bilinear_interpolation_float (tl, tr, bl, br, distx, disty);
192}
193
194static force_inline__inline__ __attribute__ ((__always_inline__)) void accum_32(unsigned int *satot, unsigned int *srtot,
195 unsigned int *sgtot, unsigned int *sbtot,
196 const void *p, pixman_fixed_t f)
197{
198 uint32_t pixel = *(uint32_t *)p;
199
200 *srtot += (int)RED_8 (pixel)(((pixel) >> 8 * 2) & 0xff) * f;
201 *sgtot += (int)GREEN_8 (pixel)(((pixel) >> 8) & 0xff) * f;
202 *sbtot += (int)BLUE_8 (pixel)((pixel) & 0xff) * f;
203 *satot += (int)ALPHA_8 (pixel)((pixel) >> 8 * 3) * f;
204}
205
206static force_inline__inline__ __attribute__ ((__always_inline__)) void reduce_32(unsigned int satot, unsigned int srtot,
207 unsigned int sgtot, unsigned int sbtot,
208 void *p)
209{
210 uint32_t *ret = p;
211
212 satot = (int32_t)(satot + 0x8000) / 65536;
213 srtot = (int32_t)(srtot + 0x8000) / 65536;
214 sgtot = (int32_t)(sgtot + 0x8000) / 65536;
215 sbtot = (int32_t)(sbtot + 0x8000) / 65536;
216
217 satot = CLIP ((int32_t)satot, 0, 0xff)(((int32_t)satot) < (0) ? (0) : (((int32_t)satot) > (0xff
) ? (0xff) : ((int32_t)satot)))
;
218 srtot = CLIP ((int32_t)srtot, 0, 0xff)(((int32_t)srtot) < (0) ? (0) : (((int32_t)srtot) > (0xff
) ? (0xff) : ((int32_t)srtot)))
;
219 sgtot = CLIP ((int32_t)sgtot, 0, 0xff)(((int32_t)sgtot) < (0) ? (0) : (((int32_t)sgtot) > (0xff
) ? (0xff) : ((int32_t)sgtot)))
;
220 sbtot = CLIP ((int32_t)sbtot, 0, 0xff)(((int32_t)sbtot) < (0) ? (0) : (((int32_t)sbtot) > (0xff
) ? (0xff) : ((int32_t)sbtot)))
;
221
222 *ret = ((satot << 24) | (srtot << 16) | (sgtot << 8) | (sbtot));
223}
224
225static force_inline__inline__ __attribute__ ((__always_inline__)) void accum_float(unsigned int *satot, unsigned int *srtot,
226 unsigned int *sgtot, unsigned int *sbtot,
227 const void *p, pixman_fixed_t f)
228{
229 const argb_t *pixel = p;
230
231 *satot += pixel->a * f;
232 *srtot += pixel->r * f;
233 *sgtot += pixel->g * f;
234 *sbtot += pixel->b * f;
235}
236
237static force_inline__inline__ __attribute__ ((__always_inline__)) void reduce_float(unsigned int satot, unsigned int srtot,
238 unsigned int sgtot, unsigned int sbtot,
239 void *p)
240{
241 argb_t *ret = p;
242
243 ret->a = CLIP ((int32_t)satot / 65536.f, 0.f, 1.f)(((int32_t)satot / 65536.f) < (0.f) ? (0.f) : (((int32_t)satot
/ 65536.f) > (1.f) ? (1.f) : ((int32_t)satot / 65536.f)))
;
244 ret->r = CLIP ((int32_t)srtot / 65536.f, 0.f, 1.f)(((int32_t)srtot / 65536.f) < (0.f) ? (0.f) : (((int32_t)srtot
/ 65536.f) > (1.f) ? (1.f) : ((int32_t)srtot / 65536.f)))
;
245 ret->g = CLIP ((int32_t)sgtot / 65536.f, 0.f, 1.f)(((int32_t)sgtot / 65536.f) < (0.f) ? (0.f) : (((int32_t)sgtot
/ 65536.f) > (1.f) ? (1.f) : ((int32_t)sgtot / 65536.f)))
;
246 ret->b = CLIP ((int32_t)sbtot / 65536.f, 0.f, 1.f)(((int32_t)sbtot / 65536.f) < (0.f) ? (0.f) : (((int32_t)sbtot
/ 65536.f) > (1.f) ? (1.f) : ((int32_t)sbtot / 65536.f)))
;
247}
248
249typedef void (* accumulate_pixel_t) (unsigned int *satot, unsigned int *srtot,
250 unsigned int *sgtot, unsigned int *sbtot,
251 const void *pixel, pixman_fixed_t f);
252
253typedef void (* reduce_pixel_t) (unsigned int satot, unsigned int srtot,
254 unsigned int sgtot, unsigned int sbtot,
255 void *out);
256
257static force_inline__inline__ __attribute__ ((__always_inline__)) void
258bits_image_fetch_pixel_convolution (bits_image_t *image,
259 pixman_fixed_t x,
260 pixman_fixed_t y,
261 get_pixel_t get_pixel,
262 void *out,
263 accumulate_pixel_t accum,
264 reduce_pixel_t reduce)
265{
266 pixman_fixed_t *params = image->common.filter_params;
267 int x_off = (params[0] - pixman_fixed_1(((pixman_fixed_t) ((uint32_t) (1) << 16)))) >> 1;
268 int y_off = (params[1] - pixman_fixed_1(((pixman_fixed_t) ((uint32_t) (1) << 16)))) >> 1;
269 int32_t cwidth = pixman_fixed_to_int (params[0])((int) ((params[0]) >> 16));
270 int32_t cheight = pixman_fixed_to_int (params[1])((int) ((params[1]) >> 16));
271 int32_t i, j, x1, x2, y1, y2;
272 pixman_repeat_t repeat_mode = image->common.repeat;
273 int width = image->width;
274 int height = image->height;
275 unsigned int srtot, sgtot, sbtot, satot;
276
277 params += 2;
278
279 x1 = pixman_fixed_to_int (x - pixman_fixed_e - x_off)((int) ((x - ((pixman_fixed_t) 1) - x_off) >> 16));
280 y1 = pixman_fixed_to_int (y - pixman_fixed_e - y_off)((int) ((y - ((pixman_fixed_t) 1) - y_off) >> 16));
281 x2 = x1 + cwidth;
282 y2 = y1 + cheight;
283
284 srtot = sgtot = sbtot = satot = 0;
285
286 for (i = y1; i < y2; ++i)
287 {
288 for (j = x1; j < x2; ++j)
289 {
290 int rx = j;
291 int ry = i;
292
293 pixman_fixed_t f = *params;
294
295 if (f)
296 {
297 /* Must be big enough to hold a argb_t */
298 argb_t pixel;
299
300 if (repeat_mode != PIXMAN_REPEAT_NONE)
301 {
302 repeat (repeat_mode, &rx, width);
303 repeat (repeat_mode, &ry, height);
304
305 get_pixel (image, rx, ry, FALSE0, &pixel);
306 }
307 else
308 {
309 get_pixel (image, rx, ry, TRUE1, &pixel);
310 }
311
312 accum (&satot, &srtot, &sgtot, &sbtot, &pixel, f);
313 }
314
315 params++;
316 }
317 }
318
319 reduce (satot, srtot, sgtot, sbtot, out);
320}
321
322static void
323bits_image_fetch_pixel_separable_convolution (bits_image_t *image,
324 pixman_fixed_t x,
325 pixman_fixed_t y,
326 get_pixel_t get_pixel,
327 void *out,
328 accumulate_pixel_t accum,
329 reduce_pixel_t reduce)
330{
331 pixman_fixed_t *params = image->common.filter_params;
332 pixman_repeat_t repeat_mode = image->common.repeat;
333 int width = image->width;
334 int height = image->height;
335 int cwidth = pixman_fixed_to_int (params[0])((int) ((params[0]) >> 16));
336 int cheight = pixman_fixed_to_int (params[1])((int) ((params[1]) >> 16));
337 int x_phase_bits = pixman_fixed_to_int (params[2])((int) ((params[2]) >> 16));
338 int y_phase_bits = pixman_fixed_to_int (params[3])((int) ((params[3]) >> 16));
339 int x_phase_shift = 16 - x_phase_bits;
340 int y_phase_shift = 16 - y_phase_bits;
341 int x_off = ((cwidth << 16) - pixman_fixed_1(((pixman_fixed_t) ((uint32_t) (1) << 16)))) >> 1;
342 int y_off = ((cheight << 16) - pixman_fixed_1(((pixman_fixed_t) ((uint32_t) (1) << 16)))) >> 1;
343 pixman_fixed_t *y_params;
344 unsigned int srtot, sgtot, sbtot, satot;
345 int32_t x1, x2, y1, y2;
346 int32_t px, py;
347 int i, j;
348
349 /* Round x and y to the middle of the closest phase before continuing. This
350 * ensures that the convolution matrix is aligned right, since it was
351 * positioned relative to a particular phase (and not relative to whatever
352 * exact fraction we happen to get here).
353 */
354 x = ((x >> x_phase_shift) << x_phase_shift) + ((1 << x_phase_shift) >> 1);
355 y = ((y >> y_phase_shift) << y_phase_shift) + ((1 << y_phase_shift) >> 1);
356
357 px = (x & 0xffff) >> x_phase_shift;
358 py = (y & 0xffff) >> y_phase_shift;
359
360 y_params = params + 4 + (1 << x_phase_bits) * cwidth + py * cheight;
361
362 x1 = pixman_fixed_to_int (x - pixman_fixed_e - x_off)((int) ((x - ((pixman_fixed_t) 1) - x_off) >> 16));
363 y1 = pixman_fixed_to_int (y - pixman_fixed_e - y_off)((int) ((y - ((pixman_fixed_t) 1) - y_off) >> 16));
364 x2 = x1 + cwidth;
365 y2 = y1 + cheight;
366
367 srtot = sgtot = sbtot = satot = 0;
368
369 for (i = y1; i < y2; ++i)
370 {
371 pixman_fixed_48_16_t fy = *y_params++;
372 pixman_fixed_t *x_params = params + 4 + px * cwidth;
373
374 if (fy)
375 {
376 for (j = x1; j < x2; ++j)
377 {
378 pixman_fixed_t fx = *x_params++;
379 int rx = j;
380 int ry = i;
381
382 if (fx)
383 {
384 /* Must be big enough to hold a argb_t */
385 argb_t pixel;
386 pixman_fixed_t f;
387
388 if (repeat_mode != PIXMAN_REPEAT_NONE)
389 {
390 repeat (repeat_mode, &rx, width);
391 repeat (repeat_mode, &ry, height);
392
393 get_pixel (image, rx, ry, FALSE0, &pixel);
394 }
395 else
396 {
397 get_pixel (image, rx, ry, TRUE1, &pixel);
398 }
399
400 f = (fy * fx + 0x8000) >> 16;
401
402 accum(&satot, &srtot, &sgtot, &sbtot, &pixel, f);
403 }
404 }
405 }
406 }
407
408
409 reduce(satot, srtot, sgtot, sbtot, out);
410}
411
412static force_inline__inline__ __attribute__ ((__always_inline__)) void
413bits_image_fetch_pixel_filtered (bits_image_t *image,
414 pixman_bool_t wide,
415 pixman_fixed_t x,
416 pixman_fixed_t y,
417 get_pixel_t get_pixel,
418 void *out)
419{
420 switch (image->common.filter)
421 {
422 case PIXMAN_FILTER_NEAREST:
423 case PIXMAN_FILTER_FAST:
424 bits_image_fetch_pixel_nearest (image, x, y, get_pixel, out);
425 break;
426
427 case PIXMAN_FILTER_BILINEAR:
428 case PIXMAN_FILTER_GOOD:
429 case PIXMAN_FILTER_BEST:
430 if (wide)
431 bits_image_fetch_pixel_bilinear_float (image, x, y, get_pixel, out);
432 else
433 bits_image_fetch_pixel_bilinear_32 (image, x, y, get_pixel, out);
434 break;
435
436 case PIXMAN_FILTER_CONVOLUTION:
437 if (wide)
438 {
439 bits_image_fetch_pixel_convolution (image, x, y,
440 get_pixel, out,
441 accum_float,
442 reduce_float);
443 }
444 else
445 {
446 bits_image_fetch_pixel_convolution (image, x, y,
447 get_pixel, out,
448 accum_32, reduce_32);
449 }
450 break;
451
452 case PIXMAN_FILTER_SEPARABLE_CONVOLUTION:
453 if (wide)
454 {
455 bits_image_fetch_pixel_separable_convolution (image, x, y,
456 get_pixel, out,
457 accum_float,
458 reduce_float);
459 }
460 else
461 {
462 bits_image_fetch_pixel_separable_convolution (image, x, y,
463 get_pixel, out,
464 accum_32, reduce_32);
465 }
466 break;
467
468 default:
469 assert (0)((void) sizeof ((0) ? 1 : 0), __extension__ ({ if (0) ; else __assert_fail
("0", "/root/firefox-clang/gfx/cairo/libpixman/src/pixman-bits-image.c"
, 469, __extension__ __PRETTY_FUNCTION__); }))
;
470 break;
471 }
472}
473
474static uint32_t *
475__bits_image_fetch_affine_no_alpha (pixman_iter_t * iter,
476 pixman_bool_t wide,
477 const uint32_t * mask)
478{
479 pixman_image_t *image = iter->image;
480 int offset = iter->x;
481 int line = iter->y++;
482 int width = iter->width;
483 uint32_t * buffer = iter->buffer;
484
485 const uint32_t wide_zero[4] = {0};
486 pixman_fixed_t x, y;
487 pixman_fixed_t ux, uy;
488 pixman_vector_t v;
489 int i;
490 get_pixel_t get_pixel =
491 wide ? fetch_pixel_no_alpha_float : fetch_pixel_no_alpha_32;
492
493 /* reference point is the center of the pixel */
494 v.vector[0] = pixman_int_to_fixed (offset)((pixman_fixed_t) ((uint32_t) (offset) << 16)) + pixman_fixed_1(((pixman_fixed_t) ((uint32_t) (1) << 16))) / 2;
495 v.vector[1] = pixman_int_to_fixed (line)((pixman_fixed_t) ((uint32_t) (line) << 16)) + pixman_fixed_1(((pixman_fixed_t) ((uint32_t) (1) << 16))) / 2;
496 v.vector[2] = pixman_fixed_1(((pixman_fixed_t) ((uint32_t) (1) << 16)));
497
498 if (image->common.transform)
499 {
500 if (!pixman_transform_point_3d_moz_pixman_transform_point_3d (image->common.transform, &v))
501 return iter->buffer;
502
503 ux = image->common.transform->matrix[0][0];
504 uy = image->common.transform->matrix[1][0];
505 }
506 else
507 {
508 ux = pixman_fixed_1(((pixman_fixed_t) ((uint32_t) (1) << 16)));
509 uy = 0;
510 }
511
512 x = v.vector[0];
513 y = v.vector[1];
514
515 for (i = 0; i < width; ++i)
516 {
517 if (!mask || (!wide && mask[i]) ||
518 (wide && memcmp(&mask[4 * i], wide_zero, 16) != 0))
519 {
520 bits_image_fetch_pixel_filtered (
521 &image->bits, wide, x, y, get_pixel, buffer);
522 }
523
524 x += ux;
525 y += uy;
526 buffer += wide ? 4 : 1;
527 }
528
529 return iter->buffer;
530}
531
532static uint32_t *
533bits_image_fetch_affine_no_alpha_32 (pixman_iter_t *iter,
534 const uint32_t *mask)
535{
536 return __bits_image_fetch_affine_no_alpha(iter, FALSE0, mask);
537}
538
539static uint32_t *
540bits_image_fetch_affine_no_alpha_float (pixman_iter_t *iter,
541 const uint32_t *mask)
542{
543 return __bits_image_fetch_affine_no_alpha(iter, TRUE1, mask);
544}
545
546/* General fetcher */
547static force_inline__inline__ __attribute__ ((__always_inline__)) void
548fetch_pixel_general_32 (bits_image_t *image,
549 int x, int y, pixman_bool_t check_bounds,
550 void *out)
551{
552 uint32_t pixel, *ret = out;
553
554 if (check_bounds &&
555 (x < 0 || x >= image->width || y < 0 || y >= image->height))
556 {
557 *ret = 0;
558 return;
559 }
560
561 pixel = image->fetch_pixel_32 (image, x, y);
562
563 if (image->common.alpha_map)
564 {
565 uint32_t pixel_a;
566
567 x -= image->common.alpha_origin_x;
568 y -= image->common.alpha_origin_y;
569
570 if (x < 0 || x >= image->common.alpha_map->width ||
571 y < 0 || y >= image->common.alpha_map->height)
572 {
573 pixel_a = 0;
574 }
575 else
576 {
577 pixel_a = image->common.alpha_map->fetch_pixel_32 (
578 image->common.alpha_map, x, y);
579
580 pixel_a = ALPHA_8 (pixel_a)((pixel_a) >> 8 * 3);
581 }
582
583 pixel &= 0x00ffffff;
584 pixel |= (pixel_a << 24);
585 }
586
587 *ret = pixel;
588}
589
590static force_inline__inline__ __attribute__ ((__always_inline__)) void
591fetch_pixel_general_float (bits_image_t *image,
592 int x, int y, pixman_bool_t check_bounds,
593 void *out)
594{
595 argb_t *ret = out;
596
597 if (check_bounds &&
598 (x < 0 || x >= image->width || y < 0 || y >= image->height))
599 {
600 ret->a = ret->r = ret->g = ret->b = 0;
601 return;
602 }
603
604 *ret = image->fetch_pixel_float (image, x, y);
605
606 if (image->common.alpha_map)
607 {
608 x -= image->common.alpha_origin_x;
609 y -= image->common.alpha_origin_y;
610
611 if (x < 0 || x >= image->common.alpha_map->width ||
612 y < 0 || y >= image->common.alpha_map->height)
613 {
614 ret->a = 0.f;
615 }
616 else
617 {
618 argb_t alpha;
619
620 alpha = image->common.alpha_map->fetch_pixel_float (
621 image->common.alpha_map, x, y);
622
623 ret->a = alpha.a;
624 }
625 }
626}
627
628static uint32_t *
629__bits_image_fetch_general (pixman_iter_t *iter,
630 pixman_bool_t wide,
631 const uint32_t *mask)
632{
633 pixman_image_t *image = iter->image;
634 int offset = iter->x;
635 int line = iter->y++;
636 int width = iter->width;
637 uint32_t * buffer = iter->buffer;
638 get_pixel_t get_pixel =
639 wide ? fetch_pixel_general_float : fetch_pixel_general_32;
640
641 const uint32_t wide_zero[4] = {0};
642 pixman_fixed_t x, y, w;
643 pixman_fixed_t ux, uy, uw;
644 pixman_vector_t v;
645 int i;
646
647 /* reference point is the center of the pixel */
648 v.vector[0] = pixman_int_to_fixed (offset)((pixman_fixed_t) ((uint32_t) (offset) << 16)) + pixman_fixed_1(((pixman_fixed_t) ((uint32_t) (1) << 16))) / 2;
649 v.vector[1] = pixman_int_to_fixed (line)((pixman_fixed_t) ((uint32_t) (line) << 16)) + pixman_fixed_1(((pixman_fixed_t) ((uint32_t) (1) << 16))) / 2;
650 v.vector[2] = pixman_fixed_1(((pixman_fixed_t) ((uint32_t) (1) << 16)));
651
652 if (image->common.transform)
653 {
654 if (!pixman_transform_point_3d_moz_pixman_transform_point_3d (image->common.transform, &v))
655 return buffer;
656
657 ux = image->common.transform->matrix[0][0];
658 uy = image->common.transform->matrix[1][0];
659 uw = image->common.transform->matrix[2][0];
660 }
661 else
662 {
663 ux = pixman_fixed_1(((pixman_fixed_t) ((uint32_t) (1) << 16)));
664 uy = 0;
665 uw = 0;
666 }
667
668 x = v.vector[0];
669 y = v.vector[1];
670 w = v.vector[2];
671
672 for (i = 0; i < width; ++i)
673 {
674 pixman_fixed_t x0, y0;
675
676 if (!mask || (!wide && mask[i]) ||
677 (wide && memcmp(&mask[4 * i], wide_zero, 16) != 0))
678 {
679 if (w != 0)
680 {
681 x0 = ((uint64_t)x << 16) / w;
682 y0 = ((uint64_t)y << 16) / w;
683 }
684 else
685 {
686 x0 = 0;
687 y0 = 0;
688 }
689
690 bits_image_fetch_pixel_filtered (
691 &image->bits, wide, x0, y0, get_pixel, buffer);
692 }
693
694 x += ux;
695 y += uy;
696 w += uw;
697 buffer += wide ? 4 : 1;
698 }
699
700 return iter->buffer;
701}
702
703static uint32_t *
704bits_image_fetch_general_32 (pixman_iter_t *iter,
705 const uint32_t *mask)
706{
707 return __bits_image_fetch_general(iter, FALSE0, mask);
708}
709
710static uint32_t *
711bits_image_fetch_general_float (pixman_iter_t *iter,
712 const uint32_t *mask)
713{
714 return __bits_image_fetch_general(iter, TRUE1, mask);
715}
716
717static void
718replicate_pixel_32 (bits_image_t * bits,
719 int x,
720 int y,
721 int width,
722 uint32_t * buffer)
723{
724 uint32_t color;
725 uint32_t *end;
726
727 color = bits->fetch_pixel_32 (bits, x, y);
728
729 end = buffer + width;
730 while (buffer < end)
731 *(buffer++) = color;
732}
733
734static void
735replicate_pixel_float (bits_image_t * bits,
736 int x,
737 int y,
738 int width,
739 uint32_t * b)
740{
741 argb_t color;
742 argb_t *buffer = (argb_t *)b;
743 argb_t *end;
744
745 color = bits->fetch_pixel_float (bits, x, y);
746
747 end = buffer + width;
748 while (buffer < end)
749 *(buffer++) = color;
750}
751
752static void
753bits_image_fetch_untransformed_repeat_none (bits_image_t *image,
754 pixman_bool_t wide,
755 int x,
756 int y,
757 int width,
758 uint32_t * buffer)
759{
760 uint32_t w;
761
762 if (y < 0 || y >= image->height)
763 {
764 memset (buffer, 0, width * (wide? sizeof (argb_t) : 4));
765 return;
766 }
767
768 if (x < 0)
769 {
770 w = MIN (width, -x)((width < -x) ? width : -x);
771
772 memset (buffer, 0, w * (wide ? sizeof (argb_t) : 4));
773
774 width -= w;
775 buffer += w * (wide? 4 : 1);
776 x += w;
777 }
778
779 if (x < image->width)
780 {
781 w = MIN (width, image->width - x)((width < image->width - x) ? width : image->width -
x)
;
782
783 if (wide)
784 image->fetch_scanline_float (image, x, y, w, buffer, NULL((void*)0));
785 else
786 image->fetch_scanline_32 (image, x, y, w, buffer, NULL((void*)0));
787
788 width -= w;
789 buffer += w * (wide? 4 : 1);
790 x += w;
Value stored to 'x' is never read
791 }
792
793 memset (buffer, 0, width * (wide ? sizeof (argb_t) : 4));
794}
795
796static void
797bits_image_fetch_untransformed_repeat_normal (bits_image_t *image,
798 pixman_bool_t wide,
799 int x,
800 int y,
801 int width,
802 uint32_t * buffer)
803{
804 uint32_t w;
805
806 while (y < 0)
807 y += image->height;
808
809 while (y >= image->height)
810 y -= image->height;
811
812 if (image->width == 1)
813 {
814 if (wide)
815 replicate_pixel_float (image, 0, y, width, buffer);
816 else
817 replicate_pixel_32 (image, 0, y, width, buffer);
818
819 return;
820 }
821
822 while (width)
823 {
824 while (x < 0)
825 x += image->width;
826 while (x >= image->width)
827 x -= image->width;
828
829 w = MIN (width, image->width - x)((width < image->width - x) ? width : image->width -
x)
;
830
831 if (wide)
832 image->fetch_scanline_float (image, x, y, w, buffer, NULL((void*)0));
833 else
834 image->fetch_scanline_32 (image, x, y, w, buffer, NULL((void*)0));
835
836 buffer += w * (wide? 4 : 1);
837 x += w;
838 width -= w;
839 }
840}
841
842static uint32_t *
843bits_image_fetch_untransformed_32 (pixman_iter_t * iter,
844 const uint32_t *mask)
845{
846 pixman_image_t *image = iter->image;
847 int x = iter->x;
848 int y = iter->y;
849 int width = iter->width;
850 uint32_t * buffer = iter->buffer;
851
852 if (image->common.repeat == PIXMAN_REPEAT_NONE)
853 {
854 bits_image_fetch_untransformed_repeat_none (
855 &image->bits, FALSE0, x, y, width, buffer);
856 }
857 else
858 {
859 bits_image_fetch_untransformed_repeat_normal (
860 &image->bits, FALSE0, x, y, width, buffer);
861 }
862
863 iter->y++;
864 return buffer;
865}
866
867static uint32_t *
868bits_image_fetch_untransformed_float (pixman_iter_t * iter,
869 const uint32_t *mask)
870{
871 pixman_image_t *image = iter->image;
872 int x = iter->x;
873 int y = iter->y;
874 int width = iter->width;
875 uint32_t * buffer = iter->buffer;
876
877 if (image->common.repeat == PIXMAN_REPEAT_NONE)
878 {
879 bits_image_fetch_untransformed_repeat_none (
880 &image->bits, TRUE1, x, y, width, buffer);
881 }
882 else
883 {
884 bits_image_fetch_untransformed_repeat_normal (
885 &image->bits, TRUE1, x, y, width, buffer);
886 }
887
888 iter->y++;
889 return buffer;
890}
891
892typedef struct
893{
894 pixman_format_code_t format;
895 uint32_t flags;
896 pixman_iter_get_scanline_t get_scanline_32;
897 pixman_iter_get_scanline_t get_scanline_float;
898} fetcher_info_t;
899
900static const fetcher_info_t fetcher_info[] =
901{
902 { PIXMAN_any(((0) << 24) | ((5) << 16) | ((0) << 12) | (
(0) << 8) | ((0) << 4) | ((0)))
,
903 (FAST_PATH_NO_ALPHA_MAP(1 << 1) |
904 FAST_PATH_ID_TRANSFORM(1 << 0) |
905 FAST_PATH_NO_CONVOLUTION_FILTER(1 << 2) |
906 FAST_PATH_NO_PAD_REPEAT(1 << 3) |
907 FAST_PATH_NO_REFLECT_REPEAT(1 << 4)),
908 bits_image_fetch_untransformed_32,
909 bits_image_fetch_untransformed_float
910 },
911
912 /* Affine, no alpha */
913 { PIXMAN_any(((0) << 24) | ((5) << 16) | ((0) << 12) | (
(0) << 8) | ((0) << 4) | ((0)))
,
914 (FAST_PATH_NO_ALPHA_MAP(1 << 1) | FAST_PATH_HAS_TRANSFORM(1 << 12) | FAST_PATH_AFFINE_TRANSFORM(1 << 17)),
915 bits_image_fetch_affine_no_alpha_32,
916 bits_image_fetch_affine_no_alpha_float,
917 },
918
919 /* General */
920 { PIXMAN_any(((0) << 24) | ((5) << 16) | ((0) << 12) | (
(0) << 8) | ((0) << 4) | ((0)))
,
921 0,
922 bits_image_fetch_general_32,
923 bits_image_fetch_general_float,
924 },
925
926 { PIXMAN_null(((0) << 24) | ((0) << 16) | ((0) << 12) | (
(0) << 8) | ((0) << 4) | ((0)))
},
927};
928
929static void
930bits_image_property_changed (pixman_image_t *image)
931{
932 _pixman_bits_image_setup_accessors (&image->bits);
933}
934
935void
936_pixman_bits_image_src_iter_init (pixman_image_t *image, pixman_iter_t *iter)
937{
938 pixman_format_code_t format = image->common.extended_format_code;
939 uint32_t flags = image->common.flags;
940 const fetcher_info_t *info;
941
942 for (info = fetcher_info; info->format != PIXMAN_null(((0) << 24) | ((0) << 16) | ((0) << 12) | (
(0) << 8) | ((0) << 4) | ((0)))
; ++info)
943 {
944 if ((info->format == format || info->format == PIXMAN_any(((0) << 24) | ((5) << 16) | ((0) << 12) | (
(0) << 8) | ((0) << 4) | ((0)))
) &&
945 (info->flags & flags) == info->flags)
946 {
947 if (iter->iter_flags & ITER_NARROW)
948 {
949 iter->get_scanline = info->get_scanline_32;
950 }
951 else
952 {
953 iter->get_scanline = info->get_scanline_float;
954 }
955 return;
956 }
957 }
958
959 /* Just in case we somehow didn't find a scanline function */
960 iter->get_scanline = _pixman_iter_get_scanline_noop;
961}
962
963static uint32_t *
964dest_get_scanline_narrow (pixman_iter_t *iter, const uint32_t *mask)
965{
966 pixman_image_t *image = iter->image;
967 int x = iter->x;
968 int y = iter->y;
969 int width = iter->width;
970 uint32_t * buffer = iter->buffer;
971
972 image->bits.fetch_scanline_32 (&image->bits, x, y, width, buffer, mask);
973 if (image->common.alpha_map)
974 {
975 uint32_t *alpha;
976
977 if ((alpha = malloc (width * sizeof (uint32_t))))
978 {
979 int i;
980
981 x -= image->common.alpha_origin_x;
982 y -= image->common.alpha_origin_y;
983
984 image->common.alpha_map->fetch_scanline_32 (
985 image->common.alpha_map, x, y, width, alpha, mask);
986
987 for (i = 0; i < width; ++i)
988 {
989 buffer[i] &= ~0xff000000;
990 buffer[i] |= (alpha[i] & 0xff000000);
991 }
992
993 free (alpha);
994 }
995 }
996
997 return iter->buffer;
998}
999
1000static uint32_t *
1001dest_get_scanline_wide (pixman_iter_t *iter, const uint32_t *mask)
1002{
1003 bits_image_t * image = &iter->image->bits;
1004 int x = iter->x;
1005 int y = iter->y;
1006 int width = iter->width;
1007 argb_t * buffer = (argb_t *)iter->buffer;
1008
1009 image->fetch_scanline_float (
1010 image, x, y, width, (uint32_t *)buffer, mask);
1011 if (image->common.alpha_map)
1012 {
1013 argb_t *alpha;
1014
1015 if ((alpha = malloc (width * sizeof (argb_t))))
1016 {
1017 int i;
1018
1019 x -= image->common.alpha_origin_x;
1020 y -= image->common.alpha_origin_y;
1021
1022 image->common.alpha_map->fetch_scanline_float (
1023 image->common.alpha_map, x, y, width, (uint32_t *)alpha, mask);
1024
1025 for (i = 0; i < width; ++i)
1026 buffer[i].a = alpha[i].a;
1027
1028 free (alpha);
1029 }
1030 }
1031
1032 return iter->buffer;
1033}
1034
1035static void
1036dest_write_back_narrow (pixman_iter_t *iter)
1037{
1038 bits_image_t * image = &iter->image->bits;
1039 int x = iter->x;
1040 int y = iter->y;
1041 int width = iter->width;
1042 const uint32_t *buffer = iter->buffer;
1043
1044 image->store_scanline_32 (image, x, y, width, buffer);
1045
1046 if (image->common.alpha_map)
1047 {
1048 x -= image->common.alpha_origin_x;
1049 y -= image->common.alpha_origin_y;
1050
1051 image->common.alpha_map->store_scanline_32 (
1052 image->common.alpha_map, x, y, width, buffer);
1053 }
1054
1055 iter->y++;
1056}
1057
1058static float
1059dither_factor_blue_noise_64 (int x, int y)
1060{
1061 float m = dither_blue_noise_64x64[((y & 0x3f) << 6) | (x & 0x3f)];
1062 return m * (1. / 4096.f) + (1. / 8192.f);
1063}
1064
1065static float
1066dither_factor_bayer_8 (int x, int y)
1067{
1068 uint32_t m;
1069
1070 y ^= x;
1071
1072 /* Compute reverse(interleave(xor(x mod n, y mod n), x mod n))
1073 * Here n = 8 and `mod n` is the bottom 3 bits.
1074 */
1075 m = ((y & 0x1) << 5) | ((x & 0x1) << 4) |
1076 ((y & 0x2) << 2) | ((x & 0x2) << 1) |
1077 ((y & 0x4) >> 1) | ((x & 0x4) >> 2);
1078
1079 /* m is in range [0, 63]. We scale it to [0, 63.0f/64.0f], then
1080 * shift it to to [1.0f/128.0f, 127.0f/128.0f] so that 0 < d < 1.
1081 * This ensures exact values are not changed by dithering.
1082 */
1083 return (float)(m) * (1 / 64.0f) + (1.0f / 128.0f);
1084}
1085
1086typedef float (* dither_factor_t)(int x, int y);
1087
1088static force_inline__inline__ __attribute__ ((__always_inline__)) float
1089dither_apply_channel (float f, float d, float s)
1090{
1091 /* float_to_unorm splits the [0, 1] segment in (1 << n_bits)
1092 * subsections of equal length; however unorm_to_float does not
1093 * map to the center of those sections. In fact, pixel value u is
1094 * mapped to:
1095 *
1096 * u u u 1
1097 * -------------- = ---------- + -------------- * ----------
1098 * 2^n_bits - 1 2^n_bits 2^n_bits - 1 2^n_bits
1099 *
1100 * Hence if f = u / (2^n_bits - 1) is exactly representable on a
1101 * n_bits palette, all the numbers between
1102 *
1103 * u
1104 * ---------- = f - f * 2^n_bits = f + (0 - f) * 2^n_bits
1105 * 2^n_bits
1106 *
1107 * and
1108 *
1109 * u + 1
1110 * ---------- = f - (f - 1) * 2^n_bits = f + (1 - f) * 2^n_bits
1111 * 2^n_bits
1112 *
1113 * are also mapped back to u.
1114 *
1115 * Hence the following calculation ensures that we add as much
1116 * noise as possible without perturbing values which are exactly
1117 * representable in the target colorspace. Note that this corresponds to
1118 * mixing the original color with noise with a ratio of `1 / 2^n_bits`.
1119 */
1120 return f + (d - f) * s;
1121}
1122
1123static force_inline__inline__ __attribute__ ((__always_inline__)) float
1124dither_compute_scale (int n_bits)
1125{
1126 // No dithering for wide formats
1127 if (n_bits == 0 || n_bits >= 32)
1128 return 0.f;
1129
1130 return 1.f / (float)(1 << n_bits);
1131}
1132
1133static const uint32_t *
1134dither_apply_ordered (pixman_iter_t *iter, dither_factor_t factor)
1135{
1136 bits_image_t *image = &iter->image->bits;
1137 int x = iter->x + image->dither_offset_x;
1138 int y = iter->y + image->dither_offset_y;
1139 int width = iter->width;
1140 argb_t *buffer = (argb_t *)iter->buffer;
1141
1142 pixman_format_code_t format = image->format;
1143 int a_size = PIXMAN_FORMAT_A (format)(((format >> (12)) & ((1 << (4)) - 1)) <<
((format >> 22) & 3))
;
1144 int r_size = PIXMAN_FORMAT_R (format)(((format >> (8)) & ((1 << (4)) - 1)) <<
((format >> 22) & 3))
;
1145 int g_size = PIXMAN_FORMAT_G (format)(((format >> (4)) & ((1 << (4)) - 1)) <<
((format >> 22) & 3))
;
1146 int b_size = PIXMAN_FORMAT_B (format)(((format >> (0)) & ((1 << (4)) - 1)) <<
((format >> 22) & 3))
;
1147
1148 float a_scale = dither_compute_scale (a_size);
1149 float r_scale = dither_compute_scale (r_size);
1150 float g_scale = dither_compute_scale (g_size);
1151 float b_scale = dither_compute_scale (b_size);
1152
1153 int i;
1154 float d;
1155
1156 for (i = 0; i < width; ++i)
1157 {
1158 d = factor (x + i, y);
1159
1160 buffer->a = dither_apply_channel (buffer->a, d, a_scale);
1161 buffer->r = dither_apply_channel (buffer->r, d, r_scale);
1162 buffer->g = dither_apply_channel (buffer->g, d, g_scale);
1163 buffer->b = dither_apply_channel (buffer->b, d, b_scale);
1164
1165 buffer++;
1166 }
1167
1168 return iter->buffer;
1169}
1170
1171static void
1172dest_write_back_wide (pixman_iter_t *iter)
1173{
1174 bits_image_t * image = &iter->image->bits;
1175 int x = iter->x;
1176 int y = iter->y;
1177 int width = iter->width;
1178 const uint32_t *buffer = iter->buffer;
1179
1180 switch (image->dither)
1181 {
1182 case PIXMAN_DITHER_NONE:
1183 break;
1184
1185 case PIXMAN_DITHER_GOOD:
1186 case PIXMAN_DITHER_BEST:
1187 case PIXMAN_DITHER_ORDERED_BLUE_NOISE_64:
1188 buffer = dither_apply_ordered (iter, dither_factor_blue_noise_64);
1189 break;
1190
1191 case PIXMAN_DITHER_FAST:
1192 case PIXMAN_DITHER_ORDERED_BAYER_8:
1193 buffer = dither_apply_ordered (iter, dither_factor_bayer_8);
1194 break;
1195 }
1196
1197 image->store_scanline_float (image, x, y, width, buffer);
1198
1199 if (image->common.alpha_map)
1200 {
1201 x -= image->common.alpha_origin_x;
1202 y -= image->common.alpha_origin_y;
1203
1204 image->common.alpha_map->store_scanline_float (
1205 image->common.alpha_map, x, y, width, buffer);
1206 }
1207
1208 iter->y++;
1209}
1210
1211void
1212_pixman_bits_image_dest_iter_init (pixman_image_t *image, pixman_iter_t *iter)
1213{
1214 if (iter->iter_flags & ITER_NARROW)
1215 {
1216 if ((iter->iter_flags & (ITER_IGNORE_RGB | ITER_IGNORE_ALPHA)) ==
1217 (ITER_IGNORE_RGB | ITER_IGNORE_ALPHA))
1218 {
1219 iter->get_scanline = _pixman_iter_get_scanline_noop;
1220 }
1221 else
1222 {
1223 iter->get_scanline = dest_get_scanline_narrow;
1224 }
1225
1226 iter->write_back = dest_write_back_narrow;
1227 }
1228 else
1229 {
1230 iter->get_scanline = dest_get_scanline_wide;
1231 iter->write_back = dest_write_back_wide;
1232 }
1233}
1234
1235static uint32_t *
1236create_bits (pixman_format_code_t format,
1237 int width,
1238 int height,
1239 int * rowstride_bytes,
1240 pixman_bool_t clear)
1241{
1242 int stride;
1243 size_t buf_size;
1244 int bpp;
1245
1246 /* what follows is a long-winded way, avoiding any possibility of integer
1247 * overflows, of saying:
1248 * stride = ((width * bpp + 0x1f) >> 5) * sizeof (uint32_t);
1249 */
1250
1251 bpp = PIXMAN_FORMAT_BPP (format)(((format >> (24)) & ((1 << (8)) - 1)) <<
((format >> 22) & 3))
;
1252 if (_pixman_multiply_overflows_int (width, bpp))
1253 return NULL((void*)0);
1254
1255 stride = width * bpp;
1256 if (_pixman_addition_overflows_int (stride, 0x1f))
1257 return NULL((void*)0);
1258
1259 stride += 0x1f;
1260 stride >>= 5;
1261
1262 stride *= sizeof (uint32_t);
1263
1264 if (_pixman_multiply_overflows_size (height, stride))
1265 return NULL((void*)0);
1266
1267 buf_size = (size_t)height * stride;
1268
1269 if (rowstride_bytes)
1270 *rowstride_bytes = stride;
1271
1272 if (clear)
1273 return calloc (1, buf_size);
1274 else
1275 return malloc (buf_size);
1276}
1277
1278pixman_bool_t
1279_pixman_bits_image_init (pixman_image_t * image,
1280 pixman_format_code_t format,
1281 int width,
1282 int height,
1283 uint32_t * bits,
1284 int rowstride,
1285 pixman_bool_t clear)
1286{
1287 uint32_t *free_me = NULL((void*)0);
1288
1289 if (PIXMAN_FORMAT_BPP (format)(((format >> (24)) & ((1 << (8)) - 1)) <<
((format >> 22) & 3))
== 128)
1290 return_val_if_fail(!(rowstride % 4), FALSE)do { if (__builtin_expect ((!(!(rowstride % 4))), 0)) { _pixman_log_error
(((const char*) (__PRETTY_FUNCTION__)), "The expression " "!(rowstride % 4)"
" was false"); return (0); } } while (0)
;
1291
1292 if (!bits && width && height)
1293 {
1294 int rowstride_bytes;
1295
1296 free_me = bits = create_bits (format, width, height, &rowstride_bytes, clear);
1297
1298 if (!bits)
1299 return FALSE0;
1300
1301 rowstride = rowstride_bytes / (int) sizeof (uint32_t);
1302 }
1303
1304 _pixman_image_init (image);
1305
1306 image->type = BITS;
1307 image->bits.format = format;
1308 image->bits.width = width;
1309 image->bits.height = height;
1310 image->bits.bits = bits;
1311 image->bits.free_me = free_me;
1312 image->bits.dither = PIXMAN_DITHER_NONE;
1313 image->bits.dither_offset_x = 0;
1314 image->bits.dither_offset_y = 0;
1315 image->bits.read_func = NULL((void*)0);
1316 image->bits.write_func = NULL((void*)0);
1317 image->bits.rowstride = rowstride;
1318 image->bits.indexed = NULL((void*)0);
1319
1320 image->common.property_changed = bits_image_property_changed;
1321
1322 _pixman_image_reset_clip_region (image);
1323
1324 return TRUE1;
1325}
1326
1327static pixman_image_t *
1328create_bits_image_internal (pixman_format_code_t format,
1329 int width,
1330 int height,
1331 uint32_t * bits,
1332 int rowstride_bytes,
1333 pixman_bool_t clear)
1334{
1335 pixman_image_t *image;
1336
1337 /* must be a whole number of uint32_t's
1338 */
1339 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)
1340 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)
;
1341
1342 return_val_if_fail (PIXMAN_FORMAT_BPP (format) >= PIXMAN_FORMAT_DEPTH (format), NULL)do { if (__builtin_expect ((!((((format >> (24)) & (
(1 << (8)) - 1)) << ((format >> 22) & 3
)) >= ((((format >> (12)) & ((1 << (4)) - 1
)) << ((format >> 22) & 3)) + (((format >>
(8)) & ((1 << (4)) - 1)) << ((format >>
22) & 3)) + (((format >> (4)) & ((1 << (
4)) - 1)) << ((format >> 22) & 3)) + (((format
>> (0)) & ((1 << (4)) - 1)) << ((format
>> 22) & 3))))), 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)
;
1343
1344 image = _pixman_image_allocate ();
1345
1346 if (!image)
1347 return NULL((void*)0);
1348
1349 if (!_pixman_bits_image_init (image, format, width, height, bits,
1350 rowstride_bytes / (int) sizeof (uint32_t),
1351 clear))
1352 {
1353 free (image);
1354 return NULL((void*)0);
1355 }
1356
1357 return image;
1358}
1359
1360/* If bits is NULL, a buffer will be allocated and initialized to 0 */
1361PIXMAN_EXPORTextern __attribute__((visibility("hidden"))) pixman_image_t *
1362pixman_image_create_bits_moz_pixman_image_create_bits (pixman_format_code_t format,
1363 int width,
1364 int height,
1365 uint32_t * bits,
1366 int rowstride_bytes)
1367{
1368 return create_bits_image_internal (
1369 format, width, height, bits, rowstride_bytes, TRUE1);
1370}
1371
1372
1373/* If bits is NULL, a buffer will be allocated and _not_ initialized */
1374PIXMAN_EXPORTextern __attribute__((visibility("hidden"))) pixman_image_t *
1375pixman_image_create_bits_no_clear (pixman_format_code_t format,
1376 int width,
1377 int height,
1378 uint32_t * bits,
1379 int rowstride_bytes)
1380{
1381 return create_bits_image_internal (
1382 format, width, height, bits, rowstride_bytes, FALSE0);
1383}