Commit d0b9110183 for ffmpeg
commit d0b91101832beac6f76a5b2a7de4a356dd513294
Author: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Thu Nov 5 10:37:47 2026 +0100
avfilter/vf_limiter_init: Avoid unnecessary shift/mask
The limiter DSP functions use the common pattern of
passing byte-strides and uint8_t* pointers which
then get immediately converted to the proper type
(i.e. uint16_t* for bitdepth >8) with the stride
being converted via /= sizeof(type).
There are several issues with this pattern:
a) Strides are signed and use ptrdiff_t, yet sizeof(type)
is size_t, so that the division is (on most systems) performed
in an unsigned type, leading to logical right shifts. This is
wrong and UB for negative strides, but it happens to work
in practice, because pointer arithmetic entails an implicit
multiplication by sizeof(type).
b) Due to this, compilers (like GCC-16 here) actually do not shift
at all; but they nevertheless need to mask the lowest bit of
the strides (which would be eliminated by the division).
This is unnecessary and eliminated by this commit.
c) On systems without alignment requirements, it would even be
possible for the strides for uint16_t to be odd. In this case,
the current pattern would just be wrong.
So change the code to convert to the byte-pointer to the actually
used types in the outer loop and increment the byte-pointers
using the byte-strides.
Reviewed-by: Marvin Scholz <epirat07@gmail.com>
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
diff --git a/libavfilter/vf_limiter_init.h b/libavfilter/vf_limiter_init.h
index a33b4dcc65..f257e706ad 100644
--- a/libavfilter/vf_limiter_init.h
+++ b/libavfilter/vf_limiter_init.h
@@ -25,23 +25,19 @@
#include "limiter.h"
#define LIMITER(n, type) \
-static void limiter##n(const uint8_t *ssrc, uint8_t *ddst, \
+static void limiter##n(const uint8_t *src8, uint8_t *dst8, \
ptrdiff_t slinesize, ptrdiff_t dlinesize,\
int w, int h, int min, int max) \
{ \
- const type *src = (const type *)ssrc; \
- type *dst = (type *)ddst; \
- \
- dlinesize /= sizeof(type); \
- slinesize /= sizeof(type); \
- \
for (int y = 0; y < h; y++) { \
+ const type *src = (const type *)src8; \
+ type *dst = (type *)dst8; \
for (int x = 0; x < w; x++) { \
dst[x] = av_clip(src[x], min, max); \
} \
\
- dst += dlinesize; \
- src += slinesize; \
+ dst8 += dlinesize; \
+ src8 += slinesize; \
} \
}