// 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; endpoint_indices_details() { utils::zero_object(*this); } }; struct selector_indices_details { union { struct { uint16 color; uint16 alpha0; uint16 alpha1; }; uint16 component[3]; }; selector_indices_details() { utils::zero_object(*this); } }; struct tile_details { crnlib::vector pixels; float weight; vec<6, float> color_endpoint; vec<2, float> alpha_endpoints[2]; uint16 cluster_indices[3]; }; crnlib::vector 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 m_block_weights; crnlib::vector m_block_encodings; crnlib::vector m_block_selectors[3]; crnlib::vector m_color_selectors; crnlib::vector m_alpha_selectors; crnlib::vector m_color_selectors_used; crnlib::vector m_alpha_selectors_used; crnlib::vector m_tile_indices; crnlib::vector m_endpoint_indices; crnlib::vector 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, crnlib::vector& selector_indices, crnlib::vector& color_endpoints, crnlib::vector& alpha_endpoints, crnlib::vector& color_selectors, crnlib::vector& alpha_selectors, const params& p ); private: params m_params; uint m_num_alpha_blocks; bool m_has_color_blocks; bool m_has_etc_color_blocks; bool m_has_subblocks; enum { cColor = 0, cAlpha0 = 1, cAlpha1 = 2, cNumComps = 3 }; struct color_cluster { color_cluster() : first_endpoint(0), second_endpoint(0) {} crnlib::vector blocks[3]; crnlib::vector pixels; uint first_endpoint; uint second_endpoint; color_quad_u8 color_values[4]; }; crnlib::vector m_color_clusters; struct alpha_cluster { alpha_cluster() : first_endpoint(0), second_endpoint(0) {} crnlib::vector blocks[3]; crnlib::vector pixels; uint first_endpoint; uint second_endpoint; uint alpha_values[8]; bool refined_alpha; uint refined_alpha_values[8]; }; crnlib::vector 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; vec<6, float> palettize_color(color_quad_u8* pixels, uint pixels_count); vec<2, float> palettize_alpha(color_quad_u8* pixels, uint pixels_count, uint comp_index); void determine_tiles_task(uint64 data, void* pData_ptr); void determine_tiles_task_etc(uint64 data, void* pData_ptr); void determine_color_endpoint_codebook_task(uint64 data, void* pData_ptr); void determine_color_endpoint_codebook_task_etc(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