jfjoch_viewer: Improve performance of image coloring

This commit is contained in:
2026-01-29 22:25:55 +01:00
parent a6a8d35a7e
commit c020ac4133
3 changed files with 78 additions and 57 deletions
+35 -40
View File
@@ -9,8 +9,35 @@ float luminance(rgb input) {
return 0.2126f * input.r + 0.7152f * input.g + 0.0722f * input.b;
}
ColorScale::ColorScale() : lut_(kLutSize) {
CalcLUT();
}
void ColorScale::Select(ColorScaleEnum val) {
current = val;
CalcLUT();
}
const std::vector<rgb> &ColorScale::LUTData() const {
return lut_;
}
void ColorScale::CalcLUT() const {
const std::vector<rgb>* map = nullptr;
switch (current) {
case ColorScaleEnum::Viridis: map = &viridis_colormap; break;
case ColorScaleEnum::Heat: map = &heat_colormap; break;
case ColorScaleEnum::Indigo: map = &white_to_indigo_colormap; break;
case ColorScaleEnum::BW: map = &white_to_black_colormap; break;
default:
throw JFJochException(JFJochExceptionCategory::InputParameterInvalid,
"Color scale unknown");
}
for (size_t i = 0; i < kLutSize; ++i) {
const float f = static_cast<float>(i) / static_cast<float>(kLutSize - 1);
lut_[i] = Apply(f, *map);
}
}
rgb ColorScale::Apply(float input, const std::vector<rgb> &map) {
@@ -45,8 +72,6 @@ rgb ColorScale::Apply(ColorScaleSpecial input) const {
}
rgb ColorScale::Apply(float input, float min, float max) const {
// Assume min and max is finite
if (!std::isfinite(input))
return gap;
@@ -58,19 +83,14 @@ rgb ColorScale::Apply(float input, float min, float max) const {
else
f = (input - min) / (max - min);
switch (current) {
case ColorScaleEnum::Viridis:
return Apply(f, viridis_colormap);
case ColorScaleEnum::Heat:
return Apply(f, heat_colormap);
case ColorScaleEnum::Indigo:
return Apply(f, white_to_indigo_colormap);
case ColorScaleEnum::BW:
return Apply(f, white_to_black_colormap);
default:
throw JFJochException(JFJochExceptionCategory::InputParameterInvalid,
"Color scale unknown");
}
const size_t idx = static_cast<size_t>(f * static_cast<float>(kLutSize - 1));
return lut_[idx];
}
rgb ColorScale::ApplyLUTIndex(size_t idx) const {
if (idx >= kLutSize)
return lut_[kLutSize-1];
return lut_[idx];
}
ColorScale &ColorScale::Gap(rgb input) {
@@ -82,28 +102,3 @@ ColorScale &ColorScale::BadPixel(rgb input) {
bad = input;
return *this;
}
rgb rainbowColor(float t) {
// Ensure t is in [0,1]
t = std::max(0.0f, std::min(1.0f, t));
// Convert to hue (0 to 6)
float hue = t * 6.0f;
int phase = static_cast<int>(hue);
float fract = hue - phase;
uint8_t p = static_cast<uint8_t>(255 * (1.0f - fract));
uint8_t q = static_cast<uint8_t>(255 * fract);
uint8_t full = 255;
switch (phase) {
case 0: return {full, q, 0}; // Red to Yellow
case 1: return {p, full, 0}; // Yellow to Green
case 2: return {0, full, q}; // Green to Cyan
case 3: return {0, p, full}; // Cyan to Blue
case 4: return {q, 0, full}; // Blue to Magenta
case 5: return {full, 0, p}; // Magenta to Red
default: return {full, 0, 0}; // Fallback (red)
}
}