From Farshid Lashkari, "I've made some changes to the IVE loader which will add the capability

of saving image files inside the IVE file. Currently, only the raw
image data is saved into the file. If your model uses jpg images as
textures then this will cause your file size to increase.

I've added an option that will embed the original image file into the
IVE file. The IVE file will then attempt to read the image from
memory. Since most image loaders support reading from memory, this
shouldn't be a problem. To use this new feature the user must specify
the option "includeImageFileInIVEFile" when converting to IVE.

I tested this out on the "skydome.osg" model that comes with OSG.
Using the old method, the IVE file size would be 785 KB, with the new
method it is only 42 KB.

Also, I've added the support for TextureRectangle's to the IVE reader/writer."
This commit is contained in:
Robert Osfield 2006-02-26 17:45:52 +00:00
parent a028f59ea0
commit 10d139fc1f
14 changed files with 301 additions and 199 deletions

View File

@ -428,6 +428,10 @@ SOURCE=..\..\..\src\osgPlugins\ive\TextureCubeMap.cpp
# End Source File
# Begin Source File
SOURCE=..\..\..\src\osgPlugins\ive\TextureRectangle.cpp
# End Source File
# Begin Source File
SOURCE=..\..\..\src\osgPlugins\ive\Transform.cpp
# End Source File
# Begin Source File
@ -784,6 +788,10 @@ SOURCE=..\..\..\src\osgPlugins\ive\TextureCubeMap.h
# End Source File
# Begin Source File
SOURCE=..\..\..\src\osgPlugins\ive\TextureRectangle.h
# End Source File
# Begin Source File
SOURCE=..\..\..\src\osgPlugins\ive\Transform.h
# End Source File
# Begin Source File

View File

