Message ID | 20211107055221.99121-1-mindmark@gmail.com |
---|---|
State | New |
Headers | show |
Series | [FFmpeg-devel] swscale/input: clamp rgbf32 values between 0, 1 before scaling | expand |
Context | Check | Description |
---|---|---|
andriy/make_ppc | success | Make finished |
andriy/make_fate_ppc | fail | Make fate failed |
andriy/make_x86 | success | Make finished |
andriy/make_fate_x86 | success | Make fate finished |
On Sat, Nov 6, 2021 at 10:52 PM <mindmark@gmail.com> wrote: > From: Mark Reid <mindmark@gmail.com> > > if the float pixel * 65535.0f > 2147483647.0f > lrintf may overfow and return negative values, depending on implementation. > nan and +/-inf values may also be implementation defined > > clamp the values between 0,1 before scaling, so lrintf > always works. > > values <=0.0f, -inf, nan = 0.0f > values >=1.0f, +inf = 1.0f > --- > libswscale/input.c | 12 +++++++----- > 1 file changed, 7 insertions(+), 5 deletions(-) > > diff --git a/libswscale/input.c b/libswscale/input.c > index 336f957c8c..ea50c9de5c 100644 > --- a/libswscale/input.c > +++ b/libswscale/input.c > @@ -964,7 +964,7 @@ static av_always_inline void > planar_rgb16_to_uv(uint8_t *_dstU, uint8_t *_dstV, > } > #undef rdpx > > -#define rdpx(src) (is_be ? av_int2float(AV_RB32(src)): > av_int2float(AV_RL32(src))) > +#define rdpx(src) (FFMIN(FFMAX(is_be ? av_int2float(AV_RB32(src)): > av_int2float(AV_RL32(src)), 0.0f), 1.0f)) > > static av_always_inline void planar_rgbf32_to_a(uint8_t *_dst, const > uint8_t *_src[4], int width, int is_be, int32_t *rgb2yuv) > { > @@ -1013,17 +1013,16 @@ static av_always_inline void > planar_rgbf32_to_y(uint8_t *_dst, const uint8_t *_s > } > } > > -#undef rdpx > - > static av_always_inline void grayf32ToY16_c(uint8_t *_dst, const uint8_t > *_src, const uint8_t *unused1, > const uint8_t *unused2, int > width, uint32_t *unused) > { > int i; > const float *src = (const float *)_src; > uint16_t *dst = (uint16_t *)_dst; > + int is_be = 0; > > for (i = 0; i < width; ++i){ > - dst[i] = av_clip_uint16(lrintf(65535.0f * src[i])); > + dst[i] = av_clip_uint16(lrintf(65535.0f * rdpx(src + i))); > } > } > > @@ -1033,12 +1032,15 @@ static av_always_inline void > grayf32ToY16_bswap_c(uint8_t *_dst, const uint8_t * > int i; > const uint32_t *src = (const uint32_t *)_src; > uint16_t *dst = (uint16_t *)_dst; > + int is_be = 1; > > for (i = 0; i < width; ++i){ > - dst[i] = av_clip_uint16(lrintf(65535.0f * > av_int2float(av_bswap32(src[i])))); > + dst[i] = av_clip_uint16(lrintf(65535.0f * rdpx(src+ i))); > } > } > > +#undef rdpx > + > #define rgb9plus_planar_funcs_endian(nbits, endian_name, endian) > \ > static void planar_rgb##nbits##endian_name##_to_y(uint8_t *dst, const > uint8_t *src[4], \ > int w, int32_t > *rgb2yuv) \ > -- > 2.29.2 > > seem to not work on PowerPC, I see what's going on, I'll send a new patch
diff --git a/libswscale/input.c b/libswscale/input.c index 336f957c8c..ea50c9de5c 100644 --- a/libswscale/input.c +++ b/libswscale/input.c @@ -964,7 +964,7 @@ static av_always_inline void planar_rgb16_to_uv(uint8_t *_dstU, uint8_t *_dstV, } #undef rdpx -#define rdpx(src) (is_be ? av_int2float(AV_RB32(src)): av_int2float(AV_RL32(src))) +#define rdpx(src) (FFMIN(FFMAX(is_be ? av_int2float(AV_RB32(src)): av_int2float(AV_RL32(src)), 0.0f), 1.0f)) static av_always_inline void planar_rgbf32_to_a(uint8_t *_dst, const uint8_t *_src[4], int width, int is_be, int32_t *rgb2yuv) { @@ -1013,17 +1013,16 @@ static av_always_inline void planar_rgbf32_to_y(uint8_t *_dst, const uint8_t *_s } } -#undef rdpx - static av_always_inline void grayf32ToY16_c(uint8_t *_dst, const uint8_t *_src, const uint8_t *unused1, const uint8_t *unused2, int width, uint32_t *unused) { int i; const float *src = (const float *)_src; uint16_t *dst = (uint16_t *)_dst; + int is_be = 0; for (i = 0; i < width; ++i){ - dst[i] = av_clip_uint16(lrintf(65535.0f * src[i])); + dst[i] = av_clip_uint16(lrintf(65535.0f * rdpx(src + i))); } } @@ -1033,12 +1032,15 @@ static av_always_inline void grayf32ToY16_bswap_c(uint8_t *_dst, const uint8_t * int i; const uint32_t *src = (const uint32_t *)_src; uint16_t *dst = (uint16_t *)_dst; + int is_be = 1; for (i = 0; i < width; ++i){ - dst[i] = av_clip_uint16(lrintf(65535.0f * av_int2float(av_bswap32(src[i])))); + dst[i] = av_clip_uint16(lrintf(65535.0f * rdpx(src+ i))); } } +#undef rdpx + #define rgb9plus_planar_funcs_endian(nbits, endian_name, endian) \ static void planar_rgb##nbits##endian_name##_to_y(uint8_t *dst, const uint8_t *src[4], \ int w, int32_t *rgb2yuv) \
From: Mark Reid <mindmark@gmail.com> if the float pixel * 65535.0f > 2147483647.0f lrintf may overfow and return negative values, depending on implementation. nan and +/-inf values may also be implementation defined clamp the values between 0,1 before scaling, so lrintf always works. values <=0.0f, -inf, nan = 0.0f values >=1.0f, +inf = 1.0f --- libswscale/input.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) -- 2.29.2