merge in nyc-release history after reset to nyc-dev
diff --git a/source/dng_info.cpp b/source/dng_info.cpp
index ed87692..5b742aa 100644
--- a/source/dng_info.cpp
+++ b/source/dng_info.cpp
@@ -1501,10 +1501,11 @@
 	
 	uint32 section_offset = 6;
 	
-	while (section_offset + 8 < fShared->fDNGPrivateDataCount)
+	while (SafeUint32Add(section_offset, 8) < fShared->fDNGPrivateDataCount)
 		{
 		
-		stream.SetReadPosition (fShared->fDNGPrivateDataOffset + section_offset);
+		stream.SetReadPosition (SafeUint64Add(fShared->fDNGPrivateDataOffset,
+												section_offset));
 		
 		uint32 section_key   = stream.Get_uint32 ();
 		uint32 section_count = stream.Get_uint32 ();
@@ -1867,11 +1868,12 @@
 			
 			}
 		
-		section_offset += 8 + section_count;
+		section_offset = SafeUint32Add(section_offset, 8);
+		section_offset = SafeUint32Add(section_offset, section_count);
 		
 		if (section_offset & 1)
 			{
-			section_offset++;
+			section_offset = SafeUint32Add(section_offset, 1);
 			}
 		
 		}
diff --git a/source/dng_memory.h b/source/dng_memory.h
index 3966106..05e6f2b 100644
--- a/source/dng_memory.h
+++ b/source/dng_memory.h
@@ -552,6 +552,7 @@
 		// Default implementations of default constructor and copy constructor.
 		dng_std_allocator () = default;
 		dng_std_allocator (const dng_std_allocator&) = default;
+		template<typename U> dng_std_allocator (const dng_std_allocator<U>&) {}
 		
 		T* allocate (size_t n)
 			{
diff --git a/source/dng_misc_opcodes.cpp b/source/dng_misc_opcodes.cpp
index 5a6fa82..38297a0 100644
--- a/source/dng_misc_opcodes.cpp
+++ b/source/dng_misc_opcodes.cpp
@@ -293,7 +293,10 @@
 	
 	fCount = stream.Get_uint32 ();
 	
-	if (dataSize != dng_area_spec::kDataSize + 4 + fCount * 2)
+	uint32 requiredSize = SafeUint32Mult(fCount, 2);
+	requiredSize = SafeUint32Add(requiredSize, dng_area_spec::kDataSize);
+	requiredSize = SafeUint32Add(requiredSize, 4);
+	if (dataSize != requiredSize)
 		{
 		ThrowBadFormat ();
 		}
@@ -591,7 +594,7 @@
 	for (uint32 j = 0; j <= kMaxDegree; j++)
 		{
 		
-		fCoefficient32 [j] = (real32) (fCoefficient [j] * factor32);
+		fCoefficient32 [j] = ConvertDoubleToFloat(fCoefficient [j] * factor32);
 		
 		factor32 *= scale32;
 		
diff --git a/source/dng_safe_arithmetic.cpp b/source/dng_safe_arithmetic.cpp
index 96eaec8..5771861 100644
--- a/source/dng_safe_arithmetic.cpp
+++ b/source/dng_safe_arithmetic.cpp
@@ -1,5 +1,6 @@
 #include "dng_safe_arithmetic.h"
 
+#include <cmath>
 #include <limits>
 
 #include "dng_exceptions.h"
@@ -295,3 +296,17 @@
     abort();  // Never reached.
   }
 }
+
+float ConvertDoubleToFloat(double val) {
+  const double kMax = std::numeric_limits<float>::max();
+  if (val > kMax) {
+    return std::numeric_limits<float>::infinity();
+  } else if (val < -kMax) {
+    return -std::numeric_limits<float>::infinity();
+  } else {
+    // The cases that end up here are:
+    // - values in [-kMax, kMax]
+    // - NaN (because it always compares false)
+    return static_cast<float>(val);
+  }
+}
diff --git a/source/dng_safe_arithmetic.h b/source/dng_safe_arithmetic.h
index 2535276..b229dc4 100644
--- a/source/dng_safe_arithmetic.h
+++ b/source/dng_safe_arithmetic.h
@@ -222,4 +222,9 @@
 std::int32_t ConvertDoubleToInt32(double val);
 std::uint32_t ConvertDoubleToUint32(double val);
 
+// Returns the result of converting val to float. If val is outside of
+// [-FLT_MAX, FLT_MAX], -infinity and infinity is returned respectively. NaN is
+// returned as NaN.
+float ConvertDoubleToFloat(double val);
+
 #endif  // __dng_safe_arithmetic__
diff --git a/source/dng_shared.cpp b/source/dng_shared.cpp
index 3ff40a4..4b00d24 100644
--- a/source/dng_shared.cpp
+++ b/source/dng_shared.cpp
@@ -640,9 +640,8 @@
 			if (!skipSat0)
 				{
 			
-				if (!CheckTagCount (parentCode, tagCode, tagCount, fProfileHues *
-																   fProfileSats * 
-																   fProfileVals * 3))
+				if (!CheckTagCount (parentCode, tagCode, tagCount,
+									SafeUint32Mult(fProfileHues, fProfileSats, fProfileVals, 3)))
 					return false;
 					
 				}
@@ -763,9 +762,10 @@
 			if (!skipSat0)
 				{
 			
-				if (!CheckTagCount (parentCode, tagCode, tagCount, fLookTableHues *
-																   fLookTableSats * 
-																   fLookTableVals * 3))
+				if (!CheckTagCount (parentCode, tagCode, tagCount,
+									SafeUint32Mult(fLookTableHues,
+													fLookTableSats,
+													fLookTableVals, 3)))
 					return false;
 					
 				}
diff --git a/source/dng_stream.cpp b/source/dng_stream.cpp
index d94a5c7..8b8fa5a 100644
--- a/source/dng_stream.cpp
+++ b/source/dng_stream.cpp
@@ -850,7 +850,7 @@
 		if (x < -2147483648.0)
 			x = -2147483648.0;
 			
-		return (int32) (x - 0.5);
+		return ConvertDoubleToInt32(x - 0.5);
 		
 		}
 		
@@ -860,7 +860,7 @@
 		if (x > 2147483647.0)
 			x = 2147483647.0;
 		
-		return (int32) (x + 0.5);
+		return ConvertDoubleToInt32(x + 0.5);
 		
 		}
 		
diff --git a/source/dng_string.cpp b/source/dng_string.cpp
index 60e7d74..13fc438 100644
--- a/source/dng_string.cpp
+++ b/source/dng_string.cpp
@@ -923,7 +923,7 @@
 		0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
 		0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
 		2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
-		3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,6,6,0,0
+		3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,0,0,0,0,0,0,0,0,0,0,0
 		};
 		
 	if (isValid)
@@ -1023,32 +1023,6 @@
 			break;
 			
 			}
-							   
-		case 5:
-			{
-			
-			aChar = ((((((((aChar << 6) + nBuf [1])
-								  << 6) + nBuf [2])
-								  << 6) + nBuf [3])
-								  << 6) + nBuf [4]) - (uint32) 0xFA082080UL;
-								  
-			break;
-			
-			}
-								 
-		case 6:
-			{
-			
-			aChar = ((((((((((aChar << 6) + nBuf [1])
-								    << 6) + nBuf [2])
-								    << 6) + nBuf [3])
-								    << 6) + nBuf [4])
-								    << 6) + nBuf [5]) - (uint32) 0x82082080UL;
-									
-			break;
-			
-			}
-								   
 		}
 		
 	if (aChar < 0x7F || aChar > 0x0010FFFF)