// basisu_comp.cpp
// Copyright (C) 2019-2024 Binomial LLC. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "basisu_comp.h"
#include "basisu_enc.h"
#include <unordered_set>
#include <atomic>
#include <map>

//#define UASTC_HDR_DEBUG_SAVE_CATEGORIZED_BLOCKS

// basisu_transcoder.cpp is where basisu_miniz lives now, we just need the declarations here.
#define MINIZ_NO_ZLIB_COMPATIBLE_NAMES
#include "basisu_miniz.h"

#include "basisu_opencl.h"

#include "../transcoder/basisu_astc_hdr_core.h"

#if !BASISD_SUPPORT_KTX2
#error BASISD_SUPPORT_KTX2 must be enabled (set to 1).
#endif

#if BASISD_SUPPORT_KTX2_ZSTD
#include "../zstd/zstd.h"
#endif

// Set to 1 to disable the mipPadding alignment workaround (which only seems to be needed when no key-values are written at all)
#define BASISU_DISABLE_KTX2_ALIGNMENT_WORKAROUND (0)

// Set to 1 to disable writing all KTX2 key values, triggering an early validator bug.
#define BASISU_DISABLE_KTX2_KEY_VALUES (0)

using namespace buminiz;

#define BASISU_USE_STB_IMAGE_RESIZE_FOR_MIPMAP_GEN 0
#define DEBUG_CROP_TEXTURE_TO_64x64 (0)
#define DEBUG_RESIZE_TEXTURE (0)
#define DEBUG_EXTRACT_SINGLE_BLOCK (0)

namespace basisu
{
	basis_compressor::basis_compressor() :
		m_pOpenCL_context(nullptr),
		m_basis_file_size(0),
		m_basis_bits_per_texel(0.0f),
		m_total_blocks(0),
		m_any_source_image_has_alpha(false),
		m_opencl_failed(false)
	{
		debug_printf("basis_compressor::basis_compressor\n");
		
		assert(g_library_initialized);
	}

	basis_compressor::~basis_compressor()
	{
		if (m_pOpenCL_context)
		{
			opencl_destroy_context(m_pOpenCL_context);
			m_pOpenCL_context = nullptr;
		}
	}

	void basis_compressor::check_for_hdr_inputs()
	{
		if ((!m_params.m_source_filenames.size()) && (!m_params.m_source_images.size()))
		{
			if (m_params.m_source_images_hdr.size())
			{
				// Assume they want UASTC HDR if they've specified any HDR source images.
				m_params.m_hdr = true;
			}
		}

		if (!m_params.m_hdr)
		{
			// See if any files are .EXR or .HDR, if so switch the compressor to UASTC HDR mode.
			for (uint32_t i = 0; i < m_params.m_source_filenames.size(); i++)
			{
				std::string filename;
				string_get_filename(m_params.m_source_filenames[i].c_str(), filename);

				std::string ext(string_get_extension(filename));
				string_tolower(ext);

				if ((ext == "exr") || (ext == "hdr"))
				{
					m_params.m_hdr = true;
					break;
				}
			}
		}

		if (m_params.m_hdr)
		{
			if (m_params.m_source_alpha_filenames.size())
			{
				debug_printf("Warning: Alpha channel image filenames are not supported in UASTC HDR mode.\n");
				m_params.m_source_alpha_filenames.clear();
			}
		}

		if (m_params.m_hdr)
			m_params.m_uastc = true;
	}

	bool basis_compressor::sanity_check_input_params()
	{
		// Check for no source filenames specified.
		if ((m_params.m_read_source_images) && (!m_params.m_source_filenames.size()))
		{
			assert(0);
			return false;
		}

		// See if they've specified any source filenames, but didn't tell us to read them.
		if ((!m_params.m_read_source_images) && (m_params.m_source_filenames.size()))
		{
			assert(0);
			return false;
		}

		// Sanity check the input image parameters.
		if (m_params.m_read_source_images)
		{
			// Caller can't specify their own images if they want us to read source images from files.
			if (m_params.m_source_images.size() || m_params.m_source_images_hdr.size())
			{
				assert(0);
				return false;
			}

			if (m_params.m_source_mipmap_images.size() || m_params.m_source_mipmap_images_hdr.size())
			{
				assert(0);
				return false;
			}
		}
		else
		{
			// They didn't tell us to read any source files, so check for no LDR/HDR source images.
			if (!m_params.m_source_images.size() && !m_params.m_source_images_hdr.size())
			{
				assert(0);
				return false;
			}

			// Now we know we've been supplied LDR and/or HDR source images, check for LDR vs. HDR conflicts.

			if (m_params.m_source_images.size())
			{
				// They've supplied LDR images, so make sure they also haven't specified HDR input images.
				if (m_params.m_source_images_hdr.size() || m_params.m_source_mipmap_images_hdr.size())
				{
					assert(0);
					return false;
				}
			}
			else
			{
				// No LDR images, so make sure they haven't specified any LDR mipmaps.
				if (m_params.m_source_mipmap_images.size())
				{
					assert(0);
					return false;
				}

				// No LDR images, so ensure they've supplied some HDR images to process.
				if (!m_params.m_source_images_hdr.size())
				{
					assert(0);
					return false;
				}
			}
		}

		return true;
	}

	bool basis_compressor::init(const basis_compressor_params &params)
	{
		debug_printf("basis_compressor::init\n");
				
		if (!g_library_initialized)
		{
			error_printf("basis_compressor::init: basisu_encoder_init() MUST be called before using any encoder functionality!\n");
			return false;
		}

		if (!params.m_pJob_pool)
		{
			error_printf("basis_compressor::init: A non-null job_pool pointer must be specified\n");
			return false;
		}
				
		m_params = params;

		if ((m_params.m_compute_stats) && (!m_params.m_validate_output_data))
			m_params.m_validate_output_data = true;

		check_for_hdr_inputs();
		
		if (m_params.m_debug)
		{
			debug_printf("basis_compressor::init:\n");

#define PRINT_BOOL_VALUE(v) debug_printf("%s: %u %u\n", BASISU_STRINGIZE2(v), static_cast<int>(m_params.v), m_params.v.was_changed());
#define PRINT_INT_VALUE(v) debug_printf("%s: %i %u\n", BASISU_STRINGIZE2(v), static_cast<int>(m_params.v), m_params.v.was_changed());
#define PRINT_UINT_VALUE(v) debug_printf("%s: %u %u\n", BASISU_STRINGIZE2(v), static_cast<uint32_t>(m_params.v), m_params.v.was_changed());
#define PRINT_FLOAT_VALUE(v) debug_printf("%s: %f %u\n", BASISU_STRINGIZE2(v), static_cast<float>(m_params.v), m_params.v.was_changed());
						
			debug_printf("Source LDR images: %u, HDR images: %u, filenames: %u, alpha filenames: %i, LDR mipmap images: %u, HDR mipmap images: %u\n",
				m_params.m_source_images.size(), m_params.m_source_images_hdr.size(),
				m_params.m_source_filenames.size(), m_params.m_source_alpha_filenames.size(),
				m_params.m_source_mipmap_images.size(), m_params.m_source_mipmap_images_hdr.size());

			if (m_params.m_source_mipmap_images.size())
			{
				debug_printf("m_source_mipmap_images array sizes:\n");
				for (uint32_t i = 0; i < m_params.m_source_mipmap_images.size(); i++)
					debug_printf("%u ", m_params.m_source_mipmap_images[i].size());
				debug_printf("\n");
			}

			if (m_params.m_source_mipmap_images_hdr.size())
			{
				debug_printf("m_source_mipmap_images_hdr array sizes:\n");
				for (uint32_t i = 0; i < m_params.m_source_mipmap_images_hdr.size(); i++)
					debug_printf("%u ", m_params.m_source_mipmap_images_hdr[i].size());
				debug_printf("\n");
			}

			PRINT_BOOL_VALUE(m_hdr);
			PRINT_BOOL_VALUE(m_uastc);
			PRINT_BOOL_VALUE(m_use_opencl);
			PRINT_BOOL_VALUE(m_y_flip);
			PRINT_BOOL_VALUE(m_debug);
			PRINT_BOOL_VALUE(m_validate_etc1s);
			PRINT_BOOL_VALUE(m_debug_images);
			PRINT_INT_VALUE(m_compression_level);
			PRINT_BOOL_VALUE(m_perceptual);
			PRINT_BOOL_VALUE(m_no_endpoint_rdo);
			PRINT_BOOL_VALUE(m_no_selector_rdo);
			PRINT_BOOL_VALUE(m_read_source_images);
			PRINT_BOOL_VALUE(m_write_output_basis_or_ktx2_files);
			PRINT_BOOL_VALUE(m_compute_stats);
			PRINT_BOOL_VALUE(m_check_for_alpha);
			PRINT_BOOL_VALUE(m_force_alpha);
			debug_printf("swizzle: %d,%d,%d,%d\n",
				m_params.m_swizzle[0],
				m_params.m_swizzle[1],
				m_params.m_swizzle[2],
				m_params.m_swizzle[3]);
			PRINT_BOOL_VALUE(m_renormalize);
			PRINT_BOOL_VALUE(m_multithreading);
			PRINT_BOOL_VALUE(m_disable_hierarchical_endpoint_codebooks);
												
			PRINT_FLOAT_VALUE(m_endpoint_rdo_thresh);
			PRINT_FLOAT_VALUE(m_selector_rdo_thresh);
			
			PRINT_BOOL_VALUE(m_mip_gen);
			PRINT_BOOL_VALUE(m_mip_renormalize);
			PRINT_BOOL_VALUE(m_mip_wrapping);
			PRINT_BOOL_VALUE(m_mip_fast);
			PRINT_BOOL_VALUE(m_mip_srgb);
			PRINT_FLOAT_VALUE(m_mip_premultiplied);
			PRINT_FLOAT_VALUE(m_mip_scale);
			PRINT_INT_VALUE(m_mip_smallest_dimension);
			debug_printf("m_mip_filter: %s\n", m_params.m_mip_filter.c_str());

			debug_printf("m_max_endpoint_clusters: %u\n", m_params.m_max_endpoint_clusters);
			debug_printf("m_max_selector_clusters: %u\n", m_params.m_max_selector_clusters);
			debug_printf("m_quality_level: %i\n", m_params.m_quality_level);
			debug_printf("UASTC HDR quality level: %u\n", m_params.m_uastc_hdr_options.m_level);

			debug_printf("m_tex_type: %u\n", m_params.m_tex_type);
			debug_printf("m_userdata0: 0x%X, m_userdata1: 0x%X\n", m_params.m_userdata0, m_params.m_userdata1);
			debug_printf("m_us_per_frame: %i (%f fps)\n", m_params.m_us_per_frame, m_params.m_us_per_frame ? 1.0f / (m_params.m_us_per_frame / 1000000.0f) : 0);
			debug_printf("m_pack_uastc_flags: 0x%X\n", m_params.m_pack_uastc_flags);
			
			PRINT_BOOL_VALUE(m_rdo_uastc);
			PRINT_FLOAT_VALUE(m_rdo_uastc_quality_scalar);
			PRINT_INT_VALUE(m_rdo_uastc_dict_size);
			PRINT_FLOAT_VALUE(m_rdo_uastc_max_allowed_rms_increase_ratio);
			PRINT_FLOAT_VALUE(m_rdo_uastc_skip_block_rms_thresh);
			PRINT_FLOAT_VALUE(m_rdo_uastc_max_smooth_block_error_scale);
			PRINT_FLOAT_VALUE(m_rdo_uastc_smooth_block_max_std_dev);
			PRINT_BOOL_VALUE(m_rdo_uastc_favor_simpler_modes_in_rdo_mode)
			PRINT_BOOL_VALUE(m_rdo_uastc_multithreading);

			PRINT_INT_VALUE(m_resample_width);
			PRINT_INT_VALUE(m_resample_height);
			PRINT_FLOAT_VALUE(m_resample_factor);
			
			debug_printf("Has global codebooks: %u\n", m_params.m_pGlobal_codebooks ? 1 : 0);
			if (m_params.m_pGlobal_codebooks)
			{
				debug_printf("Global codebook endpoints: %u selectors: %u\n", m_params.m_pGlobal_codebooks->get_endpoints().size(), m_params.m_pGlobal_codebooks->get_selectors().size());
			}

			PRINT_BOOL_VALUE(m_create_ktx2_file);

			debug_printf("KTX2 UASTC supercompression: %u\n", m_params.m_ktx2_uastc_supercompression);
			debug_printf("KTX2 Zstd supercompression level: %i\n", (int)m_params.m_ktx2_zstd_supercompression_level);
			debug_printf("KTX2 sRGB transfer func: %u\n", (int)m_params.m_ktx2_srgb_transfer_func);
			debug_printf("Total KTX2 key values: %u\n", m_params.m_ktx2_key_values.size());
			for (uint32_t i = 0; i < m_params.m_ktx2_key_values.size(); i++)
			{
				debug_printf("Key: \"%s\"\n", m_params.m_ktx2_key_values[i].m_key.data());
				debug_printf("Value size: %u\n", m_params.m_ktx2_key_values[i].m_value.size());
			}

			PRINT_BOOL_VALUE(m_validate_output_data);
			PRINT_BOOL_VALUE(m_hdr_ldr_srgb_to_linear_conversion);
			debug_printf("Allow UASTC HDR uber mode: %u\n", m_params.m_uastc_hdr_options.m_allow_uber_mode);
			PRINT_BOOL_VALUE(m_hdr_favor_astc);
						
#undef PRINT_BOOL_VALUE
#undef PRINT_INT_VALUE
#undef PRINT_UINT_VALUE
#undef PRINT_FLOAT_VALUE
		}

		if (!sanity_check_input_params())
			return false;
		
		if ((m_params.m_use_opencl) && opencl_is_available() && !m_pOpenCL_context && !m_opencl_failed)
		{
			m_pOpenCL_context = opencl_create_context();
			if (!m_pOpenCL_context)
				m_opencl_failed = true;
		}

		return true;
	}
		
	basis_compressor::error_code basis_compressor::process()
	{
		debug_printf("basis_compressor::process\n");

		if (!read_dds_source_images())
			return cECFailedReadingSourceImages;

		if (!read_source_images())
			return cECFailedReadingSourceImages;

		if (!validate_texture_type_constraints())
			return cECFailedValidating;

		if (m_params.m_create_ktx2_file)
		{
			if (!validate_ktx2_constraints())
			{
				error_printf("Inputs do not satisfy .KTX2 texture constraints: all source images must be the same resolution and have the same number of mipmap levels.\n");
				return cECFailedValidating;
			}
		}

		if (!extract_source_blocks())
			return cECFailedFrontEnd;

		if (m_params.m_hdr)
		{
			// UASTC HDR
			printf("Mode: UASTC HDR Level %u\n", m_params.m_uastc_hdr_options.m_level);

			error_code ec = encode_slices_to_uastc_hdr();
			if (ec != cECSuccess)
				return ec;
		}
		else if (m_params.m_uastc)
		{
			// UASTC
			printf("Mode: UASTC LDR Level %u\n", m_params.m_pack_uastc_flags & cPackUASTCLevelMask);

			error_code ec = encode_slices_to_uastc();
			if (ec != cECSuccess)
				return ec;
		}
		else
		{
			// ETC1S
			printf("Mode: ETC1S Quality %i, Level %i\n", m_params.m_quality_level, (int)m_params.m_compression_level);
			
			if (!process_frontend())
				return cECFailedFrontEnd;

			if (!extract_frontend_texture_data())
				return cECFailedFontendExtract;

			if (!process_backend())
				return cECFailedBackend;
		}

		if (!create_basis_file_and_transcode())
			return cECFailedCreateBasisFile;

		if (m_params.m_create_ktx2_file)
		{
			if (!create_ktx2_file())
				return cECFailedCreateKTX2File;
		}

		if (!write_output_files_and_compute_stats())
			return cECFailedWritingOutput;

		return cECSuccess;
	}

