Manta Interactive Ray Tracer Development Mailing List

Text archives Help


[MANTA] r487 - trunk/Model/Readers


Chronological Thread 
  • From: vpegorar@sci.utah.edu
  • To: manta@sci.utah.edu
  • Subject: [MANTA] r487 - trunk/Model/Readers
  • Date: Mon, 22 Aug 2005 17:00:46 -0600 (MDT)

Author: vpegorar
Date: Mon Aug 22 17:00:45 2005
New Revision: 487

Added:
   trunk/Model/Readers/VolumeReader.cc
   trunk/Model/Readers/VolumeReader.h
Modified:
   trunk/Model/Readers/CMakeLists.txt
Log:
Utilities to read/write raw and nrrd volume files.

Modified: trunk/Model/Readers/CMakeLists.txt
==============================================================================
--- trunk/Model/Readers/CMakeLists.txt  (original)
+++ trunk/Model/Readers/CMakeLists.txt  Mon Aug 22 17:00:45 2005
@@ -1,4 +1,5 @@
-
-SET (Manta_Readers_SRCS
-     Readers/PlyReader.cc
-     Readers/rply/rply.c)
+
+SET (Manta_Readers_SRCS
+     Readers/VolumeReader.cc
+     Readers/PlyReader.cc
+     Readers/rply/rply.c)

