Skip to content
Merged
Show file tree
Hide file tree
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
18 changes: 12 additions & 6 deletions src/OpenColorIO/PathUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -88,20 +88,26 @@ std::string GetFastFileHash(const std::string & filename, const Context & contex
fileHashResultPtr->ready = true;

std::string h = "";
if (!context.getConfigIOProxy())
if (context.getConfigIOProxy())
{
// Default case.
h = g_hashFunction(filename);
// Case for when ConfigIOProxy is used (callbacks mechanism).
h = context.getConfigIOProxy()->getFastLutFileHash(filename.c_str());

// For absolute paths, if the proxy does not provide a hash, try the file system.
if (h.empty() && pystring::os::path::isabs(filename))
{
h = g_hashFunction(filename);
}
}
else
{
// Case for when ConfigIOProxy is used (callbacks mechanism).
h = context.getConfigIOProxy()->getFastLutFileHash(filename.c_str());
// Default case
h = g_hashFunction(filename);
}

fileHashResultPtr->hash = h;
}

hash = fileHashResultPtr->hash;
}

Expand Down
72 changes: 27 additions & 45 deletions src/OpenColorIO/transforms/FileTransform.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -192,35 +192,33 @@ std::unique_ptr<std::istream> getLutData(
{
if (config.getConfigIOProxy())
{
std::vector<uint8_t> buffer = config.getConfigIOProxy()->getLutData(filepath.c_str());
std::stringstream ss;
ss.write(reinterpret_cast<const char*>(buffer.data()), buffer.size());

return std::unique_ptr<std::stringstream>(
new std::stringstream(std::move(ss))
);
}

// Default behavior. Return file stream.
return std::unique_ptr<std::ifstream>(
new std::ifstream(Platform::filenameToUTF(filepath).c_str(), mode)
);
}
std::vector<uint8_t> buffer;
// Try to open through proxy.
try
{
buffer = config.getConfigIOProxy()->getLutData(filepath.c_str());
}
catch (const std::exception&)
{
// If the path is absolute, we'll try the file system, but otherwise
// nothing to do.
if (!pystring::os::path::isabs(filepath))
throw;
}

// Close stream returned by getLutData
void closeLutStream(const Config & config, const std::istream & istream)
{
// No-op when it is using ConfigIOProxy since getLutData returns a vector<uint8_t>.
if (config.getConfigIOProxy() == nullptr)
{
// The std::istream is coming from a std::ifstream.
// Pointer cast to ifstream and then close it.
std::ifstream * pIfStream = (std::ifstream *) &istream;
if (pIfStream->is_open())
// If the buffer is empty, we'll try the file system for abs paths.
if (!buffer.empty() || !pystring::os::path::isabs(filepath))
{
pIfStream->close();
auto pss = std::unique_ptr<std::stringstream>(new std::stringstream);
pss->write(reinterpret_cast<const char*>(buffer.data()), buffer.size());

return pss;
}
}

// Default behavior. Return file stream.
return std::unique_ptr<std::istream>(new std::ifstream(
Platform::filenameToUTF(filepath), mode));
}

bool CollectContextVariables(const Config &,
Expand Down Expand Up @@ -635,9 +633,8 @@ void LoadFileUncached(FileFormat * & returnFormat,
filepath,
tryFormat->isBinary() ? std::ios_base::binary : std::ios_base::in
);
auto & filestream = *pStream;

if (!filestream.good())
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not good if pStream becomes null somehow. Sticking with the pointer and adding a null check instead of using a reference.

if (!pStream || !pStream->good())
{
std::ostringstream os;
os << "The specified FileTransform srcfile, '";
Expand All @@ -647,7 +644,7 @@ void LoadFileUncached(FileFormat * & returnFormat,
throw Exception(os.str().c_str());
}

CachedFileRcPtr cachedFile = tryFormat->read(filestream, filepath, interp);
CachedFileRcPtr cachedFile = tryFormat->read(*pStream, filepath, interp);

if(IsDebugLoggingEnabled())
{
Expand All @@ -660,17 +657,10 @@ void LoadFileUncached(FileFormat * & returnFormat,
returnFormat = tryFormat;
returnCachedFile = cachedFile;

closeLutStream(config, filestream);

return;
}
catch(std::exception & e)
{
if (pStream)
{
closeLutStream(config, *pStream);
}

primaryErrorText += " '";
primaryErrorText += tryFormat->getName();
primaryErrorText += "' failed with: ";
Expand Down Expand Up @@ -712,9 +702,8 @@ void LoadFileUncached(FileFormat * & returnFormat,
filepath,
altFormat->isBinary() ? std::ios_base::binary : std::ios_base::in
);
auto& filestream = *pStream;

if (!filestream.good())
if (!pStream || !pStream->good())
{
std::ostringstream os;
os << "The specified FileTransform srcfile, '";
Expand All @@ -725,7 +714,7 @@ void LoadFileUncached(FileFormat * & returnFormat,
throw Exception(os.str().c_str());
}

cachedFile = altFormat->read(filestream, filepath, interp);
cachedFile = altFormat->read(*pStream, filepath, interp);

if(IsDebugLoggingEnabled())
{
Expand All @@ -738,17 +727,10 @@ void LoadFileUncached(FileFormat * & returnFormat,
returnFormat = altFormat;
returnCachedFile = cachedFile;

closeLutStream(config, filestream);

return;
}
catch(std::exception & e)
{
if (pStream)
{
closeLutStream(config, *pStream);
}

if(IsDebugLoggingEnabled())
{
std::ostringstream os;
Expand Down
23 changes: 23 additions & 0 deletions tests/cpu/OCIOZArchive_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -435,6 +435,29 @@ OCIO_ADD_TEST(OCIOZArchive, context_test_for_search_paths_and_filetransform_sour
mtx->getMatrix(mat);
OCIO_CHECK_EQUAL(mat[0], 4.);
}

{
// File transform source is an absolute path, not in the archive.
const std::string filePath =
OCIO::GetTestFilesDir() + "/matrix_example4x4.ctf";
OCIO::FileTransformRcPtr transform = OCIO::FileTransform::Create();
transform->setSrc(filePath.c_str());
OCIO::ConstProcessorRcPtr processor = cfg->getProcessor(transform);
OCIO::ConstTransformRcPtr tr =
processor->createGroupTransform()->getTransform(0);
auto mtx = OCIO::DynamicPtrCast<const OCIO::MatrixTransform>(tr);
OCIO_REQUIRE_ASSERT(mtx);
mtx->getMatrix(mat);
OCIO_CHECK_EQUAL(mat[0], 3.24);
}

{
// File transform source is an abs path but doesn't exist anywhere.
const std::string filePath = OCIO::GetTestFilesDir() + "/missing.ctf";
OCIO::FileTransformRcPtr transform = OCIO::FileTransform::Create();
transform->setSrc(filePath.c_str());
OCIO_CHECK_THROW(cfg->getProcessor(transform), OCIO::Exception);
}
};

testPaths(cfgWindowsArchive, ctxWindowsArchive);
Expand Down