// basisu_enc.h
// Copyright (C) 2019-2026 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 <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_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];
	extern float g_srgb_to_linear_table[256]; // sRGB EOTF->linear light [0,1], 1=~100 nits

	// 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 bool g_cpu_supports_sse41;

	extern void detect_sse41();
		
	void error_vprintf(const char* pFmt, va_list args);
	void error_printf(const char *pFmt, ...);
	
	template <typename... Args>
	inline void fmt_error_printf(const char* pFmt, Args&&... args)
	{
		std::string res;
		if (!fmt_variants(res, pFmt, fmt_variant_vec{ fmt_variant(std::forward<Args>(args))... }))
			return;
		error_printf("%s", res.c_str());
	}

	void platform_sleep(uint32_t ms);
	
	// Helpers
	inline uint8_t clamp255(int32_t i)
	{
		return (uint8_t)((i & 0xFFFFFF00U) ? (~(i >> 31)) : i);
	}

	inline int left_shift32(int val, int shift)
	{
		assert((shift >= 0) && (shift < 32));
		return static_cast<int>(static_cast<uint32_t>(val) << shift);
	}

	inline uint32_t left_shift32(uint32_t val, int shift)
	{
		assert((shift >= 0) && (shift < 32));
		return val << shift;
	}

	inline int32_t clampi(int32_t value, int32_t low, int32_t high) 
	{ 
		if (value < low) 
			value = low; 
		else if (value > high) 
			value = high; 
		return value; 
	}

	inline uint8_t mul_8(uint32_t v, uint32_t a)
	{
		v = v * a + 128; 
		return (uint8_t)((v + (v >> 8)) >> 8);
	}

	inline int fast_roundf_pos_int(float x)
	{
		assert(x >= 0.0f);
		return (int)(x + 0.5f);
	}

	// basic float to int (float_to_int) with rounding without std::roundf overhead
	inline int fast_roundf_int(float x)
	{
		return (x >= 0.0f) ? (int)(x + 0.5f) : (int)(x - 0.5f);
	}

	inline int fast_floorf_int(float x)
	{
		int xi = (int)x;  // Truncate towards zero
		return ((x < 0.0f) && (x != (float)xi)) ? (xi - 1) : xi;
	}

	inline uint32_t extract_bits(uint32_t val, uint32_t ofs, uint32_t len)
	{
		assert((len) && (len < 32) && ((ofs + len) <= 32));
		return (val >> ofs) & ((1u << len) - 1u);
	}

	inline uint64_t read_bits(const uint8_t* pBuf, uint32_t& bit_offset, uint32_t codesize)
	{
		assert(codesize <= 64);
		uint64_t bits = 0;
		uint32_t total_bits = 0;

		while (total_bits < codesize)
		{
			uint32_t byte_bit_offset = bit_offset & 7;
			uint32_t bits_to_read = minimum<int>(codesize - total_bits, 8 - byte_bit_offset);

			uint32_t byte_bits = pBuf[bit_offset >> 3] >> byte_bit_offset;
			byte_bits &= ((1 << bits_to_read) - 1);

			bits |= ((uint64_t)(byte_bits) << total_bits);

			total_bits += bits_to_read;
			bit_offset += bits_to_read;
		}

		return bits;
	}

	inline uint32_t read_bits32(const uint8_t* pBuf, uint32_t& bit_offset, uint32_t codesize)
	{
		assert(codesize <= 32);
		uint32_t bits = 0;
		uint32_t total_bits = 0;

		while (total_bits < codesize)
		{
			uint32_t byte_bit_offset = bit_offset & 7;
			uint32_t bits_to_read = minimum<int>(codesize - total_bits, 8 - byte_bit_offset);

			uint32_t byte_bits = pBuf[bit_offset >> 3] >> byte_bit_offset;
			byte_bits &= ((1 << bits_to_read) - 1);

			bits |= (byte_bits << total_bits);

			total_bits += bits_to_read;
			bit_offset += bits_to_read;
		}

		return bits;
	}
		
	// Open interval
	inline int bounds_check(int v, int l, int h) { (void)v; (void)l; (void)h; assert(v >= l && v < h); return v; }
	inline uint32_t bounds_check(uint32_t v, uint32_t l, uint32_t h) { (void)v; (void)l; (void)h; assert(v >= l && v < h); return v; }

	// Closed interval
	inline int bounds_check_incl(int v, int l, int h) { (void)v; (void)l; (void)h; assert(v >= l && v <= h); return v; }
	inline uint32_t bounds_check_incl(uint32_t v, uint32_t l, uint32_t h) { (void)v; (void)l; (void)h; assert(v >= l && v <= h); return v; }

	inline bool equal_abs_tol(float a, float b, float rel_tol)
	{
		return fabsf(a - b) <= rel_tol;
	}

	inline bool equal_abs_tol(double a, double b, double rel_tol)
	{
		return fabs(a - b) <= rel_tol;
	}

	inline bool equal_rel_tol(float a, float b, float rel_tol)
	{
		const float diff = fabsf(a - b);
		const float max_abs = basisu::maximum<float>(fabsf(a), fabsf(b));
		return diff <= (rel_tol * basisu::maximum(1.0f, max_abs)); // near 0 use abs tol
	}

	inline bool equal_rel_tol(double a, double b, double rel_tol)
	{
		const double diff = fabs(a - b);
		const double max_abs = basisu::maximum<double>(fabs(a), fabs(b));
		return diff <= (rel_tol * basisu::maximum<double>(1.0f, max_abs)); // near 0 use abs tol
	}

	inline uint32_t clz(uint32_t x)
	{
		if (!x)
			return 32;

		uint32_t n = 0;
		while ((x & 0x80000000) == 0)
		{
			x <<= 1u;
			n++;
		}

		return n;
	}

	bool string_begins_with(const std::string& str, const char* pPhrase);

	// Case sensitive, returns -1 if can't find
	inline int string_find_first(const std::string& str, const char* pPhrase)
	{
		size_t res = str.find(pPhrase, 0);
		if (res == std::string::npos)
			return -1;
		return (int)res;
	}
				
	// Hashing
	
	inline uint32_t bitmix32c(uint32_t v) 
	{
		v = (v + 0x7ed55d16) + (v << 12);
		v = (v ^ 0xc761c23c) ^ (v >> 19);
		v = (v + 0x165667b1) + (v << 5);
		v = (v + 0xd3a2646c) ^ (v << 9);
		v = (v + 0xfd7046c5) + (v << 3);
		v = (v ^ 0xb55a4f09) ^ (v >> 16);
		return v;
	}

	inline uint32_t bitmix32(uint32_t v) 
	{
		v -= (v << 6);
		v ^= (v >> 17);
		v -= (v << 9);
		v ^= (v << 4);
		v -= (v << 3);
		v ^= (v << 10);
		v ^= (v >> 15);
		return v;
	}

	inline uint32_t wang_hash(uint32_t seed)
	{
		 seed = (seed ^ 61) ^ (seed >> 16);
		 seed *= 9;
		 seed = seed ^ (seed >> 4);
		 seed *= 0x27d4eb2d;
		 seed = seed ^ (seed >> 15);
		 return seed;
	}
	
	class running_stat
	{
	public:
		running_stat() { clear(); }

		void clear()
		{
			m_n = 0;
			m_total = 0;
			m_old_m = 0;
			m_new_m = 0;
			m_old_s = 0;
			m_new_s = 0;
			m_min = 0;
			m_max = 0;
		}

		void push(double x)
		{
			m_n++;
			m_total += x;
			if (m_n == 1)
			{
				m_old_m = m_new_m = x;
				m_old_s = 0.0;
				m_min = x;
				m_max = x;
			}
			else
			{
				// See Knuth TAOCP vol 2, 3rd edition, page 232
				m_new_m = m_old_m + (x - m_old_m) / m_n;
				m_new_s = m_old_s + (x - m_old_m) * (x - m_new_m);
				m_old_m = m_new_m;
				m_old_s = m_new_s;
				m_min = basisu::minimum(x, m_min);
				m_max = basisu::maximum(x, m_max);
			}
		}

		uint32_t get_num() const
		{
			return m_n;
		}

		double get_total() const
		{
			return m_total;
		}

		double get_mean() const
		{
			return (m_n > 0) ? m_new_m : 0.0;
		}

		// Returns sample variance
		double get_variance() const
		{
			return ((m_n > 1) ? m_new_s / (m_n - 1) : 0.0);
		}

		double get_std_dev() const
		{
			return sqrt(get_variance());
		}

		double get_min() const
		{
			return m_min;
		}

		double get_max() const
		{
			return m_max;
		}

	private:
		uint32_t m_n;
		double m_total, m_old_m, m_new_m, m_old_s, m_new_s, m_min, m_max;
	};

	// Linear algebra
			
	template <uint32_t N, typename T>
	class vec
	{
	protected:
		T m_v[N];

	public:
		enum { num_elements = N };
		typedef T scalar_type;

		inline vec() { }
		inline vec(eZero) { set_zero();  }

		explicit inline vec(T val) { set(val); }
		inline vec(T v0, T v1) { set(v0, v1); }
		inline vec(T v0, T v1, T v2) { set(v0, v1, v2); }
		inline vec(T v0, T v1, T v2, T v3) { set(v0, v1, v2, v3); }
		inline vec(const vec &other) { for (uint32_t i = 0; i < N; i++) m_v[i] = other.m_v[i]; }
		template <uint32_t OtherN, typename OtherT> inline vec(const vec<OtherN, OtherT> &other) { set(other); }

		inline const T& operator[](uint32_t i) const { assert(i < N); return m_v[i]; }
		inline T &operator[](uint32_t i) { assert(i < N); return m_v[i]; }

		inline T getX() const { return m_v[0]; }
		inline T getY() const { static_assert(N >= 2, "N too small"); return m_v[1]; }
		inline T getZ() const { static_assert(N >= 3, "N too small"); return m_v[2]; }
		inline T getW() const { static_assert(N >= 4, "N too small"); return m_v[3]; }

		inline bool operator==(const vec &rhs) const { for (uint32_t i = 0; i < N; i++) if (m_v[i] != rhs.m_v[i]) return false;	return true; }
		inline bool operator!=(const vec& rhs) const { return !(*this == rhs); }
		inline bool operator<(const vec &rhs) const { for (uint32_t i = 0; i < N; i++) { if (m_v[i] < rhs.m_v[i]) return true; else if (m_v[i] != rhs.m_v[i]) return false; } return false; }

		inline void set_zero() { for (uint32_t i = 0; i < N; i++) m_v[i] = 0; }
		inline void clear() { set_zero(); }

		template <uint32_t OtherN, typename OtherT>
		inline vec &set(const vec<OtherN, OtherT> &other)
		{
			uint32_t i;
			if ((const void *)(&other) == (const void *)(this))
				return *this;
			const uint32_t m = minimum(OtherN, N);
			for (i = 0; i < m; i++)
				m_v[i] = static_cast<T>(other[i]);
			for (; i < N; i++)
				m_v[i] = 0;
			return *this;
		}

		inline vec &set_component(uint32_t index, T val) { assert(index < N); m_v[index] = val; return *this; }
		inline vec &set(T val) { for (uint32_t i = 0; i < N; i++) m_v[i] = val; return *this; }
		inline void clear_elements(uint32_t s, uint32_t e) { assert(e <= N); for (uint32_t i = s; i < e; i++) m_v[i] = 0; }

		inline vec &set(T v0, T v1)
		{
			m_v[0] = v0;
			if (N >= 2)
			{
				m_v[1] = v1;
				clear_elements(2, N);
			}
			return *this;
		}

		inline vec &set(T v0, T v1, T v2)
		{
			m_v[0] = v0;
			if (N >= 2)
			{
				m_v[1] = v1;
				if (N >= 3)
				{
					m_v[2] = v2;
					clear_elements(3, N);
				}
			}
			return *this;
		}

		inline vec &set(T v0, T v1, T v2, T v3)
		{
			m_v[0] = v0;
			if (N >= 2)
			{
				m_v[1] = v1;
				if (N >= 3)
				{
					m_v[2] = v2;

					if (N >= 4)
					{
						m_v[3] = v3;
						clear_elements(5, N);
					}
				}
			}
			return *this;
		}

		inline vec &operator=(const vec &rhs) { if (this != &rhs) for (uint32_t i = 0; i < N; i++) m_v[i] = rhs.m_v[i]; return *this; }
		template <uint32_t OtherN, typename OtherT> inline vec &operator=(const vec<OtherN, OtherT> &rhs) { set(rhs); return *this; }

		inline const T *get_ptr() const { return reinterpret_cast<const T *>(&m_v[0]); }
		inline T *get_ptr() { return reinterpret_cast<T *>(&m_v[0]); }
		
		inline vec operator- () const { vec res; for (uint32_t i = 0; i < N; i++) res.m_v[i] = -m_v[i]; return res; }
		inline vec operator+ () const { return *this; }
		inline vec &operator+= (const vec &other) { for (uint32_t i = 0; i < N; i++) m_v[i] += other.m_v[i]; return *this; }
		inline vec &operator-= (const vec &other) { for (uint32_t i = 0; i < N; i++) m_v[i] -= other.m_v[i]; return *this; }
		inline vec &operator/= (const vec &other) { for (uint32_t i = 0; i < N; i++) m_v[i] /= other.m_v[i]; return *this; }
		inline vec &operator*=(const vec &other) { for (uint32_t i = 0; i < N; i++) m_v[i] *= other.m_v[i]; return *this; }
		inline vec &operator/= (T s) { for (uint32_t i = 0; i < N; i++) m_v[i] /= s; return *this; }
		inline vec &operator*= (T s) { for (uint32_t i = 0; i < N; i++) m_v[i] *= s; return *this; }
		
		friend inline vec operator+(const vec &lhs, const vec &rhs) { vec res; for (uint32_t i = 0; i < N; i++) res.m_v[i] = lhs.m_v[i] + rhs.m_v[i]; return res; }
		friend inline vec operator-(const vec &lhs, const vec &rhs) { vec res; for (uint32_t i = 0; i < N; i++) res.m_v[i] = lhs.m_v[i] - rhs.m_v[i]; return res; }
		friend inline vec operator*(const vec &lhs, T val) { vec res; for (uint32_t i = 0; i < N; i++) res.m_v[i] = lhs.m_v[i] * val; return res; }
		friend inline vec operator*(T val, const vec &rhs) { vec res; for (uint32_t i = 0; i < N; i++) res.m_v[i] = val * rhs.m_v[i]; return res; }
		friend inline vec operator/(const vec &lhs, T val) { vec res; for (uint32_t i = 0; i < N; i++) res.m_v[i] = lhs.m_v[i] / val; return res; }
		friend inline vec operator/(const vec &lhs, const vec &rhs) { vec res; for (uint32_t i = 0; i < N; i++) res.m_v[i] = lhs.m_v[i] / rhs.m_v[i]; return res; }
		
		static inline T dot_product(const vec &lhs, const vec &rhs) { T res = lhs.m_v[0] * rhs.m_v[0]; for (uint32_t i = 1; i < N; i++) res += lhs.m_v[i] * rhs.m_v[i]; return res; }
		static inline T dot_product3(const vec& lhs, const vec& rhs) { T res = lhs.m_v[0] * rhs.m_v[0]; for (uint32_t i = 1; i < minimum<uint32_t>(3u, N); i++) res += lhs.m_v[i] * rhs.m_v[i]; return res; }

		inline T dot(const vec &rhs) const { return dot_product(*this, rhs); }
		inline T dot3(const vec& rhs) const { return dot_product3(*this, rhs); }

		inline T norm() const { return dot_product(*this, *this); }
		inline T length() const { return sqrt(norm()); }

		inline T squared_distance(const vec &other) const { T d2 = 0; for (uint32_t i = 0; i < N; i++) { T d = m_v[i] - other.m_v[i]; d2 += d * d; } return d2; }
		inline double squared_distance_d(const vec& other) const { double d2 = 0; for (uint32_t i = 0; i < N; i++) { double d = (double)m_v[i] - (double)other.m_v[i]; d2 += d * d; } return d2; }

		inline T distance(const vec &other) const { return static_cast<T>(sqrt(squared_distance(other))); }
		inline double distance_d(const vec& other) const { return sqrt(squared_distance_d(other)); }

		inline vec &normalize_in_place() { T len = length(); if (len != 0.0f) *this *= (1.0f / len); return *this; }

		inline vec get_normalized() const { vec res(*this); res.normalize_in_place(); return res; }

		inline vec &clamp(T l, T h)
		{
			for (uint32_t i = 0; i < N; i++)
				m_v[i] = basisu::clamp(m_v[i], l, h);
			return *this;
		}

		static vec component_mul(const vec& a, const vec& b)
		{
			vec res;
			for (uint32_t i = 0; i < N; i++)
				res[i] = a[i] * b[i];
			return res;
		}

		static vec component_min(const vec& a, const vec& b)
		{
			vec res;
			for (uint32_t i = 0; i < N; i++)
				res[i] = minimum(a[i], b[i]);
			return res;
		}

		static vec component_max(const vec& a, const vec& b)
		{
			vec res;
			for (uint32_t i = 0; i < N; i++)
				res[i] = maximum(a[i], b[i]);
			return res;
		}

		static vec component_sqrt(const vec& a)
		{
			vec res;
			for (uint32_t i = 0; i < N; i++)
				res[i] = sqrt(a[i]);
			return res;
		}

		static vec lerp(const vec& a, const vec& b, float s)
		{
			vec res;
			for (uint32_t i = 0; i < N; i++)
				res[i] = basisu::lerp(a[i], b[i], s);
			return res;
		}
	};

	typedef vec<4, double> vec4D;
	typedef vec<3, double> vec3D;
	typedef vec<2, double> vec2D;
	typedef vec<1, double> vec1D;

	typedef vec<6, float> vec6F;
	typedef vec<5, float> vec5F;
	typedef vec<4, float> vec4F;
	typedef vec<3, float> vec3F;
	typedef vec<2, float> vec2F;
	typedef vec<1, float> vec1F;

	typedef vec<16, float> vec16F;

	template<uint32_t N, typename T> struct bitwise_copyable< vec<N, T> > { enum { cFlag = true }; };
	template<uint32_t N, typename T> struct bitwise_movable< vec<N, T> > { enum { cFlag = true }; };
		
	template <uint32_t Rows, uint32_t Cols, typename T>
	class matrix
	{
	public:
		typedef vec<Rows, T> col_vec;
		typedef vec<Cols, T> row_vec;

		typedef T scalar_type;

		enum { rows = Rows, cols = Cols };

	protected:
		row_vec m_r[Rows];

	public:
		inline matrix() {}
		inline matrix(eZero) { set_zero();  }
		inline matrix(const matrix &other) { for (uint32_t i = 0; i < Rows; i++) m_r[i] = other.m_r[i];	}
		inline matrix &operator=(const matrix &rhs) { if (this != &rhs) for (uint32_t i = 0; i < Rows; i++) m_r[i] = rhs.m_r[i]; return *this; }

		inline T operator()(uint32_t r, uint32_t c) const { assert((r < Rows) && (c < Cols)); return m_r[r][c]; }
		inline T &operator()(uint32_t r, uint32_t c) { assert((r < Rows) && (c < Cols)); return m_r[r][c]; }

		inline const row_vec &operator[](uint32_t r) const { assert(r < Rows); return m_r[r]; }
		inline row_vec &operator[](uint32_t r) { assert(r < Rows); return m_r[r]; }

		inline matrix &set_zero()
		{
			for (uint32_t i = 0; i < Rows; i++)
				m_r[i].set_zero();
			return *this;
		}

		inline matrix &set_identity()
		{
			for (uint32_t i = 0; i < Rows; i++)
			{
				m_r[i].set_zero();
				if (i < Cols)
					m_r[i][i] = 1.0f;
			}
			return *this;
		}
	};

	template<uint32_t R, uint32_t C, typename T> struct bitwise_copyable< matrix<R, C, T> > { enum { cFlag = true }; };
	template<uint32_t R, uint32_t C, typename T> struct bitwise_movable< matrix<R, C, T> > { enum { cFlag = true }; };

	template<uint32_t N, typename VectorType>
	inline VectorType compute_pca_from_covar(matrix<N, N, float> &cmatrix)
	{
		VectorType axis;
		if (N == 1)
			axis.set(1.0f);
		else
		{
			for (uint32_t i = 0; i < N; i++)
				axis[i] = lerp(.75f, 1.25f, i * (1.0f / maximum<int>(N - 1, 1)));
		}

		VectorType prev_axis(axis);

		// Power iterations
		for (uint32_t power_iter = 0; power_iter < 8; power_iter++)
		{
			VectorType trial_axis;
			double max_sum = 0;

			for (uint32_t i = 0; i < N; i++)
			{
				double sum = 0;
				for (uint32_t j = 0; j < N; j++)
					sum += cmatrix[i][j] * axis[j];

				trial_axis[i] = static_cast<float>(sum);

				max_sum = maximum(fabs(sum), max_sum);
			}

			if (max_sum != 0.0f)
				trial_axis *= static_cast<float>(1.0f / max_sum);

			VectorType delta_axis(prev_axis - trial_axis);

			prev_axis = axis;
			axis = trial_axis;

			if (delta_axis.norm() < .0024f)
				break;
		}

		return axis.normalize_in_place();
	}

	template<typename T> inline void indirect_sort(uint32_t num_indices, uint32_t* pIndices, const T* pKeys)
	{
		for (uint32_t i = 0; i < num_indices; i++)
			pIndices[i] = i;

		std::sort(
			pIndices,
			pIndices + num_indices,
			[pKeys](uint32_t a, uint32_t b) { return pKeys[a] < pKeys[b]; }
		);
	}

	// 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)
	{
		assert(key_ofs < sizeof(T));
		assert((key_size >= 1) && (key_size <= 4));

		uint32_t hist[256 * 4];

		memset(hist, 0, sizeof(hist[0]) * 256 * key_size);

#define BASISU_GET_KEY(p) (*(uint32_t *)((uint8_t *)(p) + key_ofs))

		if (key_size == 4)
		{
			T* p = pBuf0;
			T* q = pBuf0 + num_vals;
			for (; p != q; p++)
			{
				const uint32_t key = BASISU_GET_KEY(p);

				hist[key & 0xFF]++;
				hist[256 + ((key >> 8) & 0xFF)]++;
				hist[512 + ((key >> 16) & 0xFF)]++;
				hist[768 + ((key >> 24) & 0xFF)]++;
			}
		}
		else if (key_size == 3)
		{
			T* p = pBuf0;
			T* q = pBuf0 + num_vals;
			for (; p != q; p++)
			{
				const uint32_t key = BASISU_GET_KEY(p);

				hist[key & 0xFF]++;
				hist[256 + ((key >> 8) & 0xFF)]++;
				hist[512 + ((key >> 16) & 0xFF)]++;
			}
		}
		else if (key_size == 2)
		{
			T* p = pBuf0;
			T* q = pBuf0 + (num_vals >> 1) * 2;

			for (; p != q; p += 2)
			{
				const uint32_t key0 = BASISU_GET_KEY(p);
				const uint32_t key1 = BASISU_GET_KEY(p + 1);

				hist[key0 & 0xFF]++;
				hist[256 + ((key0 >> 8) & 0xFF)]++;

				hist[key1 & 0xFF]++;
				hist[256 + ((key1 >> 8) & 0xFF)]++;
			}

			if (num_vals & 1)
			{
				const uint32_t key = BASISU_GET_KEY(p);

				hist[key & 0xFF]++;
				hist[256 + ((key >> 8) & 0xFF)]++;
			}
		}
		else
		{
			assert(key_size == 1);
			if (key_size != 1)
				return NULL;

			T* p = pBuf0;
			T* q = pBuf0 + (num_vals >> 1) * 2;

			for (; p != q; p += 2)
			{
				const uint32_t key0 = BASISU_GET_KEY(p);
				const uint32_t key1 = BASISU_GET_KEY(p + 1);

				hist[key0 & 0xFF]++;
				hist[key1 & 0xFF]++;
			}

			if (num_vals & 1)
			{
				const uint32_t key = BASISU_GET_KEY(p);
				hist[key & 0xFF]++;
			}
		}

		T* pCur = pBuf0;
		T* pNew = pBuf1;

		for (uint32_t pass = 0; pass < key_size; pass++)
		{
			const uint32_t* pHist = &hist[pass << 8];

			uint32_t offsets[256];

			uint32_t cur_ofs = 0;
			for (uint32_t i = 0; i < 256; i += 2)
			{
				offsets[i] = cur_ofs;
				cur_ofs += pHist[i];

				offsets[i + 1] = cur_ofs;
				cur_ofs += pHist[i + 1];
			}

			const uint32_t pass_shift = pass << 3;

			T* p = pCur;
			T* q = pCur + (num_vals >> 1) * 2;

			for (; p != q; p += 2)
			{
				uint32_t c0 = (BASISU_GET_KEY(p) >> pass_shift) & 0xFF;
				uint32_t c1 = (BASISU_GET_KEY(p + 1) >> pass_shift) & 0xFF;

				if (c0 == c1)
				{
					uint32_t dst_offset0 = offsets[c0];

					offsets[c0] = dst_offset0 + 2;

					pNew[dst_offset0] = p[0];
					pNew[dst_offset0 + 1] = p[1];
				}
				else
				{
					uint32_t dst_offset0 = offsets[c0]++;
					uint32_t dst_offset1 = offsets[c1]++;

					pNew[dst_offset0] = p[0];
					pNew[dst_offset1] = p[1];
				}
			}

			if (num_vals & 1)
			{
				uint32_t c = (BASISU_GET_KEY(p) >> pass_shift) & 0xFF;

				uint32_t dst_offset = offsets[c];
				offsets[c] = dst_offset + 1;

				pNew[dst_offset] = *p;
			}

			T* t = pCur;
			pCur = pNew;
			pNew = t;
		}

		return pCur;
	}

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

	public:
		// num_threads is the TOTAL number of job pool threads, including the calling thread! So 2=1 new thread, 3=2 new threads, etc.
		job_pool(uint32_t num_threads);
		~job_pool();
				
		void add_job(const std::function<void()>& job);
		void add_job(std::function<void()>&& job);

		void wait_for_all();

		size_t get_total_threads() const { return 1 + m_threads.size(); }
		
	private:
		std::vector<std::thread> m_threads;
		std::vector<std::function<void()> > m_queue;
		
		std::mutex m_mutex;
		std::condition_variable m_has_work;
		std::condition_variable m_no_more_jobs;
		
		uint32_t m_num_active_jobs;
		
		std::atomic<bool> m_kill_flag;

		std::atomic<int> m_num_active_workers;

		void job_thread(uint32_t index);
	};

	// Simple 64-bit color class

	class color_rgba_i16
	{
	public:
		union
		{
			int16_t m_comps[4];

			struct
			{
				int16_t r;
				int16_t g;
				int16_t b;
				int16_t a;
			};
		};

		inline color_rgba_i16()
		{
			static_assert(sizeof(*this) == sizeof(int16_t)*4, "sizeof(*this) == sizeof(int16_t)*4");
		}

		inline color_rgba_i16(int sr, int sg, int sb, int sa)
		{
			set(sr, sg, sb, sa);
		}

		inline color_rgba_i16 &set(int sr, int sg, int sb, int sa)
		{
			m_comps[0] = (int16_t)clamp<int>(sr, INT16_MIN, INT16_MAX);
			m_comps[1] = (int16_t)clamp<int>(sg, INT16_MIN, INT16_MAX);
			m_comps[2] = (int16_t)clamp<int>(sb, INT16_MIN, INT16_MAX);
			m_comps[3] = (int16_t)clamp<int>(sa, INT16_MIN, INT16_MAX);
			return *this;
		}
	};
				
	class color_rgba
	{
	public:
		union
		{
			uint8_t m_comps[4];

			struct
			{
				uint8_t r;
				uint8_t g;
				uint8_t b;
				uint8_t a;
			};
		};

		inline color_rgba()
		{
			static_assert(sizeof(*this) == 4, "sizeof(*this) != 4");
			static_assert(sizeof(*this) == sizeof(basist::color32), "sizeof(*this) != sizeof(basist::color32)");
		}

		// Not too hot about this idea.
		inline color_rgba(const basist::color32& other) :
			r(other.r),
			g(other.g),
			b(other.b),
			a(other.a)
		{
		}

		color_rgba& operator= (const basist::color32& rhs)
		{
			r = rhs.r;
			g = rhs.g;
			b = rhs.b;
			a = rhs.a;
			return *this;
		}

		inline color_rgba(int y)
		{
			set(y);
		}

		inline color_rgba(int y, int na)
		{
			set(y, na);
		}

		inline color_rgba(int sr, int sg, int sb, int sa)
		{
			set(sr, sg, sb, sa);
		}

		inline color_rgba(eNoClamp, int sr, int sg, int sb, int sa)
		{
			set_noclamp_rgba((uint8_t)sr, (uint8_t)sg, (uint8_t)sb, (uint8_t)sa);
		}

		inline color_rgba& set_noclamp_y(int y)
		{
			m_comps[0] = (uint8_t)y;
			m_comps[1] = (uint8_t)y;
			m_comps[2] = (uint8_t)y;
			m_comps[3] = (uint8_t)255;
			return *this;
		}

		inline color_rgba &set_noclamp_rgba(int sr, int sg, int sb, int sa)
		{
			m_comps[0] = (uint8_t)sr;
			m_comps[1] = (uint8_t)sg;
			m_comps[2] = (uint8_t)sb;
			m_comps[3] = (uint8_t)sa;
			return *this;
		}

		inline color_rgba &set(int y)
		{
			m_comps[0] = static_cast<uint8_t>(clamp<int>(y, 0, 255));
			m_comps[1] = m_comps[0];
			m_comps[2] = m_comps[0];
			m_comps[3] = 255;
			return *this;
		}

		inline color_rgba &set(int y, int na)
		{
			m_comps[0] = static_cast<uint8_t>(clamp<int>(y, 0, 255));
			m_comps[1] = m_comps[0];
			m_comps[2] = m_comps[0];
			m_comps[3] = static_cast<uint8_t>(clamp<int>(na, 0, 255));
			return *this;
		}

		inline color_rgba &set(int sr, int sg, int sb, int sa)
		{
			m_comps[0] = static_cast<uint8_t>(clamp<int>(sr, 0, 255));
			m_comps[1] = static_cast<uint8_t>(clamp<int>(sg, 0, 255));
			m_comps[2] = static_cast<uint8_t>(clamp<int>(sb, 0, 255));
			m_comps[3] = static_cast<uint8_t>(clamp<int>(sa, 0, 255));
			return *this;
		}

		inline color_rgba &set_rgb(int sr, int sg, int sb)
		{
			m_comps[0] = static_cast<uint8_t>(clamp<int>(sr, 0, 255));
			m_comps[1] = static_cast<uint8_t>(clamp<int>(sg, 0, 255));
			m_comps[2] = static_cast<uint8_t>(clamp<int>(sb, 0, 255));
			return *this;
		}

		inline color_rgba &set_rgb(const color_rgba &other)
		{
			r = other.r;
			g = other.g;
			b = other.b;
			return *this;
		}

		inline const uint8_t &operator[] (uint32_t index) const { assert(index < 4); return m_comps[index]; }
		inline uint8_t &operator[] (uint32_t index) { assert(index < 4); return m_comps[index]; }
		
		inline void clear()
		{
			m_comps[0] = 0;
			m_comps[1] = 0;
			m_comps[2] = 0;
			m_comps[3] = 0;
		}

		inline bool operator== (const color_rgba &rhs) const
		{
			if (m_comps[0] != rhs.m_comps[0]) return false;
			if (m_comps[1] != rhs.m_comps[1]) return false;
			if (m_comps[2] != rhs.m_comps[2]) return false;
			if (m_comps[3] != rhs.m_comps[3]) return false;
			return true;
		}

		inline bool operator!= (const color_rgba &rhs) const
		{
			return !(*this == rhs);
		}

		inline bool operator<(const color_rgba &rhs) const
		{
			for (int i = 0; i < 4; i++)
			{
				if (m_comps[i] < rhs.m_comps[i])
					return true;
				else if (m_comps[i] != rhs.m_comps[i])
					return false;
			}
			return false;
		}

		inline int get_601_luma() const { return (19595U * m_comps[0] + 38470U * m_comps[1] + 7471U * m_comps[2] + 32768U) >> 16U; }
		inline int get_709_luma() const { return (13938U * m_comps[0] + 46869U * m_comps[1] + 4729U * m_comps[2] + 32768U) >> 16U; } 
		inline int get_luma(bool luma_601) const { return luma_601 ? get_601_luma() : get_709_luma(); }

		inline uint32_t get_bgra_uint32() const { return b | (g << 8) | (r << 16) | (a << 24); }
		inline uint32_t get_rgba_uint32() const { return r | (g << 8) | (b << 16) | (a << 24); }

		inline vec3F get_vec3F() const { return vec3F((float)r, (float)g, (float)b); }
		inline vec4F get_vec4F() const { return vec4F((float)r, (float)g, (float)b, (float)a); }

		inline uint32_t get_dist2(const color_rgba& p) const
		{
			return squarei(m_comps[0] - p[0]) + squarei(m_comps[1] - p[1]) + squarei(m_comps[2] - p[2]) + squarei(m_comps[3] - p[3]);
		}

		inline uint32_t get_weighted_dist2(const color_rgba& p, const uint32_t weights[4]) const
		{
			return squarei(m_comps[0] - p[0]) * (int)weights[0] + 
				squarei(m_comps[1] - p[1]) * (int)weights[1] +
				squarei(m_comps[2] - p[2]) * (int)weights[2] +
				squarei(m_comps[3] - p[3]) * (int)weights[3];
		}

		inline basist::color32 get_color32() const
		{
			return basist::color32(r, g, b, a);
		}

		static color_rgba comp_min(const color_rgba& a, const color_rgba& b) { return color_rgba(basisu::minimum(a[0], b[0]), basisu::minimum(a[1], b[1]), basisu::minimum(a[2], b[2]), basisu::minimum(a[3], b[3])); }
		static color_rgba comp_max(const color_rgba& a, const color_rgba& b) { return color_rgba(basisu::maximum(a[0], b[0]), basisu::maximum(a[1], b[1]), basisu::maximum(a[2], b[2]), basisu::maximum(a[3], b[3])); }
	};

	typedef basisu::vector<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)
	{
		int dr = r0 - r1, dg = g0 - g1, db = b0 - b1;
		return dr * dr + dg * dg + db * db;
	}

	inline int color_distance(int r0, int g0, int b0, int a0, int r1, int g1, int b1, int a1)
	{
		int dr = r0 - r1, dg = g0 - g1, db = b0 - b1, da = a0 - a1;
		return dr * dr + dg * dg + db * db + da * da;
	}

	inline int color_distance(const color_rgba &c0, const color_rgba &c1, bool alpha)
	{
		if (alpha)
			return color_distance(c0.r, c0.g, c0.b, c0.a, c1.r, c1.g, c1.b, c1.a);
		else
			return color_distance(c0.r, c0.g, c0.b, c1.r, c1.g, c1.b);
	}

	// Original library color_distance(), for testing
	inline uint32_t color_distance_orig(bool perceptual, const color_rgba& e1, const color_rgba& e2, bool alpha)
	{
		if (perceptual)
		{
			int dr = e1.r - e2.r;
			int dg = e1.g - e2.g;
			int db = e1.b - e2.b;

			int64_t delta_l = dr * 27 + dg * 92 + db * 9;
			int64_t delta_cr = dr * 128 - delta_l;
			int64_t delta_cb = db * 128 - delta_l;

			uint32_t id = ((uint32_t)((delta_l * delta_l) >> 7U)) +
				((((uint32_t)((delta_cr * delta_cr) >> 7U)) * 26U) >> 7U) +
				((((uint32_t)((delta_cb * delta_cb) >> 7U)) * 3U) >> 7U);

			if (alpha)
			{
				int da = (e1.a - e2.a) << 7;
				// This shouldn't overflow if da is 255 or -255: 29.99 bits after squaring.
				id += ((uint32_t)(da * da) >> 7U);
			}

			return id;
		}
		else
		{
			return color_distance(e1, e2, alpha);
		}
	}
		
	inline uint32_t color_distance(bool perceptual, const color_rgba &e1, const color_rgba &e2, bool alpha)
	{
		if (perceptual)
		{
			int dr = e1.r - e2.r;
			int dg = e1.g - e2.g;
			int db = e1.b - e2.b;

			// This calc can't overflow or the SSE variants will overflow too.
			int delta_l = dr * 14 + dg * 45 + db * 5;
			int delta_cr = dr * 64 - delta_l;
			int delta_cb = db * 64 - delta_l;
													
			// not >> 6, so the output is scaled by 7 bits, not 6 (to match the original function which scaled by 7, but had rare overflow issues)
			uint32_t id = ((uint32_t)(delta_l * delta_l) >> 5U) +
				((((uint32_t)(delta_cr * delta_cr) >> 5U) * 26U) >> 7U) +
				((((uint32_t)(delta_cb * delta_cb) >> 5U) * 3U) >> 7U);

#if defined(DEBUG) || defined(_DEBUG)
			// Shouldn't need 64-bit now, but make sure
			{
				int64_t alt_delta_l = dr * 14 + dg * 45 + db * 5;
				int64_t alt_delta_cr = dr * 64 - alt_delta_l;
				int64_t alt_delta_cb = db * 64 - alt_delta_l;

				int64_t alt_id = ((alt_delta_l * alt_delta_l) >> 5) +
					((((alt_delta_cr * alt_delta_cr) >> 5) * 26) >> 7) +
					((((alt_delta_cb * alt_delta_cb) >> 5) * 3) >> 7);

				assert(alt_id == id);
			}
#endif

			if (alpha)
			{
				int da = (e1.a - e2.a) << 7;
				
				// This shouldn't overflow if da is 255 or -255: 29.99 bits after squaring.
				uint32_t ea = ((uint32_t)(da * da) >> 7U);
				id += ea;

#if defined(DEBUG) || defined(_DEBUG)
				// Make sure it can't overflow
				assert((((int64_t)da * (int64_t)da) >> 7) == ea);
#endif
				
			}

			return id;
		}
		else
		{
			return color_distance(e1, e2, alpha);
		}
	}

	static inline uint32_t color_distance_la(const color_rgba& a, const color_rgba& b)
	{
		const int dl = a.r - b.r;
		const int da = a.a - b.a;
		return dl * dl + da * da;
	}

	// String helpers

	inline int string_find_right(const std::string& filename, char c)
	{
		size_t result = filename.find_last_of(c);
		return (result == std::string::npos) ? -1 : (int)result;
	}

	inline std::string string_get_extension(const std::string &filename)
	{
		int sep = -1;
#ifdef _WIN32
		sep = string_find_right(filename, '\\');
#endif
		if (sep < 0)
			sep = string_find_right(filename, '/');

		int dot = string_find_right(filename, '.');
		if (dot <= sep)
			return "";

		std::string result(filename);
		result.erase(0, dot + 1);

		return result;
	}

	inline bool string_remove_extension(std::string &filename)
	{
		int sep = -1;
#ifdef _WIN32
		sep = string_find_right(filename, '\\');
#endif
		if (sep < 0)
			sep = string_find_right(filename, '/');

		int dot = string_find_right(filename, '.');
		if ((dot < sep) || (dot < 0))
			return false;

		filename.resize(dot);

		return true;
	}
		
	inline std::string string_tolower(const std::string& s)
	{
		std::string result(s);
		for (size_t i = 0; i < result.size(); i++)
		{
			result[i] = (char)tolower((uint8_t)(result[i]));
		}
		return result;
	}

	inline char *strcpy_safe(char *pDst, size_t dst_len, const char *pSrc)
	{
		assert(pDst && pSrc && dst_len);
		if (!dst_len)
			return pDst;

		const size_t src_len = strlen(pSrc);
		const size_t src_len_plus_terminator = src_len + 1;

		if (src_len_plus_terminator <= dst_len)
			memcpy(pDst, pSrc, src_len_plus_terminator);
		else
		{
			if (dst_len > 1)
				memcpy(pDst, pSrc, dst_len - 1);
			pDst[dst_len - 1] = '\0';
		}

		return pDst;
	}

	inline bool string_ends_with(const std::string& s, char c)
	{
		return (s.size() != 0) && (s.back() == c);
	}

	inline bool string_split_path(const char *p, std::string *pDrive, std::string *pDir, std::string *pFilename, std::string *pExt)
	{
#ifdef _MSC_VER
		char drive_buf[_MAX_DRIVE] = { 0 };
		char dir_buf[_MAX_DIR] = { 0 };
		char fname_buf[_MAX_FNAME] = { 0 };
		char ext_buf[_MAX_EXT] = { 0 };

		errno_t error = _splitpath_s(p, 
			pDrive ? drive_buf : NULL, pDrive ? _MAX_DRIVE : 0,
			pDir ? dir_buf : NULL, pDir ? _MAX_DIR : 0,
			pFilename ? fname_buf : NULL, pFilename ? _MAX_FNAME : 0,
			pExt ? ext_buf : NULL, pExt ? _MAX_EXT : 0);
		if (error != 0)
			return false;

		if (pDrive) *pDrive = drive_buf;
		if (pDir) *pDir = dir_buf;
		if (pFilename) *pFilename = fname_buf;
		if (pExt) *pExt = ext_buf;
		return true;
#else
		char dirtmp[1024], nametmp[1024];
		strcpy_safe(dirtmp, sizeof(dirtmp), p);
		strcpy_safe(nametmp, sizeof(nametmp), p);

		if (pDrive)
			pDrive->resize(0);

		const char *pDirName = dirname(dirtmp);
		const char* pBaseName = basename(nametmp);
		if ((!pDirName) || (!pBaseName))
			return false;

		if (pDir)
		{
			*pDir = pDirName;
			if ((pDir->size()) && (pDir->back() != '/'))
				*pDir += "/";
		}
				
		if (pFilename)
		{
			*pFilename = pBaseName;
			string_remove_extension(*pFilename);
		}

		if (pExt)
		{
			*pExt = pBaseName;
			*pExt = string_get_extension(*pExt);
			if (pExt->size())
				*pExt = "." + *pExt;
		}

		return true;
#endif
	}

	inline bool is_path_separator(char c)
	{
#ifdef _WIN32
		return (c == '/') || (c == '\\');
#else
		return (c == '/');
#endif
	}
		
	inline bool is_drive_separator(char c)
	{
#ifdef _WIN32
		return (c == ':');
#else
		(void)c;
		return false;
#endif
	}

	inline void string_combine_path(std::string &dst, const char *p, const char *q)
	{
		std::string temp(p);
		if (temp.size() && !is_path_separator(q[0]))
		{
			if (!is_path_separator(temp.back()))
				temp.append(1, BASISU_PATH_SEPERATOR_CHAR);
		}
		temp += q;
		dst.swap(temp);
	}

	inline void string_combine_path(std::string &dst, const char *p, const char *q, const char *r)
	{
		string_combine_path(dst, p, q);
		string_combine_path(dst, dst.c_str(), r);
	}
		
	inline void string_combine_path_and_extension(std::string &dst, const char *p, const char *q, const char *r, const char *pExt)
	{
		string_combine_path(dst, p, q, r);
		if ((!string_ends_with(dst, '.')) && (pExt[0]) && (pExt[0] != '.'))
			dst.append(1, '.');
		dst.append(pExt);
	}

	inline bool string_get_pathname(const char *p, std::string &path)
	{
		std::string temp_drive, temp_path;
		if (!string_split_path(p, &temp_drive, &temp_path, NULL, NULL))
			return false;
		string_combine_path(path, temp_drive.c_str(), temp_path.c_str());
		return true;
	}

	inline bool string_get_filename(const char *p, std::string &filename)
	{
		std::string temp_ext;
		if (!string_split_path(p, nullptr, nullptr, &filename, &temp_ext))
			return false;
		filename += temp_ext;
		return true;
	}

	class rand
	{
		std::mt19937 m_mt;
		std::normal_distribution<float> m_norm;

	public:
		rand() {	}

		inline explicit rand(uint32_t s) { seed(s); }

		inline void seed(uint32_t s) { m_mt.seed(s); m_norm.reset(); }

		// between [l,h]
		inline int irand(int l, int h) { std::uniform_int_distribution<int> d(l, h); return d(m_mt); }

		// p=[0,100]
		inline bool iprob(int p) { assert((p >= 0) && (p <= 100)); return irand(0, 99) < p; }
				
		inline uint32_t urand32() { return std::uniform_int_distribution<uint32_t>(0, std::numeric_limits<uint32_t>::max())(m_mt);	}

		inline bool bit() { return irand(0, 1) == 1; }

		inline uint8_t byte() { return static_cast<uint8_t>(urand32()); }

		// between [l,h)
		float frand(float l, float h) 
		{ 
			assert(l <= h);

			if (l >= h)
				return l;

			std::uniform_real_distribution<float> d(l, h); 
			float x = d(m_mt); 
			
			// paranoia for buggy implementations
			if (x < l)
				x = l;
			else if (x >= h)
				x = std::nextafter(h, l);

			return x;
		}
				
		// use standard N(0,1), scale manually
		inline float gaussian(float mean, float stddev) { assert(stddev >= 0.0f); return mean + stddev * m_norm(m_mt); }
	};

	class priority_queue
	{
	public:
		priority_queue() :
			m_size(0)
		{
		}

		void clear()
		{
			m_heap.clear();
			m_size = 0;
		}

		void init(uint32_t max_entries, uint32_t first_index, float first_priority)
		{
			m_heap.resize(max_entries + 1);
			m_heap[1].m_index = first_index;
			m_heap[1].m_priority = first_priority;
			m_size = 1;
		}

		inline uint32_t size() const { return m_size; }

		inline uint32_t get_top_index() const { return m_heap[1].m_index; }
		inline float get_top_priority() const { return m_heap[1].m_priority; }

		inline void delete_top()
		{
			assert(m_size > 0);
			m_heap[1] = m_heap[m_size];
			m_size--;
			if (m_size)
				down_heap(1);
		}

		inline void add_heap(uint32_t index, float priority)
		{
			m_size++;

			uint32_t k = m_size;

			if (m_size >= m_heap.size())
				m_heap.resize(m_size + 1);

			for (;;)
			{
				uint32_t parent_index = k >> 1;
				if ((!parent_index) || (m_heap[parent_index].m_priority > priority))
					break;
				m_heap[k] = m_heap[parent_index];
				k = parent_index;
			}

			m_heap[k].m_index = index;
			m_heap[k].m_priority = priority;
		}

	private:
		struct entry
		{
			uint32_t m_index;
			float m_priority;
		};

		basisu::vector<entry> m_heap;
		uint32_t m_size;

		// Push down entry at index
		inline void down_heap(uint32_t heap_index)
		{
			uint32_t orig_index = m_heap[heap_index].m_index;
			const float orig_priority = m_heap[heap_index].m_priority;

			uint32_t child_index;
			while ((child_index = (heap_index << 1)) <= m_size)
			{
				if ((child_index < m_size) && (m_heap[child_index].m_priority < m_heap[child_index + 1].m_priority)) ++child_index;
				if (orig_priority > m_heap[child_index].m_priority)
					break;
				m_heap[heap_index] = m_heap[child_index];
				heap_index = child_index;
			}

			m_heap[heap_index].m_index = orig_index;
			m_heap[heap_index].m_priority = orig_priority;
		}
	};

	// Tree structured vector quantization (TSVQ)

	template <typename TrainingVectorType>
	class tree_vector_quant
	{
	public:
		typedef TrainingVectorType training_vec_type;
		typedef std::pair<TrainingVectorType, uint64_t> training_vec_with_weight;
		typedef basisu::vector< training_vec_with_weight > array_of_weighted_training_vecs;

		tree_vector_quant() :
			m_next_codebook_index(0)
		{
		}

		void clear()
		{
			clear_vector(m_training_vecs);
			clear_vector(m_nodes);
			m_next_codebook_index = 0;
		}

		void add_training_vec(const TrainingVectorType &v, uint64_t weight) { m_training_vecs.push_back(std::make_pair(v, weight)); }

		size_t get_total_training_vecs() const { return m_training_vecs.size(); }
		const array_of_weighted_training_vecs &get_training_vecs() const	{ return m_training_vecs; }
			  array_of_weighted_training_vecs &get_training_vecs()			{ return m_training_vecs; }

		void retrieve(basisu::vector< basisu::vector<uint32_t> > &codebook) const
		{
			for (uint32_t i = 0; i < m_nodes.size(); i++)
			{
				const tsvq_node &n = m_nodes[i];
				if (!n.is_leaf())
					continue;

				codebook.resize(codebook.size() + 1);
				codebook.back() = n.m_training_vecs;
			}
		}

		void retrieve(basisu::vector<TrainingVectorType> &codebook) const
		{
			for (uint32_t i = 0; i < m_nodes.size(); i++)
			{
				const tsvq_node &n = m_nodes[i];
				if (!n.is_leaf())
					continue;

				codebook.resize(codebook.size() + 1);
				codebook.back() = n.m_origin;
			}
		}

		void retrieve(uint32_t max_clusters, basisu::vector<uint_vec> &codebook) const
		{
			uint_vec node_stack;
			node_stack.reserve(512);

			codebook.resize(0);
			codebook.reserve(max_clusters);
			         
			uint32_t node_index = 0;

			while (true)
			{
				const tsvq_node& cur = m_nodes[node_index];

				if (cur.is_leaf() || ((2 + cur.m_codebook_index) > (int)max_clusters))
				{
					codebook.resize(codebook.size() + 1);
					codebook.back() = cur.m_training_vecs;
										
					if (node_stack.empty())
						break;

					node_index = node_stack.back();
					node_stack.pop_back();
					continue;
				}
				            
				node_stack.push_back(cur.m_right_index);
					node_index = cur.m_left_index;
			}
		}

		bool generate(uint32_t max_size)
		{
			if (!m_training_vecs.size())
				return false;

			m_next_codebook_index = 0;

			clear_vector(m_nodes);
			m_nodes.reserve(max_size * 2 + 1);

			m_nodes.push_back(prepare_root());

			priority_queue var_heap;
			var_heap.init(max_size, 0, m_nodes[0].m_var);

			basisu::vector<uint32_t> l_children, r_children;

			// Now split the worst nodes
			l_children.reserve(m_training_vecs.size() + 1);
			r_children.reserve(m_training_vecs.size() + 1);

			uint32_t total_leaf_nodes = 1;

			//interval_timer tm;
			//tm.start();

			while ((var_heap.size()) && (total_leaf_nodes < max_size))
			{
				const uint32_t node_index = var_heap.get_top_index();
				const tsvq_node &node = m_nodes[node_index];

				assert(node.m_var == var_heap.get_top_priority());
				assert(node.is_leaf());

				var_heap.delete_top();
								
				if (node.m_training_vecs.size() > 1)
				{
					if (split_node(node_index, var_heap, l_children, r_children))
					{
						// This removes one leaf node (making an internal node) and replaces it with two new leaves, so +1 total.
						total_leaf_nodes += 1;
					}
				}
			}

			//debug_printf("tree_vector_quant::generate %u: %3.3f secs\n", TrainingVectorType::num_elements, tm.get_elapsed_secs());

			return true;
		}

	private:
		class tsvq_node
		{
		public:
			inline tsvq_node() : m_weight(0), m_origin(cZero), m_left_index(-1), m_right_index(-1), m_codebook_index(-1) { }

			// vecs is erased
			inline void set(const TrainingVectorType &org, uint64_t weight, float var, basisu::vector<uint32_t> &vecs) { m_origin = org; m_weight = weight; m_var = var; m_training_vecs.swap(vecs); }

			inline bool is_leaf() const { return m_left_index < 0; }

			float m_var;
			uint64_t m_weight;
			TrainingVectorType m_origin;
			int32_t m_left_index, m_right_index;
			basisu::vector<uint32_t> m_training_vecs;
			int m_codebook_index;
		};

		typedef basisu::vector<tsvq_node> tsvq_node_vec;
		tsvq_node_vec m_nodes;

		array_of_weighted_training_vecs m_training_vecs;

		uint32_t m_next_codebook_index;

		tsvq_node prepare_root() const
		{
			double ttsum = 0.0f;

			// Prepare root node containing all training vectors
			tsvq_node root;
			root.m_training_vecs.reserve(m_training_vecs.size());

			for (uint32_t i = 0; i < m_training_vecs.size(); i++)
			{
				const TrainingVectorType &v = m_training_vecs[i].first;
				const uint64_t weight = m_training_vecs[i].second;

				root.m_training_vecs.push_back(i);

				root.m_origin += (v * static_cast<float>(weight));
				root.m_weight += weight;

				ttsum += v.dot(v) * weight;
			}

			root.m_var = static_cast<float>(ttsum - (root.m_origin.dot(root.m_origin) / root.m_weight));

			root.m_origin *= (1.0f / root.m_weight);

			return root;
		}

		bool split_node(uint32_t node_index, priority_queue &var_heap, basisu::vector<uint32_t> &l_children, basisu::vector<uint32_t> &r_children)
		{
			TrainingVectorType l_child_org, r_child_org;
			uint64_t l_weight = 0, r_weight = 0;
			float l_var = 0.0f, r_var = 0.0f;

			// Compute initial left/right child origins
			if (!prep_split(m_nodes[node_index], l_child_org, r_child_org))
				return false;

			// Use k-means iterations to refine these children vectors
			if (!refine_split(m_nodes[node_index], l_child_org, l_weight, l_var, l_children, r_child_org, r_weight, r_var, r_children))
				return false;

			// Create children
			const uint32_t l_child_index = (uint32_t)m_nodes.size(), r_child_index = (uint32_t)m_nodes.size() + 1;

			m_nodes[node_index].m_left_index = l_child_index;
			m_nodes[node_index].m_right_index = r_child_index;
			
			m_nodes[node_index].m_codebook_index = m_next_codebook_index;
			m_next_codebook_index++;

			m_nodes.resize(m_nodes.size() + 2);

			tsvq_node &l_child = m_nodes[l_child_index], &r_child = m_nodes[r_child_index];

			l_child.set(l_child_org, l_weight, l_var, l_children);
			r_child.set(r_child_org, r_weight, r_var, r_children);

			if ((l_child.m_var <= 0.0f) && (l_child.m_training_vecs.size() > 1))
			{
				TrainingVectorType v(m_training_vecs[l_child.m_training_vecs[0]].first);
				
				for (uint32_t i = 1; i < l_child.m_training_vecs.size(); i++)
				{
					if (!(v == m_training_vecs[l_child.m_training_vecs[i]].first))
					{
						l_child.m_var = 1e-4f;
						break;
					}
				}
			}

			if ((r_child.m_var <= 0.0f) && (r_child.m_training_vecs.size() > 1))
			{
				TrainingVectorType v(m_training_vecs[r_child.m_training_vecs[0]].first);

				for (uint32_t i = 1; i < r_child.m_training_vecs.size(); i++)
				{
					if (!(v == m_training_vecs[r_child.m_training_vecs[i]].first))
					{
						r_child.m_var = 1e-4f;
						break;
					}
				}
			}

			if ((l_child.m_var > 0.0f) && (l_child.m_training_vecs.size() > 1))
				var_heap.add_heap(l_child_index, l_child.m_var);
						
			if ((r_child.m_var > 0.0f) && (r_child.m_training_vecs.size() > 1))
				var_heap.add_heap(r_child_index, r_child.m_var);
						
			return true;
		}

		TrainingVectorType compute_split_axis(const tsvq_node &node) const
		{
			const uint32_t N = TrainingVectorType::num_elements;

			matrix<N, N, float> cmatrix;

			if ((N != 16) || (!g_cpu_supports_sse41))
			{
				cmatrix.set_zero();

				// Compute covariance matrix from weighted input vectors
				for (uint32_t i = 0; i < node.m_training_vecs.size(); i++)
				{
					const TrainingVectorType v(m_training_vecs[node.m_training_vecs[i]].first - node.m_origin);
					const TrainingVectorType w(static_cast<float>(m_training_vecs[node.m_training_vecs[i]].second) * v);

					for (uint32_t x = 0; x < N; x++)
						for (uint32_t y = x; y < N; y++)
							cmatrix[x][y] = cmatrix[x][y] + v[x] * w[y];
				}
			}
			else
			{
#if BASISU_SUPPORT_SSE
				// Specialize the case with 16x16 matrices, which are quite expensive without SIMD.
				// This SSE function takes pointers to void types, so do some sanity checks.
				assert(sizeof(TrainingVectorType) == sizeof(float) * 16);
				assert(sizeof(training_vec_with_weight) == sizeof(std::pair<vec16F, uint64_t>));
				update_covar_matrix_16x16_sse41(node.m_training_vecs.size_u32(), m_training_vecs.data(), &node.m_origin, node.m_training_vecs.data(), &cmatrix);
#endif
			}

			const float renorm_scale = 1.0f / node.m_weight;

			for (uint32_t x = 0; x < N; x++)
				for (uint32_t y = x; y < N; y++)
					cmatrix[x][y] *= renorm_scale;

			// Diagonal flip
			for (uint32_t x = 0; x < (N - 1); x++)
				for (uint32_t y = x + 1; y < N; y++)
					cmatrix[y][x] = cmatrix[x][y];

			return compute_pca_from_covar<N, TrainingVectorType>(cmatrix);
		}

		bool prep_split(const tsvq_node &node, TrainingVectorType &l_child_result, TrainingVectorType &r_child_result) const
		{
			//const uint32_t N = TrainingVectorType::num_elements;

			if (2 == node.m_training_vecs.size())
			{
				l_child_result = m_training_vecs[node.m_training_vecs[0]].first;
				r_child_result = m_training_vecs[node.m_training_vecs[1]].first;
				return true;
			}

			TrainingVectorType axis(compute_split_axis(node)), l_child(0.0f), r_child(0.0f);
			double l_weight = 0.0f, r_weight = 0.0f;

			// Compute initial left/right children
			for (uint32_t i = 0; i < node.m_training_vecs.size(); i++)
			{
				const float weight = (float)m_training_vecs[node.m_training_vecs[i]].second;

				const TrainingVectorType &v = m_training_vecs[node.m_training_vecs[i]].first;

				double t = (v - node.m_origin).dot(axis);
				if (t >= 0.0f)
				{
					r_child += v * weight;
					r_weight += weight;
				}
				else
				{
					l_child += v * weight;
					l_weight += weight;
				}
			}

			if ((l_weight > 0.0f) && (r_weight > 0.0f))
			{
				l_child_result = l_child * static_cast<float>(1.0f / l_weight);
				r_child_result = r_child * static_cast<float>(1.0f / r_weight);
			}
			else
			{
				TrainingVectorType l(1e+20f);
				TrainingVectorType h(-1e+20f);
				for (uint32_t i = 0; i < node.m_training_vecs.size(); i++)
				{
					const TrainingVectorType& v = m_training_vecs[node.m_training_vecs[i]].first;
					
					l = TrainingVectorType::component_min(l, v);
					h = TrainingVectorType::component_max(h, v);
				}

				TrainingVectorType r(h - l);

				float largest_axis_v = 0.0f;
				int largest_axis_index = -1;
				for (uint32_t i = 0; i < TrainingVectorType::num_elements; i++)
				{
					if (r[i] > largest_axis_v)
					{
						largest_axis_v = r[i];
						largest_axis_index = i;
					}
				}

				if (largest_axis_index < 0)
					return false;

				basisu::vector<float> keys(node.m_training_vecs.size());
				for (uint32_t i = 0; i < node.m_training_vecs.size(); i++)
					keys[i] = m_training_vecs[node.m_training_vecs[i]].first[largest_axis_index];

				uint_vec indices(node.m_training_vecs.size());
				indirect_sort((uint32_t)node.m_training_vecs.size(), &indices[0], &keys[0]);

				l_child.set_zero();
				l_weight = 0;

				r_child.set_zero();
				r_weight = 0;

				const uint32_t half_index = (uint32_t)node.m_training_vecs.size() / 2;
				for (uint32_t i = 0; i < node.m_training_vecs.size(); i++)
				{
					const float weight = (float)m_training_vecs[node.m_training_vecs[i]].second;

					const TrainingVectorType& v = m_training_vecs[node.m_training_vecs[i]].first;

					if (i < half_index)
					{
						l_child += v * weight;
						l_weight += weight;
					}
					else
					{
						r_child += v * weight;
						r_weight += weight;
					}
				}

				if ((l_weight > 0.0f) && (r_weight > 0.0f))
				{
					l_child_result = l_child * static_cast<float>(1.0f / l_weight);
					r_child_result = r_child * static_cast<float>(1.0f / r_weight);
				}
				else
				{
					l_child_result = l;
					r_child_result = h;
				}
			}

			return true;
		}

		bool refine_split(const tsvq_node &node,
			TrainingVectorType &l_child, uint64_t &l_weight, float &l_var, basisu::vector<uint32_t> &l_children,
			TrainingVectorType &r_child, uint64_t &r_weight, float &r_var, basisu::vector<uint32_t> &r_children) const
		{
			l_children.reserve(node.m_training_vecs.size());
			r_children.reserve(node.m_training_vecs.size());

			float prev_total_variance = 1e+10f;

			// Refine left/right children locations using k-means iterations
			const uint32_t cMaxIters = 6;
			for (uint32_t iter = 0; iter < cMaxIters; iter++)
			{
				l_children.resize(0); 
				r_children.resize(0); 

				TrainingVectorType new_l_child(cZero), new_r_child(cZero);

				double l_ttsum = 0.0f, r_ttsum = 0.0f;

				l_weight = 0;
				r_weight = 0;

				for (uint32_t i = 0; i < node.m_training_vecs.size(); i++)
				{
					const TrainingVectorType &v = m_training_vecs[node.m_training_vecs[i]].first;
					const uint64_t weight = m_training_vecs[node.m_training_vecs[i]].second;

					double left_dist2 = l_child.squared_distance_d(v), right_dist2 = r_child.squared_distance_d(v);

					if (left_dist2 >= right_dist2)
					{
						new_r_child += (v * static_cast<float>(weight));
						r_weight += weight;

						r_ttsum += weight * v.dot(v);
						r_children.push_back(node.m_training_vecs[i]);
					}
					else
					{
						new_l_child += (v * static_cast<float>(weight));
						l_weight += weight;

						l_ttsum += weight * v.dot(v);
						l_children.push_back(node.m_training_vecs[i]);
					}
				}

				// Node is unsplittable using the above algorithm - try something else to split it up.
				if ((!l_weight) || (!r_weight))
				{
					l_children.resize(0);
					new_l_child.set(0.0f);
					l_ttsum = 0.0f;
					l_weight = 0;

					r_children.resize(0);
					new_r_child.set(0.0f);
					r_ttsum = 0.0f;
					r_weight = 0;

					TrainingVectorType firstVec;
					firstVec.clear();
					for (uint32_t i = 0; i < node.m_training_vecs.size(); i++)
					{
						const TrainingVectorType& v = m_training_vecs[node.m_training_vecs[i]].first;
						const uint64_t weight = m_training_vecs[node.m_training_vecs[i]].second;
					
						if ((!i) || (v == firstVec))
						{
							firstVec = v;

							new_r_child += (v * static_cast<float>(weight));
							r_weight += weight;

							r_ttsum += weight * v.dot(v);
							r_children.push_back(node.m_training_vecs[i]);
						}
						else
						{
							new_l_child += (v * static_cast<float>(weight));
							l_weight += weight;

							l_ttsum += weight * v.dot(v);
							l_children.push_back(node.m_training_vecs[i]);
						}
					}

					if ((!l_weight) || (!r_weight))
						return false;
				}

				l_var = static_cast<float>(l_ttsum - (new_l_child.dot(new_l_child) / l_weight));
				r_var = static_cast<float>(r_ttsum - (new_r_child.dot(new_r_child) / r_weight));

				new_l_child *= (1.0f / l_weight);
				new_r_child *= (1.0f / r_weight);

				l_child = new_l_child;
				r_child = new_r_child;

				float total_var = l_var + r_var;
				const float cGiveupVariance = .00001f;
				if (total_var < cGiveupVariance)
					break;

				// Check to see if the variance has settled
				const float cVarianceDeltaThresh = .00125f;
				if (((prev_total_variance - total_var) / total_var) < cVarianceDeltaThresh)
					break;

				prev_total_variance = total_var;
			}

			return true;
		}
	};

	struct weighted_block_group
	{
		uint64_t m_total_weight;
		uint_vec m_indices;
	};

	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)
	{
		codebook.resize(0);
		parent_codebook.resize(0);

		if ((max_threads <= 1) || (q.get_training_vecs().size() < 256) || (max_codebook_size < max_threads * 16))
		{
			if (!q.generate(max_codebook_size))
				return false;

			q.retrieve(codebook);

			if (max_parent_codebook_size)
				q.retrieve(max_parent_codebook_size, parent_codebook);

			return true;
		}

		const uint32_t cMaxThreads = 16;
		if (max_threads > cMaxThreads)
			max_threads = cMaxThreads;

		if (!q.generate(max_threads))
			return false;

		basisu::vector<uint_vec> initial_codebook;

		q.retrieve(initial_codebook);

		if (initial_codebook.size() < max_threads)
		{
			codebook = initial_codebook;

			if (max_parent_codebook_size)
				q.retrieve(max_parent_codebook_size, parent_codebook);

			return true;
		}

		Quantizer quantizers[cMaxThreads];
		
		bool success_flags[cMaxThreads];
		clear_obj(success_flags);

		basisu::vector<uint_vec> local_clusters[cMaxThreads];
		basisu::vector<uint_vec> local_parent_clusters[cMaxThreads];

		for (uint32_t thread_iter = 0; thread_iter < max_threads; thread_iter++)
		{
			pJob_pool->add_job( [thread_iter, &local_clusters, &local_parent_clusters, &success_flags, &quantizers, &initial_codebook, &q, &limit_clusterizers, &max_codebook_size, &max_threads, &max_parent_codebook_size] {

				Quantizer& lq = quantizers[thread_iter];
				uint_vec& cluster_indices = initial_codebook[thread_iter];

				uint_vec local_to_global(cluster_indices.size());

				for (uint32_t i = 0; i < cluster_indices.size(); i++)
				{
					const uint32_t global_training_vec_index = cluster_indices[i];
					local_to_global[i] = global_training_vec_index;

					lq.add_training_vec(q.get_training_vecs()[global_training_vec_index].first, q.get_training_vecs()[global_training_vec_index].second);
				}

				const uint32_t max_clusters = limit_clusterizers ? ((max_codebook_size + max_threads - 1) / max_threads) : (uint32_t)lq.get_total_training_vecs();

				success_flags[thread_iter] = lq.generate(max_clusters);

				if (success_flags[thread_iter])
				{
					lq.retrieve(local_clusters[thread_iter]);

					for (uint32_t i = 0; i < local_clusters[thread_iter].size(); i++)
					{
						for (uint32_t j = 0; j < local_clusters[thread_iter][i].size(); j++)
							local_clusters[thread_iter][i][j] = local_to_global[local_clusters[thread_iter][i][j]];
					}

					if (max_parent_codebook_size)
					{
						lq.retrieve((max_parent_codebook_size + max_threads - 1) / max_threads, local_parent_clusters[thread_iter]);

						for (uint32_t i = 0; i < local_parent_clusters[thread_iter].size(); i++)
						{
							for (uint32_t j = 0; j < local_parent_clusters[thread_iter][i].size(); j++)
								local_parent_clusters[thread_iter][i][j] = local_to_global[local_parent_clusters[thread_iter][i][j]];
						}
					}
				}

			} );

		} // thread_iter

		pJob_pool->wait_for_all();

		uint32_t total_clusters = 0, total_parent_clusters = 0;

		for (int thread_iter = 0; thread_iter < (int)max_threads; thread_iter++)
		{
			if (!success_flags[thread_iter])
				return false;
			total_clusters += (uint32_t)local_clusters[thread_iter].size();
			total_parent_clusters += (uint32_t)local_parent_clusters[thread_iter].size();
		}

		codebook.reserve(total_clusters);
		parent_codebook.reserve(total_parent_clusters);

		for (uint32_t thread_iter = 0; thread_iter < max_threads; thread_iter++)
		{
			for (uint32_t j = 0; j < local_clusters[thread_iter].size(); j++)
			{
				codebook.resize(codebook.size() + 1);
				codebook.back().swap(local_clusters[thread_iter][j]);
			}

			for (uint32_t j = 0; j < local_parent_clusters[thread_iter].size(); j++)
			{
				parent_codebook.resize(parent_codebook.size() + 1);
				parent_codebook.back().swap(local_parent_clusters[thread_iter][j]);
			}
		}

		return true;
	}

	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)
	{
		//typedef bit_hasher<typename Quantizer::training_vec_type> training_vec_bit_hasher;

		// rg 6/24/2025 - Cross platform determinism
#if 0
		typedef std::unordered_map < typename Quantizer::training_vec_type, weighted_block_group, 
			training_vec_bit_hasher> group_hash;
#else
		typedef std::map< typename Quantizer::training_vec_type, weighted_block_group > group_hash;
#endif
		
		//interval_timer tm;
		//tm.start();

		group_hash unique_vecs;

		// rg 6/24/2025 - Cross platform determinism
#if 0
		unique_vecs.reserve(20000);
#endif

		weighted_block_group g;
		
		if (even_odd_input_pairs_equal)
		{
			g.m_indices.resize(2);

			assert(q.get_training_vecs().size() >= 2 && (q.get_training_vecs().size() & 1) == 0);

			for (uint32_t i = 0; i < q.get_training_vecs().size(); i += 2)
			{
				assert(q.get_training_vecs()[i].first == q.get_training_vecs()[i + 1].first);

				g.m_total_weight = q.get_training_vecs()[i].second + q.get_training_vecs()[i + 1].second;
				g.m_indices[0] = i;
				g.m_indices[1] = i + 1;

				auto ins_res = unique_vecs.insert(std::make_pair(q.get_training_vecs()[i].first, g));

				if (!ins_res.second)
				{
					(ins_res.first)->second.m_total_weight += g.m_total_weight;
					(ins_res.first)->second.m_indices.push_back(i);
					(ins_res.first)->second.m_indices.push_back(i + 1);
				}
			}
		}
		else
		{
			g.m_indices.resize(1);

			for (uint32_t i = 0; i < q.get_training_vecs().size(); i++)
			{
				g.m_total_weight = q.get_training_vecs()[i].second;
				g.m_indices[0] = i;

				auto ins_res = unique_vecs.insert(std::make_pair(q.get_training_vecs()[i].first, g));

				if (!ins_res.second)
				{
					(ins_res.first)->second.m_total_weight += g.m_total_weight;
					(ins_res.first)->second.m_indices.push_back(i);
				}
			}
		}

		//debug_printf("generate_hierarchical_codebook_threaded: %u training vectors, %u unique training vectors, %3.3f secs\n", q.get_total_training_vecs(), (uint32_t)unique_vecs.size(), tm.get_elapsed_secs());
		debug_printf("generate_hierarchical_codebook_threaded: %u training vectors, %u unique training vectors\n", q.get_total_training_vecs(), (uint32_t)unique_vecs.size());

		Quantizer group_quant;
		typedef typename group_hash::const_iterator group_hash_const_iter;
		basisu::vector<group_hash_const_iter> unique_vec_iters;
		unique_vec_iters.reserve(unique_vecs.size());

		for (auto iter = unique_vecs.begin(); iter != unique_vecs.end(); ++iter)
		{
			group_quant.add_training_vec(iter->first, iter->second.m_total_weight);
			unique_vec_iters.push_back(iter);
		}

		bool limit_clusterizers = true;
		if (unique_vecs.size() <= max_codebook_size)
			limit_clusterizers = false;

		debug_printf("Limit clusterizers: %u\n", limit_clusterizers);

		basisu::vector<uint_vec> group_codebook, group_parent_codebook;
		bool status = generate_hierarchical_codebook_threaded_internal(group_quant,
			max_codebook_size, max_parent_codebook_size,
			group_codebook,
			group_parent_codebook,
			(unique_vecs.size() < 65536*4) ? 1 : max_threads, limit_clusterizers, pJob_pool);

		if (!status)
			return false;

		codebook.resize(0);
		for (uint32_t i = 0; i < group_codebook.size(); i++)
		{
			codebook.resize(codebook.size() + 1);

			for (uint32_t j = 0; j < group_codebook[i].size(); j++)
			{
				const uint32_t group_index = group_codebook[i][j];

				typename group_hash::const_iterator group_iter = unique_vec_iters[group_index];
				const uint_vec& training_vec_indices = group_iter->second.m_indices;
				
				append_vector(codebook.back(), training_vec_indices);
			}
		}

		parent_codebook.resize(0);
		for (uint32_t i = 0; i < group_parent_codebook.size(); i++)
		{
			parent_codebook.resize(parent_codebook.size() + 1);

			for (uint32_t j = 0; j < group_parent_codebook[i].size(); j++)
			{
				const uint32_t group_index = group_parent_codebook[i][j];

				typename group_hash::const_iterator group_iter = unique_vec_iters[group_index];
				const uint_vec& training_vec_indices = group_iter->second.m_indices;

				append_vector(parent_codebook.back(), training_vec_indices);
			}
		}

		return true;
	}

	// Canonical Huffman coding

	class histogram
	{
		basisu::vector<uint32_t> m_hist;

	public:
		histogram(uint32_t size = 0) { init(size); }

		void clear()
		{
			clear_vector(m_hist);
		}

		void init(uint32_t size)
		{
			m_hist.resize(0);
			m_hist.resize(size);
		}

		inline uint32_t size() const { return static_cast<uint32_t>(m_hist.size()); }

		inline const uint32_t &operator[] (uint32_t index) const
		{
			return m_hist[index];
		}

		inline uint32_t &operator[] (uint32_t index)
		{
			return m_hist[index];
		}

		inline void inc(uint32_t index)
		{
			m_hist[index]++;
		}

		uint64_t get_total() const
		{
			uint64_t total = 0;
			for (uint32_t i = 0; i < m_hist.size(); ++i)
				total += m_hist[i];
			return total;
		}

		double get_entropy() const
		{
			double total = static_cast<double>(get_total());
			if (total == 0.0f)
				return 0.0f;

			const double inv_total = 1.0f / total;
			const double neg_inv_log2 = -1.0f / log(2.0f);
			
			double e = 0.0f;
			for (uint32_t i = 0; i < m_hist.size(); i++)
				if (m_hist[i])
					e += log(m_hist[i] * inv_total) * neg_inv_log2 * static_cast<double>(m_hist[i]);

			return e;
		}
	};
		
	struct sym_freq
	{
		uint32_t m_key;
		uint16_t m_sym_index;
	};

	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
	{
	public:
		huffman_encoding_table()
		{
		}

		void clear()
		{
			clear_vector(m_codes);
			clear_vector(m_code_sizes);
		}

		bool init(const histogram &h, uint32_t max_code_size = cHuffmanMaxSupportedCodeSize)
		{
			return init(h.size(), &h[0], max_code_size);
		}

		bool init(uint32_t num_syms, const uint16_t *pFreq, uint32_t max_code_size);
		bool init(uint32_t num_syms, const uint32_t *pSym_freq, uint32_t max_code_size);
		
		inline const uint16_vec &get_codes() const { return m_codes; }
		inline const uint8_vec &get_code_sizes() const { return m_code_sizes; }

		uint32_t get_total_used_codes() const
		{
			for (int i = static_cast<int>(m_code_sizes.size()) - 1; i >= 0; i--)
				if (m_code_sizes[i])
					return i + 1;
			return 0;
		}

	private:
		uint16_vec m_codes;
		uint8_vec m_code_sizes;
	};

	class bitwise_coder
	{
	public:
		bitwise_coder() :
			m_bit_buffer(0),
			m_bit_buffer_size(0),
			m_total_bits(0)
		{
		}

		bitwise_coder(const bitwise_coder& other) :
			m_bytes(other.m_bytes),
			m_bit_buffer(other.m_bit_buffer),
			m_bit_buffer_size(other.m_bit_buffer_size),
			m_total_bits(other.m_total_bits)			
		{
		}

		bitwise_coder(bitwise_coder&& other) :
			m_bytes(std::move(other.m_bytes)),
			m_bit_buffer(other.m_bit_buffer),
			m_bit_buffer_size(other.m_bit_buffer_size),
			m_total_bits(other.m_total_bits)
		{
		}

		bitwise_coder& operator= (const bitwise_coder& rhs)
		{
			if (this == &rhs)
				return *this;

			m_bytes = rhs.m_bytes;
			m_bit_buffer = rhs.m_bit_buffer;
			m_bit_buffer_size = rhs.m_bit_buffer_size;
			m_total_bits = rhs.m_total_bits;

			return *this;
		}

		bitwise_coder& operator= (bitwise_coder&& rhs)
		{
			if (this == &rhs)
				return *this;

			m_bytes = std::move(rhs.m_bytes);
			m_bit_buffer = rhs.m_bit_buffer;
			m_bit_buffer_size = rhs.m_bit_buffer_size;
			m_total_bits = rhs.m_total_bits;

			return *this;
		}

		inline void clear()
		{
			clear_vector(m_bytes);
			m_bit_buffer = 0;
			m_bit_buffer_size = 0;
			m_total_bits = 0;
		}

		inline void restart()
		{
			m_bytes.resize(0);
			m_bit_buffer = 0;
			m_bit_buffer_size = 0;
			m_total_bits = 0;
		}

		inline const uint8_vec &get_bytes() const { return m_bytes; }
		inline uint8_vec& get_bytes() { return m_bytes; }

		inline void reserve(uint32_t size) { m_bytes.reserve(size); }

		inline uint64_t get_total_bits() const { return m_total_bits; }
		inline uint32_t get_total_bits_u32() const { assert(m_total_bits <= UINT32_MAX); return static_cast<uint32_t>(m_total_bits); }
		inline void clear_total_bits() { m_total_bits = 0; }

		inline void init(uint32_t reserve_size = 1024)
		{
			m_bytes.reserve(reserve_size);
			m_bytes.resize(0);

			m_bit_buffer = 0;
			m_bit_buffer_size = 0;
			m_total_bits = 0;
		}

		inline uint32_t flush()
		{
			if (m_bit_buffer_size)
			{
				m_total_bits += 8 - (m_bit_buffer_size & 7);
				append_byte(static_cast<uint8_t>(m_bit_buffer));

				m_bit_buffer = 0;
				m_bit_buffer_size = 0;
				
				return 8;
			}

			return 0;
		}

		inline uint32_t put_bits(uint32_t bits, uint32_t num_bits)
		{
			assert(num_bits <= 32);
			assert(bits < (1ULL << num_bits));

			if (!num_bits)
				return 0;

			m_total_bits += num_bits;

			uint64_t v = (static_cast<uint64_t>(bits) << m_bit_buffer_size) | m_bit_buffer;
			m_bit_buffer_size += num_bits;

			while (m_bit_buffer_size >= 8)
			{
				append_byte(static_cast<uint8_t>(v));
				v >>= 8;
				m_bit_buffer_size -= 8;
			}

			m_bit_buffer = static_cast<uint8_t>(v);
			return num_bits;
		}

		inline uint32_t put_code(uint32_t sym, const huffman_encoding_table &tab)
		{
			uint32_t code = tab.get_codes()[sym];
			uint32_t code_size = tab.get_code_sizes()[sym];
			assert(code_size >= 1);
			put_bits(code, code_size);
			return code_size;
		}

		inline uint32_t put_truncated_binary(uint32_t v, uint32_t n)
		{
			assert((n >= 2) && (v < n));

			uint32_t k = floor_log2i(n);
			uint32_t u = (1 << (k + 1)) - n;

			if (v < u)
				return put_bits(v, k);
			
			uint32_t x = v + u;
			assert((x >> 1) >= u);

			put_bits(x >> 1, k);
			put_bits(x & 1, 1);
			return k + 1;
		}

		inline uint32_t put_rice(uint32_t v, uint32_t m)
		{
			assert(m);
			
			const uint64_t start_bits = m_total_bits;

			uint32_t q = v >> m, r = v & ((1 << m) - 1);

			// rice coding sanity check
			assert(q <= 64);
			
			for (; q > 16; q -= 16)
				put_bits(0xFFFF, 16);

			put_bits((1 << q) - 1, q);
			put_bits(r << 1, m + 1);
			
			return (uint32_t)(m_total_bits - start_bits);
		}

		inline uint32_t put_vlc(uint32_t v, uint32_t chunk_bits)
		{
			assert(chunk_bits);

			const uint32_t chunk_size = 1 << chunk_bits;
			const uint32_t chunk_mask = chunk_size - 1;
					
			uint32_t total_bits = 0;

			for ( ; ; )
			{
				uint32_t next_v = v >> chunk_bits;
								
				total_bits += put_bits((v & chunk_mask) | (next_v ? chunk_size : 0), chunk_bits + 1);
				if (!next_v)
					break;

				v = next_v;
			}

			return total_bits;
		}

		uint32_t emit_huffman_table(const huffman_encoding_table &tab);

		void append(const bitwise_coder& other)
		{
			for (uint32_t i = 0; i < other.m_bytes.size(); i++)
				put_bits(other.m_bytes[i], 8);
		
			if (other.m_bit_buffer_size)
				put_bits(other.m_bit_buffer, other.m_bit_buffer_size);
		}
		
	private:
		uint8_vec m_bytes;
		uint32_t m_bit_buffer, m_bit_buffer_size;
		uint64_t m_total_bits;

		inline void append_byte(uint8_t c)
		{
			//m_bytes.resize(m_bytes.size() + 1);
			//m_bytes.back() = c;

			m_bytes.push_back(c);
		}

		static void end_nonzero_run(uint16_vec &syms, uint32_t &run_size, uint32_t len);
		static void end_zero_run(uint16_vec &syms, uint32_t &run_size);
	};

	class huff2D
	{
	public:
		huff2D() { }
		huff2D(uint32_t bits_per_sym, uint32_t total_syms_per_group) { init(bits_per_sym, total_syms_per_group); }

		inline const histogram &get_histogram() const { return m_histogram; }
		inline const huffman_encoding_table &get_encoding_table() const { return m_encoding_table; }

		inline void init(uint32_t bits_per_sym, uint32_t total_syms_per_group)
		{
			assert((bits_per_sym * total_syms_per_group) <= 16 && total_syms_per_group >= 1 && bits_per_sym >= 1);
						
			m_bits_per_sym = bits_per_sym;
			m_total_syms_per_group = total_syms_per_group;
			m_cur_sym_bits = 0;
			m_cur_num_syms = 0;
			m_decode_syms_remaining = 0;
			m_next_decoder_group_index = 0;

			m_histogram.init(1 << (bits_per_sym * total_syms_per_group));
		}

		inline void clear()
		{
			m_group_bits.clear();

			m_cur_sym_bits = 0;
			m_cur_num_syms = 0;
			m_decode_syms_remaining = 0;
			m_next_decoder_group_index = 0;
		}

		inline void emit(uint32_t sym)
		{
			m_cur_sym_bits |= (sym << (m_cur_num_syms * m_bits_per_sym));
			m_cur_num_syms++;

			if (m_cur_num_syms == m_total_syms_per_group)
				flush();
		}

		inline void flush()
		{
			if (m_cur_num_syms)
			{
				m_group_bits.push_back(m_cur_sym_bits);
				m_histogram.inc(m_cur_sym_bits);

				m_cur_sym_bits = 0;
				m_cur_num_syms = 0;
			}
		}

		inline bool start_encoding(uint32_t code_size_limit = 16)
		{
			flush();

			if (!m_encoding_table.init(m_histogram, code_size_limit))
				return false;

			m_decode_syms_remaining = 0;
			m_next_decoder_group_index = 0;

			return true;
		}
				
		inline uint32_t emit_next_sym(bitwise_coder &c)
		{
			uint32_t bits = 0;

			if (!m_decode_syms_remaining)
			{
				bits = c.put_code(m_group_bits[m_next_decoder_group_index++], m_encoding_table);
				m_decode_syms_remaining = m_total_syms_per_group;
			}

			m_decode_syms_remaining--;
			return bits;
		}

		inline void emit_flush()
		{
			m_decode_syms_remaining = 0;
		}

	private:
		uint_vec m_group_bits;
		huffman_encoding_table m_encoding_table;
		histogram m_histogram;
		uint32_t m_bits_per_sym, m_total_syms_per_group, m_cur_sym_bits, m_cur_num_syms, m_next_decoder_group_index, m_decode_syms_remaining;
	};

	bool huffman_test(int rand_seed);

	// VQ index reordering
	
	class palette_index_reorderer
	{
	public:
		palette_index_reorderer()
		{
		}

		void clear()
		{
			clear_vector(m_hist);
			clear_vector(m_total_count_to_picked);
			clear_vector(m_entries_picked);
			clear_vector(m_entries_to_do);
			clear_vector(m_remap_table);
		}

		// returns [0,1] distance of entry i to entry j
		typedef float(*pEntry_dist_func)(uint32_t i, uint32_t j, void *pCtx);

		void init(uint32_t num_indices, const uint32_t *pIndices, uint32_t num_syms, pEntry_dist_func pDist_func, void *pCtx, float dist_func_weight);
		
		// Table remaps old to new symbol indices
		inline const uint_vec &get_remap_table() const { return m_remap_table; }

	private:
		uint_vec m_hist, m_total_count_to_picked, m_entries_picked, m_entries_to_do, m_remap_table;

		inline uint32_t get_hist(int i, int j, int n) const { return (i > j) ? m_hist[j * n + i] : m_hist[i * n + j]; }
		inline void inc_hist(int i, int j, int n) { if ((i != j) && (i < j) && (i != -1) && (j != -1)) { assert(((uint32_t)i < (uint32_t)n) && ((uint32_t)j < (uint32_t)n)); m_hist[i * n + j]++; } }

		void prepare_hist(uint32_t num_syms, uint32_t num_indices, const uint32_t *pIndices);
		void find_initial(uint32_t num_syms);
		void find_next_entry(uint32_t &best_entry, double &best_count, pEntry_dist_func pDist_func, void *pCtx, float dist_func_weight);
		float pick_side(uint32_t num_syms, uint32_t entry_to_move, pEntry_dist_func pDist_func, void *pCtx, float dist_func_weight);
	};

	// Simple 32-bit 2D image class

	class image
	{
	public:
		image() : 
			m_width(0), m_height(0), m_pitch(0)
		{
		}

		image(uint32_t w, uint32_t h, uint32_t p = UINT32_MAX) : 
			m_width(0), m_height(0), m_pitch(0)
		{
			resize(w, h, p);
		}

		image(const uint8_t *pImage, uint32_t width, uint32_t height, uint32_t comps) :
			m_width(0), m_height(0), m_pitch(0)
		{
			init(pImage, width, height, comps);
		}

		image(const image &other) :
			m_width(0), m_height(0), m_pitch(0)
		{
			*this = other;
		}

		image(image&& other) :
			m_width(other.m_width), m_height(other.m_height), m_pitch(other.m_pitch),
			m_pixels(std::move(other.m_pixels))
		{
			other.m_width = 0;
			other.m_height = 0;
			other.m_pitch = 0;
		}

		image& operator= (image&& rhs)
		{
			if (this != &rhs)
			{
				m_width = rhs.m_width;
				m_height = rhs.m_height;
				m_pitch = rhs.m_pitch;
				m_pixels = std::move(rhs.m_pixels);

				rhs.m_width = 0;
				rhs.m_height = 0;
				rhs.m_pitch = 0;
			}
			return *this;
		}

		image &swap(image &other)
		{
			std::swap(m_width, other.m_width);
			std::swap(m_height, other.m_height);
			std::swap(m_pitch, other.m_pitch);
			m_pixels.swap(other.m_pixels);
			return *this;
		}

		image &operator= (const image &rhs)
		{
			if (this != &rhs)
			{
				m_width = rhs.m_width;
				m_height = rhs.m_height;
				m_pitch = rhs.m_pitch;
				m_pixels = rhs.m_pixels;
			}
			return *this;
		}

		image &clear()
		{
			m_width = 0; 
			m_height = 0;
			m_pitch = 0;
			clear_vector(m_pixels);
			return *this;
		}

		image& match_dimensions(const image& other)
		{
			resize(other.get_width(), other.get_height());
			return *this;
		}

		image &resize(uint32_t w, uint32_t h, uint32_t p = UINT32_MAX, const color_rgba& background = g_black_color)
		{
			return crop(w, h, p, background);
		}

		image &set_all(const color_rgba &c)
		{
			for (uint32_t i = 0; i < m_pixels.size(); i++)
				m_pixels[i] = c;
			return *this;
		}

		void init(const uint8_t *pImage, uint32_t width, uint32_t height, uint32_t comps)
		{
			assert(comps >= 1 && comps <= 4);
			
			resize(width, height);

			for (uint32_t y = 0; y < height; y++)
			{
				for (uint32_t x = 0; x < width; x++)
				{
					const uint8_t *pSrc = &pImage[(x + y * width) * comps];
					color_rgba &dst = (*this)(x, y);

					if (comps == 1)
					{
						dst.r = pSrc[0];
						dst.g = pSrc[0];
						dst.b = pSrc[0];
						dst.a = 255;
					}
					else if (comps == 2)
					{
						dst.r = pSrc[0];
						dst.g = pSrc[0];
						dst.b = pSrc[0];
						dst.a = pSrc[1];
					}
					else
					{
						dst.r = pSrc[0];
						dst.g = pSrc[1];
						dst.b = pSrc[2];
						if (comps == 4)
							dst.a = pSrc[3];
						else
							dst.a = 255;
					}
				}
			}
		}

		image &fill_box(uint32_t x, uint32_t y, uint32_t w, uint32_t h, const color_rgba &c)
		{
			assert((int)w >= 0);
			assert((int)h >= 0);

			for (uint32_t iy = 0; iy < h; iy++)
				for (uint32_t ix = 0; ix < w; ix++)
					set_clipped(x + ix, y + iy, c);
			return *this;
		}

		image& fill_box_alpha(uint32_t x, uint32_t y, uint32_t w, uint32_t h, const color_rgba& c)
		{
			assert((int)w >= 0);
			assert((int)h >= 0);

			for (uint32_t iy = 0; iy < h; iy++)
				for (uint32_t ix = 0; ix < w; ix++)
					set_clipped_alpha(x + ix, y + iy, c);
			return *this;
		}

		image &crop_dup_borders(uint32_t w, uint32_t h)
		{
			const uint32_t orig_w = m_width, orig_h = m_height;

			crop(w, h);

			if (orig_w && orig_h)
			{
				if (m_width > orig_w)
				{
					for (uint32_t x = orig_w; x < m_width; x++)
						for (uint32_t y = 0; y < m_height; y++)
							set_clipped(x, y, get_clamped(minimum(x, orig_w - 1U), minimum(y, orig_h - 1U)));
				}

				if (m_height > orig_h)
				{
					for (uint32_t y = orig_h; y < m_height; y++)
						for (uint32_t x = 0; x < m_width; x++)
							set_clipped(x, y, get_clamped(minimum(x, orig_w - 1U), minimum(y, orig_h - 1U)));
				}
			}
			return *this;
		}

		// pPixels MUST have been allocated using malloc() (basisu::vector will eventually use free() on the pointer).
		image& grant_ownership(color_rgba* pPixels, uint32_t w, uint32_t h, uint32_t p = UINT32_MAX)
		{
			if (p == UINT32_MAX)
				p = w;

			clear();
			
			if ((!p) || (!w) || (!h))
				return *this;

			m_pixels.grant_ownership(pPixels, p * h, p * h);

			m_width = w;
			m_height = h;
			m_pitch = p;

			return *this;
		}

		image &crop(uint32_t w, uint32_t h, uint32_t p = UINT32_MAX, const color_rgba &background = g_black_color, bool init_image = true)
		{
			if (p == UINT32_MAX)
				p = w;

			if ((w == m_width) && (m_height == h) && (m_pitch == p))
				return *this;

			if ((!w) || (!h) || (!p))
			{
				clear();
				return *this;
			}

			color_rgba_vec cur_state;
			cur_state.swap(m_pixels);

			m_pixels.resize(p * h);

			if (init_image)
			{
				if (m_width || m_height)
				{
					for (uint32_t y = 0; y < h; y++)
					{
						for (uint32_t x = 0; x < w; x++)
						{
							if ((x < m_width) && (y < m_height))
								m_pixels[x + y * p] = cur_state[x + y * m_pitch];
							else
								m_pixels[x + y * p] = background;
						}
					}
				}
				else
				{
					m_pixels.set_all(background);
				}
			}

			m_width = w;
			m_height = h;
			m_pitch = p;

			return *this;
		}

		inline const color_rgba &operator() (uint32_t x, uint32_t y) const { assert(x < m_width && y < m_height); return m_pixels[x + y * m_pitch]; }
		inline color_rgba &operator() (uint32_t x, uint32_t y) { assert(x < m_width && y < m_height); return m_pixels[x + y * m_pitch]; }

		inline const color_rgba &get_clamped(int x, int y) const { return (*this)(clamp<int>(x, 0, m_width - 1), clamp<int>(y, 0, m_height - 1)); }
		inline color_rgba &get_clamped(int x, int y) { return (*this)(clamp<int>(x, 0, m_width - 1), clamp<int>(y, 0, m_height - 1)); }

		inline const color_rgba &get_clamped_or_wrapped(int x, int y, bool wrap_u, bool wrap_v) const
		{
			x = wrap_u ? posmod(x, m_width) : clamp<int>(x, 0, m_width - 1);
			y = wrap_v ? posmod(y, m_height) : clamp<int>(y, 0, m_height - 1);
			return m_pixels[x + y * m_pitch];
		}

		inline color_rgba &get_clamped_or_wrapped(int x, int y, bool wrap_u, bool wrap_v)
		{
			x = wrap_u ? posmod(x, m_width) : clamp<int>(x, 0, m_width - 1);
			y = wrap_v ? posmod(y, m_height) : clamp<int>(y, 0, m_height - 1);
			return m_pixels[x + y * m_pitch];
		}
		
		inline image &set_clipped(int x, int y, const color_rgba &c) 
		{
			if ((static_cast<uint32_t>(x) < m_width) && (static_cast<uint32_t>(y) < m_height))
				(*this)(x, y) = c;
			return *this;
		}

		inline image& set_clipped_alpha(int x, int y, const color_rgba& c)
		{
			if ((static_cast<uint32_t>(x) < m_width) && (static_cast<uint32_t>(y) < m_height))
				(*this)(x, y).m_comps[3] = c.m_comps[3];
			return *this;
		}

		// Very straightforward blit with full clipping. Not fast, but it works.
		image &blit(const image &src, int src_x, int src_y, int src_w, int src_h, int dst_x, int dst_y, bool set_clipped_to_black = false)
		{
			if (set_clipped_to_black)
			{
				for (int y = 0; y < src_h; y++)
				{
					const int sy = src_y + y;
					
					for (int x = 0; x < src_w; x++)
					{
						const int sx = src_x + x;
						
						const bool clipped_flag = (sx < 0) || (sx >= (int)src.get_width()) || (sy < 0) || (sy >= (int)src.get_height());

						set_clipped(dst_x + x, dst_y + y, clipped_flag ? g_black_color : src(sx, sy));
					}
				}
			}
			else
			{
				for (int y = 0; y < src_h; y++)
				{
					const int sy = src_y + y;
					if (sy < 0)
						continue;
					else if (sy >= (int)src.get_height())
						break;

					for (int x = 0; x < src_w; x++)
					{
						const int sx = src_x + x;
						if (sx < 0)
							continue;
						else if (sx >= (int)src.get_width())
							break;

						set_clipped(dst_x + x, dst_y + y, src(sx, sy));
					}
				}
			}

			return *this;
		}

		image& blit_clamped(const image& src, int src_x, int src_y, int src_w, int src_h, int dst_x, int dst_y)
		{
			for (int y = 0; y < src_h; y++)
				for (int x = 0; x < src_w; x++)
					set_clipped(dst_x + x, dst_y + y, src.get_clamped(src_x + x, src_y + y));

			return *this;
		}
				
		const image &extract_block_clamped(color_rgba *pDst, uint32_t src_x, uint32_t src_y, uint32_t w, uint32_t h) const
		{
			if (((src_x + w) > m_width) || ((src_y + h) > m_height))
			{
				// Slower clamping case
				for (uint32_t y = 0; y < h; y++)
					for (uint32_t x = 0; x < w; x++)
						*pDst++ = get_clamped(src_x + x, src_y + y);
			}
			else
			{
				const color_rgba* pSrc = &m_pixels[src_x + src_y * m_pitch];

				for (uint32_t y = 0; y < h; y++)
				{
					memcpy(pDst, pSrc, w * sizeof(color_rgba));
					pSrc += m_pitch;
					pDst += w;
				}
			}

			return *this;
		}

		image &set_block_clipped(const color_rgba *pSrc, uint32_t dst_x, uint32_t dst_y, uint32_t w, uint32_t h)
		{
			for (uint32_t y = 0; y < h; y++)
				for (uint32_t x = 0; x < w; x++)
					set_clipped(dst_x + x, dst_y + y, *pSrc++);
			return *this;
		}

		inline bool is_valid() const { return m_width > 0; }

		inline uint32_t get_width() const { return m_width; }
		inline uint32_t get_height() const { return m_height; }
		inline uint32_t get_pitch() const { return m_pitch; }
		inline uint32_t get_total_pixels() const { return m_width * m_height; }

		inline uint32_t get_block_width(uint32_t w) const { return (m_width + (w - 1)) / w; }
		inline uint32_t get_block_height(uint32_t h) const { return (m_height + (h - 1)) / h; }
		inline uint32_t get_total_blocks(uint32_t w, uint32_t h) const { return get_block_width(w) * get_block_height(h); }

		inline const color_rgba_vec &get_pixels() const { return m_pixels; }
		inline color_rgba_vec &get_pixels() { return m_pixels; }

		inline const color_rgba *get_ptr() const { return &m_pixels[0]; }
		inline color_rgba *get_ptr() { return &m_pixels[0]; }

		bool has_alpha(uint32_t channel = 3) const
		{
			for (uint32_t y = 0; y < m_height; ++y)
				for (uint32_t x = 0; x < m_width; ++x)
					if ((*this)(x, y)[channel] < 255)
						return true;

			return false;
		}

		image &set_alpha(uint8_t a)
		{
			for (uint32_t y = 0; y < m_height; ++y)
				for (uint32_t x = 0; x < m_width; ++x)
					(*this)(x, y).a = a;
			return *this;
		}

		image &flip_y()
		{
			for (uint32_t y = 0; y < m_height / 2; ++y)
				for (uint32_t x = 0; x < m_width; ++x)
					std::swap((*this)(x, y), (*this)(x, m_height - 1 - y));
			return *this;
		}

		// TODO: There are many ways to do this, not sure this is the best way.
		image &renormalize_normal_map()
		{
			for (uint32_t y = 0; y < m_height; y++)
			{
				for (uint32_t x = 0; x < m_width; x++)
				{
					color_rgba &c = (*this)(x, y);
					if ((c.r == 128) && (c.g == 128) && (c.b == 128))
						continue;

					vec3F v(c.r, c.g, c.b);
					v = (v * (2.0f / 255.0f)) - vec3F(1.0f);
					v.clamp(-1.0f, 1.0f);

					float length = v.length();
					const float cValidThresh = .077f;
					if (length < cValidThresh)
					{
						c.set(128, 128, 128, c.a);
					}
					else if (fabs(length - 1.0f) > cValidThresh)
					{
						if (length)
							v /= length;

						for (uint32_t i = 0; i < 3; i++)
							c[i] = static_cast<uint8_t>(clamp<float>(floor((v[i] + 1.0f) * 255.0f * .5f + .5f), 0.0f, 255.0f));

						if ((c.g == 128) && (c.r == 128))
						{
							if (c.b < 128)
								c.b = 0;
							else
								c.b = 255;
						}
					}
				}
			}
			return *this;
		}

		void swap_rb()
		{
			for (auto& v : m_pixels)
				std::swap(v.r, v.b);
		}

		void debug_text(uint32_t x_ofs, uint32_t y_ofs, uint32_t x_scale, uint32_t y_scale, const color_rgba &fg, const color_rgba *pBG, bool alpha_only, const char* p, ...);
				
		// bilinear filtering
		vec4F get_filtered_vec4F(float x, float y) const
		{
			x -= .5f;
			y -= .5f;

			int ix = (int)floorf(x);
			int iy = (int)floorf(y);
			float wx = x - ix;
			float wy = y - iy;

			color_rgba a(get_clamped(ix, iy));
			color_rgba b(get_clamped(ix + 1, iy));
			color_rgba c(get_clamped(ix, iy + 1));
			color_rgba d(get_clamped(ix + 1, iy + 1));

			vec4F result;

			for (uint32_t i = 0; i < 4; i++)
			{
				const float top = lerp<float>((float)a[i], (float)b[i], wx);
				const float bot = lerp<float>((float)c[i], (float)d[i], wx);
				const float m = lerp<float>((float)top, (float)bot, wy);

				result[i] = m;
			}

			return result;
		}

		// (x,y) - Continuous coordinates, where pixel centers are at (.5,.5), valid image coords are [0,width] and [0,height]. Clamp addressing.
		color_rgba get_filtered(float x, float y) const
		{
			const vec4F fresult(get_filtered_vec4F(x, y));

			color_rgba result;

			for (uint32_t i = 0; i < 4; i++)
				result[i] = (uint8_t)clamp<int>((int)(fresult[i] + .5f), 0, 255);

			return result;
		}
				
	private:
		uint32_t m_width, m_height, m_pitch;  // all in pixels
		color_rgba_vec m_pixels;
	};

	void draw_line(image& dst, int xs, int ys, int xe, int ye, const color_rgba& color);
	void draw_circle(image& dst, int cx, int cy, int r, const color_rgba& color);

	inline bool is_solid_block(uint32_t n, const color_rgba* pPixels)
	{
		assert(n);
		
		if (n <= 1)
			return true;

		const color_rgba c(pPixels[0]);

		for (uint32_t i = 1; i < n; i++)
			if (c != pPixels[i])
				return false;

		return true;
	}

	inline bool is_alpha_block(uint32_t n, const color_rgba* pPixels)
	{
		assert(n);

		for (uint32_t i = 0; i < n; i++)
			if (pPixels[i][3] != 255)
				return true;

		return false;
	}

	// Float images

	typedef basisu::vector<vec4F> vec4F_vec;

	class imagef
	{
	public:
		imagef() : 
			m_width(0), m_height(0), m_pitch(0)
		{
		}

		imagef(uint32_t w, uint32_t h, uint32_t p = UINT32_MAX) : 
			m_width(0), m_height(0), m_pitch(0)
		{
			resize(w, h, p);
		}

		imagef(const imagef &other) :
			m_width(0), m_height(0), m_pitch(0)
		{
			*this = other;
		}

		imagef(imagef&& other) :
			m_width(other.m_width), m_height(other.m_height), m_pitch(other.m_pitch),
			m_pixels(std::move(other.m_pixels))
		{
			other.m_width = 0;
			other.m_height = 0;
			other.m_pitch = 0;
		}

		imagef& operator= (imagef&& rhs)
		{
			if (this != &rhs)
			{
				m_width = rhs.m_width;
				m_height = rhs.m_height;
				m_pitch = rhs.m_pitch;
				m_pixels = std::move(rhs.m_pixels);

				rhs.m_width = 0;
				rhs.m_height = 0;
				rhs.m_pitch = 0;
			}
			return *this;
		}

		imagef &swap(imagef &other)
		{
			std::swap(m_width, other.m_width);
			std::swap(m_height, other.m_height);
			std::swap(m_pitch, other.m_pitch);
			m_pixels.swap(other.m_pixels);
			return *this;
		}

		imagef &operator= (const imagef &rhs)
		{
			if (this != &rhs)
			{
				m_width = rhs.m_width;
				m_height = rhs.m_height;
				m_pitch = rhs.m_pitch;
				m_pixels = rhs.m_pixels;
			}
			return *this;
		}

		imagef &clear()
		{
			m_width = 0; 
			m_height = 0;
			m_pitch = 0;
			clear_vector(m_pixels);
			return *this;
		}

		imagef &set(const image &src, const vec4F &scale = vec4F(1), const vec4F &bias = vec4F(0))
		{
			const uint32_t width = src.get_width();
			const uint32_t height = src.get_height();

			resize(width, height);

			for (int y = 0; y < (int)height; y++)
			{
				for (uint32_t x = 0; x < width; x++)
				{
					const color_rgba &src_pixel = src(x, y);
					(*this)(x, y).set((float)src_pixel.r * scale[0] + bias[0], (float)src_pixel.g * scale[1] + bias[1], (float)src_pixel.b * scale[2] + bias[2], (float)src_pixel.a * scale[3] + bias[3]);
				}
			}

			return *this;
		}

		imagef& match_dimensions(const imagef& other)
		{
			resize(other.get_width(), other.get_height());
			return *this;
		}

		imagef &resize(const imagef &other, uint32_t p = UINT32_MAX, const vec4F& background = vec4F(0,0,0,1))
		{
			return resize(other.get_width(), other.get_height(), p, background);
		}

		imagef &resize(uint32_t w, uint32_t h, uint32_t p = UINT32_MAX, const vec4F& background = vec4F(0,0,0,1))
		{
			return crop(w, h, p, background);
		}

		imagef &set_all(const vec4F &c)
		{
			for (uint32_t i = 0; i < m_pixels.size(); i++)
				m_pixels[i] = c;
			return *this;
		}

		imagef &fill_box(uint32_t x, uint32_t y, uint32_t w, uint32_t h, const vec4F &c)
		{
			for (uint32_t iy = 0; iy < h; iy++)
				for (uint32_t ix = 0; ix < w; ix++)
					set_clipped(x + ix, y + iy, c);
			return *this;
		}
				
		imagef &crop(uint32_t w, uint32_t h, uint32_t p = UINT32_MAX, const vec4F &background = vec4F(0,0,0,1))
		{
			if (p == UINT32_MAX)
				p = w;

			if ((w == m_width) && (m_height == h) && (m_pitch == p))
				return *this;

			if ((!w) || (!h) || (!p))
			{
				clear();
				return *this;
			}

			vec4F_vec cur_state;
			cur_state.swap(m_pixels);

			m_pixels.resize(p * h);
			
			for (uint32_t y = 0; y < h; y++)
			{
				for (uint32_t x = 0; x < w; x++)
				{
					if ((x < m_width) && (y < m_height))
						m_pixels[x + y * p] = cur_state[x + y * m_pitch];
					else
						m_pixels[x + y * p] = background;
				}
			}

			m_width = w;
			m_height = h;
			m_pitch = p;

			return *this;
		}

		imagef& crop_dup_borders(uint32_t w, uint32_t h)
		{
			const uint32_t orig_w = m_width, orig_h = m_height;

			crop(w, h);

			if (orig_w && orig_h)
			{
				if (m_width > orig_w)
				{
					for (uint32_t x = orig_w; x < m_width; x++)
						for (uint32_t y = 0; y < m_height; y++)
							set_clipped(x, y, get_clamped(minimum(x, orig_w - 1U), minimum(y, orig_h - 1U)));
				}

				if (m_height > orig_h)
				{
					for (uint32_t y = orig_h; y < m_height; y++)
						for (uint32_t x = 0; x < m_width; x++)
							set_clipped(x, y, get_clamped(minimum(x, orig_w - 1U), minimum(y, orig_h - 1U)));
				}
			}
			return *this;
		}

		inline const vec4F &operator() (uint32_t x, uint32_t y) const { assert(x < m_width && y < m_height); return m_pixels[x + y * m_pitch]; }
		inline vec4F &operator() (uint32_t x, uint32_t y) { assert(x < m_width && y < m_height); return m_pixels[x + y * m_pitch]; }

		inline const vec4F &get_clamped(int x, int y) const { return (*this)(clamp<int>(x, 0, m_width - 1), clamp<int>(y, 0, m_height - 1)); }
		inline vec4F &get_clamped(int x, int y) { return (*this)(clamp<int>(x, 0, m_width - 1), clamp<int>(y, 0, m_height - 1)); }

		inline const vec4F &get_clamped_or_wrapped(int x, int y, bool wrap_u, bool wrap_v) const
		{
			x = wrap_u ? posmod(x, m_width) : clamp<int>(x, 0, m_width - 1);
			y = wrap_v ? posmod(y, m_height) : clamp<int>(y, 0, m_height - 1);
			return m_pixels[x + y * m_pitch];
		}

		inline vec4F &get_clamped_or_wrapped(int x, int y, bool wrap_u, bool wrap_v)
		{
			x = wrap_u ? posmod(x, m_width) : clamp<int>(x, 0, m_width - 1);
			y = wrap_v ? posmod(y, m_height) : clamp<int>(y, 0, m_height - 1);
			return m_pixels[x + y * m_pitch];
		}
		
		inline imagef &set_clipped(int x, int y, const vec4F &c) 
		{
			if ((static_cast<uint32_t>(x) < m_width) && (static_cast<uint32_t>(y) < m_height))
				(*this)(x, y) = c;
			return *this;
		}

		// Very straightforward blit with full clipping. Not fast, but it works.
		imagef &blit(const imagef &src, int src_x, int src_y, int src_w, int src_h, int dst_x, int dst_y)
		{
			for (int y = 0; y < src_h; y++)
			{
				const int sy = src_y + y;
				if (sy < 0)
					continue;
				else if (sy >= (int)src.get_height())
					break;

				for (int x = 0; x < src_w; x++)
				{
					const int sx = src_x + x;
					if (sx < 0)
						continue;
					else if (sx >= (int)src.get_width())
						break;

					set_clipped(dst_x + x, dst_y + y, src(sx, sy));
				}
			}

			return *this;
		}

		const imagef &extract_block_clamped(vec4F *pDst, uint32_t src_x, uint32_t src_y, uint32_t w, uint32_t h) const
		{
			for (uint32_t y = 0; y < h; y++)
				for (uint32_t x = 0; x < w; x++)
					*pDst++ = get_clamped(src_x + x, src_y + y);
			return *this;
		}

		imagef &set_block_clipped(const vec4F *pSrc, uint32_t dst_x, uint32_t dst_y, uint32_t w, uint32_t h)
		{
			for (uint32_t y = 0; y < h; y++)
				for (uint32_t x = 0; x < w; x++)
					set_clipped(dst_x + x, dst_y + y, *pSrc++);
			return *this;
		}

		inline bool is_valid() const { return m_width > 0; }

		inline uint32_t get_width() const { return m_width; }
		inline uint32_t get_height() const { return m_height; }
		inline uint32_t get_pitch() const { return m_pitch; }
		inline uint64_t get_total_pixels() const { return (uint64_t)m_width * m_height; }

		inline uint32_t get_block_width(uint32_t w) const { return (m_width + (w - 1)) / w; }
		inline uint32_t get_block_height(uint32_t h) const { return (m_height + (h - 1)) / h; }
		inline uint32_t get_total_blocks(uint32_t w, uint32_t h) const { return get_block_width(w) * get_block_height(h); }

		inline const vec4F_vec &get_pixels() const { return m_pixels; }
		inline vec4F_vec &get_pixels() { return m_pixels; }

		inline const vec4F *get_ptr() const { return &m_pixels[0]; }
		inline vec4F *get_ptr() { return &m_pixels[0]; }

		bool clean_astc_hdr_pixels(float highest_mag)
		{
			bool status = true;
			bool nan_msg = false;
			bool inf_msg = false;
			bool neg_zero_msg = false;
			bool neg_msg = false;
			bool clamp_msg = false;

			for (uint32_t iy = 0; iy < m_height; iy++)
			{
				for (uint32_t ix = 0; ix < m_width; ix++)
				{
					vec4F& c = (*this)(ix, iy);

					for (uint32_t s = 0; s < 4; s++)
					{
						float &p = c[s];
						union { float f; uint32_t u; } x; x.f = p;
						
						if ((std::isnan(p)) || (std::isinf(p)) || (x.u == 0x80000000))
						{
							if (std::isnan(p))
							{
								if (!nan_msg)
								{
									fprintf(stderr, "One or more input pixels was NaN, setting to 0.\n");
									nan_msg = true;
								}
							}

							if (std::isinf(p))
							{
								if (!inf_msg)
								{
									fprintf(stderr, "One or more input pixels was INF, setting to 0.\n");
									inf_msg = true;
								}
							}

							if (x.u == 0x80000000)
							{
								if (!neg_zero_msg)
								{
									fprintf(stderr, "One or more input pixels was -0, setting them to 0.\n");
									neg_zero_msg = true;
								}
							}

							p = 0.0f;
							status = false;
						}
						else
						{
							//const float o = p;
							if (p < 0.0f)
							{
								p = 0.0f;

								if (!neg_msg)
								{
									fprintf(stderr, "One or more input pixels was negative -- setting these pixel components to 0 because ASTC HDR doesn't support signed values.\n");
									neg_msg = true;
								}
								
								status = false;
							}

							if (p > highest_mag)
							{
								p = highest_mag;
								
								if (!clamp_msg)
								{
									fprintf(stderr, "One or more input pixels had to be clamped to %f.\n", highest_mag);
									clamp_msg = true;
								}

								status = false;
							}
						}
					}
				}
			}

			return status;
		}

		imagef& flip_y()
		{
			for (uint32_t y = 0; y < m_height / 2; ++y)
				for (uint32_t x = 0; x < m_width; ++x)
					std::swap((*this)(x, y), (*this)(x, m_height - 1 - y));

			return *this;
		}

		bool has_alpha(uint32_t channel = 3) const
		{
			for (uint32_t y = 0; y < m_height; ++y)
				for (uint32_t x = 0; x < m_width; ++x)
					if ((*this)(x, y)[channel] != 1.0f)
						return true;

			return false;
		}

		vec4F get_filtered_vec4F(float x, float y) const
		{
			x -= .5f;
			y -= .5f;

			int ix = (int)floorf(x);
			int iy = (int)floorf(y);
			float wx = x - ix;
			float wy = y - iy;

			vec4F a(get_clamped(ix, iy));
			vec4F b(get_clamped(ix + 1, iy));
			vec4F c(get_clamped(ix, iy + 1));
			vec4F d(get_clamped(ix + 1, iy + 1));

			vec4F result;

			for (uint32_t i = 0; i < 4; i++)
			{
				const float top = lerp<float>((float)a[i], (float)b[i], wx);
				const float bot = lerp<float>((float)c[i], (float)d[i], wx);
				const float m = lerp<float>((float)top, (float)bot, wy);

				result[i] = m;
			}

			return result;
		}
						
	private:
		uint32_t m_width, m_height, m_pitch;  // all in pixels
		vec4F_vec m_pixels;
	};

	// REC 709 coefficients
	const float REC_709_R = 0.212656f, REC_709_G = 0.715158f, REC_709_B = 0.072186f;

	inline float get_luminance(const vec4F &c)
	{
		return c[0] * REC_709_R + c[1] * REC_709_G + c[2] * REC_709_B;
	}

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

	class fast_linear_to_srgb
	{
	public:
		fast_linear_to_srgb()
		{
			init();
		}

		void init()
		{
			for (int i = 0; i < LINEAR_TO_SRGB_TABLE_SIZE; ++i)
			{
				float l = (float)i * (1.0f / (LINEAR_TO_SRGB_TABLE_SIZE - 1));
				m_linear_to_srgb_table[i] = (uint8_t)basisu::fast_floorf_int(255.0f * basisu::linear_to_srgb(l));
			}

			float srgb_to_linear[256];
			for (int i = 0; i < 256; i++)
				srgb_to_linear[i] = basisu::srgb_to_linear((float)i / 255.0f);

			for (int i = 0; i < 256; i++)
				m_srgb_to_linear_thresh[i] = (srgb_to_linear[i] + srgb_to_linear[basisu::minimum<int>(i + 1, 255)]) * .5f;
		}

		inline uint8_t convert(float l) const
		{
			assert((l >= 0.0f) && (l <= 1.0f));
			int j = basisu::fast_roundf_int((LINEAR_TO_SRGB_TABLE_SIZE - 1) * l);

			assert((j >= 0) && (j < LINEAR_TO_SRGB_TABLE_SIZE));
			int b = m_linear_to_srgb_table[j];

			b += (l > m_srgb_to_linear_thresh[b]);

			return (uint8_t)b;
		}

	private:
		static constexpr int LINEAR_TO_SRGB_TABLE_SIZE = 2048;
		uint8_t m_linear_to_srgb_table[LINEAR_TO_SRGB_TABLE_SIZE];

		float m_srgb_to_linear_thresh[256];
	};

	extern fast_linear_to_srgb g_fast_linear_to_srgb;

	// Image metrics
	
	class image_metrics
	{
	public:
		uint32_t m_width, m_height;
		double m_max, m_mean, m_mean_squared, m_rms, m_psnr, m_ssim;
		bool m_has_neg, m_hf_mag_overflow, m_any_abnormal;
		uint64_t m_sum_a, m_sum_b;

		image_metrics()
		{
			clear();
		}

		void clear()
		{
			m_width = 0;
			m_height = 0;
			m_max = 0;
			m_mean = 0;
			m_mean_squared = 0;
			m_rms = 0;
			m_psnr = 0;
			m_ssim = 0;
			m_has_neg = false;
			m_hf_mag_overflow = false;
			m_any_abnormal = false;
			m_sum_a = 0;
			m_sum_b = 0;
		}

		void print(const char *pPrefix = nullptr)	
		{ 
			//fmt_printf("{}Max: {3.3} Mean: {3.3} RMS: {3.3} PSNR: {2.3} dB, Sums: {} {}, Dim: {}x{}\n", pPrefix ? pPrefix : "", m_max, m_mean, m_rms, m_psnr, m_sum_a, m_sum_b, m_width, m_height);
			fmt_printf("{}Max: {3.3} Mean: {3.3} RMS: {3.3} PSNR: {2.3} dB\n", pPrefix ? pPrefix : "", m_max, m_mean, m_rms, m_psnr);
		}

		void print_hp(const char* pPrefix = nullptr) 
		{ 
			//fmt_printf("{}Max: {3.6} Mean: {3.6} RMS: {3.6} PSNR: {2.6} dB, Any Neg: {}, Half float overflow: {}, Any NaN/Inf: {}, Sums: {} {}, Dim: {}x{}\n", 
			//	pPrefix ? pPrefix : "", m_max, m_mean, m_rms, m_psnr, m_has_neg, m_hf_mag_overflow, m_any_abnormal, m_sum_a, m_sum_b, m_width, m_height); 
			fmt_printf("{}Max: {3.6} Mean: {3.6} RMS: {3.6} PSNR: {2.6} dB, Any Neg: {}, Half float overflow: {}, Any NaN/Inf: {}\n",
				pPrefix ? pPrefix : "", m_max, m_mean, m_rms, m_psnr, m_has_neg, m_hf_mag_overflow, m_any_abnormal);
		}

		void calc(const imagef& a, const imagef& b, uint32_t first_chan = 0, uint32_t total_chans = 0, bool avg_comp_error = true, bool log = false);
		void calc_half(const imagef& a, const imagef& b, uint32_t first_chan, uint32_t total_chans, bool avg_comp_error);
		void calc_half2(const imagef& a, const imagef& b, uint32_t first_chan, uint32_t total_chans, bool avg_comp_error);
		void calc(const image &a, const image &b, uint32_t first_chan = 0, uint32_t total_chans = 0, bool avg_comp_error = true, bool use_601_luma = false);
	};

	void print_image_metrics(const image& a, const image& b);
		
	const float PSNR_HVS_LOSSLESS_DB = 100000.0f;

	inline double psnr_hvs_calc_psnr(double mseh, double peak)
	{
		if (mseh <= 0.0f)
			return PSNR_HVS_LOSSLESS_DB;

		return 10.0f * std::log10((peak * peak) / mseh);
	}

	// To match the PSNR-HVS calcs in the Python code, for testing
	// computes Y of BT.601 "studio swing" / "narrow range" YCbCr
	inline uint8_t get_psnr_hvs_601_y(const color_rgba& c)
	{
		int r = c[0], g = c[1], b = c[2];
		return (uint8_t)std::round(16.0f + 65.481f * (float)r * (1.0f / 255.0f) + 128.553f * (float)g * (1.0f / 255.0f) + 24.966f * (float)b * (1.0f / 255.0f));
	}

	inline float get_psnr_hvs_601_yf(const color_rgba& c)
	{
		float r = (float)c[0], g = (float)c[1], b = (float)c[2];
		return (16.0f + (65.481f / 255.0f) * r + (128.553f / 255.0f) * g + (24.966f / 255.0f) * b) * (1.0f / 255.0f);
	}

	struct psnr_hvs_chan_metrics
	{
		double m_mseh_hvs;
		double m_mseh_hvsm;
		double m_psnr_hvs;
		double m_psnr_hvsm;
	};
		
	// if chan<0, computes in narrow range BT.601 Y
	enum class psnr_hvs_channel_use : int
	{
		cUse601Y8Bit = -1,
		cUse601YFloat = -2
	};
	bool psnr_hvs_compute_chan(const image& a, const image& b, int chan, psnr_hvs_chan_metrics& res);

	struct psnr_hvs_metrics
	{
		psnr_hvs_chan_metrics m_y_601_8bit;
		psnr_hvs_chan_metrics m_y_601_float;

		psnr_hvs_chan_metrics m_chan[4];

		psnr_hvs_chan_metrics m_rgb;
		psnr_hvs_chan_metrics m_rgba;

		bool m_valid;

		psnr_hvs_metrics() { clear(); }

		void clear()
		{
			clear_obj(*this);
		}
	};

	bool psnr_hvs_compute_metrics(const image& a, const image& b, psnr_hvs_metrics &metrics);
	void psnr_hvs_print_metrics(const psnr_hvs_metrics& metrics);
	void print_psnr_hvs_image_metrics(const image& a, const image& b);

	// 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) { return load_png(filename.c_str(), img); }

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

	bool load_qoi(const uint8_t *pBuf, size_t buf_size, image &img);
	bool load_qoi(const char* pFilename, image& img);

	bool load_jpg(const char *pFilename, image& img);
	bool load_jpg(const uint8_t* pBuf, size_t buf_size, image& img);
	inline bool load_jpg(const std::string &filename, image &img) { return load_jpg(filename.c_str(), 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) { return load_image(filename.c_str(), img); }

	bool is_image_filename_hdr(const char* pFilename);

	void convert_ldr_to_hdr_image(imagef& img, const image& ldr_img, bool ldr_srgb_to_linear, float linear_nit_multiplier = 1.0f, float ldr_black_bias = 0.0f);

	// 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, float linear_nit_multiplier = 1.0f, float ldr_black_bias = 0.0f);
	
	inline bool load_image_hdr(const std::string& filename, imagef& img, bool ldr_srgb_to_linear = true, float linear_nit_multiplier = 1.0f, float ldr_black_bias = 0.0f)
	{ 
		return load_image_hdr(filename.c_str(), img, ldr_srgb_to_linear, linear_nit_multiplier, ldr_black_bias);
	}

	enum class hdr_image_type
	{
		cHITRGBAHalfFloat = 0,
		cHITRGBAFloat = 1,
		cHITPNGImage = 2,
		cHITEXRImage = 3,
		cHITHDRImage = 4,
		cHITJPGImage = 5,
		cHITQOIImage = 6,
		cHITRGBA8Image = 7 // plain LDR/SDR image to be upconverted
	};

	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, float linear_nit_multiplier = 1.0f, float ldr_black_bias = 0.0f);

	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
	{
		std::string m_program;

		// Note no validation is done, either gamma or exposure may be 0.
		double m_gamma;
		bool m_has_gamma;

		double m_exposure; // watts/steradian/m^2.
		bool m_has_exposure;

		void clear() 
		{ 
			m_program.clear(); 
			m_gamma = 1.0f; 
			m_has_gamma = false; 
			m_exposure = 1.0f; 
			m_has_exposure = false; 
		}
	};

	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
	{
		WRITE_EXR_LINEAR_HINT = 1, // hint for lossy comp. methods: exr_perceptual_treatment_t, logarithmic or linear, defaults to logarithmic
		WRITE_EXR_STORE_FLOATS = 2, // use 32-bit floats, otherwise it uses half floats
		WRITE_EXR_NO_COMPRESSION = 4 // no compression, otherwise it uses ZIP compression (16 scanlines per block)
	};

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

	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) { return save_png(filename.c_str(), img, image_save_flags, grayscale_comp); }

	bool save_qoi(const char* pFilename, const image& img, uint32_t qoi_colorspace = 0);
	inline bool save_qoi(const std::string& filename, const image& img, uint32_t qoi_colorspace = 0) { return save_qoi(filename.c_str(), img, qoi_colorspace); }
	
	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) {	return v.size() ? write_data_to_file(pFilename, &v[0], v.size()) : write_data_to_file(pFilename, "", 0); }
		
	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, float filter_scale_y = -1.0f);

	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
			
	typedef uint64_t timer_ticks;

	class interval_timer
	{
	public:
		interval_timer();

		void start();
		void stop();

		double get_elapsed_secs() const;
		inline double get_elapsed_ms() const { return 1000.0f* get_elapsed_secs(); }
		
		static void init();
		static inline timer_ticks get_ticks_per_sec() { return g_freq; }
		static timer_ticks get_ticks();
		static double ticks_to_secs(timer_ticks ticks);
		static inline double ticks_to_ms(timer_ticks ticks) {	return ticks_to_secs(ticks) * 1000.0f; }

	private:
		static timer_ticks g_init_ticks, g_freq;
		static double g_timer_freq;

		timer_ticks m_start_time, m_stop_time;

		bool m_started, m_stopped;
	};

	inline double get_interval_timer() { return interval_timer::ticks_to_secs(interval_timer::get_ticks()); }

	inline FILE *fopen_safe(const char *pFilename, const char *pMode)
	{
#ifdef _WIN32
		FILE *pFile = nullptr;
		fopen_s(&pFile, pFilename, pMode);
		return pFile;
#else
		return fopen(pFilename, pMode);
#endif
	}

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

	// Monte Carlo helper: returns num_samples random floats, every one inside the hard bound
	// [-half_span, half_span], whose distribution targets a standard deviation of sigma.
	//
	// The distribution is a mixture of a scaled uniform "bulk" (k*Uniform[-H,H]) and a pair of
	// symmetric "tails" placed at +/-(A*H). For small sigma the bulk alone carries the variance;
	// for large sigma (above the uniform's own variance H^2/3) the tails are added so the target
	// standard deviation can still be reached without ever exceeding the bound.
	//
	//   seed           0 => nondeterministic seed (std::random_device), otherwise deterministic.
	//   min_tail_prob  minimum probability mass placed in the +/-edge tails (in [0,1]).
	//   tail_amp_cap   max tail amplitude as a fraction of half_span (in [0,1]).
	//   fix_tail_count if true, place exactly round(p*num_samples) tail samples instead of
	//                  drawing each sample's tail/bulk choice randomly (lower-variance count).
	//   recenter       if true, subtract the realized sample mean afterwards, then re-clamp to
	//                  [-half_span, half_span].
	std::vector<float> bounded_samples(
		size_t num_samples,
		float half_span,                 // H: hard bound, all returned samples lie in [-H, H]
		float sigma,                     // target standard deviation (clamped to [0, H])
		uint32_t seed = 0,
		float min_tail_prob = 0.0f,
		float tail_amp_cap = 1.0f,
		bool fix_tail_count = false,
		bool recenter = false);

	const uint32_t cPixelBlockWidth = 4;
	const uint32_t cPixelBlockHeight = 4;
	const uint32_t cPixelBlockTotalPixels = cPixelBlockWidth * cPixelBlockHeight;

	struct pixel_block
	{
		color_rgba m_pixels[cPixelBlockHeight][cPixelBlockWidth]; // [y][x]

		inline const color_rgba& operator() (uint32_t x, uint32_t y) const { assert((x < cPixelBlockWidth) && (y < cPixelBlockHeight)); return m_pixels[y][x]; }
		inline color_rgba& operator() (uint32_t x, uint32_t y) { assert((x < cPixelBlockWidth) && (y < cPixelBlockHeight)); return m_pixels[y][x]; }

		inline const color_rgba* get_ptr() const { return &m_pixels[0][0]; }
		inline color_rgba* get_ptr() { return &m_pixels[0][0]; }

		inline void clear() { clear_obj(*this); }

		inline bool operator== (const pixel_block& rhs) const
		{
			return memcmp(m_pixels, rhs.m_pixels, sizeof(m_pixels)) == 0;
		}
	};
	typedef basisu::vector<pixel_block> pixel_block_vec;

	struct pixel_block_hdr
	{
		vec4F m_pixels[cPixelBlockHeight][cPixelBlockWidth]; // [y][x]

		inline const vec4F& operator() (uint32_t x, uint32_t y) const { assert((x < cPixelBlockWidth) && (y < cPixelBlockHeight)); return m_pixels[y][x]; }
		inline vec4F& operator() (uint32_t x, uint32_t y) { assert((x < cPixelBlockWidth) && (y < cPixelBlockHeight)); return m_pixels[y][x]; }

		inline const vec4F* get_ptr() const { return &m_pixels[0][0]; }
		inline vec4F* get_ptr() { return &m_pixels[0][0]; }

		inline void clear() { clear_obj(*this); }

		inline bool operator== (const pixel_block& rhs) const
		{
			return memcmp(m_pixels, rhs.m_pixels, sizeof(m_pixels)) == 0;
		}
	};
	typedef basisu::vector<pixel_block_hdr> pixel_block_hdr_vec;

	void tonemap_image_reinhard(image& ldr_img, const imagef& hdr_img, float exposure, bool add_noise = false, bool per_component = true, bool luma_scaling = false);
	bool tonemap_image_compressive(image& dst_img, const imagef& hdr_test_img);
	bool tonemap_image_compressive2(image& dst_img, const imagef& hdr_test_img);
	
	// Intersection
	enum eClear { cClear = 0 };
	enum eInitExpand { cInitExpand = 0 };
	enum eIdentity { cIdentity = 0 };

	template<typename vector_type>
	class ray
	{
	public:
		typedef vector_type vector_t;
		typedef typename vector_type::scalar_type scalar_type;

		inline ray() { }
		inline ray(eClear) { clear(); }
		inline ray(const vector_type& origin, const vector_type& direction) : m_origin(origin), m_direction(direction) { }

		inline void clear()
		{
			m_origin.clear();
			m_direction.clear();
		}

		inline const vector_type& get_origin(void) const { return m_origin; }
		inline void set_origin(const vector_type& origin) { m_origin = origin; }

		inline const vector_type& get_direction(void) const { return m_direction; }
		inline void set_direction(const vector_type& direction) { m_direction = direction; }

		inline void set_endpoints(const vector_type& start, const vector_type& end)
		{
			m_origin = start;

			m_direction = end - start;
			m_direction.normalize_in_place();
		}

		inline vector_type eval(scalar_type t) const
		{
			return m_origin + m_direction * t;
		}

	private:
		vector_type m_origin;
		vector_type m_direction;
	};

	typedef ray<vec2F> ray2F;
	typedef ray<vec3F> ray3F;

	template<typename T>
	class vec_interval
	{
	public:
		enum { N = T::num_elements };
		typedef typename T::scalar_type scalar_type;

		inline vec_interval(const T& v) { m_bounds[0] = v; m_bounds[1] = v; }
		inline vec_interval(const T& low, const T& high) { m_bounds[0] = low; m_bounds[1] = high; }

		inline vec_interval() { }
		inline vec_interval(eClear) { clear(); }
		inline vec_interval(eInitExpand) { init_expand(); }

		inline void clear() { m_bounds[0].clear(); m_bounds[1].clear(); }

		inline void init_expand()
		{
			m_bounds[0].set(1e+30f, 1e+30f, 1e+30f);
			m_bounds[1].set(-1e+30f, -1e+30f, -1e+30f);
		}

		inline vec_interval expand(const T& p)
		{
			for (uint32_t c = 0; c < N; c++)
			{
				if (p[c] < m_bounds[0][c])
					m_bounds[0][c] = p[c];

				if (p[c] > m_bounds[1][c])
					m_bounds[1][c] = p[c];
			}

			return *this;
		}

		inline const T& operator[] (uint32_t i) const { assert(i < 2); return m_bounds[i]; }
		inline       T& operator[] (uint32_t i) { assert(i < 2); return m_bounds[i]; }

		const T& get_low() const { return m_bounds[0]; }
		T& get_low() { return m_bounds[0]; }

		const T& get_high() const { return m_bounds[1]; }
		T& get_high() { return m_bounds[1]; }

		scalar_type get_dim(uint32_t axis) const { return m_bounds[1][axis] - m_bounds[0][axis]; }

		bool contains(const T& p) const
		{
			const T& low = get_low(), high = get_high();

			for (uint32_t i = 0; i < N; i++)
			{
				if (p[i] < low[i])
					return false;

				if (p[i] > high[i])
					return false;
			}
			return true;
		}

	private:
		T m_bounds[2];
	};

	typedef vec_interval<vec1F> vec_interval1F;
	typedef vec_interval<vec2F> vec_interval2F;
	typedef vec_interval<vec3F> vec_interval3F;
	typedef vec_interval<vec4F> vec_interval4F;

	typedef vec_interval1F aabb1F;
	typedef vec_interval2F aabb2F;
	typedef vec_interval3F aabb3F;

	namespace intersection
	{
		enum result
		{
			cBackfacing = -1,
			cFailure = 0,
			cSuccess,
			cParallel,
			cInside,
		};

		// 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)
		{
			enum
			{
				cNumDim = vector_type::num_elements,
				cRight = 0,
				cLeft = 1,
				cMiddle = 2
			};

			bool inside = true;
			int quadrant[cNumDim];
			scalar_type candidate_plane[cNumDim];

			for (int i = 0; i < cNumDim; i++)
			{
				if (ray.get_origin()[i] < box[0][i])
				{
					quadrant[i] = cLeft;
					candidate_plane[i] = box[0][i];
					inside = false;
				}
				else if (ray.get_origin()[i] > box[1][i])
				{
					quadrant[i] = cRight;
					candidate_plane[i] = box[1][i];
					inside = false;
				}
				else
				{
					quadrant[i] = cMiddle;
				}
			}

			if (inside)
			{
				coord = ray.get_origin();
				t = 0.0f;
				return cInside;
			}

			scalar_type max_t[cNumDim];
			for (int i = 0; i < cNumDim; i++)
			{
				if ((quadrant[i] != cMiddle) && (ray.get_direction()[i] != 0.0f))
					max_t[i] = (candidate_plane[i] - ray.get_origin()[i]) / ray.get_direction()[i];
				else
					max_t[i] = -1.0f;
			}

			int which_plane = 0;
			for (int i = 1; i < cNumDim; i++)
				if (max_t[which_plane] < max_t[i])
					which_plane = i;

			if (max_t[which_plane] < 0.0f)
				return cFailure;

			for (int i = 0; i < cNumDim; i++)
			{
				if (i != which_plane)
				{
					coord[i] = ray.get_origin()[i] + max_t[which_plane] * ray.get_direction()[i];

					if ((coord[i] < box[0][i]) || (coord[i] > box[1][i]))
						return cFailure;
				}
				else
				{
					coord[i] = candidate_plane[i];
				}

				assert(coord[i] >= box[0][i] && coord[i] <= box[1][i]);
			}

			t = max_t[which_plane];
			return cSuccess;
		}

		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)
		{
			if (!box.contains(ray.get_origin()))
			{
				started_within = false;
				return ray_aabb(coord, t, ray, box);
			}

			started_within = true;

			typename vector_type::T diag_dist = box.diagonal_length() * 1.5f;
			ray_type outside_ray(ray.eval(diag_dist), -ray.get_direction());

			result res(ray_aabb(coord, t, outside_ray, box));
			if (res != cSuccess)
				return res;

			t = basisu::maximum(0.0f, diag_dist - t);
			return cSuccess;
		}

	} // 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)
	{
		union { float f; int32_t i; uint32_t u; } fi = { val };
		const int flt_m = fi.i & 0x7FFFFF, flt_e = (fi.i >> 23) & 0xFF;
		int e = 0, m = 0;

		assert(((fi.i >> 31) == 0) && (flt_e != 0xFF));

		// not zero or denormal
		if (flt_e != 0)
		{
			int new_exp = flt_e - 127;
			if (new_exp > 15)
				e = 31;
			else if (new_exp < -14)
				m = (int)lrintf((1 << 24) * fabsf(fi.f));
			else
			{
				e = new_exp + 15;
				m = (int)lrintf(flt_m * (1.0f / ((float)(1 << 13))));
			}
		}

		assert((0 <= m) && (m <= 1024));
		if (m == 1024)
		{
			e++;
			m = 0;
		}

		assert((e >= 0) && (e <= 31));
		assert((m >= 0) && (m <= 1023));

		basist::half_float result = (basist::half_float)((e << 10) | m);
		return result;
	}

	union fu32
	{
		uint32_t u;
		float f;
	};

	// Supports positive and denormals only. No NaN or Inf.
	BASISU_FORCE_INLINE float fast_half_to_float_pos_not_inf_or_nan(basist::half_float h)
	{
		assert(!basist::half_is_signed(h) && !basist::is_half_inf_or_nan(h));
				
		// add 112 to the exponent (112+half float's exp bias of 15=float32's bias of 127)
		static const fu32 K = { 0x77800000 }; 

		fu32 o;
		o.u = h << 13;
		o.f *= K.f;

		return o.f;
	}

	// Positive, negative, or denormals. No NaN or Inf. Clamped to MAX_HALF_FLOAT.
	inline basist::half_float fast_float_to_half_trunc_no_nan_or_inf(float f)
	{
		assert(!isnan(f) && !isinf(f));

		// Sutract 112 from the exponent, to change the bias from 127 to 15.
		static const fu32 g_f_to_h{ 0x7800000 };
				
		fu32 fu;

		fu.f = minimum<float>((float)basist::MAX_HALF_FLOAT, fabsf(f)) * g_f_to_h.f;

		return (basist::half_float)(((fu.u >> (23 - 10)) & 0x7FFF) | ((f < 0.0f) ? 0x8000 : 0));
	}

	inline basist::half_float fast_float_to_half_trunc_no_clamp_neg_nan_or_inf(float f)
	{
		assert(!isnan(f) && !isinf(f));
		assert((f >= 0.0f) && (f <= basist::MAX_HALF_FLOAT));
		
		// Sutract 112 from the exponent, to change the bias from 127 to 15.
		static const fu32 g_f_to_h{ 0x7800000 };

		fu32 fu;

		fu.f = f * g_f_to_h.f;
		
		return (basist::half_float)((fu.u >> (23 - 10)) & 0x7FFF);
	}
		
	inline basist::half_float fast_float_to_half_no_clamp_neg_nan_or_inf(float f)
	{
		assert(!isnan(f) && !isinf(f));
		assert((f >= 0.0f) && (f <= basist::MAX_HALF_FLOAT));

		// Sutract 112 from the exponent, to change the bias from 127 to 15.
		static const fu32 g_f_to_h{ 0x7800000 };

		fu32 fu;

		fu.f = f * g_f_to_h.f;

		uint32_t h = (basist::half_float)((fu.u >> (23 - 10)) & 0x7FFF);

		// round to even or nearest
		uint32_t mant = fu.u & 8191; // examine lowest 13 bits
		uint32_t inc = (mant > 4096) | ((mant == 4096) & (h & 1));
		h += inc;

		if (h > basist::MAX_HALF_FLOAT_AS_INT_BITS)
			h = basist::MAX_HALF_FLOAT_AS_INT_BITS;

		return (basist::half_float)h;
	}

	bool arith_test();

	void set_image_alpha(image& img, uint32_t a);

	void create_bc7_debug_images(
		uint32_t width, uint32_t height,
		const void* pBlocks,
		const char* pFilename_prefix);

	struct tri2
	{
		vec2F p0, p1, p2;
		vec2F t0, t1, t2;
		color_rgba c0, c1, c2;
	};

	// simple non-perspective correct triangle rasterizer with texture mapping, useful for generating randomized test data
	void draw_tri2(image& dst, const image* pTex, const tri2& tri, bool alpha_blend);

	struct DirectionalKernel
	{
		basisu::vector<float> m_data; // row-major, size*size elements
		int	m_size; // always odd, e.g. 7 means a 7x7 kernel
	};
	
	DirectionalKernel make_directional_kernel(float angle_deg, float sigma_par, float sigma_perp = 0.5f);

	void directional_gaussian_blur(const image& src_img, image& dst_img, float angle_deg, float sigma_par, float sigma_perp = 0.5f);

	void set_num_wasi_threads(uint32_t num_threads);
	int get_num_hardware_threads();

	bool display_astc_statistics(
		const vector2D<astc_helpers::astc_block>& blocks,
		uint32_t block_width, uint32_t block_height, uint32_t image_width, uint32_t image_height, bool verbose);

	bool display_astc_statistics(
		const vector2D<astc_helpers::log_astc_block>& blocks,
		uint32_t block_width, uint32_t block_height, uint32_t image_width, uint32_t image_height, bool verbose);

	enum convar_type
	{
		cConvarFloat,
		cConvarInt
	};

	static inline const char* get_convar_type_string(convar_type t)
	{
		switch (t)
		{
		case cConvarFloat: return "float";
		case cConvarInt: return "int";
		default: assert(0); return "invalid";
		}
	}

	// intended for development only
	class convar;
	
	extern basisu::vector<convar*>& get_convars();

	// instances MUST be at global scope, and last forever
	class convar
	{
		std::string m_name;
		convar_type m_type;

		struct int_t
		{
			int m_cur, m_def, m_min, m_max;
		};

		struct float_t
		{
			float m_cur, m_def, m_min, m_max;
		};

		union
		{
			int_t m_int;
			float_t m_float;
		};

	public:
		convar(const char* pName, int def, int min_val, int max_val) : 
			m_name(pName),
			m_type(cConvarInt)
		{
			m_int.m_cur = def;
			m_int.m_def = def;
			m_int.m_min = min_val;
			m_int.m_max = max_val;

			size_t cur_idx;
			if (!get_convars().find(this, cur_idx))
				get_convars().push_back(this);
		}

		convar(const char* pName, float def, float min_val, float max_val) :
			m_name(pName),
			m_type(cConvarFloat)
		{
			m_float.m_cur = def;
			m_float.m_def = def;
			m_float.m_min = min_val;
			m_float.m_max = max_val;

			size_t cur_idx;
			if (!get_convars().find(this, cur_idx))
				get_convars().push_back(this);
		}

		~convar()
		{
			// do nothing, we assume global convars
		}

		const std::string& get_name() const { return m_name; }

		std::string get_val_as_string() const 
		{ 
			std::string res;

			if (m_type == cConvarFloat)
			{
				res = fmt_string("{}", m_float.m_cur);
			}
			else if (m_type == cConvarInt)
			{
				res = fmt_string("{}", m_int.m_cur);
			}
			else
			{
				assert(0);
			}

			return res;
		}

		convar_type get_type() const { return m_type; }

		void set(float val)
		{
			if (m_type != cConvarFloat)
			{
				assert(0);
				return;
			}
			m_float.m_cur = clamp<float>(val, m_float.m_min, m_float.m_max);
		}

		void set(int val)
		{
			if (m_type != cConvarInt)
			{
				assert(0);
				return;
			}
			m_int.m_cur = clamp<int>(val, m_int.m_min, m_int.m_max);
		}

		float get_float() const
		{
			if (m_type != cConvarFloat)
			{
				assert(0);
				return 0.0f;
			}
			return m_float.m_cur;
		}

		int get_int() const
		{
			if (m_type != cConvarInt)
			{
				assert(0);
				return 0;
			}
			return m_int.m_cur;
		}

		void reset()
		{
			if (m_type == cConvarInt)
				m_int.m_cur = m_int.m_def;
			else
			{
				assert(m_type == cConvarFloat);
				m_float.m_cur = m_float.m_def;
			}
		}

		bool get_bool() const
		{
			if (m_type == cConvarInt)
			{
				return m_int.m_cur != 0;
			}
			else
			{
				assert(m_type == cConvarFloat);
				return m_float.m_cur != 0.0f;
			}
		}
	};

	void list_convars();
	void print_convar(const std::string& name);
	void reset_convar(const std::string& name);
	void set_convar(const std::string& name, const std::string &val);
									
} // namespace basisu

#include "basisu_math.h"
