From dec6ddd4e4110b454b698c404012d959c9160290 Mon Sep 17 00:00:00 2001 From: peterhillman Date: Fri, 12 Nov 2021 15:15:08 +1300 Subject: [PATCH] Fix C++ DeepTile reading in Imf::CheckFile (#1199) * fix readDeepTile offsets and loops Signed-off-by: Peter Hillman * skip reading empty tiles in ImfCheckFile Signed-off-by: Peter Hillman --- src/lib/OpenEXRUtil/ImfCheckFile.cpp | 148 +++++++++++++-------------- 1 file changed, 72 insertions(+), 76 deletions(-) diff --git a/src/lib/OpenEXRUtil/ImfCheckFile.cpp b/src/lib/OpenEXRUtil/ImfCheckFile.cpp index 2db1fd7e08..c3e973e668 100644 --- a/src/lib/OpenEXRUtil/ImfCheckFile.cpp +++ b/src/lib/OpenEXRUtil/ImfCheckFile.cpp @@ -563,7 +563,7 @@ readDeepTile(T& in,bool reduceMemory , bool reduceTime) frameBuffer.insertSampleCountSlice (Slice (UINT, reinterpret_cast(&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 @@ -582,7 +582,7 @@ readDeepTile(T& in,bool reduceMemory , bool reduceTime) DeepSlice (FLOAT, reinterpret_cast(&data[channel][0][0]), pointerSize * 1, - pointerSize * width, + pointerSize * tileWidth, sampleSize, 1, 1, 0.0, @@ -601,107 +601,103 @@ readDeepTile(T& in,bool reduceMemory , bool reduceTime) vector 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; @@ -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); } @@ -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); @@ -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;