basisu_bc7enc.h 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  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. namespace basisu
  19. {
  20. #define BC7ENC_MAX_PARTITIONS1 (64)
  21. #define BC7ENC_MAX_UBER_LEVEL (4)
  22. typedef uint8_t bc7enc_bool;
  23. #define BC7ENC_TRUE (1)
  24. #define BC7ENC_FALSE (0)
  25. typedef struct { float m_c[4]; } bc7enc_vec4F;
  26. extern const float g_bc7_weights1x[2 * 4];
  27. extern const float g_bc7_weights2x[4 * 4];
  28. extern const float g_bc7_weights3x[8 * 4];
  29. extern const float g_bc7_weights4x[16 * 4];
  30. extern const float g_astc_weights4x[16 * 4];
  31. extern const float g_astc_weights5x[32 * 4];
  32. extern const float g_astc_weights_3levelsx[3 * 4];
  33. extern basist::astc_quant_bin g_astc_sorted_order_unquant[basist::BC7ENC_TOTAL_ASTC_RANGES][256]; // [sorted unquantized order]
  34. struct color_cell_compressor_params
  35. {
  36. uint32_t m_num_pixels;
  37. const basist::color_quad_u8* m_pPixels;
  38. uint32_t m_num_selector_weights;
  39. const uint32_t* m_pSelector_weights;
  40. const bc7enc_vec4F* m_pSelector_weightsx;
  41. uint32_t m_comp_bits;
  42. const uint8_t *m_pForce_selectors;
  43. // 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.
  44. uint32_t m_astc_endpoint_range;
  45. uint32_t m_weights[4];
  46. bc7enc_bool m_has_alpha;
  47. bc7enc_bool m_has_pbits;
  48. bc7enc_bool m_endpoints_share_pbit;
  49. bc7enc_bool m_perceptual;
  50. };
  51. struct color_cell_compressor_results
  52. {
  53. uint64_t m_best_overall_err;
  54. basist::color_quad_u8 m_low_endpoint;
  55. basist::color_quad_u8 m_high_endpoint;
  56. uint32_t m_pbits[2];
  57. uint8_t* m_pSelectors;
  58. uint8_t* m_pSelectors_temp;
  59. // Encoded ASTC indices, if ASTC mode is enabled
  60. basist::color_quad_u8 m_astc_low_endpoint;
  61. basist::color_quad_u8 m_astc_high_endpoint;
  62. };
  63. struct bc7enc_compress_block_params
  64. {
  65. // 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.
  66. uint32_t m_max_partitions_mode1;
  67. // Relative RGBA or YCbCrA weights.
  68. uint32_t m_weights[4];
  69. // 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.
  70. uint32_t m_uber_level;
  71. // If m_perceptual is true, colorspace error is computed in YCbCr space, otherwise RGB.
  72. bc7enc_bool m_perceptual;
  73. uint32_t m_least_squares_passes;
  74. };
  75. 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);
  76. uint64_t color_cell_compression_est_astc(
  77. uint32_t num_weights, uint32_t num_comps, const uint32_t* pWeight_table,
  78. uint32_t num_pixels, const basist::color_quad_u8* pPixels,
  79. uint64_t best_err_so_far, const uint32_t weights[4]);
  80. inline void bc7enc_compress_block_params_init_linear_weights(bc7enc_compress_block_params* p)
  81. {
  82. p->m_perceptual = BC7ENC_FALSE;
  83. p->m_weights[0] = 1;
  84. p->m_weights[1] = 1;
  85. p->m_weights[2] = 1;
  86. p->m_weights[3] = 1;
  87. }
  88. inline void bc7enc_compress_block_params_init_perceptual_weights(bc7enc_compress_block_params* p)
  89. {
  90. p->m_perceptual = BC7ENC_TRUE;
  91. p->m_weights[0] = 128;
  92. p->m_weights[1] = 64;
  93. p->m_weights[2] = 16;
  94. p->m_weights[3] = 32;
  95. }
  96. inline void bc7enc_compress_block_params_init(bc7enc_compress_block_params* p)
  97. {
  98. p->m_max_partitions_mode1 = BC7ENC_MAX_PARTITIONS1;
  99. p->m_least_squares_passes = 1;
  100. p->m_uber_level = 0;
  101. bc7enc_compress_block_params_init_perceptual_weights(p);
  102. }
  103. // bc7enc_compress_block_init() MUST be called before calling bc7enc_compress_block() (or you'll get artifacts).
  104. void bc7enc_compress_block_init();
  105. } // namespace basisu