diff options
author | Ronald S. Bultje <rsbultje@gmail.com> | 2011-12-17 19:56:40 +0000 |
---|---|---|
committer | Mans Rullgard <mans@mansr.com> | 2011-12-17 22:41:53 +0000 |
commit | 72dafea0fc0eb7230d7ebb0a7bc803e13b72aaad (patch) | |
tree | cee4a2212c3d21555a2c899c848191662dd18d0c | |
parent | 86a10281c7f6204b3ac1253718971b1f8c106699 (diff) | |
download | ffmpeg-72dafea0fc0eb7230d7ebb0a7bc803e13b72aaad.tar.gz |
swscale: fix overflow in gray16 vertical scaling.
This fixes the same overflow as in the RGB48/16-bit YUV scaling;
some filters can overflow both negatively and positively (e.g.
spline/lanczos), so we bias a signed integer so it's "half signed"
and "half unsigned", and can cover overflows in both directions
while maintaining full 31-bit depth.
Signed-off-by: Mans Rullgard <mans@mansr.com>
-rw-r--r-- | libswscale/swscale.c | 14 |
1 files changed, 6 insertions, 8 deletions
diff --git a/libswscale/swscale.c b/libswscale/swscale.c index 3ea37104e8..c9dfc8df2f 100644 --- a/libswscale/swscale.c +++ b/libswscale/swscale.c @@ -386,8 +386,8 @@ yuv2gray16_X_c_template(SwsContext *c, const int16_t *lumFilter, for (i = 0; i < (dstW >> 1); i++) { int j; - int Y1 = 1 << 14; - int Y2 = 1 << 14; + int Y1 = (1 << 14) - 0x40000000; + int Y2 = (1 << 14) - 0x40000000; for (j = 0; j < lumFilterSize; j++) { Y1 += lumSrc[j][i * 2] * lumFilter[j]; @@ -395,12 +395,10 @@ yuv2gray16_X_c_template(SwsContext *c, const int16_t *lumFilter, } Y1 >>= 15; Y2 >>= 15; - if ((Y1 | Y2) & 0x10000) { - Y1 = av_clip_uint16(Y1); - Y2 = av_clip_uint16(Y2); - } - output_pixel(&dest[i * 2 + 0], Y1); - output_pixel(&dest[i * 2 + 1], Y2); + Y1 = av_clip_int16(Y1); + Y2 = av_clip_int16(Y2); + output_pixel(&dest[i * 2 + 0], 0x8000 + Y1); + output_pixel(&dest[i * 2 + 1], 0x8000 + Y2); } } |