Index: openexr-2.1.0/IlmImf/ImfCompositeDeepScanLine.cpp
===================================================================
--- openexr-2.1.0.orig/IlmImf/ImfCompositeDeepScanLine.cpp	2013-11-12 00:09:51.000000000 +0100
+++ openexr-2.1.0/IlmImf/ImfCompositeDeepScanLine.cpp	2020-04-21 15:26:48.132052041 +0200
@@ -44,6 +44,7 @@
 
 #include <Iex.h>
 #include <vector>
+#include <stddef.h>
 OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
 
 using std::vector;
@@ -179,7 +180,7 @@ CompositeDeepScanLine::Data::handleDeepF
                                                     int start,
                                                     int end)
 {
-    int width=_dataWindow.size().x+1;
+    ptrdiff_t width=_dataWindow.size().x+1;
     size_t pixelcount = width * (end-start+1);
     pointers.resize(_channels.size());
     counts.resize(pixelcount);
Index: openexr-2.1.0/IlmImf/ImfDeepScanLineInputFile.cpp
===================================================================
--- openexr-2.1.0.orig/IlmImf/ImfDeepScanLineInputFile.cpp	2013-10-16 00:55:09.000000000 +0200
+++ openexr-2.1.0/IlmImf/ImfDeepScanLineInputFile.cpp	2020-04-21 15:26:48.136052062 +0200
@@ -914,8 +914,7 @@ void DeepScanLineInputFile::initialize(c
     }
     catch (...)
     {
-        delete _data;
-        _data=NULL;
+        // Don't delete _data here, leave that to caller
         throw;
     }
 }
@@ -931,8 +930,15 @@ DeepScanLineInputFile::DeepScanLineInput
     _data->memoryMapped = _data->_streamData->is->isMemoryMapped();
     _data->version = part->version;
 
-    initialize(part->header);
-
+    try
+    {
+       initialize(part->header);
+    }
+    catch(...)
+    {
+        delete _data;
+        throw;
+    }
     _data->lineOffsets = part->chunkOffsets;
 
     _data->partNumber = part->partNumber;
