| Attached Files |   vnl_matlab_read.patch [^] (6,367 bytes) 2009-04-16 17:16 [Show Content] [Hide Content]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 21:11:52 -0000
***************
*** 5,11 ****
  //:
  // \file
  // \author fsm
! 
  #include "vnl_matlab_read.h"
  #include <vcl_ios.h> // for vcl_ios_cur
  #include <vcl_iostream.h>
--- 5,11 ----
  //:
  // \file
  // \author fsm
! #include <vxl_config.h>
  #include "vnl_matlab_read.h"
  #include <vcl_ios.h> // for vcl_ios_cur
  #include <vcl_iostream.h>
***************
*** 13,20 ****
--- 13,63 ----
  #include <vcl_complex.h>
  #include <vnl/vnl_c_vector.h>
  
+ 
  // 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();
  }
--- 95,101 ----
  
  //--------------------------------------------------------------------------------
  
! vnl_matlab_readhdr::vnl_matlab_readhdr(vcl_istream &s_) : s(s_), varname(0), data_read(false), need_swap(false)
  {
    read_hdr();
  }
***************
*** 95,100 ****
--- 138,182 ----
  {
    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
+ #if VXL_BIG_ENDIAN
+       need_swap = true;
+ #endif      
+       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;
  }
  
--- 189,194 ----
***************
*** 140,151 ****
--- 221,243 ----
    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 ****
--- 245,257 ----
    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 21:11:52 -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
  };
  
 |