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