/////////////////////////////////////////////////////////////////////////////// // Name: TrackIO.h // Purpose: I/O interface for track file (.trk) // Author: Ruopeng Wang // Modified by: // Last modified: 2005.03.15 // Copyright: (c) 2004-2005 Ruopeng Wang // Licence: // // Usage: // Sample lines to read track file - // // include "TrackIO.h" // // ... // // CTrackReader reader; // TRACK_HEADER header; // if (!reader.Open("foo.trk", &header)) // { // printf(reader.GetLastErrorMessage()); // return; // } // ... // // int cnt; // if (ignore_scalars) // { // while (reader.GetNextPointCount(&cnt)) // { // float* pts = new float[cnt*3]; // reader.GetNextTrackData(cnt, pts); // ... // process_point_data(...); // ... // delete[] pts; // } // } // else // { // while (reader.GetNextPointCount(&cnt)) // { // float* pts = new float[cnt*3]; // float* scalars = new float[cnt*header.n_scalars]; // reader.GetNextTrackData(cnt, pts, scalars); // ... // process_point_and_scalar_data(...); // ... // delete[] pts; // delete[] scalars; // } // } // // reader.Close(); // /////////////////////////////////////////////////////////////////////////////// #ifndef _TrackIO_H_ #define _TrackIO_H_ #include #include "ByteSwap.h" struct TRACK_HEADER { char id_string[6]; // first 5 chars must be "TRACK" short int dim[3]; // dimensions float voxel_size[3]; // voxel size float origin[3]; // origin. default is 0,0,0. short int n_scalars; // number of scalars saved per point besides xyz coordinates. char pad1; unsigned char has_max_min; // indicate there are max and min values of the scalars stored // in the header float max[10]; // max and min values of all the scalars. can store up to 10 pairs float min[10]; char reserved[868]; int n_count; // total number of tracks. if 0, number of tracks was not recorded. // call GetNumberOfTracks() to get it. int version; // version number int hdr_size; // size of the header. used to determine byte swap TRACK_HEADER() { Initialize(); } TRACK_HEADER(int* d, float* vs, float* o, int n) { Initialize(); for (int i = 0; i < 3; i++) { dim[i] = d[i]; voxel_size[i] = vs[i]; origin[i] = o[i]; } n_scalars = n; } TRACK_HEADER(short int* d, float* vs, float* o, int n) { Initialize(); for (int i = 0; i < 3; i++) { dim[i] = d[i]; voxel_size[i] = vs[i]; origin[i] = o[i]; } n_scalars = n; } inline void ByteSwap() { SWAP_SHORT(dim, 3); SWAP_FLOAT(voxel_size, 3); SWAP_FLOAT(origin, 3); SWAP_SHORT(n_scalars); SWAP_FLOAT(max, 10); SWAP_FLOAT(min, 10); SWAP_INT(version); SWAP_INT(n_count); SWAP_INT(hdr_size); } inline void Initialize() { memset(this, 0, sizeof(struct TRACK_HEADER)); strcpy(id_string, "TRACK"); hdr_size = sizeof(struct TRACK_HEADER); } }; enum TRACKIO_ERROR { TE_NO_ERROR = 0, TE_CAN_NOT_OPEN, TE_CAN_NOT_CLOSE, TE_CAN_NOT_READ, TE_CAN_NOT_WRITE, TE_NOT_TRACK_FILE, TE_NOT_INITIALIZED }; class CTrackIO { public: CTrackIO() { m_nErrorCode = 0; m_pFile = 0; } virtual ~CTrackIO() { Close(); } BOOL GetHeader(TRACK_HEADER* header); virtual BOOL Close(); const char* GetLastErrorMessage(); int GetLastErrorCode() { return m_nErrorCode; } protected: TRACK_HEADER m_header; FILE* m_pFile; int m_nErrorCode; }; class CTrackReader : public CTrackIO { public: CTrackReader(); BOOL Open(const char* filename, TRACK_HEADER* header = NULL); BOOL GetNextPointCount(int* ncount); BOOL GetNextRawData(int ncount, float* data); BOOL GetNextTrackData(int nCount, float* pt_data, float* scalars = NULL); int GetProgress(); int GetNumberOfTracks(); BOOL GetNumberOfTracks(int* cnt); static BOOL GetHeaderOnly(const char* filename, TRACK_HEADER* header); protected: BOOL m_bByteSwap; long m_nSize; }; class CTrackWriter : public CTrackIO { public: BOOL Initialize(const char* filename, short int* dim, float* voxel_size, float* origin, short int n_scalars); BOOL Initialize(const char* filename, int* dim, float* voxel_size, float* origin, short int n_scalars); BOOL Initialize(const char* filename, TRACK_HEADER header); BOOL WriteNextTrack(int ncount, float* data); BOOL UpdateHeader(TRACK_HEADER header); virtual BOOL Close(); static BOOL UpdateHeader(const char* filename, TRACK_HEADER header); }; // find mininum value from an array template inline T fmin(const T* a, int n) { T tmin = a[0]; for (int i = 1; i < n; i++) { if (tmin > a[i]) tmin = a[i]; } return tmin; } // find maximum value from an array template inline T fmax(const T* a, int n) { T tmax = a[0]; for (int i = 1; i < n; i++) { if (tmax < a[i]) tmax = a[i]; } return tmax; } #endif