Files
HPPA/HPPA/SinglebandRasterRenderer.cpp
2026-05-22 16:21:41 +08:00

86 lines
2.3 KiB
C++

#include "SinglebandRasterRenderer.h"
#include "RasterDataProvider.h"
#include <algorithm>
SinglebandRasterRenderer::SinglebandRasterRenderer(RasterDataProvider* provider)
: RasterRendererBase(provider)
{
}
void SinglebandRasterRenderer::stretchTo8bit(const std::vector<float>& in, std::vector<unsigned char>& out, float minVal, float maxVal)
{
size_t n = in.size();
out.resize(n);
if (maxVal <= minVal) {
std::fill(out.begin(), out.end(), 0);
return;
}
float denom = 1.0f / (maxVal - minVal);
for (size_t i = 0; i < n; ++i) {
float v = (in[i] - minVal) * denom;
v = std::min(std::max(v, 0.0f), 1.0f);
out[i] = static_cast<unsigned char>(v * 255.0f);
}
}
int SinglebandRasterRenderer::nearestBandIndex(double wave) const
{
if (!m_provider) return -1;
int bands = m_provider->bandCount();
if (bands <= 0) return -1;
std::vector<double> wavelengths = m_provider->bandWavelengths();
if (wavelengths.empty()) {
// No wavelengths available, fallback to first band
return 0;
}
int best = -1;
double bestDiff = 1e12;
for (int i = 0; i < (int)wavelengths.size(); ++i) {
if (wavelengths[i] < 0) continue;
double d = std::abs(wavelengths[i] - wave);
if (d < bestDiff) {
bestDiff = d;
best = i;
}
}
return (best >= 0) ? best : 0;
}
QImage SinglebandRasterRenderer::render()
{
if (!m_provider) return QImage();
int w = m_provider->width();
int h = m_provider->height();
if (w <= 0 || h <= 0) return QImage();
int bandIdx = nearestBandIndex(m_params.wavelength);
if (bandIdx < 0 || bandIdx >= m_provider->bandCount()) {
bandIdx = 0;
}
std::vector<float> buf;
m_provider->readBandAsFloat(bandIdx, buf);
std::vector<unsigned char> gray8;
float minV = static_cast<float>(m_params.minValue);
float maxV = static_cast<float>(m_params.maxValue);
if (!buf.empty()) {
stretchTo8bit(buf, gray8, minV, maxV);
}
QImage out(w, h, QImage::Format_Grayscale8);
for (int y = 0; y < h; ++y) {
unsigned char* scan = out.scanLine(y);
for (int x = 0; x < w; ++x) {
int idx = y * w + x;
scan[x] = (gray8.size() > (size_t)idx) ? gray8[idx] : 0;
}
}
return out;
}