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