Hi Ganesh, On Nov 13, 2015 12:02 PM, "Ganesh Ajjanagadde" <gajjanaga...@gmail.com> wrote: > > The rationale for this function is reflected in the documentation for > it, and is copied here: > > Clip a double value into the long long amin-amax range. > This function is needed because conversion of floating point to integers when > it does not fit in the integer's representation does not necessarily saturate > correctly (usually converted to a cvttsd2si on x86) which saturates numbers > > INT64_MAX to INT64_MIN. The standard marks such conversions as undefined > behavior, allowing this sort of mathematically bogus conversions. This provides > a safe alternative that is slower obviously but assures safety and better > mathematical behavior. > API: > @param a value to clip > @param amin minimum value of the clip range > @param amax maximum value of the clip range > @return clipped value > > Note that a priori if one can guarantee from the calling side that the > double is in range, it is safe to simply do an explicit/implicit cast, > and that will be far faster. However, otherwise this function should be > used. > > avutil minor version is bumped. > > Reviewed-by: Ronald S. Bultje <rsbul...@gmail.com> > Signed-off-by: Ganesh Ajjanagadde <gajjanaga...@gmail.com> > --- > libavutil/common.h | 30 ++++++++++++++++++++++++++++++ > libavutil/version.h | 2 +- > 2 files changed, 31 insertions(+), 1 deletion(-) > > diff --git a/libavutil/common.h b/libavutil/common.h > index 6f0f582..f4687ab 100644 > --- a/libavutil/common.h > +++ b/libavutil/common.h > @@ -298,6 +298,33 @@ static av_always_inline av_const double av_clipd_c(double a, double amin, double > else return a; > } > > +/** > + * Clip and convert a double value into the long long amin-amax range. > + * This function is needed because conversion of floating point to integers when > + * it does not fit in the integer's representation does not necessarily saturate > + * correctly (usually converted to a cvttsd2si on x86) which saturates numbers > + * > INT64_MAX to INT64_MIN. The standard marks such conversions as undefined > + * behavior, allowing this sort of mathematically bogus conversions. This provides > + * a safe alternative that is slower obviously but assures safety and better > + * mathematical behavior. > + * @param a value to clip > + * @param amin minimum value of the clip range > + * @param amax maximum value of the clip range > + * @return clipped value > + */ > +static av_always_inline av_const int64_t av_rint64_clip_c(double a, int64_t amin, int64_t amax) > +{ > +#if defined(HAVE_AV_CONFIG_H) && defined(ASSERT_LEVEL) && ASSERT_LEVEL >= 2 > + if (amin > amax) abort(); > +#endif > + // INT64_MAX+1,INT64_MIN are exactly representable as IEEE doubles > + if (a >= 9223372036854775808.0 || llrint(a) >= amax) > + return amax; > + if (a <= -9223372036854775808.0 || llrint(a) <= amin) > + return amin;
Doesn't this allow negative overflows in the max check? I think you need both overflow checks before the min/max checks. Try the next float val smaller than int64_min as input with a small amax, eg 0. I bet it returns 0 instead of amin. Rest looks OK. I'd personally store llrint retval in a variable but let's assume compiler is clever enough to optimize that out. Ronald _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel