Integrate integer overflow fixes from security branch

cherry-pick of 55625cf05f4345dcab5d9d92b83bb8b5606debab for nyc-dev.

* Throw exception on float cast overflow in dng_stream.cpp.
* Ensure hue is in range before converting to integer.
* Replace the limits from stdint.h by the limit from std::numeric_limits<>.

Bug: 26535130
Change-Id: I660c730a8551a8613655898c0fff749925dad149
diff --git a/source/dng_safe_arithmetic.h b/source/dng_safe_arithmetic.h
index 78d8ae0..2535276 100644
--- a/source/dng_safe_arithmetic.h
+++ b/source/dng_safe_arithmetic.h
@@ -129,9 +129,12 @@
 #ifdef DNG_HAS_INT128
 inline std::int64_t SafeInt64MultByInt128(std::int64_t arg1,
                                           std::int64_t arg2) {
+  const __int128 kInt64Max =
+      static_cast<__int128>(std::numeric_limits<std::int64_t>::max());
+  const __int128 kInt64Min =
+      static_cast<__int128>(std::numeric_limits<std::int64_t>::min());
   __int128 result = static_cast<__int128>(arg1) * static_cast<__int128>(arg2);
-  if (result > static_cast<__int128>(INT64_MAX) ||
-      result < static_cast<__int128>(INT64_MIN)) {
+  if (result > kInt64Max || result < kInt64Min) {
     ThrowProgramError("Arithmetic overflow");
   }
   return static_cast<std::int64_t>(result);
@@ -213,9 +216,10 @@
   *dest = converted;
 }
 
-// Returns the result of converting val to an int32_t using truncation if val is
-// in range of int32_t values. Otherwise, throws a dng_exception with error code
-// dng_error_unknown.
+// Returns the result of converting val to the result type using truncation if
+// val is in range of the result type values. Otherwise, throws a dng_exception
+// with error code dng_error_unknown.
 std::int32_t ConvertDoubleToInt32(double val);
+std::uint32_t ConvertDoubleToUint32(double val);
 
 #endif  // __dng_safe_arithmetic__
diff --git a/source/dng_stream.cpp b/source/dng_stream.cpp
index c1db250..d94a5c7 100644
--- a/source/dng_stream.cpp
+++ b/source/dng_stream.cpp
@@ -819,7 +819,7 @@
 	if (x > (real64) 0xFFFFFFFF)
 		x = (real64) 0xFFFFFFFF;
 		
-	return (uint32) (x + 0.5);
+	return ConvertDoubleToUint32(x + 0.5);
 	
 	}
 	
@@ -960,7 +960,7 @@
 					
 					}
 				
-				result.n = (uint32) (x + 0.5);
+				result.n = ConvertDoubleToUint32(x + 0.5);
 				
 				}
 			
@@ -1012,7 +1012,7 @@
 					
 					}
 				
-				result.n = (int32) (x + 0.5);
+				result.n = ConvertDoubleToInt32(x + 0.5);
 				
 				}
 				
@@ -1028,7 +1028,7 @@
 					
 					}
 				
-				result.n = (int32) (x - 0.5);
+				result.n = ConvertDoubleToInt32(x - 0.5);
 				
 				}
 			
diff --git a/source/dng_utils.h b/source/dng_utils.h
index d87de51..691f0b9 100644
--- a/source/dng_utils.h
+++ b/source/dng_utils.h
@@ -18,6 +18,7 @@
 
 /*****************************************************************************/
 
+#include <cmath>
 #include <limits>
 
 #include "dng_classes.h"
@@ -708,12 +709,12 @@
 	if (s > 0.0f)
 		{
 		
+		if (!std::isfinite(h))
+			ThrowProgramError("Unexpected NaN or Inf");
+		h = std::fmod(h, 6.0f);
 		if (h < 0.0f)
 			h += 6.0f;
 			
-		if (h >= 6.0f)
-			h -= 6.0f;
-			
 		int32  i = (int32) h;
 		real32 f = h - (real32) i;