diff --git a/include/osgDB/InputStream b/include/osgDB/InputStream index a33da0e65..a965d24ac 100644 --- a/include/osgDB/InputStream +++ b/include/osgDB/InputStream @@ -219,6 +219,9 @@ protected: osg::ref_ptr _exception; osg::ref_ptr _options; + // object to used to read field properties that will be discarded. + osg::ref_ptr _dummyReadObject; + // store here to avoid a new and a leak in InputStream::decompress std::stringstream* _dataDecompress; }; diff --git a/src/osgDB/InputStream.cpp b/src/osgDB/InputStream.cpp index 0bf4dcd64..6bcd95137 100644 --- a/src/osgDB/InputStream.cpp +++ b/src/osgDB/InputStream.cpp @@ -23,6 +23,17 @@ using namespace osgDB; static std::string s_lastSchema; +class DummyObject : public osg::Object +{ +public: + DummyObject() {} + DummyObject(const DummyObject& dummy, const osg::CopyOp& copyop) {} + META_Object(osgDB, DummyObject) +protected: + virtual ~DummyObject() {} +}; + + InputStream::InputStream( const osgDB::Options* options ) : _fileVersion(0), _useSchemaData(false), _forceReadingImage(false), _dataDecompress(0) { @@ -65,6 +76,9 @@ InputStream::InputStream( const osgDB::Options* options ) resetSchema(); s_lastSchema.clear(); } + + // assign dummy object to used for reading field properties that will be discarded. + _dummyReadObject = new DummyObject; } InputStream::~InputStream() @@ -772,17 +786,37 @@ osg::Image* InputStream::readImage(bool readFromExternal) break; } + bool loadedFromCache = false; if ( readFromExternal && !name.empty() ) { - image = osgDB::readImageFile( name, getOptions() ); + ReaderWriter::ReadResult rr = Registry::instance()->readImage(name, getOptions()); + if (rr.validImage()) + { + image = rr.takeImage(); + loadedFromCache = rr.loadedFromCache(); + } + else + { + if (rr.error()) OSG_WARN << rr.message() << std::endl; + } + if ( !image && _forceReadingImage ) image = new osg::Image; } - image = static_cast( readObjectFields("osg::Object", id, image.get()) ); - if ( image.valid() ) + if (loadedFromCache) { - image->setFileName( name ); - image->setWriteHint( (osg::Image::WriteHint)writeHint ); + // we don't want to overwrite the properties of the image in the cache as this could cause theading problems if the object is currently being used + // so we read the properties from the file into a dummy object and discard the changes. + osg::ref_ptr temp_obj = readObjectFields("osg::Object", id, _dummyReadObject.get() ); + } + else + { + image = static_cast( readObjectFields("osg::Object", id, image.get()) ); + if ( image.valid() ) + { + image->setFileName( name ); + image->setWriteHint( (osg::Image::WriteHint)writeHint ); + } } return image.release(); }