Skip to content

Commit

Permalink
ColorMatrix
Browse files Browse the repository at this point in the history
  • Loading branch information
blackwarthog committed Mar 22, 2016
1 parent 5b5cf9e commit bf609b7
Show file tree
Hide file tree
Showing 25 changed files with 1,735 additions and 237 deletions.
205 changes: 30 additions & 175 deletions synfig-core/src/modules/mod_filter/colorcorrect.cpp
Expand Up @@ -44,7 +44,8 @@
#include <synfig/valuenode.h>
#include <synfig/cairo_renddesc.h>

#include <synfig/rendering/software/surfacesw.h>
#include <synfig/rendering/common/task/taskpixelcolormatrix.h>
#include <synfig/rendering/common/task/taskpixelgamma.h>

#endif

Expand All @@ -71,172 +72,6 @@ SYNFIG_LAYER_SET_CVS_ID(Layer_ColorCorrect,"$Id$");

/* === E N T R Y P O I N T ================================================= */

void
TaskColorCorrectSW::split(const RectInt &sub_target_rect)
{
trunc_target_rect(sub_target_rect);
if (valid_target() && sub_task() && sub_task()->valid_target())
{
sub_task() = sub_task()->clone();
sub_task()->trunc_target_rect(
get_target_rect()
- get_target_offset()
- get_offset() );
}
}

void
TaskColorCorrectSW::correct_pixel(Color &dst, const Color &src, const Angle &hue_adjust, ColorReal shift, ColorReal amplifier, const Gamma &gamma) const
{
static const double precision = 1e-8;

dst = src;

if (fabs(gamma.get_gamma_r() - 1.0) > precision)
{
if (dst.get_r() < 0)
dst.set_r(-gamma.r_F32_to_F32(-dst.get_r()));
else
dst.set_r(gamma.r_F32_to_F32(dst.get_r()));
}

if (fabs(gamma.get_gamma_g() - 1.0) > precision)
{
if (dst.get_g() < 0)
dst.set_g(-gamma.g_F32_to_F32(-dst.get_g()));
else
dst.set_g(gamma.g_F32_to_F32(dst.get_g()));
}

if (fabs(gamma.get_gamma_b() - 1.0) > precision)
{
if (dst.get_b() < 0)
dst.set_b(-gamma.b_F32_to_F32(-dst.get_b()));
else
dst.set_b(gamma.b_F32_to_F32(dst.get_b()));
}

assert(!isnan(dst.get_r()));
assert(!isnan(dst.get_g()));
assert(!isnan(dst.get_b()));

if (fabs(amplifier - 1.0) > precision)
{
dst.set_r(dst.get_r()*amplifier);
dst.set_g(dst.get_g()*amplifier);
dst.set_b(dst.get_b()*amplifier);
}

if (fabs(shift) > precision)
{
// Adjust R Channel Brightness
if (dst.get_r() > -shift)
dst.set_r(dst.get_r() + shift);
else
if(dst.get_r() < shift)
dst.set_r(dst.get_r() - shift);
else
dst.set_r(0);

// Adjust G Channel Brightness
if (dst.get_g() > -shift)
dst.set_g(dst.get_g() + shift);
else
if(dst.get_g() < shift)
dst.set_g(dst.get_g() - shift);
else
dst.set_g(0);

// Adjust B Channel Brightness
if (dst.get_b() > -shift)
dst.set_b(dst.get_b() + shift);
else
if(dst.get_b() < shift)
dst.set_b(dst.get_b() - shift);
else
dst.set_b(0);
}

// Return the color, adjusting the hue if necessary
if (!!hue_adjust)
dst.rotate_uv(hue_adjust);
}