@ -32,6 +32,7 @@
#include "Texture2D.h"
#include "Texture3D.h"
#include "TextureCubeMap.h"
#include "TextureRectangle.h"
#include "TexEnv.h"
#include "TexEnvCombine.h"
#include "TexGen.h"
@ -44,6 +45,7 @@
#include "Program.h"
#include "Viewport.h"
#include "Scissor.h"
#include "Image.h"
#include "Group.h"
#include "MatrixTransform.h"
@ -84,9 +86,10 @@
#include <osg/Notify>
#include <osg/io_utils>
#include <osgDB/ReadFile>
#include <osgDB/FileNameUtils>
#include <stdio.h>
#include <sstream>
using namespace ive;
using namespace std;
@ -812,6 +815,69 @@ osg::Image* DataInputStream::readImage(std::string filename)
return image;
}
osg::Image* DataInputStream::readImage(IncludeImageMode mode)
{
switch(mode) {
case IMAGE_INCLUDE_DATA:
// Read image data from stream
if(readBool())
{
osg::Image* image = new osg::Image();
((ive::Image*)image)->read(this);
return image;
}
break;
case IMAGE_REFERENCE_FILE:
// Only read image name from stream.
{
std::string filename = readString();
if(filename.compare("")!=0){
return readImage(filename);
}
}
break;
case IMAGE_INCLUDE_FILE:
// Read image file from stream
{
std::string filename = readString();
int size = readInt();
if(filename.compare("")!=0 && size > 0){
//Read in file
char *buffer = new char[size];
readCharArray(buffer,size);
//Get ReaderWriter from file extension
std::string ext = osgDB::getFileExtension(filename);
osgDB::ReaderWriter *reader = osgDB::Registry::instance()->getReaderWriterForExtension(ext);
osgDB::ReaderWriter::ReadResult rr;
if(reader) {
//Convert data to istream
std::stringstream inputStream;
inputStream.write(buffer,size);
//Attempt to read the image
rr = reader->readImage(inputStream,_options.get());
}
//Delete buffer
delete [] buffer;
//Return result
if(rr.validImage()) {
return rr.takeImage();
}
}
}
break;
default:
throw Exception("DataInputStream::readImage(): Invalid IncludeImageMode value.");
break;
}
return 0;
}
osg::StateSet* DataInputStream::readStateSet()
{
// Read statesets unique ID.
@ -918,6 +984,10 @@ osg::StateAttribute* DataInputStream::readStateAttribute()
attribute = new osg::TextureCubeMap();
((ive::TextureCubeMap*)(attribute))->read(this);
}
else if(attributeID == IVETEXTURERECTANGLE){
attribute = new osg::TextureRectangle();
((ive::TextureRectangle*)(attribute))->read(this);
}
else if(attributeID == IVETEXENV){
attribute = new osg::TexEnv();
((ive::TexEnv*)(attribute))->read(this);

View File

@ -85,6 +85,7 @@ public:
osg::Vec4sArray* readVec4sArray();
osg::Image* readImage(std::string s);
osg::Image* readImage(IncludeImageMode mode);
osg::StateSet* readStateSet();
osg::StateAttribute* readStateAttribute();
osg::Uniform* readUniform();

View File

@ -33,6 +33,7 @@
#include "Texture2D.h"
#include "Texture3D.h"
#include "TextureCubeMap.h"
#include "TextureRectangle.h"
#include "TexEnv.h"
#include "TexEnvCombine.h"
#include "TexGen.h"
@ -47,6 +48,7 @@
#include "Shader.h"
#include "Viewport.h"
#include "Scissor.h"
#include "Image.h"
#include "Group.h"
#include "MatrixTransform.h"
@ -84,6 +86,9 @@
#include <osg/Notify>
#include <osg/io_utils>
#include <osgDB/FileUtils>
#include <fstream>
using namespace ive;
@ -94,8 +99,12 @@ void DataOutputStream::setOptions(const osgDB::ReaderWriter::Options* options)
if (_options.get())
{
setIncludeImageData(_options->getOptionString().find("noTexturesInIVEFile")==std::string::npos);
osg::notify(osg::DEBUG_INFO) << "ive::DataOutpouStream.setIncludeImageData()=" << getIncludeImageData() << std::endl;
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);
}
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;
@ -112,7 +121,7 @@ DataOutputStream::DataOutputStream(std::ostream * ostream)
{
_verboseOutput = false;
_includeImageData= true;
_includeImageMode = IMAGE_INCLUDE_DATA;
_includeExternalReferences = false;
_writeExternalReferenceFiles = false;
@ -701,6 +710,10 @@ void DataOutputStream::writeStateAttribute(const osg::StateAttribute* attribute)
else if(dynamic_cast<const osg::TextureCubeMap*>(attribute)){
((ive::TextureCubeMap*)(attribute))->write(this);
}
// This is a TextureRectangle
else if(dynamic_cast<const osg::TextureRectangle*>(attribute)){
((ive::TextureRectangle*)(attribute))->write(this);
}
// This is a TexEnv
else if(dynamic_cast<const osg::TexEnv*>(attribute)){
((ive::TexEnv*)(attribute))->write(this);
@ -984,3 +997,68 @@ void DataOutputStream::writeNode(const osg::Node* node)
if (_verboseOutput) std::cout<<"read/writeNode() ["<<id<<"]"<<std::endl;
}
}
void DataOutputStream::writeImage(IncludeImageMode mode, osg::Image *image)
{
switch(mode) {
case IMAGE_INCLUDE_DATA:
// Include image data in stream
writeBool(image!=0);
if(image)
((ive::Image*)image)->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;
default:
throw Exception("DataOutputStream::writeImage(): Invalid IncludeImageMode value.");
break;
}
}

View File

@ -30,7 +30,7 @@ class DataOutputStream{
public:
DataOutputStream(std::ostream* ostream);
~DataOutputStream();
void setOptions(const osgDB::ReaderWriter::Options* options);
const osgDB::ReaderWriter::Options* getOptions() const { return _options.get(); }
@ -88,10 +88,11 @@ public:
void writeDrawable(const osg::Drawable* sa);
void writeShape(const osg::Shape* sa);
void writeNode(const osg::Node* sa);
void writeImage(IncludeImageMode mode, osg::Image *image);
// Set and get include image data in stream
void setIncludeImageData(bool b) {_includeImageData=b;};
bool getIncludeImageData() {return _includeImageData;};
void setIncludeImageMode(IncludeImageMode mode) {_includeImageMode=mode;};
IncludeImageMode getIncludeImageMode() {return _includeImageMode;};
// Set and get include external references in stream
void setIncludeExternalReferences(bool b) {_includeExternalReferences=b;};
@ -127,10 +128,11 @@ private:
ShapeMap _shapeMap;
NodeMap _nodeMap;
bool _includeImageData;
bool _includeExternalReferences;
bool _writeExternalReferenceFiles;
bool _useOriginalExternalReferences;
IncludeImageMode _includeImageMode;
osg::ref_ptr<const osgDB::ReaderWriter::Options> _options;
};

