Introduced a cast(T) method into the ImageUtils template functor to allow code reading images to handle casting from source data to a form that a user can use more conviently

This commit is contained in:
Robert Osfield 2013-11-06 09:23:21 +00:00
parent ef3a65b93f
commit 6f6c44446c
6 changed files with 126 additions and 5 deletions

View File

@ -132,7 +132,7 @@ struct ScaleOperator
inline void rgba(float& r,float& g,float& b,float& a) const { r*= _scale; g*=_scale; b*=_scale; a*=_scale; } inline void rgba(float& r,float& g,float& b,float& a) const { r*= _scale; g*=_scale; b*=_scale; a*=_scale; }
}; };
struct RecordRowOperator struct RecordRowOperator : public osg::CastAndScaleToFloatOperation
{ {
RecordRowOperator(unsigned int num):_colours(num),_pos(0) {} RecordRowOperator(unsigned int num):_colours(num),_pos(0) {}

View File

@ -20,6 +20,68 @@
namespace osg { namespace osg {
template <typename T, class O>
void _readRow(unsigned int num, GLenum pixelFormat, const T* data, O& operation)
{
switch(pixelFormat)
{
case(GL_INTENSITY): { for(unsigned int i=0;i<num;++i) { T v=*data++; operation.rgba( operation.cast(v),operation.cast(v),operation.cast(v),operation.cast(v)); } } break;
case(GL_LUMINANCE): { for(unsigned int i=0;i<num;++i) { operation.luminance(operation.cast(*data++)); } } break;
case(GL_ALPHA): { for(unsigned int i=0;i<num;++i) { operation.alpha(operation.cast(*data++)); } } break;
case(GL_LUMINANCE_ALPHA): { for(unsigned int i=0;i<num;++i) { T l=*data++; T a = *data++; operation.luminance_alpha(operation.cast(l),operation.cast(a)); } } break;
case(GL_RGB): { for(unsigned int i=0;i<num;++i) { T r=*data++; T g=*data++; T b=*data++; operation.rgb(operation.cast(r),operation.cast(g),operation.cast(b)); } } break;
case(GL_RGBA): { for(unsigned int i=0;i<num;++i) { T r=*data++; T g=*data++; T b=*data++; T a=*data++; operation.rgba(operation.cast(r),operation.cast(g),operation.cast(b),operation.cast(a)); } } break;
case(GL_BGR): { for(unsigned int i=0;i<num;++i) { T b=*data++; T g=*data++; T r=*data++; operation.rgb(operation.cast(r),operation.cast(g),operation.cast(b)); } } break;
case(GL_BGRA): { for(unsigned int i=0;i<num;++i) { T b=*data++; T g=*data++; T r=*data++; T a=*data++; operation.rgba(operation.cast(r),operation.cast(g),operation.cast(b),operation.cast(a)); } } break;
}
}
template <class O>
void readRow(unsigned int num, GLenum pixelFormat, GLenum dataType, const unsigned char* data, O& operation)
{
switch(dataType)
{
case(GL_BYTE): _readRow(num, pixelFormat, (const char*)data, operation); break;
case(GL_UNSIGNED_BYTE): _readRow(num, pixelFormat, (const unsigned char*)data, operation); break;
case(GL_SHORT): _readRow(num, pixelFormat, (const short*) data, operation); break;
case(GL_UNSIGNED_SHORT): _readRow(num, pixelFormat, (const unsigned short*)data, operation); break;
case(GL_INT): _readRow(num, pixelFormat, (const int*) data, operation); break;
case(GL_UNSIGNED_INT): _readRow(num, pixelFormat, (const unsigned int*) data, operation); break;
case(GL_FLOAT): _readRow(num, pixelFormat, (const float*) data, operation); break;
case(GL_DOUBLE): _readRow(num, pixelFormat, (const double*) data, operation); break;
}
}
template <class O>
void readImage(const osg::Image* image, O& operation)
{
if (!image) return;
for(int r=0;r<image->r();++r)
{
for(int t=0;t<image->t();++t)
{
readRow(image->s(), image->getPixelFormat(), image->getDataType(), image->data(0,t,r), operation);
}
}
}
/** Convinience method for making it easy to cast all pixel channels types to a unit float RGBA form.*/
struct CastAndScaleToFloatOperation
{
float cast(char v) { return static_cast<float>(v)*(1.0f/128.0f); }
float cast(unsigned char v) { return static_cast<float>(v)*(1.0f/255.0f); }
float cast(short v) { return static_cast<float>(v)*(1.0f/32768.0f); }
float cast(unsigned short v) { return static_cast<float>(v)*(1.0f/65535.0f); }
float cast(int v) { return static_cast<float>(v)*(1.0f/2147483648.0f); }
float cast(unsigned int v) { return static_cast<float>(v)*(1.0f/4294967295.0f); }
float cast(float v) { return v; }
float cast(double v) { return static_cast<double>(v); }
};
#if 0
template <typename T, class O> template <typename T, class O>
void _readRow(unsigned int num, GLenum pixelFormat, const T* data,float scale, O& operation) void _readRow(unsigned int num, GLenum pixelFormat, const T* data,float scale, O& operation)
{ {
@ -63,6 +125,9 @@ void readImage(const osg::Image* image, O& operation)
} }
} }
} }
#endif
// example ModifyOperator // example ModifyOperator
// struct ModifyOperator // struct ModifyOperator

