diff --git a/CHANGES.md b/CHANGES.md index bd30bf38d0..0d1d6cc4b8 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,6 +1,7 @@ # OpenEXR Release Notes -* [Version 2.4.0](#version-240-tbd) +* [Version 2.4.1](#version-241-february-11-2020) +* [Version 2.4.0](#version-240-september-19-2019) * [Version 2.3.0](#version-230-august-13-2018) * [Version 2.2.1](#version-221-november-30-2017) * [Version 2.2.0](#version-220-august-10-2014) @@ -30,7 +31,68 @@ * [Version 1.0.1](#version-101) * [Version 1.0](#version-10) -## Version 2.4.0 +## Version 2.4.1 (February 11, 2020) + +Patch release with minor bug fixes. + +### Summary + +* Various fixes for memory leaks and invalid memory accesses +* Various fixes for integer overflow with large images. +* Various cmake fixes for build/install of python modules. +* ImfMisc.h is no longer installed, since it's a private header. + +### Merged Pull Requests + +* [659](https://github.com/AcademySoftwareFoundation/openexr/pull/659) fix memory leaks and invalid memory accesses + +* [609](https://github.com/AcademySoftwareFoundation/openexr/pull/609) Fixes #593, others - issues with pyilmbase install + +* [605](https://github.com/AcademySoftwareFoundation/openexr/pull/605) No longer install ImfMisc.h + +* [603](https://github.com/openexr/openexr/pull/603) Update Azure build to work with new RB-2.4 branch. + +* [596](https://github.com/AcademySoftwareFoundation/openexr/pull/596) Add Boost::Python to Python modules link libraries + +* [592](https://github.com/AcademySoftwareFoundation/openexr/pull/592) Take DESTDIR into account when creating library symlinks + +* [589](https://github.com/openexr/openexr/pull/589) Fix int32 overflow bugs with deep images + +### Commits \[ git log v2.4.0...v2.4.1\] + +* [fix memory leaks and invalid memory accesses](https://github.com/AcademySoftwareFoundation/openexr/commit/e79d2296496a50826a15c667bf92bdc5a05518b4) ([Peter Hillman](@peterh@wetafx.co.nz) 2020-02-08) + +* [Fix overzealous removal of if statements breaking all builds except win32](https://github.com/openexr/openexr/commit/031199cd4fc062dd7bfe902c6552cf22f6bfbbdb) ([Kimball Thurston](@kdt3rd@gmail.com) 2019-11-07) + +* [Handle python2 not being installed, but python3 being present](https://github.com/openexr/openexr/commit/8228578da6f86d17b9a2a3f8c6053f8b4ee3fb71) ([Kimball Thurston](@kdt3rd@gmail.com) 2019-11-07) + +* [Fix issue with defines not being set correctly for win32](https://github.com/openexr/openexr/commit/d10895ef0ad25dd60e68a2ab00bab7c0592f8c5b) ([Kimball Thurston](@kdt3rd@gmail.com) 2019-11-07) + +* [Re-enable Boost_NO_BOOST_CMAKE by default, document, clean up status messages](https://github.com/openexr/openexr/commit/b303f6788a434fd61e52c1bacb93a96c4c3440ea) ([Kimball Thurston](@kdt3rd@gmail.com) 2019-11-07) + +* [Set CMP0074 such that people who set Boost_ROOT won't get warnings](https://github.com/openexr/openexr/commit/8ec1440cbd999f17457be605150bc53395fbb334) ([Kimball Thurston](@kdt3rd@gmail.com) 2019-11-07) + +* [ensure paths are canonicalized by get_filename_component prior to comparing](https://github.com/openexr/openexr/commit/28d1cb256f1b46f120adb131e606b2699acc72d7) ([Kimball Thurston](@kdt3rd@gmail.com) 2019-11-07) + +* [Fix issue with drive letter under windows](https://github.com/openexr/openexr/commit/34ce16c2653d02fcef6a297a2a61112dbf693922) ([Kimball Thurston](@kdt3rd@gmail.com) 2019-11-06) + +* [Extract to function, protect against infinite loop](https://github.com/openexr/openexr/commit/650da0d63410d863c4a0aed15a6bee1b46b559cb) ([Kimball Thurston](@kdt3rd@gmail.com) 2019-11-06) + +* [Fixes #593, others - issues with pyilmbase install](https://github.com/openexr/openexr/commit/df768ec8a97adb82947fc4b92a199db9a38c044c) ([Kimball Thurston](@kdt3rd@gmail.com) 2019-11-05) + +* [Take DESTDIR into account when creating library symlinks](https://github.com/openexr/openexr/commit/ed4807b9e4dc8d94ce79d0b2ed36acc548bee57e) ([Antonio Rojas](@arojas@archlinux.org) 2019-10-19) + +* [No longer install ImfMisc.h](https://github.com/openexr/openexr/commit/f1b017c8029b529c5c5ed01b6ad1b10a0e48036c) ([Cary Phillips](@cary@ilm.com) 2019-10-31) + +* [add boost to python module link library](https://github.com/openexr/openexr/commit/a571bdfe42866a1f1c579114e2fcae8318172c21) ([Jens Lindgren](@lindgren_jens@hotmail.com) 2019-10-22) + +* [Update Azure build to work with new branch.](https://github.com/openexr/openexr/commit/4273e84f86fe27392dec53a5cef900caf6727154) ([Christina Tempelaar-Lietz](@xlietz@gmail.com) 2019-10-26) + +* [Fix int32 overflow bugs with deep images](https://github.com/openexr/openexr/commit/e53ebd3ef677ab983f83f927f6525efcb5dcb995) ([Larry Gritz](@lg@larrygritz.com) 2019-10-17) + +* [Prepare 2.4 release branch](https://github.com/openexr/openexr/commit/486ff10547d034530c5190bbef6181324b42c209) ([Larry Gritz](@lg@larrygritz.com) 2019-10-24) + +## Version 2.4.0 (September 19, 2019) ### Summary diff --git a/OpenEXR/IlmImf/ImfInputFile.cpp b/OpenEXR/IlmImf/ImfInputFile.cpp index 106cb6ecbc..8695c65bf9 100644 --- a/OpenEXR/IlmImf/ImfInputFile.cpp +++ b/OpenEXR/IlmImf/ImfInputFile.cpp @@ -480,7 +480,15 @@ InputFile::InputFile (InputPartData* part) : _data (new Data (part->numThreads)) { _data->_deleteStream=false; - multiPartInitialize (part); + try + { + multiPartInitialize (part); + } + catch(...) + { + delete _data; + throw; + } } diff --git a/OpenEXR/IlmImf/ImfScanLineInputFile.cpp b/OpenEXR/IlmImf/ImfScanLineInputFile.cpp index 5656c45d3e..1ef4eba3f4 100644 --- a/OpenEXR/IlmImf/ImfScanLineInputFile.cpp +++ b/OpenEXR/IlmImf/ImfScanLineInputFile.cpp @@ -1181,8 +1181,11 @@ ScanLineInputFile::ScanLineInputFile(InputPartData* part) { for (size_t i = 0; i < _data->lineBuffers.size(); i++) { - EXRFreeAligned(_data->lineBuffers[i]->buffer); - _data->lineBuffers[i]->buffer=nullptr; + if( _data->lineBuffers[i] ) + { + EXRFreeAligned(_data->lineBuffers[i]->buffer); + _data->lineBuffers[i]->buffer=nullptr; + } } } @@ -1234,11 +1237,14 @@ ScanLineInputFile::ScanLineInputFile { if (!_data->memoryMapped) { - for (size_t i = 0; i < _data->lineBuffers.size(); i++) - { - EXRFreeAligned(_data->lineBuffers[i]->buffer); - _data->lineBuffers[i]->buffer=nullptr; - } + for (size_t i = 0; i < _data->lineBuffers.size(); i++) + { + if( _data->lineBuffers[i] ) + { + EXRFreeAligned(_data->lineBuffers[i]->buffer); + _data->lineBuffers[i]->buffer=nullptr; + } + } } } delete _streamData; diff --git a/OpenEXR/IlmImf/ImfTiledMisc.cpp b/OpenEXR/IlmImf/ImfTiledMisc.cpp index d262f7347a..8552ada207 100644 --- a/OpenEXR/IlmImf/ImfTiledMisc.cpp +++ b/OpenEXR/IlmImf/ImfTiledMisc.cpp @@ -363,40 +363,51 @@ getTiledChunkOffsetTableSize(const Header& header) // Int64 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 += static_cast(numXTiles[i]) * static_cast(numYTiles[i]); - if ( lineOffsetSize > static_cast(std::numeric_limits::max()) ) + switch (desc.mode) + { + case ONE_LEVEL: + case MIPMAP_LEVELS: + for (int i = 0; i < numXLevels; i++) { - throw IEX_NAMESPACE::LogicExc("Maximum number of tiles exceeded"); + lineOffsetSize += static_cast(numXTiles[i]) * static_cast(numYTiles[i]); + if ( lineOffsetSize > static_cast(std::numeric_limits::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++) + break; + case RIPMAP_LEVELS: + for (int i = 0; i < numXLevels; i++) { - lineOffsetSize += static_cast(numXTiles[i]) * static_cast(numYTiles[j]); - if ( lineOffsetSize > static_cast(std::numeric_limits::max()) ) - { - throw IEX_NAMESPACE::LogicExc("Maximum number of tiles exceeded"); - } + for (int j = 0; j < numYLevels; j++) + { + lineOffsetSize += static_cast(numXTiles[i]) * static_cast(numYTiles[j]); + if ( lineOffsetSize > static_cast(std::numeric_limits::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"); + break; + case NUM_LEVELMODES : + throw IEX_NAMESPACE::LogicExc("Bad level mode getting chunk offset table size"); + } + delete[] numXTiles; + delete[] numYTiles; + + return static_cast(lineOffsetSize); + } + catch(...) + { + delete[] numXTiles; + delete[] numYTiles; - delete[] numXTiles; - delete[] numYTiles; + throw; + } - return static_cast(lineOffsetSize); } diff --git a/OpenEXR/IlmImfFuzzTest/main.cpp b/OpenEXR/IlmImfFuzzTest/main.cpp index 0b7342f1e9..19ad55efc2 100644 --- a/OpenEXR/IlmImfFuzzTest/main.cpp +++ b/OpenEXR/IlmImfFuzzTest/main.cpp @@ -46,36 +46,82 @@ #include #include +#include #include +#include #ifdef OPENEXR_IMF_HAVE_LINUX_PROCFS #include #include #endif -#define TEST(x) if (argc < 2 || !strcmp (argv[1], #x)) x(); + +using std::set; +using std::string; +using std::cout; +using std::endl; + +#define TEST(x) if (helpMode) tests.insert(string(#x)); else if (argc < 2 || !strcmp (argv[1], #x)) x(argc==3 ? argv[2] : nullptr); int main (int argc, char *argv[]) { + bool helpMode = false; + if( argc==2 && (strcmp(argv[1],"--help")==0 || strcmp(argv[1],"-h")==0)) + { + helpMode = true; + } + set tests; + + TEST (testFuzzScanLines); TEST (testFuzzTiles); TEST (testFuzzDeepScanLines); TEST (testFuzzDeepTiles); - + + + if(helpMode) + { + cout << "IlmImfFuzzTest tests how resilient the IlmImf library is with\n" + "respect to broken input files: the program first damages\n" + "OpenEXR files by partially overwriting them with random data;\n" + "then it tries to read the damaged files. If all goes well,\n" + "then the program doesn't crash.\n"; + cout << "\n"; + cout << "If IlmImfFuzzTest does crash, it will leave a file in the current\n" + "directory, or /var/tmp. Running 'IlmImfFuzzTest test file' will\n" + "usually quickly reproduce the issue by attempting to reload the file,\n" + "(without running the normal tests) and is useful for debugging\n" + "the exact cause of the crash or confirming a bug is fixed.\n"; + cout << "\n"; + cout << "usage:\n"; + cout << " IlmImfFuzzTest : with no arguments, run all tests\n"; + cout << " IlmImfFuzzTest TEST : run specific TEST only\n"; + cout << " IlmImfFuzzTest TEST file : try to read 'file' with given TEST\n"; + cout << "\n"; + cout << "TEST can be one of the following:\n"; + for ( auto i = tests.begin() ; i!= tests.end() ; ++i ) + { + cout << ' ' << *i << endl; + } + + } + else + { + #ifdef OPENEXR_IMF_HAVE_LINUX_PROCFS // // Allow the user to check for file descriptor leaks // - std::cout << "open file descriptors:" << std::endl; + cout << "open file descriptors:" << endl; std::stringstream ss; ss << "ls -lG /proc/" << getpid() << "/fd"; system (ss.str().c_str()); #endif - + } return 0; } diff --git a/OpenEXR/IlmImfFuzzTest/testFuzzDeepScanLines.cpp b/OpenEXR/IlmImfFuzzTest/testFuzzDeepScanLines.cpp index 945ffacc52..6c92d28f3f 100644 --- a/OpenEXR/IlmImfFuzzTest/testFuzzDeepScanLines.cpp +++ b/OpenEXR/IlmImfFuzzTest/testFuzzDeepScanLines.cpp @@ -408,21 +408,29 @@ fuzzDeepScanLines (int numThreads, Rand48 &random) void -testFuzzDeepScanLines () +testFuzzDeepScanLines (const char* file) { try { - cout << "Testing deep scanline-based files " - "with randomly inserted errors" << endl; + if(file) + { + readFile(file); + } + else + { - Rand48 random (1); + cout << "Testing deep scanline-based files " + "with randomly inserted errors" << endl; - fuzzDeepScanLines (0, random); + Rand48 random (1); - if (ILMTHREAD_NAMESPACE::supportsThreads()) - fuzzDeepScanLines (2, random); + fuzzDeepScanLines (0, random); - cout << "ok\n" << endl; + if (ILMTHREAD_NAMESPACE::supportsThreads()) + fuzzDeepScanLines (2, random); + + cout << "ok\n" << endl; + } } catch (const std::exception &e) { diff --git a/OpenEXR/IlmImfFuzzTest/testFuzzDeepScanLines.h b/OpenEXR/IlmImfFuzzTest/testFuzzDeepScanLines.h index 9619589904..b663992838 100644 --- a/OpenEXR/IlmImfFuzzTest/testFuzzDeepScanLines.h +++ b/OpenEXR/IlmImfFuzzTest/testFuzzDeepScanLines.h @@ -35,5 +35,5 @@ -void testFuzzDeepScanLines (); +void testFuzzDeepScanLines (const char* file); diff --git a/OpenEXR/IlmImfFuzzTest/testFuzzDeepTiles.cpp b/OpenEXR/IlmImfFuzzTest/testFuzzDeepTiles.cpp index 835008ef72..0f46d65eab 100644 --- a/OpenEXR/IlmImfFuzzTest/testFuzzDeepTiles.cpp +++ b/OpenEXR/IlmImfFuzzTest/testFuzzDeepTiles.cpp @@ -219,7 +219,7 @@ void generateRandomFile(const char filename[], int channelCount, int parts , Com { for(int x=0;x( data[k][y][x] ); + delete [] reinterpret_cast( data[k][y][x] ); data[k][y][x]=0; } } @@ -503,23 +503,30 @@ fuzzDeepTiles (int numThreads, Rand48 &random) void -testFuzzDeepTiles () +testFuzzDeepTiles (const char* file) { try { - cout << "Testing deep tile-based files " - "with randomly inserted errors" << endl; + if(file) + { + readFile(file); + } + else + { + cout << "Testing deep tile-based files " + "with randomly inserted errors" << endl; - Rand48 random (1); + Rand48 random (1); - fuzzDeepTiles (0, random); + fuzzDeepTiles (0, random); - if (ILMTHREAD_NAMESPACE::supportsThreads()) - fuzzDeepTiles (2, random); + if (ILMTHREAD_NAMESPACE::supportsThreads()) + fuzzDeepTiles (2, random); - cout << "ok\n" << endl; + cout << "ok\n" << endl; + } } catch (const std::exception &e) { diff --git a/OpenEXR/IlmImfFuzzTest/testFuzzDeepTiles.h b/OpenEXR/IlmImfFuzzTest/testFuzzDeepTiles.h index ffb4a4aeb0..83baf2af9b 100644 --- a/OpenEXR/IlmImfFuzzTest/testFuzzDeepTiles.h +++ b/OpenEXR/IlmImfFuzzTest/testFuzzDeepTiles.h @@ -35,5 +35,5 @@ -void testFuzzDeepTiles (); +void testFuzzDeepTiles (const char* file); diff --git a/OpenEXR/IlmImfFuzzTest/testFuzzScanLines.cpp b/OpenEXR/IlmImfFuzzTest/testFuzzScanLines.cpp index c5de62231d..4ba56153d6 100644 --- a/OpenEXR/IlmImfFuzzTest/testFuzzScanLines.cpp +++ b/OpenEXR/IlmImfFuzzTest/testFuzzScanLines.cpp @@ -252,21 +252,28 @@ fuzzScanLines (int numThreads, Rand48 &random) void -testFuzzScanLines () +testFuzzScanLines (const char* file) { try { - cout << "Testing scanline-based files " - "with randomly inserted errors" << endl; + if(file) + { + readImage(file); + } + else + { + cout << "Testing scanline-based files " + "with randomly inserted errors" << endl; - Rand48 random (1); + Rand48 random (1); - fuzzScanLines (0, random); + fuzzScanLines (0, random); - if (ILMTHREAD_NAMESPACE::supportsThreads()) - fuzzScanLines (2, random); + if (ILMTHREAD_NAMESPACE::supportsThreads()) + fuzzScanLines (2, random); - cout << "ok\n" << endl; + cout << "ok\n" << endl; + } } catch (const std::exception &e) { diff --git a/OpenEXR/IlmImfFuzzTest/testFuzzScanLines.h b/OpenEXR/IlmImfFuzzTest/testFuzzScanLines.h index 71838b9842..615a6e5862 100644 --- a/OpenEXR/IlmImfFuzzTest/testFuzzScanLines.h +++ b/OpenEXR/IlmImfFuzzTest/testFuzzScanLines.h @@ -35,5 +35,5 @@ -void testFuzzScanLines (); +void testFuzzScanLines (const char* file); diff --git a/OpenEXR/IlmImfFuzzTest/testFuzzTiles.cpp b/OpenEXR/IlmImfFuzzTest/testFuzzTiles.cpp index a48a11a4a4..720b2e9032 100644 --- a/OpenEXR/IlmImfFuzzTest/testFuzzTiles.cpp +++ b/OpenEXR/IlmImfFuzzTest/testFuzzTiles.cpp @@ -406,21 +406,30 @@ fuzzTiles (int numThreads, Rand48 &random) void -testFuzzTiles () +testFuzzTiles (const char* file) { try { - cout << "Testing tile-based files " - "with randomly inserted errors" << endl; + if(file) + { + readImageONE(file); + readImageMIP(file); + readImageRIP(file); + } + else + { + cout << "Testing tile-based files " + "with randomly inserted errors" << endl; - Rand48 random (5); + Rand48 random (5); - fuzzTiles (0, random); + fuzzTiles (0, random); - if (ILMTHREAD_NAMESPACE::supportsThreads()) - fuzzTiles (2, random); + if (ILMTHREAD_NAMESPACE::supportsThreads()) + fuzzTiles (2, random); - cout << "ok\n" << endl; + cout << "ok\n" << endl; + } } catch (const std::exception &e) { diff --git a/OpenEXR/IlmImfFuzzTest/testFuzzTiles.h b/OpenEXR/IlmImfFuzzTest/testFuzzTiles.h index 12f3bddfb1..1136588ca4 100644 --- a/OpenEXR/IlmImfFuzzTest/testFuzzTiles.h +++ b/OpenEXR/IlmImfFuzzTest/testFuzzTiles.h @@ -35,5 +35,5 @@ -void testFuzzTiles (); +void testFuzzTiles (const char* file); diff --git a/OpenEXR/IlmImfTest/main.cpp b/OpenEXR/IlmImfTest/main.cpp index 26d1ccf9e5..3245fc4812 100644 --- a/OpenEXR/IlmImfTest/main.cpp +++ b/OpenEXR/IlmImfTest/main.cpp @@ -107,6 +107,8 @@ #include #include +#include + #ifdef _WIN32 # include #else @@ -118,22 +120,23 @@ using namespace std; #define TEST_STRING(x) #x #define TEST(x,y) \ - if (argc < 2 || (!strcmp (argv[1], TEST_STRING(x)) || !strcmp (argv[1], y))) \ + if (helpMode)\ + {\ + tests.insert(string(TEST_STRING(x)));\ + suites.insert(string(y));\ + }\ + else if (argc < 2 || (!strcmp (argv[1], TEST_STRING(x)) || !strcmp (argv[1], y))) \ { \ cout << "\n=======\nRunning " << TEST_STRING(x) < 4095) { cerr << "Cannot retrieve temporary directory" << endl; - return 1; + exit(1); } tempDir = tmpbuf; // windows does this automatically @@ -168,10 +171,37 @@ main (int argc, char *argv[]) { std::cerr << "ERROR -- mkdir(" << tempDir << ") failed: " "errno = " << errno << std::endl; - return 1; + exit(1); } } + return tempDir; + +} + +int +main (int argc, char *argv[]) +{ + // Create temporary files in a uniquely named private temporary + // subdirectory of IMF_TMP_DIR to avoid colliding with other + // running instances of this program. + + std::string tempDir; + + bool helpMode = false; + if( argc==2 && (strcmp(argv[1],"--help")==0 || strcmp(argv[1],"-h")==0)) + { + helpMode = true; + } + set tests; + set suites; + + + if ( !helpMode ) + { + tempDir = makeTempDir(); + } + TEST (testMagic, "core"); TEST (testXdr, "core"); TEST (testHuf, "core"); @@ -235,8 +265,43 @@ main (int argc, char *argv[]) #endif - std::cout << "removing temp dir " << tempDir << std::endl; - rmdir (tempDir.c_str()); + if ( helpMode ) + { + cout << "IlmImfTest runs a series of tests to confirm\n" + "correct behavior of the IlmImf OpenEXR library.\n" + "If all is correct, IlmImfTest will complete without\n" + "crashing or leaking memory.\n"; + cout << "\n"; + cout << "If a test fails, an individual test can be re-run, avoiding\n" + "the wait for previous tests to complete. This allows easier debugging\n" + "of the failure.\n"; + cout << "\n"; + cout << "A 'suite' of tests can also be run, to allow a subset of\n" + << "tests to run. This is useful as an initial confirmation\n" + << "that a modification to the library has not introduced an error.\n" + << "Suites can be run in parallel for speed. Every test is in one suite.\n"; + cout << "\n"; + cout << "usage:\n" + << "IlmImfTest : with no arguments, run all tests\n" + << "IlmImfTest TEST : run only specific test, then quit\n" + << "IlmImfTest SUITE : run all the tests in the given SUITE\n"; + cout << "\n"; + cout << "available TESTs:\n"; + for ( auto i = tests.begin() ; i!= tests.end() ; ++i) + { + cout << ' ' << *i << endl; + } + cout << "\n"; + cout << "available SUITEs:\n"; + for ( auto i = suites.begin() ; i!= suites.end() ; ++i ) + { + cout << ' ' << *i << endl; + } + } + else + { + cout << "removing temp dir " << tempDir << endl; + rmdir (tempDir.c_str()); #ifdef OPENEXR_IMF_HAVE_LINUX_PROCFS @@ -244,19 +309,19 @@ main (int argc, char *argv[]) // Allow the user to check for file descriptor leaks // - std::cout << "open file descriptors:" << std::endl; + cout << "open file descriptors:" << endl; - std::stringstream ss; + stringstream ss; ss << "ls -lG /proc/" << getpid() << "/fd"; if (system (ss.str().c_str()) == -1) { - std::cout << "failed to run ls\n"; + cout << "failed to run ls\n"; } - std::cout << std::endl; + cout << endl; #endif - + } return 0; } diff --git a/OpenEXR_Viewers/exrdisplay/main.cpp b/OpenEXR_Viewers/exrdisplay/main.cpp index 46ab71b7ad..7af83b2854 100644 --- a/OpenEXR_Viewers/exrdisplay/main.cpp +++ b/OpenEXR_Viewers/exrdisplay/main.cpp @@ -282,6 +282,11 @@ makeMainWindow (const char imageFile[], Header header; int zsize; + // + // limit maximum size to twice screen resolution + // + Header::setMaxImageSize(Fl::w()*2 , Fl::h()*2); + // //pass 0 as partnum for the first load //