📄 readerwriterrgb.cpp
字号:
// 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#endifusing namespace osg;typedef struct _rawImageRec{ 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; 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( imagic ); swapBytes( type ); swapBytes( dim ); swapBytes( sizeX ); swapBytes( sizeY ); swapBytes( sizeZ ); swapBytes( wasteBytes ); swapBytes( min ); swapBytes( max ); swapBytes( colorMap ); }} rawImageRec;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 void RawImageClose(rawImageRec *raw){ if (raw) { if (raw->tmp) delete [] raw->tmp; if (raw->tmpR) delete [] raw->tmpR; if (raw->tmpG) delete [] raw->tmpG; if (raw->tmpB) delete [] raw->tmpB; if (raw->tmpA) delete [] raw->tmpA; if (raw->rowStart) delete [] raw->rowStart; if (raw->rowSize) delete [] raw->rowSize; delete raw; }}static rawImageRec *RawImageOpen(std::istream& fin){ union { int testWord; char testByte[4]; } endianTest; rawImageRec *raw; int x; raw = new rawImageRec; if (raw == NULL) { notify(WARN)<< "Out of memory!"<< std::endl; return NULL; } //Set istream pointer raw->file = &fin; endianTest.testWord = 1; if (endianTest.testByte[0] == 1) { raw->swapFlag = GL_TRUE; } else { raw->swapFlag = GL_FALSE; } fin.read((char*)raw,12); if (!fin.good()) return NULL; if (raw->swapFlag) { ConvertShort(&raw->imagic, 6); } raw->tmp = raw->tmpR = raw->tmpG = raw->tmpB = raw->tmpA = 0L; raw->rowStart = 0; raw->rowSize = 0; raw->bpc = (raw->type & 0x00FF); raw->tmp = new unsigned char [raw->sizeX*256*raw->bpc]; if (raw->tmp == NULL ) { notify(FATAL)<< "Out of memory!"<< std::endl; RawImageClose(raw); return NULL; } if( raw->sizeZ >= 1 ) { if( (raw->tmpR = new unsigned char [raw->sizeX*raw->bpc]) == NULL ) { notify(FATAL)<< "Out of memory!"<< std::endl; RawImageClose(raw); return NULL; } } if( raw->sizeZ >= 2 ) { if( (raw->tmpG = new unsigned char [raw->sizeX*raw->bpc]) == NULL ) { notify(FATAL)<< "Out of memory!"<< std::endl; RawImageClose(raw); return NULL; } } if( raw->sizeZ >= 3 ) { if( (raw->tmpB = new unsigned char [raw->sizeX*raw->bpc]) == NULL ) { notify(FATAL)<< "Out of memory!"<< std::endl; RawImageClose(raw); return NULL; } } if (raw->sizeZ >= 4) { if( (raw->tmpA = new unsigned char [raw->sizeX*raw->bpc]) == NULL ) { notify(FATAL)<< "Out of memory!"<< std::endl; RawImageClose(raw); return NULL; } } if ((raw->type & 0xFF00) == 0x0100) { unsigned int ybyz = raw->sizeY * raw->sizeZ; if ( (raw->rowStart = new GLuint [ybyz]) == NULL ) { notify(FATAL)<< "Out of memory!"<< std::endl; RawImageClose(raw); return NULL; } if ( (raw->rowSize = new GLint [ybyz]) == NULL ) { notify(FATAL)<< "Out of memory!"<< std::endl; RawImageClose(raw); return NULL; } x = ybyz * sizeof(GLuint); raw->rleEnd = 512 + (2 * x); fin.seekg(512,std::ios::beg); fin.read((char*)raw->rowStart,x); fin.read((char*)raw->rowSize,x); if (raw->swapFlag) { ConvertLong(raw->rowStart, (long) (x/sizeof(GLuint))); ConvertLong((GLuint *)raw->rowSize, (long) (x/sizeof(GLint))); } } return raw;}static void RawImageGetRow(rawImageRec *raw, unsigned char *buf, int y, int z){ unsigned char *iPtr, *oPtr; unsigned short pixel; int count, done = 0; unsigned short *tempShort; if ((raw->type & 0xFF00) == 0x0100) { raw->file->seekg((long) raw->rowStart[y+z*raw->sizeY], std::ios::beg); raw->file->read((char*)raw->tmp, (unsigned int)raw->rowSize[y+z*raw->sizeY]); iPtr = raw->tmp; oPtr = buf; while (!done) { if (raw->bpc == 1) pixel = *iPtr++; else { tempShort = reinterpret_cast<unsigned short*>(iPtr); pixel = *tempShort; tempShort++; iPtr = reinterpret_cast<unsigned char *>(tempShort); } if(raw->bpc != 1) ConvertShort(&pixel, 1); count = (int)(pixel & 0x7F); // limit the count value to the remiaing row size if (oPtr + count*raw->bpc > buf + raw->sizeX*raw->bpc) { count = ( (buf + raw->sizeX*raw->bpc) - oPtr ) / raw->bpc; } if (count<=0) { done = 1; return; } if (pixel & 0x80) { while (count--) { if(raw->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 (raw->bpc == 1) { pixel = *iPtr++; } else { tempShort = reinterpret_cast<unsigned short*>(iPtr); pixel = *tempShort; tempShort++; iPtr = reinterpret_cast<unsigned char *>(tempShort);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -