1 /* 2 * Copyright (c) 2013 Paul B Mahol 3 * 4 * This file is part of FFmpeg. 5 * 6 * FFmpeg is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU Lesser General Public 8 * License as published by the Free Software Foundation; either 9 * version 2.1 of the License, or (at your option) any later version. 10 * 11 * FFmpeg is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * Lesser General Public License for more details. 15 * 16 * You should have received a copy of the GNU Lesser General Public 17 * License along with FFmpeg; if not, write to the Free Software 18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 */ 20 21 #include "libavutil/common.h" 22 #include "libavutil/intfloat.h" 23 #include "avfilter.h" 24 #include "formats.h" 25 #include "internal.h" 26 #include "video.h" 27 #include "blend.h" 28 29 #undef PIXEL 30 #undef MAX 31 #undef HALF 32 #undef CLIP 33 34 #if DEPTH == 8 35 #define PIXEL uint8_t 36 #define MAX 255 37 #define HALF 128 38 #define CLIP(x) (av_clip_uint8(x)) 39 #elif DEPTH == 32 40 #define PIXEL float 41 #define MAX 1.f 42 #define HALF 0.5f 43 #define CLIP(x) (x) 44 #else 45 #define PIXEL uint16_t 46 #define MAX ((1 << DEPTH) - 1) 47 #define HALF (1 << (DEPTH - 1)) 48 #define CLIP(x) ((int)av_clip_uintp2(x, DEPTH)) 49 #endif 50 51 #undef MULTIPLY 52 #undef SCREEN 53 #undef BURN 54 #undef DODGE 55 #undef GEOMETRIC 56 #undef INT2FLOAT 57 #undef FLOAT2INT 58 #undef MDIV 59 #undef LRINTF 60 61 #if DEPTH < 32 62 #define MULTIPLY(x, a, b) ((x) * (((a) * (b)) / MAX)) 63 #define SCREEN(x, a, b) (MAX - (x) * ((MAX - (a)) * (MAX - (b)) / MAX)) 64 #define BURN(a, b) (((a) == 0) ? (a) : FFMAX(0, MAX - ((MAX - (b)) << DEPTH) / (a))) 65 #define DODGE(a, b) (((a) == MAX) ? (a) : FFMIN(MAX, (((b) << DEPTH) / (MAX - (a))))) 66 #define GEOMETRIC(a, b) (lrintf(sqrtf((unsigned)A * B))) 67 #define INT2FLOAT(x) (x) 68 #define FLOAT2INT(x) (x) 69 #define MDIV (0.125f * (1 << DEPTH)) 70 #define LRINTF(x) lrintf(x) 71 #else 72 #define MULTIPLY(x, a, b) ((x) * (((a) * (b)) / 1.0)) 73 #define SCREEN(x, a, b) (1.0 - (x) * ((1.0 - (a)) * (1.0 - (b)) / 1.0)) 74 #define BURN(a, b) (((a) <= 0.0) ? (a) : FFMAX(0.0, 1.0 - (1.0 - (b)) / (a))) 75 #define DODGE(a, b) (((a) >= 1.0) ? (a) : FFMIN(1.0, ((b) / (1.0 - (a))))) 76 #define GEOMETRIC(a, b) (sqrtf(fmaxf(A, 0) * fmaxf(B, 0))) 77 #define INT2FLOAT(x) av_int2float(x) 78 #define FLOAT2INT(x) av_float2int(x) 79 #define MDIV 0.125f 80 #define LRINTF(x) (x) 81 #endif 82 83 #define A top[j] 84 #define B bottom[j] 85 86 #define fn2(a, b) blend_##a##_##b##bit 87 #define fn1(name, depth) fn2(name, depth) 88 #define fn0(name) fn1(name, DEPTH) 89 90 #define fn(NAME, EXPR) \ 91 static void fn0(NAME)(const uint8_t *_top, ptrdiff_t top_linesize, \ 92 const uint8_t *_bottom, ptrdiff_t bottom_linesize, \ 93 uint8_t *_dst, ptrdiff_t dst_linesize, \ 94 ptrdiff_t width, ptrdiff_t height, \ 95 FilterParams *param, double *values, int starty) \ 96 { \ 97 const PIXEL *top = (PIXEL *)_top; \ 98 const PIXEL *bottom = (PIXEL *)_bottom; \ 99 PIXEL *dst = (PIXEL *)_dst; \ 100 const float opacity = param->opacity; \ 101 \ 102 dst_linesize /= sizeof(PIXEL); \ 103 top_linesize /= sizeof(PIXEL); \ 104 bottom_linesize /= sizeof(PIXEL); \ 105 \ 106 for (int i = 0; i < height; i++) { \ 107 for (int j = 0; j < width; j++) { \ 108 dst[j] = top[j] + ((EXPR)-top[j]) * opacity; \ 109 } \ 110 dst += dst_linesize; \ 111 top += top_linesize; \ 112 bottom += bottom_linesize; \ 113 } \ 114 } 115 116 fn(addition, FFMIN(MAX, A + B)) 117 fn(grainmerge, CLIP(A + B - HALF)) 118 fn(average, (A + B) / 2) 119 fn(subtract, FFMAX(0, A - B)) 120 fn(multiply, MULTIPLY(1, A, B)) 121 fn(multiply128,CLIP((A - HALF) * B / MDIV + HALF)) 122 fn(negation, MAX - FFABS(MAX - A - B)) 123 fn(extremity, FFABS(MAX - A - B)) 124 fn(difference, FFABS(A - B)) 125 fn(grainextract, CLIP(HALF + A - B)) 126 fn(screen, SCREEN(1, A, B)) 127 fn(overlay, (A < HALF) ? MULTIPLY(2, A, B) : SCREEN(2, A, B)) 128 fn(hardlight, (B < HALF) ? MULTIPLY(2, B, A) : SCREEN(2, B, A)) 129 fn(hardmix, (A < (MAX - B)) ? 0: MAX) 130 fn(heat, (A == 0) ? 0 : MAX - FFMIN(((MAX - B) * (MAX - B)) / A, MAX)) 131 fn(freeze, (B == 0) ? 0 : MAX - FFMIN(((MAX - A) * (MAX - A)) / B, MAX)) 132 fn(darken, FFMIN(A, B)) 133 fn(lighten, FFMAX(A, B)) 134 fn(divide, CLIP(B == 0 ? MAX : MAX * A / B)) 135 fn(dodge, DODGE(A, B)) 136 fn(burn, BURN(A, B)) 137 fn(softlight, CLIP(A * A / MAX + (2 * (B * ((A * (MAX - A)) / MAX) / MAX)))) 138 fn(exclusion, A + B - 2 * A * B / MAX) 139 fn(pinlight, (B < HALF) ? FFMIN(A, 2 * B) : FFMAX(A, 2 * (B - HALF))) 140 fn(phoenix, FFMIN(A, B) - FFMAX(A, B) + MAX) 141 fn(reflect, (B == MAX) ? B : FFMIN(MAX, (A * A / (MAX - B)))) 142 fn(glow, (A == MAX) ? A : FFMIN(MAX, (B * B / (MAX - A)))) 143 fn(and, INT2FLOAT(FLOAT2INT(A) & FLOAT2INT(B))) 144 fn(or, INT2FLOAT(FLOAT2INT(A) | FLOAT2INT(B))) 145 fn(xor, INT2FLOAT(FLOAT2INT(A) ^ FLOAT2INT(B))) 146 fn(vividlight, (A < HALF) ? BURN(2 * A, B) : DODGE(2 * (A - HALF), B)) 147 fn(linearlight,CLIP((B < HALF) ? B + 2 * A - MAX : B + 2 * (A - HALF))) 148 fn(softdifference,CLIP((A > B) ? (B == MAX) ? 0 : (A - B) * MAX / (MAX - B) : (B == 0) ? 0 : (B - A) * MAX / B)) 149 fn(geometric, GEOMETRIC(A, B)) 150 fn(harmonic, A == 0 && B == 0 ? 0 : 2LL * A * B / (A + B)) 151 fn(bleach, (MAX - B) + (MAX - A) - MAX) 152 fn(stain, 2 * MAX - A - B) 153 fn(interpolate,LRINTF(MAX * (2 - cosf(A * M_PI / MAX) - cosf(B * M_PI / MAX)) * 0.25f)) 154 fn(hardoverlay,A == MAX ? MAX : FFMIN(MAX, MAX * B / (2 * MAX - 2 * A) * (A > HALF) + 2 * A * B / MAX * (A <= HALF))) 155