jpeg pushed a commit to branch master. http://git.enlightenment.org/core/efl.git/commit/?id=03505d1f81535f8cdb295c6fb7b1af3a60b0daa3
commit 03505d1f81535f8cdb295c6fb7b1af3a60b0daa3 Author: Jean-Philippe Andre <jp.an...@samsung.com> Date: Wed May 7 14:47:45 2014 +0900 Evas rg_etc2: Complete support for ETC2 with RGBA8_EAC Add support for alpha in the ETC2 decoder. --- src/static_libs/rg_etc/rg_etc2.c | 150 ++++++++++++++++++++++++++++++++------- 1 file changed, 124 insertions(+), 26 deletions(-) diff --git a/src/static_libs/rg_etc/rg_etc2.c b/src/static_libs/rg_etc/rg_etc2.c index 9204402..0aa43b0 100644 --- a/src/static_libs/rg_etc/rg_etc2.c +++ b/src/static_libs/rg_etc/rg_etc2.c @@ -51,6 +51,26 @@ static const int kSigned3bit[8] = { 0, 1, 2, 3, -4, -3, -2, -1 }; +// For alpha support +static const int kAlphaModifiers[16][8] = { + { -3, -6, -9, -15, 2, 5, 8, 14}, + { -3, -7, -10, -13, 2, 6, 9, 12}, + { -2, -5, -8, -13, 1, 4, 7, 12}, + { -2, -4, -6, -13, 1, 3, 5, 12}, + { -3, -6, -8, -12, 2, 5, 7, 11}, + { -3, -7, -9, -11, 2, 6, 8, 10}, + { -4, -7, -8, -11, 3, 6, 7, 10}, + { -3, -5, -8, -11, 2, 4, 7, 10}, + { -2, -6, -8, -10, 1, 5, 7, 9}, + { -2, -5, -8, -10, 1, 4, 7, 9}, + { -2, -4, -8, -10, 1, 3, 7, 9}, + { -2, -5, -7, -10, 1, 4, 6, 9}, + { -3, -4, -7, -10, 2, 3, 6, 9}, + { -1, -2, -3, -10, 0, 1, 2, 9}, + { -4, -6, -8, -9, 3, 5, 7, 8}, + { -3, -5, -7, -9, 2, 4, 6, 8} +}; + // Use with static constants so the compiler can optimize everything #define BITS(byteval, lowbit, highbit) \ (((byteval) >> (lowbit)) & ((1 << ((highbit) - (lowbit) + 1)) - 1)) @@ -67,6 +87,9 @@ static const int kSigned3bit[8] = { // Real clamp #define CLAMP(a) ({ int _b = (a); (((_b) >= 0) ? (((_b) < 256) ? (_b) : 255) : 0); }) +// Simple min +#define MIN(a,b) ({ int _z = (a), _y = (b); ((_z <= _y) ? _z : _y); }) + // Write a BGRA value for output to Evas #define BGRA(r,g,b,a) ((a << 24) | (r << 16) | (g << 8) | b) @@ -75,6 +98,20 @@ static const int kSigned3bit[8] = { #define _6to8(a) ({ int _a = (a) & ((1 << 6) - 1); ((_a << 2) | ((_a >> 4) & 0x3)); }) #define _7to8(a) ({ int _a = (a) & ((1 << 7) - 1); ((_a << 1) | ((_a >> 6) & 0x1)); }) +#ifndef WORDS_BIGENDIAN +/* x86 */ +#define A_VAL(p) (((uint8_t *)(p))[3]) +#define R_VAL(p) (((uint8_t *)(p))[2]) +#define G_VAL(p) (((uint8_t *)(p))[1]) +#define B_VAL(p) (((uint8_t *)(p))[0]) +#else +/* ppc */ +#define A_VAL(p) (((uint8_t *)(p))[0]) +#define R_VAL(p) (((uint8_t *)(p))[1]) +#define G_VAL(p) (((uint8_t *)(p))[2]) +#define B_VAL(p) (((uint8_t *)(p))[3]) +#endif + static inline void _T_mode_color_read(const uint8_t *etc, uint32_t *paint_colors, int alpha) @@ -176,6 +213,36 @@ _planar_mode_color_read(const uint8_t *etc, uint32_t *bgra, int alpha) } } +static inline void +_TH_paint(const uint8_t *etc, uint32_t paint_colors[4], uint32_t *bgra) +{ + // Common code for modes T and H. + + // a,b,c,d + bgra[ 0] = paint_colors[(BIT(etc[5], 0) << 1) | (BIT(etc[7], 0))]; + bgra[ 4] = paint_colors[(BIT(etc[5], 1) << 1) | (BIT(etc[7], 1))]; + bgra[ 8] = paint_colors[(BIT(etc[5], 2) << 1) | (BIT(etc[7], 2))]; + bgra[12] = paint_colors[(BIT(etc[5], 3) << 1) | (BIT(etc[7], 3))]; + + // e,f,g,h + bgra[ 1] = paint_colors[(BIT(etc[5], 4) << 1) | (BIT(etc[7], 4))]; + bgra[ 5] = paint_colors[(BIT(etc[5], 5) << 1) | (BIT(etc[7], 5))]; + bgra[ 9] = paint_colors[(BIT(etc[5], 6) << 1) | (BIT(etc[7], 6))]; + bgra[13] = paint_colors[(BIT(etc[5], 7) << 1) | (BIT(etc[7], 7))]; + + // i,j,k,l + bgra[ 2] = paint_colors[(BIT(etc[4], 0) << 1) | (BIT(etc[6], 0))]; + bgra[ 6] = paint_colors[(BIT(etc[4], 1) << 1) | (BIT(etc[6], 1))]; + bgra[10] = paint_colors[(BIT(etc[4], 2) << 1) | (BIT(etc[6], 2))]; + bgra[14] = paint_colors[(BIT(etc[4], 3) << 1) | (BIT(etc[6], 3))]; + + // m,n,o,p + bgra[ 3] = paint_colors[(BIT(etc[4], 4) << 1) | (BIT(etc[6], 4))]; + bgra[ 7] = paint_colors[(BIT(etc[4], 5) << 1) | (BIT(etc[6], 5))]; + bgra[11] = paint_colors[(BIT(etc[4], 6) << 1) | (BIT(etc[6], 6))]; + bgra[15] = paint_colors[(BIT(etc[4], 7) << 1) | (BIT(etc[6], 7))]; +} + void rg_etc2_rgb8_decode_block(const uint8_t *etc, uint32_t *bgra) { @@ -196,13 +263,15 @@ rg_etc2_rgb8_decode_block(const uint8_t *etc, uint32_t *bgra) { // T mode _T_mode_color_read(etc, paint_colors, 255); - goto th_mode; + _TH_paint(etc, paint_colors, bgra); + return; } if ((G + dG) < 0 || (G + dG) >= 32) { // H mode _H_mode_color_read(etc, paint_colors, 255); - goto th_mode; + _TH_paint(etc, paint_colors, bgra); + return; } if ((B + dB) < 0 || (B + dB) >= 32) { @@ -215,33 +284,62 @@ etc1: // Valid differential mode or individual mode: ETC1 if (!rg_etc1_unpack_block(etc, bgra, 0)) fprintf(stderr, "ETC2: Something very strange is happening here!\n"); - return; +} -th_mode: - // Common code for modes T and H. +void +rg_etc2_rgba8_decode_block(const uint8_t *etc, uint32_t *bgra) +{ + const uint8_t zeros[7] = {0}; + uint32_t table_index; + int base_codeword; + int multiplier; - // a,b,c,d - bgra[ 0] = paint_colors[(BIT(etc[5], 0) << 1) | (BIT(etc[7], 0))]; - bgra[ 4] = paint_colors[(BIT(etc[5], 1) << 1) | (BIT(etc[7], 1))]; - bgra[ 8] = paint_colors[(BIT(etc[5], 2) << 1) | (BIT(etc[7], 2))]; - bgra[12] = paint_colors[(BIT(etc[5], 3) << 1) | (BIT(etc[7], 3))]; + base_codeword = etc[0]; - // e,f,g,h - bgra[ 1] = paint_colors[(BIT(etc[5], 4) << 1) | (BIT(etc[7], 4))]; - bgra[ 5] = paint_colors[(BIT(etc[5], 5) << 1) | (BIT(etc[7], 5))]; - bgra[ 9] = paint_colors[(BIT(etc[5], 6) << 1) | (BIT(etc[7], 6))]; - bgra[13] = paint_colors[(BIT(etc[5], 7) << 1) | (BIT(etc[7], 7))]; + // Fast path if alpha is the same for all pixels + if (!memcmp(etc + 1, zeros, 7)) + { + if (!base_codeword) + memset(bgra, 0, 64); + else + { + rg_etc2_rgb8_decode_block(etc + 8, bgra); + if (base_codeword != 255) + for (int k = 0; k < 16; k++) + { + const uint32_t rgb = *bgra; + const int R = MIN(R_VAL(&rgb), base_codeword); + const int G = MIN(G_VAL(&rgb), base_codeword); + const int B = MIN(B_VAL(&rgb), base_codeword); + *bgra++ = BGRA(R, G, B, base_codeword); + } + } + return; + } - // i,j,k,l - bgra[ 2] = paint_colors[(BIT(etc[4], 0) << 1) | (BIT(etc[6], 0))]; - bgra[ 6] = paint_colors[(BIT(etc[4], 1) << 1) | (BIT(etc[6], 1))]; - bgra[10] = paint_colors[(BIT(etc[4], 2) << 1) | (BIT(etc[6], 2))]; - bgra[14] = paint_colors[(BIT(etc[4], 3) << 1) | (BIT(etc[6], 3))]; + rg_etc2_rgb8_decode_block(etc + 8, bgra); - // m,n,o,p - bgra[ 3] = paint_colors[(BIT(etc[4], 4) << 1) | (BIT(etc[6], 4))]; - bgra[ 7] = paint_colors[(BIT(etc[4], 5) << 1) | (BIT(etc[6], 5))]; - bgra[11] = paint_colors[(BIT(etc[4], 6) << 1) | (BIT(etc[6], 6))]; - bgra[15] = paint_colors[(BIT(etc[4], 7) << 1) | (BIT(etc[6], 7))]; - return; + multiplier = BITS(etc[1], 4, 7); + table_index = BITS(etc[1], 0, 3); + + for (int x = 0, k = 0; x < 4; x++) + for (int y = 0; y < 4; y++, k += 3) + { + const uint32_t byte = (k >> 3); // = [k/8] + const uint32_t bit = k - (byte << 3); // = k%8 + const uint32_t rgb = bgra[(y << 2) + x]; + uint32_t index, alpha, R, G, B; + + if (bit < 6) + index = BITS(etc[byte + 2], 5 - bit, 7 - bit); + else if (bit == 6) + index = (BITS(etc[byte + 2], 0, 1) << 1) | BIT(etc[byte + 3], 7); + else // bit == 7 + index = (BIT(etc[byte + 2], 0) << 2) | BITS(etc[byte + 3], 6, 7); + alpha = CLAMP(base_codeword + kAlphaModifiers[table_index][index] * multiplier); + R = MIN(R_VAL(&rgb), alpha); + G = MIN(G_VAL(&rgb), alpha); + B = MIN(B_VAL(&rgb), alpha); + bgra[(y << 2) + x] = BGRA(R, G, B, alpha); + } } --