// basisu_comp.cpp
// Copyright (C) 2019-2020 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>
#define MINIZ_NO_ZLIB_APIS
#include "basisu_miniz.h"

#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_basis_file_size(0),
		m_basis_bits_per_texel(0),
		m_total_blocks(0),
		m_auto_global_sel_pal(false),
		m_any_source_image_has_alpha(false)
	{
		debug_printf("basis_compressor::basis_compressor\n");
	}

	bool basis_compressor::init(const basis_compressor_params &params)
	{
		debug_printf("basis_compressor::init\n");

		m_params = params;

		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("Has global selector codebook: %i\n", m_params.m_pSel_codebook != nullptr);

			debug_printf("Source images: %u, source filenames: %u, source alpha filenames: %i\n", 
				(uint32_t)m_params.m_source_images.size(), (uint32_t)m_params.m_source_filenames.size(), (uint32_t)m_params.m_source_alpha_filenames.size());

			PRINT_BOOL_VALUE(m_uastc);
			PRINT_BOOL_VALUE(m_y_flip);
			PRINT_BOOL_VALUE(m_debug);
			PRINT_BOOL_VALUE(m_debug_images);
			PRINT_BOOL_VALUE(m_global_sel_pal);
			PRINT_BOOL_VALUE(m_auto_global_sel_pal);
			PRINT_BOOL_VALUE(m_compression_level);
			PRINT_BOOL_VALUE(m_no_hybrid_sel_cb);
			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_files);
			PRINT_BOOL_VALUE(m_compute_stats);
			PRINT_BOOL_VALUE(m_check_for_alpha)
			PRINT_BOOL_VALUE(m_force_alpha)
			PRINT_BOOL_VALUE(m_seperate_rg_to_color_alpha);
			PRINT_BOOL_VALUE(m_multithreading);
			PRINT_BOOL_VALUE(m_disable_hierarchical_endpoint_codebooks);
			
			PRINT_FLOAT_VALUE(m_hybrid_sel_cb_quality_thresh);
			
			PRINT_INT_VALUE(m_global_pal_bits);
			PRINT_INT_VALUE(m_global_mod_bits);

			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_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("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);
						
#undef PRINT_BOOL_VALUE
#undef PRINT_INT_VALUE
#undef PRINT_UINT_VALUE
#undef PRINT_FLOAT_VALUE
		}

		if ((m_params.m_read_source_images) && (!m_params.m_source_filenames.size()))
		{
			assert(0);
			return false;
		}

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

		if (!read_source_images())
			return cECFailedReadingSourceImages;

		if (!validate_texture_type_constraints())
			return cECFailedValidating;

		if (!extract_source_blocks())
			return cECFailedFrontEnd;

		if (m_params.m_uastc)
		{
			error_code ec = encode_slices_to_uastc();
			if (ec != cECSuccess)
				return ec;
		}
		else
		{
			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 (!write_output_files_and_compute_stats())
			return cECFailedWritingOutput;

		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);

				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]
					{
						BASISU_NOTE_UNUSED(num_blocks_y);
						
						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, m_params.m_pack_uastc_flags);

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

						}
					});

			} // block_index_iter

			m_params.m_pJob_pool->wait_for_all();

			if (m_params.m_rdo_uastc)
			{
				uastc_rdo_params rdo_params;
				rdo_params.m_quality_scaler = 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;
								
				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_pJob_pool,
					m_params.m_pJob_pool ? std::min<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 image &img, std::vector<image> &mips, bool has_alpha)
	{
		debug_printf("basis_compressor::generate_mipmaps\n");

		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);

			bool status = image_resample(img, 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

		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() : (uint32_t)m_params.m_source_images.size();
		if (!total_source_files)
			return false;

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

		m_total_blocks = 0;
		uint32_t total_macroblocks = 0;

		m_any_source_image_has_alpha = false;

		std::vector<image> source_images;
		std::vector<std::string> source_filenames;
		
		// 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;
			
			if (m_params.m_read_source_images)
			{
				pSource_filename = m_params.m_source_filenames[source_file_index].c_str();

				// Load the source image
				if (!load_image(pSource_filename, file_image))
				{
					error_printf("Failed reading source image: %s\n", pSource_filename);
					return false;
				}

				printf("Read source image \"%s\", %ux%u\n", pSource_filename, file_image.get_width(), file_image.get_height());

				// 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(file_image.get_width(), file_image.get_height());

					for (uint32_t y = 0; y < file_image.get_height(); y++)
						for (uint32_t x = 0; x < file_image.get_width(); x++)
							file_image(x, y).a = (uint8_t)alpha_data(x, y).get_709_luma();
				}
			}
			else
			{
				file_image = m_params.m_source_images[source_file_index];
			}

			if (m_params.m_seperate_rg_to_color_alpha)
			{
				// 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.r, c.r, c.r, c.g);
					}
			}
						
			bool has_alpha = false;
			if ((m_params.m_force_alpha) || (m_params.m_seperate_rg_to_color_alpha))
				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;

			debug_printf("Source image index %u filename %s %ux%u has alpha: %u\n", source_file_index, pSource_filename, file_image.get_width(), file_image.get_height(), has_alpha);
												
			if (m_params.m_y_flip)
				file_image.flip_y();