Added: trunk/Model/Readers/VolumeReader.cc
==============================================================================
--- (empty file)
+++ trunk/Model/Readers/VolumeReader.cc Mon Aug 22 17:00:45 2005
@@ -0,0 +1,357 @@
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <string>
+#include <fstream>
+#include <Model/Readers/VolumeReader.h>
+
+#define TMPSIZE 256
+
+using namespace std;
+using namespace Manta;
+
+//enum DataFormats        {  CHAR ,  UNSIGNED_CHAR ,  SHORT ,  
UNSIGNED_SHORT ,  INT ,  UNSIGNED_INT ,  LONG ,  UNSIGNED_LONG ,  FLOAT ,  
DOUBLE , DATAFORMATSNB };
+char * hdrFormatTags[]  = { "CHAR", "UNSIGNED_CHAR", "SHORT", 
"UNSIGNED_SHORT", "INT", "UNSIGNED_INT", "LONG", "UNSIGNED_LONG", "FLOAT", 
"DOUBLE" };
+char * nrrdFormatTags[] = { "char", "unsigned_char", "short", 
"unsigned_short", "int", "unsigned_int", "long", "unsigned_long", "float", 
"double" };
+
+
+// 
--------------------------------------------------------------------------------------
+// --- Returns true if the machine uses Big endian, false if it uses small 
endian
+// 
--------------------------------------------------------------------------------------
+bool IsMachineEndianBig()
+{
+       short tmp = 0x1234;
+       if (*reinterpret_cast<char*>(&tmp) == 0x12)     return true;
+       else                                                                  
          return false;
+}
+
+
+// 
--------------------------------------------------------------------------------------
+// --- Swap bytes to convert from big endian to little endian, and vice-versa
+// 
--------------------------------------------------------------------------------------
+void SwapBytes(void * data, int bytesNb)
+{
+       int i, bytesNb2, ind;
+       char tmp, * p;
+
+       p = (char *)data;
+       bytesNb2 = bytesNb / 2;
+
+       for(i=0; i<bytesNb2; i++)
+       {
+               ind = bytesNb - i - 1;
+               tmp = p[i];
+               p[i] = p[ind];
+               p[ind] = tmp;
+       }
+}
+
+
+// 
--------------------------------------------------------------------------------------
+// --- Split string[] into two subStrings by looking for the last occurance 
of tag
+// --- Return true if the split occured (tag found), and false otherwise
+// 
--------------------------------------------------------------------------------------
+bool SplitString(const char * string, const char tag, char subString1[], 
char subString2[])
+{
+       char * ptag = strrchr(string, tag);
+
+       if (ptag)
+       {
+               strncpy(subString1, string, ptag - string);
+               subString1[ptag - string] = '\0';
+               ptag++;
+               strcpy(subString2, ptag);
+               return true;
+       }
+       else
+       {
+               strcpy(subString1, "");
+               strcpy(subString2, "");
+               return false;
+       }
+}
+
+
+// 
--------------------------------------------------------------------------------------
+// --- Read raw values of given format and endianness from inputStream to 
data (of given dimensions)
+// --- Return true if successful, false otherwise
+// 
--------------------------------------------------------------------------------------
+bool Manta::ReadRawData(ifstream & inputStream, Array3<float> & data, 
DataFormat format, bool bigEndian)
+{
+       char * idata;
+       int i, j, k, nx, ny, nz, formatSize;
+       bool swap;
+       void * vd;
+
+       nx = data.getNx();
+       ny = data.getNy();
+       nz = data.getNz();
+
+       if              (format == CHAR                         ) formatSize 
= sizeof(char);
+       else if (format == UNSIGNED_CHAR        ) formatSize = 
sizeof(unsigned char);
+       else if (format == SHORT                        ) formatSize = 
sizeof(short);
+       else if (format == UNSIGNED_SHORT       ) formatSize = 
sizeof(unsigned short);
+       else if (format == INT                          ) formatSize = 
sizeof(int);
+       else if (format == UNSIGNED_INT         ) formatSize = 
sizeof(unsigned int);
+       else if (format == LONG                         ) formatSize = 
sizeof(long);
+       else if (format == UNSIGNED_LONG        ) formatSize = 
sizeof(unsigned long);
+       else if (format == FLOAT                        ) formatSize = 
sizeof(float);
+       else if (format == DOUBLE                       ) formatSize = 
sizeof(double);
+       else return false;
+
+       swap = (bigEndian != IsMachineEndianBig());
+       idata = (char *)malloc(nx * ny * nz * formatSize);
+
+       inputStream.read(idata, nx * ny * nz * formatSize);
+       if (!inputStream) return false;
+
+       for(i=0; i<nz; i++)
+               for(j=0; j<ny; j++)
+                       for(k=0; k<nx; k++)
+                       {
+                               vd = (void *) (&(idata[((i*ny + j)*nx + k) * 
formatSize]));
+
+                               if (swap) SwapBytes(vd, formatSize);
+
+                               if              (format == CHAR               
          ) data(k, j, i) = (float)*((char                        *)vd);
+                               else if (format == UNSIGNED_CHAR        ) 
data(k, j, i) = (float)*((unsigned char       *)vd);
+                               else if (format == SHORT                      
  ) data(k, j, i) = (float)*((short                       *)vd);
+                               else if (format == UNSIGNED_SHORT       ) 
data(k, j, i) = (float)*((unsigned short      *)vd);
+                               else if (format == INT                        
  ) data(k, j, i) = (float)*((int                         *)vd);
+                               else if (format == UNSIGNED_INT         ) 
data(k, j, i) = (float)*((unsigned int        *)vd);
+                               else if (format == LONG                       
  ) data(k, j, i) = (float)*((long                        *)vd);
+                               else if (format == UNSIGNED_LONG        ) 
data(k, j, i) = (float)*((unsigned long       *)vd);
+                               else if (format == FLOAT                      
  ) data(k, j, i) = (float)*((float                       *)vd);
+                               else if (format == DOUBLE                     
  ) data(k, j, i) = (float)*((double                      *)vd);
+                       }
+
+       free(idata);
+
+       return true;
+}
+
+
+// 
--------------------------------------------------------------------------------------
+// --- Write raw values with given format and endianness from data (of given 
dimensions) to outputStream
+// --- Return true if successful, false otherwise
+// 
--------------------------------------------------------------------------------------
+bool Manta::WriteRawData(ofstream & outputStream, const Array3<float> & 
data, DataFormat format, bool bigEndian)
+{
+       char * idata;
+       int i, j, k, nx, ny, nz, formatSize;
+       bool swap;
+       void * vd;
+
+       nx = data.getNx();
+       ny = data.getNy();
+       nz = data.getNz();
+
+       if              (format == CHAR                         ) formatSize 
= sizeof(char);
+       else if (format == UNSIGNED_CHAR        ) formatSize = 
sizeof(unsigned char);
+       else if (format == SHORT                        ) formatSize = 
sizeof(short);
+       else if (format == UNSIGNED_SHORT       ) formatSize = 
sizeof(unsigned short);
+       else if (format == INT                          ) formatSize = 
sizeof(int);
+       else if (format == UNSIGNED_INT         ) formatSize = 
sizeof(unsigned int);
+       else if (format == LONG                         ) formatSize = 
sizeof(long);
+       else if (format == UNSIGNED_LONG        ) formatSize = 
sizeof(unsigned long);
+       else if (format == FLOAT                        ) formatSize = 
sizeof(float);
+       else if (format == DOUBLE                       ) formatSize = 
sizeof(double);
+       else return false;
+
+       swap = (bigEndian != IsMachineEndianBig());
+       idata = (char *)malloc(nx * ny * nz * formatSize);
+
+       for(i=0; i<nz; i++)
+               for(j=0; j<ny; j++)
+                       for(k=0; k<nx; k++)
+                       {
+                               vd = (void *) (&(idata[((i*ny + j)*nx + k) * 
formatSize]));
+
+                               if              (format == CHAR               
          ) *((char                       *)vd) = (char                   
)data(k, j, i);
+                               else if (format == UNSIGNED_CHAR        ) 
*((unsigned char      *)vd) = (unsigned char  )data(k, j, i);
+                               else if (format == SHORT                      
  ) *((short                      *)vd) = (short                  )data(k, j, 
i);
+                               else if (format == UNSIGNED_SHORT       ) 
*((unsigned short     *)vd) = (unsigned short )data(k, j, i);
+                               else if (format == INT                        
  ) *((int                        *)vd) = (int                    )data(k, j, 
i);
+                               else if (format == UNSIGNED_INT         ) 
*((unsigned int       *)vd) = (unsigned int   )data(k, j, i);
+                               else if (format == LONG                       
  ) *((long                       *)vd) = (long                   )data(k, j, 
i);
+                               else if (format == UNSIGNED_LONG        ) 
*((unsigned long      *)vd) = (unsigned long  )data(k, j, i);
+                               else if (format == FLOAT                      
  ) *((float                      *)vd) = (float                  )data(k, j, 
i);
+                               else if (format == DOUBLE                     
  ) *((double                     *)vd) = (double                 )data(k, j, 
i);
+
+                               if (swap) SwapBytes(vd, formatSize);
+                       }
+
+       outputStream.write(idata, nx * ny * nz * formatSize);
+       if (!outputStream) return false;
+
+       free(idata);
+
+       return true;
+}
+
+
+// 
--------------------------------------------------------------------------------------
+// --- Read NRRD file
+// 
--------------------------------------------------------------------------------------
+void Manta::ReadNRRDFile(const std::string & fileName, Array3<float> & data)
+{
+       int nx, ny, nz, i, dim;
+       string tmp, encoding, formatStr, fileEndian;
+       DataFormat format;
+       bool bigEndian;
+
+       ifstream in(fileName.c_str(), std::ios::in | std::ios::binary);
+       if (!in)
+       {
+               cerr << "Error : ReadNRRDFile() : opening file " << fileName 
<< '\n';
+               exit(1);
+       }
+       in >> tmp;
+       in >> tmp >> formatStr;
+       in >> tmp >> dim;
+       if (dim != 3) {fprintf(stderr, "Error : ReadNRRDFile() : incorrect 
dimension %d\n", dim); exit(1);}
+       in >> tmp >> nx >> ny >> nz;
+       in >> tmp >> fileEndian;
+       in >> tmp >> encoding;
+       if (encoding != "raw") {fprintf(stderr, "Error : ReadNRRDFile() : 
unknown encoding %s\n", encoding.c_str()); exit(1);}
+       in.get();
+       in.get();
+
+       format = DATAFORMATSNB;
+       for(i=0; i<DATAFORMATSNB; i++)
+               if (strcmp(formatStr.c_str(), nrrdFormatTags[i]) == 0)
+               {
+                       format = DataFormats(i);
+                       break;
+               }
+       if (format == DATAFORMATSNB)
+       {
+               cerr << "Error : ReadNRRDFile() : unsupported format " << 
formatStr << '\n';
+               exit(1);
+       }
+
+       if (fileEndian == "big")        bigEndian = true;
+       else                                            bigEndian = false;
+
+       cout << "Reading " << fileName << " : " << nx << 'x' << ny << 'x' << 
nz << '\n';
+       data.resize(nx, ny, nz);
+       if (!ReadRawData(in, data, format, bigEndian))
+       {
+               cerr << "Error : ReadNRRDFile() : reading volume " << 
fileName << '\n';
+               exit(1);
+       }
+}
+
+
+// 
--------------------------------------------------------------------------------------
+// --- Write NRRD file
+// 
--------------------------------------------------------------------------------------
+void Manta::WriteNRRDFile(const std::string & fileName, const Array3<float> 
& data, DataFormat format, bool bigEndian)
+{
+       int nx, ny, nz;
+       string fileEndian;
+
+       nx = data.getNx();
+       ny = data.getNy();
+       nz = data.getNz();
+
+       if (bigEndian)  fileEndian = "big";
+       else                    fileEndian = "little";
+
+       ofstream out(fileName.c_str(), std::ios::out | std::ios::binary);
+       if (!out)
+       {
+               cerr << "Error : WriteNRRDFile() : creating file " << 
fileName << '\n';
+               exit(1);
+       }
+       out << "NRRD0001" << '\n';
+       out << "type: " << nrrdFormatTags[format] << '\n';
+       out << "dimension: " << 3 << "\n";
+       out << "sizes: " << nx << " " << ny << " " << nz << '\n';
+       out << "endian: " << fileEndian << '\n';
+       out << "encoding: " << "raw" << '\n';
+       out << '\n';
+
+       cout << "Writing " << fileName << " : " << nx << 'x' << ny << 'x' << 
nz << '\n';
+       if (!WriteRawData(out, data, format, bigEndian))
+       {
+               cerr << "Error : WriteNRRDFile() : writing volume " << 
fileName << '\n';
+               exit(1);
+       }
+}
+
+
+// 
--------------------------------------------------------------------------------------
+// --- Read HDR file
+// 
--------------------------------------------------------------------------------------
+void Manta::ReadHDRFile(const std::string & fileName, Array3<float> & data)
+{
+       int nx, ny, nz, i;
+       string tmp, volumeName, formatStr, fileEndian;
+       DataFormat format;
+       bool bigEndian;
+
+       ifstream hdr(fileName.c_str());
+       if (!hdr)
+       {
+               cerr << "Error : ReadHDRFile() : opening header " << fileName 
<< '\n';
+               exit(1);
+       }
+       hdr >> tmp >> volumeName;
+       hdr >> tmp >> nx >> ny >> nz;
+       hdr >> tmp >> formatStr;
+       hdr >> tmp >> fileEndian;
+
+       format = DATAFORMATSNB;
+       for(i=0; i<DATAFORMATSNB; i++)
+               if (strcmp(formatStr.c_str(), hdrFormatTags[i]) == 0)
+               {
+                       format = DataFormats(i);
+                       break;
+               }
+       if (format == DATAFORMATSNB)
+       {
+               cerr << "Error : ReadHDRFile() : unsupported format " << 
formatStr << '\n';
+               exit(1);
+       }
+
+       if (fileEndian == "BIG_ENDIAN") bigEndian = true;
+       else                                                    bigEndian = 
false;
+
+       cout << "Reading " << volumeName << " : " << nx << 'x' << ny << 'x' 
<< nz << '\n';
+       ifstream inputStream(volumeName.c_str(), std::ios::in | 
std::ios::binary);
+       if (!inputStream)
+       {
+               cerr << "Error : ReadHDRFile() : opening volume " << 
volumeName << '\n';
+               exit(1);
+       }
+       data.resize(nx, ny, nz);
+       if (!ReadRawData(inputStream, data, format, bigEndian))
+       {
+               cerr << "Error : ReadHDRFile() : reading volume " << 
volumeName << '\n';
+               exit(1);
+       }
+}
+
+
+// 
--------------------------------------------------------------------------------------
+// --- Read file of which format is determined by its extension
+// 
--------------------------------------------------------------------------------------
+void Manta::ReadVolumeFile(const std::string & fileName, Array3<float> & 
data)
+{
+       char name[256], extension[256];
+
+       SplitString(fileName.c_str(), '.', name, extension);
+       if              (strcmp(extension, "hdr" ) == 0) ReadHDRFile 
(fileName, data);
+       else if (strcmp(extension, "nrrd") == 0) ReadNRRDFile(fileName, data);
+       else
+       {
+               fprintf(stderr, "Error : ReadVolumeFile() : unknown file 
format %s\n", fileName.c_str());
+               exit(1);
+       }
+
+//     float min, max;
+//     data.GetMinMax(&min, &max);
+//     printf("Volume  %s MIN-MAX : %f %f\n", fileName.c_str(), min, max);
+}

Added: trunk/Model/Readers/VolumeReader.h
==============================================================================
--- (empty file)
+++ trunk/Model/Readers/VolumeReader.h  Mon Aug 22 17:00:45 2005
@@ -0,0 +1,22 @@
+
+#ifndef Manta_Model_VolumeReader_h
+#define Manta_Model_VolumeReader_h
+
+#include <iostream>
+#include <Model/Groups/GriddedGroup.h> // Array3
+
+namespace Manta
+{
+       using namespace std;
+
+       enum DataFormats { CHAR, UNSIGNED_CHAR, SHORT, UNSIGNED_SHORT, INT, 
UNSIGNED_INT, LONG, UNSIGNED_LONG, FLOAT, DOUBLE, DATAFORMATSNB };
+       typedef enum DataFormats DataFormat;
+
+       extern bool             ReadRawData (ifstream & inputStream ,       
Array3<float> & data, DataFormat format, bool bigEndian);
+       extern bool             WriteRawData(ofstream & outputStream, const 
Array3<float> & data, DataFormat format, bool bigEndian);
+       extern void             ReadNRRDFile    (const std::string & 
fileName,       Array3<float> & data);
+       extern void             WriteNRRDFile   (const std::string & 
fileName, const Array3<float> & data, DataFormat format = FLOAT, bool 
bigEndian = false);
+       extern void             ReadHDRFile             (const std::string & 
fileName,       Array3<float> & data);
+       extern void             ReadVolumeFile  (const std::string & 
fileName,       Array3<float> & data);
+}
+#endif




  • [MANTA] r487 - trunk/Model/Readers, vpegorar, 08/22/2005

Archive powered by MHonArc 2.6.16.

Top of page