/********************************************************************** * * FILE: DataOutputStream.cpp * * DESCRIPTION: Implements methods to write simple datatypes to an * output stream. * * CREATED BY: Rune Schmidt Jensen * * HISTORY: Created 11.03.2003 * Updated for 1D textures - Don Burns 27.1.2004 * Updated for light model - Stan Blinov at 25 august 7512 from World Creation (7.09.2004) * * Copyright 2003 VR-C **********************************************************************/ #include "DataOutputStream.h" #include "Exception.h" #include "StateSet.h" #include "AlphaFunc.h" #include "BlendFunc.h" #include "Material.h" #include "CullFace.h" #include "Depth.h" #include "ClipPlane.h" #include "PolygonOffset.h" #include "PolygonMode.h" #include "ShadeModel.h" #include "Point.h" #include "LineWidth.h" #include "Texture1D.h" #include "Texture2D.h" #include "Texture3D.h" #include "TextureCubeMap.h" #include "TextureRectangle.h" #include "TexEnv.h" #include "TexEnvCombine.h" #include "TexGen.h" #include "TexMat.h" #include "FragmentProgram.h" #include "VertexProgram.h" #include "LightModel.h" #include "ProxyNode.h" #include "FrontFace.h" #include "Program.h" #include "Uniform.h" #include "Shader.h" #include "Viewport.h" #include "Scissor.h" #include "Image.h" #include "Group.h" #include "MatrixTransform.h" #include "CameraNode.h" #include "CameraView.h" #include "Geode.h" #include "LightSource.h" #include "TexGenNode.h" #include "ClipNode.h" #include "Billboard.h" #include "Sequence.h" #include "LOD.h" #include "PagedLOD.h" #include "PositionAttitudeTransform.h" #include "AutoTransform.h" #include "DOFTransform.h" #include "Transform.h" #include "Switch.h" #include "OccluderNode.h" #include "Impostor.h" #include "CoordinateSystemNode.h" #include "LightPointNode.h" #include "MultiSwitch.h" #include "VisibilityGroup.h" #include "MultiTextureControl.h" #include "Geometry.h" #include "ShapeDrawable.h" #include "Shape.h" #include "Text.h" #include #include #include #include #include using namespace ive; void DataOutputStream::setOptions(const osgDB::ReaderWriter::Options* options) { _options = options; if (_options.get()) { if(_options->getOptionString().find("noTexturesInIVEFile")!=std::string::npos) { setIncludeImageMode(IMAGE_REFERENCE_FILE); } else if(_options->getOptionString().find("includeImageFileInIVEFile")!=std::string::npos) { setIncludeImageMode(IMAGE_INCLUDE_FILE); } else if(_options->getOptionString().find("compressImageData")!=std::string::npos) { setIncludeImageMode(IMAGE_COMPRESS_DATA); } osg::notify(osg::DEBUG_INFO) << "ive::DataOutpouStream.setIncludeImageMode()=" << getIncludeImageMode() << std::endl; setIncludeExternalReferences(_options->getOptionString().find("inlineExternalReferencesInIVEFile")!=std::string::npos); osg::notify(osg::DEBUG_INFO) << "ive::DataOutpouStream.setIncludeExternalReferences()=" << getIncludeExternalReferences() << std::endl; setWriteExternalReferenceFiles(_options->getOptionString().find("noWriteExternalReferenceFiles")==std::string::npos); osg::notify(osg::DEBUG_INFO) << "ive::DataOutpouStream.setWriteExternalReferenceFiles()=" << getWriteExternalReferenceFiles() << std::endl; setUseOriginalExternalReferences(_options->getOptionString().find("useOriginalExternalReferences")!=std::string::npos); osg::notify(osg::DEBUG_INFO) << "ive::DataOutpouStream.setUseOriginalExternalReferences()=" << getUseOriginalExternalReferences() << std::endl; } } DataOutputStream::DataOutputStream(std::ostream * ostream) { _verboseOutput = false; _includeImageMode = IMAGE_INCLUDE_DATA; _includeExternalReferences = false; _writeExternalReferenceFiles = false; _useOriginalExternalReferences = true; _ostream = ostream; if(!_ostream) throw Exception("DataOutputStream::DataOutputStream(): null pointer exception in argument."); writeUInt(ENDIAN_TYPE) ; writeUInt(getVersion()); } DataOutputStream::~DataOutputStream(){} void DataOutputStream::writeBool(bool b) { char c = b?1:0; _ostream->write(&c, CHARSIZE); if (_verboseOutput) std::cout<<"read/writeBool() ["<<(int)c<<"]"<write(&c, CHARSIZE); if (_verboseOutput) std::cout<<"read/writeChar() ["<<(int)c<<"]"<write((char*)&c, CHARSIZE); if (_verboseOutput) std::cout<<"read/writeUChar() ["<<(int)c<<"]"<write((char*)&s, SHORTSIZE); if (_verboseOutput) std::cout<<"read/writeUShort() ["<write((char*)&s, SHORTSIZE); if (_verboseOutput) std::cout<<"read/writeShort() ["<write((char*)&s, INTSIZE); if (_verboseOutput) std::cout<<"read/writeUInt() ["<write((char*)&i, INTSIZE); if (_verboseOutput) std::cout<<"read/writeInt() ["<write((char*)&f, FLOATSIZE); if (_verboseOutput) std::cout<<"read/writeFloat() ["<write((char*)&l, LONGSIZE); if (_verboseOutput) std::cout<<"read/writeLong() ["<write((char*)&l, LONGSIZE); if (_verboseOutput) std::cout<<"read/writeULong() ["<write((char*)&d, DOUBLESIZE); if (_verboseOutput) std::cout<<"read/writeDouble() ["<write(s.c_str(), s.size()); if (_verboseOutput) std::cout<<"read/writeString() ["<write(data, size); if (_verboseOutput) std::cout<<"read/writeCharArray() ["<getType()){ case osg::Array::IntArrayType: writeChar((char)0); writeIntArray(static_cast(a)); break; case osg::Array::UByteArrayType: writeChar((char)1); writeUByteArray(static_cast(a)); break; case osg::Array::UShortArrayType: writeChar((char)2); writeUShortArray(static_cast(a)); break; case osg::Array::UIntArrayType: writeChar((char)3); writeUIntArray(static_cast(a)); break; case osg::Array::Vec4ubArrayType: writeChar((char)4); writeVec4ubArray(static_cast(a)); break; case osg::Array::FloatArrayType: writeChar((char)5); writeFloatArray(static_cast(a)); break; case osg::Array::Vec2ArrayType: writeChar((char)6); writeVec2Array(static_cast(a)); break; case osg::Array::Vec3ArrayType: writeChar((char)7); writeVec3Array(static_cast(a)); break; case osg::Array::Vec4ArrayType: writeChar((char)8); writeVec4Array(static_cast(a)); break; case osg::Array::Vec2sArrayType: writeChar((char)9); writeVec2sArray(static_cast(a)); break; case osg::Array::Vec3sArrayType: writeChar((char)10); writeVec3sArray(static_cast(a)); break; case osg::Array::Vec4sArrayType: writeChar((char)11); writeVec4sArray(static_cast(a)); break; case osg::Array::Vec2bArrayType: writeChar((char)12); writeVec2bArray(static_cast(a)); break; case osg::Array::Vec3bArrayType: writeChar((char)13); writeVec3bArray(static_cast(a)); break; case osg::Array::Vec4bArrayType: writeChar((char)14); writeVec4bArray(static_cast(a)); break; default: throw Exception("Unknown array type in DataOutputStream::writeArray()"); } } void DataOutputStream::writeIntArray(const osg::IntArray* a) { int size = a->getNumElements(); writeInt(size); for(int i =0; iindex(i)); } if (_verboseOutput) std::cout<<"read/writeIntArray() ["<getNumElements(); writeInt(size); for(int i =0; igetNumElements(); writeInt(size); for(int i =0; igetNumElements(); writeInt(size); for(int i =0; igetNumElements(); writeInt(size); for(int i =0; igetNumElements(); writeInt(size); for(int i =0; isize(); writeInt(size); for(int i=0;isize(); writeInt(size); for(int i = 0; i < size; i++){ writeVec3((*a)[i]); } if (_verboseOutput) std::cout<<"read/writeVec3Array() ["<size(); writeInt(size); for(int i=0;igetNumElements(); writeInt(size); for(int i =0; igetNumElements(); writeInt(size); for(int i =0; igetNumElements(); writeInt(size); for(int i =0; igetNumElements(); writeInt(size); for(int i =0; igetNumElements(); writeInt(size); for(int i =0; igetNumElements(); writeInt(size); for(int i =0; isecond); if (_verboseOutput) std::cout<<"read/writeStateSet() ["<second<<"]"<write(this); if (_verboseOutput) std::cout<<"read/writeStateSet() ["<second); if (_verboseOutput) std::cout<<"read/writeStateAttribute() ["<second<<"]"<(attribute)){ ((ive::AlphaFunc*)(attribute))->write(this); } else if(dynamic_cast(attribute)){ ((ive::BlendFunc*)(attribute))->write(this); } else if(dynamic_cast(attribute)){ ((ive::Depth*)(attribute))->write(this); } else if(dynamic_cast(attribute)){ ((ive::Viewport*)(attribute))->write(this); } else if(dynamic_cast(attribute)){ ((ive::Scissor*)(attribute))->write(this); } // This is a Material else if(dynamic_cast(attribute)){ ((ive::Material*)(attribute))->write(this); } // This is a CullFace else if(dynamic_cast(attribute)){ ((ive::CullFace*)(attribute))->write(this); } // this is a Cliplane else if(dynamic_cast(attribute)){ ((ive::ClipPlane*)(attribute))->write(this); } // This is a PolygonOffset else if(dynamic_cast(attribute)){ ((ive::PolygonOffset*)(attribute))->write(this); } // This is a PolygonMode else if(dynamic_cast(attribute)){ ((ive::PolygonMode*)(attribute))->write(this); } else if(dynamic_cast(attribute)){ ((ive::ShadeModel*)(attribute))->write(this); } else if(dynamic_cast(attribute)){ ((ive::Point*)(attribute))->write(this); } else if(dynamic_cast(attribute)){ ((ive::LineWidth*)(attribute))->write(this); } else if(dynamic_cast(attribute)){ ((ive::LineWidth*)(attribute))->write(this); } // This is a Texture1D else if(dynamic_cast(attribute)){ ((ive::Texture1D*)(attribute))->write(this); } // This is a Texture2D else if(dynamic_cast(attribute)){ ((ive::Texture2D*)(attribute))->write(this); } // This is a Texture2D else if(dynamic_cast(attribute)){ ((ive::Texture3D*)(attribute))->write(this); } // This is a TextureCubeMap else if(dynamic_cast(attribute)){ ((ive::TextureCubeMap*)(attribute))->write(this); } // This is a TextureRectangle else if(dynamic_cast(attribute)){ ((ive::TextureRectangle*)(attribute))->write(this); } // This is a TexEnv else if(dynamic_cast(attribute)){ ((ive::TexEnv*)(attribute))->write(this); } // This is a TexEnvCombine else if(dynamic_cast(attribute)){ ((ive::TexEnvCombine*)(attribute))->write(this); } // This is a TexGen else if(dynamic_cast(attribute)){ ((ive::TexGen*)(attribute))->write(this); } // This is a TexMat else if(dynamic_cast(attribute)){ ((ive::TexMat*)(attribute))->write(this); } // This is a FragmentProgram else if(dynamic_cast(attribute)){ ((ive::FragmentProgram*)(attribute))->write(this); } // This is a VertexProgram else if(dynamic_cast(attribute)){ ((ive::VertexProgram*)(attribute))->write(this); } // This is a LightModel else if(dynamic_cast(attribute)){ ((ive::LightModel*)(attribute))->write(this); } // This is a FrontFace else if(dynamic_cast(attribute)){ ((ive::FrontFace*)(attribute))->write(this); } // This is a FrontFace else if(dynamic_cast(attribute)){ ((ive::Program*)(attribute))->write(this); } else{ std::string className = attribute->className(); throw Exception(std::string("StateSet::write(): Unknown StateAttribute: ").append(className)); } if (_verboseOutput) std::cout<<"read/writeStateAttribute() ["<second); if (_verboseOutput) std::cout<<"read/writeUniform() ["<second<<"]"<write(this); if (_verboseOutput) std::cout<<"read/writeUniform() ["<second); if (_verboseOutput) std::cout<<"read/writeShader() ["<second<<"]"<write(this); if (_verboseOutput) std::cout<<"read/writeShader() ["<second); if (_verboseOutput) std::cout<<"read/writeDrawable() ["<second<<"]"<(drawable)) ((ive::Geometry*)(drawable))->write(this); else if(dynamic_cast(drawable)) ((ive::ShapeDrawable*)(drawable))->write(this); else if(dynamic_cast(drawable)) ((ive::Text*)(drawable))->write(this); else { throw Exception("Unknown drawable in DataOutputStream::writeDrawable()"); } if (_verboseOutput) std::cout<<"read/writeDrawable() ["<second); if (_verboseOutput) std::cout<<"read/writeShape() ["<second<<"]"<(shape)) ((ive::Sphere*)(shape))->write(this); else if(dynamic_cast(shape)) ((ive::Box*)(shape))->write(this); else if(dynamic_cast(shape)) ((ive::Cone*)(shape))->write(this); else if(dynamic_cast(shape)) ((ive::Cylinder*)(shape))->write(this); else if(dynamic_cast(shape)) ((ive::Capsule*)(shape))->write(this); else if(dynamic_cast(shape)) ((ive::HeightField*)(shape))->write(this); else { throw Exception("Unknown shape in DataOutputStream::writeShape()"); } if (_verboseOutput) std::cout<<"read/writeShape() ["<second); if (_verboseOutput) std::cout<<"read/writeNode() ["<second<<"]"<(node)){ ((ive::MatrixTransform*)(node))->write(this); } else if(dynamic_cast(node)){ ((ive::CameraNode*)(node))->write(this); } else if(dynamic_cast(node)){ ((ive::CameraView*)(node))->write(this); } else if(dynamic_cast(node)){ ((ive::PositionAttitudeTransform*)(node))->write(this); } else if(dynamic_cast(node)){ ((ive::AutoTransform*)(node))->write(this); } else if(dynamic_cast(node)){ ((ive::DOFTransform*)(node))->write(this); } else if(dynamic_cast(node)){ ((ive::LightSource*)(node))->write(this); } else if(dynamic_cast(node)){ ((ive::TexGenNode*)(node))->write(this); } else if(dynamic_cast(node)){ ((ive::ClipNode*)(node))->write(this); } else if(dynamic_cast(node)){ ((ive::Sequence*)(node))->write(this); } else if(dynamic_cast(node)){ ((ive::Impostor*)(node))->write(this); } else if(dynamic_cast(node)){ ((ive::PagedLOD*)(node))->write(this); } else if(dynamic_cast(node)){ ((ive::LOD*)(node))->write(this); } else if(dynamic_cast(node)){ ((ive::Switch*)(node))->write(this); } else if(dynamic_cast(node)){ ((ive::CoordinateSystemNode*)(node))->write(this); } else if(dynamic_cast(node)){ ((ive::MultiSwitch*)(node))->write(this); } else if(dynamic_cast(node)){ ((ive::OccluderNode*)(node))->write(this); } else if(dynamic_cast(node)){ ((ive::Transform*)(node))->write(this); } else if(dynamic_cast(node)){ ((ive::VisibilityGroup*)(node))->write(this); } else if(dynamic_cast(node)){ ((ive::ProxyNode*)(node))->write(this); } else if(dynamic_cast(node)){ ((ive::MultiTextureControl*)(node))->write(this); } else if(dynamic_cast(node)){ ((ive::Group*)(node))->write(this); } else if(dynamic_cast(node)){ ((ive::Billboard*)(node))->write(this); } else if(dynamic_cast(node)){ ((ive::Geode*)(node))->write(this); } else if(dynamic_cast(node)){ ((ive::LightPointNode*)(node))->write(this); } else throw Exception("Unknown node in Group::write()"); if (_verboseOutput) std::cout<<"read/writeNode() ["<write(this); break; case IMAGE_REFERENCE_FILE: // Only include image name in stream if (image && !(image->getFileName().empty())){ writeString(image->getFileName()); } else{ writeString(""); } break; case IMAGE_INCLUDE_FILE: // Include image file in stream if(image && !(image->getFileName().empty())) { std::string fullPath = osgDB::findDataFile(image->getFileName(),_options.get()); std::ifstream infile(fullPath.c_str(), std::ios::in | std::ios::binary); if(infile) { //Write filename writeString(image->getFileName()); //Get size of file infile.seekg(0,std::ios::end); int size = infile.tellg(); infile.seekg(0,std::ios::beg); //Write file size writeInt(size); //Read file data char *buffer = new char[size]; infile.read(buffer,size); //Write file data writeCharArray(buffer,size); //Delete buffer delete [] buffer; //Close file infile.close(); } else { writeString(""); writeInt(0); } } else{ writeString(""); writeInt(0); } break; case IMAGE_COMPRESS_DATA: if(image) { //Get ReaderWriter for jpeg images std::string extension = "png"; if (image->getPixelFormat()==GL_RGB) extension = "jpg"; osgDB::ReaderWriter* writer = osgDB::Registry::instance()->getReaderWriterForExtension(extension); if(writer) { //Attempt to write the image to an output stream. //The reason this isn't performed directly on the internal _ostream //is because the writer might perform seek operations which could //corrupt the output stream. std::stringstream outputStream; osgDB::ReaderWriter::WriteResult wr; wr = writer->writeImage(*image,outputStream,_options.get()); if(wr.success()) { //Write file format. Do this for two reasons: // 1 - Same code can be used to read in as with IMAGE_INCLUDE_FILE mode // 2 - Maybe in future version user can specify which format to use writeString(std::string(".")+extension); //Need to add dot so osgDB::getFileExtension will work //Write size of stream int size = outputStream.tellp(); writeInt(size); //Write stream writeCharArray(outputStream.str().c_str(),size); return; } } } //Image compression failed, write blank data writeString(""); writeInt(0); break; default: throw Exception("DataOutputStream::writeImage(): Invalid IncludeImageMode value."); break; } }