	basis_compressor::error_code basis_compressor::encode_slices_to_uastc_hdr()
	{
		debug_printf("basis_compressor::encode_slices_to_uastc_hdr\n");

		interval_timer tm;
		tm.start();

		m_uastc_slice_textures.resize(m_slice_descs.size());
		for (uint32_t slice_index = 0; slice_index < m_slice_descs.size(); slice_index++)
			m_uastc_slice_textures[slice_index].init(texture_format::cUASTC_HDR_4x4, m_slice_descs[slice_index].m_orig_width, m_slice_descs[slice_index].m_orig_height);

		m_uastc_backend_output.m_tex_format = basist::basis_tex_format::cUASTC_HDR_4x4;
		m_uastc_backend_output.m_etc1s = false;
		m_uastc_backend_output.m_slice_desc = m_slice_descs;
		m_uastc_backend_output.m_slice_image_data.resize(m_slice_descs.size());
		m_uastc_backend_output.m_slice_image_crcs.resize(m_slice_descs.size());

		if (!m_params.m_perceptual)
		{
			m_params.m_uastc_hdr_options.m_r_err_scale = 1.0f;
			m_params.m_uastc_hdr_options.m_g_err_scale = 1.0f;
		}
		
		const float DEFAULT_BC6H_ERROR_WEIGHT = .85f;
		const float LOWEST_BC6H_ERROR_WEIGHT = .1f;
		m_params.m_uastc_hdr_options.m_bc6h_err_weight = m_params.m_hdr_favor_astc ? LOWEST_BC6H_ERROR_WEIGHT : DEFAULT_BC6H_ERROR_WEIGHT;

		std::atomic<bool> any_failures;
		any_failures = false;

		astc_hdr_block_stats enc_stats;
				
		struct uastc_blk_desc
		{
			uint32_t m_solid_flag;
			uint32_t m_num_partitions;
			uint32_t m_cem_index;
			uint32_t m_weight_ise_range;
			uint32_t m_endpoint_ise_range;

			bool operator< (const uastc_blk_desc& desc) const
			{
				if (this == &desc)
					return false;

#define COMP(XX) if (XX < desc.XX) return true; else if (XX != desc.XX) return false;
				COMP(m_solid_flag)
				COMP(m_num_partitions)
				COMP(m_cem_index)
				COMP(m_weight_ise_range)
				COMP(m_endpoint_ise_range)
#undef COMP

				return false;
			}
			
			bool operator== (const uastc_blk_desc& desc) const
			{
				if (this == &desc)
					return true;
				if ((*this < desc) || (desc < *this))
					return false;
				return true;
			}

			bool operator!= (const uastc_blk_desc& desc) const
			{
				return !(*this == desc);
			}
		};

		struct uastc_blk_desc_stats
		{
			uastc_blk_desc_stats() : m_count(0) { }
			uint32_t m_count;
#ifdef UASTC_HDR_DEBUG_SAVE_CATEGORIZED_BLOCKS
			basisu::vector<basist::astc_blk> m_blks;
#endif
		};

		std::map<uastc_blk_desc, uastc_blk_desc_stats> unique_block_descs;
		std::mutex unique_block_desc_mutex;
		
		for (uint32_t slice_index = 0; slice_index < m_slice_descs.size(); slice_index++)
		{
			gpu_image& tex = m_uastc_slice_textures[slice_index];
			basisu_backend_slice_desc& slice_desc = m_slice_descs[slice_index];
			(void)slice_desc;

			const uint32_t num_blocks_x = tex.get_blocks_x();
			const uint32_t num_blocks_y = tex.get_blocks_y();
			const uint32_t total_blocks = tex.get_total_blocks();
			const imagef& source_image = m_slice_images_hdr[slice_index];

			std::atomic<uint32_t> total_blocks_processed;
			total_blocks_processed = 0;
						
			const uint32_t N = 256;
			for (uint32_t block_index_iter = 0; block_index_iter < total_blocks; block_index_iter += N)
			{
				const uint32_t first_index = block_index_iter;
				const uint32_t last_index = minimum<uint32_t>(total_blocks, block_index_iter + N);
			
				// FIXME: This sucks, but we're having a stack size related problem with std::function with emscripten.
#ifndef __EMSCRIPTEN__
				m_params.m_pJob_pool->add_job([this, first_index, last_index, num_blocks_x, num_blocks_y, total_blocks, &source_image, 
					&tex, &total_blocks_processed, &any_failures, &enc_stats, &unique_block_descs, &unique_block_desc_mutex]
					{
#endif
						BASISU_NOTE_UNUSED(num_blocks_y);

						basisu::vector<astc_hdr_pack_results> all_results;
						all_results.reserve(256);

						for (uint32_t block_index = first_index; block_index < last_index; block_index++)
						{
							const uint32_t block_x = block_index % num_blocks_x;
							const uint32_t block_y = block_index / num_blocks_x;

							vec4F block_pixels[16];

							source_image.extract_block_clamped(&block_pixels[0], block_x * 4, block_y * 4, 4, 4);

							basist::astc_blk& dest_block = *(basist::astc_blk*)tex.get_block_ptr(block_x, block_y);
														
							float rgb_pixels[16 * 3];
							basist::half_float rgb_pixels_half[16 * 3];
							for (uint32_t i = 0; i < 16; i++)
							{
								rgb_pixels[i * 3 + 0] = block_pixels[i][0];
								rgb_pixels_half[i * 3 + 0] = float_to_half_non_neg_no_nan_inf(block_pixels[i][0]);

								rgb_pixels[i * 3 + 1] = block_pixels[i][1];
								rgb_pixels_half[i * 3 + 1] = float_to_half_non_neg_no_nan_inf(block_pixels[i][1]);

								rgb_pixels[i * 3 + 2] = block_pixels[i][2];
								rgb_pixels_half[i * 3 + 2] = float_to_half_non_neg_no_nan_inf(block_pixels[i][2]);
							}
														
							bool status = astc_hdr_enc_block(&rgb_pixels[0], m_params.m_uastc_hdr_options, all_results);
							if (!status)
							{
								any_failures = true;
								continue;
							}

							double best_err = 1e+30f;
							int best_result_index = -1;
											
							const double bc6h_err_weight = m_params.m_uastc_hdr_options.m_bc6h_err_weight;
							const double astc_err_weight = (1.0f - bc6h_err_weight);
										
							for (uint32_t i = 0; i < all_results.size(); i++)
							{
								basist::half_float unpacked_bc6h_block[4 * 4 * 3];
								unpack_bc6h(&all_results[i].m_bc6h_block, unpacked_bc6h_block, false);

								all_results[i].m_bc6h_block_error = compute_block_error(rgb_pixels_half, unpacked_bc6h_block, m_params.m_uastc_hdr_options);

								double overall_err = (all_results[i].m_bc6h_block_error * bc6h_err_weight) + (all_results[i].m_best_block_error * astc_err_weight);

								if ((!i) || (overall_err < best_err))
								{
									best_err = overall_err;
									best_result_index = i;
								}
							}

							const astc_hdr_pack_results& best_results = all_results[best_result_index];
							
							astc_hdr_pack_results_to_block(dest_block, best_results);
								
							// Verify that this block is valid UASTC HDR and we can successfully transcode it to BC6H.
							// (Well, except in fastest mode.)
							if (m_params.m_uastc_hdr_options.m_level > 0)
							{
								basist::bc6h_block transcoded_bc6h_blk;
								bool transcode_results = astc_hdr_transcode_to_bc6h(dest_block, transcoded_bc6h_blk);
								assert(transcode_results);
								if ((!transcode_results) && (!any_failures))
								{
									error_printf("basis_compressor::encode_slices_to_uastc_hdr: UASTC HDR block transcode check failed!\n");

									any_failures = true;
									continue;
								}
							}

							if (m_params.m_debug)
							{
								// enc_stats has its own mutex
								enc_stats.update(best_results);

								uastc_blk_desc blk_desc;
								clear_obj(blk_desc);

								blk_desc.m_solid_flag = best_results.m_is_solid;
								if (!blk_desc.m_solid_flag)
								{
									blk_desc.m_num_partitions = best_results.m_best_blk.m_num_partitions;
									blk_desc.m_cem_index = best_results.m_best_blk.m_color_endpoint_modes[0];
									blk_desc.m_weight_ise_range = best_results.m_best_blk.m_weight_ise_range;
									blk_desc.m_endpoint_ise_range = best_results.m_best_blk.m_endpoint_ise_range;
								}
								
								{
									std::lock_guard<std::mutex> lck(unique_block_desc_mutex);
																		
									auto res = unique_block_descs.insert(std::make_pair(blk_desc, uastc_blk_desc_stats()));
									
									(res.first)->second.m_count++;
#ifdef UASTC_HDR_DEBUG_SAVE_CATEGORIZED_BLOCKS
									(res.first)->second.m_blks.push_back(dest_block);
#endif
								}
							}

							total_blocks_processed++;

							uint32_t val = total_blocks_processed;
							if (((val & 1023) == 1023) && m_params.m_status_output)
							{
								debug_printf("basis_compressor::encode_slices_to_uastc_hdr: %3.1f%% done\n", static_cast<float>(val) * 100.0f / total_blocks);
							}
						}

#ifndef __EMSCRIPTEN__
					});
#endif
			
			} // block_index_iter

#ifndef __EMSCRIPTEN__
			m_params.m_pJob_pool->wait_for_all();
#endif

			if (any_failures)
				return cECFailedEncodeUASTC;

			m_uastc_backend_output.m_slice_image_data[slice_index].resize(tex.get_size_in_bytes());
			memcpy(&m_uastc_backend_output.m_slice_image_data[slice_index][0], tex.get_ptr(), tex.get_size_in_bytes());

			m_uastc_backend_output.m_slice_image_crcs[slice_index] = basist::crc16(tex.get_ptr(), tex.get_size_in_bytes(), 0);

		} // slice_index
		
		debug_printf("basis_compressor::encode_slices_to_uastc_hdr: Total time: %3.3f secs\n", tm.get_elapsed_secs());

		if (m_params.m_debug)
		{
			debug_printf("\n----- Total unique UASTC block descs: %u\n", (uint32_t)unique_block_descs.size());

			uint32_t c = 0;
			for (auto it = unique_block_descs.begin(); it != unique_block_descs.end(); ++it)
			{
				debug_printf("%u. Total uses: %u %3.2f%%, solid color: %u\n", c, it->second.m_count,
					((float)it->second.m_count * 100.0f) / enc_stats.m_total_blocks, it->first.m_solid_flag);

				if (!it->first.m_solid_flag)
				{
					debug_printf("  Num partitions: %u\n", it->first.m_num_partitions);
					debug_printf("  CEM index: %u\n", it->first.m_cem_index);
					debug_printf("  Weight ISE range: %u (%u levels)\n", it->first.m_weight_ise_range, astc_helpers::get_ise_levels(it->first.m_weight_ise_range));
					debug_printf("  Endpoint ISE range: %u (%u levels)\n", it->first.m_endpoint_ise_range, astc_helpers::get_ise_levels(it->first.m_endpoint_ise_range));
				}

#ifdef UASTC_HDR_DEBUG_SAVE_CATEGORIZED_BLOCKS
				debug_printf("  -- UASTC HDR block bytes:\n");
				for (uint32_t j = 0; j < minimum<uint32_t>(4, it->second.m_blks.size()); j++)
				{
					basist::astc_blk& blk = it->second.m_blks[j];

					debug_printf("    - UASTC HDR: { ");
					for (uint32_t k = 0; k < 16; k++)
						debug_printf("%u%s", ((const uint8_t*)&blk)[k], (k != 15) ? ", " : "");
					debug_printf(" }\n");

					basist::bc6h_block bc6h_blk;
					bool res = astc_hdr_transcode_to_bc6h(blk, bc6h_blk);
					assert(res);
					if (!res)
					{
						error_printf("astc_hdr_transcode_to_bc6h() failed!\n");
						return cECFailedEncodeUASTC;
					}

					debug_printf("    - BC6H: { ");
					for (uint32_t k = 0; k < 16; k++)
						debug_printf("%u%s", ((const uint8_t*)&bc6h_blk)[k], (k != 15) ? ", " : "");
					debug_printf(" }\n");
				}
#endif
					
				c++;
			}
			printf("\n");
			
			enc_stats.print();
		}

		return cECSuccess;
	}

	basis_compressor::error_code basis_compressor::encode_slices_to_uastc()
	{
		debug_printf("basis_compressor::encode_slices_to_uastc\n");

		m_uastc_slice_textures.resize(m_slice_descs.size());
		for (uint32_t slice_index = 0; slice_index < m_slice_descs.size(); slice_index++)
			m_uastc_slice_textures[slice_index].init(texture_format::cUASTC4x4, m_slice_descs[slice_index].m_orig_width, m_slice_descs[slice_index].m_orig_height);

		m_uastc_backend_output.m_tex_format = basist::basis_tex_format::cUASTC4x4;
		m_uastc_backend_output.m_etc1s = false;
		m_uastc_backend_output.m_slice_desc = m_slice_descs;
		m_uastc_backend_output.m_slice_image_data.resize(m_slice_descs.size());
		m_uastc_backend_output.m_slice_image_crcs.resize(m_slice_descs.size());
				
		for (uint32_t slice_index = 0; slice_index < m_slice_descs.size(); slice_index++)
		{
			gpu_image& tex = m_uastc_slice_textures[slice_index];
			basisu_backend_slice_desc& slice_desc = m_slice_descs[slice_index];
			(void)slice_desc;

			const uint32_t num_blocks_x = tex.get_blocks_x();
			const uint32_t num_blocks_y = tex.get_blocks_y();
			const uint32_t total_blocks = tex.get_total_blocks();
			const image& source_image = m_slice_images[slice_index];
			
			std::atomic<uint32_t> total_blocks_processed;
			total_blocks_processed = 0;

			const uint32_t N = 256;
			for (uint32_t block_index_iter = 0; block_index_iter < total_blocks; block_index_iter += N)
			{
				const uint32_t first_index = block_index_iter;
				const uint32_t last_index = minimum<uint32_t>(total_blocks, block_index_iter + N);

				// FIXME: This sucks, but we're having a stack size related problem with std::function with emscripten.
#ifndef __EMSCRIPTEN__
				m_params.m_pJob_pool->add_job([this, first_index, last_index, num_blocks_x, num_blocks_y, total_blocks, &source_image, &tex, &total_blocks_processed]
					{
#endif
						BASISU_NOTE_UNUSED(num_blocks_y);
						
						uint32_t uastc_flags = m_params.m_pack_uastc_flags;
						if ((m_params.m_rdo_uastc) && (m_params.m_rdo_uastc_favor_simpler_modes_in_rdo_mode))
							uastc_flags |= cPackUASTCFavorSimplerModes;

						for (uint32_t block_index = first_index; block_index < last_index; block_index++)
						{
							const uint32_t block_x = block_index % num_blocks_x;
							const uint32_t block_y = block_index / num_blocks_x;

							color_rgba block_pixels[4][4];

							source_image.extract_block_clamped((color_rgba*)block_pixels, block_x * 4, block_y * 4, 4, 4);

							basist::uastc_block& dest_block = *(basist::uastc_block*)tex.get_block_ptr(block_x, block_y);

							encode_uastc(&block_pixels[0][0].r, dest_block, uastc_flags);

							total_blocks_processed++;
							
							uint32_t val = total_blocks_processed;
							if (((val & 16383) == 16383) && m_params.m_status_output)
							{
								debug_printf("basis_compressor::encode_slices_to_uastc: %3.1f%% done\n", static_cast<float>(val) * 100.0f / total_blocks);
							}

						}

#ifndef __EMSCRIPTEN__
					});
#endif

			} // block_index_iter

#ifndef __EMSCRIPTEN__
			m_params.m_pJob_pool->wait_for_all();
#endif

			if (m_params.m_rdo_uastc)
			{
				uastc_rdo_params rdo_params;
				rdo_params.m_lambda = m_params.m_rdo_uastc_quality_scalar;
				rdo_params.m_max_allowed_rms_increase_ratio = m_params.m_rdo_uastc_max_allowed_rms_increase_ratio;
				rdo_params.m_skip_block_rms_thresh = m_params.m_rdo_uastc_skip_block_rms_thresh;
				rdo_params.m_lz_dict_size = m_params.m_rdo_uastc_dict_size;
				rdo_params.m_smooth_block_max_error_scale = m_params.m_rdo_uastc_max_smooth_block_error_scale;
				rdo_params.m_max_smooth_block_std_dev = m_params.m_rdo_uastc_smooth_block_max_std_dev;
								
				bool status = uastc_rdo(tex.get_total_blocks(), (basist::uastc_block*)tex.get_ptr(),
					(const color_rgba *)m_source_blocks[slice_desc.m_first_block_index].m_pixels, rdo_params, m_params.m_pack_uastc_flags, m_params.m_rdo_uastc_multithreading ? m_params.m_pJob_pool : nullptr,
					(m_params.m_rdo_uastc_multithreading && m_params.m_pJob_pool) ? basisu::minimum<uint32_t>(4, (uint32_t)m_params.m_pJob_pool->get_total_threads()) : 0);
				if (!status)
				{
					return cECFailedUASTCRDOPostProcess;
				}
			}

			m_uastc_backend_output.m_slice_image_data[slice_index].resize(tex.get_size_in_bytes());
			memcpy(&m_uastc_backend_output.m_slice_image_data[slice_index][0], tex.get_ptr(), tex.get_size_in_bytes());
			
			m_uastc_backend_output.m_slice_image_crcs[slice_index] = basist::crc16(tex.get_ptr(), tex.get_size_in_bytes(), 0);
						
		} // slice_index
				
		return cECSuccess;
	}

	bool basis_compressor::generate_mipmaps(const imagef& img, basisu::vector<imagef>& mips, bool has_alpha)
	{
		debug_printf("basis_compressor::generate_mipmaps\n");

		interval_timer tm;
		tm.start();

		uint32_t total_levels = 1;
		uint32_t w = img.get_width(), h = img.get_height();
		while (maximum<uint32_t>(w, h) > (uint32_t)m_params.m_mip_smallest_dimension)
		{
			w = maximum(w >> 1U, 1U);
			h = maximum(h >> 1U, 1U);
			total_levels++;
		}

		for (uint32_t level = 1; level < total_levels; level++)
		{
			const uint32_t level_width = maximum<uint32_t>(1, img.get_width() >> level);
			const uint32_t level_height = maximum<uint32_t>(1, img.get_height() >> level);

			imagef& level_img = *enlarge_vector(mips, 1);
			level_img.resize(level_width, level_height);

			const imagef* pSource_image = &img;

			if (m_params.m_mip_fast)
			{
				if (level > 1)
					pSource_image = &mips[level - 1];
			}

			bool status = image_resample(*pSource_image, level_img, 
				//m_params.m_mip_filter.c_str(), 
				"box", // TODO: negative lobes in the filter are causing negative colors, try Mitchell
				m_params.m_mip_scale, m_params.m_mip_wrapping, 0, has_alpha ? 4 : 3);
			if (!status)
			{
				error_printf("basis_compressor::generate_mipmaps: image_resample() failed!\n");
				return false;
			}

			clean_hdr_image(level_img);
		}

		if (m_params.m_debug)
			debug_printf("Total mipmap generation time: %3.3f secs\n", tm.get_elapsed_secs());

		return true;
	}

	bool basis_compressor::generate_mipmaps(const image &img, basisu::vector<image> &mips, bool has_alpha)
	{
		debug_printf("basis_compressor::generate_mipmaps\n");

		interval_timer tm;
		tm.start();

		uint32_t total_levels = 1;
		uint32_t w = img.get_width(), h = img.get_height();
		while (maximum<uint32_t>(w, h) > (uint32_t)m_params.m_mip_smallest_dimension)
		{
			w = maximum(w >> 1U, 1U);
			h = maximum(h >> 1U, 1U);
			total_levels++;
		}

#if BASISU_USE_STB_IMAGE_RESIZE_FOR_MIPMAP_GEN
		// Requires stb_image_resize
		stbir_filter filter = STBIR_FILTER_DEFAULT;
		if (m_params.m_mip_filter == "box")
			filter = STBIR_FILTER_BOX;
		else if (m_params.m_mip_filter == "triangle")
			filter = STBIR_FILTER_TRIANGLE;
		else if (m_params.m_mip_filter == "cubic")
			filter = STBIR_FILTER_CUBICBSPLINE;
		else if (m_params.m_mip_filter == "catmull")
			filter = STBIR_FILTER_CATMULLROM;
		else if (m_params.m_mip_filter == "mitchell")
			filter = STBIR_FILTER_MITCHELL;

		for (uint32_t level = 1; level < total_levels; level++)
		{
			const uint32_t level_width = maximum<uint32_t>(1, img.get_width() >> level);
			const uint32_t level_height = maximum<uint32_t>(1, img.get_height() >> level);

			image &level_img = *enlarge_vector(mips, 1);
			level_img.resize(level_width, level_height);
						
			int result = stbir_resize_uint8_generic( 
				(const uint8_t *)img.get_ptr(), img.get_width(), img.get_height(), img.get_pitch() * sizeof(color_rgba),
            (uint8_t *)level_img.get_ptr(), level_img.get_width(), level_img.get_height(), level_img.get_pitch() * sizeof(color_rgba),
            has_alpha ? 4 : 3, has_alpha ? 3 : STBIR_ALPHA_CHANNEL_NONE, m_params.m_mip_premultiplied ? STBIR_FLAG_ALPHA_PREMULTIPLIED : 0,
            m_params.m_mip_wrapping ? STBIR_EDGE_WRAP : STBIR_EDGE_CLAMP, filter, m_params.m_mip_srgb ? STBIR_COLORSPACE_SRGB : STBIR_COLORSPACE_LINEAR, 
				nullptr);

			if (result == 0)
			{
				error_printf("basis_compressor::generate_mipmaps: stbir_resize_uint8_generic() failed!\n");
				return false;
			}
			
			if (m_params.m_mip_renormalize)
				level_img.renormalize_normal_map();
		}
#else
		for (uint32_t level = 1; level < total_levels; level++)
		{
			const uint32_t level_width = maximum<uint32_t>(1, img.get_width() >> level);
			const uint32_t level_height = maximum<uint32_t>(1, img.get_height() >> level);

			image& level_img = *enlarge_vector(mips, 1);
			level_img.resize(level_width, level_height);

			const image* pSource_image = &img;

			if (m_params.m_mip_fast)
			{
				if (level > 1)
					pSource_image = &mips[level - 1];
			}

			bool status = image_resample(*pSource_image, level_img, m_params.m_mip_srgb, m_params.m_mip_filter.c_str(), m_params.m_mip_scale, m_params.m_mip_wrapping, 0, has_alpha ? 4 : 3);
			if (!status)
			{
				error_printf("basis_compressor::generate_mipmaps: image_resample() failed!\n");
				return false;
			}

			if (m_params.m_mip_renormalize)
				level_img.renormalize_normal_map();
		}
#endif

		if (m_params.m_debug)
			debug_printf("Total mipmap generation time: %3.3f secs\n", tm.get_elapsed_secs());

		return true;
	}

