| @@ -96,7 +96,7 @@ static int filter_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) · 95 unmodified lines |
| 96 | 96 | base->linesize[p], overlay->linesize[p], |
| 97 | 97 | mask->linesize[p], out->linesize[p], |
| 98 | 98 | s->width[p], slice_end - slice_start, |
| 99 | | − s->half, s->depth); |
| 99 | + s->half, s->max); |
| 100 | 100 | } |
| 101 | 101 | |
| 102 | 102 | return 0; |
| @@ -138,13 +138,13 @@ static int process_frame(FFFrameSync *fs) · 35 unmodified lines |
| 138 | 138 | return ff_filter_frame(outlink, out); |
| 139 | 139 | } |
| 140 | 140 | |
| 141 | | −#define MASKEDMERGE(n, type, half, shift) \ |
| 141 | +#define MASKEDMERGE(n, type, ctype, half, max, div) \ |
| 142 | 142 | static void maskedmerge##n(const uint8_t *bbsrc, const uint8_t *oosrc, \ |
| 143 | 143 | const uint8_t *mmsrc, uint8_t *ddst, \ |
| 144 | 144 | ptrdiff_t blinesize, ptrdiff_t olinesize, \ |
| 145 | 145 | ptrdiff_t mlinesize, ptrdiff_t dlinesize, \ |
| 146 | 146 | int w, int h, \ |
| 147 | | − int hhalf, int sshift) \ |
| 147 | + int hhalf, int mmax) \ |
| 148 | 148 | { \ |
| 149 | 149 | const type *bsrc = (const type *)bbsrc; \ |
| 150 | 150 | const type *osrc = (const type *)oosrc; \ |
| @@ -158,7 +158,10 @@ static void maskedmerge##n(const uint8_t *bbsrc, const uint8_t *oosrc, \ · 7 unmodified lines |
| 158 | 158 | \ |
| 159 | 159 | for (int y = 0; y < h; y++) { \ |
| 160 | 160 | for (int x = 0; x < w; x++) { \ |
| 161 | | − dst[x] = bsrc[x] + ((msrc[x] * (osrc[x] - bsrc[x]) + half) shift); \ |
| 161 | + const type invm = max - msrc[x]; \ |
| 162 | + const ctype r = ((ctype)(bsrc[x] * invm) + \ |
| 163 | + (ctype)(msrc[x] * osrc[x] + half)) div; \ |
| 164 | + dst[x] = r; \ |
| 162 | 165 | } \ |
| 163 | 166 | \ |
| 164 | 167 | dst += dlinesize; \ |
| @@ -168,9 +171,9 @@ static void maskedmerge##n(const uint8_t *bbsrc, const uint8_t *oosrc, \ · 3 unmodified lines |
| 168 | 171 | } \ |
| 169 | 172 | } |
| 170 | 173 | |
| 171 | | −MASKEDMERGE(8, uint8_t, 128, >> 8) |
| 172 | | −MASKEDMERGE(16, uint16_t, hhalf, >> sshift) |
| 173 | | −MASKEDMERGE(32, float, 0.f, + 0.f) |
| 174 | +MASKEDMERGE(8, uint8_t, uint16_t, 127, 255, / 255) |
| 175 | +MASKEDMERGE(16, uint16_t, uint32_t, hhalf, mmax, / mmax) |
| 176 | +MASKEDMERGE(32, float, float, 0.f, 1.f, + 0.f) |
| 174 | 177 | |
| 175 | 178 | static int config_input(AVFilterLink *inlink) |
| 176 | 179 | { |
| @@ -189,7 +192,8 @@ static int config_input(AVFilterLink *inlink) · 12 unmodified lines |
| 189 | 192 | s->width[0] = s->width[3] = inlink->w; |
| 190 | 193 | |
| 191 | 194 | s->depth = desc->comp[0].depth; |
| 192 | | − s->half = (1 << s->depth) / 2; |
| 195 | + s->max = (1 << s->depth) - 1; |
| 196 | + s->half = s->max / 2; |
| 193 | 197 | |
| 194 | 198 | if (s->depth == 8) |
| 195 | 199 | s->maskedmerge = maskedmerge8; |