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++)
|
for(int i = 0; i < 4; i++)
|
||||||
{
|
{
|
||||||
stats.m_min[i] = min[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)
|
if(min < 0.0f || max > 1.0f)
|
||||||
return {1.0f / (max - min), min / (max - min)};
|
return {1.0f / (max - min), -min / (max - min)};
|
||||||
else
|
else
|
||||||
return {1.0f, 0.0f};
|
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)
|
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();
|
s = (float)std::numeric_limits<std::remove_reference_t<decltype(*src)>>::max();
|
||||||
|
|
||||||
|
auto unit = unitScale();
|
||||||
float iscale = 1.0f / s;
|
float iscale = 1.0f / s;
|
||||||
size_t len = size() * m_ch;
|
size_t len = size() * m_ch;
|
||||||
for(size_t i = 0; i < len; i++)
|
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 = (x - mtfParams.blackPoint[0]) / (mtfParams.whitePoint[0] - mtfParams.blackPoint[0]);
|
||||||
x = std::clamp(x, 0.0f, 1.0f);
|
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]);
|
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