Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Allow target to handle alpha in 4 different ways
  • Loading branch information
morevnaproject committed Aug 4, 2014
1 parent 1b44a8a commit dc451c6
Show file tree
Hide file tree
Showing 14 changed files with 127 additions and 45 deletions.
2 changes: 1 addition & 1 deletion synfig-core/src/modules/mod_bmp/trgt_bmp.cpp
Expand Up @@ -118,7 +118,7 @@ bmp::bmp(const char *Filename, const synfig::TargetParam& params):
color_buffer(NULL),
pf()
{
set_remove_alpha();
set_alpha_mode(TARGET_ALPHA_MODE_FILL);
sequence_separator=params.sequence_separator;
}

Expand Down
2 changes: 1 addition & 1 deletion synfig-core/src/modules/mod_dv/trgt_dv.cpp
Expand Up @@ -87,7 +87,7 @@ dv_trgt::dv_trgt(const char *Filename, const synfig::TargetParam & /* params */)
buffer(NULL),
color_buffer(NULL)
{
set_remove_alpha();
set_alpha_mode(TARGET_ALPHA_MODE_FILL);
}

dv_trgt::~dv_trgt()
Expand Down
2 changes: 1 addition & 1 deletion synfig-core/src/modules/mod_ffmpeg/trgt_ffmpeg.cpp
Expand Up @@ -88,7 +88,7 @@ ffmpeg_trgt::ffmpeg_trgt(const char *Filename, const synfig::TargetParam &params
color_buffer(NULL),
bitrate()
{
set_remove_alpha();
set_alpha_mode(TARGET_ALPHA_MODE_FILL);

// Set default video codec and bitrate if they weren't given.
if (params.video_codec == "none")
Expand Down
2 changes: 1 addition & 1 deletion synfig-core/src/modules/mod_gif/trgt_gif.cpp
Expand Up @@ -221,7 +221,7 @@ gif::end_frame()
Palette prev_palette(curr_palette);

// Fill in the background color
if(!get_remove_alpha())
if(get_alpha_mode()==TARGET_ALPHA_MODE_KEEP)
{
Surface::alpha_pen pen(curr_surface.begin(),1.0,Color::BLEND_BEHIND);
pen.set_value(get_canvas()->rend_desc().get_bg_color());
Expand Down
2 changes: 1 addition & 1 deletion synfig-core/src/modules/mod_jpeg/trgt_jpeg.cpp
Expand Up @@ -69,7 +69,7 @@ jpeg_trgt::jpeg_trgt(const char *Filename, const synfig::TargetParam &params):
color_buffer(NULL),
sequence_separator(params.sequence_separator)
{
set_remove_alpha();
set_alpha_mode(TARGET_ALPHA_MODE_FILL);
}

jpeg_trgt::~jpeg_trgt()
Expand Down
2 changes: 1 addition & 1 deletion synfig-core/src/modules/mod_ppm/trgt_ppm.cpp
Expand Up @@ -64,7 +64,7 @@ ppm::ppm(const char *Filename, const synfig::TargetParam &params):
buffer(NULL),
sequence_separator(params.sequence_separator)
{
set_remove_alpha();
set_alpha_mode(TARGET_ALPHA_MODE_FILL);
}

ppm::~ppm()
Expand Down
2 changes: 1 addition & 1 deletion synfig-core/src/modules/mod_yuv420p/trgt_yuv.cpp
Expand Up @@ -67,7 +67,7 @@ yuv::yuv(const char *FILENAME, const synfig::TargetParam& /* params */):
dithering(true)
{
// YUV420P doesn't have an alpha channel
set_remove_alpha();
set_alpha_mode(TARGET_ALPHA_MODE_FILL);
}

yuv::~yuv()
Expand Down
2 changes: 1 addition & 1 deletion synfig-core/src/synfig/target.cpp
Expand Up @@ -96,7 +96,7 @@ Target::ext_book()
Target::Target():
quality_(4),
gamma_(*default_gamma_),
remove_alpha(false),
alpha_mode(TARGET_ALPHA_MODE_KEEP),
avoid_time_sync_(false),
curr_frame_(0)
{
Expand Down
24 changes: 17 additions & 7 deletions synfig-core/src/synfig/target.h
Expand Up @@ -80,6 +80,14 @@ class Canvas;
class ProgressCallback;
struct TargetParam;

enum TargetAlphaMode
{
TARGET_ALPHA_MODE_KEEP, // 0
TARGET_ALPHA_MODE_FILL, // 1
TARGET_ALPHA_MODE_REDUCE, // 2
TARGET_ALPHA_MODE_EXTRACT // 3
}; // END enum TargetAlphaMode

/*! \class Target
** \brief Used to produce rendered animations of the documents
**
Expand Down Expand Up @@ -163,10 +171,11 @@ class Target : public etl::shared_object
int quality_;
//! Gamma value used for the render process of the target
Gamma gamma_;


//! Tells how to handle alpha
//! Used by non alpha supported targets to decide if the background
//! must be filled or not
bool remove_alpha;
TargetAlphaMode alpha_mode;

//! When set to true, the target doesn't sync to canvas time.
bool avoid_time_sync_;
Expand All @@ -188,11 +197,12 @@ class Target : public etl::shared_object
void set_avoid_time_sync(bool x=true) { avoid_time_sync_=x; }
//! Gets the target avoid time synchronization
bool get_avoid_time_sync()const { return avoid_time_sync_; }
//! Gets the target remove alpha
bool get_remove_alpha()const { return remove_alpha; }
//! Sets the target remove alpha
void set_remove_alpha(bool x=true) { remove_alpha=x; }
//! Gets the target gamma
//! Tells how to handle alpha
//! Used by non alpha supported targets to decide if the background
//! must be filled or not
TargetAlphaMode get_alpha_mode()const { return alpha_mode; }
//! Sets how to handle alpha
void set_alpha_mode(TargetAlphaMode x=TARGET_ALPHA_MODE_KEEP) { alpha_mode=x; }
Gamma &gamma() { return gamma_; }
//! Sets the target gamma
const Gamma &gamma()const { return gamma_; }
Expand Down
76 changes: 59 additions & 17 deletions synfig-core/src/synfig/target_scanline.cpp
Expand Up @@ -221,13 +221,27 @@ synfig::Target_Scanline::render(ProgressCallback *cb)
return false;
}

if(get_remove_alpha())
switch(get_alpha_mode())
{
for(int i = 0; i < surface.get_w(); i++)
colordata[i] = Color::blend(surface[y][i],desc.get_bg_color(),1.0f);
}
else
memcpy(colordata,surface[y],rowspan);
case TARGET_ALPHA_MODE_FILL:
for(int i = 0; i < surface.get_w(); i++)
colordata[i] = Color::blend(surface[y][i],desc.get_bg_color(),1.0f);
break;
case TARGET_ALPHA_MODE_EXTRACT:
for(int i = 0; i < surface.get_w(); i++)
{
float a=surface[y][i].get_a();
colordata[i] = Color(a,a,a,a);
}
break;
case TARGET_ALPHA_MODE_REDUCE:
for(int i = 0; i < surface.get_w(); i++)
colordata[i] = Color(surface[y][i].get_r(),surface[y][i].get_g(),surface[y][i].get_b(),1.0f);
break;
case TARGET_ALPHA_MODE_KEEP:
memcpy(colordata,surface[y],rowspan);
break;
}

if(!end_scanline())
{
Expand Down Expand Up @@ -366,13 +380,27 @@ synfig::Target_Scanline::render(ProgressCallback *cb)
return false;
}

if(get_remove_alpha())
switch(get_alpha_mode())
{
for(int i = 0; i < surface.get_w(); i++)
colordata[i] = Color::blend(surface[y][i],desc.get_bg_color(),1.0f);
}
else
memcpy(colordata,surface[y],rowspan);
case TARGET_ALPHA_MODE_FILL:
for(int i = 0; i < surface.get_w(); i++)
colordata[i] = Color::blend(surface[y][i],desc.get_bg_color(),1.0f);
break;
case TARGET_ALPHA_MODE_EXTRACT:
for(int i = 0; i < surface.get_w(); i++)
{
float a=surface[y][i].get_a();
colordata[i] = Color(a,a,a,a);
}
break;
case TARGET_ALPHA_MODE_REDUCE:
for(int i = 0; i < surface.get_w(); i++)
colordata[i] = Color(surface[y][i].get_r(),surface[y][i].get_g(),surface[y][i].get_b(),1.0f);
break;
case TARGET_ALPHA_MODE_KEEP:
memcpy(colordata,surface[y],rowspan);
break;
}

if(!end_scanline())
{
Expand Down Expand Up @@ -458,13 +486,27 @@ Target_Scanline::add_frame(const Surface *surface)
return false;
}

if(get_remove_alpha())
switch(get_alpha_mode())
{
for(int i=0;i<surface->get_w();i++)
colordata[i]=Color::blend((*surface)[y][i],desc.get_bg_color(),1.0f);
case TARGET_ALPHA_MODE_FILL:
for(int i=0;i<surface->get_w();i++)
colordata[i]=Color::blend((*surface)[y][i],desc.get_bg_color(),1.0f);
break;
case TARGET_ALPHA_MODE_EXTRACT:
for(int i=0;i<surface->get_w();i++)
{
float a=(*surface)[y][i].get_a();
colordata[i] = Color(a,a,a,a);
}
break;
case TARGET_ALPHA_MODE_REDUCE:
for(int i = 0; i < surface->get_w(); i++)
colordata[i] = Color((*surface)[y][i].get_r(),(*surface)[y][i].get_g(),(*surface)[y][i].get_b(),1.0f);
break;
case TARGET_ALPHA_MODE_KEEP:
memcpy(colordata,(*surface)[y],rowspan);
break;
}
else
memcpy(colordata,(*surface)[y],rowspan);

if(!end_scanline())
{
Expand Down
42 changes: 36 additions & 6 deletions synfig-core/src/synfig/target_tile.cpp
Expand Up @@ -169,9 +169,24 @@ synfig::Target_Tile::render_frame_(Context context,ProgressCallback *cb)
if(cb)cb->error(_("Bad surface"));
return false;
}
if(get_remove_alpha())
for(int i=0;i<surface.get_w()*surface.get_h();i++)
surface[0][i]=Color::blend(surface[0][i],desc.get_bg_color(),1.0f);
switch(get_alpha_mode())
{
case TARGET_ALPHA_MODE_FILL:
for(int i=0;i<surface.get_w()*surface.get_h();i++)
surface[0][i]=Color::blend(surface[0][i],desc.get_bg_color(),1.0f);
break;
case TARGET_ALPHA_MODE_EXTRACT:
for(int i=0;i<surface.get_w()*surface.get_h();i++)
{
float a=surface[0][i].get_a();
surface[0][i] = Color(a,a,a,a);
}
break;
case TARGET_ALPHA_MODE_REDUCE:
for(int i=0;i<surface.get_w()*surface.get_h();i++)
surface[0][i].set_a(1.0f);
break;
}

// Add the tile to the target
if(!add_tile(surface,x,y))
Expand Down Expand Up @@ -233,9 +248,24 @@ synfig::Target_Tile::render_frame_(Context context,ProgressCallback *cb)
if(cb)cb->error(_("Bad surface"));
return false;
}
if(get_remove_alpha())
for(int i=0;i<surface.get_w()*surface.get_h();i++)
surface[0][i]=Color::blend(surface[0][i],desc.get_bg_color(),1.0f);
switch(get_alpha_mode())
{
case TARGET_ALPHA_MODE_FILL:
for(int i=0;i<surface.get_w()*surface.get_h();i++)
surface[0][i]=Color::blend(surface[0][i],desc.get_bg_color(),1.0f);
break;
case TARGET_ALPHA_MODE_EXTRACT:
for(int i=0;i<surface.get_w()*surface.get_h();i++)
{
float a=surface[0][i].get_a();
surface[0][i] = Color(a,a,a,a);
}
break;
case TARGET_ALPHA_MODE_REDUCE:
for(int i=0;i<surface.get_w()*surface.get_h();i++)
surface[0][i].set_a(1.0f);
break;
}

etl::clock timer;
timer.reset();
Expand Down
8 changes: 4 additions & 4 deletions synfig-studio/src/gui/asyncrenderer.cpp
Expand Up @@ -110,7 +110,7 @@ class AsyncTarget_Tile : public synfig::Target_Tile
set_tile_h(warm_target->get_tile_h());
set_canvas(warm_target->get_canvas());
set_quality(warm_target->get_quality());
set_remove_alpha(warm_target->get_remove_alpha());
set_alpha_mode(warm_target->get_alpha_mode());
set_threads(warm_target->get_threads());
set_clipping(warm_target->get_clipping());
set_rend_desc(&warm_target->rend_desc());
Expand Down Expand Up @@ -295,7 +295,7 @@ class AsyncTarget_Cairo_Tile : public synfig::Target_Cairo_Tile
set_tile_h(warm_target->get_tile_h());
set_canvas(warm_target->get_canvas());
set_quality(warm_target->get_quality());
set_remove_alpha(warm_target->get_remove_alpha());
set_alpha_mode(warm_target->get_alpha_mode());
set_threads(warm_target->get_threads());
set_clipping(warm_target->get_clipping());
set_rend_desc(&warm_target->rend_desc());
Expand Down Expand Up @@ -458,7 +458,7 @@ class AsyncTarget_Scanline : public synfig::Target_Scanline
set_avoid_time_sync(warm_target->get_avoid_time_sync());
set_canvas(warm_target->get_canvas());
set_quality(warm_target->get_quality());
set_remove_alpha(warm_target->get_remove_alpha());
set_alpha_mode(warm_target->get_alpha_mode());
set_threads(warm_target->get_threads());
set_rend_desc(&warm_target->rend_desc());
alive_flag=true;
Expand Down Expand Up @@ -591,7 +591,7 @@ class AsyncTarget_Cairo : public synfig::Target_Cairo
set_avoid_time_sync(warm_target->get_avoid_time_sync());
set_canvas(warm_target->get_canvas());
set_quality(warm_target->get_quality());
set_remove_alpha(warm_target->get_remove_alpha());
set_alpha_mode(warm_target->get_alpha_mode());
set_rend_desc(&warm_target->rend_desc());
alive_flag=true;
#ifndef GLIB_DISPATCHER_BROKEN
Expand Down
4 changes: 2 additions & 2 deletions synfig-studio/src/gui/docks/dock_navigator.cpp
Expand Up @@ -152,7 +152,7 @@ void studio::Widget_NavView::on_start_render()
etl::handle<Target_Cairo> targ = cairo_image_target(&cairo_surface);
// Fill the target with the proper information
targ->set_canvas(get_canvas_view()->get_canvas());
targ->set_remove_alpha();
targ->set_alpha_mode(TARGET_ALPHA_MODE_FILL);
targ->set_avoid_time_sync();
targ->set_quality(get_canvas_view()->get_work_area()->get_quality());
targ->set_rend_desc(&r);
Expand All @@ -165,7 +165,7 @@ void studio::Widget_NavView::on_start_render()
etl::handle<Target_Scanline> targ = surface_target(surface.get());
// Fill the target with the proper information
targ->set_canvas(get_canvas_view()->get_canvas());
targ->set_remove_alpha();
targ->set_alpha_mode(TARGET_ALPHA_MODE_FILL);
targ->set_avoid_time_sync();
targ->set_quality(get_canvas_view()->get_work_area()->get_quality());
targ->set_rend_desc(&r);
Expand Down
2 changes: 1 addition & 1 deletion synfig-studio/src/gui/preview.cpp
Expand Up @@ -136,7 +136,7 @@ class studio::Preview::Preview_Target : public Target_Scanline

Preview_Target()
{
set_remove_alpha();
set_alpha_mode(TARGET_ALPHA_MODE_FILL);
tbegin = tend = 0;
scanline = 0;
nframes = curframe = 0;
Expand Down

0 comments on commit dc451c6

Please sign in to comment.