7ba7fed
From 166aca9f4c33bc5642047ceafd5c6bae0d888187 Mon Sep 17 00:00:00 2001
7ba7fed
From: "Robert D. Vincent" <robert.d.vincent@mcgill.ca>
7ba7fed
Date: Wed, 7 Oct 2015 22:06:38 +0000
7ba7fed
Subject: [PATCH] Fix endian issues with label data.
7ba7fed
7ba7fed
---
7ba7fed
 libsrc2/m2util.c | 83 ++++++++++++++++++++++++++++++++++++++++++++------------
7ba7fed
 libsrc2/volume.c |  4 +--
7ba7fed
 2 files changed, 66 insertions(+), 21 deletions(-)
7ba7fed
7ba7fed
diff --git a/libsrc2/m2util.c b/libsrc2/m2util.c
7ba7fed
index a9367dc..5711208 100644
7ba7fed
--- a/libsrc2/m2util.c
7ba7fed
+++ b/libsrc2/m2util.c
7ba7fed
@@ -1343,33 +1343,80 @@ void miinit ( void )
7ba7fed
                 mi2_dbl_to_int ),"H5Tregister")
7ba7fed
 }
7ba7fed
 
7ba7fed
-/** HDF5 type conversion function for converting an arbitrary integer type to
7ba7fed
-* an arbitrary enumerated type.  The beauty part of this is that it is
7ba7fed
-* not necessary to actually perform any real conversion!
7ba7fed
-*/
7ba7fed
-static herr_t mi2_null_conv ( hid_t src_id,
7ba7fed
-                              hid_t dst_id,
7ba7fed
-                              H5T_cdata_t *cdata,
7ba7fed
-                              size_t nelements,
7ba7fed
-                              size_t buf_stride,
7ba7fed
-                              size_t bkg_stride,
7ba7fed
-                              void *buf_ptr,
7ba7fed
-                              void *bkg_ptr,
7ba7fed
-                              hid_t dset_xfer_plist )
7ba7fed
+/** HDF5 type conversion function for converting among integer types.
7ba7fed
+ * This handles byte-swapping for enumerated types where needed.
7ba7fed
+ */
7ba7fed
+static herr_t mi2_int_to_int ( hid_t src_id,
7ba7fed
+			       hid_t dst_id,
7ba7fed
+			       H5T_cdata_t *cdata,
7ba7fed
+			       size_t nelements,
7ba7fed
+			       size_t buf_stride,
7ba7fed
+			       size_t bkg_stride,
7ba7fed
+			       void *buf_ptr,
7ba7fed
+			       void *bkg_ptr,
7ba7fed
+			       hid_t dset_xfer_plist )
7ba7fed
 {
7ba7fed
+  unsigned char *dst_ptr;
7ba7fed
+  size_t dst_cnt;
7ba7fed
+  size_t dst_sz;
7ba7fed
+
7ba7fed
   switch ( cdata->command ) {
7ba7fed
   case H5T_CONV_INIT:
7ba7fed
     break;
7ba7fed
   case H5T_CONV_CONV:
7ba7fed
+    dst_ptr = ( unsigned char * ) buf_ptr;
7ba7fed
+    dst_sz = H5Tget_size( dst_id );
7ba7fed
+
7ba7fed
+    if (dst_sz != H5Tget_size( src_id )) {
7ba7fed
+      return -1;		/* Can't change size for now. */
7ba7fed
+    }
7ba7fed
+    if ( H5Tget_order ( dst_id ) == H5Tget_order ( src_id ) ) {
7ba7fed
+      return 0;			/* Nothing to do. */
7ba7fed
+    }
7ba7fed
+
7ba7fed
+    /* The logic of HDF5 seems to be that if a stride is specified,
7ba7fed
+    * both the source and destination pointers should advance by that
7ba7fed
+    * amount.  This seems wrong to me, but I've examined the HDF5 sources
7ba7fed
+    * and that's what their own type converters do.
7ba7fed
+    */
7ba7fed
+    if ( buf_stride == 0 ) {
7ba7fed
+      dst_cnt = dst_sz;
7ba7fed
+    } else {
7ba7fed
+      dst_cnt = buf_stride;
7ba7fed
+    }
7ba7fed
+
7ba7fed
+    switch ( dst_sz ) {
7ba7fed
+    case 8:
7ba7fed
+      while ( nelements-- > 0 ) {
7ba7fed
+	miswap8 ( dst_ptr );
7ba7fed
+	dst_ptr += dst_cnt;
7ba7fed
+      }
7ba7fed
+      break;
7ba7fed
+    case 4:
7ba7fed
+      while ( nelements-- > 0 ) {
7ba7fed
+	miswap4 ( dst_ptr );
7ba7fed
+	dst_ptr += dst_cnt;
7ba7fed
+      }
7ba7fed
+      break;
7ba7fed
+    case 2:
7ba7fed
+      while ( nelements-- > 0 ) {
7ba7fed
+	miswap2 ( dst_ptr );
7ba7fed
+	dst_ptr += dst_cnt;
7ba7fed
+      }
7ba7fed
+      break;
7ba7fed
+    case 1:
7ba7fed
+      break;
7ba7fed
+    default:
7ba7fed
+      return (-1);
7ba7fed
+    }
7ba7fed
     break;
7ba7fed
+
7ba7fed
   case H5T_CONV_FREE:
7ba7fed
     break;
7ba7fed
 
7ba7fed
   default:
7ba7fed
-    /* Unknown command */
7ba7fed
-    return ( -1 );
7ba7fed
+    return (-1);                /* Unknown command. */
7ba7fed
   }
7ba7fed
-
7ba7fed
   return ( 0 );
7ba7fed
 }
