Files
Jungfraujoch/common/ColorScale.cpp
2025-03-02 13:15:28 +01:00

62 lines
1.9 KiB
C++

// SPDX-FileCopyrightText: 2025 Filip Leonarski, Paul Scherrer Institute <filip.leonarski@psi.ch>
// SPDX-License-Identifier: GPL-3.0-only
#include "ColorScale.h"
#include "JFJochException.h"
float luminance(rgb input) {
return 0.2126f * input.r + 0.7152f * input.g + 0.0722f * input.b;
}
void ColorScale::Select(ColorScaleEnum val) {
current = val;
}
rgb ColorScale::Apply(float input, const std::vector<rgb> &map) {
input = std::clamp(input, 0.0f, 1.0f);
size_t num_colors = map.size();
if (num_colors < 2) {
throw std::invalid_argument("Colormap must have at least two colors.");
}
float scaled_value = input * (num_colors - 1);
size_t lower_idx = static_cast<size_t>(scaled_value);
size_t upper_idx = std::min(lower_idx + 1, num_colors - 1);
float t = scaled_value - lower_idx; // Fraction for interpolation
rgb lower = map[lower_idx];
rgb upper = map[upper_idx];
return {
.r = static_cast<uint8_t>(lower.r + t * (upper.r - lower.r)),
.g = static_cast<uint8_t>(lower.g + t * (upper.g - lower.g)),
.b = static_cast<uint8_t>(lower.b + t * (upper.b - lower.b))
};
}
rgb ColorScale::Apply(ColorScaleSpecial input) {
switch (input) {
case ColorScaleSpecial::Gap:
return gap;
default:
case ColorScaleSpecial::BadPixel:
return bad;
}
}
rgb ColorScale::Apply(float input) {
switch (current) {
case ColorScaleEnum::Viridis:
return Apply(input, viridis_colormap);
case ColorScaleEnum::Heat:
return Apply(input, heat_colormap);
case ColorScaleEnum::Indigo:
return Apply(input, white_to_indigo_colormap);
case ColorScaleEnum::BW:
return Apply(input, white_to_black_colormap);
default:
throw JFJochException(JFJochExceptionCategory::InputParameterInvalid,
"Color scale unknown");
}
}