	void basis_compressor::clean_hdr_image(imagef& src_img)
	{
		const uint32_t width = src_img.get_width();
		const uint32_t height = src_img.get_height();

		float max_used_val = 0.0f;
		for (uint32_t y = 0; y < height; y++)
		{
			for (uint32_t x = 0; x < width; x++)
			{
				vec4F& c = src_img(x, y);
				for (uint32_t i = 0; i < 3; i++)
					max_used_val = maximum(max_used_val, c[i]);
			}
		}

		double hdr_image_scale = 1.0f;
		if (max_used_val > basist::ASTC_HDR_MAX_VAL)
		{
			hdr_image_scale = max_used_val / basist::ASTC_HDR_MAX_VAL;

			const double inv_hdr_image_scale = basist::ASTC_HDR_MAX_VAL / max_used_val;

			for (uint32_t y = 0; y < src_img.get_height(); y++)
			{
				for (uint32_t x = 0; x < src_img.get_width(); x++)
				{
					vec4F& c = src_img(x, y);

					for (uint32_t i = 0; i < 3; i++)
						c[i] = (float)minimum<double>(c[i] * inv_hdr_image_scale, basist::ASTC_HDR_MAX_VAL);
				}
			}

			printf("Warning: The input HDR image's maximum used float value was %f, which is too high to encode as ASTC HDR. The image's components have been linearly scaled so the maximum used value is %f, by multiplying by %f.\n",
				max_used_val, basist::ASTC_HDR_MAX_VAL, inv_hdr_image_scale);

			printf("The decoded ASTC HDR texture will have to be scaled up by %f.\n", hdr_image_scale);
		}

		// TODO: Determine a constant scale factor, apply if > MAX_HALF_FLOAT
		if (!src_img.clean_astc_hdr_pixels(basist::ASTC_HDR_MAX_VAL))
			printf("Warning: clean_astc_hdr_pixels() had to modify the input image to encode to ASTC HDR - see previous warning(s).\n");

		float lowest_nonzero_val = 1e+30f;
		float lowest_val = 1e+30f;
		float highest_val = -1e+30f;

		for (uint32_t y = 0; y < src_img.get_height(); y++)
		{
			for (uint32_t x = 0; x < src_img.get_width(); x++)
			{
				const vec4F& c = src_img(x, y);

				for (uint32_t i = 0; i < 3; i++)
				{
					lowest_val = basisu::minimum(lowest_val, c[i]);

					if (c[i] != 0.0f)
						lowest_nonzero_val = basisu::minimum(lowest_nonzero_val, c[i]);

					highest_val = basisu::maximum(highest_val, c[i]);
				}
			}
		}

		debug_printf("Lowest image value: %e, lowest non-zero value: %e, highest value: %e, dynamic range: %e\n", lowest_val, lowest_nonzero_val, highest_val, highest_val / lowest_nonzero_val);
	}

	bool basis_compressor::read_dds_source_images()
	{
		debug_printf("basis_compressor::read_dds_source_images\n");

		// Nothing to do if the caller doesn't want us reading source images.
		if ((!m_params.m_read_source_images) || (!m_params.m_source_filenames.size()))
			return true;

		// Just bail of the caller has specified their own source images.
		if (m_params.m_source_images.size() || m_params.m_source_images_hdr.size())
			return true;

		if (m_params.m_source_mipmap_images.size() || m_params.m_source_mipmap_images_hdr.size())
			return true;
				
		// See if any input filenames are .DDS
		bool any_dds = false, all_dds = true;
		for (uint32_t i = 0; i < m_params.m_source_filenames.size(); i++)
		{
			std::string ext(string_get_extension(m_params.m_source_filenames[i]));
			if (strcasecmp(ext.c_str(), "dds") == 0)
				any_dds = true;
			else
				all_dds = false;
		}

		// Bail if no .DDS files specified.
		if (!any_dds)
			return true;

		// If any input is .DDS they all must be .DDS, for simplicity.
		if (!all_dds)
		{
			error_printf("If any filename is DDS, all filenames must be DDS.\n");
			return false;
		}

		// Can't jam in alpha channel images if any .DDS files specified.
		if (m_params.m_source_alpha_filenames.size())
		{
			error_printf("Source alpha filenames are not supported in DDS mode.\n");
			return false;
		}

		bool any_mipmaps = false;

		// Read each .DDS texture file
		for (uint32_t i = 0; i < m_params.m_source_filenames.size(); i++)
		{
			basisu::vector<image> ldr_mips;
			basisu::vector<imagef> hdr_mips;
			bool status = read_uncompressed_dds_file(m_params.m_source_filenames[i].c_str(), ldr_mips, hdr_mips);
			if (!status)
				return false;

			assert(ldr_mips.size() || hdr_mips.size());

			if (m_params.m_status_output)
			{
				printf("Read DDS file \"%s\", %s, %ux%u, %u mipmap levels\n",
					m_params.m_source_filenames[i].c_str(),
					ldr_mips.size() ? "LDR" : "HDR",
					ldr_mips.size() ? ldr_mips[0].get_width() : hdr_mips[0].get_width(),
					ldr_mips.size() ? ldr_mips[0].get_height() : hdr_mips[0].get_height(),
					ldr_mips.size() ? ldr_mips.size() : hdr_mips.size());
			}

			if (ldr_mips.size())
			{
				if (m_params.m_source_images_hdr.size())
				{
					error_printf("All DDS files must be of the same type (all LDR, or all HDR)\n");
					return false;
				}

				m_params.m_source_images.push_back(ldr_mips[0]);
				m_params.m_source_mipmap_images.resize(m_params.m_source_mipmap_images.size() + 1);

				if (ldr_mips.size() > 1)
				{
					ldr_mips.erase(0U);

					m_params.m_source_mipmap_images.back().swap(ldr_mips);
					
					any_mipmaps = true;
				}
			}
			else
			{
				if (m_params.m_source_images.size())
				{
					error_printf("All DDS files must be of the same type (all LDR, or all HDR)\n");
					return false;
				}

				m_params.m_source_images_hdr.push_back(hdr_mips[0]);
				m_params.m_source_mipmap_images_hdr.resize(m_params.m_source_mipmap_images_hdr.size() + 1);

				if (hdr_mips.size() > 1)
				{
					hdr_mips.erase(0U);

					m_params.m_source_mipmap_images_hdr.back().swap(hdr_mips);
					
					any_mipmaps = true;
				}

				m_params.m_hdr = true;
				m_params.m_uastc = true;
			}
		}

		m_params.m_read_source_images = false;
		m_params.m_source_filenames.clear();
		m_params.m_source_alpha_filenames.clear();

		if (!any_mipmaps)
		{
			m_params.m_source_mipmap_images.clear();
			m_params.m_source_mipmap_images_hdr.clear();
		}

		if ((m_params.m_hdr) && (!m_params.m_source_images_hdr.size()))
		{
			error_printf("HDR mode enabled, but only LDR .DDS files were loaded. HDR mode requires half or float (HDR) .DDS inputs.\n");
			return false;
		}
		
		return true;
	}

	bool basis_compressor::read_source_images()
	{
		debug_printf("basis_compressor::read_source_images\n");

		const uint32_t total_source_files = m_params.m_read_source_images ? (uint32_t)m_params.m_source_filenames.size() : 
			(m_params.m_hdr ? (uint32_t)m_params.m_source_images_hdr.size() : (uint32_t)m_params.m_source_images.size());

		if (!total_source_files)
		{
			debug_printf("basis_compressor::read_source_images: No source images to process\n");

			return false;
		}

		m_stats.resize(0);
		m_slice_descs.resize(0);
		m_slice_images.resize(0);
		m_slice_images_hdr.resize(0);

		m_total_blocks = 0;
		uint32_t total_macroblocks = 0;

		m_any_source_image_has_alpha = false;

		basisu::vector<image> source_images;
		basisu::vector<imagef> source_images_hdr;

		basisu::vector<std::string> source_filenames;
		
		// TODO: Note HDR images don't support alpha here, currently.

		// First load all source images, and determine if any have an alpha channel.
		for (uint32_t source_file_index = 0; source_file_index < total_source_files; source_file_index++)
		{
			const char* pSource_filename = "";

			image file_image;
			imagef file_image_hdr;

			if (m_params.m_read_source_images)
			{
				pSource_filename = m_params.m_source_filenames[source_file_index].c_str();

				// Load the source image
				if (m_params.m_hdr)
				{
					if (!load_image_hdr(pSource_filename, file_image_hdr, m_params.m_hdr_ldr_srgb_to_linear_conversion))
					{
						error_printf("Failed reading source image: %s\n", pSource_filename);
						return false;
					}

					// For now, just slam alpha to 1.0f. UASTC HDR doesn't support alpha yet.
					for (uint32_t y = 0; y < file_image_hdr.get_height(); y++)
						for (uint32_t x = 0; x < file_image_hdr.get_width(); x++)
							file_image_hdr(x, y)[3] = 1.0f;
				}
				else
				{
					if (!load_image(pSource_filename, file_image))
					{
						error_printf("Failed reading source image: %s\n", pSource_filename);
						return false;
					}
				}

				const uint32_t width = m_params.m_hdr ? file_image_hdr.get_width() : file_image.get_width();
				const uint32_t height = m_params.m_hdr ? file_image_hdr.get_height() : file_image.get_height();

				if (m_params.m_status_output)
				{
					printf("Read source image \"%s\", %ux%u\n", pSource_filename, width, height);
				}

				if (m_params.m_hdr)
				{
					clean_hdr_image(file_image_hdr);
				}
				else
				{
					// Optionally load another image and put a grayscale version of it into the alpha channel.
					if ((source_file_index < m_params.m_source_alpha_filenames.size()) && (m_params.m_source_alpha_filenames[source_file_index].size()))
					{
						const char* pSource_alpha_image = m_params.m_source_alpha_filenames[source_file_index].c_str();

						image alpha_data;

						if (!load_image(pSource_alpha_image, alpha_data))
						{
							error_printf("Failed reading source image: %s\n", pSource_alpha_image);
							return false;
						}

						printf("Read source alpha image \"%s\", %ux%u\n", pSource_alpha_image, alpha_data.get_width(), alpha_data.get_height());

						alpha_data.crop(width, height);

						for (uint32_t y = 0; y < height; y++)
							for (uint32_t x = 0; x < width; x++)
								file_image(x, y).a = (uint8_t)alpha_data(x, y).get_709_luma();
					}
				}
			}
			else
			{
				if (m_params.m_hdr)
				{
					file_image_hdr = m_params.m_source_images_hdr[source_file_index];
					clean_hdr_image(file_image_hdr);
				}
				else
				{
					file_image = m_params.m_source_images[source_file_index];
				}
			}

			if (!m_params.m_hdr)
			{
				if (m_params.m_renormalize)
					file_image.renormalize_normal_map();
			}

			bool alpha_swizzled = false;

			if (m_params.m_swizzle[0] != 0 ||
				m_params.m_swizzle[1] != 1 ||
				m_params.m_swizzle[2] != 2 ||
				m_params.m_swizzle[3] != 3)
			{
				if (!m_params.m_hdr)
				{
					// Used for XY normal maps in RG - puts X in color, Y in alpha
					for (uint32_t y = 0; y < file_image.get_height(); y++)
					{
						for (uint32_t x = 0; x < file_image.get_width(); x++)
						{
							const color_rgba& c = file_image(x, y);
							file_image(x, y).set_noclamp_rgba(c[m_params.m_swizzle[0]], c[m_params.m_swizzle[1]], c[m_params.m_swizzle[2]], c[m_params.m_swizzle[3]]);
						}
					}

					alpha_swizzled = (m_params.m_swizzle[3] != 3);
				}
				else
				{
					// Used for XY normal maps in RG - puts X in color, Y in alpha
					for (uint32_t y = 0; y < file_image_hdr.get_height(); y++)
					{
						for (uint32_t x = 0; x < file_image_hdr.get_width(); x++)
						{
							const vec4F& c = file_image_hdr(x, y);
							
							// For now, alpha is always 1.0f in UASTC HDR.
							file_image_hdr(x, y).set(c[m_params.m_swizzle[0]], c[m_params.m_swizzle[1]], c[m_params.m_swizzle[2]], 1.0f); // c[m_params.m_swizzle[3]]);
						}
					}
				}
			}

			bool has_alpha = false;

			if (!m_params.m_hdr)
			{
				if (m_params.m_force_alpha || alpha_swizzled)
					has_alpha = true;
				else if (!m_params.m_check_for_alpha)
					file_image.set_alpha(255);
				else if (file_image.has_alpha())
					has_alpha = true;

				if (has_alpha)
					m_any_source_image_has_alpha = true;
			}

			{
				const uint32_t width = m_params.m_hdr ? file_image_hdr.get_width() : file_image.get_width();
				const uint32_t height = m_params.m_hdr ? file_image_hdr.get_height() : file_image.get_height();

				debug_printf("Source image index %u filename %s %ux%u has alpha: %u\n", source_file_index, pSource_filename, width, height, has_alpha);
			}

			if (m_params.m_y_flip)
			{
				if (m_params.m_hdr)
					file_image_hdr.flip_y();
				else
					file_image.flip_y();
			}

#if DEBUG_EXTRACT_SINGLE_BLOCK
			const uint32_t block_x = 0;
			const uint32_t block_y = 0;

			if (m_params.m_hdr)
			{
				imagef block_image(4, 4);
				block_image_hdr.blit(block_x * 4, block_y * 4, 4, 4, 0, 0, file_image_hdr, 0);
				file_image_hdr = block_image;
			}
			else
			{
				image block_image(4, 4);
				block_image.blit(block_x * 4, block_y * 4, 4, 4, 0, 0, file_image, 0);
				file_image = block_image;
			}
#endif

#if DEBUG_CROP_TEXTURE_TO_64x64
			if (m_params.m_hdr)
				file_image_hdr.resize(64, 64);
			else
				file_image.resize(64, 64);
#endif

			if ((m_params.m_resample_width > 0) && (m_params.m_resample_height > 0))
			{
				int new_width = basisu::minimum<int>(m_params.m_resample_width, BASISU_MAX_SUPPORTED_TEXTURE_DIMENSION);
				int new_height = basisu::minimum<int>(m_params.m_resample_height, BASISU_MAX_SUPPORTED_TEXTURE_DIMENSION);

				debug_printf("Resampling to %ix%i\n", new_width, new_height);

				// TODO: A box filter - kaiser looks too sharp on video. Let the caller control this.
				if (m_params.m_hdr)
				{
					imagef temp_img(new_width, new_height);
					image_resample(file_image_hdr, temp_img, "box"); // "kaiser");
					clean_hdr_image(temp_img);
					temp_img.swap(file_image_hdr);
				}
				else
				{
					image temp_img(new_width, new_height);
					image_resample(file_image, temp_img, m_params.m_perceptual, "box"); // "kaiser");
					temp_img.swap(file_image);
				}
			}
			else if (m_params.m_resample_factor > 0.0f)
			{
				// TODO: A box filter - kaiser looks too sharp on video. Let the caller control this.
				if (m_params.m_hdr)
				{
					int new_width = basisu::minimum<int>(basisu::maximum(1, (int)ceilf(file_image_hdr.get_width() * m_params.m_resample_factor)), BASISU_MAX_SUPPORTED_TEXTURE_DIMENSION);
					int new_height = basisu::minimum<int>(basisu::maximum(1, (int)ceilf(file_image_hdr.get_height() * m_params.m_resample_factor)), BASISU_MAX_SUPPORTED_TEXTURE_DIMENSION);

					debug_printf("Resampling to %ix%i\n", new_width, new_height);

					imagef temp_img(new_width, new_height);
					image_resample(file_image_hdr, temp_img, "box"); // "kaiser");
					clean_hdr_image(temp_img);
					temp_img.swap(file_image_hdr);
				}
				else
				{
					int new_width = basisu::minimum<int>(basisu::maximum(1, (int)ceilf(file_image.get_width() * m_params.m_resample_factor)), BASISU_MAX_SUPPORTED_TEXTURE_DIMENSION);
					int new_height = basisu::minimum<int>(basisu::maximum(1, (int)ceilf(file_image.get_height() * m_params.m_resample_factor)), BASISU_MAX_SUPPORTED_TEXTURE_DIMENSION);

					debug_printf("Resampling to %ix%i\n", new_width, new_height);

					image temp_img(new_width, new_height);
					image_resample(file_image, temp_img, m_params.m_perceptual, "box"); // "kaiser");
					temp_img.swap(file_image);
				}
			}

			const uint32_t width = m_params.m_hdr ? file_image_hdr.get_width() : file_image.get_width();
			const uint32_t height = m_params.m_hdr ? file_image_hdr.get_height() : file_image.get_height();

			if ((!width) || (!height))
			{
				error_printf("basis_compressor::read_source_images: Source image has a zero width and/or height!\n");
				return false;
			}

			if ((width > BASISU_MAX_SUPPORTED_TEXTURE_DIMENSION) || (height > BASISU_MAX_SUPPORTED_TEXTURE_DIMENSION))
			{
				error_printf("basis_compressor::read_source_images: Source image \"%s\" is too large!\n", pSource_filename);
				return false;
			}

			if (!m_params.m_hdr)
				source_images.enlarge(1)->swap(file_image);
			else
				source_images_hdr.enlarge(1)->swap(file_image_hdr);

			source_filenames.push_back(pSource_filename);
		}

		// Check if the caller has generated their own mipmaps. 
		if (m_params.m_hdr)
		{
			if (m_params.m_source_mipmap_images_hdr.size())
			{
				// Make sure they've passed us enough mipmap chains.
				if ((m_params.m_source_images_hdr.size() != m_params.m_source_mipmap_images_hdr.size()) || (total_source_files != m_params.m_source_images_hdr.size()))
				{
					error_printf("basis_compressor::read_source_images(): m_params.m_source_mipmap_images_hdr.size() must equal m_params.m_source_images_hdr.size()!\n");
					return false;
				}
			}
		}
		else 
		{
			if (m_params.m_source_mipmap_images.size())
			{
				// Make sure they've passed us enough mipmap chains.
				if ((m_params.m_source_images.size() != m_params.m_source_mipmap_images.size()) || (total_source_files != m_params.m_source_images.size()))
				{
					error_printf("basis_compressor::read_source_images(): m_params.m_source_mipmap_images.size() must equal m_params.m_source_images.size()!\n");
					return false;
				}

				// Check if any of the user-supplied mipmap levels has alpha.
				if (!m_any_source_image_has_alpha)
				{
					for (uint32_t source_file_index = 0; source_file_index < total_source_files; source_file_index++)
					{
						for (uint32_t mip_index = 0; mip_index < m_params.m_source_mipmap_images[source_file_index].size(); mip_index++)
						{
							const image& mip_img = m_params.m_source_mipmap_images[source_file_index][mip_index];

							// Be sure to take into account any swizzling which will be applied.
							if (mip_img.has_alpha(m_params.m_swizzle[3]))
							{
								m_any_source_image_has_alpha = true;
								break;
							}
						}

						if (m_any_source_image_has_alpha)
							break;
					}
				}
			}
		}

		debug_printf("Any source image has alpha: %u\n", m_any_source_image_has_alpha);

		// Now, for each source image, create the slices corresponding to that image.
		for (uint32_t source_file_index = 0; source_file_index < total_source_files; source_file_index++)
		{
			const std::string &source_filename = source_filenames[source_file_index];
						
			basisu::vector<image> slices;
			basisu::vector<imagef> slices_hdr;
			
			slices.reserve(32);
			slices_hdr.reserve(32);
						
			// The first (largest) mipmap level.
			image *pFile_image = source_images.size() ? &source_images[source_file_index] : nullptr;
			imagef *pFile_image_hdr = source_images_hdr.size() ? &source_images_hdr[source_file_index] : nullptr;
									
			// Reserve a slot for mip0.
			if (m_params.m_hdr)
				slices_hdr.resize(1);
			else
				slices.resize(1);
			
			if ((!m_params.m_hdr) && (m_params.m_source_mipmap_images.size()))
			{
				// User-provided mipmaps for each layer or image in the texture array.
				for (uint32_t mip_index = 0; mip_index < m_params.m_source_mipmap_images[source_file_index].size(); mip_index++)
				{
					image& mip_img = m_params.m_source_mipmap_images[source_file_index][mip_index];

					if ((m_params.m_swizzle[0] != 0) ||
						(m_params.m_swizzle[1] != 1) ||
						(m_params.m_swizzle[2] != 2) ||
						(m_params.m_swizzle[3] != 3))
					{
						// Used for XY normal maps in RG - puts X in color, Y in alpha
						for (uint32_t y = 0; y < mip_img.get_height(); y++)
						{
							for (uint32_t x = 0; x < mip_img.get_width(); x++)
							{
								const color_rgba& c = mip_img(x, y);
								mip_img(x, y).set_noclamp_rgba(c[m_params.m_swizzle[0]], c[m_params.m_swizzle[1]], c[m_params.m_swizzle[2]], c[m_params.m_swizzle[3]]);
							}
						}
					}

					slices.push_back(mip_img);
				}
			}
			else if ((m_params.m_hdr) && (m_params.m_source_mipmap_images_hdr.size()))
			{
				// User-provided mipmaps for each layer or image in the texture array.
				for (uint32_t mip_index = 0; mip_index < m_params.m_source_mipmap_images_hdr[source_file_index].size(); mip_index++)
				{
					imagef& mip_img = m_params.m_source_mipmap_images_hdr[source_file_index][mip_index];

					if ((m_params.m_swizzle[0] != 0) ||
						(m_params.m_swizzle[1] != 1) ||
						(m_params.m_swizzle[2] != 2) ||
						(m_params.m_swizzle[3] != 3))
					{
						// Used for XY normal maps in RG - puts X in color, Y in alpha
						for (uint32_t y = 0; y < mip_img.get_height(); y++)
						{
							for (uint32_t x = 0; x < mip_img.get_width(); x++)
							{
								const vec4F& c = mip_img(x, y);

								// For now, HDR alpha is always 1.0f.
								mip_img(x, y).set(c[m_params.m_swizzle[0]], c[m_params.m_swizzle[1]], c[m_params.m_swizzle[2]], 1.0f); // c[m_params.m_swizzle[3]]);
							}
						}
					}

					clean_hdr_image(mip_img);

					slices_hdr.push_back(mip_img);
				}
			}
			else if (m_params.m_mip_gen)
			{
				// Automatically generate mipmaps.
				if (m_params.m_hdr)
				{
					if (!generate_mipmaps(*pFile_image_hdr, slices_hdr, m_any_source_image_has_alpha))
						return false;
				}
				else
				{
					if (!generate_mipmaps(*pFile_image, slices, m_any_source_image_has_alpha))
						return false;
				}
			}

			// Swap in the largest mipmap level here to avoid copying it, because generate_mips() will change the array.
			// NOTE: file_image is now blank.
			if (m_params.m_hdr)
				slices_hdr[0].swap(*pFile_image_hdr);
			else
				slices[0].swap(*pFile_image);

			uint_vec mip_indices(m_params.m_hdr ? slices_hdr.size() : slices.size());
			for (uint32_t i = 0; i < (m_params.m_hdr ? slices_hdr.size() : slices.size()); i++)
				mip_indices[i] = i;
						
			if ((!m_params.m_hdr) && (m_any_source_image_has_alpha) && (!m_params.m_uastc))
			{
				// For ETC1S, if source has alpha, then even mips will have RGB, and odd mips will have alpha in RGB. 
				basisu::vector<image> alpha_slices;
				uint_vec new_mip_indices;

				alpha_slices.reserve(slices.size() * 2);

				for (uint32_t i = 0; i < slices.size(); i++)
				{
					image lvl_rgb(slices[i]);
					image lvl_a(lvl_rgb);

					for (uint32_t y = 0; y < lvl_a.get_height(); y++)
					{
						for (uint32_t x = 0; x < lvl_a.get_width(); x++)
						{
							uint8_t a = lvl_a(x, y).a;
							lvl_a(x, y).set_noclamp_rgba(a, a, a, 255);
						}
					}
					
					lvl_rgb.set_alpha(255);

					alpha_slices.push_back(lvl_rgb);
					new_mip_indices.push_back(i);

					alpha_slices.push_back(lvl_a);
					new_mip_indices.push_back(i);
				}

				slices.swap(alpha_slices);
				mip_indices.swap(new_mip_indices);
			}

			if (m_params.m_hdr)
			{
				assert(slices_hdr.size() == mip_indices.size());
			}
			else
			{
				assert(slices.size() == mip_indices.size());
			}
					
			for (uint32_t slice_index = 0; slice_index < (m_params.m_hdr ? slices_hdr.size() : slices.size()); slice_index++)
			{
				image *pSlice_image = m_params.m_hdr ? nullptr : &slices[slice_index];
				imagef *pSlice_image_hdr = m_params.m_hdr ? &slices_hdr[slice_index] : nullptr;

				const uint32_t orig_width = m_params.m_hdr ? pSlice_image_hdr->get_width() : pSlice_image->get_width();
				const uint32_t orig_height = m_params.m_hdr ? pSlice_image_hdr->get_height() : pSlice_image->get_height();

				bool is_alpha_slice = false;
				if ((!m_params.m_hdr) && (m_any_source_image_has_alpha))
				{
					if (m_params.m_uastc)
					{
						is_alpha_slice = pSlice_image->has_alpha();
					}
					else
					{
						is_alpha_slice = (slice_index & 1) != 0;
					}
				}

				// Enlarge the source image to 4x4 block boundaries, duplicating edge pixels if necessary to avoid introducing extra colors into blocks.
				if (m_params.m_hdr)
					pSlice_image_hdr->crop_dup_borders(pSlice_image_hdr->get_block_width(4) * 4, pSlice_image_hdr->get_block_height(4) * 4);
				else
					pSlice_image->crop_dup_borders(pSlice_image->get_block_width(4) * 4, pSlice_image->get_block_height(4) * 4);

				if (m_params.m_debug_images)
				{
					if (m_params.m_hdr)
						write_exr(string_format("basis_debug_source_image_%u_slice_%u.exr", source_file_index, slice_index).c_str(), *pSlice_image_hdr, 3, 0);
					else
						save_png(string_format("basis_debug_source_image_%u_slice_%u.png", source_file_index, slice_index).c_str(), *pSlice_image);
				}

				const uint32_t dest_image_index = (m_params.m_hdr ? m_slice_images_hdr.size() : m_slice_images.size());

				enlarge_vector(m_stats, 1);

				if (m_params.m_hdr)
					enlarge_vector(m_slice_images_hdr, 1);
				else
					enlarge_vector(m_slice_images, 1);

				enlarge_vector(m_slice_descs, 1);

				m_stats[dest_image_index].m_filename = source_filename.c_str();
				m_stats[dest_image_index].m_width = orig_width;
				m_stats[dest_image_index].m_height = orig_height;

				debug_printf("****** Slice %u: mip %u, alpha_slice: %u, filename: \"%s\", original: %ux%u actual: %ux%u\n", 
					m_slice_descs.size() - 1, mip_indices[slice_index], is_alpha_slice, source_filename.c_str(), 
					orig_width, orig_height, 
					m_params.m_hdr ? pSlice_image_hdr->get_width() : pSlice_image->get_width(), 
					m_params.m_hdr ? pSlice_image_hdr->get_height() : pSlice_image->get_height());

				basisu_backend_slice_desc& slice_desc = m_slice_descs[dest_image_index];

				slice_desc.m_first_block_index = m_total_blocks;

				slice_desc.m_orig_width = orig_width;
				slice_desc.m_orig_height = orig_height;

				if (m_params.m_hdr)
				{
					slice_desc.m_width = pSlice_image_hdr->get_width();
					slice_desc.m_height = pSlice_image_hdr->get_height();

					slice_desc.m_num_blocks_x = pSlice_image_hdr->get_block_width(4);
					slice_desc.m_num_blocks_y = pSlice_image_hdr->get_block_height(4);
				}
				else
				{
					slice_desc.m_width = pSlice_image->get_width();
					slice_desc.m_height = pSlice_image->get_height();

					slice_desc.m_num_blocks_x = pSlice_image->get_block_width(4);
					slice_desc.m_num_blocks_y = pSlice_image->get_block_height(4);
				}

				slice_desc.m_num_macroblocks_x = (slice_desc.m_num_blocks_x + 1) >> 1;
				slice_desc.m_num_macroblocks_y = (slice_desc.m_num_blocks_y + 1) >> 1;

				slice_desc.m_source_file_index = source_file_index;

				slice_desc.m_mip_index = mip_indices[slice_index];

				slice_desc.m_alpha = is_alpha_slice;
				slice_desc.m_iframe = false;
				if (m_params.m_tex_type == basist::cBASISTexTypeVideoFrames)
				{
					slice_desc.m_iframe = (source_file_index == 0);
				}

				m_total_blocks += slice_desc.m_num_blocks_x * slice_desc.m_num_blocks_y;
				total_macroblocks += slice_desc.m_num_macroblocks_x * slice_desc.m_num_macroblocks_y;

				// Finally, swap in the slice's image to avoid copying it.
				// NOTE: slice_image is now blank.
				if (m_params.m_hdr)
					m_slice_images_hdr[dest_image_index].swap(*pSlice_image_hdr);
				else
					m_slice_images[dest_image_index].swap(*pSlice_image);

			} // slice_index

		} // source_file_index

		debug_printf("Total blocks: %u, Total macroblocks: %u\n", m_total_blocks, total_macroblocks);

		// Make sure we don't have too many slices
		if (m_slice_descs.size() > BASISU_MAX_SLICES)
		{
			error_printf("Too many slices!\n");
			return false;
		}
				
		// Basic sanity check on the slices
		for (uint32_t i = 1; i < m_slice_descs.size(); i++)
		{
			const basisu_backend_slice_desc &prev_slice_desc = m_slice_descs[i - 1];
			const basisu_backend_slice_desc &slice_desc = m_slice_descs[i];

			// Make sure images are in order
			int image_delta = (int)slice_desc.m_source_file_index - (int)prev_slice_desc.m_source_file_index;
			if (image_delta > 1)
				return false;	

			// Make sure mipmap levels are in order
			if (!image_delta)
			{
				int level_delta = (int)slice_desc.m_mip_index - (int)prev_slice_desc.m_mip_index;
				if (level_delta > 1)
					return false;
			}
		}

		if (m_params.m_status_output)
		{
			printf("Total slices: %u\n", (uint32_t)m_slice_descs.size());
		}

		for (uint32_t i = 0; i < m_slice_descs.size(); i++)
		{
			const basisu_backend_slice_desc &slice_desc = m_slice_descs[i];

			if (m_params.m_status_output)
			{
				printf("Slice: %u, alpha: %u, orig width/height: %ux%u, width/height: %ux%u, first_block: %u, image_index: %u, mip_level: %u, iframe: %u\n",
					i, slice_desc.m_alpha, slice_desc.m_orig_width, slice_desc.m_orig_height, 
					slice_desc.m_width, slice_desc.m_height, 
					slice_desc.m_first_block_index, slice_desc.m_source_file_index, slice_desc.m_mip_index, slice_desc.m_iframe);
			}

			if (m_any_source_image_has_alpha)
			{
				// HDR doesn't support alpha yet
				if (m_params.m_hdr)
					return false;

				if (!m_params.m_uastc)
				{
					// For ETC1S, alpha slices must be at odd slice indices.
					if (slice_desc.m_alpha)
					{
						if ((i & 1) == 0)
							return false;

						const basisu_backend_slice_desc& prev_slice_desc = m_slice_descs[i - 1];

						// Make sure previous slice has this image's color data
						if (prev_slice_desc.m_source_file_index != slice_desc.m_source_file_index)
							return false;
						if (prev_slice_desc.m_alpha)
							return false;
						if (prev_slice_desc.m_mip_index != slice_desc.m_mip_index)
							return false;
						if (prev_slice_desc.m_num_blocks_x != slice_desc.m_num_blocks_x)
							return false;
						if (prev_slice_desc.m_num_blocks_y != slice_desc.m_num_blocks_y)
							return false;
					}
					else if (i & 1)
						return false;
				}
			}
			else if (slice_desc.m_alpha)
			{
				return false;
			}

			if ((slice_desc.m_orig_width > slice_desc.m_width) || (slice_desc.m_orig_height > slice_desc.m_height))
				return false;

			if ((slice_desc.m_source_file_index == 0) && (m_params.m_tex_type == basist::cBASISTexTypeVideoFrames))
			{
				if (!slice_desc.m_iframe)
					return false;
			}
		}

		return true;
	}

	// Do some basic validation for 2D arrays, cubemaps, video, and volumes.
	bool basis_compressor::validate_texture_type_constraints() 
	{
		debug_printf("basis_compressor::validate_texture_type_constraints\n");

		// In 2D mode anything goes (each image may have a different resolution and # of mipmap levels).
		if (m_params.m_tex_type == basist::cBASISTexType2D)
			return true;
				
		uint32_t total_basis_images = 0;

		for (uint32_t slice_index = 0; slice_index < (m_params.m_hdr ? m_slice_images_hdr.size() : m_slice_images.size()); slice_index++)
		{
			const basisu_backend_slice_desc &slice_desc = m_slice_descs[slice_index];
				
			total_basis_images = maximum<uint32_t>(total_basis_images, slice_desc.m_source_file_index + 1);
		}

		if (m_params.m_tex_type == basist::cBASISTexTypeCubemapArray)
		{
			// For cubemaps, validate that the total # of Basis images is a multiple of 6.
			if ((total_basis_images % 6) != 0)
			{
				error_printf("basis_compressor::validate_texture_type_constraints: For cubemaps the total number of input images is not a multiple of 6!\n");
				return false;
			}
		}

		// Now validate that all the mip0's have the same dimensions, and that each image has the same # of mipmap levels.
		uint_vec image_mipmap_levels(total_basis_images);

		int width = -1, height = -1;
		for (uint32_t slice_index = 0; slice_index < (m_params.m_hdr ? m_slice_images_hdr.size() : m_slice_images.size()); slice_index++)
		{
			const basisu_backend_slice_desc &slice_desc = m_slice_descs[slice_index];

			image_mipmap_levels[slice_desc.m_source_file_index] = maximum(image_mipmap_levels[slice_desc.m_source_file_index], slice_desc.m_mip_index + 1);
				
			if (slice_desc.m_mip_index != 0)
				continue;

			if (width < 0)
			{
				width = slice_desc.m_orig_width;
				height = slice_desc.m_orig_height;
			}
			else if ((width != (int)slice_desc.m_orig_width) || (height != (int)slice_desc.m_orig_height))
			{
				error_printf("basis_compressor::validate_texture_type_constraints: The source image resolutions are not all equal!\n");
				return false;
			}
		}

		for (size_t i = 1; i < image_mipmap_levels.size(); i++)
		{
			if (image_mipmap_levels[0] != image_mipmap_levels[i])
			{
				error_printf("basis_compressor::validate_texture_type_constraints: Each image must have the same number of mipmap levels!\n");
				return false;
			}
		}

		return true;
	}

	bool basis_compressor::extract_source_blocks()
	{
		debug_printf("basis_compressor::extract_source_blocks\n");

		if (m_params.m_hdr)
			m_source_blocks_hdr.resize(m_total_blocks);
		else
			m_source_blocks.resize(m_total_blocks);

		for (uint32_t slice_index = 0; slice_index < (m_params.m_hdr ? m_slice_images_hdr.size() : m_slice_images.size()); slice_index++)
		{
			const basisu_backend_slice_desc& slice_desc = m_slice_descs[slice_index];

			const uint32_t num_blocks_x = slice_desc.m_num_blocks_x;
			const uint32_t num_blocks_y = slice_desc.m_num_blocks_y;

			const image *pSource_image = m_params.m_hdr ? nullptr : &m_slice_images[slice_index];
			const imagef *pSource_image_hdr = m_params.m_hdr ? &m_slice_images_hdr[slice_index] : nullptr;

			for (uint32_t block_y = 0; block_y < num_blocks_y; block_y++)
			{
				for (uint32_t block_x = 0; block_x < num_blocks_x; block_x++)
				{
					if (m_params.m_hdr)
					{
						vec4F* pBlock = m_source_blocks_hdr[slice_desc.m_first_block_index + block_x + block_y * num_blocks_x].get_ptr();

						pSource_image_hdr->extract_block_clamped(pBlock, block_x * 4, block_y * 4, 4, 4);

						// Additional (technically optional) early sanity checking of the block texels.
						for (uint32_t i = 0; i < 16; i++)
						{
							for (uint32_t c = 0; c < 3; c++)
							{
								float v = pBlock[i][c];

								if (std::isnan(v) || std::isinf(v) || (v < 0.0f) || (v > basist::MAX_HALF_FLOAT))
								{
									error_printf("basis_compressor::extract_source_blocks: invalid float component\n");
									return false;
								}
							}
						}
					}
					else
					{
						pSource_image->extract_block_clamped(m_source_blocks[slice_desc.m_first_block_index + block_x + block_y * num_blocks_x].get_ptr(), block_x * 4, block_y * 4, 4, 4);
					}
				}
			}
		}

		return true;
	}

	bool basis_compressor::process_frontend()
	{
		debug_printf("basis_compressor::process_frontend\n");
						
#if 0
		// TODO
		basis_etc1_pack_params pack_params;
		pack_params.m_quality = cETCQualityMedium;
		pack_params.m_perceptual = m_params.m_perceptual;
		pack_params.m_use_color4 = false;

		pack_etc1_block_context pack_context;

		std::unordered_set<uint64_t> endpoint_hash;
		std::unordered_set<uint32_t> selector_hash;

		for (uint32_t i = 0; i < m_source_blocks.size(); i++)
		{
			etc_block blk;
			pack_etc1_block(blk, m_source_blocks[i].get_ptr(), pack_params, pack_context);

			const color_rgba c0(blk.get_block_color(0, false));
			endpoint_hash.insert((c0.r | (c0.g << 5) | (c0.b << 10)) | (blk.get_inten_table(0) << 16));

			const color_rgba c1(blk.get_block_color(1, false));
			endpoint_hash.insert((c1.r | (c1.g << 5) | (c1.b << 10)) | (blk.get_inten_table(1) << 16));

			selector_hash.insert(blk.get_raw_selector_bits());
		}

		const uint32_t total_unique_endpoints = (uint32_t)endpoint_hash.size();
		const uint32_t total_unique_selectors = (uint32_t)selector_hash.size();

		if (m_params.m_debug)
		{
			debug_printf("Unique endpoints: %u, unique selectors: %u\n", total_unique_endpoints, total_unique_selectors);
		}
#endif

		const double total_texels = m_total_blocks * 16.0f;

		int endpoint_clusters = m_params.m_max_endpoint_clusters;
		int selector_clusters = m_params.m_max_selector_clusters;

		if (endpoint_clusters > basisu_frontend::cMaxEndpointClusters)
		{
			error_printf("Too many endpoint clusters! (%u but max is %u)\n", endpoint_clusters, basisu_frontend::cMaxEndpointClusters);
			return false;
		}
		if (selector_clusters > basisu_frontend::cMaxSelectorClusters)
		{
			error_printf("Too many selector clusters! (%u but max is %u)\n", selector_clusters, basisu_frontend::cMaxSelectorClusters);
			return false;
		}
		
		if (m_params.m_quality_level != -1)
		{
			const float quality = saturate(m_params.m_quality_level / 255.0f);
									
			const float bits_per_endpoint_cluster = 14.0f;
			const float max_desired_endpoint_cluster_bits_per_texel = 1.0f; // .15f
			int max_endpoints = static_cast<int>((max_desired_endpoint_cluster_bits_per_texel * total_texels) / bits_per_endpoint_cluster);
			
			const float mid = 128.0f / 255.0f;

			float color_endpoint_quality = quality;

			const float endpoint_split_point = 0.5f;
			
			// In v1.2 and in previous versions, the endpoint codebook size at quality 128 was 3072. This wasn't quite large enough.
			const int ENDPOINT_CODEBOOK_MID_QUALITY_CODEBOOK_SIZE = 4800;
			const int MAX_ENDPOINT_CODEBOOK_SIZE = 8192;

			if (color_endpoint_quality <= mid)
			{
				color_endpoint_quality = lerp(0.0f, endpoint_split_point, powf(color_endpoint_quality / mid, .65f));

				max_endpoints = clamp<int>(max_endpoints, 256, ENDPOINT_CODEBOOK_MID_QUALITY_CODEBOOK_SIZE);
				max_endpoints = minimum<uint32_t>(max_endpoints, m_total_blocks);
								
				if (max_endpoints < 64)
					max_endpoints = 64;
				endpoint_clusters = clamp<uint32_t>((uint32_t)(.5f + lerp<float>(32, static_cast<float>(max_endpoints), color_endpoint_quality)), 32, basisu_frontend::cMaxEndpointClusters);
			}
			else
			{
				color_endpoint_quality = powf((color_endpoint_quality - mid) / (1.0f - mid), 1.6f);

				max_endpoints = clamp<int>(max_endpoints, 256, MAX_ENDPOINT_CODEBOOK_SIZE);
				max_endpoints = minimum<uint32_t>(max_endpoints, m_total_blocks);
								
				if (max_endpoints < ENDPOINT_CODEBOOK_MID_QUALITY_CODEBOOK_SIZE)
					max_endpoints = ENDPOINT_CODEBOOK_MID_QUALITY_CODEBOOK_SIZE;
				endpoint_clusters = clamp<uint32_t>((uint32_t)(.5f + lerp<float>(ENDPOINT_CODEBOOK_MID_QUALITY_CODEBOOK_SIZE, static_cast<float>(max_endpoints), color_endpoint_quality)), 32, basisu_frontend::cMaxEndpointClusters);
			}
						
			float bits_per_selector_cluster = 14.0f;

			const float max_desired_selector_cluster_bits_per_texel = 1.0f; // .15f
			int max_selectors = static_cast<int>((max_desired_selector_cluster_bits_per_texel * total_texels) / bits_per_selector_cluster);
			max_selectors = clamp<int>(max_selectors, 256, basisu_frontend::cMaxSelectorClusters);
			max_selectors = minimum<uint32_t>(max_selectors, m_total_blocks);

			float color_selector_quality = quality;
			//color_selector_quality = powf(color_selector_quality, 1.65f);
			color_selector_quality = powf(color_selector_quality, 2.62f);

			if (max_selectors < 96)
				max_selectors = 96;
			selector_clusters = clamp<uint32_t>((uint32_t)(.5f + lerp<float>(96, static_cast<float>(max_selectors), color_selector_quality)), 8, basisu_frontend::cMaxSelectorClusters);

			debug_printf("Max endpoints: %u, max selectors: %u\n", endpoint_clusters, selector_clusters);

			if (m_params.m_quality_level >= 223)
			{
				if (!m_params.m_selector_rdo_thresh.was_changed())
				{
					if (!m_params.m_endpoint_rdo_thresh.was_changed())
						m_params.m_endpoint_rdo_thresh *= .25f;
					
					if (!m_params.m_selector_rdo_thresh.was_changed())
						m_params.m_selector_rdo_thresh *= .25f;
				}
			}
			else if (m_params.m_quality_level >= 192)
			{
				if (!m_params.m_endpoint_rdo_thresh.was_changed())
					m_params.m_endpoint_rdo_thresh *= .5f;

				if (!m_params.m_selector_rdo_thresh.was_changed())
					m_params.m_selector_rdo_thresh *= .5f;
			}
			else if (m_params.m_quality_level >= 160)
			{
				if (!m_params.m_endpoint_rdo_thresh.was_changed())
					m_params.m_endpoint_rdo_thresh *= .75f;

				if (!m_params.m_selector_rdo_thresh.was_changed())
					m_params.m_selector_rdo_thresh *= .75f;
			}
			else if (m_params.m_quality_level >= 129)
			{
				float l = (quality - 129 / 255.0f) / ((160 - 129) / 255.0f);

				if (!m_params.m_endpoint_rdo_thresh.was_changed())
					m_params.m_endpoint_rdo_thresh *= lerp<float>(1.0f, .75f, l);
				
				if (!m_params.m_selector_rdo_thresh.was_changed())
					m_params.m_selector_rdo_thresh *= lerp<float>(1.0f, .75f, l);
			}
		}
				
		basisu_frontend::params p;
		p.m_num_source_blocks = m_total_blocks;
		p.m_pSource_blocks = &m_source_blocks[0];
		p.m_max_endpoint_clusters = endpoint_clusters;
		p.m_max_selector_clusters = selector_clusters;
		p.m_perceptual = m_params.m_perceptual;
		p.m_debug_stats = m_params.m_debug;
		p.m_debug_images = m_params.m_debug_images;
		p.m_compression_level = m_params.m_compression_level;
		p.m_tex_type = m_params.m_tex_type;
		p.m_multithreaded = m_params.m_multithreading;
		p.m_disable_hierarchical_endpoint_codebooks = m_params.m_disable_hierarchical_endpoint_codebooks;
		p.m_validate = m_params.m_validate_etc1s;
		p.m_pJob_pool = m_params.m_pJob_pool;
		p.m_pGlobal_codebooks = m_params.m_pGlobal_codebooks;
		
		// Don't keep trying to use OpenCL if it ever fails.
		p.m_pOpenCL_context = !m_opencl_failed ? m_pOpenCL_context : nullptr;

		if (!m_frontend.init(p))
		{
			error_printf("basisu_frontend::init() failed!\n");
			return false;
		}
				
		m_frontend.compress();

		if (m_frontend.get_opencl_failed())
			m_opencl_failed = true;

		if (m_params.m_debug_images)
		{
			for (uint32_t i = 0; i < m_slice_descs.size(); i++)
			{
				char filename[1024];
#ifdef _WIN32				
				sprintf_s(filename, sizeof(filename), "rdo_frontend_output_output_blocks_%u.png", i);
#else
				snprintf(filename, sizeof(filename), "rdo_frontend_output_output_blocks_%u.png", i);
#endif				
				m_frontend.dump_debug_image(filename, m_slice_descs[i].m_first_block_index, m_slice_descs[i].m_num_blocks_x, m_slice_descs[i].m_num_blocks_y, true);

#ifdef _WIN32
				sprintf_s(filename, sizeof(filename), "rdo_frontend_output_api_%u.png", i);
#else
				snprintf(filename, sizeof(filename), "rdo_frontend_output_api_%u.png", i);
#endif				
				m_frontend.dump_debug_image(filename, m_slice_descs[i].m_first_block_index, m_slice_descs[i].m_num_blocks_x, m_slice_descs[i].m_num_blocks_y, false);
			}
		}

		return true;
	}

	bool basis_compressor::extract_frontend_texture_data()
	{
		if (!m_params.m_compute_stats)
			return true;

		debug_printf("basis_compressor::extract_frontend_texture_data\n");

		m_frontend_output_textures.resize(m_slice_descs.size());
		m_best_etc1s_images.resize(m_slice_descs.size());
		m_best_etc1s_images_unpacked.resize(m_slice_descs.size());

		for (uint32_t i = 0; i < m_slice_descs.size(); i++)
		{
			const basisu_backend_slice_desc &slice_desc = m_slice_descs[i];

			const uint32_t num_blocks_x = slice_desc.m_num_blocks_x;
			const uint32_t num_blocks_y = slice_desc.m_num_blocks_y;

			const uint32_t width = num_blocks_x * 4;
			const uint32_t height = num_blocks_y * 4;

			m_frontend_output_textures[i].init(texture_format::cETC1, width, height);

			for (uint32_t block_y = 0; block_y < num_blocks_y; block_y++)
				for (uint32_t block_x = 0; block_x < num_blocks_x; block_x++)
					memcpy(m_frontend_output_textures[i].get_block_ptr(block_x, block_y, 0), &m_frontend.get_output_block(slice_desc.m_first_block_index + block_x + block_y * num_blocks_x), sizeof(etc_block));

#if 0
			if (m_params.m_debug_images)
			{
				char filename[1024];
				sprintf_s(filename, sizeof(filename), "rdo_etc_frontend_%u_", i);
				write_etc1_vis_images(m_frontend_output_textures[i], filename);
			}
#endif

			m_best_etc1s_images[i].init(texture_format::cETC1, width, height);
			for (uint32_t block_y = 0; block_y < num_blocks_y; block_y++)
				for (uint32_t block_x = 0; block_x < num_blocks_x; block_x++)
					memcpy(m_best_etc1s_images[i].get_block_ptr(block_x, block_y, 0), &m_frontend.get_etc1s_block(slice_desc.m_first_block_index + block_x + block_y * num_blocks_x), sizeof(etc_block));

			m_best_etc1s_images[i].unpack(m_best_etc1s_images_unpacked[i]);
		}

		return true;
	}

	bool basis_compressor::process_backend()
	{
		debug_printf("basis_compressor::process_backend\n");

		basisu_backend_params backend_params;
		backend_params.m_debug = m_params.m_debug;
		backend_params.m_debug_images = m_params.m_debug_images;
		backend_params.m_etc1s = true;
		backend_params.m_compression_level = m_params.m_compression_level;
		
		if (!m_params.m_no_endpoint_rdo)
			backend_params.m_endpoint_rdo_quality_thresh = m_params.m_endpoint_rdo_thresh;

		if (!m_params.m_no_selector_rdo)
			backend_params.m_selector_rdo_quality_thresh = m_params.m_selector_rdo_thresh;
				
		backend_params.m_used_global_codebooks = m_frontend.get_params().m_pGlobal_codebooks != nullptr;
		backend_params.m_validate = m_params.m_validate_output_data;

		m_backend.init(&m_frontend, backend_params, m_slice_descs);
		uint32_t total_packed_bytes = m_backend.encode();

		if (!total_packed_bytes)
		{
			error_printf("basis_compressor::encode() failed!\n");
			return false;
		}

		debug_printf("Total packed bytes (estimated): %u\n", total_packed_bytes);

		return true;
	}

	bool basis_compressor::create_basis_file_and_transcode()
	{
		debug_printf("basis_compressor::create_basis_file_and_transcode\n");

		const basisu_backend_output& encoded_output = m_params.m_uastc ? m_uastc_backend_output : m_backend.get_output();

		if (!m_basis_file.init(encoded_output, m_params.m_tex_type, m_params.m_userdata0, m_params.m_userdata1, m_params.m_y_flip, m_params.m_us_per_frame))
		{
			error_printf("basis_compressor::create_basis_file_and_transcode: basisu_backend:init() failed!\n");
			return false;
		}
	
		const uint8_vec &comp_data = m_basis_file.get_compressed_data();

		m_output_basis_file = comp_data;

		uint32_t total_orig_pixels = 0, total_texels = 0, total_orig_texels = 0;
		(void)total_texels;

		for (uint32_t i = 0; i < m_slice_descs.size(); i++)
		{
			const basisu_backend_slice_desc& slice_desc = m_slice_descs[i];

			total_orig_pixels += slice_desc.m_orig_width * slice_desc.m_orig_height;
			total_texels += slice_desc.m_width * slice_desc.m_height;
		}

		m_basis_file_size = (uint32_t)comp_data.size();
		m_basis_bits_per_texel = total_orig_texels ? (comp_data.size() * 8.0f) / total_orig_texels : 0;

		debug_printf("Total .basis output file size: %u, %3.3f bits/texel\n", comp_data.size(), comp_data.size() * 8.0f / total_orig_pixels);

		if (m_params.m_validate_output_data)
		{
			interval_timer tm;
			tm.start();

			basist::basisu_transcoder_init();

			debug_printf("basist::basisu_transcoder_init: Took %f ms\n", tm.get_elapsed_ms());

			// Verify the compressed data by transcoding it to ASTC (or ETC1)/BC7 and validating the CRC's.
			basist::basisu_transcoder decoder;
			if (!decoder.validate_file_checksums(&comp_data[0], (uint32_t)comp_data.size(), true))
			{
				error_printf("decoder.validate_file_checksums() failed!\n");
				return false;
			}

			m_decoded_output_textures.resize(m_slice_descs.size());

			if (m_params.m_hdr)
			{
				m_decoded_output_textures_bc6h_hdr_unpacked.resize(m_slice_descs.size());

				m_decoded_output_textures_astc_hdr.resize(m_slice_descs.size());
				m_decoded_output_textures_astc_hdr_unpacked.resize(m_slice_descs.size());
			}
			else
			{
				m_decoded_output_textures_unpacked.resize(m_slice_descs.size());

				m_decoded_output_textures_bc7.resize(m_slice_descs.size());
				m_decoded_output_textures_unpacked_bc7.resize(m_slice_descs.size());
			}

			tm.start();
			if (m_params.m_pGlobal_codebooks)
			{
				decoder.set_global_codebooks(m_params.m_pGlobal_codebooks);
			}

			if (!decoder.start_transcoding(&comp_data[0], (uint32_t)comp_data.size()))
			{
				error_printf("decoder.start_transcoding() failed!\n");
				return false;
			}

			double start_transcoding_time = tm.get_elapsed_secs();

			debug_printf("basisu_compressor::start_transcoding() took %3.3fms\n", start_transcoding_time * 1000.0f);

			double total_time_etc1s_or_astc = 0;

			for (uint32_t i = 0; i < m_slice_descs.size(); i++)
			{
				basisu::texture_format tex_format = m_params.m_hdr ? texture_format::cBC6HUnsigned : (m_params.m_uastc ? texture_format::cUASTC4x4 : texture_format::cETC1);
				basist::block_format format = m_params.m_hdr ? basist::block_format::cBC6H : (m_params.m_uastc ? basist::block_format::cUASTC_4x4 : basist::block_format::cETC1);

				gpu_image decoded_texture;
				decoded_texture.init(
					tex_format, 
					m_slice_descs[i].m_width, m_slice_descs[i].m_height);

				tm.start();
								
				uint32_t bytes_per_block = m_params.m_uastc ? 16 : 8;

				if (!decoder.transcode_slice(&comp_data[0], (uint32_t)comp_data.size(), i,
					reinterpret_cast<etc_block*>(decoded_texture.get_ptr()), m_slice_descs[i].m_num_blocks_x * m_slice_descs[i].m_num_blocks_y, format, bytes_per_block))
				{
					error_printf("Transcoding failed on slice %u!\n", i);
					return false;
				}

				total_time_etc1s_or_astc += tm.get_elapsed_secs();

				if (encoded_output.m_tex_format == basist::basis_tex_format::cETC1S)
				{
					uint32_t image_crc16 = basist::crc16(decoded_texture.get_ptr(), decoded_texture.get_size_in_bytes(), 0);
					if (image_crc16 != encoded_output.m_slice_image_crcs[i])
					{
						error_printf("Decoded image data CRC check failed on slice %u!\n", i);
						return false;
					}
					debug_printf("Decoded image data CRC check succeeded on slice %i\n", i);
				}

				m_decoded_output_textures[i] = decoded_texture;
			}

			double total_alt_transcode_time = 0;
			tm.start();

			if (m_params.m_hdr)
			{
				assert(basist::basis_is_format_supported(basist::transcoder_texture_format::cTFASTC_HDR_4x4_RGBA, basist::basis_tex_format::cUASTC_HDR_4x4));

				for (uint32_t i = 0; i < m_slice_descs.size(); i++)
				{
					gpu_image decoded_texture;
					decoded_texture.init(texture_format::cASTC_HDR_4x4, m_slice_descs[i].m_width, m_slice_descs[i].m_height);

					tm.start();

					if (!decoder.transcode_slice(&comp_data[0], (uint32_t)comp_data.size(), i,
						reinterpret_cast<basist::astc_blk*>(decoded_texture.get_ptr()), m_slice_descs[i].m_num_blocks_x * m_slice_descs[i].m_num_blocks_y, basist::block_format::cASTC_HDR_4x4, 16))
					{
						error_printf("Transcoding failed to ASTC HDR on slice %u!\n", i);
						return false;
					}
										
					m_decoded_output_textures_astc_hdr[i] = decoded_texture;
				}
			}
			else
			{
				if (basist::basis_is_format_supported(basist::transcoder_texture_format::cTFBC7_RGBA, basist::basis_tex_format::cUASTC4x4) &&
					basist::basis_is_format_supported(basist::transcoder_texture_format::cTFBC7_RGBA, basist::basis_tex_format::cETC1S))
				{
					for (uint32_t i = 0; i < m_slice_descs.size(); i++)
					{
						gpu_image decoded_texture;
						decoded_texture.init(texture_format::cBC7, m_slice_descs[i].m_width, m_slice_descs[i].m_height);
												
						if (!decoder.transcode_slice(&comp_data[0], (uint32_t)comp_data.size(), i,
							reinterpret_cast<etc_block*>(decoded_texture.get_ptr()), m_slice_descs[i].m_num_blocks_x * m_slice_descs[i].m_num_blocks_y, basist::block_format::cBC7, 16))
						{
							error_printf("Transcoding failed to BC7 on slice %u!\n", i);
							return false;
						}
												
						m_decoded_output_textures_bc7[i] = decoded_texture;
					}
				}
			}

			total_alt_transcode_time = tm.get_elapsed_secs();

			for (uint32_t i = 0; i < m_slice_descs.size(); i++)
			{
				if (m_params.m_hdr)
				{
					// BC6H
					bool status = m_decoded_output_textures[i].unpack_hdr(m_decoded_output_textures_bc6h_hdr_unpacked[i]);
					assert(status);
					BASISU_NOTE_UNUSED(status);
					
					// ASTC HDR
					status = m_decoded_output_textures_astc_hdr[i].unpack_hdr(m_decoded_output_textures_astc_hdr_unpacked[i]);
					assert(status);
				}
				else
				{
					bool status = m_decoded_output_textures[i].unpack(m_decoded_output_textures_unpacked[i]);
					assert(status);
					BASISU_NOTE_UNUSED(status);

					if (m_decoded_output_textures_bc7[i].get_pixel_width())
					{
						status = m_decoded_output_textures_bc7[i].unpack(m_decoded_output_textures_unpacked_bc7[i]);
						assert(status);
					}
				}
			}

			debug_printf("Transcoded to %s in %3.3fms, %f texels/sec\n", 
				m_params.m_hdr ? "BC6H" : (m_params.m_uastc ? "ASTC" : "ETC1"),
				total_time_etc1s_or_astc * 1000.0f, total_orig_pixels / total_time_etc1s_or_astc);

			if (total_alt_transcode_time != 0)
				debug_printf("Alternate transcode in %3.3fms, %f texels/sec\n", total_alt_transcode_time * 1000.0f, total_orig_pixels / total_alt_transcode_time);

			for (uint32_t slice_index = 0; slice_index < m_slice_descs.size(); slice_index++)
			{
				const basisu_backend_slice_desc& slice_desc = m_slice_descs[slice_index];

				const uint32_t total_blocks = slice_desc.m_num_blocks_x * slice_desc.m_num_blocks_y;
				BASISU_NOTE_UNUSED(total_blocks);

				assert(m_decoded_output_textures[slice_index].get_total_blocks() == total_blocks);
			}

		} // if (m_params.m_validate_output_data)
				
		return true;
	}

	bool basis_compressor::write_hdr_debug_images(const char* pBasename, const imagef& orig_hdr_img, uint32_t width, uint32_t height)
	{
		// Copy image to account for 4x4 block expansion
		imagef hdr_img(orig_hdr_img);
		hdr_img.resize(width, height);

		image srgb_img(width, height);

		for (uint32_t y = 0; y < height; y++)
		{
			for (uint32_t x = 0; x < width; x++)
			{
				vec4F p(hdr_img(x, y));

				p[0] = clamp(p[0], 0.0f, 1.0f);
				p[1] = clamp(p[1], 0.0f, 1.0f);
				p[2] = clamp(p[2], 0.0f, 1.0f);

				int rc = (int)std::round(linear_to_srgb(p[0]) * 255.0f);
				int gc = (int)std::round(linear_to_srgb(p[1]) * 255.0f);
				int bc = (int)std::round(linear_to_srgb(p[2]) * 255.0f);

				srgb_img.set_clipped(x, y, color_rgba(rc, gc, bc, 255));
			}
		}

		{
			const std::string filename(string_format("%s_linear_clamped_to_srgb.png", pBasename));
			save_png(filename.c_str(), srgb_img);
			printf("Wrote .PNG file %s\n", filename.c_str());
		}

		{
			const std::string filename(string_format("%s_compressive_tonemapped.png", pBasename));
			image compressive_tonemapped_img;
			
			bool status = tonemap_image_compressive(compressive_tonemapped_img, hdr_img);
			if (!status)
			{
				error_printf("basis_compressor::write_hdr_debug_images: tonemap_image_compressive() failed (invalid half-float input)\n");
			}
			else
			{
				save_png(filename.c_str(), compressive_tonemapped_img);
				printf("Wrote .PNG file %s\n", filename.c_str());
			}
		}

		image tonemapped_img;

		for (int e = -5; e <= 5; e++)
		{
			const float scale = powf(2.0f, (float)e);

			tonemap_image_reinhard(tonemapped_img, hdr_img, scale);

			std::string filename(string_format("%s_reinhard_tonemapped_scale_%f.png", pBasename, scale));
			save_png(filename.c_str(), tonemapped_img, cImageSaveIgnoreAlpha);
			printf("Wrote .PNG file %s\n", filename.c_str());
		}

		return true;
	}

	bool basis_compressor::write_output_files_and_compute_stats()
	{
		debug_printf("basis_compressor::write_output_files_and_compute_stats\n");

		const uint8_vec& comp_data = m_params.m_create_ktx2_file ? m_output_ktx2_file : m_basis_file.get_compressed_data();
		if (m_params.m_write_output_basis_or_ktx2_files)
		{
			const std::string& output_filename = m_params.m_out_filename;

			if (!write_vec_to_file(output_filename.c_str(), comp_data))
			{
				error_printf("Failed writing output data to file \"%s\"\n", output_filename.c_str());
				return false;
			}

			//if (m_params.m_status_output)
			{
				printf("Wrote output .basis/.ktx2 file \"%s\"\n", output_filename.c_str());
			}
		}

		size_t comp_size = 0;
		if ((m_params.m_compute_stats) && (m_params.m_uastc) && (comp_data.size()))
		{
			void* pComp_data = tdefl_compress_mem_to_heap(&comp_data[0], comp_data.size(), &comp_size, TDEFL_MAX_PROBES_MASK);// TDEFL_DEFAULT_MAX_PROBES);
			size_t decomp_size = 0;
			void* pDecomp_data = tinfl_decompress_mem_to_heap(pComp_data, comp_size, &decomp_size, 0);
			if ((decomp_size != comp_data.size()) || (memcmp(pDecomp_data, &comp_data[0], decomp_size) != 0))
			{
				printf("basis_compressor::create_basis_file_and_transcode:: miniz compression or decompression failed!\n");
				return false;
			}

			mz_free(pComp_data);
			mz_free(pDecomp_data);

			uint32_t total_texels = 0;
			for (uint32_t i = 0; i < m_slice_descs.size(); i++)
				total_texels += (m_slice_descs[i].m_num_blocks_x * m_slice_descs[i].m_num_blocks_y) * 16;
			
			m_basis_bits_per_texel = comp_size * 8.0f / total_texels;

			debug_printf("Output file size: %u, LZ compressed file size: %u, %3.2f bits/texel\n",
				(uint32_t)comp_data.size(),
				(uint32_t)comp_size,
				m_basis_bits_per_texel);
		}

		m_stats.resize(m_slice_descs.size());
		
		if (m_params.m_validate_output_data)
		{
			if (m_params.m_hdr)
			{
				if (m_params.m_print_stats)
				{
					printf("ASTC/BC6H half float space error metrics (a piecewise linear approximation of log2 error):\n");
				}

				for (uint32_t slice_index = 0; slice_index < m_slice_descs.size(); slice_index++)
				{
					const basisu_backend_slice_desc& slice_desc = m_slice_descs[slice_index];

					if (m_params.m_compute_stats)
					{
						image_stats& s = m_stats[slice_index];

						if (m_params.m_print_stats)
						{
							printf("Slice: %u\n", slice_index);
						}

						image_metrics im;

						if (m_params.m_print_stats)
						{
							printf("\nASTC channels:\n");
							for (uint32_t i = 0; i < 3; i++)
							{
								im.calc_half(m_slice_images_hdr[slice_index], m_decoded_output_textures_astc_hdr_unpacked[slice_index], i, 1, true);

								printf("%c:   ", "RGB"[i]);
								im.print_hp();
							}

							printf("BC6H channels:\n");
							for (uint32_t i = 0; i < 3; i++)
							{
								im.calc_half(m_slice_images_hdr[slice_index], m_decoded_output_textures_bc6h_hdr_unpacked[slice_index], i, 1, true);

								printf("%c:   ", "RGB"[i]);
								im.print_hp();
							}
						}

						im.calc_half(m_slice_images_hdr[slice_index], m_decoded_output_textures_astc_hdr_unpacked[slice_index], 0, 3, true);
						s.m_basis_rgb_avg_psnr = (float)im.m_psnr;

						if (m_params.m_print_stats)
						{
							printf("\nASTC RGB: ");
							im.print_hp();
#if 0
							// Validation
							im.calc_half2(m_slice_images_hdr[slice_index], m_decoded_output_textures_astc_hdr_unpacked[slice_index], 0, 3, true);
							printf("\nASTC RGB (Alt): ");
							im.print_hp();
#endif
						}

						im.calc_half(m_slice_images_hdr[slice_index], m_decoded_output_textures_bc6h_hdr_unpacked[slice_index], 0, 3, true);
						s.m_basis_rgb_avg_bc6h_psnr = (float)im.m_psnr;

						if (m_params.m_print_stats)
						{
							printf("BC6H RGB: ");
							im.print_hp();
							printf("\n");
						}
					}
					
					if (m_params.m_debug_images)
					{
						std::string out_basename;
						if (m_params.m_out_filename.size())
							string_get_filename(m_params.m_out_filename.c_str(), out_basename);
						else if (m_params.m_source_filenames.size())
							string_get_filename(m_params.m_source_filenames[slice_desc.m_source_file_index].c_str(), out_basename);

						string_remove_extension(out_basename);
						out_basename = "basis_debug_" + out_basename + string_format("_slice_%u", slice_index);

						// Write BC6H .DDS file.
						{
							gpu_image bc6h_tex(m_decoded_output_textures[slice_index]);
							bc6h_tex.override_dimensions(slice_desc.m_orig_width, slice_desc.m_orig_height);
							
							std::string filename(out_basename + "_bc6h.dds");
							write_compressed_texture_file(filename.c_str(), bc6h_tex, true);
							printf("Wrote .DDS file %s\n", filename.c_str());
						}

						// Write ASTC .KTX/.astc files. ("astcenc -dh input.astc output.exr" to decode the astc file.)
						{
							gpu_image astc_tex(m_decoded_output_textures_astc_hdr[slice_index]);
							astc_tex.override_dimensions(slice_desc.m_orig_width, slice_desc.m_orig_height);
							
							std::string filename1(out_basename + "_astc.astc");
							write_astc_file(filename1.c_str(), astc_tex.get_ptr(), 4, 4, slice_desc.m_orig_width, slice_desc.m_orig_height);
							printf("Wrote .ASTC file %s\n", filename1.c_str());

							std::string filename2(out_basename + "_astc.ktx");
							write_compressed_texture_file(filename2.c_str(), astc_tex, true);
							printf("Wrote .KTX file %s\n", filename2.c_str());
						}

						// Write unpacked ASTC image to .EXR
						{
							imagef astc_img(m_decoded_output_textures_astc_hdr_unpacked[slice_index]);
							astc_img.resize(slice_desc.m_orig_width, slice_desc.m_orig_height);
							
							std::string filename(out_basename + "_unpacked_astc.exr");
							write_exr(filename.c_str(), astc_img, 3, 0);
							printf("Wrote .EXR file %s\n", filename.c_str());
						}

						// Write unpacked BC6H image to .EXR
						{
							imagef bc6h_img(m_decoded_output_textures_bc6h_hdr_unpacked[slice_index]);
							bc6h_img.resize(slice_desc.m_orig_width, slice_desc.m_orig_height);

							std::string filename(out_basename + "_unpacked_bc6h.exr");
							write_exr(filename.c_str(), bc6h_img, 3, 0);
							printf("Wrote .EXR file %s\n", filename.c_str());
						}

						// Write tonemapped/srgb images
						write_hdr_debug_images((out_basename + "_source").c_str(), m_slice_images_hdr[slice_index], slice_desc.m_orig_width, slice_desc.m_orig_height);
						write_hdr_debug_images((out_basename + "_unpacked_astc").c_str(), m_decoded_output_textures_astc_hdr_unpacked[slice_index], slice_desc.m_orig_width, slice_desc.m_orig_height);
						write_hdr_debug_images((out_basename + "_unpacked_bc6h").c_str(), m_decoded_output_textures_bc6h_hdr_unpacked[slice_index], slice_desc.m_orig_width, slice_desc.m_orig_height);
					}
				}
			}
			else
			{
				for (uint32_t slice_index = 0; slice_index < m_slice_descs.size(); slice_index++)
				{
					const basisu_backend_slice_desc& slice_desc = m_slice_descs[slice_index];

					if (m_params.m_compute_stats)
					{
						if (m_params.m_print_stats)
							printf("Slice: %u\n", slice_index);

						image_stats& s = m_stats[slice_index];
												
						image_metrics em;

						// ---- .basis stats
						em.calc(m_slice_images[slice_index], m_decoded_output_textures_unpacked[slice_index], 0, 3);
						if (m_params.m_print_stats)
							em.print(".basis RGB Avg:          ");
						s.m_basis_rgb_avg_psnr = (float)em.m_psnr;

						em.calc(m_slice_images[slice_index], m_decoded_output_textures_unpacked[slice_index], 0, 4);
						if (m_params.m_print_stats)
							em.print(".basis RGBA Avg:         ");
						s.m_basis_rgba_avg_psnr = (float)em.m_psnr;

						em.calc(m_slice_images[slice_index], m_decoded_output_textures_unpacked[slice_index], 0, 1);
						if (m_params.m_print_stats)
							em.print(".basis R   Avg:          ");

						em.calc(m_slice_images[slice_index], m_decoded_output_textures_unpacked[slice_index], 1, 1);
						if (m_params.m_print_stats)
							em.print(".basis G   Avg:          ");

						em.calc(m_slice_images[slice_index], m_decoded_output_textures_unpacked[slice_index], 2, 1);
						if (m_params.m_print_stats)
							em.print(".basis B   Avg:          ");

						if (m_params.m_uastc)
						{
							em.calc(m_slice_images[slice_index], m_decoded_output_textures_unpacked[slice_index], 3, 1);
							if (m_params.m_print_stats)
								em.print(".basis A   Avg:          ");

							s.m_basis_a_avg_psnr = (float)em.m_psnr;
						}

						em.calc(m_slice_images[slice_index], m_decoded_output_textures_unpacked[slice_index], 0, 0);
						if (m_params.m_print_stats)
							em.print(".basis 709 Luma:         ");
						s.m_basis_luma_709_psnr = static_cast<float>(em.m_psnr);
						s.m_basis_luma_709_ssim = static_cast<float>(em.m_ssim);

						em.calc(m_slice_images[slice_index], m_decoded_output_textures_unpacked[slice_index], 0, 0, true, true);
						if (m_params.m_print_stats)
							em.print(".basis 601 Luma:         ");
						s.m_basis_luma_601_psnr = static_cast<float>(em.m_psnr);

						if (m_slice_descs.size() == 1)
						{
							const uint32_t output_size = comp_size ? (uint32_t)comp_size : (uint32_t)comp_data.size();
							if (m_params.m_print_stats)
							{
								debug_printf(".basis RGB PSNR per bit/texel*10000: %3.3f\n", 10000.0f * s.m_basis_rgb_avg_psnr / ((output_size * 8.0f) / (slice_desc.m_orig_width * slice_desc.m_orig_height)));
								debug_printf(".basis Luma 709 PSNR per bit/texel*10000: %3.3f\n", 10000.0f * s.m_basis_luma_709_psnr / ((output_size * 8.0f) / (slice_desc.m_orig_width * slice_desc.m_orig_height)));
							}
						}

						if (m_decoded_output_textures_unpacked_bc7[slice_index].get_width())
						{
							// ---- BC7 stats
							em.calc(m_slice_images[slice_index], m_decoded_output_textures_unpacked_bc7[slice_index], 0, 3);
							//if (m_params.m_print_stats)
							//	em.print("BC7 RGB Avg:             ");
							s.m_bc7_rgb_avg_psnr = (float)em.m_psnr;

							em.calc(m_slice_images[slice_index], m_decoded_output_textures_unpacked_bc7[slice_index], 0, 4);
							//if (m_params.m_print_stats)
							//	em.print("BC7 RGBA Avg:            ");
							s.m_bc7_rgba_avg_psnr = (float)em.m_psnr;

							em.calc(m_slice_images[slice_index], m_decoded_output_textures_unpacked_bc7[slice_index], 0, 1);
							//if (m_params.m_print_stats)
							//	em.print("BC7 R   Avg:             ");

							em.calc(m_slice_images[slice_index], m_decoded_output_textures_unpacked_bc7[slice_index], 1, 1);
							//if (m_params.m_print_stats)
							//	em.print("BC7 G   Avg:             ");

							em.calc(m_slice_images[slice_index], m_decoded_output_textures_unpacked_bc7[slice_index], 2, 1);
							//if (m_params.m_print_stats)
							//	em.print("BC7 B   Avg:             ");

							if (m_params.m_uastc)
							{
								em.calc(m_slice_images[slice_index], m_decoded_output_textures_unpacked_bc7[slice_index], 3, 1);
								//if (m_params.m_print_stats)
								//	em.print("BC7 A   Avg:             ");

								s.m_bc7_a_avg_psnr = (float)em.m_psnr;
							}

							em.calc(m_slice_images[slice_index], m_decoded_output_textures_unpacked_bc7[slice_index], 0, 0);
							//if (m_params.m_print_stats)
							//	em.print("BC7 709 Luma:            ");
							s.m_bc7_luma_709_psnr = static_cast<float>(em.m_psnr);
							s.m_bc7_luma_709_ssim = static_cast<float>(em.m_ssim);

							em.calc(m_slice_images[slice_index], m_decoded_output_textures_unpacked_bc7[slice_index], 0, 0, true, true);
							//if (m_params.m_print_stats)
							//	em.print("BC7 601 Luma:            ");
							s.m_bc7_luma_601_psnr = static_cast<float>(em.m_psnr);
						}

						if (!m_params.m_uastc)
						{
							// ---- Nearly best possible ETC1S stats
							em.calc(m_slice_images[slice_index], m_best_etc1s_images_unpacked[slice_index], 0, 3);
							//if (m_params.m_print_stats)
							//	em.print("Unquantized ETC1S RGB Avg:     ");
							s.m_best_etc1s_rgb_avg_psnr = static_cast<float>(em.m_psnr);

							em.calc(m_slice_images[slice_index], m_best_etc1s_images_unpacked[slice_index], 0, 0);
							//if (m_params.m_print_stats)
							//	em.print("Unquantized ETC1S 709 Luma:    ");
							s.m_best_etc1s_luma_709_psnr = static_cast<float>(em.m_psnr);
							s.m_best_etc1s_luma_709_ssim = static_cast<float>(em.m_ssim);

							em.calc(m_slice_images[slice_index], m_best_etc1s_images_unpacked[slice_index], 0, 0, true, true);
							//if (m_params.m_print_stats)
							//	em.print("Unquantized ETC1S 601 Luma:    ");
							s.m_best_etc1s_luma_601_psnr = static_cast<float>(em.m_psnr);
						}
					}

					std::string out_basename;
					if (m_params.m_out_filename.size())
						string_get_filename(m_params.m_out_filename.c_str(), out_basename);
					else if (m_params.m_source_filenames.size())
						string_get_filename(m_params.m_source_filenames[slice_desc.m_source_file_index].c_str(), out_basename);

					string_remove_extension(out_basename);
					out_basename = "basis_debug_" + out_basename + string_format("_slice_%u", slice_index);

					if ((!m_params.m_uastc) && (m_frontend.get_params().m_debug_images))
					{
						// Write "best" ETC1S debug images
						if (!m_params.m_uastc)
						{
							gpu_image best_etc1s_gpu_image(m_best_etc1s_images[slice_index]);
							best_etc1s_gpu_image.override_dimensions(slice_desc.m_orig_width, slice_desc.m_orig_height);
							write_compressed_texture_file((out_basename + "_best_etc1s.ktx").c_str(), best_etc1s_gpu_image, true);

							image best_etc1s_unpacked;
							best_etc1s_gpu_image.unpack(best_etc1s_unpacked);
							save_png(out_basename + "_best_etc1s.png", best_etc1s_unpacked);
						}
					}

					if (m_params.m_debug_images)
					{
						// Write decoded ETC1S/ASTC debug images
						{
							gpu_image decoded_etc1s_or_astc(m_decoded_output_textures[slice_index]);
							decoded_etc1s_or_astc.override_dimensions(slice_desc.m_orig_width, slice_desc.m_orig_height);
							write_compressed_texture_file((out_basename + "_transcoded_etc1s_or_astc.ktx").c_str(), decoded_etc1s_or_astc, true);

							image temp(m_decoded_output_textures_unpacked[slice_index]);
							temp.crop(slice_desc.m_orig_width, slice_desc.m_orig_height);
							save_png(out_basename + "_transcoded_etc1s_or_astc.png", temp);
						}

						// Write decoded BC7 debug images
						if (m_decoded_output_textures_bc7[slice_index].get_pixel_width())
						{
							gpu_image decoded_bc7(m_decoded_output_textures_bc7[slice_index]);
							decoded_bc7.override_dimensions(slice_desc.m_orig_width, slice_desc.m_orig_height);
							write_compressed_texture_file((out_basename + "_transcoded_bc7.ktx").c_str(), decoded_bc7, true);

							image temp(m_decoded_output_textures_unpacked_bc7[slice_index]);
							temp.crop(slice_desc.m_orig_width, slice_desc.m_orig_height);
							save_png(out_basename + "_transcoded_bc7.png", temp);
						}
					}
				}
			} // if (m_params.m_hdr)

		} // if (m_params.m_validate_output_data)
				
		return true;
	}
	
	// Make sure all the mip 0's have the same dimensions and number of mipmap levels, or we can't encode the KTX2 file.
	bool basis_compressor::validate_ktx2_constraints()
	{
		uint32_t base_width = 0, base_height = 0;
		uint32_t total_layers = 0;
		for (uint32_t i = 0; i < m_slice_descs.size(); i++)
		{
			if (m_slice_descs[i].m_mip_index == 0)
			{
				if (!base_width)
				{
					base_width = m_slice_descs[i].m_orig_width;
					base_height = m_slice_descs[i].m_orig_height;
				}
				else
				{
					if ((m_slice_descs[i].m_orig_width != base_width) || (m_slice_descs[i].m_orig_height != base_height))
					{
						return false;
					}
				}

				total_layers = maximum<uint32_t>(total_layers, m_slice_descs[i].m_source_file_index + 1);
			}
		}

		basisu::vector<uint32_t> total_mips(total_layers);
		for (uint32_t i = 0; i < m_slice_descs.size(); i++)
			total_mips[m_slice_descs[i].m_source_file_index] = maximum<uint32_t>(total_mips[m_slice_descs[i].m_source_file_index], m_slice_descs[i].m_mip_index + 1);

		for (uint32_t i = 1; i < total_layers; i++)
		{
			if (total_mips[0] != total_mips[i])
			{
				return false;
			}
		}

		return true;
	}

	static uint8_t g_ktx2_etc1s_nonalpha_dfd[44] = { 0x2C,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x2,0x0,0x28,0x0,0xA3,0x1,0x2,0x0,0x3,0x3,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3F,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xFF,0xFF,0xFF,0xFF };
	static uint8_t g_ktx2_etc1s_alpha_dfd[60]    = { 0x3C,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x2,0x0,0x38,0x0,0xA3,0x1,0x2,0x0,0x3,0x3,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3F,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xFF,0xFF,0xFF,0xFF,0x40,0x0,0x3F,0xF,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xFF,0xFF,0xFF,0xFF };
	
	static uint8_t g_ktx2_uastc_nonalpha_dfd[44] = { 0x2C,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x2,0x0,0x28,0x0,0xA6,0x1,0x2,0x0,0x3,0x3,0x0,0x0,0x10,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x7F,0x4,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xFF,0xFF,0xFF,0xFF };
	static uint8_t g_ktx2_uastc_alpha_dfd[44]    = { 0x2C,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x2,0x0,0x28,0x0,0xA6,0x1,0x2,0x0,0x3,0x3,0x0,0x0,0x10,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x7F,0x3,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xFF,0xFF,0xFF,0xFF };

	// HDR TODO - what is the best Khronos DFD to use for UASTC HDR?
	static uint8_t g_ktx2_uastc_hdr_nonalpha_dfd[44] = 
	{
		0x2C,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,
		0x2,0x0,0x28,0x0, 0xA7,0x1,0x1,0x0,
		0x3,0x3,0x0,0x0, 0x10,0x0,0x0,0x0,
		0x0,0x0,0x0,0x0, 0x0,0x0,0x7F,0x4,
		0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,
		0xFF,0xFF,0xFF,0xFF 
	};
			
	void basis_compressor::get_dfd(uint8_vec &dfd, const basist::ktx2_header &header)
	{
		const uint8_t* pDFD;
		uint32_t dfd_len;

		if (m_params.m_uastc)
		{
			if (m_params.m_hdr)
			{
				pDFD = g_ktx2_uastc_hdr_nonalpha_dfd;
				dfd_len = sizeof(g_ktx2_uastc_hdr_nonalpha_dfd);
			}
			else if (m_any_source_image_has_alpha)
			{
				pDFD = g_ktx2_uastc_alpha_dfd;
				dfd_len = sizeof(g_ktx2_uastc_alpha_dfd);
			}
			else
			{
				pDFD = g_ktx2_uastc_nonalpha_dfd;
				dfd_len = sizeof(g_ktx2_uastc_nonalpha_dfd);
			}
		}
		else
		{
			if (m_any_source_image_has_alpha)
			{
				pDFD = g_ktx2_etc1s_alpha_dfd;
				dfd_len = sizeof(g_ktx2_etc1s_alpha_dfd);
			}
			else
			{
				pDFD = g_ktx2_etc1s_nonalpha_dfd;
				dfd_len = sizeof(g_ktx2_etc1s_nonalpha_dfd);
			}
		}
				
		assert(dfd_len >= 44);

		dfd.resize(dfd_len);
		memcpy(dfd.data(), pDFD, dfd_len);

		uint32_t dfd_bits = basisu::read_le_dword(dfd.data() + 3 * sizeof(uint32_t));
		
		dfd_bits &= ~(0xFF << 16);

		if (m_params.m_hdr)
		{
			// TODO: In HDR mode, always write linear for now.
			dfd_bits |= (basist::KTX2_KHR_DF_TRANSFER_LINEAR << 16);
		}
		else
		{
			if (m_params.m_ktx2_srgb_transfer_func)
				dfd_bits |= (basist::KTX2_KHR_DF_TRANSFER_SRGB << 16);
			else
				dfd_bits |= (basist::KTX2_KHR_DF_TRANSFER_LINEAR << 16);
		}

		basisu::write_le_dword(dfd.data() + 3 * sizeof(uint32_t), dfd_bits);

		if (header.m_supercompression_scheme != basist::KTX2_SS_NONE)
		{
			uint32_t plane_bits = basisu::read_le_dword(dfd.data() + 5 * sizeof(uint32_t));

			plane_bits &= ~0xFF;

			basisu::write_le_dword(dfd.data() + 5 * sizeof(uint32_t), plane_bits);
		}

		// Fix up the DFD channel(s)
		uint32_t dfd_chan0 = basisu::read_le_dword(dfd.data() + 7 * sizeof(uint32_t));

		if (m_params.m_uastc)
		{
			dfd_chan0 &= ~(0xF << 24);
			
			// TODO: Allow the caller to override this
			if (m_any_source_image_has_alpha)
				dfd_chan0 |= (basist::KTX2_DF_CHANNEL_UASTC_RGBA << 24);
			else
				dfd_chan0 |= (basist::KTX2_DF_CHANNEL_UASTC_RGB << 24);
		}

		basisu::write_le_dword(dfd.data() + 7 * sizeof(uint32_t), dfd_chan0);
	}

	bool basis_compressor::create_ktx2_file()
	{
		if (m_params.m_uastc)
		{
			if ((m_params.m_ktx2_uastc_supercompression != basist::KTX2_SS_NONE) && (m_params.m_ktx2_uastc_supercompression != basist::KTX2_SS_ZSTANDARD))
				return false;
		}

		const basisu_backend_output& backend_output = m_backend.get_output();

		// Determine the width/height, number of array layers, mipmap levels, and the number of faces (1 for 2D, 6 for cubemap).
		// This does not support 1D or 3D.
		uint32_t base_width = 0, base_height = 0, total_layers = 0, total_levels = 0, total_faces = 1;
				
		for (uint32_t i = 0; i < m_slice_descs.size(); i++)
		{
			if ((m_slice_descs[i].m_mip_index == 0) && (!base_width))
			{
				base_width = m_slice_descs[i].m_orig_width;
				base_height = m_slice_descs[i].m_orig_height;
			}

			total_layers = maximum<uint32_t>(total_layers, m_slice_descs[i].m_source_file_index + 1);

			if (!m_slice_descs[i].m_source_file_index)
				total_levels = maximum<uint32_t>(total_levels, m_slice_descs[i].m_mip_index + 1);
		}

		if (m_params.m_tex_type == basist::cBASISTexTypeCubemapArray)
		{
			assert((total_layers % 6) == 0);
			
			total_layers /= 6;
			assert(total_layers >= 1);

			total_faces = 6;
		}

		basist::ktx2_header header;
		memset(&header, 0, sizeof(header));

		memcpy(header.m_identifier, basist::g_ktx2_file_identifier, sizeof(basist::g_ktx2_file_identifier));
		header.m_pixel_width = base_width;
		header.m_pixel_height = base_height;
		header.m_face_count = total_faces;
		
		if (m_params.m_hdr)
			header.m_vk_format = basist::KTX2_FORMAT_UASTC_4x4_SFLOAT_BLOCK;
		else
			header.m_vk_format = basist::KTX2_VK_FORMAT_UNDEFINED;

		header.m_type_size = 1;
		header.m_level_count = total_levels;
		header.m_layer_count = (total_layers > 1) ? total_layers : 0;

		if (m_params.m_uastc)
		{
			switch (m_params.m_ktx2_uastc_supercompression)
			{
			case basist::KTX2_SS_NONE:
			{
				header.m_supercompression_scheme = basist::KTX2_SS_NONE;
				break;
			}
			case basist::KTX2_SS_ZSTANDARD:
			{
#if BASISD_SUPPORT_KTX2_ZSTD
				header.m_supercompression_scheme = basist::KTX2_SS_ZSTANDARD;
#else
				header.m_supercompression_scheme = basist::KTX2_SS_NONE;
#endif
				break;
			}
			default: assert(0); return false;
			}
		}

		basisu::vector<uint8_vec> level_data_bytes(total_levels);
		basisu::vector<uint8_vec> compressed_level_data_bytes(total_levels);
		uint_vec slice_level_offsets(m_slice_descs.size());

		// This will append the texture data in the correct order (for each level: layer, then face).
		for (uint32_t slice_index = 0; slice_index < m_slice_descs.size(); slice_index++)
		{
			const basisu_backend_slice_desc& slice_desc = m_slice_descs[slice_index];

			slice_level_offsets[slice_index] = level_data_bytes[slice_desc.m_mip_index].size();

			if (m_params.m_uastc)
				append_vector(level_data_bytes[slice_desc.m_mip_index], m_uastc_backend_output.m_slice_image_data[slice_index]);
			else
				append_vector(level_data_bytes[slice_desc.m_mip_index], backend_output.m_slice_image_data[slice_index]);
		}

		// UASTC supercompression
		if ((m_params.m_uastc) && (header.m_supercompression_scheme == basist::KTX2_SS_ZSTANDARD))
		{
#if BASISD_SUPPORT_KTX2_ZSTD
			for (uint32_t level_index = 0; level_index < total_levels; level_index++)
			{
				compressed_level_data_bytes[level_index].resize(ZSTD_compressBound(level_data_bytes[level_index].size()));

				size_t result = ZSTD_compress(compressed_level_data_bytes[level_index].data(), compressed_level_data_bytes[level_index].size(),
					level_data_bytes[level_index].data(), level_data_bytes[level_index].size(),
					m_params.m_ktx2_zstd_supercompression_level);

				if (ZSTD_isError(result))
					return false;

				compressed_level_data_bytes[level_index].resize(result);
			}
#else
			// Can't get here
			assert(0);
			return false;
#endif
		}
		else
		{
			// No supercompression
			compressed_level_data_bytes = level_data_bytes;
		}
				
		uint8_vec etc1s_global_data;

		// Create ETC1S global supercompressed data
		if (!m_params.m_uastc)
		{
			basist::ktx2_etc1s_global_data_header etc1s_global_data_header;
			clear_obj(etc1s_global_data_header);

			etc1s_global_data_header.m_endpoint_count = backend_output.m_num_endpoints;
			etc1s_global_data_header.m_selector_count = backend_output.m_num_selectors;
			etc1s_global_data_header.m_endpoints_byte_length = backend_output.m_endpoint_palette.size();
			etc1s_global_data_header.m_selectors_byte_length = backend_output.m_selector_palette.size();
			etc1s_global_data_header.m_tables_byte_length = backend_output.m_slice_image_tables.size();

			basisu::vector<basist::ktx2_etc1s_image_desc> etc1s_image_descs(total_levels * total_layers * total_faces);
			memset(etc1s_image_descs.data(), 0, etc1s_image_descs.size_in_bytes());

			for (uint32_t slice_index = 0; slice_index < m_slice_descs.size(); slice_index++)
			{
				const basisu_backend_slice_desc& slice_desc = m_slice_descs[slice_index];

				const uint32_t level_index = slice_desc.m_mip_index;
				uint32_t layer_index = slice_desc.m_source_file_index;
				uint32_t face_index = 0;

				if (m_params.m_tex_type == basist::cBASISTexTypeCubemapArray)
				{
					face_index = layer_index % 6;
					layer_index /= 6;
				}

				const uint32_t etc1s_image_index = level_index * (total_layers * total_faces) + layer_index * total_faces + face_index;

				if (slice_desc.m_alpha)
				{
					etc1s_image_descs[etc1s_image_index].m_alpha_slice_byte_length = backend_output.m_slice_image_data[slice_index].size();
					etc1s_image_descs[etc1s_image_index].m_alpha_slice_byte_offset = slice_level_offsets[slice_index];
				}
				else
				{
					if (m_params.m_tex_type == basist::cBASISTexTypeVideoFrames)
						etc1s_image_descs[etc1s_image_index].m_image_flags = !slice_desc.m_iframe ? basist::KTX2_IMAGE_IS_P_FRAME : 0;

					etc1s_image_descs[etc1s_image_index].m_rgb_slice_byte_length = backend_output.m_slice_image_data[slice_index].size();
					etc1s_image_descs[etc1s_image_index].m_rgb_slice_byte_offset = slice_level_offsets[slice_index];
				}
			} // slice_index

			append_vector(etc1s_global_data, (const uint8_t*)&etc1s_global_data_header, sizeof(etc1s_global_data_header));
			append_vector(etc1s_global_data, (const uint8_t*)etc1s_image_descs.data(), etc1s_image_descs.size_in_bytes());
			append_vector(etc1s_global_data, backend_output.m_endpoint_palette);
			append_vector(etc1s_global_data, backend_output.m_selector_palette);
			append_vector(etc1s_global_data, backend_output.m_slice_image_tables);
			
			header.m_supercompression_scheme = basist::KTX2_SS_BASISLZ;
		}

		// Key values
		basist::ktx2_transcoder::key_value_vec key_values(m_params.m_ktx2_key_values);
		key_values.enlarge(1);
		
		const char* pKTXwriter = "KTXwriter";
		key_values.back().m_key.resize(strlen(pKTXwriter) + 1);
		memcpy(key_values.back().m_key.data(), pKTXwriter, strlen(pKTXwriter) + 1);

		char writer_id[128];
#ifdef _MSC_VER
		sprintf_s(writer_id, sizeof(writer_id), "Basis Universal %s", BASISU_LIB_VERSION_STRING);
#else
		snprintf(writer_id, sizeof(writer_id), "Basis Universal %s", BASISU_LIB_VERSION_STRING);
#endif
		key_values.back().m_value.resize(strlen(writer_id) + 1);
		memcpy(key_values.back().m_value.data(), writer_id, strlen(writer_id) + 1);

		key_values.sort();

#if BASISU_DISABLE_KTX2_KEY_VALUES
		// HACK HACK - Clear the key values array, which causes no key values to be written (triggering the ktx2check validator bug).
		key_values.clear();
#endif

		uint8_vec key_value_data;

		// DFD
		uint8_vec dfd;
		get_dfd(dfd, header);

		const uint32_t kvd_file_offset = sizeof(header) + sizeof(basist::ktx2_level_index) * total_levels + dfd.size();

		for (uint32_t pass = 0; pass < 2; pass++)
		{
			for (uint32_t i = 0; i < key_values.size(); i++)
			{
				if (key_values[i].m_key.size() < 2)
					return false;

				if (key_values[i].m_key.back() != 0)
					return false;

				const uint64_t total_len = (uint64_t)key_values[i].m_key.size() + (uint64_t)key_values[i].m_value.size();
				if (total_len >= UINT32_MAX)
					return false;

				packed_uint<4> le_len((uint32_t)total_len);
				append_vector(key_value_data, (const uint8_t*)&le_len, sizeof(le_len));

				append_vector(key_value_data, key_values[i].m_key);
				append_vector(key_value_data, key_values[i].m_value);

				const uint32_t ofs = key_value_data.size() & 3;
				const uint32_t padding = (4 - ofs) & 3;
				for (uint32_t p = 0; p < padding; p++)
					key_value_data.push_back(0);
			}

			if (header.m_supercompression_scheme != basist::KTX2_SS_NONE)
				break;

#if BASISU_DISABLE_KTX2_ALIGNMENT_WORKAROUND
			break;
#endif
			
			// Hack to ensure the KVD block ends on a 16 byte boundary, because we have no other official way of aligning the data.
			uint32_t kvd_end_file_offset = kvd_file_offset + key_value_data.size();
			uint32_t bytes_needed_to_pad = (16 - (kvd_end_file_offset & 15)) & 15;
			if (!bytes_needed_to_pad)
			{
				// We're good. No need to add a dummy key.
				break;
			}

			assert(!pass);
			if (pass)
				return false;

			if (bytes_needed_to_pad < 6)
				bytes_needed_to_pad += 16;

			// Just add the padding. It's likely not necessary anymore, but can't really hurt.
			//printf("WARNING: Due to a KTX2 validator bug related to mipPadding, we must insert a dummy key into the KTX2 file of %u bytes\n", bytes_needed_to_pad);
			
			// We're not good - need to add a dummy key large enough to force file alignment so the mip level array gets aligned. 
			// We can't just add some bytes before the mip level array because ktx2check will see that as extra data in the file that shouldn't be there in ktxValidator::validateDataSize().
			key_values.enlarge(1);
			for (uint32_t i = 0; i < (bytes_needed_to_pad - 4 - 1 - 1); i++)
				key_values.back().m_key.push_back(127);
			
			key_values.back().m_key.push_back(0);

			key_values.back().m_value.push_back(0);

			key_values.sort();

			key_value_data.resize(0);
			
			// Try again
		}

		basisu::vector<basist::ktx2_level_index> level_index_array(total_levels);
		memset(level_index_array.data(), 0, level_index_array.size_in_bytes());
				
		m_output_ktx2_file.clear();
		m_output_ktx2_file.reserve(m_output_basis_file.size());

		// Dummy header
		m_output_ktx2_file.resize(sizeof(header));

		// Level index array
		append_vector(m_output_ktx2_file, (const uint8_t*)level_index_array.data(), level_index_array.size_in_bytes());
				
		// DFD
		const uint8_t* pDFD = dfd.data();
		uint32_t dfd_len = dfd.size();

		header.m_dfd_byte_offset = m_output_ktx2_file.size();
		header.m_dfd_byte_length = dfd_len;
		append_vector(m_output_ktx2_file, pDFD, dfd_len);

		// Key value data
		if (key_value_data.size())
		{
			assert(kvd_file_offset == m_output_ktx2_file.size());

			header.m_kvd_byte_offset = m_output_ktx2_file.size();
			header.m_kvd_byte_length = key_value_data.size();
			append_vector(m_output_ktx2_file, key_value_data);
		}

		// Global Supercompressed Data
		if (etc1s_global_data.size())
		{
			uint32_t ofs = m_output_ktx2_file.size() & 7;
			uint32_t padding = (8 - ofs) & 7;
			for (uint32_t i = 0; i < padding; i++)
				m_output_ktx2_file.push_back(0);

			header.m_sgd_byte_length = etc1s_global_data.size();
			header.m_sgd_byte_offset = m_output_ktx2_file.size();

			append_vector(m_output_ktx2_file, etc1s_global_data);
		}

		// mipPadding
		if (header.m_supercompression_scheme == basist::KTX2_SS_NONE)
		{
			// We currently can't do this or the validator will incorrectly give an error.
			uint32_t ofs = m_output_ktx2_file.size() & 15;
			uint32_t padding = (16 - ofs) & 15;

			// Make sure we're always aligned here (due to a validator bug).
			if (padding)
			{
				printf("Warning: KTX2 mip level data is not 16-byte aligned. This may trigger a ktx2check validation bug. Writing %u bytes of mipPadding.\n", padding);
			}

			for (uint32_t i = 0; i < padding; i++)
				m_output_ktx2_file.push_back(0);
		}

		// Level data - write the smallest mipmap first.
		for (int level = total_levels - 1; level >= 0; level--)
		{
			level_index_array[level].m_byte_length = compressed_level_data_bytes[level].size();
			if (m_params.m_uastc)
				level_index_array[level].m_uncompressed_byte_length = level_data_bytes[level].size();

			level_index_array[level].m_byte_offset = m_output_ktx2_file.size();
			append_vector(m_output_ktx2_file, compressed_level_data_bytes[level]);
		}
		
		// Write final header
		memcpy(m_output_ktx2_file.data(), &header, sizeof(header));

		// Write final level index array
		memcpy(m_output_ktx2_file.data() + sizeof(header), level_index_array.data(), level_index_array.size_in_bytes());

		debug_printf("Total .ktx2 output file size: %u\n", m_output_ktx2_file.size());

		return true;
	}