View File

@ -25,6 +25,9 @@
#include <osg/Vec2s> #include <osg/Vec2s>
#include <osg/Vec3s> #include <osg/Vec3s>
#include <osg/Vec4s> #include <osg/Vec4s>
#include <osg/Vec2i>
#include <osg/Vec3i>
#include <osg/Vec4i>
#include <osg/Matrixf> #include <osg/Matrixf>
#include <osg/Matrixd> #include <osg/Matrixd>
#include <osg/Plane> #include <osg/Plane>
@ -240,6 +243,59 @@ inline std::istream& operator >> (std::istream& input, Vec4s& vec)
} }
//////////////////////////////////////////////////////////////////////////
// Vec2i steaming operators.
inline std::ostream& operator << (std::ostream& output, const Vec2i& vec)
{
output << vec._v[0] << " "
<< vec._v[1];
return output; // to enable cascading
}
inline std::istream& operator >> (std::istream& input, Vec2i& vec)
{
input >> vec._v[0] >> std::ws >> vec._v[1];
return input;
}
//////////////////////////////////////////////////////////////////////////
// Vec3i steaming operators.
inline std::ostream& operator << (std::ostream& output, const Vec3i& vec)
{
output << vec._v[0] << " "
<< vec._v[1] << " "
<< vec._v[2];
return output; // to enable cascading
}
inline std::istream& operator >> (std::istream& input, Vec3i& vec)
{
input >> vec._v[0] >> std::ws >> vec._v[1] >> std::ws >> vec._v[2];
return input;
}
//////////////////////////////////////////////////////////////////////////
// Vec4i steaming operators.
inline std::ostream& operator << (std::ostream& output, const Vec4i& vec)
{
output << vec._v[0] << " "
<< vec._v[1] << " "
<< vec._v[2] << " "
<< vec._v[3];
return output; // to enable cascading
}
inline std::istream& operator >> (std::istream& input, Vec4i& vec)
{
input >> vec._v[0] >> std::ws
>> vec._v[1] >> std::ws
>> vec._v[2] >> std::ws
>> vec._v[3];
return input;
}
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
// Matrixf steaming operators. // Matrixf steaming operators.
inline std::ostream& operator<< (std::ostream& os, const Matrixf& m ) inline std::ostream& operator<< (std::ostream& os, const Matrixf& m )

View File

@ -22,7 +22,7 @@
namespace osg namespace osg
{ {
struct FindRangeOperator struct FindRangeOperator : public CastAndScaleToFloatOperation
{ {
FindRangeOperator(): FindRangeOperator():
_rmin(FLT_MAX), _rmin(FLT_MAX),
@ -168,7 +168,7 @@ void _copyRowAndScale(const unsigned char* src, GLenum srcDataType, unsigned cha
} }
} }
struct RecordRowOperator struct RecordRowOperator : public CastAndScaleToFloatOperation
{ {
RecordRowOperator(unsigned int num):_colours(num),_pos(0) {} RecordRowOperator(unsigned int num):_colours(num),_pos(0) {}

View File

@ -168,7 +168,7 @@ class ReaderWriterDICOM : public osgDB::ReaderWriter
tile->setVolumeTechnique(new osgVolume::RayTracedTechnique()); tile->setVolumeTechnique(new osgVolume::RayTracedTechnique());
osg::ref_ptr<osgVolume::ImageLayer> layer= new osgVolume::ImageLayer(result.getImage()); osg::ref_ptr<osgVolume::ImageLayer> layer= new osgVolume::ImageLayer(result.getImage());
layer->rescaleToZeroToOneRange(); //layer->rescaleToZeroToOneRange();
osgVolume::SwitchProperty* sp = new osgVolume::SwitchProperty; osgVolume::SwitchProperty* sp = new osgVolume::SwitchProperty;
sp->setActiveProperty(0); sp->setActiveProperty(0);

View File

@ -491,7 +491,7 @@ osg::Image* osgVolume::createNormalMapTexture(osg::Image* image_3d)
// //
// applyTransferFunction // applyTransferFunction
// //
struct ApplyTransferFunctionOperator struct ApplyTransferFunctionOperator : public osg::CastAndScaleToFloatOperation
{ {
ApplyTransferFunctionOperator(osg::TransferFunction1D* tf, unsigned char* data): ApplyTransferFunctionOperator(osg::TransferFunction1D* tf, unsigned char* data):
_tf(tf), _tf(tf),