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 <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
42 static force_inline void
fetch_pixel_no_alpha_32(bits_image_t * image,int x,int y,pixman_bool_t check_bounds,void * out)43 fetch_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
56 static force_inline void
fetch_pixel_no_alpha_float(bits_image_t * image,int x,int y,pixman_bool_t check_bounds,void * out)57 fetch_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
70 typedef void (* get_pixel_t) (bits_image_t *image,
71 int x, int y, pixman_bool_t check_bounds, void *out);
72
73 static force_inline void
bits_image_fetch_pixel_nearest(bits_image_t * image,pixman_fixed_t x,pixman_fixed_t y,get_pixel_t get_pixel,void * out)74 bits_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);
81 int y0 = pixman_fixed_to_int (y - pixman_fixed_e);
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, FALSE, out);
89 }
90 else
91 {
92 get_pixel (image, x0, y0, TRUE, out);
93 }
94 }
95
96 static force_inline void
bits_image_fetch_pixel_bilinear_32(bits_image_t * image,pixman_fixed_t x,pixman_fixed_t y,get_pixel_t get_pixel,void * out)97 bits_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 / 2;
112 y1 = y - pixman_fixed_1 / 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);
118 y1 = pixman_fixed_to_int (y1);
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, FALSE, &tl);
130 get_pixel (image, x2, y1, FALSE, &tr);
131 get_pixel (image, x1, y2, FALSE, &bl);
132 get_pixel (image, x2, y2, FALSE, &br);
133 }
134 else
135 {
136 get_pixel (image, x1, y1, TRUE, &tl);
137 get_pixel (image, x2, y1, TRUE, &tr);
138 get_pixel (image, x1, y2, TRUE, &bl);
139 get_pixel (image, x2, y2, TRUE, &br);
140 }
141
142 *ret = bilinear_interpolation (tl, tr, bl, br, distx, disty);
143 }
144
145 static force_inline void
bits_image_fetch_pixel_bilinear_float(bits_image_t * image,pixman_fixed_t x,pixman_fixed_t y,get_pixel_t get_pixel,void * out)146 bits_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 / 2;
161 y1 = y - pixman_fixed_1 / 2;
162
163 distx = ((float)pixman_fixed_fraction(x1)) / 65536.f;
164 disty = ((float)pixman_fixed_fraction(y1)) / 65536.f;
165
166 x1 = pixman_fixed_to_int (x1);
167 y1 = pixman_fixed_to_int (y1);
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, FALSE, &tl);
179 get_pixel (image, x2, y1, FALSE, &tr);
180 get_pixel (image, x1, y2, FALSE, &bl);
181 get_pixel (image, x2, y2, FALSE, &br);
182 }
183 else
184 {
185 get_pixel (image, x1, y1, TRUE, &tl);
186 get_pixel (image, x2, y1, TRUE, &tr);
187 get_pixel (image, x1, y2, TRUE, &bl);
188 get_pixel (image, x2, y2, TRUE, &br);
189 }
190
191 *ret = bilinear_interpolation_float (tl, tr, bl, br, distx, disty);
192 }
193
accum_32(unsigned int * satot,unsigned int * srtot,unsigned int * sgtot,unsigned int * sbtot,const void * p,pixman_fixed_t f)194 static force_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) * f;
201 *sgtot += (int)GREEN_8 (pixel) * f;
202 *sbtot += (int)BLUE_8 (pixel) * f;
203 *satot += (int)ALPHA_8 (pixel) * f;
204 }
205
reduce_32(unsigned int satot,unsigned int srtot,unsigned int sgtot,unsigned int sbtot,void * p)206 static force_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 = (satot + 0x8000) >> 16;
213 srtot = (srtot + 0x8000) >> 16;
214 sgtot = (sgtot + 0x8000) >> 16;
215 sbtot = (sbtot + 0x8000) >> 16;
216
217 satot = CLIP (satot, 0, 0xff);
218 srtot = CLIP (srtot, 0, 0xff);
219 sgtot = CLIP (sgtot, 0, 0xff);
220 sbtot = CLIP (sbtot, 0, 0xff);
221
222 *ret = ((satot << 24) | (srtot << 16) | (sgtot << 8) | (sbtot));
223 }
224
accum_float(unsigned int * satot,unsigned int * srtot,unsigned int * sgtot,unsigned int * sbtot,const void * p,pixman_fixed_t f)225 static force_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
reduce_float(unsigned int satot,unsigned int srtot,unsigned int sgtot,unsigned int sbtot,void * p)237 static force_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 (satot / 65536.f, 0.f, 1.f);
244 ret->r = CLIP (srtot / 65536.f, 0.f, 1.f);
245 ret->g = CLIP (sgtot / 65536.f, 0.f, 1.f);
246 ret->b = CLIP (sbtot / 65536.f, 0.f, 1.f);
247 }
248
249 typedef 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
253 typedef void (* reduce_pixel_t) (unsigned int satot, unsigned int srtot,
254 unsigned int sgtot, unsigned int sbtot,
255 void *out);
256
257 static force_inline void
bits_image_fetch_pixel_convolution(bits_image_t * image,pixman_fixed_t x,pixman_fixed_t y,get_pixel_t get_pixel,void * out,accumulate_pixel_t accum,reduce_pixel_t reduce)258 bits_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) >> 1;
268 int y_off = (params[1] - pixman_fixed_1) >> 1;
269 int32_t cwidth = pixman_fixed_to_int (params[0]);
270 int32_t cheight = pixman_fixed_to_int (params[1]);
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);
280 y1 = pixman_fixed_to_int (y - pixman_fixed_e - y_off);
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, FALSE, &pixel);
306 }
307 else
308 {
309 get_pixel (image, rx, ry, TRUE, &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
322 static void
bits_image_fetch_pixel_separable_convolution(bits_image_t * image,pixman_fixed_t x,pixman_fixed_t y,get_pixel_t get_pixel,void * out,accumulate_pixel_t accum,reduce_pixel_t reduce)323 bits_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]);
336 int cheight = pixman_fixed_to_int (params[1]);
337 int x_phase_bits = pixman_fixed_to_int (params[2]);
338 int y_phase_bits = pixman_fixed_to_int (params[3]);
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) >> 1;
342 int y_off = ((cheight << 16) - pixman_fixed_1) >> 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);
363 y1 = pixman_fixed_to_int (y - pixman_fixed_e - y_off);
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, FALSE, &pixel);
394 }
395 else
396 {
397 get_pixel (image, rx, ry, TRUE, &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
412 static force_inline void
bits_image_fetch_pixel_filtered(bits_image_t * image,pixman_bool_t wide,pixman_fixed_t x,pixman_fixed_t y,get_pixel_t get_pixel,void * out)413 bits_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);
470 break;
471 }
472 }
473
474 static uint32_t *
__bits_image_fetch_affine_no_alpha(pixman_iter_t * iter,pixman_bool_t wide,const uint32_t * mask)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 pixman_fixed_t x, y;
486 pixman_fixed_t ux, uy;
487 pixman_vector_t v;
488 int i;
489 get_pixel_t get_pixel =
490 wide ? fetch_pixel_no_alpha_float : fetch_pixel_no_alpha_32;
491
492 /* reference point is the center of the pixel */
493 v.vector[0] = pixman_int_to_fixed (offset) + pixman_fixed_1 / 2;
494 v.vector[1] = pixman_int_to_fixed (line) + pixman_fixed_1 / 2;
495 v.vector[2] = pixman_fixed_1;
496
497 if (image->common.transform)
498 {
499 if (!pixman_transform_point_3d (image->common.transform, &v))
500 return iter->buffer;
501
502 ux = image->common.transform->matrix[0][0];
503 uy = image->common.transform->matrix[1][0];
504 }
505 else
506 {
507 ux = pixman_fixed_1;
508 uy = 0;
509 }
510
511 x = v.vector[0];
512 y = v.vector[1];
513
514 for (i = 0; i < width; ++i)
515 {
516 if (!mask || mask[i])
517 {
518 bits_image_fetch_pixel_filtered (
519 &image->bits, wide, x, y, get_pixel, buffer);
520 }
521
522 x += ux;
523 y += uy;
524 buffer += wide ? 4 : 1;
525 }
526
527 return iter->buffer;
528 }
529
530 static uint32_t *
bits_image_fetch_affine_no_alpha_32(pixman_iter_t * iter,const uint32_t * mask)531 bits_image_fetch_affine_no_alpha_32 (pixman_iter_t *iter,
532 const uint32_t *mask)
533 {
534 return __bits_image_fetch_affine_no_alpha(iter, FALSE, mask);
535 }
536
537 static uint32_t *
bits_image_fetch_affine_no_alpha_float(pixman_iter_t * iter,const uint32_t * mask)538 bits_image_fetch_affine_no_alpha_float (pixman_iter_t *iter,
539 const uint32_t *mask)
540 {
541 return __bits_image_fetch_affine_no_alpha(iter, TRUE, mask);
542 }
543
544 /* General fetcher */
545 static force_inline void
fetch_pixel_general_32(bits_image_t * image,int x,int y,pixman_bool_t check_bounds,void * out)546 fetch_pixel_general_32 (bits_image_t *image,
547 int x, int y, pixman_bool_t check_bounds,
548 void *out)
549 {
550 uint32_t pixel, *ret = out;
551
552 if (check_bounds &&
553 (x < 0 || x >= image->width || y < 0 || y >= image->height))
554 {
555 *ret = 0;
556 return;
557 }
558
559 pixel = image->fetch_pixel_32 (image, x, y);
560
561 if (image->common.alpha_map)
562 {
563 uint32_t pixel_a;
564
565 x -= image->common.alpha_origin_x;
566 y -= image->common.alpha_origin_y;
567
568 if (x < 0 || x >= image->common.alpha_map->width ||
569 y < 0 || y >= image->common.alpha_map->height)
570 {
571 pixel_a = 0;
572 }
573 else
574 {
575 pixel_a = image->common.alpha_map->fetch_pixel_32 (
576 image->common.alpha_map, x, y);
577
578 pixel_a = ALPHA_8 (pixel_a);
579 }
580
581 pixel &= 0x00ffffff;
582 pixel |= (pixel_a << 24);
583 }
584
585 *ret = pixel;
586 }
587
588 static force_inline void
fetch_pixel_general_float(bits_image_t * image,int x,int y,pixman_bool_t check_bounds,void * out)589 fetch_pixel_general_float (bits_image_t *image,
590 int x, int y, pixman_bool_t check_bounds,
591 void *out)
592 {
593 argb_t *ret = out;
594
595 if (check_bounds &&
596 (x < 0 || x >= image->width || y < 0 || y >= image->height))
597 {
598 ret->a = ret->r = ret->g = ret->b = 0;
599 return;
600 }
601
602 *ret = image->fetch_pixel_float (image, x, y);
603
604 if (image->common.alpha_map)
605 {
606 x -= image->common.alpha_origin_x;
607 y -= image->common.alpha_origin_y;
608
609 if (x < 0 || x >= image->common.alpha_map->width ||
610 y < 0 || y >= image->common.alpha_map->height)
611 {
612 ret->a = 0.f;
613 }
614 else
615 {
616 argb_t alpha;
617
618 alpha = image->common.alpha_map->fetch_pixel_float (
619 image->common.alpha_map, x, y);
620
621 ret->a = alpha.a;
622 }
623 }
624 }
625
626 static uint32_t *
__bits_image_fetch_general(pixman_iter_t * iter,pixman_bool_t wide,const uint32_t * mask)627 __bits_image_fetch_general (pixman_iter_t *iter,
628 pixman_bool_t wide,
629 const uint32_t *mask)
630 {
631 pixman_image_t *image = iter->image;
632 int offset = iter->x;
633 int line = iter->y++;
634 int width = iter->width;
635 uint32_t * buffer = iter->buffer;
636 get_pixel_t get_pixel =
637 wide ? fetch_pixel_general_float : fetch_pixel_general_32;
638
639 pixman_fixed_t x, y, w;
640 pixman_fixed_t ux, uy, uw;
641 pixman_vector_t v;
642 int i;
643
644 /* reference point is the center of the pixel */
645 v.vector[0] = pixman_int_to_fixed (offset) + pixman_fixed_1 / 2;
646 v.vector[1] = pixman_int_to_fixed (line) + pixman_fixed_1 / 2;
647 v.vector[2] = pixman_fixed_1;
648
649 if (image->common.transform)
650 {
651 if (!pixman_transform_point_3d (image->common.transform, &v))
652 return buffer;
653
654 ux = image->common.transform->matrix[0][0];
655 uy = image->common.transform->matrix[1][0];
656 uw = image->common.transform->matrix[2][0];
657 }
658 else
659 {
660 ux = pixman_fixed_1;
661 uy = 0;
662 uw = 0;
663 }
664
665 x = v.vector[0];
666 y = v.vector[1];
667 w = v.vector[2];
668
669 for (i = 0; i < width; ++i)
670 {
671 pixman_fixed_t x0, y0;
672
673 if (!mask || mask[i])
674 {
675 if (w != 0)
676 {
677 x0 = ((uint64_t)x << 16) / w;
678 y0 = ((uint64_t)y << 16) / w;
679 }
680 else
681 {
682 x0 = 0;
683 y0 = 0;
684 }
685
686 bits_image_fetch_pixel_filtered (
687 &image->bits, wide, x0, y0, get_pixel, buffer);
688 }
689
690 x += ux;
691 y += uy;
692 w += uw;
693 buffer += wide ? 4 : 1;
694 }
695
696 return iter->buffer;
697 }
698
699 static uint32_t *
bits_image_fetch_general_32(pixman_iter_t * iter,const uint32_t * mask)700 bits_image_fetch_general_32 (pixman_iter_t *iter,
701 const uint32_t *mask)
702 {
703 return __bits_image_fetch_general(iter, FALSE, mask);
704 }
705
706 static uint32_t *
bits_image_fetch_general_float(pixman_iter_t * iter,const uint32_t * mask)707 bits_image_fetch_general_float (pixman_iter_t *iter,
708 const uint32_t *mask)
709 {
710 return __bits_image_fetch_general(iter, TRUE, mask);
711 }
712
713 static void
replicate_pixel_32(bits_image_t * bits,int x,int y,int width,uint32_t * buffer)714 replicate_pixel_32 (bits_image_t * bits,
715 int x,
716 int y,
717 int width,
718 uint32_t * buffer)
719 {
720 uint32_t color;
721 uint32_t *end;
722
723 color = bits->fetch_pixel_32 (bits, x, y);
724
725 end = buffer + width;
726 while (buffer < end)
727 *(buffer++) = color;
728 }
729
730 static void
replicate_pixel_float(bits_image_t * bits,int x,int y,int width,uint32_t * b)731 replicate_pixel_float (bits_image_t * bits,
732 int x,
733 int y,
734 int width,
735 uint32_t * b)
736 {
737 argb_t color;
738 argb_t *buffer = (argb_t *)b;
739 argb_t *end;
740
741 color = bits->fetch_pixel_float (bits, x, y);
742
743 end = buffer + width;
744 while (buffer < end)
745 *(buffer++) = color;
746 }
747
748 static void
bits_image_fetch_untransformed_repeat_none(bits_image_t * image,pixman_bool_t wide,int x,int y,int width,uint32_t * buffer)749 bits_image_fetch_untransformed_repeat_none (bits_image_t *image,
750 pixman_bool_t wide,
751 int x,
752 int y,
753 int width,
754 uint32_t * buffer)
755 {
756 uint32_t w;
757
758 if (y < 0 || y >= image->height)
759 {
760 memset (buffer, 0, width * (wide? sizeof (argb_t) : 4));
761 return;
762 }
763
764 if (x < 0)
765 {
766 w = MIN (width, -x);
767
768 memset (buffer, 0, w * (wide ? sizeof (argb_t) : 4));
769
770 width -= w;
771 buffer += w * (wide? 4 : 1);
772 x += w;
773 }
774
775 if (x < image->width)
776 {
777 w = MIN (width, image->width - x);
778
779 if (wide)
780 image->fetch_scanline_float (image, x, y, w, buffer, NULL);
781 else
782 image->fetch_scanline_32 (image, x, y, w, buffer, NULL);
783
784 width -= w;
785 buffer += w * (wide? 4 : 1);
786 x += w;
787 }
788
789 memset (buffer, 0, width * (wide ? sizeof (argb_t) : 4));
790 }
791
792 static void
bits_image_fetch_untransformed_repeat_normal(bits_image_t * image,pixman_bool_t wide,int x,int y,int width,uint32_t * buffer)793 bits_image_fetch_untransformed_repeat_normal (bits_image_t *image,
794 pixman_bool_t wide,
795 int x,
796 int y,
797 int width,
798 uint32_t * buffer)
799 {
800 uint32_t w;
801
802 while (y < 0)
803 y += image->height;
804
805 while (y >= image->height)
806 y -= image->height;
807
808 if (image->width == 1)
809 {
810 if (wide)
811 replicate_pixel_float (image, 0, y, width, buffer);
812 else
813 replicate_pixel_32 (image, 0, y, width, buffer);
814
815 return;
816 }
817
818 while (width)
819 {
820 while (x < 0)
821 x += image->width;
822 while (x >= image->width)
823 x -= image->width;
824
825 w = MIN (width, image->width - x);
826
827 if (wide)
828 image->fetch_scanline_float (image, x, y, w, buffer, NULL);
829 else
830 image->fetch_scanline_32 (image, x, y, w, buffer, NULL);
831
832 buffer += w * (wide? 4 : 1);
833 x += w;
834 width -= w;
835 }
836 }
837
838 static uint32_t *
bits_image_fetch_untransformed_32(pixman_iter_t * iter,const uint32_t * mask)839 bits_image_fetch_untransformed_32 (pixman_iter_t * iter,
840 const uint32_t *mask)
841 {
842 pixman_image_t *image = iter->image;
843 int x = iter->x;
844 int y = iter->y;
845 int width = iter->width;
846 uint32_t * buffer = iter->buffer;
847
848 if (image->common.repeat == PIXMAN_REPEAT_NONE)
849 {
850 bits_image_fetch_untransformed_repeat_none (
851 &image->bits, FALSE, x, y, width, buffer);
852 }
853 else
854 {
855 bits_image_fetch_untransformed_repeat_normal (
856 &image->bits, FALSE, x, y, width, buffer);
857 }
858
859 iter->y++;
860 return buffer;
861 }
862
863 static uint32_t *
bits_image_fetch_untransformed_float(pixman_iter_t * iter,const uint32_t * mask)864 bits_image_fetch_untransformed_float (pixman_iter_t * iter,
865 const uint32_t *mask)
866 {
867 pixman_image_t *image = iter->image;
868 int x = iter->x;
869 int y = iter->y;
870 int width = iter->width;
871 uint32_t * buffer = iter->buffer;
872
873 if (image->common.repeat == PIXMAN_REPEAT_NONE)
874 {
875 bits_image_fetch_untransformed_repeat_none (
876 &image->bits, TRUE, x, y, width, buffer);
877 }
878 else
879 {
880 bits_image_fetch_untransformed_repeat_normal (
881 &image->bits, TRUE, x, y, width, buffer);
882 }
883
884 iter->y++;
885 return buffer;
886 }
887
888 typedef struct
889 {
890 pixman_format_code_t format;
891 uint32_t flags;
892 pixman_iter_get_scanline_t get_scanline_32;
893 pixman_iter_get_scanline_t get_scanline_float;
894 } fetcher_info_t;
895
896 static const fetcher_info_t fetcher_info[] =
897 {
898 { PIXMAN_any,
899 (FAST_PATH_NO_ALPHA_MAP |
900 FAST_PATH_ID_TRANSFORM |
901 FAST_PATH_NO_CONVOLUTION_FILTER |
902 FAST_PATH_NO_PAD_REPEAT |
903 FAST_PATH_NO_REFLECT_REPEAT),
904 bits_image_fetch_untransformed_32,
905 bits_image_fetch_untransformed_float
906 },
907
908 /* Affine, no alpha */
909 { PIXMAN_any,
910 (FAST_PATH_NO_ALPHA_MAP | FAST_PATH_HAS_TRANSFORM | FAST_PATH_AFFINE_TRANSFORM),
911 bits_image_fetch_affine_no_alpha_32,
912 bits_image_fetch_affine_no_alpha_float,
913 },
914
915 /* General */
916 { PIXMAN_any,
917 0,
918 bits_image_fetch_general_32,
919 bits_image_fetch_general_float,
920 },
921
922 { PIXMAN_null },
923 };
924
925 static void
bits_image_property_changed(pixman_image_t * image)926 bits_image_property_changed (pixman_image_t *image)
927 {
928 _pixman_bits_image_setup_accessors (&image->bits);
929 }
930
931 void
_pixman_bits_image_src_iter_init(pixman_image_t * image,pixman_iter_t * iter)932 _pixman_bits_image_src_iter_init (pixman_image_t *image, pixman_iter_t *iter)
933 {
934 pixman_format_code_t format = image->common.extended_format_code;
935 uint32_t flags = image->common.flags;
936 const fetcher_info_t *info;
937
938 for (info = fetcher_info; info->format != PIXMAN_null; ++info)
939 {
940 if ((info->format == format || info->format == PIXMAN_any) &&
941 (info->flags & flags) == info->flags)
942 {
943 if (iter->iter_flags & ITER_NARROW)
944 {
945 iter->get_scanline = info->get_scanline_32;
946 }
947 else
948 {
949 iter->get_scanline = info->get_scanline_float;
950 }
951 return;
952 }
953 }
954
955 /* Just in case we somehow didn't find a scanline function */
956 iter->get_scanline = _pixman_iter_get_scanline_noop;
957 }
958
959 static uint32_t *
dest_get_scanline_narrow(pixman_iter_t * iter,const uint32_t * mask)960 dest_get_scanline_narrow (pixman_iter_t *iter, const uint32_t *mask)
961 {
962 pixman_image_t *image = iter->image;
963 int x = iter->x;
964 int y = iter->y;
965 int width = iter->width;
966 uint32_t * buffer = iter->buffer;
967
968 image->bits.fetch_scanline_32 (&image->bits, x, y, width, buffer, mask);
969 if (image->common.alpha_map)
970 {
971 uint32_t *alpha;
972
973 if ((alpha = malloc (width * sizeof (uint32_t))))
974 {
975 int i;
976
977 x -= image->common.alpha_origin_x;
978 y -= image->common.alpha_origin_y;
979
980 image->common.alpha_map->fetch_scanline_32 (
981 image->common.alpha_map, x, y, width, alpha, mask);
982
983 for (i = 0; i < width; ++i)
984 {
985 buffer[i] &= ~0xff000000;
986 buffer[i] |= (alpha[i] & 0xff000000);
987 }
988
989 free (alpha);
990 }
991 }
992
993 return iter->buffer;
994 }
995
996 static uint32_t *
dest_get_scanline_wide(pixman_iter_t * iter,const uint32_t * mask)997 dest_get_scanline_wide (pixman_iter_t *iter, const uint32_t *mask)
998 {
999 bits_image_t * image = &iter->image->bits;
1000 int x = iter->x;
1001 int y = iter->y;
1002 int width = iter->width;
1003 argb_t * buffer = (argb_t *)iter->buffer;
1004
1005 image->fetch_scanline_float (
1006 image, x, y, width, (uint32_t *)buffer, mask);
1007 if (image->common.alpha_map)
1008 {
1009 argb_t *alpha;
1010
1011 if ((alpha = malloc (width * sizeof (argb_t))))
1012 {
1013 int i;
1014
1015 x -= image->common.alpha_origin_x;
1016 y -= image->common.alpha_origin_y;
1017
1018 image->common.alpha_map->fetch_scanline_float (
1019 image->common.alpha_map, x, y, width, (uint32_t *)alpha, mask);
1020
1021 for (i = 0; i < width; ++i)
1022 buffer[i].a = alpha[i].a;
1023
1024 free (alpha);
1025 }
1026 }
1027
1028 return iter->buffer;
1029 }
1030
1031 static void
dest_write_back_narrow(pixman_iter_t * iter)1032 dest_write_back_narrow (pixman_iter_t *iter)
1033 {
1034 bits_image_t * image = &iter->image->bits;
1035 int x = iter->x;
1036 int y = iter->y;
1037 int width = iter->width;
1038 const uint32_t *buffer = iter->buffer;
1039
1040 image->store_scanline_32 (image, x, y, width, buffer);
1041
1042 if (image->common.alpha_map)
1043 {
1044 x -= image->common.alpha_origin_x;
1045 y -= image->common.alpha_origin_y;
1046
1047 image->common.alpha_map->store_scanline_32 (
1048 image->common.alpha_map, x, y, width, buffer);
1049 }
1050
1051 iter->y++;
1052 }
1053
1054 static const float
dither_factor_blue_noise_64(int x,int y)1055 dither_factor_blue_noise_64 (int x, int y)
1056 {
1057 float m = dither_blue_noise_64x64[((y & 0x3f) << 6) | (x & 0x3f)];
1058 return m * (1. / 4096.f) + (1. / 8192.f);
1059 }
1060
1061 static const float
dither_factor_bayer_8(int x,int y)1062 dither_factor_bayer_8 (int x, int y)
1063 {
1064 uint32_t m;
1065
1066 y ^= x;
1067
1068 /* Compute reverse(interleave(xor(x mod n, y mod n), x mod n))
1069 * Here n = 8 and `mod n` is the bottom 3 bits.
1070 */
1071 m = ((y & 0x1) << 5) | ((x & 0x1) << 4) |
1072 ((y & 0x2) << 2) | ((x & 0x2) << 1) |
1073 ((y & 0x4) >> 1) | ((x & 0x4) >> 2);
1074
1075 /* m is in range [0, 63]. We scale it to [0, 63.0f/64.0f], then
1076 * shift it to to [1.0f/128.0f, 127.0f/128.0f] so that 0 < d < 1.
1077 * This ensures exact values are not changed by dithering.
1078 */
1079 return (float)(m) * (1 / 64.0f) + (1.0f / 128.0f);
1080 }
1081
1082 typedef float (* dither_factor_t)(int x, int y);
1083
1084 static force_inline float
dither_apply_channel(float f,float d,float s)1085 dither_apply_channel (float f, float d, float s)
1086 {
1087 /* float_to_unorm splits the [0, 1] segment in (1 << n_bits)
1088 * subsections of equal length; however unorm_to_float does not
1089 * map to the center of those sections. In fact, pixel value u is
1090 * mapped to:
1091 *
1092 * u u u 1
1093 * -------------- = ---------- + -------------- * ----------
1094 * 2^n_bits - 1 2^n_bits 2^n_bits - 1 2^n_bits
1095 *
1096 * Hence if f = u / (2^n_bits - 1) is exactly representable on a
1097 * n_bits palette, all the numbers between
1098 *
1099 * u
1100 * ---------- = f - f * 2^n_bits = f + (0 - f) * 2^n_bits
1101 * 2^n_bits
1102 *
1103 * and
1104 *
1105 * u + 1
1106 * ---------- = f - (f - 1) * 2^n_bits = f + (1 - f) * 2^n_bits
1107 * 2^n_bits
1108 *
1109 * are also mapped back to u.
1110 *
1111 * Hence the following calculation ensures that we add as much
1112 * noise as possible without perturbing values which are exactly
1113 * representable in the target colorspace. Note that this corresponds to
1114 * mixing the original color with noise with a ratio of `1 / 2^n_bits`.
1115 */
1116 return f + (d - f) * s;
1117 }
1118
1119 static force_inline float
dither_compute_scale(int n_bits)1120 dither_compute_scale (int n_bits)
1121 {
1122 // No dithering for wide formats
1123 if (n_bits == 0 || n_bits >= 32)
1124 return 0.f;
1125
1126 return 1.f / (float)(1 << n_bits);
1127 }
1128
1129 static const uint32_t *
dither_apply_ordered(pixman_iter_t * iter,dither_factor_t factor)1130 dither_apply_ordered (pixman_iter_t *iter, dither_factor_t factor)
1131 {
1132 bits_image_t *image = &iter->image->bits;
1133 int x = iter->x + image->dither_offset_x;
1134 int y = iter->y + image->dither_offset_y;
1135 int width = iter->width;
1136 argb_t *buffer = (argb_t *)iter->buffer;
1137
1138 pixman_format_code_t format = image->format;
1139 int a_size = PIXMAN_FORMAT_A (format);
1140 int r_size = PIXMAN_FORMAT_R (format);
1141 int g_size = PIXMAN_FORMAT_G (format);
1142 int b_size = PIXMAN_FORMAT_B (format);
1143
1144 float a_scale = dither_compute_scale (a_size);
1145 float r_scale = dither_compute_scale (r_size);
1146 float g_scale = dither_compute_scale (g_size);
1147 float b_scale = dither_compute_scale (b_size);
1148
1149 int i;
1150 float d;
1151
1152 for (i = 0; i < width; ++i)
1153 {
1154 d = factor (x + i, y);
1155
1156 buffer->a = dither_apply_channel (buffer->a, d, a_scale);
1157 buffer->r = dither_apply_channel (buffer->r, d, r_scale);
1158 buffer->g = dither_apply_channel (buffer->g, d, g_scale);
1159 buffer->b = dither_apply_channel (buffer->b, d, b_scale);
1160
1161 buffer++;
1162 }
1163
1164 return iter->buffer;
1165 }
1166
1167 static void
dest_write_back_wide(pixman_iter_t * iter)1168 dest_write_back_wide (pixman_iter_t *iter)
1169 {
1170 bits_image_t * image = &iter->image->bits;
1171 int x = iter->x;
1172 int y = iter->y;
1173 int width = iter->width;
1174 const uint32_t *buffer = iter->buffer;
1175
1176 switch (image->dither)
1177 {
1178 case PIXMAN_DITHER_NONE:
1179 break;
1180
1181 case PIXMAN_DITHER_GOOD:
1182 case PIXMAN_DITHER_BEST:
1183 case PIXMAN_DITHER_ORDERED_BLUE_NOISE_64:
1184 buffer = dither_apply_ordered (iter, dither_factor_blue_noise_64);
1185 break;
1186
1187 case PIXMAN_DITHER_FAST:
1188 case PIXMAN_DITHER_ORDERED_BAYER_8:
1189 buffer = dither_apply_ordered (iter, dither_factor_bayer_8);
1190 break;
1191 }
1192
1193 image->store_scanline_float (image, x, y, width, buffer);
1194
1195 if (image->common.alpha_map)
1196 {
1197 x -= image->common.alpha_origin_x;
1198 y -= image->common.alpha_origin_y;
1199
1200 image->common.alpha_map->store_scanline_float (
1201 image->common.alpha_map, x, y, width, buffer);
1202 }
1203
1204 iter->y++;
1205 }
1206
1207 void
_pixman_bits_image_dest_iter_init(pixman_image_t * image,pixman_iter_t * iter)1208 _pixman_bits_image_dest_iter_init (pixman_image_t *image, pixman_iter_t *iter)
1209 {
1210 if (iter->iter_flags & ITER_NARROW)
1211 {
1212 if ((iter->iter_flags & (ITER_IGNORE_RGB | ITER_IGNORE_ALPHA)) ==
1213 (ITER_IGNORE_RGB | ITER_IGNORE_ALPHA))
1214 {
1215 iter->get_scanline = _pixman_iter_get_scanline_noop;
1216 }
1217 else
1218 {
1219 iter->get_scanline = dest_get_scanline_narrow;
1220 }
1221
1222 iter->write_back = dest_write_back_narrow;
1223 }
1224 else
1225 {
1226 iter->get_scanline = dest_get_scanline_wide;
1227 iter->write_back = dest_write_back_wide;
1228 }
1229 }
1230
1231 static uint32_t *
create_bits(pixman_format_code_t format,int width,int height,int * rowstride_bytes,pixman_bool_t clear)1232 create_bits (pixman_format_code_t format,
1233 int width,
1234 int height,
1235 int * rowstride_bytes,
1236 pixman_bool_t clear)
1237 {
1238 int stride;
1239 size_t buf_size;
1240 int bpp;
1241
1242 /* what follows is a long-winded way, avoiding any possibility of integer
1243 * overflows, of saying:
1244 * stride = ((width * bpp + 0x1f) >> 5) * sizeof (uint32_t);
1245 */
1246
1247 bpp = PIXMAN_FORMAT_BPP (format);
1248 if (_pixman_multiply_overflows_int (width, bpp))
1249 return NULL;
1250
1251 stride = width * bpp;
1252 if (_pixman_addition_overflows_int (stride, 0x1f))
1253 return NULL;
1254
1255 stride += 0x1f;
1256 stride >>= 5;
1257
1258 stride *= sizeof (uint32_t);
1259
1260 if (_pixman_multiply_overflows_size (height, stride))
1261 return NULL;
1262
1263 buf_size = (size_t)height * stride;
1264
1265 if (rowstride_bytes)
1266 *rowstride_bytes = stride;
1267
1268 if (clear)
1269 return calloc (buf_size, 1);
1270 else
1271 return malloc (buf_size);
1272 }
1273
1274 pixman_bool_t
_pixman_bits_image_init(pixman_image_t * image,pixman_format_code_t format,int width,int height,uint32_t * bits,int rowstride,pixman_bool_t clear)1275 _pixman_bits_image_init (pixman_image_t * image,
1276 pixman_format_code_t format,
1277 int width,
1278 int height,
1279 uint32_t * bits,
1280 int rowstride,
1281 pixman_bool_t clear)
1282 {
1283 uint32_t *free_me = NULL;
1284
1285 if (PIXMAN_FORMAT_BPP (format) == 128)
1286 return_val_if_fail(!(rowstride % 4), FALSE);
1287
1288 if (!bits && width && height)
1289 {
1290 int rowstride_bytes;
1291
1292 free_me = bits = create_bits (format, width, height, &rowstride_bytes, clear);
1293
1294 if (!bits)
1295 return FALSE;
1296
1297 rowstride = rowstride_bytes / (int) sizeof (uint32_t);
1298 }
1299
1300 _pixman_image_init (image);
1301
1302 image->type = BITS;
1303 image->bits.format = format;
1304 image->bits.width = width;
1305 image->bits.height = height;
1306 image->bits.bits = bits;
1307 image->bits.free_me = free_me;
1308 image->bits.dither = PIXMAN_DITHER_NONE;
1309 image->bits.dither_offset_x = 0;
1310 image->bits.dither_offset_y = 0;
1311 image->bits.read_func = NULL;
1312 image->bits.write_func = NULL;
1313 image->bits.rowstride = rowstride;
1314 image->bits.indexed = NULL;
1315
1316 image->common.property_changed = bits_image_property_changed;
1317
1318 _pixman_image_reset_clip_region (image);
1319
1320 return TRUE;
1321 }
1322
1323 static pixman_image_t *
create_bits_image_internal(pixman_format_code_t format,int width,int height,uint32_t * bits,int rowstride_bytes,pixman_bool_t clear)1324 create_bits_image_internal (pixman_format_code_t format,
1325 int width,
1326 int height,
1327 uint32_t * bits,
1328 int rowstride_bytes,
1329 pixman_bool_t clear)
1330 {
1331 pixman_image_t *image;
1332
1333 /* must be a whole number of uint32_t's
1334 */
1335 return_val_if_fail (
1336 bits == NULL || (rowstride_bytes % sizeof (uint32_t)) == 0, NULL);
1337
1338 return_val_if_fail (PIXMAN_FORMAT_BPP (format) >= PIXMAN_FORMAT_DEPTH (format), NULL);
1339
1340 image = _pixman_image_allocate ();
1341
1342 if (!image)
1343 return NULL;
1344
1345 if (!_pixman_bits_image_init (image, format, width, height, bits,
1346 rowstride_bytes / (int) sizeof (uint32_t),
1347 clear))
1348 {
1349 free (image);
1350 return NULL;
1351 }
1352
1353 return image;
1354 }
1355
1356 /* If bits is NULL, a buffer will be allocated and initialized to 0 */
1357 PIXMAN_EXPORT pixman_image_t *
pixman_image_create_bits(pixman_format_code_t format,int width,int height,uint32_t * bits,int rowstride_bytes)1358 pixman_image_create_bits (pixman_format_code_t format,
1359 int width,
1360 int height,
1361 uint32_t * bits,
1362 int rowstride_bytes)
1363 {
1364 return create_bits_image_internal (
1365 format, width, height, bits, rowstride_bytes, TRUE);
1366 }
1367
1368
1369 /* If bits is NULL, a buffer will be allocated and _not_ initialized */
1370 PIXMAN_EXPORT pixman_image_t *
pixman_image_create_bits_no_clear(pixman_format_code_t format,int width,int height,uint32_t * bits,int rowstride_bytes)1371 pixman_image_create_bits_no_clear (pixman_format_code_t format,
1372 int width,
1373 int height,
1374 uint32_t * bits,
1375 int rowstride_bytes)
1376 {
1377 return create_bits_image_internal (
1378 format, width, height, bits, rowstride_bytes, FALSE);
1379 }
1380