• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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