bool
TaskColorCorrectSW::run(RunParams & /* params */) const
{
const synfig::Surface &a =
rendering::SurfaceSW::Handle::cast_dynamic( sub_task()->target_surface )->get_surface();
synfig::Surface &c =
rendering::SurfaceSW::Handle::cast_dynamic( target_surface )->get_surface();

//debug::DebugSurface::save_to_file(a, "TaskClampSW__run__a");

RectInt r = get_target_rect();
if (r.valid())
{
VectorInt offset = get_offset();
RectInt ra = sub_task()->get_target_rect() + r.get_min() + offset;
if (ra.valid())
{
etl::set_intersect(ra, ra, r);
if (ra.valid())
{
ColorReal amplifier = (ColorReal)(contrast*exp(exposure));
ColorReal shift = (ColorReal)((brightness - 0.5)*contrast + 0.5);
Gamma g(fabs(gamma) < 1e-8 ? 1.0 : 1.0/gamma);

synfig::Surface::pen pc = c.get_pen(ra.minx, ra.maxx);
synfig::Surface::pen pa = c.get_pen(ra.minx, ra.maxx);
for(int y = ra.miny; y < ra.maxy; ++y)
{
const Color *ca = &a[y - r.miny - offset[1]][ra.minx - r.minx - offset[0]];
Color *cc = &c[y][ra.minx];
for(int x = ra.minx; x < ra.maxx; ++x, ++ca, ++cc)
correct_pixel(*cc, *ca, hue_adjust, shift, amplifier, g);
}
}
}
}

//debug::DebugSurface::save_to_file(c, "TaskClampSW__run__c");

return true;
}


void
OptimizerColorCorrectSW::run(const RunParams& params) const
{
TaskColorCorrect::Handle color_correct = TaskColorCorrect::Handle::cast_dynamic(params.ref_task);
if ( color_correct
&& color_correct->target_surface
&& color_correct.type_equal<TaskColorCorrect>() )
{
TaskColorCorrectSW::Handle color_correct_sw;
init_and_assign_all<rendering::SurfaceSW>(color_correct_sw, color_correct);

// TODO: Are we really need to check 'is_temporary' flag?
if ( color_correct_sw->sub_task()->target_surface->is_temporary )
{
color_correct_sw->sub_task()->target_surface = color_correct_sw->target_surface;
color_correct_sw->sub_task()->move_target_rect(
color_correct_sw->get_target_offset() );
}
else
{
color_correct_sw->sub_task()->set_target_origin( VectorInt::zero() );
color_correct_sw->sub_task()->target_surface->set_size(
color_correct_sw->sub_task()->get_target_rect().maxx,
color_correct_sw->sub_task()->get_target_rect().maxy );
}
assert( color_correct_sw->sub_task()->check() );

apply(params, color_correct_sw);
}
}


Layer_ColorCorrect::Layer_ColorCorrect():
param_hue_adjust(ValueBase(Angle::zero())),
param_brightness(ValueBase(Real(0))),
Expand Down Expand Up @@ -507,12 +342,32 @@ Layer_ColorCorrect::get_full_bounding_rect(Context context)const
rendering::Task::Handle
Layer_ColorCorrect::build_rendering_task_vfunc(Context context)const
{
TaskColorCorrect::Handle task_color_correct(new TaskColorCorrect());
task_color_correct->hue_adjust = param_hue_adjust.get(Angle());
task_color_correct->brightness = param_brightness.get(Real());
task_color_correct->contrast = param_contrast.get(Real());
task_color_correct->exposure = param_exposure.get(Real());
task_color_correct->gamma = param_gamma.get(Real());
task_color_correct->sub_task() = context.build_rendering_task();
return task_color_correct;
rendering::Task::Handle task = context.build_rendering_task();

ColorReal gamma = param_gamma.get(Real());
if (!approximate_equal_lp(gamma, ColorReal(1.0)))
{
rendering::TaskPixelGamma::Handle task_gamma(new rendering::TaskPixelGamma());
task_gamma->gamma_r = gamma;
task_gamma->gamma_g = gamma;
task_gamma->gamma_b = gamma;
task_gamma->sub_task() = task;
task = task_gamma;
}

ColorMatrix matrix;
matrix *= ColorMatrix().set_hue( param_hue_adjust.get(Angle()) );
matrix *= ColorMatrix().set_exposure( param_exposure.get(Real()) );
matrix *= ColorMatrix().set_brightness( param_brightness.get(Real()) );
matrix *= ColorMatrix().set_contrast( param_contrast.get(Real()) );

if (!matrix.is_copy())
{
rendering::TaskPixelColorMatrix::Handle task_matrix(new rendering::TaskPixelColorMatrix());
task_matrix->matrix = matrix;
task_matrix->sub_task() = task;
task = task_matrix;
}

return task;
}
53 changes: 0 additions & 53 deletions synfig-core/src/modules/mod_filter/colorcorrect.h
Expand Up @@ -33,11 +33,6 @@
#include <synfig/gamma.h>
#include <synfig/rect.h>

