From b6fc6eccf991044d4990a5e8a3f580ec4c6b7149 Mon Sep 17 00:00:00 2001 From: Kimball Thurston Date: Sun, 27 Oct 2024 06:37:23 +1300 Subject: [PATCH] Allow empty file name (#1898) When providing a custom stream, there is no reason a filename needs to be provided beyond clearer error messages. Because std::string does not allow null, continue to disallow a null filename. Add a test case Signed-off-by: Kimball Thurston --- src/lib/OpenEXRCore/context.c | 6 +-- src/test/OpenEXRCoreTest/read.cpp | 2 +- src/test/OpenEXRTest/testExistingStreams.cpp | 56 ++++++++++++++++++++ 3 files changed, 60 insertions(+), 4 deletions(-) diff --git a/src/lib/OpenEXRCore/context.c b/src/lib/OpenEXRCore/context.c index d371332f03..ae0e6a563a 100644 --- a/src/lib/OpenEXRCore/context.c +++ b/src/lib/OpenEXRCore/context.c @@ -150,7 +150,7 @@ exr_test_file_header ( exr_context_t ret = NULL; exr_context_initializer_t inits = fill_context_data (ctxtdata); - if (filename && filename[0] != '\0') + if (filename) { rv = internal_exr_alloc_context ( &ret, @@ -244,7 +244,7 @@ exr_start_read ( return EXR_ERR_INVALID_ARGUMENT; } - if (filename && filename[0] != '\0') + if (filename) { rv = internal_exr_alloc_context ( &ret, @@ -311,7 +311,7 @@ exr_start_write ( return EXR_ERR_INVALID_ARGUMENT; } - if (filename && filename[0] != '\0') + if (filename) { rv = internal_exr_alloc_context ( &ret, diff --git a/src/test/OpenEXRCoreTest/read.cpp b/src/test/OpenEXRCoreTest/read.cpp index f1b61ca01f..946fc40024 100644 --- a/src/test/OpenEXRCoreTest/read.cpp +++ b/src/test/OpenEXRCoreTest/read.cpp @@ -79,7 +79,7 @@ testReadBadArgs (const std::string& tempdir) EXRCORE_TEST_RVAL_FAIL ( EXR_ERR_INVALID_ARGUMENT, exr_start_read (&f, NULL, &cinit)); EXRCORE_TEST_RVAL_FAIL ( - EXR_ERR_INVALID_ARGUMENT, exr_start_read (&f, "", &cinit)); + EXR_ERR_FILE_ACCESS, exr_start_read (&f, "", &cinit)); // windows fails on directory open, where under unix you can open // the directory as a file handle but not read from it #ifdef _WIN32 diff --git a/src/test/OpenEXRTest/testExistingStreams.cpp b/src/test/OpenEXRTest/testExistingStreams.cpp index e9952494bc..faa8074e72 100644 --- a/src/test/OpenEXRTest/testExistingStreams.cpp +++ b/src/test/OpenEXRTest/testExistingStreams.cpp @@ -239,6 +239,29 @@ MMIFStream::readMemoryMapped (int n) return retVal; } +class PassThruIFStream : public OPENEXR_IMF_NAMESPACE::IStream +{ +public: + //------------------------------------------------------- + // A constructor that opens the file with the given name. + //------------------------------------------------------- + + PassThruIFStream (MMIFStream &s) : IStream(""), _s (s) {} + + virtual ~PassThruIFStream () {} + + virtual bool isMemoryMapped () const { return _s.isMemoryMapped (); } + + virtual bool read (char c[/*n*/], int n) { return _s.read (c, n); } + virtual char* readMemoryMapped (int n) { return _s.readMemoryMapped (n); } + virtual uint64_t tellg () { return _s.tellg (); } + virtual void seekg (uint64_t pos) { _s.seekg (pos); } + virtual void clear () { _s.clear (); } + +private: + MMIFStream &_s; +}; + void writeReadScanLines ( const char fileName[], @@ -345,6 +368,39 @@ writeReadScanLines ( } } + { + cout << ", reading (memory-mapped, passthru)"; + MMIFStream ifs (fileName); + PassThruIFStream pfs (ifs); + + RgbaInputFile in (pfs); + + const Box2i& dw = in.dataWindow (); + int w = dw.max.x - dw.min.x + 1; + int h = dw.max.y - dw.min.y + 1; + int dx = dw.min.x; + int dy = dw.min.y; + + Array2D p2 (h, w); + in.setFrameBuffer (&p2[-dy][-dx], 1, w); + in.readPixels (dw.min.y, dw.max.y); + + if (!isLossyCompression (compression)) + { + cout << ", comparing"; + for (int y = 0; y < h; ++y) + { + for (int x = 0; x < w; ++x) + { + assert (p2[y][x].r == p1[y][x].r); + assert (p2[y][x].g == p1[y][x].g); + assert (p2[y][x].b == p1[y][x].b); + assert (p2[y][x].a == p1[y][x].a); + } + } + } + } + cout << endl; remove (fileName);