#include "basisu_transcoder.h"
#include <limits.h>
#include "basisu_containers_impl.h"
#ifndef BASISD_IS_BIG_ENDIAN
#define BASISD_IS_BIG_ENDIAN …
#endif
#ifndef BASISD_USE_UNALIGNED_WORD_READS
#ifdef __EMSCRIPTEN__
#define BASISD_USE_UNALIGNED_WORD_READS …
#elif defined(_M_AMD64) || defined(_M_IX86) || defined(__i386__) || defined(__x86_64__)
#define BASISD_USE_UNALIGNED_WORD_READS …
#else
#define BASISD_USE_UNALIGNED_WORD_READS …
#endif
#endif
#if defined(__has_feature)
#if __has_feature(undefined_behavior_sanitizer)
#undef BASISD_USE_UNALIGNED_WORD_READS
#define BASISD_USE_UNALIGNED_WORD_READS …
#endif
#endif
#define BASISD_SUPPORTED_BASIS_VERSION …
#ifndef BASISD_SUPPORT_KTX2
#error Must have defined BASISD_SUPPORT_KTX2
#endif
#ifndef BASISD_SUPPORT_KTX2_ZSTD
#error Must have defined BASISD_SUPPORT_KTX2_ZSTD
#endif
#ifndef BASISU_NO_HEADER_OR_DATA_CRC16_CHECKS
#define BASISU_NO_HEADER_OR_DATA_CRC16_CHECKS …
#endif
#ifndef BASISD_SUPPORT_DXT1
#define BASISD_SUPPORT_DXT1 …
#endif
#ifndef BASISD_SUPPORT_DXT5A
#define BASISD_SUPPORT_DXT5A …
#endif
#if defined(BASISD_SUPPORT_BC7) && !BASISD_SUPPORT_BC7
#ifndef BASISD_SUPPORT_BC7_MODE5
#define BASISD_SUPPORT_BC7_MODE5 …
#endif
#endif
#ifndef BASISD_SUPPORT_BC7_MODE5
#define BASISD_SUPPORT_BC7_MODE5 …
#endif
#ifndef BASISD_SUPPORT_PVRTC1
#define BASISD_SUPPORT_PVRTC1 …
#endif
#ifndef BASISD_SUPPORT_ETC2_EAC_A8
#define BASISD_SUPPORT_ETC2_EAC_A8 …
#endif
#ifndef BASISD_SUPPORT_UASTC
#define BASISD_SUPPORT_UASTC …
#endif
#ifndef BASISD_SUPPORT_ASTC
#define BASISD_SUPPORT_ASTC …
#endif
#ifndef BASISD_SUPPORT_ATC
#define BASISD_SUPPORT_ATC …
#endif
#ifndef BASISD_SUPPORT_ETC2_EAC_RG11
#define BASISD_SUPPORT_ETC2_EAC_RG11 …
#endif
#ifndef BASISD_SUPPORT_ASTC_HIGHER_OPAQUE_QUALITY
#ifdef __EMSCRIPTEN__
#define BASISD_SUPPORT_ASTC_HIGHER_OPAQUE_QUALITY …
#else
#define BASISD_SUPPORT_ASTC_HIGHER_OPAQUE_QUALITY …
#endif
#endif
#ifndef BASISD_SUPPORT_FXT1
#define BASISD_SUPPORT_FXT1 …
#endif
#ifndef BASISD_SUPPORT_PVRTC2
#define BASISD_SUPPORT_PVRTC2 …
#endif
#if BASISD_SUPPORT_PVRTC2
#if !BASISD_SUPPORT_ATC
#error BASISD_SUPPORT_ATC must be 1 if BASISD_SUPPORT_PVRTC2 is 1
#endif
#endif
#if BASISD_SUPPORT_ATC
#if !BASISD_SUPPORT_DXT5A
#error BASISD_SUPPORT_DXT5A must be 1 if BASISD_SUPPORT_ATC is 1
#endif
#endif
#define BASISD_WRITE_NEW_BC7_MODE5_TABLES …
#define BASISD_WRITE_NEW_DXT1_TABLES …
#define BASISD_WRITE_NEW_ETC2_EAC_A8_TABLES …
#define BASISD_WRITE_NEW_ASTC_TABLES …
#define BASISD_WRITE_NEW_ATC_TABLES …
#define BASISD_WRITE_NEW_ETC2_EAC_R11_TABLES …
#ifndef BASISD_ENABLE_DEBUG_FLAGS
#define BASISD_ENABLE_DEBUG_FLAGS …
#endif
#if BASISD_SUPPORT_KTX2
#if BASISD_SUPPORT_KTX2_ZSTD
#include <zstd.h>
#endif
#endif
namespace basisu
{
bool g_debug_printf;
void enable_debug_printf(bool enabled)
{ … }
void debug_printf(const char* pFmt, ...)
{ … }
}
namespace basist
{
#if BASISD_ENABLE_DEBUG_FLAGS
static uint32_t g_debug_flags = 0;
#endif
uint32_t get_debug_flags()
{ … }
void set_debug_flags(uint32_t f)
{ … }
inline uint16_t byteswap_uint16(uint16_t v)
{ … }
static inline int32_t clampi(int32_t value, int32_t low, int32_t high) { … }
static inline float clampf(float value, float low, float high) { … }
static inline float saturate(float value) { … }
static inline uint8_t mul_8(uint32_t v, uint32_t q) { … }
uint16_t crc16(const void* r, size_t size, uint16_t crc)
{ … }
enum etc_constants
{ … };
#define DECLARE_ETC1_INTEN_TABLE(name, N) …
DECLARE_ETC1_INTEN_TABLE(g_etc1_inten_tables, 1);
DECLARE_ETC1_INTEN_TABLE(g_etc1_inten_tables16, 16);
DECLARE_ETC1_INTEN_TABLE(g_etc1_inten_tables48, 3 * 16);
const uint8_t g_selector_index_to_etc1[cETC1SelectorValues] = …;
static const uint8_t g_etc_5_to_8[32] = …;
struct decoder_etc_block
{ … };
enum dxt_constants
{ … };
static const uint8_t g_etc1_x_selector_unpack[4][256] = …;
struct dxt1_block
{ … };
struct dxt_selector_range
{ … };
struct etc1_to_dxt1_56_solution
{ … };
#if BASISD_SUPPORT_DXT1
static dxt_selector_range g_etc1_to_dxt1_selector_ranges[] = …;
const uint32_t NUM_ETC1_TO_DXT1_SELECTOR_RANGES = …;
static uint32_t g_etc1_to_dxt1_selector_range_index[4][4];
const uint32_t NUM_ETC1_TO_DXT1_SELECTOR_MAPPINGS = …;
static const uint8_t g_etc1_to_dxt1_selector_mappings[NUM_ETC1_TO_DXT1_SELECTOR_MAPPINGS][4] = …;
static uint8_t g_etc1_to_dxt1_selector_mappings_raw_dxt1_256[NUM_ETC1_TO_DXT1_SELECTOR_MAPPINGS][256];
static uint8_t g_etc1_to_dxt1_selector_mappings_raw_dxt1_inv_256[NUM_ETC1_TO_DXT1_SELECTOR_MAPPINGS][256];
static const etc1_to_dxt1_56_solution g_etc1_to_dxt_6[32 * 8 * NUM_ETC1_TO_DXT1_SELECTOR_MAPPINGS * NUM_ETC1_TO_DXT1_SELECTOR_RANGES] = …;
static const etc1_to_dxt1_56_solution g_etc1_to_dxt_5[32 * 8 * NUM_ETC1_TO_DXT1_SELECTOR_MAPPINGS * NUM_ETC1_TO_DXT1_SELECTOR_RANGES] = …;
#endif
#if BASISD_SUPPORT_DXT1 || BASISD_SUPPORT_UASTC
struct bc1_match_entry
{ … };
static bc1_match_entry g_bc1_match5_equals_1[256], g_bc1_match6_equals_1[256];
static bc1_match_entry g_bc1_match5_equals_0[256], g_bc1_match6_equals_0[256];
static void prepare_bc1_single_color_table(bc1_match_entry* pTable, const uint8_t* pExpand, int size0, int size1, int sel)
{ … }
#endif
#if BASISD_WRITE_NEW_DXT1_TABLES
static void create_etc1_to_dxt1_5_conversion_table()
{
FILE* pFile = nullptr;
fopen_s(&pFile, "basisu_transcoder_tables_dxt1_5.inc", "w");
uint32_t n = 0;
for (int inten = 0; inten < 8; inten++)
{
for (uint32_t g = 0; g < 32; g++)
{
color32 block_colors[4];
decoder_etc_block::get_diff_subblock_colors(block_colors, decoder_etc_block::pack_color5(color32(g, g, g, 255), false), inten);
for (uint32_t sr = 0; sr < NUM_ETC1_TO_DXT1_SELECTOR_RANGES; sr++)
{
const uint32_t low_selector = g_etc1_to_dxt1_selector_ranges[sr].m_low;
const uint32_t high_selector = g_etc1_to_dxt1_selector_ranges[sr].m_high;
for (uint32_t m = 0; m < NUM_ETC1_TO_DXT1_SELECTOR_MAPPINGS; m++)
{
uint32_t best_lo = 0;
uint32_t best_hi = 0;
uint64_t best_err = UINT64_MAX;
for (uint32_t hi = 0; hi <= 31; hi++)
{
for (uint32_t lo = 0; lo <= 31; lo++)
{
uint32_t colors[4];
colors[0] = (lo << 3) | (lo >> 2);
colors[3] = (hi << 3) | (hi >> 2);
colors[1] = (colors[0] * 2 + colors[3]) / 3;
colors[2] = (colors[3] * 2 + colors[0]) / 3;
uint64_t total_err = 0;
for (uint32_t s = low_selector; s <= high_selector; s++)
{
int err = block_colors[s].g - colors[g_etc1_to_dxt1_selector_mappings[m][s]];
total_err += err * err;
}
if (total_err < best_err)
{
best_err = total_err;
best_lo = lo;
best_hi = hi;
}
}
}
assert(best_err <= 0xFFFF);
fprintf(pFile, "{%u,%u,%u},", best_lo, best_hi, (uint32_t)best_err);
n++;
if ((n & 31) == 31)
fprintf(pFile, "\n");
}
}
}
}
fclose(pFile);
}
static void create_etc1_to_dxt1_6_conversion_table()
{
FILE* pFile = nullptr;
fopen_s(&pFile, "basisu_transcoder_tables_dxt1_6.inc", "w");
uint32_t n = 0;
for (int inten = 0; inten < 8; inten++)
{
for (uint32_t g = 0; g < 32; g++)
{
color32 block_colors[4];
decoder_etc_block::get_diff_subblock_colors(block_colors, decoder_etc_block::pack_color5(color32(g, g, g, 255), false), inten);
for (uint32_t sr = 0; sr < NUM_ETC1_TO_DXT1_SELECTOR_RANGES; sr++)
{
const uint32_t low_selector = g_etc1_to_dxt1_selector_ranges[sr].m_low;
const uint32_t high_selector = g_etc1_to_dxt1_selector_ranges[sr].m_high;
for (uint32_t m = 0; m < NUM_ETC1_TO_DXT1_SELECTOR_MAPPINGS; m++)
{
uint32_t best_lo = 0;
uint32_t best_hi = 0;
uint64_t best_err = UINT64_MAX;
for (uint32_t hi = 0; hi <= 63; hi++)
{
for (uint32_t lo = 0; lo <= 63; lo++)
{
uint32_t colors[4];
colors[0] = (lo << 2) | (lo >> 4);
colors[3] = (hi << 2) | (hi >> 4);
colors[1] = (colors[0] * 2 + colors[3]) / 3;
colors[2] = (colors[3] * 2 + colors[0]) / 3;
uint64_t total_err = 0;
for (uint32_t s = low_selector; s <= high_selector; s++)
{
int err = block_colors[s].g - colors[g_etc1_to_dxt1_selector_mappings[m][s]];
total_err += err * err;
}
if (total_err < best_err)
{
best_err = total_err;
best_lo = lo;
best_hi = hi;
}
}
}
assert(best_err <= 0xFFFF);
fprintf(pFile, "{%u,%u,%u},", best_lo, best_hi, (uint32_t)best_err);
n++;
if ((n & 31) == 31)
fprintf(pFile, "\n");
}
}
}
}
fclose(pFile);
}
#endif
#if BASISD_SUPPORT_UASTC || BASISD_SUPPORT_ETC2_EAC_A8 || BASISD_SUPPORT_ETC2_EAC_RG11
static const int8_t g_eac_modifier_table[16][8] = …;
struct eac_block
{ … };
#endif
#if BASISD_SUPPORT_ETC2_EAC_A8 || BASISD_SUPPORT_ETC2_EAC_RG11
static const dxt_selector_range s_etc2_eac_selector_ranges[] = …;
const uint32_t NUM_ETC2_EAC_SELECTOR_RANGES = …;
struct etc1_g_to_eac_conversion
{ … };
#endif
#if BASISD_SUPPORT_ETC2_EAC_A8
#if BASISD_WRITE_NEW_ETC2_EAC_A8_TABLES
struct pack_eac_a8_results
{
uint32_t m_base;
uint32_t m_table;
uint32_t m_multiplier;
basisu::vector<uint8_t> m_selectors;
basisu::vector<uint8_t> m_selectors_temp;
};
static uint64_t pack_eac_a8_exhaustive(pack_eac_a8_results& results, const uint8_t* pPixels, uint32_t num_pixels)
{
results.m_selectors.resize(num_pixels);
results.m_selectors_temp.resize(num_pixels);
uint64_t best_err = UINT64_MAX;
for (uint32_t base_color = 0; base_color < 256; base_color++)
{
for (uint32_t multiplier = 1; multiplier < 16; multiplier++)
{
for (uint32_t table = 0; table < 16; table++)
{
uint64_t total_err = 0;
for (uint32_t i = 0; i < num_pixels; i++)
{
const int a = pPixels[i];
uint32_t best_s_err = UINT32_MAX;
uint32_t best_s = 0;
for (uint32_t s = 0; s < 8; s++)
{
int v = (int)multiplier * g_eac_modifier_table[table][s] + (int)base_color;
if (v < 0)
v = 0;
else if (v > 255)
v = 255;
uint32_t err = abs(a - v);
if (err < best_s_err)
{
best_s_err = err;
best_s = s;
}
}
results.m_selectors_temp[i] = static_cast<uint8_t>(best_s);
total_err += best_s_err * best_s_err;
if (total_err >= best_err)
break;
}
if (total_err < best_err)
{
best_err = total_err;
results.m_base = base_color;
results.m_multiplier = multiplier;
results.m_table = table;
results.m_selectors.swap(results.m_selectors_temp);
}
}
}
}
return best_err;
}
#endif
static
#if !BASISD_WRITE_NEW_ETC2_EAC_A8_TABLES
const
#endif
etc1_g_to_eac_conversion s_etc1_g_to_etc2_a8[32 * 8][NUM_ETC2_EAC_SELECTOR_RANGES] = …;
#endif
#if BASISD_WRITE_NEW_ETC2_EAC_A8_TABLES
static void create_etc2_eac_a8_conversion_table()
{
FILE* pFile = fopen("basisu_decoder_tables_etc2_eac_a8.inc", "w");
for (uint32_t inten = 0; inten < 8; inten++)
{
for (uint32_t base = 0; base < 32; base++)
{
color32 block_colors[4];
decoder_etc_block::get_diff_subblock_colors(block_colors, decoder_etc_block::pack_color5(color32(base, base, base, 255), false), inten);
fprintf(pFile, "{");
for (uint32_t sel_range = 0; sel_range < NUM_ETC2_EAC_SELECTOR_RANGES; sel_range++)
{
const uint32_t low_selector = s_etc2_eac_selector_ranges[sel_range].m_low;
const uint32_t high_selector = s_etc2_eac_selector_ranges[sel_range].m_high;
uint8_t pixels[4];
uint32_t num_pixels = 0;
for (uint32_t s = low_selector; s <= high_selector; s++)
pixels[num_pixels++] = block_colors[s].g;
pack_eac_a8_results pack_results;
pack_eac_a8_exhaustive(pack_results, pixels, num_pixels);
etc1_g_to_eac_conversion& c = s_etc1_g_to_etc2_a8[base + inten * 32][sel_range];
c.m_base = pack_results.m_base;
c.m_table_mul = pack_results.m_table * 16 + pack_results.m_multiplier;
c.m_trans = 0;
for (uint32_t s = 0; s < 4; s++)
{
if ((s < low_selector) || (s > high_selector))
continue;
uint32_t etc2_selector = pack_results.m_selectors[s - low_selector];
c.m_trans |= (etc2_selector << (s * 3));
}
fprintf(pFile, "{%u,%u,%u}", c.m_base, c.m_table_mul, c.m_trans);
if (sel_range < (NUM_ETC2_EAC_SELECTOR_RANGES - 1))
fprintf(pFile, ",");
}
fprintf(pFile, "},\n");
}
}
fclose(pFile);
}
#endif
#if BASISD_WRITE_NEW_ETC2_EAC_R11_TABLES
struct pack_eac_r11_results
{
uint32_t m_base;
uint32_t m_table;
uint32_t m_multiplier;
basisu::vector<uint8_t> m_selectors;
basisu::vector<uint8_t> m_selectors_temp;
};
static uint64_t pack_eac_r11_exhaustive(pack_eac_r11_results& results, const uint8_t* pPixels, uint32_t num_pixels)
{
results.m_selectors.resize(num_pixels);
results.m_selectors_temp.resize(num_pixels);
uint64_t best_err = UINT64_MAX;
for (uint32_t base_color = 0; base_color < 256; base_color++)
{
for (uint32_t multiplier = 0; multiplier < 16; multiplier++)
{
for (uint32_t table = 0; table < 16; table++)
{
uint64_t total_err = 0;
for (uint32_t i = 0; i < num_pixels; i++)
{
const int a = (pPixels[i] * 2047 + 128) / 255;
uint32_t best_s_err = UINT32_MAX;
uint32_t best_s = 0;
for (uint32_t s = 0; s < 8; s++)
{
int v = (int)(multiplier ? (multiplier * 8) : 1) * g_eac_modifier_table[table][s] + (int)base_color * 8 + 4;
if (v < 0)
v = 0;
else if (v > 2047)
v = 2047;
uint32_t err = abs(a - v);
if (err < best_s_err)
{
best_s_err = err;
best_s = s;
}
}
results.m_selectors_temp[i] = static_cast<uint8_t>(best_s);
total_err += best_s_err * best_s_err;
if (total_err >= best_err)
break;
}
if (total_err < best_err)
{
best_err = total_err;
results.m_base = base_color;
results.m_multiplier = multiplier;
results.m_table = table;
results.m_selectors.swap(results.m_selectors_temp);
}
}
}
}
return best_err;
}
static void create_etc2_eac_r11_conversion_table()
{
FILE* pFile = nullptr;
fopen_s(&pFile, "basisu_decoder_tables_etc2_eac_r11.inc", "w");
for (uint32_t inten = 0; inten < 8; inten++)
{
for (uint32_t base = 0; base < 32; base++)
{
color32 block_colors[4];
decoder_etc_block::get_diff_subblock_colors(block_colors, decoder_etc_block::pack_color5(color32(base, base, base, 255), false), inten);
fprintf(pFile, "{");
for (uint32_t sel_range = 0; sel_range < NUM_ETC2_EAC_SELECTOR_RANGES; sel_range++)
{
const uint32_t low_selector = s_etc2_eac_selector_ranges[sel_range].m_low;
const uint32_t high_selector = s_etc2_eac_selector_ranges[sel_range].m_high;
uint8_t pixels[4];
uint32_t num_pixels = 0;
for (uint32_t s = low_selector; s <= high_selector; s++)
pixels[num_pixels++] = block_colors[s].g;
pack_eac_r11_results pack_results;
pack_eac_r11_exhaustive(pack_results, pixels, num_pixels);
etc1_g_to_eac_conversion c;
c.m_base = (uint8_t)pack_results.m_base;
c.m_table_mul = (uint8_t)(pack_results.m_table * 16 + pack_results.m_multiplier);
c.m_trans = 0;
for (uint32_t s = 0; s < 4; s++)
{
if ((s < low_selector) || (s > high_selector))
continue;
uint32_t etc2_selector = pack_results.m_selectors[s - low_selector];
c.m_trans |= (etc2_selector << (s * 3));
}
fprintf(pFile, "{%u,%u,%u}", c.m_base, c.m_table_mul, c.m_trans);
if (sel_range < (NUM_ETC2_EAC_SELECTOR_RANGES - 1))
fprintf(pFile, ",");
}
fprintf(pFile, "},\n");
}
}
fclose(pFile);
}
#endif
#if BASISD_WRITE_NEW_ASTC_TABLES
static void create_etc1_to_astc_conversion_table_0_47();
static void create_etc1_to_astc_conversion_table_0_255();
#endif
#if BASISD_SUPPORT_ASTC
static void transcoder_init_astc();
#endif
#if BASISD_WRITE_NEW_BC7_MODE5_TABLES
static void create_etc1_to_bc7_m5_color_conversion_table();
static void create_etc1_to_bc7_m5_alpha_conversion_table();
#endif
#if BASISD_SUPPORT_BC7_MODE5
static void transcoder_init_bc7_mode5();
#endif
#if BASISD_WRITE_NEW_ATC_TABLES
static void create_etc1s_to_atc_conversion_tables();
#endif
#if BASISD_SUPPORT_ATC
static void transcoder_init_atc();
#endif
#if BASISD_SUPPORT_PVRTC2
static void transcoder_init_pvrtc2();
#endif
#if BASISD_SUPPORT_UASTC
void uastc_init();
#endif
static bool g_transcoder_initialized;
void basisu_transcoder_init()
{ … }
#if BASISD_SUPPORT_DXT1
static void convert_etc1s_to_dxt1(dxt1_block* pDst_block, const endpoint *pEndpoints, const selector* pSelector, bool use_threecolor_blocks)
{ … }
#if BASISD_ENABLE_DEBUG_FLAGS
static void convert_etc1s_to_dxt1_vis(dxt1_block* pDst_block, const endpoint* pEndpoints, const selector* pSelector, bool use_threecolor_blocks)
{
convert_etc1s_to_dxt1(pDst_block, pEndpoints, pSelector, use_threecolor_blocks);
if (g_debug_flags & cDebugFlagVisBC1Sels)
{
uint32_t l = dxt1_block::pack_unscaled_color(31, 63, 31);
uint32_t h = dxt1_block::pack_unscaled_color(0, 0, 0);
pDst_block->set_low_color(static_cast<uint16_t>(l));
pDst_block->set_high_color(static_cast<uint16_t>(h));
}
else if (g_debug_flags & cDebugFlagVisBC1Endpoints)
{
for (uint32_t y = 0; y < 4; y++)
for (uint32_t x = 0; x < 4; x++)
pDst_block->set_selector(x, y, (y < 2) ? 0 : 1);
}
}
#endif
#endif
#if BASISD_SUPPORT_FXT1
struct fxt1_block
{ … };
static uint8_t conv_dxt1_to_fxt1_sels(uint32_t sels)
{ … }
static void convert_etc1s_to_fxt1(void *pDst, const endpoint *pEndpoints, const selector *pSelectors, uint32_t fxt1_subblock)
{ … }
#endif
#if BASISD_SUPPORT_DXT5A
static dxt_selector_range s_dxt5a_selector_ranges[] = …;
const uint32_t NUM_DXT5A_SELECTOR_RANGES = …;
struct etc1_g_to_dxt5a_conversion
{ … };
static etc1_g_to_dxt5a_conversion g_etc1_g_to_dxt5a[32 * 8][NUM_DXT5A_SELECTOR_RANGES] = …;
struct dxt5a_block
{ … };
static void convert_etc1s_to_dxt5a(dxt5a_block* pDst_block, const endpoint* pEndpoints, const selector* pSelector)
{ … }
#endif
#if BASISD_SUPPORT_PVRTC1 || BASISD_SUPPORT_UASTC
static const uint16_t g_pvrtc_swizzle_table[256] = …;
static const uint8_t g_pvrtc_5[32] = …;
static const uint8_t g_pvrtc_4[16] = …;
static const uint8_t g_pvrtc_3[8] = …;
static const uint8_t g_pvrtc_alpha[9] = …;
static const uint8_t g_pvrtc_5_floor[256] = …;
static const uint8_t g_pvrtc_5_ceil[256] = …;
static const uint8_t g_pvrtc_4_floor[256] = …;
static const uint8_t g_pvrtc_4_ceil[256] = …;
static const uint8_t g_pvrtc_3_floor[256] = …;
static const uint8_t g_pvrtc_3_ceil[256] = …;
static const uint8_t g_pvrtc_alpha_floor[256] = …;
static const uint8_t g_pvrtc_alpha_ceil[256] = …;
struct pvrtc4_block
{ … };
#if 0
static const uint8_t g_pvrtc_bilinear_weights[16][4] =
{
{ 4, 4, 4, 4 }, { 2, 6, 2, 6 }, { 8, 0, 8, 0 }, { 6, 2, 6, 2 },
{ 2, 2, 6, 6 }, { 1, 3, 3, 9 }, { 4, 0, 12, 0 }, { 3, 1, 9, 3 },
{ 8, 8, 0, 0 }, { 4, 12, 0, 0 }, { 16, 0, 0, 0 }, { 12, 4, 0, 0 },
{ 6, 6, 2, 2 }, { 3, 9, 1, 3 }, { 12, 0, 4, 0 }, { 9, 3, 3, 1 },
};
#endif
struct pvrtc1_temp_block
{ … };
static inline uint32_t get_opaque_endpoint_l0(uint32_t endpoints)
{ … }
static inline uint32_t get_opaque_endpoint_l1(uint32_t endpoints)
{ … }
static color32 get_endpoint_8888(uint32_t endpoints, uint32_t endpoint_index)
{ … }
static uint32_t get_endpoint_l8(uint32_t endpoints, uint32_t endpoint_index)
{ … }
#endif
#if BASISD_SUPPORT_PVRTC1
static void fixup_pvrtc1_4_modulation_rgb(const decoder_etc_block* pETC_Blocks, const uint32_t* pPVRTC_endpoints, void* pDst_blocks, uint32_t num_blocks_x, uint32_t num_blocks_y)
{ … }
static void fixup_pvrtc1_4_modulation_rgba(
const decoder_etc_block* pETC_Blocks,
const uint32_t* pPVRTC_endpoints,
void* pDst_blocks, uint32_t num_blocks_x, uint32_t num_blocks_y, void *pAlpha_blocks,
const endpoint* pEndpoints, const selector* pSelectors)
{ … }
#endif
#if BASISD_SUPPORT_BC7_MODE5
static dxt_selector_range g_etc1_to_bc7_m5_selector_ranges[] = …;
const uint32_t NUM_ETC1_TO_BC7_M5_SELECTOR_RANGES = …;
static uint32_t g_etc1_to_bc7_m5_selector_range_index[4][4];
const uint32_t NUM_ETC1_TO_BC7_M5_SELECTOR_MAPPINGS = …;
static const uint8_t g_etc1_to_bc7_m5_selector_mappings[NUM_ETC1_TO_BC7_M5_SELECTOR_MAPPINGS][4] = …;
struct etc1_to_bc7_m5_solution
{ … };
static const etc1_to_bc7_m5_solution g_etc1_to_bc7_m5_color[32 * 8 * NUM_ETC1_TO_BC7_M5_SELECTOR_MAPPINGS * NUM_ETC1_TO_BC7_M5_SELECTOR_RANGES] = …;
static dxt_selector_range g_etc1_to_bc7_m5a_selector_ranges[] = …;
const uint32_t NUM_ETC1_TO_BC7_M5A_SELECTOR_RANGES = …;
static uint32_t g_etc1_to_bc7_m5a_selector_range_index[4][4];
struct etc1_g_to_bc7_m5a_conversion
{ … };
static etc1_g_to_bc7_m5a_conversion g_etc1_g_to_bc7_m5a[8 * 32 * NUM_ETC1_TO_BC7_M5A_SELECTOR_RANGES] = …;
static inline uint32_t set_block_bits(uint8_t* pBytes, uint32_t val, uint32_t num_bits, uint32_t cur_ofs)
{ … }
struct bc7_mode_5
{ … };
#if BASISD_WRITE_NEW_BC7_MODE5_TABLES
static void create_etc1_to_bc7_m5_color_conversion_table()
{
FILE* pFile = nullptr;
fopen_s(&pFile, "basisu_transcoder_tables_bc7_m5_color.inc", "w");
uint32_t n = 0;
for (int inten = 0; inten < 8; inten++)
{
for (uint32_t g = 0; g < 32; g++)
{
color32 block_colors[4];
decoder_etc_block::get_diff_subblock_colors(block_colors, decoder_etc_block::pack_color5(color32(g, g, g, 255), false), inten);
for (uint32_t sr = 0; sr < NUM_ETC1_TO_BC7_M5_SELECTOR_RANGES; sr++)
{
const uint32_t low_selector = g_etc1_to_bc7_m5_selector_ranges[sr].m_low;
const uint32_t high_selector = g_etc1_to_bc7_m5_selector_ranges[sr].m_high;
for (uint32_t m = 0; m < NUM_ETC1_TO_BC7_M5_SELECTOR_MAPPINGS; m++)
{
uint32_t best_lo = 0;
uint32_t best_hi = 0;
uint64_t best_err = UINT64_MAX;
for (uint32_t hi = 0; hi <= 127; hi++)
{
for (uint32_t lo = 0; lo <= 127; lo++)
{
uint32_t colors[4];
colors[0] = (lo << 1) | (lo >> 6);
colors[3] = (hi << 1) | (hi >> 6);
colors[1] = (colors[0] * (64 - 21) + colors[3] * 21 + 32) / 64;
colors[2] = (colors[0] * (64 - 43) + colors[3] * 43 + 32) / 64;
uint64_t total_err = 0;
for (uint32_t s = low_selector; s <= high_selector; s++)
{
int err = block_colors[s].g - colors[g_etc1_to_bc7_m5_selector_mappings[m][s]];
int err_scale = 1;
if (((inten == 7) && (low_selector == 0) && (high_selector == 3)) && ((s == 0) || (s == 3)))
err_scale = 5;
total_err += (err * err) * err_scale;
}
if (total_err < best_err)
{
best_err = total_err;
best_lo = lo;
best_hi = hi;
}
}
}
best_err = basisu::minimum<uint32_t>(best_err, 0xFFFF);
fprintf(pFile, "{%u,%u,%u},", best_lo, best_hi, (uint32_t)best_err);
n++;
if ((n & 31) == 31)
fprintf(pFile, "\n");
}
}
}
}
fclose(pFile);
}
static void create_etc1_to_bc7_m5_alpha_conversion_table()
{
FILE* pFile = nullptr;
fopen_s(&pFile, "basisu_transcoder_tables_bc7_m5_alpha.inc", "w");
uint32_t n = 0;
for (int inten = 0; inten < 8; inten++)
{
for (uint32_t g = 0; g < 32; g++)
{
color32 block_colors[4];
decoder_etc_block::get_diff_subblock_colors(block_colors, decoder_etc_block::pack_color5(color32(g, g, g, 255), false), inten);
for (uint32_t sr = 0; sr < NUM_ETC1_TO_BC7_M5A_SELECTOR_RANGES; sr++)
{
const uint32_t low_selector = g_etc1_to_bc7_m5a_selector_ranges[sr].m_low;
const uint32_t high_selector = g_etc1_to_bc7_m5a_selector_ranges[sr].m_high;
uint32_t best_lo = 0;
uint32_t best_hi = 0;
uint64_t best_err = UINT64_MAX;
uint32_t best_output_selectors = 0;
for (uint32_t hi = 0; hi <= 255; hi++)
{
for (uint32_t lo = 0; lo <= 255; lo++)
{
uint32_t colors[4];
colors[0] = lo;
colors[3] = hi;
colors[1] = (colors[0] * (64 - 21) + colors[3] * 21 + 32) / 64;
colors[2] = (colors[0] * (64 - 43) + colors[3] * 43 + 32) / 64;
uint64_t total_err = 0;
uint32_t output_selectors = 0;
for (uint32_t s = low_selector; s <= high_selector; s++)
{
int best_mapping_err = INT_MAX;
int best_k = 0;
for (int k = 0; k < 4; k++)
{
int mapping_err = block_colors[s].g - colors[k];
mapping_err *= mapping_err;
if (((inten == 7) && (low_selector == 0) && (high_selector == 3)) && ((s == 0) || (s == 3)))
mapping_err *= 5;
if (mapping_err < best_mapping_err)
{
best_mapping_err = mapping_err;
best_k = k;
}
}
total_err += best_mapping_err;
output_selectors |= (best_k << (s * 2));
}
if (total_err < best_err)
{
best_err = total_err;
best_lo = lo;
best_hi = hi;
best_output_selectors = output_selectors;
}
}
}
fprintf(pFile, "{%u,%u,%u},", best_lo, best_hi, best_output_selectors);
n++;
if ((n & 31) == 31)
fprintf(pFile, "\n");
}
}
}
fclose(pFile);
}
#endif
struct bc7_m5_match_entry
{ … };
static bc7_m5_match_entry g_bc7_m5_equals_1[256] = …;
static void transcoder_init_bc7_mode5()
{ … }
static void convert_etc1s_to_bc7_m5_color(void* pDst, const endpoint* pEndpoints, const selector* pSelector)
{ … }
static void convert_etc1s_to_bc7_m5_alpha(void* pDst, const endpoint* pEndpoints, const selector* pSelector)
{ … }
#endif
#if BASISD_SUPPORT_ETC2_EAC_A8 || BASISD_SUPPORT_UASTC
static const uint8_t g_etc2_eac_a8_sel4[6] = …;
#endif
#if BASISD_SUPPORT_ETC2_EAC_A8
static void convert_etc1s_to_etc2_eac_a8(eac_block* pDst_block, const endpoint* pEndpoints, const selector* pSelector)
{ … }
#endif
#if BASISD_SUPPORT_ETC2_EAC_RG11
static const etc1_g_to_eac_conversion s_etc1_g_to_etc2_r11[32 * 8][NUM_ETC2_EAC_SELECTOR_RANGES] = …;
static void convert_etc1s_to_etc2_eac_r11(eac_block* pDst_block, const endpoint* pEndpoints, const selector* pSelector)
{ … }
#endif
struct etc1_to_astc_solution
{ … };
#if BASISD_SUPPORT_ASTC
static dxt_selector_range g_etc1_to_astc_selector_ranges[] = …;
const uint32_t NUM_ETC1_TO_ASTC_SELECTOR_RANGES = …;
static uint32_t g_etc1_to_astc_selector_range_index[4][4];
const uint32_t NUM_ETC1_TO_ASTC_SELECTOR_MAPPINGS = …;
static const uint8_t g_etc1_to_astc_selector_mappings[NUM_ETC1_TO_ASTC_SELECTOR_MAPPINGS][4] = …;
static const etc1_to_astc_solution g_etc1_to_astc[32 * 8 * NUM_ETC1_TO_ASTC_SELECTOR_MAPPINGS * NUM_ETC1_TO_ASTC_SELECTOR_RANGES] = …;
static uint8_t g_etc1_to_astc_best_grayscale_mapping[32][8][NUM_ETC1_TO_ASTC_SELECTOR_RANGES];
#if BASISD_SUPPORT_ASTC_HIGHER_OPAQUE_QUALITY
static const etc1_to_astc_solution g_etc1_to_astc_0_255[32 * 8 * NUM_ETC1_TO_ASTC_SELECTOR_MAPPINGS * NUM_ETC1_TO_ASTC_SELECTOR_RANGES] = …;
static uint8_t g_etc1_to_astc_best_grayscale_mapping_0_255[32][8][NUM_ETC1_TO_ASTC_SELECTOR_RANGES];
#endif
static uint32_t g_ise_to_unquant[48];
#if BASISD_WRITE_NEW_ASTC_TABLES
static void create_etc1_to_astc_conversion_table_0_47()
{
FILE* pFile = nullptr;
fopen_s(&pFile, "basisu_transcoder_tables_astc.inc", "w");
uint32_t n = 0;
for (int inten = 0; inten < 8; inten++)
{
for (uint32_t g = 0; g < 32; g++)
{
color32 block_colors[4];
decoder_etc_block::get_diff_subblock_colors(block_colors, decoder_etc_block::pack_color5(color32(g, g, g, 255), false), inten);
for (uint32_t sr = 0; sr < NUM_ETC1_TO_ASTC_SELECTOR_RANGES; sr++)
{
const uint32_t low_selector = g_etc1_to_astc_selector_ranges[sr].m_low;
const uint32_t high_selector = g_etc1_to_astc_selector_ranges[sr].m_high;
uint32_t mapping_best_low[NUM_ETC1_TO_ASTC_SELECTOR_MAPPINGS];
uint32_t mapping_best_high[NUM_ETC1_TO_ASTC_SELECTOR_MAPPINGS];
uint64_t mapping_best_err[NUM_ETC1_TO_ASTC_SELECTOR_MAPPINGS];
uint64_t highest_best_err = 0;
for (uint32_t m = 0; m < NUM_ETC1_TO_ASTC_SELECTOR_MAPPINGS; m++)
{
uint32_t best_lo = 0;
uint32_t best_hi = 0;
uint64_t best_err = UINT64_MAX;
for (uint32_t hi = 0; hi <= 47; hi++)
{
for (uint32_t lo = 0; lo <= 47; lo++)
{
uint32_t colors[4];
for (uint32_t s = 0; s < 4; s++)
{
uint32_t s_scaled = s | (s << 2) | (s << 4);
if (s_scaled > 32)
s_scaled++;
uint32_t c0 = g_ise_to_unquant[lo] | (g_ise_to_unquant[lo] << 8);
uint32_t c1 = g_ise_to_unquant[hi] | (g_ise_to_unquant[hi] << 8);
colors[s] = ((c0 * (64 - s_scaled) + c1 * s_scaled + 32) / 64) >> 8;
}
uint64_t total_err = 0;
for (uint32_t s = low_selector; s <= high_selector; s++)
{
int err = block_colors[s].g - colors[g_etc1_to_astc_selector_mappings[m][s]];
int err_scale = 1;
if (((inten == 7) && (low_selector == 0) && (high_selector == 3)) && ((s == 0) || (s == 3)))
err_scale = 8;
total_err += (err * err) * err_scale;
}
if (total_err < best_err)
{
best_err = total_err;
best_lo = lo;
best_hi = hi;
}
}
}
mapping_best_low[m] = best_lo;
mapping_best_high[m] = best_hi;
mapping_best_err[m] = best_err;
highest_best_err = basisu::maximum(highest_best_err, best_err);
}
for (uint32_t m = 0; m < NUM_ETC1_TO_ASTC_SELECTOR_MAPPINGS; m++)
{
uint64_t err = mapping_best_err[m];
err = basisu::minimum<uint64_t>(err, 0xFFFF);
fprintf(pFile, "{%u,%u,%u},", mapping_best_low[m], mapping_best_high[m], (uint32_t)err);
n++;
if ((n & 31) == 31)
fprintf(pFile, "\n");
}
}
}
}
fclose(pFile);
}
static void create_etc1_to_astc_conversion_table_0_255()
{
FILE* pFile = nullptr;
fopen_s(&pFile, "basisu_transcoder_tables_astc_0_255.inc", "w");
uint32_t n = 0;
for (int inten = 0; inten < 8; inten++)
{
for (uint32_t g = 0; g < 32; g++)
{
color32 block_colors[4];
decoder_etc_block::get_diff_subblock_colors(block_colors, decoder_etc_block::pack_color5(color32(g, g, g, 255), false), inten);
for (uint32_t sr = 0; sr < NUM_ETC1_TO_ASTC_SELECTOR_RANGES; sr++)
{
const uint32_t low_selector = g_etc1_to_astc_selector_ranges[sr].m_low;
const uint32_t high_selector = g_etc1_to_astc_selector_ranges[sr].m_high;
uint32_t mapping_best_low[NUM_ETC1_TO_ASTC_SELECTOR_MAPPINGS];
uint32_t mapping_best_high[NUM_ETC1_TO_ASTC_SELECTOR_MAPPINGS];
uint64_t mapping_best_err[NUM_ETC1_TO_ASTC_SELECTOR_MAPPINGS];
uint64_t highest_best_err = 0;
for (uint32_t m = 0; m < NUM_ETC1_TO_ASTC_SELECTOR_MAPPINGS; m++)
{
uint32_t best_lo = 0;
uint32_t best_hi = 0;
uint64_t best_err = UINT64_MAX;
for (uint32_t hi = 0; hi <= 255; hi++)
{
for (uint32_t lo = 0; lo <= 255; lo++)
{
uint32_t colors[4];
for (uint32_t s = 0; s < 4; s++)
{
uint32_t s_scaled = s | (s << 2) | (s << 4);
if (s_scaled > 32)
s_scaled++;
uint32_t c0 = lo | (lo << 8);
uint32_t c1 = hi | (hi << 8);
colors[s] = ((c0 * (64 - s_scaled) + c1 * s_scaled + 32) / 64) >> 8;
}
uint64_t total_err = 0;
for (uint32_t s = low_selector; s <= high_selector; s++)
{
int err = block_colors[s].g - colors[g_etc1_to_astc_selector_mappings[m][s]];
int err_scale = 1;
if (((inten == 7) && (low_selector == 0) && (high_selector == 3)) && ((s == 0) || (s == 3)))
err_scale = 8;
total_err += (err * err) * err_scale;
}
if (total_err < best_err)
{
best_err = total_err;
best_lo = lo;
best_hi = hi;
}
}
}
mapping_best_low[m] = best_lo;
mapping_best_high[m] = best_hi;
mapping_best_err[m] = best_err;
highest_best_err = basisu::maximum(highest_best_err, best_err);
}
for (uint32_t m = 0; m < NUM_ETC1_TO_ASTC_SELECTOR_MAPPINGS; m++)
{
uint64_t err = mapping_best_err[m];
err = basisu::minimum<uint64_t>(err, 0xFFFF);
fprintf(pFile, "{%u,%u,%u},", mapping_best_low[m], mapping_best_high[m], (uint32_t)err);
n++;
if ((n & 31) == 31)
fprintf(pFile, "\n");
}
}
}
}
fclose(pFile);
}
#endif
#endif
#if BASISD_SUPPORT_UASTC || BASISD_SUPPORT_ASTC
static const uint8_t g_astc_trit_encode[243] = …;
static inline uint32_t astc_extract_bits(uint32_t bits, int low, int high)
{ … }
static inline void astc_set_bits(uint32_t* pOutput, int& bit_pos, uint32_t value, uint32_t total_bits)
{ … }
static void astc_encode_trits(uint32_t* pOutput, const uint8_t* pValues, int& bit_pos, int n)
{ … }
#endif
#if BASISD_SUPPORT_ASTC
struct astc_block_params
{ … };
static void astc_pack_block_cem_12_weight_range2(uint32_t *pOutput, const astc_block_params* pBlock)
{ … }
static void astc_pack_block_cem_12_weight_range0(uint32_t* pOutput, const astc_block_params* pBlock)
{ … }
#if BASISD_SUPPORT_ASTC_HIGHER_OPAQUE_QUALITY
static void astc_pack_block_cem_4_weight_range2(uint32_t* pOutput, const astc_block_params* pBlock)
{ … }
static void astc_pack_block_cem_8_weight_range2(uint32_t* pOutput, const astc_block_params* pBlock)
{ … }
#endif
static uint8_t g_astc_single_color_encoding_0[256];
static struct
{ … } g_astc_single_color_encoding_1[256];
static void transcoder_init_astc()
{ … }
static void convert_etc1s_to_astc_4x4(void* pDst_block, const endpoint* pEndpoints, const selector* pSelector,
bool transcode_alpha, const endpoint *pEndpoint_codebook, const selector *pSelector_codebook)
{ … }
#endif
#if BASISD_SUPPORT_ATC
struct etc1s_to_atc_solution
{ … };
static dxt_selector_range g_etc1s_to_atc_selector_ranges[] = …;
const uint32_t NUM_ETC1S_TO_ATC_SELECTOR_RANGES = …;
static uint32_t g_etc1s_to_atc_selector_range_index[4][4];
const uint32_t NUM_ETC1S_TO_ATC_SELECTOR_MAPPINGS = …;
static const uint8_t g_etc1s_to_atc_selector_mappings[NUM_ETC1S_TO_ATC_SELECTOR_MAPPINGS][4] = …;
const uint32_t ATC_IDENTITY_SELECTOR_MAPPING_INDEX = …;
#if BASISD_SUPPORT_PVRTC2
static const etc1s_to_atc_solution g_etc1s_to_pvrtc2_45[32 * 8 * NUM_ETC1S_TO_ATC_SELECTOR_MAPPINGS * NUM_ETC1S_TO_ATC_SELECTOR_RANGES] = …;
#if 0
static const etc1s_to_atc_solution g_etc1s_to_pvrtc2_alpha_33[32 * 8 * NUM_ETC1S_TO_ATC_SELECTOR_MAPPINGS * NUM_ETC1S_TO_ATC_SELECTOR_RANGES] = {
#include "basisu_transcoder_tables_pvrtc2_alpha_33.inc"
};
#endif
#endif
static const etc1s_to_atc_solution g_etc1s_to_atc_55[32 * 8 * NUM_ETC1S_TO_ATC_SELECTOR_MAPPINGS * NUM_ETC1S_TO_ATC_SELECTOR_RANGES] = …;
static const etc1s_to_atc_solution g_etc1s_to_atc_56[32 * 8 * NUM_ETC1S_TO_ATC_SELECTOR_MAPPINGS * NUM_ETC1S_TO_ATC_SELECTOR_RANGES] = …;
struct atc_match_entry
{ … };
static atc_match_entry g_pvrtc2_match45_equals_1[256], g_atc_match55_equals_1[256], g_atc_match56_equals_1[256];
static atc_match_entry g_pvrtc2_match4[256], g_atc_match5[256], g_atc_match6[256];
static void prepare_atc_single_color_table(atc_match_entry* pTable, int size0, int size1, int sel)
{ … }
static void transcoder_init_atc()
{ … }
struct atc_block
{ … };
static void convert_etc1s_to_atc(void* pDst, const endpoint* pEndpoints, const selector* pSelector)
{ … }
#if BASISD_WRITE_NEW_ATC_TABLES
static void create_etc1s_to_atc_conversion_tables()
{
FILE* pFile = nullptr;
fopen_s(&pFile, "basisu_transcoder_tables_atc_55.inc", "w");
uint32_t n = 0;
for (int inten = 0; inten < 8; inten++)
{
for (uint32_t g = 0; g < 32; g++)
{
color32 block_colors[4];
decoder_etc_block::get_diff_subblock_colors(block_colors, decoder_etc_block::pack_color5(color32(g, g, g, 255), false), inten);
for (uint32_t sr = 0; sr < NUM_ETC1S_TO_ATC_SELECTOR_RANGES; sr++)
{
const uint32_t low_selector = g_etc1s_to_atc_selector_ranges[sr].m_low;
const uint32_t high_selector = g_etc1s_to_atc_selector_ranges[sr].m_high;
for (uint32_t m = 0; m < NUM_ETC1S_TO_ATC_SELECTOR_MAPPINGS; m++)
{
uint32_t best_lo = 0;
uint32_t best_hi = 0;
uint64_t best_err = UINT64_MAX;
for (uint32_t hi = 0; hi <= 31; hi++)
{
for (uint32_t lo = 0; lo <= 31; lo++)
{
uint32_t colors[4];
colors[0] = (lo << 3) | (lo >> 2);
colors[3] = (hi << 3) | (hi >> 2);
colors[1] = (colors[0] * 5 + colors[3] * 3) / 8;
colors[2] = (colors[3] * 5 + colors[0] * 3) / 8;
uint64_t total_err = 0;
for (uint32_t s = low_selector; s <= high_selector; s++)
{
int err = block_colors[s].g - colors[g_etc1s_to_atc_selector_mappings[m][s]];
int err_scale = 1;
if (((inten == 7) && (low_selector == 0) && (high_selector == 3)) && ((s == 0) || (s == 3)))
err_scale = 5;
total_err += (err * err) * err_scale;
}
if (total_err < best_err)
{
best_err = total_err;
best_lo = lo;
best_hi = hi;
}
}
}
best_err = basisu::minimum<uint32_t>(best_err, 0xFFFF);
fprintf(pFile, "{%u,%u,%u},", best_lo, best_hi, (uint32_t)best_err);
n++;
if ((n & 31) == 31)
fprintf(pFile, "\n");
}
}
}
}
fclose(pFile);
pFile = nullptr;
fopen_s(&pFile, "basisu_transcoder_tables_atc_56.inc", "w");
n = 0;
for (int inten = 0; inten < 8; inten++)
{
for (uint32_t g = 0; g < 32; g++)
{
color32 block_colors[4];
decoder_etc_block::get_diff_subblock_colors(block_colors, decoder_etc_block::pack_color5(color32(g, g, g, 255), false), inten);
for (uint32_t sr = 0; sr < NUM_ETC1S_TO_ATC_SELECTOR_RANGES; sr++)
{
const uint32_t low_selector = g_etc1s_to_atc_selector_ranges[sr].m_low;
const uint32_t high_selector = g_etc1s_to_atc_selector_ranges[sr].m_high;
for (uint32_t m = 0; m < NUM_ETC1S_TO_ATC_SELECTOR_MAPPINGS; m++)
{
uint32_t best_lo = 0;
uint32_t best_hi = 0;
uint64_t best_err = UINT64_MAX;
for (uint32_t hi = 0; hi <= 63; hi++)
{
for (uint32_t lo = 0; lo <= 31; lo++)
{
uint32_t colors[4];
colors[0] = (lo << 3) | (lo >> 2);
colors[3] = (hi << 2) | (hi >> 4);
colors[1] = (colors[0] * 5 + colors[3] * 3) / 8;
colors[2] = (colors[3] * 5 + colors[0] * 3) / 8;
uint64_t total_err = 0;
for (uint32_t s = low_selector; s <= high_selector; s++)
{
int err = block_colors[s].g - colors[g_etc1s_to_atc_selector_mappings[m][s]];
int err_scale = 1;
if (((inten == 7) && (low_selector == 0) && (high_selector == 3)) && ((s == 0) || (s == 3)))
err_scale = 5;
total_err += (err * err) * err_scale;
}
if (total_err < best_err)
{
best_err = total_err;
best_lo = lo;
best_hi = hi;
}
}
}
best_err = basisu::minimum<uint32_t>(best_err, 0xFFFF);
fprintf(pFile, "{%u,%u,%u},", best_lo, best_hi, (uint32_t)best_err);
n++;
if ((n & 31) == 31)
fprintf(pFile, "\n");
}
}
}
}
fclose(pFile);
fopen_s(&pFile, "basisu_transcoder_tables_pvrtc2_45.inc", "w");
n = 0;
for (int inten = 0; inten < 8; inten++)
{
for (uint32_t g = 0; g < 32; g++)
{
color32 block_colors[4];
decoder_etc_block::get_diff_subblock_colors(block_colors, decoder_etc_block::pack_color5(color32(g, g, g, 255), false), inten);
for (uint32_t sr = 0; sr < NUM_ETC1S_TO_ATC_SELECTOR_RANGES; sr++)
{
const uint32_t low_selector = g_etc1s_to_atc_selector_ranges[sr].m_low;
const uint32_t high_selector = g_etc1s_to_atc_selector_ranges[sr].m_high;
for (uint32_t m = 0; m < NUM_ETC1S_TO_ATC_SELECTOR_MAPPINGS; m++)
{
uint32_t best_lo = 0;
uint32_t best_hi = 0;
uint64_t best_err = UINT64_MAX;
for (uint32_t hi = 0; hi <= 31; hi++)
{
for (uint32_t lo = 0; lo <= 15; lo++)
{
uint32_t colors[4];
colors[0] = (lo << 1) | (lo >> 3);
colors[0] = (colors[0] << 3) | (colors[0] >> 2);
colors[3] = (hi << 3) | (hi >> 2);
colors[1] = (colors[0] * 5 + colors[3] * 3) / 8;
colors[2] = (colors[3] * 5 + colors[0] * 3) / 8;
uint64_t total_err = 0;
for (uint32_t s = low_selector; s <= high_selector; s++)
{
int err = block_colors[s].g - colors[g_etc1s_to_atc_selector_mappings[m][s]];
int err_scale = 1;
if (((inten == 7) && (low_selector == 0) && (high_selector == 3)) && ((s == 0) || (s == 3)))
err_scale = 5;
total_err += (err * err) * err_scale;
}
if (total_err < best_err)
{
best_err = total_err;
best_lo = lo;
best_hi = hi;
}
}
}
best_err = basisu::minimum<uint32_t>(best_err, 0xFFFF);
fprintf(pFile, "{%u,%u,%u},", best_lo, best_hi, (uint32_t)best_err);
n++;
if ((n & 31) == 31)
fprintf(pFile, "\n");
}
}
}
}
fclose(pFile);
#if 0
fopen_s(&pFile, "basisu_transcoder_tables_pvrtc2_34.inc", "w");
n = 0;
for (int inten = 0; inten < 8; inten++)
{
for (uint32_t g = 0; g < 32; g++)
{
color32 block_colors[4];
decoder_etc_block::get_diff_subblock_colors(block_colors, decoder_etc_block::pack_color5(color32(g, g, g, 255), false), inten);
for (uint32_t sr = 0; sr < NUM_ETC1S_TO_ATC_SELECTOR_RANGES; sr++)
{
const uint32_t low_selector = g_etc1s_to_atc_selector_ranges[sr].m_low;
const uint32_t high_selector = g_etc1s_to_atc_selector_ranges[sr].m_high;
for (uint32_t m = 0; m < NUM_ETC1S_TO_ATC_SELECTOR_MAPPINGS; m++)
{
uint32_t best_lo = 0;
uint32_t best_hi = 0;
uint64_t best_err = UINT64_MAX;
for (uint32_t hi = 0; hi <= 15; hi++)
{
for (uint32_t lo = 0; lo <= 7; lo++)
{
uint32_t colors[4];
colors[0] = (lo << 2) | (lo >> 1);
colors[0] = (colors[0] << 3) | (colors[0] >> 2);
colors[3] = (hi << 1) | (hi >> 3);
colors[3] = (colors[3] << 3) | (colors[3] >> 2);
colors[1] = (colors[0] * 5 + colors[3] * 3) / 8;
colors[2] = (colors[3] * 5 + colors[0] * 3) / 8;
uint64_t total_err = 0;
for (uint32_t s = low_selector; s <= high_selector; s++)
{
int err = block_colors[s].g - colors[g_etc1s_to_atc_selector_mappings[m][s]];
int err_scale = 1;
if (((inten == 7) && (low_selector == 0) && (high_selector == 3)) && ((s == 0) || (s == 3)))
err_scale = 5;
total_err += (err * err) * err_scale;
}
if (total_err < best_err)
{
best_err = total_err;
best_lo = lo;
best_hi = hi;
}
}
}
best_err = basisu::minimum<uint32_t>(best_err, 0xFFFF);
fprintf(pFile, "{%u,%u,%u},", best_lo, best_hi, (uint32_t)best_err);
n++;
if ((n & 31) == 31)
fprintf(pFile, "\n");
}
}
}
}
fclose(pFile);
#endif
#if 0
fopen_s(&pFile, "basisu_transcoder_tables_pvrtc2_44.inc", "w");
n = 0;
for (int inten = 0; inten < 8; inten++)
{
for (uint32_t g = 0; g < 32; g++)
{
color32 block_colors[4];
decoder_etc_block::get_diff_subblock_colors(block_colors, decoder_etc_block::pack_color5(color32(g, g, g, 255), false), inten);
for (uint32_t sr = 0; sr < NUM_ETC1S_TO_ATC_SELECTOR_RANGES; sr++)
{
const uint32_t low_selector = g_etc1s_to_atc_selector_ranges[sr].m_low;
const uint32_t high_selector = g_etc1s_to_atc_selector_ranges[sr].m_high;
for (uint32_t m = 0; m < NUM_ETC1S_TO_ATC_SELECTOR_MAPPINGS; m++)
{
uint32_t best_lo = 0;
uint32_t best_hi = 0;
uint64_t best_err = UINT64_MAX;
for (uint32_t hi = 0; hi <= 15; hi++)
{
for (uint32_t lo = 0; lo <= 15; lo++)
{
uint32_t colors[4];
colors[0] = (lo << 1) | (lo >> 3);
colors[0] = (colors[0] << 3) | (colors[0] >> 2);
colors[3] = (hi << 1) | (hi >> 3);
colors[3] = (colors[3] << 3) | (colors[3] >> 2);
colors[1] = (colors[0] * 5 + colors[3] * 3) / 8;
colors[2] = (colors[3] * 5 + colors[0] * 3) / 8;
uint64_t total_err = 0;
for (uint32_t s = low_selector; s <= high_selector; s++)
{
int err = block_colors[s].g - colors[g_etc1s_to_atc_selector_mappings[m][s]];
int err_scale = 1;
if (((inten == 7) && (low_selector == 0) && (high_selector == 3)) && ((s == 0) || (s == 3)))
err_scale = 5;
total_err += (err * err) * err_scale;
}
if (total_err < best_err)
{
best_err = total_err;
best_lo = lo;
best_hi = hi;
}
}
}
best_err = basisu::minimum<uint32_t>(best_err, 0xFFFF);
fprintf(pFile, "{%u,%u,%u},", best_lo, best_hi, (uint32_t)best_err);
n++;
if ((n & 31) == 31)
fprintf(pFile, "\n");
}
}
}
}
fclose(pFile);
#endif
fopen_s(&pFile, "basisu_transcoder_tables_pvrtc2_alpha_33.inc", "w");
n = 0;
for (int inten = 0; inten < 8; inten++)
{
for (uint32_t g = 0; g < 32; g++)
{
color32 block_colors[4];
decoder_etc_block::get_diff_subblock_colors(block_colors, decoder_etc_block::pack_color5(color32(g, g, g, 255), false), inten);
for (uint32_t sr = 0; sr < NUM_ETC1S_TO_ATC_SELECTOR_RANGES; sr++)
{
const uint32_t low_selector = g_etc1s_to_atc_selector_ranges[sr].m_low;
const uint32_t high_selector = g_etc1s_to_atc_selector_ranges[sr].m_high;
for (uint32_t m = 0; m < NUM_ETC1S_TO_ATC_SELECTOR_MAPPINGS; m++)
{
uint32_t best_lo = 0;
uint32_t best_hi = 0;
uint64_t best_err = UINT64_MAX;
for (uint32_t hi = 0; hi <= 7; hi++)
{
for (uint32_t lo = 0; lo <= 7; lo++)
{
uint32_t colors[4];
colors[0] = (lo << 1);
colors[0] = (colors[0] << 4) | colors[0];
colors[3] = (hi << 1) | 1;
colors[3] = (colors[3] << 4) | colors[3];
colors[1] = (colors[0] * 5 + colors[3] * 3) / 8;
colors[2] = (colors[3] * 5 + colors[0] * 3) / 8;
uint64_t total_err = 0;
for (uint32_t s = low_selector; s <= high_selector; s++)
{
int err = block_colors[s].g - colors[g_etc1s_to_atc_selector_mappings[m][s]];
int err_scale = 1;
if (((inten == 7) && (low_selector == 0) && (high_selector == 3)) && ((s == 0) || (s == 3)))
err_scale = 5;
total_err += (err * err) * err_scale;
}
if (total_err < best_err)
{
best_err = total_err;
best_lo = lo;
best_hi = hi;
}
}
}
best_err = basisu::minimum<uint32_t>(best_err, 0xFFFF);
fprintf(pFile, "{%u,%u,%u},", best_lo, best_hi, (uint32_t)best_err);
n++;
if ((n & 31) == 31)
fprintf(pFile, "\n");
}
}
}
}
fclose(pFile);
}
#endif
#endif
#if BASISD_SUPPORT_PVRTC2
struct pvrtc2_block
{ … };
static struct
{ … } g_pvrtc2_trans_match34[256];
static struct
{ … } g_pvrtc2_trans_match44[256];
static struct
{ … } g_pvrtc2_alpha_match33[256];
static struct
{ … } g_pvrtc2_alpha_match33_0[256];
static struct
{ … } g_pvrtc2_alpha_match33_3[256];
static void convert_etc1s_to_pvrtc2_rgb(void* pDst, const endpoint* pEndpoints, const selector* pSelector)
{ … }
vec4F;
static inline vec4F* vec4F_set_scalar(vec4F* pV, float x) { … }
static inline vec4F* vec4F_set(vec4F* pV, float x, float y, float z, float w) { … }
static inline vec4F* vec4F_saturate_in_place(vec4F* pV) { … }
static inline vec4F vec4F_saturate(const vec4F* pV) { … }
static inline vec4F vec4F_from_color(const color32* pC) { … }
static inline vec4F vec4F_add(const vec4F* pLHS, const vec4F* pRHS) { … }
static inline vec4F vec4F_sub(const vec4F* pLHS, const vec4F* pRHS) { … }
static inline float vec4F_dot(const vec4F* pLHS, const vec4F* pRHS) { … }
static inline vec4F vec4F_mul(const vec4F* pLHS, float s) { … }
static inline vec4F* vec4F_normalize_in_place(vec4F* pV) { … }
static color32 convert_rgba_5554_to_8888(const color32& col)
{ … }
static inline int sq(int x) { … }
static void convert_etc1s_to_pvrtc2_rgba(void* pDst, const endpoint* pEndpoints, const selector* pSelector, const endpoint* pEndpoint_codebook, const selector* pSelector_codebook)
{ … }
static void transcoder_init_pvrtc2()
{ … }
#endif
basisu_lowlevel_etc1s_transcoder::basisu_lowlevel_etc1s_transcoder() : … { … }
bool basisu_lowlevel_etc1s_transcoder::decode_palettes(
uint32_t num_endpoints, const uint8_t* pEndpoints_data, uint32_t endpoints_data_size,
uint32_t num_selectors, const uint8_t* pSelectors_data, uint32_t selectors_data_size)
{ … }
bool basisu_lowlevel_etc1s_transcoder::decode_tables(const uint8_t* pTable_data, uint32_t table_data_size)
{ … }
bool basisu_lowlevel_etc1s_transcoder::transcode_slice(void* pDst_blocks, uint32_t num_blocks_x, uint32_t num_blocks_y, const uint8_t* pImage_data, uint32_t image_data_size, block_format fmt,
uint32_t output_block_or_pixel_stride_in_bytes, bool bc1_allow_threecolor_blocks, const bool is_video, const bool is_alpha_slice, const uint32_t level_index, const uint32_t orig_width, const uint32_t orig_height, uint32_t output_row_pitch_in_blocks_or_pixels,
basisu_transcoder_state* pState, bool transcode_alpha, void *pAlpha_blocks, uint32_t output_rows_in_pixels)
{ … }
bool basis_validate_output_buffer_size(transcoder_texture_format target_format,
uint32_t output_blocks_buf_size_in_blocks_or_pixels,
uint32_t orig_width, uint32_t orig_height,
uint32_t output_row_pitch_in_blocks_or_pixels,
uint32_t output_rows_in_pixels,
uint32_t total_slice_blocks)
{ … }
bool basisu_lowlevel_etc1s_transcoder::transcode_image(
transcoder_texture_format target_format,
void* pOutput_blocks, uint32_t output_blocks_buf_size_in_blocks_or_pixels,
const uint8_t* pCompressed_data, uint32_t compressed_data_length,
uint32_t num_blocks_x, uint32_t num_blocks_y, uint32_t orig_width, uint32_t orig_height, uint32_t level_index,
uint32_t rgb_offset, uint32_t rgb_length, uint32_t alpha_offset, uint32_t alpha_length,
uint32_t decode_flags,
bool basis_file_has_alpha_slices,
bool is_video,
uint32_t output_row_pitch_in_blocks_or_pixels,
basisu_transcoder_state* pState,
uint32_t output_rows_in_pixels)
{ … }
basisu_lowlevel_uastc_transcoder::basisu_lowlevel_uastc_transcoder()
{ … }
bool basisu_lowlevel_uastc_transcoder::transcode_slice(void* pDst_blocks, uint32_t num_blocks_x, uint32_t num_blocks_y, const uint8_t* pImage_data, uint32_t image_data_size, block_format fmt,
uint32_t output_block_or_pixel_stride_in_bytes, bool bc1_allow_threecolor_blocks, bool has_alpha, const uint32_t orig_width, const uint32_t orig_height, uint32_t output_row_pitch_in_blocks_or_pixels,
basisu_transcoder_state* pState, uint32_t output_rows_in_pixels, int channel0, int channel1, uint32_t decode_flags)
{ … }
bool basisu_lowlevel_uastc_transcoder::transcode_image(
transcoder_texture_format target_format,
void* pOutput_blocks, uint32_t output_blocks_buf_size_in_blocks_or_pixels,
const uint8_t* pCompressed_data, uint32_t compressed_data_length,
uint32_t num_blocks_x, uint32_t num_blocks_y, uint32_t orig_width, uint32_t orig_height, uint32_t level_index,
uint32_t slice_offset, uint32_t slice_length,
uint32_t decode_flags,
bool has_alpha,
bool is_video,
uint32_t output_row_pitch_in_blocks_or_pixels,
basisu_transcoder_state* pState,
uint32_t output_rows_in_pixels,
int channel0, int channel1)
{ … }
basisu_transcoder::basisu_transcoder() : … { … }
bool basisu_transcoder::validate_file_checksums(const void* pData, uint32_t data_size, bool full_validation) const
{ … }
bool basisu_transcoder::validate_header_quick(const void* pData, uint32_t data_size) const
{ … }
bool basisu_transcoder::validate_header(const void* pData, uint32_t data_size) const
{ … }
basis_texture_type basisu_transcoder::get_texture_type(const void* pData, uint32_t data_size) const
{ … }
bool basisu_transcoder::get_userdata(const void* pData, uint32_t data_size, uint32_t& userdata0, uint32_t& userdata1) const
{ … }
uint32_t basisu_transcoder::get_total_images(const void* pData, uint32_t data_size) const
{ … }
basis_tex_format basisu_transcoder::get_tex_format(const void* pData, uint32_t data_size) const
{ … }
bool basisu_transcoder::get_image_info(const void* pData, uint32_t data_size, basisu_image_info& image_info, uint32_t image_index) const
{ … }
uint32_t basisu_transcoder::get_total_image_levels(const void* pData, uint32_t data_size, uint32_t image_index) const
{ … }
bool basisu_transcoder::get_image_level_desc(const void* pData, uint32_t data_size, uint32_t image_index, uint32_t level_index, uint32_t& orig_width, uint32_t& orig_height, uint32_t& total_blocks) const
{ … }
bool basisu_transcoder::get_image_level_info(const void* pData, uint32_t data_size, basisu_image_level_info& image_info, uint32_t image_index, uint32_t level_index) const
{ … }
bool basisu_transcoder::get_file_info(const void* pData, uint32_t data_size, basisu_file_info& file_info) const
{ … }
bool basisu_transcoder::start_transcoding(const void* pData, uint32_t data_size)
{ … }
bool basisu_transcoder::stop_transcoding()
{ … }
bool basisu_transcoder::transcode_slice(const void* pData, uint32_t data_size, uint32_t slice_index, void* pOutput_blocks, uint32_t output_blocks_buf_size_in_blocks_or_pixels, block_format fmt,
uint32_t output_block_or_pixel_stride_in_bytes, uint32_t decode_flags, uint32_t output_row_pitch_in_blocks_or_pixels, basisu_transcoder_state* pState, void *pAlpha_blocks, uint32_t output_rows_in_pixels, int channel0, int channel1) const
{ … }
int basisu_transcoder::find_first_slice_index(const void* pData, uint32_t data_size, uint32_t image_index, uint32_t level_index) const
{ … }
int basisu_transcoder::find_slice(const void* pData, uint32_t data_size, uint32_t image_index, uint32_t level_index, bool alpha_data) const
{ … }
void basisu_transcoder::write_opaque_alpha_blocks(
uint32_t num_blocks_x, uint32_t num_blocks_y,
void* pOutput_blocks, block_format fmt,
uint32_t block_stride_in_bytes, uint32_t output_row_pitch_in_blocks_or_pixels)
{ … }
bool basisu_transcoder::transcode_image_level(
const void* pData, uint32_t data_size,
uint32_t image_index, uint32_t level_index,
void* pOutput_blocks, uint32_t output_blocks_buf_size_in_blocks_or_pixels,
transcoder_texture_format fmt,
uint32_t decode_flags, uint32_t output_row_pitch_in_blocks_or_pixels, basisu_transcoder_state *pState, uint32_t output_rows_in_pixels) const
{ … }
uint32_t basis_get_bytes_per_block_or_pixel(transcoder_texture_format fmt)
{ … }
const char* basis_get_format_name(transcoder_texture_format fmt)
{ … }
const char* basis_get_block_format_name(block_format fmt)
{ … }
const char* basis_get_texture_type_name(basis_texture_type tex_type)
{ … }
bool basis_transcoder_format_has_alpha(transcoder_texture_format fmt)
{ … }
basisu::texture_format basis_get_basisu_texture_format(transcoder_texture_format fmt)
{ … }
bool basis_transcoder_format_is_uncompressed(transcoder_texture_format tex_type)
{ … }
bool basis_block_format_is_uncompressed(block_format blk_fmt)
{ … }
uint32_t basis_get_uncompressed_bytes_per_pixel(transcoder_texture_format fmt)
{ … }
uint32_t basis_get_block_width(transcoder_texture_format tex_type)
{ … }
uint32_t basis_get_block_height(transcoder_texture_format tex_type)
{ … }
bool basis_is_format_supported(transcoder_texture_format tex_type, basis_tex_format fmt)
{ … }
#if BASISD_SUPPORT_UASTC
const astc_bc7_common_partition2_desc g_astc_bc7_common_partitions2[TOTAL_ASTC_BC7_COMMON_PARTITIONS2] = …;
const bc73_astc2_common_partition_desc g_bc7_3_astc2_common_partitions[TOTAL_BC7_3_ASTC2_COMMON_PARTITIONS] = …;
const astc_bc7_common_partition3_desc g_astc_bc7_common_partitions3[TOTAL_ASTC_BC7_COMMON_PARTITIONS3] = …;
const uint8_t g_astc_to_bc7_partition_index_perm_tables[6][3] = …;
const uint8_t g_bc7_to_astc_partition_index_perm_tables[6][3] = …;
uint32_t bc7_convert_partition_index_3_to_2(uint32_t p, uint32_t k)
{ … }
static const uint8_t g_zero_pattern[16] = …;
const uint8_t g_astc_bc7_patterns2[TOTAL_ASTC_BC7_COMMON_PARTITIONS2][16] = …;
const uint8_t g_astc_bc7_patterns3[TOTAL_ASTC_BC7_COMMON_PARTITIONS3][16] = …;
const uint8_t g_bc7_3_astc2_patterns2[TOTAL_BC7_3_ASTC2_COMMON_PARTITIONS][16] = …;
const uint8_t g_astc_bc7_pattern2_anchors[TOTAL_ASTC_BC7_COMMON_PARTITIONS2][3] = …;
const uint8_t g_astc_bc7_pattern3_anchors[TOTAL_ASTC_BC7_COMMON_PARTITIONS3][3] = …;
const uint8_t g_bc7_3_astc2_patterns2_anchors[TOTAL_BC7_3_ASTC2_COMMON_PARTITIONS][3] = …;
const uint32_t g_uastc_mode_huff_codes[TOTAL_UASTC_MODES + 1][2] = …;
static const uint8_t g_uastc_huff_modes[128] = …;
const uint8_t g_uastc_mode_weight_bits[TOTAL_UASTC_MODES] = …;
const uint8_t g_uastc_mode_weight_ranges[TOTAL_UASTC_MODES] = …;
const uint8_t g_uastc_mode_endpoint_ranges[TOTAL_UASTC_MODES] = …;
const uint8_t g_uastc_mode_subsets[TOTAL_UASTC_MODES] = …;
const uint8_t g_uastc_mode_planes[TOTAL_UASTC_MODES] = …;
const uint8_t g_uastc_mode_comps[TOTAL_UASTC_MODES] = …;
const uint8_t g_uastc_mode_has_etc1_bias[TOTAL_UASTC_MODES] = …;
const uint8_t g_uastc_mode_has_bc1_hint0[TOTAL_UASTC_MODES] = …;
const uint8_t g_uastc_mode_has_bc1_hint1[TOTAL_UASTC_MODES] = …;
const uint8_t g_uastc_mode_cem[TOTAL_UASTC_MODES] = …;
const uint8_t g_uastc_mode_has_alpha[TOTAL_UASTC_MODES] = …;
const uint8_t g_uastc_mode_is_la[TOTAL_UASTC_MODES] = …;
const uint8_t g_uastc_mode_total_hint_bits[TOTAL_UASTC_MODES] = …;
const int g_astc_bise_range_table[TOTAL_ASTC_RANGES][3] = …;
int astc_get_levels(int range)
{ … }
astc_quant_bin g_astc_unquant[BC7ENC_TOTAL_ASTC_RANGES][256];
static struct
{ … } g_astc_endpoint_unquant_params[BC7ENC_TOTAL_ASTC_RANGES] = …;
bool astc_is_valid_endpoint_range(uint32_t range)
{ … }
uint32_t unquant_astc_endpoint(uint32_t packed_bits, uint32_t packed_trits, uint32_t packed_quints, uint32_t range)
{ … }
uint32_t unquant_astc_endpoint_val(uint32_t packed_val, uint32_t range)
{ … }
const uint32_t g_bc7_weights1[2] = …;
const uint32_t g_bc7_weights2[4] = …;
const uint32_t g_bc7_weights3[8] = …;
const uint32_t g_bc7_weights4[16] = …;
const uint32_t g_astc_weights4[16] = …;
const uint32_t g_astc_weights5[32] = …;
const uint32_t g_astc_weights_3levels[3] = …;
const uint8_t g_bc7_partition1[16] = …;
const uint8_t g_bc7_partition2[64 * 16] = …;
const uint8_t g_bc7_partition3[64 * 16] = …;
const uint8_t g_bc7_table_anchor_index_second_subset[64] = …;
const uint8_t g_bc7_table_anchor_index_third_subset_1[64] = …;
const uint8_t g_bc7_table_anchor_index_third_subset_2[64] = …;
const uint8_t g_bc7_num_subsets[8] = …;
const uint8_t g_bc7_partition_bits[8] = …;
const uint8_t g_bc7_color_index_bitcount[8] = …;
const uint8_t g_bc7_mode_has_p_bits[8] = …;
const uint8_t g_bc7_mode_has_shared_p_bits[8] = …;
const uint8_t g_bc7_color_precision_table[8] = …;
const int8_t g_bc7_alpha_precision_table[8] = …;
const uint8_t g_bc7_alpha_index_bitcount[8] = …;
endpoint_err g_bc7_mode_6_optimal_endpoints[256][2];
endpoint_err g_bc7_mode_5_optimal_endpoints[256];
static inline void bc7_set_block_bits(uint8_t* pBytes, uint32_t val, uint32_t num_bits, uint32_t* pCur_ofs)
{ … }
void encode_bc7_block(void* pBlock, const bc7_optimization_results* pResults)
{ … }
static inline void astc_set_bits_1_to_9(uint32_t* pDst, int& bit_offset, uint32_t code, uint32_t codesize)
{ … }
void pack_astc_solid_block(void* pDst_block, const color32& color)
{ … }
#ifdef _DEBUG
static inline uint32_t astc_hash52(uint32_t v)
{
uint32_t p = v;
p ^= p >> 15; p -= p << 17; p += p << 7; p += p << 4;
p ^= p >> 5; p += p << 16; p ^= p >> 7; p ^= p >> 3;
p ^= p << 6; p ^= p >> 17;
return p;
}
int astc_compute_texel_partition(int seed, int x, int y, int z, int partitioncount, bool small_block)
{
if (small_block)
{
x <<= 1; y <<= 1; z <<= 1;
}
seed += (partitioncount - 1) * 1024;
uint32_t rnum = astc_hash52(seed);
uint8_t seed1 = rnum & 0xF;
uint8_t seed2 = (rnum >> 4) & 0xF;
uint8_t seed3 = (rnum >> 8) & 0xF;
uint8_t seed4 = (rnum >> 12) & 0xF;
uint8_t seed5 = (rnum >> 16) & 0xF;
uint8_t seed6 = (rnum >> 20) & 0xF;
uint8_t seed7 = (rnum >> 24) & 0xF;
uint8_t seed8 = (rnum >> 28) & 0xF;
uint8_t seed9 = (rnum >> 18) & 0xF;
uint8_t seed10 = (rnum >> 22) & 0xF;
uint8_t seed11 = (rnum >> 26) & 0xF;
uint8_t seed12 = ((rnum >> 30) | (rnum << 2)) & 0xF;
seed1 *= seed1; seed2 *= seed2;
seed3 *= seed3; seed4 *= seed4;
seed5 *= seed5; seed6 *= seed6;
seed7 *= seed7; seed8 *= seed8;
seed9 *= seed9; seed10 *= seed10;
seed11 *= seed11; seed12 *= seed12;
int sh1, sh2, sh3;
if (seed & 1)
{
sh1 = (seed & 2 ? 4 : 5); sh2 = (partitioncount == 3 ? 6 : 5);
}
else
{
sh1 = (partitioncount == 3 ? 6 : 5); sh2 = (seed & 2 ? 4 : 5);
}
sh3 = (seed & 0x10) ? sh1 : sh2;
seed1 >>= sh1; seed2 >>= sh2; seed3 >>= sh1; seed4 >>= sh2;
seed5 >>= sh1; seed6 >>= sh2; seed7 >>= sh1; seed8 >>= sh2;
seed9 >>= sh3; seed10 >>= sh3; seed11 >>= sh3; seed12 >>= sh3;
int a = seed1 * x + seed2 * y + seed11 * z + (rnum >> 14);
int b = seed3 * x + seed4 * y + seed12 * z + (rnum >> 10);
int c = seed5 * x + seed6 * y + seed9 * z + (rnum >> 6);
int d = seed7 * x + seed8 * y + seed10 * z + (rnum >> 2);
a &= 0x3F; b &= 0x3F; c &= 0x3F; d &= 0x3F;
if (partitioncount < 4) d = 0;
if (partitioncount < 3) c = 0;
if (a >= b && a >= c && a >= d)
return 0;
else if (b >= c && b >= d)
return 1;
else if (c >= d)
return 2;
else
return 3;
}
#endif
static const uint8_t g_astc_quint_encode[125] = …;
static inline void astc_encode_quints(uint32_t* pOutput, const uint8_t* pValues, int& bit_pos, int n)
{ … }
static void astc_pack_bise(uint32_t* pDst, const uint8_t* pSrc_vals, int bit_pos, int num_vals, int range)
{ … }
const uint32_t ASTC_BLOCK_MODE_BITS = …;
const uint32_t ASTC_PART_BITS = …;
const uint32_t ASTC_CEM_BITS = …;
const uint32_t ASTC_PARTITION_INDEX_BITS = …;
const uint32_t ASTC_CCS_BITS = …;
const uint32_t g_uastc_mode_astc_block_mode[TOTAL_UASTC_MODES] = …;
bool pack_astc_block(uint32_t* pDst, const astc_block_desc* pBlock, uint32_t uastc_mode)
{ … }
const uint8_t* get_anchor_indices(uint32_t subsets, uint32_t mode, uint32_t common_pattern, const uint8_t*& pPartition_pattern)
{ … }
static inline uint32_t read_bit(const uint8_t* pBuf, uint32_t& bit_offset)
{ … }
static inline uint32_t read_bits1_to_9(const uint8_t* pBuf, uint32_t& bit_offset, uint32_t codesize)
{ … }
inline uint64_t read_bits64(const uint8_t* pBuf, uint32_t& bit_offset, uint32_t codesize)
{ … }
static inline uint32_t read_bits1_to_9_fst(const uint8_t* pBuf, uint32_t& bit_offset, uint32_t codesize)
{ … }
bool unpack_uastc(const uastc_block& blk, unpacked_uastc_block& unpacked, bool blue_contract_check, bool read_hints)
{ … }
static const uint32_t* g_astc_weight_tables[6] = …;
bool unpack_uastc(uint32_t mode, uint32_t common_pattern, const color32& solid_color, const astc_block_desc& astc, color32* pPixels, bool srgb)
{ … }
bool unpack_uastc(const unpacked_uastc_block& unpacked_blk, color32* pPixels, bool srgb)
{ … }
bool unpack_uastc(const uastc_block& blk, color32* pPixels, bool srgb)
{ … }
static void determine_shared_pbits(
uint32_t total_comps, uint32_t comp_bits, float xl[4], float xh[4],
color_quad_u8& bestMinColor, color_quad_u8& bestMaxColor, uint32_t best_pbits[2])
{ … }
static void determine_unique_pbits(
uint32_t total_comps, uint32_t comp_bits, float xl[4], float xh[4],
color_quad_u8& bestMinColor, color_quad_u8& bestMaxColor, uint32_t best_pbits[2])
{ … }
bool transcode_uastc_to_astc(const uastc_block& src_blk, void* pDst)
{ … }
bool transcode_uastc_to_bc7(const unpacked_uastc_block& unpacked_src_blk, bc7_optimization_results& dst_blk)
{ … }
bool transcode_uastc_to_bc7(const uastc_block& src_blk, bc7_optimization_results& dst_blk)
{ … }
bool transcode_uastc_to_bc7(const uastc_block& src_blk, void* pDst)
{ … }
color32 apply_etc1_bias(const color32 &block_color, uint32_t bias, uint32_t limit, uint32_t subblock)
{ … }
static void etc1_determine_selectors(decoder_etc_block& dst_blk, const color32* pSource_pixels, uint32_t first_subblock, uint32_t last_subblock)
{ … }
static const uint8_t s_etc1_solid_selectors[4][4] = …;
struct etc_coord2
{ … };
const etc_coord2 g_etc1_pixel_coords[2][2][8] = …;
void transcode_uastc_to_etc1(unpacked_uastc_block& unpacked_src_blk, color32 block_pixels[4][4], void* pDst)
{ … }
bool transcode_uastc_to_etc1(const uastc_block& src_blk, void* pDst)
{ … }
static inline int gray_distance2(const uint8_t c, int y)
{ … }
static bool pack_etc1_y_estimate_flipped(const uint8_t* pSrc_pixels,
int& upper_avg, int& lower_avg, int& left_avg, int& right_avg)
{ … }
static const uint16_t g_etc1_y_solid_block_configs[256] = …;
static const uint16_t g_etc1_y_solid_block_4i_configs[256] = …;
static const uint16_t g_etc1_y_solid_block_2i_configs[256] = …;
static const uint16_t g_etc1_y_solid_block_1i_configs[256] = …;
bool transcode_uastc_to_etc1(const uastc_block& src_blk, void* pDst, uint32_t channel)
{ … }
const uint32_t ETC2_EAC_MIN_VALUE_SELECTOR = …, ETC2_EAC_MAX_VALUE_SELECTOR = …;
void transcode_uastc_to_etc2_eac_a8(unpacked_uastc_block& unpacked_src_blk, color32 block_pixels[4][4], void* pDst)
{ … }
bool transcode_uastc_to_etc2_rgba(const uastc_block& src_blk, void* pDst)
{ … }
static const uint8_t s_uastc5_to_bc1[32] = …;
static const uint8_t s_uastc4_to_bc1[16] = …;
static const uint8_t s_uastc3_to_bc1[8] = …;
static const uint8_t s_uastc2_to_bc1[4] = …;
static const uint8_t s_uastc1_to_bc1[2] = …;
const uint8_t* s_uastc_to_bc1_weights[6] = …;
void encode_bc4(void* pDst, const uint8_t* pPixels, uint32_t stride)
{ … }
static void bc1_find_sels(const color32 *pSrc_pixels, uint32_t lr, uint32_t lg, uint32_t lb, uint32_t hr, uint32_t hg, uint32_t hb, uint8_t sels[16])
{ … }
static inline void bc1_find_sels_2(const color32* pSrc_pixels, uint32_t lr, uint32_t lg, uint32_t lb, uint32_t hr, uint32_t hg, uint32_t hb, uint8_t sels[16])
{ … }
struct vec3F { … };
static bool compute_least_squares_endpoints_rgb(const color32* pColors, const uint8_t* pSelectors, vec3F* pXl, vec3F* pXh)
{ … }
void encode_bc1_solid_block(void* pDst, uint32_t fr, uint32_t fg, uint32_t fb)
{ … }
static inline uint8_t to_5(uint32_t v) { … }
static inline uint8_t to_6(uint32_t v) { … }
void encode_bc1(void* pDst, const uint8_t* pPixels, uint32_t flags)
{ … }
void encode_bc1_alt(void* pDst, const uint8_t* pPixels, uint32_t flags)
{ … }
void transcode_uastc_to_bc1_hint0(const unpacked_uastc_block& unpacked_src_blk, void* pDst)
{ … }
void transcode_uastc_to_bc1_hint1(const unpacked_uastc_block& unpacked_src_blk, const color32 block_pixels[4][4], void* pDst, bool high_quality)
{ … }
bool transcode_uastc_to_bc1(const uastc_block& src_blk, void* pDst, bool high_quality)
{ … }
static void write_bc4_solid_block(uint8_t* pDst, uint32_t a)
{ … }
bool transcode_uastc_to_bc3(const uastc_block& src_blk, void* pDst, bool high_quality)
{ … }
bool transcode_uastc_to_bc4(const uastc_block& src_blk, void* pDst, bool high_quality, uint32_t chan0)
{ … }
bool transcode_uastc_to_bc5(const uastc_block& src_blk, void* pDst, bool high_quality, uint32_t chan0, uint32_t chan1)
{ … }
static const uint8_t s_etc2_eac_bit_ofs[16] = …;
static void pack_eac_solid_block(eac_block& blk, uint32_t a)
{ … }
static void pack_eac(eac_block& blk, const uint8_t* pPixels, uint32_t stride)
{ … }
static void pack_eac_high_quality(eac_block& blk, const uint8_t* pPixels, uint32_t stride)
{ … }
bool transcode_uastc_to_etc2_eac_r11(const uastc_block& src_blk, void* pDst, bool high_quality, uint32_t chan0)
{ … }
bool transcode_uastc_to_etc2_eac_rg11(const uastc_block& src_blk, void* pDst, bool high_quality, uint32_t chan0, uint32_t chan1)
{ … }
static void fixup_pvrtc1_4_modulation_rgb(
const uastc_block* pSrc_blocks,
const uint32_t* pPVRTC_endpoints,
void* pDst_blocks,
uint32_t num_blocks_x, uint32_t num_blocks_y, bool from_alpha)
{ … }
static void fixup_pvrtc1_4_modulation_rgba(
const uastc_block* pSrc_blocks,
const uint32_t* pPVRTC_endpoints,
void* pDst_blocks, uint32_t num_blocks_x, uint32_t num_blocks_y)
{ … }
bool transcode_uastc_to_pvrtc1_4_rgb(const uastc_block* pSrc_blocks, void* pDst_blocks, uint32_t num_blocks_x, uint32_t num_blocks_y, bool high_quality, bool from_alpha)
{ … }
bool transcode_uastc_to_pvrtc1_4_rgba(const uastc_block* pSrc_blocks, void* pDst_blocks, uint32_t num_blocks_x, uint32_t num_blocks_y, bool high_quality)
{ … }
void uastc_init()
{ … }
#endif
#if BASISD_SUPPORT_KTX2
const uint8_t g_ktx2_file_identifier[12] = …;
ktx2_transcoder::ktx2_transcoder() : … { … }
void ktx2_transcoder::clear()
{ … }
bool ktx2_transcoder::init(const void* pData, uint32_t data_size)
{ … }
uint32_t ktx2_transcoder::get_etc1s_image_descs_image_flags(uint32_t level_index, uint32_t layer_index, uint32_t face_index) const
{ … }
const basisu::uint8_vec* ktx2_transcoder::find_key(const std::string& key_name) const
{ … }
bool ktx2_transcoder::start_transcoding()
{ … }
bool ktx2_transcoder::get_image_level_info(ktx2_image_level_info& level_info, uint32_t level_index, uint32_t layer_index, uint32_t face_index) const
{ … }
bool ktx2_transcoder::transcode_image_level(
uint32_t level_index, uint32_t layer_index, uint32_t face_index,
void* pOutput_blocks, uint32_t output_blocks_buf_size_in_blocks_or_pixels,
basist::transcoder_texture_format fmt,
uint32_t decode_flags, uint32_t output_row_pitch_in_blocks_or_pixels, uint32_t output_rows_in_pixels, int channel0, int channel1,
ktx2_transcoder_state* pState)
{ … }
bool ktx2_transcoder::decompress_level_data(uint32_t level_index, basisu::uint8_vec& uncomp_data)
{ … }
bool ktx2_transcoder::decompress_etc1s_global_data()
{ … }
bool ktx2_transcoder::read_key_values()
{ … }
#endif
bool basisu_transcoder_supports_ktx2()
{ … }
bool basisu_transcoder_supports_ktx2_zstd()
{ … }
}