CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!
CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!
Path: blob/master/ext/basis_universal/basisu_transcoder_uastc.h
Views: 1401
// basisu_transcoder_uastc.h1#pragma once2#include "basisu_transcoder_internal.h"34namespace basist5{6struct color_quad_u87{8uint8_t m_c[4];9};1011const uint32_t TOTAL_UASTC_MODES = 19;12const uint32_t UASTC_MODE_INDEX_SOLID_COLOR = 8;1314const uint32_t TOTAL_ASTC_BC7_COMMON_PARTITIONS2 = 30;15const uint32_t TOTAL_ASTC_BC7_COMMON_PARTITIONS3 = 11;16const uint32_t TOTAL_BC7_3_ASTC2_COMMON_PARTITIONS = 19;1718extern const uint8_t g_uastc_mode_weight_bits[TOTAL_UASTC_MODES];19extern const uint8_t g_uastc_mode_weight_ranges[TOTAL_UASTC_MODES];20extern const uint8_t g_uastc_mode_endpoint_ranges[TOTAL_UASTC_MODES];21extern const uint8_t g_uastc_mode_subsets[TOTAL_UASTC_MODES];22extern const uint8_t g_uastc_mode_planes[TOTAL_UASTC_MODES];23extern const uint8_t g_uastc_mode_comps[TOTAL_UASTC_MODES];24extern const uint8_t g_uastc_mode_has_etc1_bias[TOTAL_UASTC_MODES];25extern const uint8_t g_uastc_mode_has_bc1_hint0[TOTAL_UASTC_MODES];26extern const uint8_t g_uastc_mode_has_bc1_hint1[TOTAL_UASTC_MODES];27extern const uint8_t g_uastc_mode_has_alpha[TOTAL_UASTC_MODES];28extern const uint8_t g_uastc_mode_is_la[TOTAL_UASTC_MODES];2930struct astc_bc7_common_partition2_desc31{32uint8_t m_bc7;33uint16_t m_astc;34bool m_invert;35};3637extern const astc_bc7_common_partition2_desc g_astc_bc7_common_partitions2[TOTAL_ASTC_BC7_COMMON_PARTITIONS2];3839struct bc73_astc2_common_partition_desc40{41uint8_t m_bc73;42uint16_t m_astc2;43uint8_t k; // 0-5 - how to modify the BC7 3-subset pattern to match the ASTC pattern (LSB=invert)44};4546extern const bc73_astc2_common_partition_desc g_bc7_3_astc2_common_partitions[TOTAL_BC7_3_ASTC2_COMMON_PARTITIONS];4748struct astc_bc7_common_partition3_desc49{50uint8_t m_bc7;51uint16_t m_astc;52uint8_t m_astc_to_bc7_perm; // converts ASTC to BC7 partition using g_astc_bc7_partition_index_perm_tables[][]53};5455extern const astc_bc7_common_partition3_desc g_astc_bc7_common_partitions3[TOTAL_ASTC_BC7_COMMON_PARTITIONS3];5657extern const uint8_t g_astc_bc7_patterns2[TOTAL_ASTC_BC7_COMMON_PARTITIONS2][16];58extern const uint8_t g_astc_bc7_patterns3[TOTAL_ASTC_BC7_COMMON_PARTITIONS3][16];59extern const uint8_t g_bc7_3_astc2_patterns2[TOTAL_BC7_3_ASTC2_COMMON_PARTITIONS][16];6061extern const uint8_t g_astc_bc7_pattern2_anchors[TOTAL_ASTC_BC7_COMMON_PARTITIONS2][3];62extern const uint8_t g_astc_bc7_pattern3_anchors[TOTAL_ASTC_BC7_COMMON_PARTITIONS3][3];63extern const uint8_t g_bc7_3_astc2_patterns2_anchors[TOTAL_BC7_3_ASTC2_COMMON_PARTITIONS][3];6465extern const uint32_t g_uastc_mode_huff_codes[TOTAL_UASTC_MODES + 1][2];6667extern const uint8_t g_astc_to_bc7_partition_index_perm_tables[6][3];68extern const uint8_t g_bc7_to_astc_partition_index_perm_tables[6][3]; // inverse of g_astc_to_bc7_partition_index_perm_tables6970extern const uint8_t* s_uastc_to_bc1_weights[6];7172uint32_t bc7_convert_partition_index_3_to_2(uint32_t p, uint32_t k);7374inline uint32_t astc_interpolate(uint32_t l, uint32_t h, uint32_t w, bool srgb)75{76if (srgb)77{78l = (l << 8) | 0x80;79h = (h << 8) | 0x80;80}81else82{83l = (l << 8) | l;84h = (h << 8) | h;85}8687uint32_t k = (l * (64 - w) + h * w + 32) >> 6;8889return k >> 8;90}9192struct astc_block_desc93{94int m_weight_range; // weight BISE range9596int m_subsets; // number of ASTC partitions97int m_partition_seed; // partition pattern seed98int m_cem; // color endpoint mode used by all subsets99100int m_ccs; // color component selector (dual plane only)101bool m_dual_plane; // true if dual plane102103// Weight and endpoint BISE values.104// Note these values are NOT linear, they must be BISE encoded. See Table 97 and Table 107.105uint8_t m_endpoints[18]; // endpoint values, in RR GG BB etc. order106uint8_t m_weights[64]; // weight index values, raster order, in P0 P1, P0 P1, etc. or P0, P0, P0, P0, etc. order107};108109const uint32_t BC7ENC_TOTAL_ASTC_RANGES = 21;110111// See tables 81, 93, 18.13.Endpoint Unquantization112const uint32_t TOTAL_ASTC_RANGES = 21;113extern const int g_astc_bise_range_table[TOTAL_ASTC_RANGES][3];114115struct astc_quant_bin116{117uint8_t m_unquant; // unquantized value118uint8_t m_index; // sorted index119};120121extern astc_quant_bin g_astc_unquant[BC7ENC_TOTAL_ASTC_RANGES][256]; // [ASTC encoded endpoint index]122123int astc_get_levels(int range);124bool astc_is_valid_endpoint_range(uint32_t range);125uint32_t unquant_astc_endpoint(uint32_t packed_bits, uint32_t packed_trits, uint32_t packed_quints, uint32_t range);126uint32_t unquant_astc_endpoint_val(uint32_t packed_val, uint32_t range);127128const uint8_t* get_anchor_indices(uint32_t subsets, uint32_t mode, uint32_t common_pattern, const uint8_t*& pPartition_pattern);129130// BC7131const uint32_t BC7ENC_BLOCK_SIZE = 16;132133struct bc7_block134{135uint64_t m_qwords[2];136};137138struct bc7_optimization_results139{140uint32_t m_mode;141uint32_t m_partition;142uint8_t m_selectors[16];143uint8_t m_alpha_selectors[16];144color_quad_u8 m_low[3];145color_quad_u8 m_high[3];146uint32_t m_pbits[3][2];147uint32_t m_index_selector;148uint32_t m_rotation;149};150151extern const uint32_t g_bc7_weights1[2];152extern const uint32_t g_bc7_weights2[4];153extern const uint32_t g_bc7_weights3[8];154extern const uint32_t g_bc7_weights4[16];155extern const uint32_t g_astc_weights4[16];156extern const uint32_t g_astc_weights5[32];157extern const uint32_t g_astc_weights_3levels[3];158extern const uint8_t g_bc7_partition1[16];159extern const uint8_t g_bc7_partition2[64 * 16];160extern const uint8_t g_bc7_partition3[64 * 16];161extern const uint8_t g_bc7_table_anchor_index_second_subset[64];162extern const uint8_t g_bc7_table_anchor_index_third_subset_1[64];163extern const uint8_t g_bc7_table_anchor_index_third_subset_2[64];164extern const uint8_t g_bc7_num_subsets[8];165extern const uint8_t g_bc7_partition_bits[8];166extern const uint8_t g_bc7_color_index_bitcount[8];167extern const uint8_t g_bc7_mode_has_p_bits[8];168extern const uint8_t g_bc7_mode_has_shared_p_bits[8];169extern const uint8_t g_bc7_color_precision_table[8];170extern const int8_t g_bc7_alpha_precision_table[8];171extern const uint8_t g_bc7_alpha_index_bitcount[8];172173inline bool get_bc7_mode_has_seperate_alpha_selectors(int mode) { return (mode == 4) || (mode == 5); }174inline int get_bc7_color_index_size(int mode, int index_selection_bit) { return g_bc7_color_index_bitcount[mode] + index_selection_bit; }175inline int get_bc7_alpha_index_size(int mode, int index_selection_bit) { return g_bc7_alpha_index_bitcount[mode] - index_selection_bit; }176177struct endpoint_err178{179uint16_t m_error; uint8_t m_lo; uint8_t m_hi;180};181182extern endpoint_err g_bc7_mode_6_optimal_endpoints[256][2]; // [c][pbit]183const uint32_t BC7ENC_MODE_6_OPTIMAL_INDEX = 5;184185extern endpoint_err g_bc7_mode_5_optimal_endpoints[256]; // [c]186const uint32_t BC7ENC_MODE_5_OPTIMAL_INDEX = 1;187188// Packs a BC7 block from a high-level description. Handles all BC7 modes.189void encode_bc7_block(void* pBlock, const bc7_optimization_results* pResults);190191// Packs an ASTC block192// Constraints: Always 4x4, all subset CEM's must be equal, only tested with LDR CEM's.193bool pack_astc_block(uint32_t* pDst, const astc_block_desc* pBlock, uint32_t mode);194195void pack_astc_solid_block(void* pDst_block, const color32& color);196197#ifdef _DEBUG198int astc_compute_texel_partition(int seed, int x, int y, int z, int partitioncount, bool small_block);199#endif200201struct uastc_block202{203union204{205uint8_t m_bytes[16];206uint32_t m_dwords[4];207};208};209210struct unpacked_uastc_block211{212astc_block_desc m_astc;213214uint32_t m_mode;215uint32_t m_common_pattern;216217color32 m_solid_color;218219bool m_bc1_hint0;220bool m_bc1_hint1;221222bool m_etc1_flip;223bool m_etc1_diff;224uint32_t m_etc1_inten0;225uint32_t m_etc1_inten1;226227uint32_t m_etc1_bias;228229uint32_t m_etc2_hints;230231uint32_t m_etc1_selector;232uint32_t m_etc1_r, m_etc1_g, m_etc1_b;233};234235color32 apply_etc1_bias(const color32 &block_color, uint32_t bias, uint32_t limit, uint32_t subblock);236237struct decoder_etc_block;238struct eac_block;239240bool unpack_uastc(uint32_t mode, uint32_t common_pattern, const color32& solid_color, const astc_block_desc& astc, color32* pPixels, bool srgb);241bool unpack_uastc(const unpacked_uastc_block& unpacked_blk, color32* pPixels, bool srgb);242243bool unpack_uastc(const uastc_block& blk, color32* pPixels, bool srgb);244bool unpack_uastc(const uastc_block& blk, unpacked_uastc_block& unpacked, bool undo_blue_contract, bool read_hints = true);245246bool transcode_uastc_to_astc(const uastc_block& src_blk, void* pDst);247248bool transcode_uastc_to_bc7(const unpacked_uastc_block& unpacked_src_blk, bc7_optimization_results& dst_blk);249bool transcode_uastc_to_bc7(const uastc_block& src_blk, bc7_optimization_results& dst_blk);250bool transcode_uastc_to_bc7(const uastc_block& src_blk, void* pDst);251252void transcode_uastc_to_etc1(unpacked_uastc_block& unpacked_src_blk, color32 block_pixels[4][4], void* pDst);253bool transcode_uastc_to_etc1(const uastc_block& src_blk, void* pDst);254bool transcode_uastc_to_etc1(const uastc_block& src_blk, void* pDst, uint32_t channel);255256void transcode_uastc_to_etc2_eac_a8(unpacked_uastc_block& unpacked_src_blk, color32 block_pixels[4][4], void* pDst);257bool transcode_uastc_to_etc2_rgba(const uastc_block& src_blk, void* pDst);258259// Packs 16 scalar values to BC4. Same PSNR as stb_dxt's BC4 encoder, around 13% faster.260void encode_bc4(void* pDst, const uint8_t* pPixels, uint32_t stride);261262void encode_bc1_solid_block(void* pDst, uint32_t fr, uint32_t fg, uint32_t fb);263264enum265{266cEncodeBC1HighQuality = 1,267cEncodeBC1HigherQuality = 2,268cEncodeBC1UseSelectors = 4,269};270void encode_bc1(void* pDst, const uint8_t* pPixels, uint32_t flags);271272// Alternate PCA-free encoder, around 15% faster, same (or slightly higher) avg. PSNR273void encode_bc1_alt(void* pDst, const uint8_t* pPixels, uint32_t flags);274275void transcode_uastc_to_bc1_hint0(const unpacked_uastc_block& unpacked_src_blk, void* pDst);276void transcode_uastc_to_bc1_hint1(const unpacked_uastc_block& unpacked_src_blk, const color32 block_pixels[4][4], void* pDst, bool high_quality);277278bool transcode_uastc_to_bc1(const uastc_block& src_blk, void* pDst, bool high_quality);279bool transcode_uastc_to_bc3(const uastc_block& src_blk, void* pDst, bool high_quality);280bool transcode_uastc_to_bc4(const uastc_block& src_blk, void* pDst, bool high_quality, uint32_t chan0);281bool transcode_uastc_to_bc5(const uastc_block& src_blk, void* pDst, bool high_quality, uint32_t chan0, uint32_t chan1);282283bool transcode_uastc_to_etc2_eac_r11(const uastc_block& src_blk, void* pDst, bool high_quality, uint32_t chan0);284bool transcode_uastc_to_etc2_eac_rg11(const uastc_block& src_blk, void* pDst, bool high_quality, uint32_t chan0, uint32_t chan1);285286bool transcode_uastc_to_pvrtc1_4_rgb(const uastc_block* pSrc_blocks, void* pDst_blocks, uint32_t num_blocks_x, uint32_t num_blocks_y, bool high_quality, bool from_alpha);287bool transcode_uastc_to_pvrtc1_4_rgba(const uastc_block* pSrc_blocks, void* pDst_blocks, uint32_t num_blocks_x, uint32_t num_blocks_y, bool high_quality);288289// uastc_init() MUST be called before using this module.290void uastc_init();291292} // namespace basist293294295