	bool basis_parallel_compress(
		uint32_t total_threads,
		const basisu::vector<basis_compressor_params>& params_vec,
		basisu::vector< parallel_results >& results_vec)
	{
		assert(g_library_initialized);
		if (!g_library_initialized)
		{
			error_printf("basis_parallel_compress: basisu_encoder_init() MUST be called before using any encoder functionality!\n");
			return false;
		}

		assert(total_threads >= 1);
		total_threads = basisu::maximum<uint32_t>(total_threads, 1);

		job_pool jpool(total_threads);

		results_vec.resize(0);
		results_vec.resize(params_vec.size());

		std::atomic<bool> result;
		result = true;
		
		std::atomic<bool> opencl_failed;
		opencl_failed = false;

		for (uint32_t pindex = 0; pindex < params_vec.size(); pindex++)
		{
			jpool.add_job([pindex, &params_vec, &results_vec, &result, &opencl_failed] {

				basis_compressor_params params = params_vec[pindex];
				parallel_results& results = results_vec[pindex];

				interval_timer tm;
				tm.start();

				basis_compressor c;
				
				// Dummy job pool
				job_pool task_jpool(1);
				params.m_pJob_pool = &task_jpool;
				// TODO: Remove this flag entirely
				params.m_multithreading = true; 
				
				// Stop using OpenCL if a failure ever occurs.
				if (opencl_failed)
					params.m_use_opencl = false;

				bool status = c.init(params);
				
				if (c.get_opencl_failed())
					opencl_failed = true;

				if (status)
				{
					basis_compressor::error_code ec = c.process();

					if (c.get_opencl_failed())
						opencl_failed = true;

					results.m_error_code = ec;

					if (ec == basis_compressor::cECSuccess)
					{
						results.m_basis_file = c.get_output_basis_file();
						results.m_ktx2_file = c.get_output_ktx2_file();
						results.m_stats = c.get_stats();
						results.m_basis_bits_per_texel = c.get_basis_bits_per_texel();
						results.m_any_source_image_has_alpha = c.get_any_source_image_has_alpha();
					}
					else
					{
						result = false;
					}
				}
				else
				{
					results.m_error_code = basis_compressor::cECFailedInitializing;
					
					result = false;
				}

				results.m_total_time = tm.get_elapsed_secs();
			} );

		} // pindex

		jpool.wait_for_all();

		if (opencl_failed)
			error_printf("An OpenCL error occured sometime during compression. The compressor fell back to CPU processing after the failure.\n");

		return result;
	}

	static void* basis_compress(
		const basisu::vector<image> *pSource_images,
		const basisu::vector<imagef> *pSource_images_hdr,
		uint32_t flags_and_quality, float uastc_rdo_quality,
		size_t* pSize,
		image_stats* pStats)
	{
		assert((pSource_images != nullptr) || (pSource_images_hdr != nullptr));
		assert(!((pSource_images != nullptr) && (pSource_images_hdr != nullptr)));
		
		// Check input parameters
		if (pSource_images)
		{
			if ((!pSource_images->size()) || (!pSize))
			{
				error_printf("basis_compress: Invalid parameter\n");
				assert(0);
				return nullptr;
			}
		}
		else
		{
			if ((!pSource_images_hdr->size()) || (!pSize))
			{
				error_printf("basis_compress: Invalid parameter\n");
				assert(0);
				return nullptr;
			}
		}

		*pSize = 0;

		// Initialize a job pool
		uint32_t num_threads = 1;
		if (flags_and_quality & cFlagThreaded)
			num_threads = basisu::maximum<uint32_t>(1, std::thread::hardware_concurrency());

		job_pool jp(num_threads);

		// Initialize the compressor parameter struct
		basis_compressor_params comp_params;
		comp_params.m_pJob_pool = &jp;

		comp_params.m_y_flip = (flags_and_quality & cFlagYFlip) != 0;
		comp_params.m_debug = (flags_and_quality & cFlagDebug) != 0;
		comp_params.m_debug_images = (flags_and_quality & cFlagDebugImages) != 0;
		
		// Copy the largest mipmap level
		if (pSource_images)
		{
			comp_params.m_source_images.resize(1);
			comp_params.m_source_images[0] = (*pSource_images)[0];

			// Copy the smaller mipmap levels, if any
			if (pSource_images->size() > 1)
			{
				comp_params.m_source_mipmap_images.resize(1);
				comp_params.m_source_mipmap_images[0].resize(pSource_images->size() - 1);

				for (uint32_t i = 1; i < pSource_images->size(); i++)
					comp_params.m_source_mipmap_images[0][i - 1] = (*pSource_images)[i];
			}
		}
		else
		{
			comp_params.m_source_images_hdr.resize(1);
			comp_params.m_source_images_hdr[0] = (*pSource_images_hdr)[0];

			// Copy the smaller mipmap levels, if any
			if (pSource_images_hdr->size() > 1)
			{
				comp_params.m_source_mipmap_images_hdr.resize(1);
				comp_params.m_source_mipmap_images_hdr[0].resize(pSource_images_hdr->size() - 1);

				for (uint32_t i = 1; i < pSource_images->size(); i++)
					comp_params.m_source_mipmap_images_hdr[0][i - 1] = (*pSource_images_hdr)[i];
			}
		}
				
		comp_params.m_multithreading = (flags_and_quality & cFlagThreaded) != 0;
		comp_params.m_use_opencl = (flags_and_quality & cFlagUseOpenCL) != 0;

		comp_params.m_write_output_basis_or_ktx2_files = false;

		comp_params.m_perceptual = (flags_and_quality & cFlagSRGB) != 0;
		comp_params.m_mip_srgb = comp_params.m_perceptual;
		comp_params.m_mip_gen = (flags_and_quality & (cFlagGenMipsWrap | cFlagGenMipsClamp)) != 0;
		comp_params.m_mip_wrapping = (flags_and_quality & cFlagGenMipsWrap) != 0;

		if ((pSource_images_hdr) || (flags_and_quality & cFlagHDR))
		{
			// In UASTC HDR mode, the compressor will jam this to true anyway.
			// And there's no need to set UASTC LDR or ETC1S options.
			comp_params.m_uastc = true;
		}
		else
		{
			comp_params.m_uastc = (flags_and_quality & cFlagUASTC) != 0;
			if (comp_params.m_uastc)
			{
				comp_params.m_pack_uastc_flags = flags_and_quality & cPackUASTCLevelMask;
				comp_params.m_rdo_uastc = (flags_and_quality & cFlagUASTCRDO) != 0;
				comp_params.m_rdo_uastc_quality_scalar = uastc_rdo_quality;
			}
			else
			{
				comp_params.m_quality_level = basisu::maximum<uint32_t>(1, flags_and_quality & 255);
			}
		}
				
		comp_params.m_create_ktx2_file = (flags_and_quality & cFlagKTX2) != 0;
						
		if (comp_params.m_create_ktx2_file)
		{
			// Set KTX2 specific parameters.
			if ((flags_and_quality & cFlagKTX2UASTCSuperCompression) && (comp_params.m_uastc))
				comp_params.m_ktx2_uastc_supercompression = basist::KTX2_SS_ZSTANDARD;

			comp_params.m_ktx2_srgb_transfer_func = comp_params.m_perceptual;
		}

		comp_params.m_compute_stats = (pStats != nullptr);
		comp_params.m_print_stats = (flags_and_quality & cFlagPrintStats) != 0;
		comp_params.m_status_output = (flags_and_quality & cFlagPrintStatus) != 0;

		if ((flags_and_quality & cFlagHDR) || (pSource_images_hdr))
		{
			comp_params.m_hdr = true;
			comp_params.m_uastc_hdr_options.set_quality_level(flags_and_quality & cPackUASTCLevelMask);
		}

		if (flags_and_quality & cFlagHDRLDRImageSRGBToLinearConversion)
			comp_params.m_hdr_ldr_srgb_to_linear_conversion = true;

		// Create the compressor, initialize it, and process the input
		basis_compressor comp;
		if (!comp.init(comp_params))
		{
			error_printf("basis_compress: basis_compressor::init() failed!\n");
			return nullptr;
		}

		basis_compressor::error_code ec = comp.process();

		if (ec != basis_compressor::cECSuccess)
		{
			error_printf("basis_compress: basis_compressor::process() failed with error code %u\n", (uint32_t)ec);
			return nullptr;
		}

		if ((pStats) && (comp.get_opencl_failed()))
		{
			pStats->m_opencl_failed = true;
		}

		// Get the output file data and return it to the caller
		void* pFile_data = nullptr;
		const uint8_vec* pFile_data_vec = comp_params.m_create_ktx2_file ? &comp.get_output_ktx2_file() : &comp.get_output_basis_file();

		pFile_data = malloc(pFile_data_vec->size());
		if (!pFile_data)
		{
			error_printf("basis_compress: Out of memory\n");
			return nullptr;
		}
		memcpy(pFile_data, pFile_data_vec->get_ptr(), pFile_data_vec->size());

		*pSize = pFile_data_vec->size();

		if ((pStats) && (comp.get_stats().size()))
		{
			*pStats = comp.get_stats()[0];
		}

		return pFile_data;
	}

	void* basis_compress(
		const basisu::vector<image>& source_images,
		uint32_t flags_and_quality, float uastc_rdo_quality,
		size_t* pSize,
		image_stats* pStats)
	{
		return basis_compress(&source_images, nullptr, flags_and_quality, uastc_rdo_quality, pSize, pStats);
	}

	void* basis_compress(
		const basisu::vector<imagef>& source_images_hdr,
		uint32_t flags_and_quality,
		size_t* pSize,
		image_stats* pStats)
	{
		return basis_compress(nullptr, &source_images_hdr, flags_and_quality, 0.0f, pSize, pStats);
	}

	void* basis_compress(
		const uint8_t* pImageRGBA, uint32_t width, uint32_t height, uint32_t pitch_in_pixels,
		uint32_t flags_and_quality, float uastc_rdo_quality,
		size_t* pSize,
		image_stats* pStats)
	{
		if (!pitch_in_pixels)
			pitch_in_pixels = width;

		if ((!pImageRGBA) || (!width) || (!height) || (pitch_in_pixels < width) || (!pSize))
		{
			error_printf("basis_compress: Invalid parameter\n");
			assert(0);
			return nullptr;
		}

		*pSize = 0;

		if ((width > BASISU_MAX_SUPPORTED_TEXTURE_DIMENSION) || (height > BASISU_MAX_SUPPORTED_TEXTURE_DIMENSION))
		{
			error_printf("basis_compress: Image too large\n");
			return nullptr;
		}

		// Copy the source image
		basisu::vector<image> source_image(1);
		source_image[0].crop(width, height, width, g_black_color, false);
		for (uint32_t y = 0; y < height; y++)
			memcpy(source_image[0].get_ptr() + y * width, (const color_rgba*)pImageRGBA + y * pitch_in_pixels, width * sizeof(color_rgba));

		return basis_compress(source_image, flags_and_quality, uastc_rdo_quality, pSize, pStats);
	}

	void basis_free_data(void* p)
	{
		free(p);
	}

	bool basis_benchmark_etc1s_opencl(bool* pOpenCL_failed)
	{
		if (pOpenCL_failed)
			*pOpenCL_failed = false;

		if (!opencl_is_available())
		{
			error_printf("basis_benchmark_etc1s_opencl: OpenCL support must be enabled first!\n");
			return false;
		}

		const uint32_t W = 1024, H = 1024;
		basisu::vector<image> images;
		image& img = images.enlarge(1)->resize(W, H);
		
		const uint32_t NUM_RAND_LETTERS = 6000;// 40000;

		rand r;
		r.seed(200);

		for (uint32_t i = 0; i < NUM_RAND_LETTERS; i++)
		{
			uint32_t x = r.irand(0, W - 1), y = r.irand(0, H - 1);
			uint32_t sx = r.irand(1, 4), sy = r.irand(1, 4);
			color_rgba c(r.byte(), r.byte(), r.byte(), 255);

			img.debug_text(x, y, sx, sy, c, nullptr, false, "%c", static_cast<char>(r.irand(32, 127)));
		}

		//save_png("test.png", img);

		image_stats stats;

		uint32_t flags_and_quality = cFlagSRGB | cFlagThreaded | 255;
		size_t comp_size = 0;

		double best_cpu_time = 1e+9f, best_gpu_time = 1e+9f;

		const uint32_t TIMES_TO_ENCODE = 2;
		interval_timer tm;

		for (uint32_t i = 0; i < TIMES_TO_ENCODE; i++)
		{
			tm.start();
			void* pComp_data = basis_compress(
				images,
				flags_and_quality, 1.0f,
				&comp_size,
				&stats);
			double cpu_time = tm.get_elapsed_secs();
			if (!pComp_data)
			{
				error_printf("basis_benchmark_etc1s_opencl: basis_compress() failed (CPU)!\n");
				return false;
			}
			
			best_cpu_time = minimum(best_cpu_time, cpu_time);

			basis_free_data(pComp_data);
		}

		printf("Best CPU time: %3.3f\n", best_cpu_time);

		for (uint32_t i = 0; i < TIMES_TO_ENCODE; i++)
		{
			tm.start();
			void* pComp_data = basis_compress(
				images,
				flags_and_quality | cFlagUseOpenCL, 1.0f,
				&comp_size,
				&stats);

			if (stats.m_opencl_failed)
			{
				error_printf("basis_benchmark_etc1s_opencl: OpenCL failed!\n");

				basis_free_data(pComp_data);

				if (pOpenCL_failed)
					*pOpenCL_failed = true;

				return false;
			}

			double gpu_time = tm.get_elapsed_secs();
			if (!pComp_data)
			{
				error_printf("basis_benchmark_etc1s_opencl: basis_compress() failed (GPU)!\n");
				return false;
			}

			best_gpu_time = minimum(best_gpu_time, gpu_time);

			basis_free_data(pComp_data);
		}

		printf("Best GPU time: %3.3f\n", best_gpu_time);
				
		return best_gpu_time < best_cpu_time;
	}

} // namespace basisu



