From 78cfc78d18da1f9e79dac39605aa9add9747fe14 Mon Sep 17 00:00:00 2001 From: Xiaowen Wu Date: Fri, 21 Jan 2005 13:13:49 -0500 Subject: [svn-r9854] Purpose: For N-bit filter, Adding parameter mappings from HDF5 compound datatype, array datatype and atomic datatype to cd_values inside HDF5 library. N-bit filter should work with these datatypes(string and variable length datatype haven't been considered) in the near future. Description: This is for debugging purpose, N-bit filter won't be tested in the daily test. Solution: Platforms tested: AIX 5.1 and Linux 2.4. Arabica is too slow. Hopefully shanti can be used soon. Misc. update: --- src/H5Znbit.c | 1109 ++++++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 866 insertions(+), 243 deletions(-) diff --git a/src/H5Znbit.c b/src/H5Znbit.c index 9bc2d0e..12a5c4d 100644 --- a/src/H5Znbit.c +++ b/src/H5Znbit.c @@ -29,27 +29,64 @@ #ifdef H5_HAVE_FILTER_NBIT +/* parameters needed for compressing one atomic datatype */ +typedef struct { + int sizeof_datatype; + int order; + int precision; + int offset; +} parms_atomic; + /* Local function prototypes */ static herr_t H5Z_can_apply_nbit(hid_t dcpl_id, hid_t type_id, hid_t space_id); static herr_t H5Z_set_local_nbit(hid_t dcpl_id, hid_t type_id, hid_t space_id); static size_t H5Z_filter_nbit(unsigned flags, size_t cd_nelmts, const unsigned cd_values[], size_t nbytes, size_t *buf_size, void **buf); -typedef struct { - int precision; - int offset; - int sizeof_datatype; - int order; -} para; - -void H5Z_nbit_next_char(int *j, int *buf_len); -void H5Z_nbit_byte_order(int *big_endian, int *little_endian); -void H5Z_nbit_decompress_one_byte(void *data, int i, int k, int begin_i, int end_i, char *buffer, - int *j, int *buf_len, para p); -void H5Z_nbit_compress_one_byte(void *data, int i, int k, int begin_i, int end_i, char *buffer, - int *j, int *buf_len, para p); -void H5Z_nbit_decompress(void *data, int data_size, char *buffer, int buffer_size, para p); -void H5Z_nbit_compress(void *data, int data_size, char *buffer, int buffer_size, para p); +static herr_t H5Z_calc_parms_Tatomic(hid_t type_id); +static herr_t H5Z_calc_parms_Tarray(hid_t type_id); +static herr_t H5Z_calc_parms_Tcompound(hid_t type_id); + +static herr_t H5Z_set_parms_Tatomic(hid_t type_id, unsigned cd_values[]); +static herr_t H5Z_set_parms_Tarray(hid_t type_id, unsigned cd_values[]); +static herr_t H5Z_set_parms_Tcompound(hid_t type_id, unsigned cd_values[]); + +void H5Z_nbit_next_byte(int *j, int *buf_len); +void H5Z_nbit_decompress_one_byte(void *data, int data_offset, int k, int begin_i, int end_i, + unsigned char *buffer, int *j, int *buf_len, parms_atomic p); +void H5Z_nbit_compress_one_byte(void *data, int data_offset, int k, int begin_i, int end_i, + unsigned char *buffer, int *j, int *buf_len, parms_atomic p); + +void H5Z_nbit_decompress_one_atomic(void *data, int data_offset, unsigned char *buffer, int *j, + int *buf_len, parms_atomic p); +void H5Z_nbit_decompress_one_array(void *data, int data_offset, unsigned char *buffer, int *j, + int *buf_len, const unsigned parms[]); +void H5Z_nbit_decompress_one_compound(void *data, int data_offset, unsigned char *buffer, int *j, + int *buf_len, const unsigned parms[]); + +void H5Z_nbit_decompress(void *data, int d_nelmts, unsigned char *buffer, const unsigned parms[]); + +void H5Z_nbit_compress_one_atomic(void *data, int data_offset, unsigned char *buffer, int *j, + int *buf_len, parms_atomic p); +void H5Z_nbit_compress_one_array(void *data, int data_offset, unsigned char *buffer, int *j, + int *buf_len, const unsigned parms[]); +void H5Z_nbit_compress_one_compound(void *data, int data_offset, unsigned char *buffer, int *j, + int *buf_len, const unsigned parms[]); + +void H5Z_nbit_compress(void *data, int d_nelmts, unsigned char *buffer, int *buffer_size, + const unsigned parms[]); + +/* + * Global variables + * cd_values_index: index of array cd_values + * cd_values_actual_nparms: number of valid entries in array cd_values + * parms_index: index of array parms + * compress_ratio_is_zero: flag indicating no need to do nbit filter + */ +unsigned cd_values_index = 0; +unsigned cd_values_actual_nparms = 0; +unsigned parms_index = 0; +unsigned char compress_ratio_is_zero; /* This message derives from H5Z */ H5Z_class_t H5Z_NBIT[1] = {{ @@ -64,13 +101,19 @@ H5Z_class_t H5Z_NBIT[1] = {{ }}; /* Local macros */ -#define H5Z_NBIT_USER_NPARMS 0 /* Number of parameters that users can set */ -#define H5Z_NBIT_TOTAL_NPARMS 5 /* Total number of parameters for filter */ -#define H5Z_NBIT_PARM_PRECIS 0 /* "Local" parameter for datatype precision */ -#define H5Z_NBIT_PARM_OFFSET 1 /* "Local" parameter for datatype offset */ -#define H5Z_NBIT_PARM_TSIZE 2 /* "Local" parameter for datatype size */ -#define H5Z_NBIT_PARM_NELMTS 3 /* "Local" parameter for number of elements in the chunk */ -#define H5Z_NBIT_PARM_ORDER 4 /* "Local" parameter for datatype byte order */ +#define FALSE 0 +#define TRUE 1 + +#define H5Z_NBIT_ATOMIC 1 /* Atomic datatype class for nbit */ +#define H5Z_NBIT_ARRAY 2 /* Array datatype class for nbit */ +#define H5Z_NBIT_COMPOUND 3 /* Compound datatype class for nbit */ + +#define H5Z_NBIT_USER_NPARMS 0 /* Number of parameters that users can set */ +#define H5Z_NBIT_MAX_NPARMS 4096 /* Max number of parameters for filter */ + +#define H5Z_NBIT_ORDER_BE 20 /* "Local" parameter for datatype byte order */ +#define H5Z_NBIT_ORDER_LE 10 /* "Local" parameter for datatype byte order */ + /*------------------------------------------------------------------------- * Function: H5Z_can_apply_nbit @@ -83,40 +126,429 @@ H5Z_class_t H5Z_NBIT[1] = {{ * Return: Success: Non-negative * Failure: Negative * - * Programmer: Quincey Koziol - * Monday, April 7, 2003 + * Programmer: Xiaowen Wu + * Tuesday, December 21, 2004 * * Modifications: - * Xiaowen Wu - * Tuesday, December 21, 2004 * *------------------------------------------------------------------------- */ static herr_t H5Z_can_apply_nbit(hid_t UNUSED dcpl_id, hid_t type_id, hid_t UNUSED space_id) { + H5T_class_t dtype_class; /* Datatype's class */ unsigned dtype_size; /* Datatype's size (in bytes) */ H5T_order_t dtype_order; /* Datatype's endianness order */ herr_t ret_value=TRUE; /* Return value */ FUNC_ENTER_NOAPI(H5Z_can_apply_nbit, FAIL) + /* Get datatype's class, for checking the "datatype class" */ + if((dtype_class = H5Tget_class(type_id)) == H5T_NO_CLASS ) + HGOTO_ERROR(H5E_PLINE, H5E_BADTYPE, FAIL, "bad datatype class") + /* Get datatype's size, for checking the "datatype size" */ if((dtype_size = H5Tget_size(type_id)) == 0) HGOTO_ERROR(H5E_PLINE, H5E_BADTYPE, FAIL, "bad datatype size") + /* codes below have to been updated to adjust to array and compound datatype */ + if(dtype_class == H5T_INTEGER || dtype_class == H5T_FLOAT) { + /* Get datatype's endianness order */ + if((dtype_order = H5Tget_order(type_id)) == H5T_ORDER_ERROR) + HGOTO_ERROR(H5E_PLINE, H5E_BADTYPE, FAIL, "can't retrieve datatype endianness order") + + /* Range check datatype's endianness order */ + /* (Note: this may not handle non-atomic datatypes well) */ + if(dtype_order != H5T_ORDER_LE && dtype_order != H5T_ORDER_BE) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FALSE, "invalid datatype endianness order") + } +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5Z_can_apply_nbit() */ + + +/*------------------------------------------------------------------------- + * Function: H5Z_calc_parms_Tatomic + * + * Purpose: Calculate the number of parameters of cd_values[] + * for given a certain datatype identifier type_id + * if its datatype class is integer or floating point + * + * Return: Success: Non-negative + * Failure: Negative + * + * Programmer: Xiaowen Wu + * Wednesday, January 19, 2005 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static herr_t H5Z_calc_parms_Tatomic(hid_t type_id) +{ + herr_t ret_value=SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(H5Z_calc_parms_Tatomic, FAIL) + + /* Store datatype class code */ + ++cd_values_actual_nparms; + + /* Store datatype size */ + ++cd_values_actual_nparms; + + /* Store datatype endianness */ + ++cd_values_actual_nparms; + + /* Store datatype's precision */ + ++cd_values_actual_nparms; + + /* Store datatype's offset */ + ++cd_values_actual_nparms; + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5Z_calc_parms_Tatomic() */ + + +/*------------------------------------------------------------------------- + * Function: H5Z_calc_parms_Tarray + * + * Purpose: Calculate the number of parameters of cd_values[] + * for given a certain datatype identifier type_id + * if its datatype class is array datatype + * + * Return: Success: Non-negative + * Failure: Negative + * + * Programmer: Xiaowen Wu + * Wednesday, January 19, 2005 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static herr_t H5Z_calc_parms_Tarray(hid_t type_id) +{ + hid_t dtype_base; /* Array datatype's base datatype */ + H5T_class_t dtype_base_class; /* Array datatype's base datatype's class */ + herr_t ret_value=SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(H5Z_calc_parms_Tarray, FAIL) + + /* Store datatype class code */ + ++cd_values_actual_nparms; + + /* Store array datatype's size */ + ++cd_values_actual_nparms; + + /* Get array datatype's base datatype */ + if((dtype_base=H5Tget_super(type_id))<0) + HGOTO_ERROR(H5E_PLINE, H5E_BADTYPE, FAIL, "bad base datatype") + + /* Get base datatype's class */ + if((dtype_base_class=H5Tget_class(dtype_base))==H5T_NO_CLASS ) + HGOTO_ERROR(H5E_PLINE, H5E_BADTYPE, FAIL, "bad base datatype class") + + /* Calculate number of the rest parameters according to base datatype's class */ + switch(dtype_base_class) { + case H5T_INTEGER: + case H5T_FLOAT: H5Z_calc_parms_Tatomic(dtype_base); + break; + case H5T_ARRAY: H5Z_calc_parms_Tarray(dtype_base); + break; + case H5T_COMPOUND:H5Z_calc_parms_Tcompound(dtype_base); + break; + default: + HGOTO_ERROR(H5E_PLINE, H5E_BADTYPE, FAIL, "datatype class not supported by nbit") + } /* end switch */ +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5Z_calc_parms_Tarray() */ + + +/*------------------------------------------------------------------------- + * Function: H5Z_calc_parms_Tcompound + * + * Purpose: Calculate the number of parameters of cd_values[] + * for given a certain datatype identifier type_id + * if its datatype class is compound datatype + * + * Return: Success: Non-negative + * Failure: Negative + * + * Programmer: Xiaowen Wu + * Wednesday, January 19, 2005 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static herr_t H5Z_calc_parms_Tcompound(hid_t type_id) +{ + unsigned i; + int nmembers; /* Compound datatype's number of members */ + hid_t dtype_member; /* Compound datatype's member datatype */ + H5T_class_t dtype_member_class; /* Compound datatype's member datatype's class */ + herr_t ret_value=SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(H5Z_calc_parms_Tcompound, FAIL) + + /* Store compound datatype class code */ + ++cd_values_actual_nparms; + + /* Store compound datatype's size */ + ++cd_values_actual_nparms; + + /* Get number of members */ + if((nmembers=H5Tget_nmembers(type_id))<0) + HGOTO_ERROR(H5E_PLINE, H5E_BADTYPE, FAIL, "bad datatype number of members") + + /* Store number of members */ + ++cd_values_actual_nparms; + + /* For each member, calculate parameters */ + for(i = 0; i < nmembers; i++) { + /* Get member datatype */ + if((dtype_member=H5Tget_member_type(type_id, i))<0) + HGOTO_ERROR(H5E_PLINE, H5E_BADTYPE, FAIL, "bad member datatype") + + /* Get member datatype's class */ + if((dtype_member_class=H5Tget_member_class(type_id, i))<0) + HGOTO_ERROR(H5E_PLINE, H5E_BADTYPE, FAIL, "bad member datatype class") + + /* Store member offset */ + ++cd_values_actual_nparms; + + /* Calculate parameters according to member's datatype class */ + switch(dtype_member_class) { + case H5T_INTEGER: + case H5T_FLOAT: H5Z_calc_parms_Tatomic(dtype_member); + break; + case H5T_ARRAY: H5Z_calc_parms_Tarray(dtype_member); + break; + case H5T_COMPOUND:H5Z_calc_parms_Tcompound(dtype_member); + break; + default: + HGOTO_ERROR(H5E_PLINE, H5E_BADTYPE, FAIL, "datatype class not supported by nbit") + } /* end switch */ + } /* end for */ +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5Z_calc_params_Tcompound */ + + +/*------------------------------------------------------------------------- + * Function: H5Z_set_parms_Tatomic + * + * Purpose: Set the cd_values[] for given a certain datatype identifier + * type_id if its datatype class is integer or floating point + * + * Return: Success: Non-negative + * Failure: Negative + * + * Programmer: Xiaowen Wu + * Tuesday, January 11, 2005 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static herr_t H5Z_set_parms_Tatomic(hid_t type_id, unsigned cd_values[]) +{ + H5T_order_t dtype_order; /* Atomic datatype's endianness order */ + size_t dtype_size; /* Atomic datatype's size (in bytes) */ + size_t dtype_precision; /* Atomic datatype's precision (in bits) */ + int dtype_offset; /* Atomic datatype's offset (in bits) */ + herr_t ret_value=SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(H5Z_set_parms_Tatomic, FAIL) + + /* Set datatype class code */ + cd_values[cd_values_index++] = H5Z_NBIT_ATOMIC; + + /* Get datatype's size */ + if((dtype_size=H5Tget_size(type_id))==0) + HGOTO_ERROR(H5E_PLINE, H5E_BADTYPE, FAIL, "bad datatype size") + + /* Set "local" parameter for datatype size */ + cd_values[cd_values_index++] = dtype_size; + /* Get datatype's endianness order */ - if((dtype_order = H5Tget_order(type_id)) == H5T_ORDER_ERROR) - HGOTO_ERROR(H5E_PLINE, H5E_BADTYPE, FAIL, "can't retrieve datatype endianness order") + if((dtype_order=H5Tget_order(type_id))==H5T_ORDER_ERROR) + HGOTO_ERROR(H5E_PLINE, H5E_BADTYPE, FAIL, "bad datatype endianness order") + + /* Set "local" parameter for datatype endianness */ + switch(dtype_order) { + case H5T_ORDER_LE: /* Little-endian byte order */ + cd_values[cd_values_index++] = H5Z_NBIT_ORDER_LE; + break; + case H5T_ORDER_BE: /* Big-endian byte order */ + cd_values[cd_values_index++] = H5Z_NBIT_ORDER_BE; + break; + default: + HGOTO_ERROR(H5E_PLINE, H5E_BADTYPE, FAIL, "bad datatype endianness order") + } /* end switch */ - /* Range check datatype's endianness order */ - /* (Note: this may not handle non-atomic datatypes well) */ - if(dtype_order != H5T_ORDER_LE && dtype_order != H5T_ORDER_BE) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FALSE, "invalid datatype endianness order") + /* Get datatype's precision */ + if((dtype_precision=H5Tget_precision(type_id))==0) + HGOTO_ERROR(H5E_PLINE, H5E_BADTYPE, FAIL, "bad datatype precision") + + /* Set "local" parameter for datatype precision */ + cd_values[cd_values_index++] = dtype_precision; + + /* Get datatype's offset */ + if((dtype_offset=H5Tget_offset(type_id))<0) + HGOTO_ERROR(H5E_PLINE, H5E_BADTYPE, FAIL, "bad datatype offset") + /* Set "local" parameter for datatype offset */ + cd_values[cd_values_index++] = dtype_offset; + + /* Check the compression ratio at this point */ + if(compress_ratio_is_zero) /* so far the compression ratio is zero */ + if(dtype_offset != 0 || dtype_precision != dtype_size * 8) + compress_ratio_is_zero = FALSE; done: FUNC_LEAVE_NOAPI(ret_value) -} /* end H5Z_can_apply_nbit() */ +} /* end H5Z_set_parms_Tatomic() */ + + +/*------------------------------------------------------------------------- + * Function: H5Z_set_parms_Tarray + * + * Purpose: Set the cd_values[] for given a certain datatype identifier + * type_id if its datatype class is array datatype + * + * Return: Success: Non-negative + * Failure: Negative + * + * Programmer: Xiaowen Wu + * Tuesday, January 11, 2005 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static herr_t H5Z_set_parms_Tarray(hid_t type_id, unsigned cd_values[]) +{ + hid_t dtype_base; /* Array datatype's base datatype */ + H5T_class_t dtype_base_class; /* Array datatype's base datatype's class */ + size_t dtype_size; /* Array datatype's size (in bytes) */ + herr_t ret_value=SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(H5Z_set_parms_Tarray, FAIL) + + /* Set datatype class code */ + cd_values[cd_values_index++] = H5Z_NBIT_ARRAY; + + /* Get array datatype's size */ + if((dtype_size=H5Tget_size(type_id))==0) + HGOTO_ERROR(H5E_PLINE, H5E_BADTYPE, FAIL, "bad datatype size") + + /* Set "local" parameter for array datatype's size */ + cd_values[cd_values_index++]=dtype_size; + + /* Get array datatype's base datatype */ + if((dtype_base=H5Tget_super(type_id))<0) + HGOTO_ERROR(H5E_PLINE, H5E_BADTYPE, FAIL, "bad base datatype") + + /* Get base datatype's class */ + if((dtype_base_class=H5Tget_class(dtype_base))==H5T_NO_CLASS ) + HGOTO_ERROR(H5E_PLINE, H5E_BADTYPE, FAIL, "bad base datatype class") + + /* Call appropriate function according to base datatype's class */ + switch(dtype_base_class) { + case H5T_INTEGER: + case H5T_FLOAT: H5Z_set_parms_Tatomic(dtype_base, cd_values); + break; + case H5T_ARRAY: H5Z_set_parms_Tarray(dtype_base, cd_values); + break; + case H5T_COMPOUND:H5Z_set_parms_Tcompound(dtype_base, cd_values); + break; + default: + HGOTO_ERROR(H5E_PLINE, H5E_BADTYPE, FAIL, "datatype class not supported by nbit") + } /* end switch */ +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5Z_set_parms_Tarray() */ + + +/*------------------------------------------------------------------------- + * Function: H5Z_set_parms_Tcompound + * + * Purpose: Set the cd_values[] for given a certain datatype identifier + * type_id if its datatype class is compound datatype + * + * Return: Success: Non-negative + * Failure: Negative + * + * Programmer: Xiaowen Wu + * Tuesday, January 11, 2005 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static herr_t H5Z_set_parms_Tcompound(hid_t type_id, unsigned cd_values[]) +{ + unsigned i; + int nmembers; /* Compound datatype's number of members */ + hid_t dtype_member; /* Compound datatype's member datatype */ + H5T_class_t dtype_member_class; /* Compound datatype's member datatype's class */ + size_t dtype_member_offset; /* Compound datatype's member datatype's offset (in bytes) */ + size_t dtype_size; /* Compound datatype's size (in bytes) */ + herr_t ret_value=SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(H5Z_set_parms_Tcompound, FAIL) + + /* Set "local" parameter for compound datatype class code */ + cd_values[cd_values_index++] = H5Z_NBIT_COMPOUND; + + /* Get datatype's size */ + if((dtype_size=H5Tget_size(type_id))==0) + HGOTO_ERROR(H5E_PLINE, H5E_BADTYPE, FAIL, "bad datatype size") + + /* Set "local" parameter for compound datatype size */ + cd_values[cd_values_index++] = dtype_size; + + /* Get number of members */ + if((nmembers=H5Tget_nmembers(type_id))<0) + HGOTO_ERROR(H5E_PLINE, H5E_BADTYPE, FAIL, "bad datatype number of members") + + /* Set "local" parameter for number of members */ + cd_values[cd_values_index++] = nmembers; + + /* For each member, set parameters */ + for(i = 0; i < nmembers; i++) { + /* Get member datatype */ + if((dtype_member=H5Tget_member_type(type_id, i))<0) + HGOTO_ERROR(H5E_PLINE, H5E_BADTYPE, FAIL, "bad member datatype") + + /* Get member datatype's class */ + if((dtype_member_class=H5Tget_member_class(type_id, i))<0) + HGOTO_ERROR(H5E_PLINE, H5E_BADTYPE, FAIL, "bad member datatype class") + + /* Get member offset, success if H5Tget_member_class() success */ + dtype_member_offset = H5Tget_member_offset(type_id, i); + + /* Set "local" parameter for member offset */ + cd_values[cd_values_index++] = dtype_member_offset; + + /* Call appropriate function according to member's datatype class */ + switch(dtype_member_class) { + case H5T_INTEGER: + case H5T_FLOAT: H5Z_set_parms_Tatomic(dtype_member, cd_values); + break; + case H5T_ARRAY: H5Z_set_parms_Tarray(dtype_member, cd_values); + break; + case H5T_COMPOUND:H5Z_set_parms_Tcompound(dtype_member, cd_values); + break; + default: + HGOTO_ERROR(H5E_PLINE, H5E_BADTYPE, FAIL, "datatype class not supported by nbit") + } /* end switch */ + } /* end for */ +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5Z_set_params_Tcompound */ /*------------------------------------------------------------------------- @@ -127,12 +559,10 @@ done: * Return: Success: Non-negative * Failure: Negative * - * Programmer: Quincey Koziol - * Monday, April 7, 2003 + * Programmer: Xiaowen Wu + * Tuesday, January 11, 2004 * * Modifications: - * Xiaowen Wu - * Tuesday, December 21, 2004 * *------------------------------------------------------------------------- */ @@ -140,16 +570,11 @@ static herr_t H5Z_set_local_nbit(hid_t dcpl_id, hid_t type_id, hid_t space_id) { unsigned flags; /* Filter flags */ - size_t cd_nelmts=H5Z_NBIT_USER_NPARMS; /* Number of filter parameters */ - unsigned cd_values[H5Z_NBIT_TOTAL_NPARMS]; /* Filter parameters */ - hsize_t dims[H5O_LAYOUT_NDIMS]; /* Dataspace (i.e. chunk) dimensions */ - int ndims; /* Number of (chunk) dimensions */ - hssize_t npoints; /* Number of points in the dataspace */ - H5T_order_t dtype_order; /* Datatype's endianness order */ - int dtype_size; /* Datatype's size (in bytes) */ - size_t dtype_precision; /* Datatype's precision (in bits) */ - int dtype_offset; /* Datatype's offset (in bits) */ - herr_t ret_value=SUCCEED; /* Return value */ + size_t cd_nelmts=H5Z_NBIT_USER_NPARMS; /* Number of filter parameters */ + unsigned cd_values[H5Z_NBIT_MAX_NPARMS]; /* Filter parameters */ + hssize_t npoints; /* Number of points in the dataspace */ + H5T_class_t dtype_class; /* Datatype's class */ + herr_t ret_value=SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(H5Z_set_local_nbit, FAIL) @@ -161,62 +586,61 @@ H5Z_set_local_nbit(hid_t dcpl_id, hid_t type_id, hid_t space_id) #endif HGOTO_ERROR(H5E_PLINE, H5E_CANTGET, FAIL, "can't get nbit parameters") - /* Get datatype's size, for checking the "datatype size" */ - if((dtype_size=H5Tget_size(type_id))==0) - HGOTO_ERROR(H5E_PLINE, H5E_BADTYPE, FAIL, "bad datatype size"); - - /* Set "local" parameter for this dataset's "datatype size" */ - cd_values[H5Z_NBIT_PARM_TSIZE]=dtype_size; - - /* Get datatype's precision, for checking the "datatype precision" */ - if((dtype_precision=H5Tget_precision(type_id))==0) - HGOTO_ERROR(H5E_PLINE, H5E_BADTYPE, FAIL, "bad datatype precision"); - - /* Set "local" parameter for this dataset's "datatype precision" */ - cd_values[H5Z_NBIT_PARM_PRECIS]=dtype_precision; - - /* Get datatype's offset, for checking the "datatype offset" */ - if((dtype_offset=H5Tget_offset(type_id))<0) - HGOTO_ERROR(H5E_PLINE, H5E_BADTYPE, FAIL, "bad datatype offset"); - - /* Set "local" parameter for this dataset's "datatype offset" */ - cd_values[H5Z_NBIT_PARM_OFFSET]=dtype_offset; - - /* Get dimensions for dataspace */ - if ((ndims=H5Sget_simple_extent_dims(space_id, dims, NULL))<0) - HGOTO_ERROR(H5E_PLINE, H5E_CANTGET, FAIL, "unable to get dataspace dimensions") - assert(ndims>0); + /* Get datatype's class */ + if((dtype_class = H5Tget_class(type_id)) == H5T_NO_CLASS ) + HGOTO_ERROR(H5E_PLINE, H5E_BADTYPE, FAIL, "bad datatype class") + + /* Calculate how many parameters will fill the cd_values array */ + cd_values_actual_nparms = 1; /* first parameter reserved for dataset's number of elements */ + switch(dtype_class) { + case H5T_INTEGER: + case H5T_FLOAT: H5Z_calc_parms_Tatomic(type_id); + break; + case H5T_ARRAY: H5Z_calc_parms_Tarray(type_id); + break; + case H5T_COMPOUND:H5Z_calc_parms_Tcompound(type_id); + break; + default: + HGOTO_ERROR(H5E_PLINE, H5E_BADTYPE, FAIL, "datatype class not supported by nbit") + } /* end switch */ + + /* Check if the number of parameters exceed what cd_values[] can store */ + if(cd_values_actual_nparms > H5Z_NBIT_MAX_NPARMS) + HGOTO_ERROR(H5E_PLINE, H5E_BADTYPE, FAIL, "datatype needs too many nbit parameters") /* Get total number of elements in the chunk */ if ((npoints=H5Sget_simple_extent_npoints(space_id))<0) HGOTO_ERROR(H5E_PLINE, H5E_CANTGET, FAIL, "unable to get number of points in the dataspace") - /* Set "local" parameter for this dataset's "number of elements" */ - cd_values[H5Z_NBIT_PARM_NELMTS] = npoints; + /* Initialize index for cd_values array */ + cd_values_index = 0; - /* Get datatype's endianness order */ - if((dtype_order=H5Tget_order(type_id))==H5T_ORDER_ERROR) - HGOTO_ERROR(H5E_PLINE, H5E_BADTYPE, FAIL, "bad datatype endianness order") + /* Set "local" parameter for this dataset's number of elements */ + cd_values[cd_values_index++] = npoints; - /* Set the correct endianness for nbit */ - /* (Note: this may not handle non-atomic datatypes well) */ - switch(dtype_order) { - case H5T_ORDER_LE: /* Little-endian byte order */ - cd_values[H5Z_NBIT_PARM_ORDER] = 10; - break; - case H5T_ORDER_BE: /* Big-endian byte order */ - cd_values[H5Z_NBIT_PARM_ORDER] = 20; - break; + /* Assume compression ratio is zero now, will be changed to FALSE later if not */ + compress_ratio_is_zero = TRUE; + + /* Call appropriate function according to the datatype class */ + switch(dtype_class) { + case H5T_INTEGER: + case H5T_FLOAT: H5Z_set_parms_Tatomic(type_id, cd_values); + break; + case H5T_ARRAY: H5Z_set_parms_Tarray(type_id, cd_values); + break; + case H5T_COMPOUND:H5Z_set_parms_Tcompound(type_id, cd_values); + break; default: - HGOTO_ERROR(H5E_PLINE, H5E_BADTYPE, FAIL, "bad datatype endianness order") + HGOTO_ERROR(H5E_PLINE, H5E_BADTYPE, FAIL, "datatype class not supported by nbit") } /* end switch */ /* Modify the filter's parameters for this dataset */ - if(H5Pmodify_filter(dcpl_id, H5Z_FILTER_NBIT, flags, H5Z_NBIT_TOTAL_NPARMS, cd_values)<0) + if(H5Pmodify_filter(dcpl_id, H5Z_FILTER_NBIT, flags, cd_values_actual_nparms, cd_values)<0) HGOTO_ERROR(H5E_PLINE, H5E_CANTSET, FAIL, "can't set local nbit parameters") done: FUNC_LEAVE_NOAPI(ret_value) + } /* end H5Z_set_local_nbit() */ @@ -239,60 +663,76 @@ static size_t H5Z_filter_nbit (unsigned flags, size_t cd_nelmts, const unsigned cd_values[], size_t nbytes, size_t *buf_size, void **buf) { - size_t ret_value = 0; /* return value */ - size_t size_out = 0; /* size of output buffer */ - size_t d_nelmts = 0; /* number of elements in the chunk */ - unsigned char *outbuf = NULL; /* pointer to new output buffer */ - para nbit_param; /* nbit parameter block */ + size_t ret_value = 0; /* return value */ + size_t size_out = 0; /* size of output buffer */ + size_t d_nelmts = 0; /* number of elements in the chunk */ + unsigned char *outbuf = NULL; /* pointer to new output buffer */ + size_t i; FUNC_ENTER_NOAPI(H5Z_filter_nbit, 0) /* check arguments */ - if (cd_nelmts!=5) + if (cd_nelmts!=cd_values_actual_nparms) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, 0, "invalid nbit aggression level") - /* copy the filter parameters into the nbit parameter block */ - H5_ASSIGN_OVERFLOW(nbit_param.precision,cd_values[H5Z_NBIT_PARM_PRECIS],unsigned,int); - H5_ASSIGN_OVERFLOW(nbit_param.offset,cd_values[H5Z_NBIT_PARM_OFFSET],unsigned,int); - H5_ASSIGN_OVERFLOW(nbit_param.sizeof_datatype,cd_values[H5Z_NBIT_PARM_TSIZE],unsigned,int); - H5_ASSIGN_OVERFLOW(nbit_param.order,cd_values[H5Z_NBIT_PARM_ORDER],unsigned,int); - - /* copy a filter parameter to d_nelmts */ - H5_ASSIGN_OVERFLOW(d_nelmts,cd_values[H5Z_NBIT_PARM_NELMTS],unsigned,int); - - printf("\nprecision: %d", nbit_param.precision); - printf(" offset: %d\n", nbit_param.offset); - - /* no need to compress or decompress - if (nbit_param.precision == nbit_param.sizeof_datatype * 8) { + /* no need to do nbit compress or decompress */ + if (compress_ratio_is_zero) { ret_value = *buf_size; goto done; - }*/ + } + + /* copy a filter parameter to d_nelmts */ + d_nelmts = cd_values[0]; +/* + printf("\n cd_values[%d]:\n", cd_values_actual_nparms); + for(i = 0; i < cd_values_actual_nparms; i++) + printf("%d ", cd_values[i]); + printf("\n number of elements: %d\n", d_nelmts); +*/ /* input; decompress */ if (flags & H5Z_FLAG_REVERSE) { - size_out = d_nelmts * nbit_param.sizeof_datatype; + size_out = d_nelmts * cd_values[2]; /* allocate memory space for decompressed buffer */ if(NULL==(outbuf = H5MM_malloc(size_out))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, 0, "memory allocation failed for nbit decompression") /* decompress the buffer */ - H5Z_nbit_decompress(outbuf, d_nelmts, *buf, nbytes, nbit_param); + H5Z_nbit_decompress(outbuf, d_nelmts, *buf, cd_values); +/* + printf("=== After decompression: %d bytes\n", size_out); + for (i= 0;i< size_out; i++) { + printf("outbuf[%d]: %02x ", i, ((unsigned char *)outbuf)[i]); + if((i+1)%4 == 0) printf("\n"); + } + printf("\n"); */ } /* output; compress */ else { - if((d_nelmts * nbit_param.precision) % (sizeof(char) * 8) != 0) - size_out = (d_nelmts * nbit_param.precision) / (sizeof(char) * 8) + 1; - else - size_out = (d_nelmts * nbit_param.precision) / (sizeof(char) * 8); + /*printf("=== Before compression: %d bytes\n", nbytes); + for (i= 0;i< nbytes; i++) { + printf("buf[%d]: %02x ", i, ((unsigned char *)*buf)[i]); + if((i+1)%4 == 0) printf("\n"); + } + printf("\n");*/ + + /* difficult to calculate exact buffer size after compression */ + size_out = d_nelmts * cd_values[2]; /* allocate memory space for compressed buffer */ if(NULL==(outbuf = H5MM_malloc(size_out))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, 0, "memory allocation failed for nbit compression") /* compress the buffer */ - H5Z_nbit_compress(*buf, d_nelmts, outbuf, size_out, nbit_param); + H5Z_nbit_compress(*buf, d_nelmts, outbuf, &size_out, cd_values); + + /*printf("=== After compression: %d bytes\n", size_out); + for (i= 0;i< size_out; i++) { + printf("outbuf[%d]: %02x ", i, ((unsigned char *)outbuf)[i]); + if((i+1)%4 == 0) printf("\n"); + } + printf("\n");*/ } /* free the input buffer */ @@ -310,113 +750,75 @@ done: FUNC_LEAVE_NOAPI(ret_value) } -/* assume one byte has 8 bit, padding bit is 0 - assume size of char is one byte +/* + assume one byte has 8 bit, padding bit is 0 + assume size of unsigned char is one byte assume one item of certain data type is stored continously in bytes data type regardless what is treated on byte basis */ -void H5Z_nbit_next_char(int *j, int *buf_len) +void H5Z_nbit_next_byte(int *j, int *buf_len) { ++(*j); - *buf_len = 8 * sizeof(char); + *buf_len = 8 * sizeof(unsigned char); } -void H5Z_nbit_byte_order(int *big_endian, int *little_endian) -{ - /* decide the machine's byte order */ - union { - long l; - char c[sizeof(long)]; - } u; - u.l = 1; - if(u.c[0] == 1) - *little_endian = 1; - else if(u.c[sizeof(long) - 1] == 1) - *big_endian = 1; - else { - printf("Abort: unkown byte order!\n"); - exit(1); - } -} - -void H5Z_nbit_decompress_one_byte(void *data, int i, int k, int begin_i, int end_i, char *buffer, - int *j, int *buf_len, para p) +void H5Z_nbit_decompress_one_byte(void *data, int data_offset, int k, int begin_i, int end_i, + unsigned char *buffer, int *j, int *buf_len, parms_atomic p) { - int dat_len; /* dat_len is the number of bits to be copied in each data char */ - int datatype_len, char_offset; - char val; /* value to be copied in each data char */ + int dat_len; /* dat_len is the number of bits to be copied in each data byte */ + int datatype_len, uchar_offset; + unsigned char val; /* value to be copied in each data byte */ datatype_len = p.sizeof_datatype * 8; - /* initialize value and bits of char to be copied */ + /* initialize value and bits of unsigned char to be copied */ val = buffer[*j]; - char_offset = 0; - if(begin_i != end_i) { /* significant bits occupy >1 char */ + uchar_offset = 0; + + if(begin_i != end_i) { /* significant bits occupy >1 unsigned char */ if(k == begin_i) dat_len = 8 - (datatype_len - p.precision - p.offset) % 8; else if(k == end_i) { - if(p.offset % 8 == 0) - dat_len = 8; - else - dat_len = (datatype_len - p.offset) % 8; - char_offset = 8 - dat_len; + dat_len = 8 - p.offset %8; + uchar_offset = 8 - dat_len; } else dat_len = 8; - } else { /* all significant bits in one char */ - if(p.offset % 8 != 0) - char_offset = p.offset % 8; + } else { /* all significant bits in one unsigned char */ + uchar_offset = p.offset % 8; dat_len = p.precision; } if(*buf_len > dat_len) { - ((char *)data)[i * p.sizeof_datatype + k] |= - ((val >> (*buf_len - dat_len)) & ~(~0 << dat_len)) << char_offset; + ((unsigned char *)data)[data_offset + k] = + ((val >> (*buf_len - dat_len)) & ~(~0 << dat_len)) << uchar_offset; *buf_len -= dat_len; } else { - ((char *)data)[i * p.sizeof_datatype + k] |= - ((val & ~(~0 << *buf_len)) << (dat_len - *buf_len)) << char_offset; + ((unsigned char *)data)[data_offset + k] = + ((val & ~(~0 << *buf_len)) << (dat_len - *buf_len)) << uchar_offset; dat_len -= *buf_len; - H5Z_nbit_next_char(j, buf_len); - if(dat_len == 0) - return; + H5Z_nbit_next_byte(j, buf_len); + if(dat_len == 0) return; + val = buffer[*j]; - - ((char *)data)[i * p.sizeof_datatype + k] |= - ((val >> (*buf_len - dat_len)) & ~(~0 << dat_len)) << char_offset; + ((unsigned char *)data)[data_offset + k] |= + ((val >> (*buf_len - dat_len)) & ~(~0 << dat_len)) << uchar_offset; *buf_len -= dat_len; } } /* decompress buffer to original data form */ -void H5Z_nbit_decompress(void *data, int data_size, char *buffer, int buffer_size, para p) +void H5Z_nbit_decompress_one_atomic(void *data, int data_offset, unsigned char *buffer, int *j, + int *buf_len, parms_atomic p) { - /* i: index of data, j: index of buffer, - buf_len: number of bits to be copied in current char */ - int i, j, buf_len; /* begin_i: the index of byte having first significant bit end_i: the index of byte having last significant bit */ - int k, begin_i, end_i, big_endian, little_endian, datatype_len; - - printf("decompress is called \n"); - - /* may not have to initialize to zeros */ - for(i = 0; i < data_size * p.sizeof_datatype; i++) - ((char *)data)[i] = 0; - - /* decide the byte order of the machine */ - little_endian = big_endian = 0; - H5Z_nbit_byte_order(&big_endian, &little_endian); + int k, begin_i, end_i, datatype_len; datatype_len = p.sizeof_datatype * 8; - /* initialization before the loop */ - j = 0; - buf_len = sizeof(char) * 8; - - if(p.order == 10) { /* little endian */ - printf("\ndatatype is little-endian\n"); + if(p.order == H5Z_NBIT_ORDER_LE) { /* little endian */ /* calculate begin_i and end_i */ if((p.precision + p.offset) % 8 != 0) begin_i = (p.precision + p.offset) / 8; @@ -424,13 +826,12 @@ void H5Z_nbit_decompress(void *data, int data_size, char *buffer, int buffer_siz begin_i = (p.precision + p.offset) / 8 - 1; end_i = p.offset / 8; - for(i = 0; i < data_size; i++) - for(k = begin_i; k >= end_i; k--) - H5Z_nbit_decompress_one_byte(data, i, k, begin_i, end_i, buffer, &j, &buf_len, p); + for(k = begin_i; k >= end_i; k--) + H5Z_nbit_decompress_one_byte(data, data_offset, k, begin_i, end_i, + buffer, j, buf_len, p); } - if(p.order == 20) { /* big endian */ - printf("\ndatatype is big-endian\n"); + if(p.order == H5Z_NBIT_ORDER_BE) { /* big endian */ /* calculate begin_i and end_i */ begin_i = (datatype_len - p.precision - p.offset) / 8; if(p.offset % 8 != 0) @@ -438,38 +839,155 @@ void H5Z_nbit_decompress(void *data, int data_size, char *buffer, int buffer_siz else end_i = (datatype_len - p.offset) / 8 - 1; - for(i = 0; i < data_size; i++) - for(k = begin_i; k <= end_i; k++) - H5Z_nbit_decompress_one_byte(data, i, k, begin_i, end_i, buffer, &j, &buf_len, p); + for(k = begin_i; k <= end_i; k++) + H5Z_nbit_decompress_one_byte(data, data_offset, k, begin_i, end_i, + buffer, j, buf_len, p); } } -void H5Z_nbit_compress_one_byte(void *data, int i, int k, int begin_i, int end_i, char *buffer, - int *j, int *buf_len, para p) +void H5Z_nbit_decompress_one_array(void *data, int data_offset, unsigned char *buffer, int *j, + int *buf_len, const unsigned parms[]) +{ + unsigned i, size, base_class, base_size, n, begin_index; + parms_atomic p; + + size = parms[parms_index++]; + base_class = parms[parms_index++]; + + switch(base_class) { + case H5Z_NBIT_ATOMIC: + p.sizeof_datatype = parms[parms_index++]; + p.order = parms[parms_index++]; + p.precision = parms[parms_index++]; + p.offset = parms[parms_index++]; + n = size/p.sizeof_datatype; + for(i = 0; i < n; i++) + H5Z_nbit_decompress_one_atomic(data, data_offset + i*p.sizeof_datatype, + buffer, j, buf_len, p); + break; + case H5Z_NBIT_ARRAY: + base_size = parms[parms_index]; /* read in advance */ + n = size/base_size; /* number of base_type elements inside the array datatype */ + begin_index = parms_index; + for(i = 0; i < n; i++) { + H5Z_nbit_decompress_one_array(data, data_offset + i*base_size, + buffer, j, buf_len, parms); + parms_index = begin_index; + } + break; + case H5Z_NBIT_COMPOUND: + base_size = parms[parms_index]; /* read in advance */ + n = size/base_size; /* number of base_type elements inside the array datatype */ + begin_index = parms_index; + for(i = 0; i < n; i++) { + H5Z_nbit_decompress_one_compound(data, data_offset + i*base_size, + buffer, j, buf_len, parms); + parms_index = begin_index; + } + break; + } /* end switch */ +} + +void H5Z_nbit_decompress_one_compound(void *data, int data_offset, unsigned char *buffer, int *j, + int *buf_len, const unsigned parms[]) +{ + unsigned i, nmembers, member_offset, member_class, size; + parms_atomic p; + + size = parms[parms_index++]; + nmembers = parms[parms_index++]; + + for(i = 0; i < nmembers; i++) { + member_offset = parms[parms_index++]; + member_class = parms[parms_index++]; + switch(member_class) { + case H5Z_NBIT_ATOMIC: + p.sizeof_datatype = parms[parms_index++]; + p.order = parms[parms_index++]; + p.precision = parms[parms_index++]; + p.offset = parms[parms_index++]; + H5Z_nbit_decompress_one_atomic(data, data_offset + member_offset, + buffer, j, buf_len, p); + break; + case H5Z_NBIT_ARRAY: + H5Z_nbit_decompress_one_array(data, data_offset + member_offset, + buffer, j, buf_len, parms); + break; + case H5Z_NBIT_COMPOUND: + H5Z_nbit_decompress_one_compound(data, data_offset+member_offset, + buffer, j, buf_len, parms); + break; + } /* end switch */ + } +} + +void H5Z_nbit_decompress(void *data, int d_nelmts, unsigned char *buffer, const unsigned parms[]) +{ + /* i: index of data, j: index of buffer, + buf_len: number of bits to be filled in current byte */ + int i, j, buf_len, size; + parms_atomic p; + + /* may not have to initialize to zeros */ + for(i = 0; i < d_nelmts*parms[2]; i++) + ((unsigned char *)data)[i] = 0; + + /* initialization before the loop */ + j = 0; + buf_len = sizeof(unsigned char) * 8; + + switch(parms[1]) { + case H5Z_NBIT_ATOMIC: + /* set the index before goto function call */ + p.sizeof_datatype = parms[2]; + p.order = parms[3]; + p.precision = parms[4]; + p.offset = parms[5]; + for(i = 0; i < d_nelmts; i++) { + H5Z_nbit_decompress_one_atomic(data, i*p.sizeof_datatype, buffer, &j, &buf_len, p); + } + break; + case H5Z_NBIT_ARRAY: + size = parms[2]; + parms_index = 2; + for(i = 0; i < d_nelmts; i++) { + H5Z_nbit_decompress_one_array(data, i*size, buffer, &j, &buf_len, parms); + parms_index = 2; + } + break; + case H5Z_NBIT_COMPOUND: + size = parms[2]; + parms_index = 2; + for(i = 0; i < d_nelmts; i++) { + H5Z_nbit_decompress_one_compound(data, i*size, buffer, &j, &buf_len, parms); + parms_index = 2; + } + break; + } /* end switch */ +} + +void H5Z_nbit_compress_one_byte(void *data, int data_offset, int k, int begin_i, int end_i, + unsigned char *buffer, int *j, int *buf_len, parms_atomic p) { - int dat_len; /* dat_len is the number of bits to be copied in each data char */ + int dat_len; /* dat_len is the number of bits to be copied in each data byte */ int datatype_len; - char val; /* value to be copied in each data char */ + unsigned char val; /* value to be copied in each data byte */ datatype_len = p.sizeof_datatype * 8; - /* initialize value and bits of char to be copied */ - val = ((char *)data)[i * p.sizeof_datatype + k]; - if(begin_i != end_i) { /* significant bits occupy >1 char */ + /* initialize value and bits of unsigned char to be copied */ + val = ((unsigned char *)data)[data_offset + k]; + if(begin_i != end_i) { /* significant bits occupy >1 unsigned char */ if(k == begin_i) dat_len = 8 - (datatype_len - p.precision - p.offset) % 8; else if(k == end_i) { - if(p.offset % 8 == 0) - dat_len = 8; - else - dat_len = (datatype_len - p.offset) % 8; + dat_len = 8 - p.offset % 8; val >>= 8 - dat_len; } else dat_len = 8; - } else { /* all significant bits in one char */ - if(p.offset % 8 != 0) - val >>= p.offset % 8; + } else { /* all significant bits in one unsigned char */ + val >>= p.offset % 8; dat_len = p.precision; } @@ -479,42 +997,25 @@ void H5Z_nbit_compress_one_byte(void *data, int i, int k, int begin_i, int end_i } else { buffer[*j] |= (val >> (dat_len - *buf_len)) & ~(~0 << *buf_len); dat_len -= *buf_len; - H5Z_nbit_next_char(j, buf_len); - if(dat_len == 0) - return; - val &= ~(~0 << dat_len); - - buffer[*j] |= (val & ~(~0 << dat_len)) << (*buf_len - dat_len); + H5Z_nbit_next_byte(j, buf_len); + if(dat_len == 0) return; + + buffer[*j] = (val & ~(~0 << dat_len)) << (*buf_len - dat_len); *buf_len -= dat_len; } } -/* copy array of certain data type to buffer in compressed form - return number of unused bits in the buffer */ -void H5Z_nbit_compress(void *data, int data_size, char *buffer, int buffer_size, para p) { - /* i: index of data, j: index of buffer, - buf_len: number of bits to be filled in current char */ - int i, j, buf_len; +/* copy array of certain data type to buffer in compressed form */ +void H5Z_nbit_compress_one_atomic(void *data, int data_offset, unsigned char *buffer, int *j, + int *buf_len, parms_atomic p) +{ /* begin_i: the index of byte having first significant bit end_i: the index of byte having last significant bit */ - int k, begin_i, end_i, big_endian, little_endian, datatype_len; - - printf("compress is called \n"); - - for(j = 0; j < buffer_size; j++) /* initialize buffer to be zeros */ - buffer[j] = 0; - - /* decide the byte order of the machine */ - big_endian = little_endian = 0; - H5Z_nbit_byte_order(&big_endian, &little_endian); + int k, begin_i, end_i, datatype_len; datatype_len = p.sizeof_datatype * 8; - /* initialization before the loop */ - j = 0; - buf_len = sizeof(char) * 8; - if(p.order == 10) { /* little endian */ - printf("\ndatatype is little-endian\n"); + if(p.order == H5Z_NBIT_ORDER_LE) { /* little endian */ /* calculate begin_i and end_i */ if((p.precision + p.offset) % 8 != 0) begin_i = (p.precision + p.offset) / 8; @@ -522,13 +1023,11 @@ void H5Z_nbit_compress(void *data, int data_size, char *buffer, int buffer_size, begin_i = (p.precision + p.offset) / 8 - 1; end_i = p.offset / 8; - for(i = 0; i < data_size; i++) - for(k = begin_i; k >= end_i; k--) - H5Z_nbit_compress_one_byte(data, i, k, begin_i, end_i, buffer, &j, &buf_len, p); + for(k = begin_i; k >= end_i; k--) + H5Z_nbit_compress_one_byte(data, data_offset, k, begin_i, end_i, buffer, j, buf_len, p); } - if(p.order == 20) { /* big endian */ - printf("\ndatatype is big-endian\n"); + if(p.order == H5Z_NBIT_ORDER_BE) { /* big endian */ /* calculate begin_i and end_i */ begin_i = (datatype_len - p.precision - p.offset) / 8; if(p.offset % 8 != 0) @@ -536,10 +1035,134 @@ void H5Z_nbit_compress(void *data, int data_size, char *buffer, int buffer_size, else end_i = (datatype_len - p.offset) / 8 - 1; - for(i = 0; i < data_size; i++) - for(k = begin_i; k <= end_i; k++) - H5Z_nbit_compress_one_byte(data, i, k, begin_i, end_i, buffer, &j, &buf_len, p); + for(k = begin_i; k <= end_i; k++) + H5Z_nbit_compress_one_byte(data, data_offset, k, begin_i, end_i, buffer, j, buf_len, p); } } -#endif /* H5_HAVE_FILTER_NZIP */ +void H5Z_nbit_compress_one_array(void *data, int data_offset, unsigned char *buffer, int *j, + int *buf_len, const unsigned parms[]) +{ + unsigned i, size, base_class, base_size, n, begin_index; + parms_atomic p; + + size = parms[parms_index++]; + base_class = parms[parms_index++]; + + switch(base_class) { + case H5Z_NBIT_ATOMIC: + p.sizeof_datatype = parms[parms_index++]; + p.order = parms[parms_index++]; + p.precision = parms[parms_index++]; + p.offset = parms[parms_index++]; + n = size/p.sizeof_datatype; + for(i = 0; i < n; i++) + H5Z_nbit_compress_one_atomic(data, data_offset + i*p.sizeof_datatype, + buffer, j, buf_len, p); + break; + case H5Z_NBIT_ARRAY: + base_size = parms[parms_index]; /* read in advance */ + n = size/base_size; /* number of base_type elements inside the array datatype */ + begin_index = parms_index; + for(i = 0; i < n; i++) { + H5Z_nbit_compress_one_array(data, data_offset + i*base_size, + buffer, j, buf_len, parms); + parms_index = begin_index; + } + break; + case H5Z_NBIT_COMPOUND: + base_size = parms[parms_index]; /* read in advance */ + n = size/base_size; /* number of base_type elements inside the array datatype */ + begin_index = parms_index; + for(i = 0; i < n; i++) { + H5Z_nbit_compress_one_compound(data, data_offset + i*base_size, + buffer, j, buf_len, parms); + parms_index = begin_index; + } + break; + } /* end switch */ +} + +void H5Z_nbit_compress_one_compound(void *data, int data_offset, unsigned char *buffer, int *j, + int *buf_len, const unsigned parms[]) +{ + unsigned i, nmembers, member_offset, member_class, size; + parms_atomic p; + + size = parms[parms_index++]; + nmembers = parms[parms_index++]; + + for(i = 0; i < nmembers; i++) { + member_offset = parms[parms_index++]; + member_class = parms[parms_index++]; + + switch(member_class) { + case H5Z_NBIT_ATOMIC: + p.sizeof_datatype = parms[parms_index++]; + p.order = parms[parms_index++]; + p.precision = parms[parms_index++]; + p.offset = parms[parms_index++]; + H5Z_nbit_compress_one_atomic(data, data_offset + member_offset, + buffer, j, buf_len, p); + break; + case H5Z_NBIT_ARRAY: + H5Z_nbit_compress_one_array(data, data_offset + member_offset, + buffer, j, buf_len, parms); + break; + case H5Z_NBIT_COMPOUND: + H5Z_nbit_compress_one_compound(data, data_offset+member_offset, + buffer, j, buf_len, parms); + break; + } /* end switch */ + } +} + +void H5Z_nbit_compress(void *data, int d_nelmts, unsigned char *buffer, int *buffer_size, + const unsigned parms[]) +{ + /* i: index of data, j: index of buffer, + buf_len: number of bits to be filled in current byte */ + int i, j, buf_len, size; + parms_atomic p; + + /* initialize buffer to be zeros */ + for(j = 0; j < *buffer_size; j++) + buffer[j] = 0; + + /* initialization before the loop */ + j = 0; + buf_len = sizeof(unsigned char) * 8; + + switch(parms[1]) { + case H5Z_NBIT_ATOMIC: + /* set the index before goto function call */ + p.sizeof_datatype = parms[2]; + p.order = parms[3]; + p.precision = parms[4]; + p.offset = parms[5]; + + for(i = 0; i < d_nelmts; i++) { + H5Z_nbit_compress_one_atomic(data, i*p.sizeof_datatype, buffer, &j, &buf_len, p); + } + break; + case H5Z_NBIT_ARRAY: + size = parms[2]; + parms_index = 2; + for(i = 0; i < d_nelmts; i++) { + H5Z_nbit_compress_one_array(data, i*size, buffer, &j, &buf_len, parms); + parms_index = 2; + } + break; + case H5Z_NBIT_COMPOUND: + size = parms[2]; + parms_index = 2; + for(i = 0; i < d_nelmts; i++) { + H5Z_nbit_compress_one_compound(data, i*size, buffer, &j, &buf_len, parms); + parms_index = 2; + } + break; + } /* end switch */ + + *buffer_size = j + 1; /* sometimes is catually j, but to be safe */ +} +#endif /* H5_HAVE_FILTER_NZIP */ -- cgit v0.12