From fa94c4b242e0b3dfe5d0a533a90ced8d183f66bd Mon Sep 17 00:00:00 2001
From: Mark Jenkinson <mark@fmrib.ox.ac.uk>
Date: Thu, 8 Sep 2005 18:37:42 +0000
Subject: [PATCH] Changed write_binary_matrix to avoid long ints (which have
 different sizes on different platforms!) and to do byte swapping

---
 miscmaths.cc | 125 +++++++++++++++++++++++++++++++++++++++++++++------
 miscmaths.h  |  10 ++++-
 2 files changed, 121 insertions(+), 14 deletions(-)

diff --git a/miscmaths.cc b/miscmaths.cc
index 1b1b639..8270050 100644
--- a/miscmaths.cc
+++ b/miscmaths.cc
@@ -204,29 +204,37 @@ namespace MISCMATHS {
 
   ReturnMatrix read_binary_matrix(ifstream& fs)
   {
-    long int testval;
+    bool swapbytes = false;
+    unsigned int testval;
     // test for byte swapping
     fs.read((char*)&testval,sizeof(testval));
     if (testval!=BINFLAG) {
-      cerr << "Different endian format - byte swapping not currently implemented" << endl;
-      Matrix mres;
-      mres.Release();
-      return mres;
+      swapbytes = true;
+      Swap_Nbytes(1,sizeof(testval),&testval);
+      if (testval!=BINFLAG) { 
+	cerr << "Unrecognised binary matrix file format" << endl;
+	Matrix mres;
+	mres.Release();
+	return mres;
+      }
     }
 
     // read matrix dimensions (num rows x num cols)
-    long int ival,nx,ny;
+    unsigned int ival,nx,ny;
     fs.read((char*)&ival,sizeof(ival));
+    if (swapbytes) Swap_Nbytes(1,sizeof(ival),&ival);
     nx = ival;
     fs.read((char*)&ival,sizeof(ival));
+    if (swapbytes) Swap_Nbytes(1,sizeof(ival),&ival);
     ny = ival;
 
     // set up and read matrix (rows fast, cols slow)
-    Real val;
+    double val;
     Matrix mres(nx,ny);
-    for (int y=1; y<=ny; y++) {
-      for (int x=1; x<=nx; x++) {
+    for (unsigned int y=1; y<=ny; y++) {
+      for (unsigned int x=1; x<=nx; x++) {
 	fs.read((char*)&val,sizeof(val));
+	if (swapbytes) Swap_Nbytes(1,sizeof(val),&val);
 	mres(x,y)=val;
       }
     }
@@ -326,7 +334,7 @@ namespace MISCMATHS {
 
   int write_binary_matrix(const Matrix& mat, ofstream& fs)
   {
-    long int ival, nx, ny;
+    unsigned int ival, nx, ny;
 
     ival = BINFLAG;
     fs.write((char*)&ival,sizeof(ival));
@@ -338,9 +346,9 @@ namespace MISCMATHS {
     nx = mat.Nrows();
     ny = mat.Ncols();
 
-    Real val;
-    for (int y=1; y<=ny; y++) {
-      for (int x=1; x<=nx; x++) {
+    double val;
+    for (unsigned int y=1; y<=ny; y++) {
+      for (unsigned int x=1; x<=nx; x++) {
 	val = mat(x,y);
 	fs.write((char*)&val,sizeof(val));
       }
@@ -1977,3 +1985,94 @@ vector<float> ColumnVector2vector(const ColumnVector& col)
 
 
 }
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////
+
+
+typedef struct { unsigned char a,b ; } twobytes ;
+
+void Swap_2bytes( int n , void *ar )    /* 2 bytes at a time */
+{
+   register int ii ;
+   register twobytes *tb = (twobytes *)ar ;
+   register unsigned char tt ;
+
+   for( ii=0 ; ii < n ; ii++ ){
+     tt = tb[ii].a ; tb[ii].a = tb[ii].b ; tb[ii].b = tt ;
+   }
+   return ;
+}
+
+/*---------------------------------------------------------------------------*/
+
+typedef struct { unsigned char a,b,c,d ; } fourbytes ;
+
+void Swap_4bytes( int n , void *ar )    /* 4 bytes at a time */
+{
+   register int ii ;
+   register fourbytes *tb = (fourbytes *)ar ;
+   register unsigned char tt ;
+
+   for( ii=0 ; ii < n ; ii++ ){
+     tt = tb[ii].a ; tb[ii].a = tb[ii].d ; tb[ii].d = tt ;
+     tt = tb[ii].b ; tb[ii].b = tb[ii].c ; tb[ii].c = tt ;
+   }
+   return ;
+}
+
+/*---------------------------------------------------------------------------*/
+
+typedef struct { unsigned char a,b,c,d , D,C,B,A ; } eightbytes ;
+
+void Swap_8bytes( int n , void *ar )    /* 8 bytes at a time */
+{
+   register int ii ;
+   register eightbytes *tb = (eightbytes *)ar ;
+   register unsigned char tt ;
+
+   for( ii=0 ; ii < n ; ii++ ){
+     tt = tb[ii].a ; tb[ii].a = tb[ii].A ; tb[ii].A = tt ;
+     tt = tb[ii].b ; tb[ii].b = tb[ii].B ; tb[ii].B = tt ;
+     tt = tb[ii].c ; tb[ii].c = tb[ii].C ; tb[ii].C = tt ;
+     tt = tb[ii].d ; tb[ii].d = tb[ii].D ; tb[ii].D = tt ;
+   }
+   return ;
+}
+
+/*---------------------------------------------------------------------------*/
+
+typedef struct { unsigned char a,b,c,d,e,f,g,h ,
+                               H,G,F,E,D,C,B,A  ; } sixteenbytes ;
+
+void Swap_16bytes( int n , void *ar )    /* 16 bytes at a time */
+{
+   register int ii ;
+   register sixteenbytes *tb = (sixteenbytes *)ar ;
+   register unsigned char tt ;
+
+   for( ii=0 ; ii < n ; ii++ ){
+     tt = tb[ii].a ; tb[ii].a = tb[ii].A ; tb[ii].A = tt ;
+     tt = tb[ii].b ; tb[ii].b = tb[ii].B ; tb[ii].B = tt ;
+     tt = tb[ii].c ; tb[ii].c = tb[ii].C ; tb[ii].C = tt ;
+     tt = tb[ii].d ; tb[ii].d = tb[ii].D ; tb[ii].D = tt ;
+
+     tt = tb[ii].e ; tb[ii].e = tb[ii].E ; tb[ii].E = tt ;
+     tt = tb[ii].f ; tb[ii].f = tb[ii].F ; tb[ii].F = tt ;
+     tt = tb[ii].g ; tb[ii].g = tb[ii].G ; tb[ii].G = tt ;
+     tt = tb[ii].h ; tb[ii].h = tb[ii].H ; tb[ii].H = tt ;
+   }
+   return ;
+}
+
+/*---------------------------------------------------------------------------*/
+
+void Swap_Nbytes( int n , int siz , void *ar )  /* subsuming case */
+{
+   switch( siz ){
+     case 2:  Swap_2bytes ( n , ar ) ; break ;
+     case 4:  Swap_4bytes ( n , ar ) ; break ;
+     case 8:  Swap_8bytes ( n , ar ) ; break ;
+     case 16: Swap_16bytes( n , ar ) ; break ;
+   }
+   return ;
+}
diff --git a/miscmaths.h b/miscmaths.h
index 0da285d..8ad0458 100644
--- a/miscmaths.h
+++ b/miscmaths.h
@@ -228,8 +228,16 @@ namespace MISCMATHS {
   vector<float> ColumnVector2vector(const ColumnVector& col);
   
   ///////////////////////////////////////////////////////////////////////////
+  // Uninteresting byte swapping functions
+  void Swap_2bytes ( int n , void *ar ) ;
+  void Swap_4bytes ( int n , void *ar ) ;
+  void Swap_8bytes ( int n , void *ar ) ;
+  void Swap_16bytes( int n , void *ar ) ;
+  void Swap_Nbytes ( int n , int siz , void *ar ) ;
+
   ///////////////////////////////////////////////////////////////////////////
- 
+  ///////////////////////////////////////////////////////////////////////////
+
   // TEMPLATE DEFINITIONS //
 
   template<class t> ReturnMatrix vector2ColumnVector(const vector<t>& vec)
-- 
GitLab