util: move shared rgtc code to util (v2)
authorDave Airlie <airlied@redhat.com>
Tue, 16 Sep 2014 05:33:29 +0000 (15:33 +1000)
committerDave Airlie <airlied@redhat.com>
Wed, 17 Sep 2014 01:27:25 +0000 (11:27 +1000)
This was being shared using a ../../ get out of gallium into
mesa, and I swore when I did it I'd fix things when we got a util
dir, we did, so I have.

v2: move RGTC_DEBUG define

Reviewed-by: Jason Ekstrand <jason.ekstrand@intel.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>
src/gallium/auxiliary/util/u_format_latc.c
src/gallium/auxiliary/util/u_format_rgtc.c
src/mesa/main/texcompress_rgtc.c
src/mesa/main/texcompress_rgtc_tmp.h [deleted file]
src/util/Makefile.sources
src/util/rgtc.c [new file with mode: 0644]
src/util/rgtc.h [new file with mode: 0644]
src/util/texcompress_rgtc_tmp.h [new file with mode: 0644]

index caab7e87a3fe8c257f59353631a962d1259ca58d..31d72b5a0ab5fa10e9aa7f2a852696888ac45f6f 100644 (file)
 #include "u_format.h"
 #include "u_format_rgtc.h"
 #include "u_format_latc.h"
 #include "u_format.h"
 #include "u_format_rgtc.h"
 #include "u_format_latc.h"