@@ -944,7 +950,6 @@ DeepScanLineInputFile::DeepScanLineInput
 :
      _data (new Data (numThreads))
 {
-    _data->_streamData = new InputStreamMutex();
     _data->_deleteStream = true;
     OPENEXR_IMF_INTERNAL_NAMESPACE::IStream* is = 0;
 
@@ -954,12 +959,29 @@ DeepScanLineInputFile::DeepScanLineInput
         readMagicNumberAndVersionField(*is, _data->version);
         //
         // Backward compatibility to read multpart file.
-        //
+        // multiPartInitialize will create _streamData
         if (isMultiPart(_data->version))
         {
             compatibilityInitialize(*is);
             return;
         }
+    }
+    catch (IEX_NAMESPACE::BaseExc &e)
+    {
+        if (is)          delete is;
+        if (_data)       delete _data;
+
+        REPLACE_EXC (e, "Cannot read image file "
+                     "\"" << fileName << "\". " << e.what());
+        throw;
+    }
+
+    //
+    // not multiPart - allocate stream data and intialise as normal
+    //
+    try
+    {
+        _data->_streamData = new InputStreamMutex();
         _data->_streamData->is = is;
         _data->memoryMapped = is->isMemoryMapped();
         _data->header.readFrom (*_data->_streamData->is, _data->version);
@@ -975,7 +997,10 @@ DeepScanLineInputFile::DeepScanLineInput
     catch (IEX_NAMESPACE::BaseExc &e)
     {
         if (is)          delete is;
-        if (_data && _data->_streamData) delete _data->_streamData;
+        if (_data && _data->_streamData)
+        {
+            delete _data->_streamData;
+        }
         if (_data)       delete _data;
 
         REPLACE_EXC (e, "Cannot read image file "
@@ -985,7 +1010,10 @@ DeepScanLineInputFile::DeepScanLineInput
     catch (...)
     {
         if (is)          delete is;
-        if (_data && _data->_streamData) delete _data->_streamData;
+        if (_data && _data->_streamData)
+        {
+            delete _data->_streamData;
+        }
         if (_data)       delete _data;
 
         throw;
@@ -1009,7 +1037,18 @@ DeepScanLineInputFile::DeepScanLineInput
 
     _data->version =version;
     
-    initialize (header);
+    try
+    {
+        initialize (header);
+    }
+    catch (...)
+    {
+        if (_data && _data->_streamData)
+        {
+            delete _data->_streamData;
+        }
+        if (_data)       delete _data;
+   }
 
     readLineOffsets (*_data->_streamData->is,
                      _data->lineOrder,
@@ -1041,8 +1080,9 @@ DeepScanLineInputFile::~DeepScanLineInpu
         //
 
         if (_data->partNumber == -1 && _data->_streamData)
+        {
             delete _data->_streamData;
-
+        }
         delete _data;
     }
 }
Index: openexr-2.1.0/IlmImf/ImfDeepTiledInputFile.cpp
===================================================================
--- openexr-2.1.0.orig/IlmImf/ImfDeepTiledInputFile.cpp	2013-10-16 00:55:09.000000000 +0200
+++ openexr-2.1.0/IlmImf/ImfDeepTiledInputFile.cpp	2020-04-21 15:46:24.198356406 +0200
@@ -283,6 +283,7 @@ DeepTiledInputFile::Data::Data (int numT
     multiPartBackwardSupport(false),
     numThreads(numThreads),
     memoryMapped(false),
+    sampleCountTableComp(NULL),
     _streamData(NULL),
     _deleteStream(false)
 {
@@ -308,6 +309,8 @@ DeepTiledInputFile::Data::~Data ()
 
     for (size_t i = 0; i < slices.size(); i++)
         delete slices[i];
+
+    delete sampleCountTableComp;
 }
 
 
@@ -927,7 +930,15 @@ DeepTiledInputFile::DeepTiledInputFile (
     _data (new Data (part->numThreads))
 {
     _data->_deleteStream=false;
-    multiPartInitialize(part);
+    try
+    {
+       multiPartInitialize(part);
+    }
+    catch(...)
+    {
+        delete _data;
+        throw;
+    }
 }
 
 
Index: openexr-2.1.0/IlmImf/ImfHeader.cpp
===================================================================
--- openexr-2.1.0.orig/IlmImf/ImfHeader.cpp	2020-04-21 15:26:48.124051999 +0200
+++ openexr-2.1.0/IlmImf/ImfHeader.cpp	2020-04-21 15:26:48.136052062 +0200
@@ -867,6 +867,7 @@ Header::sanityCheck (bool isTiled, bool
     }
     
     const std::string & part_type=hasType() ? type() : "";
+
     
     if(part_type!="" && !isSupportedType(part_type))
     {
@@ -876,6 +877,7 @@ Header::sanityCheck (bool isTiled, bool
         return;
     }
     
+    bool isDeep = isDeepData(part_type);
    
     //
     // If the file is tiled, verify that the tile description has reasonable
@@ -896,7 +898,7 @@ Header::sanityCheck (bool isTiled, bool
 
 	const TileDescription &tileDesc = tileDescription();
 
-	if (tileDesc.xSize <= 0 || tileDesc.ySize <= 0)
+	if (tileDesc.xSize <= 0 || tileDesc.ySize <= 0 || tileDesc.xSize > INT_MAX || tileDesc.ySize > INT_MAX )
 	    throw IEX_NAMESPACE::ArgExc ("Invalid tile size in image header.");
 
 	if (maxTileWidth > 0 &&
@@ -943,7 +945,8 @@ Header::sanityCheck (bool isTiled, bool
     if (!isValidCompression (this->compression()))
   	throw IEX_NAMESPACE::ArgExc ("Unknown compression type in image header.");
     
-    if(isDeepData(part_type))
+
+    if( isDeep )
     {
         if (!isValidDeepCompression (this->compression()))
             throw IEX_NAMESPACE::ArgExc ("Compression type in header not valid for deep data");
@@ -955,6 +958,8 @@ Header::sanityCheck (bool isTiled, bool
     // If the file is tiled then for each channel, the type must be one of the
     // predefined values, and the x and y sampling must both be 1.
     //
+    // x and y sampling must currently also be 1 for deep scanline images
+    //
     // If the file is not tiled then for each channel, the type must be one
     // of the predefined values, the x and y coordinates of the data window's
     // upper left corner must be divisible by the x and y subsampling factors,
@@ -964,7 +969,7 @@ Header::sanityCheck (bool isTiled, bool
 
     const ChannelList &channels = this->channels();
     
-    if (isTiled)
+    if (isTiled || isDeep)
     {
 	for (ChannelList::ConstIterator i = channels.begin();
 	     i != channels.end();
Index: openexr-2.1.0/IlmImf/ImfHuf.cpp
===================================================================
--- openexr-2.1.0.orig/IlmImf/ImfHuf.cpp	2020-04-21 15:26:48.092051826 +0200
+++ openexr-2.1.0/IlmImf/ImfHuf.cpp	2020-04-21 15:31:43.809638392 +0200
@@ -1044,7 +1044,10 @@ hufUncompress (const char compressed[],
 	       unsigned short raw[],
 	       int nRaw)
 {
-    if (nCompressed == 0)
+    //
+    // need at least 20 bytes for header
+    //
+    if (nCompressed < 20 )
     {
 	if (nRaw != 0)
 	    notEnoughData();
@@ -1062,6 +1065,12 @@ hufUncompress (const char compressed[],
 
     const char *ptr = compressed + 20;
 
+    if ( ptr + (nBits+7 )/8 > compressed+nCompressed)
+    {
+        notEnoughData();
+        return;
+    }
+
     AutoArray <Int64, HUF_ENCSIZE> freq;
     AutoArray <HufDec, HUF_DECSIZE> hdec;
 
Index: openexr-2.1.0/IlmImf/ImfInputFile.cpp
===================================================================
--- openexr-2.1.0.orig/IlmImf/ImfInputFile.cpp	2013-11-12 00:09:51.000000000 +0100
+++ openexr-2.1.0/IlmImf/ImfInputFile.cpp	2020-04-21 15:26:48.136052062 +0200
@@ -474,7 +474,15 @@ InputFile::InputFile (InputPartData* par
     _data (new Data (part->numThreads))
 {
     _data->_deleteStream=false;
-    multiPartInitialize (part);
+    try
+    {
+       multiPartInitialize (part);
+    }
+    catch(...)
+    {
+        delete _data;
+        throw;
+    }
 }
 
 
Index: openexr-2.1.0/IlmImf/ImfMisc.cpp
===================================================================
--- openexr-2.1.0.orig/IlmImf/ImfMisc.cpp	2013-11-07 22:45:25.000000000 +0100
+++ openexr-2.1.0/IlmImf/ImfMisc.cpp	2020-04-21 15:42:36.757138199 +0200
@@ -114,9 +114,9 @@ bytesPerLineTable (const Header &header,
 	 c != channels.end();
 	 ++c)
     {
-	int nBytes = pixelTypeSize (c.channel().type) *
-		     (dataWindow.max.x - dataWindow.min.x + 1) /
-		     c.channel().xSampling;
+	size_t nBytes = size_t(pixelTypeSize (c.channel().type)) *
+		     size_t(dataWindow.max.x - dataWindow.min.x + 1) /
+		     size_t(c.channel().xSampling);
 
 	for (int y = dataWindow.min.y, i = 0; y <= dataWindow.max.y; ++y, ++i)
 	    if (modp (y, c.channel().ySampling) == 0)
@@ -262,6 +262,7 @@ defaultFormat (Compressor * compressor)
 }
 
 
+//obsolete
 int
 numLinesInBuffer (Compressor * compressor)
 {
@@ -1811,6 +1812,35 @@ usesLongNames (const Header &header)
     return false;
 }
 
+namespace
+{
+// for a given compression type, return the number of scanlines
+// compressed into a single chunk
+// TODO add to API and move to ImfCompressor.cpp
+int
+numLinesInBuffer(Compression comp)
+{
+    switch(comp)
+    {
+        case NO_COMPRESSION :
+        case RLE_COMPRESSION:
+        case ZIPS_COMPRESSION:
+            return 1;
+        case ZIP_COMPRESSION:
+            return 16;
+        case PIZ_COMPRESSION:
+            return 32;
+        case PXR24_COMPRESSION:
+            return 16;
+        case B44_COMPRESSION:
+            return 32;
+
+        default:
+	        throw IEX_NAMESPACE::ArgExc ("Unknown compression type");
+    }
+}
+}
+
 int
 getScanlineChunkOffsetTableSize(const Header& header)
 {
@@ -1820,17 +1850,11 @@ getScanlineChunkOffsetTableSize(const He
     size_t maxBytesPerLine = bytesPerLineTable (header,
                                                 bytesPerLine);
 
-    Compressor* compressor = newCompressor(header.compression(),
-                                           maxBytesPerLine,
-                                           header);
-
-    int linesInBuffer = numLinesInBuffer (compressor);
+    int linesInBuffer = numLinesInBuffer ( header.compression() );
 
     int lineOffsetSize = (dataWindow.max.y - dataWindow.min.y +
                           linesInBuffer) / linesInBuffer;
 
-    delete compressor;
-
     return lineOffsetSize;
 }
 
Index: openexr-2.1.0/IlmImf/ImfPizCompressor.cpp
===================================================================
--- openexr-2.1.0.orig/IlmImf/ImfPizCompressor.cpp	2020-04-21 15:26:48.092051826 +0200
+++ openexr-2.1.0/IlmImf/ImfPizCompressor.cpp	2020-04-21 15:26:48.136052062 +0200
@@ -491,7 +491,9 @@ PizCompressor::uncompress (const char *i
     // This is the cunompress function which is used by both the tiled and
     // scanline decompression routines.
     //
-    
+
+    const char* inputEnd=inPtr+inSize;
+
     //
     // Special case - empty input buffer
     //
@@ -502,6 +504,7 @@ PizCompressor::uncompress (const char *i
 	return 0;
     }
 
+
     //
     // Determine the layout of the compressed pixel data
     //
@@ -548,6 +551,12 @@ PizCompressor::uncompress (const char *i
     AutoArray <unsigned char, BITMAP_SIZE> bitmap;
     memset (bitmap, 0, sizeof (unsigned char) * BITMAP_SIZE);
 
+
+    if(inPtr + sizeof(unsigned short)*2 > inputEnd)
+    {
+   	   throw InputExc ("PIZ compressed data too short");
+    }
+
     Xdr::read <CharPtrIO> (inPtr, minNonZero);
     Xdr::read <CharPtrIO> (inPtr, maxNonZero);
 
@@ -559,8 +568,14 @@ PizCompressor::uncompress (const char *i
 
     if (minNonZero <= maxNonZero)
     {
-	Xdr::read <CharPtrIO> (inPtr, (char *) &bitmap[0] + minNonZero,
-			       maxNonZero - minNonZero + 1);
+        size_t bytesToRead = maxNonZero - minNonZero + 1;
+	    if(inPtr + bytesToRead > inputEnd)
+        {
+   	      throw InputExc ("PIZ compressed data too short");
+        }
+
+Xdr::read <CharPtrIO> (inPtr, (char *) &bitmap[0] + minNonZero,
+			       bytesToRead);
     }
 
     AutoArray <unsigned short, USHORT_RANGE> lut;
@@ -569,6 +584,11 @@ PizCompressor::uncompress (const char *i
     //
     // Huffman decoding
     //
+   if(inPtr + sizeof(int)> inputEnd)
+   {
+       throw InputExc ("PIZ compressed data too short");
+   }
+
 
     int length;
     Xdr::read <CharPtrIO> (inPtr, length);
Index: openexr-2.1.0/IlmImf/ImfRleCompressor.cpp
===================================================================
--- openexr-2.1.0.orig/IlmImf/ImfRleCompressor.cpp	2020-04-21 15:26:48.136052062 +0200
+++ openexr-2.1.0/IlmImf/ImfRleCompressor.cpp	2020-04-21 15:39:43.544210447 +0200
@@ -137,6 +137,11 @@ rleUncompress (int inLength, int maxLeng
 	    if (0 > (maxLength -= count))
 		return 0;
 
+	    // check the input buffer is big enough to contain
+	    // 'count' bytes of remaining data
+	    if (inLength < 0)
+		return 0;
+
 	    while (count-- > 0)
 		*out++ = *(char *) (in++);
 	}
Index: openexr-2.1.0/IlmImf/ImfScanLineInputFile.cpp
===================================================================
--- openexr-2.1.0.orig/IlmImf/ImfScanLineInputFile.cpp	2013-11-12 00:09:51.000000000 +0100
+++ openexr-2.1.0/IlmImf/ImfScanLineInputFile.cpp	2020-04-21 15:46:58.250538347 +0200
@@ -1096,8 +1096,6 @@ newLineBufferTask (TaskGroup *group,
 
 void ScanLineInputFile::initialize(const Header& header)
 {
-    try
-    {
         _data->header = header;
 
         _data->lineOrder = _data->header.lineOrder();
@@ -1112,6 +1110,12 @@ void ScanLineInputFile::initialize(const
         size_t maxBytesPerLine = bytesPerLineTable (_data->header,
                                                     _data->bytesPerLine);
 
+        if(maxBytesPerLine > INT_MAX)
+        {
+            throw IEX_NAMESPACE::InputExc("maximum bytes per scanline exceeds maximum permissible size");
+        }
+
+
         for (size_t i = 0; i < _data->lineBuffers.size(); i++)
         {
             _data->lineBuffers[i] = new LineBuffer (newCompressor
@@ -1142,13 +1146,6 @@ void ScanLineInputFile::initialize(const
                               _data->linesInBuffer) / _data->linesInBuffer;
 
         _data->lineOffsets.resize (lineOffsetSize);
-    }
-    catch (...)
-    {
-        delete _data;
-        _data=NULL;
-        throw;
-    }
 }
 
 
@@ -1163,8 +1160,27 @@ ScanLineInputFile::ScanLineInputFile(Inp
 
     _data->version = part->version;
 
-    initialize(part->header);
+    try
+    {
+       initialize(part->header);
+    }
+    catch(...)
+    {
+        if (!_data->memoryMapped)
+        {
+            for (size_t i = 0; i < _data->lineBuffers.size(); i++)
+            {
+                if( _data->lineBuffers[i] )
+                {
+                   EXRFreeAligned(_data->lineBuffers[i]->buffer);
+                   _data->lineBuffers[i]->buffer=NULL;
+                }
+            }
+        }
 
+        delete _data;
+        throw;
+    }
     _data->lineOffsets = part->chunkOffsets;
 
     _data->partNumber = part->partNumber;
@@ -1187,19 +1203,43 @@ ScanLineInputFile::ScanLineInputFile
     _streamData->is = is;
     _data->memoryMapped = is->isMemoryMapped();
 
-    initialize(header);
-    
-    //
-    // (TODO) this is nasty - we need a better way of working out what type of file has been used.
-    // in any case I believe this constructor only gets used with single part files
-    // and 'version' currently only tracks multipart state, so setting to 0 (not multipart) works for us
-    //
-    
-    _data->version=0;
-    readLineOffsets (*_streamData->is,
-                     _data->lineOrder,
-                     _data->lineOffsets,
-                     _data->fileIsComplete);
+    try
+    {
+
+        initialize(header);
+
+        //
+        // (TODO) this is nasty - we need a better way of working out what type of file has been used.
+        // in any case I believe this constructor only gets used with single part files
+        // and 'version' currently only tracks multipart state, so setting to 0 (not multipart) works for us
+        //
+
+        _data->version=0;
+        readLineOffsets (*_streamData->is,
+                        _data->lineOrder,
+                        _data->lineOffsets,
+                        _data->fileIsComplete);
+    }
+    catch(...)
+    {
+        if(_data)
+        {
+           if (!_data->memoryMapped)
+           {
+              for (size_t i = 0; i < _data->lineBuffers.size(); i++)
+              {
+                 if( _data->lineBuffers[i] )
+                 {
+                   EXRFreeAligned(_data->lineBuffers[i]->buffer);
+                   _data->lineBuffers[i]->buffer=NULL;
+                 }
+              }
+           }
+        }
+        delete _streamData;
+        delete _data;
+        throw;
+    }
 }
 
 
@@ -1417,6 +1457,14 @@ ScanLineInputFile::setFrameBuffer (const
                       offset+=2;
                       break;
               }
+
+              //
+              // optimization mode cannot currently skip subsampled channels
+              //
+              if (i.channel().xSampling!=1 || i.channel().ySampling!=1)
+              {
+                  optimizationPossible = false;
+              }
               ++i;
 	}
 
Index: openexr-2.1.0/IlmImf/ImfTiledInputFile.cpp
===================================================================
--- openexr-2.1.0.orig/IlmImf/ImfTiledInputFile.cpp	2013-07-19 19:21:01.000000000 +0200
+++ openexr-2.1.0/IlmImf/ImfTiledInputFile.cpp	2020-04-21 15:26:48.152052148 +0200
@@ -703,61 +703,56 @@ TiledInputFile::TiledInputFile (const ch
     IStream* is = 0;
     try
     {
-        is = new StdIFStream (fileName);
-	readMagicNumberAndVersionField(*is, _data->version);
-
-	//
-        // Backward compatibility to read multpart file.
-        //
-	if (isMultiPart(_data->version))
-	{
-	    compatibilityInitialize(*is);
-	    return;
-	}
-
-	_data->_streamData = new InputStreamMutex();
-	_data->_streamData->is = is;
-	_data->header.readFrom (*_data->_streamData->is, _data->version);
-	initialize();
-        //read tile offsets - we are not multipart or deep
-        _data->tileOffsets.readFrom (*(_data->_streamData->is), _data->fileIsComplete,false,false);
-	_data->_streamData->currentPosition = _data->_streamData->is->tellg();
-    }
-    catch (IEX_NAMESPACE::BaseExc &e)
-    {
-        if (_data->_streamData != 0)
+        try
         {
-            if (_data->_streamData->is != 0)
+            is = new StdIFStream (fileName);
+            readMagicNumberAndVersionField(*is, _data->version);
+
+            //
+            // Backward compatibility to read multpart file.
+            //
+            if (isMultiPart(_data->version))
             {
-                delete _data->_streamData->is;
-                _data->_streamData->is = is = 0;
+                compatibilityInitialize(*is);
+                return;
             }
 
-            delete _data->_streamData;
+            _data->_streamData = new InputStreamMutex();
+            _data->_streamData->is = is;
+            _data->header.readFrom (*_data->_streamData->is, _data->version);
+            initialize();
+            //read tile offsets - we are not multipart or deep
+            _data->tileOffsets.readFrom (*(_data->_streamData->is), _data->fileIsComplete,false,false);
+            _data->_streamData->currentPosition = _data->_streamData->is->tellg();
+        }
+        catch (IEX_NAMESPACE::BaseExc &e)
+        {
+            REPLACE_EXC (e, "Cannot open image file "
+                    "\"" << fileName << "\". " << e.what());
+            throw;
         }
-
-        if (is != 0)
-            delete is;
-
-	REPLACE_EXC (e, "Cannot open image file "
-			"\"" << fileName << "\". " << e);
-	throw;
     }
     catch (...)
     {
-        if ( _data->_streamData != 0)
+        if (!_data->memoryMapped)
         {
-            if ( _data->_streamData->is != 0)
+            for (size_t i = 0; i < _data->tileBuffers.size(); i++)
             {
-                delete _data->_streamData->is;
-                _data->_streamData->is = is = 0;
+                if(_data->tileBuffers[i])
+                {
+                   delete [] _data->tileBuffers[i]->buffer;
+                }
             }
-
+        }
+        if ( _data->_streamData != 0)
+        {
+            delete _data->_streamData->is;
+            _data->_streamData->is = is = 0;
             delete _data->_streamData;
         }
 
-        if (is != 0)
-            delete is;
+        delete is;
+        delete _data;
         throw;
     }
 }
@@ -776,38 +771,45 @@ TiledInputFile::TiledInputFile (OPENEXR_
 
     try
     {
-	readMagicNumberAndVersionField(is, _data->version);
+        try
+        {
+            readMagicNumberAndVersionField(is, _data->version);
 
-	//
-	// Backward compatibility to read multpart file.
-	//
-	if (isMultiPart(_data->version))
-        {
-	    compatibilityInitialize(is);
-            return;
-        }
-
-	streamDataCreated = true;
-	_data->_streamData = new InputStreamMutex();
-	_data->_streamData->is = &is;
-	_data->header.readFrom (*_data->_streamData->is, _data->version);
-	initialize();
-        // file is guaranteed to be single part, regular image
-        _data->tileOffsets.readFrom (*(_data->_streamData->is), _data->fileIsComplete,false,false);
-	_data->memoryMapped = _data->_streamData->is->isMemoryMapped();
-	_data->_streamData->currentPosition = _data->_streamData->is->tellg();
-    }
-    catch (IEX_NAMESPACE::BaseExc &e)
-    {
-        if (streamDataCreated) delete _data->_streamData;
-	delete _data;
+            //
+            // Backward compatibility to read multpart file.
+            //
+            if (isMultiPart(_data->version))
+            {
+                compatibilityInitialize(is);
+                return;
+            }
 
-	REPLACE_EXC (e, "Cannot open image file "
-			"\"" << is.fileName() << "\". " << e);
-	throw;
+            streamDataCreated = true;
+            _data->_streamData = new InputStreamMutex();
+            _data->_streamData->is = &is;
+            _data->header.readFrom (*_data->_streamData->is, _data->version);
+            initialize();
+            // file is guaranteed to be single part, regular image
+            _data->tileOffsets.readFrom (*(_data->_streamData->is), _data->fileIsComplete,false,false);
+            _data->memoryMapped = _data->_streamData->is->isMemoryMapped();
+            _data->_streamData->currentPosition = _data->_streamData->is->tellg();
+        }
+        catch (IEX_NAMESPACE::BaseExc &e)
+        {
+            REPLACE_EXC (e, "Cannot open image file "
+                    "\"" << is.fileName() << "\". " << e.what());
+            throw;
+        }
     }
     catch (...)
     {
+        if (!_data->memoryMapped)
+        {
+            for (size_t i = 0; i < _data->tileBuffers.size(); i++)
+            {
+                delete [] _data->tileBuffers[i]->buffer;
+            }
+        }
         if (streamDataCreated) delete _data->_streamData;
 	delete _data;
         throw;
@@ -831,13 +833,29 @@ TiledInputFile::TiledInputFile (const He
     // we have somehow got the header.
     //
 
-    _data->_streamData->is = is;
-    _data->header = header;
-    _data->version = version;
-    initialize();
-    _data->tileOffsets.readFrom (*(_data->_streamData->is),_data->fileIsComplete,false,false);
-    _data->memoryMapped = is->isMemoryMapped();
-    _data->_streamData->currentPosition = _data->_streamData->is->tellg();
+    try
+    {
+        _data->_streamData->is = is;
+        _data->header = header;
+        _data->version = version;
+        initialize();
+        _data->tileOffsets.readFrom (*(_data->_streamData->is),_data->fileIsComplete,false,false);
+        _data->memoryMapped = is->isMemoryMapped();
+        _data->_streamData->currentPosition = _data->_streamData->is->tellg();
+    }
+    catch(...)
+    {
+        if (!_data->memoryMapped)
+        {
+            for (size_t i = 0; i < _data->tileBuffers.size(); i++)
+            {
+                delete [] _data->tileBuffers[i]->buffer;
+            }
+        }
+        delete _data->_streamData;
+	delete _data;
+        throw;
+    }
 }
 
 
@@ -845,7 +863,15 @@ TiledInputFile::TiledInputFile (InputPar
 {
     _data = new Data (part->numThreads);
     _data->_deleteStream=false;
-    multiPartInitialize(part);
+    try
+    {
+      multiPartInitialize(part);
+    }
+    catch(...)
+    {
+        if (_data) delete _data;
+        throw;
+    }
 }
 
 
Index: openexr-2.1.0/IlmImf/ImfTiledMisc.cpp
===================================================================
--- openexr-2.1.0.orig/IlmImf/ImfTiledMisc.cpp	2013-06-18 21:51:39.000000000 +0200
+++ openexr-2.1.0/IlmImf/ImfTiledMisc.cpp	2020-04-21 15:53:48.100716478 +0200
@@ -39,6 +39,8 @@
 //
 //-----------------------------------------------------------------------------
 
+#include <limits>
+
 #include <ImfTiledMisc.h>
 #include "Iex.h"
 #include <ImfMisc.h>
@@ -362,26 +364,50 @@ getTiledChunkOffsetTableSize(const Heade
     //
     int lineOffsetSize = 0;
     const TileDescription &desc = header.tileDescription();
-    switch (desc.mode)
+    try
     {
-        case ONE_LEVEL:
-        case MIPMAP_LEVELS:
-            for (int i = 0; i < numXLevels; i++)
-                lineOffsetSize += numXTiles[i] * numYTiles[i];
+        switch (desc.mode)
+        {
+            case ONE_LEVEL:
+            case MIPMAP_LEVELS:
+                for (int i = 0; i < numXLevels; i++)
+                {
+                    lineOffsetSize += static_cast<Int64>(numXTiles[i]) * static_cast<Int64>(numYTiles[i]);
+                    if ( lineOffsetSize > static_cast<Int64>(std::numeric_limits<int>::max()) )
+                    {
+                        throw IEX_NAMESPACE::LogicExc("Maximum number of tiles exceeded");
+                    }
+                }
             break;
-        case RIPMAP_LEVELS:
-            for (int i = 0; i < numXLevels; i++)
-                for (int j = 0; j < numYLevels; j++)
-                    lineOffsetSize += numXTiles[i] * numYTiles[j];
+            case RIPMAP_LEVELS:
+                for (int i = 0; i < numXLevels; i++)
+                {
+                    for (int j = 0; j < numYLevels; j++)
+                    {
+                        lineOffsetSize += static_cast<Int64>(numXTiles[i]) * static_cast<Int64>(numYTiles[j]);
+                        if ( lineOffsetSize > static_cast<Int64>(std::numeric_limits<int>::max()) )
+                        {
+                            throw IEX_NAMESPACE::LogicExc("Maximum number of tiles exceeded");
+                        }
+                    }
+                }
             break;
-        case NUM_LEVELMODES :
-            throw IEX_NAMESPACE::LogicExc("Bad level mode getting chunk offset table size");
-    }
+            case NUM_LEVELMODES :
+                throw IEX_NAMESPACE::LogicExc("Bad level mode getting chunk offset table size");
+        }
+        delete[] numXTiles;
+        delete[] numYTiles;
+
+        return static_cast<int>(lineOffsetSize);
 
-    delete[] numXTiles;
-    delete[] numYTiles;
+    }
+    catch(...)
+    {
+        delete[] numXTiles;
+        delete[] numYTiles;
 
-    return lineOffsetSize;
+        throw;
+    }
 }
 
 
Index: openexr-2.1.0/IlmImfTest/testMultiPartApi.cpp
===================================================================
--- openexr-2.1.0.orig/IlmImfTest/testMultiPartApi.cpp	2013-11-12 00:09:52.000000000 +0100
+++ openexr-2.1.0/IlmImfTest/testMultiPartApi.cpp	2020-04-21 15:26:48.152052148 +0200
@@ -459,6 +459,21 @@ generateRandomFile (int partCount, const
         }
     }
 
+    for (size_t i = 0 ; i < parts.size() ; ++i )
+    {
+        int partType = partTypes[i];
+
+        if (partType == 0)
+        {
+            delete (OutputPart*) parts[i];
+        }
+        else
+        {
+            delete (TiledOutputPart*) parts[i];
+        }
+
+    }
+
     delete[] tiledHalfData;
     delete[] tiledUintData;
     delete[] tiledFloatData;
Index: openexr-2.1.0/IlmImfTest/testMultiPartThreading.cpp
===================================================================
--- openexr-2.1.0.orig/IlmImfTest/testMultiPartThreading.cpp	2013-11-12 00:09:52.000000000 +0100
+++ openexr-2.1.0/IlmImfTest/testMultiPartThreading.cpp	2020-04-21 15:26:48.152052148 +0200
@@ -622,6 +622,18 @@ generateRandomFile (int partCount, const
         }
     }
 
+    for (int i = 0; i < partCount; i++)
+    {
+        if (partTypes[i] == 0)
+        {
+            delete (OutputPart*) parts[i];
+        }
+        else
+        {
+            delete (TiledOutputPart*) parts[i];
+        }
+    }
+
     delete threadPool;
 
     delete[] tiledHalfData;
Index: openexr-2.1.0/exrmakepreview/makePreview.cpp
===================================================================
--- openexr-2.1.0.orig/exrmakepreview/makePreview.cpp	2020-04-21 15:26:48.116051955 +0200
+++ openexr-2.1.0/exrmakepreview/makePreview.cpp	2020-04-21 15:26:48.152052148 +0200
@@ -123,8 +123,8 @@ generatePreview (const char inFileName[]
     previewHeight = max (int (h / (w * a) * previewWidth + .5f), 1);
     previewPixels.resizeErase (previewHeight, previewWidth);
 
-    float fx = (previewWidth  > 0)? (float (w - 1) / (previewWidth  - 1)): 1;
-    float fy = (previewHeight > 0)? (float (h - 1) / (previewHeight - 1)): 1;
+    double fx = (previewWidth  > 0)? (double (w - 1) / (previewWidth  - 1)): 1;
+    double fy = (previewHeight > 0)? (double (h - 1) / (previewHeight - 1)): 1;
     float m  = Math<float>::pow (2.f, clamp (exposure + 2.47393f, -20.f, 20.f));
 
     for (int y = 0; y < previewHeight; ++y)
