summaryrefslogtreecommitdiff
path: root/thirdparty/basis_universal/transcoder/basisu_transcoder.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'thirdparty/basis_universal/transcoder/basisu_transcoder.cpp')
-rw-r--r--thirdparty/basis_universal/transcoder/basisu_transcoder.cpp271
1 files changed, 74 insertions, 197 deletions
diff --git a/thirdparty/basis_universal/transcoder/basisu_transcoder.cpp b/thirdparty/basis_universal/transcoder/basisu_transcoder.cpp
index 0b3733385d..630731900f 100644
--- a/thirdparty/basis_universal/transcoder/basisu_transcoder.cpp
+++ b/thirdparty/basis_universal/transcoder/basisu_transcoder.cpp
@@ -37,6 +37,14 @@
#endif
#endif
+// Using unaligned loads and stores causes errors when using UBSan. Jam it off.
+#if defined(__has_feature)
+#if __has_feature(undefined_behavior_sanitizer)
+#undef BASISD_USE_UNALIGNED_WORD_READS
+#define BASISD_USE_UNALIGNED_WORD_READS 0
+#endif
+#endif
+
#define BASISD_SUPPORTED_BASIS_VERSION (0x13)
#ifndef BASISD_SUPPORT_KTX2
@@ -224,32 +232,7 @@ namespace basist
return static_cast<uint16_t>(~crc);
}
-
- const uint32_t g_global_selector_cb[] =
-#include "basisu_global_selector_cb.h"
- ;
-
- const uint32_t g_global_selector_cb_size = sizeof(g_global_selector_cb) / sizeof(g_global_selector_cb[0]);
-
- void etc1_global_selector_codebook::init(uint32_t N, const uint32_t* pEntries)
- {
- m_palette.resize(N);
- for (uint32_t i = 0; i < N; i++)
- m_palette[i].set_uint32(pEntries[i]);
- }
-
- void etc1_global_selector_codebook::print_code(FILE* pFile)
- {
- fprintf(pFile, "{\n");
- for (uint32_t i = 0; i < m_palette.size(); i++)
- {
- fprintf(pFile, "0x%X,", m_palette[i].get_uint32());
- if ((i & 15) == 15)
- fprintf(pFile, "\n");
- }
- fprintf(pFile, "\n}\n");
- }
-
+
enum etc_constants
{
cETC1BytesPerBlock = 8U,
@@ -7532,9 +7515,8 @@ namespace basist
}
#endif // BASISD_SUPPORT_PVRTC2
- basisu_lowlevel_etc1s_transcoder::basisu_lowlevel_etc1s_transcoder(const etc1_global_selector_codebook* pGlobal_sel_codebook) :
+ basisu_lowlevel_etc1s_transcoder::basisu_lowlevel_etc1s_transcoder() :
m_pGlobal_codebook(nullptr),
- m_pGlobal_sel_codebook(pGlobal_sel_codebook),
m_selector_history_buf_size(0)
{
}
@@ -7641,50 +7623,8 @@ namespace basist
if (used_global_selector_cb)
{
- // global selector palette
- uint32_t pal_bits = sym_codec.get_bits(4);
- uint32_t mod_bits = sym_codec.get_bits(4);
-
- basist::huffman_decoding_table mod_model;
- if (mod_bits)
- {
- if (!sym_codec.read_huffman_table(mod_model))
- {
- BASISU_DEVEL_ERROR("basisu_lowlevel_etc1s_transcoder::decode_palettes: fail 6\n");
- return false;
- }
- if (!mod_model.is_valid())
- {
- BASISU_DEVEL_ERROR("basisu_lowlevel_etc1s_transcoder::decode_palettes: fail 6a\n");
- return false;
- }
- }
-
- for (uint32_t i = 0; i < num_selectors; i++)
- {
- uint32_t pal_index = 0;
- if (pal_bits)
- pal_index = sym_codec.get_bits(pal_bits);
-
- uint32_t mod_index = 0;
- if (mod_bits)
- mod_index = sym_codec.decode_huffman(mod_model);
-
- if (pal_index >= m_pGlobal_sel_codebook->size())
- {
- BASISU_DEVEL_ERROR("basisu_lowlevel_etc1s_transcoder::decode_palettes: fail 7z\n");
- return false;
- }
-
- const etc1_selector_palette_entry e(m_pGlobal_sel_codebook->get_entry(pal_index, etc1_global_palette_entry_modifier(mod_index)));
-
- // TODO: Optimize this
- for (uint32_t y = 0; y < 4; y++)
- for (uint32_t x = 0; x < 4; x++)
- m_local_selectors[i].set_selector(x, y, e[x + y * 4]);
-
- m_local_selectors[i].init_flags();
- }
+ BASISU_DEVEL_ERROR("basisu_lowlevel_etc1s_transcoder::decode_palettes: global selector codebooks are unsupported\n");
+ return false;
}
else
{
@@ -7692,146 +7632,70 @@ namespace basist
if (used_hybrid_selector_cb)
{
- const uint32_t pal_bits = sym_codec.get_bits(4);
- const uint32_t mod_bits = sym_codec.get_bits(4);
-
- basist::huffman_decoding_table uses_global_cb_bitflags_model;
- if (!sym_codec.read_huffman_table(uses_global_cb_bitflags_model))
- {
- BASISU_DEVEL_ERROR("basisu_lowlevel_etc1s_transcoder::decode_palettes: fail 7\n");
- return false;
- }
- if (!uses_global_cb_bitflags_model.is_valid())
- {
- BASISU_DEVEL_ERROR("basisu_lowlevel_etc1s_transcoder::decode_palettes: fail 7a\n");
- return false;
- }
-
- basist::huffman_decoding_table global_mod_indices_model;
- if (mod_bits)
- {
- if (!sym_codec.read_huffman_table(global_mod_indices_model))
- {
- BASISU_DEVEL_ERROR("basisu_lowlevel_etc1s_transcoder::decode_palettes: fail 8\n");
- return false;
- }
- if (!global_mod_indices_model.is_valid())
- {
- BASISU_DEVEL_ERROR("basisu_lowlevel_etc1s_transcoder::decode_palettes: fail 8a\n");
- return false;
- }
- }
-
- uint32_t cur_uses_global_cb_bitflags = 0;
- uint32_t uses_global_cb_bitflags_remaining = 0;
+ BASISU_DEVEL_ERROR("basisu_lowlevel_etc1s_transcoder::decode_palettes: hybrid global selector codebooks are unsupported\n");
+ return false;
+ }
+
+ const bool used_raw_encoding = (sym_codec.get_bits(1) == 1);
- for (uint32_t q = 0; q < num_selectors; q++)
+ if (used_raw_encoding)
+ {
+ for (uint32_t i = 0; i < num_selectors; i++)
{
- if (!uses_global_cb_bitflags_remaining)
+ for (uint32_t j = 0; j < 4; j++)
{
- cur_uses_global_cb_bitflags = sym_codec.decode_huffman(uses_global_cb_bitflags_model);
+ uint32_t cur_byte = sym_codec.get_bits(8);
- uses_global_cb_bitflags_remaining = 8;
+ for (uint32_t k = 0; k < 4; k++)
+ m_local_selectors[i].set_selector(k, j, (cur_byte >> (k * 2)) & 3);
}
- uses_global_cb_bitflags_remaining--;
-
- const bool used_global_cb_flag = (cur_uses_global_cb_bitflags & 1) != 0;
- cur_uses_global_cb_bitflags >>= 1;
- if (used_global_cb_flag)
- {
- const uint32_t pal_index = pal_bits ? sym_codec.get_bits(pal_bits) : 0;
- const uint32_t mod_index = mod_bits ? sym_codec.decode_huffman(global_mod_indices_model) : 0;
-
- if (pal_index >= m_pGlobal_sel_codebook->size())
- {
- BASISU_DEVEL_ERROR("basisu_lowlevel_etc1s_transcoder::decode_palettes: fail 8b\n");
- return false;
- }
-
- const etc1_selector_palette_entry e(m_pGlobal_sel_codebook->get_entry(pal_index, etc1_global_palette_entry_modifier(mod_index)));
-
- for (uint32_t y = 0; y < 4; y++)
- for (uint32_t x = 0; x < 4; x++)
- m_local_selectors[q].set_selector(x, y, e[x + y * 4]);
- }
- else
- {
- for (uint32_t j = 0; j < 4; j++)
- {
- uint32_t cur_byte = sym_codec.get_bits(8);
-
- for (uint32_t k = 0; k < 4; k++)
- m_local_selectors[q].set_selector(k, j, (cur_byte >> (k * 2)) & 3);
- }
- }
-
- m_local_selectors[q].init_flags();
+ m_local_selectors[i].init_flags();
}
}
else
{
- const bool used_raw_encoding = (sym_codec.get_bits(1) == 1);
+ if (!sym_codec.read_huffman_table(delta_selector_pal_model))
+ {
+ BASISU_DEVEL_ERROR("basisu_lowlevel_etc1s_transcoder::decode_palettes: fail 10\n");
+ return false;
+ }
+
+ if ((num_selectors > 1) && (!delta_selector_pal_model.is_valid()))
+ {
+ BASISU_DEVEL_ERROR("basisu_lowlevel_etc1s_transcoder::decode_palettes: fail 10a\n");
+ return false;
+ }
+
+ uint8_t prev_bytes[4] = { 0, 0, 0, 0 };
- if (used_raw_encoding)
+ for (uint32_t i = 0; i < num_selectors; i++)
{
- for (uint32_t i = 0; i < num_selectors; i++)
+ if (!i)
{
for (uint32_t j = 0; j < 4; j++)
{
uint32_t cur_byte = sym_codec.get_bits(8);
+ prev_bytes[j] = static_cast<uint8_t>(cur_byte);
for (uint32_t k = 0; k < 4; k++)
m_local_selectors[i].set_selector(k, j, (cur_byte >> (k * 2)) & 3);
}
-
m_local_selectors[i].init_flags();
+ continue;
}
- }
- else
- {
- if (!sym_codec.read_huffman_table(delta_selector_pal_model))
- {
- BASISU_DEVEL_ERROR("basisu_lowlevel_etc1s_transcoder::decode_palettes: fail 10\n");
- return false;
- }
-
- if ((num_selectors > 1) && (!delta_selector_pal_model.is_valid()))
- {
- BASISU_DEVEL_ERROR("basisu_lowlevel_etc1s_transcoder::decode_palettes: fail 10a\n");
- return false;
- }
-
- uint8_t prev_bytes[4] = { 0, 0, 0, 0 };
- for (uint32_t i = 0; i < num_selectors; i++)
+ for (uint32_t j = 0; j < 4; j++)
{
- if (!i)
- {
- for (uint32_t j = 0; j < 4; j++)
- {
- uint32_t cur_byte = sym_codec.get_bits(8);
- prev_bytes[j] = static_cast<uint8_t>(cur_byte);
+ int delta_byte = sym_codec.decode_huffman(delta_selector_pal_model);
- for (uint32_t k = 0; k < 4; k++)
- m_local_selectors[i].set_selector(k, j, (cur_byte >> (k * 2)) & 3);
- }
- m_local_selectors[i].init_flags();
- continue;
- }
-
- for (uint32_t j = 0; j < 4; j++)
- {
- int delta_byte = sym_codec.decode_huffman(delta_selector_pal_model);
-
- uint32_t cur_byte = delta_byte ^ prev_bytes[j];
- prev_bytes[j] = static_cast<uint8_t>(cur_byte);
+ uint32_t cur_byte = delta_byte ^ prev_bytes[j];
+ prev_bytes[j] = static_cast<uint8_t>(cur_byte);
- for (uint32_t k = 0; k < 4; k++)
- m_local_selectors[i].set_selector(k, j, (cur_byte >> (k * 2)) & 3);
- }
- m_local_selectors[i].init_flags();
+ for (uint32_t k = 0; k < 4; k++)
+ m_local_selectors[i].set_selector(k, j, (cur_byte >> (k * 2)) & 3);
}
+ m_local_selectors[i].init_flags();
}
}
}
@@ -7899,6 +7763,12 @@ namespace basist
}
m_selector_history_buf_size = sym_codec.get_bits(13);
+ // Check for bogus values.
+ if (!m_selector_history_buf_size)
+ {
+ BASISU_DEVEL_ERROR("basisu_lowlevel_etc1s_transcoder::decode_tables: fail 5\n");
+ return false;
+ }
sym_codec.stop();
@@ -7979,8 +7849,11 @@ namespace basist
decoder_etc_block block;
memset(&block, 0, sizeof(block));
+
+ //block.set_flip_bit(true);
+ // Setting the flip bit to false to be compatible with the Khronos KDFS.
+ block.set_flip_bit(false);
- block.set_flip_bit(true);
block.set_diff_bit(true);
void* pPVRTC_work_mem = nullptr;
@@ -8741,7 +8614,7 @@ namespace basist
if (!output_row_pitch_in_blocks_or_pixels)
output_row_pitch_in_blocks_or_pixels = orig_width;
- if (!output_rows_in_pixels)
+ if (!output_rows_in_pixels)
output_rows_in_pixels = orig_height;
// Now make sure the output buffer is large enough, or we'll overwrite memory.
@@ -9440,6 +9313,12 @@ namespace basist
{
switch (fmt)
{
+ case block_format::cUASTC_4x4:
+ {
+ memcpy(pDst_block, pSource_block, sizeof(uastc_block));
+ status = true;
+ break;
+ }
case block_format::cETC1:
{
if (from_alpha)
@@ -9906,8 +9785,7 @@ namespace basist
return status;
}
- basisu_transcoder::basisu_transcoder(const etc1_global_selector_codebook* pGlobal_sel_codebook) :
- m_lowlevel_etc1s_decoder(pGlobal_sel_codebook),
+ basisu_transcoder::basisu_transcoder() :
m_ready_to_transcode(false)
{
}
@@ -10778,6 +10656,8 @@ namespace basist
return false;
}
+ //const bool transcode_alpha_data_to_opaque_formats = (decode_flags & cDecodeFlagsTranscodeAlphaDataToOpaqueFormats) != 0;
+
if (decode_flags & cDecodeFlagsPVRTCDecodeToNextPow2)
{
BASISU_DEVEL_ERROR("basisu_transcoder::transcode_image_level: cDecodeFlagsPVRTCDecodeToNextPow2 currently unsupported\n");
@@ -11001,6 +10881,7 @@ namespace basist
case block_format::cRGB565: return "RGB565";
case block_format::cBGR565: return "BGR565";
case block_format::cRGBA4444: return "RGBA4444";
+ case block_format::cUASTC_4x4: return "UASTC_4x4";
case block_format::cFXT1_RGB: return "FXT1_RGB";
case block_format::cPVRTC2_4_RGB: return "PVRTC2_4_RGB";
case block_format::cPVRTC2_4_RGBA: return "PVRTC2_4_RGBA";
@@ -12567,12 +12448,8 @@ namespace basist
bits = read_bits64(blk.m_bytes, bit_ofs, basisu::minimum<int>(64, 128 - (int)bit_ofs));
else
{
-#ifdef __EMSCRIPTEN__
bits = blk.m_dwords[2];
bits |= (((uint64_t)blk.m_dwords[3]) << 32U);
-#else
- bits = blk.m_qwords[1];
-#endif
if (bit_ofs >= 64U)
bits >>= (bit_ofs - 64U);
@@ -16722,8 +16599,8 @@ namespace basist
#if BASISD_SUPPORT_KTX2
const uint8_t g_ktx2_file_identifier[12] = { 0xAB, 0x4B, 0x54, 0x58, 0x20, 0x32, 0x30, 0xBB, 0x0D, 0x0A, 0x1A, 0x0A };
- ktx2_transcoder::ktx2_transcoder(basist::etc1_global_selector_codebook* pGlobal_sel_codebook) :
- m_etc1s_transcoder(pGlobal_sel_codebook)
+ ktx2_transcoder::ktx2_transcoder() :
+ m_etc1s_transcoder()
{
clear();
}
@@ -17334,6 +17211,7 @@ namespace basist
bool ktx2_transcoder::decompress_level_data(uint32_t level_index, basisu::uint8_vec& uncomp_data)
{
+ const uint8_t* pComp_data = m_levels[level_index].m_byte_offset + m_pData;
const uint64_t comp_size = m_levels[level_index].m_byte_length;
const uint64_t uncomp_size = m_levels[level_index].m_uncompressed_byte_length;
@@ -17349,7 +17227,7 @@ namespace basist
return false;
}
- if (!uncomp_data.try_resize(uncomp_size))
+ if (!uncomp_data.try_resize((size_t)uncomp_size))
{
BASISU_DEVEL_ERROR("ktx2_transcoder::decompress_level_data: Out of memory\n");
return false;
@@ -17358,7 +17236,6 @@ namespace basist
if (m_header.m_supercompression_scheme == KTX2_SS_ZSTANDARD)
{
#if BASISD_SUPPORT_KTX2_ZSTD
- const uint8_t* pComp_data = m_levels[level_index].m_byte_offset + m_pData;
size_t actualUncompSize = ZSTD_decompress(uncomp_data.data(), (size_t)uncomp_size, pComp_data, (size_t)comp_size);
if (ZSTD_isError(actualUncompSize))
{