Fix images that have values outside of 0-1 range
This commit is contained in:
+55
-2
@@ -231,6 +231,56 @@ void calcStats(const T *data, size_t n, size_t w, RawImage::Stats &stats)
|
||||
}
|
||||
}
|
||||
|
||||
if constexpr(std::is_floating_point_v<T>)
|
||||
{
|
||||
T mmin = *std::min_element(min, min + 4);
|
||||
T mmax = *std::max_element(max, max + 4);
|
||||
for(int i=0; i<4; i++)
|
||||
{
|
||||
histogram[i].clear();
|
||||
histogram[i].resize(histSize, 0);
|
||||
}
|
||||
|
||||
T a = 1.0 / (mmax - mmin);
|
||||
T b = -mmin / (mmax - mmin);
|
||||
|
||||
auto histFunc = [&](T d, int x)
|
||||
{
|
||||
uint16_t idx = std::clamp((T)(d * a + b) * histSize, (T)0.0, (T)65535.0);
|
||||
histogram[x][idx]++;
|
||||
};
|
||||
|
||||
// calculate histogram again
|
||||
if(mmin < 0.0 || mmax > 1.0)
|
||||
{
|
||||
for(size_t i = 0; i < n; i++)
|
||||
{
|
||||
histFunc(data[i*ch], 0);
|
||||
if constexpr(ch >= 3)
|
||||
{
|
||||
histFunc(data[i*ch + 1], 1);
|
||||
histFunc(data[i*ch + 2], 2);
|
||||
}
|
||||
}
|
||||
|
||||
if constexpr(ch == 1)
|
||||
{
|
||||
size_t h = (n / w) & (SIZE_MAX-1);
|
||||
w &= (SIZE_MAX-1);
|
||||
for(size_t y=0; y<h; y+=2)
|
||||
{
|
||||
for(size_t x=0; x<w; x+=2)
|
||||
{
|
||||
histFunc(data[y*w+x], 1);
|
||||
histFunc(data[y*w+x+1], 2);
|
||||
histFunc(data[(y+1)*w+x], 2);
|
||||
histFunc(data[(y+1)*w+x+1], 3);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for(int i = 0; i < 4; i++)
|
||||
{
|
||||
stats.m_min[i] = min[i];
|
||||
@@ -824,7 +874,7 @@ std::pair<float, float> RawImage::unitScale() const
|
||||
}
|
||||
|
||||
if(min < 0.0f || max > 1.0f)
|
||||
return {1.0f / (max - min), min / (max - min)};
|
||||
return {1.0f / (max - min), -min / (max - min)};
|
||||
else
|
||||
return {1.0f, 0.0f};
|
||||
}
|
||||
@@ -1112,11 +1162,14 @@ void RawImage::applySTF(const MTFParam &mtfParams)
|
||||
if constexpr(std::numeric_limits<std::remove_reference_t<decltype(*src)>>::is_integer)
|
||||
s = (float)std::numeric_limits<std::remove_reference_t<decltype(*src)>>::max();
|
||||
|
||||
auto unit = unitScale();
|
||||
float iscale = 1.0f / s;
|
||||
size_t len = size() * m_ch;
|
||||
for(size_t i = 0; i < len; i++)
|
||||
{
|
||||
float x = src[i] * iscale;
|
||||
float x;
|
||||
if constexpr(std::numeric_limits<std::remove_reference_t<decltype(*src)>>::is_integer)x = src[i] * iscale;
|
||||
else x = src[i] * unit.first + unit.second;
|
||||
x = (x - mtfParams.blackPoint[0]) / (mtfParams.whitePoint[0] - mtfParams.blackPoint[0]);
|
||||
x = std::clamp(x, 0.0f, 1.0f);
|
||||
x = ((mtfParams.midPoint[0] - 1.0f) * x) / ((2.0f * mtfParams.midPoint[0] - 1.0f) * x - mtfParams.midPoint[0]);
|
||||
|
||||
Reference in New Issue
Block a user