godot/thirdparty/basis_universal/encoder/basisu_enc.h

// basisu_enc.h
// Copyright (C) 2019-2024 Binomial LLC. All Rights Reserved.
//
// 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.
#pragma once
#include "../transcoder/basisu.h"
#include "../transcoder/basisu_transcoder_internal.h"

#include <mutex>
#include <atomic>
#include <condition_variable>
#include <functional>
#include <thread>
#include <unordered_map>
#include <ostream>

#if !defined(_WIN32) || defined(__MINGW32__)
#include <libgen.h>
#endif

// This module is really just a huge grab bag of classes and helper functions needed by the encoder.

// If BASISU_USE_HIGH_PRECISION_COLOR_DISTANCE is 1, quality in perceptual mode will be slightly greater, but at a large increase in encoding CPU time.
#define BASISU_USE_HIGH_PRECISION_COLOR_DISTANCE

#if BASISU_SUPPORT_SSE
// Declared in basisu_kernels_imp.h, but we can't include that here otherwise it would lead to circular type errors.
extern void update_covar_matrix_16x16_sse41(uint32_t num_vecs, const void* pWeighted_vecs, const void* pOrigin, const uint32_t *pVec_indices, void* pMatrix16x16);
#endif

namespace basisu
{
	extern uint8_t g_hamming_dist[256];
	extern const uint8_t g_debug_font8x8_basic[127 - 32 + 1][8];

	// true if basisu_encoder_init() has been called and returned.
	extern bool g_library_initialized;

	// Encoder library initialization.
	// This function MUST be called before encoding anything!
	// Returns false if library initialization fails.
	bool basisu_encoder_init(bool use_opencl = false, bool opencl_force_serialization = false);
	void basisu_encoder_deinit();

	// basisu_kernels_sse.cpp - will be a no-op and g_cpu_supports_sse41 will always be false unless compiled with BASISU_SUPPORT_SSE=1
	extern void detect_sse41();

#if BASISU_SUPPORT_SSE
	extern bool g_cpu_supports_sse41;
#else
	const bool g_cpu_supports_sse41 =;
#endif

	void error_vprintf(const char* pFmt, va_list args);
	void error_printf(const char *pFmt, ...);
	
	// Helpers

	inline uint8_t clamp255(int32_t i)
	{}

	inline int left_shift32(int val, int shift)
	{}

	inline uint32_t left_shift32(uint32_t val, int shift)
	{}

	inline int32_t clampi(int32_t value, int32_t low, int32_t high) 
	{}

	inline uint8_t mul_8(uint32_t v, uint32_t a)
	{}

	inline uint64_t read_bits(const uint8_t* pBuf, uint32_t& bit_offset, uint32_t codesize)
	{}

	inline uint32_t read_bits32(const uint8_t* pBuf, uint32_t& bit_offset, uint32_t codesize)
	{}
		
	// Open interval
	inline int bounds_check(int v, int l, int h) {}
	inline uint32_t bounds_check(uint32_t v, uint32_t l, uint32_t h) {}

	// Closed interval
	inline int bounds_check_incl(int v, int l, int h) {}
	inline uint32_t bounds_check_incl(uint32_t v, uint32_t l, uint32_t h) {}

	inline uint32_t clz(uint32_t x)
	{}

	bool string_begins_with(const std::string& str, const char* pPhrase);
				
	// Hashing
	
	inline uint32_t bitmix32c(uint32_t v) 
	{}

	inline uint32_t bitmix32(uint32_t v) 
	{}

	inline uint32_t wang_hash(uint32_t seed)
	{}

	uint32_t hash_hsieh(const uint8_t* pBuf, size_t len);

	template <typename Key>
	struct bit_hasher
	{};

	class running_stat
	{};

	// Linear algebra

	template <uint32_t N, typename T>
	class vec
	{};

	vec4D;
	vec3D;
	vec2D;
	vec1D;

	vec4F;
	vec3F;
	vec2F;
	vec1F;

	vec16F;
		
	template <uint32_t Rows, uint32_t Cols, typename T>
	class matrix
	{};

	template<uint32_t N, typename VectorType>
	inline VectorType compute_pca_from_covar(matrix<N, N, float> &cmatrix)
	{}

	template<typename T> inline void indirect_sort(uint32_t num_indices, uint32_t* pIndices, const T* pKeys)
	{}

	// 1-4 byte direct Radix sort.
	template <typename T>
	T* radix_sort(uint32_t num_vals, T* pBuf0, T* pBuf1, uint32_t key_ofs, uint32_t key_size)
	{}

#undef BASISU_GET_KEY
	
	// Very simple job pool with no dependencies.
	class job_pool
	{};

	// Simple 64-bit color class

	class color_rgba_i16
	{};
				
	class color_rgba
	{};

	color_rgba_vec;

