From: Aaron Plattner Date: Sat, 7 Jun 2008 02:40:25 +0000 (-0700) Subject: Take the source format into account in pixman_expand. X-Git-Tag: 1.0_branch~1318 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=7cb735c9c0fa55ae1f4d8d13da9f33e3da2ae8fe;p=profile%2Fivi%2Fpixman.git Take the source format into account in pixman_expand. Extract the original bits of the source image for each component and then replicate up to 16 bits to fill the wide components. Make sure to hard-code the alpha value to 1 if the source format didn't have alpha. Signed-off-by: Søren Sandmann Pedersen --- diff --git a/pixman/pixman-access.c b/pixman/pixman-access.c index 29ddcb3..ec187d3 100644 --- a/pixman/pixman-access.c +++ b/pixman/pixman-access.c @@ -1879,30 +1879,70 @@ storeProc64 ACCESS(pixman_storeProcForPicture64) (bits_image_t * pict) #ifndef PIXMAN_FB_ACCESSORS /* + * Helper routine to expand a color component from 0 < n <= 8 bits to 16 bits by + * replication. + */ +static inline uint64_t expand16(const uint8_t val, int nbits) +{ + // Start out with the high bit of val in the high bit of result. + uint16_t result = (uint16_t)val << (16 - nbits); + + if (nbits == 0) + return 0; + + // Copy the bits in result, doubling the number of bits each time, until we + // fill all 16 bits. + while (nbits < 16) { + result |= result >> nbits; + nbits *= 2; + } + + return result; +} + +/* * This function expands images from ARGB8 format to ARGB16. To preserve * precision, it needs to know the original source format. For example, if the * source was PIXMAN_x1r5g5b5 and the red component contained bits 12345, then * the expanded value is 12345123. To correctly expand this to 16 bits, it * should be 1234512345123451 and not 1234512312345123. - * - * XXX[AGP]: For now, this just does naïve byte replication. */ void pixman_expand(uint64_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; /* Start at the end so that we can do the expansion in place when src == dst */ for (i = width - 1; i >= 0; i--) { - const uint8_t a = src[i] >> 24, - r = src[i] >> 16, - g = src[i] >> 8, - b = src[i]; - dst[i] = (uint64_t)a << 56 | (uint64_t) a << 48 | - (uint64_t)r << 40 | (uint64_t) r << 32 | - (uint64_t)g << 24 | (uint64_t) g << 16 | - (uint64_t)b << 8 | (uint64_t)b; + const uint32_t pixel = src[i]; + // Extract the components. + 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; + const uint64_t a16 = a_size ? expand16(a, a_size) : 0xffff, + r16 = expand16(r, r_size), + g16 = expand16(g, g_size), + b16 = expand16(b, b_size); + + dst[i] = a16 << 48 | r16 << 32 | g16 << 16 | b16; } }