| // File: basisu_astc_hdr_6x6_enc.h |
| #pragma once |
| #include "basisu_enc.h" |
| #include "../transcoder/basisu_astc_hdr_core.h" |
| |
| namespace astc_6x6_hdr |
| { |
| const uint32_t ASTC_HDR_6X6_DEF_USER_COMP_LEVEL = 2; |
| const uint32_t ASTC_HDR_6X6_MAX_USER_COMP_LEVEL = 12; |
| |
| const uint32_t ASTC_HDR_6X6_MAX_COMP_LEVEL = 4; |
| |
| const float LDR_BLACK_BIAS = 0.0f;// .49f; |
| |
| // Note: This struct is copied several times, so do not place any heavyweight objects in here. |
| struct astc_hdr_6x6_global_config |
| { |
| // Important: The Delta ITP colorspace error metric we use internally makes several assumptions about the nature of the HDR RGB inputs supplied to the encoder. |
| // This encoder computes colorspace error in the ICtCp (or more accurately the delta E ITP, where CT is scaled by .5 vs. ICtCp to become T) colorspace, so getting this correct is important. |
| // By default the encoder assumes the input is in absolute luminance (in nits or candela per square meter, cd/m^2), specified as positive-only linear light RGB, using the REC 709 colorspace gamut (but NOT the sRGB transfer function, i.e. linear light). |
| // If the m_rec2020_bt2100_color_gamut flag is true, the input colorspace is treated as REC 2020/BT.2100 (which is wider than 709). |
| // For SDR/LDR->HDR upconversion, the REC 709 sRGB input should be converted to linear light (sRGB->linear) and the resulting normalized linear RGB values scaled by either 80 or 100 nits (the luminance of a typical SDR monitor). |
| // SDR upconversion to normalized [0,1] (i.e. non-absolute) luminances may work but is not supported because ITP errors will not be predicted correctly. |
| // 11/3/2025: This flag is always copied straight into the output KTX2 DFD colorspace, even for non-HDR formats. |
| // TODO: Move this parameter to reflect this. |
| bool m_rec2020_bt2100_color_gamut = false; |
| |
| // levels 0-3 normal levels, 4=exhaustive |
| uint32_t m_master_comp_level = 0; |
| uint32_t m_highest_comp_level = 1; |
| |
| float m_lambda = 0.0f; |
| |
| bool m_extra_patterns_flag = false; // def to false, works in comp levels [1,4] |
| bool m_brute_force_partition_matching = false; // def to false |
| |
| bool m_jnd_optimization = false; // defaults to false for HDR inputs, on SDR upconverted images this can default to enabled |
| float m_jnd_delta_itp_thresh = .75f; |
| |
| bool m_force_one_strip = false; |
| |
| bool m_gaussian1_fallback = true; // def to true, if this is disabled m_gaussian2_fallback should be disabled too |
| float m_gaussian1_strength = 1.45f; |
| |
| bool m_gaussian2_fallback = true; // def to true, hopefully rarely kicks in |
| float m_gaussian2_strength = 1.83f; |
| |
| // m_disable_delta_endpoint_usage may give a slight increase in RDO ASTC encoding efficiency. It's also faster. |
| bool m_disable_delta_endpoint_usage = false; |
| |
| // Scale up Delta ITP errors for very dark pixels, assuming they will be brightly exposed > 1.0x. |
| // We don't know if the output will be exposed, or not. If heavily exposed, our JND calculations will not be conservative enough. |
| bool m_delta_itp_dark_adjustment = true; |
| |
| bool m_debug_images = false; |
| std::string m_debug_image_prefix = "dbg_astc_hdr_6x6_devel_"; |
| |
| bool m_output_images = false; |
| std::string m_output_image_prefix = "dbg_astc_hdr_6x6_output_"; |
| |
| bool m_debug_output = false; |
| bool m_image_stats = false; |
| bool m_status_output = false; |
| |
| //------------------------------------------------------------------------------------- |
| // Very low level/devel parameters - intended for development. Best not to change them. |
| //------------------------------------------------------------------------------------- |
| bool m_deblocking_flag = true; |
| float m_deblock_penalty_weight = .03f; |
| bool m_disable_twothree_subsets = false; // def to false |
| bool m_use_solid_blocks = true; // def to true |
| bool m_use_runs = true; // def to true |
| bool m_block_stat_optimizations_flag = true; // def to true |
| |
| bool m_rdo_candidate_diversity_boost = true; // def to true |
| float m_rdo_candidate_diversity_boost_bit_window_weight = 1.2f; |
| |
| bool m_favor_higher_compression = true; // utilize all modes |
| uint32_t m_num_reuse_xy_deltas = basist::astc_6x6_hdr::NUM_REUSE_XY_DELTAS; |
| |
| // By default, for compatibility with KTX-Software (which uses v1.60), we write v1.6 compatible UASTC HDR 6x6i files. |
| // The transcoder is compatible with both variants. This setting impacts how 2x2 blocks are upsampled and the initial marker version. |
| // Eventually once KTX-Software upgrades to the latest version of basisu this will be defaulted to false. |
| // If this is false a v2.0 or later transcoder is required for UASTC HDR 6x6i. |
| bool m_write_basisu_1_6_compatible_files = true; |
| |
| void print() const |
| { |
| basisu::fmt_debug_printf(" m_master_comp_level: {}, m_highest_comp_level: {}\n", m_master_comp_level, m_highest_comp_level); |
| basisu::fmt_debug_printf(" m_lambda: {}\n", m_lambda); |
| basisu::fmt_debug_printf(" m_rec2020_bt2100_color_gamut: {}\n", m_rec2020_bt2100_color_gamut); |
| basisu::fmt_debug_printf(" m_extra_patterns_flag: {}, m_brute_force_partition_matching: {}\n", m_extra_patterns_flag, m_brute_force_partition_matching); |
| basisu::fmt_debug_printf(" m_jnd_optimization: {}, m_jnd_delta_itp_thresh: {}\n", m_jnd_optimization, m_jnd_delta_itp_thresh); |
| basisu::fmt_debug_printf(" m_force_one_strip: {}\n", m_force_one_strip); |
| basisu::fmt_debug_printf(" m_gaussian1_fallback: {}, m_gaussian1_strength: {}\n", m_gaussian1_fallback, m_gaussian1_strength); |
| basisu::fmt_debug_printf(" m_gaussian2_fallback: {}, m_gaussian2_strength: {}\n", m_gaussian2_fallback, m_gaussian2_strength); |
| basisu::fmt_debug_printf(" m_disable_delta_endpoint_usage: {}\n", m_disable_delta_endpoint_usage); |
| basisu::fmt_debug_printf(" m_delta_itp_dark_adjustment: {}\n", m_delta_itp_dark_adjustment); |
| basisu::fmt_debug_printf(" m_debug_images: {}, m_debug_image_prefix: {}\n", m_debug_images, m_debug_image_prefix); |
| basisu::fmt_debug_printf(" m_output_images: {}, m_output_image_prefix: {}\n", m_output_images, m_output_image_prefix); |
| basisu::fmt_debug_printf(" m_image_stats: {}, m_status_output: {}\n", m_image_stats, m_status_output); |
| basisu::fmt_debug_printf(" m_deblocking_flag: {}, m_deblock_penalty_weight: {}\n", m_deblocking_flag, m_deblock_penalty_weight); |
| basisu::fmt_debug_printf(" m_disable_twothree_subsets: {}, m_use_solid_blocks: {}\n", m_disable_twothree_subsets, m_use_solid_blocks); |
| basisu::fmt_debug_printf(" m_use_runs: {}, m_block_stat_optimizations_flag: {}\n", m_use_runs, m_block_stat_optimizations_flag); |
| basisu::fmt_debug_printf(" m_rdo_candidate_diversity_boost: {}, m_rdo_candidate_diversity_boost_bit_window_weight: {}\n", m_rdo_candidate_diversity_boost, m_rdo_candidate_diversity_boost_bit_window_weight); |
| basisu::fmt_debug_printf(" m_favor_higher_compression: {}, m_num_reuse_xy_deltas: {}\n", m_favor_higher_compression, m_num_reuse_xy_deltas); |
| basisu::fmt_debug_printf(" m_write_basisu_1_6_compatible_files: {}\n", m_write_basisu_1_6_compatible_files); |
| } |
| |
| astc_hdr_6x6_global_config() |
| { |
| } |
| |
| void clear() |
| { |
| astc_hdr_6x6_global_config def; |
| std::swap(*this, def); |
| } |
| |
| // Max level is ASTC_HDR_6X6_MAX_USER_COMP_LEVEL |
| void set_user_level(int level); |
| }; |
| |
| void global_init(); |
| |
| struct result_metrics |
| { |
| basisu::image_metrics m_im_astc_log2; |
| basisu::image_metrics m_im_astc_half; |
| |
| basisu::image_metrics m_im_bc6h_log2; |
| basisu::image_metrics m_im_bc6h_half; |
| }; |
| |
| // The input image should be unpadded to 6x6 boundaries, i.e. the original unexpanded image. |
| bool compress_photo(const basisu::imagef& orig_src_img, const astc_hdr_6x6_global_config& global_cfg, basisu::job_pool* pJob_pool, |
| basisu::uint8_vec& intermediate_tex_data, basisu::uint8_vec& astc_tex_data, result_metrics& metrics); |
| |
| } // namespace uastc_6x6_hdr |