	const color_rgba g_black_color(0, 0, 0, 255);
	const color_rgba g_black_trans_color(0, 0, 0, 0);
	const color_rgba g_white_color(255, 255, 255, 255);

	inline int color_distance(int r0, int g0, int b0, int r1, int g1, int b1)
	{}

	inline int color_distance(int r0, int g0, int b0, int a0, int r1, int g1, int b1, int a1)
	{}

	inline int color_distance(const color_rgba &c0, const color_rgba &c1, bool alpha)
	{}
		
	// TODO: Allow user to control channel weightings.
	inline uint32_t color_distance(bool perceptual, const color_rgba &e1, const color_rgba &e2, bool alpha)
	{}

	static inline uint32_t color_distance_la(const color_rgba& a, const color_rgba& b)
	{}

	// String helpers

	inline int string_find_right(const std::string& filename, char c)
	{}

	inline std::string string_get_extension(const std::string &filename)
	{}

	inline bool string_remove_extension(std::string &filename)
	{}

	inline std::string string_format(const char* pFmt, ...)
	{}

	inline std::string string_tolower(const std::string& s)
	{}

	inline char *strcpy_safe(char *pDst, size_t dst_len, const char *pSrc)
	{}

	inline bool string_ends_with(const std::string& s, char c)
	{}

	inline bool string_split_path(const char *p, std::string *pDrive, std::string *pDir, std::string *pFilename, std::string *pExt)
	{}

	inline bool is_path_separator(char c)
	{}
		
	inline bool is_drive_separator(char c)
	{}

	inline void string_combine_path(std::string &dst, const char *p, const char *q)
	{}

	inline void string_combine_path(std::string &dst, const char *p, const char *q, const char *r)
	{}
		
	inline void string_combine_path_and_extension(std::string &dst, const char *p, const char *q, const char *r, const char *pExt)
	{}

	inline bool string_get_pathname(const char *p, std::string &path)
	{}

	inline bool string_get_filename(const char *p, std::string &filename)
	{}

	class rand
	{};

	class priority_queue
	{};

	// Tree structured vector quantization (TSVQ)

	template <typename TrainingVectorType>
	class tree_vector_quant
	{};

	struct weighted_block_group
	{};

	template<typename Quantizer>
	bool generate_hierarchical_codebook_threaded_internal(Quantizer& q,
		uint32_t max_codebook_size, uint32_t max_parent_codebook_size,
		basisu::vector<uint_vec>& codebook,
		basisu::vector<uint_vec>& parent_codebook,
		uint32_t max_threads, bool limit_clusterizers, job_pool *pJob_pool)
	{}

	template<typename Quantizer>
	bool generate_hierarchical_codebook_threaded(Quantizer& q,
		uint32_t max_codebook_size, uint32_t max_parent_codebook_size,
		basisu::vector<uint_vec>& codebook,
		basisu::vector<uint_vec>& parent_codebook,
		uint32_t max_threads, job_pool *pJob_pool,
		bool even_odd_input_pairs_equal)
	{}

	// Canonical Huffman coding

	class histogram
	{};
		
	struct sym_freq
	{};

	sym_freq *canonical_huffman_radix_sort_syms(uint32_t num_syms, sym_freq *pSyms0, sym_freq *pSyms1);
	void canonical_huffman_calculate_minimum_redundancy(sym_freq *A, int num_syms);
	void canonical_huffman_enforce_max_code_size(int *pNum_codes, int code_list_len, int max_code_size);
	
	class huffman_encoding_table
	{};

	class bitwise_coder
	{};

	class huff2D
	{};

	bool huffman_test(int rand_seed);

	// VQ index reordering
	
	class palette_index_reorderer
	{};

	// Simple 32-bit 2D image class

	class image
	{};

	// Float images

	vec4F_vec;

	class imagef
	{};

	// REC 709 coefficients
	const float REC_709_R =, REC_709_G =, REC_709_B =;

	inline float get_luminance(const vec4F &c)
	{}

	float linear_to_srgb(float l);
	float srgb_to_linear(float s);

	// Image metrics
		
	class image_metrics
	{};

	// Image saving/loading/resampling

	bool load_png(const uint8_t* pBuf, size_t buf_size, image& img, const char* pFilename = nullptr);
	bool load_png(const char* pFilename, image& img);
	inline bool load_png(const std::string &filename, image &img) {}

	bool load_tga(const char* pFilename, image& img);
	inline bool load_tga(const std::string &filename, image &img) {}

	bool load_qoi(const char* pFilename, image& img);

	bool load_jpg(const char *pFilename, image& img);
	inline bool load_jpg(const std::string &filename, image &img) {}
	
	// Currently loads .PNG, .TGA, or .JPG
	bool load_image(const char* pFilename, image& img);
	inline bool load_image(const std::string &filename, image &img) {}