7ba7fed
 
7ba7fed
@@ -1380,9 +1427,9 @@ in order to facilitate conversions from the integer to the enumerated type.
7ba7fed
 void miinit_enum ( hid_t type_id )
7ba7fed
 {
7ba7fed
   H5Tregister ( H5T_PERS_SOFT, "i2e", H5T_NATIVE_INT, type_id,
7ba7fed
-                mi2_null_conv );
7ba7fed
+                mi2_int_to_int );
7ba7fed
   H5Tregister ( H5T_PERS_SOFT, "e2i", type_id, H5T_NATIVE_INT,
7ba7fed
-                mi2_null_conv );
7ba7fed
+                mi2_int_to_int );
7ba7fed
   H5Tregister ( H5T_PERS_SOFT, "d2e", H5T_NATIVE_DOUBLE, type_id,
7ba7fed
                 mi2_dbl_to_int );
7ba7fed
   H5Tregister ( H5T_PERS_SOFT, "e2d", type_id, H5T_NATIVE_DOUBLE,
7ba7fed
diff --git a/libsrc2/volume.c b/libsrc2/volume.c
7ba7fed
index b951d14..be8b7d1 100644
7ba7fed
--- a/libsrc2/volume.c
7ba7fed
+++ b/libsrc2/volume.c
7ba7fed
@@ -1449,11 +1449,9 @@ int miopen_volume(const char *filename, int mode, mihandle_t *volume)
7ba7fed
     break;
7ba7fed
 
7ba7fed
   case H5T_ENUM:
7ba7fed
-    handle->mtype_id = H5Tcopy(handle->ftype_id);
7ba7fed
+    handle->mtype_id = H5Tget_native_type(handle->ftype_id, H5T_DIR_ASCEND);
7ba7fed
     miinit_enum(handle->ftype_id);
7ba7fed
     miinit_enum(handle->mtype_id);
7ba7fed
-    /* Set native order ---> is not allowed after order is set */
7ba7fed
-    //H5Tset_order(handle->mtype_id, H5Tget_order(H5T_NATIVE_INT));
7ba7fed
     break;
7ba7fed
 
7ba7fed
   default:
7ba7fed
-- 
7ba7fed
2.6.3
7ba7fed