From 29fe23e517fa8dde0a31f33de9a00f0d5e286085 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fl=C3=B6ssie?= Date: Fri, 29 Apr 2016 17:26:56 +0200 Subject: [PATCH] Move `film_simulation_strength` calculation into `HaldCLUT::getRGB()` - Moved `film_simulation_strength` calculation into `HaldCLUT::getRGB()` - Removed unneeded base class `CLUT` - Used `_MM_SHUFFLE` --- rtengine/clutstore.cc | 103 ++++++++++++++++++++++------------------ rtengine/clutstore.h | 49 ++++++++----------- rtengine/improcfun.cc | 43 ++++++++--------- rtgui/filmsimulation.cc | 4 +- 4 files changed, 99 insertions(+), 100 deletions(-) diff --git a/rtengine/clutstore.cc b/rtengine/clutstore.cc index c9d4645a2..b5f07c121 100644 --- a/rtengine/clutstore.cc +++ b/rtengine/clutstore.cc @@ -87,40 +87,6 @@ inline vfloat getClutValue(const AlignedBuffer& clut_image, size_ } -void rtengine::CLUT::splitClutFilename( - const Glib::ustring& filename, - Glib::ustring& name, - Glib::ustring& extension, - Glib::ustring& profile_name -) -{ - Glib::ustring basename = Glib::path_get_basename(filename); - - Glib::ustring::size_type last_slash_pos = basename.rfind('/'); - if (last_slash_pos == Glib::ustring::npos) { - last_slash_pos = basename.rfind('\\'); - } - - const Glib::ustring::size_type last_dot_pos = basename.rfind('.'); - - if (last_dot_pos != Glib::ustring::npos) { - name.assign(basename, 0, last_dot_pos); - extension.assign(basename, last_dot_pos + 1, Glib::ustring::npos); - } else { - name = basename; - } - - profile_name = "sRGB"; - - for (const auto& working_profile : rtengine::getWorkingProfiles()) { - if ( std::search( name.rbegin(), name.rend(), working_profile.rbegin(), working_profile.rend() ) == name.rbegin() ) { - profile_name = working_profile; - name.erase(name.size() - working_profile.size()); - break; - } - } -} - rtengine::HaldCLUT::HaldCLUT() : clut_level(0), flevel_minus_one(0.0f), @@ -164,7 +130,14 @@ Glib::ustring rtengine::HaldCLUT::getProfile() const return clut_profile; } -void rtengine::HaldCLUT::getRGB(std::size_t line_size, const float* r, const float* g, const float* b, float* out_rgbx) const +void rtengine::HaldCLUT::getRGB( + float strength, + std::size_t line_size, + const float* r, + const float* g, + const float* b, + float* out_rgbx +) const { const unsigned int level = clut_level; // This is important @@ -219,13 +192,18 @@ void rtengine::HaldCLUT::getRGB(std::size_t line_size, const float* r, const flo out_rgbx[0] = intp(bl, tmp1[0], out_rgbx[0]); out_rgbx[1] = intp(bl, tmp1[1], out_rgbx[1]); out_rgbx[2] = intp(bl, tmp1[2], out_rgbx[2]); + + out_rgbx[0] = intp(strength, out_rgbx[0], *r); + out_rgbx[1] = intp(strength, out_rgbx[1], *g); + out_rgbx[2] = intp(strength, out_rgbx[2], *b); #else - const vfloat v_tmp = _mm_set_ps(0.0f, *b, *g, *r) * _mm_load_ps1(&flevel_minus_one); + const vfloat v_in = _mm_set_ps(0.0f, *b, *g, *r); + const vfloat v_tmp = v_in * _mm_load_ps1(&flevel_minus_one); const vfloat v_rgb = v_tmp - _mm_cvtepi32_ps(_mm_cvttps_epi32(_mm_min_ps(_mm_load_ps1(&flevel_minus_two), v_tmp))); size_t index = color * 4; - const vfloat v_r = PERMUTEPS(v_rgb, 0x00); + const vfloat v_r = PERMUTEPS(v_rgb, _MM_SHUFFLE(0, 0, 0, 0)); vfloat v_tmp1 = vintpf(v_r, getClutValue(clut_image, index + 4), getClutValue(clut_image, index)); @@ -233,7 +211,7 @@ void rtengine::HaldCLUT::getRGB(std::size_t line_size, const float* r, const flo vfloat v_tmp2 = vintpf(v_r, getClutValue(clut_image, index + 4), getClutValue(clut_image, index)); - const vfloat v_g = PERMUTEPS(v_rgb, 0x55); + const vfloat v_g = PERMUTEPS(v_rgb, _MM_SHUFFLE(1, 1, 1, 1)); vfloat v_out = vintpf(v_g, v_tmp2, v_tmp1); @@ -247,22 +225,58 @@ void rtengine::HaldCLUT::getRGB(std::size_t line_size, const float* r, const flo v_tmp1 = vintpf(v_g, v_tmp2, v_tmp1); - const vfloat v_b = PERMUTEPS(v_rgb, 0xAA); + const vfloat v_b = PERMUTEPS(v_rgb, _MM_SHUFFLE(2, 2, 2, 2)); - _mm_store_ps(out_rgbx, vintpf(v_b, v_tmp1, v_out)); + v_out = vintpf(v_b, v_tmp1, v_out); + + _mm_store_ps(out_rgbx, vintpf(_mm_load_ps1(&strength), v_out, v_in)); #endif } } +void rtengine::HaldCLUT::splitClutFilename( + const Glib::ustring& filename, + Glib::ustring& name, + Glib::ustring& extension, + Glib::ustring& profile_name +) +{ + Glib::ustring basename = Glib::path_get_basename(filename); + + Glib::ustring::size_type last_slash_pos = basename.rfind('/'); + if (last_slash_pos == Glib::ustring::npos) { + last_slash_pos = basename.rfind('\\'); + } + + const Glib::ustring::size_type last_dot_pos = basename.rfind('.'); + + if (last_dot_pos != Glib::ustring::npos) { + name.assign(basename, 0, last_dot_pos); + extension.assign(basename, last_dot_pos + 1, Glib::ustring::npos); + } else { + name = basename; + } + + profile_name = "sRGB"; + + for (const auto& working_profile : rtengine::getWorkingProfiles()) { + if ( std::search( name.rbegin(), name.rend(), working_profile.rbegin(), working_profile.rend() ) == name.rbegin() ) { + profile_name = working_profile; + name.erase(name.size() - working_profile.size()); + break; + } + } +} + rtengine::CLUTStore& rtengine::CLUTStore::getInstance() { static CLUTStore instance; return instance; } -std::shared_ptr rtengine::CLUTStore::getClut(const Glib::ustring& filename) +std::shared_ptr rtengine::CLUTStore::getClut(const Glib::ustring& filename) { - std::shared_ptr result; + std::shared_ptr result; if (!cache.get(filename, result)) { std::unique_ptr clut(new rtengine::HaldCLUT); @@ -275,11 +289,6 @@ std::shared_ptr rtengine::CLUTStore::getClut(const Glib::ustring return result; } -void rtengine::CLUTStore::releaseClut(const std::shared_ptr& clut) -{ - cache.remove(clut->getFilename()); -} - void rtengine::CLUTStore::clearCache() { cache.clear(); diff --git a/rtengine/clutstore.h b/rtengine/clutstore.h index 6203e4e61..7383b597f 100644 --- a/rtengine/clutstore.h +++ b/rtengine/clutstore.h @@ -11,20 +11,29 @@ namespace rtengine { -class CLUT +class HaldCLUT { public: - CLUT() = default; - CLUT(const CLUT& other) = delete; - CLUT& operator =(const CLUT& other) = delete; - virtual ~CLUT() = default; + HaldCLUT(); + HaldCLUT(const HaldCLUT& other) = delete; + HaldCLUT& operator =(const HaldCLUT& other) = delete; + ~HaldCLUT(); - virtual explicit operator bool() const = 0; + bool load(const Glib::ustring& filename); - virtual Glib::ustring getFilename() const = 0; - virtual Glib::ustring getProfile() const = 0; + explicit operator bool() const; - virtual void getRGB(std::size_t line_size, const float* r, const float* g, const float* b, float* out_rgbx) const = 0; + Glib::ustring getFilename() const; + Glib::ustring getProfile() const; + + void getRGB( + float strength, + std::size_t line_size, + const float* r, + const float* g, + const float* b, + float* out_rgbx + ) const; static void splitClutFilename( const Glib::ustring& filename, @@ -32,23 +41,6 @@ public: Glib::ustring& extension, Glib::ustring& profile_name ); -}; - -class HaldCLUT - : public CLUT -{ -public: - HaldCLUT(); - ~HaldCLUT(); - - bool load(const Glib::ustring& filename); - - explicit operator bool() const override; - - Glib::ustring getFilename() const override; - Glib::ustring getProfile() const override; - - void getRGB(std::size_t line_size, const float* r, const float* g, const float* b, float* out_rgbx) const override; private: AlignedBuffer clut_image; @@ -67,15 +59,14 @@ public: CLUTStore(const CLUTStore& other) = delete; CLUTStore& operator =(const CLUTStore& other) = delete; - std::shared_ptr getClut(const Glib::ustring& filename); - void releaseClut(const std::shared_ptr& clut); + std::shared_ptr getClut(const Glib::ustring& filename); void clearCache(); private: CLUTStore(); - Cache> cache; + Cache> cache; }; } diff --git a/rtengine/improcfun.cc b/rtengine/improcfun.cc index 2fd2bfb17..4bc95e5fa 100644 --- a/rtengine/improcfun.cc +++ b/rtengine/improcfun.cc @@ -16,7 +16,6 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#include #include #include #include @@ -3206,27 +3205,26 @@ void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, PipetteBuffer } } - std::shared_ptr colorLUT; + std::shared_ptr hald_clut; bool clutAndWorkingProfilesAreSame = false; TMatrix work2xyz, xyz2clut, clut2xyz, xyz2work; if ( params->filmSimulation.enabled && !params->filmSimulation.clutFilename.empty() ) { - colorLUT = CLUTStore::getInstance().getClut( params->filmSimulation.clutFilename ); + hald_clut = CLUTStore::getInstance().getClut( params->filmSimulation.clutFilename ); - if ( colorLUT ) { - clutAndWorkingProfilesAreSame = colorLUT->getProfile() == params->icm.working; + if ( hald_clut ) { + clutAndWorkingProfilesAreSame = hald_clut->getProfile() == params->icm.working; if ( !clutAndWorkingProfilesAreSame ) { work2xyz = iccStore->workingSpaceMatrix( params->icm.working ); - xyz2clut = iccStore->workingSpaceInverseMatrix( colorLUT->getProfile() ); + xyz2clut = iccStore->workingSpaceInverseMatrix( hald_clut->getProfile() ); xyz2work = iccStore->workingSpaceInverseMatrix( params->icm.working ); - clut2xyz = iccStore->workingSpaceMatrix( colorLUT->getProfile() ); + clut2xyz = iccStore->workingSpaceMatrix( hald_clut->getProfile() ); } } } - float filmSimCorrectedStrength = static_cast(params->filmSimulation.strength) / 100.0f; - float filmSimSourceStrength = 1.0f - filmSimCorrectedStrength; + const float film_simulation_strength = static_cast(params->filmSimulation.strength) / 100.0f; const float exp_scale = pow (2.0, expcomp); const float comp = (max(0.0, expcomp) + 1.0) * hlcompr / 100.0; @@ -4337,11 +4335,8 @@ void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, PipetteBuffer //Film Simulations - if ( colorLUT ) { - std::size_t out_rgbx_size = 4 * (TS + 16); - std::unique_ptr out_rgbx_buf(new float[out_rgbx_size]); - void* out_rgbx_ptr = out_rgbx_buf.get(); - float* const out_rgbx = reinterpret_cast(std::align(16, 4 * TS, out_rgbx_ptr, out_rgbx_size)); + if ( hald_clut ) { + float out_rgbx[4 * TS] ALIGNED16; for (int i = istart, ti = 0; i < tH; i++, ti++) { for (int j = jstart, tj = 0; j < tW; j++, tj++) { @@ -4362,21 +4357,25 @@ void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, PipetteBuffer sourceB = CLIP( Color::gamma_srgb( sourceB ) ); } - colorLUT->getRGB(std::min(TS, tW - jstart), rtemp + ti * TS, gtemp + ti * TS, btemp + ti * TS, out_rgbx); + const std::size_t line_offset = ti * TS; + hald_clut->getRGB( + film_simulation_strength, + std::min(TS, tW - jstart), + rtemp + line_offset, + gtemp + line_offset, + btemp + line_offset, + out_rgbx + ); for (int j = jstart, tj = 0; j < tW; j++, tj++) { float &sourceR = rtemp[ti * TS + tj]; float &sourceG = gtemp[ti * TS + tj]; float &sourceB = btemp[ti * TS + tj]; - // apply strength - sourceR = out_rgbx[tj * 4 + 0] * filmSimCorrectedStrength + sourceR * filmSimSourceStrength; - sourceG = out_rgbx[tj * 4 + 1] * filmSimCorrectedStrength + sourceG * filmSimSourceStrength; - sourceB = out_rgbx[tj * 4 + 2] * filmSimCorrectedStrength + sourceB * filmSimSourceStrength; // apply inverse gamma sRGB - sourceR = Color::igamma_srgb( sourceR ); - sourceG = Color::igamma_srgb( sourceG ); - sourceB = Color::igamma_srgb( sourceB ); + sourceR = Color::igamma_srgb(out_rgbx[tj * 4 + 0]); + sourceG = Color::igamma_srgb(out_rgbx[tj * 4 + 1]); + sourceB = Color::igamma_srgb(out_rgbx[tj * 4 + 2]); if (!clutAndWorkingProfilesAreSame) { //convert from clut to working profile diff --git a/rtgui/filmsimulation.cc b/rtgui/filmsimulation.cc index 3ee1f4742..f916a5397 100644 --- a/rtgui/filmsimulation.cc +++ b/rtgui/filmsimulation.cc @@ -72,7 +72,7 @@ void FilmSimulation::onClutSelected() if ( getEnabled() && !currentClutFilename.empty() && listener && currentClutFilename != m_oldClutFilename ) { Glib::ustring clutName, dummy; - CLUT::splitClutFilename( currentClutFilename, clutName, dummy, dummy ); + HaldCLUT::splitClutFilename( currentClutFilename, clutName, dummy, dummy ); listener->panelChanged( EvFilmSimulationFilename, clutName ); m_oldClutFilename = currentClutFilename; @@ -279,7 +279,7 @@ int ClutComboBox::parseDir (const Glib::ustring& path) for (const auto& entry : entries) { Glib::ustring name, extension, profileName; - CLUT::splitClutFilename (entry, name, extension, profileName); + HaldCLUT::splitClutFilename (entry, name, extension, profileName); extension = extension.casefold (); if (extension.compare ("tif") != 0 && extension.compare ("png") != 0) {