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);
+       }
 }

-- 


Reply via email to