1 /*-------------------------------------------------------------------------
2 * drawElements Quality Program Tester Core
3 * ----------------------------------------
5 * Copyright 2014 The Android Open Source Project
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
21 * \brief Compressed Texture Utilities.
22 *//*--------------------------------------------------------------------*/
24 #include "tcuCompressedTexture.hpp"
25 #include "tcuTextureUtil.hpp"
26 #include "tcuAstcUtil.hpp"
28 #include "deStringUtil.hpp"
29 #include "deFloat16.h"
36 int getBlockSize (CompressedTexFormat format)
38 if (isAstcFormat(format))
40 return astc::BLOCK_SIZE_BYTES;
42 else if (isEtcFormat(format))
46 case COMPRESSEDTEXFORMAT_ETC1_RGB8: return 8;
47 case COMPRESSEDTEXFORMAT_EAC_R11: return 8;
48 case COMPRESSEDTEXFORMAT_EAC_SIGNED_R11: return 8;
49 case COMPRESSEDTEXFORMAT_EAC_RG11: return 16;
50 case COMPRESSEDTEXFORMAT_EAC_SIGNED_RG11: return 16;
51 case COMPRESSEDTEXFORMAT_ETC2_RGB8: return 8;
52 case COMPRESSEDTEXFORMAT_ETC2_SRGB8: return 8;
53 case COMPRESSEDTEXFORMAT_ETC2_RGB8_PUNCHTHROUGH_ALPHA1: return 8;
54 case COMPRESSEDTEXFORMAT_ETC2_SRGB8_PUNCHTHROUGH_ALPHA1: return 8;
55 case COMPRESSEDTEXFORMAT_ETC2_EAC_RGBA8: return 16;
56 case COMPRESSEDTEXFORMAT_ETC2_EAC_SRGB8_ALPHA8: return 16;
63 else if (isBcFormat(format))
67 case COMPRESSEDTEXFORMAT_BC1_RGB_UNORM_BLOCK: return 8;
68 case COMPRESSEDTEXFORMAT_BC1_RGB_SRGB_BLOCK: return 8;
69 case COMPRESSEDTEXFORMAT_BC1_RGBA_UNORM_BLOCK: return 8;
70 case COMPRESSEDTEXFORMAT_BC1_RGBA_SRGB_BLOCK: return 8;
71 case COMPRESSEDTEXFORMAT_BC2_UNORM_BLOCK: return 16;
72 case COMPRESSEDTEXFORMAT_BC2_SRGB_BLOCK: return 16;
73 case COMPRESSEDTEXFORMAT_BC3_UNORM_BLOCK: return 16;
74 case COMPRESSEDTEXFORMAT_BC3_SRGB_BLOCK: return 16;
75 case COMPRESSEDTEXFORMAT_BC4_UNORM_BLOCK: return 8;
76 case COMPRESSEDTEXFORMAT_BC4_SNORM_BLOCK: return 8;
77 case COMPRESSEDTEXFORMAT_BC5_UNORM_BLOCK: return 16;
78 case COMPRESSEDTEXFORMAT_BC5_SNORM_BLOCK: return 16;
79 case COMPRESSEDTEXFORMAT_BC6H_UFLOAT_BLOCK: return 16;
80 case COMPRESSEDTEXFORMAT_BC6H_SFLOAT_BLOCK: return 16;
81 case COMPRESSEDTEXFORMAT_BC7_UNORM_BLOCK: return 16;
82 case COMPRESSEDTEXFORMAT_BC7_SRGB_BLOCK: return 16;
96 IVec3 getBlockPixelSize (CompressedTexFormat format)
98 if (isEtcFormat(format))
100 return IVec3(4, 4, 1);
102 else if (isAstcFormat(format))
106 case COMPRESSEDTEXFORMAT_ASTC_4x4_RGBA: return IVec3(4, 4, 1);
107 case COMPRESSEDTEXFORMAT_ASTC_5x4_RGBA: return IVec3(5, 4, 1);
108 case COMPRESSEDTEXFORMAT_ASTC_5x5_RGBA: return IVec3(5, 5, 1);
109 case COMPRESSEDTEXFORMAT_ASTC_6x5_RGBA: return IVec3(6, 5, 1);
110 case COMPRESSEDTEXFORMAT_ASTC_6x6_RGBA: return IVec3(6, 6, 1);
111 case COMPRESSEDTEXFORMAT_ASTC_8x5_RGBA: return IVec3(8, 5, 1);
112 case COMPRESSEDTEXFORMAT_ASTC_8x6_RGBA: return IVec3(8, 6, 1);
113 case COMPRESSEDTEXFORMAT_ASTC_8x8_RGBA: return IVec3(8, 8, 1);
114 case COMPRESSEDTEXFORMAT_ASTC_10x5_RGBA: return IVec3(10, 5, 1);
115 case COMPRESSEDTEXFORMAT_ASTC_10x6_RGBA: return IVec3(10, 6, 1);
116 case COMPRESSEDTEXFORMAT_ASTC_10x8_RGBA: return IVec3(10, 8, 1);
117 case COMPRESSEDTEXFORMAT_ASTC_10x10_RGBA: return IVec3(10, 10, 1);
118 case COMPRESSEDTEXFORMAT_ASTC_12x10_RGBA: return IVec3(12, 10, 1);
119 case COMPRESSEDTEXFORMAT_ASTC_12x12_RGBA: return IVec3(12, 12, 1);
120 case COMPRESSEDTEXFORMAT_ASTC_4x4_SRGB8_ALPHA8: return IVec3(4, 4, 1);
121 case COMPRESSEDTEXFORMAT_ASTC_5x4_SRGB8_ALPHA8: return IVec3(5, 4, 1);
122 case COMPRESSEDTEXFORMAT_ASTC_5x5_SRGB8_ALPHA8: return IVec3(5, 5, 1);
123 case COMPRESSEDTEXFORMAT_ASTC_6x5_SRGB8_ALPHA8: return IVec3(6, 5, 1);
124 case COMPRESSEDTEXFORMAT_ASTC_6x6_SRGB8_ALPHA8: return IVec3(6, 6, 1);
125 case COMPRESSEDTEXFORMAT_ASTC_8x5_SRGB8_ALPHA8: return IVec3(8, 5, 1);
126 case COMPRESSEDTEXFORMAT_ASTC_8x6_SRGB8_ALPHA8: return IVec3(8, 6, 1);
127 case COMPRESSEDTEXFORMAT_ASTC_8x8_SRGB8_ALPHA8: return IVec3(8, 8, 1);
128 case COMPRESSEDTEXFORMAT_ASTC_10x5_SRGB8_ALPHA8: return IVec3(10, 5, 1);
129 case COMPRESSEDTEXFORMAT_ASTC_10x6_SRGB8_ALPHA8: return IVec3(10, 6, 1);
130 case COMPRESSEDTEXFORMAT_ASTC_10x8_SRGB8_ALPHA8: return IVec3(10, 8, 1);
131 case COMPRESSEDTEXFORMAT_ASTC_10x10_SRGB8_ALPHA8: return IVec3(10, 10, 1);
132 case COMPRESSEDTEXFORMAT_ASTC_12x10_SRGB8_ALPHA8: return IVec3(12, 10, 1);
133 case COMPRESSEDTEXFORMAT_ASTC_12x12_SRGB8_ALPHA8: return IVec3(12, 12, 1);
140 else if (isBcFormat(format))
142 return IVec3(4, 4, 1);
151 bool isEtcFormat (CompressedTexFormat format)
155 case COMPRESSEDTEXFORMAT_ETC1_RGB8:
156 case COMPRESSEDTEXFORMAT_EAC_R11:
157 case COMPRESSEDTEXFORMAT_EAC_SIGNED_R11:
158 case COMPRESSEDTEXFORMAT_EAC_RG11:
159 case COMPRESSEDTEXFORMAT_EAC_SIGNED_RG11:
160 case COMPRESSEDTEXFORMAT_ETC2_RGB8:
161 case COMPRESSEDTEXFORMAT_ETC2_SRGB8:
162 case COMPRESSEDTEXFORMAT_ETC2_RGB8_PUNCHTHROUGH_ALPHA1:
163 case COMPRESSEDTEXFORMAT_ETC2_SRGB8_PUNCHTHROUGH_ALPHA1:
164 case COMPRESSEDTEXFORMAT_ETC2_EAC_RGBA8:
165 case COMPRESSEDTEXFORMAT_ETC2_EAC_SRGB8_ALPHA8:
173 bool isBcFormat (CompressedTexFormat format)
177 case COMPRESSEDTEXFORMAT_BC1_RGB_UNORM_BLOCK:
178 case COMPRESSEDTEXFORMAT_BC1_RGB_SRGB_BLOCK:
179 case COMPRESSEDTEXFORMAT_BC1_RGBA_UNORM_BLOCK:
180 case COMPRESSEDTEXFORMAT_BC1_RGBA_SRGB_BLOCK:
181 case COMPRESSEDTEXFORMAT_BC2_UNORM_BLOCK:
182 case COMPRESSEDTEXFORMAT_BC2_SRGB_BLOCK:
183 case COMPRESSEDTEXFORMAT_BC3_UNORM_BLOCK:
184 case COMPRESSEDTEXFORMAT_BC3_SRGB_BLOCK:
185 case COMPRESSEDTEXFORMAT_BC4_UNORM_BLOCK:
186 case COMPRESSEDTEXFORMAT_BC4_SNORM_BLOCK:
187 case COMPRESSEDTEXFORMAT_BC5_UNORM_BLOCK:
188 case COMPRESSEDTEXFORMAT_BC5_SNORM_BLOCK:
189 case COMPRESSEDTEXFORMAT_BC6H_UFLOAT_BLOCK:
190 case COMPRESSEDTEXFORMAT_BC6H_SFLOAT_BLOCK:
191 case COMPRESSEDTEXFORMAT_BC7_UNORM_BLOCK:
192 case COMPRESSEDTEXFORMAT_BC7_SRGB_BLOCK:
200 bool isBcBitExactFormat (CompressedTexFormat format)
204 case COMPRESSEDTEXFORMAT_BC6H_UFLOAT_BLOCK:
205 case COMPRESSEDTEXFORMAT_BC6H_SFLOAT_BLOCK:
206 case COMPRESSEDTEXFORMAT_BC7_UNORM_BLOCK:
207 case COMPRESSEDTEXFORMAT_BC7_SRGB_BLOCK:
215 bool isBcSRGBFormat (CompressedTexFormat format)
219 case COMPRESSEDTEXFORMAT_BC1_RGB_SRGB_BLOCK:
220 case COMPRESSEDTEXFORMAT_BC1_RGBA_SRGB_BLOCK:
221 case COMPRESSEDTEXFORMAT_BC2_SRGB_BLOCK:
222 case COMPRESSEDTEXFORMAT_BC3_SRGB_BLOCK:
223 case COMPRESSEDTEXFORMAT_BC7_SRGB_BLOCK:
231 bool isAstcFormat (CompressedTexFormat format)
235 case COMPRESSEDTEXFORMAT_ASTC_4x4_RGBA:
236 case COMPRESSEDTEXFORMAT_ASTC_5x4_RGBA:
237 case COMPRESSEDTEXFORMAT_ASTC_5x5_RGBA:
238 case COMPRESSEDTEXFORMAT_ASTC_6x5_RGBA:
239 case COMPRESSEDTEXFORMAT_ASTC_6x6_RGBA:
240 case COMPRESSEDTEXFORMAT_ASTC_8x5_RGBA:
241 case COMPRESSEDTEXFORMAT_ASTC_8x6_RGBA:
242 case COMPRESSEDTEXFORMAT_ASTC_8x8_RGBA:
243 case COMPRESSEDTEXFORMAT_ASTC_10x5_RGBA:
244 case COMPRESSEDTEXFORMAT_ASTC_10x6_RGBA:
245 case COMPRESSEDTEXFORMAT_ASTC_10x8_RGBA:
246 case COMPRESSEDTEXFORMAT_ASTC_10x10_RGBA:
247 case COMPRESSEDTEXFORMAT_ASTC_12x10_RGBA:
248 case COMPRESSEDTEXFORMAT_ASTC_12x12_RGBA:
249 case COMPRESSEDTEXFORMAT_ASTC_4x4_SRGB8_ALPHA8:
250 case COMPRESSEDTEXFORMAT_ASTC_5x4_SRGB8_ALPHA8:
251 case COMPRESSEDTEXFORMAT_ASTC_5x5_SRGB8_ALPHA8:
252 case COMPRESSEDTEXFORMAT_ASTC_6x5_SRGB8_ALPHA8:
253 case COMPRESSEDTEXFORMAT_ASTC_6x6_SRGB8_ALPHA8:
254 case COMPRESSEDTEXFORMAT_ASTC_8x5_SRGB8_ALPHA8:
255 case COMPRESSEDTEXFORMAT_ASTC_8x6_SRGB8_ALPHA8:
256 case COMPRESSEDTEXFORMAT_ASTC_8x8_SRGB8_ALPHA8:
257 case COMPRESSEDTEXFORMAT_ASTC_10x5_SRGB8_ALPHA8:
258 case COMPRESSEDTEXFORMAT_ASTC_10x6_SRGB8_ALPHA8:
259 case COMPRESSEDTEXFORMAT_ASTC_10x8_SRGB8_ALPHA8:
260 case COMPRESSEDTEXFORMAT_ASTC_10x10_SRGB8_ALPHA8:
261 case COMPRESSEDTEXFORMAT_ASTC_12x10_SRGB8_ALPHA8:
262 case COMPRESSEDTEXFORMAT_ASTC_12x12_SRGB8_ALPHA8:
270 bool isAstcSRGBFormat (CompressedTexFormat format)
274 case COMPRESSEDTEXFORMAT_ASTC_4x4_SRGB8_ALPHA8:
275 case COMPRESSEDTEXFORMAT_ASTC_5x4_SRGB8_ALPHA8:
276 case COMPRESSEDTEXFORMAT_ASTC_5x5_SRGB8_ALPHA8:
277 case COMPRESSEDTEXFORMAT_ASTC_6x5_SRGB8_ALPHA8:
278 case COMPRESSEDTEXFORMAT_ASTC_6x6_SRGB8_ALPHA8:
279 case COMPRESSEDTEXFORMAT_ASTC_8x5_SRGB8_ALPHA8:
280 case COMPRESSEDTEXFORMAT_ASTC_8x6_SRGB8_ALPHA8:
281 case COMPRESSEDTEXFORMAT_ASTC_8x8_SRGB8_ALPHA8:
282 case COMPRESSEDTEXFORMAT_ASTC_10x5_SRGB8_ALPHA8:
283 case COMPRESSEDTEXFORMAT_ASTC_10x6_SRGB8_ALPHA8:
284 case COMPRESSEDTEXFORMAT_ASTC_10x8_SRGB8_ALPHA8:
285 case COMPRESSEDTEXFORMAT_ASTC_10x10_SRGB8_ALPHA8:
286 case COMPRESSEDTEXFORMAT_ASTC_12x10_SRGB8_ALPHA8:
287 case COMPRESSEDTEXFORMAT_ASTC_12x12_SRGB8_ALPHA8:
295 TextureFormat getUncompressedFormat (CompressedTexFormat format)
297 if (isEtcFormat(format))
301 case COMPRESSEDTEXFORMAT_ETC1_RGB8: return TextureFormat(TextureFormat::RGB, TextureFormat::UNORM_INT8);
302 case COMPRESSEDTEXFORMAT_EAC_R11: return TextureFormat(TextureFormat::R, TextureFormat::UNORM_INT16);
303 case COMPRESSEDTEXFORMAT_EAC_SIGNED_R11: return TextureFormat(TextureFormat::R, TextureFormat::SNORM_INT16);
304 case COMPRESSEDTEXFORMAT_EAC_RG11: return TextureFormat(TextureFormat::RG, TextureFormat::UNORM_INT16);
305 case COMPRESSEDTEXFORMAT_EAC_SIGNED_RG11: return TextureFormat(TextureFormat::RG, TextureFormat::SNORM_INT16);
306 case COMPRESSEDTEXFORMAT_ETC2_RGB8: return TextureFormat(TextureFormat::RGB, TextureFormat::UNORM_INT8);
307 case COMPRESSEDTEXFORMAT_ETC2_SRGB8: return TextureFormat(TextureFormat::sRGB, TextureFormat::UNORM_INT8);
308 case COMPRESSEDTEXFORMAT_ETC2_RGB8_PUNCHTHROUGH_ALPHA1: return TextureFormat(TextureFormat::RGBA, TextureFormat::UNORM_INT8);
309 case COMPRESSEDTEXFORMAT_ETC2_SRGB8_PUNCHTHROUGH_ALPHA1: return TextureFormat(TextureFormat::sRGBA, TextureFormat::UNORM_INT8);
310 case COMPRESSEDTEXFORMAT_ETC2_EAC_RGBA8: return TextureFormat(TextureFormat::RGBA, TextureFormat::UNORM_INT8);
311 case COMPRESSEDTEXFORMAT_ETC2_EAC_SRGB8_ALPHA8: return TextureFormat(TextureFormat::sRGBA, TextureFormat::UNORM_INT8);
315 return TextureFormat();
318 else if (isAstcFormat(format))
320 if (isAstcSRGBFormat(format))
321 return TextureFormat(TextureFormat::sRGBA, TextureFormat::UNORM_INT8);
323 return TextureFormat(TextureFormat::RGBA, TextureFormat::HALF_FLOAT);
325 else if (isBcFormat(format))
327 if (format == COMPRESSEDTEXFORMAT_BC4_UNORM_BLOCK || format == COMPRESSEDTEXFORMAT_BC4_SNORM_BLOCK)
328 return TextureFormat(TextureFormat::R, TextureFormat::FLOAT);
329 else if (format == COMPRESSEDTEXFORMAT_BC5_UNORM_BLOCK || format == COMPRESSEDTEXFORMAT_BC5_SNORM_BLOCK)
330 return TextureFormat(TextureFormat::RG, TextureFormat::FLOAT);
331 else if (format == COMPRESSEDTEXFORMAT_BC6H_UFLOAT_BLOCK || format == COMPRESSEDTEXFORMAT_BC6H_SFLOAT_BLOCK)
332 return TextureFormat(TextureFormat::RGB, TextureFormat::HALF_FLOAT);
333 else if (isBcSRGBFormat(format))
334 return TextureFormat(TextureFormat::sRGBA, TextureFormat::UNORM_INT8);
336 return TextureFormat(TextureFormat::RGBA, TextureFormat::UNORM_INT8);
341 return TextureFormat();
345 CompressedTexFormat getAstcFormatByBlockSize (const IVec3& size, bool isSRGB)
348 throw InternalError("3D ASTC textures not currently supported");
350 for (int fmtI = 0; fmtI < COMPRESSEDTEXFORMAT_LAST; fmtI++)
352 const CompressedTexFormat fmt = (CompressedTexFormat)fmtI;
354 if (isAstcFormat(fmt) && getBlockPixelSize(fmt) == size && isAstcSRGBFormat(fmt) == isSRGB)
358 throw InternalError("Invalid ASTC block size " + de::toString(size.x()) + "x" + de::toString(size.y()) + "x" + de::toString(size.z()));
364 inline deUint8 extend4To8 (deUint8 src)
366 DE_ASSERT((src & ~((1<<4)-1)) == 0);
367 return (deUint8)((src << 4) | src);
370 inline deUint8 extend5To8 (deUint8 src)
372 DE_ASSERT((src & ~((1<<5)-1)) == 0);
373 return (deUint8)((src << 3) | (src >> 2));
376 inline deUint8 extend6To8 (deUint8 src)
378 DE_ASSERT((src & ~((1<<6)-1)) == 0);
379 return (deUint8)((src << 2) | (src >> 4));
382 // \todo [2013-08-06 nuutti] ETC and ASTC decompression codes are rather unrelated, and are already in their own "private" namespaces - should this be split to multiple files?
384 namespace EtcDecompressInternal
389 ETC2_BLOCK_WIDTH = 4,
390 ETC2_BLOCK_HEIGHT = 4,
391 ETC2_UNCOMPRESSED_PIXEL_SIZE_A8 = 1,
392 ETC2_UNCOMPRESSED_PIXEL_SIZE_R11 = 2,
393 ETC2_UNCOMPRESSED_PIXEL_SIZE_RG11 = 4,
394 ETC2_UNCOMPRESSED_PIXEL_SIZE_RGB8 = 3,
395 ETC2_UNCOMPRESSED_PIXEL_SIZE_RGBA8 = 4,
396 ETC2_UNCOMPRESSED_BLOCK_SIZE_A8 = ETC2_BLOCK_WIDTH*ETC2_BLOCK_HEIGHT*ETC2_UNCOMPRESSED_PIXEL_SIZE_A8,
397 ETC2_UNCOMPRESSED_BLOCK_SIZE_R11 = ETC2_BLOCK_WIDTH*ETC2_BLOCK_HEIGHT*ETC2_UNCOMPRESSED_PIXEL_SIZE_R11,
398 ETC2_UNCOMPRESSED_BLOCK_SIZE_RG11 = ETC2_BLOCK_WIDTH*ETC2_BLOCK_HEIGHT*ETC2_UNCOMPRESSED_PIXEL_SIZE_RG11,
399 ETC2_UNCOMPRESSED_BLOCK_SIZE_RGB8 = ETC2_BLOCK_WIDTH*ETC2_BLOCK_HEIGHT*ETC2_UNCOMPRESSED_PIXEL_SIZE_RGB8,
400 ETC2_UNCOMPRESSED_BLOCK_SIZE_RGBA8 = ETC2_BLOCK_WIDTH*ETC2_BLOCK_HEIGHT*ETC2_UNCOMPRESSED_PIXEL_SIZE_RGBA8
403 inline deUint64 get64BitBlock (const deUint8* src, int blockNdx)
405 // Stored in big-endian form.
408 for (int i = 0; i < 8; i++)
409 block = (block << 8ull) | (deUint64)(src[blockNdx*8+i]);
414 // Return the first 64 bits of a 128 bit block.
415 inline deUint64 get128BitBlockStart (const deUint8* src, int blockNdx)
417 return get64BitBlock(src, 2*blockNdx);
420 // Return the last 64 bits of a 128 bit block.
421 inline deUint64 get128BitBlockEnd (const deUint8* src, int blockNdx)
423 return get64BitBlock(src, 2*blockNdx + 1);
426 inline deUint32 getBit (deUint64 src, int bit)
428 return (src >> bit) & 1;
431 inline deUint32 getBits (deUint64 src, int low, int high)
433 const int numBits = (high-low) + 1;
434 DE_ASSERT(de::inRange(numBits, 1, 32));
436 return (deUint32)((src >> low) & ((1u<<numBits)-1));
438 return (deUint32)((src >> low) & 0xFFFFFFFFu);
441 inline deUint8 extend7To8 (deUint8 src)
443 DE_ASSERT((src & ~((1<<7)-1)) == 0);
444 return (deUint8)((src << 1) | (src >> 6));
447 inline deInt8 extendSigned3To8 (deUint8 src)
449 const bool isNeg = (src & (1<<2)) != 0;
450 return (deInt8)((isNeg ? ~((1<<3)-1) : 0) | src);
453 inline deUint8 extend5Delta3To8 (deUint8 base5, deUint8 delta3)
455 const deUint8 t = (deUint8)((deInt8)base5 + extendSigned3To8(delta3));
456 return extend5To8(t);
459 inline deUint16 extend11To16 (deUint16 src)
461 DE_ASSERT((src & ~((1<<11)-1)) == 0);
462 return (deUint16)((src << 5) | (src >> 6));
465 inline deInt16 extend11To16WithSign (deInt16 src)
468 return (deInt16)(-(deInt16)extend11To16((deUint16)(-src)));
470 return (deInt16)extend11To16(src);
473 void decompressETC1Block (deUint8 dst[ETC2_UNCOMPRESSED_BLOCK_SIZE_RGB8], deUint64 src)
475 const int diffBit = (int)getBit(src, 33);
476 const int flipBit = (int)getBit(src, 32);
477 const deUint32 table[2] = { getBits(src, 37, 39), getBits(src, 34, 36) };
485 baseR[0] = extend4To8((deUint8)getBits(src, 60, 63));
486 baseR[1] = extend4To8((deUint8)getBits(src, 56, 59));
487 baseG[0] = extend4To8((deUint8)getBits(src, 52, 55));
488 baseG[1] = extend4To8((deUint8)getBits(src, 48, 51));
489 baseB[0] = extend4To8((deUint8)getBits(src, 44, 47));
490 baseB[1] = extend4To8((deUint8)getBits(src, 40, 43));
494 // Differential mode (diffBit == 1).
495 deUint8 bR = (deUint8)getBits(src, 59, 63); // 5b
496 deUint8 dR = (deUint8)getBits(src, 56, 58); // 3b
497 deUint8 bG = (deUint8)getBits(src, 51, 55);
498 deUint8 dG = (deUint8)getBits(src, 48, 50);
499 deUint8 bB = (deUint8)getBits(src, 43, 47);
500 deUint8 dB = (deUint8)getBits(src, 40, 42);
502 baseR[0] = extend5To8(bR);
503 baseG[0] = extend5To8(bG);
504 baseB[0] = extend5To8(bB);
506 baseR[1] = extend5Delta3To8(bR, dR);
507 baseG[1] = extend5Delta3To8(bG, dG);
508 baseB[1] = extend5Delta3To8(bB, dB);
511 static const int modifierTable[8][4] =
517 { 13, 42, -13, -42 },
518 { 18, 60, -18, -60 },
519 { 24, 80, -24, -80 },
520 { 33, 106, -33, -106 },
521 { 47, 183, -47, -183 }
524 // Write final pixels.
525 for (int pixelNdx = 0; pixelNdx < ETC2_BLOCK_HEIGHT*ETC2_BLOCK_WIDTH; pixelNdx++)
527 const int x = pixelNdx / ETC2_BLOCK_HEIGHT;
528 const int y = pixelNdx % ETC2_BLOCK_HEIGHT;
529 const int dstOffset = (y*ETC2_BLOCK_WIDTH + x)*ETC2_UNCOMPRESSED_PIXEL_SIZE_RGB8;
530 const int subBlock = ((flipBit ? y : x) >= 2) ? 1 : 0;
531 const deUint32 tableNdx = table[subBlock];
532 const deUint32 modifierNdx = (getBit(src, 16+pixelNdx) << 1) | getBit(src, pixelNdx);
533 const int modifier = modifierTable[tableNdx][modifierNdx];
535 dst[dstOffset+0] = (deUint8)deClamp32((int)baseR[subBlock] + modifier, 0, 255);
536 dst[dstOffset+1] = (deUint8)deClamp32((int)baseG[subBlock] + modifier, 0, 255);
537 dst[dstOffset+2] = (deUint8)deClamp32((int)baseB[subBlock] + modifier, 0, 255);
541 // if alphaMode is true, do PUNCHTHROUGH and store alpha to alphaDst; otherwise do ordinary ETC2 RGB8.
542 void decompressETC2Block (deUint8 dst[ETC2_UNCOMPRESSED_BLOCK_SIZE_RGB8], deUint64 src, deUint8 alphaDst[ETC2_UNCOMPRESSED_BLOCK_SIZE_A8], bool alphaMode)
555 const int diffOpaqueBit = (int)getBit(src, 33);
556 const deInt8 selBR = (deInt8)getBits(src, 59, 63); // 5 bits.
557 const deInt8 selBG = (deInt8)getBits(src, 51, 55);
558 const deInt8 selBB = (deInt8)getBits(src, 43, 47);
559 const deInt8 selDR = extendSigned3To8((deUint8)getBits(src, 56, 58)); // 3 bits.
560 const deInt8 selDG = extendSigned3To8((deUint8)getBits(src, 48, 50));
561 const deInt8 selDB = extendSigned3To8((deUint8)getBits(src, 40, 42));
564 if (!alphaMode && diffOpaqueBit == 0)
565 mode = MODE_INDIVIDUAL;
566 else if (!de::inRange(selBR + selDR, 0, 31))
568 else if (!de::inRange(selBG + selDG, 0, 31))
570 else if (!de::inRange(selBB + selDB, 0, 31))
573 mode = MODE_DIFFERENTIAL;
575 if (mode == MODE_INDIVIDUAL || mode == MODE_DIFFERENTIAL)
577 // Individual and differential modes have some steps in common, handle them here.
578 static const int modifierTable[8][4] =
584 { 13, 42, -13, -42 },
585 { 18, 60, -18, -60 },
586 { 24, 80, -24, -80 },
587 { 33, 106, -33, -106 },
588 { 47, 183, -47, -183 }
591 const int flipBit = (int)getBit(src, 32);
592 const deUint32 table[2] = { getBits(src, 37, 39), getBits(src, 34, 36) };
597 if (mode == MODE_INDIVIDUAL)
599 // Individual mode, initial values.
600 baseR[0] = extend4To8((deUint8)getBits(src, 60, 63));
601 baseR[1] = extend4To8((deUint8)getBits(src, 56, 59));
602 baseG[0] = extend4To8((deUint8)getBits(src, 52, 55));
603 baseG[1] = extend4To8((deUint8)getBits(src, 48, 51));
604 baseB[0] = extend4To8((deUint8)getBits(src, 44, 47));
605 baseB[1] = extend4To8((deUint8)getBits(src, 40, 43));
609 // Differential mode, initial values.
610 baseR[0] = extend5To8(selBR);
611 baseG[0] = extend5To8(selBG);
612 baseB[0] = extend5To8(selBB);
614 baseR[1] = extend5To8((deUint8)(selBR + selDR));
615 baseG[1] = extend5To8((deUint8)(selBG + selDG));
616 baseB[1] = extend5To8((deUint8)(selBB + selDB));
619 // Write final pixels for individual or differential mode.
620 for (int pixelNdx = 0; pixelNdx < ETC2_BLOCK_HEIGHT*ETC2_BLOCK_WIDTH; pixelNdx++)
622 const int x = pixelNdx / ETC2_BLOCK_HEIGHT;
623 const int y = pixelNdx % ETC2_BLOCK_HEIGHT;
624 const int dstOffset = (y*ETC2_BLOCK_WIDTH + x)*ETC2_UNCOMPRESSED_PIXEL_SIZE_RGB8;
625 const int subBlock = ((flipBit ? y : x) >= 2) ? 1 : 0;
626 const deUint32 tableNdx = table[subBlock];
627 const deUint32 modifierNdx = (getBit(src, 16+pixelNdx) << 1) | getBit(src, pixelNdx);
628 const int alphaDstOffset = (y*ETC2_BLOCK_WIDTH + x)*ETC2_UNCOMPRESSED_PIXEL_SIZE_A8; // Only needed for PUNCHTHROUGH version.
630 // If doing PUNCHTHROUGH version (alphaMode), opaque bit may affect colors.
631 if (alphaMode && diffOpaqueBit == 0 && modifierNdx == 2)
633 dst[dstOffset+0] = 0;
634 dst[dstOffset+1] = 0;
635 dst[dstOffset+2] = 0;
636 alphaDst[alphaDstOffset] = 0;
642 // PUNCHTHROUGH version and opaque bit may also affect modifiers.
643 if (alphaMode && diffOpaqueBit == 0 && (modifierNdx == 0 || modifierNdx == 2))
646 modifier = modifierTable[tableNdx][modifierNdx];
648 dst[dstOffset+0] = (deUint8)deClamp32((int)baseR[subBlock] + modifier, 0, 255);
649 dst[dstOffset+1] = (deUint8)deClamp32((int)baseG[subBlock] + modifier, 0, 255);
650 dst[dstOffset+2] = (deUint8)deClamp32((int)baseB[subBlock] + modifier, 0, 255);
653 alphaDst[alphaDstOffset] = 255;
657 else if (mode == MODE_T || mode == MODE_H)
659 // T and H modes have some steps in common, handle them here.
660 static const int distTable[8] = { 3, 6, 11, 16, 23, 32, 41, 64 };
668 // T mode, calculate paint values.
669 const deUint8 R1a = (deUint8)getBits(src, 59, 60);
670 const deUint8 R1b = (deUint8)getBits(src, 56, 57);
671 const deUint8 G1 = (deUint8)getBits(src, 52, 55);
672 const deUint8 B1 = (deUint8)getBits(src, 48, 51);
673 const deUint8 R2 = (deUint8)getBits(src, 44, 47);
674 const deUint8 G2 = (deUint8)getBits(src, 40, 43);
675 const deUint8 B2 = (deUint8)getBits(src, 36, 39);
676 const deUint32 distNdx = (getBits(src, 34, 35) << 1) | getBit(src, 32);
677 const int dist = distTable[distNdx];
679 paintR[0] = extend4To8((deUint8)((R1a << 2) | R1b));
680 paintG[0] = extend4To8(G1);
681 paintB[0] = extend4To8(B1);
682 paintR[2] = extend4To8(R2);
683 paintG[2] = extend4To8(G2);
684 paintB[2] = extend4To8(B2);
685 paintR[1] = (deUint8)deClamp32((int)paintR[2] + dist, 0, 255);
686 paintG[1] = (deUint8)deClamp32((int)paintG[2] + dist, 0, 255);
687 paintB[1] = (deUint8)deClamp32((int)paintB[2] + dist, 0, 255);
688 paintR[3] = (deUint8)deClamp32((int)paintR[2] - dist, 0, 255);
689 paintG[3] = (deUint8)deClamp32((int)paintG[2] - dist, 0, 255);
690 paintB[3] = (deUint8)deClamp32((int)paintB[2] - dist, 0, 255);
694 // H mode, calculate paint values.
695 const deUint8 R1 = (deUint8)getBits(src, 59, 62);
696 const deUint8 G1a = (deUint8)getBits(src, 56, 58);
697 const deUint8 G1b = (deUint8)getBit(src, 52);
698 const deUint8 B1a = (deUint8)getBit(src, 51);
699 const deUint8 B1b = (deUint8)getBits(src, 47, 49);
700 const deUint8 R2 = (deUint8)getBits(src, 43, 46);
701 const deUint8 G2 = (deUint8)getBits(src, 39, 42);
702 const deUint8 B2 = (deUint8)getBits(src, 35, 38);
706 deUint32 baseValue[2];
710 baseR[0] = extend4To8(R1);
711 baseG[0] = extend4To8((deUint8)((G1a << 1) | G1b));
712 baseB[0] = extend4To8((deUint8)((B1a << 3) | B1b));
713 baseR[1] = extend4To8(R2);
714 baseG[1] = extend4To8(G2);
715 baseB[1] = extend4To8(B2);
716 baseValue[0] = (((deUint32)baseR[0]) << 16) | (((deUint32)baseG[0]) << 8) | baseB[0];
717 baseValue[1] = (((deUint32)baseR[1]) << 16) | (((deUint32)baseG[1]) << 8) | baseB[1];
718 distNdx = (getBit(src, 34) << 2) | (getBit(src, 32) << 1) | (deUint32)(baseValue[0] >= baseValue[1]);
719 dist = distTable[distNdx];
721 paintR[0] = (deUint8)deClamp32((int)baseR[0] + dist, 0, 255);
722 paintG[0] = (deUint8)deClamp32((int)baseG[0] + dist, 0, 255);
723 paintB[0] = (deUint8)deClamp32((int)baseB[0] + dist, 0, 255);
724 paintR[1] = (deUint8)deClamp32((int)baseR[0] - dist, 0, 255);
725 paintG[1] = (deUint8)deClamp32((int)baseG[0] - dist, 0, 255);
726 paintB[1] = (deUint8)deClamp32((int)baseB[0] - dist, 0, 255);
727 paintR[2] = (deUint8)deClamp32((int)baseR[1] + dist, 0, 255);
728 paintG[2] = (deUint8)deClamp32((int)baseG[1] + dist, 0, 255);
729 paintB[2] = (deUint8)deClamp32((int)baseB[1] + dist, 0, 255);
730 paintR[3] = (deUint8)deClamp32((int)baseR[1] - dist, 0, 255);
731 paintG[3] = (deUint8)deClamp32((int)baseG[1] - dist, 0, 255);
732 paintB[3] = (deUint8)deClamp32((int)baseB[1] - dist, 0, 255);
735 // Write final pixels for T or H mode.
736 for (int pixelNdx = 0; pixelNdx < ETC2_BLOCK_HEIGHT*ETC2_BLOCK_WIDTH; pixelNdx++)
738 const int x = pixelNdx / ETC2_BLOCK_HEIGHT;
739 const int y = pixelNdx % ETC2_BLOCK_HEIGHT;
740 const int dstOffset = (y*ETC2_BLOCK_WIDTH + x)*ETC2_UNCOMPRESSED_PIXEL_SIZE_RGB8;
741 const deUint32 paintNdx = (getBit(src, 16+pixelNdx) << 1) | getBit(src, pixelNdx);
742 const int alphaDstOffset = (y*ETC2_BLOCK_WIDTH + x)*ETC2_UNCOMPRESSED_PIXEL_SIZE_A8; // Only needed for PUNCHTHROUGH version.
744 if (alphaMode && diffOpaqueBit == 0 && paintNdx == 2)
746 dst[dstOffset+0] = 0;
747 dst[dstOffset+1] = 0;
748 dst[dstOffset+2] = 0;
749 alphaDst[alphaDstOffset] = 0;
753 dst[dstOffset+0] = (deUint8)deClamp32((int)paintR[paintNdx], 0, 255);
754 dst[dstOffset+1] = (deUint8)deClamp32((int)paintG[paintNdx], 0, 255);
755 dst[dstOffset+2] = (deUint8)deClamp32((int)paintB[paintNdx], 0, 255);
758 alphaDst[alphaDstOffset] = 255;
765 const deUint8 GO1 = (deUint8)getBit(src, 56);
766 const deUint8 GO2 = (deUint8)getBits(src, 49, 54);
767 const deUint8 BO1 = (deUint8)getBit(src, 48);
768 const deUint8 BO2 = (deUint8)getBits(src, 43, 44);
769 const deUint8 BO3 = (deUint8)getBits(src, 39, 41);
770 const deUint8 RH1 = (deUint8)getBits(src, 34, 38);
771 const deUint8 RH2 = (deUint8)getBit(src, 32);
772 const deUint8 RO = extend6To8((deUint8)getBits(src, 57, 62));
773 const deUint8 GO = extend7To8((deUint8)((GO1 << 6) | GO2));
774 const deUint8 BO = extend6To8((deUint8)((BO1 << 5) | (BO2 << 3) | BO3));
775 const deUint8 RH = extend6To8((deUint8)((RH1 << 1) | RH2));
776 const deUint8 GH = extend7To8((deUint8)getBits(src, 25, 31));
777 const deUint8 BH = extend6To8((deUint8)getBits(src, 19, 24));
778 const deUint8 RV = extend6To8((deUint8)getBits(src, 13, 18));
779 const deUint8 GV = extend7To8((deUint8)getBits(src, 6, 12));
780 const deUint8 BV = extend6To8((deUint8)getBits(src, 0, 5));
782 // Write final pixels for planar mode.
783 for (int y = 0; y < 4; y++)
785 for (int x = 0; x < 4; x++)
787 const int dstOffset = (y*ETC2_BLOCK_WIDTH + x)*ETC2_UNCOMPRESSED_PIXEL_SIZE_RGB8;
788 const int unclampedR = (x * ((int)RH-(int)RO) + y * ((int)RV-(int)RO) + 4*(int)RO + 2) >> 2;
789 const int unclampedG = (x * ((int)GH-(int)GO) + y * ((int)GV-(int)GO) + 4*(int)GO + 2) >> 2;
790 const int unclampedB = (x * ((int)BH-(int)BO) + y * ((int)BV-(int)BO) + 4*(int)BO + 2) >> 2;
791 const int alphaDstOffset = (y*ETC2_BLOCK_WIDTH + x)*ETC2_UNCOMPRESSED_PIXEL_SIZE_A8; // Only needed for PUNCHTHROUGH version.
793 dst[dstOffset+0] = (deUint8)deClamp32(unclampedR, 0, 255);
794 dst[dstOffset+1] = (deUint8)deClamp32(unclampedG, 0, 255);
795 dst[dstOffset+2] = (deUint8)deClamp32(unclampedB, 0, 255);
798 alphaDst[alphaDstOffset] = 255;
804 void decompressEAC8Block (deUint8 dst[ETC2_UNCOMPRESSED_BLOCK_SIZE_A8], deUint64 src)
806 static const int modifierTable[16][8] =
808 {-3, -6, -9, -15, 2, 5, 8, 14},
809 {-3, -7, -10, -13, 2, 6, 9, 12},
810 {-2, -5, -8, -13, 1, 4, 7, 12},
811 {-2, -4, -6, -13, 1, 3, 5, 12},
812 {-3, -6, -8, -12, 2, 5, 7, 11},
813 {-3, -7, -9, -11, 2, 6, 8, 10},
814 {-4, -7, -8, -11, 3, 6, 7, 10},
815 {-3, -5, -8, -11, 2, 4, 7, 10},
816 {-2, -6, -8, -10, 1, 5, 7, 9},
817 {-2, -5, -8, -10, 1, 4, 7, 9},
818 {-2, -4, -8, -10, 1, 3, 7, 9},
819 {-2, -5, -7, -10, 1, 4, 6, 9},
820 {-3, -4, -7, -10, 2, 3, 6, 9},
821 {-1, -2, -3, -10, 0, 1, 2, 9},
822 {-4, -6, -8, -9, 3, 5, 7, 8},
823 {-3, -5, -7, -9, 2, 4, 6, 8}
826 const deUint8 baseCodeword = (deUint8)getBits(src, 56, 63);
827 const deUint8 multiplier = (deUint8)getBits(src, 52, 55);
828 const deUint32 tableNdx = getBits(src, 48, 51);
830 for (int pixelNdx = 0; pixelNdx < ETC2_BLOCK_HEIGHT*ETC2_BLOCK_WIDTH; pixelNdx++)
832 const int x = pixelNdx / ETC2_BLOCK_HEIGHT;
833 const int y = pixelNdx % ETC2_BLOCK_HEIGHT;
834 const int dstOffset = (y*ETC2_BLOCK_WIDTH + x)*ETC2_UNCOMPRESSED_PIXEL_SIZE_A8;
835 const int pixelBitNdx = 45 - 3*pixelNdx;
836 const deUint32 modifierNdx = (getBit(src, pixelBitNdx + 2) << 2) | (getBit(src, pixelBitNdx + 1) << 1) | getBit(src, pixelBitNdx);
837 const int modifier = modifierTable[tableNdx][modifierNdx];
839 dst[dstOffset] = (deUint8)deClamp32((int)baseCodeword + (int)multiplier*modifier, 0, 255);
843 void decompressEAC11Block (deUint8 dst[ETC2_UNCOMPRESSED_BLOCK_SIZE_R11], deUint64 src, bool signedMode)
845 static const int modifierTable[16][8] =
847 {-3, -6, -9, -15, 2, 5, 8, 14},
848 {-3, -7, -10, -13, 2, 6, 9, 12},
849 {-2, -5, -8, -13, 1, 4, 7, 12},
850 {-2, -4, -6, -13, 1, 3, 5, 12},
851 {-3, -6, -8, -12, 2, 5, 7, 11},
852 {-3, -7, -9, -11, 2, 6, 8, 10},
853 {-4, -7, -8, -11, 3, 6, 7, 10},
854 {-3, -5, -8, -11, 2, 4, 7, 10},
855 {-2, -6, -8, -10, 1, 5, 7, 9},
856 {-2, -5, -8, -10, 1, 4, 7, 9},
857 {-2, -4, -8, -10, 1, 3, 7, 9},
858 {-2, -5, -7, -10, 1, 4, 6, 9},
859 {-3, -4, -7, -10, 2, 3, 6, 9},
860 {-1, -2, -3, -10, 0, 1, 2, 9},
861 {-4, -6, -8, -9, 3, 5, 7, 8},
862 {-3, -5, -7, -9, 2, 4, 6, 8}
865 const deInt32 multiplier = (deInt32)getBits(src, 52, 55);
866 const deInt32 tableNdx = (deInt32)getBits(src, 48, 51);
867 deInt32 baseCodeword = (deInt32)getBits(src, 56, 63);
871 if (baseCodeword > 127)
873 if (baseCodeword == -128)
877 for (int pixelNdx = 0; pixelNdx < ETC2_BLOCK_HEIGHT*ETC2_BLOCK_WIDTH; pixelNdx++)
879 const int x = pixelNdx / ETC2_BLOCK_HEIGHT;
880 const int y = pixelNdx % ETC2_BLOCK_HEIGHT;
881 const int dstOffset = (y*ETC2_BLOCK_WIDTH + x)*ETC2_UNCOMPRESSED_PIXEL_SIZE_R11;
882 const int pixelBitNdx = 45 - 3*pixelNdx;
883 const deUint32 modifierNdx = (getBit(src, pixelBitNdx + 2) << 2) | (getBit(src, pixelBitNdx + 1) << 1) | getBit(src, pixelBitNdx);
884 const int modifier = modifierTable[tableNdx][modifierNdx];
891 value = (deInt16)deClamp32(baseCodeword*8 + multiplier*modifier*8, -1023, 1023);
893 value = (deInt16)deClamp32(baseCodeword*8 + modifier, -1023, 1023);
895 *((deInt16*)(dst + dstOffset)) = value;
902 value = (deUint16)deClamp32(baseCodeword*8 + 4 + multiplier*modifier*8, 0, 2047);
904 value= (deUint16)deClamp32(baseCodeword*8 + 4 + modifier, 0, 2047);
906 *((deUint16*)(dst + dstOffset)) = value;
911 } // EtcDecompressInternal
913 void decompressETC1 (const PixelBufferAccess& dst, const deUint8* src)
915 using namespace EtcDecompressInternal;
917 deUint8* const dstPtr = (deUint8*)dst.getDataPtr();
918 const deUint64 compressedBlock = get64BitBlock(src, 0);
920 decompressETC1Block(dstPtr, compressedBlock);
923 void decompressETC2 (const PixelBufferAccess& dst, const deUint8* src)
925 using namespace EtcDecompressInternal;
927 deUint8* const dstPtr = (deUint8*)dst.getDataPtr();
928 const deUint64 compressedBlock = get64BitBlock(src, 0);
930 decompressETC2Block(dstPtr, compressedBlock, NULL, false);
933 void decompressETC2_EAC_RGBA8 (const PixelBufferAccess& dst, const deUint8* src)
935 using namespace EtcDecompressInternal;
937 deUint8* const dstPtr = (deUint8*)dst.getDataPtr();
938 const int dstRowPitch = dst.getRowPitch();
939 const int dstPixelSize = ETC2_UNCOMPRESSED_PIXEL_SIZE_RGBA8;
941 const deUint64 compressedBlockAlpha = get128BitBlockStart(src, 0);
942 const deUint64 compressedBlockRGB = get128BitBlockEnd(src, 0);
943 deUint8 uncompressedBlockAlpha[ETC2_UNCOMPRESSED_BLOCK_SIZE_A8];
944 deUint8 uncompressedBlockRGB[ETC2_UNCOMPRESSED_BLOCK_SIZE_RGB8];
947 decompressETC2Block(uncompressedBlockRGB, compressedBlockRGB, NULL, false);
948 decompressEAC8Block(uncompressedBlockAlpha, compressedBlockAlpha);
951 for (int y = 0; y < (int)ETC2_BLOCK_HEIGHT; y++)
953 for (int x = 0; x < (int)ETC2_BLOCK_WIDTH; x++)
955 const deUint8* const srcPixelRGB = &uncompressedBlockRGB[(y*ETC2_BLOCK_WIDTH + x)*ETC2_UNCOMPRESSED_PIXEL_SIZE_RGB8];
956 const deUint8* const srcPixelAlpha = &uncompressedBlockAlpha[(y*ETC2_BLOCK_WIDTH + x)*ETC2_UNCOMPRESSED_PIXEL_SIZE_A8];
957 deUint8* const dstPixel = dstPtr + y*dstRowPitch + x*dstPixelSize;
959 DE_STATIC_ASSERT(ETC2_UNCOMPRESSED_PIXEL_SIZE_RGBA8 == 4);
960 dstPixel[0] = srcPixelRGB[0];
961 dstPixel[1] = srcPixelRGB[1];
962 dstPixel[2] = srcPixelRGB[2];
963 dstPixel[3] = srcPixelAlpha[0];
968 void decompressETC2_RGB8_PUNCHTHROUGH_ALPHA1 (const PixelBufferAccess& dst, const deUint8* src)
970 using namespace EtcDecompressInternal;
972 deUint8* const dstPtr = (deUint8*)dst.getDataPtr();
973 const int dstRowPitch = dst.getRowPitch();
974 const int dstPixelSize = ETC2_UNCOMPRESSED_PIXEL_SIZE_RGBA8;
976 const deUint64 compressedBlockRGBA = get64BitBlock(src, 0);
977 deUint8 uncompressedBlockRGB[ETC2_UNCOMPRESSED_BLOCK_SIZE_RGB8];
978 deUint8 uncompressedBlockAlpha[ETC2_UNCOMPRESSED_BLOCK_SIZE_A8];
981 decompressETC2Block(uncompressedBlockRGB, compressedBlockRGBA, uncompressedBlockAlpha, DE_TRUE);
984 for (int y = 0; y < (int)ETC2_BLOCK_HEIGHT; y++)
986 for (int x = 0; x < (int)ETC2_BLOCK_WIDTH; x++)
988 const deUint8* const srcPixel = &uncompressedBlockRGB[(y*ETC2_BLOCK_WIDTH + x)*ETC2_UNCOMPRESSED_PIXEL_SIZE_RGB8];
989 const deUint8* const srcPixelAlpha = &uncompressedBlockAlpha[(y*ETC2_BLOCK_WIDTH + x)*ETC2_UNCOMPRESSED_PIXEL_SIZE_A8];
990 deUint8* const dstPixel = dstPtr + y*dstRowPitch + x*dstPixelSize;
992 DE_STATIC_ASSERT(ETC2_UNCOMPRESSED_PIXEL_SIZE_RGBA8 == 4);
993 dstPixel[0] = srcPixel[0];
994 dstPixel[1] = srcPixel[1];
995 dstPixel[2] = srcPixel[2];
996 dstPixel[3] = srcPixelAlpha[0];
1001 void decompressEAC_R11 (const PixelBufferAccess& dst, const deUint8* src, bool signedMode)
1003 using namespace EtcDecompressInternal;
1005 deUint8* const dstPtr = (deUint8*)dst.getDataPtr();
1006 const int dstRowPitch = dst.getRowPitch();
1007 const int dstPixelSize = ETC2_UNCOMPRESSED_PIXEL_SIZE_R11;
1009 const deUint64 compressedBlock = get64BitBlock(src, 0);
1010 deUint8 uncompressedBlock[ETC2_UNCOMPRESSED_BLOCK_SIZE_R11];
1013 decompressEAC11Block(uncompressedBlock, compressedBlock, signedMode);
1016 for (int y = 0; y < (int)ETC2_BLOCK_HEIGHT; y++)
1018 for (int x = 0; x < (int)ETC2_BLOCK_WIDTH; x++)
1020 DE_STATIC_ASSERT(ETC2_UNCOMPRESSED_PIXEL_SIZE_R11 == 2);
1024 const deInt16* const srcPixel = (deInt16*)&uncompressedBlock[(y*ETC2_BLOCK_WIDTH + x)*ETC2_UNCOMPRESSED_PIXEL_SIZE_R11];
1025 deInt16* const dstPixel = (deInt16*)(dstPtr + y*dstRowPitch + x*dstPixelSize);
1027 dstPixel[0] = extend11To16WithSign(srcPixel[0]);
1031 const deUint16* const srcPixel = (deUint16*)&uncompressedBlock[(y*ETC2_BLOCK_WIDTH + x)*ETC2_UNCOMPRESSED_PIXEL_SIZE_R11];
1032 deUint16* const dstPixel = (deUint16*)(dstPtr + y*dstRowPitch + x*dstPixelSize);
1034 dstPixel[0] = extend11To16(srcPixel[0]);
1040 void decompressEAC_RG11 (const PixelBufferAccess& dst, const deUint8* src, bool signedMode)
1042 using namespace EtcDecompressInternal;
1044 deUint8* const dstPtr = (deUint8*)dst.getDataPtr();
1045 const int dstRowPitch = dst.getRowPitch();
1046 const int dstPixelSize = ETC2_UNCOMPRESSED_PIXEL_SIZE_RG11;
1048 const deUint64 compressedBlockR = get128BitBlockStart(src, 0);
1049 const deUint64 compressedBlockG = get128BitBlockEnd(src, 0);
1050 deUint8 uncompressedBlockR[ETC2_UNCOMPRESSED_BLOCK_SIZE_R11];
1051 deUint8 uncompressedBlockG[ETC2_UNCOMPRESSED_BLOCK_SIZE_R11];
1054 decompressEAC11Block(uncompressedBlockR, compressedBlockR, signedMode);
1055 decompressEAC11Block(uncompressedBlockG, compressedBlockG, signedMode);
1058 for (int y = 0; y < (int)ETC2_BLOCK_HEIGHT; y++)
1060 for (int x = 0; x < (int)ETC2_BLOCK_WIDTH; x++)
1062 DE_STATIC_ASSERT(ETC2_UNCOMPRESSED_PIXEL_SIZE_RG11 == 4);
1066 const deInt16* const srcPixelR = (deInt16*)&uncompressedBlockR[(y*ETC2_BLOCK_WIDTH + x)*ETC2_UNCOMPRESSED_PIXEL_SIZE_R11];
1067 const deInt16* const srcPixelG = (deInt16*)&uncompressedBlockG[(y*ETC2_BLOCK_WIDTH + x)*ETC2_UNCOMPRESSED_PIXEL_SIZE_R11];
1068 deInt16* const dstPixel = (deInt16*)(dstPtr + y*dstRowPitch + x*dstPixelSize);
1070 dstPixel[0] = extend11To16WithSign(srcPixelR[0]);
1071 dstPixel[1] = extend11To16WithSign(srcPixelG[0]);
1075 const deUint16* const srcPixelR = (deUint16*)&uncompressedBlockR[(y*ETC2_BLOCK_WIDTH + x)*ETC2_UNCOMPRESSED_PIXEL_SIZE_R11];
1076 const deUint16* const srcPixelG = (deUint16*)&uncompressedBlockG[(y*ETC2_BLOCK_WIDTH + x)*ETC2_UNCOMPRESSED_PIXEL_SIZE_R11];
1077 deUint16* const dstPixel = (deUint16*)(dstPtr + y*dstRowPitch + x*dstPixelSize);
1079 dstPixel[0] = extend11To16(srcPixelR[0]);
1080 dstPixel[1] = extend11To16(srcPixelG[0]);
1086 namespace BcDecompressInternal
1095 static const deUint8 epBits[14] = { 10, 7, 11, 11, 11, 9, 8, 8, 8, 6, 10, 11, 12, 16 };
1097 static const deUint8 partitions2[64][16] =
1099 { 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1 },
1100 { 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1 },
1101 { 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1 },
1102 { 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1 },
1103 { 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 1 },
1104 { 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1 },
1105 { 0, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1 },
1106 { 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1 },
1107 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1 },
1108 { 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
1109 { 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1 },
1110 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1 },
1111 { 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
1112 { 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1 },
1113 { 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
1114 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1 },
1115 { 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1 },
1116 { 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0 },
1117 { 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0 },
1118 { 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0 },
1119 { 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0 },
1120 { 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0 },
1121 { 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0 },
1122 { 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1 },
1123 { 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0 },
1124 { 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0 },
1125 { 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0 },
1126 { 0, 0, 1, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0 },
1127 { 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0 },
1128 { 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0 },
1129 { 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 0 },
1130 { 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0 },
1131 { 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1 },
1132 { 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1 },
1133 { 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0 },
1134 { 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 0, 0 },
1135 { 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0 },
1136 { 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0 },
1137 { 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1 },
1138 { 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1 },
1139 { 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0 },
1140 { 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0 },
1141 { 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0 },
1142 { 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0 },
1143 { 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0 },
1144 { 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1 },
1145 { 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1 },
1146 { 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0 },
1147 { 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0 },
1148 { 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0 },
1149 { 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0 },
1150 { 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0 },
1151 { 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1 },
1152 { 0, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1 },
1153 { 0, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0 },
1154 { 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0 },
1155 { 0, 1, 1, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1 },
1156 { 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1 },
1157 { 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1 },
1158 { 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1 },
1159 { 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1 },
1160 { 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0 },
1161 { 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0 },
1162 { 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1 }
1165 static const deUint8 partitions3[64][16] =
1167 { 0, 0, 1, 1, 0, 0, 1, 1, 0, 2, 2, 1, 2, 2, 2, 2 },
1168 { 0, 0, 0, 1, 0, 0, 1, 1, 2, 2, 1, 1, 2, 2, 2, 1 },
1169 { 0, 0, 0, 0, 2, 0, 0, 1, 2, 2, 1, 1, 2, 2, 1, 1 },
1170 { 0, 2, 2, 2, 0, 0, 2, 2, 0, 0, 1, 1, 0, 1, 1, 1 },
1171 { 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 2, 2, 1, 1, 2, 2 },
1172 { 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 2, 2, 0, 0, 2, 2 },
1173 { 0, 0, 2, 2, 0, 0, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1 },
1174 { 0, 0, 1, 1, 0, 0, 1, 1, 2, 2, 1, 1, 2, 2, 1, 1 },
1175 { 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2 },
1176 { 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2 },
1177 { 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2 },
1178 { 0, 0, 1, 2, 0, 0, 1, 2, 0, 0, 1, 2, 0, 0, 1, 2 },
1179 { 0, 1, 1, 2, 0, 1, 1, 2, 0, 1, 1, 2, 0, 1, 1, 2 },
1180 { 0, 1, 2, 2, 0, 1, 2, 2, 0, 1, 2, 2, 0, 1, 2, 2 },
1181 { 0, 0, 1, 1, 0, 1, 1, 2, 1, 1, 2, 2, 1, 2, 2, 2 },
1182 { 0, 0, 1, 1, 2, 0, 0, 1, 2, 2, 0, 0, 2, 2, 2, 0 },
1183 { 0, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 2, 1, 1, 2, 2 },
1184 { 0, 1, 1, 1, 0, 0, 1, 1, 2, 0, 0, 1, 2, 2, 0, 0 },
1185 { 0, 0, 0, 0, 1, 1, 2, 2, 1, 1, 2, 2, 1, 1, 2, 2 },
1186 { 0, 0, 2, 2, 0, 0, 2, 2, 0, 0, 2, 2, 1, 1, 1, 1 },
1187 { 0, 1, 1, 1, 0, 1, 1, 1, 0, 2, 2, 2, 0, 2, 2, 2 },
1188 { 0, 0, 0, 1, 0, 0, 0, 1, 2, 2, 2, 1, 2, 2, 2, 1 },
1189 { 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 2, 2, 0, 1, 2, 2 },
1190 { 0, 0, 0, 0, 1, 1, 0, 0, 2, 2, 1, 0, 2, 2, 1, 0 },
1191 { 0, 1, 2, 2, 0, 1, 2, 2, 0, 0, 1, 1, 0, 0, 0, 0 },
1192 { 0, 0, 1, 2, 0, 0, 1, 2, 1, 1, 2, 2, 2, 2, 2, 2 },
1193 { 0, 1, 1, 0, 1, 2, 2, 1, 1, 2, 2, 1, 0, 1, 1, 0 },
1194 { 0, 0, 0, 0, 0, 1, 1, 0, 1, 2, 2, 1, 1, 2, 2, 1 },
1195 { 0, 0, 2, 2, 1, 1, 0, 2, 1, 1, 0, 2, 0, 0, 2, 2 },
1196 { 0, 1, 1, 0, 0, 1, 1, 0, 2, 0, 0, 2, 2, 2, 2, 2 },
1197 { 0, 0, 1, 1, 0, 1, 2, 2, 0, 1, 2, 2, 0, 0, 1, 1 },
1198 { 0, 0, 0, 0, 2, 0, 0, 0, 2, 2, 1, 1, 2, 2, 2, 1 },
1199 { 0, 0, 0, 0, 0, 0, 0, 2, 1, 1, 2, 2, 1, 2, 2, 2 },
1200 { 0, 2, 2, 2, 0, 0, 2, 2, 0, 0, 1, 2, 0, 0, 1, 1 },
1201 { 0, 0, 1, 1, 0, 0, 1, 2, 0, 0, 2, 2, 0, 2, 2, 2 },
1202 { 0, 1, 2, 0, 0, 1, 2, 0, 0, 1, 2, 0, 0, 1, 2, 0 },
1203 { 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 0, 0, 0, 0 },
1204 { 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0 },
1205 { 0, 1, 2, 0, 2, 0, 1, 2, 1, 2, 0, 1, 0, 1, 2, 0 },
1206 { 0, 0, 1, 1, 2, 2, 0, 0, 1, 1, 2, 2, 0, 0, 1, 1 },
1207 { 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 0, 0, 0, 0, 1, 1 },
1208 { 0, 1, 0, 1, 0, 1, 0, 1, 2, 2, 2, 2, 2, 2, 2, 2 },
1209 { 0, 0, 0, 0, 0, 0, 0, 0, 2, 1, 2, 1, 2, 1, 2, 1 },
1210 { 0, 0, 2, 2, 1, 1, 2, 2, 0, 0, 2, 2, 1, 1, 2, 2 },
1211 { 0, 0, 2, 2, 0, 0, 1, 1, 0, 0, 2, 2, 0, 0, 1, 1 },
1212 { 0, 2, 2, 0, 1, 2, 2, 1, 0, 2, 2, 0, 1, 2, 2, 1 },
1213 { 0, 1, 0, 1, 2, 2, 2, 2, 2, 2, 2, 2, 0, 1, 0, 1 },
1214 { 0, 0, 0, 0, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1 },
1215 { 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 2, 2, 2, 2 },
1216 { 0, 2, 2, 2, 0, 1, 1, 1, 0, 2, 2, 2, 0, 1, 1, 1 },
1217 { 0, 0, 0, 2, 1, 1, 1, 2, 0, 0, 0, 2, 1, 1, 1, 2 },
1218 { 0, 0, 0, 0, 2, 1, 1, 2, 2, 1, 1, 2, 2, 1, 1, 2 },
1219 { 0, 2, 2, 2, 0, 1, 1, 1, 0, 1, 1, 1, 0, 2, 2, 2 },
1220 { 0, 0, 0, 2, 1, 1, 1, 2, 1, 1, 1, 2, 0, 0, 0, 2 },
1221 { 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 2, 2, 2, 2 },
1222 { 0, 0, 0, 0, 0, 0, 0, 0, 2, 1, 1, 2, 2, 1, 1, 2 },
1223 { 0, 1, 1, 0, 0, 1, 1, 0, 2, 2, 2, 2, 2, 2, 2, 2 },
1224 { 0, 0, 2, 2, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 2, 2 },
1225 { 0, 0, 2, 2, 1, 1, 2, 2, 1, 1, 2, 2, 0, 0, 2, 2 },
1226 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 1, 1, 2 },
1227 { 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 1 },
1228 { 0, 2, 2, 2, 1, 2, 2, 2, 0, 2, 2, 2, 1, 2, 2, 2 },
1229 { 0, 1, 0, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 },
1230 { 0, 1, 1, 1, 2, 0, 1, 1, 2, 2, 0, 1, 2, 2, 2, 0 }
1233 static const deUint8 anchorIndicesSecondSubset2[64] = { 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 2, 8, 2, 2, 8, 8, 15, 2, 8, 2, 2, 8, 8, 2, 2,
1234 15, 15, 6, 8, 2, 8, 15, 15, 2, 8, 2, 2, 2, 15, 15, 6, 6, 2, 6, 8, 15, 15, 2, 2, 15, 15, 15, 15, 15, 2, 2, 15 };
1236 static const deUint8 anchorIndicesSecondSubset3[64] = { 3, 3, 15, 15, 8, 3, 15, 15, 8, 8, 6, 6, 6, 5, 3, 3, 3, 3, 8, 15, 3, 3, 6, 10, 5, 8, 8, 6, 8, 5, 15, 15,
1237 8, 15, 3, 5, 6, 10, 8, 15, 15, 3, 15, 5, 15, 15, 15, 15, 3, 15, 5, 5, 5, 8, 5, 10, 5, 10, 8, 13, 15, 12, 3, 3 };
1239 static const deUint8 anchorIndicesThirdSubset[64] = { 15, 8, 8, 3, 15, 15, 3, 8, 15, 15, 15, 15, 15, 15, 15, 8, 15, 8, 15, 3, 15, 8, 15, 8, 3, 15, 6, 10, 15, 15, 10, 8,
1240 15, 3, 15, 10, 10, 8, 9, 10, 6, 15, 8, 15, 3, 6, 6, 8, 15, 3, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 3, 15, 15, 8 };
1242 static const deUint16 weights2[4] = { 0, 21, 43, 64 };
1243 static const deUint16 weights3[8] = { 0, 9, 18, 27, 37, 46, 55, 64 };
1244 static const deUint16 weights4[16] = { 0, 4, 9, 13, 17, 21, 26, 30, 34, 38, 43, 47, 51, 55, 60, 64 };
1246 inline float uint8ToFloat (deUint8 src)
1248 return ((float)src / 255.0f);
1251 inline float int8ToFloat (deInt8 src)
1253 return ((float)src / 128.0f);
1256 inline deUint32 bgr16torgba32 (deUint16 src)
1258 const deUint32 src32 = src;
1259 const deUint8 b5 = (src32 & 0x1f);
1260 const deUint8 g6 = (src32 >> 5) & 0x3f;
1261 const deUint8 r5 = (src32 >> 11) & 0x1f;
1262 const deUint32 a8 = 0xff;
1263 const deUint32 b8 = extend5To8(b5);
1264 const deUint32 g8 = extend6To8(g6);
1265 const deUint32 r8 = extend5To8(r5);
1267 return (r8 | (g8 <<8) | (b8 << 16) | (a8 << 24));
1270 // Interpolates color = 1/3 * c0 + 2/3 * c1
1271 inline deUint32 interpolateColor (deUint32 c0, deUint32 c1)
1273 const deUint32 r0 = c0 & 0xff;
1274 const deUint32 g0 = (c0 >> 8) & 0xff;
1275 const deUint32 b0 = (c0 >> 16) & 0xff;
1276 const deUint32 a0 = (c0 >> 24) & 0xff;
1278 const deUint32 r1 = c1 & 0xff;
1279 const deUint32 g1 = (c1 >> 8) & 0xff;
1280 const deUint32 b1 = (c1 >> 16) & 0xff;
1281 const deUint32 a1 = (c1 >> 24) & 0xff;
1283 const deUint32 r = (r0 + (r1 << 1)) / 3;
1284 const deUint32 g = (g0 + (g1 << 1)) / 3;
1285 const deUint32 b = (b0 + (b1 << 1)) / 3;
1286 const deUint32 a = (a0 + (a1 << 1)) / 3;
1288 return (r | (g << 8) | (b << 16) | (a << 24));
1291 // Average of two colors
1292 inline deUint32 averageColor (deUint32 c0, deUint32 c1)
1294 const deUint32 r0 = c0 & 0xff;
1295 const deUint32 g0 = (c0 >> 8) & 0xff;
1296 const deUint32 b0 = (c0 >> 16) & 0xff;
1297 const deUint32 a0 = (c0 >> 24) & 0xff;
1299 const deUint32 r1 = c1 & 0xff;
1300 const deUint32 g1 = (c1 >> 8) & 0xff;
1301 const deUint32 b1 = (c1 >> 16) & 0xff;
1302 const deUint32 a1 = (c1 >> 24) & 0xff;
1304 const deUint32 r = (r0 + r1) >> 1;
1305 const deUint32 g = (g0 + g1) >> 1;
1306 const deUint32 b = (b0 + b1) >> 1;
1307 const deUint32 a = (a0 + a1) >> 1;
1309 return (r | (g << 8) | (b << 16) | (a << 24));
1312 inline deInt8 extractModeBc6 (deUint8 src)
1314 // Catch illegal modes
1328 case 2: return (deInt8)(2 + ((src >> 2) & 0x7));
1329 case 3: return (deInt8)(10 + ((src >> 2) & 0x7));
1335 inline deInt8 extractModeBc7 (deUint8 src)
1337 for (deInt8 i = 0; i < 8; i++)
1344 inline deUint64 get64BitBlockLE (const deUint8* src, int blockNdx)
1346 // Same as get64BitBlock, but little-endian.
1349 for (int i = 0; i < 8; i++)
1350 block |= (deUint64)(src[blockNdx*8+i]) << (8ull*i);
1355 inline deUint32 getBits128 (deUint64 low, deUint64 high, deUint32 first, deUint32 last)
1357 const deUint64 d[2] = { low, high };
1358 const bool reverse = first > last;
1363 const deUint32 tmp = first;
1368 const int elementFirst = first / 64;
1369 const int elementLast = last / 64;
1371 if (elementFirst == elementLast)
1373 // Bits contained in one of the 64bit elements
1374 const deUint32 shift = first % 64;
1375 const deUint32 len = last - first + 1;
1376 const deUint32 mask = (1 << len) - 1;
1377 ret = (deUint32)((d[elementFirst] >> shift) & mask);
1381 // Bits contained in both of the 64bit elements
1382 DE_ASSERT(last > 63);
1383 DE_ASSERT(first < 64);
1384 const deUint32 len0 = 64 - first;
1385 const deUint32 mask0 = (1 << len0) - 1;
1386 const deUint32 data0 = (deUint32)(low >> first) & mask0;
1387 const deUint32 len1 = last - 63;
1388 const deUint32 mask1 = (1 << len1) - 1;
1389 const deUint32 data1 = (deUint32)(high & mask1);
1390 ret = (deUint32)((data1 << len0) | data0);
1395 const deUint32 len = last - first + 1;
1396 const deUint32 orig = ret;
1399 for (deUint32 i = 0; i < len; i++)
1401 ret |= ((orig >> (len - 1 - i)) & 1) << i;
1408 inline deInt32 signExtend (deInt32 value, deInt32 srcBits, deInt32 dstBits)
1410 deUint32 sign = value & (1 << (srcBits - 1));
1412 if (!sign) return value;
1414 deInt32 dstMask = (deInt32)(((deUint64)1 << dstBits) - 1);
1415 deInt32 extendedBits = 0xffffffff << srcBits;
1416 return (value | extendedBits) & dstMask;
1419 inline deInt32 unquantize (deInt32 x, int mode, bool hasSign)
1425 if (epBits[mode] >= 16) return x;
1435 else if (x >= (((deInt32)1 << (epBits[mode] - 1)) - 1))
1438 x = (((deInt32)x << 15) + 0x4000) >> (epBits[mode] - 1);
1447 if (epBits[mode] >= 15)
1451 else if (x == (((deInt32)1 << epBits[mode]) - 1))
1454 return ((((deInt32)x << 15) + 0x4000) >> (epBits[mode] - 1));
1458 inline deInt32 interpolate (deInt32 a, deInt32 b, deUint32 index, deUint32 indexPrecision)
1460 const deUint16* weights[] = {weights2, weights3, weights4};
1461 const deUint16* weight = weights[indexPrecision-2];
1462 DE_ASSERT(indexPrecision >= 2 && indexPrecision <= 4);
1464 return (((64 - weight[index]) * a + weight[index] * b + 32) >> 6);
1467 inline deInt16 finishUnquantize (deInt32 x, bool hasSign)
1472 x = -(((-x) * 31) >> 5);
1487 } // BcDecompressInternal
1489 void decompressBc1 (const PixelBufferAccess& dst, const deUint8* src, bool hasAlpha)
1491 using namespace BcDecompressInternal;
1493 deUint8* const dstPtr = (deUint8*)dst.getDataPtr();
1494 const deUint32 dstRowPitch = dst.getRowPitch();
1495 const deUint32 dstPixelSize = 4;
1496 const deUint16 color0_16 = ((deUint16*)src)[0];
1497 const deUint16 color1_16 = ((deUint16*)src)[1];
1498 const deUint32 color0 = bgr16torgba32(color0_16);
1499 const deUint32 color1 = bgr16torgba32(color1_16);
1500 const deUint8* const indices8 = &src[4];
1502 const bool alphaMode = color1_16 > color0_16;
1504 const deInt32 indices[16] =
1506 (indices8[0] >> 0) & 0x3,
1507 (indices8[0] >> 2) & 0x3,
1508 (indices8[0] >> 4) & 0x3,
1509 (indices8[0] >> 6) & 0x3,
1510 (indices8[1] >> 0) & 0x3,
1511 (indices8[1] >> 2) & 0x3,
1512 (indices8[1] >> 4) & 0x3,
1513 (indices8[1] >> 6) & 0x3,
1514 (indices8[2] >> 0) & 0x3,
1515 (indices8[2] >> 2) & 0x3,
1516 (indices8[2] >> 4) & 0x3,
1517 (indices8[2] >> 6) & 0x3,
1518 (indices8[3] >> 0) & 0x3,
1519 (indices8[3] >> 2) & 0x3,
1520 (indices8[3] >> 4) & 0x3,
1521 (indices8[3] >> 6) & 0x3
1524 const deUint32 colors[4] =
1528 alphaMode ? averageColor(color0, color1) : interpolateColor(color1, color0),
1529 alphaMode ? (hasAlpha ? 0 : 0xff000000) : interpolateColor(color0, color1)
1532 for (deUint32 y = 0; y < (deUint32)BC_BLOCK_HEIGHT; y++)
1534 for (deUint32 x = 0; x < (deUint32)BC_BLOCK_WIDTH; x++)
1536 deUint32* const dstPixel = (deUint32*)(dstPtr + y * dstRowPitch + x * dstPixelSize);
1537 *dstPixel = colors[indices[y * BC_BLOCK_WIDTH + x]];
1542 void decompressBc2 (const PixelBufferAccess& dst, const deUint8* src)
1544 using namespace BcDecompressInternal;
1546 deUint8* const dstPtr = (deUint8*)dst.getDataPtr();
1547 const deUint32 dstRowPitch = dst.getRowPitch();
1548 const deUint32 dstPixelSize = 4;
1549 const deUint16 color0_16 = ((deUint16*)src)[4];
1550 const deUint16 color1_16 = ((deUint16*)src)[5];
1551 const deUint32 color0 = bgr16torgba32(color0_16);
1552 const deUint32 color1 = bgr16torgba32(color1_16);
1553 const deUint8* const indices8 = &src[12];
1554 const deUint8* const alphas8 = src;
1556 const deInt32 indices[16] =
1558 (indices8[0] >> 0) & 0x3,
1559 (indices8[0] >> 2) & 0x3,
1560 (indices8[0] >> 4) & 0x3,
1561 (indices8[0] >> 6) & 0x3,
1562 (indices8[1] >> 0) & 0x3,
1563 (indices8[1] >> 2) & 0x3,
1564 (indices8[1] >> 4) & 0x3,
1565 (indices8[1] >> 6) & 0x3,
1566 (indices8[2] >> 0) & 0x3,
1567 (indices8[2] >> 2) & 0x3,
1568 (indices8[2] >> 4) & 0x3,
1569 (indices8[2] >> 6) & 0x3,
1570 (indices8[3] >> 0) & 0x3,
1571 (indices8[3] >> 2) & 0x3,
1572 (indices8[3] >> 4) & 0x3,
1573 (indices8[3] >> 6) & 0x3
1576 const deInt32 alphas[16] =
1578 extend4To8(((alphas8[0] >> 0) & 0xf)) << 24,
1579 extend4To8(((alphas8[0] >> 4) & 0xf)) << 24,
1580 extend4To8(((alphas8[1] >> 0) & 0xf)) << 24,
1581 extend4To8(((alphas8[1] >> 4) & 0xf)) << 24,
1582 extend4To8(((alphas8[2] >> 0) & 0xf)) << 24,
1583 extend4To8(((alphas8[2] >> 4) & 0xf)) << 24,
1584 extend4To8(((alphas8[3] >> 0) & 0xf)) << 24,
1585 extend4To8(((alphas8[3] >> 4) & 0xf)) << 24,
1586 extend4To8(((alphas8[4] >> 0) & 0xf)) << 24,
1587 extend4To8(((alphas8[4] >> 4) & 0xf)) << 24,
1588 extend4To8(((alphas8[5] >> 0) & 0xf)) << 24,
1589 extend4To8(((alphas8[5] >> 4) & 0xf)) << 24,
1590 extend4To8(((alphas8[6] >> 0) & 0xf)) << 24,
1591 extend4To8(((alphas8[6] >> 4) & 0xf)) << 24,
1592 extend4To8(((alphas8[7] >> 0) & 0xf)) << 24,
1593 extend4To8(((alphas8[7] >> 4) & 0xf)) << 24
1596 const deUint32 colors[4] =
1600 interpolateColor(color1, color0),
1601 interpolateColor(color0, color1)
1604 for (deUint32 y = 0; y < (deUint32)BC_BLOCK_HEIGHT; y++)
1606 for (deUint32 x = 0; x < (deUint32)BC_BLOCK_WIDTH; x++)
1608 deUint32* const dstPixel = (deUint32*)(dstPtr + y * dstRowPitch + x * dstPixelSize);
1609 *dstPixel = (colors[indices[y * BC_BLOCK_WIDTH + x]] & 0x00ffffff) | alphas[y * BC_BLOCK_WIDTH + x];
1614 void decompressBc3 (const PixelBufferAccess& dst, const deUint8* src)
1616 using namespace BcDecompressInternal;
1618 deUint8* const dstPtr = (deUint8*)dst.getDataPtr();
1619 const deUint32 dstRowPitch = dst.getRowPitch();
1620 const deUint32 dstPixelSize = 4;
1621 const deUint8 alpha0 = src[0];
1622 const deUint8 alpha1 = src[1];
1623 const deUint16 color0_16 = ((deUint16*)src)[4];
1624 const deUint16 color1_16 = ((deUint16*)src)[5];
1625 const deUint32 color0 = bgr16torgba32(color0_16);
1626 const deUint32 color1 = bgr16torgba32(color1_16);
1627 const deUint8* const indices8 = &src[12];
1628 const deUint64 alphaBits = get64BitBlockLE(src, 0) >> 16;
1631 const deInt32 indices[16] =
1633 (indices8[0] >> 0) & 0x3,
1634 (indices8[0] >> 2) & 0x3,
1635 (indices8[0] >> 4) & 0x3,
1636 (indices8[0] >> 6) & 0x3,
1637 (indices8[1] >> 0) & 0x3,
1638 (indices8[1] >> 2) & 0x3,
1639 (indices8[1] >> 4) & 0x3,
1640 (indices8[1] >> 6) & 0x3,
1641 (indices8[2] >> 0) & 0x3,
1642 (indices8[2] >> 2) & 0x3,
1643 (indices8[2] >> 4) & 0x3,
1644 (indices8[2] >> 6) & 0x3,
1645 (indices8[3] >> 0) & 0x3,
1646 (indices8[3] >> 2) & 0x3,
1647 (indices8[3] >> 4) & 0x3,
1648 (indices8[3] >> 6) & 0x3
1651 const deInt32 alphaIndices[16] =
1653 (deInt32)((alphaBits >> 0) & 0x7),
1654 (deInt32)((alphaBits >> 3) & 0x7),
1655 (deInt32)((alphaBits >> 6) & 0x7),
1656 (deInt32)((alphaBits >> 9) & 0x7),
1657 (deInt32)((alphaBits >> 12) & 0x7),
1658 (deInt32)((alphaBits >> 15) & 0x7),
1659 (deInt32)((alphaBits >> 18) & 0x7),
1660 (deInt32)((alphaBits >> 21) & 0x7),
1661 (deInt32)((alphaBits >> 24) & 0x7),
1662 (deInt32)((alphaBits >> 27) & 0x7),
1663 (deInt32)((alphaBits >> 30) & 0x7),
1664 (deInt32)((alphaBits >> 33) & 0x7),
1665 (deInt32)((alphaBits >> 36) & 0x7),
1666 (deInt32)((alphaBits >> 39) & 0x7),
1667 (deInt32)((alphaBits >> 42) & 0x7),
1668 (deInt32)((alphaBits >> 45) & 0x7)
1671 const deUint32 colors[4] =
1675 interpolateColor(color1, color0),
1676 interpolateColor(color0, color1)
1679 alphas[0] = alpha0 << 24;
1680 alphas[1] = alpha1 << 24;
1682 if (alpha0 > alpha1)
1684 for (deUint32 i = 0; i < 6; i++)
1685 alphas[i + 2] = (((deUint32)alpha0 * (6 - i) + (deUint32)alpha1 * (1 + i)) / 7) << 24;
1689 for (deUint32 i = 0; i < 4; i++)
1690 alphas[i + 2] = (((deUint32)alpha0 * (4 - i) + (deUint32)alpha1 * (1 + i)) / 5) << 24;
1692 alphas[7] = 0xff000000;
1695 for (deUint32 y = 0; y < (deUint32)BC_BLOCK_HEIGHT; y++)
1697 for (deUint32 x = 0; x < (deUint32)BC_BLOCK_WIDTH; x++)
1699 deUint32* const dstPixel = (deUint32*)(dstPtr + y * dstRowPitch + x * dstPixelSize);
1700 *dstPixel = (colors[indices[y * BC_BLOCK_WIDTH + x]] & 0x00ffffff) | alphas[alphaIndices[y * BC_BLOCK_WIDTH + x]];
1705 void decompressBc4 (const PixelBufferAccess& dst, const deUint8* src, bool hasSign)
1707 using namespace BcDecompressInternal;
1709 deUint8* const dstPtr = (deUint8*)dst.getDataPtr();
1710 const deUint32 dstRowPitch = dst.getRowPitch();
1711 const deUint32 dstPixelSize = 4;
1712 const deUint8 red0 = src[0];
1713 const deUint8 red1 = src[1];
1714 const deInt8 red0s = ((deInt8*)src)[0];
1715 const deInt8 red1s = ((deInt8*)src)[1];
1716 const deUint64 indexBits = get64BitBlockLE(src, 0) >> 16;
1719 const deInt32 indices[16] =
1721 (deInt32)((indexBits >> 0) & 0x7),
1722 (deInt32)((indexBits >> 3) & 0x7),
1723 (deInt32)((indexBits >> 6) & 0x7),
1724 (deInt32)((indexBits >> 9) & 0x7),
1725 (deInt32)((indexBits >> 12) & 0x7),
1726 (deInt32)((indexBits >> 15) & 0x7),
1727 (deInt32)((indexBits >> 18) & 0x7),
1728 (deInt32)((indexBits >> 21) & 0x7),
1729 (deInt32)((indexBits >> 24) & 0x7),
1730 (deInt32)((indexBits >> 27) & 0x7),
1731 (deInt32)((indexBits >> 30) & 0x7),
1732 (deInt32)((indexBits >> 33) & 0x7),
1733 (deInt32)((indexBits >> 36) & 0x7),
1734 (deInt32)((indexBits >> 39) & 0x7),
1735 (deInt32)((indexBits >> 42) & 0x7),
1736 (deInt32)((indexBits >> 45) & 0x7)
1739 reds[0] = hasSign ? int8ToFloat(red0s) : uint8ToFloat(red0);
1740 reds[1] = hasSign ? int8ToFloat(red1s) : uint8ToFloat(red1);
1742 if (reds[0] > reds[1])
1744 for (deUint32 i = 0; i < 6; i++)
1745 reds[i + 2] = (reds[0] * (6.0f - (float)i) + reds[1] * (1.0f + (float)i)) / 7.0f;
1749 for (deUint32 i = 0; i < 4; i++)
1750 reds[i + 2] = (reds[0] * (4.0f - (float)i) + reds[1] * (1.0f + (float)i)) / 5.0f;
1751 reds[6] = hasSign ? -1.0f : 0.0f;
1755 for (deUint32 y = 0; y < (deUint32)BC_BLOCK_HEIGHT; y++)
1757 for (deUint32 x = 0; x < (deUint32)BC_BLOCK_WIDTH; x++)
1759 float* const dstPixel = (float*)(dstPtr + y * dstRowPitch + x * dstPixelSize);
1760 *dstPixel = reds[indices[y * BC_BLOCK_WIDTH + x]];
1765 void decompressBc5 (const PixelBufferAccess& dst, const deUint8* src, bool hasSign)
1767 using namespace BcDecompressInternal;
1769 deUint8* const dstPtr = (deUint8*)dst.getDataPtr();
1770 const deUint32 dstRowPitch = dst.getRowPitch();
1771 const deUint32 dstPixelSize = 8;
1773 deUint32 indices[2][16];
1775 for (deUint32 c = 0; c < 2; c++)
1777 const deUint32 offset = c * 8;
1778 const deUint8 rg0 = src[offset];
1779 const deUint8 rg1 = src[offset + 1];
1780 const deInt8 rg0s = ((deInt8*)src)[offset];
1781 const deInt8 rg1s = ((deInt8*)src)[offset + 1];
1782 const deUint64 indexBits = get64BitBlockLE(src, c) >> 16;
1784 for (deUint32 i = 0; i < 16; i++)
1785 indices[c][i] = (indexBits >> (i * 3)) & 0x7;
1787 rg[c][0] = hasSign ? int8ToFloat(rg0s) : uint8ToFloat(rg0);
1788 rg[c][1] = hasSign ? int8ToFloat(rg1s) : uint8ToFloat(rg1);
1790 if (rg[c][0] > rg[c][1])
1792 for (deUint32 i = 0; i < 6; i++)
1793 rg[c][i + 2] = (rg[c][0] * (6.0f - (float)i) + rg[c][1] * (1.0f + (float)i)) / 7.0f;
1797 for (deUint32 i = 0; i < 4; i++)
1798 rg[c][i + 2] = (rg[c][0] * (4.0f - (float)i) + rg[c][1] * (1.0f + (float)i)) / 5.0f;
1799 rg[c][6] = hasSign ? -1.0f : 0.0f;
1804 for (deUint32 y = 0; y < (deUint32)BC_BLOCK_HEIGHT; y++)
1806 for (deUint32 x = 0; x < (deUint32)BC_BLOCK_WIDTH; x++)
1808 float* const dstPixel = (float*)(dstPtr + y * dstRowPitch + x * dstPixelSize);
1809 for (deUint32 i = 0; i < 2; i++)
1810 dstPixel[i] = rg[i][indices[i][y * BC_BLOCK_WIDTH + x]];
1815 void decompressBc6H (const PixelBufferAccess& dst, const deUint8* src, bool hasSign)
1817 using namespace BcDecompressInternal;
1819 deUint8* const dstPtr = (deUint8*)dst.getDataPtr();
1820 const deUint32 dstRowPitch = dst.getRowPitch();
1821 const deUint32 dstPixelSize = 6;
1823 deInt32 mode = extractModeBc6(src[0]);
1827 deUint32 deltaBitsR = 0;
1828 deUint32 deltaBitsG = 0;
1829 deUint32 deltaBitsB = 0;
1830 const deUint64 low = ((deUint64*)src)[0];
1831 const deUint64 high = ((deUint64*)src)[1];
1832 const deUint32 d = mode < 10 ? getBits128(low, high, 77, 81) : 0;
1833 const deUint32 numRegions = mode > 9 ? 1 : 2;
1834 const deUint32 numEndpoints = numRegions * 2;
1835 const bool transformed = mode != 9 && mode != 10;
1836 const deUint32 colorIndexBC = mode < 10 ? 3 : 4;
1837 deUint64 colorIndexData = high >> (mode < 10 ? 18 : 1);
1838 const deUint32 anchorIndex[2] = { 0, anchorIndicesSecondSubset2[d] };
1843 g[2] |= getBits128(low, high, 2, 2) << 4;
1844 b[2] |= getBits128(low, high, 3, 3) << 4;
1845 b[3] |= getBits128(low, high, 4, 4) << 4;
1846 r[0] |= getBits128(low, high, 5, 14);
1847 g[0] |= getBits128(low, high, 15, 24);
1848 b[0] |= getBits128(low, high, 25, 34);
1849 r[1] |= getBits128(low, high, 35, 39);
1850 g[3] |= getBits128(low, high, 40, 40) << 4;
1851 g[2] |= getBits128(low, high, 41, 44);
1852 g[1] |= getBits128(low, high, 45, 49);
1853 b[3] |= getBits128(low, high, 50, 50);
1854 g[3] |= getBits128(low, high, 51, 54);
1855 b[1] |= getBits128(low, high, 55, 59);
1856 b[3] |= getBits128(low, high, 60, 60) << 1;
1857 b[2] |= getBits128(low, high, 61, 64);
1858 r[2] |= getBits128(low, high, 65, 69);
1859 b[3] |= getBits128(low, high, 70, 70) << 2;
1860 r[3] |= getBits128(low, high, 71, 75);
1861 b[3] |= getBits128(low, high, 76, 76) << 3;
1862 deltaBitsR = deltaBitsG = deltaBitsB = 5;
1866 g[2] |= getBits128(low, high, 2, 2) << 5;
1867 g[3] |= getBits128(low, high, 3, 3) << 4;
1868 g[3] |= getBits128(low, high, 4, 4) << 5;
1869 r[0] |= getBits128(low, high, 5, 11);
1870 b[3] |= getBits128(low, high, 12, 12);
1871 b[3] |= getBits128(low, high, 13, 13) << 1;
1872 b[2] |= getBits128(low, high, 14, 14) << 4;
1873 g[0] |= getBits128(low, high, 15, 21);
1874 b[2] |= getBits128(low, high, 22, 22) << 5;
1875 b[3] |= getBits128(low, high, 23, 23) << 2;
1876 g[2] |= getBits128(low, high, 24, 24) << 4;
1877 b[0] |= getBits128(low, high, 25, 31);
1878 b[3] |= getBits128(low, high, 32, 32) << 3;
1879 b[3] |= getBits128(low, high, 33, 33) << 5;
1880 b[3] |= getBits128(low, high, 34, 34) << 4;
1881 r[1] |= getBits128(low, high, 35, 40);
1882 g[2] |= getBits128(low, high, 41, 44);
1883 g[1] |= getBits128(low, high, 45, 50);
1884 g[3] |= getBits128(low, high, 51, 54);
1885 b[1] |= getBits128(low, high, 55, 60);
1886 b[2] |= getBits128(low, high, 61, 64);
1887 r[2] |= getBits128(low, high, 65, 70);
1888 r[3] |= getBits128(low, high, 71, 76);
1889 deltaBitsR = deltaBitsG = deltaBitsB = 6;
1893 r[0] |= getBits128(low, high, 5, 14);
1894 g[0] |= getBits128(low, high, 15, 24);
1895 b[0] |= getBits128(low, high, 25, 34);
1896 r[1] |= getBits128(low, high, 35, 39);
1897 r[0] |= getBits128(low, high, 40, 40) << 10;
1898 g[2] |= getBits128(low, high, 41, 44);
1899 g[1] |= getBits128(low, high, 45, 48);
1900 g[0] |= getBits128(low, high, 49, 49) << 10;
1901 b[3] |= getBits128(low, high, 50, 50);
1902 g[3] |= getBits128(low, high, 51, 54);
1903 b[1] |= getBits128(low, high, 55, 58);
1904 b[0] |= getBits128(low, high, 59, 59) << 10;
1905 b[3] |= getBits128(low, high, 60, 60) << 1;
1906 b[2] |= getBits128(low, high, 61, 64);
1907 r[2] |= getBits128(low, high, 65, 69);
1908 b[3] |= getBits128(low, high, 70, 70) << 2;
1909 r[3] |= getBits128(low, high, 71, 75);
1910 b[3] |= getBits128(low, high, 76, 76) << 3;
1912 deltaBitsG = deltaBitsB = 4;
1916 r[0] |= getBits128(low, high, 5, 14);
1917 g[0] |= getBits128(low, high, 15, 24);
1918 b[0] |= getBits128(low, high, 25, 34);
1919 r[1] |= getBits128(low, high, 35, 38);
1920 r[0] |= getBits128(low, high, 39, 39) << 10;
1921 g[3] |= getBits128(low, high, 40, 40) << 4;
1922 g[2] |= getBits128(low, high, 41, 44);
1923 g[1] |= getBits128(low, high, 45, 49);
1924 g[0] |= getBits128(low, high, 50, 50) << 10;
1925 g[3] |= getBits128(low, high, 51, 54);
1926 b[1] |= getBits128(low, high, 55, 58);
1927 b[0] |= getBits128(low, high, 59, 59) << 10;
1928 b[3] |= getBits128(low, high, 60, 60) << 1;
1929 b[2] |= getBits128(low, high, 61, 64);
1930 r[2] |= getBits128(low, high, 65, 68);
1931 b[3] |= getBits128(low, high, 69, 69);
1932 b[3] |= getBits128(low, high, 70, 70) << 2;
1933 r[3] |= getBits128(low, high, 71, 74);
1934 g[2] |= getBits128(low, high, 75, 75) << 4;
1935 b[3] |= getBits128(low, high, 76, 76) << 3;
1936 deltaBitsR = deltaBitsB = 4;
1941 r[0] |= getBits128(low, high, 5, 14);
1942 g[0] |= getBits128(low, high, 15, 24);
1943 b[0] |= getBits128(low, high, 25, 34);
1944 r[1] |= getBits128(low, high, 35, 38);
1945 r[0] |= getBits128(low, high, 39, 39) << 10;
1946 b[2] |= getBits128(low, high, 40, 40) << 4;
1947 g[2] |= getBits128(low, high, 41, 44);
1948 g[1] |= getBits128(low, high, 45, 48);
1949 g[0] |= getBits128(low, high, 49, 49) << 10;
1950 b[3] |= getBits128(low, high, 50, 50);
1951 g[3] |= getBits128(low, high, 51, 54);
1952 b[1] |= getBits128(low, high, 55, 59);
1953 b[0] |= getBits128(low, high, 60, 60) << 10;
1954 b[2] |= getBits128(low, high, 61, 64);
1955 r[2] |= getBits128(low, high, 65, 68);
1956 b[3] |= getBits128(low, high, 69, 69) << 1;
1957 b[3] |= getBits128(low, high, 70, 70) << 2;
1958 r[3] |= getBits128(low, high, 71, 74);
1959 b[3] |= getBits128(low, high, 75, 75) << 4;
1960 b[3] |= getBits128(low, high, 76, 76) << 3;
1961 deltaBitsR = deltaBitsG = 4;
1966 r[0] |= getBits128(low, high, 5, 13);
1967 b[2] |= getBits128(low, high, 14, 14) << 4;
1968 g[0] |= getBits128(low, high, 15, 23);
1969 g[2] |= getBits128(low, high, 24, 24) << 4;
1970 b[0] |= getBits128(low, high, 25, 33);
1971 b[3] |= getBits128(low, high, 34, 34) << 4;
1972 r[1] |= getBits128(low, high, 35, 39);
1973 g[3] |= getBits128(low, high, 40, 40) << 4;
1974 g[2] |= getBits128(low, high, 41, 44);
1975 g[1] |= getBits128(low, high, 45, 49);
1976 b[3] |= getBits128(low, high, 50, 50);
1977 g[3] |= getBits128(low, high, 51, 54);
1978 b[1] |= getBits128(low, high, 55, 59);
1979 b[3] |= getBits128(low, high, 60, 60) << 1;
1980 b[2] |= getBits128(low, high, 61, 64);
1981 r[2] |= getBits128(low, high, 65, 69);
1982 b[3] |= getBits128(low, high, 70, 70) << 2;
1983 r[3] |= getBits128(low, high, 71, 75);
1984 b[3] |= getBits128(low, high, 76, 76) << 3;
1985 deltaBitsR = deltaBitsG = deltaBitsB = 5;
1989 r[0] |= getBits128(low, high, 5, 12);
1990 g[3] |= getBits128(low, high, 13, 13) << 4;
1991 b[2] |= getBits128(low, high, 14, 14) << 4;
1992 g[0] |= getBits128(low, high, 15, 22);
1993 b[3] |= getBits128(low, high, 23, 23) << 2;
1994 g[2] |= getBits128(low, high, 24, 24) << 4;
1995 b[0] |= getBits128(low, high, 25, 32);
1996 b[3] |= getBits128(low, high, 33, 33) << 3;
1997 b[3] |= getBits128(low, high, 34, 34) << 4;
1998 r[1] |= getBits128(low, high, 35, 40);
1999 g[2] |= getBits128(low, high, 41, 44);
2000 g[1] |= getBits128(low, high, 45, 49);
2001 b[3] |= getBits128(low, high, 50, 50);
2002 g[3] |= getBits128(low, high, 51, 54);
2003 b[1] |= getBits128(low, high, 55, 59);
2004 b[3] |= getBits128(low, high, 60, 60) << 1;
2005 b[2] |= getBits128(low, high, 61, 64);
2006 r[2] |= getBits128(low, high, 65, 70);
2007 r[3] |= getBits128(low, high, 71, 76);
2009 deltaBitsG = deltaBitsB = 5;
2013 r[0] |= getBits128(low, high, 5, 12);
2014 b[3] |= getBits128(low, high, 13, 13);
2015 b[2] |= getBits128(low, high, 14, 14) << 4;
2016 g[0] |= getBits128(low, high, 15, 22);
2017 g[2] |= getBits128(low, high, 23, 23) << 5;
2018 g[2] |= getBits128(low, high, 24, 24) << 4;
2019 b[0] |= getBits128(low, high, 25, 32);
2020 g[3] |= getBits128(low, high, 33, 33) << 5;
2021 b[3] |= getBits128(low, high, 34, 34) << 4;
2022 r[1] |= getBits128(low, high, 35, 39);
2023 g[3] |= getBits128(low, high, 40, 40) << 4;
2024 g[2] |= getBits128(low, high, 41, 44);
2025 g[1] |= getBits128(low, high, 45, 50);
2026 g[3] |= getBits128(low, high, 51, 54);
2027 b[1] |= getBits128(low, high, 55, 59);
2028 b[3] |= getBits128(low, high, 60, 60) << 1;
2029 b[2] |= getBits128(low, high, 61, 64);
2030 r[2] |= getBits128(low, high, 65, 69);
2031 b[3] |= getBits128(low, high, 70, 70) << 2;
2032 r[3] |= getBits128(low, high, 71, 75);
2033 b[3] |= getBits128(low, high, 76, 76) << 3;
2034 deltaBitsR = deltaBitsB = 5;
2039 r[0] |= getBits128(low, high, 5, 12);
2040 b[3] |= getBits128(low, high, 13, 13) << 1;
2041 b[2] |= getBits128(low, high, 14, 14) << 4;
2042 g[0] |= getBits128(low, high, 15, 22);
2043 b[2] |= getBits128(low, high, 23, 23) << 5;
2044 g[2] |= getBits128(low, high, 24, 24) << 4;
2045 b[0] |= getBits128(low, high, 25, 32);
2046 b[3] |= getBits128(low, high, 33, 33) << 5;
2047 b[3] |= getBits128(low, high, 34, 34) << 4;
2048 r[1] |= getBits128(low, high, 35, 39);
2049 g[3] |= getBits128(low, high, 40, 40) << 4;
2050 g[2] |= getBits128(low, high, 41, 44);
2051 g[1] |= getBits128(low, high, 45, 49);
2052 b[3] |= getBits128(low, high, 50, 50);
2053 g[3] |= getBits128(low, high, 51, 54);
2054 b[1] |= getBits128(low, high, 55, 60);
2055 b[2] |= getBits128(low, high, 61, 64);
2056 r[2] |= getBits128(low, high, 65, 69);
2057 b[3] |= getBits128(low, high, 70, 70) << 2;
2058 r[3] |= getBits128(low, high, 71, 75);
2059 b[3] |= getBits128(low, high, 76, 76) << 3;
2060 deltaBitsR = deltaBitsG = 5;
2065 r[0] |= getBits128(low, high, 5, 10);
2066 g[3] |= getBits128(low, high, 11, 11) << 4;
2067 b[3] |= getBits128(low, high, 12, 13);
2068 b[2] |= getBits128(low, high, 14, 14) << 4;
2069 g[0] |= getBits128(low, high, 15, 20);
2070 g[2] |= getBits128(low, high, 21, 21) << 5;
2071 b[2] |= getBits128(low, high, 22, 22) << 5;
2072 b[3] |= getBits128(low, high, 23, 23) << 2;
2073 g[2] |= getBits128(low, high, 24, 24) << 4;
2074 b[0] |= getBits128(low, high, 25, 30);
2075 g[3] |= getBits128(low, high, 31, 31) << 5;
2076 b[3] |= getBits128(low, high, 32, 32) << 3;
2077 b[3] |= getBits128(low, high, 33, 33) << 5;
2078 b[3] |= getBits128(low, high, 34, 34) << 4;
2079 r[1] |= getBits128(low, high, 35, 40);
2080 g[2] |= getBits128(low, high, 41, 44);
2081 g[1] |= getBits128(low, high, 45, 50);
2082 g[3] |= getBits128(low, high, 51, 54);
2083 b[1] |= getBits128(low, high, 55, 60);
2084 b[2] |= getBits128(low, high, 61, 64);
2085 r[2] |= getBits128(low, high, 65, 70);
2086 r[3] |= getBits128(low, high, 71, 76);
2087 deltaBitsR = deltaBitsG = deltaBitsB = 6;
2091 r[0] |= getBits128(low, high, 5, 14);
2092 g[0] |= getBits128(low, high, 15, 24);
2093 b[0] |= getBits128(low, high, 25, 34);
2094 r[1] |= getBits128(low, high, 35, 44);
2095 g[1] |= getBits128(low, high, 45, 54);
2096 b[1] |= getBits128(low, high, 55, 64);
2097 deltaBitsR = deltaBitsG = deltaBitsB = 10;
2101 r[0] |= getBits128(low, high, 5, 14);
2102 g[0] |= getBits128(low, high, 15, 24);
2103 b[0] |= getBits128(low, high, 25, 34);
2104 r[1] |= getBits128(low, high, 35, 43);
2105 r[0] |= getBits128(low, high, 44, 44) << 10;
2106 g[1] |= getBits128(low, high, 45, 53);
2107 g[0] |= getBits128(low, high, 54, 54) << 10;
2108 b[1] |= getBits128(low, high, 55, 63);
2109 b[0] |= getBits128(low, high, 64, 64) << 10;
2110 deltaBitsR = deltaBitsG = deltaBitsB = 9;
2114 r[0] |= getBits128(low, high, 5, 14);
2115 g[0] |= getBits128(low, high, 15, 24);
2116 b[0] |= getBits128(low, high, 25, 34);
2117 r[1] |= getBits128(low, high, 35, 42);
2118 r[0] |= getBits128(low, high, 44, 43) << 10;
2119 g[1] |= getBits128(low, high, 45, 52);
2120 g[0] |= getBits128(low, high, 54, 53) << 10;
2121 b[1] |= getBits128(low, high, 55, 62);
2122 b[0] |= getBits128(low, high, 64, 63) << 10;
2123 deltaBitsR = deltaBitsG = deltaBitsB = 8;
2127 r[0] |= getBits128(low, high, 5, 14);
2128 g[0] |= getBits128(low, high, 15, 24);
2129 b[0] |= getBits128(low, high, 25, 34);
2130 r[1] |= getBits128(low, high, 35, 38);
2131 r[0] |= getBits128(low, high, 44, 39) << 10;
2132 g[1] |= getBits128(low, high, 45, 48);
2133 g[0] |= getBits128(low, high, 54, 49) << 10;
2134 b[1] |= getBits128(low, high, 55, 58);
2135 b[0] |= getBits128(low, high, 64, 59) << 10;
2136 deltaBitsR = deltaBitsG = deltaBitsB = 4;
2142 r[0] = signExtend(r[0], epBits[mode], 32);
2143 g[0] = signExtend(g[0], epBits[mode], 32);
2144 b[0] = signExtend(b[0], epBits[mode], 32);
2149 for (deUint32 i = 1; i < numEndpoints; i++)
2151 r[i] = signExtend(r[i], deltaBitsR, 32);
2152 r[i] = (r[0] + r[i]) & (((deUint32)1 << epBits[mode]) - 1);
2153 g[i] = signExtend(g[i], deltaBitsG, 32);
2154 g[i] = (g[0] + g[i]) & (((deUint32)1 << epBits[mode]) - 1);
2155 b[i] = signExtend(b[i], deltaBitsB, 32);
2156 b[i] = (b[0] + b[i]) & (((deUint32)1 << epBits[mode]) - 1);
2162 for (deUint32 i = 1; i < 4; i++)
2164 r[i] = signExtend(r[i], epBits[mode], 32);
2165 g[i] = signExtend(g[i], epBits[mode], 32);
2166 b[i] = signExtend(b[i], epBits[mode], 32);
2170 for (deUint32 i = 0; i < numEndpoints; i++)
2172 r[i] = unquantize(r[i], mode, hasSign);
2173 g[i] = unquantize(g[i], mode, hasSign);
2174 b[i] = unquantize(b[i], mode, hasSign);
2177 for (deUint32 i = 0; i < 16; i++)
2179 const deUint32 subsetIndex = (numRegions == 1 ? 0 : partitions2[d][i]);
2180 const deUint32 bits = (i == anchorIndex[subsetIndex]) ? (colorIndexBC - 1) : colorIndexBC;
2181 const deUint32 colorIndex = (deUint32)(colorIndexData & ((1 << bits) - 1));
2182 const deInt32 endpointStartR = r[2 * subsetIndex];
2183 const deInt32 endpointEndR = r[2 * subsetIndex + 1];
2184 const deInt32 endpointStartG = g[2 * subsetIndex];
2185 const deInt32 endpointEndG = g[2 * subsetIndex + 1];
2186 const deInt32 endpointStartB = b[2 * subsetIndex];
2187 const deInt32 endpointEndB = b[2 * subsetIndex + 1];
2188 const deInt16 r16 = finishUnquantize(interpolate(endpointStartR, endpointEndR, colorIndex, colorIndexBC), hasSign);
2189 const deInt16 g16 = finishUnquantize(interpolate(endpointStartG, endpointEndG, colorIndex, colorIndexBC), hasSign);
2190 const deInt16 b16 = finishUnquantize(interpolate(endpointStartB, endpointEndB, colorIndex, colorIndexBC), hasSign);
2191 const deInt32 y = i / 4;
2192 const deInt32 x = i % 4;
2193 deInt16* const dstPixel = (deInt16*)(dstPtr + y * dstRowPitch + x * dstPixelSize);
2208 colorIndexData >>= bits;
2212 void decompressBc7 (const PixelBufferAccess& dst, const deUint8* src)
2214 using namespace BcDecompressInternal;
2216 static const deUint8 subsets[] = { 3, 2, 3, 2, 1, 1, 1, 2 };
2217 static const deUint8 partitionBits[] = { 4, 6, 6, 6, 0, 0, 0, 6 };
2218 static const deUint8 endpointBits[8][5] =
2230 static const deUint8 indexBits[] = { 3, 3, 2, 2, 2, 2, 4, 2 };
2232 deUint8* const dstPtr = (deUint8*)dst.getDataPtr();
2233 const deUint32 dstRowPitch = dst.getRowPitch();
2234 const deUint32 dstPixelSize = 4;
2236 const deUint64 low = ((deUint64*)src)[0];
2237 const deUint64 high = ((deUint64*)src)[1];
2238 const deInt32 mode = extractModeBc7(src[0]);
2239 deUint32 numSubsets = 1;
2240 deUint32 offset = mode + 1;
2241 deUint32 rotation = 0;
2242 deUint32 idxMode = 0;
2243 deUint32 endpoints[6][5];
2244 deUint32 partitionSetId = 0;
2246 // Decode partition data from explicit partition bits
2247 if (mode == 0 || mode == 1 || mode == 2 || mode == 3 || mode == 7)
2249 numSubsets = subsets[mode];
2250 partitionSetId = getBits128(low, high, offset, offset + partitionBits[mode] - 1);
2251 offset += partitionBits[mode];
2254 // Extract rotation bits
2255 if (mode == 4 || mode == 5)
2257 rotation = getBits128(low, high, offset, offset + 1);
2261 idxMode = getBits128(low, high, offset, offset);
2267 const deUint32 numEndpoints = numSubsets * 2;
2269 // Extract raw, compressed endpoint bits
2270 for (deUint32 cpnt = 0; cpnt < 5; cpnt++)
2272 for (deUint32 ep = 0; ep < numEndpoints; ep++)
2274 if (mode == 1 && cpnt == 4 && ep > 1)
2275 continue; // Mode 1 has shared P bits
2277 int n = mode == -1 ? 0 : endpointBits[mode][cpnt];
2279 endpoints[ep][cpnt] = getBits128(low, high, offset, offset + n - 1);
2285 if (mode == 0 || mode == 1 || mode == 3 || mode == 6 || mode == 7)
2287 // First handle modes that have P-bits
2288 for (deUint32 ep = 0; ep < numEndpoints; ep++)
2290 for (deUint32 cpnt = 0; cpnt < 4; cpnt++)
2292 endpoints[ep][cpnt] <<= 1;
2299 const deUint32 pbitZero = endpoints[0][4];
2300 const deUint32 pbitOne = endpoints[1][4];
2302 for (deUint32 cpnt = 0; cpnt < 3; cpnt++)
2304 endpoints[0][cpnt] |= pbitZero;
2305 endpoints[1][cpnt] |= pbitZero;
2306 endpoints[2][cpnt] |= pbitOne;
2307 endpoints[3][cpnt] |= pbitOne;
2312 // Unique p-bit per endpoint
2313 for (deUint32 ep = 0; ep < numEndpoints; ep++)
2315 for (deUint32 cpnt = 0; cpnt < 4; cpnt++)
2317 endpoints[ep][cpnt] |= endpoints[ep][4];
2323 for (deUint32 ep = 0; ep < numEndpoints; ep++)
2325 // Left shift endpoint components so that their MSB lies in bit 7
2326 for (deUint32 cpnt = 0; cpnt < 4; cpnt++)
2327 endpoints[ep][cpnt] <<= 8 - (endpointBits[mode][cpnt] + endpointBits[mode][4]);
2329 // Replicate each component's MSB into the LSBs revealed by the left-shift operation above
2330 for (deUint32 cpnt = 0; cpnt < 4; cpnt++)
2331 endpoints[ep][cpnt] |= endpoints[ep][cpnt] >> (endpointBits[mode][cpnt] + endpointBits[mode][4]);
2334 // If this mode does not explicitly define the alpha component set alpha equal to 1.0
2337 for (deUint32 ep = 0; ep < numEndpoints; ep++)
2338 endpoints[ep][3] = 255;
2343 deUint32 colorIdxOffset = offset + ((mode == 4 && idxMode) ? 31 : 0);
2344 deUint32 alphaIdxOffset = offset + ((mode == 5 || (mode == 4 && !idxMode)) ? 31 : 0);
2346 for (deUint32 pixel = 0; pixel < 16; pixel++)
2348 const deUint32 y = pixel / 4;
2349 const deUint32 x = pixel % 4;
2350 deUint32* const dstPixel = (deUint32*)(dstPtr + y * dstRowPitch + x * dstPixelSize);
2351 deUint32 subsetIndex = 0;
2352 deUint32 anchorIndex = 0;
2353 deUint32 endpointStart[4];
2354 deUint32 endpointEnd[4];
2362 if (numSubsets == 2)
2363 subsetIndex = partitions2[partitionSetId][pixel];
2364 else if (numSubsets == 3)
2365 subsetIndex = partitions3[partitionSetId][pixel];
2367 if (numSubsets == 2 && subsetIndex == 1)
2369 anchorIndex = anchorIndicesSecondSubset2[partitionSetId];
2371 else if (numSubsets == 3)
2373 if (subsetIndex == 1)
2374 anchorIndex = anchorIndicesSecondSubset3[partitionSetId];
2375 else if (subsetIndex == 2)
2376 anchorIndex = anchorIndicesThirdSubset[partitionSetId];
2379 for (deUint32 cpnt = 0; cpnt < 4; cpnt++)
2381 endpointStart[cpnt] = endpoints[2 * subsetIndex][cpnt];
2382 endpointEnd[cpnt] = endpoints[2 * subsetIndex + 1][cpnt];
2386 const deUint32 colorInterpolationBits = indexBits[mode] + idxMode;
2387 const deUint32 colorIndexBits = colorInterpolationBits - ((anchorIndex == pixel) ? 1 : 0);
2388 const deUint32 alphaInterpolationBits = mode == 4 ? 3 - idxMode : (mode == 5 ? 2 : colorInterpolationBits);
2389 const deUint32 alphaIndexBits = alphaInterpolationBits - ((anchorIndex == pixel) ? 1 : 0);
2390 const deUint32 colorIdx = getBits128(low, high, colorIdxOffset, colorIdxOffset + colorIndexBits - 1);
2391 const deUint32 alphaIdx = (mode == 4 || mode == 5) ? getBits128(low, high, alphaIdxOffset, alphaIdxOffset + alphaIndexBits - 1) : colorIdx;
2392 const deUint32 r = interpolate(endpointStart[0], endpointEnd[0], colorIdx, colorInterpolationBits);
2393 const deUint32 g = interpolate(endpointStart[1], endpointEnd[1], colorIdx, colorInterpolationBits);
2394 const deUint32 b = interpolate(endpointStart[2], endpointEnd[2], colorIdx, colorInterpolationBits);
2395 const deUint32 a = interpolate(endpointStart[3], endpointEnd[3], alphaIdx, alphaInterpolationBits);
2397 colorIdxOffset += colorIndexBits;
2398 alphaIdxOffset += alphaIndexBits;
2400 if ((mode == 4 || mode == 5) && rotation != 0)
2403 *dstPixel = a | (g << 8) | (b << 16) | (r << 24);
2404 else if (rotation == 2)
2405 *dstPixel = r | (a << 8) | (b << 16) | (g << 24);
2407 *dstPixel = r | (g << 8) | (a << 16) | (b << 24);
2411 *dstPixel = r | (g << 8) | (b << 16) | (a << 24);
2418 void decompressBlock (CompressedTexFormat format, const PixelBufferAccess& dst, const deUint8* src, const TexDecompressionParams& params)
2420 // No 3D blocks supported right now
2421 DE_ASSERT(dst.getDepth() == 1);
2425 case COMPRESSEDTEXFORMAT_ETC1_RGB8: decompressETC1 (dst, src); break;
2426 case COMPRESSEDTEXFORMAT_EAC_R11: decompressEAC_R11 (dst, src, false); break;
2427 case COMPRESSEDTEXFORMAT_EAC_SIGNED_R11: decompressEAC_R11 (dst, src, true); break;
2428 case COMPRESSEDTEXFORMAT_EAC_RG11: decompressEAC_RG11 (dst, src, false); break;
2429 case COMPRESSEDTEXFORMAT_EAC_SIGNED_RG11: decompressEAC_RG11 (dst, src, true); break;
2430 case COMPRESSEDTEXFORMAT_ETC2_RGB8: decompressETC2 (dst, src); break;
2431 case COMPRESSEDTEXFORMAT_ETC2_SRGB8: decompressETC2 (dst, src); break;
2432 case COMPRESSEDTEXFORMAT_ETC2_RGB8_PUNCHTHROUGH_ALPHA1: decompressETC2_RGB8_PUNCHTHROUGH_ALPHA1 (dst, src); break;
2433 case COMPRESSEDTEXFORMAT_ETC2_SRGB8_PUNCHTHROUGH_ALPHA1: decompressETC2_RGB8_PUNCHTHROUGH_ALPHA1 (dst, src); break;
2434 case COMPRESSEDTEXFORMAT_ETC2_EAC_RGBA8: decompressETC2_EAC_RGBA8 (dst, src); break;
2435 case COMPRESSEDTEXFORMAT_ETC2_EAC_SRGB8_ALPHA8: decompressETC2_EAC_RGBA8 (dst, src); break;
2437 case COMPRESSEDTEXFORMAT_ASTC_4x4_RGBA:
2438 case COMPRESSEDTEXFORMAT_ASTC_5x4_RGBA:
2439 case COMPRESSEDTEXFORMAT_ASTC_5x5_RGBA:
2440 case COMPRESSEDTEXFORMAT_ASTC_6x5_RGBA:
2441 case COMPRESSEDTEXFORMAT_ASTC_6x6_RGBA:
2442 case COMPRESSEDTEXFORMAT_ASTC_8x5_RGBA:
2443 case COMPRESSEDTEXFORMAT_ASTC_8x6_RGBA:
2444 case COMPRESSEDTEXFORMAT_ASTC_8x8_RGBA:
2445 case COMPRESSEDTEXFORMAT_ASTC_10x5_RGBA:
2446 case COMPRESSEDTEXFORMAT_ASTC_10x6_RGBA:
2447 case COMPRESSEDTEXFORMAT_ASTC_10x8_RGBA:
2448 case COMPRESSEDTEXFORMAT_ASTC_10x10_RGBA:
2449 case COMPRESSEDTEXFORMAT_ASTC_12x10_RGBA:
2450 case COMPRESSEDTEXFORMAT_ASTC_12x12_RGBA:
2451 case COMPRESSEDTEXFORMAT_ASTC_4x4_SRGB8_ALPHA8:
2452 case COMPRESSEDTEXFORMAT_ASTC_5x4_SRGB8_ALPHA8:
2453 case COMPRESSEDTEXFORMAT_ASTC_5x5_SRGB8_ALPHA8:
2454 case COMPRESSEDTEXFORMAT_ASTC_6x5_SRGB8_ALPHA8:
2455 case COMPRESSEDTEXFORMAT_ASTC_6x6_SRGB8_ALPHA8:
2456 case COMPRESSEDTEXFORMAT_ASTC_8x5_SRGB8_ALPHA8:
2457 case COMPRESSEDTEXFORMAT_ASTC_8x6_SRGB8_ALPHA8:
2458 case COMPRESSEDTEXFORMAT_ASTC_8x8_SRGB8_ALPHA8:
2459 case COMPRESSEDTEXFORMAT_ASTC_10x5_SRGB8_ALPHA8:
2460 case COMPRESSEDTEXFORMAT_ASTC_10x6_SRGB8_ALPHA8:
2461 case COMPRESSEDTEXFORMAT_ASTC_10x8_SRGB8_ALPHA8:
2462 case COMPRESSEDTEXFORMAT_ASTC_10x10_SRGB8_ALPHA8:
2463 case COMPRESSEDTEXFORMAT_ASTC_12x10_SRGB8_ALPHA8:
2464 case COMPRESSEDTEXFORMAT_ASTC_12x12_SRGB8_ALPHA8:
2465 astc::decompress(dst, src, format, params.astcMode);
2468 case COMPRESSEDTEXFORMAT_BC1_RGB_UNORM_BLOCK: decompressBc1 (dst, src, false); break;
2469 case COMPRESSEDTEXFORMAT_BC1_RGB_SRGB_BLOCK: decompressBc1 (dst, src, false); break;
2470 case COMPRESSEDTEXFORMAT_BC1_RGBA_UNORM_BLOCK: decompressBc1 (dst, src, true); break;
2471 case COMPRESSEDTEXFORMAT_BC1_RGBA_SRGB_BLOCK: decompressBc1 (dst, src, true); break;
2472 case COMPRESSEDTEXFORMAT_BC2_UNORM_BLOCK: decompressBc2 (dst, src); break;
2473 case COMPRESSEDTEXFORMAT_BC2_SRGB_BLOCK: decompressBc2 (dst, src); break;
2474 case COMPRESSEDTEXFORMAT_BC3_UNORM_BLOCK: decompressBc3 (dst, src); break;
2475 case COMPRESSEDTEXFORMAT_BC3_SRGB_BLOCK: decompressBc3 (dst, src); break;
2476 case COMPRESSEDTEXFORMAT_BC4_UNORM_BLOCK: decompressBc4 (dst, src, false); break;
2477 case COMPRESSEDTEXFORMAT_BC4_SNORM_BLOCK: decompressBc4 (dst, src, true); break;
2478 case COMPRESSEDTEXFORMAT_BC5_UNORM_BLOCK: decompressBc5 (dst, src, false); break;
2479 case COMPRESSEDTEXFORMAT_BC5_SNORM_BLOCK: decompressBc5 (dst, src, true); break;
2480 case COMPRESSEDTEXFORMAT_BC6H_UFLOAT_BLOCK: decompressBc6H (dst, src, false); break;
2481 case COMPRESSEDTEXFORMAT_BC6H_SFLOAT_BLOCK: decompressBc6H (dst, src, true); break;
2482 case COMPRESSEDTEXFORMAT_BC7_UNORM_BLOCK: decompressBc7 (dst, src); break;
2483 case COMPRESSEDTEXFORMAT_BC7_SRGB_BLOCK: decompressBc7 (dst, src); break;
2486 DE_FATAL("Unexpected format");
2491 int componentSum (const IVec3& vec)
2493 return vec.x() + vec.y() + vec.z();
2498 void decompress (const PixelBufferAccess& dst, CompressedTexFormat fmt, const deUint8* src, const TexDecompressionParams& params)
2500 const int blockSize = getBlockSize(fmt);
2501 const IVec3 blockPixelSize (getBlockPixelSize(fmt));
2502 const IVec3 blockCount (deDivRoundUp32(dst.getWidth(), blockPixelSize.x()),
2503 deDivRoundUp32(dst.getHeight(), blockPixelSize.y()),
2504 deDivRoundUp32(dst.getDepth(), blockPixelSize.z()));
2505 const IVec3 blockPitches (blockSize, blockSize * blockCount.x(), blockSize * blockCount.x() * blockCount.y());
2507 std::vector<deUint8> uncompressedBlock (dst.getFormat().getPixelSize() * blockPixelSize.x() * blockPixelSize.y() * blockPixelSize.z());
2508 const PixelBufferAccess blockAccess (getUncompressedFormat(fmt), blockPixelSize.x(), blockPixelSize.y(), blockPixelSize.z(), &uncompressedBlock[0]);
2510 DE_ASSERT(dst.getFormat() == getUncompressedFormat(fmt));
2512 for (int blockZ = 0; blockZ < blockCount.z(); blockZ++)
2513 for (int blockY = 0; blockY < blockCount.y(); blockY++)
2514 for (int blockX = 0; blockX < blockCount.x(); blockX++)
2516 const IVec3 blockPos (blockX, blockY, blockZ);
2517 const deUint8* const blockPtr = src + componentSum(blockPos * blockPitches);
2518 const IVec3 copySize (de::min(blockPixelSize.x(), dst.getWidth() - blockPos.x() * blockPixelSize.x()),
2519 de::min(blockPixelSize.y(), dst.getHeight() - blockPos.y() * blockPixelSize.y()),
2520 de::min(blockPixelSize.z(), dst.getDepth() - blockPos.z() * blockPixelSize.z()));
2521 const IVec3 dstPixelPos = blockPos * blockPixelSize;
2523 decompressBlock(fmt, blockAccess, blockPtr, params);
2525 copy(getSubregion(dst, dstPixelPos.x(), dstPixelPos.y(), dstPixelPos.z(), copySize.x(), copySize.y(), copySize.z()), getSubregion(blockAccess, 0, 0, 0, copySize.x(), copySize.y(), copySize.z()));
2529 CompressedTexture::CompressedTexture (void)
2530 : m_format (COMPRESSEDTEXFORMAT_LAST)
2537 CompressedTexture::CompressedTexture (CompressedTexFormat format, int width, int height, int depth)
2538 : m_format (COMPRESSEDTEXFORMAT_LAST)
2543 setStorage(format, width, height, depth);
2546 CompressedTexture::~CompressedTexture (void)
2550 void CompressedTexture::setStorage (CompressedTexFormat format, int width, int height, int depth)
2557 if (m_format != COMPRESSEDTEXFORMAT_LAST)
2559 const IVec3 blockPixelSize = getBlockPixelSize(m_format);
2560 const int blockSize = getBlockSize(m_format);
2562 m_data.resize(deDivRoundUp32(m_width, blockPixelSize.x()) * deDivRoundUp32(m_height, blockPixelSize.y()) * deDivRoundUp32(m_depth, blockPixelSize.z()) * blockSize);
2566 DE_ASSERT(m_format == COMPRESSEDTEXFORMAT_LAST);
2567 DE_ASSERT(m_width == 0 && m_height == 0 && m_depth == 0);
2572 /*--------------------------------------------------------------------*//*!
2573 * \brief Decode to uncompressed pixel data
2574 * \param dst Destination buffer
2575 *//*--------------------------------------------------------------------*/
2576 void CompressedTexture::decompress (const PixelBufferAccess& dst, const TexDecompressionParams& params) const
2578 DE_ASSERT(dst.getWidth() == m_width && dst.getHeight() == m_height && dst.getDepth() == m_depth);
2579 DE_ASSERT(dst.getFormat() == getUncompressedFormat(m_format));
2581 tcu::decompress(dst, m_format, &m_data[0], params);