static bool realign_weights(
	astcenc_profile decode_mode,
	const block_size_descriptor& bsd,
	const image_block& blk,
	const error_weight_block& ewb,
	symbolic_compressed_block& scb,
	uint8_t* dec_weights_quant_pvalue_plane1,
	uint8_t* dec_weights_quant_pvalue_plane2
) {
	// Get the partition descriptor
	unsigned int partition_count = scb.partition_count;
	const auto& pi = bsd.get_partition_info(partition_count, scb.partition_index);

	// Get the quantization table
	const block_mode& bm = bsd.get_block_mode(scb.block_mode);
	unsigned int weight_quant_level = bm.quant_mode;
	const quantization_and_transfer_table *qat = &(quant_and_xfer_tables[weight_quant_level]);

	// Get the decimation table
	const decimation_info& di = bsd.get_decimation_info(bm.decimation_mode);
	unsigned int weight_count = di.weight_count;

	unsigned int max_plane = bm.is_dual_plane;
	int plane2_component = bm.is_dual_plane ? scb.plane2_component : -1;
	vmask4 plane_mask = vint4::lane_id() == vint4(plane2_component);

	// Decode the color endpoints
	bool rgb_hdr;
	bool alpha_hdr;
	vint4 endpnt0[BLOCK_MAX_PARTITIONS];
	vint4 endpnt1[BLOCK_MAX_PARTITIONS];
	vfloat4 endpnt0f[BLOCK_MAX_PARTITIONS];
	vfloat4 offset[BLOCK_MAX_PARTITIONS];

	promise(partition_count > 0);
	promise(weight_count > 0);

	for (unsigned int pa_idx = 0; pa_idx < partition_count; pa_idx++)
	{
		unpack_color_endpoints(decode_mode,
		                       scb.color_formats[pa_idx],
		                       scb.get_color_quant_mode(),
		                       scb.color_values[pa_idx],
		                       rgb_hdr, alpha_hdr,
		                       endpnt0[pa_idx],
		                       endpnt1[pa_idx]);
	}

	uint8_t uq_pl_weights[BLOCK_MAX_WEIGHTS];
	uint8_t* dec_weights_quant_pvalue = dec_weights_quant_pvalue_plane1;
	bool adjustments = false;

	// For each plane and partition ...
	for (unsigned int pl_idx = 0; pl_idx <= max_plane; pl_idx++)
	{
		for (unsigned int pa_idx = 0; pa_idx < partition_count; pa_idx++)
		{
			// Compute the endpoint delta for all components in current plane
			vint4 epd = endpnt1[pa_idx] - endpnt0[pa_idx];
			epd = select(epd, vint4::zero(), plane_mask);

			endpnt0f[pa_idx] = int_to_float(endpnt0[pa_idx]);
			offset[pa_idx] = int_to_float(epd) * (1.0f / 64.0f);
		}

		// Create an unquantized weight grid for this decimation level
		for (unsigned int we_idx = 0; we_idx < weight_count; we_idx++)
		{
			uq_pl_weights[we_idx] = qat->unquantized_value[dec_weights_quant_pvalue[we_idx]];
		}

		// For each weight compute previous, current, and next errors
		for (unsigned int we_idx = 0; we_idx < weight_count; we_idx++)
		{
			unsigned int uqw = uq_pl_weights[we_idx];

			uint32_t prev_and_next = qat->prev_next_values[uqw];
			unsigned int prev_wt_uq = prev_and_next & 0xFF;
			unsigned int next_wt_uq = (prev_and_next >> 8) & 0xFF;

			int uqw_next_dif = next_wt_uq - uqw;
			int uqw_prev_dif = prev_wt_uq - uqw;

			float current_error = 0.0f;
			float up_error = 0.0f;
			float down_error = 0.0f;

			// Interpolate the colors to create the diffs
			unsigned int texels_to_evaluate = di.weight_texel_count[we_idx];
			promise(texels_to_evaluate > 0);
			for (unsigned int te_idx = 0; te_idx < texels_to_evaluate; te_idx++)
			{
				unsigned int texel = di.weight_texel[te_idx][we_idx];
				const uint8_t *texel_weights = di.texel_weights_texel[we_idx][te_idx];
				const float *texel_weights_float = di.texel_weights_float_texel[we_idx][te_idx];
				float twf0 = texel_weights_float[0];

				float weight_base = static_cast<float>(uqw) * twf0;

				// Don't interpolate filtered weights for a 1:1 weight grid
				if (weight_count != bsd.texel_count)
				{
					weight_base =
						(( weight_base
						+ static_cast<float>(uq_pl_weights[texel_weights[1]])  * texel_weights_float[1])
						+ (static_cast<float>(uq_pl_weights[texel_weights[2]]) * texel_weights_float[2]
						+ static_cast<float>(uq_pl_weights[texel_weights[3]]) * texel_weights_float[3]));
				}

				unsigned int partition = pi.partition_of_texel[texel];

				weight_base = weight_base + 0.5f;
				float plane_weight = astc::flt_rd(weight_base);
				float plane_up_weight = astc::flt_rd(weight_base + static_cast<float>(uqw_next_dif) * twf0) - plane_weight;
				float plane_down_weight = astc::flt_rd(weight_base + static_cast<float>(uqw_prev_dif) * twf0) - plane_weight;

				vfloat4 color_offset = offset[partition];
				vfloat4 color_base   = endpnt0f[partition];

				vfloat4 color = color_base + color_offset * plane_weight;

				vfloat4 origcolor    = blk.texel(texel);
				vfloat4 error_weight = ewb.error_weights[texel];

				vfloat4 colordiff       = color - origcolor;
				vfloat4 color_up_diff   = colordiff + color_offset * plane_up_weight;
				vfloat4 color_down_diff = colordiff + color_offset * plane_down_weight;
				current_error += dot_s(colordiff       * colordiff,       error_weight);
				up_error      += dot_s(color_up_diff   * color_up_diff,   error_weight);
				down_error    += dot_s(color_down_diff * color_down_diff, error_weight);
			}

			// Check if the prev or next error is better, and if so use it
			if ((up_error < current_error) && (up_error < down_error))
			{
				uq_pl_weights[we_idx] = static_cast<uint8_t>(next_wt_uq);
				dec_weights_quant_pvalue[we_idx] = (uint8_t)((prev_and_next >> 24) & 0xFF);
				adjustments = true;
			}
			else if (down_error < current_error)
			{
				uq_pl_weights[we_idx] = static_cast<uint8_t>(prev_wt_uq);
				dec_weights_quant_pvalue[we_idx] = (uint8_t)((prev_and_next >> 16) & 0xFF);
				adjustments = true;
			}
		}

		// Prepare iteration for plane 2
		dec_weights_quant_pvalue = dec_weights_quant_pvalue_plane2;
		plane_mask = ~plane_mask;
	}

	return adjustments;
}
static bool realign_weights(
	astcenc_profile decode_mode,
	const block_size_descriptor& bsd,
	const image_block& blk,
	const error_weight_block& ewb,
	symbolic_compressed_block& scb,
	uint8_t* dec_weights_quant_pvalue_plane1,
	uint8_t* dec_weights_quant_pvalue_plane2
) {
	 
	unsigned int partition_count = scb.partition_count;
	const auto& pi = bsd.get_partition_info(partition_count, scb.partition_index);

	 
	const block_mode& bm = bsd.get_block_mode(scb.block_mode);
	unsigned int weight_quant_level = bm.quant_mode;
	const quantization_and_transfer_table *qat = &(quant_and_xfer_tables[weight_quant_level]);

	 
	const decimation_info& di = bsd.get_decimation_info(bm.decimation_mode);
	unsigned int weight_count = di.weight_count;

	unsigned int max_plane = bm.is_dual_plane;
	int plane2_component = bm.is_dual_plane ? scb.plane2_component : -1;
	vmask4 plane_mask = vint4::lane_id() == vint4(plane2_component);

	 
	bool rgb_hdr;
	bool alpha_hdr;
	vint4 endpnt0[BLOCK_MAX_PARTITIONS];
	vint4 endpnt1[BLOCK_MAX_PARTITIONS];
	vfloat4 endpnt0f[BLOCK_MAX_PARTITIONS];
	vfloat4 offset[BLOCK_MAX_PARTITIONS];

	promise(partition_count > 0);
	promise(weight_count > 0);

	for (unsigned int pa_idx = 0; pa_idx < partition_count; pa_idx++)
	{
		unpack_color_endpoints(decode_mode,
		                       scb.color_formats[pa_idx],
		                       scb.get_color_quant_mode(),
		                       scb.color_values[pa_idx],
		                       rgb_hdr, alpha_hdr,
		                       endpnt0[pa_idx],
		                       endpnt1[pa_idx]);
	}

	uint8_t uq_pl_weights[BLOCK_MAX_WEIGHTS];
	uint8_t* dec_weights_quant_pvalue = dec_weights_quant_pvalue_plane1;
	bool adjustments = false;

	 
	for (unsigned int pl_idx = 0; pl_idx <= max_plane; pl_idx++)
	{
		for (unsigned int pa_idx = 0; pa_idx < partition_count; pa_idx++)
		{
			 
			vint4 epd = endpnt1[pa_idx] - endpnt0[pa_idx];
			epd = select(epd, vint4::zero(), plane_mask);

			endpnt0f[pa_idx] = int_to_float(endpnt0[pa_idx]);
			offset[pa_idx] = int_to_float(epd) * (1.0f / 64.0f);
		}

		 
		for (unsigned int we_idx = 0; we_idx < weight_count; we_idx++)
		{
			uq_pl_weights[we_idx] = qat->unquantized_value[dec_weights_quant_pvalue[we_idx]];
		}

		 
		for (unsigned int we_idx = 0; we_idx < weight_count; we_idx++)
		{
			unsigned int uqw = uq_pl_weights[we_idx];

			uint32_t prev_and_next = qat->prev_next_values[uqw];
			unsigned int prev_wt_uq = prev_and_next & 0xFF;
			unsigned int next_wt_uq = (prev_and_next >> 8) & 0xFF;

			int uqw_next_dif = next_wt_uq - uqw;
			int uqw_prev_dif = prev_wt_uq - uqw;

			float current_error = 0.0f;
			float up_error = 0.0f;
			float down_error = 0.0f;

			 
			unsigned int texels_to_evaluate = di.weight_texel_count[we_idx];
			promise(texels_to_evaluate > 0);
			for (unsigned int te_idx = 0; te_idx < texels_to_evaluate; te_idx++)
			{
				unsigned int texel = di.weight_texel[te_idx][we_idx];
				const uint8_t *texel_weights = di.texel_weights_texel[we_idx][te_idx];
				const float *texel_weights_float = di.texel_weights_float_texel[we_idx][te_idx];
				float twf0 = texel_weights_float[0];

				float weight_base = static_cast<float>(uqw) * twf0;

				 
				if (weight_count != bsd.texel_count)
				{
					weight_base =
						(( weight_base
						+ static_cast<float>(uq_pl_weights[texel_weights[1]])  * texel_weights_float[1])
						+ (static_cast<float>(uq_pl_weights[texel_weights[2]]) * texel_weights_float[2]
						+ static_cast<float>(uq_pl_weights[texel_weights[3]]) * texel_weights_float[3]));
				}

				unsigned int partition = pi.partition_of_texel[texel];

				weight_base = weight_base + 0.5f;
				float plane_weight = astc::flt_rd(weight_base);
				float plane_up_weight = astc::flt_rd(weight_base + static_cast<float>(uqw_next_dif) * twf0) - plane_weight;
				float plane_down_weight = astc::flt_rd(weight_base + static_cast<float>(uqw_prev_dif) * twf0) - plane_weight;

				vfloat4 color_offset = offset[partition];
				vfloat4 color_base   = endpnt0f[partition];

				vfloat4 color = color_base + color_offset * plane_weight;

				vfloat4 origcolor    = blk.texel(texel);
				vfloat4 error_weight = ewb.error_weights[texel];

				vfloat4 colordiff       = color - origcolor;
				vfloat4 color_up_diff   = colordiff + color_offset * plane_up_weight;
				vfloat4 color_down_diff = colordiff + color_offset * plane_down_weight;
				current_error += dot_s(colordiff       * colordiff,       error_weight);
				up_error      += dot_s(color_up_diff   * color_up_diff,   error_weight);
				down_error    += dot_s(color_down_diff * color_down_diff, error_weight);
			}

			 
			if ((up_error < current_error) && (up_error < down_error))
			{
				uq_pl_weights[we_idx] = static_cast<uint8_t>(next_wt_uq);
				dec_weights_quant_pvalue[we_idx] = (uint8_t)((prev_and_next >> 24) & 0xFF);
				adjustments = true;
			}
			else if (down_error < current_error)
			{
				uq_pl_weights[we_idx] = static_cast<uint8_t>(prev_wt_uq);
				dec_weights_quant_pvalue[we_idx] = (uint8_t)((prev_and_next >> 16) & 0xFF);
				adjustments = true;
			}
		}

		 
		dec_weights_quant_pvalue = dec_weights_quant_pvalue_plane2;
		plane_mask = ~plane_mask;
	}

	return adjustments;
}