Example #1
0
void GammaModification::apply(Color *input, Color *output)
{
	Color linear_input, linear_output;
	color_rgb_get_linear(input, &linear_input);
	linear_output.rgb.red = pow(linear_input.rgb.red, value);
	linear_output.rgb.green= pow(linear_input.rgb.green, value);
	linear_output.rgb.blue = pow(linear_input.rgb.blue, value);
	color_linear_get_rgb(&linear_output, output);
	color_rgb_normalize(output);
}
void ColorVisionDeficiency::apply(Color *input, Color *output)
{
	Color linear_input, linear_output;
	color_rgb_get_linear(input, &linear_input);
	vector3 vi, vo1, vo2;
	load_vector(&linear_input, &vi);
	matrix3x3 matrix1, matrix2;
	int index = floor(strength * 10);
	int index_secondary = std::min(index + 1, 10);
	float interpolation_factor = 1 - ((strength * 10) - index);

	vector3 lms;
	if ((type == PROTANOPIA) || (type == DEUTERANOPIA) || (type == TRITANOPIA)){
		load_matrix(rgb_to_lms, &matrix1);
		load_matrix(lms_to_rgb, &matrix2);
		vector3_multiply_matrix3x3(&vi, &matrix1, &lms);
	}

	switch (type){
		case PROTANOMALY:
			load_matrix(protanomaly[index], &matrix1);
			load_matrix(protanomaly[index_secondary], &matrix2);
			vector3_multiply_matrix3x3(&vi, &matrix1, &vo1);
			vector3_multiply_matrix3x3(&vi, &matrix2, &vo2);
			break;
		case DEUTERANOMALY:
			load_matrix(deuteranomaly[index], &matrix1);
			load_matrix(deuteranomaly[index_secondary], &matrix2);
			vector3_multiply_matrix3x3(&vi, &matrix1, &vo1);
			vector3_multiply_matrix3x3(&vi, &matrix2, &vo2);
			break;
		case TRITANOMALY:
			load_matrix(tritanomaly[index], &matrix1);
			load_matrix(tritanomaly[index_secondary], &matrix2);
			vector3_multiply_matrix3x3(&vi, &matrix1, &vo1);
			vector3_multiply_matrix3x3(&vi, &matrix2, &vo2);
			break;
		case PROTANOPIA:
			if (lms.z / lms.y < rgb_anchor[2] / rgb_anchor[1]){
				lms.x = -(protanopia_abc[0].y * lms.y + protanopia_abc[0].z * lms.z) / protanopia_abc[0].x;
			}else{
				lms.x = -(protanopia_abc[1].y * lms.y + protanopia_abc[1].z * lms.z) / protanopia_abc[1].x;
			}
			vector3_multiply_matrix3x3(&lms, &matrix2, &vo1);
			load_vector(&linear_input, &vo2);
			interpolation_factor = strength;
			break;
		case DEUTERANOPIA:
			if (lms.z / lms.x < rgb_anchor[2] / rgb_anchor[0]){
				lms.y = -(deuteranopia_abc[0].x * lms.x + deuteranopia_abc[0].z * lms.z) / deuteranopia_abc[0].y;
			}else{
				lms.y = -(deuteranopia_abc[1].x * lms.x + deuteranopia_abc[1].z * lms.z) / deuteranopia_abc[1].y;
			}
			vector3_multiply_matrix3x3(&lms, &matrix2, &vo1);
			load_vector(&linear_input, &vo2);
			interpolation_factor = strength;
			break;
		case TRITANOPIA:
			if (lms.y / lms.x < rgb_anchor[1] / rgb_anchor[0]){
				lms.z = -(tritanopia_abc[0].x * lms.x + tritanopia_abc[0].y * lms.y) / tritanopia_abc[0].z;
			}else{
				lms.z = -(tritanopia_abc[1].x * lms.x + tritanopia_abc[1].y * lms.y) / tritanopia_abc[1].z;
			}
			vector3_multiply_matrix3x3(&lms, &matrix2, &vo1);
			load_vector(&linear_input, &vo2);
			interpolation_factor = strength;
			break;
		default:
			color_copy(input, output);
			return;
	}

	linear_output.rgb.red = vo1.x * interpolation_factor + vo2.x * (1 - interpolation_factor);
	linear_output.rgb.green = vo1.y * interpolation_factor + vo2.y * (1 - interpolation_factor);
	linear_output.rgb.blue = vo1.z * interpolation_factor + vo2.z * (1 - interpolation_factor);
	color_linear_get_rgb(&linear_output, output);
	color_rgb_normalize(output);
}