|
Carlos Lopez |
a09598 |
/* === S Y N F I G ========================================================= */
|
|
Carlos Lopez |
a09598 |
/*! \file colorcorrect.cpp
|
|
Carlos Lopez |
a09598 |
** \brief Implementation of the "Color Correct" layer
|
|
Carlos Lopez |
a09598 |
**
|
|
Carlos Lopez |
a09598 |
** $Id$
|
|
Carlos Lopez |
a09598 |
**
|
|
Carlos Lopez |
a09598 |
** \legal
|
|
Carlos Lopez |
a09598 |
** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
|
|
Carlos Lopez |
e83454 |
** Copyright (c) 2012-2013 Carlos Lรณpez
|
|
Carlos Lopez |
a09598 |
**
|
|
Carlos Lopez |
a09598 |
** This package is free software; you can redistribute it and/or
|
|
Carlos Lopez |
a09598 |
** modify it under the terms of the GNU General Public License as
|
|
Carlos Lopez |
a09598 |
** published by the Free Software Foundation; either version 2 of
|
|
Carlos Lopez |
a09598 |
** the License, or (at your option) any later version.
|
|
Carlos Lopez |
a09598 |
**
|
|
Carlos Lopez |
a09598 |
** This package is distributed in the hope that it will be useful,
|
|
Carlos Lopez |
a09598 |
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Carlos Lopez |
a09598 |
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Carlos Lopez |
a09598 |
** General Public License for more details.
|
|
Carlos Lopez |
a09598 |
** \endlegal
|
|
Carlos Lopez |
a09598 |
*/
|
|
Carlos Lopez |
a09598 |
/* ========================================================================= */
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
/* === H E A D E R S ======================================================= */
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
#ifdef USING_PCH
|
|
Carlos Lopez |
a09598 |
# include "pch.h"
|
|
Carlos Lopez |
a09598 |
#else
|
|
Carlos Lopez |
a09598 |
#ifdef HAVE_CONFIG_H
|
|
Carlos Lopez |
a09598 |
# include <config.h></config.h>
|
|
Carlos Lopez |
a09598 |
#endif
|
|
Carlos Lopez |
a09598 |
|
|
bw |
94d8a6 |
#include <synfig localization.h=""></synfig>
|
|
bw |
94d8a6 |
#include <synfig general.h=""></synfig>
|
|
bw |
94d8a6 |
|
|
Carlos Lopez |
a09598 |
#include "colorcorrect.h"
|
|
Carlos Lopez |
a09598 |
#include <synfig string.h=""></synfig>
|
|
Carlos Lopez |
a09598 |
#include <synfig time.h=""></synfig>
|
|
Carlos Lopez |
a09598 |
#include <synfig context.h=""></synfig>
|
|
Carlos Lopez |
a09598 |
#include <synfig paramdesc.h=""></synfig>
|
|
Carlos Lopez |
a09598 |
#include <synfig renddesc.h=""></synfig>
|
|
Carlos Lopez |
a09598 |
#include <synfig surface.h=""></synfig>
|
|
Carlos Lopez |
a09598 |
#include <synfig value.h=""></synfig>
|
|
Carlos Lopez |
a09598 |
#include <synfig valuenode.h=""></synfig>
|
|
Carlos Lopez |
3a61ac |
#include <synfig cairo_renddesc.h=""></synfig>
|
|
Carlos Lopez |
a09598 |
|
|
|
5e2754 |
#include <synfig common="" rendering="" task="" taskpixelprocessor.h=""></synfig>
|
|
|
a94d49 |
|
|
Carlos Lopez |
a09598 |
#endif
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
/* === U S I N G =========================================================== */
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
using namespace etl;
|
|
Carlos Lopez |
a09598 |
using namespace std;
|
|
Carlos Lopez |
a09598 |
using namespace synfig;
|
|
|
93caa9 |
using namespace modules;
|
|
|
93caa9 |
using namespace mod_filter;
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
/* === G L O B A L S ======================================================= */
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
SYNFIG_LAYER_INIT(Layer_ColorCorrect);
|
|
Carlos Lopez |
a09598 |
SYNFIG_LAYER_SET_NAME(Layer_ColorCorrect,"colorcorrect");
|
|
Carlos Lopez |
a09598 |
SYNFIG_LAYER_SET_LOCAL_NAME(Layer_ColorCorrect,N_("Color Correct"));
|
|
Carlos Lopez |
a09598 |
SYNFIG_LAYER_SET_CATEGORY(Layer_ColorCorrect,N_("Filters"));
|
|
Carlos Lopez |
a09598 |
SYNFIG_LAYER_SET_VERSION(Layer_ColorCorrect,"0.1");
|
|
Carlos Lopez |
a09598 |
SYNFIG_LAYER_SET_CVS_ID(Layer_ColorCorrect,"$Id$");
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
/* === P R O C E D U R E S ================================================= */
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
/* === M E T H O D S ======================================================= */
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
/* === E N T R Y P O I N T ================================================= */
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
Layer_ColorCorrect::Layer_ColorCorrect():
|
|
Carlos Lopez |
9a0f27 |
param_hue_adjust(ValueBase(Angle::zero())),
|
|
Carlos Lopez |
9a0f27 |
param_brightness(ValueBase(Real(0))),
|
|
Carlos Lopez |
9a0f27 |
param_contrast(ValueBase(Real(1.0))),
|
|
Carlos Lopez |
9a0f27 |
param_exposure(ValueBase(Real(0.0))),
|
|
Carlos Lopez |
9a0f27 |
param_gamma(ValueBase(Real(1.0)))
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
9a0f27 |
SET_INTERPOLATION_DEFAULTS();
|
|
Carlos Lopez |
9a0f27 |
SET_STATIC_DEFAULTS();
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
inline Color
|
|
Carlos Lopez |
a09598 |
Layer_ColorCorrect::correct_color(const Color &in)const
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
9a0f27 |
Angle hue_adjust=param_hue_adjust.get(Angle());
|
|
Carlos Lopez |
9a0f27 |
Real _brightness=param_brightness.get(Real());
|
|
Carlos Lopez |
9a0f27 |
Real contrast=param_contrast.get(Real());
|
|
Carlos Lopez |
9a0f27 |
Real exposure=param_exposure.get(Real());
|
|
Carlos Lopez |
9a0f27 |
|
|
Carlos Lopez |
9a0f27 |
Real brightness((_brightness-0.5)*contrast+0.5);
|
|
Carlos Lopez |
a09598 |
|
|
|
a4bbdd |
Color ret = gamma.apply(in);
|
|
Carlos Lopez |
a09598 |
|
|
[d.j.a.y] Jerome Blanchi |
c14c8d |
assert(!std::isnan(ret.get_r()));
|
|
[d.j.a.y] Jerome Blanchi |
c14c8d |
assert(!std::isnan(ret.get_g()));
|
|
[d.j.a.y] Jerome Blanchi |
c14c8d |
assert(!std::isnan(ret.get_b()));
|
|
|
23b4d4 |
assert(!std::isnan(ret.get_a()));
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
if(exposure!=0.0)
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
const float factor(exp(exposure));
|
|
Carlos Lopez |
a09598 |
ret.set_r(ret.get_r()*factor);
|
|
Carlos Lopez |
a09598 |
ret.set_g(ret.get_g()*factor);
|
|
Carlos Lopez |
a09598 |
ret.set_b(ret.get_b()*factor);
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
// Adjust Contrast
|
|
Carlos Lopez |
a09598 |
if(contrast!=1.0)
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
ret.set_r(ret.get_r()*contrast);
|
|
Carlos Lopez |
a09598 |
ret.set_g(ret.get_g()*contrast);
|
|
Carlos Lopez |
a09598 |
ret.set_b(ret.get_b()*contrast);
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
if(brightness)
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
// Adjust R Channel Brightness
|
|
Carlos Lopez |
a09598 |
if(ret.get_r()>-brightness)
|
|
Carlos Lopez |
a09598 |
ret.set_r(ret.get_r()+brightness);
|
|
Carlos Lopez |
a09598 |
else if(ret.get_r()
|
|
Carlos Lopez |
a09598 |
ret.set_r(ret.get_r()-brightness);
|
|
Carlos Lopez |
a09598 |
else
|
|
Carlos Lopez |
a09598 |
ret.set_r(0);
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
// Adjust G Channel Brightness
|
|
Carlos Lopez |
a09598 |
if(ret.get_g()>-brightness)
|
|
Carlos Lopez |
a09598 |
ret.set_g(ret.get_g()+brightness);
|
|
Carlos Lopez |
a09598 |
else if(ret.get_g()
|
|
Carlos Lopez |
a09598 |
ret.set_g(ret.get_g()-brightness);
|
|
Carlos Lopez |
a09598 |
else
|
|
Carlos Lopez |
a09598 |
ret.set_g(0);
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
// Adjust B Channel Brightness
|
|
Carlos Lopez |
a09598 |
if(ret.get_b()>-brightness)
|
|
Carlos Lopez |
a09598 |
ret.set_b(ret.get_b()+brightness);
|
|
Carlos Lopez |
a09598 |
else if(ret.get_b()
|
|
Carlos Lopez |
a09598 |
ret.set_b(ret.get_b()-brightness);
|
|
Carlos Lopez |
a09598 |
else
|
|
Carlos Lopez |
a09598 |
ret.set_b(0);
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
// Return the color, adjusting the hue if necessary
|
|
Carlos Lopez |
a09598 |
if(!!hue_adjust)
|
|
Carlos Lopez |
a09598 |
return ret.rotate_uv(hue_adjust);
|
|
Carlos Lopez |
a09598 |
else
|
|
Carlos Lopez |
a09598 |
return ret;
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
bool
|
|
Carlos Lopez |
a09598 |
Layer_ColorCorrect::set_param(const String & param, const ValueBase &value)
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
9a0f27 |
IMPORT_VALUE(param_hue_adjust);
|
|
Carlos Lopez |
9a0f27 |
IMPORT_VALUE(param_brightness);
|
|
Carlos Lopez |
9a0f27 |
IMPORT_VALUE(param_contrast);
|
|
Carlos Lopez |
9a0f27 |
IMPORT_VALUE(param_exposure);
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
9a0f27 |
IMPORT_VALUE_PLUS(param_gamma,
|
|
Carlos Lopez |
9a0f27 |
{
|
|
|
a4bbdd |
gamma.set(1.0/param_gamma.get(Real()));
|
|
Carlos Lopez |
9a0f27 |
return true;
|
|
Carlos Lopez |
9a0f27 |
});
|
|
Carlos Lopez |
a09598 |
return false;
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
ValueBase
|
|
Carlos Lopez |
a09598 |
Layer_ColorCorrect::get_param(const String ¶m)const
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
9a0f27 |
EXPORT_VALUE(param_hue_adjust);
|
|
Carlos Lopez |
9a0f27 |
EXPORT_VALUE(param_brightness);
|
|
Carlos Lopez |
9a0f27 |
EXPORT_VALUE(param_contrast);
|
|
Carlos Lopez |
9a0f27 |
EXPORT_VALUE(param_exposure);
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
if(param=="gamma")
|
|
Carlos Lopez |
35ab92 |
{
|
|
Carlos Lopez |
9a0f27 |
ValueBase ret=param_gamma;
|
|
|
a4bbdd |
ret.set(1.0/gamma.get());
|
|
Carlos Lopez |
35ab92 |
return ret;
|
|
Carlos Lopez |
35ab92 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
EXPORT_NAME();
|
|
Carlos Lopez |
a09598 |
EXPORT_VERSION();
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
return ValueBase();
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
Layer::Vocab
|
|
Carlos Lopez |
a09598 |
Layer_ColorCorrect::get_param_vocab()const
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
Layer::Vocab ret;
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
ret.push_back(ParamDesc("hue_adjust")
|
|
Carlos Lopez |
a09598 |
.set_local_name(_("Hue Adjust"))
|
|
Carlos Lopez |
a09598 |
);
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
ret.push_back(ParamDesc("brightness")
|
|
Carlos Lopez |
a09598 |
.set_local_name(_("Brightness"))
|
|
Carlos Lopez |
a09598 |
);
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
ret.push_back(ParamDesc("contrast")
|
|
Carlos Lopez |
a09598 |
.set_local_name(_("Contrast"))
|
|
Carlos Lopez |
a09598 |
);
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
ret.push_back(ParamDesc("exposure")
|
|
Carlos Lopez |
a09598 |
.set_local_name(_("Exposure Adjust"))
|
|
Carlos Lopez |
a09598 |
);
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
ret.push_back(ParamDesc("gamma")
|
|
Carlos Lopez |
a09598 |
.set_local_name(_("Gamma Adjustment"))
|
|
Carlos Lopez |
a09598 |
);
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
return ret;
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
Color
|
|
Carlos Lopez |
a09598 |
Layer_ColorCorrect::get_color(Context context, const Point &pos)const
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
return correct_color(context.get_color(pos));
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
Rect
|
|
Carlos Lopez |
a09598 |
Layer_ColorCorrect::get_full_bounding_rect(Context context)const
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
return context.get_full_bounding_rect();
|
|
Carlos Lopez |
a09598 |
}
|
|
|
a94d49 |
|
|
|
a94d49 |
rendering::Task::Handle
|
|
|
a94d49 |
Layer_ColorCorrect::build_rendering_task_vfunc(Context context)const
|
|
|
a94d49 |
{
|
|
|
bf609b |
rendering::Task::Handle task = context.build_rendering_task();
|
|
|
bf609b |
|
|
|
bf609b |
ColorReal gamma = param_gamma.get(Real());
|
|
|
bf609b |
if (!approximate_equal_lp(gamma, ColorReal(1.0)))
|
|
|
bf609b |
{
|
|
|
bf609b |
rendering::TaskPixelGamma::Handle task_gamma(new rendering::TaskPixelGamma());
|
|
|
a4bbdd |
task_gamma->gamma = Gamma(gamma).get_inverted();
|
|
|
bf609b |
task_gamma->sub_task() = task;
|
|
|
bf609b |
task = task_gamma;
|
|
|
bf609b |
}
|
|
|
bf609b |
|
|
|
bf609b |
ColorMatrix matrix;
|
|
|
bf609b |
matrix *= ColorMatrix().set_hue( param_hue_adjust.get(Angle()) );
|
|
|
bf609b |
matrix *= ColorMatrix().set_exposure( param_exposure.get(Real()) );
|
|
|
bf609b |
matrix *= ColorMatrix().set_brightness( param_brightness.get(Real()) );
|
|
|
bf609b |
matrix *= ColorMatrix().set_contrast( param_contrast.get(Real()) );
|
|
|
bf609b |
|
|
|
bf609b |
if (!matrix.is_copy())
|
|
|
bf609b |
{
|
|
|
bf609b |
rendering::TaskPixelColorMatrix::Handle task_matrix(new rendering::TaskPixelColorMatrix());
|
|
|
bf609b |
task_matrix->matrix = matrix;
|
|
|
bf609b |
task_matrix->sub_task() = task;
|
|
|
bf609b |
task = task_matrix;
|
|
|
bf609b |
}
|
|
|
bf609b |
|
|
|
bf609b |
return task;
|
|
|
a94d49 |
}
|