From: kent w. <nkw...@gm...> - 2009-04-16 20:59:09
|
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 byte-order 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 double-precision values, column-major, little-endian, + // so you need to swap if the system is big-endian + break; + case 10: + // Regardless of endian-ness, 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 same-endian + // 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 byte-swapped + // we hope that it means the file needs byte-swapping, 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 }; |
From: Miguel A. Figueroa-V. <mi...@ie...> - 2009-04-16 22:02:43
|
On Thu, Apr 16, 2009 at 4:58 PM, kent williams wrote: > 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 > byte-order 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? I think the list is a good start, but it would help a lot if you could submit a bug report with the patch attached at: https://apps.sourceforge.net/trac/vxl/newticket --Miguel |
From: kent w. <nkw...@gm...> - 2009-04-17 15:22:55
|
Done -- https://apps.sourceforge.net/trac/vxl/ticket/25 The patch is relative to whatever version of VXL is currently included in ITK, but I doubt the files in question have changed since then. In order to test 'different-endian' file reads, a different-endian test file would have to be created in test_matlab.cxx. I can take a crack at that as well... On Thu, Apr 16, 2009 at 5:02 PM, Miguel A. Figueroa-Villanueva <mi...@ie...> wrote: > On Thu, Apr 16, 2009 at 4:58 PM, kent williams wrote: >> 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 >> byte-order 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? > > I think the list is a good start, but it would help a lot if you could > submit a bug report with the patch attached at: > > https://apps.sourceforge.net/trac/vxl/newticket > > --Miguel > |
From: Peter V. <pet...@ya...> - 2009-04-21 15:01:47
|
The patch has been applied. -- Peter. __________________________________________________________ Låna pengar utan säkerhet. Jämför vilkor online hos Kelkoo. http://www.kelkoo.se/c-100390123-lan-utan-sakerhet.html?partnerId=96915014 |