1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/cairo/libpixman/src/pixman-utils.c Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,315 @@ 1.4 +/* 1.5 + * Copyright © 2000 SuSE, Inc. 1.6 + * Copyright © 1999 Keith Packard 1.7 + * 1.8 + * Permission to use, copy, modify, distribute, and sell this software and its 1.9 + * documentation for any purpose is hereby granted without fee, provided that 1.10 + * the above copyright notice appear in all copies and that both that 1.11 + * copyright notice and this permission notice appear in supporting 1.12 + * documentation, and that the name of SuSE not be used in advertising or 1.13 + * publicity pertaining to distribution of the software without specific, 1.14 + * written prior permission. SuSE makes no representations about the 1.15 + * suitability of this software for any purpose. It is provided "as is" 1.16 + * without express or implied warranty. 1.17 + * 1.18 + * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL 1.19 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE 1.20 + * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 1.21 + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION 1.22 + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 1.23 + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 1.24 + * 1.25 + * Author: Keith Packard, SuSE, Inc. 1.26 + */ 1.27 + 1.28 +#ifdef HAVE_CONFIG_H 1.29 +#include <config.h> 1.30 +#endif 1.31 +#include <stdio.h> 1.32 +#include <stdlib.h> 1.33 +#include <limits.h> 1.34 + 1.35 +#include "pixman-private.h" 1.36 + 1.37 +pixman_bool_t 1.38 +_pixman_multiply_overflows_size (size_t a, size_t b) 1.39 +{ 1.40 + return a >= SIZE_MAX / b; 1.41 +} 1.42 + 1.43 +pixman_bool_t 1.44 +_pixman_multiply_overflows_int (unsigned int a, unsigned int b) 1.45 +{ 1.46 + return a >= INT32_MAX / b; 1.47 +} 1.48 + 1.49 +pixman_bool_t 1.50 +_pixman_addition_overflows_int (unsigned int a, unsigned int b) 1.51 +{ 1.52 + return a > INT32_MAX - b; 1.53 +} 1.54 + 1.55 +void * 1.56 +pixman_malloc_ab (unsigned int a, 1.57 + unsigned int b) 1.58 +{ 1.59 + if (a >= INT32_MAX / b) 1.60 + return NULL; 1.61 + 1.62 + return malloc (a * b); 1.63 +} 1.64 + 1.65 +void * 1.66 +pixman_malloc_abc (unsigned int a, 1.67 + unsigned int b, 1.68 + unsigned int c) 1.69 +{ 1.70 + if (a >= INT32_MAX / b) 1.71 + return NULL; 1.72 + else if (a * b >= INT32_MAX / c) 1.73 + return NULL; 1.74 + else 1.75 + return malloc (a * b * c); 1.76 +} 1.77 + 1.78 +static force_inline uint16_t 1.79 +float_to_unorm (float f, int n_bits) 1.80 +{ 1.81 + uint32_t u; 1.82 + 1.83 + if (f > 1.0) 1.84 + f = 1.0; 1.85 + if (f < 0.0) 1.86 + f = 0.0; 1.87 + 1.88 + u = f * (1 << n_bits); 1.89 + u -= (u >> n_bits); 1.90 + 1.91 + return u; 1.92 +} 1.93 + 1.94 +static force_inline float 1.95 +unorm_to_float (uint16_t u, int n_bits) 1.96 +{ 1.97 + uint32_t m = ((1 << n_bits) - 1); 1.98 + 1.99 + return (u & m) * (1.f / (float)m); 1.100 +} 1.101 + 1.102 +/* 1.103 + * This function expands images from a8r8g8b8 to argb_t. To preserve 1.104 + * precision, it needs to know from which source format the a8r8g8b8 pixels 1.105 + * originally came. 1.106 + * 1.107 + * For example, if the source was PIXMAN_x1r5g5b5 and the red component 1.108 + * contained bits 12345, then the 8-bit value is 12345123. To correctly 1.109 + * expand this to floating point, it should be 12345 / 31.0 and not 1.110 + * 12345123 / 255.0. 1.111 + */ 1.112 +void 1.113 +pixman_expand_to_float (argb_t *dst, 1.114 + const uint32_t *src, 1.115 + pixman_format_code_t format, 1.116 + int width) 1.117 +{ 1.118 + static const float multipliers[16] = { 1.119 + 0.0f, 1.120 + 1.0f / ((1 << 1) - 1), 1.121 + 1.0f / ((1 << 2) - 1), 1.122 + 1.0f / ((1 << 3) - 1), 1.123 + 1.0f / ((1 << 4) - 1), 1.124 + 1.0f / ((1 << 5) - 1), 1.125 + 1.0f / ((1 << 6) - 1), 1.126 + 1.0f / ((1 << 7) - 1), 1.127 + 1.0f / ((1 << 8) - 1), 1.128 + 1.0f / ((1 << 9) - 1), 1.129 + 1.0f / ((1 << 10) - 1), 1.130 + 1.0f / ((1 << 11) - 1), 1.131 + 1.0f / ((1 << 12) - 1), 1.132 + 1.0f / ((1 << 13) - 1), 1.133 + 1.0f / ((1 << 14) - 1), 1.134 + 1.0f / ((1 << 15) - 1), 1.135 + }; 1.136 + int a_size, r_size, g_size, b_size; 1.137 + int a_shift, r_shift, g_shift, b_shift; 1.138 + float a_mul, r_mul, g_mul, b_mul; 1.139 + uint32_t a_mask, r_mask, g_mask, b_mask; 1.140 + int i; 1.141 + 1.142 + if (!PIXMAN_FORMAT_VIS (format)) 1.143 + format = PIXMAN_a8r8g8b8; 1.144 + 1.145 + /* 1.146 + * Determine the sizes of each component and the masks and shifts 1.147 + * required to extract them from the source pixel. 1.148 + */ 1.149 + a_size = PIXMAN_FORMAT_A (format); 1.150 + r_size = PIXMAN_FORMAT_R (format); 1.151 + g_size = PIXMAN_FORMAT_G (format); 1.152 + b_size = PIXMAN_FORMAT_B (format); 1.153 + 1.154 + a_shift = 32 - a_size; 1.155 + r_shift = 24 - r_size; 1.156 + g_shift = 16 - g_size; 1.157 + b_shift = 8 - b_size; 1.158 + 1.159 + a_mask = ((1 << a_size) - 1); 1.160 + r_mask = ((1 << r_size) - 1); 1.161 + g_mask = ((1 << g_size) - 1); 1.162 + b_mask = ((1 << b_size) - 1); 1.163 + 1.164 + a_mul = multipliers[a_size]; 1.165 + r_mul = multipliers[r_size]; 1.166 + g_mul = multipliers[g_size]; 1.167 + b_mul = multipliers[b_size]; 1.168 + 1.169 + /* Start at the end so that we can do the expansion in place 1.170 + * when src == dst 1.171 + */ 1.172 + for (i = width - 1; i >= 0; i--) 1.173 + { 1.174 + const uint32_t pixel = src[i]; 1.175 + 1.176 + dst[i].a = a_mask? ((pixel >> a_shift) & a_mask) * a_mul : 1.0f; 1.177 + dst[i].r = ((pixel >> r_shift) & r_mask) * r_mul; 1.178 + dst[i].g = ((pixel >> g_shift) & g_mask) * g_mul; 1.179 + dst[i].b = ((pixel >> b_shift) & b_mask) * b_mul; 1.180 + } 1.181 +} 1.182 + 1.183 +uint16_t 1.184 +pixman_float_to_unorm (float f, int n_bits) 1.185 +{ 1.186 + return float_to_unorm (f, n_bits); 1.187 +} 1.188 + 1.189 +float 1.190 +pixman_unorm_to_float (uint16_t u, int n_bits) 1.191 +{ 1.192 + return unorm_to_float (u, n_bits); 1.193 +} 1.194 + 1.195 +void 1.196 +pixman_contract_from_float (uint32_t *dst, 1.197 + const argb_t *src, 1.198 + int width) 1.199 +{ 1.200 + int i; 1.201 + 1.202 + for (i = 0; i < width; ++i) 1.203 + { 1.204 + uint8_t a, r, g, b; 1.205 + 1.206 + a = float_to_unorm (src[i].a, 8); 1.207 + r = float_to_unorm (src[i].r, 8); 1.208 + g = float_to_unorm (src[i].g, 8); 1.209 + b = float_to_unorm (src[i].b, 8); 1.210 + 1.211 + dst[i] = (a << 24) | (r << 16) | (g << 8) | (b << 0); 1.212 + } 1.213 +} 1.214 + 1.215 +uint32_t * 1.216 +_pixman_iter_get_scanline_noop (pixman_iter_t *iter, const uint32_t *mask) 1.217 +{ 1.218 + return iter->buffer; 1.219 +} 1.220 + 1.221 +#define N_TMP_BOXES (16) 1.222 + 1.223 +pixman_bool_t 1.224 +pixman_region16_copy_from_region32 (pixman_region16_t *dst, 1.225 + pixman_region32_t *src) 1.226 +{ 1.227 + int n_boxes, i; 1.228 + pixman_box32_t *boxes32; 1.229 + pixman_box16_t *boxes16; 1.230 + pixman_bool_t retval; 1.231 + 1.232 + boxes32 = pixman_region32_rectangles (src, &n_boxes); 1.233 + 1.234 + boxes16 = pixman_malloc_ab (n_boxes, sizeof (pixman_box16_t)); 1.235 + 1.236 + if (!boxes16) 1.237 + return FALSE; 1.238 + 1.239 + for (i = 0; i < n_boxes; ++i) 1.240 + { 1.241 + boxes16[i].x1 = boxes32[i].x1; 1.242 + boxes16[i].y1 = boxes32[i].y1; 1.243 + boxes16[i].x2 = boxes32[i].x2; 1.244 + boxes16[i].y2 = boxes32[i].y2; 1.245 + } 1.246 + 1.247 + pixman_region_fini (dst); 1.248 + retval = pixman_region_init_rects (dst, boxes16, n_boxes); 1.249 + free (boxes16); 1.250 + return retval; 1.251 +} 1.252 + 1.253 +pixman_bool_t 1.254 +pixman_region32_copy_from_region16 (pixman_region32_t *dst, 1.255 + pixman_region16_t *src) 1.256 +{ 1.257 + int n_boxes, i; 1.258 + pixman_box16_t *boxes16; 1.259 + pixman_box32_t *boxes32; 1.260 + pixman_box32_t tmp_boxes[N_TMP_BOXES]; 1.261 + pixman_bool_t retval; 1.262 + 1.263 + boxes16 = pixman_region_rectangles (src, &n_boxes); 1.264 + 1.265 + if (n_boxes > N_TMP_BOXES) 1.266 + boxes32 = pixman_malloc_ab (n_boxes, sizeof (pixman_box32_t)); 1.267 + else 1.268 + boxes32 = tmp_boxes; 1.269 + 1.270 + if (!boxes32) 1.271 + return FALSE; 1.272 + 1.273 + for (i = 0; i < n_boxes; ++i) 1.274 + { 1.275 + boxes32[i].x1 = boxes16[i].x1; 1.276 + boxes32[i].y1 = boxes16[i].y1; 1.277 + boxes32[i].x2 = boxes16[i].x2; 1.278 + boxes32[i].y2 = boxes16[i].y2; 1.279 + } 1.280 + 1.281 + pixman_region32_fini (dst); 1.282 + retval = pixman_region32_init_rects (dst, boxes32, n_boxes); 1.283 + 1.284 + if (boxes32 != tmp_boxes) 1.285 + free (boxes32); 1.286 + 1.287 + return retval; 1.288 +} 1.289 + 1.290 +/* This function is exported for the sake of the test suite and not part 1.291 + * of the ABI. 1.292 + */ 1.293 +PIXMAN_EXPORT pixman_implementation_t * 1.294 +_pixman_internal_only_get_implementation (void) 1.295 +{ 1.296 + return get_implementation (); 1.297 +} 1.298 + 1.299 +#ifdef DEBUG 1.300 + 1.301 +void 1.302 +_pixman_log_error (const char *function, const char *message) 1.303 +{ 1.304 + static int n_messages = 0; 1.305 + 1.306 + if (n_messages < 10) 1.307 + { 1.308 + fprintf (stderr, 1.309 + "*** BUG ***\n" 1.310 + "In %s: %s\n" 1.311 + "Set a breakpoint on '_pixman_log_error' to debug\n\n", 1.312 + function, message); 1.313 + 1.314 + n_messages++; 1.315 + } 1.316 +} 1.317 + 1.318 +#endif