diff options
author | Søren Sandmann Pedersen <ssp@redhat.com> | 2010-05-19 17:49:51 -0400 |
---|---|---|
committer | Andrea Canciani <ranma42@gmail.com> | 2010-12-13 17:22:35 +0100 |
commit | 67a34ccc4827997a63fd3585ce3b7afffdac80f3 (patch) | |
tree | b861c30742f5fc366823fce8f524d293b11cd20e | |
parent | 33843d4123f7a5c6128030b9d9e05e0e4a44232d (diff) |
Some conversion
-rw-r--r-- | pixman/pixman-access.c | 13 | ||||
-rw-r--r-- | pixman/pixman-combine-float.c | 2 | ||||
-rw-r--r-- | pixman/pixman-general.c | 1 | ||||
-rw-r--r-- | pixman/pixman-private.h | 21 | ||||
-rw-r--r-- | pixman/pixman-utils.c | 75 |
5 files changed, 110 insertions, 2 deletions
diff --git a/pixman/pixman-access.c b/pixman/pixman-access.c index 594cc12..97e548d 100644 --- a/pixman/pixman-access.c +++ b/pixman/pixman-access.c @@ -839,6 +839,19 @@ fetch_scanline_generic_64 (pixman_image_t *image, pixman_expand ((uint64_t *)buffer, buffer, format, width); } +static void +fetch_scanline_generic_float (pixman_image_t *image, + int x, + int y, + int width, + uint32_t * buffer, + const uint32_t *mask) +{ + image->bits.fetch_scanline_32 (image, x, y, width, buffer, NULL); + + pixman_expand_to_float ((uint64_t *)buffer, buffer, image->bits.format, width); +} + /* Despite the type, this function expects a uint64_t *buffer */ static uint64_t fetch_pixel_generic_64 (bits_image_t *image, diff --git a/pixman/pixman-combine-float.c b/pixman/pixman-combine-float.c index abee5da..2945de6 100644 --- a/pixman/pixman-combine-float.c +++ b/pixman/pixman-combine-float.c @@ -803,7 +803,7 @@ MAKE_NON_SEPARABLE_PDF_COMBINERS(hsl_color) MAKE_NON_SEPARABLE_PDF_COMBINERS(hsl_luminosity) void -_pixman_setup_combiner_functions_width (pixman_implementation_t *imp) +_pixman_setup_combiner_functions_float (pixman_implementation_t *imp) { /* Unified alpha */ imp->combine_float[PIXMAN_OP_CLEAR] = combine_clear_u_float; diff --git a/pixman/pixman-general.c b/pixman/pixman-general.c index 8130f16..95b64b7 100644 --- a/pixman/pixman-general.c +++ b/pixman/pixman-general.c @@ -306,6 +306,7 @@ _pixman_implementation_create_general (void) _pixman_setup_combiner_functions_32 (imp); _pixman_setup_combiner_functions_64 (imp); + _pixman_setup_combiner_functions_float (imp); imp->blt = general_blt; imp->fill = general_fill; diff --git a/pixman/pixman-private.h b/pixman/pixman-private.h index 455ccd3..9910ec0 100644 --- a/pixman/pixman-private.h +++ b/pixman/pixman-private.h @@ -31,6 +31,16 @@ typedef struct radial_gradient radial_gradient_t; typedef struct bits_image bits_image_t; typedef struct circle circle_t; +typedef struct argb_t argb_t; + +struct argb_t +{ + float a; + float r; + float g; + float b; +}; + typedef void (*fetch_scanline_t) (pixman_image_t *image, int x, int y, @@ -46,6 +56,10 @@ typedef uint64_t (*fetch_pixel_64_t) (bits_image_t *image, int x, int y); +typedef argb_t (*fetch_pixel_float_t) (bits_image_t *image, + int x, + int y); + typedef void (*store_scanline_t) (bits_image_t * image, int x, int y, @@ -100,6 +114,7 @@ struct image_common property_changed_func_t property_changed; fetch_scanline_t get_scanline_32; fetch_scanline_t get_scanline_64; + fetch_scanline_t get_scanline_float; pixman_image_destroy_func_t destroy_func; void * destroy_data; @@ -177,6 +192,10 @@ struct bits_image fetch_pixel_64_t fetch_pixel_64; store_scanline_t store_scanline_64; + fetch_scanline_t fetch_scanline_float; + fetch_pixel_float_t fetch_pixel_float; + store_scanline_t store_scanline_float; + /* Used for indirect access to the bits */ pixman_read_memory_func_t read_func; pixman_write_memory_func_t write_func; @@ -407,6 +426,7 @@ typedef pixman_bool_t (*pixman_fill_func_t) (pixman_implementation_t *imp, void _pixman_setup_combiner_functions_32 (pixman_implementation_t *imp); void _pixman_setup_combiner_functions_64 (pixman_implementation_t *imp); +void _pixman_setup_combiner_functions_float (pixman_implementation_t *imp); typedef struct { @@ -433,7 +453,6 @@ struct pixman_implementation_t pixman_combine_32_func_t combine_32_ca[PIXMAN_N_OPERATORS]; pixman_combine_64_func_t combine_64[PIXMAN_N_OPERATORS]; pixman_combine_64_func_t combine_64_ca[PIXMAN_N_OPERATORS]; - pixman_combine_float_func_t combine_float[PIXMAN_N_OPERATORS]; pixman_combine_float_func_t combine_float_ca[PIXMAN_N_OPERATORS]; }; diff --git a/pixman/pixman-utils.c b/pixman/pixman-utils.c index f86e278..0ad1a5d 100644 --- a/pixman/pixman-utils.c +++ b/pixman/pixman-utils.c @@ -118,6 +118,81 @@ pixman_expand (uint64_t * dst, } } +void +pixman_expand_to_float (argb_t *dst, + const uint32_t *src, + pixman_format_code_t format, + int width) +{ + /* + * Determine the sizes of each component and the masks and shifts + * required to extract them from the source pixel. + */ + const int a_size = PIXMAN_FORMAT_A (format), + r_size = PIXMAN_FORMAT_R (format), + g_size = PIXMAN_FORMAT_G (format), + b_size = PIXMAN_FORMAT_B (format); + const int a_shift = 32 - a_size, + r_shift = 24 - r_size, + g_shift = 16 - g_size, + b_shift = 8 - b_size; + const uint8_t a_mask = ~(~0 << a_size), + r_mask = ~(~0 << r_size), + g_mask = ~(~0 << g_size), + b_mask = ~(~0 << b_size); + int i; + + for (i = 0; i < width; ++i) + { + const uint32_t pixel = src[i]; + const uint8_t a = (pixel >> a_shift) & a_mask, + r = (pixel >> r_shift) & r_mask, + g = (pixel >> g_shift) & g_mask, + b = (pixel >> b_shift) & b_mask; + + dst[i].a = a_size? a * (1 / (a_size - 1.0)) : 1.0; + dst[i].r = r_size? r * (1 / (r_size - 1.0)) : 0.0; + dst[i].g = g_size? g * (1 / (g_size - 1.0)) : 0.0; + dst[i].b = b_size? b * (1 / (b_size - 1.0)) : 0.0; + } +} + +static force_inline uint16_t +float_to_unorm (float f, int n_bits) +{ + uint32_t u; + + if (f > 1.0) + f = 1.0; + if (f < 0.0) + f = 0.0; + + u = f * (1 << n_bits); + u -= (u >> n_bits); + + return u; +} + +void +pixman_contract_from_float (uint32_t * dst, + const argb_t *src, + int width) +{ + int i; + + for (i = 0; i < width; ++i) + { + uint8_t a, r, g, b; + + a = float_to_unorm (src[i].a, 8); + r = float_to_unorm (src[i].r, 8); + g = float_to_unorm (src[i].g, 8); + b = float_to_unorm (src[i].b, 8); + + dst[i] = (a << 24) | (r << 16) | (g << 8) | (b << 0); + } +} + /* * Contracting is easier than expanding. We just need to truncate the * components. |