You've already forked FFmpeg
mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2025-10-06 05:47:18 +02:00
avfilter/blend_modes: Use stride in bytes
The blend functions currently convert strides from bytes to elements of the type by using the stride /= sizeof(pixel) idiom. Yet this has several drawbacks: 1. It invokes undefined behavior that happens to work when stride is negative: size_t is typically the unsigned type of ptrdiff_t and therefore the division will be performed as size_t, i.e. use logical right shifts, making stride very big when sizeof(pixel) is > 1. This works, because pointer to pixel for accesses entails an implicit factor of sizeof(pixel) so that everything is correct modulo SIZE_MAX. Yet this is UB and UBSan complains about it. 2. It makes the compiler emit actual shifts/ands to discard the low bits shifted away. 3. There may be systems where alignof(uint16_t) or alignof(float) is strictly smaller than their sizeof, so that the stride (in bytes) is not guaranteed to be multiple of these sizeofs. In this case, dividing by sizeof(pixel) is simply wrong. Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
This commit is contained in:
@@ -92,22 +92,18 @@ static void fn0(NAME)(const uint8_t *_top, ptrdiff_t top_linesize, \
|
||||
ptrdiff_t width, ptrdiff_t height, \
|
||||
FilterParams *param, SliceParams *sliceparam) \
|
||||
{ \
|
||||
const PIXEL *top = (const PIXEL *)_top; \
|
||||
const PIXEL *bottom = (const PIXEL *)_bottom; \
|
||||
PIXEL *dst = (PIXEL *)_dst; \
|
||||
const float opacity = param->opacity; \
|
||||
\
|
||||
dst_linesize /= sizeof(PIXEL); \
|
||||
top_linesize /= sizeof(PIXEL); \
|
||||
bottom_linesize /= sizeof(PIXEL); \
|
||||
\
|
||||
for (int i = 0; i < height; i++) { \
|
||||
const PIXEL *top = (const PIXEL *)_top; \
|
||||
const PIXEL *bottom = (const PIXEL *)_bottom; \
|
||||
PIXEL *dst = (PIXEL *)_dst; \
|
||||
for (int j = 0; j < width; j++) { \
|
||||
dst[j] = top[j] + ((EXPR)-top[j]) * opacity; \
|
||||
} \
|
||||
dst += dst_linesize; \
|
||||
top += top_linesize; \
|
||||
bottom += bottom_linesize; \
|
||||
_dst += dst_linesize; \
|
||||
_top += top_linesize; \
|
||||
_bottom += bottom_linesize; \
|
||||
} \
|
||||
}
|
||||
|
||||
|
@@ -82,22 +82,18 @@ static void blend_normal_##name(const uint8_t *_top, ptrdiff_t top_linesize,
|
||||
ptrdiff_t width, ptrdiff_t height, \
|
||||
FilterParams *param, SliceParams *sliceparam) \
|
||||
{ \
|
||||
const type *top = (const type*)_top; \
|
||||
const type *bottom = (const type*)_bottom; \
|
||||
type *dst = (type*)_dst; \
|
||||
const float opacity = param->opacity; \
|
||||
\
|
||||
dst_linesize /= sizeof(type); \
|
||||
top_linesize /= sizeof(type); \
|
||||
bottom_linesize /= sizeof(type); \
|
||||
\
|
||||
for (int i = 0; i < height; i++) { \
|
||||
const type *top = (const type*)_top; \
|
||||
const type *bottom = (const type*)_bottom; \
|
||||
type *dst = (type*)_dst; \
|
||||
for (int j = 0; j < width; j++) { \
|
||||
dst[j] = top[j] * opacity + bottom[j] * (1.f - opacity); \
|
||||
} \
|
||||
dst += dst_linesize; \
|
||||
top += top_linesize; \
|
||||
bottom += bottom_linesize; \
|
||||
_dst += dst_linesize; \
|
||||
_top += top_linesize; \
|
||||
_bottom += bottom_linesize; \
|
||||
} \
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user