eee6b26e5d
This change significantly improves compression speed. Explanation: The main ideas used for the endpoint and selector sorting optimization: - unpacked color and alpha endpoints can be cached - pixel selectors can be processed in groups, while the intermediate error results for those groups can be precalculated - instead of maintaining the mask of the processed elements, the remaining elements can be reorganized to form a continuous block on each iteration (the last remaining element is moved into the position of the processed element) - after optimization, endpoint sorting works significantly faster than endpoint reordering, so the overall performance can be improved by moving selector optimization into the endpoint sorting thread 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. [Compressing Kodak set without mipmaps] Original: 1582222 bytes / 28.863 sec Modified: 1482780 bytes / 14.564 sec Improvement: 6.28% (compression ratio) / 49.54% (compression time) [Compressing Kodak set with mipmaps] Original: 2065243 bytes / 36.968 sec Modified: 1931586 bytes / 19.717 sec Improvement: 6.47% (compression ratio) / 46.66% (compression time)
123 lines
3.9 KiB
C++
123 lines
3.9 KiB
C++
// File: crn_comp.h
|
|
// See Copyright Notice and license at the end of inc/crnlib.h
|
|
#pragma once
|
|
|
|
#include "../inc/crn_defs.h"
|
|
|
|
#include "../inc/crnlib.h"
|
|
#include "crn_symbol_codec.h"
|
|
#include "crn_dxt_hc.h"
|
|
#include "crn_image.h"
|
|
#include "crn_image_utils.h"
|
|
#include "crn_texture_comp.h"
|
|
|
|
namespace crnlib {
|
|
class crn_comp : public itexture_comp {
|
|
CRNLIB_NO_COPY_OR_ASSIGNMENT_OP(crn_comp);
|
|
|
|
public:
|
|
crn_comp();
|
|
virtual ~crn_comp();
|
|
|
|
virtual const char* get_ext() const { return "CRN"; }
|
|
|
|
virtual bool compress_init(const crn_comp_params& params);
|
|
virtual bool compress_pass(const crn_comp_params& params, float* pEffective_bitrate);
|
|
virtual void compress_deinit();
|
|
|
|
virtual const crnlib::vector<uint8>& get_comp_data() const { return m_comp_data; }
|
|
virtual crnlib::vector<uint8>& get_comp_data() { return m_comp_data; }
|
|
|
|
uint get_comp_data_size() const { return m_comp_data.size(); }
|
|
const uint8* get_comp_data_ptr() const { return m_comp_data.size() ? &m_comp_data[0] : NULL; }
|
|
|
|
private:
|
|
task_pool m_task_pool;
|
|
const crn_comp_params* m_pParams;
|
|
|
|
image_u8 m_images[cCRNMaxFaces][cCRNMaxLevels];
|
|
|
|
enum comp {
|
|
cColor,
|
|
cAlpha0,
|
|
cAlpha1,
|
|
cNumComps
|
|
};
|
|
|
|
bool m_has_comp[cNumComps];
|
|
|
|
struct level_details {
|
|
uint first_block;
|
|
uint num_blocks;
|
|
uint block_width;
|
|
};
|
|
crnlib::vector<level_details> m_levels;
|
|
|
|
uint m_total_blocks;
|
|
crnlib::vector<uint32> m_color_endpoints;
|
|
crnlib::vector<uint32> m_alpha_endpoints;
|
|
crnlib::vector<uint32> m_color_selectors;
|
|
crnlib::vector<uint64> m_alpha_selectors;
|
|
crnlib::vector<dxt_hc::endpoint_indices_details> m_endpoint_indices;
|
|
crnlib::vector<dxt_hc::selector_indices_details> m_selector_indices;
|
|
|
|
crnd::crn_header m_crn_header;
|
|
crnlib::vector<uint8> m_comp_data;
|
|
|
|
dxt_hc m_hvq;
|
|
|
|
symbol_histogram m_reference_hist;
|
|
static_huffman_data_model m_reference_dm;
|
|
|
|
crnlib::vector<uint16> m_endpoint_remaping[2];
|
|
symbol_histogram m_endpoint_index_hist[2];
|
|
static_huffman_data_model m_endpoint_index_dm[2];
|
|
|
|
crnlib::vector<uint16> m_selector_remaping[2];
|
|
symbol_histogram m_selector_index_hist[2];
|
|
static_huffman_data_model m_selector_index_dm[2];
|
|
|
|
crnlib::vector<uint8> m_packed_blocks[cCRNMaxLevels];
|
|
crnlib::vector<uint8> m_packed_data_models;
|
|
crnlib::vector<uint8> m_packed_color_endpoints;
|
|
crnlib::vector<uint8> m_packed_color_selectors;
|
|
crnlib::vector<uint8> m_packed_alpha_endpoints;
|
|
crnlib::vector<uint8> m_packed_alpha_selectors;
|
|
|
|
bool pack_color_endpoints(crnlib::vector<uint8>& packed_data, const crnlib::vector<uint16>& remapping);
|
|
bool pack_color_selectors(crnlib::vector<uint8>& packed_data, const crnlib::vector<uint16>& remapping);
|
|
bool pack_alpha_endpoints(crnlib::vector<uint8>& packed_data, const crnlib::vector<uint16>& remapping);
|
|
bool pack_alpha_selectors(crnlib::vector<uint8>& packed_data, const crnlib::vector<uint16>& remapping);
|
|
bool pack_blocks(
|
|
uint group,
|
|
bool clear_histograms,
|
|
symbol_codec* pCodec,
|
|
const crnlib::vector<uint16>* pColor_endpoint_remap,
|
|
const crnlib::vector<uint16>* pColor_selector_remap,
|
|
const crnlib::vector<uint16>* pAlpha_endpoint_remap,
|
|
const crnlib::vector<uint16>* pAlpha_selector_remap
|
|
);
|
|
|
|
bool alias_images();
|
|
void clear();
|
|
bool quantize_images();
|
|
|
|
void optimize_color_endpoints_task(uint64 data, void* pData_ptr);
|
|
void optimize_color_selectors();
|
|
void optimize_color();
|
|
|
|
void optimize_alpha_endpoints_task(uint64 data, void* pData_ptr);
|
|
void optimize_alpha_selectors();
|
|
void optimize_alpha();
|
|
|
|
bool pack_data_models();
|
|
static void append_vec(crnlib::vector<uint8>& a, const void* p, uint size);
|
|
static void append_vec(crnlib::vector<uint8>& a, const crnlib::vector<uint8>& b);
|
|
bool create_comp_data();
|
|
|
|
bool update_progress(uint phase_index, uint subphase_index, uint subphase_total);
|
|
bool compress_internal();
|
|
};
|
|
|
|
} // namespace crnlib
|