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