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 29static void u_format_unsigned_encode_rgtc_ubyte(uint8_t *blkaddr, uint8_t srccolors[4][4], 30 int numxpixels, int numypixels); 31 32static void u_format_unsigned_fetch_texel_rgtc(unsigned srcRowStride, const uint8_t *pixdata, 33 unsigned i, unsigned j, uint8_t *value, unsigned comps); 34 35static void u_format_signed_encode_rgtc_ubyte(int8_t *blkaddr, int8_t srccolors[4][4], 36 int numxpixels, int numypixels); 37 38static void u_format_signed_fetch_texel_rgtc(unsigned srcRowStride, const int8_t *pixdata, 39 unsigned i, unsigned j, int8_t *value, unsigned comps); 40 41void 42util_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 50void 51util_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 75void 76util_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 98void 99util_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 123void 124util_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 145void 146util_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 156void 157util_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 162void 163util_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 168void 169util_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 174void 175util_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 196void 197util_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 221void 222util_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 233void 234util_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 242void 243util_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 267void 268util_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 292void 293util_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 317void 318util_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 323void 324util_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 349void 350util_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 362void 363util_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 368void 369util_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 374void 375util_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 380void 381util_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 406void 407util_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 431void 432util_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 437void 438util_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