Hi,
Attached is a fix in ReaderWriterRGB, based on latest from Git, that
encapsulates the true raw image data in a separate struct.
After the change from 2016 that made rawImageRec extend osg::Referenced
and implement a constructor/destructor, it wasn't really 'raw' and
didn't work when writing .rgb files - unwanted header data was written.
Regards,
Andreas
// Released under the OSGPL license, as part of the OpenSceneGraph distribution.
//
// ReaderWriter for sgi's .rgb format.
// specification can be found at
http://local.wasp.uwa.edu.au/~pbourke/dataformats/sgirgb/sgiversion.html
#include <osg/Image>
#include <osg/Notify>
#include <osg/Geode>
#include <osg/GL>
#include <osgDB/FileNameUtils>
#include <osgDB/FileUtils>
#include <osgDB/Registry>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifndef SEEK_SET
# define SEEK_SET 0
#endif
#if defined(OSG_GLES1_AVAILABLE) || defined(OSG_GLES2_AVAILABLE)
#define GL_BITMAP 0x1A00
#define GL_RED 0x1903
#define GL_GREEN 0x1904
#define GL_BLUE 0x1905
#define GL_COLOR_INDEX 0x1900
#endif
#if defined(OSG_GL3_AVAILABLE)
#define GL_BITMAP 0x1A00
#define GL_COLOR_INDEX 0x1900
#endif
using namespace osg;
typedef unsigned int size_pos;
struct ImageRec : public osg::Referenced
{
ImageRec() {
rawData.imagic = 0;
rawData.type = 0;
rawData.dim = 0;
rawData.sizeX = 0;
rawData.sizeY = 0;
rawData.sizeZ = 0;
rawData.min = 0;
rawData.max = 0;
rawData.wasteBytes = 0;
rawData.colorMap = 0;
rawData.file = 0;
rawData.tmp = 0;
rawData.tmpR = 0;
rawData.tmpG = 0;
rawData.tmpB = 0;
rawData.tmpA = 0;
rawData.rleEnd = 0;
rawData.rowStart = 0;
rawData.rowSize = 0;
rawData.swapFlag = 0;
rawData.bpc = 0;
}
virtual ~ImageRec()
{
if (rawData.tmp) delete[] rawData.tmp;
if (rawData.tmpR) delete[] rawData.tmpR;
if (rawData.tmpG) delete[] rawData.tmpG;
if (rawData.tmpB) delete[] rawData.tmpB;
if (rawData.tmpA) delete[] rawData.tmpA;
if (rawData.rowStart) delete[] rawData.rowStart;
if (rawData.rowSize) delete[] rawData.rowSize;
}
struct {
unsigned short imagic;
unsigned short type;
unsigned short dim;
unsigned short sizeX, sizeY, sizeZ;
unsigned long min, max;
unsigned long wasteBytes;
char name[80];
unsigned long colorMap;
std::istream *file;
unsigned char *tmp, *tmpR, *tmpG, *tmpB, *tmpA;
unsigned long rleEnd;
GLuint *rowStart;
GLint *rowSize;
GLenum swapFlag;
short bpc;
} rawData;
typedef unsigned char * BytePtr;
bool needsBytesSwapped()
{
union {
int testWord;
char testByte[sizeof(int)];
}endianTest;
endianTest.testWord = 1;
if( endianTest.testByte[0] == 1 )
return true;
else
return false;
}
template <class T>
inline void swapBytes( T &s )
{
if( sizeof( T ) == 1 )
return;
T d = s;
BytePtr sptr = (BytePtr)&s;
BytePtr dptr = &(((BytePtr)&d)[sizeof(T)-1]);
for( unsigned int i = 0; i < sizeof(T); i++ )
*(sptr++) = *(dptr--);
}
void swapBytes()
{
swapBytes(rawData.imagic);
swapBytes(rawData.type);
swapBytes(rawData.dim);
swapBytes(rawData.sizeX);
swapBytes(rawData.sizeY);
swapBytes(rawData.sizeZ);
swapBytes(rawData.wasteBytes);
swapBytes(rawData.min);
swapBytes(rawData.max);
swapBytes(rawData.colorMap);
}
};
static void ConvertShort(unsigned short *array, long length)
{
unsigned long b1, b2;
unsigned char *ptr;
ptr = (unsigned char *)array;
while (length--)
{
b1 = *ptr++;
b2 = *ptr++;
*array++ = (unsigned short) ((b1 << 8) | (b2));
}
}
static void ConvertLong(GLuint *array, long length)
{
unsigned long b1, b2, b3, b4;
unsigned char *ptr;
ptr = (unsigned char *)array;
while (length--)
{
b1 = *ptr++;
b2 = *ptr++;
b3 = *ptr++;
b4 = *ptr++;
*array++ = (b1 << 24) | (b2 << 16) | (b3 << 8) | (b4);
}
}
static osg::ref_ptr<ImageRec> RawImageOpen(std::istream& fin)
{
union
{
int testWord;
char testByte[4];
} endianTest;
int x;
osg::ref_ptr<ImageRec> imageRec = new ImageRec;
if (imageRec == NULL)
{
OSG_WARN<< "Out of memory!"<< std::endl;
return NULL;
}
//Set istream pointer
imageRec->rawData.file = &fin;
endianTest.testWord = 1;
if (endianTest.testByte[0] == 1)
{
imageRec->rawData.swapFlag = GL_TRUE;
}
else
{
imageRec->rawData.swapFlag = GL_FALSE;
}
fin.read((char*)&(imageRec->rawData.imagic), 12);
if (!fin.good())
{
return NULL;
}
if (imageRec->rawData.swapFlag)
{
ConvertShort(&imageRec->rawData.imagic, 6);
}
imageRec->rawData.tmp = imageRec->rawData.tmpR = imageRec->rawData.tmpG =
imageRec->rawData.tmpB = imageRec->rawData.tmpA = 0L;
imageRec->rawData.rowStart = 0;
imageRec->rawData.rowSize = 0;
imageRec->rawData.bpc = (imageRec->rawData.type & 0x00FF);
imageRec->rawData.tmp = new unsigned
char[static_cast<size_pos>(imageRec->rawData.sizeX) * 256 *
static_cast<size_pos>(imageRec->rawData.bpc)];
if (imageRec->rawData.tmp == NULL)
{
OSG_FATAL<< "Out of memory!"<< std::endl;
return NULL;
}
if (imageRec->rawData.sizeZ >= 1)
{
if ((imageRec->rawData.tmpR = new unsigned
char[static_cast<size_pos>(imageRec->rawData.sizeX) *
static_cast<size_pos>(imageRec->rawData.bpc)]) == NULL)
{
OSG_FATAL<< "Out of memory!"<< std::endl;
return NULL;
}
}
if (imageRec->rawData.sizeZ >= 2)
{
if ((imageRec->rawData.tmpG = new unsigned
char[static_cast<size_pos>(imageRec->rawData.sizeX) *
static_cast<size_pos>(imageRec->rawData.bpc)]) == NULL)
{
OSG_FATAL<< "Out of memory!"<< std::endl;
return NULL;
}
}
if (imageRec->rawData.sizeZ >= 3)
{
if ((imageRec->rawData.tmpB = new unsigned
char[static_cast<size_pos>(imageRec->rawData.sizeX) *
static_cast<size_pos>(imageRec->rawData.bpc)]) == NULL)
{
OSG_FATAL<< "Out of memory!"<< std::endl;
return NULL;
}
}
if (imageRec->rawData.sizeZ >= 4)
{
if ((imageRec->rawData.tmpA = new unsigned
char[static_cast<size_pos>(imageRec->rawData.sizeX) *
static_cast<size_pos>(imageRec->rawData.bpc)]) == NULL)
{
OSG_FATAL<< "Out of memory!"<< std::endl;
return NULL;
}
}
if ((imageRec->rawData.type & 0xFF00) == 0x0100)
{
unsigned int ybyz = static_cast<size_pos>(imageRec->rawData.sizeY) *
static_cast<size_pos>(imageRec->rawData.sizeZ);
if ((imageRec->rawData.rowStart = new GLuint[ybyz]) == NULL)
{
OSG_FATAL<< "Out of memory!"<< std::endl;
return NULL;
}
if ((imageRec->rawData.rowSize = new GLint[ybyz]) == NULL)
{
OSG_FATAL<< "Out of memory!"<< std::endl;
return NULL;
}
x = ybyz * sizeof(GLuint);
imageRec->rawData.rleEnd = 512 + (2 * x);
fin.seekg(512, std::ios::beg);
fin.read((char*)imageRec->rawData.rowStart, x);
fin.read((char*)imageRec->rawData.rowSize, x);
if (imageRec->rawData.swapFlag)
{
ConvertLong(imageRec->rawData.rowStart, (long)(x / sizeof(GLuint)));
ConvertLong((GLuint *)imageRec->rawData.rowSize, (long)(x /
sizeof(GLint)));
}
}
return imageRec;
}
static void RawImageGetRow(ImageRec *imageRec, unsigned char *buf, int y, int z)
{
unsigned char *iPtr, *oPtr;
unsigned short pixel;
int count, done = 0;
unsigned short *tempShort;
if ((imageRec->rawData.type & 0xFF00) == 0x0100)
{
size_pos pos =
imageRec->rawData.rowStart[static_cast<size_pos>(y)+static_cast<size_pos>(z)*static_cast<size_pos>(imageRec->rawData.sizeY)];
size_pos amount =
imageRec->rawData.rowSize[static_cast<size_pos>(y)+static_cast<size_pos>(z)*static_cast<size_pos>(imageRec->rawData.sizeY)];
imageRec->rawData.file->seekg(pos, std::ios::beg);
imageRec->rawData.file->read((char*)imageRec->rawData.tmp, amount);
iPtr = imageRec->rawData.tmp;
oPtr = buf;
while (!done)
{
if (imageRec->rawData.bpc == 1)
pixel = *iPtr++;
else
{
tempShort = reinterpret_cast<unsigned short*>(iPtr);
pixel = *tempShort;
tempShort++;
iPtr = reinterpret_cast<unsigned char *>(tempShort);
}
if (imageRec->rawData.bpc != 1)
ConvertShort(&pixel, 1);
count = (int)(pixel & 0x7F);
// limit the count value to the remiaing row size
if
((static_cast<size_pos>(imageRec->rawData.sizeX)*static_cast<size_pos>(imageRec->rawData.bpc))
<= (oPtr - buf))
{
count = static_cast<size_pos>(imageRec->rawData.sizeX) - (oPtr
- buf) / static_cast<size_pos>(imageRec->rawData.bpc);
}
if (count<=0)
{
done = 1;
return;
}
if (pixel & 0x80)
{
while (count--)
{
if (imageRec->rawData.bpc == 1)
*oPtr++ = *iPtr++;
else{
tempShort = reinterpret_cast<unsigned short*>(iPtr);
pixel = *tempShort;
tempShort++;
iPtr = reinterpret_cast<unsigned char *>(tempShort);
ConvertShort(&pixel, 1);
tempShort = reinterpret_cast<unsigned short*>(oPtr);
*tempShort = pixel;
tempShort++;
oPtr = reinterpret_cast<unsigned char *>(tempShort);
}
}
}
else
{
if (imageRec->rawData.bpc == 1)
{
pixel = *iPtr++;
}
else
{
tempShort = reinterpret_cast<unsigned short*>(iPtr);
pixel = *tempShort;
tempShort++;
iPtr = reinterpret_cast<unsigned char *>(tempShort);
}
if (imageRec->rawData.bpc != 1)
ConvertShort(&pixel, 1);
while (count--)
{
if (imageRec->rawData.bpc == 1)
*oPtr++ = pixel;
else
{
tempShort = reinterpret_cast<unsigned short*>(oPtr);
*tempShort = pixel;
tempShort++;
oPtr = reinterpret_cast<unsigned char *>(tempShort);
}
}
}
}
}
else
{
size_pos pos = static_cast<size_pos>(512) +
(static_cast<size_pos>(y)*static_cast<size_pos>(imageRec->rawData.sizeX)*static_cast<size_pos>(imageRec->rawData.bpc))
+
(static_cast<size_pos>(z)*static_cast<size_pos>(imageRec->rawData.sizeX)*static_cast<size_pos>(imageRec->rawData.sizeY)*static_cast<size_pos>(imageRec->rawData.bpc));
size_pos amount =
static_cast<size_pos>(imageRec->rawData.sizeX)*static_cast<size_pos>(imageRec->rawData.bpc);
imageRec->rawData.file->seekg(pos, std::ios::beg);
imageRec->rawData.file->read((char*)buf, amount);
if (imageRec->rawData.swapFlag && imageRec->rawData.bpc != 1){
ConvertShort(reinterpret_cast<unsigned short*>(buf),
imageRec->rawData.sizeX);
}
}
}
static void RawImageGetData(ImageRec *imageRec, unsigned char **data)
{
unsigned char *ptr;
int i, j;
unsigned short *tempShort;
// // round the width to a factor 4
// int width =
(int)(floorf((float)imageRec->rawData.sizeX/4.0f)*4.0f);
// if (width!=imageRec->rawData.sizeX) width += 4;
// byte aligned.
OSG_INFO << "imageRec->rawData.sizeX = " << imageRec->rawData.sizeX <<
std::endl;
OSG_INFO << "imageRec->rawData.sizeY = " << imageRec->rawData.sizeY <<
std::endl;
OSG_INFO << "imageRec->rawData.sizeZ = " << imageRec->rawData.sizeZ <<
std::endl;
OSG_INFO << "imageRec->rawData.bpc = " << imageRec->rawData.bpc <<
std::endl;
*data = new unsigned
char[(imageRec->rawData.sizeX)*(imageRec->rawData.sizeY)*(imageRec->rawData.sizeZ)*(imageRec->rawData.bpc)];
ptr = *data;
for (i = 0; i < (int)(imageRec->rawData.sizeY); i++)
{
if (imageRec->rawData.sizeZ >= 1)
RawImageGetRow(imageRec, imageRec->rawData.tmpR, i, 0);
if (imageRec->rawData.sizeZ >= 2)
RawImageGetRow(imageRec, imageRec->rawData.tmpG, i, 1);
if (imageRec->rawData.sizeZ >= 3)
RawImageGetRow(imageRec, imageRec->rawData.tmpB, i, 2);
if (imageRec->rawData.sizeZ >= 4)
RawImageGetRow(imageRec, imageRec->rawData.tmpA, i, 3);
for (j = 0; j < (int)(imageRec->rawData.sizeX); j++)
{
if (imageRec->rawData.bpc == 1){
if (imageRec->rawData.sizeZ >= 1)
*ptr++ = *(imageRec->rawData.tmpR + j);
if (imageRec->rawData.sizeZ >= 2)
*ptr++ = *(imageRec->rawData.tmpG + j);
if (imageRec->rawData.sizeZ >= 3)
*ptr++ = *(imageRec->rawData.tmpB + j);
if (imageRec->rawData.sizeZ >= 4)
*ptr++ = *(imageRec->rawData.tmpA + j);
}else{
if (imageRec->rawData.sizeZ >= 1)
{
tempShort = reinterpret_cast<unsigned short*>(ptr);
*tempShort = *(reinterpret_cast<unsigned
short*>(imageRec->rawData.tmpR) + j);
tempShort++;
ptr = reinterpret_cast<unsigned char *>(tempShort);
}
if (imageRec->rawData.sizeZ >= 2)
{
tempShort = reinterpret_cast<unsigned short*>(ptr);
*tempShort = *(reinterpret_cast<unsigned
short*>(imageRec->rawData.tmpG) + j);
tempShort++;
ptr = reinterpret_cast<unsigned char *>(tempShort);
}
if (imageRec->rawData.sizeZ >= 3)
{
tempShort = reinterpret_cast<unsigned short*>(ptr);
*tempShort = *(reinterpret_cast<unsigned
short*>(imageRec->rawData.tmpB) + j);
tempShort++;
ptr = reinterpret_cast<unsigned char *>(tempShort);
}
if (imageRec->rawData.sizeZ >= 4)
{
tempShort = reinterpret_cast<unsigned short*>(ptr);
*tempShort = *(reinterpret_cast<unsigned
short*>(imageRec->rawData.tmpA) + j);
tempShort++;
ptr = reinterpret_cast<unsigned char *>(tempShort);
}
}
}
// // pad the image width with blanks to bring it up to the
rounded width.
// for(;j<width;++j) *ptr++ = 0;
}
}
class ReaderWriterRGB : public osgDB::ReaderWriter
{
public:
ReaderWriterRGB()
{
supportsExtension("rgb","rgb image format");
supportsExtension("rgba","rgba image format");
supportsExtension("sgi","sgi image format");
supportsExtension("int","int image format");
supportsExtension("inta","inta image format");
supportsExtension("bw","bw image format");
}
virtual const char* className() const { return "RGB Image
Reader/Writer"; }
ReadResult readRGBStream(std::istream& fin) const
{
osg::ref_ptr<ImageRec> imageRec;
if ((imageRec = RawImageOpen(fin)) == NULL)
{
return ReadResult::ERROR_IN_READING_FILE;
}
int s = imageRec->rawData.sizeX;
int t = imageRec->rawData.sizeY;
int r = 1;
unsigned int pixelFormat =
imageRec->rawData.sizeZ == 1 ? GL_LUMINANCE :
imageRec->rawData.sizeZ == 2 ? GL_LUMINANCE_ALPHA :
imageRec->rawData.sizeZ == 3 ? GL_RGB :
imageRec->rawData.sizeZ == 4 ? GL_RGBA : (GLenum)-1;
int internalFormat = pixelFormat;
unsigned int dataType = imageRec->rawData.bpc == 1 ?
GL_UNSIGNED_BYTE :
GL_UNSIGNED_SHORT;
unsigned char *data;
RawImageGetData(imageRec.get(), &data);
Image* image = new Image();
image->setImage(s,t,r,
internalFormat,
pixelFormat,
dataType,
data,
osg::Image::USE_NEW_DELETE);
OSG_INFO << "image read ok "<<s<<" "<<t<< std::endl;
return image;
}
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
osgDB::ReaderWriter::Options* =NULL) const
{
return readRGBStream(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;
osgDB::ifstream istream(fileName.c_str(), std::ios::in |
std::ios::binary);
if(!istream) return ReadResult::FILE_NOT_HANDLED;
ReadResult rr = readRGBStream(istream);
if(rr.validImage()) rr.getImage()->setFileName(file);
return rr;
}
WriteResult writeRGBStream(const osg::Image& img, std::ostream &fout,
const std::string& name) const
{
ImageRec imageRec;
imageRec.rawData.imagic = 0732;
GLenum dataType = img.getDataType();
imageRec.rawData.type = dataType == GL_UNSIGNED_BYTE ? 1 :
dataType == GL_BYTE ? 1 :
dataType == GL_BITMAP ? 1 :
dataType == GL_UNSIGNED_SHORT ? 2 :
dataType == GL_SHORT ? 2 :
dataType == GL_UNSIGNED_INT ? 4 :
dataType == GL_INT ? 4 :
dataType == GL_FLOAT ? 4 :
dataType == GL_UNSIGNED_BYTE_3_3_2 ? 1 :
dataType == GL_UNSIGNED_BYTE_2_3_3_REV ? 1 :
dataType == GL_UNSIGNED_SHORT_5_6_5 ? 2 :
dataType == GL_UNSIGNED_SHORT_5_6_5_REV ? 2 :
dataType == GL_UNSIGNED_SHORT_4_4_4_4 ? 2 :
dataType == GL_UNSIGNED_SHORT_4_4_4_4_REV ? 2 :
dataType == GL_UNSIGNED_SHORT_5_5_5_1 ? 2 :
dataType == GL_UNSIGNED_SHORT_1_5_5_5_REV ? 2 :
dataType == GL_UNSIGNED_INT_8_8_8_8 ? 4 :
dataType == GL_UNSIGNED_INT_8_8_8_8_REV ? 4 :
dataType == GL_UNSIGNED_INT_10_10_10_2 ? 4 :
dataType == GL_UNSIGNED_INT_2_10_10_10_REV ? 4 : 4;
GLenum pixelFormat = img.getPixelFormat();
imageRec.rawData.dim = 3;
imageRec.rawData.sizeX = img.s();
imageRec.rawData.sizeY = img.t();
imageRec.rawData.sizeZ =
pixelFormat == GL_COLOR_INDEX? 1 :
pixelFormat == GL_RED? 1 :
pixelFormat == GL_GREEN? 1 :
pixelFormat == GL_BLUE? 1 :
pixelFormat == GL_ALPHA? 1 :
pixelFormat == GL_RGB? 3 :
pixelFormat == GL_BGR ? 3 :
pixelFormat == GL_RGBA? 4 :
pixelFormat == GL_BGRA? 4 :
pixelFormat == GL_LUMINANCE? 1 :
pixelFormat == GL_LUMINANCE_ALPHA ? 2 : 1;
imageRec.rawData.min = 0;
imageRec.rawData.max = 0xFF;
imageRec.rawData.wasteBytes = 0;
size_t name_size = sizeof(imageRec.rawData.name) - 1;
strncpy(imageRec.rawData.name, name.c_str(), name_size);
imageRec.rawData.name[name_size] = 0;
imageRec.rawData.colorMap = 0;
imageRec.rawData.bpc = (img.getPixelSizeInBits() /
imageRec.rawData.sizeZ) / 8;
int isize = img.getImageSizeInBytes();
unsigned char *buffer = new unsigned char[isize];
if (imageRec.rawData.bpc == 1)
{
unsigned char *dptr = buffer;
int i, j;
for (i = 0; i < imageRec.rawData.sizeZ; ++i)
{
const unsigned char *ptr = img.data();
ptr += i;
for (j = 0; j < isize / imageRec.rawData.sizeZ; ++j)
{
*(dptr++) = *ptr;
ptr += imageRec.rawData.sizeZ;
}
}
}
else
{ // bpc == 2
unsigned short *dptr = reinterpret_cast<unsigned
short*>(buffer);
int i, j;
for (i = 0; i < imageRec.rawData.sizeZ; ++i)
{
const unsigned short *ptr = reinterpret_cast<const unsigned
short*>(img.data());
ptr += i;
for (j = 0; j < isize / (imageRec.rawData.sizeZ * 2); ++j)
{
*dptr = *ptr;
ConvertShort(dptr++, 1);
ptr += imageRec.rawData.sizeZ;
}
}
}
if (imageRec.needsBytesSwapped())
imageRec.swapBytes();
/*
swapBytes( imageRec.rawData.imagic );
swapBytes( imageRec.rawData.type );
swapBytes( imageRec.rawData.dim );
swapBytes( imageRec.rawData.sizeX );
swapBytes( imageRec.rawData.sizeY );
swapBytes( imageRec.rawData.sizeZ );
swapBytes( imageRec.rawData.min );
swapBytes( imageRec.rawData.max );
swapBytes( imageRec.rawData.colorMap );
*/
char pad[512 - sizeof(ImageRec)];
memset( pad, 0, sizeof(pad));
fout.write((const char*)&(imageRec.rawData), sizeof(ImageRec));
fout.write((const char*)pad,sizeof(pad));
fout.write((const char*)buffer,isize);
delete [] buffer;
return WriteResult::FILE_SAVED;
}
virtual WriteResult writeImage(const osg::Image& img,std::ostream&
fout,const osgDB::ReaderWriter::Options*) const
{
if (img.isCompressed())
{
OSG_NOTICE<<"Warning: RGB plugin does not supporting writing
compressed imagery."<<std::endl;
return WriteResult::ERROR_IN_WRITING_FILE;
}
if (!img.isDataContiguous())
{
OSG_NOTICE<<"Warning: RGB plugin does not supporting writing
non contiguous imagery."<<std::endl;
return WriteResult::ERROR_IN_WRITING_FILE;
}
return writeRGBStream(img,fout,"");
}
virtual WriteResult writeImage(const osg::Image &img,const std::string&
fileName, const osgDB::ReaderWriter::Options*) const
{
if (img.isCompressed())
{
OSG_NOTICE<<"Warning: RGB plugin does not supporting writing
compressed imagery."<<std::endl;
return WriteResult::ERROR_IN_WRITING_FILE;
}
if (!img.isDataContiguous())
{
OSG_NOTICE<<"Warning: RGB plugin does not supporting writing
non contiguous imagery."<<std::endl;
return WriteResult::ERROR_IN_WRITING_FILE;
}
std::string ext = osgDB::getFileExtension(fileName);
if (!acceptsExtension(ext)) return WriteResult::FILE_NOT_HANDLED;
osgDB::ofstream fout(fileName.c_str(), std::ios::out |
std::ios::binary);
if(!fout) return WriteResult::ERROR_IN_WRITING_FILE;
return writeRGBStream(img,fout,fileName);
}
};
// now register with Registry to instantiate the above
// reader/writer.
REGISTER_OSGPLUGIN(rgb, ReaderWriterRGB)
_______________________________________________
osg-submissions mailing list
[email protected]
http://lists.openscenegraph.org/listinfo.cgi/osg-submissions-openscenegraph.org