#include <synfig/rendering/optimizer.h>
#include <synfig/rendering/common/task/taskpixelprocessor.h>
#include <synfig/rendering/common/task/tasksplittable.h>
#include <synfig/rendering/software/task/tasksw.h>

/* === M A C R O S ========================================================= */

/* === T Y P E D E F S ===================================================== */
Expand All @@ -48,54 +43,6 @@ namespace synfig {
namespace modules {
namespace mod_filter {

class TaskColorCorrect: public rendering::TaskPixelProcessor
{
public:
typedef etl::handle<TaskColorCorrect> Handle;

Angle hue_adjust;
Real brightness;
Real contrast;
Real exposure;
Real gamma;

TaskColorCorrect():
hue_adjust(Angle::zero()),
brightness(0.0),
contrast(1.0),
exposure(0.0),
gamma(1.0) { }
Task::Handle clone() const { return clone_pointer(this); }
};


class TaskColorCorrectSW: public TaskColorCorrect, public rendering::TaskSW, public rendering::TaskSplittable
{
private:
void correct_pixel(Color &dst, const Color &src, const Angle &hue_djust, ColorReal shift, ColorReal amplifier, const Gamma &gamma) const;

public:
typedef etl::handle<TaskColorCorrectSW> Handle;
Task::Handle clone() const { return clone_pointer(this); }
virtual void split(const RectInt &sub_target_rect);
virtual bool run(RunParams &params) const;
};


class OptimizerColorCorrectSW: public rendering::Optimizer
{
public:
OptimizerColorCorrectSW()
{
category_id = CATEGORY_ID_SPECIALIZE;
depends_from = CATEGORY_COMMON & CATEGORY_PRE_SPECIALIZE;
for_task = true;
}

virtual void run(const RunParams &params) const;
};


class Layer_ColorCorrect : public Layer
{
SYNFIG_LAYER_MODULE_EXT
Expand Down
4 changes: 0 additions & 4 deletions synfig-core/src/modules/mod_filter/main.cpp
Expand Up @@ -74,8 +74,4 @@ MODULE_INVENTORY_BEGIN(libmod_filter)
LAYER(RadialBlur)
LAYER(Layer_ColorCorrect)
END_LAYERS
BEGIN_OPTIMIZERS
OPTIMIZER(OptimizerColorCorrectSW)
END_OPTIMIZERS
rendering::Renderer::get_renderer("safe")->register_optimizer(new OptimizerColorCorrectSW());
MODULE_INVENTORY_END
2 changes: 2 additions & 0 deletions synfig-core/src/synfig/color/Makefile_insert
Expand Up @@ -2,13 +2,15 @@ COLOR_HH = \
color/color.h \
color/color.hpp \
color/coloraccumulator.h \
color/colormatrix.h \
color/cairocolor.h \
color/cairocoloraccumulator.h \
color/pixelformat.h \
color/common.h

COLOR_CC = \
color/color.cpp \
color/colormatrix.cpp \
color/cairocolor.cpp

libsynfig_include_HH += \
Expand Down

0 comments on commit bf609b7

Please sign in to comment.