1 /*------------------------------------------------------------------------- 2 * drawElements Quality Program Tester Core 3 * ---------------------------------------- 4 * 5 * Copyright 2014 The Android Open Source Project 6 * 7 * Licensed under the Apache License, Version 2.0 (the "License"); 8 * you may not use this file except in compliance with the License. 9 * You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, software 14 * distributed under the License is distributed on an "AS IS" BASIS, 15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 * See the License for the specific language governing permissions and 17 * limitations under the License. 18 * 19 *//*! 20 * \file 21 * \brief Compressed Texture Utilities. 22 *//*--------------------------------------------------------------------*/ 23 24 #include "tcuCompressedTexture.hpp" 25 #include "tcuTextureUtil.hpp" 26 #include "tcuAstcUtil.hpp" 27 28 #include "deStringUtil.hpp" 29 #include "deFloat16.h" 30 31 #include <algorithm> 32 33 namespace tcu 34 { 35 36 int getBlockSize (CompressedTexFormat format) 37 { 38 if (isAstcFormat(format)) 39 { 40 return astc::BLOCK_SIZE_BYTES; 41 } 42 else if (isEtcFormat(format)) 43 { 44 switch (format) 45 { 46 case COMPRESSEDTEXFORMAT_ETC1_RGB8: return 8; 47 case COMPRESSEDTEXFORMAT_EAC_R11: return 8; 48 case COMPRESSEDTEXFORMAT_EAC_SIGNED_R11: return 8; 49 case COMPRESSEDTEXFORMAT_EAC_RG11: return 16; 50 case COMPRESSEDTEXFORMAT_EAC_SIGNED_RG11: return 16; 51 case COMPRESSEDTEXFORMAT_ETC2_RGB8: return 8; 52 case COMPRESSEDTEXFORMAT_ETC2_SRGB8: return 8; 53 case COMPRESSEDTEXFORMAT_ETC2_RGB8_PUNCHTHROUGH_ALPHA1: return 8; 54 case COMPRESSEDTEXFORMAT_ETC2_SRGB8_PUNCHTHROUGH_ALPHA1: return 8; 55 case COMPRESSEDTEXFORMAT_ETC2_EAC_RGBA8: return 16; 56 case COMPRESSEDTEXFORMAT_ETC2_EAC_SRGB8_ALPHA8: return 16; 57 58 default: 59 DE_ASSERT(false); 60 return -1; 61 } 62 } 63 else if (isBcFormat(format)) 64 { 65 switch (format) 66 { 67 case COMPRESSEDTEXFORMAT_BC1_RGB_UNORM_BLOCK: return 8; 68 case COMPRESSEDTEXFORMAT_BC1_RGB_SRGB_BLOCK: return 8; 69 case COMPRESSEDTEXFORMAT_BC1_RGBA_UNORM_BLOCK: return 8; 70 case COMPRESSEDTEXFORMAT_BC1_RGBA_SRGB_BLOCK: return 8; 71 case COMPRESSEDTEXFORMAT_BC2_UNORM_BLOCK: return 16; 72 case COMPRESSEDTEXFORMAT_BC2_SRGB_BLOCK: return 16; 73 case COMPRESSEDTEXFORMAT_BC3_UNORM_BLOCK: return 16; 74 case COMPRESSEDTEXFORMAT_BC3_SRGB_BLOCK: return 16; 75 case COMPRESSEDTEXFORMAT_BC4_UNORM_BLOCK: return 8; 76 case COMPRESSEDTEXFORMAT_BC4_SNORM_BLOCK: return 8; 77 case COMPRESSEDTEXFORMAT_BC5_UNORM_BLOCK: return 16; 78 case COMPRESSEDTEXFORMAT_BC5_SNORM_BLOCK: return 16; 79 case COMPRESSEDTEXFORMAT_BC6H_UFLOAT_BLOCK: return 16; 80 case COMPRESSEDTEXFORMAT_BC6H_SFLOAT_BLOCK: return 16; 81 case COMPRESSEDTEXFORMAT_BC7_UNORM_BLOCK: return 16; 82 case COMPRESSEDTEXFORMAT_BC7_SRGB_BLOCK: return 16; 83 84 default: 85 DE_ASSERT(false); 86 return -1; 87 } 88 } 89 else 90 { 91 DE_ASSERT(false); 92 return -1; 93 } 94 } 95 96 IVec3 getBlockPixelSize (CompressedTexFormat format) 97 { 98 if (isEtcFormat(format)) 99 { 100 return IVec3(4, 4, 1); 101 } 102 else if (isAstcFormat(format)) 103 { 104 switch (format) 105 { 106 case COMPRESSEDTEXFORMAT_ASTC_4x4_RGBA: return IVec3(4, 4, 1); 107 case COMPRESSEDTEXFORMAT_ASTC_5x4_RGBA: return IVec3(5, 4, 1); 108 case COMPRESSEDTEXFORMAT_ASTC_5x5_RGBA: return IVec3(5, 5, 1); 109 case COMPRESSEDTEXFORMAT_ASTC_6x5_RGBA: return IVec3(6, 5, 1); 110 case COMPRESSEDTEXFORMAT_ASTC_6x6_RGBA: return IVec3(6, 6, 1); 111 case COMPRESSEDTEXFORMAT_ASTC_8x5_RGBA: return IVec3(8, 5, 1); 112 case COMPRESSEDTEXFORMAT_ASTC_8x6_RGBA: return IVec3(8, 6, 1); 113 case COMPRESSEDTEXFORMAT_ASTC_8x8_RGBA: return IVec3(8, 8, 1); 114 case COMPRESSEDTEXFORMAT_ASTC_10x5_RGBA: return IVec3(10, 5, 1); 115 case COMPRESSEDTEXFORMAT_ASTC_10x6_RGBA: return IVec3(10, 6, 1); 116 case COMPRESSEDTEXFORMAT_ASTC_10x8_RGBA: return IVec3(10, 8, 1); 117 case COMPRESSEDTEXFORMAT_ASTC_10x10_RGBA: return IVec3(10, 10, 1); 118 case COMPRESSEDTEXFORMAT_ASTC_12x10_RGBA: return IVec3(12, 10, 1); 119 case COMPRESSEDTEXFORMAT_ASTC_12x12_RGBA: return IVec3(12, 12, 1); 120 case COMPRESSEDTEXFORMAT_ASTC_4x4_SRGB8_ALPHA8: return IVec3(4, 4, 1); 121 case COMPRESSEDTEXFORMAT_ASTC_5x4_SRGB8_ALPHA8: return IVec3(5, 4, 1); 122 case COMPRESSEDTEXFORMAT_ASTC_5x5_SRGB8_ALPHA8: return IVec3(5, 5, 1); 123 case COMPRESSEDTEXFORMAT_ASTC_6x5_SRGB8_ALPHA8: return IVec3(6, 5, 1); 124 case COMPRESSEDTEXFORMAT_ASTC_6x6_SRGB8_ALPHA8: return IVec3(6, 6, 1); 125 case COMPRESSEDTEXFORMAT_ASTC_8x5_SRGB8_ALPHA8: return IVec3(8, 5, 1); 126 case COMPRESSEDTEXFORMAT_ASTC_8x6_SRGB8_ALPHA8: return IVec3(8, 6, 1); 127 case COMPRESSEDTEXFORMAT_ASTC_8x8_SRGB8_ALPHA8: return IVec3(8, 8, 1); 128 case COMPRESSEDTEXFORMAT_ASTC_10x5_SRGB8_ALPHA8: return IVec3(10, 5, 1); 129 case COMPRESSEDTEXFORMAT_ASTC_10x6_SRGB8_ALPHA8: return IVec3(10, 6, 1); 130 case COMPRESSEDTEXFORMAT_ASTC_10x8_SRGB8_ALPHA8: return IVec3(10, 8, 1); 131 case COMPRESSEDTEXFORMAT_ASTC_10x10_SRGB8_ALPHA8: return IVec3(10, 10, 1); 132 case COMPRESSEDTEXFORMAT_ASTC_12x10_SRGB8_ALPHA8: return IVec3(12, 10, 1); 133 case COMPRESSEDTEXFORMAT_ASTC_12x12_SRGB8_ALPHA8: return IVec3(12, 12, 1); 134 135 default: 136 DE_ASSERT(false); 137 return IVec3(); 138 } 139 } 140 else if (isBcFormat(format)) 141 { 142 return IVec3(4, 4, 1); 143 } 144 else 145 { 146 DE_ASSERT(false); 147 return IVec3(-1); 148 } 149 } 150 151 bool isEtcFormat (CompressedTexFormat format) 152 { 153 switch (format) 154 { 155 case COMPRESSEDTEXFORMAT_ETC1_RGB8: 156 case COMPRESSEDTEXFORMAT_EAC_R11: 157 case COMPRESSEDTEXFORMAT_EAC_SIGNED_R11: 158 case COMPRESSEDTEXFORMAT_EAC_RG11: 159 case COMPRESSEDTEXFORMAT_EAC_SIGNED_RG11: 160 case COMPRESSEDTEXFORMAT_ETC2_RGB8: 161 case COMPRESSEDTEXFORMAT_ETC2_SRGB8: 162 case COMPRESSEDTEXFORMAT_ETC2_RGB8_PUNCHTHROUGH_ALPHA1: 163 case COMPRESSEDTEXFORMAT_ETC2_SRGB8_PUNCHTHROUGH_ALPHA1: 164 case COMPRESSEDTEXFORMAT_ETC2_EAC_RGBA8: 165 case COMPRESSEDTEXFORMAT_ETC2_EAC_SRGB8_ALPHA8: 166 return true; 167 168 default: 169 return false; 170 } 171 } 172 173 bool isBcFormat (CompressedTexFormat format) 174 { 175 switch (format) 176 { 177 case COMPRESSEDTEXFORMAT_BC1_RGB_UNORM_BLOCK: 178 case COMPRESSEDTEXFORMAT_BC1_RGB_SRGB_BLOCK: 179 case COMPRESSEDTEXFORMAT_BC1_RGBA_UNORM_BLOCK: 180 case COMPRESSEDTEXFORMAT_BC1_RGBA_SRGB_BLOCK: 181 case COMPRESSEDTEXFORMAT_BC2_UNORM_BLOCK: 182 case COMPRESSEDTEXFORMAT_BC2_SRGB_BLOCK: 183 case COMPRESSEDTEXFORMAT_BC3_UNORM_BLOCK: 184 case COMPRESSEDTEXFORMAT_BC3_SRGB_BLOCK: 185 case COMPRESSEDTEXFORMAT_BC4_UNORM_BLOCK: 186 case COMPRESSEDTEXFORMAT_BC4_SNORM_BLOCK: 187 case COMPRESSEDTEXFORMAT_BC5_UNORM_BLOCK: 188 case COMPRESSEDTEXFORMAT_BC5_SNORM_BLOCK: 189 case COMPRESSEDTEXFORMAT_BC6H_UFLOAT_BLOCK: 190 case COMPRESSEDTEXFORMAT_BC6H_SFLOAT_BLOCK: 191 case COMPRESSEDTEXFORMAT_BC7_UNORM_BLOCK: 192 case COMPRESSEDTEXFORMAT_BC7_SRGB_BLOCK: 193 return true; 194 195 default: 196 return false; 197 } 198 } 199 200 bool isBcBitExactFormat (CompressedTexFormat format) 201 { 202 switch (format) 203 { 204 case COMPRESSEDTEXFORMAT_BC6H_UFLOAT_BLOCK: 205 case COMPRESSEDTEXFORMAT_BC6H_SFLOAT_BLOCK: 206 case COMPRESSEDTEXFORMAT_BC7_UNORM_BLOCK: 207 case COMPRESSEDTEXFORMAT_BC7_SRGB_BLOCK: 208 return true; 209 210 default: 211 return false; 212 } 213 } 214 215 bool isBcSRGBFormat (CompressedTexFormat format) 216 { 217 switch (format) 218 { 219 case COMPRESSEDTEXFORMAT_BC1_RGB_SRGB_BLOCK: 220 case COMPRESSEDTEXFORMAT_BC1_RGBA_SRGB_BLOCK: 221 case COMPRESSEDTEXFORMAT_BC2_SRGB_BLOCK: 222 case COMPRESSEDTEXFORMAT_BC3_SRGB_BLOCK: 223 case COMPRESSEDTEXFORMAT_BC7_SRGB_BLOCK: 224 return true; 225 226 default: 227 return false; 228 } 229 } 230 231 bool isAstcFormat (CompressedTexFormat format) 232 { 233 switch (format) 234 { 235 case COMPRESSEDTEXFORMAT_ASTC_4x4_RGBA: 236 case COMPRESSEDTEXFORMAT_ASTC_5x4_RGBA: 237 case COMPRESSEDTEXFORMAT_ASTC_5x5_RGBA: 238 case COMPRESSEDTEXFORMAT_ASTC_6x5_RGBA: 239 case COMPRESSEDTEXFORMAT_ASTC_6x6_RGBA: 240 case COMPRESSEDTEXFORMAT_ASTC_8x5_RGBA: 241 case COMPRESSEDTEXFORMAT_ASTC_8x6_RGBA: 242 case COMPRESSEDTEXFORMAT_ASTC_8x8_RGBA: 243 case COMPRESSEDTEXFORMAT_ASTC_10x5_RGBA: 244 case COMPRESSEDTEXFORMAT_ASTC_10x6_RGBA: 245 case COMPRESSEDTEXFORMAT_ASTC_10x8_RGBA: 246 case COMPRESSEDTEXFORMAT_ASTC_10x10_RGBA: 247 case COMPRESSEDTEXFORMAT_ASTC_12x10_RGBA: 248 case COMPRESSEDTEXFORMAT_ASTC_12x12_RGBA: 249 case COMPRESSEDTEXFORMAT_ASTC_4x4_SRGB8_ALPHA8: 250 case COMPRESSEDTEXFORMAT_ASTC_5x4_SRGB8_ALPHA8: 251 case COMPRESSEDTEXFORMAT_ASTC_5x5_SRGB8_ALPHA8: 252 case COMPRESSEDTEXFORMAT_ASTC_6x5_SRGB8_ALPHA8: 253 case COMPRESSEDTEXFORMAT_ASTC_6x6_SRGB8_ALPHA8: 254 case COMPRESSEDTEXFORMAT_ASTC_8x5_SRGB8_ALPHA8: 255 case COMPRESSEDTEXFORMAT_ASTC_8x6_SRGB8_ALPHA8: 256 case COMPRESSEDTEXFORMAT_ASTC_8x8_SRGB8_ALPHA8: 257 case COMPRESSEDTEXFORMAT_ASTC_10x5_SRGB8_ALPHA8: 258 case COMPRESSEDTEXFORMAT_ASTC_10x6_SRGB8_ALPHA8: 259 case COMPRESSEDTEXFORMAT_ASTC_10x8_SRGB8_ALPHA8: 260 case COMPRESSEDTEXFORMAT_ASTC_10x10_SRGB8_ALPHA8: 261 case COMPRESSEDTEXFORMAT_ASTC_12x10_SRGB8_ALPHA8: 262 case COMPRESSEDTEXFORMAT_ASTC_12x12_SRGB8_ALPHA8: 263 return true; 264 265 default: 266 return false; 267 } 268 } 269 270 bool isAstcSRGBFormat (CompressedTexFormat format) 271 { 272 switch (format) 273 { 274 case COMPRESSEDTEXFORMAT_ASTC_4x4_SRGB8_ALPHA8: 275 case COMPRESSEDTEXFORMAT_ASTC_5x4_SRGB8_ALPHA8: 276 case COMPRESSEDTEXFORMAT_ASTC_5x5_SRGB8_ALPHA8: 277 case COMPRESSEDTEXFORMAT_ASTC_6x5_SRGB8_ALPHA8: 278 case COMPRESSEDTEXFORMAT_ASTC_6x6_SRGB8_ALPHA8: 279 case COMPRESSEDTEXFORMAT_ASTC_8x5_SRGB8_ALPHA8: 280 case COMPRESSEDTEXFORMAT_ASTC_8x6_SRGB8_ALPHA8: 281 case COMPRESSEDTEXFORMAT_ASTC_8x8_SRGB8_ALPHA8: 282 case COMPRESSEDTEXFORMAT_ASTC_10x5_SRGB8_ALPHA8: 283 case COMPRESSEDTEXFORMAT_ASTC_10x6_SRGB8_ALPHA8: 284 case COMPRESSEDTEXFORMAT_ASTC_10x8_SRGB8_ALPHA8: 285 case COMPRESSEDTEXFORMAT_ASTC_10x10_SRGB8_ALPHA8: 286 case COMPRESSEDTEXFORMAT_ASTC_12x10_SRGB8_ALPHA8: 287 case COMPRESSEDTEXFORMAT_ASTC_12x12_SRGB8_ALPHA8: 288 return true; 289 290 default: 291 return false; 292 } 293 } 294 295 TextureFormat getUncompressedFormat (CompressedTexFormat format) 296 { 297 if (isEtcFormat(format)) 298 { 299 switch (format) 300 { 301 case COMPRESSEDTEXFORMAT_ETC1_RGB8: return TextureFormat(TextureFormat::RGB, TextureFormat::UNORM_INT8); 302 case COMPRESSEDTEXFORMAT_EAC_R11: return TextureFormat(TextureFormat::R, TextureFormat::UNORM_INT16); 303 case COMPRESSEDTEXFORMAT_EAC_SIGNED_R11: return TextureFormat(TextureFormat::R, TextureFormat::SNORM_INT16); 304 case COMPRESSEDTEXFORMAT_EAC_RG11: return TextureFormat(TextureFormat::RG, TextureFormat::UNORM_INT16); 305 case COMPRESSEDTEXFORMAT_EAC_SIGNED_RG11: return TextureFormat(TextureFormat::RG, TextureFormat::SNORM_INT16); 306 case COMPRESSEDTEXFORMAT_ETC2_RGB8: return TextureFormat(TextureFormat::RGB, TextureFormat::UNORM_INT8); 307 case COMPRESSEDTEXFORMAT_ETC2_SRGB8: return TextureFormat(TextureFormat::sRGB, TextureFormat::UNORM_INT8); 308 case COMPRESSEDTEXFORMAT_ETC2_RGB8_PUNCHTHROUGH_ALPHA1: return TextureFormat(TextureFormat::RGBA, TextureFormat::UNORM_INT8); 309 case COMPRESSEDTEXFORMAT_ETC2_SRGB8_PUNCHTHROUGH_ALPHA1: return TextureFormat(TextureFormat::sRGBA, TextureFormat::UNORM_INT8); 310 case COMPRESSEDTEXFORMAT_ETC2_EAC_RGBA8: return TextureFormat(TextureFormat::RGBA, TextureFormat::UNORM_INT8); 311 case COMPRESSEDTEXFORMAT_ETC2_EAC_SRGB8_ALPHA8: return TextureFormat(TextureFormat::sRGBA, TextureFormat::UNORM_INT8); 312 313 default: 314 DE_ASSERT(false); 315 return TextureFormat(); 316 } 317 } 318 else if (isAstcFormat(format)) 319 { 320 if (isAstcSRGBFormat(format)) 321 return TextureFormat(TextureFormat::sRGBA, TextureFormat::UNORM_INT8); 322 else 323 return TextureFormat(TextureFormat::RGBA, TextureFormat::HALF_FLOAT); 324 } 325 else if (isBcFormat(format)) 326 { 327 if (format == COMPRESSEDTEXFORMAT_BC4_UNORM_BLOCK || format == COMPRESSEDTEXFORMAT_BC4_SNORM_BLOCK) 328 return TextureFormat(TextureFormat::R, TextureFormat::FLOAT); 329 else if (format == COMPRESSEDTEXFORMAT_BC5_UNORM_BLOCK || format == COMPRESSEDTEXFORMAT_BC5_SNORM_BLOCK) 330 return TextureFormat(TextureFormat::RG, TextureFormat::FLOAT); 331 else if (format == COMPRESSEDTEXFORMAT_BC6H_UFLOAT_BLOCK || format == COMPRESSEDTEXFORMAT_BC6H_SFLOAT_BLOCK) 332 return TextureFormat(TextureFormat::RGB, TextureFormat::HALF_FLOAT); 333 else if (isBcSRGBFormat(format)) 334 return TextureFormat(TextureFormat::sRGBA, TextureFormat::UNORM_INT8); 335 else 336 return TextureFormat(TextureFormat::RGBA, TextureFormat::UNORM_INT8); 337 } 338 else 339 { 340 DE_ASSERT(false); 341 return TextureFormat(); 342 } 343 } 344 345 CompressedTexFormat getAstcFormatByBlockSize (const IVec3& size, bool isSRGB) 346 { 347 if (size.z() > 1) 348 throw InternalError("3D ASTC textures not currently supported"); 349 350 for (int fmtI = 0; fmtI < COMPRESSEDTEXFORMAT_LAST; fmtI++) 351 { 352 const CompressedTexFormat fmt = (CompressedTexFormat)fmtI; 353 354 if (isAstcFormat(fmt) && getBlockPixelSize(fmt) == size && isAstcSRGBFormat(fmt) == isSRGB) 355 return fmt; 356 } 357 358 throw InternalError("Invalid ASTC block size " + de::toString(size.x()) + "x" + de::toString(size.y()) + "x" + de::toString(size.z())); 359 } 360 361 namespace 362 { 363 364 inline deUint8 extend4To8 (deUint8 src) 365 { 366 DE_ASSERT((src & ~((1<<4)-1)) == 0); 367 return (deUint8)((src << 4) | src); 368 } 369 370 inline deUint8 extend5To8 (deUint8 src) 371 { 372 DE_ASSERT((src & ~((1<<5)-1)) == 0); 373 return (deUint8)((src << 3) | (src >> 2)); 374 } 375 376 inline deUint8 extend6To8 (deUint8 src) 377 { 378 DE_ASSERT((src & ~((1<<6)-1)) == 0); 379 return (deUint8)((src << 2) | (src >> 4)); 380 } 381 382 // \todo [2013-08-06 nuutti] ETC and ASTC decompression codes are rather unrelated, and are already in their own "private" namespaces - should this be split to multiple files? 383 384 namespace EtcDecompressInternal 385 { 386 387 enum 388 { 389 ETC2_BLOCK_WIDTH = 4, 390 ETC2_BLOCK_HEIGHT = 4, 391 ETC2_UNCOMPRESSED_PIXEL_SIZE_A8 = 1, 392 ETC2_UNCOMPRESSED_PIXEL_SIZE_R11 = 2, 393 ETC2_UNCOMPRESSED_PIXEL_SIZE_RG11 = 4, 394 ETC2_UNCOMPRESSED_PIXEL_SIZE_RGB8 = 3, 395 ETC2_UNCOMPRESSED_PIXEL_SIZE_RGBA8 = 4, 396 ETC2_UNCOMPRESSED_BLOCK_SIZE_A8 = ETC2_BLOCK_WIDTH*ETC2_BLOCK_HEIGHT*ETC2_UNCOMPRESSED_PIXEL_SIZE_A8, 397 ETC2_UNCOMPRESSED_BLOCK_SIZE_R11 = ETC2_BLOCK_WIDTH*ETC2_BLOCK_HEIGHT*ETC2_UNCOMPRESSED_PIXEL_SIZE_R11, 398 ETC2_UNCOMPRESSED_BLOCK_SIZE_RG11 = ETC2_BLOCK_WIDTH*ETC2_BLOCK_HEIGHT*ETC2_UNCOMPRESSED_PIXEL_SIZE_RG11, 399 ETC2_UNCOMPRESSED_BLOCK_SIZE_RGB8 = ETC2_BLOCK_WIDTH*ETC2_BLOCK_HEIGHT*ETC2_UNCOMPRESSED_PIXEL_SIZE_RGB8, 400 ETC2_UNCOMPRESSED_BLOCK_SIZE_RGBA8 = ETC2_BLOCK_WIDTH*ETC2_BLOCK_HEIGHT*ETC2_UNCOMPRESSED_PIXEL_SIZE_RGBA8 401 }; 402 403 inline deUint64 get64BitBlock (const deUint8* src, int blockNdx) 404 { 405 // Stored in big-endian form. 406 deUint64 block = 0; 407 408 for (int i = 0; i < 8; i++) 409 block = (block << 8ull) | (deUint64)(src[blockNdx*8+i]); 410 411 return block; 412 } 413 414 // Return the first 64 bits of a 128 bit block. 415 inline deUint64 get128BitBlockStart (const deUint8* src, int blockNdx) 416 { 417 return get64BitBlock(src, 2*blockNdx); 418 } 419 420 // Return the last 64 bits of a 128 bit block. 421 inline deUint64 get128BitBlockEnd (const deUint8* src, int blockNdx) 422 { 423 return get64BitBlock(src, 2*blockNdx + 1); 424 } 425 426 inline deUint32 getBit (deUint64 src, int bit) 427 { 428 return (src >> bit) & 1; 429 } 430 431 inline deUint32 getBits (deUint64 src, int low, int high) 432 { 433 const int numBits = (high-low) + 1; 434 DE_ASSERT(de::inRange(numBits, 1, 32)); 435 if (numBits < 32) 436 return (deUint32)((src >> low) & ((1u<<numBits)-1)); 437 else 438 return (deUint32)((src >> low) & 0xFFFFFFFFu); 439 } 440 441 inline deUint8 extend7To8 (deUint8 src) 442 { 443 DE_ASSERT((src & ~((1<<7)-1)) == 0); 444 return (deUint8)((src << 1) | (src >> 6)); 445 } 446 447 inline deInt8 extendSigned3To8 (deUint8 src) 448 { 449 const bool isNeg = (src & (1<<2)) != 0; 450 return (deInt8)((isNeg ? ~((1<<3)-1) : 0) | src); 451 } 452 453 inline deUint8 extend5Delta3To8 (deUint8 base5, deUint8 delta3) 454 { 455 const deUint8 t = (deUint8)((deInt8)base5 + extendSigned3To8(delta3)); 456 return extend5To8(t); 457 } 458 459 inline deUint16 extend11To16 (deUint16 src) 460 { 461 DE_ASSERT((src & ~((1<<11)-1)) == 0); 462 return (deUint16)((src << 5) | (src >> 6)); 463 } 464 465 inline deInt16 extend11To16WithSign (deInt16 src) 466 { 467 if (src < 0) 468 return (deInt16)(-(deInt16)extend11To16((deUint16)(-src))); 469 else 470 return (deInt16)extend11To16(src); 471 } 472 473 void decompressETC1Block (deUint8 dst[ETC2_UNCOMPRESSED_BLOCK_SIZE_RGB8], deUint64 src) 474 { 475 const int diffBit = (int)getBit(src, 33); 476 const int flipBit = (int)getBit(src, 32); 477 const deUint32 table[2] = { getBits(src, 37, 39), getBits(src, 34, 36) }; 478 deUint8 baseR[2]; 479 deUint8 baseG[2]; 480 deUint8 baseB[2]; 481 482 if (diffBit == 0) 483 { 484 // Individual mode. 485 baseR[0] = extend4To8((deUint8)getBits(src, 60, 63)); 486 baseR[1] = extend4To8((deUint8)getBits(src, 56, 59)); 487 baseG[0] = extend4To8((deUint8)getBits(src, 52, 55)); 488 baseG[1] = extend4To8((deUint8)getBits(src, 48, 51)); 489 baseB[0] = extend4To8((deUint8)getBits(src, 44, 47)); 490 baseB[1] = extend4To8((deUint8)getBits(src, 40, 43)); 491 } 492 else 493 { 494 // Differential mode (diffBit == 1). 495 deUint8 bR = (deUint8)getBits(src, 59, 63); // 5b 496 deUint8 dR = (deUint8)getBits(src, 56, 58); // 3b 497 deUint8 bG = (deUint8)getBits(src, 51, 55); 498 deUint8 dG = (deUint8)getBits(src, 48, 50); 499 deUint8 bB = (deUint8)getBits(src, 43, 47); 500 deUint8 dB = (deUint8)getBits(src, 40, 42); 501 502 baseR[0] = extend5To8(bR); 503 baseG[0] = extend5To8(bG); 504 baseB[0] = extend5To8(bB); 505 506 baseR[1] = extend5Delta3To8(bR, dR); 507 baseG[1] = extend5Delta3To8(bG, dG); 508 baseB[1] = extend5Delta3To8(bB, dB); 509 } 510 511 static const int modifierTable[8][4] = 512 { 513 // 00 01 10 11 514 { 2, 8, -2, -8 }, 515 { 5, 17, -5, -17 }, 516 { 9, 29, -9, -29 }, 517 { 13, 42, -13, -42 }, 518 { 18, 60, -18, -60 }, 519 { 24, 80, -24, -80 }, 520 { 33, 106, -33, -106 }, 521 { 47, 183, -47, -183 } 522 }; 523 524 // Write final pixels. 525 for (int pixelNdx = 0; pixelNdx < ETC2_BLOCK_HEIGHT*ETC2_BLOCK_WIDTH; pixelNdx++) 526 { 527 const int x = pixelNdx / ETC2_BLOCK_HEIGHT; 528 const int y = pixelNdx % ETC2_BLOCK_HEIGHT; 529 const int dstOffset = (y*ETC2_BLOCK_WIDTH + x)*ETC2_UNCOMPRESSED_PIXEL_SIZE_RGB8; 530 const int subBlock = ((flipBit ? y : x) >= 2) ? 1 : 0; 531 const deUint32 tableNdx = table[subBlock]; 532 const deUint32 modifierNdx = (getBit(src, 16+pixelNdx) << 1) | getBit(src, pixelNdx); 533 const int modifier = modifierTable[tableNdx][modifierNdx]; 534 535 dst[dstOffset+0] = (deUint8)deClamp32((int)baseR[subBlock] + modifier, 0, 255); 536 dst[dstOffset+1] = (deUint8)deClamp32((int)baseG[subBlock] + modifier, 0, 255); 537 dst[dstOffset+2] = (deUint8)deClamp32((int)baseB[subBlock] + modifier, 0, 255); 538 } 539 } 540 541 // if alphaMode is true, do PUNCHTHROUGH and store alpha to alphaDst; otherwise do ordinary ETC2 RGB8. 542 void decompressETC2Block (deUint8 dst[ETC2_UNCOMPRESSED_BLOCK_SIZE_RGB8], deUint64 src, deUint8 alphaDst[ETC2_UNCOMPRESSED_BLOCK_SIZE_A8], bool alphaMode) 543 { 544 enum Etc2Mode 545 { 546 MODE_INDIVIDUAL = 0, 547 MODE_DIFFERENTIAL, 548 MODE_T, 549 MODE_H, 550 MODE_PLANAR, 551 552 MODE_LAST 553 }; 554 555 const int diffOpaqueBit = (int)getBit(src, 33); 556 const deInt8 selBR = (deInt8)getBits(src, 59, 63); // 5 bits. 557 const deInt8 selBG = (deInt8)getBits(src, 51, 55); 558 const deInt8 selBB = (deInt8)getBits(src, 43, 47); 559 const deInt8 selDR = extendSigned3To8((deUint8)getBits(src, 56, 58)); // 3 bits. 560 const deInt8 selDG = extendSigned3To8((deUint8)getBits(src, 48, 50)); 561 const deInt8 selDB = extendSigned3To8((deUint8)getBits(src, 40, 42)); 562 Etc2Mode mode; 563 564 if (!alphaMode && diffOpaqueBit == 0) 565 mode = MODE_INDIVIDUAL; 566 else if (!de::inRange(selBR + selDR, 0, 31)) 567 mode = MODE_T; 568 else if (!de::inRange(selBG + selDG, 0, 31)) 569 mode = MODE_H; 570 else if (!de::inRange(selBB + selDB, 0, 31)) 571 mode = MODE_PLANAR; 572 else 573 mode = MODE_DIFFERENTIAL; 574 575 if (mode == MODE_INDIVIDUAL || mode == MODE_DIFFERENTIAL) 576 { 577 // Individual and differential modes have some steps in common, handle them here. 578 static const int modifierTable[8][4] = 579 { 580 // 00 01 10 11 581 { 2, 8, -2, -8 }, 582 { 5, 17, -5, -17 }, 583 { 9, 29, -9, -29 }, 584 { 13, 42, -13, -42 }, 585 { 18, 60, -18, -60 }, 586 { 24, 80, -24, -80 }, 587 { 33, 106, -33, -106 }, 588 { 47, 183, -47, -183 } 589 }; 590 591 const int flipBit = (int)getBit(src, 32); 592 const deUint32 table[2] = { getBits(src, 37, 39), getBits(src, 34, 36) }; 593 deUint8 baseR[2]; 594 deUint8 baseG[2]; 595 deUint8 baseB[2]; 596 597 if (mode == MODE_INDIVIDUAL) 598 { 599 // Individual mode, initial values. 600 baseR[0] = extend4To8((deUint8)getBits(src, 60, 63)); 601 baseR[1] = extend4To8((deUint8)getBits(src, 56, 59)); 602 baseG[0] = extend4To8((deUint8)getBits(src, 52, 55)); 603 baseG[1] = extend4To8((deUint8)getBits(src, 48, 51)); 604 baseB[0] = extend4To8((deUint8)getBits(src, 44, 47)); 605 baseB[1] = extend4To8((deUint8)getBits(src, 40, 43)); 606 } 607 else 608 { 609 // Differential mode, initial values. 610 baseR[0] = extend5To8(selBR); 611 baseG[0] = extend5To8(selBG); 612 baseB[0] = extend5To8(selBB); 613 614 baseR[1] = extend5To8((deUint8)(selBR + selDR)); 615 baseG[1] = extend5To8((deUint8)(selBG + selDG)); 616 baseB[1] = extend5To8((deUint8)(selBB + selDB)); 617 } 618 619 // Write final pixels for individual or differential mode. 620 for (int pixelNdx = 0; pixelNdx < ETC2_BLOCK_HEIGHT*ETC2_BLOCK_WIDTH; pixelNdx++) 621 { 622 const int x = pixelNdx / ETC2_BLOCK_HEIGHT; 623 const int y = pixelNdx % ETC2_BLOCK_HEIGHT; 624 const int dstOffset = (y*ETC2_BLOCK_WIDTH + x)*ETC2_UNCOMPRESSED_PIXEL_SIZE_RGB8; 625 const int subBlock = ((flipBit ? y : x) >= 2) ? 1 : 0; 626 const deUint32 tableNdx = table[subBlock]; 627 const deUint32 modifierNdx = (getBit(src, 16+pixelNdx) << 1) | getBit(src, pixelNdx); 628 const int alphaDstOffset = (y*ETC2_BLOCK_WIDTH + x)*ETC2_UNCOMPRESSED_PIXEL_SIZE_A8; // Only needed for PUNCHTHROUGH version. 629 630 // If doing PUNCHTHROUGH version (alphaMode), opaque bit may affect colors. 631 if (alphaMode && diffOpaqueBit == 0 && modifierNdx == 2) 632 { 633 dst[dstOffset+0] = 0; 634 dst[dstOffset+1] = 0; 635 dst[dstOffset+2] = 0; 636 alphaDst[alphaDstOffset] = 0; 637 } 638 else 639 { 640 int modifier; 641 642 // PUNCHTHROUGH version and opaque bit may also affect modifiers. 643 if (alphaMode && diffOpaqueBit == 0 && (modifierNdx == 0 || modifierNdx == 2)) 644 modifier = 0; 645 else 646 modifier = modifierTable[tableNdx][modifierNdx]; 647 648 dst[dstOffset+0] = (deUint8)deClamp32((int)baseR[subBlock] + modifier, 0, 255); 649 dst[dstOffset+1] = (deUint8)deClamp32((int)baseG[subBlock] + modifier, 0, 255); 650 dst[dstOffset+2] = (deUint8)deClamp32((int)baseB[subBlock] + modifier, 0, 255); 651 652 if (alphaMode) 653 alphaDst[alphaDstOffset] = 255; 654 } 655 } 656 } 657 else if (mode == MODE_T || mode == MODE_H) 658 { 659 // T and H modes have some steps in common, handle them here. 660 static const int distTable[8] = { 3, 6, 11, 16, 23, 32, 41, 64 }; 661 662 deUint8 paintR[4]; 663 deUint8 paintG[4]; 664 deUint8 paintB[4]; 665 666 if (mode == MODE_T) 667 { 668 // T mode, calculate paint values. 669 const deUint8 R1a = (deUint8)getBits(src, 59, 60); 670 const deUint8 R1b = (deUint8)getBits(src, 56, 57); 671 const deUint8 G1 = (deUint8)getBits(src, 52, 55); 672 const deUint8 B1 = (deUint8)getBits(src, 48, 51); 673 const deUint8 R2 = (deUint8)getBits(src, 44, 47); 674 const deUint8 G2 = (deUint8)getBits(src, 40, 43); 675 const deUint8 B2 = (deUint8)getBits(src, 36, 39); 676 const deUint32 distNdx = (getBits(src, 34, 35) << 1) | getBit(src, 32); 677 const int dist = distTable[distNdx]; 678 679 paintR[0] = extend4To8((deUint8)((R1a << 2) | R1b)); 680 paintG[0] = extend4To8(G1); 681 paintB[0] = extend4To8(B1); 682 paintR[2] = extend4To8(R2); 683 paintG[2] = extend4To8(G2); 684 paintB[2] = extend4To8(B2); 685 paintR[1] = (deUint8)deClamp32((int)paintR[2] + dist, 0, 255); 686 paintG[1] = (deUint8)deClamp32((int)paintG[2] + dist, 0, 255); 687 paintB[1] = (deUint8)deClamp32((int)paintB[2] + dist, 0, 255); 688 paintR[3] = (deUint8)deClamp32((int)paintR[2] - dist, 0, 255); 689 paintG[3] = (deUint8)deClamp32((int)paintG[2] - dist, 0, 255); 690 paintB[3] = (deUint8)deClamp32((int)paintB[2] - dist, 0, 255); 691 } 692 else 693 { 694 // H mode, calculate paint values. 695 const deUint8 R1 = (deUint8)getBits(src, 59, 62); 696 const deUint8 G1a = (deUint8)getBits(src, 56, 58); 697 const deUint8 G1b = (deUint8)getBit(src, 52); 698 const deUint8 B1a = (deUint8)getBit(src, 51); 699 const deUint8 B1b = (deUint8)getBits(src, 47, 49); 700 const deUint8 R2 = (deUint8)getBits(src, 43, 46); 701 const deUint8 G2 = (deUint8)getBits(src, 39, 42); 702 const deUint8 B2 = (deUint8)getBits(src, 35, 38); 703 deUint8 baseR[2]; 704 deUint8 baseG[2]; 705 deUint8 baseB[2]; 706 deUint32 baseValue[2]; 707 deUint32 distNdx; 708 int dist; 709 710 baseR[0] = extend4To8(R1); 711 baseG[0] = extend4To8((deUint8)((G1a << 1) | G1b)); 712 baseB[0] = extend4To8((deUint8)((B1a << 3) | B1b)); 713 baseR[1] = extend4To8(R2); 714 baseG[1] = extend4To8(G2); 715 baseB[1] = extend4To8(B2); 716 baseValue[0] = (((deUint32)baseR[0]) << 16) | (((deUint32)baseG[0]) << 8) | baseB[0]; 717 baseValue[1] = (((deUint32)baseR[1]) << 16) | (((deUint32)baseG[1]) << 8) | baseB[1]; 718 distNdx = (getBit(src, 34) << 2) | (getBit(src, 32) << 1) | (deUint32)(baseValue[0] >= baseValue[1]); 719 dist = distTable[distNdx]; 720 721 paintR[0] = (deUint8)deClamp32((int)baseR[0] + dist, 0, 255); 722 paintG[0] = (deUint8)deClamp32((int)baseG[0] + dist, 0, 255); 723 paintB[0] = (deUint8)deClamp32((int)baseB[0] + dist, 0, 255); 724 paintR[1] = (deUint8)deClamp32((int)baseR[0] - dist, 0, 255); 725 paintG[1] = (deUint8)deClamp32((int)baseG[0] - dist, 0, 255); 726 paintB[1] = (deUint8)deClamp32((int)baseB[0] - dist, 0, 255); 727 paintR[2] = (deUint8)deClamp32((int)baseR[1] + dist, 0, 255); 728 paintG[2] = (deUint8)deClamp32((int)baseG[1] + dist, 0, 255); 729 paintB[2] = (deUint8)deClamp32((int)baseB[1] + dist, 0, 255); 730 paintR[3] = (deUint8)deClamp32((int)baseR[1] - dist, 0, 255); 731 paintG[3] = (deUint8)deClamp32((int)baseG[1] - dist, 0, 255); 732 paintB[3] = (deUint8)deClamp32((int)baseB[1] - dist, 0, 255); 733 } 734 735 // Write final pixels for T or H mode. 736 for (int pixelNdx = 0; pixelNdx < ETC2_BLOCK_HEIGHT*ETC2_BLOCK_WIDTH; pixelNdx++) 737 { 738 const int x = pixelNdx / ETC2_BLOCK_HEIGHT; 739 const int y = pixelNdx % ETC2_BLOCK_HEIGHT; 740 const int dstOffset = (y*ETC2_BLOCK_WIDTH + x)*ETC2_UNCOMPRESSED_PIXEL_SIZE_RGB8; 741 const deUint32 paintNdx = (getBit(src, 16+pixelNdx) << 1) | getBit(src, pixelNdx); 742 const int alphaDstOffset = (y*ETC2_BLOCK_WIDTH + x)*ETC2_UNCOMPRESSED_PIXEL_SIZE_A8; // Only needed for PUNCHTHROUGH version. 743 744 if (alphaMode && diffOpaqueBit == 0 && paintNdx == 2) 745 { 746 dst[dstOffset+0] = 0; 747 dst[dstOffset+1] = 0; 748 dst[dstOffset+2] = 0; 749 alphaDst[alphaDstOffset] = 0; 750 } 751 else 752 { 753 dst[dstOffset+0] = (deUint8)deClamp32((int)paintR[paintNdx], 0, 255); 754 dst[dstOffset+1] = (deUint8)deClamp32((int)paintG[paintNdx], 0, 255); 755 dst[dstOffset+2] = (deUint8)deClamp32((int)paintB[paintNdx], 0, 255); 756 757 if (alphaMode) 758 alphaDst[alphaDstOffset] = 255; 759 } 760 } 761 } 762 else 763 { 764 // Planar mode. 765 const deUint8 GO1 = (deUint8)getBit(src, 56); 766 const deUint8 GO2 = (deUint8)getBits(src, 49, 54); 767 const deUint8 BO1 = (deUint8)getBit(src, 48); 768 const deUint8 BO2 = (deUint8)getBits(src, 43, 44); 769 const deUint8 BO3 = (deUint8)getBits(src, 39, 41); 770 const deUint8 RH1 = (deUint8)getBits(src, 34, 38); 771 const deUint8 RH2 = (deUint8)getBit(src, 32); 772 const deUint8 RO = extend6To8((deUint8)getBits(src, 57, 62)); 773 const deUint8 GO = extend7To8((deUint8)((GO1 << 6) | GO2)); 774 const deUint8 BO = extend6To8((deUint8)((BO1 << 5) | (BO2 << 3) | BO3)); 775 const deUint8 RH = extend6To8((deUint8)((RH1 << 1) | RH2)); 776 const deUint8 GH = extend7To8((deUint8)getBits(src, 25, 31)); 777 const deUint8 BH = extend6To8((deUint8)getBits(src, 19, 24)); 778 const deUint8 RV = extend6To8((deUint8)getBits(src, 13, 18)); 779 const deUint8 GV = extend7To8((deUint8)getBits(src, 6, 12)); 780 const deUint8 BV = extend6To8((deUint8)getBits(src, 0, 5)); 781 782 // Write final pixels for planar mode. 783 for (int y = 0; y < 4; y++) 784 { 785 for (int x = 0; x < 4; x++) 786 { 787 const int dstOffset = (y*ETC2_BLOCK_WIDTH + x)*ETC2_UNCOMPRESSED_PIXEL_SIZE_RGB8; 788 const int unclampedR = (x * ((int)RH-(int)RO) + y * ((int)RV-(int)RO) + 4*(int)RO + 2) >> 2; 789 const int unclampedG = (x * ((int)GH-(int)GO) + y * ((int)GV-(int)GO) + 4*(int)GO + 2) >> 2; 790 const int unclampedB = (x * ((int)BH-(int)BO) + y * ((int)BV-(int)BO) + 4*(int)BO + 2) >> 2; 791 const int alphaDstOffset = (y*ETC2_BLOCK_WIDTH + x)*ETC2_UNCOMPRESSED_PIXEL_SIZE_A8; // Only needed for PUNCHTHROUGH version. 792 793 dst[dstOffset+0] = (deUint8)deClamp32(unclampedR, 0, 255); 794 dst[dstOffset+1] = (deUint8)deClamp32(unclampedG, 0, 255); 795 dst[dstOffset+2] = (deUint8)deClamp32(unclampedB, 0, 255); 796 797 if (alphaMode) 798 alphaDst[alphaDstOffset] = 255; 799 } 800 } 801 } 802 } 803 804 void decompressEAC8Block (deUint8 dst[ETC2_UNCOMPRESSED_BLOCK_SIZE_A8], deUint64 src) 805 { 806 static const int modifierTable[16][8] = 807 { 808 {-3, -6, -9, -15, 2, 5, 8, 14}, 809 {-3, -7, -10, -13, 2, 6, 9, 12}, 810 {-2, -5, -8, -13, 1, 4, 7, 12}, 811 {-2, -4, -6, -13, 1, 3, 5, 12}, 812 {-3, -6, -8, -12, 2, 5, 7, 11}, 813 {-3, -7, -9, -11, 2, 6, 8, 10}, 814 {-4, -7, -8, -11, 3, 6, 7, 10}, 815 {-3, -5, -8, -11, 2, 4, 7, 10}, 816 {-2, -6, -8, -10, 1, 5, 7, 9}, 817 {-2, -5, -8, -10, 1, 4, 7, 9}, 818 {-2, -4, -8, -10, 1, 3, 7, 9}, 819 {-2, -5, -7, -10, 1, 4, 6, 9}, 820 {-3, -4, -7, -10, 2, 3, 6, 9}, 821 {-1, -2, -3, -10, 0, 1, 2, 9}, 822 {-4, -6, -8, -9, 3, 5, 7, 8}, 823 {-3, -5, -7, -9, 2, 4, 6, 8} 824 }; 825 826 const deUint8 baseCodeword = (deUint8)getBits(src, 56, 63); 827 const deUint8 multiplier = (deUint8)getBits(src, 52, 55); 828 const deUint32 tableNdx = getBits(src, 48, 51); 829 830 for (int pixelNdx = 0; pixelNdx < ETC2_BLOCK_HEIGHT*ETC2_BLOCK_WIDTH; pixelNdx++) 831 { 832 const int x = pixelNdx / ETC2_BLOCK_HEIGHT; 833 const int y = pixelNdx % ETC2_BLOCK_HEIGHT; 834 const int dstOffset = (y*ETC2_BLOCK_WIDTH + x)*ETC2_UNCOMPRESSED_PIXEL_SIZE_A8; 835 const int pixelBitNdx = 45 - 3*pixelNdx; 836 const deUint32 modifierNdx = (getBit(src, pixelBitNdx + 2) << 2) | (getBit(src, pixelBitNdx + 1) << 1) | getBit(src, pixelBitNdx); 837 const int modifier = modifierTable[tableNdx][modifierNdx]; 838 839 dst[dstOffset] = (deUint8)deClamp32((int)baseCodeword + (int)multiplier*modifier, 0, 255); 840 } 841 } 842 843 void decompressEAC11Block (deUint8 dst[ETC2_UNCOMPRESSED_BLOCK_SIZE_R11], deUint64 src, bool signedMode) 844 { 845 static const int modifierTable[16][8] = 846 { 847 {-3, -6, -9, -15, 2, 5, 8, 14}, 848 {-3, -7, -10, -13, 2, 6, 9, 12}, 849 {-2, -5, -8, -13, 1, 4, 7, 12}, 850 {-2, -4, -6, -13, 1, 3, 5, 12}, 851 {-3, -6, -8, -12, 2, 5, 7, 11}, 852 {-3, -7, -9, -11, 2, 6, 8, 10}, 853 {-4, -7, -8, -11, 3, 6, 7, 10}, 854 {-3, -5, -8, -11, 2, 4, 7, 10}, 855 {-2, -6, -8, -10, 1, 5, 7, 9}, 856 {-2, -5, -8, -10, 1, 4, 7, 9}, 857 {-2, -4, -8, -10, 1, 3, 7, 9}, 858 {-2, -5, -7, -10, 1, 4, 6, 9}, 859 {-3, -4, -7, -10, 2, 3, 6, 9}, 860 {-1, -2, -3, -10, 0, 1, 2, 9}, 861 {-4, -6, -8, -9, 3, 5, 7, 8}, 862 {-3, -5, -7, -9, 2, 4, 6, 8} 863 }; 864 865 const deInt32 multiplier = (deInt32)getBits(src, 52, 55); 866 const deInt32 tableNdx = (deInt32)getBits(src, 48, 51); 867 deInt32 baseCodeword = (deInt32)getBits(src, 56, 63); 868 869 if (signedMode) 870 { 871 if (baseCodeword > 127) 872 baseCodeword -= 256; 873 if (baseCodeword == -128) 874 baseCodeword = -127; 875 } 876 877 for (int pixelNdx = 0; pixelNdx < ETC2_BLOCK_HEIGHT*ETC2_BLOCK_WIDTH; pixelNdx++) 878 { 879 const int x = pixelNdx / ETC2_BLOCK_HEIGHT; 880 const int y = pixelNdx % ETC2_BLOCK_HEIGHT; 881 const int dstOffset = (y*ETC2_BLOCK_WIDTH + x)*ETC2_UNCOMPRESSED_PIXEL_SIZE_R11; 882 const int pixelBitNdx = 45 - 3*pixelNdx; 883 const deUint32 modifierNdx = (getBit(src, pixelBitNdx + 2) << 2) | (getBit(src, pixelBitNdx + 1) << 1) | getBit(src, pixelBitNdx); 884 const int modifier = modifierTable[tableNdx][modifierNdx]; 885 886 if (signedMode) 887 { 888 deInt16 value; 889 890 if (multiplier != 0) 891 value = (deInt16)deClamp32(baseCodeword*8 + multiplier*modifier*8, -1023, 1023); 892 else 893 value = (deInt16)deClamp32(baseCodeword*8 + modifier, -1023, 1023); 894 895 *((deInt16*)(dst + dstOffset)) = value; 896 } 897 else 898 { 899 deUint16 value; 900 901 if (multiplier != 0) 902 value = (deUint16)deClamp32(baseCodeword*8 + 4 + multiplier*modifier*8, 0, 2047); 903 else 904 value= (deUint16)deClamp32(baseCodeword*8 + 4 + modifier, 0, 2047); 905 906 *((deUint16*)(dst + dstOffset)) = value; 907 } 908 } 909 } 910 911 } // EtcDecompressInternal 912 913 void decompressETC1 (const PixelBufferAccess& dst, const deUint8* src) 914 { 915 using namespace EtcDecompressInternal; 916 917 deUint8* const dstPtr = (deUint8*)dst.getDataPtr(); 918 const deUint64 compressedBlock = get64BitBlock(src, 0); 919 920 decompressETC1Block(dstPtr, compressedBlock); 921 } 922 923 void decompressETC2 (const PixelBufferAccess& dst, const deUint8* src) 924 { 925 using namespace EtcDecompressInternal; 926 927 deUint8* const dstPtr = (deUint8*)dst.getDataPtr(); 928 const deUint64 compressedBlock = get64BitBlock(src, 0); 929 930 decompressETC2Block(dstPtr, compressedBlock, NULL, false); 931 } 932 933 void decompressETC2_EAC_RGBA8 (const PixelBufferAccess& dst, const deUint8* src) 934 { 935 using namespace EtcDecompressInternal; 936 937 deUint8* const dstPtr = (deUint8*)dst.getDataPtr(); 938 const int dstRowPitch = dst.getRowPitch(); 939 const int dstPixelSize = ETC2_UNCOMPRESSED_PIXEL_SIZE_RGBA8; 940 941 const deUint64 compressedBlockAlpha = get128BitBlockStart(src, 0); 942 const deUint64 compressedBlockRGB = get128BitBlockEnd(src, 0); 943 deUint8 uncompressedBlockAlpha[ETC2_UNCOMPRESSED_BLOCK_SIZE_A8]; 944 deUint8 uncompressedBlockRGB[ETC2_UNCOMPRESSED_BLOCK_SIZE_RGB8]; 945 946 // Decompress. 947 decompressETC2Block(uncompressedBlockRGB, compressedBlockRGB, NULL, false); 948 decompressEAC8Block(uncompressedBlockAlpha, compressedBlockAlpha); 949 950 // Write to dst. 951 for (int y = 0; y < (int)ETC2_BLOCK_HEIGHT; y++) 952 { 953 for (int x = 0; x < (int)ETC2_BLOCK_WIDTH; x++) 954 { 955 const deUint8* const srcPixelRGB = &uncompressedBlockRGB[(y*ETC2_BLOCK_WIDTH + x)*ETC2_UNCOMPRESSED_PIXEL_SIZE_RGB8]; 956 const deUint8* const srcPixelAlpha = &uncompressedBlockAlpha[(y*ETC2_BLOCK_WIDTH + x)*ETC2_UNCOMPRESSED_PIXEL_SIZE_A8]; 957 deUint8* const dstPixel = dstPtr + y*dstRowPitch + x*dstPixelSize; 958 959 DE_STATIC_ASSERT(ETC2_UNCOMPRESSED_PIXEL_SIZE_RGBA8 == 4); 960 dstPixel[0] = srcPixelRGB[0]; 961 dstPixel[1] = srcPixelRGB[1]; 962 dstPixel[2] = srcPixelRGB[2]; 963 dstPixel[3] = srcPixelAlpha[0]; 964 } 965 } 966 } 967 968 void decompressETC2_RGB8_PUNCHTHROUGH_ALPHA1 (const PixelBufferAccess& dst, const deUint8* src) 969 { 970 using namespace EtcDecompressInternal; 971 972 deUint8* const dstPtr = (deUint8*)dst.getDataPtr(); 973 const int dstRowPitch = dst.getRowPitch(); 974 const int dstPixelSize = ETC2_UNCOMPRESSED_PIXEL_SIZE_RGBA8; 975 976 const deUint64 compressedBlockRGBA = get64BitBlock(src, 0); 977 deUint8 uncompressedBlockRGB[ETC2_UNCOMPRESSED_BLOCK_SIZE_RGB8]; 978 deUint8 uncompressedBlockAlpha[ETC2_UNCOMPRESSED_BLOCK_SIZE_A8]; 979 980 // Decompress. 981 decompressETC2Block(uncompressedBlockRGB, compressedBlockRGBA, uncompressedBlockAlpha, DE_TRUE); 982 983 // Write to dst. 984 for (int y = 0; y < (int)ETC2_BLOCK_HEIGHT; y++) 985 { 986 for (int x = 0; x < (int)ETC2_BLOCK_WIDTH; x++) 987 { 988 const deUint8* const srcPixel = &uncompressedBlockRGB[(y*ETC2_BLOCK_WIDTH + x)*ETC2_UNCOMPRESSED_PIXEL_SIZE_RGB8]; 989 const deUint8* const srcPixelAlpha = &uncompressedBlockAlpha[(y*ETC2_BLOCK_WIDTH + x)*ETC2_UNCOMPRESSED_PIXEL_SIZE_A8]; 990 deUint8* const dstPixel = dstPtr + y*dstRowPitch + x*dstPixelSize; 991 992 DE_STATIC_ASSERT(ETC2_UNCOMPRESSED_PIXEL_SIZE_RGBA8 == 4); 993 dstPixel[0] = srcPixel[0]; 994 dstPixel[1] = srcPixel[1]; 995 dstPixel[2] = srcPixel[2]; 996 dstPixel[3] = srcPixelAlpha[0]; 997 } 998 } 999 } 1000 1001 void decompressEAC_R11 (const PixelBufferAccess& dst, const deUint8* src, bool signedMode) 1002 { 1003 using namespace EtcDecompressInternal; 1004 1005 deUint8* const dstPtr = (deUint8*)dst.getDataPtr(); 1006 const int dstRowPitch = dst.getRowPitch(); 1007 const int dstPixelSize = ETC2_UNCOMPRESSED_PIXEL_SIZE_R11; 1008 1009 const deUint64 compressedBlock = get64BitBlock(src, 0); 1010 deUint8 uncompressedBlock[ETC2_UNCOMPRESSED_BLOCK_SIZE_R11]; 1011 1012 // Decompress. 1013 decompressEAC11Block(uncompressedBlock, compressedBlock, signedMode); 1014 1015 // Write to dst. 1016 for (int y = 0; y < (int)ETC2_BLOCK_HEIGHT; y++) 1017 { 1018 for (int x = 0; x < (int)ETC2_BLOCK_WIDTH; x++) 1019 { 1020 DE_STATIC_ASSERT(ETC2_UNCOMPRESSED_PIXEL_SIZE_R11 == 2); 1021 1022 if (signedMode) 1023 { 1024 const deInt16* const srcPixel = (deInt16*)&uncompressedBlock[(y*ETC2_BLOCK_WIDTH + x)*ETC2_UNCOMPRESSED_PIXEL_SIZE_R11]; 1025 deInt16* const dstPixel = (deInt16*)(dstPtr + y*dstRowPitch + x*dstPixelSize); 1026 1027 dstPixel[0] = extend11To16WithSign(srcPixel[0]); 1028 } 1029 else 1030 { 1031 const deUint16* const srcPixel = (deUint16*)&uncompressedBlock[(y*ETC2_BLOCK_WIDTH + x)*ETC2_UNCOMPRESSED_PIXEL_SIZE_R11]; 1032 deUint16* const dstPixel = (deUint16*)(dstPtr + y*dstRowPitch + x*dstPixelSize); 1033 1034 dstPixel[0] = extend11To16(srcPixel[0]); 1035 } 1036 } 1037 } 1038 } 1039 1040 void decompressEAC_RG11 (const PixelBufferAccess& dst, const deUint8* src, bool signedMode) 1041 { 1042 using namespace EtcDecompressInternal; 1043 1044 deUint8* const dstPtr = (deUint8*)dst.getDataPtr(); 1045 const int dstRowPitch = dst.getRowPitch(); 1046 const int dstPixelSize = ETC2_UNCOMPRESSED_PIXEL_SIZE_RG11; 1047 1048 const deUint64 compressedBlockR = get128BitBlockStart(src, 0); 1049 const deUint64 compressedBlockG = get128BitBlockEnd(src, 0); 1050 deUint8 uncompressedBlockR[ETC2_UNCOMPRESSED_BLOCK_SIZE_R11]; 1051 deUint8 uncompressedBlockG[ETC2_UNCOMPRESSED_BLOCK_SIZE_R11]; 1052 1053 // Decompress. 1054 decompressEAC11Block(uncompressedBlockR, compressedBlockR, signedMode); 1055 decompressEAC11Block(uncompressedBlockG, compressedBlockG, signedMode); 1056 1057 // Write to dst. 1058 for (int y = 0; y < (int)ETC2_BLOCK_HEIGHT; y++) 1059 { 1060 for (int x = 0; x < (int)ETC2_BLOCK_WIDTH; x++) 1061 { 1062 DE_STATIC_ASSERT(ETC2_UNCOMPRESSED_PIXEL_SIZE_RG11 == 4); 1063 1064 if (signedMode) 1065 { 1066 const deInt16* const srcPixelR = (deInt16*)&uncompressedBlockR[(y*ETC2_BLOCK_WIDTH + x)*ETC2_UNCOMPRESSED_PIXEL_SIZE_R11]; 1067 const deInt16* const srcPixelG = (deInt16*)&uncompressedBlockG[(y*ETC2_BLOCK_WIDTH + x)*ETC2_UNCOMPRESSED_PIXEL_SIZE_R11]; 1068 deInt16* const dstPixel = (deInt16*)(dstPtr + y*dstRowPitch + x*dstPixelSize); 1069 1070 dstPixel[0] = extend11To16WithSign(srcPixelR[0]); 1071 dstPixel[1] = extend11To16WithSign(srcPixelG[0]); 1072 } 1073 else 1074 { 1075 const deUint16* const srcPixelR = (deUint16*)&uncompressedBlockR[(y*ETC2_BLOCK_WIDTH + x)*ETC2_UNCOMPRESSED_PIXEL_SIZE_R11]; 1076 const deUint16* const srcPixelG = (deUint16*)&uncompressedBlockG[(y*ETC2_BLOCK_WIDTH + x)*ETC2_UNCOMPRESSED_PIXEL_SIZE_R11]; 1077 deUint16* const dstPixel = (deUint16*)(dstPtr + y*dstRowPitch + x*dstPixelSize); 1078 1079 dstPixel[0] = extend11To16(srcPixelR[0]); 1080 dstPixel[1] = extend11To16(srcPixelG[0]); 1081 } 1082 } 1083 } 1084 } 1085 1086 namespace BcDecompressInternal 1087 { 1088 1089 enum 1090 { 1091 BC_BLOCK_WIDTH = 4, 1092 BC_BLOCK_HEIGHT = 4 1093 }; 1094 1095 static const deUint8 epBits[14] = { 10, 7, 11, 11, 11, 9, 8, 8, 8, 6, 10, 11, 12, 16 }; 1096 1097 static const deUint8 partitions2[64][16] = 1098 { 1099 { 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1 }, 1100 { 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1 }, 1101 { 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1 }, 1102 { 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1 }, 1103 { 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 1 }, 1104 { 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1 }, 1105 { 0, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1 }, 1106 { 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1 }, 1107 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1 }, 1108 { 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, 1109 { 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1 }, 1110 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1 }, 1111 { 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, 1112 { 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1 }, 1113 { 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, 1114 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1 }, 1115 { 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1 }, 1116 { 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0 }, 1117 { 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0 }, 1118 { 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0 }, 1119 { 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0 }, 1120 { 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0 }, 1121 { 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0 }, 1122 { 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1 }, 1123 { 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0 }, 1124 { 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0 }, 1125 { 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0 }, 1126 { 0, 0, 1, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0 }, 1127 { 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0 }, 1128 { 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0 }, 1129 { 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 0 }, 1130 { 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0 }, 1131 { 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1 }, 1132 { 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1 }, 1133 { 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0 }, 1134 { 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 0, 0 }, 1135 { 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0 }, 1136 { 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0 }, 1137 { 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1 }, 1138 { 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1 }, 1139 { 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0 }, 1140 { 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0 }, 1141 { 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0 }, 1142 { 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0 }, 1143 { 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0 }, 1144 { 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1 }, 1145 { 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1 }, 1146 { 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0 }, 1147 { 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, 1148 { 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0 }, 1149 { 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0 }, 1150 { 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0 }, 1151 { 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1 }, 1152 { 0, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1 }, 1153 { 0, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0 }, 1154 { 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0 }, 1155 { 0, 1, 1, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1 }, 1156 { 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1 }, 1157 { 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1 }, 1158 { 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1 }, 1159 { 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1 }, 1160 { 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0 }, 1161 { 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0 }, 1162 { 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1 } 1163 }; 1164 1165 static const deUint8 partitions3[64][16] = 1166 { 1167 { 0, 0, 1, 1, 0, 0, 1, 1, 0, 2, 2, 1, 2, 2, 2, 2 }, 1168 { 0, 0, 0, 1, 0, 0, 1, 1, 2, 2, 1, 1, 2, 2, 2, 1 }, 1169 { 0, 0, 0, 0, 2, 0, 0, 1, 2, 2, 1, 1, 2, 2, 1, 1 }, 1170 { 0, 2, 2, 2, 0, 0, 2, 2, 0, 0, 1, 1, 0, 1, 1, 1 }, 1171 { 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 2, 2, 1, 1, 2, 2 }, 1172 { 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 2, 2, 0, 0, 2, 2 }, 1173 { 0, 0, 2, 2, 0, 0, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1 }, 1174 { 0, 0, 1, 1, 0, 0, 1, 1, 2, 2, 1, 1, 2, 2, 1, 1 }, 1175 { 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2 }, 1176 { 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2 }, 1177 { 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2 }, 1178 { 0, 0, 1, 2, 0, 0, 1, 2, 0, 0, 1, 2, 0, 0, 1, 2 }, 1179 { 0, 1, 1, 2, 0, 1, 1, 2, 0, 1, 1, 2, 0, 1, 1, 2 }, 1180 { 0, 1, 2, 2, 0, 1, 2, 2, 0, 1, 2, 2, 0, 1, 2, 2 }, 1181 { 0, 0, 1, 1, 0, 1, 1, 2, 1, 1, 2, 2, 1, 2, 2, 2 }, 1182 { 0, 0, 1, 1, 2, 0, 0, 1, 2, 2, 0, 0, 2, 2, 2, 0 }, 1183 { 0, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 2, 1, 1, 2, 2 }, 1184 { 0, 1, 1, 1, 0, 0, 1, 1, 2, 0, 0, 1, 2, 2, 0, 0 }, 1185 { 0, 0, 0, 0, 1, 1, 2, 2, 1, 1, 2, 2, 1, 1, 2, 2 }, 1186 { 0, 0, 2, 2, 0, 0, 2, 2, 0, 0, 2, 2, 1, 1, 1, 1 }, 1187 { 0, 1, 1, 1, 0, 1, 1, 1, 0, 2, 2, 2, 0, 2, 2, 2 }, 1188 { 0, 0, 0, 1, 0, 0, 0, 1, 2, 2, 2, 1, 2, 2, 2, 1 }, 1189 { 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 2, 2, 0, 1, 2, 2 }, 1190 { 0, 0, 0, 0, 1, 1, 0, 0, 2, 2, 1, 0, 2, 2, 1, 0 }, 1191 { 0, 1, 2, 2, 0, 1, 2, 2, 0, 0, 1, 1, 0, 0, 0, 0 }, 1192 { 0, 0, 1, 2, 0, 0, 1, 2, 1, 1, 2, 2, 2, 2, 2, 2 }, 1193 { 0, 1, 1, 0, 1, 2, 2, 1, 1, 2, 2, 1, 0, 1, 1, 0 }, 1194 { 0, 0, 0, 0, 0, 1, 1, 0, 1, 2, 2, 1, 1, 2, 2, 1 }, 1195 { 0, 0, 2, 2, 1, 1, 0, 2, 1, 1, 0, 2, 0, 0, 2, 2 }, 1196 { 0, 1, 1, 0, 0, 1, 1, 0, 2, 0, 0, 2, 2, 2, 2, 2 }, 1197 { 0, 0, 1, 1, 0, 1, 2, 2, 0, 1, 2, 2, 0, 0, 1, 1 }, 1198 { 0, 0, 0, 0, 2, 0, 0, 0, 2, 2, 1, 1, 2, 2, 2, 1 }, 1199 { 0, 0, 0, 0, 0, 0, 0, 2, 1, 1, 2, 2, 1, 2, 2, 2 }, 1200 { 0, 2, 2, 2, 0, 0, 2, 2, 0, 0, 1, 2, 0, 0, 1, 1 }, 1201 { 0, 0, 1, 1, 0, 0, 1, 2, 0, 0, 2, 2, 0, 2, 2, 2 }, 1202 { 0, 1, 2, 0, 0, 1, 2, 0, 0, 1, 2, 0, 0, 1, 2, 0 }, 1203 { 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 0, 0, 0, 0 }, 1204 { 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0 }, 1205 { 0, 1, 2, 0, 2, 0, 1, 2, 1, 2, 0, 1, 0, 1, 2, 0 }, 1206 { 0, 0, 1, 1, 2, 2, 0, 0, 1, 1, 2, 2, 0, 0, 1, 1 }, 1207 { 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 0, 0, 0, 0, 1, 1 }, 1208 { 0, 1, 0, 1, 0, 1, 0, 1, 2, 2, 2, 2, 2, 2, 2, 2 }, 1209 { 0, 0, 0, 0, 0, 0, 0, 0, 2, 1, 2, 1, 2, 1, 2, 1 }, 1210 { 0, 0, 2, 2, 1, 1, 2, 2, 0, 0, 2, 2, 1, 1, 2, 2 }, 1211 { 0, 0, 2, 2, 0, 0, 1, 1, 0, 0, 2, 2, 0, 0, 1, 1 }, 1212 { 0, 2, 2, 0, 1, 2, 2, 1, 0, 2, 2, 0, 1, 2, 2, 1 }, 1213 { 0, 1, 0, 1, 2, 2, 2, 2, 2, 2, 2, 2, 0, 1, 0, 1 }, 1214 { 0, 0, 0, 0, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1 }, 1215 { 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 2, 2, 2, 2 }, 1216 { 0, 2, 2, 2, 0, 1, 1, 1, 0, 2, 2, 2, 0, 1, 1, 1 }, 1217 { 0, 0, 0, 2, 1, 1, 1, 2, 0, 0, 0, 2, 1, 1, 1, 2 }, 1218 { 0, 0, 0, 0, 2, 1, 1, 2, 2, 1, 1, 2, 2, 1, 1, 2 }, 1219 { 0, 2, 2, 2, 0, 1, 1, 1, 0, 1, 1, 1, 0, 2, 2, 2 }, 1220 { 0, 0, 0, 2, 1, 1, 1, 2, 1, 1, 1, 2, 0, 0, 0, 2 }, 1221 { 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 2, 2, 2, 2 }, 1222 { 0, 0, 0, 0, 0, 0, 0, 0, 2, 1, 1, 2, 2, 1, 1, 2 }, 1223 { 0, 1, 1, 0, 0, 1, 1, 0, 2, 2, 2, 2, 2, 2, 2, 2 }, 1224 { 0, 0, 2, 2, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 2, 2 }, 1225 { 0, 0, 2, 2, 1, 1, 2, 2, 1, 1, 2, 2, 0, 0, 2, 2 }, 1226 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 1, 1, 2 }, 1227 { 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 1 }, 1228 { 0, 2, 2, 2, 1, 2, 2, 2, 0, 2, 2, 2, 1, 2, 2, 2 }, 1229 { 0, 1, 0, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 }, 1230 { 0, 1, 1, 1, 2, 0, 1, 1, 2, 2, 0, 1, 2, 2, 2, 0 } 1231 }; 1232 1233 static const deUint8 anchorIndicesSecondSubset2[64] = { 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 2, 8, 2, 2, 8, 8, 15, 2, 8, 2, 2, 8, 8, 2, 2, 1234 15, 15, 6, 8, 2, 8, 15, 15, 2, 8, 2, 2, 2, 15, 15, 6, 6, 2, 6, 8, 15, 15, 2, 2, 15, 15, 15, 15, 15, 2, 2, 15 }; 1235 1236 static const deUint8 anchorIndicesSecondSubset3[64] = { 3, 3, 15, 15, 8, 3, 15, 15, 8, 8, 6, 6, 6, 5, 3, 3, 3, 3, 8, 15, 3, 3, 6, 10, 5, 8, 8, 6, 8, 5, 15, 15, 1237 8, 15, 3, 5, 6, 10, 8, 15, 15, 3, 15, 5, 15, 15, 15, 15, 3, 15, 5, 5, 5, 8, 5, 10, 5, 10, 8, 13, 15, 12, 3, 3 }; 1238 1239 static const deUint8 anchorIndicesThirdSubset[64] = { 15, 8, 8, 3, 15, 15, 3, 8, 15, 15, 15, 15, 15, 15, 15, 8, 15, 8, 15, 3, 15, 8, 15, 8, 3, 15, 6, 10, 15, 15, 10, 8, 1240 15, 3, 15, 10, 10, 8, 9, 10, 6, 15, 8, 15, 3, 6, 6, 8, 15, 3, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 3, 15, 15, 8 }; 1241 1242 static const deUint16 weights2[4] = { 0, 21, 43, 64 }; 1243 static const deUint16 weights3[8] = { 0, 9, 18, 27, 37, 46, 55, 64 }; 1244 static const deUint16 weights4[16] = { 0, 4, 9, 13, 17, 21, 26, 30, 34, 38, 43, 47, 51, 55, 60, 64 }; 1245 1246 inline float uint8ToFloat (deUint8 src) 1247 { 1248 return ((float)src / 255.0f); 1249 } 1250 1251 inline float int8ToFloat (deInt8 src) 1252 { 1253 return ((float)src / 128.0f); 1254 } 1255 1256 inline deUint32 bgr16torgba32 (deUint16 src) 1257 { 1258 const deUint32 src32 = src; 1259 const deUint8 b5 = (src32 & 0x1f); 1260 const deUint8 g6 = (src32 >> 5) & 0x3f; 1261 const deUint8 r5 = (src32 >> 11) & 0x1f; 1262 const deUint32 a8 = 0xff; 1263 const deUint32 b8 = extend5To8(b5); 1264 const deUint32 g8 = extend6To8(g6); 1265 const deUint32 r8 = extend5To8(r5); 1266 1267 return (r8 | (g8 <<8) | (b8 << 16) | (a8 << 24)); 1268 } 1269 1270 // Interpolates color = 1/3 * c0 + 2/3 * c1 1271 inline deUint32 interpolateColor (deUint32 c0, deUint32 c1) 1272 { 1273 const deUint32 r0 = c0 & 0xff; 1274 const deUint32 g0 = (c0 >> 8) & 0xff; 1275 const deUint32 b0 = (c0 >> 16) & 0xff; 1276 const deUint32 a0 = (c0 >> 24) & 0xff; 1277 1278 const deUint32 r1 = c1 & 0xff; 1279 const deUint32 g1 = (c1 >> 8) & 0xff; 1280 const deUint32 b1 = (c1 >> 16) & 0xff; 1281 const deUint32 a1 = (c1 >> 24) & 0xff; 1282 1283 const deUint32 r = (r0 + (r1 << 1)) / 3; 1284 const deUint32 g = (g0 + (g1 << 1)) / 3; 1285 const deUint32 b = (b0 + (b1 << 1)) / 3; 1286 const deUint32 a = (a0 + (a1 << 1)) / 3; 1287 1288 return (r | (g << 8) | (b << 16) | (a << 24)); 1289 } 1290 1291 // Average of two colors 1292 inline deUint32 averageColor (deUint32 c0, deUint32 c1) 1293 { 1294 const deUint32 r0 = c0 & 0xff; 1295 const deUint32 g0 = (c0 >> 8) & 0xff; 1296 const deUint32 b0 = (c0 >> 16) & 0xff; 1297 const deUint32 a0 = (c0 >> 24) & 0xff; 1298 1299 const deUint32 r1 = c1 & 0xff; 1300 const deUint32 g1 = (c1 >> 8) & 0xff; 1301 const deUint32 b1 = (c1 >> 16) & 0xff; 1302 const deUint32 a1 = (c1 >> 24) & 0xff; 1303 1304 const deUint32 r = (r0 + r1) >> 1; 1305 const deUint32 g = (g0 + g1) >> 1; 1306 const deUint32 b = (b0 + b1) >> 1; 1307 const deUint32 a = (a0 + a1) >> 1; 1308 1309 return (r | (g << 8) | (b << 16) | (a << 24)); 1310 } 1311 1312 inline deInt8 extractModeBc6 (deUint8 src) 1313 { 1314 // Catch illegal modes 1315 switch(src & 0x1f) 1316 { 1317 case 0x13: 1318 case 0x17: 1319 case 0x1b: 1320 case 0x1f: 1321 return -1; 1322 }; 1323 1324 switch (src & 0x3) 1325 { 1326 case 0: return 0; 1327 case 1: return 1; 1328 case 2: return (deInt8)(2 + ((src >> 2) & 0x7)); 1329 case 3: return (deInt8)(10 + ((src >> 2) & 0x7)); 1330 }; 1331 1332 return -1; 1333 } 1334 1335 inline deInt8 extractModeBc7 (deUint8 src) 1336 { 1337 for (deInt8 i = 0; i < 8; i++) 1338 if (src & (1 << i)) 1339 return i; 1340 1341 return -1; 1342 } 1343 1344 inline deUint64 get64BitBlockLE (const deUint8* src, int blockNdx) 1345 { 1346 // Same as get64BitBlock, but little-endian. 1347 deUint64 block = 0; 1348 1349 for (int i = 0; i < 8; i++) 1350 block |= (deUint64)(src[blockNdx*8+i]) << (8ull*i); 1351 1352 return block; 1353 } 1354 1355 inline deUint32 getBits128 (deUint64 low, deUint64 high, deUint32 first, deUint32 last) 1356 { 1357 const deUint64 d[2] = { low, high }; 1358 const bool reverse = first > last; 1359 deUint32 ret = 0; 1360 1361 if (reverse) 1362 { 1363 const deUint32 tmp = first; 1364 first = last; 1365 last = tmp; 1366 } 1367 1368 const int elementFirst = first / 64; 1369 const int elementLast = last / 64; 1370 1371 if (elementFirst == elementLast) 1372 { 1373 // Bits contained in one of the 64bit elements 1374 const deUint32 shift = first % 64; 1375 const deUint32 len = last - first + 1; 1376 const deUint32 mask = (1 << len) - 1; 1377 ret = (deUint32)((d[elementFirst] >> shift) & mask); 1378 } 1379 else 1380 { 1381 // Bits contained in both of the 64bit elements 1382 DE_ASSERT(last > 63); 1383 DE_ASSERT(first < 64); 1384 const deUint32 len0 = 64 - first; 1385 const deUint32 mask0 = (1 << len0) - 1; 1386 const deUint32 data0 = (deUint32)(low >> first) & mask0; 1387 const deUint32 len1 = last - 63; 1388 const deUint32 mask1 = (1 << len1) - 1; 1389 const deUint32 data1 = (deUint32)(high & mask1); 1390 ret = (deUint32)((data1 << len0) | data0); 1391 } 1392 1393 if (reverse) 1394 { 1395 const deUint32 len = last - first + 1; 1396 const deUint32 orig = ret; 1397 ret = 0; 1398 1399 for (deUint32 i = 0; i < len; i++) 1400 { 1401 ret |= ((orig >> (len - 1 - i)) & 1) << i; 1402 } 1403 } 1404 1405 return ret; 1406 } 1407 1408 inline deInt32 signExtend (deInt32 value, deInt32 srcBits, deInt32 dstBits) 1409 { 1410 deUint32 sign = value & (1 << (srcBits - 1)); 1411 1412 if (!sign) return value; 1413 1414 deInt32 dstMask = (deInt32)(((deUint64)1 << dstBits) - 1); 1415 deInt32 extendedBits = 0xffffffff << srcBits; 1416 return (value | extendedBits) & dstMask; 1417 } 1418 1419 inline deInt32 unquantize (deInt32 x, int mode, bool hasSign) 1420 { 1421 if (hasSign) 1422 { 1423 bool s = false; 1424 1425 if (epBits[mode] >= 16) return x; 1426 1427 if (x < 0) 1428 { 1429 s = true; 1430 x = -x; 1431 } 1432 1433 if (x == 0) 1434 x = 0; 1435 else if (x >= (((deInt32)1 << (epBits[mode] - 1)) - 1)) 1436 x = 0x7fff; 1437 else 1438 x = (((deInt32)x << 15) + 0x4000) >> (epBits[mode] - 1); 1439 1440 if (s) 1441 x = -x; 1442 1443 return x; 1444 } 1445 else 1446 { 1447 if (epBits[mode] >= 15) 1448 return x; 1449 else if (x == 0) 1450 return 0; 1451 else if (x == (((deInt32)1 << epBits[mode]) - 1)) 1452 return 0xffff; 1453 else 1454 return ((((deInt32)x << 15) + 0x4000) >> (epBits[mode] - 1)); 1455 } 1456 } 1457 1458 inline deInt32 interpolate (deInt32 a, deInt32 b, deUint32 index, deUint32 indexPrecision) 1459 { 1460 const deUint16* weights[] = {weights2, weights3, weights4}; 1461 const deUint16* weight = weights[indexPrecision-2]; 1462 DE_ASSERT(indexPrecision >= 2 && indexPrecision <= 4); 1463 1464 return (((64 - weight[index]) * a + weight[index] * b + 32) >> 6); 1465 } 1466 1467 inline deInt16 finishUnquantize (deInt32 x, bool hasSign) 1468 { 1469 if (hasSign) 1470 { 1471 if (x < 0) 1472 x = -(((-x) * 31) >> 5); 1473 else 1474 x = (x * 31) >> 5; 1475 1476 if (x < 0) 1477 x = (-x) | 0x8000; 1478 } 1479 else 1480 { 1481 x = (x * 31) / 64; 1482 } 1483 1484 return (deInt16)x; 1485 } 1486 1487 } // BcDecompressInternal 1488 1489 void decompressBc1 (const PixelBufferAccess& dst, const deUint8* src, bool hasAlpha) 1490 { 1491 using namespace BcDecompressInternal; 1492 1493 deUint8* const dstPtr = (deUint8*)dst.getDataPtr(); 1494 const deUint32 dstRowPitch = dst.getRowPitch(); 1495 const deUint32 dstPixelSize = 4; 1496 const deUint16 color0_16 = ((deUint16*)src)[0]; 1497 const deUint16 color1_16 = ((deUint16*)src)[1]; 1498 const deUint32 color0 = bgr16torgba32(color0_16); 1499 const deUint32 color1 = bgr16torgba32(color1_16); 1500 const deUint8* const indices8 = &src[4]; 1501 1502 const bool alphaMode = color1_16 > color0_16; 1503 1504 const deInt32 indices[16] = 1505 { 1506 (indices8[0] >> 0) & 0x3, 1507 (indices8[0] >> 2) & 0x3, 1508 (indices8[0] >> 4) & 0x3, 1509 (indices8[0] >> 6) & 0x3, 1510 (indices8[1] >> 0) & 0x3, 1511 (indices8[1] >> 2) & 0x3, 1512 (indices8[1] >> 4) & 0x3, 1513 (indices8[1] >> 6) & 0x3, 1514 (indices8[2] >> 0) & 0x3, 1515 (indices8[2] >> 2) & 0x3, 1516 (indices8[2] >> 4) & 0x3, 1517 (indices8[2] >> 6) & 0x3, 1518 (indices8[3] >> 0) & 0x3, 1519 (indices8[3] >> 2) & 0x3, 1520 (indices8[3] >> 4) & 0x3, 1521 (indices8[3] >> 6) & 0x3 1522 }; 1523 1524 const deUint32 colors[4] = 1525 { 1526 color0, 1527 color1, 1528 alphaMode ? averageColor(color0, color1) : interpolateColor(color1, color0), 1529 alphaMode ? (hasAlpha ? 0 : 0xff000000) : interpolateColor(color0, color1) 1530 }; 1531 1532 for (deUint32 y = 0; y < (deUint32)BC_BLOCK_HEIGHT; y++) 1533 { 1534 for (deUint32 x = 0; x < (deUint32)BC_BLOCK_WIDTH; x++) 1535 { 1536 deUint32* const dstPixel = (deUint32*)(dstPtr + y * dstRowPitch + x * dstPixelSize); 1537 *dstPixel = colors[indices[y * BC_BLOCK_WIDTH + x]]; 1538 } 1539 } 1540 } 1541 1542 void decompressBc2 (const PixelBufferAccess& dst, const deUint8* src) 1543 { 1544 using namespace BcDecompressInternal; 1545 1546 deUint8* const dstPtr = (deUint8*)dst.getDataPtr(); 1547 const deUint32 dstRowPitch = dst.getRowPitch(); 1548 const deUint32 dstPixelSize = 4; 1549 const deUint16 color0_16 = ((deUint16*)src)[4]; 1550 const deUint16 color1_16 = ((deUint16*)src)[5]; 1551 const deUint32 color0 = bgr16torgba32(color0_16); 1552 const deUint32 color1 = bgr16torgba32(color1_16); 1553 const deUint8* const indices8 = &src[12]; 1554 const deUint8* const alphas8 = src; 1555 1556 const deInt32 indices[16] = 1557 { 1558 (indices8[0] >> 0) & 0x3, 1559 (indices8[0] >> 2) & 0x3, 1560 (indices8[0] >> 4) & 0x3, 1561 (indices8[0] >> 6) & 0x3, 1562 (indices8[1] >> 0) & 0x3, 1563 (indices8[1] >> 2) & 0x3, 1564 (indices8[1] >> 4) & 0x3, 1565 (indices8[1] >> 6) & 0x3, 1566 (indices8[2] >> 0) & 0x3, 1567 (indices8[2] >> 2) & 0x3, 1568 (indices8[2] >> 4) & 0x3, 1569 (indices8[2] >> 6) & 0x3, 1570 (indices8[3] >> 0) & 0x3, 1571 (indices8[3] >> 2) & 0x3, 1572 (indices8[3] >> 4) & 0x3, 1573 (indices8[3] >> 6) & 0x3 1574 }; 1575 1576 const deInt32 alphas[16] = 1577 { 1578 extend4To8(((alphas8[0] >> 0) & 0xf)) << 24, 1579 extend4To8(((alphas8[0] >> 4) & 0xf)) << 24, 1580 extend4To8(((alphas8[1] >> 0) & 0xf)) << 24, 1581 extend4To8(((alphas8[1] >> 4) & 0xf)) << 24, 1582 extend4To8(((alphas8[2] >> 0) & 0xf)) << 24, 1583 extend4To8(((alphas8[2] >> 4) & 0xf)) << 24, 1584 extend4To8(((alphas8[3] >> 0) & 0xf)) << 24, 1585 extend4To8(((alphas8[3] >> 4) & 0xf)) << 24, 1586 extend4To8(((alphas8[4] >> 0) & 0xf)) << 24, 1587 extend4To8(((alphas8[4] >> 4) & 0xf)) << 24, 1588 extend4To8(((alphas8[5] >> 0) & 0xf)) << 24, 1589 extend4To8(((alphas8[5] >> 4) & 0xf)) << 24, 1590 extend4To8(((alphas8[6] >> 0) & 0xf)) << 24, 1591 extend4To8(((alphas8[6] >> 4) & 0xf)) << 24, 1592 extend4To8(((alphas8[7] >> 0) & 0xf)) << 24, 1593 extend4To8(((alphas8[7] >> 4) & 0xf)) << 24 1594 }; 1595 1596 const deUint32 colors[4] = 1597 { 1598 color0, 1599 color1, 1600 interpolateColor(color1, color0), 1601 interpolateColor(color0, color1) 1602 }; 1603 1604 for (deUint32 y = 0; y < (deUint32)BC_BLOCK_HEIGHT; y++) 1605 { 1606 for (deUint32 x = 0; x < (deUint32)BC_BLOCK_WIDTH; x++) 1607 { 1608 deUint32* const dstPixel = (deUint32*)(dstPtr + y * dstRowPitch + x * dstPixelSize); 1609 *dstPixel = (colors[indices[y * BC_BLOCK_WIDTH + x]] & 0x00ffffff) | alphas[y * BC_BLOCK_WIDTH + x]; 1610 } 1611 } 1612 } 1613 1614 void decompressBc3 (const PixelBufferAccess& dst, const deUint8* src) 1615 { 1616 using namespace BcDecompressInternal; 1617 1618 deUint8* const dstPtr = (deUint8*)dst.getDataPtr(); 1619 const deUint32 dstRowPitch = dst.getRowPitch(); 1620 const deUint32 dstPixelSize = 4; 1621 const deUint8 alpha0 = src[0]; 1622 const deUint8 alpha1 = src[1]; 1623 const deUint16 color0_16 = ((deUint16*)src)[4]; 1624 const deUint16 color1_16 = ((deUint16*)src)[5]; 1625 const deUint32 color0 = bgr16torgba32(color0_16); 1626 const deUint32 color1 = bgr16torgba32(color1_16); 1627 const deUint8* const indices8 = &src[12]; 1628 const deUint64 alphaBits = get64BitBlockLE(src, 0) >> 16; 1629 deUint32 alphas[8]; 1630 1631 const deInt32 indices[16] = 1632 { 1633 (indices8[0] >> 0) & 0x3, 1634 (indices8[0] >> 2) & 0x3, 1635 (indices8[0] >> 4) & 0x3, 1636 (indices8[0] >> 6) & 0x3, 1637 (indices8[1] >> 0) & 0x3, 1638 (indices8[1] >> 2) & 0x3, 1639 (indices8[1] >> 4) & 0x3, 1640 (indices8[1] >> 6) & 0x3, 1641 (indices8[2] >> 0) & 0x3, 1642 (indices8[2] >> 2) & 0x3, 1643 (indices8[2] >> 4) & 0x3, 1644 (indices8[2] >> 6) & 0x3, 1645 (indices8[3] >> 0) & 0x3, 1646 (indices8[3] >> 2) & 0x3, 1647 (indices8[3] >> 4) & 0x3, 1648 (indices8[3] >> 6) & 0x3 1649 }; 1650 1651 const deInt32 alphaIndices[16] = 1652 { 1653 (deInt32)((alphaBits >> 0) & 0x7), 1654 (deInt32)((alphaBits >> 3) & 0x7), 1655 (deInt32)((alphaBits >> 6) & 0x7), 1656 (deInt32)((alphaBits >> 9) & 0x7), 1657 (deInt32)((alphaBits >> 12) & 0x7), 1658 (deInt32)((alphaBits >> 15) & 0x7), 1659 (deInt32)((alphaBits >> 18) & 0x7), 1660 (deInt32)((alphaBits >> 21) & 0x7), 1661 (deInt32)((alphaBits >> 24) & 0x7), 1662 (deInt32)((alphaBits >> 27) & 0x7), 1663 (deInt32)((alphaBits >> 30) & 0x7), 1664 (deInt32)((alphaBits >> 33) & 0x7), 1665 (deInt32)((alphaBits >> 36) & 0x7), 1666 (deInt32)((alphaBits >> 39) & 0x7), 1667 (deInt32)((alphaBits >> 42) & 0x7), 1668 (deInt32)((alphaBits >> 45) & 0x7) 1669 }; 1670 1671 const deUint32 colors[4] = 1672 { 1673 color0, 1674 color1, 1675 interpolateColor(color1, color0), 1676 interpolateColor(color0, color1) 1677 }; 1678 1679 alphas[0] = alpha0 << 24; 1680 alphas[1] = alpha1 << 24; 1681 1682 if (alpha0 > alpha1) 1683 { 1684 for (deUint32 i = 0; i < 6; i++) 1685 alphas[i + 2] = (((deUint32)alpha0 * (6 - i) + (deUint32)alpha1 * (1 + i)) / 7) << 24; 1686 } 1687 else 1688 { 1689 for (deUint32 i = 0; i < 4; i++) 1690 alphas[i + 2] = (((deUint32)alpha0 * (4 - i) + (deUint32)alpha1 * (1 + i)) / 5) << 24; 1691 alphas[6] = 0; 1692 alphas[7] = 0xff000000; 1693 } 1694 1695 for (deUint32 y = 0; y < (deUint32)BC_BLOCK_HEIGHT; y++) 1696 { 1697 for (deUint32 x = 0; x < (deUint32)BC_BLOCK_WIDTH; x++) 1698 { 1699 deUint32* const dstPixel = (deUint32*)(dstPtr + y * dstRowPitch + x * dstPixelSize); 1700 *dstPixel = (colors[indices[y * BC_BLOCK_WIDTH + x]] & 0x00ffffff) | alphas[alphaIndices[y * BC_BLOCK_WIDTH + x]]; 1701 } 1702 } 1703 } 1704 1705 void decompressBc4 (const PixelBufferAccess& dst, const deUint8* src, bool hasSign) 1706 { 1707 using namespace BcDecompressInternal; 1708 1709 deUint8* const dstPtr = (deUint8*)dst.getDataPtr(); 1710 const deUint32 dstRowPitch = dst.getRowPitch(); 1711 const deUint32 dstPixelSize = 4; 1712 const deUint8 red0 = src[0]; 1713 const deUint8 red1 = src[1]; 1714 const deInt8 red0s = ((deInt8*)src)[0]; 1715 const deInt8 red1s = ((deInt8*)src)[1]; 1716 const deUint64 indexBits = get64BitBlockLE(src, 0) >> 16; 1717 float reds[8]; 1718 1719 const deInt32 indices[16] = 1720 { 1721 (deInt32)((indexBits >> 0) & 0x7), 1722 (deInt32)((indexBits >> 3) & 0x7), 1723 (deInt32)((indexBits >> 6) & 0x7), 1724 (deInt32)((indexBits >> 9) & 0x7), 1725 (deInt32)((indexBits >> 12) & 0x7), 1726 (deInt32)((indexBits >> 15) & 0x7), 1727 (deInt32)((indexBits >> 18) & 0x7), 1728 (deInt32)((indexBits >> 21) & 0x7), 1729 (deInt32)((indexBits >> 24) & 0x7), 1730 (deInt32)((indexBits >> 27) & 0x7), 1731 (deInt32)((indexBits >> 30) & 0x7), 1732 (deInt32)((indexBits >> 33) & 0x7), 1733 (deInt32)((indexBits >> 36) & 0x7), 1734 (deInt32)((indexBits >> 39) & 0x7), 1735 (deInt32)((indexBits >> 42) & 0x7), 1736 (deInt32)((indexBits >> 45) & 0x7) 1737 }; 1738 1739 reds[0] = hasSign ? int8ToFloat(red0s) : uint8ToFloat(red0); 1740 reds[1] = hasSign ? int8ToFloat(red1s) : uint8ToFloat(red1); 1741 1742 if (reds[0] > reds[1]) 1743 { 1744 for (deUint32 i = 0; i < 6; i++) 1745 reds[i + 2] = (reds[0] * (6.0f - (float)i) + reds[1] * (1.0f + (float)i)) / 7.0f; 1746 } 1747 else 1748 { 1749 for (deUint32 i = 0; i < 4; i++) 1750 reds[i + 2] = (reds[0] * (4.0f - (float)i) + reds[1] * (1.0f + (float)i)) / 5.0f; 1751 reds[6] = hasSign ? -1.0f : 0.0f; 1752 reds[7] = 1.0f; 1753 } 1754 1755 for (deUint32 y = 0; y < (deUint32)BC_BLOCK_HEIGHT; y++) 1756 { 1757 for (deUint32 x = 0; x < (deUint32)BC_BLOCK_WIDTH; x++) 1758 { 1759 float* const dstPixel = (float*)(dstPtr + y * dstRowPitch + x * dstPixelSize); 1760 *dstPixel = reds[indices[y * BC_BLOCK_WIDTH + x]]; 1761 } 1762 } 1763 } 1764 1765 void decompressBc5 (const PixelBufferAccess& dst, const deUint8* src, bool hasSign) 1766 { 1767 using namespace BcDecompressInternal; 1768 1769 deUint8* const dstPtr = (deUint8*)dst.getDataPtr(); 1770 const deUint32 dstRowPitch = dst.getRowPitch(); 1771 const deUint32 dstPixelSize = 8; 1772 float rg[2][8]; 1773 deUint32 indices[2][16]; 1774 1775 for (deUint32 c = 0; c < 2; c++) 1776 { 1777 const deUint32 offset = c * 8; 1778 const deUint8 rg0 = src[offset]; 1779 const deUint8 rg1 = src[offset + 1]; 1780 const deInt8 rg0s = ((deInt8*)src)[offset]; 1781 const deInt8 rg1s = ((deInt8*)src)[offset + 1]; 1782 const deUint64 indexBits = get64BitBlockLE(src, c) >> 16; 1783 1784 for (deUint32 i = 0; i < 16; i++) 1785 indices[c][i] = (indexBits >> (i * 3)) & 0x7; 1786 1787 rg[c][0] = hasSign ? int8ToFloat(rg0s) : uint8ToFloat(rg0); 1788 rg[c][1] = hasSign ? int8ToFloat(rg1s) : uint8ToFloat(rg1); 1789 1790 if (rg[c][0] > rg[c][1]) 1791 { 1792 for (deUint32 i = 0; i < 6; i++) 1793 rg[c][i + 2] = (rg[c][0] * (6.0f - (float)i) + rg[c][1] * (1.0f + (float)i)) / 7.0f; 1794 } 1795 else 1796 { 1797 for (deUint32 i = 0; i < 4; i++) 1798 rg[c][i + 2] = (rg[c][0] * (4.0f - (float)i) + rg[c][1] * (1.0f + (float)i)) / 5.0f; 1799 rg[c][6] = hasSign ? -1.0f : 0.0f; 1800 rg[c][7] = 1.0f; 1801 } 1802 } 1803 1804 for (deUint32 y = 0; y < (deUint32)BC_BLOCK_HEIGHT; y++) 1805 { 1806 for (deUint32 x = 0; x < (deUint32)BC_BLOCK_WIDTH; x++) 1807 { 1808 float* const dstPixel = (float*)(dstPtr + y * dstRowPitch + x * dstPixelSize); 1809 for (deUint32 i = 0; i < 2; i++) 1810 dstPixel[i] = rg[i][indices[i][y * BC_BLOCK_WIDTH + x]]; 1811 } 1812 } 1813 } 1814 1815 void decompressBc6H (const PixelBufferAccess& dst, const deUint8* src, bool hasSign) 1816 { 1817 using namespace BcDecompressInternal; 1818 1819 deUint8* const dstPtr = (deUint8*)dst.getDataPtr(); 1820 const deUint32 dstRowPitch = dst.getRowPitch(); 1821 const deUint32 dstPixelSize = 6; 1822 1823 deInt32 mode = extractModeBc6(src[0]); 1824 IVec4 r (0); 1825 IVec4 g (0); 1826 IVec4 b (0); 1827 deUint32 deltaBitsR = 0; 1828 deUint32 deltaBitsG = 0; 1829 deUint32 deltaBitsB = 0; 1830 const deUint64 low = ((deUint64*)src)[0]; 1831 const deUint64 high = ((deUint64*)src)[1]; 1832 const deUint32 d = mode < 10 ? getBits128(low, high, 77, 81) : 0; 1833 const deUint32 numRegions = mode > 9 ? 1 : 2; 1834 const deUint32 numEndpoints = numRegions * 2; 1835 const bool transformed = mode != 9 && mode != 10; 1836 const deUint32 colorIndexBC = mode < 10 ? 3 : 4; 1837 deUint64 colorIndexData = high >> (mode < 10 ? 18 : 1); 1838 const deUint32 anchorIndex[2] = { 0, anchorIndicesSecondSubset2[d] }; 1839 1840 switch (mode) 1841 { 1842 case 0: 1843 g[2] |= getBits128(low, high, 2, 2) << 4; 1844 b[2] |= getBits128(low, high, 3, 3) << 4; 1845 b[3] |= getBits128(low, high, 4, 4) << 4; 1846 r[0] |= getBits128(low, high, 5, 14); 1847 g[0] |= getBits128(low, high, 15, 24); 1848 b[0] |= getBits128(low, high, 25, 34); 1849 r[1] |= getBits128(low, high, 35, 39); 1850 g[3] |= getBits128(low, high, 40, 40) << 4; 1851 g[2] |= getBits128(low, high, 41, 44); 1852 g[1] |= getBits128(low, high, 45, 49); 1853 b[3] |= getBits128(low, high, 50, 50); 1854 g[3] |= getBits128(low, high, 51, 54); 1855 b[1] |= getBits128(low, high, 55, 59); 1856 b[3] |= getBits128(low, high, 60, 60) << 1; 1857 b[2] |= getBits128(low, high, 61, 64); 1858 r[2] |= getBits128(low, high, 65, 69); 1859 b[3] |= getBits128(low, high, 70, 70) << 2; 1860 r[3] |= getBits128(low, high, 71, 75); 1861 b[3] |= getBits128(low, high, 76, 76) << 3; 1862 deltaBitsR = deltaBitsG = deltaBitsB = 5; 1863 break; 1864 1865 case 1: 1866 g[2] |= getBits128(low, high, 2, 2) << 5; 1867 g[3] |= getBits128(low, high, 3, 3) << 4; 1868 g[3] |= getBits128(low, high, 4, 4) << 5; 1869 r[0] |= getBits128(low, high, 5, 11); 1870 b[3] |= getBits128(low, high, 12, 12); 1871 b[3] |= getBits128(low, high, 13, 13) << 1; 1872 b[2] |= getBits128(low, high, 14, 14) << 4; 1873 g[0] |= getBits128(low, high, 15, 21); 1874 b[2] |= getBits128(low, high, 22, 22) << 5; 1875 b[3] |= getBits128(low, high, 23, 23) << 2; 1876 g[2] |= getBits128(low, high, 24, 24) << 4; 1877 b[0] |= getBits128(low, high, 25, 31); 1878 b[3] |= getBits128(low, high, 32, 32) << 3; 1879 b[3] |= getBits128(low, high, 33, 33) << 5; 1880 b[3] |= getBits128(low, high, 34, 34) << 4; 1881 r[1] |= getBits128(low, high, 35, 40); 1882 g[2] |= getBits128(low, high, 41, 44); 1883 g[1] |= getBits128(low, high, 45, 50); 1884 g[3] |= getBits128(low, high, 51, 54); 1885 b[1] |= getBits128(low, high, 55, 60); 1886 b[2] |= getBits128(low, high, 61, 64); 1887 r[2] |= getBits128(low, high, 65, 70); 1888 r[3] |= getBits128(low, high, 71, 76); 1889 deltaBitsR = deltaBitsG = deltaBitsB = 6; 1890 break; 1891 1892 case 2: 1893 r[0] |= getBits128(low, high, 5, 14); 1894 g[0] |= getBits128(low, high, 15, 24); 1895 b[0] |= getBits128(low, high, 25, 34); 1896 r[1] |= getBits128(low, high, 35, 39); 1897 r[0] |= getBits128(low, high, 40, 40) << 10; 1898 g[2] |= getBits128(low, high, 41, 44); 1899 g[1] |= getBits128(low, high, 45, 48); 1900 g[0] |= getBits128(low, high, 49, 49) << 10; 1901 b[3] |= getBits128(low, high, 50, 50); 1902 g[3] |= getBits128(low, high, 51, 54); 1903 b[1] |= getBits128(low, high, 55, 58); 1904 b[0] |= getBits128(low, high, 59, 59) << 10; 1905 b[3] |= getBits128(low, high, 60, 60) << 1; 1906 b[2] |= getBits128(low, high, 61, 64); 1907 r[2] |= getBits128(low, high, 65, 69); 1908 b[3] |= getBits128(low, high, 70, 70) << 2; 1909 r[3] |= getBits128(low, high, 71, 75); 1910 b[3] |= getBits128(low, high, 76, 76) << 3; 1911 deltaBitsR = 5; 1912 deltaBitsG = deltaBitsB = 4; 1913 break; 1914 1915 case 3: 1916 r[0] |= getBits128(low, high, 5, 14); 1917 g[0] |= getBits128(low, high, 15, 24); 1918 b[0] |= getBits128(low, high, 25, 34); 1919 r[1] |= getBits128(low, high, 35, 38); 1920 r[0] |= getBits128(low, high, 39, 39) << 10; 1921 g[3] |= getBits128(low, high, 40, 40) << 4; 1922 g[2] |= getBits128(low, high, 41, 44); 1923 g[1] |= getBits128(low, high, 45, 49); 1924 g[0] |= getBits128(low, high, 50, 50) << 10; 1925 g[3] |= getBits128(low, high, 51, 54); 1926 b[1] |= getBits128(low, high, 55, 58); 1927 b[0] |= getBits128(low, high, 59, 59) << 10; 1928 b[3] |= getBits128(low, high, 60, 60) << 1; 1929 b[2] |= getBits128(low, high, 61, 64); 1930 r[2] |= getBits128(low, high, 65, 68); 1931 b[3] |= getBits128(low, high, 69, 69); 1932 b[3] |= getBits128(low, high, 70, 70) << 2; 1933 r[3] |= getBits128(low, high, 71, 74); 1934 g[2] |= getBits128(low, high, 75, 75) << 4; 1935 b[3] |= getBits128(low, high, 76, 76) << 3; 1936 deltaBitsR = deltaBitsB = 4; 1937 deltaBitsG = 5; 1938 break; 1939 1940 case 4: 1941 r[0] |= getBits128(low, high, 5, 14); 1942 g[0] |= getBits128(low, high, 15, 24); 1943 b[0] |= getBits128(low, high, 25, 34); 1944 r[1] |= getBits128(low, high, 35, 38); 1945 r[0] |= getBits128(low, high, 39, 39) << 10; 1946 b[2] |= getBits128(low, high, 40, 40) << 4; 1947 g[2] |= getBits128(low, high, 41, 44); 1948 g[1] |= getBits128(low, high, 45, 48); 1949 g[0] |= getBits128(low, high, 49, 49) << 10; 1950 b[3] |= getBits128(low, high, 50, 50); 1951 g[3] |= getBits128(low, high, 51, 54); 1952 b[1] |= getBits128(low, high, 55, 59); 1953 b[0] |= getBits128(low, high, 60, 60) << 10; 1954 b[2] |= getBits128(low, high, 61, 64); 1955 r[2] |= getBits128(low, high, 65, 68); 1956 b[3] |= getBits128(low, high, 69, 69) << 1; 1957 b[3] |= getBits128(low, high, 70, 70) << 2; 1958 r[3] |= getBits128(low, high, 71, 74); 1959 b[3] |= getBits128(low, high, 75, 75) << 4; 1960 b[3] |= getBits128(low, high, 76, 76) << 3; 1961 deltaBitsR = deltaBitsG = 4; 1962 deltaBitsB = 5; 1963 break; 1964 1965 case 5: 1966 r[0] |= getBits128(low, high, 5, 13); 1967 b[2] |= getBits128(low, high, 14, 14) << 4; 1968 g[0] |= getBits128(low, high, 15, 23); 1969 g[2] |= getBits128(low, high, 24, 24) << 4; 1970 b[0] |= getBits128(low, high, 25, 33); 1971 b[3] |= getBits128(low, high, 34, 34) << 4; 1972 r[1] |= getBits128(low, high, 35, 39); 1973 g[3] |= getBits128(low, high, 40, 40) << 4; 1974 g[2] |= getBits128(low, high, 41, 44); 1975 g[1] |= getBits128(low, high, 45, 49); 1976 b[3] |= getBits128(low, high, 50, 50); 1977 g[3] |= getBits128(low, high, 51, 54); 1978 b[1] |= getBits128(low, high, 55, 59); 1979 b[3] |= getBits128(low, high, 60, 60) << 1; 1980 b[2] |= getBits128(low, high, 61, 64); 1981 r[2] |= getBits128(low, high, 65, 69); 1982 b[3] |= getBits128(low, high, 70, 70) << 2; 1983 r[3] |= getBits128(low, high, 71, 75); 1984 b[3] |= getBits128(low, high, 76, 76) << 3; 1985 deltaBitsR = deltaBitsG = deltaBitsB = 5; 1986 break; 1987 1988 case 6: 1989 r[0] |= getBits128(low, high, 5, 12); 1990 g[3] |= getBits128(low, high, 13, 13) << 4; 1991 b[2] |= getBits128(low, high, 14, 14) << 4; 1992 g[0] |= getBits128(low, high, 15, 22); 1993 b[3] |= getBits128(low, high, 23, 23) << 2; 1994 g[2] |= getBits128(low, high, 24, 24) << 4; 1995 b[0] |= getBits128(low, high, 25, 32); 1996 b[3] |= getBits128(low, high, 33, 33) << 3; 1997 b[3] |= getBits128(low, high, 34, 34) << 4; 1998 r[1] |= getBits128(low, high, 35, 40); 1999 g[2] |= getBits128(low, high, 41, 44); 2000 g[1] |= getBits128(low, high, 45, 49); 2001 b[3] |= getBits128(low, high, 50, 50); 2002 g[3] |= getBits128(low, high, 51, 54); 2003 b[1] |= getBits128(low, high, 55, 59); 2004 b[3] |= getBits128(low, high, 60, 60) << 1; 2005 b[2] |= getBits128(low, high, 61, 64); 2006 r[2] |= getBits128(low, high, 65, 70); 2007 r[3] |= getBits128(low, high, 71, 76); 2008 deltaBitsR = 6; 2009 deltaBitsG = deltaBitsB = 5; 2010 break; 2011 2012 case 7: 2013 r[0] |= getBits128(low, high, 5, 12); 2014 b[3] |= getBits128(low, high, 13, 13); 2015 b[2] |= getBits128(low, high, 14, 14) << 4; 2016 g[0] |= getBits128(low, high, 15, 22); 2017 g[2] |= getBits128(low, high, 23, 23) << 5; 2018 g[2] |= getBits128(low, high, 24, 24) << 4; 2019 b[0] |= getBits128(low, high, 25, 32); 2020 g[3] |= getBits128(low, high, 33, 33) << 5; 2021 b[3] |= getBits128(low, high, 34, 34) << 4; 2022 r[1] |= getBits128(low, high, 35, 39); 2023 g[3] |= getBits128(low, high, 40, 40) << 4; 2024 g[2] |= getBits128(low, high, 41, 44); 2025 g[1] |= getBits128(low, high, 45, 50); 2026 g[3] |= getBits128(low, high, 51, 54); 2027 b[1] |= getBits128(low, high, 55, 59); 2028 b[3] |= getBits128(low, high, 60, 60) << 1; 2029 b[2] |= getBits128(low, high, 61, 64); 2030 r[2] |= getBits128(low, high, 65, 69); 2031 b[3] |= getBits128(low, high, 70, 70) << 2; 2032 r[3] |= getBits128(low, high, 71, 75); 2033 b[3] |= getBits128(low, high, 76, 76) << 3; 2034 deltaBitsR = deltaBitsB = 5; 2035 deltaBitsG = 6; 2036 break; 2037 2038 case 8: 2039 r[0] |= getBits128(low, high, 5, 12); 2040 b[3] |= getBits128(low, high, 13, 13) << 1; 2041 b[2] |= getBits128(low, high, 14, 14) << 4; 2042 g[0] |= getBits128(low, high, 15, 22); 2043 b[2] |= getBits128(low, high, 23, 23) << 5; 2044 g[2] |= getBits128(low, high, 24, 24) << 4; 2045 b[0] |= getBits128(low, high, 25, 32); 2046 b[3] |= getBits128(low, high, 33, 33) << 5; 2047 b[3] |= getBits128(low, high, 34, 34) << 4; 2048 r[1] |= getBits128(low, high, 35, 39); 2049 g[3] |= getBits128(low, high, 40, 40) << 4; 2050 g[2] |= getBits128(low, high, 41, 44); 2051 g[1] |= getBits128(low, high, 45, 49); 2052 b[3] |= getBits128(low, high, 50, 50); 2053 g[3] |= getBits128(low, high, 51, 54); 2054 b[1] |= getBits128(low, high, 55, 60); 2055 b[2] |= getBits128(low, high, 61, 64); 2056 r[2] |= getBits128(low, high, 65, 69); 2057 b[3] |= getBits128(low, high, 70, 70) << 2; 2058 r[3] |= getBits128(low, high, 71, 75); 2059 b[3] |= getBits128(low, high, 76, 76) << 3; 2060 deltaBitsR = deltaBitsG = 5; 2061 deltaBitsB = 6; 2062 break; 2063 2064 case 9: 2065 r[0] |= getBits128(low, high, 5, 10); 2066 g[3] |= getBits128(low, high, 11, 11) << 4; 2067 b[3] |= getBits128(low, high, 12, 13); 2068 b[2] |= getBits128(low, high, 14, 14) << 4; 2069 g[0] |= getBits128(low, high, 15, 20); 2070 g[2] |= getBits128(low, high, 21, 21) << 5; 2071 b[2] |= getBits128(low, high, 22, 22) << 5; 2072 b[3] |= getBits128(low, high, 23, 23) << 2; 2073 g[2] |= getBits128(low, high, 24, 24) << 4; 2074 b[0] |= getBits128(low, high, 25, 30); 2075 g[3] |= getBits128(low, high, 31, 31) << 5; 2076 b[3] |= getBits128(low, high, 32, 32) << 3; 2077 b[3] |= getBits128(low, high, 33, 33) << 5; 2078 b[3] |= getBits128(low, high, 34, 34) << 4; 2079 r[1] |= getBits128(low, high, 35, 40); 2080 g[2] |= getBits128(low, high, 41, 44); 2081 g[1] |= getBits128(low, high, 45, 50); 2082 g[3] |= getBits128(low, high, 51, 54); 2083 b[1] |= getBits128(low, high, 55, 60); 2084 b[2] |= getBits128(low, high, 61, 64); 2085 r[2] |= getBits128(low, high, 65, 70); 2086 r[3] |= getBits128(low, high, 71, 76); 2087 deltaBitsR = deltaBitsG = deltaBitsB = 6; 2088 break; 2089 2090 case 10: 2091 r[0] |= getBits128(low, high, 5, 14); 2092 g[0] |= getBits128(low, high, 15, 24); 2093 b[0] |= getBits128(low, high, 25, 34); 2094 r[1] |= getBits128(low, high, 35, 44); 2095 g[1] |= getBits128(low, high, 45, 54); 2096 b[1] |= getBits128(low, high, 55, 64); 2097 deltaBitsR = deltaBitsG = deltaBitsB = 10; 2098 break; 2099 2100 case 11: 2101 r[0] |= getBits128(low, high, 5, 14); 2102 g[0] |= getBits128(low, high, 15, 24); 2103 b[0] |= getBits128(low, high, 25, 34); 2104 r[1] |= getBits128(low, high, 35, 43); 2105 r[0] |= getBits128(low, high, 44, 44) << 10; 2106 g[1] |= getBits128(low, high, 45, 53); 2107 g[0] |= getBits128(low, high, 54, 54) << 10; 2108 b[1] |= getBits128(low, high, 55, 63); 2109 b[0] |= getBits128(low, high, 64, 64) << 10; 2110 deltaBitsR = deltaBitsG = deltaBitsB = 9; 2111 break; 2112 2113 case 12: 2114 r[0] |= getBits128(low, high, 5, 14); 2115 g[0] |= getBits128(low, high, 15, 24); 2116 b[0] |= getBits128(low, high, 25, 34); 2117 r[1] |= getBits128(low, high, 35, 42); 2118 r[0] |= getBits128(low, high, 44, 43) << 10; 2119 g[1] |= getBits128(low, high, 45, 52); 2120 g[0] |= getBits128(low, high, 54, 53) << 10; 2121 b[1] |= getBits128(low, high, 55, 62); 2122 b[0] |= getBits128(low, high, 64, 63) << 10; 2123 deltaBitsR = deltaBitsG = deltaBitsB = 8; 2124 break; 2125 2126 case 13: 2127 r[0] |= getBits128(low, high, 5, 14); 2128 g[0] |= getBits128(low, high, 15, 24); 2129 b[0] |= getBits128(low, high, 25, 34); 2130 r[1] |= getBits128(low, high, 35, 38); 2131 r[0] |= getBits128(low, high, 44, 39) << 10; 2132 g[1] |= getBits128(low, high, 45, 48); 2133 g[0] |= getBits128(low, high, 54, 49) << 10; 2134 b[1] |= getBits128(low, high, 55, 58); 2135 b[0] |= getBits128(low, high, 64, 59) << 10; 2136 deltaBitsR = deltaBitsG = deltaBitsB = 4; 2137 break; 2138 }; 2139 2140 if (hasSign) 2141 { 2142 r[0] = signExtend(r[0], epBits[mode], 32); 2143 g[0] = signExtend(g[0], epBits[mode], 32); 2144 b[0] = signExtend(b[0], epBits[mode], 32); 2145 } 2146 2147 if (transformed) 2148 { 2149 for (deUint32 i = 1; i < numEndpoints; i++) 2150 { 2151 r[i] = signExtend(r[i], deltaBitsR, 32); 2152 r[i] = (r[0] + r[i]) & (((deUint32)1 << epBits[mode]) - 1); 2153 g[i] = signExtend(g[i], deltaBitsG, 32); 2154 g[i] = (g[0] + g[i]) & (((deUint32)1 << epBits[mode]) - 1); 2155 b[i] = signExtend(b[i], deltaBitsB, 32); 2156 b[i] = (b[0] + b[i]) & (((deUint32)1 << epBits[mode]) - 1); 2157 } 2158 } 2159 2160 if (hasSign) 2161 { 2162 for (deUint32 i = 1; i < 4; i++) 2163 { 2164 r[i] = signExtend(r[i], epBits[mode], 32); 2165 g[i] = signExtend(g[i], epBits[mode], 32); 2166 b[i] = signExtend(b[i], epBits[mode], 32); 2167 } 2168 } 2169 2170 for (deUint32 i = 0; i < numEndpoints; i++) 2171 { 2172 r[i] = unquantize(r[i], mode, hasSign); 2173 g[i] = unquantize(g[i], mode, hasSign); 2174 b[i] = unquantize(b[i], mode, hasSign); 2175 } 2176 2177 for (deUint32 i = 0; i < 16; i++) 2178 { 2179 const deUint32 subsetIndex = (numRegions == 1 ? 0 : partitions2[d][i]); 2180 const deUint32 bits = (i == anchorIndex[subsetIndex]) ? (colorIndexBC - 1) : colorIndexBC; 2181 const deUint32 colorIndex = (deUint32)(colorIndexData & ((1 << bits) - 1)); 2182 const deInt32 endpointStartR = r[2 * subsetIndex]; 2183 const deInt32 endpointEndR = r[2 * subsetIndex + 1]; 2184 const deInt32 endpointStartG = g[2 * subsetIndex]; 2185 const deInt32 endpointEndG = g[2 * subsetIndex + 1]; 2186 const deInt32 endpointStartB = b[2 * subsetIndex]; 2187 const deInt32 endpointEndB = b[2 * subsetIndex + 1]; 2188 const deInt16 r16 = finishUnquantize(interpolate(endpointStartR, endpointEndR, colorIndex, colorIndexBC), hasSign); 2189 const deInt16 g16 = finishUnquantize(interpolate(endpointStartG, endpointEndG, colorIndex, colorIndexBC), hasSign); 2190 const deInt16 b16 = finishUnquantize(interpolate(endpointStartB, endpointEndB, colorIndex, colorIndexBC), hasSign); 2191 const deInt32 y = i / 4; 2192 const deInt32 x = i % 4; 2193 deInt16* const dstPixel = (deInt16*)(dstPtr + y * dstRowPitch + x * dstPixelSize); 2194 2195 if (mode == -1) 2196 { 2197 dstPixel[0] = 0; 2198 dstPixel[1] = 0; 2199 dstPixel[2] = 0; 2200 } 2201 else 2202 { 2203 dstPixel[0] = r16; 2204 dstPixel[1] = g16; 2205 dstPixel[2] = b16; 2206 } 2207 2208 colorIndexData >>= bits; 2209 } 2210 } 2211 2212 void decompressBc7 (const PixelBufferAccess& dst, const deUint8* src) 2213 { 2214 using namespace BcDecompressInternal; 2215 2216 static const deUint8 subsets[] = { 3, 2, 3, 2, 1, 1, 1, 2 }; 2217 static const deUint8 partitionBits[] = { 4, 6, 6, 6, 0, 0, 0, 6 }; 2218 static const deUint8 endpointBits[8][5] = 2219 { 2220 //r, g, b, a, p 2221 { 4, 4, 4, 0, 1 }, 2222 { 6, 6, 6, 0, 1 }, 2223 { 5, 5, 5, 0, 0 }, 2224 { 7, 7, 7, 0, 1 }, 2225 { 5, 5, 5, 6, 0 }, 2226 { 7, 7, 7, 8, 0 }, 2227 { 7, 7, 7, 7, 1 }, 2228 { 5, 5, 5, 5, 1 } 2229 }; 2230 static const deUint8 indexBits[] = { 3, 3, 2, 2, 2, 2, 4, 2 }; 2231 2232 deUint8* const dstPtr = (deUint8*)dst.getDataPtr(); 2233 const deUint32 dstRowPitch = dst.getRowPitch(); 2234 const deUint32 dstPixelSize = 4; 2235 2236 const deUint64 low = ((deUint64*)src)[0]; 2237 const deUint64 high = ((deUint64*)src)[1]; 2238 const deInt32 mode = extractModeBc7(src[0]); 2239 deUint32 numSubsets = 1; 2240 deUint32 offset = mode + 1; 2241 deUint32 rotation = 0; 2242 deUint32 idxMode = 0; 2243 deUint32 endpoints[6][5]; 2244 deUint32 partitionSetId = 0; 2245 2246 // Decode partition data from explicit partition bits 2247 if (mode == 0 || mode == 1 || mode == 2 || mode == 3 || mode == 7) 2248 { 2249 numSubsets = subsets[mode]; 2250 partitionSetId = getBits128(low, high, offset, offset + partitionBits[mode] - 1); 2251 offset += partitionBits[mode]; 2252 } 2253 2254 // Extract rotation bits 2255 if (mode == 4 || mode == 5) 2256 { 2257 rotation = getBits128(low, high, offset, offset + 1); 2258 offset += 2; 2259 if (mode == 4) 2260 { 2261 idxMode = getBits128(low, high, offset, offset); 2262 offset++; 2263 } 2264 } 2265 2266 { 2267 const deUint32 numEndpoints = numSubsets * 2; 2268 2269 // Extract raw, compressed endpoint bits 2270 for (deUint32 cpnt = 0; cpnt < 5; cpnt++) 2271 { 2272 for (deUint32 ep = 0; ep < numEndpoints; ep++) 2273 { 2274 if (mode == 1 && cpnt == 4 && ep > 1) 2275 continue; // Mode 1 has shared P bits 2276 2277 int n = mode == -1 ? 0 : endpointBits[mode][cpnt]; 2278 if (n > 0) 2279 endpoints[ep][cpnt] = getBits128(low, high, offset, offset + n - 1); 2280 offset += n; 2281 } 2282 } 2283 2284 // Decode endpoints 2285 if (mode == 0 || mode == 1 || mode == 3 || mode == 6 || mode == 7) 2286 { 2287 // First handle modes that have P-bits 2288 for (deUint32 ep = 0; ep < numEndpoints; ep++) 2289 { 2290 for (deUint32 cpnt = 0; cpnt < 4; cpnt++) 2291 { 2292 endpoints[ep][cpnt] <<= 1; 2293 } 2294 } 2295 2296 if (mode == 1) 2297 { 2298 // P-bit is shared 2299 const deUint32 pbitZero = endpoints[0][4]; 2300 const deUint32 pbitOne = endpoints[1][4]; 2301 2302 for (deUint32 cpnt = 0; cpnt < 3; cpnt++) 2303 { 2304 endpoints[0][cpnt] |= pbitZero; 2305 endpoints[1][cpnt] |= pbitZero; 2306 endpoints[2][cpnt] |= pbitOne; 2307 endpoints[3][cpnt] |= pbitOne; 2308 } 2309 } 2310 else 2311 { 2312 // Unique p-bit per endpoint 2313 for (deUint32 ep = 0; ep < numEndpoints; ep++) 2314 { 2315 for (deUint32 cpnt = 0; cpnt < 4; cpnt++) 2316 { 2317 endpoints[ep][cpnt] |= endpoints[ep][4]; 2318 } 2319 } 2320 } 2321 } 2322 2323 for (deUint32 ep = 0; ep < numEndpoints; ep++) 2324 { 2325 // Left shift endpoint components so that their MSB lies in bit 7 2326 for (deUint32 cpnt = 0; cpnt < 4; cpnt++) 2327 endpoints[ep][cpnt] <<= 8 - (endpointBits[mode][cpnt] + endpointBits[mode][4]); 2328 2329 // Replicate each component's MSB into the LSBs revealed by the left-shift operation above 2330 for (deUint32 cpnt = 0; cpnt < 4; cpnt++) 2331 endpoints[ep][cpnt] |= endpoints[ep][cpnt] >> (endpointBits[mode][cpnt] + endpointBits[mode][4]); 2332 } 2333 2334 // If this mode does not explicitly define the alpha component set alpha equal to 1.0 2335 if (mode < 4) 2336 { 2337 for (deUint32 ep = 0; ep < numEndpoints; ep++) 2338 endpoints[ep][3] = 255; 2339 } 2340 } 2341 2342 { 2343 deUint32 colorIdxOffset = offset + ((mode == 4 && idxMode) ? 31 : 0); 2344 deUint32 alphaIdxOffset = offset + ((mode == 5 || (mode == 4 && !idxMode)) ? 31 : 0); 2345 2346 for (deUint32 pixel = 0; pixel < 16; pixel++) 2347 { 2348 const deUint32 y = pixel / 4; 2349 const deUint32 x = pixel % 4; 2350 deUint32* const dstPixel = (deUint32*)(dstPtr + y * dstRowPitch + x * dstPixelSize); 2351 deUint32 subsetIndex = 0; 2352 deUint32 anchorIndex = 0; 2353 deUint32 endpointStart[4]; 2354 deUint32 endpointEnd[4]; 2355 2356 if (mode == -1) 2357 { 2358 *dstPixel = 0; 2359 continue; 2360 } 2361 2362 if (numSubsets == 2) 2363 subsetIndex = partitions2[partitionSetId][pixel]; 2364 else if (numSubsets == 3) 2365 subsetIndex = partitions3[partitionSetId][pixel]; 2366 2367 if (numSubsets == 2 && subsetIndex == 1) 2368 { 2369 anchorIndex = anchorIndicesSecondSubset2[partitionSetId]; 2370 } 2371 else if (numSubsets == 3) 2372 { 2373 if (subsetIndex == 1) 2374 anchorIndex = anchorIndicesSecondSubset3[partitionSetId]; 2375 else if (subsetIndex == 2) 2376 anchorIndex = anchorIndicesThirdSubset[partitionSetId]; 2377 } 2378 2379 for (deUint32 cpnt = 0; cpnt < 4; cpnt++) 2380 { 2381 endpointStart[cpnt] = endpoints[2 * subsetIndex][cpnt]; 2382 endpointEnd[cpnt] = endpoints[2 * subsetIndex + 1][cpnt]; 2383 } 2384 2385 { 2386 const deUint32 colorInterpolationBits = indexBits[mode] + idxMode; 2387 const deUint32 colorIndexBits = colorInterpolationBits - ((anchorIndex == pixel) ? 1 : 0); 2388 const deUint32 alphaInterpolationBits = mode == 4 ? 3 - idxMode : (mode == 5 ? 2 : colorInterpolationBits); 2389 const deUint32 alphaIndexBits = alphaInterpolationBits - ((anchorIndex == pixel) ? 1 : 0); 2390 const deUint32 colorIdx = getBits128(low, high, colorIdxOffset, colorIdxOffset + colorIndexBits - 1); 2391 const deUint32 alphaIdx = (mode == 4 || mode == 5) ? getBits128(low, high, alphaIdxOffset, alphaIdxOffset + alphaIndexBits - 1) : colorIdx; 2392 const deUint32 r = interpolate(endpointStart[0], endpointEnd[0], colorIdx, colorInterpolationBits); 2393 const deUint32 g = interpolate(endpointStart[1], endpointEnd[1], colorIdx, colorInterpolationBits); 2394 const deUint32 b = interpolate(endpointStart[2], endpointEnd[2], colorIdx, colorInterpolationBits); 2395 const deUint32 a = interpolate(endpointStart[3], endpointEnd[3], alphaIdx, alphaInterpolationBits); 2396 2397 colorIdxOffset += colorIndexBits; 2398 alphaIdxOffset += alphaIndexBits; 2399 2400 if ((mode == 4 || mode == 5) && rotation != 0) 2401 { 2402 if (rotation == 1) 2403 *dstPixel = a | (g << 8) | (b << 16) | (r << 24); 2404 else if (rotation == 2) 2405 *dstPixel = r | (a << 8) | (b << 16) | (g << 24); 2406 else 2407 *dstPixel = r | (g << 8) | (a << 16) | (b << 24); 2408 } 2409 else 2410 { 2411 *dstPixel = r | (g << 8) | (b << 16) | (a << 24); 2412 } 2413 } 2414 } 2415 } 2416 } 2417 2418 void decompressBlock (CompressedTexFormat format, const PixelBufferAccess& dst, const deUint8* src, const TexDecompressionParams& params) 2419 { 2420 // No 3D blocks supported right now 2421 DE_ASSERT(dst.getDepth() == 1); 2422 2423 switch (format) 2424 { 2425 case COMPRESSEDTEXFORMAT_ETC1_RGB8: decompressETC1 (dst, src); break; 2426 case COMPRESSEDTEXFORMAT_EAC_R11: decompressEAC_R11 (dst, src, false); break; 2427 case COMPRESSEDTEXFORMAT_EAC_SIGNED_R11: decompressEAC_R11 (dst, src, true); break; 2428 case COMPRESSEDTEXFORMAT_EAC_RG11: decompressEAC_RG11 (dst, src, false); break; 2429 case COMPRESSEDTEXFORMAT_EAC_SIGNED_RG11: decompressEAC_RG11 (dst, src, true); break; 2430 case COMPRESSEDTEXFORMAT_ETC2_RGB8: decompressETC2 (dst, src); break; 2431 case COMPRESSEDTEXFORMAT_ETC2_SRGB8: decompressETC2 (dst, src); break; 2432 case COMPRESSEDTEXFORMAT_ETC2_RGB8_PUNCHTHROUGH_ALPHA1: decompressETC2_RGB8_PUNCHTHROUGH_ALPHA1 (dst, src); break; 2433 case COMPRESSEDTEXFORMAT_ETC2_SRGB8_PUNCHTHROUGH_ALPHA1: decompressETC2_RGB8_PUNCHTHROUGH_ALPHA1 (dst, src); break; 2434 case COMPRESSEDTEXFORMAT_ETC2_EAC_RGBA8: decompressETC2_EAC_RGBA8 (dst, src); break; 2435 case COMPRESSEDTEXFORMAT_ETC2_EAC_SRGB8_ALPHA8: decompressETC2_EAC_RGBA8 (dst, src); break; 2436 2437 case COMPRESSEDTEXFORMAT_ASTC_4x4_RGBA: 2438 case COMPRESSEDTEXFORMAT_ASTC_5x4_RGBA: 2439 case COMPRESSEDTEXFORMAT_ASTC_5x5_RGBA: 2440 case COMPRESSEDTEXFORMAT_ASTC_6x5_RGBA: 2441 case COMPRESSEDTEXFORMAT_ASTC_6x6_RGBA: 2442 case COMPRESSEDTEXFORMAT_ASTC_8x5_RGBA: 2443 case COMPRESSEDTEXFORMAT_ASTC_8x6_RGBA: 2444 case COMPRESSEDTEXFORMAT_ASTC_8x8_RGBA: 2445 case COMPRESSEDTEXFORMAT_ASTC_10x5_RGBA: 2446 case COMPRESSEDTEXFORMAT_ASTC_10x6_RGBA: 2447 case COMPRESSEDTEXFORMAT_ASTC_10x8_RGBA: 2448 case COMPRESSEDTEXFORMAT_ASTC_10x10_RGBA: 2449 case COMPRESSEDTEXFORMAT_ASTC_12x10_RGBA: 2450 case COMPRESSEDTEXFORMAT_ASTC_12x12_RGBA: 2451 case COMPRESSEDTEXFORMAT_ASTC_4x4_SRGB8_ALPHA8: 2452 case COMPRESSEDTEXFORMAT_ASTC_5x4_SRGB8_ALPHA8: 2453 case COMPRESSEDTEXFORMAT_ASTC_5x5_SRGB8_ALPHA8: 2454 case COMPRESSEDTEXFORMAT_ASTC_6x5_SRGB8_ALPHA8: 2455 case COMPRESSEDTEXFORMAT_ASTC_6x6_SRGB8_ALPHA8: 2456 case COMPRESSEDTEXFORMAT_ASTC_8x5_SRGB8_ALPHA8: 2457 case COMPRESSEDTEXFORMAT_ASTC_8x6_SRGB8_ALPHA8: 2458 case COMPRESSEDTEXFORMAT_ASTC_8x8_SRGB8_ALPHA8: 2459 case COMPRESSEDTEXFORMAT_ASTC_10x5_SRGB8_ALPHA8: 2460 case COMPRESSEDTEXFORMAT_ASTC_10x6_SRGB8_ALPHA8: 2461 case COMPRESSEDTEXFORMAT_ASTC_10x8_SRGB8_ALPHA8: 2462 case COMPRESSEDTEXFORMAT_ASTC_10x10_SRGB8_ALPHA8: 2463 case COMPRESSEDTEXFORMAT_ASTC_12x10_SRGB8_ALPHA8: 2464 case COMPRESSEDTEXFORMAT_ASTC_12x12_SRGB8_ALPHA8: 2465 astc::decompress(dst, src, format, params.astcMode); 2466 break; 2467 2468 case COMPRESSEDTEXFORMAT_BC1_RGB_UNORM_BLOCK: decompressBc1 (dst, src, false); break; 2469 case COMPRESSEDTEXFORMAT_BC1_RGB_SRGB_BLOCK: decompressBc1 (dst, src, false); break; 2470 case COMPRESSEDTEXFORMAT_BC1_RGBA_UNORM_BLOCK: decompressBc1 (dst, src, true); break; 2471 case COMPRESSEDTEXFORMAT_BC1_RGBA_SRGB_BLOCK: decompressBc1 (dst, src, true); break; 2472 case COMPRESSEDTEXFORMAT_BC2_UNORM_BLOCK: decompressBc2 (dst, src); break; 2473 case COMPRESSEDTEXFORMAT_BC2_SRGB_BLOCK: decompressBc2 (dst, src); break; 2474 case COMPRESSEDTEXFORMAT_BC3_UNORM_BLOCK: decompressBc3 (dst, src); break; 2475 case COMPRESSEDTEXFORMAT_BC3_SRGB_BLOCK: decompressBc3 (dst, src); break; 2476 case COMPRESSEDTEXFORMAT_BC4_UNORM_BLOCK: decompressBc4 (dst, src, false); break; 2477 case COMPRESSEDTEXFORMAT_BC4_SNORM_BLOCK: decompressBc4 (dst, src, true); break; 2478 case COMPRESSEDTEXFORMAT_BC5_UNORM_BLOCK: decompressBc5 (dst, src, false); break; 2479 case COMPRESSEDTEXFORMAT_BC5_SNORM_BLOCK: decompressBc5 (dst, src, true); break; 2480 case COMPRESSEDTEXFORMAT_BC6H_UFLOAT_BLOCK: decompressBc6H (dst, src, false); break; 2481 case COMPRESSEDTEXFORMAT_BC6H_SFLOAT_BLOCK: decompressBc6H (dst, src, true); break; 2482 case COMPRESSEDTEXFORMAT_BC7_UNORM_BLOCK: decompressBc7 (dst, src); break; 2483 case COMPRESSEDTEXFORMAT_BC7_SRGB_BLOCK: decompressBc7 (dst, src); break; 2484 2485 default: 2486 DE_FATAL("Unexpected format"); 2487 break; 2488 } 2489 } 2490 2491 int componentSum (const IVec3& vec) 2492 { 2493 return vec.x() + vec.y() + vec.z(); 2494 } 2495 2496 } // anonymous 2497 2498 void decompress (const PixelBufferAccess& dst, CompressedTexFormat fmt, const deUint8* src, const TexDecompressionParams& params) 2499 { 2500 const int blockSize = getBlockSize(fmt); 2501 const IVec3 blockPixelSize (getBlockPixelSize(fmt)); 2502 const IVec3 blockCount (deDivRoundUp32(dst.getWidth(), blockPixelSize.x()), 2503 deDivRoundUp32(dst.getHeight(), blockPixelSize.y()), 2504 deDivRoundUp32(dst.getDepth(), blockPixelSize.z())); 2505 const IVec3 blockPitches (blockSize, blockSize * blockCount.x(), blockSize * blockCount.x() * blockCount.y()); 2506 2507 std::vector<deUint8> uncompressedBlock (dst.getFormat().getPixelSize() * blockPixelSize.x() * blockPixelSize.y() * blockPixelSize.z()); 2508 const PixelBufferAccess blockAccess (getUncompressedFormat(fmt), blockPixelSize.x(), blockPixelSize.y(), blockPixelSize.z(), &uncompressedBlock[0]); 2509 2510 DE_ASSERT(dst.getFormat() == getUncompressedFormat(fmt)); 2511 2512 for (int blockZ = 0; blockZ < blockCount.z(); blockZ++) 2513 for (int blockY = 0; blockY < blockCount.y(); blockY++) 2514 for (int blockX = 0; blockX < blockCount.x(); blockX++) 2515 { 2516 const IVec3 blockPos (blockX, blockY, blockZ); 2517 const deUint8* const blockPtr = src + componentSum(blockPos * blockPitches); 2518 const IVec3 copySize (de::min(blockPixelSize.x(), dst.getWidth() - blockPos.x() * blockPixelSize.x()), 2519 de::min(blockPixelSize.y(), dst.getHeight() - blockPos.y() * blockPixelSize.y()), 2520 de::min(blockPixelSize.z(), dst.getDepth() - blockPos.z() * blockPixelSize.z())); 2521 const IVec3 dstPixelPos = blockPos * blockPixelSize; 2522 2523 decompressBlock(fmt, blockAccess, blockPtr, params); 2524 2525 copy(getSubregion(dst, dstPixelPos.x(), dstPixelPos.y(), dstPixelPos.z(), copySize.x(), copySize.y(), copySize.z()), getSubregion(blockAccess, 0, 0, 0, copySize.x(), copySize.y(), copySize.z())); 2526 } 2527 } 2528 2529 CompressedTexture::CompressedTexture (void) 2530 : m_format (COMPRESSEDTEXFORMAT_LAST) 2531 , m_width (0) 2532 , m_height (0) 2533 , m_depth (0) 2534 { 2535 } 2536 2537 CompressedTexture::CompressedTexture (CompressedTexFormat format, int width, int height, int depth) 2538 : m_format (COMPRESSEDTEXFORMAT_LAST) 2539 , m_width (0) 2540 , m_height (0) 2541 , m_depth (0) 2542 { 2543 setStorage(format, width, height, depth); 2544 } 2545 2546 CompressedTexture::~CompressedTexture (void) 2547 { 2548 } 2549 2550 void CompressedTexture::setStorage (CompressedTexFormat format, int width, int height, int depth) 2551 { 2552 m_format = format; 2553 m_width = width; 2554 m_height = height; 2555 m_depth = depth; 2556 2557 if (m_format != COMPRESSEDTEXFORMAT_LAST) 2558 { 2559 const IVec3 blockPixelSize = getBlockPixelSize(m_format); 2560 const int blockSize = getBlockSize(m_format); 2561 2562 m_data.resize(deDivRoundUp32(m_width, blockPixelSize.x()) * deDivRoundUp32(m_height, blockPixelSize.y()) * deDivRoundUp32(m_depth, blockPixelSize.z()) * blockSize); 2563 } 2564 else 2565 { 2566 DE_ASSERT(m_format == COMPRESSEDTEXFORMAT_LAST); 2567 DE_ASSERT(m_width == 0 && m_height == 0 && m_depth == 0); 2568 m_data.resize(0); 2569 } 2570 } 2571 2572 /*--------------------------------------------------------------------*//*! 2573 * \brief Decode to uncompressed pixel data 2574 * \param dst Destination buffer 2575 *//*--------------------------------------------------------------------*/ 2576 void CompressedTexture::decompress (const PixelBufferAccess& dst, const TexDecompressionParams& params) const 2577 { 2578 DE_ASSERT(dst.getWidth() == m_width && dst.getHeight() == m_height && dst.getDepth() == m_depth); 2579 DE_ASSERT(dst.getFormat() == getUncompressedFormat(m_format)); 2580 2581 tcu::decompress(dst, m_format, &m_data[0], params); 2582 } 2583 2584 } // tcu 2585