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