| 1 | // File: basisu_bc7enc.h | 
|---|
| 2 | // Copyright (C) 2019-2021 Binomial LLC. All Rights Reserved. | 
|---|
| 3 | // | 
|---|
| 4 | // Licensed under the Apache License, Version 2.0 (the "License"); | 
|---|
| 5 | // you may not use this file except in compliance with the License. | 
|---|
| 6 | // You may obtain a copy of the License at | 
|---|
| 7 | // | 
|---|
| 8 | //    http://www.apache.org/licenses/LICENSE-2.0 | 
|---|
| 9 | // | 
|---|
| 10 | // Unless required by applicable law or agreed to in writing, software | 
|---|
| 11 | // distributed under the License is distributed on an "AS IS" BASIS, | 
|---|
| 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
|---|
| 13 | // See the License for the specific language governing permissions and | 
|---|
| 14 | // limitations under the License. | 
|---|
| 15 | #pragma once | 
|---|
| 16 | #include "basisu_enc.h" | 
|---|
| 17 | #include "../transcoder/basisu_transcoder_uastc.h" | 
|---|
| 18 |  | 
|---|
| 19 | namespace basisu | 
|---|
| 20 | { | 
|---|
| 21 |  | 
|---|
| 22 | #define BC7ENC_MAX_PARTITIONS1 (64) | 
|---|
| 23 | #define BC7ENC_MAX_UBER_LEVEL (4) | 
|---|
| 24 |  | 
|---|
| 25 | typedef uint8_t bc7enc_bool; | 
|---|
| 26 |  | 
|---|
| 27 | #define BC7ENC_TRUE (1) | 
|---|
| 28 | #define BC7ENC_FALSE (0) | 
|---|
| 29 |  | 
|---|
| 30 | typedef struct { float m_c[4]; } bc7enc_vec4F; | 
|---|
| 31 |  | 
|---|
| 32 | extern const float g_bc7_weights1x[2 * 4]; | 
|---|
| 33 | extern const float g_bc7_weights2x[4 * 4]; | 
|---|
| 34 | extern const float g_bc7_weights3x[8 * 4]; | 
|---|
| 35 | extern const float g_bc7_weights4x[16 * 4]; | 
|---|
| 36 | extern const float g_astc_weights4x[16 * 4]; | 
|---|
| 37 | extern const float g_astc_weights5x[32 * 4]; | 
|---|
| 38 | extern const float g_astc_weights_3levelsx[3 * 4]; | 
|---|
| 39 |  | 
|---|
| 40 | extern basist::astc_quant_bin g_astc_sorted_order_unquant[basist::BC7ENC_TOTAL_ASTC_RANGES][256]; // [sorted unquantized order] | 
|---|
| 41 |  | 
|---|
| 42 | struct color_cell_compressor_params | 
|---|
| 43 | { | 
|---|
| 44 | uint32_t m_num_pixels; | 
|---|
| 45 | const basist::color_quad_u8* m_pPixels; | 
|---|
| 46 |  | 
|---|
| 47 | uint32_t m_num_selector_weights; | 
|---|
| 48 | const uint32_t* m_pSelector_weights; | 
|---|
| 49 |  | 
|---|
| 50 | const bc7enc_vec4F* m_pSelector_weightsx; | 
|---|
| 51 | uint32_t m_comp_bits; | 
|---|
| 52 |  | 
|---|
| 53 | const uint8_t *m_pForce_selectors; | 
|---|
| 54 |  | 
|---|
| 55 | // Non-zero m_astc_endpoint_range enables ASTC mode. m_comp_bits and m_has_pbits are always false. We only support 2, 3, or 4 bit weight encodings. | 
|---|
| 56 | uint32_t m_astc_endpoint_range; | 
|---|
| 57 |  | 
|---|
| 58 | uint32_t m_weights[4]; | 
|---|
| 59 | bc7enc_bool m_has_alpha; | 
|---|
| 60 | bc7enc_bool m_has_pbits; | 
|---|
| 61 | bc7enc_bool m_endpoints_share_pbit; | 
|---|
| 62 | bc7enc_bool m_perceptual; | 
|---|
| 63 | }; | 
|---|
| 64 |  | 
|---|
| 65 | struct color_cell_compressor_results | 
|---|
| 66 | { | 
|---|
| 67 | uint64_t m_best_overall_err; | 
|---|
| 68 | basist::color_quad_u8 m_low_endpoint; | 
|---|
| 69 | basist::color_quad_u8 m_high_endpoint; | 
|---|
| 70 | uint32_t m_pbits[2]; | 
|---|
| 71 | uint8_t* m_pSelectors; | 
|---|
| 72 | uint8_t* m_pSelectors_temp; | 
|---|
| 73 |  | 
|---|
| 74 | // Encoded ASTC indices, if ASTC mode is enabled | 
|---|
| 75 | basist::color_quad_u8 m_astc_low_endpoint; | 
|---|
| 76 | basist::color_quad_u8 m_astc_high_endpoint; | 
|---|
| 77 | }; | 
|---|
| 78 |  | 
|---|
| 79 | struct bc7enc_compress_block_params | 
|---|
| 80 | { | 
|---|
| 81 | // m_max_partitions_mode1 may range from 0 (disables mode 1) to BC7ENC_MAX_PARTITIONS1. The higher this value, the slower the compressor, but the higher the quality. | 
|---|
| 82 | uint32_t m_max_partitions_mode1; | 
|---|
| 83 |  | 
|---|
| 84 | // Relative RGBA or YCbCrA weights. | 
|---|
| 85 | uint32_t m_weights[4]; | 
|---|
| 86 |  | 
|---|
| 87 | // m_uber_level may range from 0 to BC7ENC_MAX_UBER_LEVEL. The higher this value, the slower the compressor, but the higher the quality. | 
|---|
| 88 | uint32_t m_uber_level; | 
|---|
| 89 |  | 
|---|
| 90 | // If m_perceptual is true, colorspace error is computed in YCbCr space, otherwise RGB. | 
|---|
| 91 | bc7enc_bool m_perceptual; | 
|---|
| 92 |  | 
|---|
| 93 | uint32_t m_least_squares_passes; | 
|---|
| 94 | }; | 
|---|
| 95 |  | 
|---|
| 96 | uint64_t color_cell_compression(uint32_t mode, const color_cell_compressor_params* pParams, color_cell_compressor_results* pResults, const bc7enc_compress_block_params* pComp_params); | 
|---|
| 97 |  | 
|---|
| 98 | uint64_t color_cell_compression_est_astc( | 
|---|
| 99 | uint32_t num_weights, uint32_t num_comps, const uint32_t* pWeight_table, | 
|---|
| 100 | uint32_t num_pixels, const basist::color_quad_u8* pPixels, | 
|---|
| 101 | uint64_t best_err_so_far, const uint32_t weights[4]); | 
|---|
| 102 |  | 
|---|
| 103 | inline void bc7enc_compress_block_params_init_linear_weights(bc7enc_compress_block_params* p) | 
|---|
| 104 | { | 
|---|
| 105 | p->m_perceptual = BC7ENC_FALSE; | 
|---|
| 106 | p->m_weights[0] = 1; | 
|---|
| 107 | p->m_weights[1] = 1; | 
|---|
| 108 | p->m_weights[2] = 1; | 
|---|
| 109 | p->m_weights[3] = 1; | 
|---|
| 110 | } | 
|---|
| 111 |  | 
|---|
| 112 | inline void bc7enc_compress_block_params_init_perceptual_weights(bc7enc_compress_block_params* p) | 
|---|
| 113 | { | 
|---|
| 114 | p->m_perceptual = BC7ENC_TRUE; | 
|---|
| 115 | p->m_weights[0] = 128; | 
|---|
| 116 | p->m_weights[1] = 64; | 
|---|
| 117 | p->m_weights[2] = 16; | 
|---|
| 118 | p->m_weights[3] = 32; | 
|---|
| 119 | } | 
|---|
| 120 |  | 
|---|
| 121 | inline void bc7enc_compress_block_params_init(bc7enc_compress_block_params* p) | 
|---|
| 122 | { | 
|---|
| 123 | p->m_max_partitions_mode1 = BC7ENC_MAX_PARTITIONS1; | 
|---|
| 124 | p->m_least_squares_passes = 1; | 
|---|
| 125 | p->m_uber_level = 0; | 
|---|
| 126 | bc7enc_compress_block_params_init_perceptual_weights(p); | 
|---|
| 127 | } | 
|---|
| 128 |  | 
|---|
| 129 | // bc7enc_compress_block_init() MUST be called before calling bc7enc_compress_block() (or you'll get artifacts). | 
|---|
| 130 | void bc7enc_compress_block_init(); | 
|---|
| 131 |  | 
|---|
| 132 | } // namespace basisu | 
|---|
| 133 |  | 
|---|