From: Søren Sandmann Pedersen Date: Mon, 15 Aug 2011 14:22:05 +0000 (-0400) Subject: Add a generic unorm_to_unorm() conversion utility X-Git-Tag: pixman-0.23.6~40 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=22f54dde6bbf87251a0b4ad93bacbdaa7cb508d8;p=platform%2Fupstream%2Fpixman.git Add a generic unorm_to_unorm() conversion utility This function can convert between normalized numbers of different depths. When converting to higher bit depths, it will replicate the existing bits, when converting to lower bit depths, it will simply truncate. This function replaces the expand16() function in pixman-utils.c --- diff --git a/pixman/pixman-private.h b/pixman/pixman-private.h index a25897d..90d9011 100644 --- a/pixman/pixman-private.h +++ b/pixman/pixman-private.h @@ -783,6 +783,49 @@ pixman_region16_copy_from_region32 (pixman_region16_t *dst, # define SCREEN_SHIFT_RIGHT(x,n) ((x) << (n)) #endif +static force_inline uint32_t +unorm_to_unorm (uint32_t val, int from_bits, int to_bits) +{ + uint32_t result; + + if (from_bits == 0) + return 0; + + /* Delete any extra bits */ + val &= ((1 << from_bits) - 1); + + if (from_bits >= to_bits) + return val >> (from_bits - to_bits); + + /* Start out with the high bit of val in the high bit of result. */ + result = val << (to_bits - from_bits); + + /* Copy the bits in result, doubling the number of bits each time, until + * we fill all to_bits. Unrolled manually because from_bits and to_bits + * are usually known statically, so the compiler can turn all of this + * into a few shifts. + */ +#define REPLICATE() \ + do \ + { \ + if (from_bits < to_bits) \ + { \ + result |= result >> from_bits; \ + \ + from_bits *= 2; \ + } \ + } \ + while (0) + + REPLICATE(); + REPLICATE(); + REPLICATE(); + REPLICATE(); + REPLICATE(); + + return result; +} + /* * Various debugging code */ diff --git a/pixman/pixman-utils.c b/pixman/pixman-utils.c index 49e3488..768ca1b 100644 --- a/pixman/pixman-utils.c +++ b/pixman/pixman-utils.c @@ -72,31 +72,6 @@ pixman_malloc_abc (unsigned int a, } /* - * 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 @@ -137,10 +112,11 @@ pixman_expand (uint64_t * dst, 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); + const uint64_t + a16 = a_size ? unorm_to_unorm (a, a_size, 16) : 0xffff, + r16 = unorm_to_unorm (r, r_size, 16), + g16 = unorm_to_unorm (g, g_size, 16), + b16 = unorm_to_unorm (b, b_size, 16); dst[i] = a16 << 48 | r16 << 32 | g16 << 16 | b16; }