The open source OpenXR runtime
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
102BCDECDEF void bcdec_bc1(const void* compressedBlock, void* decompressedBlock, int destinationPitch);
103BCDECDEF void bcdec_bc2(const void* compressedBlock, void* decompressedBlock, int destinationPitch);
104BCDECDEF void bcdec_bc3(const void* compressedBlock, void* decompressedBlock, int destinationPitch);
105#ifndef BCDEC_BC4BC5_PRECISE
106BCDECDEF void bcdec_bc4(const void* compressedBlock, void* decompressedBlock, int destinationPitch);
107BCDECDEF void bcdec_bc5(const void* compressedBlock, void* decompressedBlock, int destinationPitch);
108#else
109BCDECDEF void bcdec_bc4(const void* compressedBlock, void* decompressedBlock, int destinationPitch, int isSigned);
110BCDECDEF void bcdec_bc5(const void* compressedBlock, void* decompressedBlock, int destinationPitch, int isSigned);
111BCDECDEF void bcdec_bc4_float(const void* compressedBlock, void* decompressedBlock, int destinationPitch, int isSigned);
112BCDECDEF void bcdec_bc5_float(const void* compressedBlock, void* decompressedBlock, int destinationPitch, int isSigned);
113#endif
114BCDECDEF void bcdec_bc6h_float(const void* compressedBlock, void* decompressedBlock, int destinationPitch, int isSigned);
115BCDECDEF void bcdec_bc6h_half(const void* compressedBlock, void* decompressedBlock, int destinationPitch, int isSigned);
116BCDECDEF void bcdec_bc7(const void* compressedBlock, void* decompressedBlock, int destinationPitch);
117
118#endif /* BCDEC_HEADER_INCLUDED */
119
120#ifdef BCDEC_IMPLEMENTATION
121
122static 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
191static 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
208static 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
251static 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
313static 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
361typedef struct bcdec__bitstream {
362 unsigned long long low;
363 unsigned long long high;
364} bcdec__bitstream_t;
365
366static 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
379static 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 ??? */
385static 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
399BCDECDEF void bcdec_bc1(const void* compressedBlock, void* decompressedBlock, int destinationPitch) {
400 bcdec__color_block(compressedBlock, decompressedBlock, destinationPitch, 0);
401}
402
403BCDECDEF 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
408BCDECDEF 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
414BCDECDEF void bcdec_bc4(const void* compressedBlock, void* decompressedBlock, int destinationPitch) {
415 bcdec__smooth_alpha_block(compressedBlock, decompressedBlock, destinationPitch, 1);
416#else
417BCDECDEF 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
423BCDECDEF 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
427BCDECDEF 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
434BCDECDEF 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
438BCDECDEF 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 */
445static int bcdec__extend_sign(int val, int bits) {
446 return (val << (32 - bits)) >> (32 - bits);
447}
448
449static 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 */
460static 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
498static int bcdec__interpolate(int a, int b, int* weights, int index) {
499 return (a * (64 - weights[index]) + b * weights[index] + 32) >> 6;
500}
501
502static 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 */
519static 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
546BCDECDEF 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
1056BCDECDEF 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
1075static void bcdec__swap_values(int* a, int* b) {
1076 a[0] ^= b[0], b[0] ^= a[0], a[0] ^= b[0];
1077}
1078
1079BCDECDEF 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
1436This software is available under 2 licenses -- choose whichever you prefer.
1437
1438------------------------------------------------------------------------------
1439ALTERNATIVE A - MIT License
1440
1441Copyright (c) 2022 Sergii Kudlai
1442
1443Permission is hereby granted, free of charge, to any person obtaining a copy of
1444this software and associated documentation files (the "Software"), to deal in
1445the Software without restriction, including without limitation the rights to
1446use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
1447of the Software, and to permit persons to whom the Software is furnished to do
1448so, subject to the following conditions:
1449
1450The above copyright notice and this permission notice shall be included in all
1451copies or substantial portions of the Software.
1452
1453THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1454IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1455FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
1456AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
1457LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
1458OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
1459SOFTWARE.
1460
1461------------------------------------------------------------------------------
1462ALTERNATIVE B - The Unlicense
1463
1464This is free and unencumbered software released into the public domain.
1465
1466Anyone is free to copy, modify, publish, use, compile, sell, or
1467distribute this software, either in source code form or as a compiled
1468binary, for any purpose, commercial or non-commercial, and by any
1469means.
1470
1471In jurisdictions that recognize copyright laws, the author or authors
1472of this software dedicate any and all copyright interest in the
1473software to the public domain. We make this dedication for the benefit
1474of the public at large and to the detriment of our heirs and
1475successors. We intend this dedication to be an overt act of
1476relinquishment in perpetuity of all present and future rights to this
1477software under copyright law.
1478
1479THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
1480EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
1481MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
1482IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
1483OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
1484ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
1485OTHER DEALINGS IN THE SOFTWARE.
1486
1487For more information, please refer to <https://unlicense.org>
1488
1489*/