I do not get the same error in my compiler (vc2009), so I don't know if these
actually fix your errors. But if I read you error right the C_Ostream::operator
= is not implemented in Imf. So my fix is to simply replace the = by calling
the constructor directly.
Pleas let me know if this fix did not work. If so I can look it over with other
compilers later this weak when I have more time.
Regards Ragnar
-----Ursprungligt meddelande-----
Från: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] För Robert Osfield
Skickat: den 26 november 2008 13:39
Till: OpenSceneGraph Submissions
Ämne: Re: [osg-submissions] EXR read and writer
HI Ragnar et al,
I have had a bash at porting the code, but it's not complete yet.
I've written an CMakeModules/FindOpenEXR.cmake, wired up the CMakefile but
stumbled on the an error:
[ 77%] Building CXX object
src/osgPlugins/exr/CMakeFiles/osgdb_exr.dir/ReaderWriterEXR.o
/usr/include/OpenEXR/ImfIO.h: In copy constructor 'C_IStream::C_IStream(const
C_IStream&)':
/usr/include/OpenEXR/ImfIO.h:113: error: 'Imf::IStream::IStream(const
Imf::IStream&)' is private
/home/robert/OpenSceneGraph/src/osgPlugins/exr/ReaderWriterEXR.cpp:33:
error: within this context
/home/robert/OpenSceneGraph/src/osgPlugins/exr/ReaderWriterEXR.cpp: In function
'unsigned char* exr_load(std::istream&, int*, int*, int*, unsigned int*)':
/home/robert/OpenSceneGraph/src/osgPlugins/exr/ReaderWriterEXR.cpp:97:
note: synthesized method 'C_IStream::C_IStream(const C_IStream&)'
first required here
/usr/include/OpenEXR/ImfIO.h: In copy constructor 'C_OStream::C_OStream(const
C_OStream&)':
/usr/include/OpenEXR/ImfIO.h:176: error: 'Imf::OStream::OStream(const
Imf::OStream&)' is private
/home/robert/OpenSceneGraph/src/osgPlugins/exr/ReaderWriterEXR.cpp:60:
error: within this context
/home/robert/OpenSceneGraph/src/osgPlugins/exr/ReaderWriterEXR.cpp: In member
function 'bool ReaderWriterEXR::writeEXRStream(const
osg::Image&, std::ostream&, const std::string&) const':
/home/robert/OpenSceneGraph/src/osgPlugins/exr/ReaderWriterEXR.cpp:271:
note: synthesized method 'C_OStream::C_OStream(const C_OStream&)'
first required here
make[2]: *** [src/osgPlugins/exr/CMakeFiles/osgdb_exr.dir/ReaderWriterEXR.o]
Error 1
make[1]: *** [src/osgPlugins/exr/CMakeFiles/osgdb_exr.dir/all] Error 2
make: *** [all] Error 2
Because of this compile error I've just comment out the inclusion of the exr
plugin from src/CMakeLists.txt:
IF(OPENEXR_FOUND)
# ADD_SUBDIRECTORY(exr)
ENDIF(OPENEXR_FOUND)
So at least it doesn't break the build for others.
Must admit I'm pretty miffed with having to do lots of work trying complete a
half backed submissions - I have dozens of submissions to review and merge and
way too many have required me to dive in fix bugs, fix porting issues.
Decent submissions work out of the box, and take five minutes of my time to
review, compile and check-in. Submissions like these suck hours of my time.
Pile a dozen of such submissions up on one week I you completely suck up all my
time. I have to earn a living too guys... I can't just do open source charity
work all the time.
So please can someone fix this stuff and get back to me when it actually works.
Robert.
_______________________________________________
osg-submissions mailing list
[email protected]
http://lists.openscenegraph.org/listinfo.cgi/osg-submissions-openscenegraph.org
#include <osg/Image>
#include <osg/Notify>
#include <osg/Geode>
#include <osg/Image>
#include <osg/GL>
//Make the half format work against openEXR libs
#define OPENEXR_DLL
#include <osgDB/Registry>
#include <osgDB/FileNameUtils>
#include <osgDB/FileUtils>
#include <ImfRgbaFile.h>
#include <ImfIO.h>
#include <ImfArray.h>
using namespace std;
using namespace Imf;
using namespace Imath;
/****************************************************************************
*
* Follows is code written by FOI (www.foi.se)
* it is a wraper of openEXR(www.openexr.com)
* to add suport of exr images into osg
*
* Ported to a OSG-plugin, Ragnar Hammarqvist.
* For patches, bugs and new features
* please send them direct to the OSG dev team.
**********************************************************************/
class C_IStream: public Imf::IStream
{
public:
C_IStream (istream *fin) :
IStream(""),_inStream(fin){}
virtual bool read (char c[/*n*/], int n)
{
return _inStream->read(c,n).good();
};
virtual Int64 tellg ()
{
return _inStream->tellg();
};
virtual void seekg (Int64 pos)
{
_inStream->seekg(pos);
};
virtual void clear ()
{
_inStream->clear();
};
private:
std::istream * _inStream;
};
class C_OStream: public Imf::OStream
{
public:
C_OStream (ostream *fin) :
OStream(""),_outStream(fin)
{};
virtual void write (const char c[/*n*/], int n)
{
_outStream->write(c,n);
};
virtual Int64 tellp ()
{
return _outStream->tellp();
};
virtual void seekp (Int64 pos)
{
_outStream->seekp(pos);
};
private:
std::ostream * _outStream;
};
unsigned char *exr_load(std::istream& fin,
int *width_ret,
int *height_ret,
int *numComponents_ret,
unsigned int *dataType_ret)
{
unsigned char *buffer=NULL; // returned to sender & as read from the
disk
bool inputError = false;
Array2D<Rgba> pixels;
int width,height,numComponents;
try
{
C_IStream inStream(&fin);
RgbaInputFile rgbafile(inStream);
Box2i dw = rgbafile.dataWindow();
RgbaChannels channels = rgbafile.channels();
(*width_ret) = width = dw.max.x - dw.min.x + 1;
(*height_ret)=height = dw.max.y - dw.min.y + 1;
(*dataType_ret) = GL_HALF_FLOAT_ARB;
pixels.resizeErase (height, width);
rgbafile.setFrameBuffer((&pixels)[0][0] - dw.min.x - dw.min.y *
width, 1, width);
rgbafile.readPixels(dw.min.y, dw.max.y);
}
catch( char * str ) {
inputError = true;
}
//If error during stream read return a empty pointer
if (inputError)
{
return buffer;
}
//If there is no information in alpha channel do not store the alpha
channel
numComponents = 3;
for (long i = height-1; i >= 0; i--)
{
for (long j = 0 ; j < width; j++)
{
if (pixels[i][j].a != half(1.0f) )
{
numComponents = 4;
break;
}
}
}
(*numComponents_ret) = numComponents;
if (!( numComponents == 3 ||
numComponents == 4))
{
return NULL;
}
//Copy and allocate data to a unsigned char array that OSG can use for
texturing
unsigned dataSize = (sizeof(half) * height * width * numComponents);
//buffer = new unsigned char[dataSize];
buffer = (unsigned char*)malloc(dataSize);
half* pOut = (half*) buffer;
for (long i = height-1; i >= 0; i--)
{
for (long j = 0 ; j < width; j++)
{
(*pOut) = pixels[i][j].r;
pOut++;
(*pOut) = pixels[i][j].g;
pOut++;
(*pOut) = pixels[i][j].b;
pOut++;
if (numComponents >= 4)
{
(*pOut) = pixels[i][j].a;
pOut++;
}
}
}
return buffer;
}
class ReaderWriterEXR : public osgDB::ReaderWriter
{
public:
ReaderWriterEXR()
{
}
virtual bool acceptsExtension(const std::string& extension) const {
return osgDB::equalCaseInsensitive(extension,"exr"); }
virtual const char* className() const { return "EXR Image Reader"; }
virtual ReadResult readObject(std::istream& fin,const
osgDB::ReaderWriter::Options* options =NULL) const
{
return readImage(fin, options);
}
virtual ReadResult readObject(const std::string& file, const
osgDB::ReaderWriter::Options* options =NULL) const
{
return readImage(file, options);
}
virtual ReadResult readImage(std::istream& fin,const Options* =NULL)
const
{
return readEXRStream(fin);
}
virtual ReadResult readImage(const std::string& file, const
osgDB::ReaderWriter::Options* options) const
{
std::string ext = osgDB::getLowerCaseFileExtension(file);
if (!acceptsExtension(ext)) return ReadResult::FILE_NOT_HANDLED;
std::string fileName = osgDB::findDataFile( file, options );
if (fileName.empty()) return ReadResult::FILE_NOT_FOUND;
std::ifstream istream(fileName.c_str(), std::ios::in |
std::ios::binary);
if(!istream) return ReadResult::FILE_NOT_HANDLED;
ReadResult rr = readEXRStream(istream);
if(rr.validImage())
{
rr.getImage()->setFileName(fileName);
}
return rr;
}
virtual WriteResult writeImage(const osg::Image& image,std::ostream&
fout,const Options*) const
{
bool success = writeEXRStream(image, fout, "<output stream>");
if(success)
return WriteResult::FILE_SAVED;
else
return WriteResult::ERROR_IN_WRITING_FILE;
}
virtual WriteResult writeImage(const osg::Image &img,const std::string&
fileName, const osgDB::ReaderWriter::Options*) const
{
std::string ext = osgDB::getFileExtension(fileName);
if (!acceptsExtension(ext)) return
WriteResult::FILE_NOT_HANDLED;
std::ofstream fout(fileName.c_str(), std::ios::out |
std::ios::binary);
if(!fout) return WriteResult::ERROR_IN_WRITING_FILE;
bool success = writeEXRStream(img, fout, fileName);
fout.close();
if(success)
return WriteResult::FILE_SAVED;
else
return WriteResult::ERROR_IN_WRITING_FILE;
}
protected:
bool writeEXRStream(const osg::Image &img, std::ostream& fout, const
std::string &fileName) const
{
bool writeOK = true;
//Obtain data from texture
int width = img.s();
int height = img.t();
unsigned int intenalTextureFormat =
img.getInternalTextureFormat();
unsigned int pixelFormat = img.getPixelFormat();
int numComponents = img.computeNumComponents(pixelFormat);
unsigned int dataType = img.getDataType();
//Validates image data
//if numbers of components matches
if (!( numComponents == 3 ||
numComponents == 4))
{
writeOK = false;
return false;
}
if (!( dataType == GL_HALF_FLOAT_ARB ||
dataType == GL_FLOAT))
{
writeOK = false;
return false;
}
//Create a stream to save to
C_OStream outStream(&fout);
//Copy data from texture to rgba pixel format
Array2D<Rgba> outPixels(height,width);
//If texture is half format
if (dataType == GL_HALF_FLOAT_ARB)
{
half* pOut = (half*) img.data();
for (long i = height-1; i >= 0; i--)
{
for (long j = 0 ; j < width; j++)
{
outPixels[i][j].r = (*pOut);
pOut++;
outPixels[i][j].g = (*pOut);
pOut++;
outPixels[i][j].b = (*pOut);
pOut++;
if (numComponents >= 4)
{
outPixels[i][j].a = (*pOut);
pOut++;
}
else{outPixels[i][j].a = 1.0f;}
}
}
}
else if (dataType == GL_FLOAT)
{
float* pOut = (float*) img.data();
for (long i = height-1; i >= 0; i--)
{
for (long j = 0 ; j < width; j++)
{
outPixels[i][j].r = half(*pOut);
pOut++;
outPixels[i][j].g = half(*pOut);
pOut++;
outPixels[i][j].b = half(*pOut);
pOut++;
if (numComponents >= 4)
{
outPixels[i][j].a = half(*pOut);
pOut++;
}
else
{outPixels[i][j].a = 1.0f;}
}
}
}
else
{
//If texture format not supported
return false;
}
try
{
//Write to stream
Header outHeader(width, height);
RgbaOutputFile rgbaFile (outStream, outHeader,
WRITE_RGBA);
rgbaFile.setFrameBuffer ((&outPixels)[0][0], 1, width);
rgbaFile.writePixels (height);
}
catch( char * str )
{
writeOK = false;
}
return writeOK;
}
ReadResult readEXRStream(std::istream& fin) const
{
unsigned char *imageData = NULL;
int width_ret = 0;
int height_ret = 0;
int numComponents_ret = 4;
unsigned int dataType_ret = GL_UNSIGNED_BYTE;
unsigned int pixelFormat = GL_RGB;
unsigned int interNalTextureFormat = GL_RGB;
imageData =
exr_load(fin,&width_ret,&height_ret,&numComponents_ret,&dataType_ret);
if (imageData==NULL)
return ReadResult::FILE_NOT_HANDLED;
int s = width_ret;
int t = height_ret;
int r = 1;
int internalFormat = numComponents_ret;
if (dataType_ret == GL_HALF_FLOAT_ARB)
{
interNalTextureFormat =
numComponents_ret == 1 ? GL_LUMINANCE16F_ARB :
numComponents_ret == 2 ?
GL_LUMINANCE_ALPHA16F_ARB :
numComponents_ret == 3 ? GL_RGB16F_ARB :
numComponents_ret == 4 ? GL_RGBA16F_ARB :
(GLenum)-1;
}
else if (dataType_ret == GL_FLOAT)
{
interNalTextureFormat =
numComponents_ret == 1 ? GL_LUMINANCE32F_ARB :
numComponents_ret == 2 ?
GL_LUMINANCE_ALPHA32F_ARB :
numComponents_ret == 3 ? GL_RGB32F_ARB :
numComponents_ret == 4 ? GL_RGBA32F_ARB :
(GLenum)-1;
}
pixelFormat =
numComponents_ret == 1 ? GL_LUMINANCE :
numComponents_ret == 2 ? GL_LUMINANCE_ALPHA :
numComponents_ret == 3 ? GL_RGB :
numComponents_ret == 4 ? GL_RGBA : (GLenum)-1;
unsigned int dataType = dataType_ret;
osg::Image* pOsgImage = new osg::Image;
pOsgImage->setImage(s,t,r,
interNalTextureFormat,
pixelFormat,
dataType,
imageData,
osg::Image::USE_MALLOC_FREE);
return pOsgImage;
}
};
// now register with Registry to instantiate the exr suport
// reader/writer.
REGISTER_OSGPLUGIN(exr, ReaderWriterEXR)_______________________________________________
osg-submissions mailing list
[email protected]
http://lists.openscenegraph.org/listinfo.cgi/osg-submissions-openscenegraph.org