diff --git a/cinelerra-5.1/cinelerra/overlayframe.C b/cinelerra-5.1/cinelerra/overlayframe.C index 270755cc..801ae9d3 100644 --- a/cinelerra-5.1/cinelerra/overlayframe.C +++ b/cinelerra-5.1/cinelerra/overlayframe.C @@ -351,5 +351,3 @@ int OverlayFrame::overlay(VFrame *output, VFrame *input, } return 0; } - - diff --git a/cinelerra-5.1/cinelerra/overlayframe.h b/cinelerra-5.1/cinelerra/overlayframe.h index 13c2e4bd..a95ae7e7 100644 --- a/cinelerra-5.1/cinelerra/overlayframe.h +++ b/cinelerra-5.1/cinelerra/overlayframe.h @@ -45,6 +45,9 @@ #define ONE 1 #define TWO 2 +// Sa = source alpha, Sc = source color +// Da = dst alpha, Dc = dst color + // NORMAL [Sa + Da * (1 - Sa), Sc * Sa + Dc * (1 - Sa)]) #define ALPHA_NORMAL(mx, Sa, Da) (Sa + (Da * (mx - Sa)) / mx) #define COLOR_NORMAL(mx, Sc, Sa, Dc, Da) ((Sc * Sa + Dc * (mx - Sa)) / mx) @@ -220,6 +223,34 @@ (mabs(Sc * Da - Dc * Sa) / mx)) #define CHROMA_DIFFERENCE COLOR_DIFFERENCE +// REFLECT [Sa * Sa / (1 - Da] +#define ALPHA_REFLECT (mx, Sa, Da) (Sa * Sa * (mx - Da) / mx) +#define COLOR_REFLECT (mx, Sc, Sa, Dc, Da) (Sc * Sc * (mx - Dc) / mx) +#define CHROMA_REFLECT COLOR_REFLECT + +// AVERAGE (Sa + Da)/2 , (Sc + Dc)/2 +#define ALPHA_AVERAGE (mx, Sa, Da)( ((Sa +Da)/2 )/mx) +#define COLOR_AVERAGE (mx, Sc, Sa, Dc, Da)(((Sc + Dc)/2)/ mx) +#define CHROMA_AVERAGE COLOR_AVERAGE + +#define GAMMA 2.4 +static inline double mpow(double a, double b) { return pow(a, b); } + +#define LINEAR2SRGB(in) (in <= 0.0031308 ? 12.92 * in : 1.055 * mpow(in, 1.0/GAMMA) - 0.055) +#define SRGB2LINEAR(in) (in <= 0.04045 ? in / 12.92 : mpow((in + 0.055) / 1.055, GAMMA)) + +#define A_BLEND(top, bottom, alpha, max) \ + max * LINEAR2SRGB(SRGB2LINEAR(1. * top / max)+ SRGB2LINEAR(1. * bottom / max)*(1.0 - (1. * alpha / max))) + +// Change lines: +// #define ALPHA_NORMAL(mx, Sa, Da) (Sa + (Da * (mx - Sa)) / mx) +// #define COLOR_NORMAL(mx, Sc, Sa, Dc, Da) ((Sc * Sa + Dc * (mx - Sa)) / mx) +// To: +#define ALPHA_NORMALS(mx, Sa, Da) ((Sa + (mx - Sa)*(mx - Sa)) / mx) +#define COLOR_NORMALS(mx, Sc, Sa, Dc, Da) A_BLEND(Sc, Dc, Sa, mx) +#define CHROMA_NORMALS COLOR_NORMALS + + static inline int mabs(int32_t v) { return abs(v); } static inline int mabs(int64_t v) { return llabs(v); } static inline float mabs(float v) { return fabsf(v); } @@ -366,6 +397,7 @@ ZTYP(float); ZTYP(double); case TRANSFER_HARDLIGHT: FN(HARDLIGHT); \ case TRANSFER_SOFTLIGHT: FN(SOFTLIGHT); \ case TRANSFER_DIFFERENCE: FN(DIFFERENCE); \ + case TRANSFER_NORMALS: FN(NORMALS); \ } class OverlayKernel diff --git a/cinelerra-5.1/cinelerra/overlayframe.inc b/cinelerra-5.1/cinelerra/overlayframe.inc index 5f84036d..f155eb4a 100644 --- a/cinelerra-5.1/cinelerra/overlayframe.inc +++ b/cinelerra-5.1/cinelerra/overlayframe.inc @@ -24,7 +24,7 @@ // Modes -#define TRANSFER_TYPES 30 +#define TRANSFER_TYPES 33 #define TRANSFER_NORMAL 0 #define TRANSFER_ADDITION 1 @@ -56,6 +56,9 @@ #define TRANSFER_HARDLIGHT 27 #define TRANSFER_SOFTLIGHT 28 #define TRANSFER_DIFFERENCE 29 +#define TRANSFER_REFLECT 30 +#define TRANSFER_AVERAGE 31 +#define TRANSFER_NORMALS 32 // Interpolation types diff --git a/cinelerra-5.1/cinelerra/patchbay.C b/cinelerra-5.1/cinelerra/patchbay.C index c2ae534d..bc593617 100644 --- a/cinelerra-5.1/cinelerra/patchbay.C +++ b/cinelerra-5.1/cinelerra/patchbay.C @@ -218,6 +218,9 @@ void PatchBay::create_objects() "mode_hardlight", "mode_softlight", "mode_difference", + "mode_reflect", + "mode_average", + "mode_normals", }; for( int mode=0; modeadd_submenuitem(new VModeSubMenuItem(submenu, mode_to_text(TRANSFER_DIVIDE), TRANSFER_DIVIDE)); submenu->add_submenuitem(new VModeSubMenuItem(submenu, mode_to_text(TRANSFER_MULTIPLY), TRANSFER_MULTIPLY)); submenu->add_submenuitem(new VModeSubMenuItem(submenu, mode_to_text(TRANSFER_REPLACE), TRANSFER_REPLACE)); + //submenu->add_submenuitem(new VModeSubMenuItem(submenu, mode_to_text(TRANSFER_REFLECT), TRANSFER_REFLECT)); + //submenu->add_submenuitem(new VModeSubMenuItem(submenu, mode_to_text(TRANSFER_AVERAGE), TRANSFER_AVERAGE)); + submenu->add_submenuitem(new VModeSubMenuItem(submenu, mode_to_text(TRANSFER_NORMALS), TRANSFER_NORMALS)); add_item(mode_item = new VModePatchItem(this, _("PorterDuff..."), -1)); mode_item->add_submenu(submenu = new VModePatchSubMenu(mode_item)); submenu->add_submenuitem(new VModeSubMenuItem(submenu, mode_to_text(TRANSFER_DST), TRANSFER_DST)); @@ -436,6 +439,9 @@ const char* VModePatch::mode_to_text(int mode) case TRANSFER_HARDLIGHT: return _("Hardlight"); case TRANSFER_SOFTLIGHT: return _("Softlight"); case TRANSFER_DIFFERENCE: return _("Difference"); + case TRANSFER_REFLECT: return _("Reflect"); + case TRANSFER_AVERAGE: return _("Average"); + case TRANSFER_NORMALS: return _("NormalS"); } return _("Normal"); }