Home | History | Annotate | Download | only in util
      1 /**************************************************************************
      2  *
      3  * Copyright (C) 2011 Red Hat Inc.
      4  *
      5  * Permission is hereby granted, free of charge, to any person obtaining a
      6  * copy of this software and associated documentation files (the "Software"),
      7  * to deal in the Software without restriction, including without limitation
      8  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      9  * and/or sell copies of the Software, and to permit persons to whom the
     10  * Software is furnished to do so, subject to the following conditions:
     11  *
     12  * The above copyright notice and this permission notice shall be included
     13  * in all copies or substantial portions of the Software.
     14  *
     15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
     16  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
     18  * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
     19  * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
     20  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
     21  *
     22  **************************************************************************/
     23 
     24 #include <stdio.h>
     25 #include "u_math.h"
     26 #include "u_format.h"
     27 #include "u_format_rgtc.h"
     28 
     29 static void u_format_unsigned_encode_rgtc_ubyte(uint8_t *blkaddr, uint8_t srccolors[4][4],
     30 					       int numxpixels, int numypixels);
     31 
     32 static void u_format_unsigned_fetch_texel_rgtc(unsigned srcRowStride, const uint8_t *pixdata,
     33 					       unsigned i, unsigned j, uint8_t *value, unsigned comps);
     34 
     35 static void u_format_signed_encode_rgtc_ubyte(int8_t *blkaddr, int8_t srccolors[4][4],
     36 					     int numxpixels, int numypixels);
     37 
     38 static void u_format_signed_fetch_texel_rgtc(unsigned srcRowStride, const int8_t *pixdata,
     39 					       unsigned i, unsigned j, int8_t *value, unsigned comps);
     40 
     41 void
     42 util_format_rgtc1_unorm_fetch_rgba_8unorm(uint8_t *dst, const uint8_t *src, unsigned i, unsigned j)
     43 {
     44    u_format_unsigned_fetch_texel_rgtc(0, src, i, j, dst, 1);
     45    dst[1] = 0;
     46    dst[2] = 0;
     47    dst[3] = 255;
     48 }
     49 
     50 void
     51 util_format_rgtc1_unorm_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height)
     52 {
     53    const unsigned bw = 4, bh = 4, comps = 4;
     54    unsigned x, y, i, j;
     55    unsigned block_size = 8;
     56 
     57    for(y = 0; y < height; y += bh) {
     58       const uint8_t *src = src_row;
     59       for(x = 0; x < width; x += bw) {
     60          for(j = 0; j < bh; ++j) {
     61             for(i = 0; i < bw; ++i) {
     62                uint8_t *dst = dst_row + (y + j)*dst_stride/sizeof(*dst_row) + (x + i)*comps;
     63 	       u_format_unsigned_fetch_texel_rgtc(0, src, i, j, dst, 1);
     64 	       dst[1] = 0;
     65 	       dst[2] = 0;
     66 	       dst[3] = 255;
     67 	    }
     68 	 }
     69 	 src += block_size;
     70       }
     71       src_row += src_stride;
     72    }
     73 }
     74 
     75 void
     76 util_format_rgtc1_unorm_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row,
     77 					 unsigned src_stride, unsigned width, unsigned height)
     78 {
     79    const unsigned bw = 4, bh = 4, bytes_per_block = 8;
     80    unsigned x, y, i, j;
     81 
     82    for(y = 0; y < height; y += bh) {
     83       uint8_t *dst = dst_row;
     84       for(x = 0; x < width; x += bw) {
     85          uint8_t tmp[4][4];  /* [bh][bw][comps] */
     86          for(j = 0; j < bh; ++j) {
     87             for(i = 0; i < bw; ++i) {
     88 	       tmp[j][i] = src_row[(y + j)*src_stride/sizeof(*src_row) + (x + i)*4];
     89             }
     90          }
     91          u_format_unsigned_encode_rgtc_ubyte(dst, tmp, 4, 4);
     92          dst += bytes_per_block;
     93       }
     94       dst_row += dst_stride / sizeof(*dst_row);
     95    }
     96 }
     97 
     98 void
     99 util_format_rgtc1_unorm_unpack_rgba_float(float *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height)
    100 {
    101    unsigned x, y, i, j;
    102    int block_size = 8;
    103    for(y = 0; y < height; y += 4) {
    104       const uint8_t *src = src_row;
    105       for(x = 0; x < width; x += 4) {
    106          for(j = 0; j < 4; ++j) {
    107             for(i = 0; i < 4; ++i) {
    108                float *dst = dst_row + (y + j)*dst_stride/sizeof(*dst_row) + (x + i)*4;
    109                uint8_t tmp_r;
    110                u_format_unsigned_fetch_texel_rgtc(0, src, i, j, &tmp_r, 1);
    111                dst[0] = ubyte_to_float(tmp_r);
    112                dst[1] = 0.0;
    113                dst[2] = 0.0;
    114                dst[3] = 1.0;
    115             }
    116          }
    117          src += block_size;
    118       }
    119       src_row += src_stride;
    120    }
    121 }
    122 
    123 void
    124 util_format_rgtc1_unorm_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height)
    125 {
    126    const unsigned bw = 4, bh = 4, bytes_per_block = 8;
    127    unsigned x, y, i, j;
    128 
    129    for(y = 0; y < height; y += bh) {
    130       uint8_t *dst = dst_row;
    131       for(x = 0; x < width; x += bw) {
    132          uint8_t tmp[4][4];  /* [bh][bw][comps] */
    133          for(j = 0; j < bh; ++j) {
    134             for(i = 0; i < bw; ++i) {
    135 	       tmp[j][i] = float_to_ubyte(src_row[(y + j)*src_stride/sizeof(*src_row) + (x + i)*4]);
    136             }
    137          }
    138          u_format_unsigned_encode_rgtc_ubyte(dst, tmp, 4, 4);
    139          dst += bytes_per_block;
    140       }
    141       dst_row += dst_stride / sizeof(*dst_row);
    142    }
    143 }
    144 
    145 void
    146 util_format_rgtc1_unorm_fetch_rgba_float(float *dst, const uint8_t *src, unsigned i, unsigned j)
    147 {
    148    uint8_t tmp_r;
    149    u_format_unsigned_fetch_texel_rgtc(0, src, i, j, &tmp_r, 1);
    150    dst[0] = ubyte_to_float(tmp_r);
    151    dst[1] = 0.0;
    152    dst[2] = 0.0;
    153    dst[3] = 1.0;
    154 }
    155 
    156 void
    157 util_format_rgtc1_snorm_fetch_rgba_8unorm(uint8_t *dst, const uint8_t *src, unsigned i, unsigned j)
    158 {
    159    fprintf(stderr,"%s\n", __func__);
    160 }
    161 
    162 void
    163 util_format_rgtc1_snorm_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height)
    164 {
    165    fprintf(stderr,"%s\n", __func__);
    166 }
    167 
    168 void
    169 util_format_rgtc1_snorm_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height)
    170 {
    171    fprintf(stderr,"%s\n", __func__);
    172 }
    173 
    174 void
    175 util_format_rgtc1_snorm_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height)
    176 {
    177    const unsigned bw = 4, bh = 4, bytes_per_block = 8;
    178    unsigned x, y, i, j;
    179 
    180    for(y = 0; y < height; y += bh) {
    181       int8_t *dst = (int8_t *)dst_row;
    182       for(x = 0; x < width; x += bw) {
    183          int8_t tmp[4][4];  /* [bh][bw][comps] */
    184          for(j = 0; j < bh; ++j) {
    185             for(i = 0; i < bw; ++i) {
    186 	       tmp[j][i] = float_to_byte_tex(src_row[(y + j)*src_stride/sizeof(*src_row) + (x + i)*4]);
    187             }
    188          }
    189          u_format_signed_encode_rgtc_ubyte(dst, tmp, 4, 4);
    190          dst += bytes_per_block;
    191       }
    192       dst_row += dst_stride / sizeof(*dst_row);
    193    }
    194 }
    195 
    196 void
    197 util_format_rgtc1_snorm_unpack_rgba_float(float *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height)
    198 {
    199    unsigned x, y, i, j;
    200    int block_size = 8;
    201    for(y = 0; y < height; y += 4) {
    202       const int8_t *src = (int8_t *)src_row;
    203       for(x = 0; x < width; x += 4) {
    204          for(j = 0; j < 4; ++j) {
    205             for(i = 0; i < 4; ++i) {
    206                float *dst = dst_row + (y + j)*dst_stride/sizeof(*dst_row) + (x + i)*4;
    207                int8_t tmp_r;
    208                u_format_signed_fetch_texel_rgtc(0, src, i, j, &tmp_r, 1);
    209                dst[0] = byte_to_float_tex(tmp_r);
    210                dst[1] = 0.0;
    211                dst[2] = 0.0;
    212                dst[3] = 1.0;
    213             }
    214          }
    215          src += block_size;
    216       }
    217       src_row += src_stride;
    218    }
    219 }
    220 
    221 void
    222 util_format_rgtc1_snorm_fetch_rgba_float(float *dst, const uint8_t *src, unsigned i, unsigned j)
    223 {
    224    int8_t tmp_r;
    225    u_format_signed_fetch_texel_rgtc(0, (int8_t *)src, i, j, &tmp_r, 1);
    226    dst[0] = byte_to_float_tex(tmp_r);
    227    dst[1] = 0.0;
    228    dst[2] = 0.0;
    229    dst[3] = 1.0;
    230 }
    231 
    232 
    233 void
    234 util_format_rgtc2_unorm_fetch_rgba_8unorm(uint8_t *dst, const uint8_t *src, unsigned i, unsigned j)
    235 {
    236    u_format_unsigned_fetch_texel_rgtc(0, src, i, j, dst, 2);
    237    u_format_unsigned_fetch_texel_rgtc(0, src + 8, i, j, dst + 1, 2);
    238    dst[2] = 0;
    239    dst[3] = 255;
    240 }
    241 
    242 void
    243 util_format_rgtc2_unorm_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height)
    244 {
    245    const unsigned bw = 4, bh = 4, comps = 4;
    246    unsigned x, y, i, j;
    247    unsigned block_size = 16;
    248 
    249    for(y = 0; y < height; y += bh) {
    250       const uint8_t *src = src_row;
    251       for(x = 0; x < width; x += bw) {
    252          for(j = 0; j < bh; ++j) {
    253             for(i = 0; i < bw; ++i) {
    254                uint8_t *dst = dst_row + (y + j)*dst_stride/sizeof(*dst_row) + (x + i)*comps;
    255 	       u_format_unsigned_fetch_texel_rgtc(0, src, i, j, dst, 2);
    256 	       u_format_unsigned_fetch_texel_rgtc(0, src + 8, i, j, dst + 1, 2);
    257 	       dst[2] = 0;
    258 	       dst[3] = 255;
    259 	    }
    260 	 }
    261 	 src += block_size;
    262       }
    263       src_row += src_stride;
    264    }
    265 }
    266 
    267 void
    268 util_format_rgtc2_unorm_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height)
    269 {
    270    const unsigned bw = 4, bh = 4, bytes_per_block = 16;
    271    unsigned x, y, i, j;
    272 
    273    for(y = 0; y < height; y += bh) {
    274       uint8_t *dst = dst_row;
    275       for(x = 0; x < width; x += bw) {
    276          uint8_t tmp_r[4][4];  /* [bh][bw] */
    277          uint8_t tmp_g[4][4];  /* [bh][bw] */
    278          for(j = 0; j < bh; ++j) {
    279             for(i = 0; i < bw; ++i) {
    280 	       tmp_r[j][i] = src_row[(y + j)*src_stride/sizeof(*src_row) + (x + i)*4];
    281 	       tmp_g[j][i] = src_row[((y + j)*src_stride/sizeof(*src_row) + (x + i)*4) + 1];
    282             }
    283          }
    284          u_format_unsigned_encode_rgtc_ubyte(dst, tmp_r, 4, 4);
    285          u_format_unsigned_encode_rgtc_ubyte(dst + 8, tmp_g, 4, 4);
    286          dst += bytes_per_block;
    287       }
    288       dst_row += dst_stride / sizeof(*dst_row);
    289    }
    290 }
    291 
    292 void
    293 util_format_rxtc2_unorm_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height, unsigned chan2off)
    294 {
    295    const unsigned bw = 4, bh = 4, bytes_per_block = 16;
    296    unsigned x, y, i, j;
    297 
    298    for(y = 0; y < height; y += bh) {
    299       uint8_t *dst = dst_row;
    300       for(x = 0; x < width; x += bw) {
    301          uint8_t tmp_r[4][4];  /* [bh][bw][comps] */
    302          uint8_t tmp_g[4][4];  /* [bh][bw][comps] */
    303          for(j = 0; j < bh; ++j) {
    304             for(i = 0; i < bw; ++i) {
    305 	       tmp_r[j][i] = float_to_ubyte(src_row[(y + j)*src_stride/sizeof(*src_row) + (x + i)*4]);
    306                tmp_g[j][i] = float_to_ubyte(src_row[(y + j)*src_stride/sizeof(*src_row) + (x + i)*4 + chan2off]);
    307             }
    308          }
    309          u_format_unsigned_encode_rgtc_ubyte(dst, tmp_r, 4, 4);
    310          u_format_unsigned_encode_rgtc_ubyte(dst + 8, tmp_g, 4, 4);
    311          dst += bytes_per_block;
    312       }
    313       dst_row += dst_stride / sizeof(*dst_row);
    314    }
    315 }
    316 
    317 void
    318 util_format_rgtc2_unorm_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height)
    319 {
    320    util_format_rxtc2_unorm_pack_rgba_float(dst_row, dst_stride, src_row, src_stride, width, height, 1);
    321 }
    322 
    323 void
    324 util_format_rgtc2_unorm_unpack_rgba_float(float *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height)
    325 {
    326    unsigned x, y, i, j;
    327    int block_size = 16;
    328    for(y = 0; y < height; y += 4) {
    329       const uint8_t *src = src_row;
    330       for(x = 0; x < width; x += 4) {
    331          for(j = 0; j < 4; ++j) {
    332             for(i = 0; i < 4; ++i) {
    333                float *dst = dst_row + (y + j)*dst_stride/sizeof(*dst_row) + (x + i)*4;
    334                uint8_t tmp_r, tmp_g;
    335                u_format_unsigned_fetch_texel_rgtc(0, src, i, j, &tmp_r, 2);
    336                u_format_unsigned_fetch_texel_rgtc(0, src + 8, i, j, &tmp_g, 2);
    337                dst[0] = ubyte_to_float(tmp_r);
    338                dst[1] = ubyte_to_float(tmp_g);
    339                dst[2] = 0.0;
    340                dst[3] = 1.0;
    341             }
    342          }
    343          src += block_size;
    344       }
    345       src_row += src_stride;
    346    }
    347 }
    348 
    349 void
    350 util_format_rgtc2_unorm_fetch_rgba_float(float *dst, const uint8_t *src, unsigned i, unsigned j)
    351 {
    352    uint8_t tmp_r, tmp_g;
    353    u_format_unsigned_fetch_texel_rgtc(0, src, i, j, &tmp_r, 2);
    354    u_format_unsigned_fetch_texel_rgtc(0, src + 8, i, j, &tmp_g, 2);
    355    dst[0] = ubyte_to_float(tmp_r);
    356    dst[1] = ubyte_to_float(tmp_g);
    357    dst[2] = 0.0;
    358    dst[3] = 1.0;
    359 }
    360 
    361 
    362 void
    363 util_format_rgtc2_snorm_fetch_rgba_8unorm(uint8_t *dst, const uint8_t *src, unsigned i, unsigned j)
    364 {
    365    fprintf(stderr,"%s\n", __func__);
    366 }
    367 
    368 void
    369 util_format_rgtc2_snorm_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height)
    370 {
    371    fprintf(stderr,"%s\n", __func__);
    372 }
    373 
    374 void
    375 util_format_rgtc2_snorm_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height)
    376 {
    377    fprintf(stderr,"%s\n", __func__);
    378 }
    379 
    380 void
    381 util_format_rgtc2_snorm_unpack_rgba_float(float *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height)
    382 {
    383    unsigned x, y, i, j;
    384    int block_size = 16;
    385    for(y = 0; y < height; y += 4) {
    386       const int8_t *src = (int8_t *)src_row;
    387       for(x = 0; x < width; x += 4) {
    388          for(j = 0; j < 4; ++j) {
    389             for(i = 0; i < 4; ++i) {
    390                float *dst = dst_row + (y + j)*dst_stride/sizeof(*dst_row) + (x + i)*4;
    391                int8_t tmp_r, tmp_g;
    392                u_format_signed_fetch_texel_rgtc(0, src, i, j, &tmp_r, 2);
    393                u_format_signed_fetch_texel_rgtc(0, src + 8, i, j, &tmp_g, 2);
    394                dst[0] = byte_to_float_tex(tmp_r);
    395                dst[1] = byte_to_float_tex(tmp_g);
    396                dst[2] = 0.0;
    397                dst[3] = 1.0;
    398             }
    399          }
    400          src += block_size;
    401       }
    402       src_row += src_stride;
    403    }
    404 }
    405 
    406 void
    407 util_format_rxtc2_snorm_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height, unsigned chan2off)
    408 {
    409    const unsigned bw = 4, bh = 4, bytes_per_block = 16;
    410    unsigned x, y, i, j;
    411 
    412    for(y = 0; y < height; y += bh) {
    413       int8_t *dst = (int8_t *)dst_row;
    414       for(x = 0; x < width; x += bw) {
    415          int8_t tmp_r[4][4];  /* [bh][bw][comps] */
    416          int8_t tmp_g[4][4];  /* [bh][bw][comps] */
    417          for(j = 0; j < bh; ++j) {
    418             for(i = 0; i < bw; ++i) {
    419 	       tmp_r[j][i] = float_to_byte_tex(src_row[(y + j)*src_stride/sizeof(*src_row) + (x + i)*4]);
    420                tmp_g[j][i] = float_to_byte_tex(src_row[(y + j)*src_stride/sizeof(*src_row) + (x + i)*4 + chan2off]);
    421             }
    422          }
    423          u_format_signed_encode_rgtc_ubyte(dst, tmp_r, 4, 4);
    424          u_format_signed_encode_rgtc_ubyte(dst + 8, tmp_g, 4, 4);
    425          dst += bytes_per_block;
    426       }
    427       dst_row += dst_stride / sizeof(*dst_row);
    428    }
    429 }
    430 
    431 void
    432 util_format_rgtc2_snorm_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height)
    433 {
    434    util_format_rxtc2_snorm_pack_rgba_float(dst_row, dst_stride, src_row, src_stride, width, height, 1);
    435 }
    436 
    437 void
    438 util_format_rgtc2_snorm_fetch_rgba_float(float *dst, const uint8_t *src, unsigned i, unsigned j)
    439 {
    440    int8_t tmp_r, tmp_g;
    441    u_format_signed_fetch_texel_rgtc(0, (int8_t *)src, i, j, &tmp_r, 2);
    442    u_format_signed_fetch_texel_rgtc(0, (int8_t *)src + 8, i, j, &tmp_g, 2);
    443    dst[0] = byte_to_float_tex(tmp_r);
    444    dst[1] = byte_to_float_tex(tmp_g);
    445    dst[2] = 0.0;
    446    dst[3] = 1.0;
    447 }
    448 
    449 
    450 #define TAG(x) u_format_unsigned_##x
    451 #define TYPE uint8_t
    452 #define T_MIN 0
    453 #define T_MAX 255
    454 
    455 #include "../../../mesa/main/texcompress_rgtc_tmp.h"
    456 
    457 #undef TYPE
    458 #undef TAG
    459 #undef T_MIN
    460 #undef T_MAX
    461 
    462 
    463 #define TAG(x) u_format_signed_##x
    464 #define TYPE int8_t
    465 #define T_MIN (int8_t)-128
    466 #define T_MAX (int8_t)127
    467 
    468 #include "../../../mesa/main/texcompress_rgtc_tmp.h"
    469 
    470 #undef TYPE
    471 #undef TAG
    472 #undef T_MIN
    473 #undef T_MAX
    474