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