-
-static void u_format_unsigned_encode_rgtc_ubyte(uint8_t *blkaddr, uint8_t srccolors[4][4],
-                                              int numxpixels, int numypixels);
-
-static void u_format_unsigned_fetch_texel_rgtc(unsigned srcRowStride, const uint8_t *pixdata,
-                                              unsigned i, unsigned j, uint8_t *value, unsigned comps);
-
-static void u_format_signed_encode_rgtc_ubyte(int8_t *blkaddr, int8_t srccolors[4][4],
-                                            int numxpixels, int numypixels);
-
-static void u_format_signed_fetch_texel_rgtc(unsigned srcRowStride, const int8_t *pixdata,
-                                              unsigned i, unsigned j, int8_t *value, unsigned comps);
+#include "util/rgtc.h"
 
 void
 util_format_latc1_unorm_fetch_rgba_8unorm(uint8_t *dst, const uint8_t *src, unsigned i, unsigned j)
 {
    /* Fix warnings here: */
 
 void
 util_format_latc1_unorm_fetch_rgba_8unorm(uint8_t *dst, const uint8_t *src, unsigned i, unsigned j)
 {
    /* Fix warnings here: */
-   (void) u_format_unsigned_encode_rgtc_ubyte;
-   (void) u_format_signed_encode_rgtc_ubyte;
+   (void) util_format_unsigned_encode_rgtc_ubyte;
+   (void) util_format_signed_encode_rgtc_ubyte;
 
 
-   u_format_unsigned_fetch_texel_rgtc(0, src, i, j, dst, 1);
+   util_format_unsigned_fetch_texel_rgtc(0, src, i, j, dst, 1);
    dst[1] = dst[0];
    dst[2] = dst[0];
    dst[3] = 255;
    dst[1] = dst[0];
    dst[2] = dst[0];
    dst[3] = 255;
@@ -79,7 +68,7 @@ util_format_latc1_unorm_unpack_rgba_float(float *dst_row, unsigned dst_stride, c
             for(i = 0; i < 4; ++i) {
                float *dst = dst_row + (y + j)*dst_stride/sizeof(*dst_row) + (x + i)*4;
                uint8_t tmp_r;
             for(i = 0; i < 4; ++i) {
                float *dst = dst_row + (y + j)*dst_stride/sizeof(*dst_row) + (x + i)*4;
                uint8_t tmp_r;
-               u_format_unsigned_fetch_texel_rgtc(0, src, i, j, &tmp_r, 1);
+               util_format_unsigned_fetch_texel_rgtc(0, src, i, j, &tmp_r, 1);
                dst[0] =
                dst[1] =
                dst[2] = ubyte_to_float(tmp_r);
                dst[0] =
                dst[1] =
                dst[2] = ubyte_to_float(tmp_r);
@@ -103,7 +92,7 @@ util_format_latc1_unorm_fetch_rgba_float(float *dst, const uint8_t *src, unsigne
 {
    uint8_t tmp_r;
 
 {
    uint8_t tmp_r;
 
-   u_format_unsigned_fetch_texel_rgtc(0, src, i, j, &tmp_r, 1);
+   util_format_unsigned_fetch_texel_rgtc(0, src, i, j, &tmp_r, 1);
    dst[0] =
    dst[1] =
    dst[2] = ubyte_to_float(tmp_r);
    dst[0] =
    dst[1] =
    dst[2] = ubyte_to_float(tmp_r);
@@ -147,7 +136,7 @@ util_format_latc1_snorm_unpack_rgba_float(float *dst_row, unsigned dst_stride, c
             for(i = 0; i < 4; ++i) {
                float *dst = dst_row + (y + j)*dst_stride/sizeof(*dst_row) + (x + i)*4;
                int8_t tmp_r;
             for(i = 0; i < 4; ++i) {
                float *dst = dst_row + (y + j)*dst_stride/sizeof(*dst_row) + (x + i)*4;
                int8_t tmp_r;
-               u_format_signed_fetch_texel_rgtc(0, src, i, j, &tmp_r, 1);
+               util_format_signed_fetch_texel_rgtc(0, src, i, j, &tmp_r, 1);
                dst[0] =
                dst[1] =
                dst[2] = byte_to_float_tex(tmp_r);
                dst[0] =
                dst[1] =
                dst[2] = byte_to_float_tex(tmp_r);
@@ -165,7 +154,7 @@ util_format_latc1_snorm_fetch_rgba_float(float *dst, const uint8_t *src, unsigne
 {
    int8_t tmp_r;
 
 {
    int8_t tmp_r;
 
-   u_format_signed_fetch_texel_rgtc(0, (int8_t *)src, i, j, &tmp_r, 1);
+   util_format_signed_fetch_texel_rgtc(0, (int8_t *)src, i, j, &tmp_r, 1);
    dst[0] =
    dst[1] =
    dst[2] = byte_to_float_tex(tmp_r);
    dst[0] =
    dst[1] =
    dst[2] = byte_to_float_tex(tmp_r);
@@ -176,10 +165,10 @@ util_format_latc1_snorm_fetch_rgba_float(float *dst, const uint8_t *src, unsigne
 void
 util_format_latc2_unorm_fetch_rgba_8unorm(uint8_t *dst, const uint8_t *src, unsigned i, unsigned j)
 {
 void
 util_format_latc2_unorm_fetch_rgba_8unorm(uint8_t *dst, const uint8_t *src, unsigned i, unsigned j)
 {
-   u_format_unsigned_fetch_texel_rgtc(0, src, i, j, dst, 2);
+   util_format_unsigned_fetch_texel_rgtc(0, src, i, j, dst, 2);
    dst[1] = dst[0];
    dst[2] = dst[0];
    dst[1] = dst[0];
    dst[2] = dst[0];
-   u_format_unsigned_fetch_texel_rgtc(0, src + 8, i, j, dst + 3, 2);
+   util_format_unsigned_fetch_texel_rgtc(0, src + 8, i, j, dst + 3, 2);
 }
 
 void
 }
 
 void
@@ -213,8 +202,8 @@ util_format_latc2_unorm_unpack_rgba_float(float *dst_row, unsigned dst_stride, c
             for(i = 0; i < 4; ++i) {
                float *dst = dst_row + (y + j)*dst_stride/sizeof(*dst_row) + (x + i)*4;
                uint8_t tmp_r, tmp_g;
             for(i = 0; i < 4; ++i) {
                float *dst = dst_row + (y + j)*dst_stride/sizeof(*dst_row) + (x + i)*4;
                uint8_t tmp_r, tmp_g;
-               u_format_unsigned_fetch_texel_rgtc(0, src, i, j, &tmp_r, 2);
-               u_format_unsigned_fetch_texel_rgtc(0, src + 8, i, j, &tmp_g, 2);
+               util_format_unsigned_fetch_texel_rgtc(0, src, i, j, &tmp_r, 2);
+               util_format_unsigned_fetch_texel_rgtc(0, src + 8, i, j, &tmp_g, 2);
                dst[0] =
                dst[1] =
                dst[2] = ubyte_to_float(tmp_r);
                dst[0] =
                dst[1] =
                dst[2] = ubyte_to_float(tmp_r);
@@ -232,8 +221,8 @@ util_format_latc2_unorm_fetch_rgba_float(float *dst, const uint8_t *src, unsigne
 {
    uint8_t tmp_r, tmp_g;
 
 {
    uint8_t tmp_r, tmp_g;
 
-   u_format_unsigned_fetch_texel_rgtc(0, src, i, j, &tmp_r, 2);
-   u_format_unsigned_fetch_texel_rgtc(0, src + 8, i, j, &tmp_g, 2);
+   util_format_unsigned_fetch_texel_rgtc(0, src, i, j, &tmp_r, 2);
+   util_format_unsigned_fetch_texel_rgtc(0, src + 8, i, j, &tmp_g, 2);
    dst[0] =
    dst[1] =
    dst[2] = ubyte_to_float(tmp_r);
    dst[0] =
    dst[1] =
    dst[2] = ubyte_to_float(tmp_r);
@@ -272,8 +261,8 @@ util_format_latc2_snorm_unpack_rgba_float(float *dst_row, unsigned dst_stride, c
             for(i = 0; i < 4; ++i) {
                float *dst = dst_row + (y + j)*dst_stride/sizeof(*dst_row) + (x + i)*4;
                int8_t tmp_r, tmp_g;
             for(i = 0; i < 4; ++i) {
                float *dst = dst_row + (y + j)*dst_stride/sizeof(*dst_row) + (x + i)*4;
                int8_t tmp_r, tmp_g;
-               u_format_signed_fetch_texel_rgtc(0, src, i, j, &tmp_r, 2);
-               u_format_signed_fetch_texel_rgtc(0, src + 8, i, j, &tmp_g, 2);
+               util_format_signed_fetch_texel_rgtc(0, src, i, j, &tmp_r, 2);
+               util_format_signed_fetch_texel_rgtc(0, src + 8, i, j, &tmp_g, 2);
                dst[0] =
                dst[1] =
                dst[2] = byte_to_float_tex(tmp_r);
                dst[0] =
                dst[1] =
                dst[2] = byte_to_float_tex(tmp_r);
@@ -297,36 +286,11 @@ util_format_latc2_snorm_fetch_rgba_float(float *dst, const uint8_t *src, unsigne
 {
    int8_t tmp_r, tmp_g;
 
 {
    int8_t tmp_r, tmp_g;
 
-   u_format_signed_fetch_texel_rgtc(0, (int8_t *)src, i, j, &tmp_r, 2);
-   u_format_signed_fetch_texel_rgtc(0, (int8_t *)src + 8, i, j, &tmp_g, 2);
+   util_format_signed_fetch_texel_rgtc(0, (int8_t *)src, i, j, &tmp_r, 2);
+   util_format_signed_fetch_texel_rgtc(0, (int8_t *)src + 8, i, j, &tmp_g, 2);
    dst[0] =
    dst[1] =
    dst[2] = byte_to_float_tex(tmp_r);
    dst[3] = byte_to_float_tex(tmp_g);
 }
 
    dst[0] =
    dst[1] =
    dst[2] = byte_to_float_tex(tmp_r);
    dst[3] = byte_to_float_tex(tmp_g);
 }
 
-
-#define TAG(x) u_format_unsigned_##x
-#define TYPE uint8_t
-#define T_MIN 0
-#define T_MAX 255
-
-#include "../../../mesa/main/texcompress_rgtc_tmp.h"
-
-#undef TYPE
-#undef TAG
-#undef T_MIN
-#undef T_MAX
-
-
-#define TAG(x) u_format_signed_##x
-#define TYPE int8_t
-#define T_MIN (int8_t)-128
-#define T_MAX (int8_t)127
-
-#include "../../../mesa/main/texcompress_rgtc_tmp.h"
-
-#undef TYPE
-#undef TAG
-#undef T_MIN
-#undef T_MAX
index 758e337749ee7604989a3219bcd66efb36db9e99..15969174358eb5cc616bea942e1b9e459f501881 100644 (file)
 #include "u_math.h"
 #include "u_format.h"
 #include "u_format_rgtc.h"
 #include "u_math.h"
 #include "u_format.h"
 #include "u_format_rgtc.h"
-
-static void u_format_unsigned_encode_rgtc_ubyte(uint8_t *blkaddr, uint8_t srccolors[4][4],
-                                              int numxpixels, int numypixels);
-
-static void u_format_unsigned_fetch_texel_rgtc(unsigned srcRowStride, const uint8_t *pixdata,
-                                              unsigned i, unsigned j, uint8_t *value, unsigned comps);
-
-static void u_format_signed_encode_rgtc_ubyte(int8_t *blkaddr, int8_t srccolors[4][4],
-                                            int numxpixels, int numypixels);
-
-static void u_format_signed_fetch_texel_rgtc(unsigned srcRowStride, const int8_t *pixdata,
-                                              unsigned i, unsigned j, int8_t *value, unsigned comps);
+#include "util/rgtc.h"
 
 void
 util_format_rgtc1_unorm_fetch_rgba_8unorm(uint8_t *dst, const uint8_t *src, unsigned i, unsigned j)
 {
 
 void
 util_format_rgtc1_unorm_fetch_rgba_8unorm(uint8_t *dst, const uint8_t *src, unsigned i, unsigned j)
 {
-   u_format_unsigned_fetch_texel_rgtc(0, src, i, j, dst, 1);
+   util_format_unsigned_fetch_texel_rgtc(0, src, i, j, dst, 1);
    dst[1] = 0;
    dst[2] = 0;
    dst[3] = 255;
    dst[1] = 0;
    dst[2] = 0;
    dst[3] = 255;
@@ -61,7 +50,7 @@ util_format_rgtc1_unorm_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride
          for(j = 0; j < bh; ++j) {
             for(i = 0; i < bw; ++i) {
                uint8_t *dst = dst_row + (y + j)*dst_stride/sizeof(*dst_row) + (x + i)*comps;
          for(j = 0; j < bh; ++j) {
             for(i = 0; i < bw; ++i) {
                uint8_t *dst = dst_row + (y + j)*dst_stride/sizeof(*dst_row) + (x + i)*comps;
-              u_format_unsigned_fetch_texel_rgtc(0, src, i, j, dst, 1);
+              util_format_unsigned_fetch_texel_rgtc(0, src, i, j, dst, 1);
               dst[1] = 0;
               dst[2] = 0;
               dst[3] = 255;
               dst[1] = 0;
               dst[2] = 0;
               dst[3] = 255;
@@ -89,7 +78,7 @@ util_format_rgtc1_unorm_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride,
               tmp[j][i] = src_row[(y + j)*src_stride/sizeof(*src_row) + (x + i)*4];
             }
          }
               tmp[j][i] = src_row[(y + j)*src_stride/sizeof(*src_row) + (x + i)*4];
             }
          }
-         u_format_unsigned_encode_rgtc_ubyte(dst, tmp, 4, 4);
+         util_format_unsigned_encode_rgtc_ubyte(dst, tmp, 4, 4);
          dst += bytes_per_block;
       }
       dst_row += dst_stride / sizeof(*dst_row);
          dst += bytes_per_block;
       }
       dst_row += dst_stride / sizeof(*dst_row);
@@ -108,7 +97,7 @@ util_format_rgtc1_unorm_unpack_rgba_float(float *dst_row, unsigned dst_stride, c
             for(i = 0; i < 4; ++i) {
                float *dst = dst_row + (y + j)*dst_stride/sizeof(*dst_row) + (x + i)*4;
                uint8_t tmp_r;
             for(i = 0; i < 4; ++i) {
                float *dst = dst_row + (y + j)*dst_stride/sizeof(*dst_row) + (x + i)*4;
                uint8_t tmp_r;
-               u_format_unsigned_fetch_texel_rgtc(0, src, i, j, &tmp_r, 1);
+               util_format_unsigned_fetch_texel_rgtc(0, src, i, j, &tmp_r, 1);
                dst[0] = ubyte_to_float(tmp_r);
                dst[1] = 0.0;
                dst[2] = 0.0;
                dst[0] = ubyte_to_float(tmp_r);
                dst[1] = 0.0;
                dst[2] = 0.0;
@@ -136,7 +125,7 @@ util_format_rgtc1_unorm_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, c
               tmp[j][i] = float_to_ubyte(src_row[(y + j)*src_stride/sizeof(*src_row) + (x + i)*4]);
             }
          }
               tmp[j][i] = float_to_ubyte(src_row[(y + j)*src_stride/sizeof(*src_row) + (x + i)*4]);
             }
          }
-         u_format_unsigned_encode_rgtc_ubyte(dst, tmp, 4, 4);
+         util_format_unsigned_encode_rgtc_ubyte(dst, tmp, 4, 4);
          dst += bytes_per_block;
       }
       dst_row += dst_stride / sizeof(*dst_row);
          dst += bytes_per_block;
       }
       dst_row += dst_stride / sizeof(*dst_row);
@@ -147,7 +136,7 @@ void
 util_format_rgtc1_unorm_fetch_rgba_float(float *dst, const uint8_t *src, unsigned i, unsigned j)
 {
    uint8_t tmp_r;
 util_format_rgtc1_unorm_fetch_rgba_float(float *dst, const uint8_t *src, unsigned i, unsigned j)
 {
    uint8_t tmp_r;
-   u_format_unsigned_fetch_texel_rgtc(0, src, i, j, &tmp_r, 1);
+   util_format_unsigned_fetch_texel_rgtc(0, src, i, j, &tmp_r, 1);
    dst[0] = ubyte_to_float(tmp_r);
    dst[1] = 0.0;
    dst[2] = 0.0;
    dst[0] = ubyte_to_float(tmp_r);
    dst[1] = 0.0;
    dst[2] = 0.0;
@@ -187,7 +176,7 @@ util_format_rgtc1_snorm_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, c
               tmp[j][i] = float_to_byte_tex(src_row[(y + j)*src_stride/sizeof(*src_row) + (x + i)*4]);
             }
          }
               tmp[j][i] = float_to_byte_tex(src_row[(y + j)*src_stride/sizeof(*src_row) + (x + i)*4]);
             }
          }
-         u_format_signed_encode_rgtc_ubyte(dst, tmp, 4, 4);
+         util_format_signed_encode_rgtc_ubyte(dst, tmp, 4, 4);
          dst += bytes_per_block;
       }
       dst_row += dst_stride / sizeof(*dst_row);
          dst += bytes_per_block;
       }
       dst_row += dst_stride / sizeof(*dst_row);
@@ -206,7 +195,7 @@ util_format_rgtc1_snorm_unpack_rgba_float(float *dst_row, unsigned dst_stride, c
             for(i = 0; i < 4; ++i) {
                float *dst = dst_row + (y + j)*dst_stride/sizeof(*dst_row) + (x + i)*4;
                int8_t tmp_r;
             for(i = 0; i < 4; ++i) {
                float *dst = dst_row + (y + j)*dst_stride/sizeof(*dst_row) + (x + i)*4;
                int8_t tmp_r;
-               u_format_signed_fetch_texel_rgtc(0, src, i, j, &tmp_r, 1);
+               util_format_signed_fetch_texel_rgtc(0, src, i, j, &tmp_r, 1);
                dst[0] = byte_to_float_tex(tmp_r);
                dst[1] = 0.0;
                dst[2] = 0.0;
                dst[0] = byte_to_float_tex(tmp_r);
                dst[1] = 0.0;
                dst[2] = 0.0;
@@ -223,7 +212,7 @@ void
 util_format_rgtc1_snorm_fetch_rgba_float(float *dst, const uint8_t *src, unsigned i, unsigned j)
 {
    int8_t tmp_r;
 util_format_rgtc1_snorm_fetch_rgba_float(float *dst, const uint8_t *src, unsigned i, unsigned j)
 {
    int8_t tmp_r;
-   u_format_signed_fetch_texel_rgtc(0, (int8_t *)src, i, j, &tmp_r, 1);
+   util_format_signed_fetch_texel_rgtc(0, (int8_t *)src, i, j, &tmp_r, 1);
    dst[0] = byte_to_float_tex(tmp_r);
    dst[1] = 0.0;
    dst[2] = 0.0;
    dst[0] = byte_to_float_tex(tmp_r);
    dst[1] = 0.0;
    dst[2] = 0.0;
@@ -234,8 +223,8 @@ util_format_rgtc1_snorm_fetch_rgba_float(float *dst, const uint8_t *src, unsigne
 void
 util_format_rgtc2_unorm_fetch_rgba_8unorm(uint8_t *dst, const uint8_t *src, unsigned i, unsigned j)
 {
 void
 util_format_rgtc2_unorm_fetch_rgba_8unorm(uint8_t *dst, const uint8_t *src, unsigned i, unsigned j)
 {
-   u_format_unsigned_fetch_texel_rgtc(0, src, i, j, dst, 2);
-   u_format_unsigned_fetch_texel_rgtc(0, src + 8, i, j, dst + 1, 2);
+   util_format_unsigned_fetch_texel_rgtc(0, src, i, j, dst, 2);
+   util_format_unsigned_fetch_texel_rgtc(0, src + 8, i, j, dst + 1, 2);
    dst[2] = 0;
    dst[3] = 255;
 }
    dst[2] = 0;
    dst[3] = 255;
 }
@@ -253,8 +242,8 @@ util_format_rgtc2_unorm_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride
          for(j = 0; j < bh; ++j) {
             for(i = 0; i < bw; ++i) {
                uint8_t *dst = dst_row + (y + j)*dst_stride/sizeof(*dst_row) + (x + i)*comps;
          for(j = 0; j < bh; ++j) {
             for(i = 0; i < bw; ++i) {
                uint8_t *dst = dst_row + (y + j)*dst_stride/sizeof(*dst_row) + (x + i)*comps;
-              u_format_unsigned_fetch_texel_rgtc(0, src, i, j, dst, 2);
-              u_format_unsigned_fetch_texel_rgtc(0, src + 8, i, j, dst + 1, 2);
+              util_format_unsigned_fetch_texel_rgtc(0, src, i, j, dst, 2);
+              util_format_unsigned_fetch_texel_rgtc(0, src + 8, i, j, dst + 1, 2);
               dst[2] = 0;
               dst[3] = 255;
            }
               dst[2] = 0;
               dst[3] = 255;
            }
@@ -282,8 +271,8 @@ util_format_rgtc2_unorm_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride,
               tmp_g[j][i] = src_row[((y + j)*src_stride/sizeof(*src_row) + (x + i)*4) + 1];
             }
          }
               tmp_g[j][i] = src_row[((y + j)*src_stride/sizeof(*src_row) + (x + i)*4) + 1];
             }
          }
-         u_format_unsigned_encode_rgtc_ubyte(dst, tmp_r, 4, 4);
-         u_format_unsigned_encode_rgtc_ubyte(dst + 8, tmp_g, 4, 4);
+         util_format_unsigned_encode_rgtc_ubyte(dst, tmp_r, 4, 4);
+         util_format_unsigned_encode_rgtc_ubyte(dst + 8, tmp_g, 4, 4);
          dst += bytes_per_block;
       }
       dst_row += dst_stride / sizeof(*dst_row);
          dst += bytes_per_block;
       }
       dst_row += dst_stride / sizeof(*dst_row);
@@ -307,8 +296,8 @@ util_format_rxtc2_unorm_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, c
                tmp_g[j][i] = float_to_ubyte(src_row[(y + j)*src_stride/sizeof(*src_row) + (x + i)*4 + chan2off]);
             }
          }
                tmp_g[j][i] = float_to_ubyte(src_row[(y + j)*src_stride/sizeof(*src_row) + (x + i)*4 + chan2off]);
             }
          }
-         u_format_unsigned_encode_rgtc_ubyte(dst, tmp_r, 4, 4);
-         u_format_unsigned_encode_rgtc_ubyte(dst + 8, tmp_g, 4, 4);
+         util_format_unsigned_encode_rgtc_ubyte(dst, tmp_r, 4, 4);
+         util_format_unsigned_encode_rgtc_ubyte(dst + 8, tmp_g, 4, 4);
          dst += bytes_per_block;
       }
       dst_row += dst_stride / sizeof(*dst_row);
          dst += bytes_per_block;
       }
       dst_row += dst_stride / sizeof(*dst_row);
@@ -333,8 +322,8 @@ util_format_rgtc2_unorm_unpack_rgba_float(float *dst_row, unsigned dst_stride, c
             for(i = 0; i < 4; ++i) {
                float *dst = dst_row + (y + j)*dst_stride/sizeof(*dst_row) + (x + i)*4;
                uint8_t tmp_r, tmp_g;
             for(i = 0; i < 4; ++i) {
                float *dst = dst_row + (y + j)*dst_stride/sizeof(*dst_row) + (x + i)*4;
                uint8_t tmp_r, tmp_g;
-               u_format_unsigned_fetch_texel_rgtc(0, src, i, j, &tmp_r, 2);
-               u_format_unsigned_fetch_texel_rgtc(0, src + 8, i, j, &tmp_g, 2);
+               util_format_unsigned_fetch_texel_rgtc(0, src, i, j, &tmp_r, 2);
+               util_format_unsigned_fetch_texel_rgtc(0, src + 8, i, j, &tmp_g, 2);
                dst[0] = ubyte_to_float(tmp_r);
                dst[1] = ubyte_to_float(tmp_g);
                dst[2] = 0.0;
                dst[0] = ubyte_to_float(tmp_r);
                dst[1] = ubyte_to_float(tmp_g);
                dst[2] = 0.0;
@@ -351,8 +340,8 @@ void
 util_format_rgtc2_unorm_fetch_rgba_float(float *dst, const uint8_t *src, unsigned i, unsigned j)
 {
    uint8_t tmp_r, tmp_g;
 util_format_rgtc2_unorm_fetch_rgba_float(float *dst, const uint8_t *src, unsigned i, unsigned j)
 {
    uint8_t tmp_r, tmp_g;
-   u_format_unsigned_fetch_texel_rgtc(0, src, i, j, &tmp_r, 2);
-   u_format_unsigned_fetch_texel_rgtc(0, src + 8, i, j, &tmp_g, 2);
+   util_format_unsigned_fetch_texel_rgtc(0, src, i, j, &tmp_r, 2);
+   util_format_unsigned_fetch_texel_rgtc(0, src + 8, i, j, &tmp_g, 2);
    dst[0] = ubyte_to_float(tmp_r);
    dst[1] = ubyte_to_float(tmp_g);
    dst[2] = 0.0;
    dst[0] = ubyte_to_float(tmp_r);
    dst[1] = ubyte_to_float(tmp_g);
    dst[2] = 0.0;
@@ -390,8 +379,8 @@ util_format_rgtc2_snorm_unpack_rgba_float(float *dst_row, unsigned dst_stride, c
             for(i = 0; i < 4; ++i) {
                float *dst = dst_row + (y + j)*dst_stride/sizeof(*dst_row) + (x + i)*4;
                int8_t tmp_r, tmp_g;
             for(i = 0; i < 4; ++i) {
                float *dst = dst_row + (y + j)*dst_stride/sizeof(*dst_row) + (x + i)*4;
                int8_t tmp_r, tmp_g;
-               u_format_signed_fetch_texel_rgtc(0, src, i, j, &tmp_r, 2);
-               u_format_signed_fetch_texel_rgtc(0, src + 8, i, j, &tmp_g, 2);
+               util_format_signed_fetch_texel_rgtc(0, src, i, j, &tmp_r, 2);
+               util_format_signed_fetch_texel_rgtc(0, src + 8, i, j, &tmp_g, 2);
                dst[0] = byte_to_float_tex(tmp_r);
                dst[1] = byte_to_float_tex(tmp_g);
                dst[2] = 0.0;
                dst[0] = byte_to_float_tex(tmp_r);
                dst[1] = byte_to_float_tex(tmp_g);
                dst[2] = 0.0;
@@ -421,8 +410,8 @@ util_format_rxtc2_snorm_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, c
                tmp_g[j][i] = float_to_byte_tex(src_row[(y + j)*src_stride/sizeof(*src_row) + (x + i)*4 + chan2off]);
             }
          }
                tmp_g[j][i] = float_to_byte_tex(src_row[(y + j)*src_stride/sizeof(*src_row) + (x + i)*4 + chan2off]);
             }
          }
-         u_format_signed_encode_rgtc_ubyte(dst, tmp_r, 4, 4);
-         u_format_signed_encode_rgtc_ubyte(dst + 8, tmp_g, 4, 4);
+         util_format_signed_encode_rgtc_ubyte(dst, tmp_r, 4, 4);
+         util_format_signed_encode_rgtc_ubyte(dst + 8, tmp_g, 4, 4);
          dst += bytes_per_block;
       }
       dst_row += dst_stride / sizeof(*dst_row);
          dst += bytes_per_block;
       }
       dst_row += dst_stride / sizeof(*dst_row);
@@ -439,36 +428,11 @@ void
 util_format_rgtc2_snorm_fetch_rgba_float(float *dst, const uint8_t *src, unsigned i, unsigned j)
 {
    int8_t tmp_r, tmp_g;
 util_format_rgtc2_snorm_fetch_rgba_float(float *dst, const uint8_t *src, unsigned i, unsigned j)
 {
    int8_t tmp_r, tmp_g;
-   u_format_signed_fetch_texel_rgtc(0, (int8_t *)src, i, j, &tmp_r, 2);
-   u_format_signed_fetch_texel_rgtc(0, (int8_t *)src + 8, i, j, &tmp_g, 2);
+   util_format_signed_fetch_texel_rgtc(0, (int8_t *)src, i, j, &tmp_r, 2);
+   util_format_signed_fetch_texel_rgtc(0, (int8_t *)src + 8, i, j, &tmp_g, 2);
    dst[0] = byte_to_float_tex(tmp_r);
    dst[1] = byte_to_float_tex(tmp_g);
    dst[2] = 0.0;
    dst[3] = 1.0;
 }
 
    dst[0] = byte_to_float_tex(tmp_r);
    dst[1] = byte_to_float_tex(tmp_g);
    dst[2] = 0.0;
    dst[3] = 1.0;
 }
 
-
-#define TAG(x) u_format_unsigned_##x
-#define TYPE uint8_t
-#define T_MIN 0
-#define T_MAX 255
-
-#include "../../../mesa/main/texcompress_rgtc_tmp.h"
-
-#undef TYPE
-#undef TAG
-#undef T_MIN
-#undef T_MAX
-
-
-#define TAG(x) u_format_signed_##x
-#define TYPE int8_t
-#define T_MIN (int8_t)-128
-#define T_MAX (int8_t)127
-
-#include "../../../mesa/main/texcompress_rgtc_tmp.h"
-
-#undef TYPE
-#undef TAG
-#undef T_MIN
-#undef T_MAX
index 1012699f55538fd79b35a773d2ce6f55a80187af..f7ee24d47fe62777f03efd05529212b24b445d2b 100644 (file)
 #include "macros.h"
 #include "mipmap.h"
 #include "texcompress.h"
 #include "macros.h"
 #include "mipmap.h"
 #include "texcompress.h"
+#include "util/rgtc.h"
 #include "texcompress_rgtc.h"
 #include "texstore.h"
 
 #include "texcompress_rgtc.h"
 #include "texstore.h"
 
-
-#define RGTC_DEBUG 0
-
-static void unsigned_encode_rgtc_ubyte(GLubyte *blkaddr, GLubyte srccolors[4][4],
-                                       GLint numxpixels, GLint numypixels);
-static void signed_encode_rgtc_ubyte(GLbyte *blkaddr, GLbyte srccolors[4][4],
-                            GLint numxpixels, GLint numypixels);
-
-static void unsigned_fetch_texel_rgtc(unsigned srcRowStride, const GLubyte *pixdata,
-                                     unsigned i, unsigned j, GLubyte *value, unsigned comps);
-
-static void signed_fetch_texel_rgtc(unsigned srcRowStride, const GLbyte *pixdata,
-                                     unsigned i, unsigned j, GLbyte *value, unsigned comps);
-
 static void extractsrc_u( GLubyte srcpixels[4][4], const GLubyte *srcaddr,
                          GLint srcRowStride, GLint numxpixels, GLint numypixels, GLint comps)
 {
 static void extractsrc_u( GLubyte srcpixels[4][4], const GLubyte *srcaddr,
                          GLint srcRowStride, GLint numxpixels, GLint numypixels, GLint comps)
 {
@@ -121,7 +108,7 @@ _mesa_texstore_red_rgtc1(TEXSTORE_PARAMS)
         if (srcWidth > i + 3) numxpixels = 4;
         else numxpixels = srcWidth - i;
         extractsrc_u(srcpixels, srcaddr, srcWidth, numxpixels, numypixels, 1);
         if (srcWidth > i + 3) numxpixels = 4;
         else numxpixels = srcWidth - i;
         extractsrc_u(srcpixels, srcaddr, srcWidth, numxpixels, numypixels, 1);
-        unsigned_encode_rgtc_ubyte(blkaddr, srcpixels, numxpixels, numypixels);
+        util_format_unsigned_encode_rgtc_ubyte(blkaddr, srcpixels, numxpixels, numypixels);
         srcaddr += numxpixels;
         blkaddr += 8;
       }
         srcaddr += numxpixels;
         blkaddr += 8;
       }
@@ -168,7 +155,7 @@ _mesa_texstore_signed_red_rgtc1(TEXSTORE_PARAMS)
         if (srcWidth > i + 3) numxpixels = 4;
         else numxpixels = srcWidth - i;
         extractsrc_s(srcpixels, srcaddr, srcWidth, numxpixels, numypixels, 1);
         if (srcWidth > i + 3) numxpixels = 4;
         else numxpixels = srcWidth - i;
         extractsrc_s(srcpixels, srcaddr, srcWidth, numxpixels, numypixels, 1);
-        signed_encode_rgtc_ubyte(blkaddr, srcpixels, numxpixels, numypixels);
+        util_format_signed_encode_rgtc_ubyte(blkaddr, srcpixels, numxpixels, numypixels);
         srcaddr += numxpixels;
         blkaddr += 8;
       }
         srcaddr += numxpixels;
         blkaddr += 8;
       }
@@ -216,11 +203,11 @@ _mesa_texstore_rg_rgtc2(TEXSTORE_PARAMS)
         if (srcWidth > i + 3) numxpixels = 4;
         else numxpixels = srcWidth - i;
         extractsrc_u(srcpixels, srcaddr, srcWidth, numxpixels, numypixels, 2);
         if (srcWidth > i + 3) numxpixels = 4;
         else numxpixels = srcWidth - i;
         extractsrc_u(srcpixels, srcaddr, srcWidth, numxpixels, numypixels, 2);
-        unsigned_encode_rgtc_ubyte(blkaddr, srcpixels, numxpixels, numypixels);
+        util_format_unsigned_encode_rgtc_ubyte(blkaddr, srcpixels, numxpixels, numypixels);
 
         blkaddr += 8;
         extractsrc_u(srcpixels, (GLubyte *)srcaddr + 1, srcWidth, numxpixels, numypixels, 2);
 
         blkaddr += 8;
         extractsrc_u(srcpixels, (GLubyte *)srcaddr + 1, srcWidth, numxpixels, numypixels, 2);
-        unsigned_encode_rgtc_ubyte(blkaddr, srcpixels, numxpixels, numypixels);
+        util_format_unsigned_encode_rgtc_ubyte(blkaddr, srcpixels, numxpixels, numypixels);
 
         blkaddr += 8;
 
 
         blkaddr += 8;
 
@@ -271,11 +258,11 @@ _mesa_texstore_signed_rg_rgtc2(TEXSTORE_PARAMS)
         else numxpixels = srcWidth - i;
 
         extractsrc_s(srcpixels, srcaddr, srcWidth, numxpixels, numypixels, 2);
         else numxpixels = srcWidth - i;
 
         extractsrc_s(srcpixels, srcaddr, srcWidth, numxpixels, numypixels, 2);
-        signed_encode_rgtc_ubyte(blkaddr, srcpixels, numxpixels, numypixels);
+        util_format_signed_encode_rgtc_ubyte(blkaddr, srcpixels, numxpixels, numypixels);
         blkaddr += 8;
 
         extractsrc_s(srcpixels, srcaddr + 1, srcWidth, numxpixels, numypixels, 2);
         blkaddr += 8;
 
         extractsrc_s(srcpixels, srcaddr + 1, srcWidth, numxpixels, numypixels, 2);
-        signed_encode_rgtc_ubyte(blkaddr, srcpixels, numxpixels, numypixels);
+        util_format_signed_encode_rgtc_ubyte(blkaddr, srcpixels, numxpixels, numypixels);
         blkaddr += 8;
 
         srcaddr += numxpixels * 2;
         blkaddr += 8;
 
         srcaddr += numxpixels * 2;
@@ -289,40 +276,12 @@ _mesa_texstore_signed_rg_rgtc2(TEXSTORE_PARAMS)
    return GL_TRUE;
 }
 
    return GL_TRUE;
 }
 
-
-#define TAG(x) unsigned_##x
-
-#define TYPE GLubyte
-#define T_MIN 0
-#define T_MAX 0xff
-
-#include "texcompress_rgtc_tmp.h"
-
-#undef TAG
-#undef TYPE
-#undef T_MIN
-#undef T_MAX
-
-#define TAG(x) signed_##x
-#define TYPE GLbyte
-#define T_MIN (GLbyte)-128
-#define T_MAX (GLbyte)127
-
-#include "texcompress_rgtc_tmp.h"
-
-#undef TAG
-#undef TYPE
-#undef T_MIN
-#undef T_MAX
-
-
-
 static void
 fetch_red_rgtc1(const GLubyte *map,
                 GLint rowStride, GLint i, GLint j, GLfloat *texel)
 {
    GLubyte red;
 static void
 fetch_red_rgtc1(const GLubyte *map,
                 GLint rowStride, GLint i, GLint j, GLfloat *texel)
 {
    GLubyte red;
-   unsigned_fetch_texel_rgtc(rowStride, map, i, j, &red, 1);
+   util_format_unsigned_fetch_texel_rgtc(rowStride, map, i, j, &red, 1);
    texel[RCOMP] = UBYTE_TO_FLOAT(red);
    texel[GCOMP] = 0.0;
    texel[BCOMP] = 0.0;
    texel[RCOMP] = UBYTE_TO_FLOAT(red);
    texel[GCOMP] = 0.0;
    texel[BCOMP] = 0.0;
@@ -334,7 +293,7 @@ fetch_l_latc1(const GLubyte *map,
               GLint rowStride, GLint i, GLint j, GLfloat *texel)
 {
    GLubyte red;
               GLint rowStride, GLint i, GLint j, GLfloat *texel)
 {
    GLubyte red;
-   unsigned_fetch_texel_rgtc(rowStride, map, i, j, &red, 1);
+   util_format_unsigned_fetch_texel_rgtc(rowStride, map, i, j, &red, 1);
    texel[RCOMP] =
    texel[GCOMP] =
    texel[BCOMP] = UBYTE_TO_FLOAT(red);
    texel[RCOMP] =
    texel[GCOMP] =
    texel[BCOMP] = UBYTE_TO_FLOAT(red);
@@ -346,7 +305,7 @@ fetch_signed_red_rgtc1(const GLubyte *map,
                        GLint rowStride, GLint i, GLint j, GLfloat *texel)
 {
    GLbyte red;
                        GLint rowStride, GLint i, GLint j, GLfloat *texel)
 {
    GLbyte red;
-   signed_fetch_texel_rgtc(rowStride, (const GLbyte *) map,
+   util_format_signed_fetch_texel_rgtc(rowStride, (const GLbyte *) map,
                            i, j, &red, 1);
    texel[RCOMP] = BYTE_TO_FLOAT_TEX(red);
    texel[GCOMP] = 0.0;
                            i, j, &red, 1);
    texel[RCOMP] = BYTE_TO_FLOAT_TEX(red);
    texel[GCOMP] = 0.0;
@@ -359,7 +318,7 @@ fetch_signed_l_latc1(const GLubyte *map,
                      GLint rowStride, GLint i, GLint j, GLfloat *texel)
 {
    GLbyte red;
                      GLint rowStride, GLint i, GLint j, GLfloat *texel)
 {
    GLbyte red;
-   signed_fetch_texel_rgtc(rowStride, (GLbyte *) map,
+   util_format_signed_fetch_texel_rgtc(rowStride, (GLbyte *) map,
                            i, j, &red, 1);
    texel[RCOMP] =
    texel[GCOMP] =
                            i, j, &red, 1);
    texel[RCOMP] =
    texel[GCOMP] =
@@ -372,10 +331,10 @@ fetch_rg_rgtc2(const GLubyte *map,
                GLint rowStride, GLint i, GLint j, GLfloat *texel)
 {
    GLubyte red, green;
                GLint rowStride, GLint i, GLint j, GLfloat *texel)
 {
    GLubyte red, green;
-   unsigned_fetch_texel_rgtc(rowStride,
+   util_format_unsigned_fetch_texel_rgtc(rowStride,
                              map,
                              i, j, &red, 2);
                              map,
                              i, j, &red, 2);
-   unsigned_fetch_texel_rgtc(rowStride,
+   util_format_unsigned_fetch_texel_rgtc(rowStride,
                              map + 8,
                              i, j, &green, 2);
    texel[RCOMP] = UBYTE_TO_FLOAT(red);
                              map + 8,
                              i, j, &green, 2);
    texel[RCOMP] = UBYTE_TO_FLOAT(red);
@@ -389,10 +348,10 @@ fetch_la_latc2(const GLubyte *map,
                GLint rowStride, GLint i, GLint j, GLfloat *texel)
 {
    GLubyte red, green;
                GLint rowStride, GLint i, GLint j, GLfloat *texel)
 {
    GLubyte red, green;
-   unsigned_fetch_texel_rgtc(rowStride,
+   util_format_unsigned_fetch_texel_rgtc(rowStride,
                              map,
                              i, j, &red, 2);
                              map,
                              i, j, &red, 2);
-   unsigned_fetch_texel_rgtc(rowStride,
+   util_format_unsigned_fetch_texel_rgtc(rowStride,
                              map + 8,
                              i, j, &green, 2);
    texel[RCOMP] =
                              map + 8,
                              i, j, &green, 2);
    texel[RCOMP] =
@@ -407,10 +366,10 @@ fetch_signed_rg_rgtc2(const GLubyte *map,
                       GLint rowStride, GLint i, GLint j, GLfloat *texel)
 {
    GLbyte red, green;
                       GLint rowStride, GLint i, GLint j, GLfloat *texel)
 {
    GLbyte red, green;
-   signed_fetch_texel_rgtc(rowStride,
+   util_format_signed_fetch_texel_rgtc(rowStride,
                            (GLbyte *) map,
                            i, j, &red, 2);
                            (GLbyte *) map,
                            i, j, &red, 2);
-   signed_fetch_texel_rgtc(rowStride,
+   util_format_signed_fetch_texel_rgtc(rowStride,
                            (GLbyte *) map + 8,
                            i, j, &green, 2);
    texel[RCOMP] = BYTE_TO_FLOAT_TEX(red);
                            (GLbyte *) map + 8,
                            i, j, &green, 2);
    texel[RCOMP] = BYTE_TO_FLOAT_TEX(red);
@@ -425,10 +384,10 @@ fetch_signed_la_latc2(const GLubyte *map,
                       GLint rowStride, GLint i, GLint j, GLfloat *texel)
 {
    GLbyte red, green;
                       GLint rowStride, GLint i, GLint j, GLfloat *texel)
 {
    GLbyte red, green;
-   signed_fetch_texel_rgtc(rowStride,
+   util_format_signed_fetch_texel_rgtc(rowStride,
                            (GLbyte *) map,
                            i, j, &red, 2);
                            (GLbyte *) map,
                            i, j, &red, 2);
-   signed_fetch_texel_rgtc(rowStride,
+   util_format_signed_fetch_texel_rgtc(rowStride,
                            (GLbyte *) map + 8,
                            i, j, &green, 2);
    texel[RCOMP] =
                            (GLbyte *) map + 8,
                            i, j, &green, 2);
    texel[RCOMP] =
diff --git a/src/mesa/main/texcompress_rgtc_tmp.h b/src/mesa/main/texcompress_rgtc_tmp.h
deleted file mode 100644 (file)
index 5fa9de6..0000000
+++ /dev/null
@@ -1,418 +0,0 @@
-/*
- * Copyright (C) 2011 Red Hat Inc.
- * 
- * block compression parts are:
- * Copyright (C) 2004  Roland Scheidegger   All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Author:
- *    Dave Airlie
- */
-
-/* included by texcompress_rgtc to define byte/ubyte compressors */
-
-static void TAG(fetch_texel_rgtc)(unsigned srcRowStride, const TYPE *pixdata,
-                                 unsigned i, unsigned j, TYPE *value, unsigned comps)
-{
-   TYPE decode;
-   const TYPE *blksrc = (pixdata + ((srcRowStride + 3) / 4 * (j / 4) + (i / 4)) * 8 * comps);
-   const TYPE alpha0 = blksrc[0];
-   const TYPE alpha1 = blksrc[1];
-   const char bit_pos = ((j&3) * 4 + (i&3)) * 3;
-   const unsigned char acodelow = blksrc[2 + bit_pos / 8];
-   const unsigned char acodehigh = (3 + bit_pos / 8) < 8 ? blksrc[3 + bit_pos / 8] : 0;
-   const unsigned char code = (acodelow >> (bit_pos & 0x7) |
-      (acodehigh  << (8 - (bit_pos & 0x7)))) & 0x7;
-
-   if (code == 0)
-      decode = alpha0;
-   else if (code == 1)
-      decode = alpha1;
-   else if (alpha0 > alpha1)
-      decode = ((alpha0 * (8 - code) + (alpha1 * (code - 1))) / 7);
-   else if (code < 6)
-      decode = ((alpha0 * (6 - code) + (alpha1 * (code - 1))) / 5);
-   else if (code == 6)
-      decode = T_MIN;
-   else
-      decode = T_MAX;
-
-   *value = decode;
-}
-
-static void TAG(write_rgtc_encoded_channel)(TYPE *blkaddr,
-                                           TYPE alphabase1,
-                                           TYPE alphabase2,
-                                           TYPE alphaenc[16])
-{
-   *blkaddr++ = alphabase1;
-   *blkaddr++ = alphabase2;
-   *blkaddr++ = alphaenc[0] | (alphaenc[1] << 3) | ((alphaenc[2] & 3) << 6);
-   *blkaddr++ = (alphaenc[2] >> 2) | (alphaenc[3] << 1) | (alphaenc[4] << 4) | ((alphaenc[5] & 1) << 7);
-   *blkaddr++ = (alphaenc[5] >> 1) | (alphaenc[6] << 2) | (alphaenc[7] << 5);
-   *blkaddr++ = alphaenc[8] | (alphaenc[9] << 3) | ((alphaenc[10] & 3) << 6);
-   *blkaddr++ = (alphaenc[10] >> 2) | (alphaenc[11] << 1) | (alphaenc[12] << 4) | ((alphaenc[13] & 1) << 7);
-   *blkaddr++ = (alphaenc[13] >> 1) | (alphaenc[14] << 2) | (alphaenc[15] << 5);
-}
-
-static void TAG(encode_rgtc_ubyte)(TYPE *blkaddr, TYPE srccolors[4][4],
-                            int numxpixels, int numypixels)
-{
-   TYPE alphabase[2], alphause[2];
-   short alphatest[2] = { 0 };
-   unsigned int alphablockerror1, alphablockerror2, alphablockerror3;
-   TYPE i, j, aindex, acutValues[7];
-   TYPE alphaenc1[16], alphaenc2[16], alphaenc3[16];
-   int alphaabsmin = 0, alphaabsmax = 0;
-   short alphadist;
-
-   /* find lowest and highest alpha value in block, alphabase[0] lowest, alphabase[1] highest */
-   alphabase[0] = T_MAX; alphabase[1] = T_MIN;
-   for (j = 0; j < numypixels; j++) {
-      for (i = 0; i < numxpixels; i++) {
-        if (srccolors[j][i] == T_MIN)
-            alphaabsmin = 1;
-         else if (srccolors[j][i] == T_MAX)
-            alphaabsmax = 1;
-         else {
-            if (srccolors[j][i] > alphabase[1])
-               alphabase[1] = srccolors[j][i];
-            if (srccolors[j][i] < alphabase[0])
-               alphabase[0] = srccolors[j][i];
-         }
-      }
-   }
-
-
-   if (((alphabase[0] > alphabase[1]) && !(alphaabsmin && alphaabsmax))
-       || (alphabase[0] == alphabase[1] && !alphaabsmin && !alphaabsmax)) { /* one color, either max or min */
-      /* shortcut here since it is a very common case (and also avoids later problems) */
-      /* could also thest for alpha0 == alpha1 (and not min/max), but probably not common, so don't bother */
-
-      *blkaddr++ = srccolors[0][0];
-      blkaddr++;
-      *blkaddr++ = 0;
-      *blkaddr++ = 0;
-      *blkaddr++ = 0;
-      *blkaddr++ = 0;
-      *blkaddr++ = 0;
-      *blkaddr++ = 0;
-#if RGTC_DEBUG
-      fprintf(stderr, "enc0 used\n");
-#endif
-      return;
-   }
-
-   /* find best encoding for alpha0 > alpha1 */
-   /* it's possible this encoding is better even if both alphaabsmin and alphaabsmax are true */
-   alphablockerror1 = 0x0;
-   alphablockerror2 = 0xffffffff;
-   alphablockerror3 = 0xffffffff;
-   if (alphaabsmin) alphause[0] = T_MIN;
-   else alphause[0] = alphabase[0];
-   if (alphaabsmax) alphause[1] = T_MAX;
-   else alphause[1] = alphabase[1];
-   /* calculate the 7 cut values, just the middle between 2 of the computed alpha values */
-   for (aindex = 0; aindex < 7; aindex++) {
-      /* don't forget here is always rounded down */
-      acutValues[aindex] = (alphause[0] * (2*aindex + 1) + alphause[1] * (14 - (2*aindex + 1))) / 14;
-   }
-
-   for (j = 0; j < numypixels; j++) {
-      for (i = 0; i < numxpixels; i++) {
-         /* maybe it's overkill to have the most complicated calculation just for the error
-            calculation which we only need to figure out if encoding1 or encoding2 is better... */
-         if (srccolors[j][i] > acutValues[0]) {
-            alphaenc1[4*j + i] = 0;
-            alphadist = srccolors[j][i] - alphause[1];
-         }
-         else if (srccolors[j][i] > acutValues[1]) {
-            alphaenc1[4*j + i] = 2;
-            alphadist = srccolors[j][i] - (alphause[1] * 6 + alphause[0] * 1) / 7;
-         }
-         else if (srccolors[j][i] > acutValues[2]) {
-            alphaenc1[4*j + i] = 3;
-            alphadist = srccolors[j][i] - (alphause[1] * 5 + alphause[0] * 2) / 7;
-         }
-         else if (srccolors[j][i] > acutValues[3]) {
-            alphaenc1[4*j + i] = 4;
-            alphadist = srccolors[j][i] - (alphause[1] * 4 + alphause[0] * 3) / 7;
-         }
-         else if (srccolors[j][i] > acutValues[4]) {
-            alphaenc1[4*j + i] = 5;
-            alphadist = srccolors[j][i] - (alphause[1] * 3 + alphause[0] * 4) / 7;
-         }
-         else if (srccolors[j][i] > acutValues[5]) {
-            alphaenc1[4*j + i] = 6;
-            alphadist = srccolors[j][i] - (alphause[1] * 2 + alphause[0] * 5) / 7;
-         }
-         else if (srccolors[j][i] > acutValues[6]) {
-            alphaenc1[4*j + i] = 7;
-            alphadist = srccolors[j][i] - (alphause[1] * 1 + alphause[0] * 6) / 7;
-         }
-         else {
-            alphaenc1[4*j + i] = 1;
-            alphadist = srccolors[j][i] - alphause[0];
-         }
-         alphablockerror1 += alphadist * alphadist;
-      }
-   }
-
-#if RGTC_DEBUG
-   for (i = 0; i < 16; i++) {
-      fprintf(stderr, "%d ", alphaenc1[i]);
-   }
-   fprintf(stderr, "cutVals ");
-   for (i = 0; i < 7; i++) {
-      fprintf(stderr, "%d ", acutValues[i]);
-   }
-   fprintf(stderr, "srcVals ");
-   for (j = 0; j < numypixels; j++) {
-      for (i = 0; i < numxpixels; i++) {
-        fprintf(stderr, "%d ", srccolors[j][i]);
-      }
-   }
-   fprintf(stderr, "\n");
-#endif
-
-   /* it's not very likely this encoding is better if both alphaabsmin and alphaabsmax
-      are false but try it anyway */
-   if (alphablockerror1 >= 32) {
-
-      /* don't bother if encoding is already very good, this condition should also imply
-      we have valid alphabase colors which we absolutely need (alphabase[0] <= alphabase[1]) */
-      alphablockerror2 = 0;
-      for (aindex = 0; aindex < 5; aindex++) {
-         /* don't forget here is always rounded down */
-         acutValues[aindex] = (alphabase[0] * (10 - (2*aindex + 1)) + alphabase[1] * (2*aindex + 1)) / 10;
-      }
-      for (j = 0; j < numypixels; j++) {
-         for (i = 0; i < numxpixels; i++) {
-             /* maybe it's overkill to have the most complicated calculation just for the error
-               calculation which we only need to figure out if encoding1 or encoding2 is better... */
-            if (srccolors[j][i] == T_MIN) {
-               alphaenc2[4*j + i] = 6;
-               alphadist = 0;
-            }
-            else if (srccolors[j][i] == T_MAX) {
-               alphaenc2[4*j + i] = 7;
-               alphadist = 0;
-            }
-            else if (srccolors[j][i] <= acutValues[0]) {
-               alphaenc2[4*j + i] = 0;
-               alphadist = srccolors[j][i] - alphabase[0];
-            }
-            else if (srccolors[j][i] <= acutValues[1]) {
-               alphaenc2[4*j + i] = 2;
-               alphadist = srccolors[j][i] - (alphabase[0] * 4 + alphabase[1] * 1) / 5;
-            }
-            else if (srccolors[j][i] <= acutValues[2]) {
-               alphaenc2[4*j + i] = 3;
-               alphadist = srccolors[j][i] - (alphabase[0] * 3 + alphabase[1] * 2) / 5;
-            }
-            else if (srccolors[j][i] <= acutValues[3]) {
-               alphaenc2[4*j + i] = 4;
-               alphadist = srccolors[j][i] - (alphabase[0] * 2 + alphabase[1] * 3) / 5;
-            }
-            else if (srccolors[j][i] <= acutValues[4]) {
-               alphaenc2[4*j + i] = 5;
-               alphadist = srccolors[j][i] - (alphabase[0] * 1 + alphabase[1] * 4) / 5;
-            }
-            else {
-               alphaenc2[4*j + i] = 1;
-               alphadist = srccolors[j][i] - alphabase[1];
-            }
-            alphablockerror2 += alphadist * alphadist;
-         }
-      }
-
-
-      /* skip this if the error is already very small
-         this encoding is MUCH better on average than #2 though, but expensive! */
-      if ((alphablockerror2 > 96) && (alphablockerror1 > 96)) {
-         short blockerrlin1 = 0;
-         short blockerrlin2 = 0;
-         TYPE nralphainrangelow = 0;
-         TYPE nralphainrangehigh = 0;
-         alphatest[0] = T_MAX;
-         alphatest[1] = T_MIN;
-         /* if we have large range it's likely there are values close to 0/255, try to map them to 0/255 */
-         for (j = 0; j < numypixels; j++) {
-            for (i = 0; i < numxpixels; i++) {
-               if ((srccolors[j][i] > alphatest[1]) && (srccolors[j][i] < (T_MAX -(alphabase[1] - alphabase[0]) / 28)))
-                  alphatest[1] = srccolors[j][i];
-               if ((srccolors[j][i] < alphatest[0]) && (srccolors[j][i] > (alphabase[1] - alphabase[0]) / 28))
-                  alphatest[0] = srccolors[j][i];
-            }
-         }
-          /* shouldn't happen too often, don't really care about those degenerated cases */
-          if (alphatest[1] <= alphatest[0]) {
-             alphatest[0] = T_MIN+1;
-             alphatest[1] = T_MAX-1;
-         }
-         for (aindex = 0; aindex < 5; aindex++) {
-         /* don't forget here is always rounded down */
-            acutValues[aindex] = (alphatest[0] * (10 - (2*aindex + 1)) + alphatest[1] * (2*aindex + 1)) / 10;
-         }
-
-         /* find the "average" difference between the alpha values and the next encoded value.
-            This is then used to calculate new base values.
-            Should there be some weighting, i.e. those values closer to alphatest[x] have more weight,
-            since they will see more improvement, and also because the values in the middle are somewhat
-            likely to get no improvement at all (because the base values might move in different directions)?
-            OTOH it would mean the values in the middle are even less likely to get an improvement
-         */
-         for (j = 0; j < numypixels; j++) {
-            for (i = 0; i < numxpixels; i++) {
-               if (srccolors[j][i] <= alphatest[0] / 2) {
-               }
-               else if (srccolors[j][i] > ((T_MAX + alphatest[1]) / 2)) {
-               }
-               else if (srccolors[j][i] <= acutValues[0]) {
-                  blockerrlin1 += (srccolors[j][i] - alphatest[0]);
-                  nralphainrangelow += 1;
-               }
-               else if (srccolors[j][i] <= acutValues[1]) {
-                  blockerrlin1 += (srccolors[j][i] - (alphatest[0] * 4 + alphatest[1] * 1) / 5);
-                  blockerrlin2 += (srccolors[j][i] - (alphatest[0] * 4 + alphatest[1] * 1) / 5);
-                  nralphainrangelow += 1;
-                  nralphainrangehigh += 1;
-               }
-               else if (srccolors[j][i] <= acutValues[2]) {
-                  blockerrlin1 += (srccolors[j][i] - (alphatest[0] * 3 + alphatest[1] * 2) / 5);
-                  blockerrlin2 += (srccolors[j][i] - (alphatest[0] * 3 + alphatest[1] * 2) / 5);
-                  nralphainrangelow += 1;
-                  nralphainrangehigh += 1;
-               }
-               else if (srccolors[j][i] <= acutValues[3]) {
-                  blockerrlin1 += (srccolors[j][i] - (alphatest[0] * 2 + alphatest[1] * 3) / 5);
-                  blockerrlin2 += (srccolors[j][i] - (alphatest[0] * 2 + alphatest[1] * 3) / 5);
-                  nralphainrangelow += 1;
-                  nralphainrangehigh += 1;
-               }
-               else if (srccolors[j][i] <= acutValues[4]) {
-                  blockerrlin1 += (srccolors[j][i] - (alphatest[0] * 1 + alphatest[1] * 4) / 5);
-                  blockerrlin2 += (srccolors[j][i] - (alphatest[0] * 1 + alphatest[1] * 4) / 5);
-                  nralphainrangelow += 1;
-                  nralphainrangehigh += 1;
-                  }
-               else {
-                  blockerrlin2 += (srccolors[j][i] - alphatest[1]);
-                  nralphainrangehigh += 1;
-               }
-            }
-         }
-         /* shouldn't happen often, needed to avoid div by zero */
-         if (nralphainrangelow == 0) nralphainrangelow = 1;
-         if (nralphainrangehigh == 0) nralphainrangehigh = 1;
-         alphatest[0] = alphatest[0] + (blockerrlin1 / nralphainrangelow);
-#if RGTC_DEBUG
-         fprintf(stderr, "block err lin low %d, nr %d\n", blockerrlin1, nralphainrangelow);
-         fprintf(stderr, "block err lin high %d, nr %d\n", blockerrlin2, nralphainrangehigh);
-#endif
-         /* again shouldn't really happen often... */
-         if (alphatest[0] < T_MIN) {
-            alphatest[0] = T_MIN;
-         }
-         alphatest[1] = alphatest[1] + (blockerrlin2 / nralphainrangehigh);
-         if (alphatest[1] > T_MAX) {
-            alphatest[1] = T_MAX;
-         }
-
-         alphablockerror3 = 0;
-         for (aindex = 0; aindex < 5; aindex++) {
-         /* don't forget here is always rounded down */
-            acutValues[aindex] = (alphatest[0] * (10 - (2*aindex + 1)) + alphatest[1] * (2*aindex + 1)) / 10;
-         }
-         for (j = 0; j < numypixels; j++) {
-            for (i = 0; i < numxpixels; i++) {
-                /* maybe it's overkill to have the most complicated calculation just for the error
-                  calculation which we only need to figure out if encoding1 or encoding2 is better... */
-               if (srccolors[j][i] <= alphatest[0] / 2) {
-                  alphaenc3[4*j + i] = 6;
-                  alphadist = srccolors[j][i];
-               }
-               else if (srccolors[j][i] > ((T_MAX + alphatest[1]) / 2)) {
-                  alphaenc3[4*j + i] = 7;
-                  alphadist = T_MAX - srccolors[j][i];
-               }
-               else if (srccolors[j][i] <= acutValues[0]) {
-                  alphaenc3[4*j + i] = 0;
-                  alphadist = srccolors[j][i] - alphatest[0];
-               }
-               else if (srccolors[j][i] <= acutValues[1]) {
-                 alphaenc3[4*j + i] = 2;
-                 alphadist = srccolors[j][i] - (alphatest[0] * 4 + alphatest[1] * 1) / 5;
-               }
-               else if (srccolors[j][i] <= acutValues[2]) {
-                  alphaenc3[4*j + i] = 3;
-                  alphadist = srccolors[j][i] - (alphatest[0] * 3 + alphatest[1] * 2) / 5;
-               }
-               else if (srccolors[j][i] <= acutValues[3]) {
-                  alphaenc3[4*j + i] = 4;
-                  alphadist = srccolors[j][i] - (alphatest[0] * 2 + alphatest[1] * 3) / 5;
-               }
-               else if (srccolors[j][i] <= acutValues[4]) {
-                  alphaenc3[4*j + i] = 5;
-                  alphadist = srccolors[j][i] - (alphatest[0] * 1 + alphatest[1] * 4) / 5;
-               }
-               else {
-                  alphaenc3[4*j + i] = 1;
-                  alphadist = srccolors[j][i] - alphatest[1];
-               }
-               alphablockerror3 += alphadist * alphadist;
-            }
-         }
-      }
-   }
-
-  /* write the alpha values and encoding back. */
-   if ((alphablockerror1 <= alphablockerror2) && (alphablockerror1 <= alphablockerror3)) {
-#if RGTC_DEBUG
-      if (alphablockerror1 > 96) fprintf(stderr, "enc1 used, error %d\n", alphablockerror1);
-      fprintf(stderr,"w1: min %d max %d au0 %d au1 %d\n",
-             T_MIN, T_MAX,
-             alphause[1], alphause[0]);
-#endif
-
-      TAG(write_rgtc_encoded_channel)( blkaddr, alphause[1], alphause[0], alphaenc1 );
-   }
-   else if (alphablockerror2 <= alphablockerror3) {
-#if RGTC_DEBUG
-      if (alphablockerror2 > 96) fprintf(stderr, "enc2 used, error %d\n", alphablockerror2);
-      fprintf(stderr,"w2: min %d max %d au0 %d au1 %d\n",
-             T_MIN, T_MAX,
-             alphabase[0], alphabase[1]);
-#endif
-
-      TAG(write_rgtc_encoded_channel)( blkaddr, alphabase[0], alphabase[1], alphaenc2 );
-   }
-   else {
-#if RGTC_DEBUG
-      fprintf(stderr, "enc3 used, error %d\n", alphablockerror3);
-      fprintf(stderr,"w3: min %d max %d au0 %d au1 %d\n",
-             T_MIN, T_MAX,
-             alphatest[0], alphatest[1]);
-#endif
-
-      TAG(write_rgtc_encoded_channel)( blkaddr, (TYPE)alphatest[0], (TYPE)alphatest[1], alphaenc3 );
-   }
-}
index b99aa25e86e8e8639c935dc31a0389298b4aed19..c34475a849371b1b648bf1588b7bf74681c3c0ae 100644 (file)
@@ -1,6 +1,7 @@
 MESA_UTIL_FILES :=     \
        hash_table.c    \
 MESA_UTIL_FILES :=     \
        hash_table.c    \
-       ralloc.c
+       ralloc.c \
+       rgtc.c
 
 MESA_UTIL_GENERATED_FILES = \
        format_srgb.c
 
 MESA_UTIL_GENERATED_FILES = \
        format_srgb.c
diff --git a/src/util/rgtc.c b/src/util/rgtc.c
new file mode 100644 (file)
index 0000000..6886ac0
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2011 Red Hat Inc.
+ * 
+ * block compression parts are:
+ * Copyright (C) 2004  Roland Scheidegger   All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Author:
+ *    Dave Airlie
+ */
+
+#include <inttypes.h>
+#include "macros.h"
+
+#include "rgtc.h"
+
+#define RGTC_DEBUG 0
+
+#define TAG(x) util_format_unsigned_##x
+
+#define TYPE unsigned char
+#define T_MIN 0
+#define T_MAX 0xff
+
+#include "texcompress_rgtc_tmp.h"
+
+#undef TAG
+#undef TYPE
+#undef T_MIN
+#undef T_MAX
+
+#define TAG(x) util_format_signed_##x
+#define TYPE signed char
+#define T_MIN (signed char)-128
+#define T_MAX (signed char)127
+
+#include "texcompress_rgtc_tmp.h"
+
+#undef TAG
+#undef TYPE
+#undef T_MIN
+#undef T_MAX
+
diff --git a/src/util/rgtc.h b/src/util/rgtc.h
new file mode 100644 (file)
index 0000000..6bba9f2
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * Copyright Â© 2014 Red Hat
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ */
+
+#ifndef _RGTC_H
+#define _RGTC_H
+
+void util_format_unsigned_fetch_texel_rgtc(unsigned srcRowStride, const unsigned char *pixdata,
+                                           unsigned i, unsigned j, unsigned char *value, unsigned comps);
+
+void util_format_signed_fetch_texel_rgtc(unsigned srcRowStride, const signed char *pixdata,
+                                           unsigned i, unsigned j, signed char *value, unsigned comps);
+
+void util_format_unsigned_encode_rgtc_ubyte(unsigned char *blkaddr, unsigned char srccolors[4][4],
+                                            int numxpixels, int numypixels);
+
+void util_format_signed_encode_rgtc_ubyte(signed char *blkaddr, signed char srccolors[4][4],
+                                            int numxpixels, int numypixels);
+#endif /* _RGTC_H */
diff --git a/src/util/texcompress_rgtc_tmp.h b/src/util/texcompress_rgtc_tmp.h
new file mode 100644 (file)
index 0000000..6bbae5e
--- /dev/null
@@ -0,0 +1,418 @@
+/*
+ * Copyright (C) 2011 Red Hat Inc.
+ * 
+ * block compression parts are:
+ * Copyright (C) 2004  Roland Scheidegger   All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Author:
+ *    Dave Airlie
+ */
+
+/* included by texcompress_rgtc to define byte/ubyte compressors */
+
+void TAG(fetch_texel_rgtc)(unsigned srcRowStride, const TYPE *pixdata,
+                          unsigned i, unsigned j, TYPE *value, unsigned comps)
+{
+   TYPE decode;
+   const TYPE *blksrc = (pixdata + ((srcRowStride + 3) / 4 * (j / 4) + (i / 4)) * 8 * comps);
+   const TYPE alpha0 = blksrc[0];
+   const TYPE alpha1 = blksrc[1];
+   const char bit_pos = ((j&3) * 4 + (i&3)) * 3;
+   const unsigned char acodelow = blksrc[2 + bit_pos / 8];
+   const unsigned char acodehigh = (3 + bit_pos / 8) < 8 ? blksrc[3 + bit_pos / 8] : 0;
+   const unsigned char code = (acodelow >> (bit_pos & 0x7) |
+      (acodehigh  << (8 - (bit_pos & 0x7)))) & 0x7;
+
+   if (code == 0)
+      decode = alpha0;
+   else if (code == 1)
+      decode = alpha1;
+   else if (alpha0 > alpha1)
+      decode = ((alpha0 * (8 - code) + (alpha1 * (code - 1))) / 7);
+   else if (code < 6)
+      decode = ((alpha0 * (6 - code) + (alpha1 * (code - 1))) / 5);
+   else if (code == 6)
+      decode = T_MIN;
+   else
+      decode = T_MAX;
+
+   *value = decode;
+}
+
+static void TAG(write_rgtc_encoded_channel)(TYPE *blkaddr,
+                                            TYPE alphabase1,
+                                            TYPE alphabase2,
+                                            TYPE alphaenc[16])
+{
+   *blkaddr++ = alphabase1;
+   *blkaddr++ = alphabase2;
+   *blkaddr++ = alphaenc[0] | (alphaenc[1] << 3) | ((alphaenc[2] & 3) << 6);
+   *blkaddr++ = (alphaenc[2] >> 2) | (alphaenc[3] << 1) | (alphaenc[4] << 4) | ((alphaenc[5] & 1) << 7);
+   *blkaddr++ = (alphaenc[5] >> 1) | (alphaenc[6] << 2) | (alphaenc[7] << 5);
+   *blkaddr++ = alphaenc[8] | (alphaenc[9] << 3) | ((alphaenc[10] & 3) << 6);
+   *blkaddr++ = (alphaenc[10] >> 2) | (alphaenc[11] << 1) | (alphaenc[12] << 4) | ((alphaenc[13] & 1) << 7);
+   *blkaddr++ = (alphaenc[13] >> 1) | (alphaenc[14] << 2) | (alphaenc[15] << 5);
+}
+
+void TAG(encode_rgtc_ubyte)(TYPE *blkaddr, TYPE srccolors[4][4],
+                            int numxpixels, int numypixels)
+{
+   TYPE alphabase[2], alphause[2];
+   short alphatest[2] = { 0 };
+   unsigned int alphablockerror1, alphablockerror2, alphablockerror3;
+   TYPE i, j, aindex, acutValues[7];
+   TYPE alphaenc1[16], alphaenc2[16], alphaenc3[16];
+   int alphaabsmin = 0, alphaabsmax = 0;
+   short alphadist;
+
+   /* find lowest and highest alpha value in block, alphabase[0] lowest, alphabase[1] highest */
+   alphabase[0] = T_MAX; alphabase[1] = T_MIN;
+   for (j = 0; j < numypixels; j++) {
+      for (i = 0; i < numxpixels; i++) {
+        if (srccolors[j][i] == T_MIN)
+            alphaabsmin = 1;
+         else if (srccolors[j][i] == T_MAX)
+            alphaabsmax = 1;
+         else {
+            if (srccolors[j][i] > alphabase[1])
+               alphabase[1] = srccolors[j][i];
+            if (srccolors[j][i] < alphabase[0])
+               alphabase[0] = srccolors[j][i];
+         }
+      }
+   }
+
+
+   if (((alphabase[0] > alphabase[1]) && !(alphaabsmin && alphaabsmax))
+       || (alphabase[0] == alphabase[1] && !alphaabsmin && !alphaabsmax)) { /* one color, either max or min */
+      /* shortcut here since it is a very common case (and also avoids later problems) */
+      /* could also thest for alpha0 == alpha1 (and not min/max), but probably not common, so don't bother */
+
+      *blkaddr++ = srccolors[0][0];
+      blkaddr++;
+      *blkaddr++ = 0;
+      *blkaddr++ = 0;
+      *blkaddr++ = 0;
+      *blkaddr++ = 0;
+      *blkaddr++ = 0;
+      *blkaddr++ = 0;
+#if RGTC_DEBUG
+      fprintf(stderr, "enc0 used\n");
+#endif
+      return;
+   }
+
+   /* find best encoding for alpha0 > alpha1 */
+   /* it's possible this encoding is better even if both alphaabsmin and alphaabsmax are true */
+   alphablockerror1 = 0x0;
+   alphablockerror2 = 0xffffffff;
+   alphablockerror3 = 0xffffffff;
+   if (alphaabsmin) alphause[0] = T_MIN;
+   else alphause[0] = alphabase[0];
+   if (alphaabsmax) alphause[1] = T_MAX;
+   else alphause[1] = alphabase[1];
+   /* calculate the 7 cut values, just the middle between 2 of the computed alpha values */
+   for (aindex = 0; aindex < 7; aindex++) {
+      /* don't forget here is always rounded down */
+      acutValues[aindex] = (alphause[0] * (2*aindex + 1) + alphause[1] * (14 - (2*aindex + 1))) / 14;
+   }
+
+   for (j = 0; j < numypixels; j++) {
+      for (i = 0; i < numxpixels; i++) {
+         /* maybe it's overkill to have the most complicated calculation just for the error
+            calculation which we only need to figure out if encoding1 or encoding2 is better... */
+         if (srccolors[j][i] > acutValues[0]) {
+            alphaenc1[4*j + i] = 0;
+            alphadist = srccolors[j][i] - alphause[1];
+         }
+         else if (srccolors[j][i] > acutValues[1]) {
+            alphaenc1[4*j + i] = 2;
+            alphadist = srccolors[j][i] - (alphause[1] * 6 + alphause[0] * 1) / 7;
+         }
+         else if (srccolors[j][i] > acutValues[2]) {
+            alphaenc1[4*j + i] = 3;
+            alphadist = srccolors[j][i] - (alphause[1] * 5 + alphause[0] * 2) / 7;
+         }
+         else if (srccolors[j][i] > acutValues[3]) {
+            alphaenc1[4*j + i] = 4;
+            alphadist = srccolors[j][i] - (alphause[1] * 4 + alphause[0] * 3) / 7;
+         }
+         else if (srccolors[j][i] > acutValues[4]) {
+            alphaenc1[4*j + i] = 5;
+            alphadist = srccolors[j][i] - (alphause[1] * 3 + alphause[0] * 4) / 7;
+         }
+         else if (srccolors[j][i] > acutValues[5]) {
+            alphaenc1[4*j + i] = 6;
+            alphadist = srccolors[j][i] - (alphause[1] * 2 + alphause[0] * 5) / 7;
+         }
+         else if (srccolors[j][i] > acutValues[6]) {
+            alphaenc1[4*j + i] = 7;
+            alphadist = srccolors[j][i] - (alphause[1] * 1 + alphause[0] * 6) / 7;
+         }
+         else {
+            alphaenc1[4*j + i] = 1;
+            alphadist = srccolors[j][i] - alphause[0];
+         }
+         alphablockerror1 += alphadist * alphadist;
+      }
+   }
+
+#if RGTC_DEBUG
+   for (i = 0; i < 16; i++) {
+      fprintf(stderr, "%d ", alphaenc1[i]);
+   }
+   fprintf(stderr, "cutVals ");
+   for (i = 0; i < 7; i++) {
+      fprintf(stderr, "%d ", acutValues[i]);
+   }
+   fprintf(stderr, "srcVals ");
+   for (j = 0; j < numypixels; j++) {
+      for (i = 0; i < numxpixels; i++) {
+        fprintf(stderr, "%d ", srccolors[j][i]);
+      }
+   }
+   fprintf(stderr, "\n");
+#endif
+
+   /* it's not very likely this encoding is better if both alphaabsmin and alphaabsmax
+      are false but try it anyway */
+   if (alphablockerror1 >= 32) {
+
+      /* don't bother if encoding is already very good, this condition should also imply
+      we have valid alphabase colors which we absolutely need (alphabase[0] <= alphabase[1]) */
+      alphablockerror2 = 0;
+      for (aindex = 0; aindex < 5; aindex++) {
+         /* don't forget here is always rounded down */
+         acutValues[aindex] = (alphabase[0] * (10 - (2*aindex + 1)) + alphabase[1] * (2*aindex + 1)) / 10;
+      }
+      for (j = 0; j < numypixels; j++) {
+         for (i = 0; i < numxpixels; i++) {
+             /* maybe it's overkill to have the most complicated calculation just for the error
+               calculation which we only need to figure out if encoding1 or encoding2 is better... */
+            if (srccolors[j][i] == T_MIN) {
+               alphaenc2[4*j + i] = 6;
+               alphadist = 0;
+            }
+            else if (srccolors[j][i] == T_MAX) {
+               alphaenc2[4*j + i] = 7;
+               alphadist = 0;
+            }
+            else if (srccolors[j][i] <= acutValues[0]) {
+               alphaenc2[4*j + i] = 0;
+               alphadist = srccolors[j][i] - alphabase[0];
+            }
+            else if (srccolors[j][i] <= acutValues[1]) {
+               alphaenc2[4*j + i] = 2;
+               alphadist = srccolors[j][i] - (alphabase[0] * 4 + alphabase[1] * 1) / 5;
+            }
+            else if (srccolors[j][i] <= acutValues[2]) {
+               alphaenc2[4*j + i] = 3;
+               alphadist = srccolors[j][i] - (alphabase[0] * 3 + alphabase[1] * 2) / 5;
+            }
+            else if (srccolors[j][i] <= acutValues[3]) {
+               alphaenc2[4*j + i] = 4;
+               alphadist = srccolors[j][i] - (alphabase[0] * 2 + alphabase[1] * 3) / 5;
+            }
+            else if (srccolors[j][i] <= acutValues[4]) {
+               alphaenc2[4*j + i] = 5;
+               alphadist = srccolors[j][i] - (alphabase[0] * 1 + alphabase[1] * 4) / 5;
+            }
+            else {
+               alphaenc2[4*j + i] = 1;
+               alphadist = srccolors[j][i] - alphabase[1];
+            }
+            alphablockerror2 += alphadist * alphadist;
+         }
+      }
+
+
+      /* skip this if the error is already very small
+         this encoding is MUCH better on average than #2 though, but expensive! */
+      if ((alphablockerror2 > 96) && (alphablockerror1 > 96)) {
+         short blockerrlin1 = 0;
+         short blockerrlin2 = 0;
+         TYPE nralphainrangelow = 0;
+         TYPE nralphainrangehigh = 0;
+         alphatest[0] = T_MAX;
+         alphatest[1] = T_MIN;
+         /* if we have large range it's likely there are values close to 0/255, try to map them to 0/255 */
+         for (j = 0; j < numypixels; j++) {
+            for (i = 0; i < numxpixels; i++) {
+               if ((srccolors[j][i] > alphatest[1]) && (srccolors[j][i] < (T_MAX -(alphabase[1] - alphabase[0]) / 28)))
+                  alphatest[1] = srccolors[j][i];
+               if ((srccolors[j][i] < alphatest[0]) && (srccolors[j][i] > (alphabase[1] - alphabase[0]) / 28))
+                  alphatest[0] = srccolors[j][i];
+            }
+         }
+          /* shouldn't happen too often, don't really care about those degenerated cases */
+          if (alphatest[1] <= alphatest[0]) {
+             alphatest[0] = T_MIN+1;
+             alphatest[1] = T_MAX-1;
+         }
+         for (aindex = 0; aindex < 5; aindex++) {
+         /* don't forget here is always rounded down */
+            acutValues[aindex] = (alphatest[0] * (10 - (2*aindex + 1)) + alphatest[1] * (2*aindex + 1)) / 10;
+         }
+
+         /* find the "average" difference between the alpha values and the next encoded value.
+            This is then used to calculate new base values.
+            Should there be some weighting, i.e. those values closer to alphatest[x] have more weight,
+            since they will see more improvement, and also because the values in the middle are somewhat
+            likely to get no improvement at all (because the base values might move in different directions)?
+            OTOH it would mean the values in the middle are even less likely to get an improvement
+         */
+         for (j = 0; j < numypixels; j++) {
+            for (i = 0; i < numxpixels; i++) {
+               if (srccolors[j][i] <= alphatest[0] / 2) {
+               }
+               else if (srccolors[j][i] > ((T_MAX + alphatest[1]) / 2)) {
+               }
+               else if (srccolors[j][i] <= acutValues[0]) {
+                  blockerrlin1 += (srccolors[j][i] - alphatest[0]);
+                  nralphainrangelow += 1;
+               }
+               else if (srccolors[j][i] <= acutValues[1]) {
+                  blockerrlin1 += (srccolors[j][i] - (alphatest[0] * 4 + alphatest[1] * 1) / 5);
+                  blockerrlin2 += (srccolors[j][i] - (alphatest[0] * 4 + alphatest[1] * 1) / 5);
+                  nralphainrangelow += 1;
+                  nralphainrangehigh += 1;
+               }
+               else if (srccolors[j][i] <= acutValues[2]) {
+                  blockerrlin1 += (srccolors[j][i] - (alphatest[0] * 3 + alphatest[1] * 2) / 5);
+                  blockerrlin2 += (srccolors[j][i] - (alphatest[0] * 3 + alphatest[1] * 2) / 5);
+                  nralphainrangelow += 1;
+                  nralphainrangehigh += 1;
+               }
+               else if (srccolors[j][i] <= acutValues[3]) {
+                  blockerrlin1 += (srccolors[j][i] - (alphatest[0] * 2 + alphatest[1] * 3) / 5);
+                  blockerrlin2 += (srccolors[j][i] - (alphatest[0] * 2 + alphatest[1] * 3) / 5);
+                  nralphainrangelow += 1;
+                  nralphainrangehigh += 1;
+               }
+               else if (srccolors[j][i] <= acutValues[4]) {
+                  blockerrlin1 += (srccolors[j][i] - (alphatest[0] * 1 + alphatest[1] * 4) / 5);
+                  blockerrlin2 += (srccolors[j][i] - (alphatest[0] * 1 + alphatest[1] * 4) / 5);
+                  nralphainrangelow += 1;
+                  nralphainrangehigh += 1;
+                  }
+               else {
+                  blockerrlin2 += (srccolors[j][i] - alphatest[1]);
+                  nralphainrangehigh += 1;
+               }
+            }
+         }
+         /* shouldn't happen often, needed to avoid div by zero */
+         if (nralphainrangelow == 0) nralphainrangelow = 1;
+         if (nralphainrangehigh == 0) nralphainrangehigh = 1;
+         alphatest[0] = alphatest[0] + (blockerrlin1 / nralphainrangelow);
+#if RGTC_DEBUG
+         fprintf(stderr, "block err lin low %d, nr %d\n", blockerrlin1, nralphainrangelow);
+         fprintf(stderr, "block err lin high %d, nr %d\n", blockerrlin2, nralphainrangehigh);
+#endif
+         /* again shouldn't really happen often... */
+         if (alphatest[0] < T_MIN) {
+            alphatest[0] = T_MIN;
+         }
+         alphatest[1] = alphatest[1] + (blockerrlin2 / nralphainrangehigh);
+         if (alphatest[1] > T_MAX) {
+            alphatest[1] = T_MAX;
+         }
+
+         alphablockerror3 = 0;
+         for (aindex = 0; aindex < 5; aindex++) {
+         /* don't forget here is always rounded down */
+            acutValues[aindex] = (alphatest[0] * (10 - (2*aindex + 1)) + alphatest[1] * (2*aindex + 1)) / 10;
+         }
+         for (j = 0; j < numypixels; j++) {
+            for (i = 0; i < numxpixels; i++) {
+                /* maybe it's overkill to have the most complicated calculation just for the error
+                  calculation which we only need to figure out if encoding1 or encoding2 is better... */
+               if (srccolors[j][i] <= alphatest[0] / 2) {
+                  alphaenc3[4*j + i] = 6;
+                  alphadist = srccolors[j][i];
+               }
+               else if (srccolors[j][i] > ((T_MAX + alphatest[1]) / 2)) {
+                  alphaenc3[4*j + i] = 7;
+                  alphadist = T_MAX - srccolors[j][i];
+               }
+               else if (srccolors[j][i] <= acutValues[0]) {
+                  alphaenc3[4*j + i] = 0;
+                  alphadist = srccolors[j][i] - alphatest[0];
+               }
+               else if (srccolors[j][i] <= acutValues[1]) {
+                 alphaenc3[4*j + i] = 2;
+                 alphadist = srccolors[j][i] - (alphatest[0] * 4 + alphatest[1] * 1) / 5;
+               }
+               else if (srccolors[j][i] <= acutValues[2]) {
+                  alphaenc3[4*j + i] = 3;
+                  alphadist = srccolors[j][i] - (alphatest[0] * 3 + alphatest[1] * 2) / 5;
+               }
+               else if (srccolors[j][i] <= acutValues[3]) {
+                  alphaenc3[4*j + i] = 4;
+                  alphadist = srccolors[j][i] - (alphatest[0] * 2 + alphatest[1] * 3) / 5;
+               }
+               else if (srccolors[j][i] <= acutValues[4]) {
+                  alphaenc3[4*j + i] = 5;
+                  alphadist = srccolors[j][i] - (alphatest[0] * 1 + alphatest[1] * 4) / 5;
+               }
+               else {
+                  alphaenc3[4*j + i] = 1;
+                  alphadist = srccolors[j][i] - alphatest[1];
+               }
+               alphablockerror3 += alphadist * alphadist;
+            }
+         }
+      }
+   }
+
+  /* write the alpha values and encoding back. */
+   if ((alphablockerror1 <= alphablockerror2) && (alphablockerror1 <= alphablockerror3)) {
+#if RGTC_DEBUG
+      if (alphablockerror1 > 96) fprintf(stderr, "enc1 used, error %d\n", alphablockerror1);
+      fprintf(stderr,"w1: min %d max %d au0 %d au1 %d\n",
+             T_MIN, T_MAX,
+             alphause[1], alphause[0]);
+#endif
+
+      TAG(write_rgtc_encoded_channel)( blkaddr, alphause[1], alphause[0], alphaenc1 );
+   }
+   else if (alphablockerror2 <= alphablockerror3) {
+#if RGTC_DEBUG
+      if (alphablockerror2 > 96) fprintf(stderr, "enc2 used, error %d\n", alphablockerror2);
+      fprintf(stderr,"w2: min %d max %d au0 %d au1 %d\n",
+             T_MIN, T_MAX,
+             alphabase[0], alphabase[1]);
+#endif
+
+      TAG(write_rgtc_encoded_channel)( blkaddr, alphabase[0], alphabase[1], alphaenc2 );
+   }
+   else {
+#if RGTC_DEBUG
+      fprintf(stderr, "enc3 used, error %d\n", alphablockerror3);
+      fprintf(stderr,"w3: min %d max %d au0 %d au1 %d\n",
+             T_MIN, T_MAX,
+             alphatest[0], alphatest[1]);
+#endif
+
+      TAG(write_rgtc_encoded_channel)( blkaddr, (TYPE)alphatest[0], (TYPE)alphatest[1], alphaenc3 );
+   }
+}