Move film_simulation_strength calculation into HaldCLUT::getRGB()

- Moved `film_simulation_strength` calculation into `HaldCLUT::getRGB()`
- Removed unneeded base class `CLUT`
- Used `_MM_SHUFFLE`
This commit is contained in:
Flössie
2016-04-29 17:26:56 +02:00
parent 9dee6dddf1
commit 29fe23e517
4 changed files with 99 additions and 100 deletions

View File

@@ -87,40 +87,6 @@ inline vfloat getClutValue(const AlignedBuffer<std::uint16_t>& 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<float>(bl, tmp1[0], out_rgbx[0]);
out_rgbx[1] = intp<float>(bl, tmp1[1], out_rgbx[1]);
out_rgbx[2] = intp<float>(bl, tmp1[2], out_rgbx[2]);
out_rgbx[0] = intp<float>(strength, out_rgbx[0], *r);
out_rgbx[1] = intp<float>(strength, out_rgbx[1], *g);
out_rgbx[2] = intp<float>(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::CLUT> rtengine::CLUTStore::getClut(const Glib::ustring& filename)
std::shared_ptr<rtengine::HaldCLUT> rtengine::CLUTStore::getClut(const Glib::ustring& filename)
{
std::shared_ptr<rtengine::CLUT> result;
std::shared_ptr<rtengine::HaldCLUT> result;
if (!cache.get(filename, result)) {
std::unique_ptr<rtengine::HaldCLUT> clut(new rtengine::HaldCLUT);
@@ -275,11 +289,6 @@ std::shared_ptr<rtengine::CLUT> rtengine::CLUTStore::getClut(const Glib::ustring
return result;
}
void rtengine::CLUTStore::releaseClut(const std::shared_ptr<rtengine::CLUT>& clut)
{
cache.remove(clut->getFilename());
}
void rtengine::CLUTStore::clearCache()
{
cache.clear();

View File

@@ -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<std::uint16_t> clut_image;
@@ -67,15 +59,14 @@ public:
CLUTStore(const CLUTStore& other) = delete;
CLUTStore& operator =(const CLUTStore& other) = delete;
std::shared_ptr<CLUT> getClut(const Glib::ustring& filename);
void releaseClut(const std::shared_ptr<CLUT>& clut);
std::shared_ptr<HaldCLUT> getClut(const Glib::ustring& filename);
void clearCache();
private:
CLUTStore();
Cache<Glib::ustring, std::shared_ptr<CLUT>> cache;
Cache<Glib::ustring, std::shared_ptr<HaldCLUT>> cache;
};
}

View File

@@ -16,7 +16,6 @@
* You should have received a copy of the GNU General Public License
* along with RawTherapee. If not, see <http://www.gnu.org/licenses/>.
*/
#include <memory>
#include <cmath>
#include <glib.h>
#include <glibmm.h>
@@ -3206,27 +3205,26 @@ void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, PipetteBuffer
}
}
std::shared_ptr<CLUT> colorLUT;
std::shared_ptr<HaldCLUT> 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<float>(params->filmSimulation.strength) / 100.0f;
float filmSimSourceStrength = 1.0f - filmSimCorrectedStrength;
const float film_simulation_strength = static_cast<float>(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<float> out_rgbx_buf(new float[out_rgbx_size]);
void* out_rgbx_ptr = out_rgbx_buf.get();
float* const out_rgbx = reinterpret_cast<float*>(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<float>( 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

View File

@@ -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) {