Text archives Help
- 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.