64 static const char *
const var_names[] = {   
"X",   
"Y",   
"W",   
"H",   
"SW",   
"SH",   
"T",   
"N",   
"A",   
"B",   
"TOP",   
"BOTTOM",        NULL };
 
   65 enum                                   { 
VAR_X, 
VAR_Y, 
VAR_W, 
VAR_H, 
VAR_SW, 
VAR_SH, 
VAR_T, 
VAR_N, 
VAR_A, 
VAR_B, 
VAR_TOP, 
VAR_BOTTOM, 
VAR_VARS_NB };
 
   73                   const uint8_t *bottom, 
int bottom_linesize,
 
  100 #define OFFSET(x) offsetof(BlendContext, x) 
  101 #define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM 
  143     { 
"shortest",    
"force termination when the shortest input terminates", 
OFFSET(dinput.shortest), 
AV_OPT_TYPE_INT, {.i64=0}, 0, 1, 
FLAGS },
 
  151                          const uint8_t *bottom, 
int bottom_linesize,
 
  152                          uint8_t *dst, 
int dst_linesize,
 
  159 #define DEFINE_BLEND(name, expr)                                      \ 
  160 static void blend_## name(const uint8_t *top, int top_linesize,       \ 
  161                           const uint8_t *bottom, int bottom_linesize, \ 
  162                           uint8_t *dst, int dst_linesize,             \ 
  163                           int width, int start, int end,              \ 
  164                           FilterParams *param, double *values)        \ 
  166     double opacity = param->opacity;                                  \ 
  169     for (i = start; i < end; i++) {                                   \ 
  170         for (j = 0; j < width; j++) {                                 \ 
  171             dst[j] = top[j] + ((expr) - top[j]) * opacity;            \ 
  173         dst    += dst_linesize;                                       \ 
  174         top    += top_linesize;                                       \ 
  175         bottom += bottom_linesize;                                    \ 
  182 #define MULTIPLY(x, a, b) ((x) * (((a) * (b)) / 255)) 
  183 #define SCREEN(x, a, b)   (255 - (x) * ((255 - (a)) * (255 - (b)) / 255)) 
  184 #define BURN(a, b)        (((a) == 0) ? (a) : FFMAX(0, 255 - ((255 - (b)) << 8) / (a))) 
  185 #define DODGE(a, b)       (((a) == 255) ? (a) : FFMIN(255, (((b) << 8) / (255 - (a))))) 
  195 DEFINE_BLEND(hardlight,  (
B < 128) ? MULTIPLY(2, 
B, A) : SCREEN(2, B, A))
 
  201 DEFINE_BLEND(softlight,  (A > 127) ? B + (255 - B) * (A - 127.5) / 127.5 * (0.5 - 
FFABS(B - 127.5) / 255): B - B * ((127.5 - A) / 127.5) * (0.5 - 
FFABS(B - 127.5)/255))
 
  211 static 
void blend_expr(const 
uint8_t *top, 
int top_linesize,
 
  212                        const 
uint8_t *bottom, 
int bottom_linesize,
 
  213                        uint8_t *dst, 
int dst_linesize,
 
  220     for (y = start; y < 
end; y++) {
 
  222         for (x = 0; x < 
width; x++) {
 
  230         bottom += bottom_linesize;
 
  237     int slice_start = (td->
h *  jobnr   ) / nb_jobs;
 
  238     int slice_end   = (td->
h * (jobnr+1)) / nb_jobs;
 
  257                      td->
w, slice_start, slice_end, td->
param, &values[0]);
 
  275     for (plane = 0; plane < b->
nb_planes; plane++) {
 
  276         int hsub = plane == 1 || plane == 2 ? b->
hsub : 0;
 
  277         int vsub = plane == 1 || plane == 2 ? b->
vsub : 0;
 
  281         ThreadData td = { .top = top_buf, .bottom = bottom_buf, .dst = dst_buf,
 
  282                           .w = outw, .h = outh, .param = param, .plane = plane,
 
  306         switch (param->
mode) {
 
  340                                 NULL, NULL, NULL, NULL, 0, ctx);
 
  343             param->
blend = blend_expr;
 
  377     if (toplink->
w                       != bottomlink->
w ||
 
  378         toplink->
h                       != bottomlink->
h ||
 
  382                "(size %dx%d, SAR %d:%d) do not match the corresponding " 
  383                "second input link %s parameters (%dx%d, SAR %d:%d)\n",
 
  393     outlink->
w = toplink->
w;
 
  394     outlink->
h = toplink->
h;
 
  463     .priv_class    = &blend_class,