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