Subversion Repositories Kolibri OS

Rev

Rev 1891 | Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

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