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_int (unsigned int a,
37 return a >= INT32_MAX / b;
41 pixman_addition_overflows_int (unsigned int a,
44 return a > INT32_MAX - b;
48 pixman_malloc_ab (unsigned int a,
51 if (a >= INT32_MAX / b)
54 return malloc (a * b);
58 pixman_malloc_abc (unsigned int a,
62 if (a >= INT32_MAX / b)
64 else if (a * b >= INT32_MAX / c)
67 return malloc (a * b * c);
71 * Helper routine to expand a color component from 0 < n <= 8 bits to 16
72 * bits by replication.
74 static inline uint64_t
75 expand16 (const uint8_t val, int nbits)
77 /* Start out with the high bit of val in the high bit of result. */
78 uint16_t result = (uint16_t)val << (16 - nbits);
83 /* Copy the bits in result, doubling the number of bits each time, until
84 * we fill all 16 bits.
88 result |= result >> nbits;
96 * This function expands images from ARGB8 format to ARGB16. To preserve
97 * precision, it needs to know the original source format. For example, if the
98 * source was PIXMAN_x1r5g5b5 and the red component contained bits 12345, then
99 * the expanded value is 12345123. To correctly expand this to 16 bits, it
100 * should be 1234512345123451 and not 1234512312345123.
103 pixman_expand (uint64_t * dst,
104 const uint32_t * src,
105 pixman_format_code_t format,
109 * Determine the sizes of each component and the masks and shifts
110 * required to extract them from the source pixel.
112 const int a_size = PIXMAN_FORMAT_A (format),
113 r_size = PIXMAN_FORMAT_R (format),
114 g_size = PIXMAN_FORMAT_G (format),
115 b_size = PIXMAN_FORMAT_B (format);
116 const int a_shift = 32 - a_size,
117 r_shift = 24 - r_size,
118 g_shift = 16 - g_size,
119 b_shift = 8 - b_size;
120 const uint8_t a_mask = ~(~0 << a_size),
121 r_mask = ~(~0 << r_size),
122 g_mask = ~(~0 << g_size),
123 b_mask = ~(~0 << b_size);
126 /* Start at the end so that we can do the expansion in place
129 for (i = width - 1; i >= 0; i--)
131 const uint32_t pixel = src[i];
132 const uint8_t a = (pixel >> a_shift) & a_mask,
133 r = (pixel >> r_shift) & r_mask,
134 g = (pixel >> g_shift) & g_mask,
135 b = (pixel >> b_shift) & b_mask;
136 const uint64_t a16 = a_size ? expand16 (a, a_size) : 0xffff,
137 r16 = expand16 (r, r_size),
138 g16 = expand16 (g, g_size),
139 b16 = expand16 (b, b_size);
141 dst[i] = a16 << 48 | r16 << 32 | g16 << 16 | b16;
146 * Contracting is easier than expanding. We just need to truncate the
150 pixman_contract (uint32_t * dst,
156 /* Start at the beginning so that we can do the contraction in
157 * place when src == dst
159 for (i = 0; i < width; i++)
161 const uint8_t a = src[i] >> 56,
166 dst[i] = a << 24 | r << 16 | g << 8 | b;
171 _pixman_iter_get_scanline_noop (pixman_iter_t *iter, const uint32_t *mask)
176 #define N_TMP_BOXES (16)
179 pixman_region16_copy_from_region32 (pixman_region16_t *dst,
180 pixman_region32_t *src)
183 pixman_box32_t *boxes32;
184 pixman_box16_t *boxes16;
185 pixman_bool_t retval;
187 boxes32 = pixman_region32_rectangles (src, &n_boxes);
189 boxes16 = pixman_malloc_ab (n_boxes, sizeof (pixman_box16_t));
194 for (i = 0; i < n_boxes; ++i)
196 boxes16[i].x1 = boxes32[i].x1;
197 boxes16[i].y1 = boxes32[i].y1;
198 boxes16[i].x2 = boxes32[i].x2;
199 boxes16[i].y2 = boxes32[i].y2;
202 pixman_region_fini (dst);
203 retval = pixman_region_init_rects (dst, boxes16, n_boxes);
209 pixman_region32_copy_from_region16 (pixman_region32_t *dst,
210 pixman_region16_t *src)
213 pixman_box16_t *boxes16;
214 pixman_box32_t *boxes32;
215 pixman_box32_t tmp_boxes[N_TMP_BOXES];
216 pixman_bool_t retval;
218 boxes16 = pixman_region_rectangles (src, &n_boxes);
220 if (n_boxes > N_TMP_BOXES)
221 boxes32 = pixman_malloc_ab (n_boxes, sizeof (pixman_box32_t));
228 for (i = 0; i < n_boxes; ++i)
230 boxes32[i].x1 = boxes16[i].x1;
231 boxes32[i].y1 = boxes16[i].y1;
232 boxes32[i].x2 = boxes16[i].x2;
233 boxes32[i].y2 = boxes16[i].y2;
236 pixman_region32_fini (dst);
237 retval = pixman_region32_init_rects (dst, boxes32, n_boxes);
239 if (boxes32 != tmp_boxes)
248 _pixman_log_error (const char *function, const char *message)
250 static int n_messages = 0;
257 "Set a breakpoint on '_pixman_log_error' to debug\n\n",