// File: crn_comp.h // See Copyright Notice and license at the end of inc/crnlib.h #pragma once #define CRND_HEADER_FILE_ONLY #include "../inc/crn_decomp.h" #undef CRND_HEADER_FILE_ONLY #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& get_comp_data() const { return m_comp_data; } virtual crnlib::vector& 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]; struct level_tag { uint m_width, m_height; uint m_chunk_width, m_chunk_height; uint m_group_index; uint m_num_chunks; uint m_first_chunk; uint m_group_first_chunk; } m_levels[cCRNMaxLevels]; struct mip_group { mip_group() : m_first_chunk(0), m_num_chunks(0) { } uint m_first_chunk; uint m_num_chunks; }; crnlib::vector m_mip_groups; enum comp { cColor, cAlpha0, cAlpha1, cNumComps }; bool m_has_comp[cNumComps]; struct chunk_detail { chunk_detail() { utils::zero_object(*this); } uint m_first_endpoint_index; uint m_first_selector_index; }; typedef crnlib::vector chunk_detail_vec; chunk_detail_vec m_chunk_details; crnlib::vector m_endpoint_indices[cNumComps]; crnlib::vector m_selector_indices[cNumComps]; uint m_total_chunks; dxt_hc::pixel_chunk_vec m_chunks; crnd::crn_header m_crn_header; crnlib::vector m_comp_data; dxt_hc m_hvq; symbol_histogram m_chunk_encoding_hist; static_huffman_data_model m_chunk_encoding_dm; symbol_histogram m_endpoint_index_hist[2]; static_huffman_data_model m_endpoint_index_dm[2]; // color, alpha symbol_histogram m_selector_index_hist[2]; static_huffman_data_model m_selector_index_dm[2]; // color, alpha crnlib::vector m_packed_chunks[cCRNMaxLevels]; crnlib::vector m_packed_data_models; crnlib::vector m_packed_color_endpoints; crnlib::vector m_packed_color_selectors; crnlib::vector m_packed_alpha_endpoints; crnlib::vector m_packed_alpha_selectors; void clear(); void append_chunks(const image_u8& img, uint num_chunks_x, uint num_chunks_y, dxt_hc::pixel_chunk_vec& chunks, float weight); static float color_endpoint_similarity_func(uint index_a, uint index_b, void* pContext); static float alpha_endpoint_similarity_func(uint index_a, uint index_b, void* pContext); void sort_color_endpoint_codebook(crnlib::vector& remapping, const crnlib::vector& endpoints); void sort_alpha_endpoint_codebook(crnlib::vector& remapping, const crnlib::vector& endpoints); bool pack_color_endpoints(crnlib::vector& data, const crnlib::vector& remapping, const crnlib::vector& endpoint_indices, uint trial_index); bool pack_alpha_endpoints(crnlib::vector& data, const crnlib::vector& remapping, const crnlib::vector& endpoint_indices, uint trial_index); static float color_selector_similarity_func(uint index_a, uint index_b, void* pContext); static float alpha_selector_similarity_func(uint index_a, uint index_b, void* pContext); void sort_selector_codebook(crnlib::vector& remapping, const crnlib::vector& selectors, const uint8* pTo_linear); bool pack_selectors( crnlib::vector& packed_data, const crnlib::vector& selector_indices, const crnlib::vector& selectors, const crnlib::vector& remapping, uint max_selector_value, const uint8* pTo_linear, uint trial_index); bool alias_images(); void create_chunks(); bool quantize_chunks(); void create_chunk_indices(); bool pack_chunks( uint first_chunk, uint num_chunks, bool clear_histograms, symbol_codec* pCodec, const crnlib::vector* pColor_endpoint_remap, const crnlib::vector* pColor_selector_remap, const crnlib::vector* pAlpha_endpoint_remap, const crnlib::vector* pAlpha_selector_remap); bool pack_chunks_simulation( uint first_chunk, uint num_chunks, uint& total_bits, const crnlib::vector* pColor_endpoint_remap, const crnlib::vector* pColor_selector_remap, const crnlib::vector* pAlpha_endpoint_remap, const crnlib::vector* pAlpha_selector_remap); void optimize_color_endpoint_codebook_task(uint64 data, void* pData_ptr); bool optimize_color_endpoint_codebook(crnlib::vector& remapping); void optimize_color_selector_codebook_task(uint64 data, void* pData_ptr); bool optimize_color_selector_codebook(crnlib::vector& remapping); void optimize_alpha_endpoint_codebook_task(uint64 data, void* pData_ptr); bool optimize_alpha_endpoint_codebook(crnlib::vector& remapping); void optimize_alpha_selector_codebook_task(uint64 data, void* pData_ptr); bool optimize_alpha_selector_codebook(crnlib::vector& remapping); bool create_comp_data(); bool pack_data_models(); bool update_progress(uint phase_index, uint subphase_index, uint subphase_total); bool compress_internal(); static void append_vec(crnlib::vector& a, const void* p, uint size); static void append_vec(crnlib::vector& a, const crnlib::vector& b); }; } // namespace crnlib