diff --git a/rawimage.cpp b/rawimage.cpp index 7d4e954..a35be38 100644 --- a/rawimage.cpp +++ b/rawimage.cpp @@ -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 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 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>::is_integer) s = (float)std::numeric_limits>::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>::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]);