summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSøren Sandmann Pedersen <ssp@redhat.com>2010-05-19 17:49:51 -0400
committerAndrea Canciani <ranma42@gmail.com>2010-12-13 17:22:35 +0100
commit67a34ccc4827997a63fd3585ce3b7afffdac80f3 (patch)
treeb861c30742f5fc366823fce8f524d293b11cd20e
parent33843d4123f7a5c6128030b9d9e05e0e4a44232d (diff)
Some conversion
-rw-r--r--pixman/pixman-access.c13
-rw-r--r--pixman/pixman-combine-float.c2
-rw-r--r--pixman/pixman-general.c1
-rw-r--r--pixman/pixman-private.h21
-rw-r--r--pixman/pixman-utils.c75
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.