5822475b22
This change slightly improves compression speed and simplifies further modification of the code. Explanation: Additional performance boost is achieved by using linear representation for selectors and storing block selectors in a single uint32/uint64. 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.927 sec Modified: 1494501 bytes / 17.301 sec Improvement: 5.54% (compression ratio) / 40.19% (compression time) [Compressing Kodak set with mipmaps] Original: 2065243 bytes / 36.992 sec Modified: 1945365 bytes / 22.548 sec Improvement: 5.80% (compression ratio) / 39.05% (compression time)
206 lines
5.7 KiB
C++
206 lines
5.7 KiB
C++
// File: crn_dxt_hc.h
|
|
// See Copyright Notice and license at the end of inc/crnlib.h
|
|
#pragma once
|
|
#include "crn_dxt1.h"
|
|
#include "crn_dxt5a.h"
|
|
#include "crn_dxt_endpoint_refiner.h"
|
|
#include "crn_image.h"
|
|
#include "crn_dxt.h"
|
|
#include "crn_image.h"
|
|
#include "crn_dxt_hc_common.h"
|
|
#include "crn_tree_clusterizer.h"
|
|
#include "crn_threading.h"
|
|
|
|
#define CRN_NO_FUNCTION_DEFINITIONS
|
|
#include "../inc/crnlib.h"
|
|
|
|
namespace crnlib {
|
|
const uint cTotalCompressionPhases = 25;
|
|
|
|
class dxt_hc {
|
|
public:
|
|
dxt_hc();
|
|
~dxt_hc();
|
|
|
|
struct endpoint_indices_details {
|
|
union {
|
|
struct {
|
|
uint16 color;
|
|
uint16 alpha0;
|
|
uint16 alpha1;
|
|
};
|
|
uint16 component[3];
|
|
};
|
|
uint8 reference;
|
|
};
|
|
|
|
struct selector_indices_details {
|
|
union {
|
|
struct {
|
|
uint16 color;
|
|
uint16 alpha0;
|
|
uint16 alpha1;
|
|
};
|
|
uint16 component[3];
|
|
};
|
|
};
|
|
|
|
struct tile_details {
|
|
crnlib::vector<color_quad_u8> pixels;
|
|
float weight;
|
|
vec<6, float> color_endpoint;
|
|
vec<2, float> alpha_endpoints[2];
|
|
uint16 cluster_indices[3];
|
|
};
|
|
crnlib::vector<tile_details> m_tiles;
|
|
uint m_num_tiles;
|
|
float m_color_derating[cCRNMaxLevels][8];
|
|
float m_alpha_derating[8];
|
|
float m_uint8_to_float[256];
|
|
|
|
color_quad_u8 (*m_blocks)[16];
|
|
uint m_num_blocks;
|
|
crnlib::vector<float> m_block_weights;
|
|
crnlib::vector<uint8> m_block_encodings;
|
|
crnlib::vector<uint64> m_block_selectors[3];
|
|
crnlib::vector<uint32> m_color_selectors;
|
|
crnlib::vector<uint64> m_alpha_selectors;
|
|
crnlib::vector<bool> m_color_selectors_used;
|
|
crnlib::vector<bool> m_alpha_selectors_used;
|
|
crnlib::vector<uint> m_tile_indices;
|
|
crnlib::vector<endpoint_indices_details> m_endpoint_indices;
|
|
crnlib::vector<selector_indices_details> m_selector_indices;
|
|
|
|
struct params {
|
|
params()
|
|
: m_num_blocks(0),
|
|
m_num_levels(0),
|
|
m_num_faces(0),
|
|
m_format(cDXT1),
|
|
m_perceptual(true),
|
|
m_hierarchical(true),
|
|
m_color_endpoint_codebook_size(3072),
|
|
m_color_selector_codebook_size(3072),
|
|
m_alpha_endpoint_codebook_size(3072),
|
|
m_alpha_selector_codebook_size(3072),
|
|
m_adaptive_tile_color_psnr_derating(2.0f),
|
|
m_adaptive_tile_alpha_psnr_derating(2.0f),
|
|
m_adaptive_tile_color_alpha_weighting_ratio(3.0f),
|
|
m_debugging(false),
|
|
m_pProgress_func(0),
|
|
m_pProgress_func_data(0) {
|
|
m_alpha_component_indices[0] = 3;
|
|
m_alpha_component_indices[1] = 0;
|
|
for (uint i = 0; i < cCRNMaxLevels; i++) {
|
|
m_levels[i].m_first_block = 0;
|
|
m_levels[i].m_num_blocks = 0;
|
|
m_levels[i].m_block_width = 0;
|
|
}
|
|
}
|
|
|
|
uint m_num_blocks;
|
|
uint m_num_levels;
|
|
uint m_num_faces;
|
|
|
|
struct {
|
|
uint m_first_block;
|
|
uint m_num_blocks;
|
|
uint m_block_width;
|
|
float m_weight;
|
|
} m_levels[cCRNMaxLevels];
|
|
|
|
dxt_format m_format;
|
|
bool m_perceptual;
|
|
bool m_hierarchical;
|
|
|
|
uint m_color_endpoint_codebook_size;
|
|
uint m_color_selector_codebook_size;
|
|
uint m_alpha_endpoint_codebook_size;
|
|
uint m_alpha_selector_codebook_size;
|
|
|
|
float m_adaptive_tile_color_psnr_derating;
|
|
float m_adaptive_tile_alpha_psnr_derating;
|
|
float m_adaptive_tile_color_alpha_weighting_ratio;
|
|
uint m_alpha_component_indices[2];
|
|
|
|
task_pool* m_pTask_pool;
|
|
bool m_debugging;
|
|
crn_progress_callback_func m_pProgress_func;
|
|
void* m_pProgress_func_data;
|
|
};
|
|
|
|
void clear();
|
|
bool compress(
|
|
color_quad_u8 (*blocks)[16],
|
|
crnlib::vector<endpoint_indices_details>& endpoint_indices,
|
|
crnlib::vector<selector_indices_details>& selector_indices,
|
|
crnlib::vector<uint32>& color_endpoints,
|
|
crnlib::vector<uint32>& alpha_endpoints,
|
|
crnlib::vector<uint32>& color_selectors,
|
|
crnlib::vector<uint64>& alpha_selectors,
|
|
const params& p
|
|
);
|
|
|
|
private:
|
|
params m_params;
|
|
|
|
uint m_num_alpha_blocks;
|
|
bool m_has_color_blocks;
|
|
|
|
enum {
|
|
cColor = 0,
|
|
cAlpha0 = 1,
|
|
cAlpha1 = 2,
|
|
cNumComps = 3
|
|
};
|
|
|
|
struct color_cluster {
|
|
color_cluster() : first_endpoint(0), second_endpoint(0) {}
|
|
crnlib::vector<uint> blocks[3];
|
|
crnlib::vector<color_quad_u8> pixels;
|
|
uint first_endpoint;
|
|
uint second_endpoint;
|
|
color_quad_u8 color_values[4];
|
|
};
|
|
crnlib::vector<color_cluster> m_color_clusters;
|
|
|
|
struct alpha_cluster {
|
|
alpha_cluster() : first_endpoint(0), second_endpoint(0) {}
|
|
crnlib::vector<uint> blocks[3];
|
|
crnlib::vector<color_quad_u8> pixels;
|
|
uint first_endpoint;
|
|
uint second_endpoint;
|
|
uint alpha_values[8];
|
|
bool refined_alpha;
|
|
uint refined_alpha_values[8];
|
|
};
|
|
crnlib::vector<alpha_cluster> m_alpha_clusters;
|
|
|
|
crn_thread_id_t m_main_thread_id;
|
|
bool m_canceled;
|
|
task_pool* m_pTask_pool;
|
|
|
|
int m_prev_phase_index;
|
|
int m_prev_percentage_complete;
|
|
|
|
void determine_tiles_task(uint64 data, void* pData_ptr);
|
|
|
|
void determine_color_endpoint_codebook_task(uint64 data, void* pData_ptr);
|
|
void determine_color_endpoint_clusters_task(uint64 data, void* pData_ptr);
|
|
void determine_color_endpoints();
|
|
|
|
void determine_alpha_endpoint_codebook_task(uint64 data, void* pData_ptr);
|
|
void determine_alpha_endpoint_clusters_task(uint64 data, void* pData_ptr);
|
|
void determine_alpha_endpoints();
|
|
|
|
void create_color_selector_codebook_task(uint64 data, void* pData_ptr);
|
|
void create_color_selector_codebook();
|
|
|
|
void create_alpha_selector_codebook_task(uint64 data, void* pData_ptr);
|
|
void create_alpha_selector_codebook();
|
|
|
|
bool update_progress(uint phase_index, uint subphase_index, uint subphase_total);
|
|
};
|
|
|
|
} // namespace crnlib
|