View File

@ -2,12 +2,17 @@
#define IVE_DATATYPESIZE 1
#define BOOLSIZE 1
#define CHARSIZE 1
#define SHORTSIZE 2
#define INTSIZE 4
#define FLOATSIZE 4
#define LONGSIZE 4
#define DOUBLESIZE 8
#define BOOLSIZE 1
#define CHARSIZE 1
#define SHORTSIZE 2
#define INTSIZE 4
#define FLOATSIZE 4
#define LONGSIZE 4
#define DOUBLESIZE 8
//Don't know where else to put this
namespace ive{
typedef enum IncludeImageMode { IMAGE_REFERENCE_FILE=0,IMAGE_INCLUDE_DATA,IMAGE_INCLUDE_FILE };
}
#endif

View File

@ -74,6 +74,7 @@ namespace ive {
#define IVEVIEWPORT 0x00001127
#define IVESCISSOR 0x00001128
#define IVEPOLYGONMODE 0x00001129
#define IVETEXTURERECTANGLE 0x00001130
// Drawables
#define IVEDRAWABLE 0x00001000
@ -117,7 +118,6 @@ namespace ive {
//osgText classes
#define IVETEXT 0x10000001
class ReadWrite{
public:

View File

@ -33,24 +33,10 @@ void Texture1D::write(DataOutputStream* out){
// Write image.
// Should we include images date in stream
bool includeImg = out->getIncludeImageData();
out->writeBool(includeImg);
IncludeImageMode includeImg = out->getIncludeImageMode();
out->writeChar(includeImg);
// Include image data in stream
if(includeImg){
out->writeBool(getImage()!=0);
if(getImage())
((ive::Image*)getImage())->write(out);
}
// Only include image name in stream
else{
if (getImage() && !(getImage()->getFileName().empty())){
out->writeString(getImage()->getFileName());
}
else{
out->writeString("");
}
}
out->writeImage(includeImg,getImage());
}
void Texture1D::read(DataInputStream* in){
@ -69,27 +55,11 @@ void Texture1D::read(DataInputStream* in){
// Read image.
// Should we read image data from stream
bool includeImg = in->readBool();
IncludeImageMode includeImg = (IncludeImageMode)in->readChar();
// Read image data from stream
if(includeImg)
{
if(in->readBool())
{
osg::Image* image = new osg::Image();
((ive::Image*)image)->read(in);
setImage(image);
}
}
// Only read image name from stream.
else{
std::string filename = in->readString();
if(filename.compare("")!=0){
osg::Image* image = in->readImage(filename);
if (image){
setImage(image);
}
}
osg::Image *image = in->readImage(includeImg);
if(image) {
setImage(image);
}
}
else{

View File

@ -33,25 +33,10 @@ void Texture2D::write(DataOutputStream* out){
// Write image.
// Should we include images date in stream
bool includeImg = out->getIncludeImageData();
out->writeBool(includeImg);
// Include image data in stream
if(includeImg){
out->writeBool(getImage()!=0);
if(getImage())
((ive::Image*)getImage())->write(out);
}
// Only include image name in stream
else{
if (getImage() && !(getImage()->getFileName().empty())){
out->writeString(getImage()->getFileName());
}
else{
out->writeString("");
}
}
IncludeImageMode includeImg = out->getIncludeImageMode();
out->writeChar(includeImg);
out->writeImage(includeImg,getImage());
}
void Texture2D::read(DataInputStream* in){
@ -70,27 +55,11 @@ void Texture2D::read(DataInputStream* in){
// Read image.
// Should we read image data from stream
bool includeImg = in->readBool();
IncludeImageMode includeImg = (IncludeImageMode)in->readChar();
// Read image data from stream
if(includeImg)
{
if(in->readBool())
{
osg::Image* image = new osg::Image();
((ive::Image*)image)->read(in);
setImage(image);
}
}
// Only read image name from stream.
else{
std::string filename = in->readString();
if(filename.compare("")!=0){
osg::Image* image = in->readImage(filename);
if (image){
setImage(image);
}
}
osg::Image *image = in->readImage(includeImg);
if(image) {
setImage(image);
}
}
else{

View File

@ -33,25 +33,10 @@ void Texture3D::write(DataOutputStream* out){
// Write image.
// Should we include images date in stream
bool includeImg = out->getIncludeImageData();
out->writeBool(includeImg);
// Include image data in stream
if(includeImg){
out->writeBool(getImage()!=0);
if(getImage())
((ive::Image*)getImage())->write(out);
}
// Only include image name in stream
else{
if (getImage() && !(getImage()->getFileName().empty())){
out->writeString(getImage()->getFileName());
}
else{
out->writeString("");
}
}
IncludeImageMode includeImg = out->getIncludeImageMode();
out->writeChar(includeImg);
out->writeImage(includeImg,getImage());
}
void Texture3D::read(DataInputStream* in){
@ -70,27 +55,11 @@ void Texture3D::read(DataInputStream* in){
// Read image.
// Should we read image data from stream
bool includeImg = in->readBool();
IncludeImageMode includeImg = (IncludeImageMode)in->readChar();
// Read image data from stream
if(includeImg)
{
if(in->readBool())
{
osg::Image* image = new osg::Image();
((ive::Image*)image)->read(in);
setImage(image);
}
}
// Only read image name from stream.
else{
std::string filename = in->readString();
if(filename.compare("")!=0){
osg::Image* image = in->readImage(filename);
if (image){
setImage(image);
}
}
osg::Image *image = in->readImage(includeImg);
if(image) {
setImage(image);
}
}
else{

View File

@ -39,37 +39,15 @@ void TextureCubeMap::write(DataOutputStream* out){
out->writeInt(getNumMipmapLevels());
// Should we include images date in stream
bool includeImg = out->getIncludeImageData();
out->writeBool(includeImg);
IncludeImageMode includeImg = out->getIncludeImageMode();
out->writeChar(includeImg);
writeImage(out,includeImg,getImage(osg::TextureCubeMap::POSITIVE_X));
writeImage(out,includeImg,getImage(osg::TextureCubeMap::NEGATIVE_X));
writeImage(out,includeImg,getImage(osg::TextureCubeMap::POSITIVE_Y));
writeImage(out,includeImg,getImage(osg::TextureCubeMap::NEGATIVE_Y));
writeImage(out,includeImg,getImage(osg::TextureCubeMap::POSITIVE_Z));
writeImage(out,includeImg,getImage(osg::TextureCubeMap::NEGATIVE_Z));
}
void TextureCubeMap::writeImage(DataOutputStream* out,bool includeImg,osg::Image* image)
{
if(includeImg)
{
// Write images if any
out->writeBool(image!=0);
if(image)
((ive::Image*)(image))->write(out);
}
else
{
if (image && !(image->getFileName().empty())){
out->writeString(image->getFileName());
}
else{
out->writeString("");
}
}
out->writeImage(includeImg,getImage(osg::TextureCubeMap::POSITIVE_X));
out->writeImage(includeImg,getImage(osg::TextureCubeMap::NEGATIVE_X));
out->writeImage(includeImg,getImage(osg::TextureCubeMap::POSITIVE_Y));
out->writeImage(includeImg,getImage(osg::TextureCubeMap::NEGATIVE_Y));
out->writeImage(includeImg,getImage(osg::TextureCubeMap::POSITIVE_Z));
out->writeImage(includeImg,getImage(osg::TextureCubeMap::NEGATIVE_Z));
}
void TextureCubeMap::read(DataInputStream* in)
@ -97,14 +75,14 @@ void TextureCubeMap::read(DataInputStream* in)
setNumMipmapLevels((unsigned int)in->readInt());
// Should we read image data from stream
bool includeImg = in->readBool();
IncludeImageMode includeImg = (IncludeImageMode)in->readChar();
setImage(osg::TextureCubeMap::POSITIVE_X,readImage(in, includeImg));
setImage(osg::TextureCubeMap::NEGATIVE_X,readImage(in, includeImg));
setImage(osg::TextureCubeMap::POSITIVE_Y,readImage(in, includeImg));
setImage(osg::TextureCubeMap::NEGATIVE_Y,readImage(in, includeImg));
setImage(osg::TextureCubeMap::POSITIVE_Z,readImage(in, includeImg));
setImage(osg::TextureCubeMap::NEGATIVE_Z,readImage(in, includeImg));
setImage(osg::TextureCubeMap::POSITIVE_X,in->readImage(includeImg));
setImage(osg::TextureCubeMap::NEGATIVE_X,in->readImage(includeImg));
setImage(osg::TextureCubeMap::POSITIVE_Y,in->readImage(includeImg));
setImage(osg::TextureCubeMap::NEGATIVE_Y,in->readImage(includeImg));
setImage(osg::TextureCubeMap::POSITIVE_Z,in->readImage(includeImg));
setImage(osg::TextureCubeMap::NEGATIVE_Z,in->readImage(includeImg));
}
else{
@ -112,27 +90,3 @@ void TextureCubeMap::read(DataInputStream* in)
}
}
osg::Image* TextureCubeMap::readImage(DataInputStream* in, bool includeImg)
{
if(includeImg)
{
// Read image data from stream
if(in->readBool())
{
osg::Image* image = new osg::Image();
((ive::Image*)image)->read(in);
return image;
}
}
else
{
// Only read image name from stream.
std::string filename = in->readString();
if(filename.compare("")!=0)
{
osg::Image* image = in->readImage(filename);
return image;
}
}
return 0;
}

View File

@ -10,15 +10,8 @@ namespace ive
class TextureCubeMap : public osg::TextureCubeMap, public ReadWrite
{
public:
void write(DataOutputStream* out);
void writeImage(DataOutputStream* out,bool includeImg,osg::Image* image);
void read(DataInputStream* in);
osg::Image* readImage(DataInputStream* in, bool includeImg);
void write(DataOutputStream* out);
void read(DataInputStream* in);
};
}

View File

@ -0,0 +1,68 @@
/**********************************************************************
*
* FILE: TextureRectangle.cpp
*
* DESCRIPTION: Read/Write osg::TextureRectangle in binary format to disk.
*
* CREATED BY: Auto generated by iveGenerated
* and later modified by Rune Schmidt Jensen.
*
* HISTORY: Created 20.3.2003
*
* Copyright 2003 VR-C
**********************************************************************/
#include "Exception.h"
#include "TextureRectangle.h"
#include "Texture.h"
#include "Image.h"
using namespace ive;
void TextureRectangle::write(DataOutputStream* out){
// Write TextureRectangle's identification.
out->writeInt(IVETEXTURERECTANGLE);
// If the osg class is inherited by any other class we should also write this to file.
osg::Texture* tex = dynamic_cast<osg::Texture*>(this);
if(tex){
((ive::Texture*)(tex))->write(out);
}
else
throw Exception("TextureRectangle::write(): Could not cast this osg::TextureRectangle to an osg::Texture.");
// Write TextureRectangle's properties.
// Write image.
// Should we include images date in stream
IncludeImageMode includeImg = out->getIncludeImageMode();
out->writeChar(includeImg);
out->writeImage(includeImg,getImage());
}
void TextureRectangle::read(DataInputStream* in){
// Read TextureRectangle's identification.
int id = in->peekInt();
if(id == IVETEXTURERECTANGLE){
// Code to read TextureRectangle's properties.
id = in->readInt();
// If the osg class is inherited by any other class we should also read this from file.
osg::Texture* tex = dynamic_cast<osg::Texture*>(this);
if(tex){
((ive::Texture*)(tex))->read(in);
}
else
throw Exception("TextureRectangle::read(): Could not cast this osg::TextureRectangle to an osg::Texture.");
// Read image.
// Should we read image data from stream
IncludeImageMode includeImg = (IncludeImageMode)in->readChar();
osg::Image *image = in->readImage(includeImg);
if(image) {
setImage(image);
}
}
else{
throw Exception("TextureRectangle::read(): Expected TextureRectangle identification.");
}
}

View File

@ -0,0 +1,15 @@
#ifndef IVE_TEXTURERECTANGLE
#define IVE_TEXTURERECTANGLE 1
#include <osg/TextureRectangle>
#include "ReadWrite.h"
namespace ive{
class TextureRectangle : public osg::TextureRectangle, public ReadWrite {
public:
void write(DataOutputStream* out);
void read(DataInputStream* in);
};
}
#endif