diff --git a/basisu_backend.cpp b/basisu_backend.cpp index 898b4fc..4aa297a 100644 --- a/basisu_backend.cpp +++ b/basisu_backend.cpp @@ -267,10 +267,10 @@ namespace basisu int selector_index = remaining_selectors[j]; uint32_t hamming_dist = - basist::g_hamming_dist[m_selector_palette[prev_selector_index].get_byte(0) ^ m_selector_palette[selector_index].get_byte(0)] + - basist::g_hamming_dist[m_selector_palette[prev_selector_index].get_byte(1) ^ m_selector_palette[selector_index].get_byte(1)] + - basist::g_hamming_dist[m_selector_palette[prev_selector_index].get_byte(2) ^ m_selector_palette[selector_index].get_byte(2)] + - basist::g_hamming_dist[m_selector_palette[prev_selector_index].get_byte(3) ^ m_selector_palette[selector_index].get_byte(3)]; + g_hamming_dist[m_selector_palette[prev_selector_index].get_byte(0) ^ m_selector_palette[selector_index].get_byte(0)] + + g_hamming_dist[m_selector_palette[prev_selector_index].get_byte(1) ^ m_selector_palette[selector_index].get_byte(1)] + + g_hamming_dist[m_selector_palette[prev_selector_index].get_byte(2) ^ m_selector_palette[selector_index].get_byte(2)] + + g_hamming_dist[m_selector_palette[prev_selector_index].get_byte(3) ^ m_selector_palette[selector_index].get_byte(3)]; if (hamming_dist < best_hamming_dist) { diff --git a/basisu_enc.cpp b/basisu_enc.cpp index 18a860c..8b6c211 100644 --- a/basisu_enc.cpp +++ b/basisu_enc.cpp @@ -30,6 +30,26 @@ namespace basisu uint64_t interval_timer::g_init_ticks, interval_timer::g_freq; double interval_timer::g_timer_freq; + uint8_t g_hamming_dist[256] = + { + 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, + 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, + 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, + 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, + 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, + 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8 + }; + // Encoder library initialization (just call once at startup) void basisu_encoder_init() { diff --git a/basisu_enc.h b/basisu_enc.h index 03b90d4..0ec1547 100644 --- a/basisu_enc.h +++ b/basisu_enc.h @@ -23,6 +23,8 @@ namespace basisu { + extern uint8_t g_hamming_dist[256]; + // Encoder library initialization void basisu_encoder_init(); diff --git a/transcoder/basisu_file_headers.h b/transcoder/basisu_file_headers.h index 64f11f9..fd7615e 100644 --- a/transcoder/basisu_file_headers.h +++ b/transcoder/basisu_file_headers.h @@ -17,7 +17,8 @@ namespace basist { - enum + // Slice desc header flags + enum basis_slice_desc_flags { cSliceDescFlagsIsAlphaData = 1, }; @@ -26,31 +27,33 @@ namespace basist #pragma pack(1) struct basis_slice_desc { - basisu::packed_uint<3> m_image_index; // the index of the source image provided to the encoder - basisu::packed_uint<1> m_level_index; // the mipmap level index (mipmaps will always appear from largest to smallest) - basisu::packed_uint<1> m_flags; + basisu::packed_uint<3> m_image_index; // The index of the source image provided to the encoder (will always appear in order from first to last, first image index is 0, no skipping allowed) + basisu::packed_uint<1> m_level_index; // The mipmap level index (mipmaps will always appear from largest to smallest) + basisu::packed_uint<1> m_flags; // enum basis_slice_desc_flags - basisu::packed_uint<2> m_orig_width; - basisu::packed_uint<2> m_orig_height; + basisu::packed_uint<2> m_orig_width; // The original image width (may not be a multiple of 4 pixels) + basisu::packed_uint<2> m_orig_height; // The original image height (may not be a multiple of 4 pixels) - basisu::packed_uint<2> m_num_blocks_x; - basisu::packed_uint<2> m_num_blocks_y; + basisu::packed_uint<2> m_num_blocks_x; // The slice's block X dimensions. Each block is 4x4 pixels. The slice's pixel resolution may or may not be a power of 2. + basisu::packed_uint<2> m_num_blocks_y; // The slice's block Y dimensions. - basisu::packed_uint<4> m_file_ofs; - basisu::packed_uint<4> m_file_size; + basisu::packed_uint<4> m_file_ofs; // Offset from the header to the start of the slice's data + basisu::packed_uint<4> m_file_size; // The size of the compressed slice data in bytes - basisu::packed_uint<2> m_slice_data_crc16; + basisu::packed_uint<2> m_slice_data_crc16; // The CRC16 of the compressed slice data, for extra-paranoid use cases }; + // File header files enum basis_header_flags { - cBASISHeaderFlagETC1S = 1, - cBASISHeaderFlagYFlipped = 2, - cBASISHeaderFlagHasAlphaSlices = 4 + cBASISHeaderFlagETC1S = 1, // Always set for basis universal files + cBASISHeaderFlagYFlipped = 2, // Set if the texture had to be Y flipped before encoding + cBASISHeaderFlagHasAlphaSlices = 4 // True if the odd slices contain alpha data }; // The image type field attempts to describe how to interpret the image data in a Basis file. - // The encoder library doesn't really do anything special or different with these texture types, this is mostly here for the benefit of the user. + // The encoder library doesn't really do anything special or different with these texture types, this is mostly here for the benefit of the user. + // We do make sure the various constraints are followed (2DArray/cubemap/videoframes/volume implies that each image has the same resolution and # of mipmap levels, etc., cubemap implies that the # of image slices is a multiple of 6) enum basis_texture_type { cBASISTexType2D = 0, // An arbitrary array of 2D RGB or RGBA images with optional mipmaps, array size = # images, each image may have a different resolution and # of mipmap levels @@ -73,42 +76,42 @@ namespace basist cBASISFirstVersion = 0x10 }; - basisu::packed_uint<2> m_sig; - basisu::packed_uint<2> m_ver; - basisu::packed_uint<2> m_header_size; - basisu::packed_uint<2> m_header_crc16; + basisu::packed_uint<2> m_sig; // 2 byte file signature + basisu::packed_uint<2> m_ver; // Baseline file version + basisu::packed_uint<2> m_header_size; // Header size in bytes, sizeof(basis_file_header) + basisu::packed_uint<2> m_header_crc16; // crc16 of the remaining header data - basisu::packed_uint<4> m_data_size; - basisu::packed_uint<2> m_data_crc16; + basisu::packed_uint<4> m_data_size; // The total size of all data after the header + basisu::packed_uint<2> m_data_crc16; // The CRC16 of all data after the header - basisu::packed_uint<3> m_total_slices; + basisu::packed_uint<3> m_total_slices; // The total # of compressed slices (1 slice per image, or 2 for alpha basis files) - basisu::packed_uint<3> m_total_images; + basisu::packed_uint<3> m_total_images; // The total # of images basisu::packed_uint<1> m_format; // enum basist::block_format basisu::packed_uint<2> m_flags; // enum basist::header_flags basisu::packed_uint<1> m_tex_type; // enum basist::basis_texture_type - basisu::packed_uint<3> m_us_per_frame; // framerate of video, in microseconds per frame + basisu::packed_uint<3> m_us_per_frame; // Framerate of video, in microseconds per frame - basisu::packed_uint<4> m_reserved; - basisu::packed_uint<4> m_userdata0; - basisu::packed_uint<4> m_userdata1; + basisu::packed_uint<4> m_reserved; // For future use + basisu::packed_uint<4> m_userdata0; // For client use + basisu::packed_uint<4> m_userdata1; // For client use - basisu::packed_uint<2> m_total_endpoints; - basisu::packed_uint<4> m_endpoint_cb_file_ofs; - basisu::packed_uint<3> m_endpoint_cb_file_size; + basisu::packed_uint<2> m_total_endpoints; // The number of endpoints in the endpoint codebook + basisu::packed_uint<4> m_endpoint_cb_file_ofs; // The compressed endpoint codebook's file offset relative to the header + basisu::packed_uint<3> m_endpoint_cb_file_size; // The compressed endpoint codebook's size in bytes - basisu::packed_uint<2> m_total_selectors; - basisu::packed_uint<4> m_selector_cb_file_ofs; - basisu::packed_uint<3> m_selector_cb_file_size; + basisu::packed_uint<2> m_total_selectors; // The number of selectors in the endpoint codebook + basisu::packed_uint<4> m_selector_cb_file_ofs; // The compressed selectors codebook's file offset relative to the header + basisu::packed_uint<3> m_selector_cb_file_size; // The compressed selector codebook's size in bytes - basisu::packed_uint<4> m_tables_file_ofs; - basisu::packed_uint<4> m_tables_file_size; + basisu::packed_uint<4> m_tables_file_ofs; // The file offset of the compressed Huffman codelength tables, for decompressing slices + basisu::packed_uint<4> m_tables_file_size; // The file size in bytes of the compressed huffman codelength tables - basisu::packed_uint<4> m_slice_desc_file_ofs; + basisu::packed_uint<4> m_slice_desc_file_ofs; // The file offset to the slice description array, usually follows the header - basisu::packed_uint<4> m_extended_file_ofs; - basisu::packed_uint<4> m_extended_file_size; + basisu::packed_uint<4> m_extended_file_ofs; // The file offset of the "extended" header and compressed data, for future use + basisu::packed_uint<4> m_extended_file_size; // The file size in bytes of the "extended" header and compressed data, for future use }; #pragma pack (pop) diff --git a/transcoder/basisu_global_selector_palette.h b/transcoder/basisu_global_selector_palette.h index ac7532d..70c663a 100644 --- a/transcoder/basisu_global_selector_palette.h +++ b/transcoder/basisu_global_selector_palette.h @@ -162,6 +162,7 @@ namespace basist return dist; } +#if 0 uint32_t calc_hamming_dist(const etc1_selector_palette_entry &other) const { uint32_t dist = 0; @@ -169,6 +170,7 @@ namespace basist dist += g_hamming_dist[get_byte(i) ^ other.get_byte(i)]; return dist; } +#endif etc1_selector_palette_entry get_inverted() const { diff --git a/transcoder/basisu_transcoder.cpp b/transcoder/basisu_transcoder.cpp index 64954cc..a580891 100644 --- a/transcoder/basisu_transcoder.cpp +++ b/transcoder/basisu_transcoder.cpp @@ -72,27 +72,7 @@ namespace basist return static_cast(~crc); } - - uint8_t g_hamming_dist[256] = - { - 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, - 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, - 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, - 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, - 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, - 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, - 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, - 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, - 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, - 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, - 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, - 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8 - }; - + const uint32_t g_global_selector_cb[] = #include "basisu_global_selector_cb.h" ; diff --git a/transcoder/basisu_transcoder_internal.h b/transcoder/basisu_transcoder_internal.h index 9dfbcbb..b864b09 100644 --- a/transcoder/basisu_transcoder_internal.h +++ b/transcoder/basisu_transcoder_internal.h @@ -51,9 +51,7 @@ namespace basist const uint32_t SELECTOR_HISTORY_BUF_RLE_COUNT_TOTAL = (1 << SELECTOR_HISTORY_BUF_RLE_COUNT_BITS); uint16_t crc16(const void *r, size_t size, uint16_t crc); - - extern uint8_t g_hamming_dist[256]; - + class huffman_decoding_table { friend class bitwise_decoder;