| 71 | | template <typename T, class O> |
| 72 | | void _readRow(unsigned int num, GLenum pixelFormat, T* data,float scale, const O& operation) |
| 73 | | { |
| 74 | | switch(pixelFormat) |
| 75 | | { |
| 76 | | case(GL_LUMINANCE): { for(unsigned int i=0;i<num;++i) { float l = float(*data++)*scale; operation.luminance(l); } } break; |
| 77 | | case(GL_ALPHA): { for(unsigned int i=0;i<num;++i) { float a = float(*data++)*scale; operation.alpha(a); } } break; |
| 78 | | case(GL_LUMINANCE_ALPHA): { for(unsigned int i=0;i<num;++i) { float l = float(*data++)*scale; float a = float(*data++)*scale; operation.luminance_alpha(l,a); } } break; |
| 79 | | case(GL_RGB): { for(unsigned int i=0;i<num;++i) { float r = float(*data++)*scale; float g = float(*data++)*scale; float b = float(*data++)*scale; operation.rgb(r,g,b); } } break; |
| 80 | | case(GL_RGBA): { for(unsigned int i=0;i<num;++i) { float r = float(*data++)*scale; float g = float(*data++)*scale; float b = float(*data++)*scale; float a = float(*data++)*scale; operation.rgba(r,g,b,a); } } break; |
| 81 | | case(GL_BGR): { for(unsigned int i=0;i<num;++i) { float b = float(*data++)*scale; float g = float(*data++)*scale; float r = float(*data++)*scale; operation.rgb(r,g,b); } } break; |
| 82 | | case(GL_BGRA): { for(unsigned int i=0;i<num;++i) { float b = float(*data++)*scale; float g = float(*data++)*scale; float r = float(*data++)*scale; float a = float(*data++)*scale; operation.rgba(r,g,b,a); } } break; |
| 83 | | } |
| 84 | | } |
| 85 | | |
| 86 | | template <class O> |
| 87 | | void readRow(unsigned int num, GLenum pixelFormat, GLenum dataType, unsigned char* data, const O& operation) |
| 88 | | { |
| 89 | | switch(dataType) |
| 90 | | { |
| 91 | | case(GL_BYTE): _readRow(num,pixelFormat, (char*)data, 1.0f/128.0f, operation); break; |
| 92 | | case(GL_UNSIGNED_BYTE): _readRow(num,pixelFormat, (unsigned char*)data, 1.0f/255.0f, operation); break; |
| 93 | | case(GL_SHORT): _readRow(num,pixelFormat, (short*) data, 1.0f/32768.0f, operation); break; |
| 94 | | case(GL_UNSIGNED_SHORT): _readRow(num,pixelFormat, (unsigned short*)data, 1.0f/65535.0f, operation); break; |
| 95 | | case(GL_INT): _readRow(num,pixelFormat, (int*) data, 1.0f/2147483648.0f, operation); break; |
| 96 | | case(GL_UNSIGNED_INT): _readRow(num,pixelFormat, (unsigned int*) data, 1.0f/4294967295.0f, operation); break; |
| 97 | | case(GL_FLOAT): _readRow(num,pixelFormat, (float*) data, 1.0f, operation); break; |
| 98 | | } |
| 99 | | } |
| 100 | | |
| 101 | | template <class O> |
| 102 | | void readImage(osg::Image* image, const O& operation) |
| 103 | | { |
| 104 | | if (!image) return; |
| 105 | | |
| 106 | | for(int r=0;r<image->r();++r) |
| 107 | | { |
| 108 | | for(int t=0;t<image->t();++t) |
| 109 | | { |
| 110 | | readRow(image->s(), image->getPixelFormat(), image->getDataType(), image->data(0,t,r), operation); |
| 111 | | } |
| 112 | | } |
| 113 | | } |
| 114 | | |
| 115 | | // example ModifyOperator |
| 116 | | // struct ModifyOperator |
| 117 | | // { |
| 118 | | // inline void luminance(float& l) const {} |
| 119 | | // inline void alpha(float& a) const {} |
| 120 | | // inline void luminance_alpha(float& l,float& a) const {} |
| 121 | | // inline void rgb(float& r,float& g,float& b) const {} |
| 122 | | // inline void rgba(float& r,float& g,float& b,float& a) const {} |
| 123 | | // }; |
| 124 | | |
| 125 | | |
| 126 | | template <typename T, class M> |
| 127 | | void _modifyRow(unsigned int num, GLenum pixelFormat, T* data,float scale, const M& operation) |
| 128 | | { |
| 129 | | float inv_scale = 1.0f/scale; |
| 130 | | switch(pixelFormat) |
| 131 | | { |
| 132 | | case(GL_LUMINANCE): { for(unsigned int i=0;i<num;++i) { float l = float(*data)*scale; operation.luminance(l); *data++ = T(l*inv_scale); } } break; |
| 133 | | case(GL_ALPHA): { for(unsigned int i=0;i<num;++i) { float a = float(*data)*scale; operation.alpha(a); *data++ = T(a*inv_scale); } } break; |
| 134 | | case(GL_LUMINANCE_ALPHA): { for(unsigned int i=0;i<num;++i) { float l = float(*data)*scale; float a = float(*(data+1))*scale; operation.luminance_alpha(l,a); *data++ = T(l*inv_scale); *data++ = T(a*inv_scale); } } break; |
| 135 | | case(GL_RGB): { for(unsigned int i=0;i<num;++i) { float r = float(*data)*scale; float g = float(*(data+1))*scale; float b = float(*(data+2))*scale; operation.rgb(r,g,b); *data++ = T(r*inv_scale); *data++ = T(g*inv_scale); *data++ = T(b*inv_scale); } } break; |
| 136 | | case(GL_RGBA): { for(unsigned int i=0;i<num;++i) { float r = float(*data)*scale; float g = float(*(data+1))*scale; float b = float(*(data+2))*scale; float a = float(*(data+3))*scale; operation.rgba(r,g,b,a); *data++ = T(r*inv_scale); *data++ = T(g*inv_scale); *data++ = T(g*inv_scale); *data++ = T(a*inv_scale); } } break; |
| 137 | | case(GL_BGR): { for(unsigned int i=0;i<num;++i) { float b = float(*data)*scale; float g = float(*(data+1))*scale; float r = float(*(data+2))*scale; operation.rgb(r,g,b); *data++ = T(b*inv_scale); *data++ = T(g*inv_scale); *data++ = T(r*inv_scale); } } break; |
| 138 | | case(GL_BGRA): { for(unsigned int i=0;i<num;++i) { float b = float(*data)*scale; float g = float(*(data+1))*scale; float r = float(*(data+2))*scale; float a = float(*(data+3))*scale; operation.rgba(r,g,b,a); *data++ = T(g*inv_scale); *data++ = T(b*inv_scale); *data++ = T(r*inv_scale); *data++ = T(a*inv_scale); } } break; |
| 139 | | } |
| 140 | | } |
| 141 | | |
| 142 | | template <class M> |
| 143 | | void modifyRow(unsigned int num, GLenum pixelFormat, GLenum dataType, unsigned char* data, const M& operation) |
| 144 | | { |
| 145 | | switch(dataType) |
| 146 | | { |
| 147 | | case(GL_BYTE): _modifyRow(num,pixelFormat, (char*)data, 1.0f/128.0f, operation); break; |
| 148 | | case(GL_UNSIGNED_BYTE): _modifyRow(num,pixelFormat, (unsigned char*)data, 1.0f/255.0f, operation); break; |
| 149 | | case(GL_SHORT): _modifyRow(num,pixelFormat, (short*) data, 1.0f/32768.0f, operation); break; |
| 150 | | case(GL_UNSIGNED_SHORT): _modifyRow(num,pixelFormat, (unsigned short*)data, 1.0f/65535.0f, operation); break; |
| 151 | | case(GL_INT): _modifyRow(num,pixelFormat, (int*) data, 1.0f/2147483648.0f, operation); break; |
| 152 | | case(GL_UNSIGNED_INT): _modifyRow(num,pixelFormat, (unsigned int*) data, 1.0f/4294967295.0f, operation); break; |
| 153 | | case(GL_FLOAT): _modifyRow(num,pixelFormat, (float*) data, 1.0f, operation); break; |
| 154 | | } |
| 155 | | } |
| 156 | | |
| 157 | | template <class M> |
| 158 | | void modifyImage(osg::Image* image, const M& operation) |
| 159 | | { |
| 160 | | if (!image) return; |
| 161 | | |
| 162 | | for(int r=0;r<image->r();++r) |
| 163 | | { |
| 164 | | for(int t=0;t<image->t();++t) |
| 165 | | { |
| 166 | | modifyRow(image->s(), image->getPixelFormat(), image->getDataType(), image->data(0,t,r), operation); |
| 167 | | } |
| 168 | | } |
| 169 | | } |
| | 1808 | osg::Vec4 minValue, maxValue; |
| | 1809 | if (osgVolume::computeMinMax(image_3d.get(), minValue, maxValue)); |
| | 1810 | { |
| | 1811 | osg::notify(osg::NOTICE)<<"Min value "<<minValue<<std::endl; |
| | 1812 | osg::notify(osg::NOTICE)<<"Max value "<<maxValue<<std::endl; |
| | 1813 | |
| | 1814 | float minComponent = minValue[0]; |
| | 1815 | minComponent = osg::minimum(minComponent,minValue[1]); |
| | 1816 | minComponent = osg::minimum(minComponent,minValue[2]); |
| | 1817 | minComponent = osg::minimum(minComponent,minValue[3]); |
| | 1818 | |
| | 1819 | float maxComponent = maxValue[0]; |
| | 1820 | maxComponent = osg::maximum(maxComponent,maxValue[1]); |
| | 1821 | maxComponent = osg::maximum(maxComponent,maxValue[2]); |
| | 1822 | maxComponent = osg::maximum(maxComponent,maxValue[3]); |
| | 1823 | |
| | 1824 | float scale = 0.99f/(maxComponent-minComponent); |
| | 1825 | float offset = -minComponent * scale; |
| | 1826 | |
| | 1827 | osgVolume::offsetAndScaleImage(image_3d.get(), |
| | 1828 | osg::Vec4(offset, offset, offset, offset), |
| | 1829 | osg::Vec4(scale, scale, scale, scale)); |
| | 1830 | |
| | 1831 | } |
| | 1832 | |
| | 1833 | #if 0 |
| | 1834 | osg::Vec4 newMinValue, newMaxValue; |
| | 1835 | if (osgVolume::computeMinMax(image_3d.get(), newMinValue, newMaxValue)); |
| | 1836 | { |
| | 1837 | osg::notify(osg::NOTICE)<<"After min value "<<newMinValue<<std::endl; |
| | 1838 | osg::notify(osg::NOTICE)<<"After max value "<<newMaxValue<<std::endl; |
| | 1839 | |
| | 1840 | } |
| | 1841 | #endif |
| | 1842 | |
| | 1843 | if (colourSpaceOperation!=NO_COLOUR_SPACE_OPERATION) |
| | 1844 | { |
| | 1845 | doColourSpaceConversion(colourSpaceOperation, image_3d.get(), colourModulate); |
| | 1846 | } |
| | 1847 | |
| | 1848 | if (transferFunction.valid()) |
| | 1849 | { |
| | 1850 | image_3d = applyTransferFunction(image_3d.get(), transferFunction.get()); |
| | 1851 | } |
| | 1852 | |
| | 1853 | osg::ref_ptr<osg::Image> normalmap_3d = createNormalMap ? createNormalMapTexture(image_3d.get()) : 0; |
| | 1854 | |
| | 1855 | |
| | 1856 | |