diff options
Diffstat (limited to 'pixman/pixman/pixman-access.c')
-rw-r--r-- | pixman/pixman/pixman-access.c | 134 |
1 files changed, 133 insertions, 1 deletions
diff --git a/pixman/pixman/pixman-access.c b/pixman/pixman/pixman-access.c index 6743887d0..9feafc49d 100644 --- a/pixman/pixman/pixman-access.c +++ b/pixman/pixman/pixman-access.c @@ -32,8 +32,8 @@ #include <string.h> #include <assert.h> -#include "pixman-private.h" #include "pixman-accessor.h" +#include "pixman-private.h" #define CONVERT_RGB24_TO_Y15(s) \ (((((s) >> 16) & 0xff) * 153 + \ @@ -210,6 +210,7 @@ get_shifts (pixman_format_code_t format, break; case PIXMAN_TYPE_ARGB: + case PIXMAN_TYPE_ARGB_SRGB: *b = 0; *g = *b + PIXMAN_FORMAT_B (format); *r = *g + PIXMAN_FORMAT_G (format); @@ -1027,6 +1028,130 @@ fetch_pixel_generic_64 (bits_image_t *image, return result; } +/* The 32_sRGB paths should be deleted after narrow processing + * is no longer invoked for formats that are considered wide. + * (Also see fetch_pixel_generic_lossy_32) */ +static void +fetch_scanline_a8r8g8b8_32_sRGB (pixman_image_t *image, + int x, + int y, + int width, + uint32_t *buffer, + const uint32_t *mask) +{ + const uint32_t *bits = image->bits.bits + y * image->bits.rowstride; + const uint32_t *pixel = (uint32_t *)bits + x; + const uint32_t *end = pixel + width; + uint32_t tmp; + + while (pixel < end) + { + tmp = READ (image, pixel++); + *buffer++ = (tmp >> 24) << 24 + | (srgb_to_linear[(tmp >> 16) & 0xff] >> 8) << 16 + | (srgb_to_linear[(tmp >> 8) & 0xff] >> 8) << 8 + | (srgb_to_linear[(tmp >> 0) & 0xff] >> 8) << 0; + } +} + +static void +fetch_scanline_a8r8g8b8_64_sRGB (pixman_image_t *image, + int x, + int y, + int width, + uint32_t *b, + const uint32_t *mask) +{ + const uint32_t *bits = image->bits.bits + y * image->bits.rowstride; + const uint32_t *pixel = (uint32_t *)bits + x; + const uint32_t *end = pixel + width; + uint64_t *buffer = (uint64_t *)b; + uint32_t tmp; + + while (pixel < end) + { + tmp = READ (image, pixel++); + *buffer++ = (uint64_t) ((tmp >> 24) * 257) << 48 + | (uint64_t) srgb_to_linear[(tmp >> 16) & 0xff] << 32 + | (uint64_t) srgb_to_linear[(tmp >> 8) & 0xff] << 16 + | (uint64_t) srgb_to_linear[(tmp >> 0) & 0xff] << 0; + } +} + +static uint32_t +fetch_pixel_a8r8g8b8_32_sRGB (bits_image_t *image, + int offset, + int line) +{ + uint32_t *bits = image->bits + line * image->rowstride; + uint32_t tmp = READ (image, bits + offset); + return (tmp >> 24) << 24 + | (srgb_to_linear[(tmp >> 16) & 0xff] >> 8) << 16 + | (srgb_to_linear[(tmp >> 8) & 0xff] >> 8) << 8 + | (srgb_to_linear[(tmp >> 0) & 0xff] >> 8) << 0; +} + +static uint64_t +fetch_pixel_a8r8g8b8_64_sRGB (bits_image_t *image, + int offset, + int line) +{ + uint32_t *bits = image->bits + line * image->rowstride; + uint32_t tmp = READ (image, bits + offset); + return (uint64_t) ((tmp >> 24) * 257) << 48 + | (uint64_t) srgb_to_linear[(tmp >> 16) & 0xff] << 32 + | (uint64_t) srgb_to_linear[(tmp >> 8) & 0xff] << 16 + | (uint64_t) srgb_to_linear[(tmp >> 0) & 0xff] << 0; +} + +static void +store_scanline_a8r8g8b8_32_sRGB (bits_image_t *image, + int x, + int y, + int width, + const uint32_t *v) +{ + uint32_t *bits = image->bits + image->rowstride * y; + uint64_t *values = (uint64_t *)v; + uint32_t *pixel = bits + x; + uint64_t tmp; + int i; + + for (i = 0; i < width; ++i) + { + tmp = values[i]; + WRITE (image, pixel++, + ((uint32_t) (tmp >> 24 ) << 24) + | (linear_to_srgb[(tmp >> 16 << 4) & 0xfff] << 16) + | (linear_to_srgb[(tmp >> 8 << 4) & 0xfff] << 8) + | (linear_to_srgb[(tmp >> 0 << 4) & 0xfff] << 0)); + } +} + +static void +store_scanline_a8r8g8b8_64_sRGB (bits_image_t *image, + int x, + int y, + int width, + const uint32_t *v) +{ + uint32_t *bits = image->bits + image->rowstride * y; + uint64_t *values = (uint64_t *)v; + uint32_t *pixel = bits + x; + uint64_t tmp; + int i; + + for (i = 0; i < width; ++i) + { + tmp = values[i]; + WRITE (image, pixel++, + ((uint32_t) (tmp >> 56) << 24) + | (linear_to_srgb[(tmp >> 36) & 0xfff] << 16) + | (linear_to_srgb[(tmp >> 20) & 0xfff] << 8) + | (linear_to_srgb[(tmp >> 4) & 0xfff] << 0)); + } +} + /* * XXX: The transformed fetch path only works at 32-bpp so far. When all * paths have wide versions, this can be removed. @@ -1079,6 +1204,13 @@ static const format_info_t accessors[] = FORMAT_INFO (r8g8b8x8), FORMAT_INFO (x14r6g6b6), +/* sRGB formats */ + { PIXMAN_a8r8g8b8_sRGB, + fetch_scanline_a8r8g8b8_32_sRGB, + fetch_scanline_a8r8g8b8_64_sRGB, + fetch_pixel_a8r8g8b8_32_sRGB, fetch_pixel_a8r8g8b8_64_sRGB, + store_scanline_a8r8g8b8_32_sRGB, store_scanline_a8r8g8b8_64_sRGB }, + /* 24bpp formats */ FORMAT_INFO (r8g8b8), FORMAT_INFO (b8g8r8), |