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>
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.
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
35 #include "pixman-private.h"
36 #include "pixman-combine32.h"
37 #include "pixman-inlines.h"
40 _pixman_image_get_scanline_generic_float (pixman_iter_t
* iter
,
43 pixman_iter_get_scanline_t fetch_32
= iter
->data
;
44 uint32_t *buffer
= iter
->buffer
;
46 fetch_32 (iter
, NULL
);
48 pixman_expand_to_float ((argb_t
*)buffer
, buffer
, PIXMAN_a8r8g8b8
, iter
->width
);
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
)
60 (x
< 0 || x
>= image
->width
|| y
< 0 || y
>= image
->height
))
65 return image
->fetch_pixel_32 (image
, x
, y
);
68 typedef uint32_t (* get_pixel_t
) (bits_image_t
*image
,
69 int x
, int y
, pixman_bool_t check_bounds
);
71 static force_inline
uint32_t
72 bits_image_fetch_pixel_nearest (bits_image_t
*image
,
75 get_pixel_t get_pixel
)
77 int x0
= pixman_fixed_to_int (x
- pixman_fixed_e
);
78 int y0
= pixman_fixed_to_int (y
- pixman_fixed_e
);
80 if (image
->common
.repeat
!= PIXMAN_REPEAT_NONE
)
82 repeat (image
->common
.repeat
, &x0
, image
->width
);
83 repeat (image
->common
.repeat
, &y0
, image
->height
);
85 return get_pixel (image
, x0
, y0
, FALSE
);
89 return get_pixel (image
, x0
, y0
, TRUE
);
93 static force_inline
uint32_t
94 bits_image_fetch_pixel_bilinear (bits_image_t
*image
,
97 get_pixel_t get_pixel
)
99 pixman_repeat_t repeat_mode
= image
->common
.repeat
;
100 int width
= image
->width
;
101 int height
= image
->height
;
103 uint32_t tl
, tr
, bl
, br
;
104 int32_t distx
, disty
;
106 x1
= x
- pixman_fixed_1
/ 2;
107 y1
= y
- pixman_fixed_1
/ 2;
109 distx
= pixman_fixed_to_bilinear_weight (x1
);
110 disty
= pixman_fixed_to_bilinear_weight (y1
);
112 x1
= pixman_fixed_to_int (x1
);
113 y1
= pixman_fixed_to_int (y1
);
117 if (repeat_mode
!= PIXMAN_REPEAT_NONE
)
119 repeat (repeat_mode
, &x1
, width
);
120 repeat (repeat_mode
, &y1
, height
);
121 repeat (repeat_mode
, &x2
, width
);
122 repeat (repeat_mode
, &y2
, height
);
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
);
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
);
137 return bilinear_interpolation (tl
, tr
, bl
, br
, distx
, disty
);
140 static force_inline
uint32_t
141 bits_image_fetch_pixel_convolution (bits_image_t
*image
,
144 get_pixel_t get_pixel
)
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
;
159 x1
= pixman_fixed_to_int (x
- pixman_fixed_e
- x_off
);
160 y1
= pixman_fixed_to_int (y
- pixman_fixed_e
- y_off
);
164 srtot
= sgtot
= sbtot
= satot
= 0;
166 for (i
= y1
; i
< y2
; ++i
)
168 for (j
= x1
; j
< x2
; ++j
)
173 pixman_fixed_t f
= *params
;
179 if (repeat_mode
!= PIXMAN_REPEAT_NONE
)
181 repeat (repeat_mode
, &rx
, width
);
182 repeat (repeat_mode
, &ry
, height
);
184 pixel
= get_pixel (image
, rx
, ry
, FALSE
);
188 pixel
= get_pixel (image
, rx
, ry
, TRUE
);
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
;
201 satot
= (satot
+ 0x8000) >> 16;
202 srtot
= (srtot
+ 0x8000) >> 16;
203 sgtot
= (sgtot
+ 0x8000) >> 16;
204 sbtot
= (sbtot
+ 0x8000) >> 16;
206 satot
= CLIP (satot
, 0, 0xff);
207 srtot
= CLIP (srtot
, 0, 0xff);
208 sgtot
= CLIP (sgtot
, 0, 0xff);
209 sbtot
= CLIP (sbtot
, 0, 0xff);
211 return ((satot
<< 24) | (srtot
<< 16) | (sgtot
<< 8) | (sbtot
));
215 bits_image_fetch_pixel_separable_convolution (bits_image_t
*image
,
218 get_pixel_t get_pixel
)
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
;
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).
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);
246 px
= (x
& 0xffff) >> x_phase_shift
;
247 py
= (y
& 0xffff) >> y_phase_shift
;
249 y_params
= params
+ 4 + (1 << x_phase_bits
) * cwidth
+ py
* cheight
;
251 x1
= pixman_fixed_to_int (x
- pixman_fixed_e
- x_off
);
252 y1
= pixman_fixed_to_int (y
- pixman_fixed_e
- y_off
);
256 srtot
= sgtot
= sbtot
= satot
= 0;
258 for (i
= y1
; i
< y2
; ++i
)
260 pixman_fixed_48_16_t fy
= *y_params
++;
261 pixman_fixed_t
*x_params
= params
+ 4 + px
* cwidth
;
265 for (j
= x1
; j
< x2
; ++j
)
267 pixman_fixed_t fx
= *x_params
++;
276 if (repeat_mode
!= PIXMAN_REPEAT_NONE
)
278 repeat (repeat_mode
, &rx
, width
);
279 repeat (repeat_mode
, &ry
, height
);
281 pixel
= get_pixel (image
, rx
, ry
, FALSE
);
285 pixel
= get_pixel (image
, rx
, ry
, TRUE
);
288 f
= (fy
* fx
+ 0x8000) >> 16;
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
;
299 satot
= (satot
+ 0x8000) >> 16;
300 srtot
= (srtot
+ 0x8000) >> 16;
301 sgtot
= (sgtot
+ 0x8000) >> 16;
302 sbtot
= (sbtot
+ 0x8000) >> 16;
304 satot
= CLIP (satot
, 0, 0xff);
305 srtot
= CLIP (srtot
, 0, 0xff);
306 sgtot
= CLIP (sgtot
, 0, 0xff);
307 sbtot
= CLIP (sbtot
, 0, 0xff);
309 return ((satot
<< 24) | (srtot
<< 16) | (sgtot
<< 8) | (sbtot
));
312 static force_inline
uint32_t
313 bits_image_fetch_pixel_filtered (bits_image_t
*image
,
316 get_pixel_t get_pixel
)
318 switch (image
->common
.filter
)
320 case PIXMAN_FILTER_NEAREST
:
321 case PIXMAN_FILTER_FAST
:
322 return bits_image_fetch_pixel_nearest (image
, x
, y
, get_pixel
);
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
);
331 case PIXMAN_FILTER_CONVOLUTION
:
332 return bits_image_fetch_pixel_convolution (image
, x
, y
, get_pixel
);
335 case PIXMAN_FILTER_SEPARABLE_CONVOLUTION
:
336 return bits_image_fetch_pixel_separable_convolution (image
, x
, y
, get_pixel
);
347 bits_image_fetch_affine_no_alpha (pixman_iter_t
* iter
,
348 const uint32_t * mask
)
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
;
357 pixman_fixed_t ux
, uy
;
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
;
366 if (image
->common
.transform
)
368 if (!pixman_transform_point_3d (image
->common
.transform
, &v
))
371 ux
= image
->common
.transform
->matrix
[0][0];
372 uy
= image
->common
.transform
->matrix
[1][0];
383 for (i
= 0; i
< width
; ++i
)
385 if (!mask
|| mask
[i
])
387 buffer
[i
] = bits_image_fetch_pixel_filtered (
388 &image
->bits
, x
, y
, fetch_pixel_no_alpha
);
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
)
405 (x
< 0 || x
>= image
->width
|| y
< 0 || y
>= image
->height
))
410 pixel
= image
->fetch_pixel_32 (image
, x
, y
);
412 if (image
->common
.alpha_map
)
416 x
-= image
->common
.alpha_origin_x
;
417 y
-= image
->common
.alpha_origin_y
;
419 if (x
< 0 || x
>= image
->common
.alpha_map
->width
||
420 y
< 0 || y
>= image
->common
.alpha_map
->height
)
426 pixel_a
= image
->common
.alpha_map
->fetch_pixel_32 (
427 image
->common
.alpha_map
, x
, y
);
429 pixel_a
= ALPHA_8 (pixel_a
);
433 pixel
|= (pixel_a
<< 24);
440 bits_image_fetch_general (pixman_iter_t
*iter
,
441 const uint32_t *mask
)
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
;
449 pixman_fixed_t x
, y
, w
;
450 pixman_fixed_t ux
, uy
, uw
;
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
;
459 if (image
->common
.transform
)
461 if (!pixman_transform_point_3d (image
->common
.transform
, &v
))
464 ux
= image
->common
.transform
->matrix
[0][0];
465 uy
= image
->common
.transform
->matrix
[1][0];
466 uw
= image
->common
.transform
->matrix
[2][0];
479 for (i
= 0; i
< width
; ++i
)
481 pixman_fixed_t x0
, y0
;
483 if (!mask
|| mask
[i
])
487 x0
= ((pixman_fixed_48_16_t
)x
<< 16) / w
;
488 y0
= ((pixman_fixed_48_16_t
)y
<< 16) / w
;
496 buffer
[i
] = bits_image_fetch_pixel_filtered (
497 &image
->bits
, x0
, y0
, fetch_pixel_general
);
509 replicate_pixel_32 (bits_image_t
* bits
,
518 color
= bits
->fetch_pixel_32 (bits
, x
, y
);
520 end
= buffer
+ width
;
526 replicate_pixel_float (bits_image_t
* bits
,
533 argb_t
*buffer
= (argb_t
*)b
;
536 color
= bits
->fetch_pixel_float (bits
, x
, y
);
538 end
= buffer
+ width
;
544 bits_image_fetch_untransformed_repeat_none (bits_image_t
*image
,
553 if (y
< 0 || y
>= image
->height
)
555 memset (buffer
, 0, width
* (wide
? sizeof (argb_t
) : 4));
563 memset (buffer
, 0, w
* (wide
? sizeof (argb_t
) : 4));
566 buffer
+= w
* (wide
? 4 : 1);
570 if (x
< image
->width
)
572 w
= MIN (width
, image
->width
- x
);
575 image
->fetch_scanline_float (image
, x
, y
, w
, buffer
, NULL
);
577 image
->fetch_scanline_32 (image
, x
, y
, w
, buffer
, NULL
);
580 buffer
+= w
* (wide
? 4 : 1);
584 memset (buffer
, 0, width
* (wide
? sizeof (argb_t
) : 4));
588 bits_image_fetch_untransformed_repeat_normal (bits_image_t
*image
,
600 while (y
>= image
->height
)
603 if (image
->width
== 1)
606 replicate_pixel_float (image
, 0, y
, width
, buffer
);
608 replicate_pixel_32 (image
, 0, y
, width
, buffer
);
617 while (x
>= image
->width
)
620 w
= MIN (width
, image
->width
- x
);
623 image
->fetch_scanline_float (image
, x
, y
, w
, buffer
, NULL
);
625 image
->fetch_scanline_32 (image
, x
, y
, w
, buffer
, NULL
);
627 buffer
+= w
* (wide
? 4 : 1);
634 bits_image_fetch_untransformed_32 (pixman_iter_t
* iter
,
635 const uint32_t *mask
)
637 pixman_image_t
*image
= iter
->image
;
640 int width
= iter
->width
;
641 uint32_t * buffer
= iter
->buffer
;
643 if (image
->common
.repeat
== PIXMAN_REPEAT_NONE
)
645 bits_image_fetch_untransformed_repeat_none (
646 &image
->bits
, FALSE
, x
, y
, width
, buffer
);
650 bits_image_fetch_untransformed_repeat_normal (
651 &image
->bits
, FALSE
, x
, y
, width
, buffer
);
659 bits_image_fetch_untransformed_float (pixman_iter_t
* iter
,
660 const uint32_t *mask
)
662 pixman_image_t
*image
= iter
->image
;
665 int width
= iter
->width
;
666 uint32_t * buffer
= iter
->buffer
;
668 if (image
->common
.repeat
== PIXMAN_REPEAT_NONE
)
670 bits_image_fetch_untransformed_repeat_none (
671 &image
->bits
, TRUE
, x
, y
, width
, buffer
);
675 bits_image_fetch_untransformed_repeat_normal (
676 &image
->bits
, TRUE
, x
, y
, width
, buffer
);
685 pixman_format_code_t format
;
687 pixman_iter_get_scanline_t get_scanline_32
;
688 pixman_iter_get_scanline_t get_scanline_float
;
691 static const fetcher_info_t fetcher_info
[] =
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
703 /* Affine, no alpha */
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
713 bits_image_fetch_general
,
714 _pixman_image_get_scanline_generic_float
721 bits_image_property_changed (pixman_image_t
*image
)
723 _pixman_bits_image_setup_accessors (&image
->bits
);
727 _pixman_bits_image_src_iter_init (pixman_image_t
*image
, pixman_iter_t
*iter
)
729 pixman_format_code_t format
= image
->common
.extended_format_code
;
730 uint32_t flags
= image
->common
.flags
;
731 const fetcher_info_t
*info
;
733 for (info
= fetcher_info
; info
->format
!= PIXMAN_null
; ++info
)
735 if ((info
->format
== format
|| info
->format
== PIXMAN_any
) &&
736 (info
->flags
& flags
) == info
->flags
)
738 if (iter
->iter_flags
& ITER_NARROW
)
740 iter
->get_scanline
= info
->get_scanline_32
;
744 iter
->data
= info
->get_scanline_32
;
745 iter
->get_scanline
= info
->get_scanline_float
;
751 /* Just in case we somehow didn't find a scanline function */
752 iter
->get_scanline
= _pixman_iter_get_scanline_noop
;
756 dest_get_scanline_narrow (pixman_iter_t
*iter
, const uint32_t *mask
)
758 pixman_image_t
*image
= iter
->image
;
761 int width
= iter
->width
;
762 uint32_t * buffer
= iter
->buffer
;
764 image
->bits
.fetch_scanline_32 (&image
->bits
, x
, y
, width
, buffer
, mask
);
765 if (image
->common
.alpha_map
)
769 if ((alpha
= malloc (width
* sizeof (uint32_t))))
773 x
-= image
->common
.alpha_origin_x
;
774 y
-= image
->common
.alpha_origin_y
;
776 image
->common
.alpha_map
->fetch_scanline_32 (
777 image
->common
.alpha_map
, x
, y
, width
, alpha
, mask
);
779 for (i
= 0; i
< width
; ++i
)
781 buffer
[i
] &= ~0xff000000;
782 buffer
[i
] |= (alpha
[i
] & 0xff000000);
793 dest_get_scanline_wide (pixman_iter_t
*iter
, const uint32_t *mask
)
795 bits_image_t
* image
= &iter
->image
->bits
;
798 int width
= iter
->width
;
799 argb_t
* buffer
= (argb_t
*)iter
->buffer
;
801 image
->fetch_scanline_float (
802 image
, x
, y
, width
, (uint32_t *)buffer
, mask
);
803 if (image
->common
.alpha_map
)
807 if ((alpha
= malloc (width
* sizeof (argb_t
))))
811 x
-= image
->common
.alpha_origin_x
;
812 y
-= image
->common
.alpha_origin_y
;
814 image
->common
.alpha_map
->fetch_scanline_float (
815 image
->common
.alpha_map
, x
, y
, width
, (uint32_t *)alpha
, mask
);
817 for (i
= 0; i
< width
; ++i
)
818 buffer
[i
].a
= alpha
[i
].a
;
828 dest_write_back_narrow (pixman_iter_t
*iter
)
830 bits_image_t
* image
= &iter
->image
->bits
;
833 int width
= iter
->width
;
834 const uint32_t *buffer
= iter
->buffer
;
836 image
->store_scanline_32 (image
, x
, y
, width
, buffer
);
838 if (image
->common
.alpha_map
)
840 x
-= image
->common
.alpha_origin_x
;
841 y
-= image
->common
.alpha_origin_y
;
843 image
->common
.alpha_map
->store_scanline_32 (
844 image
->common
.alpha_map
, x
, y
, width
, buffer
);
851 dest_write_back_wide (pixman_iter_t
*iter
)
853 bits_image_t
* image
= &iter
->image
->bits
;
856 int width
= iter
->width
;
857 const uint32_t *buffer
= iter
->buffer
;
859 image
->store_scanline_float (image
, x
, y
, width
, buffer
);
861 if (image
->common
.alpha_map
)
863 x
-= image
->common
.alpha_origin_x
;
864 y
-= image
->common
.alpha_origin_y
;
866 image
->common
.alpha_map
->store_scanline_float (
867 image
->common
.alpha_map
, x
, y
, width
, buffer
);
874 _pixman_bits_image_dest_iter_init (pixman_image_t
*image
, pixman_iter_t
*iter
)
876 if (iter
->iter_flags
& ITER_NARROW
)
878 if ((iter
->iter_flags
& (ITER_IGNORE_RGB
| ITER_IGNORE_ALPHA
)) ==
879 (ITER_IGNORE_RGB
| ITER_IGNORE_ALPHA
))
881 iter
->get_scanline
= _pixman_iter_get_scanline_noop
;
885 iter
->get_scanline
= dest_get_scanline_narrow
;
888 iter
->write_back
= dest_write_back_narrow
;
892 iter
->get_scanline
= dest_get_scanline_wide
;
893 iter
->write_back
= dest_write_back_wide
;
898 create_bits (pixman_format_code_t format
,
901 int * rowstride_bytes
,
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);
913 bpp
= PIXMAN_FORMAT_BPP (format
);
914 if (_pixman_multiply_overflows_int (width
, bpp
))
917 stride
= width
* bpp
;
918 if (_pixman_addition_overflows_int (stride
, 0x1f))
924 stride
*= sizeof (uint32_t);
926 if (_pixman_multiply_overflows_size (height
, stride
))
929 buf_size
= (size_t)height
* stride
;
932 *rowstride_bytes
= stride
;
935 return calloc (buf_size
, 1);
937 return malloc (buf_size
);
941 _pixman_bits_image_init (pixman_image_t
* image
,
942 pixman_format_code_t format
,
949 uint32_t *free_me
= NULL
;
951 if (!bits
&& width
&& height
)
955 free_me
= bits
= create_bits (format
, width
, height
, &rowstride_bytes
, clear
);
960 rowstride
= rowstride_bytes
/ (int) sizeof (uint32_t);
963 _pixman_image_init (image
);
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
;
976 image
->common
.property_changed
= bits_image_property_changed
;
978 _pixman_image_reset_clip_region (image
);
983 static pixman_image_t
*
984 create_bits_image_internal (pixman_format_code_t format
,
991 pixman_image_t
*image
;
993 /* must be a whole number of uint32_t's
996 bits
== NULL
|| (rowstride_bytes
% sizeof (uint32_t)) == 0, NULL
);
998 return_val_if_fail (PIXMAN_FORMAT_BPP (format
) >= PIXMAN_FORMAT_DEPTH (format
), NULL
);
1000 image
= _pixman_image_allocate ();
1005 if (!_pixman_bits_image_init (image
, format
, width
, height
, bits
,
1006 rowstride_bytes
/ (int) sizeof (uint32_t),
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
,
1022 int rowstride_bytes
)
1024 return create_bits_image_internal (
1025 format
, width
, height
, bits
, rowstride_bytes
, TRUE
);
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
,
1035 int rowstride_bytes
)
1037 return create_bits_image_internal (
1038 format
, width
, height
, bits
, rowstride_bytes
, FALSE
);