root/OpenSceneGraph/trunk/src/osgPlugins/Inventor/ReaderWriterIV.cpp @ 12577

Revision 12577, 9.8 kB (checked in by robert, 3 years ago)

Fixed a range of issues reported by cppcheck:

[examples/osgphotoalbum/PhotoArchive.cpp:56]: (error) Memory leak: fileIndentifier
[examples/osgphotoalbum/PhotoArchive.cpp:257]: (error) Deallocating a deallocated pointer: newData
[examples/osgphotoalbum/PhotoArchive.cpp:318]: (error) Deallocating a deallocated pointer: newData
[src/osg/ImageUtils.cpp:116]: (portability) Extra qualification 'osg::' unnecessary and considered an error by many compilers.
[src/osg/ImageUtils.cpp:307]: (portability) Extra qualification 'osg::' unnecessary and considered an error by many compilers.
[src/osg/ImageUtils.cpp:312]: (portability) Extra qualification 'osg::' unnecessary and considered an error by many compilers.
[src/osg/ImageUtils.cpp:367]: (portability) Extra qualification 'osg::' unnecessary and considered an error by many compilers.
[src/osg/ImageUtils.cpp:399]: (portability) Extra qualification 'osg::' unnecessary and considered an error by many compilers.
[src/osg/ImageUtils.cpp:400]: (portability) Extra qualification 'osg::' unnecessary and considered an error by many compilers.
[src/osg/ImageUtils.cpp:482]: (portability) Extra qualification 'osg::' unnecessary and considered an error by many compilers.
[src/osg/ImageUtils.cpp:483]: (portability) Extra qualification 'osg::' unnecessary and considered an error by many compilers.
[src/osg/ImageUtils.cpp:484]: (portability) Extra qualification 'osg::' unnecessary and considered an error by many compilers.
[src/osg/ImageUtils.cpp:519]: (portability) Extra qualification 'osg::' unnecessary and considered an error by many compilers.
[src/osg/ImageUtils.cpp:536]: (portability) Extra qualification 'osg::' unnecessary and considered an error by many compilers.
[src/osg/OcclusionQueryNode.cpp:71]: (portability) Extra qualification 'osg::' unnecessary and considered an error by many compilers.
[src/osg/OcclusionQueryNode.cpp:74]: (portability) Extra qualification 'osg::' unnecessary and considered an error by many compilers.
[src/osg/OcclusionQueryNode.cpp:77]: (portability) Extra qualification 'osg::' unnecessary and considered an error by many compilers.
[src/osg/OcclusionQueryNode.cpp:82]: (portability) Extra qualification 'osg::' unnecessary and considered an error by many compilers.
[src/osg/OcclusionQueryNode.cpp:102]: (portability) Extra qualification 'osg::' unnecessary and considered an error by many compilers.
[src/osg/OcclusionQueryNode.cpp:107]: (portability) Extra qualification 'osg::' unnecessary and considered an error by many compilers.
[src/osg/OcclusionQueryNode.cpp:599]: (portability) Extra qualification 'osg::' unnecessary and considered an error by many compilers.
[src/osg/OcclusionQueryNode.cpp:600]: (portability) Extra qualification 'osg::' unnecessary and considered an error by many compilers.
[src/osg/OcclusionQueryNode.cpp:601]: (portability) Extra qualification 'osg::' unnecessary and considered an error by many compilers.
[src/osg/OcclusionQueryNode.cpp:602]: (portability) Extra qualification 'osg::' unnecessary and considered an error by many compilers.
[src/osg/OcclusionQueryNode.cpp:603]: (portability) Extra qualification 'osg::' unnecessary and considered an error by many compilers.
[src/osg/OcclusionQueryNode.cpp:604]: (portability) Extra qualification 'osg::' unnecessary and considered an error by many compilers.
[src/osg/OcclusionQueryNode.cpp:605]: (portability) Extra qualification 'osg::' unnecessary and considered an error by many compilers.
[src/osg/OcclusionQueryNode.cpp:606]: (portability) Extra qualification 'osg::' unnecessary and considered an error by many compilers.
[src/osgDB/ExternalFileWriter.cpp:134]: (portability) Extra qualification 'osgDB::' unnecessary and considered an error by many compilers.
[src/osgDB/ExternalFileWriter.cpp:135]: (portability) Extra qualification 'osgDB::' unnecessary and considered an error by many compilers.
[src/osgDB/ExternalFileWriter.cpp:136]: (portability) Extra qualification 'osgDB::' unnecessary and considered an error by many compilers.
[src/osgDB/ExternalFileWriter.cpp:137]: (portability) Extra qualification 'osgDB::' unnecessary and considered an error by many compilers.
[src/osgDB/ExternalFileWriter.cpp:139]: (portability) Extra qualification 'osgDB::' unnecessary and considered an error by many compilers.
[src/osgDB/ExternalFileWriter.cpp:177]: (portability) Extra qualification 'osgDB::' unnecessary and considered an error by many compilers.
[src/osgDB/ExternalFileWriter.cpp:178]: (portability) Extra qualification 'osgDB::' unnecessary and considered an error by many compilers.
[src/osgDB/ExternalFileWriter.cpp:195]: (portability) Extra qualification 'osgDB::' unnecessary and considered an error by many compilers.
[src/osgDB/ExternalFileWriter.cpp:198]: (portability) Extra qualification 'osgDB::' unnecessary and considered an error by many compilers.
[src/osgDB/ExternalFileWriter.cpp:203]: (portability) Extra qualification 'osgDB::' unnecessary and considered an error by many compilers.
[src/osgDB/ExternalFileWriter.cpp:205]: (portability) Extra qualification 'osgDB::' unnecessary and considered an error by many compilers.
[src/osgDB/ExternalFileWriter.cpp:253]: (portability) Extra qualification 'osgDB::' unnecessary and considered an error by many compilers.
[src/osgDB/InputStream.cpp:553]: (error) Memory leak: data
[src/osgDB/OutputStream.cpp:393]: (error) Memory leak: data
[src/osgPlugins/Inventor/ConvertToInventor.cpp:656]: (error) Mismatching allocation and deallocation: tmpArray
[src/osgPlugins/Inventor/ReaderWriterIV.cpp:237]: (error) Common realloc mistake: 'buf' nulled but not freed upon failure
[src/osgPlugins/OpenFlight/expGeometryRecords.cpp:167]: (portability) Extra qualification 'flt::' unnecessary and considered an error by many compilers.
[src/osgPlugins/OpenFlight/expGeometryRecords.cpp:373]: (portability) Extra qualification 'flt::' unnecessary and considered an error by many compilers.
[src/osgPlugins/cfg/CameraConfig.cpp:635]: (error) Unusual pointer arithmetic
[src/osgPlugins/freetype/FreeTypeLibrary.cpp:122]: (error) Memory leak: buffer
[src/osgPlugins/geo/ReaderWriterGEO.cpp:210]: (error) Possible null pointer dereference: gfd - otherwise it is redundant to check if gfd is null at line 211
[src/osgPlugins/geo/ReaderWriterGEO.cpp:227]: (error) Possible null pointer dereference: gfd - otherwise it is redundant to check if gfd is null at line 228
[src/osgPlugins/geo/ReaderWriterGEO.cpp:903]: (error) Possible null pointer dereference: gfd - otherwise it is redundant to check if gfd is null at line 904
[src/osgPlugins/geo/osgGeoNodes.h:180]: (error) Memory leak: geoHeaderGeo::intVars
[src/osgPlugins/geo/osgGeoNodes.h:181]: (error) Memory leak: geoHeaderGeo::useVars
[src/osgPlugins/geo/osgGeoNodes.h:182]: (error) Memory leak: geoHeaderGeo::extVars
[src/osgPlugins/md2/ReaderWriterMD2.cpp:180]: (error) Memory leak: mapbase
[src/osgPlugins/md2/ReaderWriterMD2.cpp:166]: (error) Resource leak: file_fd
[src/osgPlugins/pic/ReaderWriterPIC.cpp:152]: (error) Mismatching allocation and deallocation: tmpbuf
[src/osgPlugins/pic/ReaderWriterPIC.cpp:153]: (error) Mismatching allocation and deallocation: buffer
[src/osgPlugins/ply/plyfile.cpp:843]: (error) Memory leak: plyfile
[src/osgPlugins/pvr/ReaderWriterPVR.cpp:179]: (error) Memory leak: imageData
[src/osgPlugins/shp/ESRIShapeParser.cpp:29]: (error) Resource leak: fd
[src/osgPlugins/shp/XBaseParser.cpp:96]: (error) Resource leak: fd
[src/osgPlugins/zip/unzip.cpp:3158]: (error) Possible null pointer dereference: s - otherwise it is redundant to check if s is null at line 3159
[src/osgPlugins/zip/unzip.cpp:4155]: (error) Dangerous usage of 'rd' (strncpy doesn't always 0-terminate it)
[src/osgShadow/MinimalCullBoundsShadowMap.cpp:334]: (error) Possible null pointer dereference: rl - otherwise it is redundant to check if rl is null at line 331
[src/osgViewer/ScreenCaptureHandler.cpp:617]: (error) Possible null pointer dereference: camera - otherwise it is redundant to check if camera is null at line 611
[src/osgViewer/ScreenCaptureHandler.cpp:632]: (error) Possible null pointer dereference: camera - otherwise it is redundant to check if camera is null at line 626
[src/osgVolume/Locator.cpp:209]: (error) Dangerous iterator usage after erase()-method.
[src/osgVolume/RayTracedTechnique.cpp:274]: (error) Possible null pointer dereference: imageLayer - otherwise it is redundant to check if imageLayer is null at line 259
[src/osgVolume/RayTracedTechnique.cpp:275]: (error) Possible null pointer dereference: imageLayer - otherwise it is redundant to check if imageLayer is null at line 259
[src/osgWrappers/serializers/osg/ShaderBinary.cpp:28]: (error) Mismatching allocation and deallocation: data

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1// OSG headers
2#include <osg/Notify>
3#include <osgDB/FileUtils>
4#include <osgDB/FileNameUtils>
5
6// Inventor headers
7#include <Inventor/SoDB.h>
8#include <Inventor/SoInteraction.h>
9#include <Inventor/nodekits/SoNodeKit.h>
10#include <Inventor/errors/SoDebugError.h>
11#include <Inventor/errors/SoMemoryError.h>
12#include <Inventor/errors/SoReadError.h>
13#include <Inventor/nodes/SoSeparator.h>
14#include <Inventor/actions/SoWriteAction.h>
15#include <Inventor/actions/SoCallbackAction.h>
16#ifdef __COIN__
17# include <Inventor/VRMLnodes/SoVRMLImageTexture.h>
18#endif
19
20#include "ReaderWriterIV.h"
21#include "ConvertFromInventor.h"
22#include "ConvertToInventor.h"
23
24// forward declarations of static functions
25static void addSearchPaths(const osgDB::FilePathList *searchPaths);
26static void removeSearchPaths(const osgDB::FilePathList *searchPaths);
27static void errorCallback(const SoError *error, void * data);
28
29
30// Register with Registry to instantiate the inventor reader.
31REGISTER_OSGPLUGIN(Inventor, ReaderWriterIV)
32
33
34/**
35 * Constructor.
36 * Initializes the ReaderWriterIV.
37 */
38ReaderWriterIV::ReaderWriterIV()
39{
40    // Set supported extensions and options
41    supportsExtension("iv","Inventor format");
42    supportsExtension("wrl","VRML world file");
43
44    // Initialize Inventor
45    initInventor();
46}
47
48
49/**
50 * Initializes Open Inventor.
51 */
52void ReaderWriterIV::initInventor() const
53{
54    // Initialize Inventor
55    SoDB::init();
56    SoNodeKit::init();
57    SoInteraction::init();
58
59    // Redirect error messages to OSG notify
60    SoError::setHandlerCallback(errorCallback, NULL);
61    SoDebugError::setHandlerCallback(errorCallback, NULL);
62    SoMemoryError::setHandlerCallback(errorCallback, NULL);
63    SoReadError::setHandlerCallback(errorCallback, NULL);
64
65#ifdef __COIN__
66    // Disable delayed loading of VRML textures
67    SoVRMLImageTexture::setDelayFetchURL(FALSE);
68
69    // initialize convertor
70    ConvertFromInventor::init();
71#endif
72}
73
74
75static void errorCallback(const SoError *error, void *data)
76{
77    // note: Coin and SGI Inventor puts "Inventor read error..." or "Coin warning..."
78    // introduction string to the error message, so we do not prepend the error message
79    // by anything.
80
81    if (error->isOfType(SoDebugError::getClassTypeId()))
82    {
83        switch (((SoDebugError*)error)->getSeverity())
84        {
85            case SoDebugError::INFO:
86                OSG_INFO << error->getDebugString().getString() << std::endl;
87                break;
88            case SoDebugError::WARNING:
89                OSG_WARN << error->getDebugString().getString() << std::endl;
90                break;
91            case SoDebugError::ERROR:
92            default:
93                OSG_WARN << error->getDebugString().getString() << std::endl;
94                break;
95        }
96    }
97    else
98    {
99        OSG_WARN << error->getDebugString().getString() << std::endl;
100    }
101}
102
103
104/**
105 * Read from SoInput and convert to OSG.
106 * This is a method used by readNode(string,options) and readNode(istream,options).
107 */
108osgDB::ReaderWriter::ReadResult
109ReaderWriterIV::readNodeFromSoInput(SoInput &input,
110          std::string &fileName, const osgDB::ReaderWriter::Options *options) const
111{
112    // Parse options and add search paths to SoInput
113    const osgDB::FilePathList *searchPaths = options ? &options->getDatabasePathList() : NULL;
114    if (options)
115        addSearchPaths(searchPaths);
116
117    // Create the inventor scenegraph by reading from SoInput
118    SoSeparator* rootIVNode = SoDB::readAll(&input);
119
120    // Remove recently appened search paths
121    if (options)
122        removeSearchPaths(searchPaths);
123
124    // Close the file
125    input.closeFile();
126
127    // Perform conversion
128    ReadResult result;
129    if (rootIVNode)
130    {
131        rootIVNode->ref();
132        // Convert the inventor scenegraph to an osg scenegraph
133        ConvertFromInventor convertIV;
134        convertIV.preprocess(rootIVNode);
135        result = convertIV.convert(rootIVNode);
136        rootIVNode->unref();
137    } else
138        result = ReadResult::FILE_NOT_HANDLED;
139
140    // Notify
141    if (result.success()) {
142        if (fileName.length())
143        {
144            OSG_NOTICE << "osgDB::ReaderWriterIV::readNode() "
145                      << "File " << fileName.data()
146                      << " loaded successfully." << std::endl;
147        }
148        else
149        {
150            OSG_NOTICE << "osgDB::ReaderWriterIV::readNode() "
151                      << "Stream loaded successfully." << std::endl;
152        }
153    } else {
154        if (fileName.length())
155        {
156            OSG_WARN << "osgDB::ReaderWriterIV::readNode() "
157                      << "Failed to load file " << fileName.data()
158                      << "." << std::endl;
159        }
160        else
161        {
162            OSG_WARN << "osgDB::ReaderWriterIV::readNode() "
163                  << "Failed to load stream." << std::endl;
164        }
165    }
166
167    return result;
168}
169
170
171// Read file and convert to OSG
172osgDB::ReaderWriter::ReadResult
173ReaderWriterIV::readNode(const std::string& file,
174                         const osgDB::ReaderWriter::Options* options) const
175{
176    // Accept extension
177    std::string ext = osgDB::getLowerCaseFileExtension(file);
178    if (!acceptsExtension(ext)) return ReadResult::FILE_NOT_HANDLED;
179
180    // Find file
181    std::string fileName = osgDB::findDataFile( file, options );
182    if (fileName.empty()) return ReadResult::FILE_NOT_FOUND;
183
184    // Notify
185    OSG_NOTICE << "osgDB::ReaderWriterIV::readNode() Reading file "
186                             << fileName.data() << std::endl;
187    OSG_INFO << "osgDB::ReaderWriterIV::readNode() Inventor version: "
188                           << SoDB::getVersion() << std::endl;
189
190    // Open the file
191    SoInput input;
192    if (!input.openFile(fileName.data()))
193    {
194        OSG_WARN << "osgDB::ReaderWriterIV::readIVFile() "
195                               << "Cannot open file " << fileName << std::endl;
196        return ReadResult::ERROR_IN_READING_FILE;
197    }
198
199    // Perform reading from SoInput
200    return readNodeFromSoInput(input, fileName, options);
201}
202
203
204osgDB::ReaderWriter::ReadResult
205ReaderWriterIV::readNode(std::istream& fin,
206                         const osgDB::ReaderWriter::Options* options) const
207{
208    // Notify
209    OSG_NOTICE << "osgDB::ReaderWriterIV::readNode() "
210              "Reading from stream." << std::endl;
211    OSG_INFO << "osgDB::ReaderWriterIV::readNode() "
212              "Inventor version: " << SoDB::getVersion() << std::endl;
213
214    // Open the file
215    SoInput input;
216
217    // Assign istream to SoInput
218    // note: It seems there is no straightforward way to do that.
219    // SoInput accepts only FILE by setFilePointer or memory buffer
220    // by setBuffer. The FILE is dangerous on Windows, since it forces
221    // the plugin and Inventor DLL to use the same runtime library
222    // (otherwise there are app crashes).
223    // The memory buffer seems much better option here, even although
224    // there will not be a real streaming. However, the model data
225    // are usually much smaller than textures, so we should not worry
226    // about it and think how to stream textures instead.
227
228    // Get the data to the buffer
229    size_t bufSize = 126*1024; // let's make it something bellow 128KB
230    char *buf = (char*)malloc(bufSize);
231    size_t dataSize = 0;
232    while (!fin.eof() && fin.good()) {
233        fin.read(buf+dataSize, bufSize-dataSize);
234        dataSize += fin.gcount();
235        if (bufSize == dataSize) {
236           bufSize *= 2;
237           char* new_buf = (char*)realloc(buf, bufSize);
238           if (!new_buf)
239           {
240               free(buf);
241               return osgDB::ReaderWriter::ReadResult::INSUFFICIENT_MEMORY_TO_LOAD;
242           }
243           buf = new_buf;
244        }
245    }
246    input.setBuffer(buf, dataSize);
247    OSG_INFO << "osgDB::ReaderWriterIV::readNode() "
248              "Stream size: " << dataSize << std::endl;
249
250    // Perform reading from SoInput
251    osgDB::ReaderWriter::ReadResult r;
252    std::string fileName("");
253    r = readNodeFromSoInput(input, fileName, options);
254
255    // clean up and return
256    free(buf);
257    return r;
258}
259
260
261osgDB::ReaderWriter::WriteResult
262ReaderWriterIV::writeNode(const osg::Node& node, const std::string& fileName,
263                          const osgDB::ReaderWriter::Options* options) const
264{
265    // accept extension
266    std::string ext = osgDB::getLowerCaseFileExtension(fileName);
267    if (!acceptsExtension(ext)) return WriteResult::FILE_NOT_HANDLED;
268    bool useVRML1 = !isInventorExtension(osgDB::getFileExtension(fileName));
269
270    OSG_NOTICE << "osgDB::ReaderWriterIV::writeNode() Writing file "
271                             << fileName.data() << std::endl;
272
273    // Convert OSG graph to Inventor graph
274    ConvertToInventor osg2iv;
275    osg2iv.setVRML1Conversion(useVRML1);
276    (const_cast<osg::Node*>(&node))->accept(osg2iv);
277    SoNode *ivRoot = osg2iv.getIvSceneGraph();
278    if (ivRoot == NULL)
279        return WriteResult::ERROR_IN_WRITING_FILE;
280    ivRoot->ref();
281
282    // Change prefix according to VRML spec:
283    // Node names must not begin with a digit, and must not contain spaces or
284    // control characters, single or double quote characters, backslashes, curly braces,
285    // the sharp (#) character, the plus (+) character or the period character.
286    if (useVRML1)
287      SoBase::setInstancePrefix("_");
288
289    // Write Inventor graph to file
290    SoOutput out;
291    out.setHeaderString((useVRML1) ? "#VRML V1.0 ascii" : "#Inventor V2.1 ascii");
292    if (!out.openFile(fileName.c_str()))
293        return WriteResult::ERROR_IN_WRITING_FILE;
294    SoWriteAction wa(&out);
295    wa.apply(ivRoot);
296    ivRoot->unref();
297
298    return WriteResult::FILE_SAVED;
299}
300
301
302static void addSearchPaths(const osgDB::FilePathList *searchPaths)
303{
304    for (int i=searchPaths->size()-1; i>=0; i--)
305        SoInput::addDirectoryFirst(searchPaths->operator[](i).c_str());
306}
307
308
309static void removeSearchPaths(const osgDB::FilePathList *searchPaths)
310{
311    for (int i=0, c=searchPaths->size(); i<c; i++)
312        SoInput::addDirectoryFirst(searchPaths->operator[](i).c_str());
313}
Note: See TracBrowser for help on using the browser.