From 0004876e5c088fd56e1e49e5420c5c3eae9b2189 Mon Sep 17 00:00:00 2001 From: Peter Hillman Date: Mon, 15 Mar 2021 18:17:29 +1300 Subject: [PATCH] exrcheck: account for size of pixels when estimating memory Signed-off-by: Peter Hillman --- src/lib/OpenEXRUtil/ImfCheckFile.cpp | 40 +++++++++++++++++----------- 1 file changed, 25 insertions(+), 15 deletions(-) diff --git a/src/lib/OpenEXRUtil/ImfCheckFile.cpp b/src/lib/OpenEXRUtil/ImfCheckFile.cpp index a5ed61f73c..662939b5ae 100644 --- a/src/lib/OpenEXRUtil/ImfCheckFile.cpp +++ b/src/lib/OpenEXRUtil/ImfCheckFile.cpp @@ -15,6 +15,7 @@ #include "ImfStdIO.h" #include "ImfMultiPartInputFile.h" #include "ImfStandardAttributes.h" +#include "ImfTiledMisc.h" #include #include @@ -32,10 +33,10 @@ using IMATH_NAMESPACE::Box2i; // limits for reduceMemory mode // const uint64_t gMaxScanlineWidth= 1000000; -const uint64_t gMaxTilePixelsPerScanline = 8000000; -const uint64_t gMaxTileSize = 1000*1000; -const uint64_t gMaxSamplesPerDeepPixel = 1000; -const uint64_t gMaxSamplesPerScanline = 1<<12; +const uint64_t gMaxTileBytesPerScanline = 8000000; +const uint64_t gMaxTileBytes = 1000*1000; +const uint64_t gMaxBytesPerDeepPixel = 1000; +const uint64_t gMaxBytesPerDeepScanline = 1<<12; // // limits for reduceTime mode @@ -222,8 +223,9 @@ readTileRgba( T& in,bool reduceMemory, bool reduceTime) int w = dw.max.x - dw.min.x + 1; int h = dw.max.y - dw.min.y + 1; + int bytes = calculateBytesPerPixel(in.header()); - if ( (reduceMemory || reduceTime ) && h*w > gMaxTileSize ) + if ( (reduceMemory || reduceTime ) && h*w*bytes > gMaxTileBytes ) { return false; } @@ -262,9 +264,10 @@ readTile(T& in, bool reduceMemory , bool reduceTime) int numYLevels = in.numYLevels(); const TileDescription& td = in.header().tileDescription(); + int bytes = calculateBytesPerPixel(in.header()); - if (reduceMemory && (w > gMaxScanlineWidth || (td.xSize*td.ySize) > gMaxTileSize) ) + if (reduceMemory && (w > gMaxScanlineWidth || (td.xSize*td.ySize*bytes) > gMaxTileBytes) ) { return false; } @@ -364,6 +367,9 @@ bool readDeepScanLine(T& in,bool reduceMemory, bool reduceTime) int w = dw.max.x - dw.min.x + 1; int dwx = dw.min.x; + int bytesPerSample = calculateBytesPerPixel(in.header()); + + if ( reduceMemory && w > gMaxScanlineWidth ) { return false; @@ -425,7 +431,7 @@ bool readDeepScanLine(T& in,bool reduceMemory, bool reduceTime) // // don't read samples which require a lot of memory in reduceMemory mode // - if (!reduceMemory || localSampleCount[j] <= gMaxSamplesPerDeepPixel ) + if (!reduceMemory || localSampleCount[j]*bytesPerSample <= gMaxBytesPerDeepPixel ) { bufferSize += localSampleCount[j]; } @@ -448,7 +454,7 @@ bool readDeepScanLine(T& in,bool reduceMemory, bool reduceTime) for (int k = 0; k < channelCount; k++) { - if (localSampleCount[j]==0 || ( reduceMemory && localSampleCount[j] > gMaxSamplesPerDeepPixel ) ) + if (localSampleCount[j]==0 || ( reduceMemory && localSampleCount[j]*bytesPerSample > gMaxBytesPerDeepPixel ) ) { data[k][j] = nullptr; } @@ -507,6 +513,7 @@ readDeepTile(T& in,bool reduceMemory , bool reduceTime) // uint64_t height = static_cast(dataWindow.size().y)+1; uint64_t width = static_cast(dataWindow.size().x)+1; + int bytesPerSample = calculateBytesPerPixel(in.header()); const TileDescription& td = in.header().tileDescription(); int tileWidth = td.xSize; @@ -614,7 +621,7 @@ readDeepTile(T& in,bool reduceMemory , bool reduceTime) { for (int tx = 0 ; tx < tileWidth ; ++tx ) { - if (!reduceMemory || localSampleCount[ty][tx] < gMaxSamplesPerDeepPixel ) + if (!reduceMemory || localSampleCount[ty][tx]*bytesPerSample < gMaxBytesPerDeepScanline ) { bufferSize += channelCount * localSampleCount[ty][tx]; } @@ -622,7 +629,7 @@ readDeepTile(T& in,bool reduceMemory , bool reduceTime) } // limit total samples allocated for this tile - if (!reduceMemory || bufferSize < gMaxSamplesPerScanline ) + if (!reduceMemory || bufferSize*bytesPerSample < gMaxBytesPerDeepPixel ) { pixelBuffer.resize( bufferSize ); @@ -632,7 +639,7 @@ readDeepTile(T& in,bool reduceMemory , bool reduceTime) { for (int tx = 0 ; tx < tileWidth ; ++tx ) { - if (!reduceMemory || localSampleCount[ty][tx] < gMaxSamplesPerDeepPixel ) + if (!reduceMemory || localSampleCount[ty][tx]*bytesPerSample < gMaxBytesPerDeepPixel ) { for (int k = 0 ; k < channelCount ; ++k ) { @@ -738,6 +745,7 @@ readMultiPart(MultiPartInputFile& in,bool reduceMemory,bool reduceTime) bool widePart = false; bool largeTiles = false; Box2i b = in.header( part ).dataWindow(); + int bytesPerPixel = calculateBytesPerPixel(in.header(part)); uint64_t imageWidth = static_cast(b.max.x) - static_cast(b.min.x) + 1ll; // @@ -763,11 +771,12 @@ readMultiPart(MultiPartInputFile& in,bool reduceMemory,bool reduceTime) uint64_t tilesPerScanline = ( imageWidth + tileDescription.xSize - 1ll) / tileDescription.xSize; uint64_t tileSize = static_cast(tileDescription.xSize) * static_cast(tileDescription.ySize); - if ( tileSize * tilesPerScanline > gMaxTilePixelsPerScanline ) + + if ( tileSize * tilesPerScanline*bytesPerPixel > gMaxTileBytesPerScanline ) { widePart = true; } - if( tileSize > gMaxTileSize) + if( tileSize*bytesPerPixel > gMaxTileBytes) { largeTiles = true; } @@ -1006,12 +1015,13 @@ runChecks(T& source,bool reduceMemory,bool reduceTime) const TileDescription& tileDescription = multi.header(0).tileDescription(); uint64_t tilesPerScanline = ( imageWidth + tileDescription.xSize - 1ll) / tileDescription.xSize; uint64_t tileSize = static_cast(tileDescription.xSize) * static_cast(tileDescription.ySize); - if ( tileSize * tilesPerScanline > gMaxTilePixelsPerScanline ) + int bytesPerPixel = calculateBytesPerPixel(multi.header(0)); + if ( tileSize * tilesPerScanline*bytesPerPixel > gMaxTileBytesPerScanline ) { firstPartWide = true; } - if( tileSize <= gMaxTileSize) + if( tileSize*bytesPerPixel <= gMaxTileBytes) { largeTiles = false; }