LCOV - code coverage report
Current view: directory - gfx/cairo/libpixman/src - pixman-utils.c (source / functions) Found Hit Coverage
Test: app.info Lines: 88 0 0.0 %
Date: 2012-06-02 Functions: 10 0 0.0 %

       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                 : 
      31                 : #include "pixman-private.h"
      32                 : 
      33                 : pixman_bool_t
      34               0 : pixman_multiply_overflows_int (unsigned int a,
      35                 :                                unsigned int b)
      36                 : {
      37               0 :     return a >= INT32_MAX / b;
      38                 : }
      39                 : 
      40                 : pixman_bool_t
      41               0 : pixman_addition_overflows_int (unsigned int a,
      42                 :                                unsigned int b)
      43                 : {
      44               0 :     return a > INT32_MAX - b;
      45                 : }
      46                 : 
      47                 : void *
      48               0 : pixman_malloc_ab (unsigned int a,
      49                 :                   unsigned int b)
      50                 : {
      51               0 :     if (a >= INT32_MAX / b)
      52               0 :         return NULL;
      53                 : 
      54               0 :     return malloc (a * b);
      55                 : }
      56                 : 
      57                 : void *
      58               0 : pixman_malloc_abc (unsigned int a,
      59                 :                    unsigned int b,
      60                 :                    unsigned int c)
      61                 : {
      62               0 :     if (a >= INT32_MAX / b)
      63               0 :         return NULL;
      64               0 :     else if (a * b >= INT32_MAX / c)
      65               0 :         return NULL;
      66                 :     else
      67               0 :         return malloc (a * b * c);
      68                 : }
      69                 : 
      70                 : /*
      71                 :  * Helper routine to expand a color component from 0 < n <= 8 bits to 16
      72                 :  * bits by replication.
      73                 :  */
      74                 : static inline uint64_t
      75               0 : expand16 (const uint8_t val, int nbits)
      76                 : {
      77                 :     /* Start out with the high bit of val in the high bit of result. */
      78               0 :     uint16_t result = (uint16_t)val << (16 - nbits);
      79                 : 
      80               0 :     if (nbits == 0)
      81               0 :         return 0;
      82                 : 
      83                 :     /* Copy the bits in result, doubling the number of bits each time, until
      84                 :      * we fill all 16 bits.
      85                 :      */
      86               0 :     while (nbits < 16)
      87                 :     {
      88               0 :         result |= result >> nbits;
      89               0 :         nbits *= 2;
      90                 :     }
      91                 : 
      92               0 :     return result;
      93                 : }
      94                 : 
      95                 : /*
      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.
     101                 :  */
     102                 : void
     103               0 : pixman_expand (uint64_t *           dst,
     104                 :                const uint32_t *     src,
     105                 :                pixman_format_code_t format,
     106                 :                int                  width)
     107                 : {
     108                 :     /*
     109                 :      * Determine the sizes of each component and the masks and shifts
     110                 :      * required to extract them from the source pixel.
     111                 :      */
     112               0 :     const int a_size = PIXMAN_FORMAT_A (format),
     113               0 :               r_size = PIXMAN_FORMAT_R (format),
     114               0 :               g_size = PIXMAN_FORMAT_G (format),
     115               0 :               b_size = PIXMAN_FORMAT_B (format);
     116               0 :     const int a_shift = 32 - a_size,
     117               0 :               r_shift = 24 - r_size,
     118               0 :               g_shift = 16 - g_size,
     119               0 :               b_shift =  8 - b_size;
     120               0 :     const uint8_t a_mask = ~(~0 << a_size),
     121               0 :                   r_mask = ~(~0 << r_size),
     122               0 :                   g_mask = ~(~0 << g_size),
     123               0 :                   b_mask = ~(~0 << b_size);
     124                 :     int i;
     125                 : 
     126                 :     /* Start at the end so that we can do the expansion in place
     127                 :      * when src == dst
     128                 :      */
     129               0 :     for (i = width - 1; i >= 0; i--)
     130                 :     {
     131               0 :         const uint32_t pixel = src[i];
     132               0 :         const uint8_t a = (pixel >> a_shift) & a_mask,
     133               0 :                       r = (pixel >> r_shift) & r_mask,
     134               0 :                       g = (pixel >> g_shift) & g_mask,
     135               0 :                       b = (pixel >> b_shift) & b_mask;
     136               0 :         const uint64_t a16 = a_size ? expand16 (a, a_size) : 0xffff,
     137               0 :                        r16 = expand16 (r, r_size),
     138               0 :                        g16 = expand16 (g, g_size),
     139               0 :                        b16 = expand16 (b, b_size);
     140                 : 
     141               0 :         dst[i] = a16 << 48 | r16 << 32 | g16 << 16 | b16;
     142                 :     }
     143               0 : }
     144                 : 
     145                 : /*
     146                 :  * Contracting is easier than expanding.  We just need to truncate the
     147                 :  * components.
     148                 :  */
     149                 : void
     150               0 : pixman_contract (uint32_t *      dst,
     151                 :                  const uint64_t *src,
     152                 :                  int             width)
     153                 : {
     154                 :     int i;
     155                 : 
     156                 :     /* Start at the beginning so that we can do the contraction in
     157                 :      * place when src == dst
     158                 :      */
     159               0 :     for (i = 0; i < width; i++)
     160                 :     {
     161               0 :         const uint8_t a = src[i] >> 56,
     162               0 :                       r = src[i] >> 40,
     163               0 :                       g = src[i] >> 24,
     164               0 :                       b = src[i] >> 8;
     165                 : 
     166               0 :         dst[i] = a << 24 | r << 16 | g << 8 | b;
     167                 :     }
     168               0 : }
     169                 : 
     170                 : uint32_t *
     171               0 : _pixman_iter_get_scanline_noop (pixman_iter_t *iter, const uint32_t *mask)
     172                 : {
     173               0 :     return iter->buffer;
     174                 : }
     175                 : 
     176                 : #define N_TMP_BOXES (16)
     177                 : 
     178                 : pixman_bool_t
     179               0 : pixman_region16_copy_from_region32 (pixman_region16_t *dst,
     180                 :                                     pixman_region32_t *src)
     181                 : {
     182                 :     int n_boxes, i;
     183                 :     pixman_box32_t *boxes32;
     184                 :     pixman_box16_t *boxes16;
     185                 :     pixman_bool_t retval;
     186                 : 
     187               0 :     boxes32 = pixman_region32_rectangles (src, &n_boxes);
     188                 : 
     189               0 :     boxes16 = pixman_malloc_ab (n_boxes, sizeof (pixman_box16_t));
     190                 : 
     191               0 :     if (!boxes16)
     192               0 :         return FALSE;
     193                 : 
     194               0 :     for (i = 0; i < n_boxes; ++i)
     195                 :     {
     196               0 :         boxes16[i].x1 = boxes32[i].x1;
     197               0 :         boxes16[i].y1 = boxes32[i].y1;
     198               0 :         boxes16[i].x2 = boxes32[i].x2;
     199               0 :         boxes16[i].y2 = boxes32[i].y2;
     200                 :     }
     201                 : 
     202               0 :     pixman_region_fini (dst);
     203               0 :     retval = pixman_region_init_rects (dst, boxes16, n_boxes);
     204               0 :     free (boxes16);
     205               0 :     return retval;
     206                 : }
     207                 : 
     208                 : pixman_bool_t
     209               0 : pixman_region32_copy_from_region16 (pixman_region32_t *dst,
     210                 :                                     pixman_region16_t *src)
     211                 : {
     212                 :     int n_boxes, i;
     213                 :     pixman_box16_t *boxes16;
     214                 :     pixman_box32_t *boxes32;
     215                 :     pixman_box32_t tmp_boxes[N_TMP_BOXES];
     216                 :     pixman_bool_t retval;
     217                 : 
     218               0 :     boxes16 = pixman_region_rectangles (src, &n_boxes);
     219                 : 
     220               0 :     if (n_boxes > N_TMP_BOXES)
     221               0 :         boxes32 = pixman_malloc_ab (n_boxes, sizeof (pixman_box32_t));
     222                 :     else
     223               0 :         boxes32 = tmp_boxes;
     224                 : 
     225               0 :     if (!boxes32)
     226               0 :         return FALSE;
     227                 : 
     228               0 :     for (i = 0; i < n_boxes; ++i)
     229                 :     {
     230               0 :         boxes32[i].x1 = boxes16[i].x1;
     231               0 :         boxes32[i].y1 = boxes16[i].y1;
     232               0 :         boxes32[i].x2 = boxes16[i].x2;
     233               0 :         boxes32[i].y2 = boxes16[i].y2;
     234                 :     }
     235                 : 
     236               0 :     pixman_region32_fini (dst);
     237               0 :     retval = pixman_region32_init_rects (dst, boxes32, n_boxes);
     238                 : 
     239               0 :     if (boxes32 != tmp_boxes)
     240               0 :         free (boxes32);
     241                 : 
     242               0 :     return retval;
     243                 : }
     244                 : 
     245                 : #ifdef DEBUG
     246                 : 
     247                 : void
     248                 : _pixman_log_error (const char *function, const char *message)
     249                 : {
     250                 :     static int n_messages = 0;
     251                 : 
     252                 :     if (n_messages < 10)
     253                 :     {
     254                 :         fprintf (stderr,
     255                 :                  "*** BUG ***\n"
     256                 :                  "In %s: %s\n"
     257                 :                  "Set a breakpoint on '_pixman_log_error' to debug\n\n",
     258                 :                  function, message);
     259                 : 
     260                 :         n_messages++;
     261                 :     }
     262                 : }
     263                 : 
     264                 : #endif

Generated by: LCOV version 1.7