I am an ITK developer, and was asked by my boss here at U of Iowa to
fix the vnl matlab reader such that it properly swapped bytes when
reading a binary matlab matrix file on a machine with a different
byteorder convention. So I have a patch (enclosed below), that
works in the case where we actually use it.
Who should I talk to about getting this propogated back into VXL?
Index: core/vnl/vnl_matlab_read.cxx
===================================================================
RCS file: /cvsroot/Insight/Insight/Utilities/vxl/core/vnl/vnl_matlab_read.cxx,v
retrieving revision 1.3
diff c r1.3 vnl_matlab_read.cxx
*** core/vnl/vnl_matlab_read.cxx 13 Nov 2007 14:56:52 0000 1.3
 core/vnl/vnl_matlab_read.cxx 16 Apr 2009 20:54:19 0000
***************
*** 15,20 ****
 15,62 
// FIXME: Currently ignores the byte ordering of the MAT file
header, effectively
// assuming the MAT file was written with the native byte ordering.
+ namespace
+ {
+ //
+ // byteswap routines, stolen from
+ // ITK
+ inline void
+ swap32(void *ptr)
+ {
+ char one_byte;
+ char *p = reinterpret_cast<char *>(ptr);
+
+ one_byte = p[0];
+ p[0] = p[3];
+ p[3] = one_byte;
+
+ one_byte = p[1];
+ p[1] = p[2];
+ p[2] = one_byte;
+ }
+ inline void
+ swap64(void *ptr)
+ {
+ char one_byte;
+ char *p = reinterpret_cast<char *>(ptr);
+
+ one_byte = p[0];
+ p[0] = p[7];
+ p[7] = one_byte;
+
+ one_byte = p[1];
+ p[1] = p[6];
+ p[6] = one_byte;
+
+ one_byte = p[2];
+ p[2] = p[5];
+ p[5] = one_byte;
+
+ one_byte = p[3];
+ p[3] = p[4];
+ p[4] = one_byte;
+ }
+ }
//
***************
*** 52,58 ****
//
! vnl_matlab_readhdr::vnl_matlab_readhdr(vcl_istream &s_) : s(s_),
varname(0), data_read(false)
{
read_hdr();
}
 94,100 
//
! vnl_matlab_readhdr::vnl_matlab_readhdr(vcl_istream &s_) : s(s_),
varname(0), data_read(false), need_swap(false)
{
read_hdr();
}
***************
*** 95,100 ****
 137,178 
{
vcl_memset(&hdr, 0, sizeof hdr);
::vnl_read_bytes(s, &hdr, sizeof(hdr));
+ //
+ // determine if data needs swapping when read
+ // Everything else depends on this; if the header needs swapping
+ // and is not, nothing good will happen.
+ switch(hdr.type)
+ {
+ case 0:
+ // 0 means doubleprecision values, columnmajor, littleendian,
+ // so you need to swap if the system is bigendian
+ break;
+ case 10:
+ // Regardless of endianness, these flag values are
+ // what the writer puts in the header in the native format,
+ // therefore if you see any of them, the file is the sameendian
+ // as the system you're reading on.
+ case 100:
+ case 110:
+ case 1000:
+ case 1100:
+ case 1110:
+ need_swap = false;
+ break;
+ default:
+ // any other values are either gibberish, or need to be byteswapped
+ // we hope that it means the file needs byteswapping, and not that
+ // the file is corrupt.
+ need_swap = true;
+ }
+ if(need_swap)
+ {
+ swap32(&hdr.type);
+ swap32(&hdr.rows);
+ swap32(&hdr.cols);
+ swap32(&hdr.imag);
+ swap32(&hdr.namlen);
+ }
if (varname)
delete [] varname;
varname = new char[hdr.namlen+1];
***************
*** 107,113 ****
#endif
::vnl_read_bytes(s, varname, hdr.namlen);
varname[hdr.namlen] = '\0';

data_read = false;
}
 185,190 
***************
*** 140,151 ****
 217,239 
if (!type_chck(v)) { vcl_cerr << "type_check\n"; return false; }\
if (rows()!=1  cols()!=1) { vcl_cerr << "size0\n"; return false; } \
vnl_matlab_read_data(s, &v, 1); \
+ if(need_swap) \
+ { \
+ if(sizeof(v) == 4) swap32(&v); else swap64(&v); \
+ } \
data_read = true; return *this; \
} \
bool vnl_matlab_readhdr::read_data(T *p) { \
if (!type_chck(p[0])) { vcl_cerr << "type_check\n"; return false; } \
if (rows()!=1 && cols()!=1) { vcl_cerr << "size1\n"; return false; } \
vnl_matlab_read_data(s, p, rows()*cols()); \
+ if(need_swap) \
+ { \
+ for(unsigned i = 0; i < rows()*cols(); i++) \
+ { \
+ if(sizeof(*p) == 4) swap32(&(p[i])); else swap64(&(p[i])); \
+ } \
+ } \
data_read = true; return *this; \
} \
bool vnl_matlab_readhdr::read_data(T * const *m) { \
***************
*** 153,158 ****
 241,253 
T *tmp = vnl_c_vector<T >::allocate_T(rows()*cols()); \
/*vnl_c_vector<T >::fill(tmp, rows()*cols(), 3.14159);*/ \
vnl_matlab_read_data(s, tmp, rows()*cols()); \
+ if(need_swap) \
+ { \
+ for(unsigned i = 0; i < rows()*cols(); i++) \
+ { \
+ if(sizeof(T) == 4) swap32(&(tmp[i])); else swap64(&(tmp[i])); \
+ } \
+ } \
int a, b; \
if (is_rowwise()) { \
a = cols(); \
Index: core/vnl/vnl_matlab_read.h
===================================================================
RCS file: /cvsroot/Insight/Insight/Utilities/vxl/core/vnl/vnl_matlab_read.h,v
retrieving revision 1.2
diff c r1.2 vnl_matlab_read.h
*** core/vnl/vnl_matlab_read.h 1 Aug 2005 20:53:39 0000 1.2
 core/vnl/vnl_matlab_read.h 16 Apr 2009 20:54:19 0000
***************
*** 81,87 ****
vnl_matlab_header hdr;
char *varname;
bool data_read;
!
void read_hdr(); // internal work routine
};
 81,87 
vnl_matlab_header hdr;
char *varname;
bool data_read;
! bool need_swap;
void read_hdr(); // internal work routine
};
