On Monday, September 27, 2021, Stefan de Konink via Cin < [email protected]> wrote:
> On Monday, September 27, 2021 10:45:55 AM CEST, Igor BEGHETTO via Cin > wrote: > >> It seems pretty good. For you, is it the right way? >> > > I got it to work under FFmpeg as well, code quality is still subpar... but > in general I would love to have thing thing natively in Cinerella as well. > The variant with a single color make sense, but also subtracting another > layer. > > <https://github.com/skinkie/FFmpeg/commit/7683c206446661e04b > fc34b0149cbcf4c19a3d55#diff-30bbbdaad37f440707bda666ec8c00a0 > c3d6812cc62a54a873bcb16ea7487bd3R690> well, if you have patch for ffmpeg (relatively new version) you can also patch Cinelerra-gg's internal copy of ffmpeg and try your filter from there, or add it as new blending mode as I tried (for other equations) some time ago (hack attached) > -- > Stefan
From b441771132a507ba00b0c1def1a570501ea4fc2b Mon Sep 17 00:00:00 2001 From: Andrew Randrianasulu <[email protected]> Date: Fri, 2 Jul 2021 23:23:29 +0300 Subject: [PATCH 32/64] Add hackish new overlay/blend modes --- cinelerra-5.1/cinelerra/overlayframe.C | 2 - cinelerra-5.1/cinelerra/overlayframe.h | 86 ++++++++++++++++++++++++ cinelerra-5.1/cinelerra/overlayframe.inc | 5 +- cinelerra-5.1/cinelerra/patchbay.C | 3 + cinelerra-5.1/cinelerra/vpatchgui.C | 6 ++ 5 files changed, 99 insertions(+), 3 deletions(-) diff --git a/cinelerra-5.1/cinelerra/overlayframe.C b/cinelerra-5.1/cinelerra/overlayframe.C index 270755ccd9497dd95de9639072f16483c0dc2c67..801ae9d32016cb0a5fd2a97c273cf64c6d7614cc 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 13c2e4bd0b26b0b5994eea343e02bdd8a4c074be..ace2fa0244d652ecc0b5f678df369f4978af975c 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,86 @@ (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) +#define COLOR_AVERAGE(mx, Sc, Sa, Dc, Da) ((Sc + Dc) / 2 ) +#define CHROMA_AVERAGE COLOR_AVERAGE + +#define GAMMA 2.4 +static inline double mpow(double a, double b) { return pow(a, b); } + +inline double poly7(double x, double a, double b, double c, double d, + double e, double f, double g, double h) { + double ab, cd, ef, gh, abcd, efgh, x2, x4; + x2 = x*x; x4 = x2*x2; + ab = a*x + b; cd = c*x + d; + ef = e*x + f; gh = g*x + h; + abcd = ab*x2 + cd; efgh = ef*x2 + gh; + return abcd*x4 + efgh; +} + +inline double srgb_to_linear(double x) { + if (x <= 0.04045) return x / 12.92; + + // Polynomial approximation of ((x+0.055)/1.055)^2.4. + return poly7(x, 0.15237971711927983387, + -0.57235993072870072762, + 0.92097986411523535821, + -0.90208229831912012386, + 0.88348956209696805075, + 0.48110797889132134175, + 0.03563925285274562038, + 0.00084585397227064120); +} + +inline double linear_to_srgb(double x) { + if (x <= 0.0031308) return x * 12.92; + + // Piecewise polynomial approximation (divided by x^3) + // of 1.055 * x^(1/2.4) - 0.055. + if (x <= 0.0523) return poly7(x, -6681.49576364495442248881, + 1224.97114922729451791383, + -100.23413743425112443219, + 6.60361150127077944916, + 0.06114808961060447245, + -0.00022244138470139442, + 0.00000041231840827815, + -0.00000000035133685895) / (x*x*x); + + return poly7(x, -0.18730034115395793881, + 0.64677431008037400417, + -0.99032868647877825286, + 1.20939072663263713636, + 0.33433459165487383613, + -0.01345095746411287783, + 0.00044351684288719036, + -0.00000664263587520855) / (x*x*x); +} + +// from https://stackoverflow.com/questions/6475373/optimizations-for-pow-with-const-non-integer-exponent + + + +//#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 * linear_to_srgb(srgb_to_linear(1. * top / max)+ srgb_to_linear(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 +449,9 @@ ZTYP(float); ZTYP(double); case TRANSFER_HARDLIGHT: FN(HARDLIGHT); \ case TRANSFER_SOFTLIGHT: FN(SOFTLIGHT); \ case TRANSFER_DIFFERENCE: FN(DIFFERENCE); \ + case TRANSFER_REFLECT: FN(REFLECT); \ + case TRANSFER_AVERAGE: FN(AVERAGE); \ + case TRANSFER_NORMALS: FN(NORMALS); \ } class OverlayKernel diff --git a/cinelerra-5.1/cinelerra/overlayframe.inc b/cinelerra-5.1/cinelerra/overlayframe.inc index 5f84036d06c91b8b4e0ce9bbea2b33f4ee03d6c0..f155eb4a13dde577900f261f2370ab49960efd43 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 c2ae534dc4ed137f90c0e35d61ef110aed9ca2c6..bc593617f6410fdb20a937ec3f20b7d7209a5772 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; mode<TRANSFER_TYPES; ++mode ) { mode_icons[mode] = new BC_Pixmap(this, diff --git a/cinelerra-5.1/cinelerra/vpatchgui.C b/cinelerra-5.1/cinelerra/vpatchgui.C index 53ec27fb3af0d935b5d14f6d7b9df0ba56a0c63e..d8e64c5cf3d0311c1d4dee7d939c299aa8f60f77 100644 --- a/cinelerra-5.1/cinelerra/vpatchgui.C +++ b/cinelerra-5.1/cinelerra/vpatchgui.C @@ -354,6 +354,9 @@ void VModePatch::create_objects() submenu->add_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"); } -- 2.33.0
-- Cin mailing list [email protected] https://lists.cinelerra-gg.org/mailman/listinfo/cin

