2 * Copyright © 2000 SuSE, Inc.
3 * Copyright © 1999 Keith Packard
5 * Permission to use, copy, modify, distribute, and sell this software and its
6 * documentation for any purpose is hereby granted without fee, provided that
7 * the above copyright notice appear in all copies and that both that
8 * copyright notice and this permission notice appear in supporting
9 * documentation, and that the name of SuSE not be used in advertising or
10 * publicity pertaining to distribution of the software without specific,
11 * written prior permission. SuSE makes no representations about the
12 * suitability of this software for any purpose. It is provided "as is"
13 * without express or implied warranty.
15 * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
17 * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
18 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
19 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
20 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22 * Author: Keith Packard, SuSE, Inc.
31 #include "pixman-private.h"
34 _pixman_multiply_overflows_size (size_t a, size_t b)
36 return a >= SIZE_MAX / b;
40 _pixman_multiply_overflows_int (unsigned int a, unsigned int b)
42 return a >= INT32_MAX / b;
46 _pixman_addition_overflows_int (unsigned int a, unsigned int b)
48 return a > INT32_MAX - b;
52 pixman_malloc_ab (unsigned int a,
55 if (a >= INT32_MAX / b)
58 return malloc (a * b);
62 pixman_malloc_abc (unsigned int a,
66 if (a >= INT32_MAX / b)
68 else if (a * b >= INT32_MAX / c)
71 return malloc (a * b * c);
75 * This function expands images from ARGB8 format to ARGB16. To preserve
76 * precision, it needs to know the original source format. For example, if the
77 * source was PIXMAN_x1r5g5b5 and the red component contained bits 12345, then
78 * the expanded value is 12345123. To correctly expand this to 16 bits, it
79 * should be 1234512345123451 and not 1234512312345123.
82 pixman_expand (uint64_t * dst,
84 pixman_format_code_t format,
88 * Determine the sizes of each component and the masks and shifts
89 * required to extract them from the source pixel.
91 const int a_size = PIXMAN_FORMAT_A (format),
92 r_size = PIXMAN_FORMAT_R (format),
93 g_size = PIXMAN_FORMAT_G (format),
94 b_size = PIXMAN_FORMAT_B (format);
95 const int a_shift = 32 - a_size,
96 r_shift = 24 - r_size,
97 g_shift = 16 - g_size,
99 const uint8_t a_mask = ~(~0 << a_size),
100 r_mask = ~(~0 << r_size),
101 g_mask = ~(~0 << g_size),
102 b_mask = ~(~0 << b_size);
105 /* Start at the end so that we can do the expansion in place
108 for (i = width - 1; i >= 0; i--)
110 const uint32_t pixel = src[i];
111 const uint8_t a = (pixel >> a_shift) & a_mask,
112 r = (pixel >> r_shift) & r_mask,
113 g = (pixel >> g_shift) & g_mask,
114 b = (pixel >> b_shift) & b_mask;
116 a16 = a_size ? unorm_to_unorm (a, a_size, 16) : 0xffff,
117 r16 = unorm_to_unorm (r, r_size, 16),
118 g16 = unorm_to_unorm (g, g_size, 16),
119 b16 = unorm_to_unorm (b, b_size, 16);
121 dst[i] = a16 << 48 | r16 << 32 | g16 << 16 | b16;
126 * Contracting is easier than expanding. We just need to truncate the
130 pixman_contract (uint32_t * dst,
136 /* Start at the beginning so that we can do the contraction in
137 * place when src == dst
139 for (i = 0; i < width; i++)
141 const uint8_t a = src[i] >> 56,
146 dst[i] = a << 24 | r << 16 | g << 8 | b;
151 _pixman_iter_get_scanline_noop (pixman_iter_t *iter, const uint32_t *mask)
156 #define N_TMP_BOXES (16)
159 pixman_region16_copy_from_region32 (pixman_region16_t *dst,
160 pixman_region32_t *src)
163 pixman_box32_t *boxes32;
164 pixman_box16_t *boxes16;
165 pixman_bool_t retval;
167 boxes32 = pixman_region32_rectangles (src, &n_boxes);
169 boxes16 = pixman_malloc_ab (n_boxes, sizeof (pixman_box16_t));
174 for (i = 0; i < n_boxes; ++i)
176 boxes16[i].x1 = boxes32[i].x1;
177 boxes16[i].y1 = boxes32[i].y1;
178 boxes16[i].x2 = boxes32[i].x2;
179 boxes16[i].y2 = boxes32[i].y2;
182 pixman_region_fini (dst);
183 retval = pixman_region_init_rects (dst, boxes16, n_boxes);
189 pixman_region32_copy_from_region16 (pixman_region32_t *dst,
190 pixman_region16_t *src)
193 pixman_box16_t *boxes16;
194 pixman_box32_t *boxes32;
195 pixman_box32_t tmp_boxes[N_TMP_BOXES];
196 pixman_bool_t retval;
198 boxes16 = pixman_region_rectangles (src, &n_boxes);
200 if (n_boxes > N_TMP_BOXES)
201 boxes32 = pixman_malloc_ab (n_boxes, sizeof (pixman_box32_t));
208 for (i = 0; i < n_boxes; ++i)
210 boxes32[i].x1 = boxes16[i].x1;
211 boxes32[i].y1 = boxes16[i].y1;
212 boxes32[i].x2 = boxes16[i].x2;
213 boxes32[i].y2 = boxes16[i].y2;
216 pixman_region32_fini (dst);
217 retval = pixman_region32_init_rects (dst, boxes32, n_boxes);
219 if (boxes32 != tmp_boxes)
228 _pixman_log_error (const char *function, const char *message)
230 static int n_messages = 0;
237 "Set a breakpoint on '_pixman_log_error' to debug\n\n",