static void compute_ideal_colors_and_weights_4_comp(
	const block_size_descriptor& bsd,
	const image_block& blk,
	const error_weight_block& ewb,
	const partition_info& pi,
	endpoints_and_weights& ei
) {
	const float *error_weights = ewb.texel_weight;

	int partition_count = pi.partition_count;

	int texel_count= bsd.texel_count;
	promise(texel_count > 0);
	promise(partition_count > 0);

	float lowparam[BLOCK_MAX_PARTITIONS] { 1e10f, 1e10f, 1e10f, 1e10f };
	float highparam[BLOCK_MAX_PARTITIONS] { -1e10f, -1e10f, -1e10f, -1e10f };

	line4 lines[BLOCK_MAX_PARTITIONS];

	float scale[BLOCK_MAX_PARTITIONS];
	float length_squared[BLOCK_MAX_PARTITIONS];

	partition_metrics pms[BLOCK_MAX_PARTITIONS];

	compute_avgs_and_dirs_4_comp(pi, blk, ewb, pms);

	// If the direction points from light to dark then flip so ep0 is darkest
	for (int i = 0; i < partition_count; i++)
	{
		vfloat4 dir = pms[i].dir;
		if (hadd_rgb_s(dir) < 0.0f)
		{
			dir = vfloat4::zero() - dir;
		}

		lines[i].a = pms[i].avg;
		lines[i].b = normalize_safe(dir, unit4());
	}

	for (int i = 0; i < texel_count; i++)
	{
		if (error_weights[i] > 1e-10f)
		{
			int partition = pi.partition_of_texel[i];

			vfloat4 point = blk.texel(i) * pms[partition].color_scale;
			line4 l = lines[partition];

			float param = dot_s(point - l.a, l.b);
			ei.weights[i] = param;

			lowparam[partition] = astc::min(param, lowparam[partition]);
			highparam[partition] = astc::max(param, highparam[partition]);
		}
		else
		{
			ei.weights[i] = -1e38f;
		}
	}

	for (int i = 0; i < partition_count; i++)
	{
		float length = highparam[i] - lowparam[i];
		if (length < 0)
		{
			lowparam[i] = 0.0f;
			highparam[i] = 1e-7f;
		}

		// It is possible for a uniform-color partition to produce length=0; this causes NaN issues
		// so set to a small value to avoid this problem.
		length = astc::max(length, 1e-7f);

		length_squared[i] = length * length;
		scale[i] = 1.0f / length;

		vfloat4 ep0 = lines[i].a + lines[i].b * lowparam[i];
		vfloat4 ep1 = lines[i].a + lines[i].b * highparam[i];

		ei.ep.endpt0[i] = ep0 * pms[i].icolor_scale;
		ei.ep.endpt1[i] = ep1 * pms[i].icolor_scale;
	}

	bool is_constant_wes = true;
	float constant_wes = length_squared[pi.partition_of_texel[0]] * error_weights[0];

	for (int i = 0; i < texel_count; i++)
	{
		int partition = pi.partition_of_texel[i];
		float idx = (ei.weights[i] - lowparam[partition]) * scale[partition];
		idx = astc::clamp1f(idx);

		ei.weights[i] = idx;
		ei.weight_error_scale[i] = error_weights[i] * length_squared[partition];
		assert(!astc::isnan(ei.weight_error_scale[i]));

		is_constant_wes = is_constant_wes && ei.weight_error_scale[i] == constant_wes;
	}

	// Zero initialize any SIMD over-fetch
	int texel_count_simd = round_up_to_simd_multiple_vla(texel_count);
	for (int i = texel_count; i < texel_count_simd; i++)
	{
		ei.weights[i] = 0.0f;
		ei.weight_error_scale[i] = 0.0f;
	}

	ei.is_constant_weight_error_scale = is_constant_wes;
}
static void compute_ideal_colors_and_weights_4_comp(
	const block_size_descriptor& bsd,
	const image_block& blk,
	const error_weight_block& ewb,
	const partition_info& pi,
	endpoints_and_weights& ei
) {
	const float *error_weights = ewb.texel_weight;

	int partition_count = pi.partition_count;

	int texel_count= bsd.texel_count;
	promise(texel_count > 0);
	promise(partition_count > 0);

	float lowparam[BLOCK_MAX_PARTITIONS] { 1e10f, 1e10f, 1e10f, 1e10f };
	float highparam[BLOCK_MAX_PARTITIONS] { -1e10f, -1e10f, -1e10f, -1e10f };

	line4 lines[BLOCK_MAX_PARTITIONS];

	float scale[BLOCK_MAX_PARTITIONS];
	float length_squared[BLOCK_MAX_PARTITIONS];

	partition_metrics pms[BLOCK_MAX_PARTITIONS];

	compute_avgs_and_dirs_4_comp(pi, blk, ewb, pms);

	 
	for (int i = 0; i < partition_count; i++)
	{
		vfloat4 dir = pms[i].dir;
		if (hadd_rgb_s(dir) < 0.0f)
		{
			dir = vfloat4::zero() - dir;
		}

		lines[i].a = pms[i].avg;
		lines[i].b = normalize_safe(dir, unit4());
	}

	for (int i = 0; i < texel_count; i++)
	{
		if (error_weights[i] > 1e-10f)
		{
			int partition = pi.partition_of_texel[i];

			vfloat4 point = blk.texel(i) * pms[partition].color_scale;
			line4 l = lines[partition];

			float param = dot_s(point - l.a, l.b);
			ei.weights[i] = param;

			lowparam[partition] = astc::min(param, lowparam[partition]);
			highparam[partition] = astc::max(param, highparam[partition]);
		}
		else
		{
			ei.weights[i] = -1e38f;
		}
	}

	for (int i = 0; i < partition_count; i++)
	{
		float length = highparam[i] - lowparam[i];
		if (length < 0)
		{
			lowparam[i] = 0.0f;
			highparam[i] = 1e-7f;
		}

		 
		 
		length = astc::max(length, 1e-7f);

		length_squared[i] = length * length;
		scale[i] = 1.0f / length;

		vfloat4 ep0 = lines[i].a + lines[i].b * lowparam[i];
		vfloat4 ep1 = lines[i].a + lines[i].b * highparam[i];

		ei.ep.endpt0[i] = ep0 * pms[i].icolor_scale;
		ei.ep.endpt1[i] = ep1 * pms[i].icolor_scale;
	}

	bool is_constant_wes = true;
	float constant_wes = length_squared[pi.partition_of_texel[0]] * error_weights[0];

	for (int i = 0; i < texel_count; i++)
	{
		int partition = pi.partition_of_texel[i];
		float idx = (ei.weights[i] - lowparam[partition]) * scale[partition];
		idx = astc::clamp1f(idx);

		ei.weights[i] = idx;
		ei.weight_error_scale[i] = error_weights[i] * length_squared[partition];
		assert(!astc::isnan(ei.weight_error_scale[i]));

		is_constant_wes = is_constant_wes && ei.weight_error_scale[i] == constant_wes;
	}

	 
	int texel_count_simd = round_up_to_simd_multiple_vla(texel_count);
	for (int i = texel_count; i < texel_count_simd; i++)
	{
		ei.weights[i] = 0.0f;
		ei.weight_error_scale[i] = 0.0f;
	}

	ei.is_constant_weight_error_scale = is_constant_wes;
}