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