From 742160d2f161b316ad923b0ea0c60d79193c3357 Mon Sep 17 00:00:00 2001
From: Martin Vignali <martin.vignali@gmail.com>
Date: Mon, 20 Aug 2018 16:35:13 +0200
Subject: [PATCH 4/4] swscale/input : avoid float calc for grayFloat to uint16 
 conversion

reuse the float to uint16 func currently use inside exr decoder
---
 libswscale/input.c            | 10 +++++-----
 libswscale/swscale_internal.h | 20 ++++++++++++++++++++
 2 files changed, 25 insertions(+), 5 deletions(-)

diff --git a/libswscale/input.c b/libswscale/input.c
index 4099c19c2b..db8bac39af 100644
--- a/libswscale/input.c
+++ b/libswscale/input.c
@@ -946,11 +946,11 @@ static av_always_inline void grayf32ToY16_c(uint8_t *_dst, const uint8_t *_src,
                                             const uint8_t *unused2, int width, uint32_t *unused)
 {
     int i;
-    const float *src = (const float *)_src;
+    const uint32_t * src = (const uint32_t *) _src;
     uint16_t *dst    = (uint16_t *)_dst;
 
-    for (i = 0; i < width; ++i){
-        dst[i] = av_clip_uint16(lrintf(65535.0f * src[i]));
+    for (i = 0; i < width; i++) {
+        dst[i] = ff_flt2uint(src[i]);
     }
 }
 
@@ -961,8 +961,8 @@ static av_always_inline void grayf32ToY16_bswap_c(uint8_t *_dst, const uint8_t *
     const uint32_t *src = (const uint32_t *)_src;
     uint16_t *dst    = (uint16_t *)_dst;
 
-    for (i = 0; i < width; ++i){
-        dst[i] = av_clip_uint16(lrintf(65535.0f * av_int2float(av_bswap32(src[i]))));
+    for (i = 0; i < width; i++) {
+        dst[i] = ff_flt2uint(av_bswap32(src[i]));
     }
 }
 
diff --git a/libswscale/swscale_internal.h b/libswscale/swscale_internal.h
index 4fa59386a6..068e4202aa 100644
--- a/libswscale/swscale_internal.h
+++ b/libswscale/swscale_internal.h
@@ -922,6 +922,26 @@ static inline void fillPlane16(uint8_t *plane, int stride, int width, int height
     }
 }
 
+/**
+ * Convert from 32-bit float as uint32_t to uint16_t.
+ *
+ * @param v 32-bit float
+ *
+ * @return normalized 16-bit unsigned int
+ */
+static inline uint16_t ff_flt2uint(int32_t v)
+{
+    int32_t exp = v >> 23;
+    // "HACK": negative values result in exp<  0, so clipping them to 0
+    // is also handled by this condition, avoids explicit check for sign bit.
+    if (exp <= 127 + 7 - 24) // we would shift out all bits anyway
+        return 0;
+    if (exp >= 127)
+        return 0xffff;
+    v &= 0x007fffff;
+    return (v + (1 << 23)) >> (127 + 7 - exp);
+}
+
 #define MAX_SLICE_PLANES 4
 
 /// Slice plane
-- 
2.14.3 (Apple Git-98)

