// basisu_backend.cpp
// Copyright (C) 2019 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.
//
// TODO: This code originally supported full ETC1 and ETC1S, so there's some legacy stuff in here.
//
#include "basisu_backend.h"

#define BASISU_FASTER_SELECTOR_REORDERING 0
#define BASISU_BACKEND_VERIFY(c) verify(c, __LINE__);

namespace basisu
{
	// TODO
	static inline void verify(bool condition, int line)
	{
		if (!condition)
		{
			fprintf(stderr, "ERROR: basisu_backend: verify() failed at line %i!\n", line);
			abort();
		}
	}

	basisu_backend::basisu_backend()
	{
		clear();
	}

	void basisu_backend::clear()
	{
		m_pFront_end = NULL;
		m_params.clear();
		m_output.clear();
	}

	void basisu_backend::init(basisu_frontend* pFront_end, basisu_backend_params& params, const basisu_backend_slice_desc_vec& slice_descs, const basist::etc1_global_selector_codebook* pGlobal_sel_codebook)
	{
		m_pFront_end = pFront_end;
		m_params = params;
		m_slices = slice_descs;
		m_pGlobal_sel_codebook = pGlobal_sel_codebook;

		debug_printf("basisu_backend::Init: Slices: %u, ETC1S: %u, EndpointRDOQualityThresh: %f, SelectorRDOQualityThresh: %f, UseGlobalSelCodebook: %u, GlobalSelCodebookPalBits: %u, GlobalSelCodebookModBits: %u, Use hybrid selector codebooks: %u\n",
			m_slices.size(),
			params.m_etc1s,
			params.m_endpoint_rdo_quality_thresh,
			params.m_selector_rdo_quality_thresh,
			params.m_use_global_sel_codebook,
			params.m_global_sel_codebook_pal_bits,
			params.m_global_sel_codebook_mod_bits,
			params.m_use_hybrid_sel_codebooks);

		debug_printf("Frontend endpoints: %u selectors: %u\n", m_pFront_end->get_total_endpoint_clusters(), m_pFront_end->get_total_selector_clusters());

		for (uint32_t i = 0; i < m_slices.size(); i++)
		{
			debug_printf("Slice: %u, OrigWidth: %u, OrigHeight: %u, Width: %u, Height: %u, NumBlocksX: %u, NumBlocksY: %u, FirstBlockIndex: %u\n",
				i,
				m_slices[i].m_orig_width, m_slices[i].m_orig_height,
				m_slices[i].m_width, m_slices[i].m_height,
				m_slices[i].m_num_blocks_x, m_slices[i].m_num_blocks_y,
				m_slices[i].m_first_block_index);
		}
	}

	void basisu_backend::create_endpoint_palette()
	{
		const basisu_frontend& r = *m_pFront_end;

		m_output.m_num_endpoints = r.get_total_endpoint_clusters();

		m_endpoint_palette.resize(r.get_total_endpoint_clusters());
		for (uint32_t i = 0; i < r.get_total_endpoint_clusters(); i++)
		{
			etc1_endpoint_palette_entry& e = m_endpoint_palette[i];

			e.m_color5_valid = r.get_endpoint_cluster_color_is_used(i, false);
			e.m_color5 = r.get_endpoint_cluster_unscaled_color(i, false);
			e.m_inten5 = r.get_endpoint_cluster_inten_table(i, false);

			BASISU_BACKEND_VERIFY(e.m_color5_valid);
		}
	}

	void basisu_backend::create_selector_palette()
	{
		const basisu_frontend& r = *m_pFront_end;

		m_output.m_num_selectors = r.get_total_selector_clusters();

		m_selector_palette.resize(r.get_total_selector_clusters());

		if (m_params.m_use_global_sel_codebook)
		{
			m_global_selector_palette_desc.resize(r.get_total_selector_clusters());

			for (int i = 0; i < static_cast<int>(r.get_total_selector_clusters()); i++)
			{
				basist::etc1_selector_palette_entry& selector_pal_entry = m_selector_palette[i];

				etc1_global_selector_cb_entry_desc& pal_entry_desc = m_global_selector_palette_desc[i];
				pal_entry_desc.m_pal_index = r.get_selector_cluster_global_selector_entry_ids()[i].m_palette_index;
				pal_entry_desc.m_mod_index = r.get_selector_cluster_global_selector_entry_ids()[i].m_modifier.get_index();

				pal_entry_desc.m_was_used = true;
				if (m_params.m_use_hybrid_sel_codebooks)
					pal_entry_desc.m_was_used = r.get_selector_cluster_uses_global_cb_vec()[i];

				if (pal_entry_desc.m_was_used)
				{
					const etc_block& selector_bits = r.get_selector_cluster_selector_bits(i);
					(void)selector_bits;

					basist::etc1_selector_palette_entry global_pal_entry(m_pGlobal_sel_codebook->get_entry(r.get_selector_cluster_global_selector_entry_ids()[i]));

					for (uint32_t y = 0; y < 4; y++)
					{
						for (uint32_t x = 0; x < 4; x++)
						{
							selector_pal_entry(x, y) = global_pal_entry(x, y);

							assert(selector_bits.get_selector(x, y) == global_pal_entry(x, y));
						}
					}
				}
				else
				{
					const etc_block& selector_bits = r.get_selector_cluster_selector_bits(i);

					for (uint32_t y = 0; y < 4; y++)
						for (uint32_t x = 0; x < 4; x++)
							selector_pal_entry[y * 4 + x] = static_cast<uint8_t>(selector_bits.get_selector(x, y));
				}
			}
		}
		else
		{
			for (uint32_t i = 0; i < r.get_total_selector_clusters(); i++)
			{
				basist::etc1_selector_palette_entry& s = m_selector_palette[i];

				const etc_block& selector_bits = r.get_selector_cluster_selector_bits(i);

				for (uint32_t y = 0; y < 4; y++)
				{
					for (uint32_t x = 0; x < 4; x++)
					{
						s[y * 4 + x] = static_cast<uint8_t>(selector_bits.get_selector(x, y));
					}
				}
			}
		}
	}

	static const struct
	{
		int8_t m_dx, m_dy;
	} g_endpoint_preds[] =
	{
		{ -1, 0 },
		{ 0, -1 },
		{ -1, -1 }
	};

	void basisu_backend::reoptimize_and_sort_endpoints_codebook(uint32_t total_block_endpoints_remapped, uint_vec& all_endpoint_indices)
	{
		basisu_frontend& r = *m_pFront_end;
		const bool is_video = r.get_params().m_tex_type == basist::cBASISTexTypeVideoFrames;

		if ((total_block_endpoints_remapped) && (m_params.m_compression_level > 0))
		{
			// We're changed the block endpoint indices, so we need to go and adjust the endpoint codebook (remove unused entries, optimize existing entries that have changed)
			uint_vec new_block_endpoints(get_total_blocks());

			for (uint32_t slice_index = 0; slice_index < m_slices.size(); slice_index++)
			{
				const uint32_t first_block_index = m_slices[slice_index].m_first_block_index;
				const uint32_t num_blocks_x = m_slices[slice_index].m_num_blocks_x;
				const uint32_t num_blocks_y = m_slices[slice_index].m_num_blocks_y;

				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++)
						new_block_endpoints[first_block_index + block_x + block_y * num_blocks_x] = m_slice_encoder_blocks[slice_index](block_x, block_y).m_endpoint_index;
			}

			int_vec old_to_new_endpoint_indices;
			r.reoptimize_remapped_endpoints(new_block_endpoints, old_to_new_endpoint_indices, true);

			create_endpoint_palette();

			for (uint32_t slice_index = 0; slice_index < m_slices.size(); slice_index++)
			{
				const uint32_t first_block_index = m_slices[slice_index].m_first_block_index;

				const uint32_t width = m_slices[slice_index].m_width;
				const uint32_t height = m_slices[slice_index].m_height;
				const uint32_t num_blocks_x = m_slices[slice_index].m_num_blocks_x;
				const uint32_t num_blocks_y = m_slices[slice_index].m_num_blocks_y;

				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++)
					{
						const uint32_t block_index = first_block_index + block_x + block_y * num_blocks_x;

						encoder_block& m = m_slice_encoder_blocks[slice_index](block_x, block_y);

						m.m_endpoint_index = old_to_new_endpoint_indices[m.m_endpoint_index];
					} // block_x
				} // block_y
			} // slice_index

			for (uint32_t i = 0; i < all_endpoint_indices.size(); i++)
				all_endpoint_indices[i] = old_to_new_endpoint_indices[all_endpoint_indices[i]];

		} //if (total_block_endpoints_remapped)

		// Sort endpoint codebook
		palette_index_reorderer reorderer;
		reorderer.init((uint32_t)all_endpoint_indices.size(), &all_endpoint_indices[0], r.get_total_endpoint_clusters(), nullptr, nullptr, 0);
		m_endpoint_remap_table_old_to_new = reorderer.get_remap_table();

		m_endpoint_remap_table_new_to_old.resize(r.get_total_endpoint_clusters());
		for (uint32_t i = 0; i < m_endpoint_remap_table_old_to_new.size(); i++)
			m_endpoint_remap_table_new_to_old[m_endpoint_remap_table_old_to_new[i]] = i;
	}

	void basisu_backend::sort_selector_codebook()
	{
		basisu_frontend& r = *m_pFront_end;

		m_selector_remap_table_new_to_old.resize(r.get_total_selector_clusters());

		if (m_params.m_compression_level == 0)
		{
			for (uint32_t i = 0; i < r.get_total_selector_clusters(); i++)
				m_selector_remap_table_new_to_old[i] = i;
		}
		else
		{
			m_selector_remap_table_new_to_old[0] = 0;
			uint32_t prev_selector_index = 0;

			int_vec remaining_selectors;
			remaining_selectors.reserve(r.get_total_selector_clusters() - 1);
			for (uint32_t i = 1; i < r.get_total_selector_clusters(); i++)
				remaining_selectors.push_back(i);

			uint_vec selector_palette_bytes(m_selector_palette.size());
			for (uint32_t i = 0; i < m_selector_palette.size(); i++)
				selector_palette_bytes[i] = m_selector_palette[i].get_byte(0) | (m_selector_palette[i].get_byte(1) << 8) | (m_selector_palette[i].get_byte(2) << 16) | (m_selector_palette[i].get_byte(3) << 24);

			// This is the traveling salesman problem.
			for (uint32_t i = 1; i < r.get_total_selector_clusters(); i++)
			{
				uint32_t best_hamming_dist = 100;
				uint32_t best_index = 0;

#if BASISU_FASTER_SELECTOR_REORDERING
				const uint32_t step = (remaining_selectors.size() > 16) ? 16 : 1;
				for (uint32_t j = 0; j < remaining_selectors.size(); j += step)
#else
				for (uint32_t j = 0; j < remaining_selectors.size(); j++)
#endif
				{
					int selector_index = remaining_selectors[j];

					uint32_t k = selector_palette_bytes[prev_selector_index] ^ selector_palette_bytes[selector_index];
					uint32_t hamming_dist = g_hamming_dist[k & 0xFF] + g_hamming_dist[(k >> 8) & 0xFF] + g_hamming_dist[(k >> 16) & 0xFF] + g_hamming_dist[k >> 24];

					if (hamming_dist < best_hamming_dist)
					{
						best_hamming_dist = hamming_dist;
						best_index = j;
						if (best_hamming_dist <= 1)
							break;
					}
				}

				prev_selector_index = remaining_selectors[best_index];
				m_selector_remap_table_new_to_old[i] = prev_selector_index;

				remaining_selectors[best_index] = remaining_selectors.back();
				remaining_selectors.resize(remaining_selectors.size() - 1);
			}
		}

		m_selector_remap_table_old_to_new.resize(r.get_total_selector_clusters());
		for (uint32_t i = 0; i < m_selector_remap_table_new_to_old.size(); i++)
			m_selector_remap_table_old_to_new[m_selector_remap_table_new_to_old[i]] = i;
	}
	int basisu_backend::find_video_frame(int slice_index, int delta)
	{
		for (uint32_t s = 0; s < m_slices.size(); s++)
		{
			if ((int)m_slices[s].m_source_file_index != ((int)m_slices[slice_index].m_source_file_index + delta))
				continue;
			if (m_slices[s].m_mip_index != m_slices[slice_index].m_mip_index)
				continue;

			// Being super paranoid here.
			if (m_slices[s].m_num_blocks_x != (m_slices[slice_index].m_num_blocks_x))
				continue;
			if (m_slices[s].m_num_blocks_y != (m_slices[slice_index].m_num_blocks_y))
				continue;
			if (m_slices[s].m_alpha != (m_slices[slice_index].m_alpha))
				continue;
			return s;
		}

		return -1;
	}

	void basisu_backend::check_for_valid_cr_blocks()
	{
		basisu_frontend& r = *m_pFront_end;
		const bool is_video = r.get_params().m_tex_type == basist::cBASISTexTypeVideoFrames;

		if (!is_video)
			return;

		uint32_t total_crs = 0;
		uint32_t total_invalid_crs = 0;

		for (uint32_t slice_index = 0; slice_index < m_slices.size(); slice_index++)
		{
			const bool is_iframe = m_slices[slice_index].m_iframe;
			const uint32_t first_block_index = m_slices[slice_index].m_first_block_index;

			const uint32_t width = m_slices[slice_index].m_width;
			const uint32_t height = m_slices[slice_index].m_height;
			const uint32_t num_blocks_x = m_slices[slice_index].m_num_blocks_x;
			const uint32_t num_blocks_y = m_slices[slice_index].m_num_blocks_y;
			const int prev_frame_slice_index = find_video_frame(slice_index, -1);

			// If we don't have a previous frame, and we're not an i-frame, something is wrong.
			if ((prev_frame_slice_index < 0) && (!is_iframe))
			{
				BASISU_BACKEND_VERIFY(0);
			}

			if ((is_iframe) || (prev_frame_slice_index < 0))
			{
				// Ensure no blocks use CR's
				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++)
					{
						encoder_block& m = m_slice_encoder_blocks[slice_index](block_x, block_y);
						BASISU_BACKEND_VERIFY(m.m_endpoint_predictor != basist::CR_ENDPOINT_PRED_INDEX);
					}
				}
			}
			else
			{
				// For blocks that use CR's, make sure the endpoints/selectors haven't really changed.
				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++)
					{
						encoder_block& m = m_slice_encoder_blocks[slice_index](block_x, block_y);

						if (m.m_endpoint_predictor == basist::CR_ENDPOINT_PRED_INDEX)
						{
							total_crs++;

							encoder_block& prev_m = m_slice_encoder_blocks[prev_frame_slice_index](block_x, block_y);

							if ((m.m_endpoint_index != prev_m.m_endpoint_index) || (m.m_selector_index != prev_m.m_selector_index))
							{
								total_invalid_crs++;
							}
						}
					} // block_x
				} // block_y

			} // !slice_index

		} // slice_index

		debug_printf("Total CR's: %u, Total invalid CR's: %u\n", total_crs, total_invalid_crs);

		BASISU_BACKEND_VERIFY(total_invalid_crs == 0);
	}
	void basisu_backend::create_encoder_blocks()
	{
		basisu_frontend& r = *m_pFront_end;
		const bool is_video = r.get_params().m_tex_type == basist::cBASISTexTypeVideoFrames;

		m_slice_encoder_blocks.resize(m_slices.size());

		uint32_t total_endpoint_pred_missed = 0, total_endpoint_pred_hits = 0, total_block_endpoints_remapped = 0;

		uint_vec all_endpoint_indices;
		all_endpoint_indices.reserve(get_total_blocks());

		for (uint32_t slice_index = 0; slice_index < m_slices.size(); slice_index++)
		{
			const int prev_frame_slice_index = is_video ? find_video_frame(slice_index, -1) : -1;
			const bool is_iframe = m_slices[slice_index].m_iframe;
			const uint32_t first_block_index = m_slices[slice_index].m_first_block_index;

			const uint32_t width = m_slices[slice_index].m_width;
			const uint32_t height = m_slices[slice_index].m_height;
			const uint32_t num_blocks_x = m_slices[slice_index].m_num_blocks_x;
			const uint32_t num_blocks_y = m_slices[slice_index].m_num_blocks_y;

			m_slice_encoder_blocks[slice_index].resize(num_blocks_x, num_blocks_y);

			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++)
				{
					const uint32_t block_index = first_block_index + block_x + block_y * num_blocks_x;

					encoder_block& m = m_slice_encoder_blocks[slice_index](block_x, block_y);

					m.m_endpoint_index = r.get_subblock_endpoint_cluster_index(block_index, 0);
					BASISU_BACKEND_VERIFY(r.get_subblock_endpoint_cluster_index(block_index, 0) == r.get_subblock_endpoint_cluster_index(block_index, 1));

					m.m_selector_index = r.get_block_selector_cluster_index(block_index);

					m.m_endpoint_predictor = basist::NO_ENDPOINT_PRED_INDEX;

					const uint32_t block_endpoint = m.m_endpoint_index;

					uint32_t best_endpoint_pred = UINT32_MAX;

					for (uint32_t endpoint_pred = 0; endpoint_pred < basist::NUM_ENDPOINT_PREDS; endpoint_pred++)
					{
						if ((is_video) && (endpoint_pred == basist::CR_ENDPOINT_PRED_INDEX))
						{
							if ((prev_frame_slice_index != -1) && (!is_iframe))
							{
								const uint32_t cur_endpoint = m_slice_encoder_blocks[slice_index](block_x, block_y).m_endpoint_index;
								const uint32_t cur_selector = m_slice_encoder_blocks[slice_index](block_x, block_y).m_selector_index;
								const uint32_t prev_endpoint = m_slice_encoder_blocks[prev_frame_slice_index](block_x, block_y).m_endpoint_index;
								const uint32_t prev_selector = m_slice_encoder_blocks[prev_frame_slice_index](block_x, block_y).m_selector_index;
								if ((cur_endpoint == prev_endpoint) && (cur_selector == prev_selector))
								{
									best_endpoint_pred = basist::CR_ENDPOINT_PRED_INDEX;
									m_slice_encoder_blocks[prev_frame_slice_index](block_x, block_y).m_is_cr_target = true;
								}
							}
						}
						else
						{
							int pred_block_x = block_x + g_endpoint_preds[endpoint_pred].m_dx;
							if ((pred_block_x < 0) || (pred_block_x >= (int)num_blocks_x))
								continue;

							int pred_block_y = block_y + g_endpoint_preds[endpoint_pred].m_dy;
							if ((pred_block_y < 0) || (pred_block_y >= (int)num_blocks_y))
								continue;

							uint32_t pred_endpoint = m_slice_encoder_blocks[slice_index](pred_block_x, pred_block_y).m_endpoint_index;

							if (pred_endpoint == block_endpoint)
							{
								if (endpoint_pred < best_endpoint_pred)
								{
									best_endpoint_pred = endpoint_pred;
								}
							}
						}

					} // endpoint_pred

					if (best_endpoint_pred != UINT32_MAX)
					{
						m.m_endpoint_predictor = best_endpoint_pred;

						total_endpoint_pred_hits++;
					}
					else if (m_params.m_endpoint_rdo_quality_thresh > 0.0f)
					{
						const pixel_block& src_pixels = r.get_source_pixel_block(block_index);

						etc_block etc_blk(r.get_output_block(block_index));

						uint64_t cur_err = etc_blk.evaluate_etc1_error(src_pixels.get_ptr(), r.get_params().m_perceptual);

						if (cur_err)
						{
							const uint64_t thresh_err = (uint64_t)(cur_err * maximum(1.0f, m_params.m_endpoint_rdo_quality_thresh));

							etc_block trial_etc_block(etc_blk);

							uint64_t best_err = UINT64_MAX;
							uint32_t best_endpoint_index = 0;

							best_endpoint_pred = UINT32_MAX;

							for (uint32_t endpoint_pred = 0; endpoint_pred < basist::NUM_ENDPOINT_PREDS; endpoint_pred++)
							{
								if ((is_video) && (endpoint_pred == basist::CR_ENDPOINT_PRED_INDEX))
									continue;
								int pred_block_x = block_x + g_endpoint_preds[endpoint_pred].m_dx;
								if ((pred_block_x < 0) || (pred_block_x >= (int)num_blocks_x))
									continue;

								int pred_block_y = block_y + g_endpoint_preds[endpoint_pred].m_dy;
								if ((pred_block_y < 0) || (pred_block_y >= (int)num_blocks_y))
									continue;

								uint32_t pred_endpoint_index = m_slice_encoder_blocks[slice_index](pred_block_x, pred_block_y).m_endpoint_index;

								uint32_t pred_inten = r.get_endpoint_cluster_inten_table(pred_endpoint_index, false);
								color_rgba pred_color = r.get_endpoint_cluster_unscaled_color(pred_endpoint_index, false);

								trial_etc_block.set_block_color5(pred_color, pred_color);
								trial_etc_block.set_inten_table(0, pred_inten);
								trial_etc_block.set_inten_table(1, pred_inten);

								color_rgba trial_colors[16];
								unpack_etc1(trial_etc_block, trial_colors);

								uint64_t trial_err = 0;
								for (uint32_t p = 0; p < 16; p++)
								{
									trial_err += color_distance(r.get_params().m_perceptual, src_pixels.get_ptr()[p], trial_colors[p], false);
									if (trial_err > thresh_err)
										break;
								}

								if (trial_err <= thresh_err)
								{
									if ((trial_err < best_err) || ((trial_err == best_err) && (endpoint_pred < best_endpoint_pred)))
									{
										best_endpoint_pred = endpoint_pred;
										best_err = trial_err;
										best_endpoint_index = pred_endpoint_index;
									}
								}
							} // endpoint_pred

							if (best_endpoint_pred != UINT32_MAX)
							{
								m.m_endpoint_index = best_endpoint_index;
								m.m_endpoint_predictor = best_endpoint_pred;

								total_endpoint_pred_hits++;
								total_block_endpoints_remapped++;
							}
							else
							{
								total_endpoint_pred_missed++;
							}
						}
					}
					else
					{
						total_endpoint_pred_missed++;
					}

					if (m.m_endpoint_predictor == basist::NO_ENDPOINT_PRED_INDEX)
					{
						all_endpoint_indices.push_back(m.m_endpoint_index);
					}

				} // block_x

			} // block_y

		} // slice

		debug_printf("total_endpoint_pred_missed: %u (%3.2f%%) total_endpoint_pred_hit: %u (%3.2f%%), total_block_endpoints_remapped: %u (%3.2f%%)\n",
			total_endpoint_pred_missed, total_endpoint_pred_missed * 100.0f / get_total_blocks(),
			total_endpoint_pred_hits, total_endpoint_pred_hits * 100.0f / get_total_blocks(),
			total_block_endpoints_remapped, total_block_endpoints_remapped * 100.0f / get_total_blocks());

		reoptimize_and_sort_endpoints_codebook(total_block_endpoints_remapped, all_endpoint_indices);

		sort_selector_codebook();
		check_for_valid_cr_blocks();
	}

	void basisu_backend::compute_slice_crcs()
	{
		for (uint32_t slice_index = 0; slice_index < m_slices.size(); slice_index++)
		{
			const uint32_t first_block_index = m_slices[slice_index].m_first_block_index;
			const uint32_t width = m_slices[slice_index].m_width;
			const uint32_t height = m_slices[slice_index].m_height;
			const uint32_t num_blocks_x = m_slices[slice_index].m_num_blocks_x;
			const uint32_t num_blocks_y = m_slices[slice_index].m_num_blocks_y;

			gpu_image gi;
			gi.init(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++)
				{
					const uint32_t block_index = first_block_index + block_x + block_y * num_blocks_x;

					encoder_block& m = m_slice_encoder_blocks[slice_index](block_x, block_y);

					{
						etc_block& output_block = *(etc_block*)gi.get_block_ptr(block_x, block_y);

						output_block.set_diff_bit(true);
						output_block.set_flip_bit(true);

						const uint32_t endpoint_index = m.m_endpoint_index;

						output_block.set_block_color5_etc1s(m_endpoint_palette[endpoint_index].m_color5);
						output_block.set_inten_tables_etc1s(m_endpoint_palette[endpoint_index].m_inten5);

						const uint32_t selector_idx = m.m_selector_index;

						const basist::etc1_selector_palette_entry& selectors = m_selector_palette[selector_idx];
						for (uint32_t sy = 0; sy < 4; sy++)
							for (uint32_t sx = 0; sx < 4; sx++)
								output_block.set_selector(sx, sy, selectors(sx, sy));
					}

				} // block_x
			} // block_y

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

			if (m_params.m_debug_images)
			{
				image gi_unpacked;
				gi.unpack(gi_unpacked);

				char buf[256];
#ifdef _WIN32				
				sprintf_s(buf, sizeof(buf), "basisu_backend_slice_%u.png", slice_index);
#else
				snprintf(buf, sizeof(buf), "basisu_backend_slice_%u.png", slice_index);
#endif				
				save_png(buf, gi_unpacked);
			}

		} // slice_index
	}

	// TODO: Split this into multiple methods.
	bool basisu_backend::encode_image()
	{
		basisu_frontend& r = *m_pFront_end;
		const bool is_video = r.get_params().m_tex_type == basist::cBASISTexTypeVideoFrames;

		uint32_t total_used_selector_history_buf = 0;
		uint32_t total_selector_indices_remapped = 0;

		basist::approx_move_to_front selector_history_buf(basist::MAX_SELECTOR_HISTORY_BUF_SIZE);
		histogram selector_history_buf_histogram(basist::MAX_SELECTOR_HISTORY_BUF_SIZE);
		histogram selector_histogram(r.get_total_selector_clusters() + basist::MAX_SELECTOR_HISTORY_BUF_SIZE + 1);
		histogram selector_history_buf_rle_histogram(1 << basist::SELECTOR_HISTORY_BUF_RLE_COUNT_BITS);

		std::vector<uint_vec> selector_syms(m_slices.size());

		const uint32_t SELECTOR_HISTORY_BUF_FIRST_SYMBOL_INDEX = r.get_total_selector_clusters();
		const uint32_t SELECTOR_HISTORY_BUF_RLE_SYMBOL_INDEX = SELECTOR_HISTORY_BUF_FIRST_SYMBOL_INDEX + basist::MAX_SELECTOR_HISTORY_BUF_SIZE;

		m_output.m_slice_image_crcs.resize(m_slices.size());

		histogram delta_endpoint_histogram(r.get_total_endpoint_clusters());

		histogram endpoint_pred_histogram(basist::ENDPOINT_PRED_TOTAL_SYMBOLS);
		std::vector<uint_vec> endpoint_pred_syms(m_slices.size());

		uint32_t total_endpoint_indices_remapped = 0;

		uint_vec block_endpoint_indices, block_selector_indices;

		for (uint32_t slice_index = 0; slice_index < m_slices.size(); slice_index++)
		{
			const int prev_frame_slice_index = is_video ? find_video_frame(slice_index, -1) : -1;
			const int next_frame_slice_index = is_video ? find_video_frame(slice_index, 1) : -1;
			const uint32_t first_block_index = m_slices[slice_index].m_first_block_index;
			const uint32_t width = m_slices[slice_index].m_width;
			const uint32_t height = m_slices[slice_index].m_height;
			const uint32_t num_blocks_x = m_slices[slice_index].m_num_blocks_x;
			const uint32_t num_blocks_y = m_slices[slice_index].m_num_blocks_y;

			selector_history_buf.reset();

			int selector_history_buf_rle_count = 0;

			int prev_endpoint_pred_sym_bits = -1, endpoint_pred_repeat_count = 0;

			uint32_t prev_endpoint_index = 0;

			vector2D<uint8_t> block_endpoints_are_referenced(num_blocks_x, num_blocks_y);

			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++)
				{
					const uint32_t block_index = first_block_index + block_x + block_y * num_blocks_x;

					encoder_block& m = m_slice_encoder_blocks[slice_index](block_x, block_y);

					if (m.m_endpoint_predictor == 0)
						block_endpoints_are_referenced(block_x - 1, block_y) = true;
					else if (m.m_endpoint_predictor == 1)
						block_endpoints_are_referenced(block_x, block_y - 1) = true;
					else if (m.m_endpoint_predictor == 2)
					{
						if (!is_video)
							block_endpoints_are_referenced(block_x - 1, block_y - 1) = true;
					}
					if (is_video)
					{
						if (m.m_is_cr_target)
							block_endpoints_are_referenced(block_x, block_y) = true;
					}

				}  // block_x
			} // block_y
			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++)
				{
					const uint32_t block_index = first_block_index + block_x + block_y * num_blocks_x;

					encoder_block& m = m_slice_encoder_blocks[slice_index](block_x, block_y);

					if (((block_x & 1) == 0) && ((block_y & 1) == 0))
					{
						uint32_t endpoint_pred_cur_sym_bits = 0;

						for (uint32_t y = 0; y < 2; y++)
						{
							for (uint32_t x = 0; x < 2; x++)
							{
								const uint32_t bx = block_x + x;
								const uint32_t by = block_y + y;

								uint32_t pred = basist::NO_ENDPOINT_PRED_INDEX;
								if ((bx < num_blocks_x) && (by < num_blocks_y))
									pred = m_slice_encoder_blocks[slice_index](bx, by).m_endpoint_predictor;

								endpoint_pred_cur_sym_bits |= (pred << (x * 2 + y * 4));
							}
						}

						if ((int)endpoint_pred_cur_sym_bits == prev_endpoint_pred_sym_bits)
						{
							endpoint_pred_repeat_count++;
						}
						else
						{
							if (endpoint_pred_repeat_count > 0)
							{
								if (endpoint_pred_repeat_count > (int)basist::ENDPOINT_PRED_MIN_REPEAT_COUNT)
								{
									endpoint_pred_histogram.inc(basist::ENDPOINT_PRED_REPEAT_LAST_SYMBOL);
									endpoint_pred_syms[slice_index].push_back(basist::ENDPOINT_PRED_REPEAT_LAST_SYMBOL);

									endpoint_pred_syms[slice_index].push_back(endpoint_pred_repeat_count);
								}
								else
								{
									for (int j = 0; j < endpoint_pred_repeat_count; j++)
									{
										endpoint_pred_histogram.inc(prev_endpoint_pred_sym_bits);
										endpoint_pred_syms[slice_index].push_back(prev_endpoint_pred_sym_bits);
									}
								}

								endpoint_pred_repeat_count = 0;
							}

							endpoint_pred_histogram.inc(endpoint_pred_cur_sym_bits);
							endpoint_pred_syms[slice_index].push_back(endpoint_pred_cur_sym_bits);

							prev_endpoint_pred_sym_bits = endpoint_pred_cur_sym_bits;
						}
					}

					int new_endpoint_index = m_endpoint_remap_table_old_to_new[m.m_endpoint_index];

					if (m.m_endpoint_predictor == basist::NO_ENDPOINT_PRED_INDEX)
					{
						int endpoint_delta = new_endpoint_index - prev_endpoint_index;

						if ((m_params.m_endpoint_rdo_quality_thresh > 1.0f) && (iabs(endpoint_delta) > 1) && (!block_endpoints_are_referenced(block_x, block_y)))
						{
							const pixel_block& src_pixels = r.get_source_pixel_block(block_index);

							etc_block etc_blk(r.get_output_block(block_index));

							const uint64_t cur_err = etc_blk.evaluate_etc1_error(src_pixels.get_ptr(), r.get_params().m_perceptual);

							if (cur_err)
							{
								const float endpoint_remap_thresh = maximum(1.0f, m_params.m_endpoint_rdo_quality_thresh);
								const uint64_t thresh_err = (uint64_t)(cur_err * endpoint_remap_thresh);

								uint64_t best_trial_err = UINT64_MAX;
								int best_trial_idx = 0;

								etc_block trial_etc_blk(etc_blk);

								const int MAX_ENDPOINT_SEARCH_DIST = 32;
								const int search_dist = minimum<int>(iabs(endpoint_delta) - 1, MAX_ENDPOINT_SEARCH_DIST);
								for (int d = -search_dist; d < search_dist; d++)
								{
									int trial_idx = prev_endpoint_index + d;
									if (trial_idx < 0)
										trial_idx += (int)r.get_total_endpoint_clusters();
									else if (trial_idx >= (int)r.get_total_endpoint_clusters())
										trial_idx -= (int)r.get_total_endpoint_clusters();

									if (trial_idx == new_endpoint_index)
										continue;

									const etc1_endpoint_palette_entry& p = m_endpoint_palette[m_endpoint_remap_table_new_to_old[trial_idx]];
									trial_etc_blk.set_block_color5_etc1s(p.m_color5);
									trial_etc_blk.set_inten_tables_etc1s(p.m_inten5);

									uint64_t trial_err = trial_etc_blk.evaluate_etc1_error(src_pixels.get_ptr(), r.get_params().m_perceptual);

									if (trial_err <= thresh_err)
									{
										if (trial_err < best_trial_err)
										{
											best_trial_err = trial_err;
											best_trial_idx = trial_idx;
										}
									}
								}

								if (best_trial_err != UINT64_MAX)
								{
									m.m_endpoint_index = m_endpoint_remap_table_new_to_old[best_trial_idx];

									new_endpoint_index = best_trial_idx;

									endpoint_delta = new_endpoint_index - prev_endpoint_index;

									total_endpoint_indices_remapped++;
								}
							}
						}

						if (endpoint_delta < 0)
							endpoint_delta += (int)r.get_total_endpoint_clusters();

						delta_endpoint_histogram.inc(endpoint_delta);
					}

					block_endpoint_indices.push_back(m_endpoint_remap_table_new_to_old[new_endpoint_index]);

					prev_endpoint_index = new_endpoint_index;

					if ((!is_video) || (m.m_endpoint_predictor != basist::CR_ENDPOINT_PRED_INDEX))
					{
						int new_selector_index = m_selector_remap_table_old_to_new[m.m_selector_index];

						int selector_history_buf_index = -1;

						if (m.m_is_cr_target)
						{
							for (uint32_t j = 0; j < selector_history_buf.size(); j++)
							{
								const int trial_idx = selector_history_buf[j];
								if (trial_idx == new_selector_index)
								{
									total_used_selector_history_buf++;
									selector_history_buf_index = j;
									selector_history_buf_histogram.inc(j);
									break;
								}
							}
						}
						else
						{
							const pixel_block& src_pixels = r.get_source_pixel_block(block_index);

							etc_block etc_blk(r.get_output_block(block_index));

							color_rgba etc_blk_unpacked[16];
							unpack_etc1(etc_blk, etc_blk_unpacked);

							uint64_t cur_err = 0;
							for (uint32_t p = 0; p < 16; p++)
								cur_err += color_distance(r.get_params().m_perceptual, src_pixels.get_ptr()[p], etc_blk_unpacked[p], false);

							uint64_t best_trial_err = UINT64_MAX;
							int best_trial_idx = 0;
							uint32_t best_trial_history_buf_idx = 0;


							const float selector_remap_thresh = maximum(1.0f, m_params.m_selector_rdo_quality_thresh); //2.5f;
							const bool use_strict_search = (m_params.m_compression_level == 0) && (selector_remap_thresh == 1.0f);

							for (uint32_t j = 0; j < selector_history_buf.size(); j++)
							{
								const int trial_idx = selector_history_buf[j];

								if (use_strict_search)
								{
									if (trial_idx == new_selector_index)
									{
										best_trial_err = 0;
										best_trial_idx = trial_idx;
										best_trial_history_buf_idx = j;
										break;
									}
								}
								else
								{
									for (uint32_t sy = 0; sy < 4; sy++)
										for (uint32_t sx = 0; sx < 4; sx++)
											etc_blk.set_selector(sx, sy, m_selector_palette[m_selector_remap_table_new_to_old[trial_idx]](sx, sy));

									// TODO: Optimize this
									unpack_etc1(etc_blk, etc_blk_unpacked);

									uint64_t trial_err = 0;
									const uint64_t thresh_err = minimum((uint64_t)ceilf(cur_err * selector_remap_thresh), best_trial_err);
									for (uint32_t p = 0; p < 16; p++)
									{
										trial_err += color_distance(r.get_params().m_perceptual, src_pixels.get_ptr()[p], etc_blk_unpacked[p], false);
										if (trial_err > thresh_err)
											break;
									}

									if (trial_err <= cur_err * selector_remap_thresh)
									{
										if (trial_err < best_trial_err)
										{
											best_trial_err = trial_err;
											best_trial_idx = trial_idx;
											best_trial_history_buf_idx = j;
										}
									}
								}
							}

							if (best_trial_err != UINT64_MAX)
							{
								if (new_selector_index != best_trial_idx)
									total_selector_indices_remapped++;

								new_selector_index = best_trial_idx;

								total_used_selector_history_buf++;

								selector_history_buf_index = best_trial_history_buf_idx;

								selector_history_buf_histogram.inc(best_trial_history_buf_idx);
							}
						} // if (m_params.m_selector_rdo_quality_thresh > 0.0f)

						m.m_selector_index = m_selector_remap_table_new_to_old[new_selector_index];


						if ((selector_history_buf_rle_count) && (selector_history_buf_index != 0))
						{
							if (selector_history_buf_rle_count >= (int)basist::SELECTOR_HISTORY_BUF_RLE_COUNT_THRESH)
							{
								selector_syms[slice_index].push_back(SELECTOR_HISTORY_BUF_RLE_SYMBOL_INDEX);
								selector_syms[slice_index].push_back(selector_history_buf_rle_count);

								int run_sym = selector_history_buf_rle_count - basist::SELECTOR_HISTORY_BUF_RLE_COUNT_THRESH;
								if (run_sym >= ((int)basist::SELECTOR_HISTORY_BUF_RLE_COUNT_TOTAL - 1))
									selector_history_buf_rle_histogram.inc(basist::SELECTOR_HISTORY_BUF_RLE_COUNT_TOTAL - 1);
								else
									selector_history_buf_rle_histogram.inc(run_sym);

								selector_histogram.inc(SELECTOR_HISTORY_BUF_RLE_SYMBOL_INDEX);
							}
							else
							{
								for (int k = 0; k < selector_history_buf_rle_count; k++)
								{
									uint32_t sym_index = SELECTOR_HISTORY_BUF_FIRST_SYMBOL_INDEX + 0;

									selector_syms[slice_index].push_back(sym_index);

									selector_histogram.inc(sym_index);
								}
							}

							selector_history_buf_rle_count = 0;
						}

						if (selector_history_buf_index >= 0)
						{
							if (selector_history_buf_index == 0)
								selector_history_buf_rle_count++;
							else
							{
								uint32_t history_buf_sym = SELECTOR_HISTORY_BUF_FIRST_SYMBOL_INDEX + selector_history_buf_index;

								selector_syms[slice_index].push_back(history_buf_sym);

								selector_histogram.inc(history_buf_sym);
							}
						}
						else
						{
							selector_syms[slice_index].push_back(new_selector_index);

							selector_histogram.inc(new_selector_index);
						}

						m.m_selector_history_buf_index = selector_history_buf_index;

						if (selector_history_buf_index < 0)
							selector_history_buf.add(new_selector_index);
						else if (selector_history_buf.size())
							selector_history_buf.use(selector_history_buf_index);
					}
					block_selector_indices.push_back(m.m_selector_index);

				} // block_x

			} // block_y

			if (endpoint_pred_repeat_count > 0)
			{
				if (endpoint_pred_repeat_count > (int)basist::ENDPOINT_PRED_MIN_REPEAT_COUNT)
				{
					endpoint_pred_histogram.inc(basist::ENDPOINT_PRED_REPEAT_LAST_SYMBOL);
					endpoint_pred_syms[slice_index].push_back(basist::ENDPOINT_PRED_REPEAT_LAST_SYMBOL);

					endpoint_pred_syms[slice_index].push_back(endpoint_pred_repeat_count);
				}
				else
				{
					for (int j = 0; j < endpoint_pred_repeat_count; j++)
					{
						endpoint_pred_histogram.inc(prev_endpoint_pred_sym_bits);
						endpoint_pred_syms[slice_index].push_back(prev_endpoint_pred_sym_bits);
					}
				}

				endpoint_pred_repeat_count = 0;
			}

			if (selector_history_buf_rle_count)
			{
				if (selector_history_buf_rle_count >= (int)basist::SELECTOR_HISTORY_BUF_RLE_COUNT_THRESH)
				{
					selector_syms[slice_index].push_back(SELECTOR_HISTORY_BUF_RLE_SYMBOL_INDEX);
					selector_syms[slice_index].push_back(selector_history_buf_rle_count);

					int run_sym = selector_history_buf_rle_count - basist::SELECTOR_HISTORY_BUF_RLE_COUNT_THRESH;
					if (run_sym >= ((int)basist::SELECTOR_HISTORY_BUF_RLE_COUNT_TOTAL - 1))
						selector_history_buf_rle_histogram.inc(basist::SELECTOR_HISTORY_BUF_RLE_COUNT_TOTAL - 1);
					else
						selector_history_buf_rle_histogram.inc(run_sym);

					selector_histogram.inc(SELECTOR_HISTORY_BUF_RLE_SYMBOL_INDEX);
				}
				else
				{
					for (int i = 0; i < selector_history_buf_rle_count; i++)
					{
						uint32_t sym_index = SELECTOR_HISTORY_BUF_FIRST_SYMBOL_INDEX + 0;

						selector_syms[slice_index].push_back(sym_index);

						selector_histogram.inc(sym_index);
					}
				}

				selector_history_buf_rle_count = 0;
			}

		} // slice_index

		debug_printf("Endpoint pred RDO total endpoint indices remapped: %u %3.2f%%\n",
			total_endpoint_indices_remapped, total_endpoint_indices_remapped * 100.0f / get_total_blocks());

		debug_printf("Selector history RDO total selector indices remapped: %u %3.2f%%, Used history buf: %u %3.2f%%\n",
			total_selector_indices_remapped, total_selector_indices_remapped * 100.0f / get_total_blocks(),
			total_used_selector_history_buf, total_used_selector_history_buf * 100.0f / get_total_blocks());

		if ((total_endpoint_indices_remapped) && (m_params.m_compression_level > 0))
		{
			int_vec unused;
			r.reoptimize_remapped_endpoints(block_endpoint_indices, unused, false, &block_selector_indices);

			create_endpoint_palette();
		}

		check_for_valid_cr_blocks();
		compute_slice_crcs();

		double endpoint_pred_entropy = endpoint_pred_histogram.get_entropy() / endpoint_pred_histogram.get_total();
		double delta_endpoint_entropy = delta_endpoint_histogram.get_entropy() / delta_endpoint_histogram.get_total();
		double selector_entropy = selector_histogram.get_entropy() / selector_histogram.get_total();

		debug_printf("Histogram entropy: EndpointPred: %3.3f DeltaEndpoint: %3.3f DeltaSelector: %3.3f\n", endpoint_pred_entropy, delta_endpoint_entropy, selector_entropy);

		if (!endpoint_pred_histogram.get_total())
			endpoint_pred_histogram.inc(0);
		huffman_encoding_table endpoint_pred_model;
		if (!endpoint_pred_model.init(endpoint_pred_histogram, 16))
		{
			error_printf("endpoint_pred_model.init() failed!");
			return false;
		}

		if (!delta_endpoint_histogram.get_total())
			delta_endpoint_histogram.inc(0);
		huffman_encoding_table delta_endpoint_model;
		if (!delta_endpoint_model.init(delta_endpoint_histogram, 16))
		{
			error_printf("delta_endpoint_model.init() failed!");
			return false;
		}
		if (!selector_histogram.get_total())
			selector_histogram.inc(0);

		huffman_encoding_table selector_model;
		if (!selector_model.init(selector_histogram, 16))
		{
			error_printf("selector_model.init() failed!");
			return false;
		}

		if (!selector_history_buf_rle_histogram.get_total())
			selector_history_buf_rle_histogram.inc(0);

		huffman_encoding_table selector_history_buf_rle_model;
		if (!selector_history_buf_rle_model.init(selector_history_buf_rle_histogram, 16))
		{
			error_printf("selector_history_buf_rle_model.init() failed!");
			return false;
		}

		bitwise_coder coder;
		coder.init(1024 * 1024 * 4);

		uint32_t endpoint_pred_model_bits = coder.emit_huffman_table(endpoint_pred_model);
		uint32_t delta_endpoint_bits = coder.emit_huffman_table(delta_endpoint_model);
		uint32_t selector_model_bits = coder.emit_huffman_table(selector_model);
		uint32_t selector_history_buf_run_sym_bits = coder.emit_huffman_table(selector_history_buf_rle_model);

		coder.put_bits(basist::MAX_SELECTOR_HISTORY_BUF_SIZE, 13);

		debug_printf("Model sizes: EndpointPred: %u bits %u bytes (%3.3f bpp) DeltaEndpoint: %u bits %u bytes (%3.3f bpp) Selector: %u bits %u bytes (%3.3f bpp) SelectorHistBufRLE: %u bits %u bytes (%3.3f bpp)\n",
			endpoint_pred_model_bits, (endpoint_pred_model_bits + 7) / 8, endpoint_pred_model_bits / float(get_total_input_texels()),
			delta_endpoint_bits, (delta_endpoint_bits + 7) / 8, delta_endpoint_bits / float(get_total_input_texels()),
			selector_model_bits, (selector_model_bits + 7) / 8, selector_model_bits / float(get_total_input_texels()),
			selector_history_buf_run_sym_bits, (selector_history_buf_run_sym_bits + 7) / 8, selector_history_buf_run_sym_bits / float(get_total_input_texels()));

		coder.flush();

		m_output.m_slice_image_tables = coder.get_bytes();

		uint32_t total_endpoint_pred_bits = 0, total_delta_endpoint_bits = 0, total_selector_bits = 0;

		uint32_t total_image_bytes = 0;

		m_output.m_slice_image_data.resize(m_slices.size());

		for (uint32_t slice_index = 0; slice_index < m_slices.size(); slice_index++)
		{
			const uint32_t width = m_slices[slice_index].m_width;
			const uint32_t height = m_slices[slice_index].m_height;
			const uint32_t num_blocks_x = m_slices[slice_index].m_num_blocks_x;
			const uint32_t num_blocks_y = m_slices[slice_index].m_num_blocks_y;

			coder.init(1024 * 1024 * 4);

			uint32_t cur_selector_sym_ofs = 0;
			uint32_t selector_rle_count = 0;

			int endpoint_pred_repeat_count = 0;
			uint32_t cur_endpoint_pred_sym_ofs = 0;
//			uint32_t prev_endpoint_pred_sym = 0;
			uint32_t prev_endpoint_index = 0;

			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++)
				{
					const encoder_block& m = m_slice_encoder_blocks[slice_index](block_x, block_y);

					if (((block_x & 1) == 0) && ((block_y & 1) == 0))
					{
						if (endpoint_pred_repeat_count > 0)
						{
							endpoint_pred_repeat_count--;
						}
						else
						{
							uint32_t sym = endpoint_pred_syms[slice_index][cur_endpoint_pred_sym_ofs++];

							if (sym == basist::ENDPOINT_PRED_REPEAT_LAST_SYMBOL)
							{
								total_endpoint_pred_bits += coder.put_code(sym, endpoint_pred_model);

								endpoint_pred_repeat_count = endpoint_pred_syms[slice_index][cur_endpoint_pred_sym_ofs++];
								assert(endpoint_pred_repeat_count >= (int)basist::ENDPOINT_PRED_MIN_REPEAT_COUNT);

								total_endpoint_pred_bits += coder.put_vlc(endpoint_pred_repeat_count - basist::ENDPOINT_PRED_MIN_REPEAT_COUNT, basist::ENDPOINT_PRED_COUNT_VLC_BITS);

								endpoint_pred_repeat_count--;
							}
							else
							{
								total_endpoint_pred_bits += coder.put_code(sym, endpoint_pred_model);

								//prev_endpoint_pred_sym = sym;
							}
						}
					}

					const int new_endpoint_index = m_endpoint_remap_table_old_to_new[m.m_endpoint_index];

					if (m.m_endpoint_predictor == basist::NO_ENDPOINT_PRED_INDEX)
					{
						int endpoint_delta = new_endpoint_index - prev_endpoint_index;
						if (endpoint_delta < 0)
							endpoint_delta += (int)r.get_total_endpoint_clusters();

						total_delta_endpoint_bits += coder.put_code(endpoint_delta, delta_endpoint_model);
					}

					prev_endpoint_index = new_endpoint_index;

					if ((!is_video) || (m.m_endpoint_predictor != basist::CR_ENDPOINT_PRED_INDEX))
					{
						if (!selector_rle_count)
						{
							uint32_t selector_sym_index = selector_syms[slice_index][cur_selector_sym_ofs++];

							if (selector_sym_index == SELECTOR_HISTORY_BUF_RLE_SYMBOL_INDEX)
								selector_rle_count = selector_syms[slice_index][cur_selector_sym_ofs++];

							total_selector_bits += coder.put_code(selector_sym_index, selector_model);

							if (selector_sym_index == SELECTOR_HISTORY_BUF_RLE_SYMBOL_INDEX)
							{
								int run_sym = selector_rle_count - basist::SELECTOR_HISTORY_BUF_RLE_COUNT_THRESH;
								if (run_sym >= ((int)basist::SELECTOR_HISTORY_BUF_RLE_COUNT_TOTAL - 1))
								{
									total_selector_bits += coder.put_code(basist::SELECTOR_HISTORY_BUF_RLE_COUNT_TOTAL - 1, selector_history_buf_rle_model);

									uint32_t n = selector_rle_count - basist::SELECTOR_HISTORY_BUF_RLE_COUNT_THRESH;
									total_selector_bits += coder.put_vlc(n, 7);
								}
								else
									total_selector_bits += coder.put_code(run_sym, selector_history_buf_rle_model);
							}
						}

						if (selector_rle_count)
							selector_rle_count--;
					}

				} // block_x

			} // block_y

			BASISU_BACKEND_VERIFY(cur_endpoint_pred_sym_ofs == endpoint_pred_syms[slice_index].size());
			BASISU_BACKEND_VERIFY(cur_selector_sym_ofs == selector_syms[slice_index].size());

			coder.flush();

			m_output.m_slice_image_data[slice_index] = coder.get_bytes();

			total_image_bytes += (uint32_t)coder.get_bytes().size();

			debug_printf("Slice %u compressed size: %u bytes, %3.3f bits per slice texel\n", slice_index, m_output.m_slice_image_data[slice_index].size(), m_output.m_slice_image_data[slice_index].size() * 8.0f / (m_slices[slice_index].m_orig_width * m_slices[slice_index].m_orig_height));

		} // slice_index

		const double total_texels = static_cast<double>(get_total_input_texels());
		const double total_blocks = static_cast<double>(get_total_blocks());

		debug_printf("Total endpoint pred bits: %u bytes: %u bits/texel: %3.3f bits/block: %3.3f\n", total_endpoint_pred_bits, total_endpoint_pred_bits / 8, total_endpoint_pred_bits / total_texels, total_endpoint_pred_bits / total_blocks);
		debug_printf("Total delta endpoint bits: %u bytes: %u bits/texel: %3.3f bits/block: %3.3f\n", total_delta_endpoint_bits, total_delta_endpoint_bits / 8, total_delta_endpoint_bits / total_texels, total_delta_endpoint_bits / total_blocks);
		debug_printf("Total selector bits: %u bytes: %u bits/texel: %3.3f bits/block: %3.3f\n", total_selector_bits, total_selector_bits / 8, total_selector_bits / total_texels, total_selector_bits / total_blocks);

		debug_printf("Total table bytes: %u, %3.3f bits/texel\n", m_output.m_slice_image_tables.size(), m_output.m_slice_image_tables.size() * 8.0f / total_texels);
		debug_printf("Total image bytes: %u, %3.3f bits/texel\n", total_image_bytes, total_image_bytes * 8.0f / total_texels);

		return true;
	}

	bool basisu_backend::encode_endpoint_palette()
	{
		const basisu_frontend& r = *m_pFront_end;

		// Maps NEW to OLD endpoints
		uint_vec endpoint_remap_table_inv(r.get_total_endpoint_clusters());
		for (uint32_t old_endpoint_index = 0; old_endpoint_index < m_endpoint_remap_table_old_to_new.size(); old_endpoint_index++)
			endpoint_remap_table_inv[m_endpoint_remap_table_old_to_new[old_endpoint_index]] = old_endpoint_index;

		bool is_grayscale = true;
		for (uint32_t old_endpoint_index = 0; old_endpoint_index < (uint32_t)m_endpoint_palette.size(); old_endpoint_index++)
		{
			int r5 = m_endpoint_palette[old_endpoint_index].m_color5[0];
			int g5 = m_endpoint_palette[old_endpoint_index].m_color5[1];
			int b5 = m_endpoint_palette[old_endpoint_index].m_color5[2];
			if ((r5 != g5) || (r5 != b5))
			{
				is_grayscale = false;
				break;
			}
		}

		histogram color5_delta_hist0(32); // prev 0-9, delta is -9 to 31
		histogram color5_delta_hist1(32); // prev 10-21, delta is -21 to 21
		histogram color5_delta_hist2(32); // prev 22-31, delta is -31 to 9
		histogram inten_delta_hist(8);

		color_rgba prev_color5(16, 16, 16, 0);
		uint32_t prev_inten = 0;

		for (uint32_t new_endpoint_index = 0; new_endpoint_index < r.get_total_endpoint_clusters(); new_endpoint_index++)
		{
			const uint32_t old_endpoint_index = endpoint_remap_table_inv[new_endpoint_index];

			int delta_inten = m_endpoint_palette[old_endpoint_index].m_inten5 - prev_inten;
			inten_delta_hist.inc(delta_inten & 7);
			prev_inten = m_endpoint_palette[old_endpoint_index].m_inten5;

			for (uint32_t i = 0; i < (is_grayscale ? 1U : 3U); i++)
			{
				const int delta = (m_endpoint_palette[old_endpoint_index].m_color5[i] - prev_color5[i]) & 31;

				if (prev_color5[i] <= basist::COLOR5_PAL0_PREV_HI)
					color5_delta_hist0.inc(delta);
				else if (prev_color5[i] <= basist::COLOR5_PAL1_PREV_HI)
					color5_delta_hist1.inc(delta);
				else
					color5_delta_hist2.inc(delta);

				prev_color5[i] = m_endpoint_palette[old_endpoint_index].m_color5[i];
			}
		}

		if (!color5_delta_hist0.get_total()) color5_delta_hist0.inc(0);
		if (!color5_delta_hist1.get_total()) color5_delta_hist1.inc(0);
		if (!color5_delta_hist2.get_total()) color5_delta_hist2.inc(0);

		huffman_encoding_table color5_delta_model0, color5_delta_model1, color5_delta_model2, inten_delta_model;
		if (!color5_delta_model0.init(color5_delta_hist0, 16))
		{
			error_printf("color5_delta_model.init() failed!");
			return false;
		}

		if (!color5_delta_model1.init(color5_delta_hist1, 16))
		{
			error_printf("color5_delta_model.init() failed!");
			return false;
		}

		if (!color5_delta_model2.init(color5_delta_hist2, 16))
		{
			error_printf("color5_delta_model.init() failed!");
			return false;
		}

		if (!inten_delta_model.init(inten_delta_hist, 16))
		{
			error_printf("inten3_model.init() failed!");
			return false;
		}

		bitwise_coder coder;

		coder.init(8192);

		coder.emit_huffman_table(color5_delta_model0);
		coder.emit_huffman_table(color5_delta_model1);
		coder.emit_huffman_table(color5_delta_model2);
		coder.emit_huffman_table(inten_delta_model);

		coder.put_bits(is_grayscale, 1);

		prev_color5.set(16, 16, 16, 0);
		prev_inten = 0;

		for (uint32_t new_endpoint_index = 0; new_endpoint_index < r.get_total_endpoint_clusters(); new_endpoint_index++)
		{
			const uint32_t old_endpoint_index = endpoint_remap_table_inv[new_endpoint_index];

			int delta_inten = (m_endpoint_palette[old_endpoint_index].m_inten5 - prev_inten) & 7;
			coder.put_code(delta_inten, inten_delta_model);
			prev_inten = m_endpoint_palette[old_endpoint_index].m_inten5;

			for (uint32_t i = 0; i < (is_grayscale ? 1U : 3U); i++)
			{
				const int delta = (m_endpoint_palette[old_endpoint_index].m_color5[i] - prev_color5[i]) & 31;

				if (prev_color5[i] <= basist::COLOR5_PAL0_PREV_HI)
					coder.put_code(delta, color5_delta_model0);
				else if (prev_color5[i] <= basist::COLOR5_PAL1_PREV_HI)
					coder.put_code(delta, color5_delta_model1);
				else
					coder.put_code(delta, color5_delta_model2);

				prev_color5[i] = m_endpoint_palette[old_endpoint_index].m_color5[i];
			}

		} // q

		coder.flush();

		m_output.m_endpoint_palette = coder.get_bytes();

		debug_printf("Endpoint codebook size: %u bits %u bytes, Bits per entry: %3.1f, Avg bits/texel: %3.3f\n",
			8 * (int)m_output.m_endpoint_palette.size(), (int)m_output.m_endpoint_palette.size(), m_output.m_endpoint_palette.size() * 8.0f / r.get_total_endpoint_clusters(), m_output.m_endpoint_palette.size() * 8.0f / get_total_input_texels());

		return true;
	}

	bool basisu_backend::encode_selector_palette()
	{
		const basisu_frontend& r = *m_pFront_end;

		if ((m_params.m_use_global_sel_codebook) && (!m_params.m_use_hybrid_sel_codebooks))
		{
			histogram global_mod_indices(1 << m_params.m_global_sel_codebook_mod_bits);

			for (uint32_t q = 0; q < r.get_total_selector_clusters(); q++)
				global_mod_indices.inc(m_global_selector_palette_desc[q].m_mod_index);

			huffman_encoding_table global_pal_model, global_mod_model;

			if (!global_mod_model.init(global_mod_indices, 16))
			{
				error_printf("global_mod_model.init() failed!");
				return false;
			}

			bitwise_coder coder;
			coder.init(1024 * 1024);

			coder.put_bits(1, 1); // use global codebook

			coder.put_bits(m_params.m_global_sel_codebook_pal_bits, 4); // pal bits
			coder.put_bits(m_params.m_global_sel_codebook_mod_bits, 4); // mod bits

			uint32_t mod_model_bits = 0;
			if (m_params.m_global_sel_codebook_mod_bits)
				mod_model_bits = coder.emit_huffman_table(global_mod_model);

			uint32_t total_pal_bits = 0;
			uint32_t total_mod_bits = 0;
			for (uint32_t q = 0; q < r.get_total_selector_clusters(); q++)
			{
				const uint32_t i = m_selector_remap_table_new_to_old[q];

				if (m_params.m_global_sel_codebook_pal_bits)
				{
					coder.put_bits(m_global_selector_palette_desc[i].m_pal_index, m_params.m_global_sel_codebook_pal_bits);
					total_pal_bits += m_params.m_global_sel_codebook_pal_bits;
				}

				if (m_params.m_global_sel_codebook_mod_bits)
					total_mod_bits += coder.put_code(m_global_selector_palette_desc[i].m_mod_index, global_mod_model);
			}

			coder.flush();

			m_output.m_selector_palette = coder.get_bytes();

			debug_printf("Modifier model bits: %u Avg per entry: %3.3f\n", mod_model_bits, mod_model_bits / float(r.get_total_selector_clusters()));
			debug_printf("Palette bits: %u Avg per entry: %3.3f, Modifier bits: %u Avg per entry: %3.3f\n", total_pal_bits, total_pal_bits / float(r.get_total_selector_clusters()), total_mod_bits, total_mod_bits / float(r.get_total_selector_clusters()));
		}
		else if (m_params.m_use_hybrid_sel_codebooks)
		{
			huff2D used_global_cb_bitflag_huff2D(1, 8);

			histogram global_mod_indices(1 << m_params.m_global_sel_codebook_mod_bits);

			for (uint32_t s = 0; s < r.get_total_selector_clusters(); s++)
			{
				const uint32_t q = m_selector_remap_table_new_to_old[s];

				const bool used_global_cb_flag = r.get_selector_cluster_uses_global_cb_vec()[q];

				used_global_cb_bitflag_huff2D.emit(used_global_cb_flag);

				global_mod_indices.inc(m_global_selector_palette_desc[q].m_mod_index);
			}

			huffman_encoding_table global_mod_indices_model;
			if (!global_mod_indices_model.init(global_mod_indices, 16))
			{
				error_printf("global_mod_indices_model.init() failed!");
				return false;
			}

			bitwise_coder coder;
			coder.init(1024 * 1024);

			coder.put_bits(0, 1); // use global codebook
			coder.put_bits(1, 1); // uses hybrid codebooks

			coder.put_bits(m_params.m_global_sel_codebook_pal_bits, 4); // pal bits
			coder.put_bits(m_params.m_global_sel_codebook_mod_bits, 4); // mod bits

			used_global_cb_bitflag_huff2D.start_encoding(16);
			coder.emit_huffman_table(used_global_cb_bitflag_huff2D.get_encoding_table());

			if (m_params.m_global_sel_codebook_mod_bits)
				coder.emit_huffman_table(global_mod_indices_model);

			uint32_t total_global_cb_entries = 0;
			uint32_t total_pal_bits = 0;
			uint32_t total_mod_bits = 0;
			uint32_t total_selectors = 0;
			uint32_t total_selector_bits = 0;
			uint32_t total_flag_bits = 0;

			for (uint32_t s = 0; s < r.get_total_selector_clusters(); s++)
			{
				const uint32_t q = m_selector_remap_table_new_to_old[s];

				total_flag_bits += used_global_cb_bitflag_huff2D.emit_next_sym(coder);

				const bool used_global_cb_flag = r.get_selector_cluster_uses_global_cb_vec()[q];

				if (used_global_cb_flag)
				{
					total_global_cb_entries++;

					total_pal_bits += coder.put_bits(r.get_selector_cluster_global_selector_entry_ids()[q].m_palette_index, m_params.m_global_sel_codebook_pal_bits);
					total_mod_bits += coder.put_code(r.get_selector_cluster_global_selector_entry_ids()[q].m_modifier.get_index(), global_mod_indices_model);
				}
				else
				{
					total_selectors++;
					total_selector_bits += 32;

					for (uint32_t j = 0; j < 4; j++)
						coder.put_bits(m_selector_palette[q].get_byte(j), 8);
				}
			}

			coder.flush();

			m_output.m_selector_palette = coder.get_bytes();

			debug_printf("Total global CB entries: %u %3.2f%%\n", total_global_cb_entries, total_global_cb_entries * 100.0f / r.get_total_selector_clusters());
			debug_printf("Total selector entries: %u %3.2f%%\n", total_selectors, total_selectors * 100.0f / r.get_total_selector_clusters());
			debug_printf("Total pal bits: %u, mod bits: %u, selector bits: %u, flag bits: %u\n", total_pal_bits, total_mod_bits, total_selector_bits, total_flag_bits);
		}
		else
		{
			histogram delta_selector_pal_histogram(256);

			for (uint32_t q = 0; q < r.get_total_selector_clusters(); q++)
			{
				if (!q)
					continue;

				const basist::etc1_selector_palette_entry& cur = m_selector_palette[m_selector_remap_table_new_to_old[q]];
				const basist::etc1_selector_palette_entry predictor(m_selector_palette[m_selector_remap_table_new_to_old[q - 1]]);

				for (uint32_t j = 0; j < 4; j++)
					delta_selector_pal_histogram.inc(cur.get_byte(j) ^ predictor.get_byte(j));
			}

			if (!delta_selector_pal_histogram.get_total())
				delta_selector_pal_histogram.inc(0);

			huffman_encoding_table delta_selector_pal_model;
			if (!delta_selector_pal_model.init(delta_selector_pal_histogram, 16))
			{
				error_printf("delta_selector_pal_model.init() failed!");
				return false;
			}

			bitwise_coder coder;
			coder.init(1024 * 1024);

			coder.put_bits(0, 1); // use global codebook
			coder.put_bits(0, 1); // uses hybrid codebooks

			coder.put_bits(0, 1); // raw bytes

			coder.emit_huffman_table(delta_selector_pal_model);

			for (uint32_t q = 0; q < r.get_total_selector_clusters(); q++)
			{
				if (!q)
				{
					for (uint32_t j = 0; j < 4; j++)
						coder.put_bits(m_selector_palette[m_selector_remap_table_new_to_old[q]].get_byte(j), 8);
					continue;
				}

				const basist::etc1_selector_palette_entry& cur = m_selector_palette[m_selector_remap_table_new_to_old[q]];
				const basist::etc1_selector_palette_entry predictor(m_selector_palette[m_selector_remap_table_new_to_old[q - 1]]);

				for (uint32_t j = 0; j < 4; j++)
					coder.put_code(cur.get_byte(j) ^ predictor.get_byte(j), delta_selector_pal_model);
			}

			coder.flush();

			m_output.m_selector_palette = coder.get_bytes();

			if (m_output.m_selector_palette.size() >= r.get_total_selector_clusters() * 4)
			{
				coder.init(1024 * 1024);

				coder.put_bits(0, 1); // use global codebook
				coder.put_bits(0, 1); // uses hybrid codebooks

				coder.put_bits(1, 1); // raw bytes

				for (uint32_t q = 0; q < r.get_total_selector_clusters(); q++)
				{
					const uint32_t i = m_selector_remap_table_new_to_old[q];

					for (uint32_t j = 0; j < 4; j++)
						coder.put_bits(m_selector_palette[i].get_byte(j), 8);
				}

				coder.flush();

				m_output.m_selector_palette = coder.get_bytes();
			}

		}  // if (m_params.m_use_global_sel_codebook)        

		debug_printf("Selector codebook bits: %u bytes: %u, Bits per entry: %3.1f, Avg bits/texel: %3.3f\n",
			(int)m_output.m_selector_palette.size() * 8, (int)m_output.m_selector_palette.size(),
			m_output.m_selector_palette.size() * 8.0f / r.get_total_selector_clusters(), m_output.m_selector_palette.size() * 8.0f / get_total_input_texels());

		return true;
	}

	uint32_t basisu_backend::encode()
	{
		const bool is_video = m_pFront_end->get_params().m_tex_type == basist::cBASISTexTypeVideoFrames;
		m_output.m_slice_desc = m_slices;
		m_output.m_etc1s = m_params.m_etc1s;

		create_endpoint_palette();
		create_selector_palette();

		create_encoder_blocks();

		if (!encode_image())
			return 0;

		if (!encode_endpoint_palette())
			return 0;

		if (!encode_selector_palette())
			return 0;

		uint32_t total_compressed_bytes = (uint32_t)(m_output.m_slice_image_tables.size() + m_output.m_endpoint_palette.size() + m_output.m_selector_palette.size());
		for (uint32_t i = 0; i < m_output.m_slice_image_data.size(); i++)
			total_compressed_bytes += (uint32_t)m_output.m_slice_image_data[i].size();

		debug_printf("Wrote %u bytes, %3.3f bits/texel\n", total_compressed_bytes, total_compressed_bytes * 8.0f / get_total_input_texels());

		return total_compressed_bytes;
	}

} // namespace basisu
