Fix miscellaneous compiler warnings

DXT Testing:

The modified algorithm has been tested on the Kodak test set using 64-bit build with default settings (running on Windows 10, i7-4790, 3.6GHz). All the decompressed test images are identical to the images being compressed and decompressed using original version of Crunch (revision ea9b8d8).

[Compressing Kodak set without mipmaps using DXT1 encoding]
Original: 1582222 bytes / 28.866 sec
Modified: 1468204 bytes / 11.858 sec
Improvement: 7.21% (compression ratio) / 58.92% (compression time)

[Compressing Kodak set with mipmaps using DXT1 encoding]
Original: 2065243 bytes / 36.878 sec
Modified: 1914805 bytes / 15.625 sec
Improvement: 7.28% (compression ratio) / 57.63% (compression time)

ETC Testing:

The modified algorithm has been tested on the Kodak test set using 64-bit build with default settings (running on Windows 10, i7-4790, 3.6GHz). The ETC1 quantization parameters have been selected in such a way, so that ETC1 compression gives approximately the same average Luma PSNR as the corresponding DXT1 compression (which is equal to 34.044 dB for the Kodak test set compressed without mipmaps using DXT1 encoding and default quality settings).

[Compressing Kodak set without mipmaps using ETC1 encoding]
Total size: 1607858 bytes
Total time: 17.181 sec
Average bitrate: 1.363 bpp
Average Luma PSNR: 34.050 dB
This commit is contained in:
Alexander Suvorov
2017-09-11 13:51:50 +02:00
parent 6b3172f793
commit 3e12aff909
41 changed files with 163 additions and 333 deletions
Binary file not shown.
+1 -2
View File
@@ -8,8 +8,7 @@
namespace crnlib {
static void area_fatal_error(const char* pFunc, const char* pMsg, ...) {
pFunc;
static void area_fatal_error(const char*, const char* pMsg, ...) {
va_list args;
va_start(args, pMsg);
+2 -4
View File
@@ -46,13 +46,11 @@ struct crnlib_assume_try {};
#ifdef NDEBUG
template <typename T>
inline T crnlib_assert_range(T i, T m) {
m;
inline T crnlib_assert_range(T i, T) {
return i;
}
template <typename T>
inline T crnlib_assert_range_incl(T i, T m) {
m;
inline T crnlib_assert_range_incl(T i, T) {
return i;
}
#else
-3
View File
@@ -652,10 +652,7 @@ class clusterizer {
new_right_child *= (1.0f / right_weight);
left_child = new_left_child;
left_weight = left_weight;
right_child = new_right_child;
right_weight = right_weight;
float total_variance = left_variance + right_variance;
if (total_variance < .00001f)
+3 -3
View File
@@ -469,9 +469,9 @@ struct scalar_type<color_quad<c, q> > {
enum { cFlag = true };
static inline void construct(color_quad<c, q>* p) {}
static inline void construct(color_quad<c, q>* p, const color_quad<c, q>& init) { memcpy(p, &init, sizeof(color_quad<c, q>)); }
static inline void construct_array(color_quad<c, q>* p, uint n) { p, n; }
static inline void destruct(color_quad<c, q>* p) { p; }
static inline void destruct_array(color_quad<c, q>* p, uint n) { p, n; }
static inline void construct_array(color_quad<c, q>*, uint) {}
static inline void destruct(color_quad<c, q>*) {}
static inline void destruct_array(color_quad<c, q>*, uint) {}
};
typedef color_quad<uint8, int> color_quad_u8;
+2 -5
View File
@@ -21,9 +21,7 @@ void colorized_console::tick() {
}
#ifdef CRNLIB_USE_WIN32_API
bool colorized_console::console_output_func(eConsoleMessageType type, const char* pMsg, void* pData) {
pData;
bool colorized_console::console_output_func(eConsoleMessageType type, const char* pMsg, void*) {
if (console::get_output_disabled())
return true;
@@ -78,8 +76,7 @@ bool colorized_console::console_output_func(eConsoleMessageType type, const char
return true;
}
#else
bool colorized_console::console_output_func(eConsoleMessageType type, const char* pMsg, void* pData) {
pData;
bool colorized_console::console_output_func(eConsoleMessageType type, const char* pMsg, void*) {
if (console::get_output_disabled())
return true;
+17 -28
View File
@@ -74,9 +74,6 @@ bool crn_comp::pack_color_endpoints(crnlib::vector<uint8>& packed_data, const cr
return false;
}
uint start_bits = codec.encode_get_total_bits_written();
start_bits;
for (uint i = 0; i < residual_syms.size(); i++) {
const uint sym = residual_syms[i];
const uint table = ((i % 3) == 1) ? 1 : 0;
@@ -93,12 +90,12 @@ bool crn_comp::pack_color_endpoints(crnlib::vector<uint8>& packed_data, const cr
bool crn_comp::pack_color_endpoints_etc(crnlib::vector<uint8>& packed_data, const crnlib::vector<uint16>& remapping) {
crnlib::vector<uint32> remapped_endpoints(m_color_endpoints.size());
for (uint i = 0; i < m_color_endpoints.size(); i++)
remapped_endpoints[remapping[i]] = m_color_endpoints[i] & 0x07000000 | m_color_endpoints[i] >> 3 & 0x001F1F1F;
remapped_endpoints[remapping[i]] = (m_color_endpoints[i] & 0x07000000) | (m_color_endpoints[i] >> 3 & 0x001F1F1F);
symbol_histogram hist(32);
for (uint32 prev_endpoint = 0, p = 0; p < remapped_endpoints.size(); p++) {
for (uint32 _e = prev_endpoint, e = prev_endpoint = remapped_endpoints[p], c = 0; c < 4; c++, _e >>= 8, e >>= 8)
hist.inc_freq(e - _e & 0x1F);
hist.inc_freq((e - _e) & 0x1F);
}
static_huffman_data_model dm;
dm.init(true, hist, 15);
@@ -107,7 +104,7 @@ bool crn_comp::pack_color_endpoints_etc(crnlib::vector<uint8>& packed_data, cons
codec.encode_transmit_static_huffman_data_model(dm, false);
for (uint32 prev_endpoint = 0, p = 0; p < remapped_endpoints.size(); p++) {
for (uint32 _e = prev_endpoint, e = prev_endpoint = remapped_endpoints[p], c = 0; c < 4; c++, _e >>= 8, e >>= 8)
codec.encode(e - _e & 0x1F, dm);
codec.encode((e - _e) & 0x1F, dm);
}
codec.stop_encoding(false);
packed_data.swap(codec.get_encoding_buf());
@@ -165,9 +162,6 @@ bool crn_comp::pack_alpha_endpoints(crnlib::vector<uint8>& packed_data, const cr
if (!codec.encode_transmit_static_huffman_data_model(residual_dm, false))
return false;
uint start_bits = codec.encode_get_total_bits_written();
start_bits;
for (uint i = 0; i < residual_syms.size(); i++) {
const uint sym = residual_syms[i];
codec.encode(sym, residual_dm);
@@ -341,8 +335,8 @@ bool crn_comp::alias_images() {
m_levels.resize(m_pParams->m_levels);
m_total_blocks = 0;
for (uint level = 0; level < m_pParams->m_levels; level++) {
uint blockHeight = (math::maximum(1U, m_pParams->m_height >> level) + 7 & ~7) >> 2;
m_levels[level].block_width = (math::maximum(1U, m_pParams->m_width >> level) + 7 & ~7) >> (m_has_etc_color_blocks ? 1 : 2);
uint blockHeight = ((math::maximum(1U, m_pParams->m_height >> level) + 7) & ~7) >> 2;
m_levels[level].block_width = ((math::maximum(1U, m_pParams->m_width >> level) + 7) & ~7) >> (m_has_etc_color_blocks ? 1 : 2);
m_levels[level].first_block = m_total_blocks;
m_levels[level].num_blocks = m_pParams->m_faces * m_levels[level].block_width * blockHeight;
m_total_blocks += m_levels[level].num_blocks;
@@ -558,8 +552,8 @@ bool crn_comp::quantize_images() {
image_u8& image = m_images[face][level];
uint width = image.get_width();
uint height = image.get_height();
uint blockWidth = (width + 7 & ~7) >> 2;
uint blockHeight = (height + 7 & ~7) >> 2;
uint blockWidth = ((width + 7) & ~7) >> 2;
uint blockHeight = ((height + 7) & ~7) >> 2;
for (uint by = 0; by < blockHeight; by++) {
for (uint y0 = by << 2, bx = 0; bx < blockWidth; bx++, b++) {
for (uint t = 0, x0 = bx << 2, dy = 0; dy < 4; dy++) {
@@ -634,8 +628,8 @@ static void remap_color_endpoints(uint16* remapping, const optimize_color_params
for (uint similarity_base = (uint)(4000 * (1.0f + weight)), total_frequency_normalizer = 0; remaining.size();) {
const optimize_color_params::unpacked_endpoint& e_front = unpacked_endpoints[chosen.front()];
const optimize_color_params::unpacked_endpoint& e_back = unpacked_endpoints[chosen.back()];
uint16 selected_index;
uint64 best_value = 0, selected_similarity_front, selected_similarity_back;
uint16 selected_index = 0;
uint64 best_value = 0, selected_similarity_front = 0, selected_similarity_back = 0;
for (uint16 i = 0; i < remaining.size(); i++) {
uint remaining_index = remaining[i];
const optimize_color_params::unpacked_endpoint& e_remaining = unpacked_endpoints[remaining_index];
@@ -730,7 +724,7 @@ void crn_comp::optimize_color_selectors() {
D4[i] = d[(i ^ i >> 4) & 3] + d[(i >> 2 ^ i >> 6) & 3];
uint8 D8[0x10000];
for (uint32 i = 0; i < 0x10000; i++)
D8[i] = D4[i >> 8 & 0xF0 | i >> 4 & 0xF] + D4[i >> 4 & 0xF0 | i & 0xF];
D8[i] = D4[(i >> 8 & 0xF0) | (i >> 4 & 0xF)] + D4[(i >> 4 & 0xF0) | (i & 0xF)];
crnlib::vector<uint32> selectors(n);
crnlib::vector<uint16> indices(n);
@@ -744,10 +738,10 @@ void crn_comp::optimize_color_selectors() {
uint min_error = cUINT32_MAX;
for (uint16 i = 0; i < left; i++) {
uint32 selector = selectors[i];
uint8 d0 = D8[selector >> 16 & 0xFF00 | selected_selector >> 24 & 0xFF];
uint8 d1 = D8[selector >> 8 & 0xFF00 | selected_selector >> 16 & 0xFF];
uint8 d2 = D8[selector & 0xFF00 | selected_selector >> 8 & 0xFF];
uint8 d3 = D8[selector << 8 & 0xFF00 | selected_selector & 0xFF];
uint8 d0 = D8[(selector >> 16 & 0xFF00) | (selected_selector >> 24 & 0xFF)];
uint8 d1 = D8[(selector >> 8 & 0xFF00) | (selected_selector >> 16 & 0xFF)];
uint8 d2 = D8[(selector & 0xFF00) | (selected_selector >> 8 & 0xFF)];
uint8 d3 = D8[(selector << 8 & 0xFF00) | (selected_selector & 0xFF)];
uint error = d0 + d1 + d2 + d3;
if (error < min_error) {
min_error = error;
@@ -872,8 +866,8 @@ static void remap_alpha_endpoints(uint16* remapping, const optimize_alpha_params
for (uint similarity_base = (uint)(1000 * (1.0f + weight)), total_frequency_normalizer = 0; remaining.size();) {
const optimize_alpha_params::unpacked_endpoint& e_front = unpacked_endpoints[chosen.front()];
const optimize_alpha_params::unpacked_endpoint& e_back = unpacked_endpoints[chosen.back()];
uint16 selected_index;
uint64 best_value = 0, selected_similarity_front, selected_similarity_back;
uint16 selected_index = 0;
uint64 best_value = 0, selected_similarity_front = 0, selected_similarity_back = 0;
for (uint16 i = 0; i < remaining.size(); i++) {
uint remaining_index = remaining[i];
const optimize_alpha_params::unpacked_endpoint& e_remaining = unpacked_endpoints[remaining_index];
@@ -991,7 +985,7 @@ void crn_comp::optimize_alpha_selectors() {
for (uint16 i = 0; i < left; i++) {
uint error = 0;
for (uint64 selector = selectors[i] << 6, delta_selector = selected_selector, j = 0; j < 8; j++, selector >>= 6, delta_selector >>= 6)
error += D6[selector & 0xFC0 | delta_selector & 0x3F];
error += D6[(selector & 0xFC0) | (delta_selector & 0x3F)];
if (error < min_error) {
min_error = error;
selected_index = i;
@@ -1269,11 +1263,6 @@ bool crn_comp::compress_internal() {
return true;
}
bool crn_comp::compress_init(const crn_comp_params& params) {
params;
return true;
}
bool crn_comp::compress_pass(const crn_comp_params& params, float* pEffective_bitrate) {
clear();
+1 -1
View File
@@ -21,7 +21,7 @@ class crn_comp : public itexture_comp {
virtual const char* get_ext() const { return "CRN"; }
virtual bool compress_init(const crn_comp_params& params);
virtual bool compress_init(const crn_comp_params&) { return true; };
virtual bool compress_pass(const crn_comp_params& params, float* pEffective_bitrate);
virtual void compress_deinit();
-2
View File
@@ -1625,8 +1625,6 @@ void dxt1_endpoint_optimizer::try_combinatorial_encoding() {
// The fourth (transparent) color in 3 color "transparent" blocks is black, which can be optionally exploited for small gains in DXT1 mode if the caller
// doesn't actually use alpha. (But not in DXT5 mode, because 3-color blocks aren't permitted by GPU's for DXT5.)
bool dxt1_endpoint_optimizer::try_alpha_as_black_optimization() {
const params* pOrig_params = m_pParams;
pOrig_params;
results* pOrig_results = m_pResults;
uint num_dark_colors = 0;
+11 -14
View File
@@ -231,7 +231,7 @@ bool dxt_hc::compress(
return true;
}
void dxt_hc::determine_tiles_task(uint64 data, void* pData_ptr) {
void dxt_hc::determine_tiles_task(uint64 data, void*) {
uint num_tasks = m_pTask_pool->get_num_threads() + 1;
uint offsets[9] = {0, 16, 32, 48, 0, 32, 64, 96, 64};
uint8 tiles[8][4] = {{8}, {6, 7}, {4, 5}, {6, 1, 3}, {7, 0, 2}, {4, 2, 3}, {5, 0, 1}, {0, 2, 1, 3}};
@@ -376,7 +376,7 @@ void dxt_hc::determine_tiles_task(uint64 data, void* pData_ptr) {
}
}
void dxt_hc::determine_tiles_task_etc(uint64 data, void* pData_ptr) {
void dxt_hc::determine_tiles_task_etc(uint64 data, void*) {
uint num_tasks = m_pTask_pool->get_num_threads() + 1;
uint offsets[5] = {0, 8, 16, 24, 16};
uint8 tiles[3][2] = {{4}, {2, 3}, {0, 1}};
@@ -399,11 +399,11 @@ void dxt_hc::determine_tiles_task_etc(uint64 data, void* pData_ptr) {
for (uint level = 0; level < m_params.m_num_levels; level++) {
float weight = m_params.m_levels[level].m_weight;
uint b = m_params.m_levels[level].m_first_block + m_params.m_levels[level].m_num_blocks * data / num_tasks & ~1;
uint bEnd = m_params.m_levels[level].m_first_block + m_params.m_levels[level].m_num_blocks * (data + 1) / num_tasks & ~1;
uint b = (m_params.m_levels[level].m_first_block + m_params.m_levels[level].m_num_blocks * data / num_tasks) & ~1;
uint bEnd = (m_params.m_levels[level].m_first_block + m_params.m_levels[level].m_num_blocks * (data + 1) / num_tasks) & ~1;
for (; b < bEnd; b += 2) {
for (uint p = 0; p < 16; p++)
tilePixels[p] = m_blocks[b >> 1][p << 2 & 12 | p >> 2];
tilePixels[p] = m_blocks[b >> 1][(p << 2 & 12) | p >> 2];
memcpy(tilePixels + 16, m_blocks[b >> 1], 64);
for (uint t = 0; t < 5; t++) {
params.m_pSrc_pixels = tilePixels + offsets[t];
@@ -483,14 +483,12 @@ void dxt_hc::determine_tiles_task_etc(uint64 data, void* pData_ptr) {
}
}
void dxt_hc::determine_color_endpoint_codebook_task(uint64 data, void* pData_ptr) {
pData_ptr;
void dxt_hc::determine_color_endpoint_codebook_task(uint64 data, void*) {
const uint thread_index = static_cast<uint>(data);
if (!m_has_color_blocks)
return;
uint total_empty_clusters = 0;
for (uint cluster_index = 0; cluster_index < m_color_clusters.size(); cluster_index++) {
if (m_canceled)
return;
@@ -580,7 +578,7 @@ void dxt_hc::determine_color_endpoint_codebook_task(uint64 data, void* pData_ptr
}
}
void dxt_hc::determine_color_endpoint_codebook_task_etc(uint64 data, void* pData_ptr) {
void dxt_hc::determine_color_endpoint_codebook_task_etc(uint64 data, void*) {
uint num_tasks = m_pTask_pool->get_num_threads() + 1;
uint8 delta[8][2] = { {2, 8}, {5, 17}, {9, 29}, {13, 42}, {18, 60}, {24, 80}, {33, 106}, {47, 183} };
int scan[] = {-1, 0, 1};
@@ -681,7 +679,7 @@ void dxt_hc::determine_color_endpoints() {
if (m_endpoint_indices[b].reference >> 1) {
color_quad_u8 mirror[16];
for (uint p = 0; p < 16; p++)
mirror[p] = m_blocks[b >> 1][p << 2 & 12 | p >> 2];
mirror[p] = m_blocks[b >> 1][(p << 2 & 12) | p >> 2];
memcpy(m_blocks[b >> 1], mirror, 64);
}
m_endpoint_indices[b].reference = 0;
@@ -693,8 +691,7 @@ void dxt_hc::determine_color_endpoints() {
m_pTask_pool->join();
}
void dxt_hc::determine_alpha_endpoint_codebook_task(uint64 data, void* pData_ptr) {
pData_ptr;
void dxt_hc::determine_alpha_endpoint_codebook_task(uint64 data, void*) {
const uint thread_index = static_cast<uint>(data);
for (uint cluster_index = 0; cluster_index < m_alpha_clusters.size(); cluster_index++) {
@@ -923,7 +920,7 @@ void dxt_hc::create_color_selector_codebook() {
}
uint num_tasks = m_pTask_pool->get_num_threads() + 1;
crnlib::vector<crnlib::vector<color_selector_details>> selector_details(num_tasks);
crnlib::vector<crnlib::vector<color_selector_details> > selector_details(num_tasks);
for (uint t = 0; t < num_tasks; t++) {
selector_details[t].resize(m_color_selectors.size());
m_pTask_pool->queue_object_task(this, &dxt_hc::create_color_selector_codebook_task, t, &selector_details[t]);
@@ -1037,7 +1034,7 @@ void dxt_hc::create_alpha_selector_codebook() {
}
uint num_tasks = m_pTask_pool->get_num_threads() + 1;
crnlib::vector<crnlib::vector<alpha_selector_details>> selector_details(num_tasks);
crnlib::vector<crnlib::vector<alpha_selector_details> > selector_details(num_tasks);
for (uint t = 0; t < num_tasks; t++) {
selector_details[t].resize(m_alpha_selectors.size());
m_pTask_pool->queue_object_task(this, &dxt_hc::create_alpha_selector_codebook_task, t, &selector_details[t]);
+2 -2
View File
@@ -863,7 +863,7 @@ void dxt_image::set_pixel(uint x, uint y, const color_quad_u8& c, bool perceptua
uint best_selector = 0;
for (uint i = 0; i < cDXT5SelectorValues; i++) {
uint error = labs(values[i] - c[comp_index]); // no need to square
uint error = labs((int)values[i] - (int)c[comp_index]); // no need to square
if (error < best_error) {
best_error = error;
@@ -1096,7 +1096,7 @@ void dxt_image::set_block_pixels(
}
if (m_format == cDXT5A)
ryg_dxt::sCompressDXT5ABlock((sU8*)pElement, (const sU32*)pixels, 0);
ryg_dxt::sCompressDXT5ABlock((sU8*)pElement, (const sU32*)pixels);
else
ryg_dxt::sCompressDXTBlock((sU8*)pElement, (const sU32*)pixels, m_format == cDXT5, 0);
} else if ((p.m_compressor == cCRNDXTCompressorCRNF) && (m_format != cDXT1A)) {
+1 -3
View File
@@ -6,10 +6,8 @@
namespace crnlib {
dynamic_string g_empty_dynamic_string;
dynamic_string::dynamic_string(eVarArg dummy, const char* p, ...)
dynamic_string::dynamic_string(eVarArg, const char* p, ...)
: m_buf_size(0), m_len(0), m_pStr(NULL) {
dummy;
CRNLIB_ASSERT(p);
va_list args;
+4 -6
View File
@@ -1014,7 +1014,7 @@ bool etc1_optimizer::evaluate_solution_fast(const etc1_solution_coordinates& coo
const color_quad_u8* pSrc_pixels = m_pParams->m_pSrc_pixels;
if ((m_pSorted_luma[n - 1] * 2) < block_inten_midpoints[0]) {
if (block_inten[0] > m_pSorted_luma[n - 1]) {
const uint min_error = labs(block_inten[0] - m_pSorted_luma[n - 1]);
const uint min_error = block_inten[0] - m_pSorted_luma[n - 1];
if (min_error >= trial_solution.m_error)
continue;
}
@@ -1025,7 +1025,7 @@ bool etc1_optimizer::evaluate_solution_fast(const etc1_solution_coordinates& coo
total_error += color::elucidian_distance(block_colors[0], pSrc_pixels[c], false);
} else if ((m_pSorted_luma[0] * 2) >= block_inten_midpoints[2]) {
if (m_pSorted_luma[0] > block_inten[3]) {
const uint min_error = labs(m_pSorted_luma[0] - block_inten[3]);
const uint min_error = m_pSorted_luma[0] - block_inten[3];
if (min_error >= trial_solution.m_error)
continue;
}
@@ -1117,9 +1117,7 @@ static void DitherBlock(color_quad_u8* dest, const color_quad_u8* block) {
}
static uint etc1_decode_value(uint diff, uint inten, uint selector, uint packed_c) {
const uint limit = diff ? 32 : 16;
limit;
CRNLIB_ASSERT((diff < 2) && (inten < 8) && (selector < 4) && (packed_c < limit));
CRNLIB_ASSERT((diff < 2) && (inten < 8) && (selector < 4) && (packed_c < (diff ? 32 : 16)));
int c;
if (diff)
c = (packed_c >> 2) | (packed_c << 3);
@@ -1137,7 +1135,7 @@ void pack_etc1_block_init() {
for (uint inten = 0; inten < 8; inten++) {
for (uint selector = 0; selector < 4; selector++) {
const uint inverse_table_index = diff + (inten << 1) + (selector << 4);
for (uint color = 0; color < 256; color++) {
for (int color = 0; color < 256; color++) {
uint best_error = cUINT32_MAX, best_packed_c = 0;
for (uint packed_c = 0; packed_c < limit; packed_c++) {
int v = etc1_decode_value(diff, inten, selector, packed_c);
+2 -1
View File
@@ -409,8 +409,9 @@ bool file_utils::remove_extension(dynamic_string& filename) {
}
bool file_utils::create_path(const dynamic_string& fullpath) {
#ifdef WIN32
bool got_unc = false;
got_unc;
#endif
dynamic_string cur_path;
const int l = fullpath.get_len();
+1 -1
View File
@@ -46,7 +46,7 @@ inline void construct_array(T* p, uint n, const U& init) {
template <typename T>
inline void destruct(T* p) {
p;
(void)p;
p->~T();
}
+2 -2
View File
@@ -335,7 +335,7 @@ class image {
uint height = math::minimum(m_height - dst_y, src.get_height() - src_y);
bool success = unclipped_blit(src_x, src_y, width, height, dst_x, dst_y, src);
success;
(void)success;
CRNLIB_ASSERT(success);
return true;
@@ -360,7 +360,7 @@ class image {
src_rect.get_left(), src_rect.get_top(),
math::minimum(src_rect.get_width(), dst_rect.get_width()), math::minimum(src_rect.get_height(), dst_rect.get_height()),
dst_rect.get_left(), dst_rect.get_top(), src);
success;
(void)success;
CRNLIB_ASSERT(success);
return true;
+2 -2
View File
@@ -752,8 +752,8 @@ double compute_ssim(const image_u8& a, const image_u8& b, int channel_index) {
}
void print_ssim(const image_u8& src_img, const image_u8& dst_img) {
src_img;
dst_img;
(void)src_img;
(void)dst_img;
//double y_ssim = compute_ssim(src_img, dst_img, -1);
//console::printf("Luma MSSIM: %f, Scaled: %f", y_ssim, (y_ssim - .8f) / .2f);
+1 -1
View File
@@ -587,7 +587,7 @@ inline int jpeg_decoder::huff_decode(huff_tables* pH, int& extra_bits) {
// Tables and macro used to fully decode the DPCM differences.
static const int s_extend_test[16] = {0, 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080, 0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000};
static const int s_extend_offset[16] = {0, ((-1) << 1) + 1, ((-1) << 2) + 1, ((-1) << 3) + 1, ((-1) << 4) + 1, ((-1) << 5) + 1, ((-1) << 6) + 1, ((-1) << 7) + 1, ((-1) << 8) + 1, ((-1) << 9) + 1, ((-1) << 10) + 1, ((-1) << 11) + 1, ((-1) << 12) + 1, ((-1) << 13) + 1, ((-1) << 14) + 1, ((-1) << 15) + 1};
static const int s_extend_offset[16] = {0, 1 - (1 << 1), 1 - (1 << 2), 1 - (1 << 3), 1 - (1 << 4), 1 - (1 << 5), 1 - (1 << 6), 1 - (1 << 7), 1 - (1 << 8), 1 - (1 << 9), 1 - (1 << 10), 1 - (1 << 11), 1 - (1 << 12), 1 - (1 << 13), 1 - (1 << 14), 1 - (1 << 15)};
static const int s_extend_mask[] = {0, (1 << 0), (1 << 1), (1 << 2), (1 << 3), (1 << 4), (1 << 5), (1 << 6), (1 << 7), (1 << 8), (1 << 9), (1 << 10), (1 << 11), (1 << 12), (1 << 13), (1 << 14), (1 << 15), (1 << 16)};
// The logical AND's in this macro are to shut up static code analysis (aren't really necessary - couldn't find another way to do this)
#define JPGD_HUFF_EXTEND(x, s) (((x) < s_extend_test[s & 15]) ? ((x) + s_extend_offset[s & 15]) : (x))
-3
View File
@@ -362,9 +362,6 @@ bool ktx_texture::read_from_stream(data_stream_serializer& serializer) {
if ((!mip0_row_blocks) || (!mip0_col_blocks))
return false;
const uint mip0_depth = CRNLIB_MAX(1, m_header.m_pixelDepth);
mip0_depth;
bool has_valid_image_size_fields = true;
bool disable_mip_and_cubemap_padding = false;
+2 -82
View File
@@ -56,9 +56,7 @@ static mem_stat_t update_total_allocated(int block_delta, mem_stat_t byte_delta)
}
#endif // CRNLIB_MEM_STATS
static void* crnlib_default_realloc(void* p, size_t size, size_t* pActual_size, bool movable, void* pUser_data) {
pUser_data;
static void* crnlib_default_realloc(void* p, size_t size, size_t* pActual_size, bool movable, void*) {
void* p_new;
if (!p) {
@@ -106,90 +104,12 @@ static void* crnlib_default_realloc(void* p, size_t size, size_t* pActual_size,
return p_new;
}
static size_t crnlib_default_msize(void* p, void* pUser_data) {
pUser_data;
static size_t crnlib_default_msize(void* p, void*) {
return p ? _msize(p) : 0;
}
#if 0
static __declspec(thread) void *g_pBuf;
static __declspec(thread) size_t g_buf_size;
static __declspec(thread) size_t g_buf_ofs;
static size_t crnlib_nofree_msize(void* p, void* pUser_data)
{
pUser_data;
return p ? ((const size_t*)p)[-1] : 0;
}
static void* crnlib_nofree_realloc(void* p, size_t size, size_t* pActual_size, bool movable, void* pUser_data)
{
pUser_data;
void* p_new;
if (!p)
{
size = math::align_up_value(size, CRNLIB_MIN_ALLOC_ALIGNMENT);
size_t actual_size = sizeof(size_t)*2 + size;
size_t num_remaining = g_buf_size - g_buf_ofs;
if (num_remaining < actual_size)
{
g_buf_size = CRNLIB_MAX(actual_size, 32*1024*1024);
g_buf_ofs = 0;
g_pBuf = malloc(g_buf_size);
if (!g_pBuf)
return NULL;
}
p_new = (uint8*)g_pBuf + g_buf_ofs;
((size_t*)p_new)[1] = size;
p_new = (size_t*)p_new + 2;
g_buf_ofs += actual_size;
if (pActual_size)
*pActual_size = size;
CRNLIB_ASSERT(crnlib_nofree_msize(p_new, NULL) == size);
}
else if (!size)
{
if (pActual_size)
*pActual_size = 0;
p_new = NULL;
}
else
{
size_t cur_size = crnlib_nofree_msize(p, NULL);
p_new = p;
if (!movable)
return NULL;
if (size > cur_size)
{
p_new = crnlib_nofree_realloc(NULL, size, NULL, true, NULL);
if (!p_new)
return NULL;
memcpy(p_new, p, cur_size);
cur_size = size;
}
if (pActual_size)
*pActual_size = cur_size;
}
return p_new;
}
static crn_realloc_func g_pRealloc = crnlib_nofree_realloc;
static crn_msize_func g_pMSize = crnlib_nofree_msize;
#else
static crn_realloc_func g_pRealloc = crnlib_default_realloc;
static crn_msize_func g_pMSize = crnlib_default_msize;
#endif
static void* g_pUser_data;
void crnlib_mem_error(const char* p_msg) {
+1 -1
View File
@@ -2310,7 +2310,7 @@ void* tdefl_write_image_to_png_file_in_memory(const void* pImage, int w, int h,
*pLen_out = out_buf.m_size - 41;
{
mz_uint8 pnghdr[41] = {0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52,
0, 0, (mz_uint8)(w >> 8), (mz_uint8)w, 0, 0, (mz_uint8)(h >> 8), (mz_uint8)h, 8, "\0\0\04\02\06"[num_chans], 0, 0, 0, 0, 0, 0, 0,
0, 0, (mz_uint8)(w >> 8), (mz_uint8)w, 0, 0, (mz_uint8)(h >> 8), (mz_uint8)h, 8, (mz_uint8)"\0\0\04\02\06"[num_chans], 0, 0, 0, 0, 0, 0, 0,
(mz_uint8)(*pLen_out >> 24), (mz_uint8)(*pLen_out >> 16), (mz_uint8)(*pLen_out >> 8), (mz_uint8)*pLen_out, 0x49, 0x44, 0x41, 0x54};
c = (mz_uint32)mz_crc32(MZ_CRC32_INIT, pnghdr + 12, 17);
for (i = 0; i < 4; ++i, c <<= 8)
+3 -8
View File
@@ -169,10 +169,7 @@ bool mip_level::unpack_from_dxt(bool uncook) {
return false;
image_u8* pNew_img = crnlib_new<image_u8>();
image_u8* pImg = get_unpacked_image(*pNew_img, uncook ? cUnpackFlagUncook : 0);
pImg;
CRNLIB_ASSERT(pImg == pNew_img);
CRNLIB_ASSERT(get_unpacked_image(*pNew_img, uncook ? cUnpackFlagUncook : 0) == pNew_img);
assign(pNew_img, PIXEL_FMT_INVALID, m_orient_flags);
return true;
@@ -2590,7 +2587,7 @@ bool mipmapped_texture::read_from_stream(data_stream_serializer& serializer, tex
bool success = false;
if (!texture_file_types::supports_mipmaps(file_format)) {
success = read_regular_image(serializer, file_format);
success = read_regular_image(serializer);
} else {
switch (file_format) {
case texture_file_types::cFormatDDS: {
@@ -2623,9 +2620,7 @@ bool mipmapped_texture::read_from_stream(data_stream_serializer& serializer, tex
return success;
}
bool mipmapped_texture::read_regular_image(data_stream_serializer& serializer, texture_file_types::format file_format) {
file_format;
bool mipmapped_texture::read_regular_image(data_stream_serializer& serializer) {
image_u8* pImg = crnlib_new<image_u8>();
bool status = image_utils::read_from_stream(*pImg, serializer, 0);
if (!status) {
+1 -1
View File
@@ -321,7 +321,7 @@ class mipmapped_texture {
inline void set_last_error(const char* p) const { m_last_error = p; }
void free_all_mips();
bool read_regular_image(data_stream_serializer& serializer, texture_file_types::format file_format);
bool read_regular_image(data_stream_serializer& serializer);
bool write_regular_image(const char* pFilename, uint32 image_write_flags);
bool read_dds_internal(data_stream_serializer& serializer);
void print_crn_comp_params(const crn_comp_params& p);
+1 -2
View File
@@ -383,8 +383,7 @@ bool qdxt1::update_progress(uint value, uint max_value) {
return true;
}
void qdxt1::pack_endpoints_task(uint64 data, void* pData_ptr) {
pData_ptr;
void qdxt1::pack_endpoints_task(uint64 data, void*) {
const uint thread_index = static_cast<uint>(data);
crnlib::vector<color_quad_u8> cluster_pixels;
+1 -2
View File
@@ -358,8 +358,7 @@ bool qdxt5::update_progress(uint value, uint max_value) {
return true;
}
void qdxt5::pack_endpoints_task(uint64 data, void* pData_ptr) {
pData_ptr;
void qdxt5::pack_endpoints_task(uint64 data, void*) {
const uint thread_index = static_cast<uint>(data);
crnlib::vector<color_quad_u8> cluster_pixels;
+2
View File
@@ -4,7 +4,9 @@
#include "crn_resample_filters.h"
namespace crnlib {
#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif
// To add your own filter, insert the new function below and update the filter table.
// There is no need to make the filter function particularly fast, because it's
+1 -1
View File
@@ -8,7 +8,7 @@ namespace crnlib {
#define resampler_assert CRNLIB_ASSERT
static inline int resampler_range_check(int v, int h) {
h;
(void)h;
resampler_assert((v >= 0) && (v < h));
return v;
}
+34 -42
View File
@@ -1457,37 +1457,34 @@ bool unpack_etc2_color(const void* pBlock, unsigned int* pDst_pixels_rgba, bool
color_quad_u8* pDst = reinterpret_cast<color_quad_u8*>(pDst_pixels_rgba);
const etc1_block& block = *static_cast<const etc1_block*>(pBlock);
const uint8* B = block.m_bytes;
const bool rOverflow = (int8(B[0] << 5) >> 5) + (B[0] >> 3) & 0x20;
const bool gOverflow = (int8(B[1] << 5) >> 5) + (B[1] >> 3) & 0x20;
const bool rOverflow = ((int8(B[0] << 5) >> 5) + (B[0] >> 3)) & 0x20;
const bool gOverflow = ((int8(B[1] << 5) >> 5) + (B[1] >> 3)) & 0x20;
if (rOverflow || gOverflow) {
color_quad_u8 block_colors[4];
uint8 unpacked[3];
if (rOverflow) {
uint8 unpacked[3] = {
B[0] & 0x3 | B[0] >> 1 & 0xC | B[2] & 0xF0,
B[1] >> 4 | B[2] << 4,
B[1] & 0xF | B[3] & 0xF0,
};
uint8 delta = g_etc2_modifier_table[B[3] & 1 | B[3] >> 1 & 6];
unpacked[0] = (B[0] & 0x3) | (B[0] >> 1 & 0xC) | (B[2] & 0xF0);
unpacked[1] = B[1] >> 4 | B[2] << 4;
unpacked[2] = (B[1] & 0xF) | (B[3] & 0xF0);
uint8 delta = g_etc2_modifier_table[(B[3] & 1) | (B[3] >> 1 & 6)];
for (uint c = 0; c < 3; c++) {
block_colors[2][c] = unpacked[c] << 4 | unpacked[c] & 0xF;
block_colors[1][c] = unpacked[c] >> 4 | unpacked[c] & 0xF0;
block_colors[2][c] = unpacked[c] << 4 | (unpacked[c] & 0xF);
block_colors[1][c] = unpacked[c] >> 4 | (unpacked[c] & 0xF0);
block_colors[0][c] = math::maximum(0, block_colors[1][c] - delta);
block_colors[3][c] = math::minimum(255, block_colors[1][c] + delta);
}
} else {
uint8 unpacked[3] = {
B[0] >> 3 & 0xF | B[2] << 1 & 0xF0,
B[1] >> 4 & 0x1 | B[0] << 1 & 0xE | B[3] >> 3 & 0x10 | B[2] << 5,
B[2] >> 7 | B[1] << 1 & 0x6 | B[1] & 0x8 | B[3] << 1 & 0xF0,
};
uint8 modifier = B[3] & 4 | B[3] << 1 & 2 | 1;
unpacked[0] = (B[0] >> 3 & 0xF) | (B[2] << 1 & 0xF0);
unpacked[1] = (B[1] >> 4 & 0x1) | (B[0] << 1 & 0xE) | (B[3] >> 3 & 0x10) | B[2] << 5;
unpacked[2] = B[2] >> 7 | (B[1] << 1 & 0x6) | (B[1] & 0x8) | (B[3] << 1 & 0xF0);
uint8 modifier = (B[3] & 4) | (B[3] << 1 & 2) | 1;
for (int d = 0, c = 0; !d && c < 3; c++, modifier &= d < 0 ? 6 : 7)
d = (unpacked[c] & 0xF) - (unpacked[c] >> 4);
uint8 delta = g_etc2_modifier_table[modifier];
for (uint c = 0; c < 3; c++) {
uint8 c0 = unpacked[c] << 4 | unpacked[c] & 0xF;
uint8 c1 = unpacked[c] >> 4 | unpacked[c] & 0xF0;
uint8 c0 = unpacked[c] << 4 | (unpacked[c] & 0xF);
uint8 c1 = unpacked[c] >> 4 | (unpacked[c] & 0xF0);
block_colors[0][c] = math::maximum(0, c1 - delta);
block_colors[1][c] = math::minimum(255, c1 + delta);
block_colors[2][c] = math::minimum(255, c0 + delta);
@@ -1503,15 +1500,15 @@ bool unpack_etc2_color(const void* pBlock, unsigned int* pDst_pixels_rgba, bool
}
} else {
int16 base[3], dj[3], di[3], color[3];
base[0] = B[0] << 1 & 0xFC | B[0] >> 5 & 3;
base[1] = B[0] << 7 & 0x80 | B[1] & 0x7E | B[0] & 1;
base[2] = B[1] << 7 & 0x80 | B[2] << 2 & 0x60 | B[2] << 3 & 0x18 | B[3] >> 5 & 4 | B[1] << 1 & 2 | B[2] >> 4 & 1;
di[0] = (B[5] << 5 & 0xE0 | B[6] >> 3 & 0x1C | B[5] >> 1 & 0x3) - base[0];
di[1] = (B[6] << 3 & 0xF8 | B[7] >> 5 & 0x6 | B[6] >> 4 & 0x1) - base[1];
di[2] = (B[7] << 2 & 0xFC | B[7] >> 4 & 0x3) - base[2];
dj[0] = (B[3] << 1 & 0xF8 | B[3] << 2 & 0x4 | B[3] >> 5 & 0x3) - base[0];
dj[1] = (B[4] & 0xFE | B[4] >> 7) - base[1];
dj[2] = (B[4] << 7 & 0x80 | B[5] >> 1 & 0x7C | B[4] << 1 & 0x2 | B[5] >> 7) - base[2];
base[0] = (B[0] << 1 & 0xFC) | (B[0] >> 5 & 3);
base[1] = (B[0] << 7 & 0x80) | (B[1] & 0x7E) | (B[0] & 1);
base[2] = (B[1] << 7 & 0x80) | (B[2] << 2 & 0x60) | (B[2] << 3 & 0x18) | (B[3] >> 5 & 4) | (B[1] << 1 & 2) | (B[2] >> 4 & 1);
di[0] = ((B[5] << 5 & 0xE0) | (B[6] >> 3 & 0x1C) | (B[5] >> 1 & 0x3)) - base[0];
di[1] = ((B[6] << 3 & 0xF8) | (B[7] >> 5 & 0x6) | (B[6] >> 4 & 0x1)) - base[1];
di[2] = ((B[7] << 2 & 0xFC) | (B[7] >> 4 & 0x3)) - base[2];
dj[0] = ((B[3] << 1 & 0xF8) | (B[3] << 2 & 0x4) | (B[3] >> 5 & 0x3)) - base[0];
dj[1] = ((B[4] & 0xFE) | B[4] >> 7) - base[1];
dj[2] = ((B[4] << 7 & 0x80) | (B[5] >> 1 & 0x7C) | (B[4] << 1 & 0x2) | B[5] >> 7) - base[2];
for (uint c = 0; c < 3; c++)
base[c] = (base[c] << 2) + 2;
for (uint i = 0; i < 4; i++) {
@@ -1539,7 +1536,7 @@ bool unpack_etc2_alpha(const void* pBlock, unsigned int* pDst_pixels_rgba, int c
for (uint d = d0, j = 0; j < 4; j++, pDst++, d += 12) {
int byte_offset = 2 + (d >> 3);
int bit_offset = d & 7;
int s = B[byte_offset] >> 8 - bit_offset & 7;
int s = B[byte_offset] >> (8 - bit_offset) & 7;
if (bit_offset < 3)
s |= B[byte_offset - 1] << bit_offset & 7;
pDst->c[comp_index] = values[s];
@@ -2045,7 +2042,7 @@ bool etc1_optimizer::evaluate_solution_fast(const etc1_solution_coordinates& coo
const color_quad_u8* pSrc_pixels = m_pParams->m_pSrc_pixels;
if ((m_pSorted_luma[n - 1] * 2) < block_inten_midpoints[0]) {
if (block_inten[0] > m_pSorted_luma[n - 1]) {
const uint min_error = labs(block_inten[0] - m_pSorted_luma[n - 1]);
const uint min_error = block_inten[0] - m_pSorted_luma[n - 1];
if (min_error >= trial_solution.m_error)
continue;
}
@@ -2056,7 +2053,7 @@ bool etc1_optimizer::evaluate_solution_fast(const etc1_solution_coordinates& coo
total_error += block_colors[0].squared_distance_rgb(pSrc_pixels[c]);
} else if ((m_pSorted_luma[0] * 2) >= block_inten_midpoints[2]) {
if (m_pSorted_luma[0] > block_inten[3]) {
const uint min_error = labs(m_pSorted_luma[0] - block_inten[3]);
const uint min_error = m_pSorted_luma[0] - block_inten[3];
if (min_error >= trial_solution.m_error)
continue;
}
@@ -2109,9 +2106,7 @@ bool etc1_optimizer::evaluate_solution_fast(const etc1_solution_coordinates& coo
}
static uint etc1_decode_value(uint diff, uint inten, uint selector, uint packed_c) {
const uint limit = diff ? 32 : 16;
limit;
RG_ETC1_ASSERT((diff < 2) && (inten < 8) && (selector < 4) && (packed_c < limit));
RG_ETC1_ASSERT((diff < 2) && (inten < 8) && (selector < 4) && (packed_c < (diff ? 32 : 16)));
int c;
if (diff)
c = (packed_c >> 2) | (packed_c << 3);
@@ -2134,7 +2129,7 @@ void pack_etc1_block_init() {
for (uint inten = 0; inten < 8; inten++) {
for (uint selector = 0; selector < 4; selector++) {
const uint inverse_table_index = diff + (inten << 1) + (selector << 4);
for (uint color = 0; color < 256; color++) {
for (int color = 0; color < 256; color++) {
uint best_error = cUINT32_MAX, best_packed_c = 0;
for (uint packed_c = 0; packed_c < limit; packed_c++) {
int v = etc1_decode_value(diff, inten, selector, packed_c);
@@ -2165,8 +2160,7 @@ void pack_etc1_block_init() {
// Packs solid color blocks efficiently using a set of small precomputed tables.
// For random 888 inputs, MSE results are better than Erricson's ETC1 packer in "slow" mode ~9.5% of the time, is slightly worse only ~.01% of the time, and is equal the rest of the time.
static uint64 pack_etc1_block_solid_color(etc1_block& block, const uint8* pColor, etc1_pack_params& pack_params) {
pack_params;
static uint64 pack_etc1_block_solid_color(etc1_block& block, const uint8* pColor) {
RG_ETC1_ASSERT(g_etc1_inverse_lookup[0][255]);
static uint s_next_comp[4] = {1, 2, 0, 1};
@@ -2245,12 +2239,10 @@ found_perfect_match:
static uint pack_etc1_block_solid_color_constrained(
etc1_optimizer::results& results,
uint num_colors, const uint8* pColor,
etc1_pack_params& pack_params,
bool use_diff,
const color_quad_u8* pBase_color5_unscaled) {
RG_ETC1_ASSERT(g_etc1_inverse_lookup[0][255]);
pack_params;
static uint s_next_comp[4] = {1, 2, 0, 1};
uint best_error = cUINT32_MAX, best_i = 0;
@@ -2404,7 +2396,7 @@ unsigned int pack_etc1_block(void* pETC1_block, const unsigned int* pSrc_pixels_
if (pSrc_pixels[r].m_u32 != first_pixel_u32)
break;
if (!r)
return static_cast<unsigned int>(16 * pack_etc1_block_solid_color(dst_block, &pSrc_pixels[0].r, pack_params));
return static_cast<unsigned int>(16 * pack_etc1_block_solid_color(dst_block, &pSrc_pixels[0].r));
color_quad_u8 dithered_pixels[16];
if (pack_params.m_dithering) {
@@ -2465,7 +2457,7 @@ unsigned int pack_etc1_block(void* pETC1_block, const unsigned int* pSrc_pixels_
if (subblock_pixels[r].m_u32 != subblock_pixel0_u32)
break;
if (!r) {
pack_etc1_block_solid_color_constrained(results[2], 8, &subblock_pixels[0].r, pack_params, !use_color4, (subblock && !use_color4) ? &results[0].m_block_color_unscaled : NULL);
pack_etc1_block_solid_color_constrained(results[2], 8, &subblock_pixels[0].r, !use_color4, (subblock && !use_color4) ? &results[0].m_block_color_unscaled : NULL);
}
}
@@ -2654,7 +2646,7 @@ unsigned int pack_etc2_alpha(void* pBlock, const unsigned int* pSrc_pixels_rgba,
for (int modifier_index = 0; modifier_index < 16; modifier_index++) {
const int* modifier = g_etc2a_modifier_table[modifier_index];
int multiplier = math::clamp<int>((results.m_first_endpoint - results.m_second_endpoint + modifier[7] + (modifier[7] >> 1)) / (modifier[7] << 1), 1, 15);
uint8 data[8] = {base_codeword, multiplier << 4 | modifier_index}, values[8];
uint8 data[8] = {(uint8)base_codeword, (uint8)(multiplier << 4 | modifier_index)}, values[8];
for (int i = 0; i < 8; i++)
values[i] = math::clamp<int>(base_codeword + modifier[i] * multiplier, 0, 255);
uint error = 0;
@@ -2673,7 +2665,7 @@ unsigned int pack_etc2_alpha(void* pBlock, const unsigned int* pSrc_pixels_rgba,
}
}
error += best_delta * best_delta;
data[byte_offset] |= best_s << 8 - bit_offset;
data[byte_offset] |= best_s << (8 - bit_offset);
if (bit_offset < 3)
data[byte_offset - 1] |= best_s >> bit_offset;
}
+4 -5
View File
@@ -462,8 +462,7 @@ static void CompressColorBlock(sU8* dest, const sU32* src, sInt quality) {
}
// Alpha block compression (this is easy for a change)
static void CompressAlphaBlock(sU8* dest, const sU32* src, sInt quality) {
quality;
static void CompressAlphaBlock(sU8* dest, const sU32* src) {
const Pixel* block = (const Pixel*)src;
// find min/max color
@@ -540,7 +539,7 @@ void sCompressDXTBlock(sU8* dest, const sU32* src, sBool alpha, sInt quality) {
// if alpha specified, compress alpha as well
if (alpha) {
CompressAlphaBlock(dest, src, quality);
CompressAlphaBlock(dest, src);
dest += 8;
}
@@ -548,10 +547,10 @@ void sCompressDXTBlock(sU8* dest, const sU32* src, sBool alpha, sInt quality) {
CompressColorBlock(dest, src, quality);
}
void sCompressDXT5ABlock(sU8* dest, const sU32* src, sInt quality) {
void sCompressDXT5ABlock(sU8* dest, const sU32* src) {
CRNLIB_ASSERT(Expand5[1]);
CompressAlphaBlock(dest, src, quality);
CompressAlphaBlock(dest, src);
}
} // namespace ryg_dxt
+1 -1
View File
@@ -22,6 +22,6 @@ void sInitDXT();
// quality: 0=fastest (no dither), 1=medium (dither)
void sCompressDXTBlock(sU8* dest, const sU32* src, sBool alpha, sInt quality);
void sCompressDXT5ABlock(sU8* dest, const sU32* src, sInt quality);
void sCompressDXT5ABlock(sU8* dest, const sU32* src);
} // namespace ryg_dxt
+9 -16
View File
@@ -743,8 +743,7 @@ static uint32 get32le(stbi* s) {
static void getn(stbi* s, stbi_uc* buffer, int n) {
#ifndef STBI_NO_STDIO
if (s->img_file) {
size_t nr = fread(buffer, 1, n, s->img_file);
nr;
fread(buffer, 1, n, s->img_file);
return;
}
#endif
@@ -1712,13 +1711,11 @@ typedef uint8* (*resample_row_func)(uint8* out, uint8* in0, uint8* in1,
#define div4(x) ((uint8)((x) >> 2))
static uint8* resample_row_1(uint8* out, uint8* in_near, uint8* in_far, int w, int hs) {
out, in_far, w, hs;
static uint8* resample_row_1(uint8*, uint8* in_near, uint8*, int, int) {
return in_near;
}
static uint8* resample_row_v_2(uint8* out, uint8* in_near, uint8* in_far, int w, int hs) {
hs;
static uint8* resample_row_v_2(uint8* out, uint8* in_near, uint8* in_far, int w, int) {
// need to generate two samples vertically for every one in input
int i;
for (i = 0; i < w; ++i)
@@ -1726,8 +1723,7 @@ static uint8* resample_row_v_2(uint8* out, uint8* in_near, uint8* in_far, int w,
return out;
}
static uint8* resample_row_h_2(uint8* out, uint8* in_near, uint8* in_far, int w, int hs) {
hs, in_far;
static uint8* resample_row_h_2(uint8* out, uint8* in_near, uint8*, int w, int) {
// need to generate two samples horizontally for every one in input
int i;
uint8* input = in_near;
@@ -1751,8 +1747,7 @@ static uint8* resample_row_h_2(uint8* out, uint8* in_near, uint8* in_far, int w,
#define div16(x) ((uint8)((x) >> 4))
static uint8* resample_row_hv_2(uint8* out, uint8* in_near, uint8* in_far, int w, int hs) {
hs;
static uint8* resample_row_hv_2(uint8* out, uint8* in_near, uint8* in_far, int w, int) {
// need to generate 2x2 samples for every one in input
int i, t0, t1;
if (w == 1) {
@@ -1772,8 +1767,7 @@ static uint8* resample_row_hv_2(uint8* out, uint8* in_near, uint8* in_far, int w
return out;
}
static uint8* resample_row_generic(uint8* out, uint8* in_near, uint8* in_far, int w, int hs) {
in_far;
static uint8* resample_row_generic(uint8* out, uint8* in_near, uint8*, int w, int hs) {
// resample with nearest-neighbor
int i, j;
for (i = 0; i < w; ++i)
@@ -2723,8 +2717,7 @@ static int compute_transparency(png* z, uint8 tc[3], int out_n) {
return 1;
}
static int expand_palette(png* a, uint8* palette, int len, int pal_img_n) {
len;
static int expand_palette(png* a, uint8* palette, int pal_img_n) {
uint32 i, pixel_count = a->s.img_x * a->s.img_y;
uint8 *p, *temp_out, *orig = a->out;
@@ -2926,7 +2919,7 @@ static int parse_png_file(png* z, int scan, int req_comp) {
s->img_out_n = pal_img_n;
if (req_comp >= 3)
s->img_out_n = req_comp;
if (!expand_palette(z, palette, pal_len, s->img_out_n))
if (!expand_palette(z, palette, s->img_out_n))
return 0;
}
stb_free(z->expanded);
@@ -4020,7 +4013,7 @@ static float* hdr_load(stbi* s, int* x, int* y, int* comp, int req_comp) {
if (c1 != 2 || c2 != 2 || (len & 0x80)) {
// not run-length encoded, so we have to actually use THIS data as a decoded
// pixel (note this can't be a valid pixel--one of RGB must be >= 128)
stbi_uc rgbe[4] = {c1, c2, len, get8(s)};
stbi_uc rgbe[4] = {(stbi_uc)c1, (stbi_uc)c2, (stbi_uc)len, (stbi_uc)get8(s)};
hdr_convert(hdr_data, rgbe, req_comp);
i = 1;
j = 0;
+2 -3
View File
@@ -200,7 +200,7 @@ void adaptive_huffman_data_model::update() {
status = prefix_coding::generate_decoder_tables(m_total_syms, &m_code_sizes[0], m_pDecode_tables, m_decoder_table_bits);
CRNLIB_ASSERT(status);
status;
(void)status;
m_update_cycle = (5 * m_update_cycle) >> 2;
uint max_cycle = (m_total_syms + 6) << 3; // this was << 2 - which is ~12% slower but compresses around .5% better
@@ -488,8 +488,7 @@ void adaptive_arith_data_model::clear() {
m_probs.clear();
}
void adaptive_arith_data_model::init(bool encoding, uint total_syms) {
encoding;
void adaptive_arith_data_model::init(bool, uint total_syms) {
if (!total_syms) {
clear();
return;
+2 -4
View File
@@ -174,7 +174,7 @@ class adaptive_arith_data_model {
friend class symbol_codec;
};
#if (defined(_XBOX) || defined(_WIN64))
#if defined(_WIN64)
#define CRNLIB_SYMBOL_CODEC_USE_64_BIT_BUFFER 1
#else
#define CRNLIB_SYMBOL_CODEC_USE_64_BIT_BUFFER 0
@@ -311,9 +311,7 @@ class symbol_codec {
#define CRNLIB_SYMBOL_CODEC_USE_MACROS 1
#ifdef _XBOX
#define CRNLIB_READ_BIG_ENDIAN_UINT32(p) *reinterpret_cast<const uint32*>(p)
#elif defined(_MSC_VER)
#if defined(_MSC_VER)
#define CRNLIB_READ_BIG_ENDIAN_UINT32(p) _byteswap_ulong(*reinterpret_cast<const uint32*>(p))
#else
#define CRNLIB_READ_BIG_ENDIAN_UINT32(p) utils::swap32(*reinterpret_cast<const uint32*>(p))
+1 -3
View File
@@ -273,9 +273,7 @@ class threaded_clusterizer {
compute_division(axis, centroid, vecs, indices, left_indices, right_indices);
}
static bool generate_codebook_dummy_progress_callback(uint percentage_completed, void* pData) {
percentage_completed;
static bool generate_codebook_dummy_progress_callback(uint, void* pData) {
if (static_cast<threaded_clusterizer*>(pData)->m_canceled)
return false;
+2 -5
View File
@@ -36,8 +36,7 @@ void threaded_resampler::free_contrib_lists() {
}
}
void threaded_resampler::resample_x_task(uint64 data, void* pData_ptr) {
pData_ptr;
void threaded_resampler::resample_x_task(uint64 data, void*) {
const uint thread_index = (uint)data;
for (uint src_y = 0; src_y < m_pParams->m_src_height; src_y++) {
@@ -138,9 +137,7 @@ void threaded_resampler::resample_x_task(uint64 data, void* pData_ptr) {
}
}
void threaded_resampler::resample_y_task(uint64 data, void* pData_ptr) {
pData_ptr;
void threaded_resampler::resample_y_task(uint64 data, void*) {
const uint thread_index = (uint)data;
crnlib::vector<vec4F> tmp(m_pParams->m_dst_width);
+1 -1
View File
@@ -46,7 +46,7 @@ class timed_scope {
timer m_tm;
public:
inline timed_scope(char* pName = "timed_scope")
inline timed_scope(const char* pName = "timed_scope")
: m_pName(pName) { m_tm.start(); }
inline double get_elapsed_secs() const { return m_tm.get_elapsed_secs(); }
+4 -4
View File
@@ -63,8 +63,8 @@ struct scalar_type<T*> {
static inline void construct(T** p) { memset(p, 0, sizeof(T*)); }
static inline void construct(T** p, T* init) { *p = init; }
static inline void construct_array(T** p, uint n) { memset(p, 0, sizeof(T*) * n); }
static inline void destruct(T** p) { p; }
static inline void destruct_array(T** p, uint n) { p, n; }
static inline void destruct(T**) {}
static inline void destruct_array(T**, uint) {}
};
#define CRNLIB_DEFINE_BUILT_IN_TYPE(X) \
@@ -74,8 +74,8 @@ struct scalar_type<T*> {
static inline void construct(X* p) { memset(p, 0, sizeof(X)); } \
static inline void construct(X* p, const X& init) { memcpy(p, &init, sizeof(X)); } \
static inline void construct_array(X* p, uint n) { memset(p, 0, sizeof(X) * n); } \
static inline void destruct(X* p) { p; } \
static inline void destruct_array(X* p, uint n) { p, n; } \
static inline void destruct(X*) {} \
static inline void destruct_array(X*, uint) {} \
};
CRNLIB_DEFINE_BUILT_IN_TYPE(bool)
-3
View File
@@ -377,10 +377,7 @@ class tree_clusterizer {
new_right_child *= (1.0f / right_weight);
left_child = new_left_child;
left_weight = left_weight;
right_child = new_right_child;
right_weight = right_weight;
float total_variance = left_variance + right_variance;
if (total_variance < .00001f)
+3 -3
View File
@@ -748,9 +748,9 @@ struct scalar_type<vec<N, T> > {
enum { cFlag = true };
static inline void construct(vec<N, T>* p) {}
static inline void construct(vec<N, T>* p, const vec<N, T>& init) { memcpy(p, &init, sizeof(vec<N, T>)); }
static inline void construct_array(vec<N, T>* p, uint n) { p, n; }
static inline void destruct(vec<N, T>* p) { p; }
static inline void destruct_array(vec<N, T>* p, uint n) { p, n; }
static inline void construct_array(vec<N, T>*, uint) {}
static inline void destruct(vec<N, T>*) {}
static inline void destruct_array(vec<N, T>*, uint) {}
};
} // namespace crnlib
+2 -4
View File
@@ -14,13 +14,11 @@
#include "crn_rg_etc1.h"
namespace crnlib {
static void* realloc_func(void* p, size_t size, size_t* pActual_size, bool movable, void* pUser_data) {
pUser_data;
static void* realloc_func(void* p, size_t size, size_t* pActual_size, bool movable, void*) {
return crnlib_realloc(p, size, pActual_size, movable);
}
static size_t msize_func(void* p, void* pUser_data) {
pUser_data;
static size_t msize_func(void* p, void*) {
return crnlib_msize(p);
}
+34 -59
View File
@@ -64,16 +64,6 @@ enum eClear { cClear };
const uint32 cIntBits = 32U;
#ifdef _WIN64
typedef uint64 ptr_bits;
#else
#ifdef __x86_64__
typedef uint64 ptr_bits;
#else
typedef uint32 ptr_bits;
#endif
#endif
template <typename T>
struct int_traits {
enum { cMin = crnd::cINT32_MIN,
@@ -190,7 +180,6 @@ void construct_array(T* p, uint32 n, const U& init) {
template <typename T>
inline void destruct(T* p) {
p;
p->~T();
}
@@ -223,8 +212,8 @@ struct scalar_type<T*> {
static inline void construct(T** p) { memset(p, 0, sizeof(T*)); }
static inline void construct(T** p, T* init) { *p = init; }
static inline void construct_array(T** p, uint32 n) { memset(p, 0, sizeof(T*) * n); }
static inline void destruct(T** p) { p; }
static inline void destruct_array(T** p, uint32 n) { p, n; }
static inline void destruct(T**) {}
static inline void destruct_array(T**, uint32) {}
};
#define CRND_DEFINE_BUILT_IN_TYPE(X) \
@@ -234,8 +223,8 @@ struct scalar_type<T*> {
static inline void construct(X* p) { memset(p, 0, sizeof(X)); } \
static inline void construct(X* p, const X& init) { memcpy(p, &init, sizeof(X)); } \
static inline void construct_array(X* p, uint32 n) { memset(p, 0, sizeof(X) * n); } \
static inline void destruct(X* p) { p; } \
static inline void destruct_array(X* p, uint32 n) { p, n; } \
static inline void destruct(X*) {} \
static inline void destruct_array(X*, uint32) {} \
};
CRND_DEFINE_BUILT_IN_TYPE(bool)
@@ -355,9 +344,7 @@ template <typename T>
inline void crnd_delete_array(T* p) {
if (p) {
const uint32 num = reinterpret_cast<uint32*>(p)[-1];
const uint32 num_check = reinterpret_cast<uint32*>(p)[-2];
num_check;
CRND_ASSERT(num && (num == ~num_check));
CRND_ASSERT(num && (num == ~reinterpret_cast<uint32*>(p)[-2]));
helpers::destruct_array(p, num);
@@ -830,7 +817,7 @@ extern void vector_test();
// File: crnd_private.h
namespace crnd {
const crn_header* crnd_get_header(crn_header& header, const void* pData, uint32 data_size);
const crn_header* crnd_get_header(const void* pData, uint32 data_size);
} // namespace crnd
@@ -1917,7 +1904,7 @@ void crnd_debug_break() {
}
void crnd_output_debug_string(const char* p) {
p;
(void)p;
#ifdef CRND_DEVEL
OutputDebugStringA(p);
#endif
@@ -1929,9 +1916,7 @@ void crnd_output_debug_string(const char* p) {
namespace crnd {
const uint32 MAX_POSSIBLE_BLOCK_SIZE = 0x7FFF0000U;
static void* crnd_default_realloc(void* p, size_t size, size_t* pActual_size, bool movable, void* pUser_data) {
pUser_data;
static void* crnd_default_realloc(void* p, size_t size, size_t* pActual_size, bool movable, void*) {
void* p_new;
if (!p) {
@@ -2029,13 +2014,13 @@ void* crnd_malloc(size_t size, size_t* pActual_size) {
return NULL;
}
CRND_ASSERT(((uint32)p_new & (CRND_MIN_ALLOC_ALIGNMENT - 1)) == 0);
CRND_ASSERT(((uint32) reinterpret_cast<uintptr_t>(p_new) & (CRND_MIN_ALLOC_ALIGNMENT - 1)) == 0);
return p_new;
}
void* crnd_realloc(void* p, size_t size, size_t* pActual_size, bool movable) {
if ((uint32) reinterpret_cast<ptr_bits>(p) & (CRND_MIN_ALLOC_ALIGNMENT - 1)) {
if ((uint32) reinterpret_cast<uintptr_t>(p) & (CRND_MIN_ALLOC_ALIGNMENT - 1)) {
crnd_mem_error("crnd_realloc: bad ptr");
return NULL;
}
@@ -2051,7 +2036,7 @@ void* crnd_realloc(void* p, size_t size, size_t* pActual_size, bool movable) {
if (pActual_size)
*pActual_size = actual_size;
CRND_ASSERT(((uint32)p_new & (CRND_MIN_ALLOC_ALIGNMENT - 1)) == 0);
CRND_ASSERT(((uint32) reinterpret_cast<uintptr_t>(p_new) & (CRND_MIN_ALLOC_ALIGNMENT - 1)) == 0);
return p_new;
}
@@ -2060,7 +2045,7 @@ void crnd_free(void* p) {
if (!p)
return;
if ((uint32) reinterpret_cast<ptr_bits>(p) & (CRND_MIN_ALLOC_ALIGNMENT - 1)) {
if ((uint32) reinterpret_cast<uintptr_t>(p) & (CRND_MIN_ALLOC_ALIGNMENT - 1)) {
crnd_mem_error("crnd_free: bad ptr");
return;
}
@@ -2072,7 +2057,7 @@ size_t crnd_msize(void* p) {
if (!p)
return 0;
if ((uint32) reinterpret_cast<ptr_bits>(p) & (CRND_MIN_ALLOC_ALIGNMENT - 1)) {
if ((uint32) reinterpret_cast<uintptr_t>(p) & (CRND_MIN_ALLOC_ALIGNMENT - 1)) {
crnd_mem_error("crnd_msize: bad ptr");
return 0;
}
@@ -2180,9 +2165,7 @@ uint32 crnd_get_bytes_per_dxt_block(crn_format fmt) {
}
// TODO: tmp_header isn't used/This function is a helper to support old headers.
const crn_header* crnd_get_header(crn_header& tmp_header, const void* pData, uint32 data_size) {
tmp_header;
const crn_header* crnd_get_header(const void* pData, uint32 data_size) {
if ((!pData) || (data_size < sizeof(crn_header)))
return NULL;
@@ -2207,8 +2190,7 @@ bool crnd_validate_file(const void* pData, uint32 data_size, crn_file_info* pFil
if ((!pData) || (data_size < cCRNHeaderMinSize))
return false;
crn_header tmp_header;
const crn_header* pHeader = crnd_get_header(tmp_header, pData, data_size);
const crn_header* pHeader = crnd_get_header(pData, data_size);
if (!pHeader)
return false;
@@ -2268,8 +2250,7 @@ bool crnd_get_texture_info(const void* pData, uint32 data_size, crn_texture_info
if (pInfo->m_struct_size != sizeof(crn_texture_info))
return false;
crn_header tmp_header;
const crn_header* pHeader = crnd_get_header(tmp_header, pData, data_size);
const crn_header* pHeader = crnd_get_header(pData, data_size);
if (!pHeader)
return false;
@@ -2292,8 +2273,7 @@ bool crnd_get_level_info(const void* pData, uint32 data_size, uint32 level_index
if (pLevel_info->m_struct_size != sizeof(crn_level_info))
return false;
crn_header tmp_header;
const crn_header* pHeader = crnd_get_header(tmp_header, pData, data_size);
const crn_header* pHeader = crnd_get_header(pData, data_size);
if (!pHeader)
return false;
@@ -2321,8 +2301,7 @@ const void* crnd_get_level_data(const void* pData, uint32 data_size, uint32 leve
if ((!pData) || (data_size < cCRNHeaderMinSize))
return NULL;
crn_header tmp_header;
const crn_header* pHeader = crnd_get_header(tmp_header, pData, data_size);
const crn_header* pHeader = crnd_get_header(pData, data_size);
if (!pHeader)
return NULL;
@@ -2346,8 +2325,7 @@ uint32 crnd_get_segmented_file_size(const void* pData, uint32 data_size) {
if ((!pData) || (data_size < cCRNHeaderMinSize))
return false;
crn_header tmp_header;
const crn_header* pHeader = crnd_get_header(tmp_header, pData, data_size);
const crn_header* pHeader = crnd_get_header(pData, data_size);
if (!pHeader)
return false;
@@ -2366,8 +2344,7 @@ bool crnd_create_segmented_file(const void* pData, uint32 data_size, void* pBase
if ((!pData) || (data_size < cCRNHeaderMinSize))
return false;
crn_header tmp_header;
const crn_header* pHeader = crnd_get_header(tmp_header, pData, data_size);
const crn_header* pHeader = crnd_get_header(pData, data_size);
if (!pHeader)
return false;
@@ -2971,7 +2948,7 @@ class crn_unpacker {
inline bool is_valid() const { return m_magic == cMagicValue; }
bool init(const void* pData, uint32 data_size) {
m_pHeader = crnd_get_header(m_tmp_header, pData, data_size);
m_pHeader = crnd_get_header(pData, data_size);
if (!m_pHeader)
return false;
@@ -3005,7 +2982,6 @@ class crn_unpacker {
const void* pSrc, uint32 src_size_in_bytes,
void** pDst, uint32 dst_size_in_bytes, uint32 row_pitch_in_bytes,
uint32 level_index) {
dst_size_in_bytes;
#ifdef CRND_BUILD_DEBUG
for (uint32 f = 0; f < m_pHeader->m_faces; f++)
@@ -3077,7 +3053,6 @@ class crn_unpacker {
const uint8* m_pData;
uint32 m_data_size;
crn_header m_tmp_header;
const crn_header* m_pHeader;
symbol_codec m_codec;
@@ -3198,16 +3173,16 @@ class crn_unpacker {
for (uint32 j = 0; j < 32; j += 4)
s ^= m_codec.decode(dm) << j;
if (has_etc_color_blocks) {
for (uint32 selector = ~s & 0xAAAAAAAA | ~(s ^ s >> 1) & 0x55555555, t = 8, h = 0; h < 4; h++, t -= 15) {
for (uint32 selector = (~s & 0xAAAAAAAA) | (~(s ^ s >> 1) & 0x55555555), t = 8, h = 0; h < 4; h++, t -= 15) {
for (uint32 w = 0; w < 4; w++, t += 4) {
uint32 s0 = selector >> (w << 3 | h << 1);
m_color_selectors[i << 1] |= (s0 >> 1 & 1 | (s0 & 1) << 16) << (t & 15);
m_color_selectors[i << 1] |= ((s0 >> 1 & 1) | (s0 & 1) << 16) << (t & 15);
uint32 s1 = selector >> (h << 3 | w << 1);
m_color_selectors[i << 1 | 1] |= (s1 >> 1 & 1 | (s1 & 1) << 16) << (t & 15);
m_color_selectors[i << 1 | 1] |= ((s1 >> 1 & 1) | (s1 & 1) << 16) << (t & 15);
}
}
} else {
m_color_selectors[i] = (s ^ s << 1) & 0xAAAAAAAA | s >> 1 & 0x55555555;
m_color_selectors[i] = ((s ^ s << 1) & 0xAAAAAAAA) | (s >> 1 & 0x55555555);
}
}
m_codec.stop_decoding();
@@ -3271,7 +3246,7 @@ class crn_unpacker {
uint8 s_linear[8] = {};
uint8* data = (uint8*)m_alpha_selectors.begin();
for (uint i = 0; i < m_alpha_selectors.size(); i += 6, data += 12) {
for (uint s_group, p = 0; p < 16; p++) {
for (uint s_group = 0, p = 0; p < 16; p++) {
s_group = p & 1 ? s_group >> 3 : s_linear[p >> 1] ^= m_codec.decode(dm);
uint8 s = s_group & 7;
if (s <= 3)
@@ -3279,13 +3254,13 @@ class crn_unpacker {
uint8 d = 3 * (p + 1);
uint8 byte_offset = d >> 3;
uint8 bit_offset = d & 7;
data[byte_offset] |= s << 8 - bit_offset;
data[byte_offset] |= s << (8 - bit_offset);
if (bit_offset < 3)
data[byte_offset - 1] |= s >> bit_offset;
d += 9 * ((p & 3) - (p >> 2));
byte_offset = d >> 3;
bit_offset = d & 7;
data[byte_offset + 6] |= s << 8 - bit_offset;
data[byte_offset + 6] |= s << (8 - bit_offset);
if (bit_offset < 3)
data[byte_offset + 5] |= s >> bit_offset;
}
@@ -3573,8 +3548,8 @@ class crn_unpacker {
endpoint_reference = buffer.endpoint_reference;
} else {
reference_group = m_codec.decode(m_reference_encoding_dm);
endpoint_reference = reference_group & 3 | reference_group >> 2 & 12;
buffer.endpoint_reference = reference_group >> 2 & 3 | reference_group >> 4 & 12;
endpoint_reference = (reference_group & 3) | (reference_group >> 2 & 12);
buffer.endpoint_reference = (reference_group >> 2 & 3) | (reference_group >> 4 & 12);
}
if (!(endpoint_reference & 3)) {
color_endpoint_index += m_codec.decode(m_endpoint_delta_dm[0]);
@@ -3604,7 +3579,7 @@ class crn_unpacker {
for (uint c = 0; diff && c < 3; c++)
diff = e0[c] + 3 >= e1[c] && e1[c] + 4 >= e0[c] ? diff : 0;
for (uint c = 0; c < 3; c++)
block_endpoint[c] = diff ? e0[c] << 3 | e1[c] - e0[c] & 7 : e0[c] << 3 & 0xF0 | e1[c] >> 1;
block_endpoint[c] = diff ? e0[c] << 3 | ((e1[c] - e0[c]) & 7) : (e0[c] << 3 & 0xF0) | e1[c] >> 1;
block_endpoint[3] = e0[3] << 5 | e1[3] << 2 | diff << 1 | flip;
pData[0] = *(uint32*)&block_endpoint;
pData[1] = m_color_selectors[selector_index << 1 | flip];
@@ -3640,8 +3615,8 @@ class crn_unpacker {
endpoint_reference = buffer.endpoint_reference;
} else {
reference_group = m_codec.decode(m_reference_encoding_dm);
endpoint_reference = reference_group & 3 | reference_group >> 2 & 12;
buffer.endpoint_reference = reference_group >> 2 & 3 | reference_group >> 4 & 12;
endpoint_reference = (reference_group & 3) | (reference_group >> 2 & 12);
buffer.endpoint_reference = (reference_group >> 2 & 3) | (reference_group >> 4 & 12);
}
if (!(endpoint_reference & 3)) {
color_endpoint_index += m_codec.decode(m_endpoint_delta_dm[0]);
@@ -3681,7 +3656,7 @@ class crn_unpacker {
for (uint c = 0; diff && c < 3; c++)
diff = e0[c] + 3 >= e1[c] && e1[c] + 4 >= e0[c] ? diff : 0;
for (uint c = 0; c < 3; c++)
block_endpoint[c] = diff ? e0[c] << 3 | e1[c] - e0[c] & 7 : e0[c] << 3 & 0xF0 | e1[c] >> 1;
block_endpoint[c] = diff ? e0[c] << 3 | ((e1[c] - e0[c]) & 7) : (e0[c] << 3 & 0xF0) | e1[c] >> 1;
block_endpoint[3] = e0[3] << 5 | e1[3] << 2 | diff << 1 | flip;
const uint16* pAlpha0_selectors = &m_alpha_selectors[alpha0_selector_index * 6 + (flip ? 3 : 0)];
pData[0] = m_alpha_endpoints[alpha0_endpoint_index] | pAlpha0_selectors[0] << 16;