root/OpenSceneGraph/trunk/src/osgPlugins/osg/ReaderWriterOSG2.cpp @ 10986

Revision 10986, 10.6 kB (checked in by robert, 4 years ago)

From Wang Rui, refactored the InputStream/OutputStream? operations so that the binar/ascii foramts are implemented via subclasses.

Line 
1/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2010 Robert Osfield
2 *
3 * This library is open source and may be redistributed and/or modified under
4 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
5 * (at your option) any later version.  The full license is in LICENSE file
6 * included with this distribution, and on the openscenegraph.org website.
7 *
8 * This library is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 * OpenSceneGraph Public License for more details.
12*/
13// Written by Wang Rui, (C) 2010
14
15#include <osgDB/FileNameUtils>
16#include <osgDB/FileUtils>
17#include <osgDB/Registry>
18#include <osgDB/ObjectWrapper>
19#include "AsciiStreamOperator.h"
20#include "BinaryStreamOperator.h"
21
22using namespace osgDB;
23
24bool checkBinary( std::istream* fin )
25{
26    unsigned int headerLow = 0, headerHigh = 0;
27    fin->read( (char*)&headerLow, INT_SIZE );
28    fin->read( (char*)&headerHigh, INT_SIZE );
29    if ( headerLow!=OSG_HEADER_LOW || headerHigh!=OSG_HEADER_HIGH )
30    {
31        fin->seekg( 0, std::ios::beg );
32        return false;
33    }
34    return true;
35}
36
37class ReaderWriterOSG2 : public osgDB::ReaderWriter
38{
39public:
40    ReaderWriterOSG2()
41    {
42        supportsExtension( "osg2", "OpenSceneGraph extendable format" );
43        supportsExtension( "osgt", "OpenSceneGraph extendable ascii format" );
44        supportsExtension( "osgb", "OpenSceneGraph extendable binary format" );
45       
46        supportsOption( "Ascii", "Import/Export option: Force the writer export ascii file" );
47        supportsOption( "SchemaFile=<file>", "Import/Export option: Use/Record a ascii schema file" );
48        supportsOption( "Compressor=<name>", "Export option: Use an inbuilt or user-defined compressor" );
49        supportsOption( "WriteImageHint=<hint>", "Export option: Hint of writing image to stream: "
50                        "<IncludeData> writes Image::data() directly; "
51                        "<IncludeFile> writes the image file itself to stream; "
52                        "<UseExternal> writes only the filename; "
53                        "<WriteOut> writes Image::data() to disk as external file." );
54
55        std::string filename = osgDB::Registry::instance()->createLibraryNameForExtension("serializers_osg");
56        if (osgDB::Registry::instance()->loadLibrary(filename)==osgDB::Registry::LOADED)
57        {
58            osg::notify(osg::NOTICE)<<"Constructor ReaderWriterOSG2 - loaded OK"<<std::endl;
59        }
60        else
61        {
62            osg::notify(osg::NOTICE)<<"Constructor ReaderWriterOSG2 - failed to load"<<std::endl;
63        }
64    }
65   
66    virtual const char* className() const
67    { return "OpenSceneGraph Native Format Reader/Writer"; }
68   
69    virtual ReadResult readObject( const std::string& file, const Options* options ) const
70    { return readNode(file, options); }
71   
72    virtual ReadResult readObject( std::istream& fin, const Options* options ) const
73    { return readNode(fin, options); }
74   
75    virtual ReadResult readImage( const std::string& file, const Options* options ) const
76    {
77        std::string ext = osgDB::getLowerCaseFileExtension( file );
78        if ( !acceptsExtension(ext) ) return ReadResult::FILE_NOT_HANDLED;
79        std::string fileName = osgDB::findDataFile( file, options );
80        if ( fileName.empty() ) return ReadResult::FILE_NOT_FOUND;
81       
82        osg::ref_ptr<Options> local_opt = options ?
83            static_cast<Options*>(options->clone(osg::CopyOp::SHALLOW_COPY)) : new Options;
84        local_opt->getDatabasePathList().push_front(osgDB::getFilePath(fileName));
85       
86        osgDB::ifstream istream( fileName.c_str(), std::ios::out|std::ios::binary );
87        return readImage( istream, local_opt.get() );
88    }
89   
90    virtual ReadResult readImage( std::istream& fin, const Options* options ) const
91    {
92        try
93        {
94            InputStream is( options );
95           
96            InputIterator* ii = NULL;
97            if ( !checkBinary(&fin) )
98                ii = new AsciiInputIterator(&fin);
99            else
100                ii = new BinaryInputIterator(&fin);
101           
102            if ( is.start(ii)!=InputStream::READ_IMAGE )
103                return ReadResult::FILE_NOT_HANDLED;
104            is.decompress();
105            return is.readImage();
106        }
107        catch ( InputException e )
108        {
109            return e.getError() + " At " + e.getField();
110        }
111    }
112   
113    virtual ReadResult readNode( const std::string& file, const Options* options ) const
114    {
115        std::string ext = osgDB::getLowerCaseFileExtension( file );
116        if ( !acceptsExtension(ext) ) return ReadResult::FILE_NOT_HANDLED;
117        std::string fileName = osgDB::findDataFile( file, options );
118        if ( fileName.empty() ) return ReadResult::FILE_NOT_FOUND;
119       
120        osg::ref_ptr<Options> local_opt = options ?
121            static_cast<Options*>(options->clone(osg::CopyOp::SHALLOW_COPY)) : new Options;
122        local_opt->getDatabasePathList().push_front(osgDB::getFilePath(fileName));
123       
124        osgDB::ifstream istream( fileName.c_str(), std::ios::out|std::ios::binary );
125        return readNode( istream, local_opt.get() );
126    }
127   
128    virtual ReadResult readNode( std::istream& fin, const Options* options ) const
129    {
130        try
131        {
132            InputStream is( options );
133           
134            InputIterator* ii = NULL;
135            if ( !checkBinary(&fin) )
136                ii = new AsciiInputIterator(&fin);
137            else
138                ii = new BinaryInputIterator(&fin);
139           
140            if ( is.start(ii)!=InputStream::READ_SCENE )
141                return ReadResult::FILE_NOT_HANDLED;
142            is.decompress();
143            return dynamic_cast<osg::Node*>( is.readObject() );
144        }
145        catch ( InputException e )
146        {
147            return e.getError() + " At " + e.getField();
148        }
149    }
150   
151    virtual WriteResult writeObject( const osg::Object& object, const std::string& fileName, const Options* options ) const
152    {
153        const osg::Node* node = dynamic_cast<const osg::Node*>( &object );
154        if ( node ) return writeNode( *node, fileName, options );
155       
156        const osg::Image* image = dynamic_cast<const osg::Image*>( &object );
157        if ( image ) return writeImage( *image, fileName, options );
158        return WriteResult::FILE_NOT_HANDLED;
159    }
160   
161    virtual WriteResult writeObject( const osg::Object& object, std::ostream& fout, const Options* options ) const
162    {
163        const osg::Node* node = dynamic_cast<const osg::Node*>( &object );
164        if ( node ) return writeNode( *node, fout, options );
165       
166        const osg::Image* image = dynamic_cast<const osg::Image*>( &object );
167        if ( image ) return writeImage( *image, fout, options );
168        return WriteResult::FILE_NOT_HANDLED;
169    }
170   
171    virtual WriteResult writeImage( const osg::Image& image, const std::string& fileName, const Options* options ) const
172    {
173        std::string ext = osgDB::getFileExtension( fileName );
174        if ( !acceptsExtension(ext) ) return WriteResult::FILE_NOT_HANDLED;
175       
176        osg::ref_ptr<Options> local_opt = options ?
177            static_cast<Options*>(options->clone(osg::CopyOp::SHALLOW_COPY)) : new Options;
178        if( local_opt->getDatabasePathList().empty() )
179            local_opt->setDatabasePath( osgDB::getFilePath(fileName) );
180        if ( ext=="osgt" ) local_opt->setOptionString( local_opt->getOptionString() + " Ascii" );
181       
182        osgDB::ofstream fout( fileName.c_str(), std::ios::out|std::ios::binary );
183        if ( !fout ) return WriteResult::ERROR_IN_WRITING_FILE;
184       
185        WriteResult result = writeImage( image, fout, local_opt.get() );
186        fout.close();
187        return result;
188    }
189   
190    virtual WriteResult writeImage( const osg::Image& image, std::ostream& fout, const Options* options ) const
191    {
192        try
193        {
194            OutputStream os( options );
195           
196            osgDB::OutputIterator* oi = NULL;
197            if ( options && options->getOptionString().find("Ascii")!=std::string::npos )
198                oi = new AsciiOutputIterator(&fout);
199            else
200                oi = new BinaryOutputIterator(&fout);
201           
202            os.start( oi, OutputStream::WRITE_IMAGE );
203            os.writeImage( &image );
204            os.compress( &fout );
205           
206            if ( fout.fail() ) return WriteResult::ERROR_IN_WRITING_FILE;
207            return WriteResult::FILE_SAVED;
208        }
209        catch ( OutputException e )
210        {
211            osg::notify(osg::WARN) << "ReaderWriterOSG2::writeImage(): " << e.getError()
212                                   << " At " << e.getField() << std::endl;
213        }
214        return WriteResult::FILE_NOT_HANDLED;
215    }
216   
217    virtual WriteResult writeNode( const osg::Node& node, const std::string& fileName, const Options* options ) const
218    {
219        std::string ext = osgDB::getFileExtension( fileName );
220        if ( !acceptsExtension(ext) ) return WriteResult::FILE_NOT_HANDLED;
221       
222        osg::ref_ptr<Options> local_opt = options ?
223            static_cast<Options*>(options->clone(osg::CopyOp::SHALLOW_COPY)) : new Options;
224        if ( local_opt->getDatabasePathList().empty() )
225            local_opt->setDatabasePath( osgDB::getFilePath(fileName) );
226        if ( ext=="osgt" ) local_opt->setOptionString( local_opt->getOptionString() + " Ascii" );
227       
228        osgDB::ofstream fout( fileName.c_str(), std::ios::out|std::ios::binary );
229        if ( !fout ) return WriteResult::ERROR_IN_WRITING_FILE;
230       
231        WriteResult result = writeNode( node, fout, local_opt.get() );
232        fout.close();
233        return result;
234    }
235   
236    virtual WriteResult writeNode( const osg::Node& node, std::ostream& fout, const Options* options ) const
237    {
238        try
239        {
240            OutputStream os( options );
241           
242            osgDB::OutputIterator* oi = NULL;
243            if ( options && options->getOptionString().find("Ascii")!=std::string::npos )
244                oi = new AsciiOutputIterator(&fout);
245            else
246                oi = new BinaryOutputIterator(&fout);
247           
248            os.start( oi, OutputStream::WRITE_SCENE );
249            os.writeObject( &node );
250            os.compress( &fout );
251           
252            if ( fout.fail() ) return WriteResult::ERROR_IN_WRITING_FILE;
253            return WriteResult::FILE_SAVED;
254        }
255        catch ( OutputException e )
256        {
257            osg::notify(osg::WARN) << "ReaderWriterOSG2::writeNode(): " << e.getError()
258                                   << " At " << e.getField() << std::endl;
259        }
260        return WriteResult::FILE_NOT_HANDLED;
261    }
262};
263
264REGISTER_OSGPLUGIN( osg2, ReaderWriterOSG2 )
Note: See TracBrowser for help on using the browser.