LCOV - code coverage report
Current view: top level - gfx/cairo/libpixman/src - pixman-utils.c (source / functions) Hit Total Coverage
Test: output.info Lines: 0 98 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 13 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  * Copyright © 2000 SuSE, Inc.
       3             :  * Copyright © 1999 Keith Packard
       4             :  *
       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.
      14             :  *
      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.
      21             :  *
      22             :  * Author:  Keith Packard, SuSE, Inc.
      23             :  */
      24             : 
      25             : #ifdef HAVE_CONFIG_H
      26             : #include <config.h>
      27             : #endif
      28             : #include <stdio.h>
      29             : #include <stdlib.h>
      30             : #include <limits.h>
      31             : 
      32             : #include "pixman-private.h"
      33             : 
      34             : pixman_bool_t
      35           0 : _pixman_multiply_overflows_size (size_t a, size_t b)
      36             : {
      37           0 :     return a >= SIZE_MAX / b;
      38             : }
      39             : 
      40             : pixman_bool_t
      41           0 : _pixman_multiply_overflows_int (unsigned int a, unsigned int b)
      42             : {
      43           0 :     return a >= INT32_MAX / b;
      44             : }
      45             : 
      46             : pixman_bool_t
      47           0 : _pixman_addition_overflows_int (unsigned int a, unsigned int b)
      48             : {
      49           0 :     return a > INT32_MAX - b;
      50             : }
      51             : 
      52             : void *
      53           0 : pixman_malloc_ab (unsigned int a,
      54             :                   unsigned int b)
      55             : {
      56           0 :     if (a >= INT32_MAX / b)
      57           0 :         return NULL;
      58             : 
      59           0 :     return malloc (a * b);
      60             : }
      61             : 
      62             : void *
      63           0 : pixman_malloc_abc (unsigned int a,
      64             :                    unsigned int b,
      65             :                    unsigned int c)
      66             : {
      67           0 :     if (a >= INT32_MAX / b)
      68           0 :         return NULL;
      69           0 :     else if (a * b >= INT32_MAX / c)
      70           0 :         return NULL;
      71             :     else
      72           0 :         return malloc (a * b * c);
      73             : }
      74             : 
      75             : static force_inline uint16_t
      76             : float_to_unorm (float f, int n_bits)
      77             : {
      78             :     uint32_t u;
      79             : 
      80           0 :     if (f > 1.0)
      81           0 :         f = 1.0;
      82           0 :     if (f < 0.0)
      83           0 :         f = 0.0;
      84             : 
      85           0 :     u = f * (1 << n_bits);
      86           0 :     u -= (u >> n_bits);
      87             : 
      88           0 :     return u;
      89             : }
      90             : 
      91             : static force_inline float
      92             : unorm_to_float (uint16_t u, int n_bits)
      93             : {
      94           0 :     uint32_t m = ((1 << n_bits) - 1);
      95             : 
      96           0 :     return (u & m) * (1.f / (float)m);
      97             : }
      98             : 
      99             : /*
     100             :  * This function expands images from a8r8g8b8 to argb_t.  To preserve
     101             :  * precision, it needs to know from which source format the a8r8g8b8 pixels
     102             :  * originally came.
     103             :  *
     104             :  * For example, if the source was PIXMAN_x1r5g5b5 and the red component
     105             :  * contained bits 12345, then the 8-bit value is 12345123.  To correctly
     106             :  * expand this to floating point, it should be 12345 / 31.0 and not
     107             :  * 12345123 / 255.0.
     108             :  */
     109             : void
     110           0 : pixman_expand_to_float (argb_t               *dst,
     111             :                         const uint32_t       *src,
     112             :                         pixman_format_code_t  format,
     113             :                         int                   width)
     114             : {
     115             :     static const float multipliers[16] = {
     116             :         0.0f,
     117             :         1.0f / ((1 <<  1) - 1),
     118             :         1.0f / ((1 <<  2) - 1),
     119             :         1.0f / ((1 <<  3) - 1),
     120             :         1.0f / ((1 <<  4) - 1),
     121             :         1.0f / ((1 <<  5) - 1),
     122             :         1.0f / ((1 <<  6) - 1),
     123             :         1.0f / ((1 <<  7) - 1),
     124             :         1.0f / ((1 <<  8) - 1),
     125             :         1.0f / ((1 <<  9) - 1),
     126             :         1.0f / ((1 << 10) - 1),
     127             :         1.0f / ((1 << 11) - 1),
     128             :         1.0f / ((1 << 12) - 1),
     129             :         1.0f / ((1 << 13) - 1),
     130             :         1.0f / ((1 << 14) - 1),
     131             :         1.0f / ((1 << 15) - 1),
     132             :     };
     133             :     int a_size, r_size, g_size, b_size;
     134             :     int a_shift, r_shift, g_shift, b_shift;
     135             :     float a_mul, r_mul, g_mul, b_mul;
     136             :     uint32_t a_mask, r_mask, g_mask, b_mask;
     137             :     int i;
     138             : 
     139           0 :     if (!PIXMAN_FORMAT_VIS (format))
     140           0 :         format = PIXMAN_a8r8g8b8;
     141             : 
     142             :     /*
     143             :      * Determine the sizes of each component and the masks and shifts
     144             :      * required to extract them from the source pixel.
     145             :      */
     146           0 :     a_size = PIXMAN_FORMAT_A (format);
     147           0 :     r_size = PIXMAN_FORMAT_R (format);
     148           0 :     g_size = PIXMAN_FORMAT_G (format);
     149           0 :     b_size = PIXMAN_FORMAT_B (format);
     150             : 
     151           0 :     a_shift = 32 - a_size;
     152           0 :     r_shift = 24 - r_size;
     153           0 :     g_shift = 16 - g_size;
     154           0 :     b_shift =  8 - b_size;
     155             : 
     156           0 :     a_mask = ((1 << a_size) - 1);
     157           0 :     r_mask = ((1 << r_size) - 1);
     158           0 :     g_mask = ((1 << g_size) - 1);
     159           0 :     b_mask = ((1 << b_size) - 1);
     160             : 
     161           0 :     a_mul = multipliers[a_size];
     162           0 :     r_mul = multipliers[r_size];
     163           0 :     g_mul = multipliers[g_size];
     164           0 :     b_mul = multipliers[b_size];
     165             : 
     166             :     /* Start at the end so that we can do the expansion in place
     167             :      * when src == dst
     168             :      */
     169           0 :     for (i = width - 1; i >= 0; i--)
     170             :     {
     171           0 :         const uint32_t pixel = src[i];
     172             : 
     173           0 :         dst[i].a = a_mask? ((pixel >> a_shift) & a_mask) * a_mul : 1.0f;
     174           0 :         dst[i].r = ((pixel >> r_shift) & r_mask) * r_mul;
     175           0 :         dst[i].g = ((pixel >> g_shift) & g_mask) * g_mul;
     176           0 :         dst[i].b = ((pixel >> b_shift) & b_mask) * b_mul;
     177             :     }
     178           0 : }
     179             : 
     180             : uint16_t
     181           0 : pixman_float_to_unorm (float f, int n_bits)
     182             : {
     183           0 :     return float_to_unorm (f, n_bits);
     184             : }
     185             : 
     186             : float
     187           0 : pixman_unorm_to_float (uint16_t u, int n_bits)
     188             : {
     189           0 :     return unorm_to_float (u, n_bits);
     190             : }
     191             : 
     192             : void
     193           0 : pixman_contract_from_float (uint32_t     *dst,
     194             :                             const argb_t *src,
     195             :                             int           width)
     196             : {
     197             :     int i;
     198             : 
     199           0 :     for (i = 0; i < width; ++i)
     200             :     {
     201             :         uint8_t a, r, g, b;
     202             : 
     203           0 :         a = float_to_unorm (src[i].a, 8);
     204           0 :         r = float_to_unorm (src[i].r, 8);
     205           0 :         g = float_to_unorm (src[i].g, 8);
     206           0 :         b = float_to_unorm (src[i].b, 8);
     207             : 
     208           0 :         dst[i] = (a << 24) | (r << 16) | (g << 8) | (b << 0);
     209             :     }
     210           0 : }
     211             : 
     212             : uint32_t *
     213           0 : _pixman_iter_get_scanline_noop (pixman_iter_t *iter, const uint32_t *mask)
     214             : {
     215           0 :     return iter->buffer;
     216             : }
     217             : 
     218             : #define N_TMP_BOXES (16)
     219             : 
     220             : pixman_bool_t
     221           0 : pixman_region16_copy_from_region32 (pixman_region16_t *dst,
     222             :                                     pixman_region32_t *src)
     223             : {
     224             :     int n_boxes, i;
     225             :     pixman_box32_t *boxes32;
     226             :     pixman_box16_t *boxes16;
     227             :     pixman_bool_t retval;
     228             : 
     229           0 :     boxes32 = pixman_region32_rectangles (src, &n_boxes);
     230             : 
     231           0 :     boxes16 = pixman_malloc_ab (n_boxes, sizeof (pixman_box16_t));
     232             : 
     233           0 :     if (!boxes16)
     234           0 :         return FALSE;
     235             : 
     236           0 :     for (i = 0; i < n_boxes; ++i)
     237             :     {
     238           0 :         boxes16[i].x1 = boxes32[i].x1;
     239           0 :         boxes16[i].y1 = boxes32[i].y1;
     240           0 :         boxes16[i].x2 = boxes32[i].x2;
     241           0 :         boxes16[i].y2 = boxes32[i].y2;
     242             :     }
     243             : 
     244           0 :     pixman_region_fini (dst);
     245           0 :     retval = pixman_region_init_rects (dst, boxes16, n_boxes);
     246           0 :     free (boxes16);
     247           0 :     return retval;
     248             : }
     249             : 
     250             : pixman_bool_t
     251           0 : pixman_region32_copy_from_region16 (pixman_region32_t *dst,
     252             :                                     pixman_region16_t *src)
     253             : {
     254             :     int n_boxes, i;
     255             :     pixman_box16_t *boxes16;
     256             :     pixman_box32_t *boxes32;
     257             :     pixman_box32_t tmp_boxes[N_TMP_BOXES];
     258             :     pixman_bool_t retval;
     259             : 
     260           0 :     boxes16 = pixman_region_rectangles (src, &n_boxes);
     261             : 
     262           0 :     if (n_boxes > N_TMP_BOXES)
     263           0 :         boxes32 = pixman_malloc_ab (n_boxes, sizeof (pixman_box32_t));
     264             :     else
     265           0 :         boxes32 = tmp_boxes;
     266             : 
     267           0 :     if (!boxes32)
     268           0 :         return FALSE;
     269             : 
     270           0 :     for (i = 0; i < n_boxes; ++i)
     271             :     {
     272           0 :         boxes32[i].x1 = boxes16[i].x1;
     273           0 :         boxes32[i].y1 = boxes16[i].y1;
     274           0 :         boxes32[i].x2 = boxes16[i].x2;
     275           0 :         boxes32[i].y2 = boxes16[i].y2;
     276             :     }
     277             : 
     278           0 :     pixman_region32_fini (dst);
     279           0 :     retval = pixman_region32_init_rects (dst, boxes32, n_boxes);
     280             : 
     281           0 :     if (boxes32 != tmp_boxes)
     282           0 :         free (boxes32);
     283             : 
     284           0 :     return retval;
     285             : }
     286             : 
     287             : /* This function is exported for the sake of the test suite and not part
     288             :  * of the ABI.
     289             :  */
     290             : PIXMAN_EXPORT pixman_implementation_t *
     291           0 : _pixman_internal_only_get_implementation (void)
     292             : {
     293           0 :     return get_implementation ();
     294             : }
     295             : 
     296             : #ifdef DEBUG
     297             : 
     298             : void
     299             : _pixman_log_error (const char *function, const char *message)
     300             : {
     301             :     static int n_messages = 0;
     302             : 
     303             :     if (n_messages < 10)
     304             :     {
     305             :         fprintf (stderr,
     306             :                  "*** BUG ***\n"
     307             :                  "In %s: %s\n"
     308             :                  "Set a breakpoint on '_pixman_log_error' to debug\n\n",
     309             :                  function, message);
     310             : 
     311             :         n_messages++;
     312             :     }
     313             : }
     314             : 
     315             : #endif

Generated by: LCOV version 1.13