Skip to content

Commit

Permalink
Fix C++ DeepTile reading in Imf::CheckFile (#1199)
Browse files Browse the repository at this point in the history
* fix readDeepTile offsets and loops

Signed-off-by: Peter Hillman <peterh@wetafx.co.nz>

* skip reading empty tiles in ImfCheckFile

Signed-off-by: Peter Hillman <peterh@wetafx.co.nz>
  • Loading branch information
peterhillman authored Nov 12, 2021
1 parent b158f6a commit dec6ddd
Showing 1 changed file with 72 additions and 76 deletions.
148 changes: 72 additions & 76 deletions src/lib/OpenEXRUtil/ImfCheckFile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -563,7 +563,7 @@ readDeepTile(T& in,bool reduceMemory , bool reduceTime)
frameBuffer.insertSampleCountSlice (Slice (UINT,
reinterpret_cast<char*>(&localSampleCount[0][0]),
sizeof (unsigned int) * 1,
sizeof (unsigned int) * width,
sizeof (unsigned int) * tileWidth,
1, 1, // x/ysampling
0.0, // fill
true, // relative x
Expand All @@ -582,7 +582,7 @@ readDeepTile(T& in,bool reduceMemory , bool reduceTime)
DeepSlice (FLOAT,
reinterpret_cast<char*>(&data[channel][0][0]),
pointerSize * 1,
pointerSize * width,
pointerSize * tileWidth,
sampleSize,
1, 1,
0.0,
Expand All @@ -601,107 +601,103 @@ readDeepTile(T& in,bool reduceMemory , bool reduceTime)
vector<float> pixelBuffer;


for (int ly = 0; ly < numYLevels; ly++)
{
for (int lx = 0; lx < numXLevels; lx++)
{


//
// read all tiles from all levels.
//
for (int ylevel = 0; ylevel < numYLevels; ++ylevel )

//
// read all tiles from all levels.
//
for (int ylevel = 0; ylevel < numYLevels; ++ylevel )
{
for (int xlevel = 0; xlevel < numXLevels; ++xlevel )
{
for(int y = 0 ; y < in.numYTiles(ylevel) ; ++y )
{
for (int xlevel = 0; xlevel < numXLevels; ++xlevel )
for(int x = 0 ; x < in.numXTiles(xlevel) ; ++x )
{
for(int y = 0 ; y < in.numYTiles(ylevel) ; ++y )
if(tileIndex % step == 0)
{
for(int x = 0 ; x < in.numXTiles(xlevel) ; ++x )
try
{
if(tileIndex % step == 0)

in.readPixelSampleCounts( x , y , x , y, xlevel, ylevel);


size_t bufferSize = 0;

for (int ty = 0 ; ty < tileHeight ; ++ty )
{
try
for (int tx = 0 ; tx < tileWidth ; ++tx )
{
if (!reduceMemory || localSampleCount[ty][tx]*bytesPerSample < gMaxBytesPerDeepScanline )
{
bufferSize += channelCount * localSampleCount[ty][tx];
}
}
}

in.readPixelSampleCounts( x , y , x , y, lx, ly);

// skip reading if no data to read, or limiting memory and tile is too large
if ( bufferSize>0 && (!reduceMemory || bufferSize*bytesPerSample < gMaxBytesPerDeepPixel ))
{

size_t bufferSize = 0;
pixelBuffer.resize( bufferSize );
size_t bufferIndex = 0;

for (int ty = 0 ; ty < tileHeight ; ++ty )
for (int ty = 0 ; ty < tileHeight ; ++ty )
{
for (int tx = 0 ; tx < tileWidth ; ++tx )
{
for (int tx = 0 ; tx < tileWidth ; ++tx )
if (!reduceMemory || localSampleCount[ty][tx]*bytesPerSample < gMaxBytesPerDeepPixel )
{
if (!reduceMemory || localSampleCount[ty][tx]*bytesPerSample < gMaxBytesPerDeepScanline )
for (int k = 0 ; k < channelCount ; ++k )
{
bufferSize += channelCount * localSampleCount[ty][tx];
data[k][ty][tx] = &pixelBuffer[bufferIndex];
bufferIndex += localSampleCount[ty][tx];
}
}
}

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

pixelBuffer.resize( bufferSize );
size_t bufferIndex = 0;

for (int ty = 0 ; ty < tileHeight ; ++ty )
else
{
for (int tx = 0 ; tx < tileWidth ; ++tx )
for (int k = 0 ; k < channelCount ; ++k )
{
if (!reduceMemory || localSampleCount[ty][tx]*bytesPerSample < gMaxBytesPerDeepPixel )
{
for (int k = 0 ; k < channelCount ; ++k )
{
data[k][ty][tx] = &pixelBuffer[bufferIndex];
bufferIndex += localSampleCount[ty][tx];
}
}
else
{
for (int k = 0 ; k < channelCount ; ++k )
{
data[k][ty][tx] = nullptr;
}
}
data[k][ty][tx] = nullptr;
}
}


in.readTile ( x, y, xlevel , ylevel);
}
}

catch(...)
{
//
// for one level and mipmapped images,
// xlevel must match ylevel,
// otherwise an exception is thrown
// ignore that exception
//
if (isRipMap || xlevel==ylevel)
{
threw = true;
//
// in reduceTime mode, fail immediately - the file is corrupt
//
if (reduceTime)
{
return threw;
}
}

in.readTile ( x, y, xlevel , ylevel);
}
}

catch(...)
{
//
// for one level and mipmapped images,
// xlevel must match ylevel,
// otherwise an exception is thrown
// ignore that exception
//
if (isRipMap || xlevel==ylevel)
{
threw = true;
//
// in reduceTime mode, fail immediately - the file is corrupt
//
if (reduceTime)
{
return threw;
}
}
tileIndex++;

}
}
tileIndex++;
}
}
}
}
}
}

}catch(...)
{
threw = true;
Expand Down Expand Up @@ -1255,7 +1251,7 @@ bool readCoreScanlinePart(exr_context_t f, int part, bool reduceMemory, bool red
}

exr_decoding_destroy (f, &decoder);

return (rv != EXR_ERR_SUCCESS);
}

Expand Down Expand Up @@ -1337,7 +1333,7 @@ bool readCoreTiledPart(exr_context_t f, int part, bool reduceMemory, bool reduce
}
continue;
}

if (decoder.channels == NULL)
{
rv = exr_decoding_initialize (f, part, &cinfo, &decoder);
Expand Down Expand Up @@ -1434,7 +1430,7 @@ bool checkCoreFile(exr_context_t f, bool reduceMemory, bool reduceTime)
rv = exr_get_storage (f, p, &store);
if (rv != EXR_ERR_SUCCESS)
return true;

// TODO: Need to fill this in
if (store == EXR_STORAGE_DEEP_SCANLINE || store == EXR_STORAGE_DEEP_TILED)
continue;
Expand Down

0 comments on commit dec6ddd

Please sign in to comment.