	// Supports .HDR and most (but not all) .EXR's (see TinyEXR).
	bool load_image_hdr(const char* pFilename, imagef& img, bool ldr_srgb_to_linear = true);
	inline bool load_image_hdr(const std::string& filename, imagef& img, bool ldr_srgb_to_linear = true) {}

	enum class hdr_image_type
	{};

	bool load_image_hdr(const void* pMem, size_t mem_size, imagef& img, uint32_t width, uint32_t height, hdr_image_type img_type, bool ldr_srgb_to_linear);

	uint8_t *read_tga(const uint8_t *pBuf, uint32_t buf_size, int &width, int &height, int &n_chans);
	uint8_t *read_tga(const char *pFilename, int &width, int &height, int &n_chans);
		
	struct rgbe_header_info
	{};

	bool read_rgbe(const uint8_vec& filedata, imagef& img, rgbe_header_info& hdr_info);
	bool read_rgbe(const char* pFilename, imagef& img, rgbe_header_info &hdr_info);

	bool write_rgbe(uint8_vec& file_data, imagef& img, rgbe_header_info& hdr_info);
	bool write_rgbe(const char* pFilename, imagef& img, rgbe_header_info& hdr_info);

	bool read_exr(const char* pFilename, imagef& img, int& n_chans);
	bool read_exr(const void* pMem, size_t mem_size, imagef& img);
	
	enum
	{};

	// Supports 1 (Y), 3 (RGB), or 4 (RGBA) channel images.
	bool write_exr(const char* pFilename, imagef& img, uint32_t n_chans, uint32_t flags);
			
	enum
	{};

	bool save_png(const char* pFilename, const image& img, uint32_t image_save_flags = 0, uint32_t grayscale_comp = 0);
	inline bool save_png(const std::string &filename, const image &img, uint32_t image_save_flags = 0, uint32_t grayscale_comp = 0) {}
	
	bool read_file_to_vec(const char* pFilename, uint8_vec& data);
	bool read_file_to_data(const char* pFilename, void *pData, size_t len);	

	bool write_data_to_file(const char* pFilename, const void* pData, size_t len);
	
	inline bool write_vec_to_file(const char* pFilename, const uint8_vec& v) {}
		
	bool image_resample(const image &src, image &dst, bool srgb = false,
		const char *pFilter = "lanczos4", float filter_scale = 1.0f, 
		bool wrapping = false,
		uint32_t first_comp = 0, uint32_t num_comps = 4);

	bool image_resample(const imagef& src, imagef& dst, 
		const char* pFilter = "lanczos4", float filter_scale = 1.0f,
		bool wrapping = false,
		uint32_t first_comp = 0, uint32_t num_comps = 4);
		
	// Timing
			
	timer_ticks;

	class interval_timer
	{};

	inline double get_interval_timer() {}

	// 2D array

	template<typename T>
	class vector2D
	{};

	inline FILE *fopen_safe(const char *pFilename, const char *pMode)
	{}

	void fill_buffer_with_random_bytes(void *pBuf, size_t size, uint32_t seed = 1);

	const uint32_t cPixelBlockWidth =;
	const uint32_t cPixelBlockHeight =;
	const uint32_t cPixelBlockTotalPixels =;

	struct pixel_block
	{};
	pixel_block_vec;

	struct pixel_block_hdr
	{};
	pixel_block_hdr_vec;

	void tonemap_image_reinhard(image& ldr_img, const imagef& hdr_img, float exposure);
	bool tonemap_image_compressive(image& dst_img, const imagef& hdr_test_img);
	
	// Intersection
	enum eClear {};
	enum eInitExpand {};

	template<typename vector_type>
	class ray
	{};

	ray2F;
	ray3F;

	template<typename T>
	class vec_interval
	{};

	vec_interval1F;
	vec_interval2F;
	vec_interval3F;
	vec_interval4F;

	aabb2F;
	aabb3F;

	namespace intersection
	{
		enum result
		{};

		// Returns cInside, cSuccess, or cFailure.
		// Algorithm: Graphics Gems 1
		template<typename vector_type, typename scalar_type, typename ray_type, typename aabb_type>
		result ray_aabb(vector_type& coord, scalar_type& t, const ray_type& ray, const aabb_type& box)
		{}

		template<typename vector_type, typename scalar_type, typename ray_type, typename aabb_type>
		result ray_aabb(bool& started_within, vector_type& coord, scalar_type& t, const ray_type& ray, const aabb_type& box)
		{}

	} // intersect

	// This float->half conversion matches how "F32TO16" works on Intel GPU's.
	// Input cannot be negative, Inf or Nan.
	inline basist::half_float float_to_half_non_neg_no_nan_inf(float val)
	{}

	// Supports positive and denormals only. No NaN or Inf.
	inline float fast_half_to_float_pos_not_inf_or_nan(basist::half_float h)
	{}
				
} // namespace basisu