13c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*-------------------------------------------------------------------------
23c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * drawElements Quality Program Tester Core
33c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * ----------------------------------------
43c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
53c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Copyright 2014 The Android Open Source Project
63c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
73c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Licensed under the Apache License, Version 2.0 (the "License");
83c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * you may not use this file except in compliance with the License.
93c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * You may obtain a copy of the License at
103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *      http://www.apache.org/licenses/LICENSE-2.0
123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Unless required by applicable law or agreed to in writing, software
143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * distributed under the License is distributed on an "AS IS" BASIS,
153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * See the License for the specific language governing permissions and
173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * limitations under the License.
183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*!
203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \file
213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Compressed Texture Utilities.
223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/
233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuCompressedTexture.hpp"
253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuTextureUtil.hpp"
26efb83e1354edd463650ad0404b18e9a7efc307e4Pyry Haulos#include "tcuAstcUtil.hpp"
27becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi
283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deStringUtil.hpp"
293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deFloat16.h"
303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <algorithm>
323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
333c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace tcu
343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
36becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärviint getBlockSize (CompressedTexFormat format)
373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
38becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi	if (isAstcFormat(format))
39becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi	{
40efb83e1354edd463650ad0404b18e9a7efc307e4Pyry Haulos		return astc::BLOCK_SIZE_BYTES;
41becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi	}
42becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi	else if (isEtcFormat(format))
43becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi	{
44becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi		switch (format)
45becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi		{
46becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi			case COMPRESSEDTEXFORMAT_ETC1_RGB8:							return 8;
47becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi			case COMPRESSEDTEXFORMAT_EAC_R11:							return 8;
48becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi			case COMPRESSEDTEXFORMAT_EAC_SIGNED_R11:					return 8;
49becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi			case COMPRESSEDTEXFORMAT_EAC_RG11:							return 16;
50becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi			case COMPRESSEDTEXFORMAT_EAC_SIGNED_RG11:					return 16;
51becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi			case COMPRESSEDTEXFORMAT_ETC2_RGB8:							return 8;
52becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi			case COMPRESSEDTEXFORMAT_ETC2_SRGB8:						return 8;
53becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi			case COMPRESSEDTEXFORMAT_ETC2_RGB8_PUNCHTHROUGH_ALPHA1:		return 8;
54becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi			case COMPRESSEDTEXFORMAT_ETC2_SRGB8_PUNCHTHROUGH_ALPHA1:	return 8;
55becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi			case COMPRESSEDTEXFORMAT_ETC2_EAC_RGBA8:					return 16;
56becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi			case COMPRESSEDTEXFORMAT_ETC2_EAC_SRGB8_ALPHA8:				return 16;
573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
58becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi			default:
59becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi				DE_ASSERT(false);
60becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi				return -1;
61becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi		}
62becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi	}
63becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi	else
64becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi	{
65becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi		DE_ASSERT(false);
66becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi		return -1;
67becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi	}
683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
70becd5d53015521acf7536ba754de326d8b1da2f3Mika IsojärviIVec3 getBlockPixelSize (CompressedTexFormat format)
713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
72becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi	if (isEtcFormat(format))
73becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi	{
74becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi		return IVec3(4, 4, 1);
75becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi	}
76becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi	else if (isAstcFormat(format))
77becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi	{
78becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi		switch (format)
79becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi		{
80becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi			case COMPRESSEDTEXFORMAT_ASTC_4x4_RGBA:				return IVec3(4,  4,  1);
81becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi			case COMPRESSEDTEXFORMAT_ASTC_5x4_RGBA:				return IVec3(5,  4,  1);
82becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi			case COMPRESSEDTEXFORMAT_ASTC_5x5_RGBA:				return IVec3(5,  5,  1);
83becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi			case COMPRESSEDTEXFORMAT_ASTC_6x5_RGBA:				return IVec3(6,  5,  1);
84becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi			case COMPRESSEDTEXFORMAT_ASTC_6x6_RGBA:				return IVec3(6,  6,  1);
85becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi			case COMPRESSEDTEXFORMAT_ASTC_8x5_RGBA:				return IVec3(8,  5,  1);
86becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi			case COMPRESSEDTEXFORMAT_ASTC_8x6_RGBA:				return IVec3(8,  6,  1);
87becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi			case COMPRESSEDTEXFORMAT_ASTC_8x8_RGBA:				return IVec3(8,  8,  1);
88becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi			case COMPRESSEDTEXFORMAT_ASTC_10x5_RGBA:			return IVec3(10, 5,  1);
89becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi			case COMPRESSEDTEXFORMAT_ASTC_10x6_RGBA:			return IVec3(10, 6,  1);
90becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi			case COMPRESSEDTEXFORMAT_ASTC_10x8_RGBA:			return IVec3(10, 8,  1);
91becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi			case COMPRESSEDTEXFORMAT_ASTC_10x10_RGBA:			return IVec3(10, 10, 1);
92becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi			case COMPRESSEDTEXFORMAT_ASTC_12x10_RGBA:			return IVec3(12, 10, 1);
93becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi			case COMPRESSEDTEXFORMAT_ASTC_12x12_RGBA:			return IVec3(12, 12, 1);
94becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi			case COMPRESSEDTEXFORMAT_ASTC_4x4_SRGB8_ALPHA8:		return IVec3(4,  4,  1);
95becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi			case COMPRESSEDTEXFORMAT_ASTC_5x4_SRGB8_ALPHA8:		return IVec3(5,  4,  1);
96becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi			case COMPRESSEDTEXFORMAT_ASTC_5x5_SRGB8_ALPHA8:		return IVec3(5,  5,  1);
97becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi			case COMPRESSEDTEXFORMAT_ASTC_6x5_SRGB8_ALPHA8:		return IVec3(6,  5,  1);
98becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi			case COMPRESSEDTEXFORMAT_ASTC_6x6_SRGB8_ALPHA8:		return IVec3(6,  6,  1);
99becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi			case COMPRESSEDTEXFORMAT_ASTC_8x5_SRGB8_ALPHA8:		return IVec3(8,  5,  1);
100becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi			case COMPRESSEDTEXFORMAT_ASTC_8x6_SRGB8_ALPHA8:		return IVec3(8,  6,  1);
101becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi			case COMPRESSEDTEXFORMAT_ASTC_8x8_SRGB8_ALPHA8:		return IVec3(8,  8,  1);
102becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi			case COMPRESSEDTEXFORMAT_ASTC_10x5_SRGB8_ALPHA8:	return IVec3(10, 5,  1);
103becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi			case COMPRESSEDTEXFORMAT_ASTC_10x6_SRGB8_ALPHA8:	return IVec3(10, 6,  1);
104becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi			case COMPRESSEDTEXFORMAT_ASTC_10x8_SRGB8_ALPHA8:	return IVec3(10, 8,  1);
105becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi			case COMPRESSEDTEXFORMAT_ASTC_10x10_SRGB8_ALPHA8:	return IVec3(10, 10, 1);
106becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi			case COMPRESSEDTEXFORMAT_ASTC_12x10_SRGB8_ALPHA8:	return IVec3(12, 10, 1);
107becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi			case COMPRESSEDTEXFORMAT_ASTC_12x12_SRGB8_ALPHA8:	return IVec3(12, 12, 1);
108becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi
109becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi			default:
110becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi				DE_ASSERT(false);
111becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi				return IVec3();
112becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi		}
113becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi	}
114becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi	else
115becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi	{
116becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi		DE_ASSERT(false);
117becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi		return IVec3(-1);
118becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi	}
1193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
121becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvibool isEtcFormat (CompressedTexFormat format)
1223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
123becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi	switch (format)
1243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
125becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi		case COMPRESSEDTEXFORMAT_ETC1_RGB8:
126becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi		case COMPRESSEDTEXFORMAT_EAC_R11:
127becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi		case COMPRESSEDTEXFORMAT_EAC_SIGNED_R11:
128becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi		case COMPRESSEDTEXFORMAT_EAC_RG11:
129becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi		case COMPRESSEDTEXFORMAT_EAC_SIGNED_RG11:
130becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi		case COMPRESSEDTEXFORMAT_ETC2_RGB8:
131becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi		case COMPRESSEDTEXFORMAT_ETC2_SRGB8:
132becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi		case COMPRESSEDTEXFORMAT_ETC2_RGB8_PUNCHTHROUGH_ALPHA1:
133becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi		case COMPRESSEDTEXFORMAT_ETC2_SRGB8_PUNCHTHROUGH_ALPHA1:
134becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi		case COMPRESSEDTEXFORMAT_ETC2_EAC_RGBA8:
135becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi		case COMPRESSEDTEXFORMAT_ETC2_EAC_SRGB8_ALPHA8:
1363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return true;
1373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
1393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return false;
1403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
143becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvibool isAstcFormat (CompressedTexFormat format)
144becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi{
145becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi	switch (format)
146becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi	{
147becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi		case COMPRESSEDTEXFORMAT_ASTC_4x4_RGBA:
148becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi		case COMPRESSEDTEXFORMAT_ASTC_5x4_RGBA:
149becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi		case COMPRESSEDTEXFORMAT_ASTC_5x5_RGBA:
150becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi		case COMPRESSEDTEXFORMAT_ASTC_6x5_RGBA:
151becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi		case COMPRESSEDTEXFORMAT_ASTC_6x6_RGBA:
152becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi		case COMPRESSEDTEXFORMAT_ASTC_8x5_RGBA:
153becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi		case COMPRESSEDTEXFORMAT_ASTC_8x6_RGBA:
154becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi		case COMPRESSEDTEXFORMAT_ASTC_8x8_RGBA:
155becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi		case COMPRESSEDTEXFORMAT_ASTC_10x5_RGBA:
156becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi		case COMPRESSEDTEXFORMAT_ASTC_10x6_RGBA:
157becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi		case COMPRESSEDTEXFORMAT_ASTC_10x8_RGBA:
158becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi		case COMPRESSEDTEXFORMAT_ASTC_10x10_RGBA:
159becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi		case COMPRESSEDTEXFORMAT_ASTC_12x10_RGBA:
160becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi		case COMPRESSEDTEXFORMAT_ASTC_12x12_RGBA:
161becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi		case COMPRESSEDTEXFORMAT_ASTC_4x4_SRGB8_ALPHA8:
162becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi		case COMPRESSEDTEXFORMAT_ASTC_5x4_SRGB8_ALPHA8:
163becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi		case COMPRESSEDTEXFORMAT_ASTC_5x5_SRGB8_ALPHA8:
164becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi		case COMPRESSEDTEXFORMAT_ASTC_6x5_SRGB8_ALPHA8:
165becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi		case COMPRESSEDTEXFORMAT_ASTC_6x6_SRGB8_ALPHA8:
166becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi		case COMPRESSEDTEXFORMAT_ASTC_8x5_SRGB8_ALPHA8:
167becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi		case COMPRESSEDTEXFORMAT_ASTC_8x6_SRGB8_ALPHA8:
168becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi		case COMPRESSEDTEXFORMAT_ASTC_8x8_SRGB8_ALPHA8:
169becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi		case COMPRESSEDTEXFORMAT_ASTC_10x5_SRGB8_ALPHA8:
170becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi		case COMPRESSEDTEXFORMAT_ASTC_10x6_SRGB8_ALPHA8:
171becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi		case COMPRESSEDTEXFORMAT_ASTC_10x8_SRGB8_ALPHA8:
172becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi		case COMPRESSEDTEXFORMAT_ASTC_10x10_SRGB8_ALPHA8:
173becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi		case COMPRESSEDTEXFORMAT_ASTC_12x10_SRGB8_ALPHA8:
174becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi		case COMPRESSEDTEXFORMAT_ASTC_12x12_SRGB8_ALPHA8:
1753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return true;
1763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
1783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return false;
1793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
182becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvibool isAstcSRGBFormat (CompressedTexFormat format)
1833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
184becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi	switch (format)
1853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
186becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi		case COMPRESSEDTEXFORMAT_ASTC_4x4_SRGB8_ALPHA8:
187becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi		case COMPRESSEDTEXFORMAT_ASTC_5x4_SRGB8_ALPHA8:
188becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi		case COMPRESSEDTEXFORMAT_ASTC_5x5_SRGB8_ALPHA8:
189becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi		case COMPRESSEDTEXFORMAT_ASTC_6x5_SRGB8_ALPHA8:
190becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi		case COMPRESSEDTEXFORMAT_ASTC_6x6_SRGB8_ALPHA8:
191becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi		case COMPRESSEDTEXFORMAT_ASTC_8x5_SRGB8_ALPHA8:
192becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi		case COMPRESSEDTEXFORMAT_ASTC_8x6_SRGB8_ALPHA8:
193becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi		case COMPRESSEDTEXFORMAT_ASTC_8x8_SRGB8_ALPHA8:
194becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi		case COMPRESSEDTEXFORMAT_ASTC_10x5_SRGB8_ALPHA8:
195becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi		case COMPRESSEDTEXFORMAT_ASTC_10x6_SRGB8_ALPHA8:
196becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi		case COMPRESSEDTEXFORMAT_ASTC_10x8_SRGB8_ALPHA8:
197becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi		case COMPRESSEDTEXFORMAT_ASTC_10x10_SRGB8_ALPHA8:
198becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi		case COMPRESSEDTEXFORMAT_ASTC_12x10_SRGB8_ALPHA8:
199becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi		case COMPRESSEDTEXFORMAT_ASTC_12x12_SRGB8_ALPHA8:
2003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return true;
2013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
2033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return false;
2043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
207becd5d53015521acf7536ba754de326d8b1da2f3Mika IsojärviTextureFormat getUncompressedFormat (CompressedTexFormat format)
2083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
209becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi	if (isEtcFormat(format))
2103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
211becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi		switch (format)
2123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
213becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi			case COMPRESSEDTEXFORMAT_ETC1_RGB8:							return TextureFormat(TextureFormat::RGB,	TextureFormat::UNORM_INT8);
214becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi			case COMPRESSEDTEXFORMAT_EAC_R11:							return TextureFormat(TextureFormat::R,		TextureFormat::UNORM_INT16);
215becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi			case COMPRESSEDTEXFORMAT_EAC_SIGNED_R11:					return TextureFormat(TextureFormat::R,		TextureFormat::SNORM_INT16);
216becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi			case COMPRESSEDTEXFORMAT_EAC_RG11:							return TextureFormat(TextureFormat::RG,		TextureFormat::UNORM_INT16);
217becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi			case COMPRESSEDTEXFORMAT_EAC_SIGNED_RG11:					return TextureFormat(TextureFormat::RG,		TextureFormat::SNORM_INT16);
218becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi			case COMPRESSEDTEXFORMAT_ETC2_RGB8:							return TextureFormat(TextureFormat::RGB,	TextureFormat::UNORM_INT8);
219becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi			case COMPRESSEDTEXFORMAT_ETC2_SRGB8:						return TextureFormat(TextureFormat::sRGB,	TextureFormat::UNORM_INT8);
220becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi			case COMPRESSEDTEXFORMAT_ETC2_RGB8_PUNCHTHROUGH_ALPHA1:		return TextureFormat(TextureFormat::RGBA,	TextureFormat::UNORM_INT8);
221becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi			case COMPRESSEDTEXFORMAT_ETC2_SRGB8_PUNCHTHROUGH_ALPHA1:	return TextureFormat(TextureFormat::sRGBA,	TextureFormat::UNORM_INT8);
222becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi			case COMPRESSEDTEXFORMAT_ETC2_EAC_RGBA8:					return TextureFormat(TextureFormat::RGBA,	TextureFormat::UNORM_INT8);
223becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi			case COMPRESSEDTEXFORMAT_ETC2_EAC_SRGB8_ALPHA8:				return TextureFormat(TextureFormat::sRGBA,	TextureFormat::UNORM_INT8);
2243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			default:
2263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				DE_ASSERT(false);
2273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return TextureFormat();
2283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
2293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
230becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi	else if (isAstcFormat(format))
2313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
232becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi		if (isAstcSRGBFormat(format))
2333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return TextureFormat(TextureFormat::sRGBA, TextureFormat::UNORM_INT8);
2343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
2353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return TextureFormat(TextureFormat::RGBA, TextureFormat::HALF_FLOAT);
2363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
2383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(false);
2403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return TextureFormat();
2413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
244becd5d53015521acf7536ba754de326d8b1da2f3Mika IsojärviCompressedTexFormat getAstcFormatByBlockSize (const IVec3& size, bool isSRGB)
245becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi{
246becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi	if (size.z() > 1)
247becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi		throw InternalError("3D ASTC textures not currently supported");
248becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi
249becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi	for (int fmtI = 0; fmtI < COMPRESSEDTEXFORMAT_LAST; fmtI++)
250becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi	{
251becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi		const CompressedTexFormat fmt = (CompressedTexFormat)fmtI;
252becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi
253becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi		if (isAstcFormat(fmt) && getBlockPixelSize(fmt) == size && isAstcSRGBFormat(fmt) == isSRGB)
254becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi			return fmt;
255becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi	}
256becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi
257becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi	throw InternalError("Invalid ASTC block size " + de::toString(size.x()) + "x" + de::toString(size.y()) + "x" + de::toString(size.z()));
258becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi}
259becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi
260becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvinamespace
261becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi{
262becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi
2633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// \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?
2643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2653c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace EtcDecompressInternal
2663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2683c827367444ee418f129b2c238299f49d3264554Jarkko Poyryenum
2693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ETC2_BLOCK_WIDTH					= 4,
2713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ETC2_BLOCK_HEIGHT					= 4,
2723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ETC2_UNCOMPRESSED_PIXEL_SIZE_A8		= 1,
2733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ETC2_UNCOMPRESSED_PIXEL_SIZE_R11	= 2,
2743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ETC2_UNCOMPRESSED_PIXEL_SIZE_RG11	= 4,
2753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ETC2_UNCOMPRESSED_PIXEL_SIZE_RGB8	= 3,
2763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ETC2_UNCOMPRESSED_PIXEL_SIZE_RGBA8	= 4,
2773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ETC2_UNCOMPRESSED_BLOCK_SIZE_A8		= ETC2_BLOCK_WIDTH*ETC2_BLOCK_HEIGHT*ETC2_UNCOMPRESSED_PIXEL_SIZE_A8,
2783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ETC2_UNCOMPRESSED_BLOCK_SIZE_R11	= ETC2_BLOCK_WIDTH*ETC2_BLOCK_HEIGHT*ETC2_UNCOMPRESSED_PIXEL_SIZE_R11,
2793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ETC2_UNCOMPRESSED_BLOCK_SIZE_RG11	= ETC2_BLOCK_WIDTH*ETC2_BLOCK_HEIGHT*ETC2_UNCOMPRESSED_PIXEL_SIZE_RG11,
2803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ETC2_UNCOMPRESSED_BLOCK_SIZE_RGB8	= ETC2_BLOCK_WIDTH*ETC2_BLOCK_HEIGHT*ETC2_UNCOMPRESSED_PIXEL_SIZE_RGB8,
2813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ETC2_UNCOMPRESSED_BLOCK_SIZE_RGBA8	= ETC2_BLOCK_WIDTH*ETC2_BLOCK_HEIGHT*ETC2_UNCOMPRESSED_PIXEL_SIZE_RGBA8
2823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
2833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
284becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärviinline deUint64 get64BitBlock (const deUint8* src, int blockNdx)
2853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Stored in big-endian form.
2873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint64 block = 0;
288becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi
2893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int i = 0; i < 8; i++)
2903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		block = (block << 8ull) | (deUint64)(src[blockNdx*8+i]);
291becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi
2923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return block;
2933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Return the first 64 bits of a 128 bit block.
296becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärviinline deUint64 get128BitBlockStart (const deUint8* src, int blockNdx)
2973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return get64BitBlock(src, 2*blockNdx);
2993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Return the last 64 bits of a 128 bit block.
302becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärviinline deUint64 get128BitBlockEnd (const deUint8* src, int blockNdx)
3033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return get64BitBlock(src, 2*blockNdx + 1);
3053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
307becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärviinline deUint32 getBit (deUint64 src, int bit)
3083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return (src >> bit) & 1;
3103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
312becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärviinline deUint32 getBits (deUint64 src, int low, int high)
3133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int numBits = (high-low) + 1;
3153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(de::inRange(numBits, 1, 32));
316e2bf5f5b2620951f377bb2a4c1358e358c8f3a07Jarkko Pöyry	if (numBits < 32)
31709307280328f7fe333960a53cddf8c2962af5536Jarkko Pöyry		return (deUint32)((src >> low) & ((1u<<numBits)-1));
318e2bf5f5b2620951f377bb2a4c1358e358c8f3a07Jarkko Pöyry	else
31909307280328f7fe333960a53cddf8c2962af5536Jarkko Pöyry		return (deUint32)((src >> low) & 0xFFFFFFFFu);
3203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
322becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärviinline deUint8 extend4To8 (deUint8 src)
3233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT((src & ~((1<<4)-1)) == 0);
32509307280328f7fe333960a53cddf8c2962af5536Jarkko Pöyry	return (deUint8)((src << 4) | src);
3263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
328becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärviinline deUint8 extend5To8 (deUint8 src)
3293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT((src & ~((1<<5)-1)) == 0);
33109307280328f7fe333960a53cddf8c2962af5536Jarkko Pöyry	return (deUint8)((src << 3) | (src >> 2));
3323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
334becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärviinline deUint8 extend6To8 (deUint8 src)
3353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT((src & ~((1<<6)-1)) == 0);
33709307280328f7fe333960a53cddf8c2962af5536Jarkko Pöyry	return (deUint8)((src << 2) | (src >> 4));
3383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
340becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärviinline deUint8 extend7To8 (deUint8 src)
3413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT((src & ~((1<<7)-1)) == 0);
34309307280328f7fe333960a53cddf8c2962af5536Jarkko Pöyry	return (deUint8)((src << 1) | (src >> 6));
3443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
346becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärviinline deInt8 extendSigned3To8 (deUint8 src)
3473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const bool isNeg = (src & (1<<2)) != 0;
3493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return (deInt8)((isNeg ? ~((1<<3)-1) : 0) | src);
3503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
352becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärviinline deUint8 extend5Delta3To8 (deUint8 base5, deUint8 delta3)
3533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deUint8 t = (deUint8)((deInt8)base5 + extendSigned3To8(delta3));
3553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return extend5To8(t);
3563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
358becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärviinline deUint16 extend11To16 (deUint16 src)
3593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT((src & ~((1<<11)-1)) == 0);
3618a9067322d4c5131405e6706faa7422ee4454149Jarkko Pöyry	return (deUint16)((src << 5) | (src >> 6));
3623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
364becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärviinline deInt16 extend11To16WithSign (deInt16 src)
3653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (src < 0)
36709307280328f7fe333960a53cddf8c2962af5536Jarkko Pöyry		return (deInt16)(-(deInt16)extend11To16((deUint16)(-src)));
3683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
3693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return (deInt16)extend11To16(src);
3703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
372becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvivoid decompressETC1Block (deUint8 dst[ETC2_UNCOMPRESSED_BLOCK_SIZE_RGB8], deUint64 src)
3733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int		diffBit		= (int)getBit(src, 33);
3753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int		flipBit		= (int)getBit(src, 32);
3763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deUint32	table[2]	= { getBits(src, 37, 39), getBits(src, 34, 36) };
3773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint8			baseR[2];
3783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint8			baseG[2];
3793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint8			baseB[2];
3803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (diffBit == 0)
3823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Individual mode.
3843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		baseR[0] = extend4To8((deUint8)getBits(src, 60, 63));
3853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		baseR[1] = extend4To8((deUint8)getBits(src, 56, 59));
3863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		baseG[0] = extend4To8((deUint8)getBits(src, 52, 55));
3873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		baseG[1] = extend4To8((deUint8)getBits(src, 48, 51));
3883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		baseB[0] = extend4To8((deUint8)getBits(src, 44, 47));
3893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		baseB[1] = extend4To8((deUint8)getBits(src, 40, 43));
3903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
3923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Differential mode (diffBit == 1).
3943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deUint8 bR = (deUint8)getBits(src, 59, 63); // 5b
3953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deUint8 dR = (deUint8)getBits(src, 56, 58); // 3b
3963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deUint8 bG = (deUint8)getBits(src, 51, 55);
3973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deUint8 dG = (deUint8)getBits(src, 48, 50);
3983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deUint8 bB = (deUint8)getBits(src, 43, 47);
3993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deUint8 dB = (deUint8)getBits(src, 40, 42);
4003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		baseR[0] = extend5To8(bR);
4023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		baseG[0] = extend5To8(bG);
4033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		baseB[0] = extend5To8(bB);
4043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		baseR[1] = extend5Delta3To8(bR, dR);
4063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		baseG[1] = extend5Delta3To8(bG, dG);
4073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		baseB[1] = extend5Delta3To8(bB, dB);
4083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const int modifierTable[8][4] =
4113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	//	  00   01   10    11
4133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{  2,   8,  -2,   -8 },
4143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{  5,  17,  -5,  -17 },
4153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{  9,  29,  -9,  -29 },
4163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ 13,  42, -13,  -42 },
4173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ 18,  60, -18,  -60 },
4183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ 24,  80, -24,  -80 },
4193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ 33, 106, -33, -106 },
4203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ 47, 183, -47, -183 }
4213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
4223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Write final pixels.
4243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int pixelNdx = 0; pixelNdx < ETC2_BLOCK_HEIGHT*ETC2_BLOCK_WIDTH; pixelNdx++)
4253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int		x				= pixelNdx / ETC2_BLOCK_HEIGHT;
4273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int		y				= pixelNdx % ETC2_BLOCK_HEIGHT;
4283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int		dstOffset		= (y*ETC2_BLOCK_WIDTH + x)*ETC2_UNCOMPRESSED_PIXEL_SIZE_RGB8;
4293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int		subBlock		= ((flipBit ? y : x) >= 2) ? 1 : 0;
4303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const deUint32	tableNdx		= table[subBlock];
4313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const deUint32	modifierNdx		= (getBit(src, 16+pixelNdx) << 1) | getBit(src, pixelNdx);
4323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int		modifier		= modifierTable[tableNdx][modifierNdx];
4333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		dst[dstOffset+0] = (deUint8)deClamp32((int)baseR[subBlock] + modifier, 0, 255);
4353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		dst[dstOffset+1] = (deUint8)deClamp32((int)baseG[subBlock] + modifier, 0, 255);
4363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		dst[dstOffset+2] = (deUint8)deClamp32((int)baseB[subBlock] + modifier, 0, 255);
4373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
4393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// if alphaMode is true, do PUNCHTHROUGH and store alpha to alphaDst; otherwise do ordinary ETC2 RGB8.
441becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvivoid decompressETC2Block (deUint8 dst[ETC2_UNCOMPRESSED_BLOCK_SIZE_RGB8], deUint64 src, deUint8 alphaDst[ETC2_UNCOMPRESSED_BLOCK_SIZE_A8], bool alphaMode)
4423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	enum Etc2Mode
4443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		MODE_INDIVIDUAL = 0,
4463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		MODE_DIFFERENTIAL,
4473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		MODE_T,
4483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		MODE_H,
4493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		MODE_PLANAR,
4503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		MODE_LAST
4523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
4533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int		diffOpaqueBit	= (int)getBit(src, 33);
4553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deInt8	selBR			= (deInt8)getBits(src, 59, 63);	// 5 bits.
4563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deInt8	selBG			= (deInt8)getBits(src, 51, 55);
4573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deInt8	selBB			= (deInt8)getBits(src, 43, 47);
4583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deInt8	selDR			= extendSigned3To8((deUint8)getBits(src, 56, 58)); // 3 bits.
4593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deInt8	selDG			= extendSigned3To8((deUint8)getBits(src, 48, 50));
4603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deInt8	selDB			= extendSigned3To8((deUint8)getBits(src, 40, 42));
4613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Etc2Mode		mode;
4623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (!alphaMode && diffOpaqueBit == 0)
4643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		mode = MODE_INDIVIDUAL;
4653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (!de::inRange(selBR + selDR, 0, 31))
4663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		mode = MODE_T;
4673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (!de::inRange(selBG + selDG, 0, 31))
4683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		mode = MODE_H;
4693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (!de::inRange(selBB + selDB, 0, 31))
4703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		mode = MODE_PLANAR;
4713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
4723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		mode = MODE_DIFFERENTIAL;
4733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (mode == MODE_INDIVIDUAL || mode == MODE_DIFFERENTIAL)
4753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Individual and differential modes have some steps in common, handle them here.
4773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		static const int modifierTable[8][4] =
4783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
4793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		//	  00   01   10    11
4803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{  2,   8,  -2,   -8 },
4813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{  5,  17,  -5,  -17 },
4823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{  9,  29,  -9,  -29 },
4833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{ 13,  42, -13,  -42 },
4843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{ 18,  60, -18,  -60 },
4853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{ 24,  80, -24,  -80 },
4863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{ 33, 106, -33, -106 },
4873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{ 47, 183, -47, -183 }
4883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		};
4893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int		flipBit		= (int)getBit(src, 32);
4913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const deUint32	table[2]	= { getBits(src, 37, 39), getBits(src, 34, 36) };
4923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deUint8			baseR[2];
4933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deUint8			baseG[2];
4943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deUint8			baseB[2];
4953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (mode == MODE_INDIVIDUAL)
4973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
4983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// Individual mode, initial values.
4993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			baseR[0] = extend4To8((deUint8)getBits(src, 60, 63));
5003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			baseR[1] = extend4To8((deUint8)getBits(src, 56, 59));
5013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			baseG[0] = extend4To8((deUint8)getBits(src, 52, 55));
5023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			baseG[1] = extend4To8((deUint8)getBits(src, 48, 51));
5033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			baseB[0] = extend4To8((deUint8)getBits(src, 44, 47));
5043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			baseB[1] = extend4To8((deUint8)getBits(src, 40, 43));
5053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
5063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
5073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
5083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// Differential mode, initial values.
5093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			baseR[0] = extend5To8(selBR);
5103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			baseG[0] = extend5To8(selBG);
5113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			baseB[0] = extend5To8(selBB);
5123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			baseR[1] = extend5To8((deUint8)(selBR + selDR));
5143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			baseG[1] = extend5To8((deUint8)(selBG + selDG));
5153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			baseB[1] = extend5To8((deUint8)(selBB + selDB));
5163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
5173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Write final pixels for individual or differential mode.
5193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int pixelNdx = 0; pixelNdx < ETC2_BLOCK_HEIGHT*ETC2_BLOCK_WIDTH; pixelNdx++)
5203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
5213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const int		x				= pixelNdx / ETC2_BLOCK_HEIGHT;
5223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const int		y				= pixelNdx % ETC2_BLOCK_HEIGHT;
5233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const int		dstOffset		= (y*ETC2_BLOCK_WIDTH + x)*ETC2_UNCOMPRESSED_PIXEL_SIZE_RGB8;
5243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const int		subBlock		= ((flipBit ? y : x) >= 2) ? 1 : 0;
5253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const deUint32	tableNdx		= table[subBlock];
5263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const deUint32	modifierNdx		= (getBit(src, 16+pixelNdx) << 1) | getBit(src, pixelNdx);
5273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const int		alphaDstOffset	= (y*ETC2_BLOCK_WIDTH + x)*ETC2_UNCOMPRESSED_PIXEL_SIZE_A8; // Only needed for PUNCHTHROUGH version.
5283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// If doing PUNCHTHROUGH version (alphaMode), opaque bit may affect colors.
5303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (alphaMode && diffOpaqueBit == 0 && modifierNdx == 2)
5313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
5323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				dst[dstOffset+0]			= 0;
5333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				dst[dstOffset+1]			= 0;
5343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				dst[dstOffset+2]			= 0;
5353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				alphaDst[alphaDstOffset]	= 0;
5363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
5373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
5383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
5393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				int modifier;
5403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				// PUNCHTHROUGH version and opaque bit may also affect modifiers.
5423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (alphaMode && diffOpaqueBit == 0 && (modifierNdx == 0 || modifierNdx == 2))
5433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					modifier = 0;
5443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				else
5453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					modifier = modifierTable[tableNdx][modifierNdx];
5463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				dst[dstOffset+0] = (deUint8)deClamp32((int)baseR[subBlock] + modifier, 0, 255);
5483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				dst[dstOffset+1] = (deUint8)deClamp32((int)baseG[subBlock] + modifier, 0, 255);
5493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				dst[dstOffset+2] = (deUint8)deClamp32((int)baseB[subBlock] + modifier, 0, 255);
5503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (alphaMode)
5523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					alphaDst[alphaDstOffset] = 255;
5533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
5543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
5553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
5563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (mode == MODE_T || mode == MODE_H)
5573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// T and H modes have some steps in common, handle them here.
5593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		static const int distTable[8] = { 3, 6, 11, 16, 23, 32, 41, 64 };
5603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deUint8 paintR[4];
5623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deUint8 paintG[4];
5633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deUint8 paintB[4];
5643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (mode == MODE_T)
5663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
5673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// T mode, calculate paint values.
5683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const deUint8	R1a			= (deUint8)getBits(src, 59, 60);
5693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const deUint8	R1b			= (deUint8)getBits(src, 56, 57);
5703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const deUint8	G1			= (deUint8)getBits(src, 52, 55);
5713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const deUint8	B1			= (deUint8)getBits(src, 48, 51);
5723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const deUint8	R2			= (deUint8)getBits(src, 44, 47);
5733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const deUint8	G2			= (deUint8)getBits(src, 40, 43);
5743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const deUint8	B2			= (deUint8)getBits(src, 36, 39);
5753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const deUint32	distNdx		= (getBits(src, 34, 35) << 1) | getBit(src, 32);
5763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const int		dist		= distTable[distNdx];
5773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
57809307280328f7fe333960a53cddf8c2962af5536Jarkko Pöyry			paintR[0] = extend4To8((deUint8)((R1a << 2) | R1b));
5793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			paintG[0] = extend4To8(G1);
5803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			paintB[0] = extend4To8(B1);
5813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			paintR[2] = extend4To8(R2);
5823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			paintG[2] = extend4To8(G2);
5833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			paintB[2] = extend4To8(B2);
5843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			paintR[1] = (deUint8)deClamp32((int)paintR[2] + dist, 0, 255);
5853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			paintG[1] = (deUint8)deClamp32((int)paintG[2] + dist, 0, 255);
5863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			paintB[1] = (deUint8)deClamp32((int)paintB[2] + dist, 0, 255);
5873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			paintR[3] = (deUint8)deClamp32((int)paintR[2] - dist, 0, 255);
5883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			paintG[3] = (deUint8)deClamp32((int)paintG[2] - dist, 0, 255);
5893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			paintB[3] = (deUint8)deClamp32((int)paintB[2] - dist, 0, 255);
5903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
5913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
5923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
5933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// H mode, calculate paint values.
5943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const deUint8	R1		= (deUint8)getBits(src, 59, 62);
5953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const deUint8	G1a		= (deUint8)getBits(src, 56, 58);
5963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const deUint8	G1b		= (deUint8)getBit(src, 52);
5973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const deUint8	B1a		= (deUint8)getBit(src, 51);
5983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const deUint8	B1b		= (deUint8)getBits(src, 47, 49);
5993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const deUint8	R2		= (deUint8)getBits(src, 43, 46);
6003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const deUint8	G2		= (deUint8)getBits(src, 39, 42);
6013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const deUint8	B2		= (deUint8)getBits(src, 35, 38);
6023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			deUint8			baseR[2];
6033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			deUint8			baseG[2];
6043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			deUint8			baseB[2];
6053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			deUint32		baseValue[2];
6063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			deUint32		distNdx;
6073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int				dist;
6083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			baseR[0]		= extend4To8(R1);
61009307280328f7fe333960a53cddf8c2962af5536Jarkko Pöyry			baseG[0]		= extend4To8((deUint8)((G1a << 1) | G1b));
61109307280328f7fe333960a53cddf8c2962af5536Jarkko Pöyry			baseB[0]		= extend4To8((deUint8)((B1a << 3) | B1b));
6123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			baseR[1]		= extend4To8(R2);
6133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			baseG[1]		= extend4To8(G2);
6143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			baseB[1]		= extend4To8(B2);
6153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			baseValue[0]	= (((deUint32)baseR[0]) << 16) | (((deUint32)baseG[0]) << 8) | baseB[0];
6163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			baseValue[1]	= (((deUint32)baseR[1]) << 16) | (((deUint32)baseG[1]) << 8) | baseB[1];
6173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			distNdx			= (getBit(src, 34) << 2) | (getBit(src, 32) << 1) | (deUint32)(baseValue[0] >= baseValue[1]);
6183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			dist			= distTable[distNdx];
6193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			paintR[0]		= (deUint8)deClamp32((int)baseR[0] + dist, 0, 255);
6213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			paintG[0]		= (deUint8)deClamp32((int)baseG[0] + dist, 0, 255);
6223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			paintB[0]		= (deUint8)deClamp32((int)baseB[0] + dist, 0, 255);
6233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			paintR[1]		= (deUint8)deClamp32((int)baseR[0] - dist, 0, 255);
6243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			paintG[1]		= (deUint8)deClamp32((int)baseG[0] - dist, 0, 255);
6253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			paintB[1]		= (deUint8)deClamp32((int)baseB[0] - dist, 0, 255);
6263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			paintR[2]		= (deUint8)deClamp32((int)baseR[1] + dist, 0, 255);
6273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			paintG[2]		= (deUint8)deClamp32((int)baseG[1] + dist, 0, 255);
6283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			paintB[2]		= (deUint8)deClamp32((int)baseB[1] + dist, 0, 255);
6293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			paintR[3]		= (deUint8)deClamp32((int)baseR[1] - dist, 0, 255);
6303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			paintG[3]		= (deUint8)deClamp32((int)baseG[1] - dist, 0, 255);
6313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			paintB[3]		= (deUint8)deClamp32((int)baseB[1] - dist, 0, 255);
6323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
6333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Write final pixels for T or H mode.
6353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int pixelNdx = 0; pixelNdx < ETC2_BLOCK_HEIGHT*ETC2_BLOCK_WIDTH; pixelNdx++)
6363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
6373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const int		x				= pixelNdx / ETC2_BLOCK_HEIGHT;
6383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const int		y				= pixelNdx % ETC2_BLOCK_HEIGHT;
6393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const int		dstOffset		= (y*ETC2_BLOCK_WIDTH + x)*ETC2_UNCOMPRESSED_PIXEL_SIZE_RGB8;
6403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const deUint32	paintNdx		= (getBit(src, 16+pixelNdx) << 1) | getBit(src, pixelNdx);
6413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const int		alphaDstOffset	= (y*ETC2_BLOCK_WIDTH + x)*ETC2_UNCOMPRESSED_PIXEL_SIZE_A8; // Only needed for PUNCHTHROUGH version.
6423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (alphaMode && diffOpaqueBit == 0 && paintNdx == 2)
6443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
6453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				dst[dstOffset+0]			= 0;
6463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				dst[dstOffset+1]			= 0;
6473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				dst[dstOffset+2]			= 0;
6483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				alphaDst[alphaDstOffset]	= 0;
6493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
6503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
6513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
6523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				dst[dstOffset+0] = (deUint8)deClamp32((int)paintR[paintNdx], 0, 255);
6533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				dst[dstOffset+1] = (deUint8)deClamp32((int)paintG[paintNdx], 0, 255);
6543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				dst[dstOffset+2] = (deUint8)deClamp32((int)paintB[paintNdx], 0, 255);
6553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (alphaMode)
6573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					alphaDst[alphaDstOffset] = 255;
6583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
6593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
6603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
6613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
6623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
6633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Planar mode.
6643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const deUint8 GO1	= (deUint8)getBit(src, 56);
6653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const deUint8 GO2	= (deUint8)getBits(src, 49, 54);
6663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const deUint8 BO1	= (deUint8)getBit(src, 48);
6673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const deUint8 BO2	= (deUint8)getBits(src, 43, 44);
6683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const deUint8 BO3	= (deUint8)getBits(src, 39, 41);
6693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const deUint8 RH1	= (deUint8)getBits(src, 34, 38);
6703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const deUint8 RH2	= (deUint8)getBit(src, 32);
6713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const deUint8 RO	= extend6To8((deUint8)getBits(src, 57, 62));
67209307280328f7fe333960a53cddf8c2962af5536Jarkko Pöyry		const deUint8 GO	= extend7To8((deUint8)((GO1 << 6) | GO2));
67309307280328f7fe333960a53cddf8c2962af5536Jarkko Pöyry		const deUint8 BO	= extend6To8((deUint8)((BO1 << 5) | (BO2 << 3) | BO3));
67409307280328f7fe333960a53cddf8c2962af5536Jarkko Pöyry		const deUint8 RH	= extend6To8((deUint8)((RH1 << 1) | RH2));
6753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const deUint8 GH	= extend7To8((deUint8)getBits(src, 25, 31));
6763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const deUint8 BH	= extend6To8((deUint8)getBits(src, 19, 24));
6773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const deUint8 RV	= extend6To8((deUint8)getBits(src, 13, 18));
6783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const deUint8 GV	= extend7To8((deUint8)getBits(src, 6, 12));
6793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const deUint8 BV	= extend6To8((deUint8)getBits(src, 0, 5));
6803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Write final pixels for planar mode.
6823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int y = 0; y < 4; y++)
6833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
6843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int x = 0; x < 4; x++)
6853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
6863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const int dstOffset			= (y*ETC2_BLOCK_WIDTH + x)*ETC2_UNCOMPRESSED_PIXEL_SIZE_RGB8;
6873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const int unclampedR		= (x * ((int)RH-(int)RO) + y * ((int)RV-(int)RO) + 4*(int)RO + 2) >> 2;
6883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const int unclampedG		= (x * ((int)GH-(int)GO) + y * ((int)GV-(int)GO) + 4*(int)GO + 2) >> 2;
6893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const int unclampedB		= (x * ((int)BH-(int)BO) + y * ((int)BV-(int)BO) + 4*(int)BO + 2) >> 2;
6903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const int alphaDstOffset	= (y*ETC2_BLOCK_WIDTH + x)*ETC2_UNCOMPRESSED_PIXEL_SIZE_A8; // Only needed for PUNCHTHROUGH version.
6913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				dst[dstOffset+0] = (deUint8)deClamp32(unclampedR, 0, 255);
6933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				dst[dstOffset+1] = (deUint8)deClamp32(unclampedG, 0, 255);
6943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				dst[dstOffset+2] = (deUint8)deClamp32(unclampedB, 0, 255);
6953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (alphaMode)
6973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					alphaDst[alphaDstOffset] = 255;
6983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
6993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
7003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
7013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
7023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
703becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvivoid decompressEAC8Block (deUint8 dst[ETC2_UNCOMPRESSED_BLOCK_SIZE_A8], deUint64 src)
7043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
7053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const int modifierTable[16][8] =
7063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
7073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{-3,  -6,  -9, -15,  2,  5,  8, 14},
7083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{-3,  -7, -10, -13,  2,  6,  9, 12},
7093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{-2,  -5,  -8, -13,  1,  4,  7, 12},
7103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{-2,  -4,  -6, -13,  1,  3,  5, 12},
7113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{-3,  -6,  -8, -12,  2,  5,  7, 11},
7123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{-3,  -7,  -9, -11,  2,  6,  8, 10},
7133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{-4,  -7,  -8, -11,  3,  6,  7, 10},
7143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{-3,  -5,  -8, -11,  2,  4,  7, 10},
7153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{-2,  -6,  -8, -10,  1,  5,  7,  9},
7163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{-2,  -5,  -8, -10,  1,  4,  7,  9},
7173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{-2,  -4,  -8, -10,  1,  3,  7,  9},
7183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{-2,  -5,  -7, -10,  1,  4,  6,  9},
7193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{-3,  -4,  -7, -10,  2,  3,  6,  9},
7203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{-1,  -2,  -3, -10,  0,  1,  2,  9},
7213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{-4,  -6,  -8,  -9,  3,  5,  7,  8},
7223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{-3,  -5,  -7,  -9,  2,  4,  6,  8}
7233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
7243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deUint8	baseCodeword	= (deUint8)getBits(src, 56, 63);
7263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deUint8	multiplier		= (deUint8)getBits(src, 52, 55);
7273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deUint32	tableNdx		= getBits(src, 48, 51);
7283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int pixelNdx = 0; pixelNdx < ETC2_BLOCK_HEIGHT*ETC2_BLOCK_WIDTH; pixelNdx++)
7303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
7313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int		x				= pixelNdx / ETC2_BLOCK_HEIGHT;
7323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int		y				= pixelNdx % ETC2_BLOCK_HEIGHT;
7333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int		dstOffset		= (y*ETC2_BLOCK_WIDTH + x)*ETC2_UNCOMPRESSED_PIXEL_SIZE_A8;
7343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int		pixelBitNdx		= 45 - 3*pixelNdx;
7353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const deUint32	modifierNdx		= (getBit(src, pixelBitNdx + 2) << 2) | (getBit(src, pixelBitNdx + 1) << 1) | getBit(src, pixelBitNdx);
7363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int		modifier		= modifierTable[tableNdx][modifierNdx];
7373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		dst[dstOffset] = (deUint8)deClamp32((int)baseCodeword + (int)multiplier*modifier, 0, 255);
7393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
7403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
7413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
742becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvivoid decompressEAC11Block (deUint8 dst[ETC2_UNCOMPRESSED_BLOCK_SIZE_R11], deUint64 src, bool signedMode)
7433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
7443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const int modifierTable[16][8] =
7453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
7463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{-3,  -6,  -9, -15,  2,  5,  8, 14},
7473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{-3,  -7, -10, -13,  2,  6,  9, 12},
7483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{-2,  -5,  -8, -13,  1,  4,  7, 12},
7493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{-2,  -4,  -6, -13,  1,  3,  5, 12},
7503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{-3,  -6,  -8, -12,  2,  5,  7, 11},
7513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{-3,  -7,  -9, -11,  2,  6,  8, 10},
7523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{-4,  -7,  -8, -11,  3,  6,  7, 10},
7533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{-3,  -5,  -8, -11,  2,  4,  7, 10},
7543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{-2,  -6,  -8, -10,  1,  5,  7,  9},
7553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{-2,  -5,  -8, -10,  1,  4,  7,  9},
7563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{-2,  -4,  -8, -10,  1,  3,  7,  9},
7573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{-2,  -5,  -7, -10,  1,  4,  6,  9},
7583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{-3,  -4,  -7, -10,  2,  3,  6,  9},
7593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{-1,  -2,  -3, -10,  0,  1,  2,  9},
7603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{-4,  -6,  -8,  -9,  3,  5,  7,  8},
7613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{-3,  -5,  -7,  -9,  2,  4,  6,  8}
7623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
7633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deInt32 multiplier	= (deInt32)getBits(src, 52, 55);
7653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deInt32 tableNdx		= (deInt32)getBits(src, 48, 51);
7663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deInt32 baseCodeword		= (deInt32)getBits(src, 56, 63);
7673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (signedMode)
7693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
7703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (baseCodeword > 127)
7713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			baseCodeword -= 256;
7723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (baseCodeword == -128)
7733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			baseCodeword = -127;
7743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
7753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int pixelNdx = 0; pixelNdx < ETC2_BLOCK_HEIGHT*ETC2_BLOCK_WIDTH; pixelNdx++)
7773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
7783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int		x				= pixelNdx / ETC2_BLOCK_HEIGHT;
7793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int		y				= pixelNdx % ETC2_BLOCK_HEIGHT;
7803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int		dstOffset		= (y*ETC2_BLOCK_WIDTH + x)*ETC2_UNCOMPRESSED_PIXEL_SIZE_R11;
7813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int		pixelBitNdx		= 45 - 3*pixelNdx;
7823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const deUint32	modifierNdx		= (getBit(src, pixelBitNdx + 2) << 2) | (getBit(src, pixelBitNdx + 1) << 1) | getBit(src, pixelBitNdx);
7833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int		modifier		= modifierTable[tableNdx][modifierNdx];
7843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (signedMode)
7863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
787becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi			deInt16 value;
788becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi
7893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (multiplier != 0)
790becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi				value = (deInt16)deClamp32(baseCodeword*8 + multiplier*modifier*8, -1023, 1023);
7913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
792becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi				value = (deInt16)deClamp32(baseCodeword*8 + modifier, -1023, 1023);
793becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi
794becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi			*((deInt16*)(dst + dstOffset)) = value;
7953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
7963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
7973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
798becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi			deUint16 value;
799becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi
8003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (multiplier != 0)
801becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi				value = (deUint16)deClamp32(baseCodeword*8 + 4 + multiplier*modifier*8, 0, 2047);
8023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
803becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi				value= (deUint16)deClamp32(baseCodeword*8 + 4 + modifier, 0, 2047);
804becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi
805becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi			*((deUint16*)(dst + dstOffset)) = value;
8063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
8073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
8083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
8093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // EtcDecompressInternal
8113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
812becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvivoid decompressETC1 (const PixelBufferAccess& dst, const deUint8* src)
8133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
8143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	using namespace EtcDecompressInternal;
8153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint8* const	dstPtr			= (deUint8*)dst.getDataPtr();
817becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi	const deUint64	compressedBlock = get64BitBlock(src, 0);
8183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
819becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi	decompressETC1Block(dstPtr, compressedBlock);
8203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
8213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
822becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvivoid decompressETC2 (const PixelBufferAccess& dst, const deUint8* src)
8233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
8243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	using namespace EtcDecompressInternal;
8253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint8* const	dstPtr			= (deUint8*)dst.getDataPtr();
827becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi	const deUint64	compressedBlock = get64BitBlock(src, 0);
8283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
829becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi	decompressETC2Block(dstPtr, compressedBlock, NULL, false);
8303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
8313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
832becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvivoid decompressETC2_EAC_RGBA8 (const PixelBufferAccess& dst, const deUint8* src)
8333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
8343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	using namespace EtcDecompressInternal;
8353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint8* const	dstPtr			= (deUint8*)dst.getDataPtr();
8373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int		dstRowPitch		= dst.getRowPitch();
8383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int		dstPixelSize	= ETC2_UNCOMPRESSED_PIXEL_SIZE_RGBA8;
8393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
840becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi	const deUint64	compressedBlockAlpha	= get128BitBlockStart(src, 0);
841becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi	const deUint64	compressedBlockRGB		= get128BitBlockEnd(src, 0);
842becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi	deUint8			uncompressedBlockAlpha[ETC2_UNCOMPRESSED_BLOCK_SIZE_A8];
843becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi	deUint8			uncompressedBlockRGB[ETC2_UNCOMPRESSED_BLOCK_SIZE_RGB8];
844becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi
845becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi	// Decompress.
846becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi	decompressETC2Block(uncompressedBlockRGB, compressedBlockRGB, NULL, false);
847becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi	decompressEAC8Block(uncompressedBlockAlpha, compressedBlockAlpha);
848becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi
849becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi	// Write to dst.
850becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi	for (int y = 0; y < (int)ETC2_BLOCK_HEIGHT; y++)
8513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
852becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi		for (int x = 0; x < (int)ETC2_BLOCK_WIDTH; x++)
8533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
854becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi			const deUint8* const	srcPixelRGB		= &uncompressedBlockRGB[(y*ETC2_BLOCK_WIDTH + x)*ETC2_UNCOMPRESSED_PIXEL_SIZE_RGB8];
855becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi			const deUint8* const	srcPixelAlpha	= &uncompressedBlockAlpha[(y*ETC2_BLOCK_WIDTH + x)*ETC2_UNCOMPRESSED_PIXEL_SIZE_A8];
856becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi			deUint8* const			dstPixel		= dstPtr + y*dstRowPitch + x*dstPixelSize;
857becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi
858becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi			DE_STATIC_ASSERT(ETC2_UNCOMPRESSED_PIXEL_SIZE_RGBA8 == 4);
859becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi			dstPixel[0] = srcPixelRGB[0];
860becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi			dstPixel[1] = srcPixelRGB[1];
861becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi			dstPixel[2] = srcPixelRGB[2];
862becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi			dstPixel[3] = srcPixelAlpha[0];
8633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
8643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
8653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
8663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
867becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvivoid decompressETC2_RGB8_PUNCHTHROUGH_ALPHA1 (const PixelBufferAccess& dst, const deUint8* src)
8683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
8693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	using namespace EtcDecompressInternal;
8703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint8* const	dstPtr			= (deUint8*)dst.getDataPtr();
8723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int		dstRowPitch		= dst.getRowPitch();
8733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int		dstPixelSize	= ETC2_UNCOMPRESSED_PIXEL_SIZE_RGBA8;
8743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
875becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi	const deUint64	compressedBlockRGBA	= get64BitBlock(src, 0);
876becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi	deUint8			uncompressedBlockRGB[ETC2_UNCOMPRESSED_BLOCK_SIZE_RGB8];
877becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi	deUint8			uncompressedBlockAlpha[ETC2_UNCOMPRESSED_BLOCK_SIZE_A8];
8783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
879becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi	// Decompress.
880becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi	decompressETC2Block(uncompressedBlockRGB, compressedBlockRGBA, uncompressedBlockAlpha, DE_TRUE);
8813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
882becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi	// Write to dst.
883becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi	for (int y = 0; y < (int)ETC2_BLOCK_HEIGHT; y++)
884becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi	{
885becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi		for (int x = 0; x < (int)ETC2_BLOCK_WIDTH; x++)
886becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi		{
887becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi			const deUint8* const	srcPixel		= &uncompressedBlockRGB[(y*ETC2_BLOCK_WIDTH + x)*ETC2_UNCOMPRESSED_PIXEL_SIZE_RGB8];
888becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi			const deUint8* const	srcPixelAlpha	= &uncompressedBlockAlpha[(y*ETC2_BLOCK_WIDTH + x)*ETC2_UNCOMPRESSED_PIXEL_SIZE_A8];
889becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi			deUint8* const			dstPixel		= dstPtr + y*dstRowPitch + x*dstPixelSize;
890becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi
891becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi			DE_STATIC_ASSERT(ETC2_UNCOMPRESSED_PIXEL_SIZE_RGBA8 == 4);
892becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi			dstPixel[0] = srcPixel[0];
893becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi			dstPixel[1] = srcPixel[1];
894becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi			dstPixel[2] = srcPixel[2];
895becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi			dstPixel[3] = srcPixelAlpha[0];
8963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
8973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
8983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
8993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
900becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvivoid decompressEAC_R11 (const PixelBufferAccess& dst, const deUint8* src, bool signedMode)
9013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
9023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	using namespace EtcDecompressInternal;
9033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint8* const	dstPtr			= (deUint8*)dst.getDataPtr();
9053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int		dstRowPitch		= dst.getRowPitch();
9063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int		dstPixelSize	= ETC2_UNCOMPRESSED_PIXEL_SIZE_R11;
9073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
908becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi	const deUint64	compressedBlock = get64BitBlock(src, 0);
909becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi	deUint8			uncompressedBlock[ETC2_UNCOMPRESSED_BLOCK_SIZE_R11];
910becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi
911becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi	// Decompress.
912becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi	decompressEAC11Block(uncompressedBlock, compressedBlock, signedMode);
913becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi
914becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi	// Write to dst.
915becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi	for (int y = 0; y < (int)ETC2_BLOCK_HEIGHT; y++)
9163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
917becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi		for (int x = 0; x < (int)ETC2_BLOCK_WIDTH; x++)
9183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
919becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi			DE_STATIC_ASSERT(ETC2_UNCOMPRESSED_PIXEL_SIZE_R11 == 2);
9203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
921becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi			if (signedMode)
9223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
923becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi				const deInt16* const	srcPixel = (deInt16*)&uncompressedBlock[(y*ETC2_BLOCK_WIDTH + x)*ETC2_UNCOMPRESSED_PIXEL_SIZE_R11];
924becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi				deInt16* const			dstPixel = (deInt16*)(dstPtr + y*dstRowPitch + x*dstPixelSize);
9253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
926becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi				dstPixel[0] = extend11To16WithSign(srcPixel[0]);
927becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi			}
928becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi			else
929becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi			{
930becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi				const deUint16* const	srcPixel = (deUint16*)&uncompressedBlock[(y*ETC2_BLOCK_WIDTH + x)*ETC2_UNCOMPRESSED_PIXEL_SIZE_R11];
931becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi				deUint16* const			dstPixel = (deUint16*)(dstPtr + y*dstRowPitch + x*dstPixelSize);
9323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
933becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi				dstPixel[0] = extend11To16(srcPixel[0]);
9343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
9353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
9363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
9373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
9383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
939becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvivoid decompressEAC_RG11 (const PixelBufferAccess& dst, const deUint8* src, bool signedMode)
9403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
9413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	using namespace EtcDecompressInternal;
9423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint8* const	dstPtr			= (deUint8*)dst.getDataPtr();
9443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int		dstRowPitch		= dst.getRowPitch();
9453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int		dstPixelSize	= ETC2_UNCOMPRESSED_PIXEL_SIZE_RG11;
9463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
947becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi	const deUint64	compressedBlockR = get128BitBlockStart(src, 0);
948becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi	const deUint64	compressedBlockG = get128BitBlockEnd(src, 0);
949becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi	deUint8			uncompressedBlockR[ETC2_UNCOMPRESSED_BLOCK_SIZE_R11];
950becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi	deUint8			uncompressedBlockG[ETC2_UNCOMPRESSED_BLOCK_SIZE_R11];
951becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi
952becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi	// Decompress.
953becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi	decompressEAC11Block(uncompressedBlockR, compressedBlockR, signedMode);
954becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi	decompressEAC11Block(uncompressedBlockG, compressedBlockG, signedMode);
955becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi
956becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi	// Write to dst.
957becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi	for (int y = 0; y < (int)ETC2_BLOCK_HEIGHT; y++)
9583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
959becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi		for (int x = 0; x < (int)ETC2_BLOCK_WIDTH; x++)
9603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
961becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi			DE_STATIC_ASSERT(ETC2_UNCOMPRESSED_PIXEL_SIZE_RG11 == 4);
962becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi
963becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi			if (signedMode)
9643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
965becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi				const deInt16* const	srcPixelR	= (deInt16*)&uncompressedBlockR[(y*ETC2_BLOCK_WIDTH + x)*ETC2_UNCOMPRESSED_PIXEL_SIZE_R11];
966becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi				const deInt16* const	srcPixelG	= (deInt16*)&uncompressedBlockG[(y*ETC2_BLOCK_WIDTH + x)*ETC2_UNCOMPRESSED_PIXEL_SIZE_R11];
967becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi				deInt16* const			dstPixel	= (deInt16*)(dstPtr + y*dstRowPitch + x*dstPixelSize);
9683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
969becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi				dstPixel[0] = extend11To16WithSign(srcPixelR[0]);
970becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi				dstPixel[1] = extend11To16WithSign(srcPixelG[0]);
971becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi			}
972becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi			else
973becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi			{
974becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi				const deUint16* const	srcPixelR	= (deUint16*)&uncompressedBlockR[(y*ETC2_BLOCK_WIDTH + x)*ETC2_UNCOMPRESSED_PIXEL_SIZE_R11];
975becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi				const deUint16* const	srcPixelG	= (deUint16*)&uncompressedBlockG[(y*ETC2_BLOCK_WIDTH + x)*ETC2_UNCOMPRESSED_PIXEL_SIZE_R11];
976becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi				deUint16* const			dstPixel	= (deUint16*)(dstPtr + y*dstRowPitch + x*dstPixelSize);
9773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
978becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi				dstPixel[0] = extend11To16(srcPixelR[0]);
979becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi				dstPixel[1] = extend11To16(srcPixelG[0]);
9803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
9813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
9823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
9833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
9843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
985efb83e1354edd463650ad0404b18e9a7efc307e4Pyry Haulosvoid decompressBlock (CompressedTexFormat format, const PixelBufferAccess& dst, const deUint8* src, const TexDecompressionParams& params)
9863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
987efb83e1354edd463650ad0404b18e9a7efc307e4Pyry Haulos	// No 3D blocks supported right now
988efb83e1354edd463650ad0404b18e9a7efc307e4Pyry Haulos	DE_ASSERT(dst.getDepth() == 1);
9893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
990efb83e1354edd463650ad0404b18e9a7efc307e4Pyry Haulos	switch (format)
9913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
992efb83e1354edd463650ad0404b18e9a7efc307e4Pyry Haulos		case COMPRESSEDTEXFORMAT_ETC1_RGB8:							decompressETC1							(dst, src);			break;
993efb83e1354edd463650ad0404b18e9a7efc307e4Pyry Haulos		case COMPRESSEDTEXFORMAT_EAC_R11:							decompressEAC_R11						(dst, src, false);	break;
994efb83e1354edd463650ad0404b18e9a7efc307e4Pyry Haulos		case COMPRESSEDTEXFORMAT_EAC_SIGNED_R11:					decompressEAC_R11						(dst, src, true);	break;
995efb83e1354edd463650ad0404b18e9a7efc307e4Pyry Haulos		case COMPRESSEDTEXFORMAT_EAC_RG11:							decompressEAC_RG11						(dst, src, false);	break;
996efb83e1354edd463650ad0404b18e9a7efc307e4Pyry Haulos		case COMPRESSEDTEXFORMAT_EAC_SIGNED_RG11:					decompressEAC_RG11						(dst, src, true);	break;
997efb83e1354edd463650ad0404b18e9a7efc307e4Pyry Haulos		case COMPRESSEDTEXFORMAT_ETC2_RGB8:							decompressETC2							(dst, src);			break;
998efb83e1354edd463650ad0404b18e9a7efc307e4Pyry Haulos		case COMPRESSEDTEXFORMAT_ETC2_SRGB8:						decompressETC2							(dst, src);			break;
999efb83e1354edd463650ad0404b18e9a7efc307e4Pyry Haulos		case COMPRESSEDTEXFORMAT_ETC2_RGB8_PUNCHTHROUGH_ALPHA1:		decompressETC2_RGB8_PUNCHTHROUGH_ALPHA1	(dst, src);			break;
1000efb83e1354edd463650ad0404b18e9a7efc307e4Pyry Haulos		case COMPRESSEDTEXFORMAT_ETC2_SRGB8_PUNCHTHROUGH_ALPHA1:	decompressETC2_RGB8_PUNCHTHROUGH_ALPHA1	(dst, src);			break;
1001efb83e1354edd463650ad0404b18e9a7efc307e4Pyry Haulos		case COMPRESSEDTEXFORMAT_ETC2_EAC_RGBA8:					decompressETC2_EAC_RGBA8				(dst, src);			break;
1002efb83e1354edd463650ad0404b18e9a7efc307e4Pyry Haulos		case COMPRESSEDTEXFORMAT_ETC2_EAC_SRGB8_ALPHA8:				decompressETC2_EAC_RGBA8				(dst, src);			break;
1003becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi
1004becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi		case COMPRESSEDTEXFORMAT_ASTC_4x4_RGBA:
1005becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi		case COMPRESSEDTEXFORMAT_ASTC_5x4_RGBA:
1006becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi		case COMPRESSEDTEXFORMAT_ASTC_5x5_RGBA:
1007becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi		case COMPRESSEDTEXFORMAT_ASTC_6x5_RGBA:
1008becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi		case COMPRESSEDTEXFORMAT_ASTC_6x6_RGBA:
1009becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi		case COMPRESSEDTEXFORMAT_ASTC_8x5_RGBA:
1010becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi		case COMPRESSEDTEXFORMAT_ASTC_8x6_RGBA:
1011becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi		case COMPRESSEDTEXFORMAT_ASTC_8x8_RGBA:
1012becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi		case COMPRESSEDTEXFORMAT_ASTC_10x5_RGBA:
1013becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi		case COMPRESSEDTEXFORMAT_ASTC_10x6_RGBA:
1014becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi		case COMPRESSEDTEXFORMAT_ASTC_10x8_RGBA:
1015becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi		case COMPRESSEDTEXFORMAT_ASTC_10x10_RGBA:
1016becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi		case COMPRESSEDTEXFORMAT_ASTC_12x10_RGBA:
1017becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi		case COMPRESSEDTEXFORMAT_ASTC_12x12_RGBA:
1018becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi		case COMPRESSEDTEXFORMAT_ASTC_4x4_SRGB8_ALPHA8:
1019becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi		case COMPRESSEDTEXFORMAT_ASTC_5x4_SRGB8_ALPHA8:
1020becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi		case COMPRESSEDTEXFORMAT_ASTC_5x5_SRGB8_ALPHA8:
1021becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi		case COMPRESSEDTEXFORMAT_ASTC_6x5_SRGB8_ALPHA8:
1022becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi		case COMPRESSEDTEXFORMAT_ASTC_6x6_SRGB8_ALPHA8:
1023becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi		case COMPRESSEDTEXFORMAT_ASTC_8x5_SRGB8_ALPHA8:
1024becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi		case COMPRESSEDTEXFORMAT_ASTC_8x6_SRGB8_ALPHA8:
1025becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi		case COMPRESSEDTEXFORMAT_ASTC_8x8_SRGB8_ALPHA8:
1026becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi		case COMPRESSEDTEXFORMAT_ASTC_10x5_SRGB8_ALPHA8:
1027becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi		case COMPRESSEDTEXFORMAT_ASTC_10x6_SRGB8_ALPHA8:
1028becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi		case COMPRESSEDTEXFORMAT_ASTC_10x8_SRGB8_ALPHA8:
1029becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi		case COMPRESSEDTEXFORMAT_ASTC_10x10_SRGB8_ALPHA8:
1030becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi		case COMPRESSEDTEXFORMAT_ASTC_12x10_SRGB8_ALPHA8:
1031becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi		case COMPRESSEDTEXFORMAT_ASTC_12x12_SRGB8_ALPHA8:
1032efb83e1354edd463650ad0404b18e9a7efc307e4Pyry Haulos			astc::decompress(dst, src, format, params.astcMode);
1033becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi			break;
1034becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi
1035becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi		default:
1036becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi			DE_ASSERT(false);
1037becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi			break;
10383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1039becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi}
1040becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi
1041becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärviint componentSum (const IVec3& vec)
1042becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi{
1043becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi	return vec.x() + vec.y() + vec.z();
1044becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi}
1045becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi
1046becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi} // anonymous
1047becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi
1048becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvivoid decompress (const PixelBufferAccess& dst, CompressedTexFormat fmt, const deUint8* src, const TexDecompressionParams& params)
1049becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi{
10505f78b1323b6ef28d8b9cdce6fefcbbb61a0477a9Pyry Haulos	const int				blockSize			= getBlockSize(fmt);
1051becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi	const IVec3				blockPixelSize		(getBlockPixelSize(fmt));
1052efb83e1354edd463650ad0404b18e9a7efc307e4Pyry Haulos	const IVec3				blockCount			(deDivRoundUp32(dst.getWidth(),		blockPixelSize.x()),
1053efb83e1354edd463650ad0404b18e9a7efc307e4Pyry Haulos												 deDivRoundUp32(dst.getHeight(),	blockPixelSize.y()),
1054efb83e1354edd463650ad0404b18e9a7efc307e4Pyry Haulos												 deDivRoundUp32(dst.getDepth(),		blockPixelSize.z()));
1055becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi	const IVec3				blockPitches		(blockSize, blockSize * blockCount.x(), blockSize * blockCount.x() * blockCount.y());
1056becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi
1057becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi	std::vector<deUint8>	uncompressedBlock	(dst.getFormat().getPixelSize() * blockPixelSize.x() * blockPixelSize.y() * blockPixelSize.z());
1058becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi	const PixelBufferAccess	blockAccess			(getUncompressedFormat(fmt), blockPixelSize.x(), blockPixelSize.y(), blockPixelSize.z(), &uncompressedBlock[0]);
1059becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi
1060becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi	DE_ASSERT(dst.getFormat() == getUncompressedFormat(fmt));
1061becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi
1062becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi	for (int blockZ = 0; blockZ < blockCount.z(); blockZ++)
1063becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi	for (int blockY = 0; blockY < blockCount.y(); blockY++)
1064becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi	for (int blockX = 0; blockX < blockCount.x(); blockX++)
10653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1066becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi		const IVec3				blockPos	(blockX, blockY, blockZ);
1067becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi		const deUint8* const	blockPtr	= src + componentSum(blockPos * blockPitches);
1068becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi		const IVec3				copySize	(de::min(blockPixelSize.x(), dst.getWidth()		- blockPos.x() * blockPixelSize.x()),
1069becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi											 de::min(blockPixelSize.y(), dst.getHeight()	- blockPos.y() * blockPixelSize.y()),
1070becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi											 de::min(blockPixelSize.z(), dst.getDepth()		- blockPos.z() * blockPixelSize.z()));
1071becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi		const IVec3				dstPixelPos	= blockPos * blockPixelSize;
10723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1073becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi		decompressBlock(fmt, blockAccess, blockPtr, params);
10743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10756c307165131fb7249bb044fc79ff0c2747263b3dJarkko Pöyry		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()));
1076becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi	}
1077becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi}
1078becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi
1079becd5d53015521acf7536ba754de326d8b1da2f3Mika IsojärviCompressedTexture::CompressedTexture (void)
1080becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi	: m_format	(COMPRESSEDTEXFORMAT_LAST)
1081becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi	, m_width	(0)
1082becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi	, m_height	(0)
1083becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi	, m_depth	(0)
1084becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi{
1085becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi}
1086becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi
1087becd5d53015521acf7536ba754de326d8b1da2f3Mika IsojärviCompressedTexture::CompressedTexture (CompressedTexFormat format, int width, int height, int depth)
1088becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi	: m_format	(COMPRESSEDTEXFORMAT_LAST)
1089becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi	, m_width	(0)
1090becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi	, m_height	(0)
1091becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi	, m_depth	(0)
1092becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi{
1093becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi	setStorage(format, width, height, depth);
1094becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi}
1095becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi
1096becd5d53015521acf7536ba754de326d8b1da2f3Mika IsojärviCompressedTexture::~CompressedTexture (void)
1097becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi{
1098becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi}
1099becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi
1100becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvivoid CompressedTexture::setStorage (CompressedTexFormat format, int width, int height, int depth)
1101becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi{
1102becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi	m_format	= format;
1103becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi	m_width		= width;
1104becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi	m_height	= height;
1105becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi	m_depth		= depth;
1106becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi
1107becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi	if (m_format != COMPRESSEDTEXFORMAT_LAST)
1108becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi	{
1109becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi		const IVec3	blockPixelSize	= getBlockPixelSize(m_format);
1110becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi		const int	blockSize		= getBlockSize(m_format);
1111becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi
1112efb83e1354edd463650ad0404b18e9a7efc307e4Pyry Haulos		m_data.resize(deDivRoundUp32(m_width, blockPixelSize.x()) * deDivRoundUp32(m_height, blockPixelSize.y()) * deDivRoundUp32(m_depth, blockPixelSize.z()) * blockSize);
11133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
11143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
1115becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi	{
1116becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi		DE_ASSERT(m_format == COMPRESSEDTEXFORMAT_LAST);
1117becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi		DE_ASSERT(m_width == 0 && m_height == 0 && m_depth == 0);
1118becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi		m_data.resize(0);
1119becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi	}
1120becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi}
1121becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi
1122becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi/*--------------------------------------------------------------------*//*!
1123becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi * \brief Decode to uncompressed pixel data
1124becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi * \param dst Destination buffer
1125becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi *//*--------------------------------------------------------------------*/
1126becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvivoid CompressedTexture::decompress (const PixelBufferAccess& dst, const TexDecompressionParams& params) const
1127becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi{
1128becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi	DE_ASSERT(dst.getWidth() == m_width && dst.getHeight() == m_height && dst.getDepth() == m_depth);
1129becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi	DE_ASSERT(dst.getFormat() == getUncompressedFormat(m_format));
1130becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi
1131becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi	tcu::decompress(dst, m_format, &m_data[0], params);
11323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
11333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // tcu
1135