// SPDX-License-Identifier: Apache-2.0 // ---------------------------------------------------------------------------- // Copyright 2011-2022 Arm Limited // // Licensed under the Apache License, Version 2.0 (the "License"); you may not // use this file except in compliance with the License. You may obtain a copy // of the License at: // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the // License for the specific language governing permissions and limitations // under the License. // ---------------------------------------------------------------------------- #if !defined(ASTCENC_DECOMPRESS_ONLY) /** * @brief Functions for finding best endpoint format. * * We assume there are two independent sources of error in any given partition: * * - Encoding choice errors * - Quantization errors * * Encoding choice errors are caused by encoder decisions. For example: * * - Using luminance instead of separate RGB components. * - Using a constant 1.0 alpha instead of storing an alpha component. * - Using RGB+scale instead of storing two full RGB endpoints. * * Quantization errors occur due to the limited precision we use for storage. These errors generally * scale with quantization level, but are not actually independent of color encoding. In particular: * * - If we can use offset encoding then quantization error is halved. * - If we can use blue-contraction then quantization error for RG is halved. * - If we use HDR endpoints the quantization error is higher. * * Apart from these effects, we assume the error is proportional to the quantization step size. */ #include "astcenc_internal.h" #include "astcenc_vecmathlib.h" #include <assert.h> /** * @brief Compute the errors of the endpoint line options for one partition. * * Uncorrelated data assumes storing completely independent RGBA channels for each endpoint. Same * chroma data assumes storing RGBA endpoints which pass though the origin (LDR only). RGBL data * assumes storing RGB + lumashift (HDR only). Luminance error assumes storing RGB channels as a * single value. * * * @param pi The partition info data. * @param partition_index The partition index to compule the error for. * @param blk The image block. * @param uncor_pline The endpoint line assuming uncorrelated endpoints. * @param[out] uncor_err The computed error for the uncorrelated endpoint line. * @param samec_pline The endpoint line assuming the same chroma for both endpoints. * @param[out] samec_err The computed error for the uncorrelated endpoint line. * @param rgbl_pline The endpoint line assuming RGB + lumashift data. * @param[out] rgbl_err The computed error for the RGB + lumashift endpoint line. * @param l_pline The endpoint line assuming luminance data. * @param[out] l_err The computed error for the luminance endpoint line. * @param[out] a_drop_err The computed error for dropping the alpha component. */ static void compute_error_squared_rgb_single_partition( const partition_info& pi, int partition_index, const image_block& blk, const processed_line3& uncor_pline, float& uncor_err, const processed_line3& samec_pline, float& samec_err, const processed_line3& rgbl_pline, float& rgbl_err, const processed_line3& l_pline, float& l_err, float& a_drop_err ) { … } /** * @brief For a given set of input colors and partitioning determine endpoint encode errors. * * This function determines the color error that results from RGB-scale encoding (LDR only), * RGB-lumashift encoding (HDR only), luminance-encoding, and alpha drop. Also determines whether * the endpoints are eligible for offset encoding or blue-contraction * * @param blk The image block. * @param pi The partition info data. * @param ep The idealized endpoints. * @param[out] eci The resulting encoding choice error metrics. */ static void compute_encoding_choice_errors( const image_block& blk, const partition_info& pi, const endpoints& ep, encoding_choice_errors eci[BLOCK_MAX_PARTITIONS]) { … } /** * @brief For a given partition compute the error for every endpoint integer count and quant level. * * @param encode_hdr_rgb @c true if using HDR for RGB, @c false for LDR. * @param encode_hdr_alpha @c true if using HDR for alpha, @c false for LDR. * @param partition_index The partition index. * @param pi The partition info. * @param eci The encoding choice error metrics. * @param ep The idealized endpoints. * @param error_weight The resulting encoding choice error metrics. * @param[out] best_error The best error for each integer count and quant level. * @param[out] format_of_choice The preferred endpoint format for each integer count and quant level. */ static void compute_color_error_for_every_integer_count_and_quant_level( bool encode_hdr_rgb, bool encode_hdr_alpha, int partition_index, const partition_info& pi, const encoding_choice_errors& eci, const endpoints& ep, vfloat4 error_weight, float best_error[21][4], uint8_t format_of_choice[21][4] ) { … } /** * @brief For one partition compute the best format and quantization for a given bit count. * * @param best_combined_error The best error for each quant level and integer count. * @param best_combined_format The best format for each quant level and integer count. * @param bits_available The number of bits available for encoding. * @param[out] best_quant_level The output best color quant level. * @param[out] best_format The output best color format. * * @return The output error for the best pairing. */ static float one_partition_find_best_combination_for_bitcount( const float best_combined_error[21][4], const uint8_t best_combined_format[21][4], int bits_available, uint8_t& best_quant_level, uint8_t& best_format ) { … } /** * @brief For 2 partitions compute the best format combinations for every pair of quant mode and integer count. * * @param best_error The best error for a single endpoint quant level and integer count. * @param best_format The best format for a single endpoint quant level and integer count. * @param[out] best_combined_error The best combined error pairings for the 2 partitions. * @param[out] best_combined_format The best combined format pairings for the 2 partitions. */ static void two_partitions_find_best_combination_for_every_quantization_and_integer_count( const float best_error[2][21][4], // indexed by (partition, quant-level, integer-pair-count-minus-1) const uint8_t best_format[2][21][4], float best_combined_error[21][7], // indexed by (quant-level, integer-pair-count-minus-2) uint8_t best_combined_format[21][7][2] ) { … } /** * @brief For 2 partitions compute the best format and quantization for a given bit count. * * @param best_combined_error The best error for each quant level and integer count. * @param best_combined_format The best format for each quant level and integer count. * @param bits_available The number of bits available for encoding. * @param[out] best_quant_level The output best color quant level. * @param[out] best_quant_level_mod The output best color quant level assuming two more bits are available. * @param[out] best_formats The output best color formats. * * @return The output error for the best pairing. */ static float two_partitions_find_best_combination_for_bitcount( float best_combined_error[21][7], uint8_t best_combined_format[21][7][2], int bits_available, uint8_t& best_quant_level, uint8_t& best_quant_level_mod, uint8_t* best_formats ) { … } /** * @brief For 3 partitions compute the best format combinations for every pair of quant mode and integer count. * * @param best_error The best error for a single endpoint quant level and integer count. * @param best_format The best format for a single endpoint quant level and integer count. * @param[out] best_combined_error The best combined error pairings for the 3 partitions. * @param[out] best_combined_format The best combined format pairings for the 3 partitions. */ static void three_partitions_find_best_combination_for_every_quantization_and_integer_count( const float best_error[3][21][4], // indexed by (partition, quant-level, integer-count) const uint8_t best_format[3][21][4], float best_combined_error[21][10], uint8_t best_combined_format[21][10][3] ) { … } /** * @brief For 3 partitions compute the best format and quantization for a given bit count. * * @param best_combined_error The best error for each quant level and integer count. * @param best_combined_format The best format for each quant level and integer count. * @param bits_available The number of bits available for encoding. * @param[out] best_quant_level The output best color quant level. * @param[out] best_quant_level_mod The output best color quant level assuming two more bits are available. * @param[out] best_formats The output best color formats. * * @return The output error for the best pairing. */ static float three_partitions_find_best_combination_for_bitcount( const float best_combined_error[21][10], const uint8_t best_combined_format[21][10][3], int bits_available, uint8_t& best_quant_level, uint8_t& best_quant_level_mod, uint8_t* best_formats ) { … } /** * @brief For 4 partitions compute the best format combinations for every pair of quant mode and integer count. * * @param best_error The best error for a single endpoint quant level and integer count. * @param best_format The best format for a single endpoint quant level and integer count. * @param[out] best_combined_error The best combined error pairings for the 4 partitions. * @param[out] best_combined_format The best combined format pairings for the 4 partitions. */ static void four_partitions_find_best_combination_for_every_quantization_and_integer_count( const float best_error[4][21][4], // indexed by (partition, quant-level, integer-count) const uint8_t best_format[4][21][4], float best_combined_error[21][13], uint8_t best_combined_format[21][13][4] ) { … } /** * @brief For 4 partitions compute the best format and quantization for a given bit count. * * @param best_combined_error The best error for each quant level and integer count. * @param best_combined_format The best format for each quant level and integer count. * @param bits_available The number of bits available for encoding. * @param[out] best_quant_level The output best color quant level. * @param[out] best_quant_level_mod The output best color quant level assuming two more bits are available. * @param[out] best_formats The output best color formats. * * @return best_error The output error for the best pairing. */ static float four_partitions_find_best_combination_for_bitcount( const float best_combined_error[21][13], const uint8_t best_combined_format[21][13][4], int bits_available, uint8_t& best_quant_level, uint8_t& best_quant_level_mod, uint8_t* best_formats ) { … } /* See header for documentation. */ unsigned int compute_ideal_endpoint_formats( const partition_info& pi, const image_block& blk, const endpoints& ep, // bitcounts and errors computed for the various quantization methods const int8_t* qwt_bitcounts, const float* qwt_errors, unsigned int tune_candidate_limit, unsigned int start_block_mode, unsigned int end_block_mode, // output data uint8_t partition_format_specifiers[TUNE_MAX_TRIAL_CANDIDATES][BLOCK_MAX_PARTITIONS], int block_mode[TUNE_MAX_TRIAL_CANDIDATES], quant_method quant_level[TUNE_MAX_TRIAL_CANDIDATES], quant_method quant_level_mod[TUNE_MAX_TRIAL_CANDIDATES], compression_working_buffers& tmpbuf ) { … } #endif