The open source OpenXR runtime

external: Add bcdec for BC4 decoding

Part-of: <https://gitlab.freedesktop.org/monado/monado/-/merge_requests/2457>

authored by

Beyley Cardellio and committed by
Marge Bot
a56078e7 83f4422d

+1498
+5
.reuse/dep5
··· 90 90 License: MIT OR Unlicense 91 91 Comment: SPDX-License-Identifier missing. 92 92 93 + Files: src/external/bcdec/bcdec* 94 + Copyright: 2022, Sergii Kudlai 95 + License: MIT OR Unlicense 96 + Comment: SPDX-License-Identifier missing. 97 + 93 98 Files: src/external/glad/include/EGL/eglplatform.h 94 99 Copyright: 2007-2020, The Khronos Group Inc. 95 100 License: Apache-2.0
+4
src/external/CMakeLists.txt
··· 108 108 add_library(xrt-external-stb INTERFACE) 109 109 target_include_directories(xrt-external-stb SYSTEM INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/stb) 110 110 111 + # bcdec 112 + add_library(xrt-external-bcdec INTERFACE) 113 + target_include_directories(xrt-external-bcdec SYSTEM INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/bcdec) 114 + 111 115 # renderdoc 112 116 add_library(xrt-external-renderdoc INTERFACE) 113 117 target_include_directories(
+1489
src/external/bcdec/bcdec.h
··· 1 + /* bcdec.h - v0.97 2 + provides functions to decompress blocks of BC compressed images 3 + written by Sergii "iOrange" Kudlai in 2022 4 + 5 + This library does not allocate memory and is trying to use as less stack as possible 6 + 7 + The library was never optimized specifically for speed but for the overall size 8 + it has zero external dependencies and is not using any runtime functions 9 + 10 + Supported BC formats: 11 + BC1 (also known as DXT1) + it's "binary alpha" variant BC1A (DXT1A) 12 + BC2 (also known as DXT3) 13 + BC3 (also known as DXT5) 14 + BC4 (also known as ATI1N) 15 + BC5 (also known as ATI2N) 16 + BC6H (HDR format) 17 + BC7 18 + 19 + BC1/BC2/BC3/BC7 are expected to decompress into 4*4 RGBA blocks 8bit per component (32bit pixel) 20 + BC4/BC5 are expected to decompress into 4*4 R/RG blocks 8bit per component (8bit and 16bit pixel) 21 + BC6H is expected to decompress into 4*4 RGB blocks of either 32bit float or 16bit "half" per 22 + component (96bit or 48bit pixel) 23 + 24 + For more info, issues and suggestions please visit https://github.com/iOrange/bcdec 25 + 26 + Configuration: 27 + #define BCDEC_BC4BC5_PRECISE: 28 + enables more precise but slower BC4/BC5 decoding + signed/unsigned mode 29 + 30 + CREDITS: 31 + Aras Pranckevicius (@aras-p) - BC1/BC3 decoders optimizations (up to 3x the speed) 32 + - BC6H/BC7 bits pulling routines optimizations 33 + - optimized BC6H by moving unquantize out of the loop 34 + - Split BC6H decompression function into 'half' and 35 + 'float' variants 36 + 37 + Michael Schmidt (@RunDevelopment) - Found better "magic" coefficients for integer interpolation 38 + of reference colors in BC1 color block, that match with 39 + the floating point interpolation. This also made it faster 40 + than integer division by 3! 41 + 42 + bugfixes: 43 + @linkmauve 44 + 45 + LICENSE: See end of file for license information. 46 + */ 47 + 48 + #ifndef BCDEC_HEADER_INCLUDED 49 + #define BCDEC_HEADER_INCLUDED 50 + 51 + #define BCDEC_VERSION_MAJOR 0 52 + #define BCDEC_VERSION_MINOR 98 53 + 54 + /* if BCDEC_STATIC causes problems, try defining BCDECDEF to 'inline' or 'static inline' */ 55 + #ifndef BCDECDEF 56 + #ifdef BCDEC_STATIC 57 + #define BCDECDEF static 58 + #else 59 + #ifdef __cplusplus 60 + #define BCDECDEF extern "C" 61 + #else 62 + #define BCDECDEF extern 63 + #endif 64 + #endif 65 + #endif 66 + 67 + /* Used information sources: 68 + https://docs.microsoft.com/en-us/windows/win32/direct3d10/d3d10-graphics-programming-guide-resources-block-compression 69 + https://docs.microsoft.com/en-us/windows/win32/direct3d11/bc6h-format 70 + https://docs.microsoft.com/en-us/windows/win32/direct3d11/bc7-format 71 + https://docs.microsoft.com/en-us/windows/win32/direct3d11/bc7-format-mode-reference 72 + 73 + ! WARNING ! Khronos's BPTC partitions tables contain mistakes, do not use them! 74 + https://www.khronos.org/registry/DataFormat/specs/1.1/dataformat.1.1.html#BPTC 75 + 76 + ! Use tables from here instead ! 77 + https://www.khronos.org/registry/OpenGL/extensions/ARB/ARB_texture_compression_bptc.txt 78 + 79 + Leaving it here as it's a nice read 80 + https://fgiesen.wordpress.com/2021/10/04/gpu-bcn-decoding/ 81 + 82 + Fast half to float function from here 83 + https://gist.github.com/rygorous/2144712 84 + */ 85 + 86 + #define BCDEC_BC1_BLOCK_SIZE 8 87 + #define BCDEC_BC2_BLOCK_SIZE 16 88 + #define BCDEC_BC3_BLOCK_SIZE 16 89 + #define BCDEC_BC4_BLOCK_SIZE 8 90 + #define BCDEC_BC5_BLOCK_SIZE 16 91 + #define BCDEC_BC6H_BLOCK_SIZE 16 92 + #define BCDEC_BC7_BLOCK_SIZE 16 93 + 94 + #define BCDEC_BC1_COMPRESSED_SIZE(w, h) ((((w)>>2)*((h)>>2))*BCDEC_BC1_BLOCK_SIZE) 95 + #define BCDEC_BC2_COMPRESSED_SIZE(w, h) ((((w)>>2)*((h)>>2))*BCDEC_BC2_BLOCK_SIZE) 96 + #define BCDEC_BC3_COMPRESSED_SIZE(w, h) ((((w)>>2)*((h)>>2))*BCDEC_BC3_BLOCK_SIZE) 97 + #define BCDEC_BC4_COMPRESSED_SIZE(w, h) ((((w)>>2)*((h)>>2))*BCDEC_BC4_BLOCK_SIZE) 98 + #define BCDEC_BC5_COMPRESSED_SIZE(w, h) ((((w)>>2)*((h)>>2))*BCDEC_BC5_BLOCK_SIZE) 99 + #define BCDEC_BC6H_COMPRESSED_SIZE(w, h) ((((w)>>2)*((h)>>2))*BCDEC_BC6H_BLOCK_SIZE) 100 + #define BCDEC_BC7_COMPRESSED_SIZE(w, h) ((((w)>>2)*((h)>>2))*BCDEC_BC7_BLOCK_SIZE) 101 + 102 + BCDECDEF void bcdec_bc1(const void* compressedBlock, void* decompressedBlock, int destinationPitch); 103 + BCDECDEF void bcdec_bc2(const void* compressedBlock, void* decompressedBlock, int destinationPitch); 104 + BCDECDEF void bcdec_bc3(const void* compressedBlock, void* decompressedBlock, int destinationPitch); 105 + #ifndef BCDEC_BC4BC5_PRECISE 106 + BCDECDEF void bcdec_bc4(const void* compressedBlock, void* decompressedBlock, int destinationPitch); 107 + BCDECDEF void bcdec_bc5(const void* compressedBlock, void* decompressedBlock, int destinationPitch); 108 + #else 109 + BCDECDEF void bcdec_bc4(const void* compressedBlock, void* decompressedBlock, int destinationPitch, int isSigned); 110 + BCDECDEF void bcdec_bc5(const void* compressedBlock, void* decompressedBlock, int destinationPitch, int isSigned); 111 + BCDECDEF void bcdec_bc4_float(const void* compressedBlock, void* decompressedBlock, int destinationPitch, int isSigned); 112 + BCDECDEF void bcdec_bc5_float(const void* compressedBlock, void* decompressedBlock, int destinationPitch, int isSigned); 113 + #endif 114 + BCDECDEF void bcdec_bc6h_float(const void* compressedBlock, void* decompressedBlock, int destinationPitch, int isSigned); 115 + BCDECDEF void bcdec_bc6h_half(const void* compressedBlock, void* decompressedBlock, int destinationPitch, int isSigned); 116 + BCDECDEF void bcdec_bc7(const void* compressedBlock, void* decompressedBlock, int destinationPitch); 117 + 118 + #endif /* BCDEC_HEADER_INCLUDED */ 119 + 120 + #ifdef BCDEC_IMPLEMENTATION 121 + 122 + static void bcdec__color_block(const void* compressedBlock, void* decompressedBlock, int destinationPitch, int onlyOpaqueMode) { 123 + unsigned short c0, c1; 124 + unsigned int refColors[4]; /* 0xAABBGGRR */ 125 + unsigned char* dstColors; 126 + unsigned int colorIndices; 127 + int i, j, idx; 128 + unsigned int r0, g0, b0, r1, g1, b1, r, g, b; 129 + 130 + c0 = ((unsigned short*)compressedBlock)[0]; 131 + c1 = ((unsigned short*)compressedBlock)[1]; 132 + 133 + /* Unpack 565 ref colors */ 134 + r0 = (c0 >> 11) & 0x1F; 135 + g0 = (c0 >> 5) & 0x3F; 136 + b0 = c0 & 0x1F; 137 + 138 + r1 = (c1 >> 11) & 0x1F; 139 + g1 = (c1 >> 5) & 0x3F; 140 + b1 = c1 & 0x1F; 141 + 142 + /* Expand 565 ref colors to 888 */ 143 + r = (r0 * 527 + 23) >> 6; 144 + g = (g0 * 259 + 33) >> 6; 145 + b = (b0 * 527 + 23) >> 6; 146 + refColors[0] = 0xFF000000 | (b << 16) | (g << 8) | r; 147 + 148 + r = (r1 * 527 + 23) >> 6; 149 + g = (g1 * 259 + 33) >> 6; 150 + b = (b1 * 527 + 23) >> 6; 151 + refColors[1] = 0xFF000000 | (b << 16) | (g << 8) | r; 152 + 153 + if (c0 > c1 || onlyOpaqueMode) { /* Standard BC1 mode (also BC3 color block uses ONLY this mode) */ 154 + /* color_2 = 2/3*color_0 + 1/3*color_1 155 + color_3 = 1/3*color_0 + 2/3*color_1 */ 156 + r = ((2 * r0 + r1) * 351 + 61) >> 7; 157 + g = ((2 * g0 + g1) * 2763 + 1039) >> 11; 158 + b = ((2 * b0 + b1) * 351 + 61) >> 7; 159 + refColors[2] = 0xFF000000 | (b << 16) | (g << 8) | r; 160 + 161 + r = ((r0 + r1 * 2) * 351 + 61) >> 7; 162 + g = ((g0 + g1 * 2) * 2763 + 1039) >> 11; 163 + b = ((b0 + b1 * 2) * 351 + 61) >> 7; 164 + refColors[3] = 0xFF000000 | (b << 16) | (g << 8) | r; 165 + } else { /* Quite rare BC1A mode */ 166 + /* color_2 = 1/2*color_0 + 1/2*color_1; 167 + color_3 = 0; */ 168 + r = ((r0 + r1) * 1053 + 125) >> 8; 169 + g = ((g0 + g1) * 4145 + 1019) >> 11; 170 + b = ((b0 + b1) * 1053 + 125) >> 8; 171 + refColors[2] = 0xFF000000 | (b << 16) | (g << 8) | r; 172 + 173 + refColors[3] = 0x00000000; 174 + } 175 + 176 + colorIndices = ((unsigned int*)compressedBlock)[1]; 177 + 178 + /* Fill out the decompressed color block */ 179 + dstColors = (unsigned char*)decompressedBlock; 180 + for (i = 0; i < 4; ++i) { 181 + for (j = 0; j < 4; ++j) { 182 + idx = colorIndices & 0x03; 183 + ((unsigned int*)dstColors)[j] = refColors[idx]; 184 + colorIndices >>= 2; 185 + } 186 + 187 + dstColors += destinationPitch; 188 + } 189 + } 190 + 191 + static void bcdec__sharp_alpha_block(const void* compressedBlock, void* decompressedBlock, int destinationPitch) { 192 + unsigned short* alpha; 193 + unsigned char* decompressed; 194 + int i, j; 195 + 196 + alpha = (unsigned short*)compressedBlock; 197 + decompressed = (unsigned char*)decompressedBlock; 198 + 199 + for (i = 0; i < 4; ++i) { 200 + for (j = 0; j < 4; ++j) { 201 + decompressed[j * 4] = ((alpha[i] >> (4 * j)) & 0x0F) * 17; 202 + } 203 + 204 + decompressed += destinationPitch; 205 + } 206 + } 207 + 208 + static void bcdec__smooth_alpha_block(const void* compressedBlock, void* decompressedBlock, int destinationPitch, int pixelSize) { 209 + unsigned char* decompressed; 210 + unsigned char alpha[8]; 211 + int i, j; 212 + unsigned long long block, indices; 213 + 214 + block = *(unsigned long long*)compressedBlock; 215 + decompressed = (unsigned char*)decompressedBlock; 216 + 217 + alpha[0] = block & 0xFF; 218 + alpha[1] = (block >> 8) & 0xFF; 219 + 220 + if (alpha[0] > alpha[1]) { 221 + /* 6 interpolated alpha values. */ 222 + alpha[2] = (6 * alpha[0] + alpha[1]) / 7; /* 6/7*alpha_0 + 1/7*alpha_1 */ 223 + alpha[3] = (5 * alpha[0] + 2 * alpha[1]) / 7; /* 5/7*alpha_0 + 2/7*alpha_1 */ 224 + alpha[4] = (4 * alpha[0] + 3 * alpha[1]) / 7; /* 4/7*alpha_0 + 3/7*alpha_1 */ 225 + alpha[5] = (3 * alpha[0] + 4 * alpha[1]) / 7; /* 3/7*alpha_0 + 4/7*alpha_1 */ 226 + alpha[6] = (2 * alpha[0] + 5 * alpha[1]) / 7; /* 2/7*alpha_0 + 5/7*alpha_1 */ 227 + alpha[7] = ( alpha[0] + 6 * alpha[1]) / 7; /* 1/7*alpha_0 + 6/7*alpha_1 */ 228 + } 229 + else { 230 + /* 4 interpolated alpha values. */ 231 + alpha[2] = (4 * alpha[0] + alpha[1]) / 5; /* 4/5*alpha_0 + 1/5*alpha_1 */ 232 + alpha[3] = (3 * alpha[0] + 2 * alpha[1]) / 5; /* 3/5*alpha_0 + 2/5*alpha_1 */ 233 + alpha[4] = (2 * alpha[0] + 3 * alpha[1]) / 5; /* 2/5*alpha_0 + 3/5*alpha_1 */ 234 + alpha[5] = ( alpha[0] + 4 * alpha[1]) / 5; /* 1/5*alpha_0 + 4/5*alpha_1 */ 235 + alpha[6] = 0x00; 236 + alpha[7] = 0xFF; 237 + } 238 + 239 + indices = block >> 16; 240 + for (i = 0; i < 4; ++i) { 241 + for (j = 0; j < 4; ++j) { 242 + decompressed[j * pixelSize] = alpha[indices & 0x07]; 243 + indices >>= 3; 244 + } 245 + 246 + decompressed += destinationPitch; 247 + } 248 + } 249 + 250 + #ifdef BCDEC_BC4BC5_PRECISE 251 + static void bcdec__bc4_block(const void* compressedBlock, void* decompressedBlock, int destinationPitch, int pixelSize, int isSigned) { 252 + signed char* sblock; 253 + unsigned char* ublock; 254 + int alpha[8]; 255 + int i, j; 256 + unsigned long long block, indices; 257 + 258 + static int aWeights4[4] = { 13107, 26215, 39321, 52429 }; 259 + static int aWeights6[6] = { 9363, 18724, 28086, 37450, 46812, 56173 }; 260 + 261 + block = *(unsigned long long*)compressedBlock; 262 + 263 + if (isSigned) { 264 + alpha[0] = (char)(block & 0xFF); 265 + alpha[1] = (char)((block >> 8) & 0xFF); 266 + if (alpha[0] < -127) alpha[0] = -127; /* -128 clamps to -127 */ 267 + if (alpha[1] < -127) alpha[1] = -127; /* -128 clamps to -127 */ 268 + } else { 269 + alpha[0] = block & 0xFF; 270 + alpha[1] = (block >> 8) & 0xFF; 271 + } 272 + 273 + if (alpha[0] > alpha[1]) { 274 + /* 6 interpolated alpha values. */ 275 + alpha[2] = (aWeights6[5] * alpha[0] + aWeights6[0] * alpha[1] + 32768) >> 16; /* 6/7*alpha_0 + 1/7*alpha_1 */ 276 + alpha[3] = (aWeights6[4] * alpha[0] + aWeights6[1] * alpha[1] + 32768) >> 16; /* 5/7*alpha_0 + 2/7*alpha_1 */ 277 + alpha[4] = (aWeights6[3] * alpha[0] + aWeights6[2] * alpha[1] + 32768) >> 16; /* 4/7*alpha_0 + 3/7*alpha_1 */ 278 + alpha[5] = (aWeights6[2] * alpha[0] + aWeights6[3] * alpha[1] + 32768) >> 16; /* 3/7*alpha_0 + 4/7*alpha_1 */ 279 + alpha[6] = (aWeights6[1] * alpha[0] + aWeights6[4] * alpha[1] + 32768) >> 16; /* 2/7*alpha_0 + 5/7*alpha_1 */ 280 + alpha[7] = (aWeights6[0] * alpha[0] + aWeights6[5] * alpha[1] + 32768) >> 16; /* 1/7*alpha_0 + 6/7*alpha_1 */ 281 + } else { 282 + /* 4 interpolated alpha values. */ 283 + alpha[2] = (aWeights4[3] * alpha[0] + aWeights4[0] * alpha[1] + 32768) >> 16; /* 4/5*alpha_0 + 1/5*alpha_1 */ 284 + alpha[3] = (aWeights4[2] * alpha[0] + aWeights4[1] * alpha[1] + 32768) >> 16; /* 3/5*alpha_0 + 2/5*alpha_1 */ 285 + alpha[4] = (aWeights4[1] * alpha[0] + aWeights4[2] * alpha[1] + 32768) >> 16; /* 2/5*alpha_0 + 3/5*alpha_1 */ 286 + alpha[5] = (aWeights4[0] * alpha[0] + aWeights4[3] * alpha[1] + 32768) >> 16; /* 1/5*alpha_0 + 4/5*alpha_1 */ 287 + alpha[6] = isSigned ? -127 : 0; 288 + alpha[7] = isSigned ? 127 : 255; 289 + } 290 + 291 + indices = block >> 16; 292 + if (isSigned) { 293 + sblock = (char*)decompressedBlock; 294 + for (i = 0; i < 4; ++i) { 295 + for (j = 0; j < 4; ++j) { 296 + sblock[j * pixelSize] = (char)alpha[indices & 0x07]; 297 + indices >>= 3; 298 + } 299 + sblock += destinationPitch; 300 + } 301 + } else { 302 + ublock = (unsigned char*)decompressedBlock; 303 + for (i = 0; i < 4; ++i) { 304 + for (j = 0; j < 4; ++j) { 305 + ublock[j * pixelSize] = (unsigned char)alpha[indices & 0x07]; 306 + indices >>= 3; 307 + } 308 + ublock += destinationPitch; 309 + } 310 + } 311 + } 312 + 313 + static void bcdec__bc4_block_float(const void* compressedBlock, void* decompressedBlock, int destinationPitch, int pixelSize, int isSigned) { 314 + float* decompressed; 315 + float alpha[8]; 316 + int i, j; 317 + unsigned long long block, indices; 318 + 319 + block = *(unsigned long long*)compressedBlock; 320 + decompressed = (float*)decompressedBlock; 321 + 322 + if (isSigned) { 323 + alpha[0] = (float)((char)(block & 0xFF)) / 127.0f; 324 + alpha[1] = (float)((char)((block >> 8) & 0xFF)) / 127.0f; 325 + if (alpha[0] < -1.0f) alpha[0] = -1.0f; /* -128 clamps to -127 */ 326 + if (alpha[1] < -1.0f) alpha[1] = -1.0f; /* -128 clamps to -127 */ 327 + } else { 328 + alpha[0] = (float)(block & 0xFF) / 255.0f; 329 + alpha[1] = (float)((block >> 8) & 0xFF) / 255.0f; 330 + } 331 + 332 + if (alpha[0] > alpha[1]) { 333 + /* 6 interpolated alpha values. */ 334 + alpha[2] = (6.0f * alpha[0] + alpha[1]) / 7.0f; /* 6/7*alpha_0 + 1/7*alpha_1 */ 335 + alpha[3] = (5.0f * alpha[0] + 2.0f * alpha[1]) / 7.0f; /* 5/7*alpha_0 + 2/7*alpha_1 */ 336 + alpha[4] = (4.0f * alpha[0] + 3.0f * alpha[1]) / 7.0f; /* 4/7*alpha_0 + 3/7*alpha_1 */ 337 + alpha[5] = (3.0f * alpha[0] + 4.0f * alpha[1]) / 7.0f; /* 3/7*alpha_0 + 4/7*alpha_1 */ 338 + alpha[6] = (2.0f * alpha[0] + 5.0f * alpha[1]) / 7.0f; /* 2/7*alpha_0 + 5/7*alpha_1 */ 339 + alpha[7] = ( alpha[0] + 6.0f * alpha[1]) / 7.0f; /* 1/7*alpha_0 + 6/7*alpha_1 */ 340 + } else { 341 + /* 4 interpolated alpha values. */ 342 + alpha[2] = (4.0f * alpha[0] + alpha[1]) / 5.0f; /* 4/5*alpha_0 + 1/5*alpha_1 */ 343 + alpha[3] = (3.0f * alpha[0] + 2.0f * alpha[1]) / 5.0f; /* 3/5*alpha_0 + 2/5*alpha_1 */ 344 + alpha[4] = (2.0f * alpha[0] + 3.0f * alpha[1]) / 5.0f; /* 2/5*alpha_0 + 3/5*alpha_1 */ 345 + alpha[5] = ( alpha[0] + 4.0f * alpha[1]) / 5.0f; /* 1/5*alpha_0 + 4/5*alpha_1 */ 346 + alpha[6] = isSigned ? -1.0f : 0.0f; 347 + alpha[7] = 1.0f; 348 + } 349 + 350 + indices = block >> 16; 351 + for (i = 0; i < 4; ++i) { 352 + for (j = 0; j < 4; ++j) { 353 + decompressed[j * pixelSize] = alpha[indices & 0x07]; 354 + indices >>= 3; 355 + } 356 + decompressed += destinationPitch; 357 + } 358 + } 359 + #endif /* BCDEC_BC4BC5_PRECISE */ 360 + 361 + typedef struct bcdec__bitstream { 362 + unsigned long long low; 363 + unsigned long long high; 364 + } bcdec__bitstream_t; 365 + 366 + static int bcdec__bitstream_read_bits(bcdec__bitstream_t* bstream, int numBits) { 367 + unsigned int mask = (1 << numBits) - 1; 368 + /* Read the low N bits */ 369 + unsigned int bits = (bstream->low & mask); 370 + 371 + bstream->low >>= numBits; 372 + /* Put the low N bits of "high" into the high 64-N bits of "low". */ 373 + bstream->low |= (bstream->high & mask) << (sizeof(bstream->high) * 8 - numBits); 374 + bstream->high >>= numBits; 375 + 376 + return bits; 377 + } 378 + 379 + static int bcdec__bitstream_read_bit(bcdec__bitstream_t* bstream) { 380 + return bcdec__bitstream_read_bits(bstream, 1); 381 + } 382 + 383 + /* reversed bits pulling, used in BC6H decoding 384 + why ?? just why ??? */ 385 + static int bcdec__bitstream_read_bits_r(bcdec__bitstream_t* bstream, int numBits) { 386 + int bits = bcdec__bitstream_read_bits(bstream, numBits); 387 + /* Reverse the bits. */ 388 + int result = 0; 389 + while (numBits--) { 390 + result <<= 1; 391 + result |= (bits & 1); 392 + bits >>= 1; 393 + } 394 + return result; 395 + } 396 + 397 + 398 + 399 + BCDECDEF void bcdec_bc1(const void* compressedBlock, void* decompressedBlock, int destinationPitch) { 400 + bcdec__color_block(compressedBlock, decompressedBlock, destinationPitch, 0); 401 + } 402 + 403 + BCDECDEF void bcdec_bc2(const void* compressedBlock, void* decompressedBlock, int destinationPitch) { 404 + bcdec__color_block(((char*)compressedBlock) + 8, decompressedBlock, destinationPitch, 1); 405 + bcdec__sharp_alpha_block(compressedBlock, ((char*)decompressedBlock) + 3, destinationPitch); 406 + } 407 + 408 + BCDECDEF void bcdec_bc3(const void* compressedBlock, void* decompressedBlock, int destinationPitch) { 409 + bcdec__color_block(((char*)compressedBlock) + 8, decompressedBlock, destinationPitch, 1); 410 + bcdec__smooth_alpha_block(compressedBlock, ((char*)decompressedBlock) + 3, destinationPitch, 4); 411 + } 412 + 413 + #ifndef BCDEC_BC4BC5_PRECISE 414 + BCDECDEF void bcdec_bc4(const void* compressedBlock, void* decompressedBlock, int destinationPitch) { 415 + bcdec__smooth_alpha_block(compressedBlock, decompressedBlock, destinationPitch, 1); 416 + #else 417 + BCDECDEF void bcdec_bc4(const void* compressedBlock, void* decompressedBlock, int destinationPitch, int isSigned) { 418 + bcdec__bc4_block(compressedBlock, decompressedBlock, destinationPitch, 1, isSigned); 419 + #endif 420 + } 421 + 422 + #ifndef BCDEC_BC4BC5_PRECISE 423 + BCDECDEF void bcdec_bc5(const void* compressedBlock, void* decompressedBlock, int destinationPitch) { 424 + bcdec__smooth_alpha_block(compressedBlock, decompressedBlock, destinationPitch, 2); 425 + bcdec__smooth_alpha_block(((char*)compressedBlock) + 8, ((char*)decompressedBlock) + 1, destinationPitch, 2); 426 + #else 427 + BCDECDEF void bcdec_bc5(const void* compressedBlock, void* decompressedBlock, int destinationPitch, int isSigned) { 428 + bcdec__bc4_block(compressedBlock, decompressedBlock, destinationPitch, 2, isSigned); 429 + bcdec__bc4_block(((char*)compressedBlock) + 8, ((char*)decompressedBlock) + 1, destinationPitch, 2, isSigned); 430 + #endif 431 + } 432 + 433 + #ifdef BCDEC_BC4BC5_PRECISE 434 + BCDECDEF void bcdec_bc4_float(const void* compressedBlock, void* decompressedBlock, int destinationPitch, int isSigned) { 435 + bcdec__bc4_block_float(compressedBlock, decompressedBlock, destinationPitch, 1, isSigned); 436 + } 437 + 438 + BCDECDEF void bcdec_bc5_float(const void* compressedBlock, void* decompressedBlock, int destinationPitch, int isSigned) { 439 + bcdec__bc4_block_float(compressedBlock, decompressedBlock, destinationPitch, 2, isSigned); 440 + bcdec__bc4_block_float(((char*)compressedBlock) + 8, ((float*)decompressedBlock) + 1, destinationPitch, 2, isSigned); 441 + } 442 + #endif /* BCDEC_BC4BC5_PRECISE */ 443 + 444 + /* http://graphics.stanford.edu/~seander/bithacks.html#VariableSignExtend */ 445 + static int bcdec__extend_sign(int val, int bits) { 446 + return (val << (32 - bits)) >> (32 - bits); 447 + } 448 + 449 + static int bcdec__transform_inverse(int val, int a0, int bits, int isSigned) { 450 + /* If the precision of A0 is "p" bits, then the transform algorithm is: 451 + B0 = (B0 + A0) & ((1 << p) - 1) */ 452 + val = (val + a0) & ((1 << bits) - 1); 453 + if (isSigned) { 454 + val = bcdec__extend_sign(val, bits); 455 + } 456 + return val; 457 + } 458 + 459 + /* pretty much copy-paste from documentation */ 460 + static int bcdec__unquantize(int val, int bits, int isSigned) { 461 + int unq, s = 0; 462 + 463 + if (!isSigned) { 464 + if (bits >= 15) { 465 + unq = val; 466 + } else if (!val) { 467 + unq = 0; 468 + } else if (val == ((1 << bits) - 1)) { 469 + unq = 0xFFFF; 470 + } else { 471 + unq = ((val << 16) + 0x8000) >> bits; 472 + } 473 + } else { 474 + if (bits >= 16) { 475 + unq = val; 476 + } else { 477 + if (val < 0) { 478 + s = 1; 479 + val = -val; 480 + } 481 + 482 + if (val == 0) { 483 + unq = 0; 484 + } else if (val >= ((1 << (bits - 1)) - 1)) { 485 + unq = 0x7FFF; 486 + } else { 487 + unq = ((val << 15) + 0x4000) >> (bits - 1); 488 + } 489 + 490 + if (s) { 491 + unq = -unq; 492 + } 493 + } 494 + } 495 + return unq; 496 + } 497 + 498 + static int bcdec__interpolate(int a, int b, int* weights, int index) { 499 + return (a * (64 - weights[index]) + b * weights[index] + 32) >> 6; 500 + } 501 + 502 + static unsigned short bcdec__finish_unquantize(int val, int isSigned) { 503 + int s; 504 + 505 + if (!isSigned) { 506 + return (unsigned short)((val * 31) >> 6); /* scale the magnitude by 31 / 64 */ 507 + } else { 508 + val = (val < 0) ? -(((-val) * 31) >> 5) : (val * 31) >> 5; /* scale the magnitude by 31 / 32 */ 509 + s = 0; 510 + if (val < 0) { 511 + s = 0x8000; 512 + val = -val; 513 + } 514 + return (unsigned short)(s | val); 515 + } 516 + } 517 + 518 + /* modified half_to_float_fast4 from https://gist.github.com/rygorous/2144712 */ 519 + static float bcdec__half_to_float_quick(unsigned short half) { 520 + typedef union { 521 + unsigned int u; 522 + float f; 523 + } FP32; 524 + 525 + static const FP32 magic = { 113 << 23 }; 526 + static const unsigned int shifted_exp = 0x7c00 << 13; /* exponent mask after shift */ 527 + FP32 o; 528 + unsigned int exp; 529 + 530 + o.u = (half & 0x7fff) << 13; /* exponent/mantissa bits */ 531 + exp = shifted_exp & o.u; /* just the exponent */ 532 + o.u += (127 - 15) << 23; /* exponent adjust */ 533 + 534 + /* handle exponent special cases */ 535 + if (exp == shifted_exp) { /* Inf/NaN? */ 536 + o.u += (128 - 16) << 23; /* extra exp adjust */ 537 + } else if (exp == 0) { /* Zero/Denormal? */ 538 + o.u += 1 << 23; /* extra exp adjust */ 539 + o.f -= magic.f; /* renormalize */ 540 + } 541 + 542 + o.u |= (half & 0x8000) << 16; /* sign bit */ 543 + return o.f; 544 + } 545 + 546 + BCDECDEF void bcdec_bc6h_half(const void* compressedBlock, void* decompressedBlock, int destinationPitch, int isSigned) { 547 + static char actual_bits_count[4][14] = { 548 + { 10, 7, 11, 11, 11, 9, 8, 8, 8, 6, 10, 11, 12, 16 }, /* W */ 549 + { 5, 6, 5, 4, 4, 5, 6, 5, 5, 6, 10, 9, 8, 4 }, /* dR */ 550 + { 5, 6, 4, 5, 4, 5, 5, 6, 5, 6, 10, 9, 8, 4 }, /* dG */ 551 + { 5, 6, 4, 4, 5, 5, 5, 5, 6, 6, 10, 9, 8, 4 } /* dB */ 552 + }; 553 + 554 + /* There are 32 possible partition sets for a two-region tile. 555 + Each 4x4 block represents a single shape. 556 + Here also every fix-up index has MSB bit set. */ 557 + static unsigned char partition_sets[32][4][4] = { 558 + { {128, 0, 1, 1}, {0, 0, 1, 1}, { 0, 0, 1, 1}, {0, 0, 1, 129} }, /* 0 */ 559 + { {128, 0, 0, 1}, {0, 0, 0, 1}, { 0, 0, 0, 1}, {0, 0, 0, 129} }, /* 1 */ 560 + { {128, 1, 1, 1}, {0, 1, 1, 1}, { 0, 1, 1, 1}, {0, 1, 1, 129} }, /* 2 */ 561 + { {128, 0, 0, 1}, {0, 0, 1, 1}, { 0, 0, 1, 1}, {0, 1, 1, 129} }, /* 3 */ 562 + { {128, 0, 0, 0}, {0, 0, 0, 1}, { 0, 0, 0, 1}, {0, 0, 1, 129} }, /* 4 */ 563 + { {128, 0, 1, 1}, {0, 1, 1, 1}, { 0, 1, 1, 1}, {1, 1, 1, 129} }, /* 5 */ 564 + { {128, 0, 0, 1}, {0, 0, 1, 1}, { 0, 1, 1, 1}, {1, 1, 1, 129} }, /* 6 */ 565 + { {128, 0, 0, 0}, {0, 0, 0, 1}, { 0, 0, 1, 1}, {0, 1, 1, 129} }, /* 7 */ 566 + { {128, 0, 0, 0}, {0, 0, 0, 0}, { 0, 0, 0, 1}, {0, 0, 1, 129} }, /* 8 */ 567 + { {128, 0, 1, 1}, {0, 1, 1, 1}, { 1, 1, 1, 1}, {1, 1, 1, 129} }, /* 9 */ 568 + { {128, 0, 0, 0}, {0, 0, 0, 1}, { 0, 1, 1, 1}, {1, 1, 1, 129} }, /* 10 */ 569 + { {128, 0, 0, 0}, {0, 0, 0, 0}, { 0, 0, 0, 1}, {0, 1, 1, 129} }, /* 11 */ 570 + { {128, 0, 0, 1}, {0, 1, 1, 1}, { 1, 1, 1, 1}, {1, 1, 1, 129} }, /* 12 */ 571 + { {128, 0, 0, 0}, {0, 0, 0, 0}, { 1, 1, 1, 1}, {1, 1, 1, 129} }, /* 13 */ 572 + { {128, 0, 0, 0}, {1, 1, 1, 1}, { 1, 1, 1, 1}, {1, 1, 1, 129} }, /* 14 */ 573 + { {128, 0, 0, 0}, {0, 0, 0, 0}, { 0, 0, 0, 0}, {1, 1, 1, 129} }, /* 15 */ 574 + { {128, 0, 0, 0}, {1, 0, 0, 0}, { 1, 1, 1, 0}, {1, 1, 1, 129} }, /* 16 */ 575 + { {128, 1, 129, 1}, {0, 0, 0, 1}, { 0, 0, 0, 0}, {0, 0, 0, 0} }, /* 17 */ 576 + { {128, 0, 0, 0}, {0, 0, 0, 0}, {129, 0, 0, 0}, {1, 1, 1, 0} }, /* 18 */ 577 + { {128, 1, 129, 1}, {0, 0, 1, 1}, { 0, 0, 0, 1}, {0, 0, 0, 0} }, /* 19 */ 578 + { {128, 0, 129, 1}, {0, 0, 0, 1}, { 0, 0, 0, 0}, {0, 0, 0, 0} }, /* 20 */ 579 + { {128, 0, 0, 0}, {1, 0, 0, 0}, {129, 1, 0, 0}, {1, 1, 1, 0} }, /* 21 */ 580 + { {128, 0, 0, 0}, {0, 0, 0, 0}, {129, 0, 0, 0}, {1, 1, 0, 0} }, /* 22 */ 581 + { {128, 1, 1, 1}, {0, 0, 1, 1}, { 0, 0, 1, 1}, {0, 0, 0, 129} }, /* 23 */ 582 + { {128, 0, 129, 1}, {0, 0, 0, 1}, { 0, 0, 0, 1}, {0, 0, 0, 0} }, /* 24 */ 583 + { {128, 0, 0, 0}, {1, 0, 0, 0}, {129, 0, 0, 0}, {1, 1, 0, 0} }, /* 25 */ 584 + { {128, 1, 129, 0}, {0, 1, 1, 0}, { 0, 1, 1, 0}, {0, 1, 1, 0} }, /* 26 */ 585 + { {128, 0, 129, 1}, {0, 1, 1, 0}, { 0, 1, 1, 0}, {1, 1, 0, 0} }, /* 27 */ 586 + { {128, 0, 0, 1}, {0, 1, 1, 1}, {129, 1, 1, 0}, {1, 0, 0, 0} }, /* 28 */ 587 + { {128, 0, 0, 0}, {1, 1, 1, 1}, {129, 1, 1, 1}, {0, 0, 0, 0} }, /* 29 */ 588 + { {128, 1, 129, 1}, {0, 0, 0, 1}, { 1, 0, 0, 0}, {1, 1, 1, 0} }, /* 30 */ 589 + { {128, 0, 129, 1}, {1, 0, 0, 1}, { 1, 0, 0, 1}, {1, 1, 0, 0} } /* 31 */ 590 + }; 591 + 592 + static int aWeight3[8] = { 0, 9, 18, 27, 37, 46, 55, 64 }; 593 + static int aWeight4[16] = { 0, 4, 9, 13, 17, 21, 26, 30, 34, 38, 43, 47, 51, 55, 60, 64 }; 594 + 595 + bcdec__bitstream_t bstream; 596 + int mode, partition, numPartitions, i, j, partitionSet, indexBits, index, ep_i, actualBits0Mode; 597 + int r[4], g[4], b[4]; /* wxyz */ 598 + unsigned short* decompressed; 599 + int* weights; 600 + 601 + decompressed = (unsigned short*)decompressedBlock; 602 + 603 + bstream.low = ((unsigned long long*)compressedBlock)[0]; 604 + bstream.high = ((unsigned long long*)compressedBlock)[1]; 605 + 606 + r[0] = r[1] = r[2] = r[3] = 0; 607 + g[0] = g[1] = g[2] = g[3] = 0; 608 + b[0] = b[1] = b[2] = b[3] = 0; 609 + 610 + mode = bcdec__bitstream_read_bits(&bstream, 2); 611 + if (mode > 1) { 612 + mode |= (bcdec__bitstream_read_bits(&bstream, 3) << 2); 613 + } 614 + 615 + /* modes >= 11 (10 in my code) are using 0 one, others will read it from the bitstream */ 616 + partition = 0; 617 + 618 + switch (mode) { 619 + /* mode 1 */ 620 + case 0b00: { 621 + /* Partitition indices: 46 bits 622 + Partition: 5 bits 623 + Color Endpoints: 75 bits (10.555, 10.555, 10.555) */ 624 + g[2] |= bcdec__bitstream_read_bit(&bstream) << 4; /* gy[4] */ 625 + b[2] |= bcdec__bitstream_read_bit(&bstream) << 4; /* by[4] */ 626 + b[3] |= bcdec__bitstream_read_bit(&bstream) << 4; /* bz[4] */ 627 + r[0] |= bcdec__bitstream_read_bits(&bstream, 10); /* rw[9:0] */ 628 + g[0] |= bcdec__bitstream_read_bits(&bstream, 10); /* gw[9:0] */ 629 + b[0] |= bcdec__bitstream_read_bits(&bstream, 10); /* bw[9:0] */ 630 + r[1] |= bcdec__bitstream_read_bits(&bstream, 5); /* rx[4:0] */ 631 + g[3] |= bcdec__bitstream_read_bit(&bstream) << 4; /* gz[4] */ 632 + g[2] |= bcdec__bitstream_read_bits(&bstream, 4); /* gy[3:0] */ 633 + g[1] |= bcdec__bitstream_read_bits(&bstream, 5); /* gx[4:0] */ 634 + b[3] |= bcdec__bitstream_read_bit(&bstream); /* bz[0] */ 635 + g[3] |= bcdec__bitstream_read_bits(&bstream, 4); /* gz[3:0] */ 636 + b[1] |= bcdec__bitstream_read_bits(&bstream, 5); /* bx[4:0] */ 637 + b[3] |= bcdec__bitstream_read_bit(&bstream) << 1; /* bz[1] */ 638 + b[2] |= bcdec__bitstream_read_bits(&bstream, 4); /* by[3:0] */ 639 + r[2] |= bcdec__bitstream_read_bits(&bstream, 5); /* ry[4:0] */ 640 + b[3] |= bcdec__bitstream_read_bit(&bstream) << 2; /* bz[2] */ 641 + r[3] |= bcdec__bitstream_read_bits(&bstream, 5); /* rz[4:0] */ 642 + b[3] |= bcdec__bitstream_read_bit(&bstream) << 3; /* bz[3] */ 643 + partition = bcdec__bitstream_read_bits(&bstream, 5); /* d[4:0] */ 644 + mode = 0; 645 + } break; 646 + 647 + /* mode 2 */ 648 + case 0b01: { 649 + /* Partitition indices: 46 bits 650 + Partition: 5 bits 651 + Color Endpoints: 75 bits (7666, 7666, 7666) */ 652 + g[2] |= bcdec__bitstream_read_bit(&bstream) << 5; /* gy[5] */ 653 + g[3] |= bcdec__bitstream_read_bit(&bstream) << 4; /* gz[4] */ 654 + g[3] |= bcdec__bitstream_read_bit(&bstream) << 5; /* gz[5] */ 655 + r[0] |= bcdec__bitstream_read_bits(&bstream, 7); /* rw[6:0] */ 656 + b[3] |= bcdec__bitstream_read_bit(&bstream); /* bz[0] */ 657 + b[3] |= bcdec__bitstream_read_bit(&bstream) << 1; /* bz[1] */ 658 + b[2] |= bcdec__bitstream_read_bit(&bstream) << 4; /* by[4] */ 659 + g[0] |= bcdec__bitstream_read_bits(&bstream, 7); /* gw[6:0] */ 660 + b[2] |= bcdec__bitstream_read_bit(&bstream) << 5; /* by[5] */ 661 + b[3] |= bcdec__bitstream_read_bit(&bstream) << 2; /* bz[2] */ 662 + g[2] |= bcdec__bitstream_read_bit(&bstream) << 4; /* gy[4] */ 663 + b[0] |= bcdec__bitstream_read_bits(&bstream, 7); /* bw[6:0] */ 664 + b[3] |= bcdec__bitstream_read_bit(&bstream) << 3; /* bz[3] */ 665 + b[3] |= bcdec__bitstream_read_bit(&bstream) << 5; /* bz[5] */ 666 + b[3] |= bcdec__bitstream_read_bit(&bstream) << 4; /* bz[4] */ 667 + r[1] |= bcdec__bitstream_read_bits(&bstream, 6); /* rx[5:0] */ 668 + g[2] |= bcdec__bitstream_read_bits(&bstream, 4); /* gy[3:0] */ 669 + g[1] |= bcdec__bitstream_read_bits(&bstream, 6); /* gx[5:0] */ 670 + g[3] |= bcdec__bitstream_read_bits(&bstream, 4); /* gz[3:0] */ 671 + b[1] |= bcdec__bitstream_read_bits(&bstream, 6); /* bx[5:0] */ 672 + b[2] |= bcdec__bitstream_read_bits(&bstream, 4); /* by[3:0] */ 673 + r[2] |= bcdec__bitstream_read_bits(&bstream, 6); /* ry[5:0] */ 674 + r[3] |= bcdec__bitstream_read_bits(&bstream, 6); /* rz[5:0] */ 675 + partition = bcdec__bitstream_read_bits(&bstream, 5); /* d[4:0] */ 676 + mode = 1; 677 + } break; 678 + 679 + /* mode 3 */ 680 + case 0b00010: { 681 + /* Partitition indices: 46 bits 682 + Partition: 5 bits 683 + Color Endpoints: 72 bits (11.555, 11.444, 11.444) */ 684 + r[0] |= bcdec__bitstream_read_bits(&bstream, 10); /* rw[9:0] */ 685 + g[0] |= bcdec__bitstream_read_bits(&bstream, 10); /* gw[9:0] */ 686 + b[0] |= bcdec__bitstream_read_bits(&bstream, 10); /* bw[9:0] */ 687 + r[1] |= bcdec__bitstream_read_bits(&bstream, 5); /* rx[4:0] */ 688 + r[0] |= bcdec__bitstream_read_bit(&bstream) << 10; /* rw[10] */ 689 + g[2] |= bcdec__bitstream_read_bits(&bstream, 4); /* gy[3:0] */ 690 + g[1] |= bcdec__bitstream_read_bits(&bstream, 4); /* gx[3:0] */ 691 + g[0] |= bcdec__bitstream_read_bit(&bstream) << 10; /* gw[10] */ 692 + b[3] |= bcdec__bitstream_read_bit(&bstream); /* bz[0] */ 693 + g[3] |= bcdec__bitstream_read_bits(&bstream, 4); /* gz[3:0] */ 694 + b[1] |= bcdec__bitstream_read_bits(&bstream, 4); /* bx[3:0] */ 695 + b[0] |= bcdec__bitstream_read_bit(&bstream) << 10; /* bw[10] */ 696 + b[3] |= bcdec__bitstream_read_bit(&bstream) << 1; /* bz[1] */ 697 + b[2] |= bcdec__bitstream_read_bits(&bstream, 4); /* by[3:0] */ 698 + r[2] |= bcdec__bitstream_read_bits(&bstream, 5); /* ry[4:0] */ 699 + b[3] |= bcdec__bitstream_read_bit(&bstream) << 2; /* bz[2] */ 700 + r[3] |= bcdec__bitstream_read_bits(&bstream, 5); /* rz[4:0] */ 701 + b[3] |= bcdec__bitstream_read_bit(&bstream) << 3; /* bz[3] */ 702 + partition = bcdec__bitstream_read_bits(&bstream, 5); /* d[4:0] */ 703 + mode = 2; 704 + } break; 705 + 706 + /* mode 4 */ 707 + case 0b00110: { 708 + /* Partitition indices: 46 bits 709 + Partition: 5 bits 710 + Color Endpoints: 72 bits (11.444, 11.555, 11.444) */ 711 + r[0] |= bcdec__bitstream_read_bits(&bstream, 10); /* rw[9:0] */ 712 + g[0] |= bcdec__bitstream_read_bits(&bstream, 10); /* gw[9:0] */ 713 + b[0] |= bcdec__bitstream_read_bits(&bstream, 10); /* bw[9:0] */ 714 + r[1] |= bcdec__bitstream_read_bits(&bstream, 4); /* rx[3:0] */ 715 + r[0] |= bcdec__bitstream_read_bit(&bstream) << 10; /* rw[10] */ 716 + g[3] |= bcdec__bitstream_read_bit(&bstream) << 4; /* gz[4] */ 717 + g[2] |= bcdec__bitstream_read_bits(&bstream, 4); /* gy[3:0] */ 718 + g[1] |= bcdec__bitstream_read_bits(&bstream, 5); /* gx[4:0] */ 719 + g[0] |= bcdec__bitstream_read_bit(&bstream) << 10; /* gw[10] */ 720 + g[3] |= bcdec__bitstream_read_bits(&bstream, 4); /* gz[3:0] */ 721 + b[1] |= bcdec__bitstream_read_bits(&bstream, 4); /* bx[3:0] */ 722 + b[0] |= bcdec__bitstream_read_bit(&bstream) << 10; /* bw[10] */ 723 + b[3] |= bcdec__bitstream_read_bit(&bstream) << 1; /* bz[1] */ 724 + b[2] |= bcdec__bitstream_read_bits(&bstream, 4); /* by[3:0] */ 725 + r[2] |= bcdec__bitstream_read_bits(&bstream, 4); /* ry[3:0] */ 726 + b[3] |= bcdec__bitstream_read_bit(&bstream); /* bz[0] */ 727 + b[3] |= bcdec__bitstream_read_bit(&bstream) << 2; /* bz[2] */ 728 + r[3] |= bcdec__bitstream_read_bits(&bstream, 4); /* rz[3:0] */ 729 + g[2] |= bcdec__bitstream_read_bit(&bstream) << 4; /* gy[4] */ 730 + b[3] |= bcdec__bitstream_read_bit(&bstream) << 3; /* bz[3] */ 731 + partition = bcdec__bitstream_read_bits(&bstream, 5); /* d[4:0] */ 732 + mode = 3; 733 + } break; 734 + 735 + /* mode 5 */ 736 + case 0b01010: { 737 + /* Partitition indices: 46 bits 738 + Partition: 5 bits 739 + Color Endpoints: 72 bits (11.444, 11.444, 11.555) */ 740 + r[0] |= bcdec__bitstream_read_bits(&bstream, 10); /* rw[9:0] */ 741 + g[0] |= bcdec__bitstream_read_bits(&bstream, 10); /* gw[9:0] */ 742 + b[0] |= bcdec__bitstream_read_bits(&bstream, 10); /* bw[9:0] */ 743 + r[1] |= bcdec__bitstream_read_bits(&bstream, 4); /* rx[3:0] */ 744 + r[0] |= bcdec__bitstream_read_bit(&bstream) << 10; /* rw[10] */ 745 + b[2] |= bcdec__bitstream_read_bit(&bstream) << 4; /* by[4] */ 746 + g[2] |= bcdec__bitstream_read_bits(&bstream, 4); /* gy[3:0] */ 747 + g[1] |= bcdec__bitstream_read_bits(&bstream, 4); /* gx[3:0] */ 748 + g[0] |= bcdec__bitstream_read_bit(&bstream) << 10; /* gw[10] */ 749 + b[3] |= bcdec__bitstream_read_bit(&bstream); /* bz[0] */ 750 + g[3] |= bcdec__bitstream_read_bits(&bstream, 4); /* gz[3:0] */ 751 + b[1] |= bcdec__bitstream_read_bits(&bstream, 5); /* bx[4:0] */ 752 + b[0] |= bcdec__bitstream_read_bit(&bstream) << 10; /* bw[10] */ 753 + b[2] |= bcdec__bitstream_read_bits(&bstream, 4); /* by[3:0] */ 754 + r[2] |= bcdec__bitstream_read_bits(&bstream, 4); /* ry[3:0] */ 755 + b[3] |= bcdec__bitstream_read_bit(&bstream) << 1; /* bz[1] */ 756 + b[3] |= bcdec__bitstream_read_bit(&bstream) << 2; /* bz[2] */ 757 + r[3] |= bcdec__bitstream_read_bits(&bstream, 4); /* rz[3:0] */ 758 + b[3] |= bcdec__bitstream_read_bit(&bstream) << 4; /* bz[4] */ 759 + b[3] |= bcdec__bitstream_read_bit(&bstream) << 3; /* bz[3] */ 760 + partition = bcdec__bitstream_read_bits(&bstream, 5); /* d[4:0] */ 761 + mode = 4; 762 + } break; 763 + 764 + /* mode 6 */ 765 + case 0b01110: { 766 + /* Partitition indices: 46 bits 767 + Partition: 5 bits 768 + Color Endpoints: 72 bits (9555, 9555, 9555) */ 769 + r[0] |= bcdec__bitstream_read_bits(&bstream, 9); /* rw[8:0] */ 770 + b[2] |= bcdec__bitstream_read_bit(&bstream) << 4; /* by[4] */ 771 + g[0] |= bcdec__bitstream_read_bits(&bstream, 9); /* gw[8:0] */ 772 + g[2] |= bcdec__bitstream_read_bit(&bstream) << 4; /* gy[4] */ 773 + b[0] |= bcdec__bitstream_read_bits(&bstream, 9); /* bw[8:0] */ 774 + b[3] |= bcdec__bitstream_read_bit(&bstream) << 4; /* bz[4] */ 775 + r[1] |= bcdec__bitstream_read_bits(&bstream, 5); /* rx[4:0] */ 776 + g[3] |= bcdec__bitstream_read_bit(&bstream) << 4; /* gz[4] */ 777 + g[2] |= bcdec__bitstream_read_bits(&bstream, 4); /* gy[3:0] */ 778 + g[1] |= bcdec__bitstream_read_bits(&bstream, 5); /* gx[4:0] */ 779 + b[3] |= bcdec__bitstream_read_bit(&bstream); /* bz[0] */ 780 + g[3] |= bcdec__bitstream_read_bits(&bstream, 4); /* gx[3:0] */ 781 + b[1] |= bcdec__bitstream_read_bits(&bstream, 5); /* bx[4:0] */ 782 + b[3] |= bcdec__bitstream_read_bit(&bstream) << 1; /* bz[1] */ 783 + b[2] |= bcdec__bitstream_read_bits(&bstream, 4); /* by[3:0] */ 784 + r[2] |= bcdec__bitstream_read_bits(&bstream, 5); /* ry[4:0] */ 785 + b[3] |= bcdec__bitstream_read_bit(&bstream) << 2; /* bz[2] */ 786 + r[3] |= bcdec__bitstream_read_bits(&bstream, 5); /* rz[4:0] */ 787 + b[3] |= bcdec__bitstream_read_bit(&bstream) << 3; /* bz[3] */ 788 + partition = bcdec__bitstream_read_bits(&bstream, 5); /* d[4:0] */ 789 + mode = 5; 790 + } break; 791 + 792 + /* mode 7 */ 793 + case 0b10010: { 794 + /* Partitition indices: 46 bits 795 + Partition: 5 bits 796 + Color Endpoints: 72 bits (8666, 8555, 8555) */ 797 + r[0] |= bcdec__bitstream_read_bits(&bstream, 8); /* rw[7:0] */ 798 + g[3] |= bcdec__bitstream_read_bit(&bstream) << 4; /* gz[4] */ 799 + b[2] |= bcdec__bitstream_read_bit(&bstream) << 4; /* by[4] */ 800 + g[0] |= bcdec__bitstream_read_bits(&bstream, 8); /* gw[7:0] */ 801 + b[3] |= bcdec__bitstream_read_bit(&bstream) << 2; /* bz[2] */ 802 + g[2] |= bcdec__bitstream_read_bit(&bstream) << 4; /* gy[4] */ 803 + b[0] |= bcdec__bitstream_read_bits(&bstream, 8); /* bw[7:0] */ 804 + b[3] |= bcdec__bitstream_read_bit(&bstream) << 3; /* bz[3] */ 805 + b[3] |= bcdec__bitstream_read_bit(&bstream) << 4; /* bz[4] */ 806 + r[1] |= bcdec__bitstream_read_bits(&bstream, 6); /* rx[5:0] */ 807 + g[2] |= bcdec__bitstream_read_bits(&bstream, 4); /* gy[3:0] */ 808 + g[1] |= bcdec__bitstream_read_bits(&bstream, 5); /* gx[4:0] */ 809 + b[3] |= bcdec__bitstream_read_bit(&bstream); /* bz[0] */ 810 + g[3] |= bcdec__bitstream_read_bits(&bstream, 4); /* gz[3:0] */ 811 + b[1] |= bcdec__bitstream_read_bits(&bstream, 5); /* bx[4:0] */ 812 + b[3] |= bcdec__bitstream_read_bit(&bstream) << 1; /* bz[1] */ 813 + b[2] |= bcdec__bitstream_read_bits(&bstream, 4); /* by[3:0] */ 814 + r[2] |= bcdec__bitstream_read_bits(&bstream, 6); /* ry[5:0] */ 815 + r[3] |= bcdec__bitstream_read_bits(&bstream, 6); /* rz[5:0] */ 816 + partition = bcdec__bitstream_read_bits(&bstream, 5); /* d[4:0] */ 817 + mode = 6; 818 + } break; 819 + 820 + /* mode 8 */ 821 + case 0b10110: { 822 + /* Partitition indices: 46 bits 823 + Partition: 5 bits 824 + Color Endpoints: 72 bits (8555, 8666, 8555) */ 825 + r[0] |= bcdec__bitstream_read_bits(&bstream, 8); /* rw[7:0] */ 826 + b[3] |= bcdec__bitstream_read_bit(&bstream); /* bz[0] */ 827 + b[2] |= bcdec__bitstream_read_bit(&bstream) << 4; /* by[4] */ 828 + g[0] |= bcdec__bitstream_read_bits(&bstream, 8); /* gw[7:0] */ 829 + g[2] |= bcdec__bitstream_read_bit(&bstream) << 5; /* gy[5] */ 830 + g[2] |= bcdec__bitstream_read_bit(&bstream) << 4; /* gy[4] */ 831 + b[0] |= bcdec__bitstream_read_bits(&bstream, 8); /* bw[7:0] */ 832 + g[3] |= bcdec__bitstream_read_bit(&bstream) << 5; /* gz[5] */ 833 + b[3] |= bcdec__bitstream_read_bit(&bstream) << 4; /* bz[4] */ 834 + r[1] |= bcdec__bitstream_read_bits(&bstream, 5); /* rx[4:0] */ 835 + g[3] |= bcdec__bitstream_read_bit(&bstream) << 4; /* gz[4] */ 836 + g[2] |= bcdec__bitstream_read_bits(&bstream, 4); /* gy[3:0] */ 837 + g[1] |= bcdec__bitstream_read_bits(&bstream, 6); /* gx[5:0] */ 838 + g[3] |= bcdec__bitstream_read_bits(&bstream, 4); /* zx[3:0] */ 839 + b[1] |= bcdec__bitstream_read_bits(&bstream, 5); /* bx[4:0] */ 840 + b[3] |= bcdec__bitstream_read_bit(&bstream) << 1; /* bz[1] */ 841 + b[2] |= bcdec__bitstream_read_bits(&bstream, 4); /* by[3:0] */ 842 + r[2] |= bcdec__bitstream_read_bits(&bstream, 5); /* ry[4:0] */ 843 + b[3] |= bcdec__bitstream_read_bit(&bstream) << 2; /* bz[2] */ 844 + r[3] |= bcdec__bitstream_read_bits(&bstream, 5); /* rz[4:0] */ 845 + b[3] |= bcdec__bitstream_read_bit(&bstream) << 3; /* bz[3] */ 846 + partition = bcdec__bitstream_read_bits(&bstream, 5); /* d[4:0] */ 847 + mode = 7; 848 + } break; 849 + 850 + /* mode 9 */ 851 + case 0b11010: { 852 + /* Partitition indices: 46 bits 853 + Partition: 5 bits 854 + Color Endpoints: 72 bits (8555, 8555, 8666) */ 855 + r[0] |= bcdec__bitstream_read_bits(&bstream, 8); /* rw[7:0] */ 856 + b[3] |= bcdec__bitstream_read_bit(&bstream) << 1; /* bz[1] */ 857 + b[2] |= bcdec__bitstream_read_bit(&bstream) << 4; /* by[4] */ 858 + g[0] |= bcdec__bitstream_read_bits(&bstream, 8); /* gw[7:0] */ 859 + b[2] |= bcdec__bitstream_read_bit(&bstream) << 5; /* by[5] */ 860 + g[2] |= bcdec__bitstream_read_bit(&bstream) << 4; /* gy[4] */ 861 + b[0] |= bcdec__bitstream_read_bits(&bstream, 8); /* bw[7:0] */ 862 + b[3] |= bcdec__bitstream_read_bit(&bstream) << 5; /* bz[5] */ 863 + b[3] |= bcdec__bitstream_read_bit(&bstream) << 4; /* bz[4] */ 864 + r[1] |= bcdec__bitstream_read_bits(&bstream, 5); /* bw[4:0] */ 865 + g[3] |= bcdec__bitstream_read_bit(&bstream) << 4; /* gz[4] */ 866 + g[2] |= bcdec__bitstream_read_bits(&bstream, 4); /* gy[3:0] */ 867 + g[1] |= bcdec__bitstream_read_bits(&bstream, 5); /* gx[4:0] */ 868 + b[3] |= bcdec__bitstream_read_bit(&bstream); /* bz[0] */ 869 + g[3] |= bcdec__bitstream_read_bits(&bstream, 4); /* gz[3:0] */ 870 + b[1] |= bcdec__bitstream_read_bits(&bstream, 6); /* bx[5:0] */ 871 + b[2] |= bcdec__bitstream_read_bits(&bstream, 4); /* by[3:0] */ 872 + r[2] |= bcdec__bitstream_read_bits(&bstream, 5); /* ry[4:0] */ 873 + b[3] |= bcdec__bitstream_read_bit(&bstream) << 2; /* bz[2] */ 874 + r[3] |= bcdec__bitstream_read_bits(&bstream, 5); /* rz[4:0] */ 875 + b[3] |= bcdec__bitstream_read_bit(&bstream) << 3; /* bz[3] */ 876 + partition = bcdec__bitstream_read_bits(&bstream, 5); /* d[4:0] */ 877 + mode = 8; 878 + } break; 879 + 880 + /* mode 10 */ 881 + case 0b11110: { 882 + /* Partitition indices: 46 bits 883 + Partition: 5 bits 884 + Color Endpoints: 72 bits (6666, 6666, 6666) */ 885 + r[0] |= bcdec__bitstream_read_bits(&bstream, 6); /* rw[5:0] */ 886 + g[3] |= bcdec__bitstream_read_bit(&bstream) << 4; /* gz[4] */ 887 + b[3] |= bcdec__bitstream_read_bit(&bstream); /* bz[0] */ 888 + b[3] |= bcdec__bitstream_read_bit(&bstream) << 1; /* bz[1] */ 889 + b[2] |= bcdec__bitstream_read_bit(&bstream) << 4; /* by[4] */ 890 + g[0] |= bcdec__bitstream_read_bits(&bstream, 6); /* gw[5:0] */ 891 + g[2] |= bcdec__bitstream_read_bit(&bstream) << 5; /* gy[5] */ 892 + b[2] |= bcdec__bitstream_read_bit(&bstream) << 5; /* by[5] */ 893 + b[3] |= bcdec__bitstream_read_bit(&bstream) << 2; /* bz[2] */ 894 + g[2] |= bcdec__bitstream_read_bit(&bstream) << 4; /* gy[4] */ 895 + b[0] |= bcdec__bitstream_read_bits(&bstream, 6); /* bw[5:0] */ 896 + g[3] |= bcdec__bitstream_read_bit(&bstream) << 5; /* gz[5] */ 897 + b[3] |= bcdec__bitstream_read_bit(&bstream) << 3; /* bz[3] */ 898 + b[3] |= bcdec__bitstream_read_bit(&bstream) << 5; /* bz[5] */ 899 + b[3] |= bcdec__bitstream_read_bit(&bstream) << 4; /* bz[4] */ 900 + r[1] |= bcdec__bitstream_read_bits(&bstream, 6); /* rx[5:0] */ 901 + g[2] |= bcdec__bitstream_read_bits(&bstream, 4); /* gy[3:0] */ 902 + g[1] |= bcdec__bitstream_read_bits(&bstream, 6); /* gx[5:0] */ 903 + g[3] |= bcdec__bitstream_read_bits(&bstream, 4); /* gz[3:0] */ 904 + b[1] |= bcdec__bitstream_read_bits(&bstream, 6); /* bx[5:0] */ 905 + b[2] |= bcdec__bitstream_read_bits(&bstream, 4); /* by[3:0] */ 906 + r[2] |= bcdec__bitstream_read_bits(&bstream, 6); /* ry[5:0] */ 907 + r[3] |= bcdec__bitstream_read_bits(&bstream, 6); /* rz[5:0] */ 908 + partition = bcdec__bitstream_read_bits(&bstream, 5); /* d[4:0] */ 909 + mode = 9; 910 + } break; 911 + 912 + /* mode 11 */ 913 + case 0b00011: { 914 + /* Partitition indices: 63 bits 915 + Partition: 0 bits 916 + Color Endpoints: 60 bits (10.10, 10.10, 10.10) */ 917 + r[0] |= bcdec__bitstream_read_bits(&bstream, 10); /* rw[9:0] */ 918 + g[0] |= bcdec__bitstream_read_bits(&bstream, 10); /* gw[9:0] */ 919 + b[0] |= bcdec__bitstream_read_bits(&bstream, 10); /* bw[9:0] */ 920 + r[1] |= bcdec__bitstream_read_bits(&bstream, 10); /* rx[9:0] */ 921 + g[1] |= bcdec__bitstream_read_bits(&bstream, 10); /* gx[9:0] */ 922 + b[1] |= bcdec__bitstream_read_bits(&bstream, 10); /* bx[9:0] */ 923 + mode = 10; 924 + } break; 925 + 926 + /* mode 12 */ 927 + case 0b00111: { 928 + /* Partitition indices: 63 bits 929 + Partition: 0 bits 930 + Color Endpoints: 60 bits (11.9, 11.9, 11.9) */ 931 + r[0] |= bcdec__bitstream_read_bits(&bstream, 10); /* rw[9:0] */ 932 + g[0] |= bcdec__bitstream_read_bits(&bstream, 10); /* gw[9:0] */ 933 + b[0] |= bcdec__bitstream_read_bits(&bstream, 10); /* bw[9:0] */ 934 + r[1] |= bcdec__bitstream_read_bits(&bstream, 9); /* rx[8:0] */ 935 + r[0] |= bcdec__bitstream_read_bit(&bstream) << 10; /* rw[10] */ 936 + g[1] |= bcdec__bitstream_read_bits(&bstream, 9); /* gx[8:0] */ 937 + g[0] |= bcdec__bitstream_read_bit(&bstream) << 10; /* gw[10] */ 938 + b[1] |= bcdec__bitstream_read_bits(&bstream, 9); /* bx[8:0] */ 939 + b[0] |= bcdec__bitstream_read_bit(&bstream) << 10; /* bw[10] */ 940 + mode = 11; 941 + } break; 942 + 943 + /* mode 13 */ 944 + case 0b01011: { 945 + /* Partitition indices: 63 bits 946 + Partition: 0 bits 947 + Color Endpoints: 60 bits (12.8, 12.8, 12.8) */ 948 + r[0] |= bcdec__bitstream_read_bits(&bstream, 10); /* rw[9:0] */ 949 + g[0] |= bcdec__bitstream_read_bits(&bstream, 10); /* gw[9:0] */ 950 + b[0] |= bcdec__bitstream_read_bits(&bstream, 10); /* bw[9:0] */ 951 + r[1] |= bcdec__bitstream_read_bits(&bstream, 8); /* rx[7:0] */ 952 + r[0] |= bcdec__bitstream_read_bits_r(&bstream, 2) << 10;/* rx[10:11] */ 953 + g[1] |= bcdec__bitstream_read_bits(&bstream, 8); /* gx[7:0] */ 954 + g[0] |= bcdec__bitstream_read_bits_r(&bstream, 2) << 10;/* gx[10:11] */ 955 + b[1] |= bcdec__bitstream_read_bits(&bstream, 8); /* bx[7:0] */ 956 + b[0] |= bcdec__bitstream_read_bits_r(&bstream, 2) << 10;/* bx[10:11] */ 957 + mode = 12; 958 + } break; 959 + 960 + /* mode 14 */ 961 + case 0b01111: { 962 + /* Partitition indices: 63 bits 963 + Partition: 0 bits 964 + Color Endpoints: 60 bits (16.4, 16.4, 16.4) */ 965 + r[0] |= bcdec__bitstream_read_bits(&bstream, 10); /* rw[9:0] */ 966 + g[0] |= bcdec__bitstream_read_bits(&bstream, 10); /* gw[9:0] */ 967 + b[0] |= bcdec__bitstream_read_bits(&bstream, 10); /* bw[9:0] */ 968 + r[1] |= bcdec__bitstream_read_bits(&bstream, 4); /* rx[3:0] */ 969 + r[0] |= bcdec__bitstream_read_bits_r(&bstream, 6) << 10;/* rw[10:15] */ 970 + g[1] |= bcdec__bitstream_read_bits(&bstream, 4); /* gx[3:0] */ 971 + g[0] |= bcdec__bitstream_read_bits_r(&bstream, 6) << 10;/* gw[10:15] */ 972 + b[1] |= bcdec__bitstream_read_bits(&bstream, 4); /* bx[3:0] */ 973 + b[0] |= bcdec__bitstream_read_bits_r(&bstream, 6) << 10;/* bw[10:15] */ 974 + mode = 13; 975 + } break; 976 + 977 + default: { 978 + /* Modes 10011, 10111, 11011, and 11111 (not shown) are reserved. 979 + Do not use these in your encoder. If the hardware is passed blocks 980 + with one of these modes specified, the resulting decompressed block 981 + must contain all zeroes in all channels except for the alpha channel. */ 982 + for (i = 0; i < 4; ++i) { 983 + for (j = 0; j < 4; ++j) { 984 + decompressed[j * 3 + 0] = 0; 985 + decompressed[j * 3 + 1] = 0; 986 + decompressed[j * 3 + 2] = 0; 987 + } 988 + decompressed += destinationPitch; 989 + } 990 + 991 + return; 992 + } 993 + } 994 + 995 + numPartitions = (mode >= 10) ? 0 : 1; 996 + 997 + actualBits0Mode = actual_bits_count[0][mode]; 998 + if (isSigned) { 999 + r[0] = bcdec__extend_sign(r[0], actualBits0Mode); 1000 + g[0] = bcdec__extend_sign(g[0], actualBits0Mode); 1001 + b[0] = bcdec__extend_sign(b[0], actualBits0Mode); 1002 + } 1003 + 1004 + /* Mode 11 (like Mode 10) does not use delta compression, 1005 + and instead stores both color endpoints explicitly. */ 1006 + if ((mode != 9 && mode != 10) || isSigned) { 1007 + for (i = 1; i < (numPartitions + 1) * 2; ++i) { 1008 + r[i] = bcdec__extend_sign(r[i], actual_bits_count[1][mode]); 1009 + g[i] = bcdec__extend_sign(g[i], actual_bits_count[2][mode]); 1010 + b[i] = bcdec__extend_sign(b[i], actual_bits_count[3][mode]); 1011 + } 1012 + } 1013 + 1014 + if (mode != 9 && mode != 10) { 1015 + for (i = 1; i < (numPartitions + 1) * 2; ++i) { 1016 + r[i] = bcdec__transform_inverse(r[i], r[0], actualBits0Mode, isSigned); 1017 + g[i] = bcdec__transform_inverse(g[i], g[0], actualBits0Mode, isSigned); 1018 + b[i] = bcdec__transform_inverse(b[i], b[0], actualBits0Mode, isSigned); 1019 + } 1020 + } 1021 + 1022 + for (i = 0; i < (numPartitions + 1) * 2; ++i) { 1023 + r[i] = bcdec__unquantize(r[i], actualBits0Mode, isSigned); 1024 + g[i] = bcdec__unquantize(g[i], actualBits0Mode, isSigned); 1025 + b[i] = bcdec__unquantize(b[i], actualBits0Mode, isSigned); 1026 + } 1027 + 1028 + weights = (mode >= 10) ? aWeight4 : aWeight3; 1029 + for (i = 0; i < 4; ++i) { 1030 + for (j = 0; j < 4; ++j) { 1031 + partitionSet = (mode >= 10) ? ((i|j) ? 0 : 128) : partition_sets[partition][i][j]; 1032 + 1033 + indexBits = (mode >= 10) ? 4 : 3; 1034 + /* fix-up index is specified with one less bit */ 1035 + /* The fix-up index for subset 0 is always index 0 */ 1036 + if (partitionSet & 0x80) { 1037 + indexBits--; 1038 + } 1039 + partitionSet &= 0x01; 1040 + 1041 + index = bcdec__bitstream_read_bits(&bstream, indexBits); 1042 + 1043 + ep_i = partitionSet * 2; 1044 + decompressed[j * 3 + 0] = bcdec__finish_unquantize( 1045 + bcdec__interpolate(r[ep_i], r[ep_i+1], weights, index), isSigned); 1046 + decompressed[j * 3 + 1] = bcdec__finish_unquantize( 1047 + bcdec__interpolate(g[ep_i], g[ep_i+1], weights, index), isSigned); 1048 + decompressed[j * 3 + 2] = bcdec__finish_unquantize( 1049 + bcdec__interpolate(b[ep_i], b[ep_i+1], weights, index), isSigned); 1050 + } 1051 + 1052 + decompressed += destinationPitch; 1053 + } 1054 + } 1055 + 1056 + BCDECDEF void bcdec_bc6h_float(const void* compressedBlock, void* decompressedBlock, int destinationPitch, int isSigned) { 1057 + unsigned short block[16*3]; 1058 + float* decompressed; 1059 + const unsigned short* b; 1060 + int i, j; 1061 + 1062 + bcdec_bc6h_half(compressedBlock, block, 4*3, isSigned); 1063 + b = block; 1064 + decompressed = (float*)decompressedBlock; 1065 + for (i = 0; i < 4; ++i) { 1066 + for (j = 0; j < 4; ++j) { 1067 + decompressed[j * 3 + 0] = bcdec__half_to_float_quick(*b++); 1068 + decompressed[j * 3 + 1] = bcdec__half_to_float_quick(*b++); 1069 + decompressed[j * 3 + 2] = bcdec__half_to_float_quick(*b++); 1070 + } 1071 + decompressed += destinationPitch; 1072 + } 1073 + } 1074 + 1075 + static void bcdec__swap_values(int* a, int* b) { 1076 + a[0] ^= b[0], b[0] ^= a[0], a[0] ^= b[0]; 1077 + } 1078 + 1079 + BCDECDEF void bcdec_bc7(const void* compressedBlock, void* decompressedBlock, int destinationPitch) { 1080 + static char actual_bits_count[2][8] = { 1081 + { 4, 6, 5, 7, 5, 7, 7, 5 }, /* RGBA */ 1082 + { 0, 0, 0, 0, 6, 8, 7, 5 }, /* Alpha */ 1083 + }; 1084 + 1085 + /* There are 64 possible partition sets for a two-region tile. 1086 + Each 4x4 block represents a single shape. 1087 + Here also every fix-up index has MSB bit set. */ 1088 + static unsigned char partition_sets[2][64][4][4] = { 1089 + { /* Partition table for 2-subset BPTC */ 1090 + { {128, 0, 1, 1}, {0, 0, 1, 1}, { 0, 0, 1, 1}, {0, 0, 1, 129} }, /* 0 */ 1091 + { {128, 0, 0, 1}, {0, 0, 0, 1}, { 0, 0, 0, 1}, {0, 0, 0, 129} }, /* 1 */ 1092 + { {128, 1, 1, 1}, {0, 1, 1, 1}, { 0, 1, 1, 1}, {0, 1, 1, 129} }, /* 2 */ 1093 + { {128, 0, 0, 1}, {0, 0, 1, 1}, { 0, 0, 1, 1}, {0, 1, 1, 129} }, /* 3 */ 1094 + { {128, 0, 0, 0}, {0, 0, 0, 1}, { 0, 0, 0, 1}, {0, 0, 1, 129} }, /* 4 */ 1095 + { {128, 0, 1, 1}, {0, 1, 1, 1}, { 0, 1, 1, 1}, {1, 1, 1, 129} }, /* 5 */ 1096 + { {128, 0, 0, 1}, {0, 0, 1, 1}, { 0, 1, 1, 1}, {1, 1, 1, 129} }, /* 6 */ 1097 + { {128, 0, 0, 0}, {0, 0, 0, 1}, { 0, 0, 1, 1}, {0, 1, 1, 129} }, /* 7 */ 1098 + { {128, 0, 0, 0}, {0, 0, 0, 0}, { 0, 0, 0, 1}, {0, 0, 1, 129} }, /* 8 */ 1099 + { {128, 0, 1, 1}, {0, 1, 1, 1}, { 1, 1, 1, 1}, {1, 1, 1, 129} }, /* 9 */ 1100 + { {128, 0, 0, 0}, {0, 0, 0, 1}, { 0, 1, 1, 1}, {1, 1, 1, 129} }, /* 10 */ 1101 + { {128, 0, 0, 0}, {0, 0, 0, 0}, { 0, 0, 0, 1}, {0, 1, 1, 129} }, /* 11 */ 1102 + { {128, 0, 0, 1}, {0, 1, 1, 1}, { 1, 1, 1, 1}, {1, 1, 1, 129} }, /* 12 */ 1103 + { {128, 0, 0, 0}, {0, 0, 0, 0}, { 1, 1, 1, 1}, {1, 1, 1, 129} }, /* 13 */ 1104 + { {128, 0, 0, 0}, {1, 1, 1, 1}, { 1, 1, 1, 1}, {1, 1, 1, 129} }, /* 14 */ 1105 + { {128, 0, 0, 0}, {0, 0, 0, 0}, { 0, 0, 0, 0}, {1, 1, 1, 129} }, /* 15 */ 1106 + { {128, 0, 0, 0}, {1, 0, 0, 0}, { 1, 1, 1, 0}, {1, 1, 1, 129} }, /* 16 */ 1107 + { {128, 1, 129, 1}, {0, 0, 0, 1}, { 0, 0, 0, 0}, {0, 0, 0, 0} }, /* 17 */ 1108 + { {128, 0, 0, 0}, {0, 0, 0, 0}, {129, 0, 0, 0}, {1, 1, 1, 0} }, /* 18 */ 1109 + { {128, 1, 129, 1}, {0, 0, 1, 1}, { 0, 0, 0, 1}, {0, 0, 0, 0} }, /* 19 */ 1110 + { {128, 0, 129, 1}, {0, 0, 0, 1}, { 0, 0, 0, 0}, {0, 0, 0, 0} }, /* 20 */ 1111 + { {128, 0, 0, 0}, {1, 0, 0, 0}, {129, 1, 0, 0}, {1, 1, 1, 0} }, /* 21 */ 1112 + { {128, 0, 0, 0}, {0, 0, 0, 0}, {129, 0, 0, 0}, {1, 1, 0, 0} }, /* 22 */ 1113 + { {128, 1, 1, 1}, {0, 0, 1, 1}, { 0, 0, 1, 1}, {0, 0, 0, 129} }, /* 23 */ 1114 + { {128, 0, 129, 1}, {0, 0, 0, 1}, { 0, 0, 0, 1}, {0, 0, 0, 0} }, /* 24 */ 1115 + { {128, 0, 0, 0}, {1, 0, 0, 0}, {129, 0, 0, 0}, {1, 1, 0, 0} }, /* 25 */ 1116 + { {128, 1, 129, 0}, {0, 1, 1, 0}, { 0, 1, 1, 0}, {0, 1, 1, 0} }, /* 26 */ 1117 + { {128, 0, 129, 1}, {0, 1, 1, 0}, { 0, 1, 1, 0}, {1, 1, 0, 0} }, /* 27 */ 1118 + { {128, 0, 0, 1}, {0, 1, 1, 1}, {129, 1, 1, 0}, {1, 0, 0, 0} }, /* 28 */ 1119 + { {128, 0, 0, 0}, {1, 1, 1, 1}, {129, 1, 1, 1}, {0, 0, 0, 0} }, /* 29 */ 1120 + { {128, 1, 129, 1}, {0, 0, 0, 1}, { 1, 0, 0, 0}, {1, 1, 1, 0} }, /* 30 */ 1121 + { {128, 0, 129, 1}, {1, 0, 0, 1}, { 1, 0, 0, 1}, {1, 1, 0, 0} }, /* 31 */ 1122 + { {128, 1, 0, 1}, {0, 1, 0, 1}, { 0, 1, 0, 1}, {0, 1, 0, 129} }, /* 32 */ 1123 + { {128, 0, 0, 0}, {1, 1, 1, 1}, { 0, 0, 0, 0}, {1, 1, 1, 129} }, /* 33 */ 1124 + { {128, 1, 0, 1}, {1, 0, 129, 0}, { 0, 1, 0, 1}, {1, 0, 1, 0} }, /* 34 */ 1125 + { {128, 0, 1, 1}, {0, 0, 1, 1}, {129, 1, 0, 0}, {1, 1, 0, 0} }, /* 35 */ 1126 + { {128, 0, 129, 1}, {1, 1, 0, 0}, { 0, 0, 1, 1}, {1, 1, 0, 0} }, /* 36 */ 1127 + { {128, 1, 0, 1}, {0, 1, 0, 1}, {129, 0, 1, 0}, {1, 0, 1, 0} }, /* 37 */ 1128 + { {128, 1, 1, 0}, {1, 0, 0, 1}, { 0, 1, 1, 0}, {1, 0, 0, 129} }, /* 38 */ 1129 + { {128, 1, 0, 1}, {1, 0, 1, 0}, { 1, 0, 1, 0}, {0, 1, 0, 129} }, /* 39 */ 1130 + { {128, 1, 129, 1}, {0, 0, 1, 1}, { 1, 1, 0, 0}, {1, 1, 1, 0} }, /* 40 */ 1131 + { {128, 0, 0, 1}, {0, 0, 1, 1}, {129, 1, 0, 0}, {1, 0, 0, 0} }, /* 41 */ 1132 + { {128, 0, 129, 1}, {0, 0, 1, 0}, { 0, 1, 0, 0}, {1, 1, 0, 0} }, /* 42 */ 1133 + { {128, 0, 129, 1}, {1, 0, 1, 1}, { 1, 1, 0, 1}, {1, 1, 0, 0} }, /* 43 */ 1134 + { {128, 1, 129, 0}, {1, 0, 0, 1}, { 1, 0, 0, 1}, {0, 1, 1, 0} }, /* 44 */ 1135 + { {128, 0, 1, 1}, {1, 1, 0, 0}, { 1, 1, 0, 0}, {0, 0, 1, 129} }, /* 45 */ 1136 + { {128, 1, 1, 0}, {0, 1, 1, 0}, { 1, 0, 0, 1}, {1, 0, 0, 129} }, /* 46 */ 1137 + { {128, 0, 0, 0}, {0, 1, 129, 0}, { 0, 1, 1, 0}, {0, 0, 0, 0} }, /* 47 */ 1138 + { {128, 1, 0, 0}, {1, 1, 129, 0}, { 0, 1, 0, 0}, {0, 0, 0, 0} }, /* 48 */ 1139 + { {128, 0, 129, 0}, {0, 1, 1, 1}, { 0, 0, 1, 0}, {0, 0, 0, 0} }, /* 49 */ 1140 + { {128, 0, 0, 0}, {0, 0, 129, 0}, { 0, 1, 1, 1}, {0, 0, 1, 0} }, /* 50 */ 1141 + { {128, 0, 0, 0}, {0, 1, 0, 0}, {129, 1, 1, 0}, {0, 1, 0, 0} }, /* 51 */ 1142 + { {128, 1, 1, 0}, {1, 1, 0, 0}, { 1, 0, 0, 1}, {0, 0, 1, 129} }, /* 52 */ 1143 + { {128, 0, 1, 1}, {0, 1, 1, 0}, { 1, 1, 0, 0}, {1, 0, 0, 129} }, /* 53 */ 1144 + { {128, 1, 129, 0}, {0, 0, 1, 1}, { 1, 0, 0, 1}, {1, 1, 0, 0} }, /* 54 */ 1145 + { {128, 0, 129, 1}, {1, 0, 0, 1}, { 1, 1, 0, 0}, {0, 1, 1, 0} }, /* 55 */ 1146 + { {128, 1, 1, 0}, {1, 1, 0, 0}, { 1, 1, 0, 0}, {1, 0, 0, 129} }, /* 56 */ 1147 + { {128, 1, 1, 0}, {0, 0, 1, 1}, { 0, 0, 1, 1}, {1, 0, 0, 129} }, /* 57 */ 1148 + { {128, 1, 1, 1}, {1, 1, 1, 0}, { 1, 0, 0, 0}, {0, 0, 0, 129} }, /* 58 */ 1149 + { {128, 0, 0, 1}, {1, 0, 0, 0}, { 1, 1, 1, 0}, {0, 1, 1, 129} }, /* 59 */ 1150 + { {128, 0, 0, 0}, {1, 1, 1, 1}, { 0, 0, 1, 1}, {0, 0, 1, 129} }, /* 60 */ 1151 + { {128, 0, 129, 1}, {0, 0, 1, 1}, { 1, 1, 1, 1}, {0, 0, 0, 0} }, /* 61 */ 1152 + { {128, 0, 129, 0}, {0, 0, 1, 0}, { 1, 1, 1, 0}, {1, 1, 1, 0} }, /* 62 */ 1153 + { {128, 1, 0, 0}, {0, 1, 0, 0}, { 0, 1, 1, 1}, {0, 1, 1, 129} } /* 63 */ 1154 + }, 1155 + { /* Partition table for 3-subset BPTC */ 1156 + { {128, 0, 1, 129}, {0, 0, 1, 1}, { 0, 2, 2, 1}, { 2, 2, 2, 130} }, /* 0 */ 1157 + { {128, 0, 0, 129}, {0, 0, 1, 1}, {130, 2, 1, 1}, { 2, 2, 2, 1} }, /* 1 */ 1158 + { {128, 0, 0, 0}, {2, 0, 0, 1}, {130, 2, 1, 1}, { 2, 2, 1, 129} }, /* 2 */ 1159 + { {128, 2, 2, 130}, {0, 0, 2, 2}, { 0, 0, 1, 1}, { 0, 1, 1, 129} }, /* 3 */ 1160 + { {128, 0, 0, 0}, {0, 0, 0, 0}, {129, 1, 2, 2}, { 1, 1, 2, 130} }, /* 4 */ 1161 + { {128, 0, 1, 129}, {0, 0, 1, 1}, { 0, 0, 2, 2}, { 0, 0, 2, 130} }, /* 5 */ 1162 + { {128, 0, 2, 130}, {0, 0, 2, 2}, { 1, 1, 1, 1}, { 1, 1, 1, 129} }, /* 6 */ 1163 + { {128, 0, 1, 1}, {0, 0, 1, 1}, {130, 2, 1, 1}, { 2, 2, 1, 129} }, /* 7 */ 1164 + { {128, 0, 0, 0}, {0, 0, 0, 0}, {129, 1, 1, 1}, { 2, 2, 2, 130} }, /* 8 */ 1165 + { {128, 0, 0, 0}, {1, 1, 1, 1}, {129, 1, 1, 1}, { 2, 2, 2, 130} }, /* 9 */ 1166 + { {128, 0, 0, 0}, {1, 1, 129, 1}, { 2, 2, 2, 2}, { 2, 2, 2, 130} }, /* 10 */ 1167 + { {128, 0, 1, 2}, {0, 0, 129, 2}, { 0, 0, 1, 2}, { 0, 0, 1, 130} }, /* 11 */ 1168 + { {128, 1, 1, 2}, {0, 1, 129, 2}, { 0, 1, 1, 2}, { 0, 1, 1, 130} }, /* 12 */ 1169 + { {128, 1, 2, 2}, {0, 129, 2, 2}, { 0, 1, 2, 2}, { 0, 1, 2, 130} }, /* 13 */ 1170 + { {128, 0, 1, 129}, {0, 1, 1, 2}, { 1, 1, 2, 2}, { 1, 2, 2, 130} }, /* 14 */ 1171 + { {128, 0, 1, 129}, {2, 0, 0, 1}, {130, 2, 0, 0}, { 2, 2, 2, 0} }, /* 15 */ 1172 + { {128, 0, 0, 129}, {0, 0, 1, 1}, { 0, 1, 1, 2}, { 1, 1, 2, 130} }, /* 16 */ 1173 + { {128, 1, 1, 129}, {0, 0, 1, 1}, {130, 0, 0, 1}, { 2, 2, 0, 0} }, /* 17 */ 1174 + { {128, 0, 0, 0}, {1, 1, 2, 2}, {129, 1, 2, 2}, { 1, 1, 2, 130} }, /* 18 */ 1175 + { {128, 0, 2, 130}, {0, 0, 2, 2}, { 0, 0, 2, 2}, { 1, 1, 1, 129} }, /* 19 */ 1176 + { {128, 1, 1, 129}, {0, 1, 1, 1}, { 0, 2, 2, 2}, { 0, 2, 2, 130} }, /* 20 */ 1177 + { {128, 0, 0, 129}, {0, 0, 0, 1}, {130, 2, 2, 1}, { 2, 2, 2, 1} }, /* 21 */ 1178 + { {128, 0, 0, 0}, {0, 0, 129, 1}, { 0, 1, 2, 2}, { 0, 1, 2, 130} }, /* 22 */ 1179 + { {128, 0, 0, 0}, {1, 1, 0, 0}, {130, 2, 129, 0}, { 2, 2, 1, 0} }, /* 23 */ 1180 + { {128, 1, 2, 130}, {0, 129, 2, 2}, { 0, 0, 1, 1}, { 0, 0, 0, 0} }, /* 24 */ 1181 + { {128, 0, 1, 2}, {0, 0, 1, 2}, {129, 1, 2, 2}, { 2, 2, 2, 130} }, /* 25 */ 1182 + { {128, 1, 1, 0}, {1, 2, 130, 1}, {129, 2, 2, 1}, { 0, 1, 1, 0} }, /* 26 */ 1183 + { {128, 0, 0, 0}, {0, 1, 129, 0}, { 1, 2, 130, 1}, { 1, 2, 2, 1} }, /* 27 */ 1184 + { {128, 0, 2, 2}, {1, 1, 0, 2}, {129, 1, 0, 2}, { 0, 0, 2, 130} }, /* 28 */ 1185 + { {128, 1, 1, 0}, {0, 129, 1, 0}, { 2, 0, 0, 2}, { 2, 2, 2, 130} }, /* 29 */ 1186 + { {128, 0, 1, 1}, {0, 1, 2, 2}, { 0, 1, 130, 2}, { 0, 0, 1, 129} }, /* 30 */ 1187 + { {128, 0, 0, 0}, {2, 0, 0, 0}, {130, 2, 1, 1}, { 2, 2, 2, 129} }, /* 31 */ 1188 + { {128, 0, 0, 0}, {0, 0, 0, 2}, {129, 1, 2, 2}, { 1, 2, 2, 130} }, /* 32 */ 1189 + { {128, 2, 2, 130}, {0, 0, 2, 2}, { 0, 0, 1, 2}, { 0, 0, 1, 129} }, /* 33 */ 1190 + { {128, 0, 1, 129}, {0, 0, 1, 2}, { 0, 0, 2, 2}, { 0, 2, 2, 130} }, /* 34 */ 1191 + { {128, 1, 2, 0}, {0, 129, 2, 0}, { 0, 1, 130, 0}, { 0, 1, 2, 0} }, /* 35 */ 1192 + { {128, 0, 0, 0}, {1, 1, 129, 1}, { 2, 2, 130, 2}, { 0, 0, 0, 0} }, /* 36 */ 1193 + { {128, 1, 2, 0}, {1, 2, 0, 1}, {130, 0, 129, 2}, { 0, 1, 2, 0} }, /* 37 */ 1194 + { {128, 1, 2, 0}, {2, 0, 1, 2}, {129, 130, 0, 1}, { 0, 1, 2, 0} }, /* 38 */ 1195 + { {128, 0, 1, 1}, {2, 2, 0, 0}, { 1, 1, 130, 2}, { 0, 0, 1, 129} }, /* 39 */ 1196 + { {128, 0, 1, 1}, {1, 1, 130, 2}, { 2, 2, 0, 0}, { 0, 0, 1, 129} }, /* 40 */ 1197 + { {128, 1, 0, 129}, {0, 1, 0, 1}, { 2, 2, 2, 2}, { 2, 2, 2, 130} }, /* 41 */ 1198 + { {128, 0, 0, 0}, {0, 0, 0, 0}, {130, 1, 2, 1}, { 2, 1, 2, 129} }, /* 42 */ 1199 + { {128, 0, 2, 2}, {1, 129, 2, 2}, { 0, 0, 2, 2}, { 1, 1, 2, 130} }, /* 43 */ 1200 + { {128, 0, 2, 130}, {0, 0, 1, 1}, { 0, 0, 2, 2}, { 0, 0, 1, 129} }, /* 44 */ 1201 + { {128, 2, 2, 0}, {1, 2, 130, 1}, { 0, 2, 2, 0}, { 1, 2, 2, 129} }, /* 45 */ 1202 + { {128, 1, 0, 1}, {2, 2, 130, 2}, { 2, 2, 2, 2}, { 0, 1, 0, 129} }, /* 46 */ 1203 + { {128, 0, 0, 0}, {2, 1, 2, 1}, {130, 1, 2, 1}, { 2, 1, 2, 129} }, /* 47 */ 1204 + { {128, 1, 0, 129}, {0, 1, 0, 1}, { 0, 1, 0, 1}, { 2, 2, 2, 130} }, /* 48 */ 1205 + { {128, 2, 2, 130}, {0, 1, 1, 1}, { 0, 2, 2, 2}, { 0, 1, 1, 129} }, /* 49 */ 1206 + { {128, 0, 0, 2}, {1, 129, 1, 2}, { 0, 0, 0, 2}, { 1, 1, 1, 130} }, /* 50 */ 1207 + { {128, 0, 0, 0}, {2, 129, 1, 2}, { 2, 1, 1, 2}, { 2, 1, 1, 130} }, /* 51 */ 1208 + { {128, 2, 2, 2}, {0, 129, 1, 1}, { 0, 1, 1, 1}, { 0, 2, 2, 130} }, /* 52 */ 1209 + { {128, 0, 0, 2}, {1, 1, 1, 2}, {129, 1, 1, 2}, { 0, 0, 0, 130} }, /* 53 */ 1210 + { {128, 1, 1, 0}, {0, 129, 1, 0}, { 0, 1, 1, 0}, { 2, 2, 2, 130} }, /* 54 */ 1211 + { {128, 0, 0, 0}, {0, 0, 0, 0}, { 2, 1, 129, 2}, { 2, 1, 1, 130} }, /* 55 */ 1212 + { {128, 1, 1, 0}, {0, 129, 1, 0}, { 2, 2, 2, 2}, { 2, 2, 2, 130} }, /* 56 */ 1213 + { {128, 0, 2, 2}, {0, 0, 1, 1}, { 0, 0, 129, 1}, { 0, 0, 2, 130} }, /* 57 */ 1214 + { {128, 0, 2, 2}, {1, 1, 2, 2}, {129, 1, 2, 2}, { 0, 0, 2, 130} }, /* 58 */ 1215 + { {128, 0, 0, 0}, {0, 0, 0, 0}, { 0, 0, 0, 0}, { 2, 129, 1, 130} }, /* 59 */ 1216 + { {128, 0, 0, 130}, {0, 0, 0, 1}, { 0, 0, 0, 2}, { 0, 0, 0, 129} }, /* 60 */ 1217 + { {128, 2, 2, 2}, {1, 2, 2, 2}, { 0, 2, 2, 2}, {129, 2, 2, 130} }, /* 61 */ 1218 + { {128, 1, 0, 129}, {2, 2, 2, 2}, { 2, 2, 2, 2}, { 2, 2, 2, 130} }, /* 62 */ 1219 + { {128, 1, 1, 129}, {2, 0, 1, 1}, {130, 2, 0, 1}, { 2, 2, 2, 0} } /* 63 */ 1220 + } 1221 + }; 1222 + 1223 + static int aWeight2[] = { 0, 21, 43, 64 }; 1224 + static int aWeight3[] = { 0, 9, 18, 27, 37, 46, 55, 64 }; 1225 + static int aWeight4[] = { 0, 4, 9, 13, 17, 21, 26, 30, 34, 38, 43, 47, 51, 55, 60, 64 }; 1226 + 1227 + static unsigned char sModeHasPBits = 0b11001011; 1228 + 1229 + bcdec__bitstream_t bstream; 1230 + int mode, partition, numPartitions, numEndpoints, i, j, k, rotation, partitionSet; 1231 + int indexSelectionBit, indexBits, indexBits2, index, index2; 1232 + int endpoints[6][4]; 1233 + char indices[4][4]; 1234 + int r, g, b, a; 1235 + int* weights, * weights2; 1236 + unsigned char* decompressed; 1237 + 1238 + decompressed = (unsigned char*)decompressedBlock; 1239 + 1240 + bstream.low = ((unsigned long long*)compressedBlock)[0]; 1241 + bstream.high = ((unsigned long long*)compressedBlock)[1]; 1242 + 1243 + for (mode = 0; mode < 8 && (0 == bcdec__bitstream_read_bit(&bstream)); ++mode); 1244 + 1245 + /* unexpected mode, clear the block (transparent black) */ 1246 + if (mode >= 8) { 1247 + for (i = 0; i < 4; ++i) { 1248 + for (j = 0; j < 4; ++j) { 1249 + decompressed[j * 4 + 0] = 0; 1250 + decompressed[j * 4 + 1] = 0; 1251 + decompressed[j * 4 + 2] = 0; 1252 + decompressed[j * 4 + 3] = 0; 1253 + } 1254 + decompressed += destinationPitch; 1255 + } 1256 + 1257 + return; 1258 + } 1259 + 1260 + partition = 0; 1261 + numPartitions = 1; 1262 + rotation = 0; 1263 + indexSelectionBit = 0; 1264 + 1265 + if (mode == 0 || mode == 1 || mode == 2 || mode == 3 || mode == 7) { 1266 + numPartitions = (mode == 0 || mode == 2) ? 3 : 2; 1267 + partition = bcdec__bitstream_read_bits(&bstream, (mode == 0) ? 4 : 6); 1268 + } 1269 + 1270 + numEndpoints = numPartitions * 2; 1271 + 1272 + if (mode == 4 || mode == 5) { 1273 + rotation = bcdec__bitstream_read_bits(&bstream, 2); 1274 + 1275 + if (mode == 4) { 1276 + indexSelectionBit = bcdec__bitstream_read_bit(&bstream); 1277 + } 1278 + } 1279 + 1280 + /* Extract endpoints */ 1281 + /* RGB */ 1282 + for (i = 0; i < 3; ++i) { 1283 + for (j = 0; j < numEndpoints; ++j) { 1284 + endpoints[j][i] = bcdec__bitstream_read_bits(&bstream, actual_bits_count[0][mode]); 1285 + } 1286 + } 1287 + /* Alpha (if any) */ 1288 + if (actual_bits_count[1][mode] > 0) { 1289 + for (j = 0; j < numEndpoints; ++j) { 1290 + endpoints[j][3] = bcdec__bitstream_read_bits(&bstream, actual_bits_count[1][mode]); 1291 + } 1292 + } 1293 + 1294 + /* Fully decode endpoints */ 1295 + /* First handle modes that have P-bits */ 1296 + if (mode == 0 || mode == 1 || mode == 3 || mode == 6 || mode == 7) { 1297 + for (i = 0; i < numEndpoints; ++i) { 1298 + /* component-wise left-shift */ 1299 + for (j = 0; j < 4; ++j) { 1300 + endpoints[i][j] <<= 1; 1301 + } 1302 + } 1303 + 1304 + /* if P-bit is shared */ 1305 + if (mode == 1) { 1306 + i = bcdec__bitstream_read_bit(&bstream); 1307 + j = bcdec__bitstream_read_bit(&bstream); 1308 + 1309 + /* rgb component-wise insert pbits */ 1310 + for (k = 0; k < 3; ++k) { 1311 + endpoints[0][k] |= i; 1312 + endpoints[1][k] |= i; 1313 + endpoints[2][k] |= j; 1314 + endpoints[3][k] |= j; 1315 + } 1316 + } else if (sModeHasPBits & (1 << mode)) { 1317 + /* unique P-bit per endpoint */ 1318 + for (i = 0; i < numEndpoints; ++i) { 1319 + j = bcdec__bitstream_read_bit(&bstream); 1320 + for (k = 0; k < 4; ++k) { 1321 + endpoints[i][k] |= j; 1322 + } 1323 + } 1324 + } 1325 + } 1326 + 1327 + for (i = 0; i < numEndpoints; ++i) { 1328 + /* get color components precision including pbit */ 1329 + j = actual_bits_count[0][mode] + ((sModeHasPBits >> mode) & 1); 1330 + 1331 + for (k = 0; k < 3; ++k) { 1332 + /* left shift endpoint components so that their MSB lies in bit 7 */ 1333 + endpoints[i][k] = endpoints[i][k] << (8 - j); 1334 + /* Replicate each component's MSB into the LSBs revealed by the left-shift operation above */ 1335 + endpoints[i][k] = endpoints[i][k] | (endpoints[i][k] >> j); 1336 + } 1337 + 1338 + /* get alpha component precision including pbit */ 1339 + j = actual_bits_count[1][mode] + ((sModeHasPBits >> mode) & 1); 1340 + 1341 + /* left shift endpoint components so that their MSB lies in bit 7 */ 1342 + endpoints[i][3] = endpoints[i][3] << (8 - j); 1343 + /* Replicate each component's MSB into the LSBs revealed by the left-shift operation above */ 1344 + endpoints[i][3] = endpoints[i][3] | (endpoints[i][3] >> j); 1345 + } 1346 + 1347 + /* If this mode does not explicitly define the alpha component */ 1348 + /* set alpha equal to 1.0 */ 1349 + if (!actual_bits_count[1][mode]) { 1350 + for (j = 0; j < numEndpoints; ++j) { 1351 + endpoints[j][3] = 0xFF; 1352 + } 1353 + } 1354 + 1355 + /* Determine weights tables */ 1356 + indexBits = (mode == 0 || mode == 1) ? 3 : ((mode == 6) ? 4 : 2); 1357 + indexBits2 = (mode == 4) ? 3 : ((mode == 5) ? 2 : 0); 1358 + weights = (indexBits == 2) ? aWeight2 : ((indexBits == 3) ? aWeight3 : aWeight4); 1359 + weights2 = (indexBits2 == 2) ? aWeight2 : aWeight3; 1360 + 1361 + /* Quite inconvenient that indices aren't interleaved so we have to make 2 passes here */ 1362 + /* Pass #1: collecting color indices */ 1363 + for (i = 0; i < 4; ++i) { 1364 + for (j = 0; j < 4; ++j) { 1365 + partitionSet = (numPartitions == 1) ? ((i | j) ? 0 : 128) : partition_sets[numPartitions - 2][partition][i][j]; 1366 + 1367 + indexBits = (mode == 0 || mode == 1) ? 3 : ((mode == 6) ? 4 : 2); 1368 + /* fix-up index is specified with one less bit */ 1369 + /* The fix-up index for subset 0 is always index 0 */ 1370 + if (partitionSet & 0x80) { 1371 + indexBits--; 1372 + } 1373 + 1374 + indices[i][j] = bcdec__bitstream_read_bits(&bstream, indexBits); 1375 + } 1376 + } 1377 + 1378 + /* Pass #2: reading alpha indices (if any) and interpolating & rotating */ 1379 + for (i = 0; i < 4; ++i) { 1380 + for (j = 0; j < 4; ++j) { 1381 + partitionSet = (numPartitions == 1) ? ((i|j) ? 0 : 128) : partition_sets[numPartitions - 2][partition][i][j]; 1382 + partitionSet &= 0x03; 1383 + 1384 + index = indices[i][j]; 1385 + 1386 + if (!indexBits2) { 1387 + r = bcdec__interpolate(endpoints[partitionSet * 2][0], endpoints[partitionSet * 2 + 1][0], weights, index); 1388 + g = bcdec__interpolate(endpoints[partitionSet * 2][1], endpoints[partitionSet * 2 + 1][1], weights, index); 1389 + b = bcdec__interpolate(endpoints[partitionSet * 2][2], endpoints[partitionSet * 2 + 1][2], weights, index); 1390 + a = bcdec__interpolate(endpoints[partitionSet * 2][3], endpoints[partitionSet * 2 + 1][3], weights, index); 1391 + } else { 1392 + index2 = bcdec__bitstream_read_bits(&bstream, (i|j) ? indexBits2 : (indexBits2 - 1)); 1393 + /* The index value for interpolating color comes from the secondary index bits for the texel 1394 + if the mode has an index selection bit and its value is one, and from the primary index bits otherwise. 1395 + The alpha index comes from the secondary index bits if the block has a secondary index and 1396 + the block either doesn’t have an index selection bit or that bit is zero, and from the primary index bits otherwise. */ 1397 + if (!indexSelectionBit) { 1398 + r = bcdec__interpolate(endpoints[partitionSet * 2][0], endpoints[partitionSet * 2 + 1][0], weights, index); 1399 + g = bcdec__interpolate(endpoints[partitionSet * 2][1], endpoints[partitionSet * 2 + 1][1], weights, index); 1400 + b = bcdec__interpolate(endpoints[partitionSet * 2][2], endpoints[partitionSet * 2 + 1][2], weights, index); 1401 + a = bcdec__interpolate(endpoints[partitionSet * 2][3], endpoints[partitionSet * 2 + 1][3], weights2, index2); 1402 + } else { 1403 + r = bcdec__interpolate(endpoints[partitionSet * 2][0], endpoints[partitionSet * 2 + 1][0], weights2, index2); 1404 + g = bcdec__interpolate(endpoints[partitionSet * 2][1], endpoints[partitionSet * 2 + 1][1], weights2, index2); 1405 + b = bcdec__interpolate(endpoints[partitionSet * 2][2], endpoints[partitionSet * 2 + 1][2], weights2, index2); 1406 + a = bcdec__interpolate(endpoints[partitionSet * 2][3], endpoints[partitionSet * 2 + 1][3], weights, index); 1407 + } 1408 + } 1409 + 1410 + switch (rotation) { 1411 + case 1: { /* 01 – Block format is Scalar(R) Vector(AGB) - swap A and R */ 1412 + bcdec__swap_values(&a, &r); 1413 + } break; 1414 + case 2: { /* 10 – Block format is Scalar(G) Vector(RAB) - swap A and G */ 1415 + bcdec__swap_values(&a, &g); 1416 + } break; 1417 + case 3: { /* 11 - Block format is Scalar(B) Vector(RGA) - swap A and B */ 1418 + bcdec__swap_values(&a, &b); 1419 + } break; 1420 + } 1421 + 1422 + decompressed[j * 4 + 0] = r; 1423 + decompressed[j * 4 + 1] = g; 1424 + decompressed[j * 4 + 2] = b; 1425 + decompressed[j * 4 + 3] = a; 1426 + } 1427 + 1428 + decompressed += destinationPitch; 1429 + } 1430 + } 1431 + 1432 + #endif /* BCDEC_IMPLEMENTATION */ 1433 + 1434 + /* LICENSE: 1435 + 1436 + This software is available under 2 licenses -- choose whichever you prefer. 1437 + 1438 + ------------------------------------------------------------------------------ 1439 + ALTERNATIVE A - MIT License 1440 + 1441 + Copyright (c) 2022 Sergii Kudlai 1442 + 1443 + Permission is hereby granted, free of charge, to any person obtaining a copy of 1444 + this software and associated documentation files (the "Software"), to deal in 1445 + the Software without restriction, including without limitation the rights to 1446 + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 1447 + of the Software, and to permit persons to whom the Software is furnished to do 1448 + so, subject to the following conditions: 1449 + 1450 + The above copyright notice and this permission notice shall be included in all 1451 + copies or substantial portions of the Software. 1452 + 1453 + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 1454 + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 1455 + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 1456 + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 1457 + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 1458 + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 1459 + SOFTWARE. 1460 + 1461 + ------------------------------------------------------------------------------ 1462 + ALTERNATIVE B - The Unlicense 1463 + 1464 + This is free and unencumbered software released into the public domain. 1465 + 1466 + Anyone is free to copy, modify, publish, use, compile, sell, or 1467 + distribute this software, either in source code form or as a compiled 1468 + binary, for any purpose, commercial or non-commercial, and by any 1469 + means. 1470 + 1471 + In jurisdictions that recognize copyright laws, the author or authors 1472 + of this software dedicate any and all copyright interest in the 1473 + software to the public domain. We make this dedication for the benefit 1474 + of the public at large and to the detriment of our heirs and 1475 + successors. We intend this dedication to be an overt act of 1476 + relinquishment in perpetuity of all present and future rights to this 1477 + software under copyright law. 1478 + 1479 + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 1480 + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 1481 + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 1482 + IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 1483 + OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 1484 + ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 1485 + OTHER DEALINGS IN THE SOFTWARE. 1486 + 1487 + For more information, please refer to <https://unlicense.org> 1488 + 1489 + */