diff --git a/bin/crunch_x64.exe b/bin/crunch_x64.exe index 460ee76..33eba9a 100644 Binary files a/bin/crunch_x64.exe and b/bin/crunch_x64.exe differ diff --git a/crnlib/crn_comp.cpp b/crnlib/crn_comp.cpp index 98ef8f3..de1d83b 100644 --- a/crnlib/crn_comp.cpp +++ b/crnlib/crn_comp.cpp @@ -191,7 +191,7 @@ bool crn_comp::pack_color_selectors(crnlib::vector& packed_data, const cr for (uint selector_index = 0; selector_index < m_color_selectors.size(); selector_index++) { uint32 cur_selector = remapped_selectors[selector_index]; uint prev_sym = 0; - for (uint32 selector = cur_selector, s = m_pParams->m_format == cCRNFmtETC1 ? 8 : 16, i = 0; i < s; i++, selector >>= 2, prev_selector >>= 2) { + for (uint32 selector = cur_selector, i = 0; i < 16; i++, selector >>= 2, prev_selector >>= 2) { int sym = 3 + (selector & 3) - (prev_selector & 3); if (i & 1) { uint paired_sym = 7 * sym + prev_sym; @@ -337,7 +337,7 @@ bool crn_comp::pack_blocks( } } for (uint c = 0; c < cNumComps; c++) { - if (selector_remap[c]) { + if (selector_remap[c] && (m_pParams->m_format != cCRNFmtETC1 || !(bx & 1))) { uint index = (*selector_remap[c])[m_selector_indices[b].component[c]]; if (!pCodec) m_selector_index_hist[c ? 1 : 0].inc_freq(index); @@ -458,12 +458,12 @@ bool crn_comp::quantize_images() { } else if (m_pParams->m_format == cCRNFmtDXT5) { color_quality_power_mul = .75f; } else if (m_pParams->m_format == cCRNFmtETC1) { - color_quality_power_mul = 1.6f; + color_quality_power_mul = 1.28f; params.m_adaptive_tile_color_psnr_derating = 5.0f; } float color_endpoint_quality = powf(quality, 1.8f * color_quality_power_mul); - float color_selector_quality = powf(quality, 1.65f * color_quality_power_mul * (m_pParams->m_format == cCRNFmtETC1 ? 2 : 1)); + float color_selector_quality = powf(quality, 1.65f * color_quality_power_mul); params.m_color_endpoint_codebook_size = math::clamp(math::float_to_uint(.5f + math::lerp(math::maximum(64, cCRNMinPaletteSize), (float)max_codebook_entries, color_endpoint_quality)), cCRNMinPaletteSize, cCRNMaxPaletteSize); params.m_color_selector_codebook_size = math::clamp(math::float_to_uint(.5f + math::lerp(math::maximum(96, cCRNMinPaletteSize), (float)max_codebook_entries, color_selector_quality)), cCRNMinPaletteSize, cCRNMaxPaletteSize); diff --git a/crnlib/crn_dxt_hc.cpp b/crnlib/crn_dxt_hc.cpp index 427820c..f7c7f09 100644 --- a/crnlib/crn_dxt_hc.cpp +++ b/crnlib/crn_dxt_hc.cpp @@ -839,12 +839,12 @@ void dxt_hc::create_color_selector_codebook_task(uint64 data, void* pData_ptr) { uint E2[16][4]; uint E4[8][16]; uint E8[4][256]; - for (uint b = m_num_blocks * data / num_tasks, bEnd = m_num_blocks * (data + 1) / num_tasks; b < bEnd; b++) { + for (uint n = m_params.m_format == cETC1 ? m_num_blocks >> 1 : m_num_blocks, b = n * data / num_tasks, bEnd = n * (data + 1) / num_tasks; b < bEnd; b++) { color_cluster& cluster = m_color_clusters[m_endpoint_indices[b].color]; color_quad_u8* endpoint_colors = cluster.color_values; for (uint p = 0; p < 16; p++) { for (uint s = 0; s < 4; s++) - E2[p][s] = m_params.m_format == cETC1 ? p & 8 ? 0 : color::color_distance(m_params.m_perceptual, ((color_quad_u8(*)[8])m_blocks)[b][p], endpoint_colors[s], false) : + E2[p][s] = m_params.m_format == cETC1 ? color::color_distance(m_params.m_perceptual, m_blocks[b][p], m_color_clusters[m_endpoint_indices[b << 1 | p >> 3].color].color_values[s], false) : color::color_distance(m_params.m_perceptual, m_blocks[b][p], endpoint_colors[s], false); } for (uint p = 0; p < 8; p++) { @@ -870,18 +870,18 @@ void dxt_hc::create_color_selector_codebook_task(uint64 data, void* pData_ptr) { total_errors[p][s] += E2[p][s]; } selector_details[best_index].used = true; - m_selector_indices[b].color = best_index; + m_selector_indices[m_params.m_format == cETC1 ? b << 1 : b].color = best_index; } } void dxt_hc::create_color_selector_codebook() { tree_clusterizer selector_vq; vec16F v; - for (uint b = 0; b < m_num_blocks; b++) { - uint64 selector = m_block_selectors[cColor][b]; + for (uint n = m_params.m_format == cETC1 ? m_num_blocks >> 1 : m_num_blocks, b = 0; b < n; b++) { + uint64 selector = m_params.m_format == cETC1 ? m_block_selectors[cColor][b << 1] | m_block_selectors[cColor][b << 1 | 1] << 16 : m_block_selectors[cColor][b]; for (uint8 p = 0; p < 16; p++, selector >>= 2) v[p] = ((selector & 3) + 0.5f) * 0.25f; - selector_vq.add_training_vec(v, selector); + selector_vq.add_training_vec(v, m_params.m_format == cETC1 ? (selector & 0xFFFF) + (selector >> 16) : selector); } selector_vq.generate_codebook(m_params.m_color_selector_codebook_size); m_color_selectors.resize(selector_vq.get_codebook_size()); diff --git a/inc/crn_decomp.h b/inc/crn_decomp.h index e0396e5..ed96227 100644 --- a/inc/crn_decomp.h +++ b/inc/crn_decomp.h @@ -3211,8 +3211,8 @@ class crn_unpacker { const uint8* pFrom_linear = m_pHeader->m_format == cCRNFmtETC1 ? g_etc1_from_linear : g_dxt1_from_linear; - for (uint32 s = m_pHeader->m_format == cCRNFmtETC1 ? 4 : 8, i = 0; i < num_color_selectors; i++) { - for (uint32 j = 0; j < s; j++) { + for (uint32 i = 0; i < num_color_selectors; i++) { + for (uint32 j = 0; j < 8; j++) { int32 sym = m_codec.decode(dm); cur[j * 2 + 0] = (delta0[sym] + cur[j * 2 + 0]) & 3; cur[j * 2 + 1] = (delta1[sym] + cur[j * 2 + 1]) & 3; @@ -3603,14 +3603,13 @@ class crn_unpacker { if (color_endpoint_index >= num_color_endpoints) color_endpoint_index -= num_color_endpoints; *(uint32*)&e0 = m_color_endpoints[color_endpoint_index]; - uint32 selector = m_color_selectors[m_codec.decode(m_selector_delta_dm[0])] & 0xFFFF; + uint32 selector = m_color_selectors[m_codec.decode(m_selector_delta_dm[0])]; if (endpoint_reference) { color_endpoint_index += m_codec.decode(m_endpoint_delta_dm[0]); if (color_endpoint_index >= num_color_endpoints) color_endpoint_index -= num_color_endpoints; } *(uint32*)&e1 = m_color_endpoints[color_endpoint_index]; - selector |= m_color_selectors[m_codec.decode(m_selector_delta_dm[0])] << 16; if (visible) { uint32 block_selector = 0, flip = endpoint_reference >> 1 ^ 1, diff = 1; for (uint32 t = 8, i = 0; i < 4; i++, t -= 15) {