Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

exrcheck: account for size of pixels when estimating memory #966

Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 25 additions & 15 deletions src/lib/OpenEXRUtil/ImfCheckFile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include "ImfStdIO.h"
#include "ImfMultiPartInputFile.h"
#include "ImfStandardAttributes.h"
#include "ImfTiledMisc.h"

#include <vector>
#include <algorithm>
Expand All @@ -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
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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];
}
Expand All @@ -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;
}
Expand Down Expand Up @@ -507,6 +513,7 @@ readDeepTile(T& in,bool reduceMemory , bool reduceTime)
//
uint64_t height = static_cast<uint64_t>(dataWindow.size().y)+1;
uint64_t width = static_cast<uint64_t>(dataWindow.size().x)+1;
int bytesPerSample = calculateBytesPerPixel(in.header());

const TileDescription& td = in.header().tileDescription();
int tileWidth = td.xSize;
Expand Down Expand Up @@ -614,15 +621,15 @@ 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];
}
}
}

// limit total samples allocated for this tile
if (!reduceMemory || bufferSize < gMaxSamplesPerScanline )
if (!reduceMemory || bufferSize*bytesPerSample < gMaxBytesPerDeepPixel )
{

pixelBuffer.resize( bufferSize );
Expand All @@ -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 )
{
Expand Down Expand Up @@ -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<uint64_t>(b.max.x) - static_cast<uint64_t>(b.min.x) + 1ll;

//
Expand All @@ -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<uint64_t>(tileDescription.xSize) * static_cast<uint64_t>(tileDescription.ySize);

if ( tileSize * tilesPerScanline > gMaxTilePixelsPerScanline )

if ( tileSize * tilesPerScanline*bytesPerPixel > gMaxTileBytesPerScanline )
{
widePart = true;
}
if( tileSize > gMaxTileSize)
if( tileSize*bytesPerPixel > gMaxTileBytes)
{
largeTiles = true;
}
Expand Down Expand Up @@ -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<uint64_t>(tileDescription.xSize) * static_cast<uint64_t>(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;
}
Expand Down