From 2af2abf9402f6bc7165cb039961abf6879ebd113 Mon Sep 17 00:00:00 2001 From: Peter Hillman Date: Wed, 20 Feb 2013 15:50:17 +1300 Subject: [PATCH] All fuzz tests now check multipart files too Fuzz tests don't leak memory if readPixels calls fail sanityCheck re-ordered so that some checks still take place for unknown types --- OpenEXR/IlmImf/ImfHeader.cpp | 22 +- .../IlmImfFuzzTest/testFuzzDeepScanLines.cpp | 222 ++++++++++++---- OpenEXR/IlmImfFuzzTest/testFuzzDeepTiles.cpp | 249 +++++++++++++++--- OpenEXR/IlmImfFuzzTest/testFuzzScanLines.cpp | 106 ++++---- OpenEXR/IlmImfFuzzTest/testFuzzTiles.cpp | 125 +++++++-- 5 files changed, 547 insertions(+), 177 deletions(-) diff --git a/OpenEXR/IlmImf/ImfHeader.cpp b/OpenEXR/IlmImf/ImfHeader.cpp index b1c3712a9..010591119 100644 --- a/OpenEXR/IlmImf/ImfHeader.cpp +++ b/OpenEXR/IlmImf/ImfHeader.cpp @@ -751,15 +751,6 @@ void Header::sanityCheck (bool isTiled, bool isMultipartFile) const { - const std::string & part_type=hasType() ? type() : ""; - - if(part_type!="" && !isSupportedType(part_type)) - { - // - // skip sanity checks with unsupported types - // - return; - } // // The display window and the data window must each @@ -875,7 +866,18 @@ Header::sanityCheck (bool isTiled, bool isMultipartFile) const } } - + + const std::string & part_type=hasType() ? type() : ""; + + if(part_type!="" && !isSupportedType(part_type)) + { + // + // skip remaining sanity checks with unsupported types - they may not hold + // + return; + } + + // // If the file is tiled, verify that the tile description has reasonable // values and check to see if the lineOrder is one of the predefined 3. diff --git a/OpenEXR/IlmImfFuzzTest/testFuzzDeepScanLines.cpp b/OpenEXR/IlmImfFuzzTest/testFuzzDeepScanLines.cpp index 7ed46e4c7..56e1f61db 100644 --- a/OpenEXR/IlmImfFuzzTest/testFuzzDeepScanLines.cpp +++ b/OpenEXR/IlmImfFuzzTest/testFuzzDeepScanLines.cpp @@ -55,6 +55,10 @@ // Handle the case when the custom namespace is not exposed #include #include +#include +#include +#include +#include using namespace OPENEXR_IMF_INTERNAL_NAMESPACE; using namespace std; @@ -73,12 +77,13 @@ const Box2i dataWindow(V2i(minX, minY), V2i(minX + width - 1, minY + height - 1) const Box2i displayWindow(V2i(0, 0), V2i(minX + width * 2, minY + height * 2)); Array2D sampleCount; -Header header; -void generateRandomFile(const char filename[], int channelCount,Compression compression) +void generateRandomFile(const char filename[], int channelCount,int parts , Compression compression) { - cout << "generating " << flush; - header = Header(displayWindow, dataWindow, + cout << "generating file with " << parts << " parts and compression " << compression << flush; + vector
headers(parts); + + headers[0] = Header(displayWindow, dataWindow, 1, IMATH_NAMESPACE::V2f (0, 0), 1, @@ -92,11 +97,22 @@ void generateRandomFile(const char filename[], int channelCount,Compression comp stringstream ss; ss << i; string str = ss.str(); - header.channels().insert(str, Channel(FLOAT)); + headers[0].channels().insert(str, Channel(FLOAT)); } - header.setType(DEEPSCANLINE); - + headers[0].setType(DEEPSCANLINE); + + headers[0].setName("bob"); + + for(int p=1;p > data(channelCount); for (int i = 0; i < channelCount; i++) data[i].resizeErase(height, width); @@ -104,10 +120,12 @@ void generateRandomFile(const char filename[], int channelCount,Compression comp sampleCount.resizeErase(height, width); remove (filename); - DeepScanLineOutputFile file(filename, header, 8); - + + + MultiPartOutputFile file(filename,&headers[0],parts); + DeepFrameBuffer frameBuffer; - + frameBuffer.insertSampleCountSlice (Slice (UINT, // type // 7 (char *) (&sampleCount[0][0] - dataWindow.min.x @@ -135,41 +153,46 @@ void generateRandomFile(const char filename[], int channelCount,Compression comp pointerSize * width, // yStride// 10 sampleSize)); // sampleStride } + + for(int p=0;p localSampleCount; + localSampleCount.resizeErase(height, width); + Array > data(channelCount); + + + for (int i = 0; i < channelCount; i++) + data[i].resizeErase(height, width); + + DeepFrameBuffer frameBuffer; + + frameBuffer.insertSampleCountSlice (Slice (UINT, // type // 7 + (char *) (&localSampleCount[0][0] + - dataWindow.min.x + - dataWindow.min.y * width), // base // 8) + sizeof (unsigned int) * 1, // xStride// 9 + sizeof (unsigned int) * width)); // yStride// 10 + + vector read_channel(channelCount); + + + for (int i = 0; i < channelCount; i++) + { + PixelType type = FLOAT; + + stringstream ss; + ss << i; + string str = ss.str(); + + int sampleSize = sizeof (float); + + int pointerSize = sizeof (char *); + + frameBuffer.insert (str, + DeepSlice (type, + (char *) (&data[i][0][0] + - dataWindow.min.x + - dataWindow.min.y * width), // base // 8) + pointerSize * 1, // xStride// 9 + pointerSize * width, // yStride// 10 + sampleSize)); // sampleStride + } + + inpart.setFrameBuffer(frameBuffer); + inpart.readPixelSampleCounts(dataWindow.min.y, dataWindow.max.y); + for (int i = 0; i < dataWindow.max.y - dataWindow.min.y + 1; i++) + { + int y = i + dataWindow.min.y; + + for (int j = 0; j < width; j++) + { + for (int k = 0; k < channelCount; k++) + { + data[k][i][j] = new float[localSampleCount[i][j]]; + } + } + } + try{ + inpart.readPixels(dataWindow.min.y, dataWindow.max.y); + }catch(...) + { + + } + + for (int i = 0; i < height; i++) + { + for (int j = 0; j < width; j++) + { + for (int k = 0; k < channelCount; k++) + { + delete[] (float*) data[k][i][j]; + } + } + } + } + }catch(...) + { + // nothing + } +} + void fuzzDeepScanLines (int numThreads, Rand48 &random) @@ -261,13 +383,17 @@ fuzzDeepScanLines (int numThreads, Rand48 &random) Header::setMaxImageSize (10000, 10000); - const char *goodFile = IMF_TMP_DIR "imf_test_file_fuzz_good.exr"; - const char *brokenFile = IMF_TMP_DIR "imf_test_file_fuzz_broken.exr"; + const char *goodFile = IMF_TMP_DIR "imf_test_deep_scanline_file_fuzz_good.exr"; + const char *brokenFile = IMF_TMP_DIR "imf_test_deep_scanline_file_fuzz_broken.exr"; - for(int comp_method=0;comp_method<2;comp_method++) + + for(int parts=1 ; parts < 3 ; parts++) { - generateRandomFile(goodFile,8,comp_method==0 ? NO_COMPRESSION : ZIPS_COMPRESSION); - fuzzFile (goodFile, brokenFile, readFile, 5000, 3000, random); + for(int comp_method=0;comp_method<2;comp_method++) + { + generateRandomFile(goodFile,8,parts,comp_method==0 ? NO_COMPRESSION : ZIPS_COMPRESSION); + fuzzFile (goodFile, brokenFile, readFile, 5000, 3000, random); + } } remove (goodFile); diff --git a/OpenEXR/IlmImfFuzzTest/testFuzzDeepTiles.cpp b/OpenEXR/IlmImfFuzzTest/testFuzzDeepTiles.cpp index 5795c7462..690fe9047 100644 --- a/OpenEXR/IlmImfFuzzTest/testFuzzDeepTiles.cpp +++ b/OpenEXR/IlmImfFuzzTest/testFuzzDeepTiles.cpp @@ -56,6 +56,10 @@ // Handle the case when the custom namespace is not exposed #include #include +#include +#include +#include +#include using namespace OPENEXR_IMF_INTERNAL_NAMESPACE; using namespace std; @@ -74,11 +78,13 @@ const Box2i displayWindow(V2i(0, 0), V2i(minX + width * 2, minY + height * 2)); Array2D< Array2D > sampleCountWhole; Header header; -void generateRandomFile(const char filename[], int channelCount, Compression compression) +void generateRandomFile(const char filename[], int channelCount, int parts , Compression compression) { - + + vector
headers(parts); + cout << "generating " << flush; - header = Header(displayWindow, dataWindow, + headers[0] = Header(displayWindow, dataWindow, 1, IMATH_NAMESPACE::V2f (0, 0), 1, @@ -92,12 +98,24 @@ void generateRandomFile(const char filename[], int channelCount, Compression com ostringstream ss; ss << i; string str = ss.str(); - header.channels().insert(str, Channel(OPENEXR_IMF_NAMESPACE::FLOAT)); + headers[0].channels().insert(str, Channel(OPENEXR_IMF_NAMESPACE::FLOAT)); } - header.setType(DEEPTILE); - header.setTileDescription( TileDescription(rand() % width + 1, rand() % height + 1, RIPMAP_LEVELS)); + headers[0].setType(DEEPTILE); + headers[0].setTileDescription( TileDescription(rand() % width + 1, rand() % height + 1, RIPMAP_LEVELS)); + headers[0].setName("bob"); + + for(int p=1;p > data(channelCount); for (int i = 0; i < channelCount; i++) { @@ -108,11 +126,14 @@ void generateRandomFile(const char filename[], int channelCount, Compression com sampleCount.resizeErase(height, width); remove (filename); - DeepTiledOutputFile file(filename, header, 8); - cout << "tileSizeX " << file.tileXSize() << " tileSizeY " << file.tileYSize() << " "; + MultiPartOutputFile file(filename, &headers[0], parts); + + DeepTiledOutputPart part(file,0); - sampleCountWhole.resizeErase(file.numYLevels(), file.numXLevels()); + cout << "tileSizeX " << part.tileXSize() << " tileSizeY " << part.tileYSize() << " "; + + sampleCountWhole.resizeErase(part.numYLevels(), part.numXLevels()); for (int i = 0; i < sampleCountWhole.height(); i++) { for (int j = 0; j < sampleCountWhole.width(); j++) @@ -147,45 +168,65 @@ void generateRandomFile(const char filename[], int channelCount, Compression com sampleSize)); } - file.setFrameBuffer(frameBuffer); + for(int part=0;part localSampleCount; + + Box2i dataWindow = fileHeader.dataWindow(); + + int height = dataWindow.size().y+1; + int width = dataWindow.size().x+1; + + + localSampleCount.resizeErase(height, width); + + int channelCount=0; + for(ChannelList::ConstIterator i=fileHeader.channels().begin();i!=fileHeader.channels().end();++i, channelCount++); + + Array > data(channelCount); + + for (int i = 0; i < channelCount; i++) + { + data[i].resizeErase(height, width); + } + + DeepFrameBuffer frameBuffer; + + int memOffset = dataWindow.min.x + dataWindow.min.y * width; + frameBuffer.insertSampleCountSlice (Slice (OPENEXR_IMF_NAMESPACE::UINT, + (char *) (&localSampleCount[0][0] - memOffset), + sizeof (unsigned int) * 1, + sizeof (unsigned int) * width) + ); + + for (int i = 0; i < channelCount; i++) + { + stringstream ss; + ss << i; + string str = ss.str(); + + int sampleSize = sizeof (float); + + int pointerSize = sizeof (char *); + + frameBuffer.insert (str, + DeepSlice (FLOAT, + (char *) (&data[i][0][0] - memOffset), + pointerSize * 1, + pointerSize * width, + sampleSize) ); + } + + part.setFrameBuffer(frameBuffer); + + for (int ly = 0; ly < part.numYLevels(); ly++) + { + for (int lx = 0; lx < part.numXLevels(); lx++) + { + Box2i dataWindowL = part.dataWindowForLevel(lx, ly); + + + part.readPixelSampleCounts(0, part.numXTiles(lx) - 1, 0, part.numYTiles(ly) - 1, lx, ly); + + for (int i = 0; i < part.numYTiles(ly); i++) + { + for (int j = 0; j < part.numXTiles(lx); j++) + { + Box2i box = part.dataWindowForTile(j, i, lx, ly); + for (int y = box.min.y; y <= box.max.y; y++) + for (int x = box.min.x; x <= box.max.x; x++) + { + int dwy = y - dataWindowL.min.y; + int dwx = x - dataWindowL.min.x; + + for (int k = 0; k < channelCount; k++) + { + data[k][dwy][dwx] = new float[localSampleCount[dwy][dwx]]; + } + } + } + } + + try{ + part.readTiles(0, part.numXTiles(lx) - 1, 0, part.numYTiles(ly) - 1, lx, ly); + }catch(...) + { + + } + + for (int i = 0; i < part.levelHeight(ly); i++) + { + for (int j = 0; j < part.levelWidth(lx); j++) + { + for (int k = 0; k < channelCount; k++) + { + delete[] (float*) data[k][i][j]; + } + } + } + } + } + } + }catch(std::exception & e) + { + /* expect to get exceptions*/ + } + } @@ -311,19 +471,22 @@ fuzzDeepTiles (int numThreads, Rand48 &random) Header::setMaxImageSize (10000, 10000); - const char *goodFile = IMF_TMP_DIR "imf_test_file_fuzz_good.exr"; - const char *brokenFile = IMF_TMP_DIR "imf_test_file_fuzz_broken.exr"; + const char *goodFile = IMF_TMP_DIR "imf_test_deep_tile_file_fuzz_good.exr"; + const char *brokenFile = IMF_TMP_DIR "imf_test_deel_tile_file_fuzz_broken.exr"; // read file if it already exists: allows re-testing reading of broken file readFile(brokenFile); - - for(int comp_method=0;comp_method<2;comp_method++) + for(int parts=1;parts<3;parts++) { - generateRandomFile(goodFile,8,comp_method==0 ? NO_COMPRESSION : ZIPS_COMPRESSION); - fuzzFile (goodFile, brokenFile, readFile, 5000, 3000, random); + + for(int comp_method=0;comp_method<2;comp_method++) + { + generateRandomFile(goodFile,8,parts , comp_method==0 ? NO_COMPRESSION : ZIPS_COMPRESSION); + fuzzFile (goodFile, brokenFile, readFile, 5000, 3000, random); + } } remove (goodFile); diff --git a/OpenEXR/IlmImfFuzzTest/testFuzzScanLines.cpp b/OpenEXR/IlmImfFuzzTest/testFuzzScanLines.cpp index f07cb2f79..27e02b149 100644 --- a/OpenEXR/IlmImfFuzzTest/testFuzzScanLines.cpp +++ b/OpenEXR/IlmImfFuzzTest/testFuzzScanLines.cpp @@ -152,64 +152,60 @@ readImage (const char fileName[]) // but it should not crash for any reason. // - for(int pass=0;pass<2;pass++) + try { - try + // first , test Rgba interface + RgbaInputFile in (fileName); + const Box2i &dw = in.dataWindow(); + + int w = dw.max.x - dw.min.x + 1; + int dx = dw.min.x; + + if (w > (1 << 24)) + return; + + Array pixels (w); + in.setFrameBuffer (&pixels[-dx], 1, 0); + + for (int y = dw.min.y; y <= dw.max.y; ++y) + in.readPixels (y); + }catch(...) + { + // expect exceptions + } + try{ + // now test Multipart interface (even for single part files) + + MultiPartInputFile file(fileName); + + for(int p=0;p (1 << 24)) + return; + + Array pixels (w); + FrameBuffer i; + i.insert("R",Slice(HALF,(char *)&(pixels[-dx].r),sizeof(Rgba),0)); + i.insert("G",Slice(HALF,(char *)&(pixels[-dx].g),sizeof(Rgba),0)); + i.insert("B",Slice(HALF,(char *)&(pixels[-dx].b),sizeof(Rgba),0)); + i.insert("A",Slice(HALF,(char *)&(pixels[-dx].a),sizeof(Rgba),0)); + + in.setFrameBuffer (i); + for (int y = dw.min.y; y <= dw.max.y; ++y) + in.readPixels (y); - if (w > (1 << 24)) - return; - - Array pixels (w); - in.setFrameBuffer (&pixels[-dx], 1, 0); - - for (int y = dw.min.y; y <= dw.max.y; ++y) - in.readPixels (y); - }else{ - - // now test Multipart interface (even for single part files) - - MultiPartInputFile file(fileName); - - for(int p=0;p (1 << 24)) - return; - - Array pixels (w); - FrameBuffer i; - i.insert("R",Slice(HALF,(char *)&(pixels[-dx].r),sizeof(Rgba),0)); - i.insert("G",Slice(HALF,(char *)&(pixels[-dx].g),sizeof(Rgba),0)); - i.insert("B",Slice(HALF,(char *)&(pixels[-dx].b),sizeof(Rgba),0)); - i.insert("A",Slice(HALF,(char *)&(pixels[-dx].a),sizeof(Rgba),0)); - - in.setFrameBuffer (i); - for (int y = dw.min.y; y <= dw.max.y; ++y) - in.readPixels (y); - - } - } - } - catch (...) - { - // empty } } + catch (...) + { + // empty + } } @@ -230,8 +226,8 @@ fuzzScanLines (int numThreads, Rand48 &random) Array2D pixels (H, W); fillPixels (pixels, W, H); - const char *goodFile = IMF_TMP_DIR "imf_test_file_fuzz_good.exr"; - const char *brokenFile = IMF_TMP_DIR "imf_test_file_fuzz_broken.exr"; + const char *goodFile = IMF_TMP_DIR "imf_test_scanline_file_fuzz_good.exr"; + const char *brokenFile = IMF_TMP_DIR "imf_test_scanline_file_fuzz_broken.exr"; // re-attempt to read broken file if it still remains on disk from previous aborted run readImage(brokenFile); diff --git a/OpenEXR/IlmImfFuzzTest/testFuzzTiles.cpp b/OpenEXR/IlmImfFuzzTest/testFuzzTiles.cpp index 04dc03f06..0ef10c8df 100644 --- a/OpenEXR/IlmImfFuzzTest/testFuzzTiles.cpp +++ b/OpenEXR/IlmImfFuzzTest/testFuzzTiles.cpp @@ -45,9 +45,16 @@ #include #include +#include // Handle the case when the custom namespace is not exposed #include +#include +#include +#include +#include +#include +#include using namespace OPENEXR_IMF_INTERNAL_NAMESPACE; using namespace std; using namespace IMATH_NAMESPACE; @@ -77,9 +84,10 @@ void writeImageONE (const char fileName[], int width, int height, int xSize, int ySize, + int parts, Compression comp) { - cout << "levelMode 0" << ", compression " << comp << endl; + cout << "levelMode 0" << ", compression " << comp << " parts " << parts << endl; Header header (width, height); header.lineOrder() = INCREASING_Y; @@ -88,11 +96,49 @@ writeImageONE (const char fileName[], Array2D pixels (height, width); fillPixels (pixels, width, height); - TiledRgbaOutputFile out (fileName, header, WRITE_RGBA, - xSize, ySize, ONE_LEVEL); + if(parts==1) + { + TiledRgbaOutputFile out (fileName, header, WRITE_RGBA, + xSize, ySize, ONE_LEVEL); + + out.setFrameBuffer (&pixels[0][0], 1, width); + out.writeTiles (0, out.numXTiles() - 1, 0, out.numYTiles() - 1); + }else{ + + header.setTileDescription(TileDescription(xSize,ySize,ONE_LEVEL)); + + header.setType(TILEDIMAGE); + + header.channels().insert("R",Channel(HALF)); + header.channels().insert("G",Channel(HALF)); + header.channels().insert("B",Channel(HALF)); + header.channels().insert("A",Channel(HALF)); - out.setFrameBuffer (&pixels[0][0], 1, width); - out.writeTiles (0, out.numXTiles() - 1, 0, out.numYTiles() - 1); + + FrameBuffer f; + f.insert("R",Slice(HALF,(char *) &(pixels[0][0].r),sizeof(Rgba),width*sizeof(Rgba))); + f.insert("G",Slice(HALF,(char *) &(pixels[0][0].g),sizeof(Rgba),width*sizeof(Rgba))); + f.insert("B",Slice(HALF,(char *) &(pixels[0][0].b),sizeof(Rgba),width*sizeof(Rgba))); + f.insert("A",Slice(HALF,(char *) &(pixels[0][0].a),sizeof(Rgba),width*sizeof(Rgba))); + + + vector
headers(parts); + for(int p=0;p pixels (h, w); in.setFrameBuffer (&pixels[-dwy][-dwx], 1, w); in.readTiles (0, in.numXTiles() - 1, 0, in.numYTiles() - 1); } catch (...) { - // empty + // empty + } + try + { + + // attempt MultiPart interface + MultiPartInputFile in(fileName); + for(int p=0;p pixels (h, w); + FrameBuffer i; + i.insert("R",Slice(HALF,(char *)&(pixels[-dwy][-dwx].r),sizeof(Rgba),w*sizeof(Rgba))); + i.insert("G",Slice(HALF,(char *)&(pixels[-dwy][-dwx].g),sizeof(Rgba),w*sizeof(Rgba))); + i.insert("B",Slice(HALF,(char *)&(pixels[-dwy][-dwx].b),sizeof(Rgba),w*sizeof(Rgba))); + i.insert("A",Slice(HALF,(char *)&(pixels[-dwy][-dwx].a),sizeof(Rgba),w*sizeof(Rgba))); + + inpart.setFrameBuffer (i); + inpart.readTiles (0, inpart.numXTiles() - 1, 0, inpart.numYTiles() - 1); + } + } + catch (...) + { + // empty } } @@ -130,6 +206,7 @@ void writeImageMIP (const char fileName[], int width, int height, int xSize, int ySize, + int parts, ///\todo support multipart MIP files Compression comp) { cout << "levelMode 1" << ", compression " << comp << endl; @@ -201,6 +278,7 @@ void writeImageRIP (const char fileName[], int width, int height, int xSize, int ySize, + int parts, ///\todo support multipart RIP files Compression comp) { cout << "levelMode 2" << ", compression " << comp << endl; @@ -293,21 +371,26 @@ fuzzTiles (int numThreads, Rand48 &random) const int TW = 64; const int TH = 64; - const char *goodFile = IMF_TMP_DIR "imf_test_file_fuzz_good.exr"; - const char *brokenFile = IMF_TMP_DIR "imf_test_file_fuzz_broken.exr"; + const char *goodFile = IMF_TMP_DIR "imf_test_tile_file_fuzz_good.exr"; + const char *brokenFile = IMF_TMP_DIR "imf_test_tile_file_fuzz_broken.exr"; - for (int comp = 0; comp < NUM_COMPRESSION_METHODS; ++comp) + for (int parts = 1 ; parts < 3 ; parts++) { - writeImageONE (goodFile, W, H, TW, TH, Compression (comp)); - fuzzFile (goodFile, brokenFile, readImageONE, 5000, 3000, random); - - writeImageMIP (goodFile, W, H, TW, TH, Compression (comp)); - fuzzFile (goodFile, brokenFile, readImageMIP, 5000, 3000, random); - - writeImageRIP (goodFile, W, H, TW, TH, Compression (comp)); - fuzzFile (goodFile, brokenFile, readImageRIP, 5000, 3000, random); + for (int comp = 0; comp < NUM_COMPRESSION_METHODS; ++comp) + { + writeImageONE (goodFile, W, H, TW, TH, parts , Compression (comp)); + fuzzFile (goodFile, brokenFile, readImageONE, 5000, 3000, random); + + if(parts==1) + { + writeImageMIP (goodFile, W, H, TW, TH, parts , Compression (comp)); + fuzzFile (goodFile, brokenFile, readImageMIP, 5000, 3000, random); + + writeImageRIP (goodFile, W, H, TW, TH, parts , Compression (comp)); + fuzzFile (goodFile, brokenFile, readImageRIP, 5000, 3000, random); + } + } } - remove (goodFile); remove (brokenFile); }