root/OpenSceneGraph/trunk/src/osgDB/InputStream.cpp @ 13788

Revision 13788, 28.9 kB (checked in by robert, 7 days ago)

Fixed comment

  • Property svn:eol-style set to native
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 <osg/Notify>
16#include <osg/ImageSequence>
17#include <osgDB/ReadFile>
18#include <osgDB/XmlParser>
19#include <osgDB/FileNameUtils>
20#include <osgDB/ObjectWrapper>
21
22using namespace osgDB;
23
24static std::string s_lastSchema;
25
26InputStream::InputStream( const osgDB::Options* options )
27    :   _fileVersion(0), _useSchemaData(false), _forceReadingImage(false), _dataDecompress(0)
28{
29    BEGIN_BRACKET.set( "{", +INDENT_VALUE );
30    END_BRACKET.set( "}", -INDENT_VALUE );
31
32    if ( !options ) return;
33    _options = options;
34
35    if ( options->getPluginStringData("ForceReadingImage")=="true" )
36        _forceReadingImage = true;
37
38    if ( !options->getPluginStringData("CustomDomains").empty() )
39    {
40        StringList domains, keyAndValue;
41        split( options->getPluginStringData("CustomDomains"), domains, ';' );
42        for ( unsigned int i=0; i<domains.size(); ++i )
43        {
44            split( domains[i], keyAndValue, ':' );
45            if ( keyAndValue.size()>1 )
46                _domainVersionMap[keyAndValue.front()] = atoi(keyAndValue.back().c_str());
47        }
48    }
49
50    std::string schema;
51    if ( !options->getPluginStringData("SchemaFile").empty() )
52    {
53        schema = options->getPluginStringData("SchemaFile");
54        if ( s_lastSchema!=schema )
55        {
56            osgDB::ifstream schemaStream( schema.c_str(), std::ios::in );
57            if ( !schemaStream.fail() ) readSchema( schemaStream );
58            schemaStream.close();
59            s_lastSchema = schema;
60        }
61    }
62
63    if ( schema.empty() )
64    {
65        resetSchema();
66        s_lastSchema.clear();
67    }
68}
69
70InputStream::~InputStream()
71{
72    if (_dataDecompress)
73        delete _dataDecompress;
74}
75
76int InputStream::getFileVersion( const std::string& d ) const
77{
78    if ( d.empty() ) return _fileVersion;
79    VersionMap::const_iterator itr = _domainVersionMap.find(d);
80    return itr==_domainVersionMap.end() ? 0 : itr->second;
81}
82
83InputStream& InputStream::operator>>( osg::Vec2b& v )
84{
85    char x, y; *this >> x >> y;
86    v.set( x, y );
87    return *this;
88}
89
90InputStream& InputStream::operator>>( osg::Vec3b& v )
91{
92    char x, y, z; *this >> x >> y >> z;
93    v.set( x, y, z );
94    return *this;
95}
96
97InputStream& InputStream::operator>>( osg::Vec4b& v )
98{
99    char x, y, z, w; *this >> x >> y >> z >> w;
100    v.set( x, y, z, w );
101    return *this;
102}
103
104InputStream& InputStream::operator>>( osg::Vec2ub& v )
105{
106    unsigned char x, y; *this >> x >> y;
107    v.set( x, y );
108    return *this;
109}
110
111InputStream& InputStream::operator>>( osg::Vec3ub& v )
112{
113    unsigned char x, y, z; *this >> x >> y >> z;
114    v.set( x, y, z );
115    return *this;
116}
117
118InputStream& InputStream::operator>>( osg::Vec4ub& v )
119{
120    unsigned char r, g, b, a; *this >> r >> g >> b >> a;
121    v.set( r, g, b, a );
122    return *this;
123}
124
125InputStream& InputStream::operator>>( osg::Vec2s& v )
126{ *this >> v.x() >> v.y(); return *this; }
127
128InputStream& InputStream::operator>>( osg::Vec3s& v )
129{ *this >> v.x() >> v.y() >> v.z(); return *this; }
130
131InputStream& InputStream::operator>>( osg::Vec4s& v )
132{ *this >> v.x() >> v.y() >> v.z() >> v.w(); return *this; }
133
134InputStream& InputStream::operator>>( osg::Vec2us& v )
135{ *this >> v.x() >> v.y(); return *this; }
136
137InputStream& InputStream::operator>>( osg::Vec3us& v )
138{ *this >> v.x() >> v.y() >> v.z(); return *this; }
139
140InputStream& InputStream::operator>>( osg::Vec4us& v )
141{ *this >> v.x() >> v.y() >> v.z() >> v.w(); return *this; }
142
143
144InputStream& InputStream::operator>>( osg::Vec2i& v )
145{ *this >> v.x() >> v.y(); return *this; }
146
147InputStream& InputStream::operator>>( osg::Vec3i& v )
148{ *this >> v.x() >> v.y() >> v.z(); return *this; }
149
150InputStream& InputStream::operator>>( osg::Vec4i& v )
151{ *this >> v.x() >> v.y() >> v.z() >> v.w(); return *this; }
152
153
154InputStream& InputStream::operator>>( osg::Vec2ui& v )
155{ *this >> v.x() >> v.y(); return *this; }
156
157InputStream& InputStream::operator>>( osg::Vec3ui& v )
158{ *this >> v.x() >> v.y() >> v.z(); return *this; }
159
160InputStream& InputStream::operator>>( osg::Vec4ui& v )
161{ *this >> v.x() >> v.y() >> v.z() >> v.w(); return *this; }
162
163
164InputStream& InputStream::operator>>( osg::Vec2f& v )
165{ *this >> v.x() >> v.y(); return *this; }
166
167InputStream& InputStream::operator>>( osg::Vec3f& v )
168{ *this >> v.x() >> v.y() >> v.z(); return *this; }
169
170InputStream& InputStream::operator>>( osg::Vec4f& v )
171{ *this >> v.x() >> v.y() >> v.z() >> v.w(); return *this; }
172
173
174InputStream& InputStream::operator>>( osg::Vec2d& v )
175{ *this >> v.x() >> v.y(); return *this; }
176
177InputStream& InputStream::operator>>( osg::Vec3d& v )
178{ *this >> v.x() >> v.y() >> v.z(); return *this; }
179
180InputStream& InputStream::operator>>( osg::Vec4d& v )
181{ *this >> v.x() >> v.y() >> v.z() >> v.w(); return *this; }
182
183
184InputStream& InputStream::operator>>( osg::Quat& q )
185{ *this >> q.x() >> q.y() >> q.z() >> q.w(); return *this; }
186
187InputStream& InputStream::operator>>( osg::Plane& p )
188{
189    double p0, p1, p2, p3; *this >> p0 >> p1 >> p2 >> p3;
190    p.set( p0, p1, p2, p3 ); return *this;
191}
192
193#if 0
194InputStream& InputStream::operator>>( osg::Matrixf& mat )
195{
196   ObjectProperty property("");
197   *this >> property  >> BEGIN_BRACKET;
198
199   if (property._name == "Matrixf")
200   {
201        // stream has same type as what we want to read so read directly
202        for ( int r=0; r<4; ++r )
203        {
204            *this >> mat(r, 0) >> mat(r, 1) >> mat(r, 2) >> mat(r, 3);
205        }
206   }
207   else if (property._name == "Matrixd")
208   {
209        // stream has different type than what we want to read so read stream into
210        // a temporary and then copy across to the final matrix
211        double value;
212        for ( int r=0; r<4; ++r )
213        {
214            for ( int c=0; c<4; ++c)
215            {
216                *this >> value;
217                mat(r,c) = static_cast<float>(value);
218            }
219        }
220   }
221
222   *this >> END_BRACKET;
223   return *this;
224}
225
226InputStream& InputStream::operator>>( osg::Matrixd& mat )
227{
228   ObjectProperty property("");
229   *this >> property  >> BEGIN_BRACKET;
230
231   if (property._name == "Matrixf")
232   {
233        // stream has different type than what we want to read so read stream into
234        // a temporary and then copy across to the final matrix
235        float value;
236        for ( int r=0; r<4; ++r )
237        {
238            for ( int c=0; c<4; ++c)
239            {
240                *this >> value;
241                mat(r,c) = static_cast<float>(value);
242            }
243        }
244   }
245   else if (property._name == "Matrixd")
246   {
247        // stream has same type as what we want to read so read directly
248        for ( int r=0; r<4; ++r )
249        {
250            *this >> mat(r, 0) >> mat(r, 1) >> mat(r, 2) >> mat(r, 3);
251        }
252   }
253
254   *this >> END_BRACKET;
255   return *this;
256}
257#else
258InputStream& InputStream::operator>>( osg::Matrixf& mat )
259{
260    *this >> BEGIN_BRACKET;
261
262    // stream has different type than what we want to read so read stream into
263    // a temporary and then copy across to the final matrix
264    double value;
265    for ( int r=0; r<4; ++r )
266    {
267        for ( int c=0; c<4; ++c)
268        {
269            *this >> value;
270            mat(r,c) = static_cast<float>(value);
271        }
272    }
273
274    *this >> END_BRACKET;
275    return *this;
276}
277
278InputStream& InputStream::operator>>( osg::Matrixd& mat )
279{
280    *this >> BEGIN_BRACKET;
281
282    for ( int r=0; r<4; ++r )
283    {
284        *this >> mat(r, 0) >> mat(r, 1) >> mat(r, 2) >> mat(r, 3);
285    }
286
287    *this >> END_BRACKET;
288    return *this;
289}
290#endif
291
292osg::Array* InputStream::readArray()
293{
294    osg::ref_ptr<osg::Array> array = NULL;
295
296    unsigned int id = 0;
297    *this >> PROPERTY("ArrayID") >> id;
298
299    ArrayMap::iterator itr = _arrayMap.find( id );
300    if ( itr!=_arrayMap.end() )
301    {
302        return itr->second.get();
303    }
304
305    DEF_MAPPEE(ArrayType, type);
306    *this >> type;
307    switch ( type.get() )
308    {
309    case ID_BYTE_ARRAY:
310        {
311            osg::ByteArray* ba = new osg::ByteArray;
312            readArrayImplementation( ba, 1, CHAR_SIZE);
313            array = ba;
314        }
315        break;
316    case ID_UBYTE_ARRAY:
317        {
318            osg::UByteArray* uba = new osg::UByteArray;
319            readArrayImplementation( uba, 1, CHAR_SIZE );
320            array = uba;
321        }
322        break;
323    case ID_SHORT_ARRAY:
324        {
325            osg::ShortArray* sa = new osg::ShortArray;
326            readArrayImplementation( sa, 1, SHORT_SIZE );
327            array = sa;
328        }
329        break;
330    case ID_USHORT_ARRAY:
331        {
332            osg::UShortArray* usa = new osg::UShortArray;
333            readArrayImplementation( usa, 1, SHORT_SIZE );
334            array = usa;
335        }
336        break;
337    case ID_INT_ARRAY:
338        {
339            osg::IntArray* ia = new osg::IntArray;
340            readArrayImplementation( ia, 1, INT_SIZE );
341            array = ia;
342        }
343        break;
344    case ID_UINT_ARRAY:
345        {
346            osg::UIntArray* uia = new osg::UIntArray;
347            readArrayImplementation( uia, 1, INT_SIZE );
348            array = uia;
349        }
350        break;
351    case ID_FLOAT_ARRAY:
352        {
353            osg::FloatArray* fa = new osg::FloatArray;
354            readArrayImplementation( fa, 1, FLOAT_SIZE );
355            array = fa;
356        }
357        break;
358    case ID_DOUBLE_ARRAY:
359        {
360            osg::DoubleArray* da = new osg::DoubleArray;
361            readArrayImplementation( da, 1, DOUBLE_SIZE );
362            array = da;
363        }
364        break;
365    case ID_VEC2B_ARRAY:
366        {
367            osg::Vec2bArray* va = new osg::Vec2bArray;
368            readArrayImplementation( va, 2, CHAR_SIZE );
369            array = va;
370        }
371        break;
372    case ID_VEC3B_ARRAY:
373        {
374            osg::Vec3bArray* va = new osg::Vec3bArray;
375            readArrayImplementation( va, 3, CHAR_SIZE );
376            array = va;
377        }
378        break;
379    case ID_VEC4B_ARRAY:
380        {
381            osg::Vec4bArray* va = new osg::Vec4bArray;
382            readArrayImplementation( va, 4, CHAR_SIZE );
383            array = va;
384        }
385        break;
386    case ID_VEC2UB_ARRAY:
387        {
388            osg::Vec2ubArray* va = new osg::Vec2ubArray;
389            readArrayImplementation( va, 2, CHAR_SIZE );
390            array = va;
391        }
392        break;
393    case ID_VEC3UB_ARRAY:
394        {
395            osg::Vec3ubArray* va = new osg::Vec3ubArray;
396            readArrayImplementation( va, 3, CHAR_SIZE );
397            array = va;
398        }
399        break;
400    case ID_VEC4UB_ARRAY:
401        {
402            osg::Vec4ubArray* va = new osg::Vec4ubArray;
403            readArrayImplementation( va, 4, CHAR_SIZE );
404            array = va;
405        }
406        break;
407    case ID_VEC2S_ARRAY:
408        {
409            osg::Vec2sArray* va = new osg::Vec2sArray;
410            readArrayImplementation( va, 2, SHORT_SIZE );
411            array = va;
412        }
413        break;
414    case ID_VEC3S_ARRAY:
415        {
416            osg::Vec3sArray* va = new osg::Vec3sArray;
417            readArrayImplementation( va, 3, SHORT_SIZE );
418            array = va;
419        }
420        break;
421    case ID_VEC4S_ARRAY:
422        {
423            osg::Vec4sArray* va = new osg::Vec4sArray;
424            readArrayImplementation( va, 4, SHORT_SIZE );
425            array = va;
426        }
427        break;
428    case ID_VEC2US_ARRAY:
429        {
430            osg::Vec2usArray* va = new osg::Vec2usArray;
431            readArrayImplementation( va, 2, SHORT_SIZE );
432            array = va;
433        }
434        break;
435    case ID_VEC3US_ARRAY:
436        {
437            osg::Vec3usArray* va = new osg::Vec3usArray;
438            readArrayImplementation( va, 3, SHORT_SIZE );
439            array = va;
440        }
441        break;
442    case ID_VEC4US_ARRAY:
443        {
444            osg::Vec4usArray* va = new osg::Vec4usArray;
445            readArrayImplementation( va, 4, SHORT_SIZE );
446            array = va;
447        }
448        break;
449    case ID_VEC2_ARRAY:
450        {
451            osg::Vec2Array* va = new osg::Vec2Array;
452            readArrayImplementation( va, 2, FLOAT_SIZE );
453            array = va;
454        }
455        break;
456    case ID_VEC3_ARRAY:
457        {
458            osg::Vec3Array* va = new osg::Vec3Array;
459            readArrayImplementation( va, 3, FLOAT_SIZE );
460            array = va;
461        }
462        break;
463    case ID_VEC4_ARRAY:
464        {
465            osg::Vec4Array* va = new osg::Vec4Array;
466            readArrayImplementation( va, 4, FLOAT_SIZE );
467            array = va;
468        }
469        break;
470    case ID_VEC2D_ARRAY:
471        {
472            osg::Vec2dArray* va = new osg::Vec2dArray;
473            readArrayImplementation( va, 2, DOUBLE_SIZE );
474            array = va;
475        }
476        break;
477    case ID_VEC3D_ARRAY:
478        {
479            osg::Vec3dArray* va = new osg::Vec3dArray;
480            readArrayImplementation( va, 3, DOUBLE_SIZE );
481            array = va;
482        }
483        break;
484    case ID_VEC4D_ARRAY:
485        {
486            osg::Vec4dArray* va = new osg::Vec4dArray;
487            readArrayImplementation( va, 4, DOUBLE_SIZE );
488            array = va;
489        }
490        break;
491
492    case ID_VEC2I_ARRAY:
493        {
494            osg::Vec2iArray* va = new osg::Vec2iArray;
495            readArrayImplementation( va, 2, INT_SIZE );
496            array = va;
497        }
498        break;
499    case ID_VEC3I_ARRAY:
500        {
501            osg::Vec3iArray* va = new osg::Vec3iArray;
502            readArrayImplementation( va, 3, INT_SIZE );
503            array = va;
504        }
505        break;
506    case ID_VEC4I_ARRAY:
507        {
508            osg::Vec4iArray* va = new osg::Vec4iArray;
509            readArrayImplementation( va, 4, INT_SIZE );
510            array = va;
511        }
512        break;
513
514    case ID_VEC2UI_ARRAY:
515        {
516            osg::Vec2uiArray* va = new osg::Vec2uiArray;
517            readArrayImplementation( va, 2, INT_SIZE );
518            array = va;
519        }
520        break;
521    case ID_VEC3UI_ARRAY:
522        {
523            osg::Vec3uiArray* va = new osg::Vec3uiArray;
524            readArrayImplementation( va, 3, INT_SIZE );
525            array = va;
526        }
527        break;
528    case ID_VEC4UI_ARRAY:
529        {
530            osg::Vec4uiArray* va = new osg::Vec4uiArray;
531            readArrayImplementation( va, 4, INT_SIZE );
532            array = va;
533        }
534        break;
535
536    default:
537        throwException( "InputStream::readArray(): Unsupported array type." );
538    }
539
540    if ( getException() ) return NULL;
541    _arrayMap[id] = array;
542
543    return array.release();
544}
545
546osg::PrimitiveSet* InputStream::readPrimitiveSet()
547{
548    osg::ref_ptr<osg::PrimitiveSet> primitive = NULL;
549
550    DEF_MAPPEE(PrimitiveType, type);
551    DEF_MAPPEE(PrimitiveType, mode);
552    unsigned int numInstances = 0u;
553    *this >> type >> mode;
554    if ( _fileVersion>96 )
555    {
556        *this >> numInstances;
557    }
558
559    switch ( type.get() )
560    {
561    case ID_DRAWARRAYS:
562        {
563            int first = 0, count = 0;
564            *this >> first >> count;
565            osg::DrawArrays* da = new osg::DrawArrays( mode.get(), first, count );
566            primitive = da;
567            primitive->setNumInstances( numInstances );
568        }
569        break;
570    case ID_DRAWARRAY_LENGTH:
571        {
572            int first = 0, value = 0; unsigned int size = 0;
573            *this >> first >> size >> BEGIN_BRACKET;
574            osg::DrawArrayLengths* dl = new osg::DrawArrayLengths( mode.get(), first );
575            for ( unsigned int i=0; i<size; ++i )
576            {
577                *this >> value;
578                dl->push_back( value );
579            }
580            *this >> END_BRACKET;
581            primitive = dl;
582            primitive->setNumInstances( numInstances );
583        }
584        break;
585    case ID_DRAWELEMENTS_UBYTE:
586        {
587            osg::DrawElementsUByte* de = new osg::DrawElementsUByte( mode.get() );
588            unsigned int size = 0; unsigned char value = 0;
589            *this >> size >> BEGIN_BRACKET;
590            for ( unsigned int i=0; i<size; ++i )
591            {
592                *this >> value;
593                de->push_back( value );
594            }
595            *this >> END_BRACKET;
596            primitive = de;
597            primitive->setNumInstances( numInstances );
598        }
599        break;
600    case ID_DRAWELEMENTS_USHORT:
601        {
602            osg::DrawElementsUShort* de = new osg::DrawElementsUShort( mode.get() );
603            unsigned int size = 0; unsigned short value = 0;
604            *this >> size >> BEGIN_BRACKET;
605            for ( unsigned int i=0; i<size; ++i )
606            {
607                *this >> value;
608                de->push_back( value );
609            }
610            *this >> END_BRACKET;
611            primitive = de;
612            primitive->setNumInstances( numInstances );
613        }
614        break;
615    case ID_DRAWELEMENTS_UINT:
616        {
617            osg::DrawElementsUInt* de = new osg::DrawElementsUInt( mode.get() );
618            unsigned int size = 0, value = 0;
619            *this >> size >> BEGIN_BRACKET;
620            for ( unsigned int i=0; i<size; ++i )
621            {
622                *this >> value;
623                de->push_back( value );
624            }
625            *this >> END_BRACKET;
626            primitive = de;
627            primitive->setNumInstances( numInstances );
628        }
629        break;
630    default:
631        throwException( "InputStream::readPrimitiveSet(): Unsupported array type." );
632    }
633
634    if ( getException() ) return NULL;
635    return primitive.release();
636}
637
638osg::Image* InputStream::readImage(bool readFromExternal)
639{
640    std::string className = "osg::Image";
641    if ( _fileVersion>94 )  // ClassName property is only supported in 3.1.4 and higher
642        *this >> PROPERTY("ClassName") >> className;
643
644    unsigned int id = 0;
645    *this >> PROPERTY("UniqueID") >> id;
646    if ( getException() ) return NULL;
647
648    IdentifierMap::iterator itr = _identifierMap.find( id );
649    if ( itr!=_identifierMap.end() )
650    {
651        return static_cast<osg::Image*>( itr->second.get() );
652    }
653
654    std::string name;
655    int writeHint, decision = IMAGE_EXTERNAL;
656    *this >> PROPERTY("FileName"); readWrappedString(name);
657    *this >> PROPERTY("WriteHint") >> writeHint >> decision;
658    if ( getException() ) return NULL;
659
660    osg::ref_ptr<osg::Image> image = NULL;
661    switch ( decision )
662    {
663    case IMAGE_INLINE_DATA:
664        if ( isBinary() )
665        {
666            // _origin, _s & _t & _r, _internalTextureFormat
667            int origin, s, t, r, internalFormat;
668            *this >> origin >> s >> t >> r >> internalFormat;
669
670            // _pixelFormat, _dataType, _packing, _allocationMode
671            int pixelFormat, dataType, packing, mode;
672            *this >> pixelFormat >> dataType >> packing >> mode;
673
674            // _data
675            unsigned int size = 0; *this >> size;
676            if ( size )
677            {
678                char* data = new char[size];
679                if ( !data )
680                    throwException( "InputStream::readImage() Out of memory." );
681                if ( getException() ) return NULL;
682
683                readCharArray( data, size );
684                image = new osg::Image;
685                image->setOrigin( (osg::Image::Origin)origin );
686                image->setImage( s, t, r, internalFormat, pixelFormat, dataType,
687                    (unsigned char*)data, (osg::Image::AllocationMode)mode, packing );
688            }
689
690            // _mipmapData
691            unsigned int levelSize = readSize();
692            osg::Image::MipmapDataType levels(levelSize);
693            for ( unsigned int i=0; i<levelSize; ++i )
694            {
695                *this >> levels[i];
696            }
697            if ( image && levelSize>0 )
698                image->setMipmapLevels( levels );
699            readFromExternal = false;
700        }
701        break;
702    case IMAGE_INLINE_FILE:
703        if ( isBinary() )
704        {
705            unsigned int size = readSize();
706            if ( size>0 )
707            {
708                char* data = new char[size];
709                if ( !data )
710                {
711                    throwException( "InputStream::readImage(): Out of memory." );
712                    if ( getException() ) return NULL;
713                }
714                readCharArray( data, size );
715
716                std::string ext = osgDB::getFileExtension( name );
717                osgDB::ReaderWriter* reader =
718                    osgDB::Registry::instance()->getReaderWriterForExtension( ext );
719                if ( reader )
720                {
721                    std::stringstream inputStream;
722                    inputStream.write( data, size );
723
724                    osgDB::ReaderWriter::ReadResult rr = reader->readImage( inputStream );
725                    if ( rr.validImage() )
726                        image = rr.takeImage();
727                    else
728                    {
729                        OSG_WARN << "InputStream::readImage(): "
730                                               << rr.message() << std::endl;
731                    }
732                }
733                else
734                {
735                    OSG_WARN << "InputStream::readImage(): Unable to find a plugin for "
736                                           << ext << std::endl;
737                }
738                delete[] data;
739            }
740            readFromExternal = false;
741        }
742        break;
743    case IMAGE_EXTERNAL: case IMAGE_WRITE_OUT:
744        break;
745    default:
746        break;
747    }
748
749    if ( readFromExternal && !name.empty() )
750    {
751        image = osgDB::readImageFile( name, getOptions() );
752        if ( !image && _forceReadingImage ) image = new osg::Image;
753    }
754
755    image = static_cast<osg::Image*>( readObjectFields(className, id, image.get()) );
756    if ( image.valid() )
757    {
758        image->setFileName( name );
759        image->setWriteHint( (osg::Image::WriteHint)writeHint );
760    }
761    return image.release();
762}
763
764osg::Object* InputStream::readObject( osg::Object* existingObj )
765{
766    std::string className;
767    unsigned int id = 0;
768    *this >> className >> BEGIN_BRACKET >> PROPERTY("UniqueID") >> id;
769    if ( getException() ) return NULL;
770
771    IdentifierMap::iterator itr = _identifierMap.find( id );
772    if ( itr!=_identifierMap.end() )
773    {
774        advanceToCurrentEndBracket();
775        return itr->second.get();
776    }
777
778    osg::ref_ptr<osg::Object> obj = readObjectFields( className, id, existingObj );
779
780    advanceToCurrentEndBracket();
781
782    return obj.release();
783}
784
785osg::Object* InputStream::readObjectFields( const std::string& className, unsigned int id, osg::Object* existingObj )
786{
787    ObjectWrapper* wrapper = Registry::instance()->getObjectWrapperManager()->findWrapper( className );
788    if ( !wrapper )
789    {
790        OSG_WARN << "InputStream::readObject(): Unsupported wrapper class "
791                               << className << std::endl;
792        return NULL;
793    }
794
795    osg::ref_ptr<osg::Object> obj = existingObj ? existingObj : wrapper->getProto()->cloneType();
796    _identifierMap[id] = obj;
797    if ( obj.valid() )
798    {
799        const StringList& associates = wrapper->getAssociates();
800        for ( StringList::const_iterator itr=associates.begin(); itr!=associates.end(); ++itr )
801        {
802            ObjectWrapper* assocWrapper = Registry::instance()->getObjectWrapperManager()->findWrapper(*itr);
803            if ( !assocWrapper )
804            {
805                OSG_WARN << "InputStream::readObject(): Unsupported associated class "
806                                       << *itr << std::endl;
807                continue;
808            }
809            _fields.push_back( assocWrapper->getName() );
810            assocWrapper->read( *this, *obj );
811            if ( getException() ) return NULL;
812
813            _fields.pop_back();
814        }
815    }
816    return obj.release();
817}
818
819void InputStream::readSchema( std::istream& fin )
820{
821    // Read from external ascii stream
822    std::string line;
823    while ( std::getline(fin, line) )
824    {
825        if ( line[0]=='#' ) continue// Comment
826
827        StringList keyAndValue;
828        split( line, keyAndValue, '=' );
829        if ( keyAndValue.size()<2 ) continue;
830
831        setWrapperSchema( osgDB::trimEnclosingSpaces(keyAndValue[0]),
832                          osgDB::trimEnclosingSpaces(keyAndValue[1]) );
833    }
834}
835
836InputStream::ReadType InputStream::start( InputIterator* inIterator )
837{
838    _fields.clear();
839    _fields.push_back( "Start" );
840
841    ReadType type = READ_UNKNOWN;
842    _in = inIterator;
843    if ( !_in )
844        throwException( "InputStream: Null stream specified." );
845    if ( getException() ) return type;
846
847    _in->setInputStream(this);
848
849    // Check OSG header information
850    unsigned int version = 0;
851    if ( isBinary() )
852    {
853        unsigned int typeValue;
854        *this >> typeValue >> version;
855        type = static_cast<ReadType>(typeValue);
856
857        unsigned int attributes; *this >> attributes;
858        if ( attributes&0x4 ) inIterator->setSupportBinaryBrackets( true );
859        if ( attributes&0x2 ) _useSchemaData = true;
860
861        // Record custom domains
862        if ( attributes&0x1 )
863        {
864            unsigned int numDomains; *this >> numDomains;
865            for ( unsigned int i=0; i<numDomains; ++i )
866            {
867                std::string domainName; *this >> domainName;
868                int domainVersion; *this >> domainVersion;
869                _domainVersionMap[domainName] = domainVersion;
870            }
871        }
872    }
873    if ( !isBinary() )
874    {
875        std::string typeString; *this >> typeString;
876        if ( typeString=="Scene" ) type = READ_SCENE;
877        else if ( typeString=="Image" ) type = READ_IMAGE;
878        else if ( typeString=="Object" ) type = READ_OBJECT;
879
880        std::string osgName, osgVersion;
881        *this >> PROPERTY("#Version") >> version;
882        *this >> PROPERTY("#Generator") >> osgName >> osgVersion;
883
884        while ( matchString("#CustomDomain") )
885        {
886            std::string domainName; *this >> domainName;
887            int domainVersion; *this >> domainVersion;
888            _domainVersionMap[domainName] = domainVersion;
889        }
890    }
891
892    // Record file version for back-compatibility checking of wrappers
893    _fileVersion = version;
894    _fields.pop_back();
895    return type;
896}
897
898void InputStream::decompress()
899{
900    if ( !isBinary() ) return;
901    _fields.clear();
902
903    std::string compressorName; *this >> compressorName;
904    if ( compressorName!="0" )
905    {
906        std::string data;
907        _fields.push_back( "Decompression" );
908
909        BaseCompressor* compressor = Registry::instance()->getObjectWrapperManager()->findCompressor(compressorName);
910        if ( !compressor )
911        {
912            OSG_WARN << "InputStream::decompress(): No such compressor "
913                                   << compressorName << std::endl;
914        }
915
916        if ( !compressor->decompress(*(_in->getStream()), data) )
917            throwException( "InputStream: Failed to decompress stream." );
918        if ( getException() ) return;
919
920        _dataDecompress = new std::stringstream(data);
921        _in->setStream( _dataDecompress );
922        _fields.pop_back();
923    }
924
925    if ( _useSchemaData )
926    {
927        _fields.push_back( "SchemaData" );
928        std::string schemaSource; *this >> schemaSource;
929        std::istringstream iss( schemaSource );
930        readSchema( iss );
931        _fields.pop_back();
932    }
933}
934
935// PROTECTED METHODS
936
937void InputStream::setWrapperSchema( const std::string& name, const std::string& properties )
938{
939    ObjectWrapper* wrapper = Registry::instance()->getObjectWrapperManager()->findWrapper(name);
940    if ( !wrapper )
941    {
942        OSG_WARN << "InputStream::setSchema(): Unsupported wrapper class "
943                               << name << std::endl;
944        return;
945    }
946
947    StringList schema, methods, keyAndValue;
948    std::vector<int> types;
949    split( properties, schema );
950    for ( StringList::iterator itr=schema.begin(); itr!=schema.end(); ++itr )
951    {
952        split( *itr, keyAndValue, ':' );
953        if ( keyAndValue.size()>1 )
954        {
955            methods.push_back( keyAndValue.front() );
956            types.push_back( atoi(keyAndValue.back().c_str()) );
957        }
958        else
959        {
960            methods.push_back( *itr );
961            types.push_back( 0 );
962        }
963        keyAndValue.clear();
964    }
965    wrapper->readSchema( methods, types );
966}
967
968void InputStream::resetSchema()
969{
970    const ObjectWrapperManager::WrapperMap& wrappers = Registry::instance()->getObjectWrapperManager()->getWrapperMap();
971    for ( ObjectWrapperManager::WrapperMap::const_iterator itr=wrappers.begin();
972          itr!=wrappers.end(); ++itr )
973    {
974        ObjectWrapper* wrapper = itr->second.get();
975        wrapper->resetSchema();
976    }
977}
978
979template<typename T>
980void InputStream::readArrayImplementation( T* a, unsigned int numComponentsPerElements, unsigned int componentSizeInBytes )
981{
982    int size = 0;
983    *this >> size >> BEGIN_BRACKET;
984    if ( size )
985    {
986        a->resize( size );
987        if ( isBinary() )
988        {
989            readComponentArray( (char*)&((*a)[0]), size, numComponentsPerElements, componentSizeInBytes );
990            checkStream();
991        }
992        else
993        {
994            for ( int i=0; i<size; ++i )
995                *this >> (*a)[i];
996        }
997    }
998    *this >> END_BRACKET;
999}
Note: See TracBrowser for help on using the browser.