#if DEBUG_EXTRACT_SINGLE_BLOCK
			image block_image(4, 4);
			const uint32_t block_x = 0;
			const uint32_t block_y = 0;
			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
			file_image.resize(64, 64);
#endif
#if DEBUG_RESIZE_TEXTURE
			image temp_img((file_image.get_width() + 1) / 2, (file_image.get_height() + 1) / 2);
			image_resample(file_image, temp_img, m_params.m_perceptual, "kaiser");
			temp_img.swap(file_image);
#endif

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

			if ((file_image.get_width() > BASISU_MAX_SUPPORTED_TEXTURE_DIMENSION) || (file_image.get_height() > BASISU_MAX_SUPPORTED_TEXTURE_DIMENSION))
			{
				error_printf("basis_compressor::read_source_images: Source image is too large!\n");
				return false;
			}

			source_images.push_back(file_image);
			source_filenames.push_back(pSource_filename);
		}

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

		for (uint32_t source_file_index = 0; source_file_index < total_source_files; source_file_index++)
		{
			image &file_image = source_images[source_file_index];
			const std::string &source_filename = source_filenames[source_file_index];

			// Now, for each source image, create the slices corresponding to that image.
			std::vector<image> slices;
			
			slices.reserve(32);
			slices.push_back(file_image);
									
			if (m_params.m_mip_gen)
			{
				if (!generate_mipmaps(file_image, slices, m_any_source_image_has_alpha))
					return false;
			}

			uint_vec mip_indices(slices.size());
			for (uint32_t i = 0; i < slices.size(); i++)
				mip_indices[i] = i;
						
			if ((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. 
				std::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);
			}

			assert(slices.size() == mip_indices.size());
						
			for (uint32_t slice_index = 0; slice_index < slices.size(); slice_index++)
			{
				image& slice_image = slices[slice_index];
				const uint32_t orig_width = slice_image.get_width();
				const uint32_t orig_height = slice_image.get_height();

				bool is_alpha_slice = false;
				if (m_any_source_image_has_alpha)
				{
					if (m_params.m_uastc)
					{
						is_alpha_slice = slice_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.
				slice_image.crop_dup_borders(slice_image.get_block_width(4) * 4, slice_image.get_block_height(4) * 4);

				if (m_params.m_debug_images)
				{
					save_png(string_format("basis_debug_source_image_%u_slice_%u.png", source_file_index, slice_index).c_str(), slice_image);
				}

				enlarge_vector(m_stats, 1);
				enlarge_vector(m_slice_images, 1);
				enlarge_vector(m_slice_descs, 1);

				const uint32_t dest_image_index = (uint32_t)m_stats.size() - 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;

				m_slice_images[dest_image_index] = slice_image;

				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, slice_image.get_width(), slice_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;

				slice_desc.m_width = slice_image.get_width();
				slice_desc.m_height = slice_image.get_height();

				slice_desc.m_num_blocks_x = slice_image.get_block_width(4);
				slice_desc.m_num_blocks_y = slice_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;
			
			} // 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;
			}
		}

		printf("Total basis file 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];

			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)
			{
				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_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_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");

		m_source_blocks.resize(m_total_blocks);

		for (uint32_t slice_index = 0; slice_index < 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& source_image = m_slice_images[slice_index];

			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++)
					source_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;
			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, 3072);
				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, 8192);
				max_endpoints = minimum<uint32_t>(max_endpoints, m_total_blocks);
								
				if (max_endpoints < 3072)
					max_endpoints = 3072;
				endpoint_clusters = clamp<uint32_t>((uint32_t)(.5f + lerp<float>(3072, static_cast<float>(max_endpoints), color_endpoint_quality)), 32, basisu_frontend::cMaxEndpointClusters);
			}
						
			float bits_per_selector_cluster = m_params.m_global_sel_pal ? 21.0f : 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);
			}
		}

		m_auto_global_sel_pal = false;
		if (!m_params.m_global_sel_pal && m_params.m_auto_global_sel_pal)
		{
			const float bits_per_selector_cluster = 31.0f;
			double selector_codebook_bpp_est = (bits_per_selector_cluster * selector_clusters) / total_texels;
			debug_printf("selector_codebook_bpp_est: %f\n", selector_codebook_bpp_est);
			const float force_global_sel_pal_bpp_threshold = .15f;
			if ((total_texels <= 128.0f*128.0f) && (selector_codebook_bpp_est > force_global_sel_pal_bpp_threshold))
			{
				m_auto_global_sel_pal = true;
				debug_printf("Auto global selector palette enabled\n");
			}
		}

		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_pJob_pool = m_params.m_pJob_pool;

		if ((m_params.m_global_sel_pal) || (m_auto_global_sel_pal))
		{
			p.m_pGlobal_sel_codebook = m_params.m_pSel_codebook;
			p.m_num_global_sel_codebook_pal_bits = m_params.m_global_pal_bits;
			p.m_num_global_sel_codebook_mod_bits = m_params.m_global_mod_bits;
			p.m_use_hybrid_selector_codebooks = !m_params.m_no_hybrid_sel_cb;
			p.m_hybrid_codebook_quality_thresh = m_params.m_hybrid_sel_cb_quality_thresh;
		}

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

		m_frontend.compress();

		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()
	{
		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_use_global_sel_codebook = (m_frontend.get_params().m_pGlobal_sel_codebook != NULL);
		backend_params.m_global_sel_codebook_pal_bits = m_frontend.get_params().m_num_global_sel_codebook_pal_bits;
		backend_params.m_global_sel_codebook_mod_bits = m_frontend.get_params().m_num_global_sel_codebook_mod_bits;
		backend_params.m_use_hybrid_sel_codebooks = m_frontend.get_params().m_use_hybrid_selector_codebooks;

		m_backend.init(&m_frontend, backend_params, m_slice_descs, m_params.m_pSel_codebook);
		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;

		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(m_params.m_pSel_codebook);
		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());
		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 (!decoder.start_transcoding(&comp_data[0], (uint32_t)comp_data.size()))
		{
			error_printf("decoder.start_transcoding() failed!\n");
			return false;
		}

		debug_printf("basisu_comppressor::start_transcoding() took %3.3fms\n", tm.get_elapsed_ms());

		uint32_t total_orig_pixels = 0;
		uint32_t total_texels = 0;

		double total_time_etc1 = 0;

		for (uint32_t i = 0; i < m_slice_descs.size(); i++)
		{
			gpu_image decoded_texture;
			decoded_texture.init(m_params.m_uastc ? texture_format::cASTC4x4 : texture_format::cETC1, m_slice_descs[i].m_width, m_slice_descs[i].m_height);
						
			tm.start();

			basist::block_format format = m_params.m_uastc ? basist::block_format::cASTC_4x4 : basist::block_format::cETC1;
			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_etc1 += 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;

			total_orig_pixels += m_slice_descs[i].m_orig_width * m_slice_descs[i].m_orig_height;
			total_texels += m_slice_descs[i].m_width * m_slice_descs[i].m_height;
		}
								
		double total_time_bc7 = 0;

		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);

			tm.start();

			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;
			}

			total_time_bc7 += tm.get_elapsed_secs();

			m_decoded_output_textures_bc7[i] = decoded_texture;
		}

		for (uint32_t i = 0; i < m_slice_descs.size(); i++)
		{
			m_decoded_output_textures[i].unpack(m_decoded_output_textures_unpacked[i]);
			m_decoded_output_textures_bc7[i].unpack(m_decoded_output_textures_unpacked_bc7[i]);
		}

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

		debug_printf("Transcoded to BC7 in %3.3fms, %f texels/sec\n", total_time_bc7 * 1000.0f, total_orig_pixels / total_time_bc7);

		debug_printf("Total .basis output file size: %u, %3.3f bits/texel\n", comp_data.size(), comp_data.size() * 8.0f / total_orig_pixels);
				
		uint32_t total_orig_texels = 0;
		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];

			total_orig_texels += slice_desc.m_orig_width * slice_desc.m_orig_height;

			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);
		}

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

		return true;
	}

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

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

		const uint8_vec& comp_data = m_basis_file.get_compressed_data();
		if (m_params.m_write_output_basis_files)
		{

			const std::string& basis_filename = m_params.m_out_filename;

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

			printf("Wrote output .basis file \"%s\"\n", basis_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;
			debug_printf(".basis file size: %u, LZ compressed file size: %u, %3.2f bits/texel\n",
				(uint32_t)comp_data.size(),
				(uint32_t)comp_size,
				comp_size * 8.0f / total_texels);
		}

		m_stats.resize(m_slice_descs.size());
		
		uint32_t total_orig_texels = 0;

		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];
						
			total_orig_texels += slice_desc.m_orig_width * slice_desc.m_orig_height;

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

				image_stats &s = m_stats[slice_index];

				// TODO: We used to output SSIM (during heavy encoder development), but this slowed down compression too much. We'll be adding it back.

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

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

				em.calc(m_slice_images[slice_index], m_decoded_output_textures_unpacked[slice_index], 0, 1);
				em.print(".basis R   Avg:          ");
				
				em.calc(m_slice_images[slice_index], m_decoded_output_textures_unpacked[slice_index], 1, 1);
				em.print(".basis G   Avg:          ");
				
				em.calc(m_slice_images[slice_index], m_decoded_output_textures_unpacked[slice_index], 2, 1);
				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);
					em.print(".basis A   Avg:          ");

					s.m_basis_a_avg_psnr = em.m_psnr;
				}

				em.calc(m_slice_images[slice_index], m_decoded_output_textures_unpacked[slice_index], 0, 0);
				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);
				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();
					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)));
				}

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

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

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

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

					em.calc(m_slice_images[slice_index], m_decoded_output_textures_unpacked_bc7[slice_index], 2, 1);
					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);
						em.print("BC7 A   Avg:             ");

						s.m_bc7_a_avg_psnr = em.m_psnr;
					}

					em.calc(m_slice_images[slice_index], m_decoded_output_textures_unpacked_bc7[slice_index], 0, 0);
					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);
					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, 0);
					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);
					em.print("Unquantized ETC1S 601 Luma:    ");

					s.m_best_etc1s_luma_601_psnr = static_cast<float>(em.m_psnr);

					em.calc(m_slice_images[slice_index], m_best_etc1s_images_unpacked[slice_index], 0, 3);
					em.print("Unquantized ETC1S RGB Avg:     ");

					s.m_best_etc1s_rgb_avg_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);

					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_astc.ktx").c_str(), decoded_etc1s_or_astc);

					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_astc.png", temp);
				}

				// Write decoded BC7 debug images
				{
					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);

					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);
				}
			}
		}
				
		return true;
	}

} // namespace basisu
