summaryrefslogtreecommitdiffstats
path: root/src/H5Zszip.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/H5Zszip.c')
-rw-r--r--src/H5Zszip.c189
1 files changed, 187 insertions, 2 deletions
diff --git a/src/H5Zszip.c b/src/H5Zszip.c
index b6e9972..1124d1e 100644
--- a/src/H5Zszip.c
+++ b/src/H5Zszip.c
@@ -12,10 +12,16 @@
* access to either file, you may request a copy from hdfhelp@ncsa.uiuc.edu. *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+#define H5Z_PACKAGE /*suppress error about including H5Zpkg */
+
#include "H5private.h" /* Generic Functions */
#include "H5Eprivate.h" /* Error handling */
+#include "H5Fprivate.h" /* File access */
#include "H5MMprivate.h" /* Memory management */
-#include "H5Zprivate.h" /* Data filters */
+#include "H5Oprivate.h" /* Object headers */
+#include "H5Ppublic.h" /* Property lists */
+#include "H5Tpublic.h" /* Datatype functions */
+#include "H5Zpkg.h" /* Data filters */
#ifdef H5_HAVE_FILTER_SZIP
@@ -28,6 +34,185 @@
#define INTERFACE_INIT NULL
static int interface_initialize_g = 0;
+/* Local function prototypes */
+static herr_t H5Z_can_apply_szip(hid_t dcpl_id, hid_t type_id, hid_t space_id);
+static herr_t H5Z_set_local_szip(hid_t dcpl_id, hid_t type_id, hid_t space_id);
+static size_t H5Z_filter_szip (unsigned flags, size_t cd_nelmts,
+ const unsigned cd_values[], size_t nbytes, size_t *buf_size, void **buf);
+
+/* This message derives from H5Z */
+const H5Z_class_t H5Z_SZIP[1] = {{
+ H5Z_FILTER_SZIP, /* Filter id number */
+ "szip", /* Filter name for debugging */
+ H5Z_can_apply_szip, /* The "can apply" callback */
+ H5Z_set_local_szip, /* The "set local" callback */
+ H5Z_filter_szip, /* The actual filter function */
+}};
+
+/* Local macros */
+#define H5Z_SZIP_USER_NPARMS 2 /* Number of parameters that users can set */
+#define H5Z_SZIP_TOTAL_NPARMS 4 /* Total number of parameters for filter */
+#define H5Z_SZIP_PARM_MASK 0 /* "User" parameter for option mask */
+#define H5Z_SZIP_PARM_PPB 1 /* "User" parameter for pixels-per-block */
+#define H5Z_SZIP_PARM_BPP 2 /* "Local" parameter for bits-per-pixel */
+#define H5Z_SZIP_PARM_PPS 3 /* "Local" parameter for pixels-per-scanline */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Z_can_apply_szip
+ *
+ * Purpose: Check the parameters for szip compression for validity and
+ * whether they fit a particular dataset.
+ *
+ * Note: This function currently range-checks for datatypes with
+ * 8-bit boundaries (8, 16, 24, etc.). It appears that the szip
+ * library can actually handle 1-24, 32 & 64 bit samples. If
+ * this becomes important, we should make the checks below more
+ * sophisticated and have them check for n-bit datatypes of the
+ * correct size, etc. - QAK
+ *
+ * Return: Success: Non-negative
+ * Failure: Negative
+ *
+ * Programmer: Quincey Koziol
+ * Monday, April 7, 2003
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5Z_can_apply_szip(hid_t dcpl_id, hid_t type_id, hid_t space_id)
+{
+ unsigned flags; /* Filter flags */
+ size_t cd_nelmts=H5Z_SZIP_USER_NPARMS; /* Number of filter parameters */
+ unsigned cd_values[H5Z_SZIP_TOTAL_NPARMS]; /* Filter parameters */
+ hsize_t dims[H5O_LAYOUT_NDIMS]; /* Dataspace (i.e. chunk) dimensions */
+ int dtype_size; /* Datatype's size (in bits) */
+ H5T_order_t dtype_order; /* Datatype's endianness order */
+ hsize_t scanline; /* Size of dataspace's fastest changing dimension */
+ herr_t ret_value=TRUE; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5Z_can_apply_szip, FAIL);
+
+ /* Get the filter's current parameters */
+ if(H5Pget_filter_by_id(dcpl_id,H5Z_FILTER_SZIP,&flags,&cd_nelmts, cd_values,0,NULL)<0)
+ HGOTO_ERROR(H5E_PLINE, H5E_CANTGET, FAIL, "can't get szip parameters");
+
+ /* Check that no parameters are currently set */
+ if(cd_nelmts!=H5Z_SZIP_USER_NPARMS)
+ HGOTO_ERROR(H5E_PLINE, H5E_BADVALUE, FAIL, "incorrect # of szip parameters");
+
+ /* Get datatype's size, for checking the "bits-per-pixel" */
+ if((dtype_size=(sizeof(unsigned char)*H5Tget_size(type_id)))==0)
+ HGOTO_ERROR(H5E_PLINE, H5E_BADTYPE, FAIL, "bad datatype size");
+
+ /* Range check datatype's size */
+ if(dtype_size>32 && dtype_size!=64)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FALSE, "invalid datatype 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");
+
+ /* 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 dimensions for dataspace */
+ if (H5Sget_simple_extent_dims(space_id, dims, NULL)<0)
+ HGOTO_ERROR(H5E_PLINE, H5E_CANTGET, FAIL, "unable to get dataspace dimensions");
+
+ /* Get "local" parameter for this dataset's "pixels-per-scanline" */
+ scanline=dims[0];
+
+ /* Range check the scanline's size */
+ if(scanline > SZ_MAX_PIXELS_PER_SCANLINE)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FALSE, "invalid scanline size");
+
+ /* Range check the scanline's number of blocks */
+ if((scanline/cd_values[H5Z_SZIP_PARM_PPB]) > SZ_MAX_BLOCKS_PER_SCANLINE)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FALSE, "invalid number of blocks per scanline");
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value);
+} /* end H5Z_can_apply_szip() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Z_set_local_szip
+ *
+ * Purpose: Set the "local" dataset parameters for szip compression.
+ *
+ * Return: Success: Non-negative
+ * Failure: Negative
+ *
+ * Programmer: Quincey Koziol
+ * Monday, April 7, 2003
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5Z_set_local_szip(hid_t dcpl_id, hid_t type_id, hid_t space_id)
+{
+ unsigned flags; /* Filter flags */
+ size_t cd_nelmts=H5Z_SZIP_USER_NPARMS; /* Number of filter parameters */
+ unsigned cd_values[H5Z_SZIP_TOTAL_NPARMS]; /* Filter parameters */
+ hsize_t dims[H5O_LAYOUT_NDIMS]; /* Dataspace (i.e. chunk) dimensions */
+ H5T_order_t dtype_order; /* Datatype's endianness order */
+ herr_t ret_value=SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5Z_set_local_szip, FAIL);
+
+ /* Get the filter's current parameters */
+ if(H5Pget_filter_by_id(dcpl_id,H5Z_FILTER_SZIP,&flags,&cd_nelmts, cd_values,0,NULL)<0)
+ HGOTO_ERROR(H5E_PLINE, H5E_CANTGET, FAIL, "can't get szip parameters");
+
+ /* Check that no parameters are currently set */
+ if(cd_nelmts!=H5Z_SZIP_USER_NPARMS)
+ HGOTO_ERROR(H5E_PLINE, H5E_BADVALUE, FAIL, "incorrect # of szip parameters");
+
+ /* Get dimensions for dataspace */
+ if (H5Sget_simple_extent_dims(space_id, dims, NULL)<0)
+ HGOTO_ERROR(H5E_PLINE, H5E_CANTGET, FAIL, "unable to get dataspace dimensions");
+
+ /* Set "local" parameter for this dataset's "bits-per-pixel" */
+ if((cd_values[H5Z_SZIP_PARM_BPP]=(sizeof(unsigned char)*H5Tget_size(type_id)))==0)
+ HGOTO_ERROR(H5E_PLINE, H5E_BADTYPE, FAIL, "bad datatype size");
+
+ /* Set "local" parameter for this dataset's "pixels-per-scanline" */
+ cd_values[H5Z_SZIP_PARM_PPS]=dims[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 the correct endianness flag for szip */
+ /* (Note: this may not handle non-atomic datatypes well) */
+ switch(dtype_order) {
+ case H5T_ORDER_LE: /* Little-endian byte order */
+ cd_values[H5Z_SZIP_PARM_MASK] |= SZ_LSB_OPTION_MASK;
+ break;
+
+ case H5T_ORDER_BE: /* Big-endian byte order */
+ cd_values[H5Z_SZIP_PARM_MASK] |= SZ_MSB_OPTION_MASK;
+ break;
+
+ default:
+ HGOTO_ERROR(H5E_PLINE, H5E_BADTYPE, FAIL, "bad datatype endianness order");
+ } /* end switch */
+
+ /* Modify the filter's parameters for this dataset */
+ if(H5Pmodify_filter(dcpl_id, H5Z_FILTER_SZIP, flags, H5Z_SZIP_TOTAL_NPARMS, cd_values)<0)
+ HGOTO_ERROR(H5E_PLINE, H5E_CANTSET, FAIL, "can't set local szip parameters");
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value);
+} /* end H5Z_set_local_szip() */
+
/*-------------------------------------------------------------------------
* Function: H5Z_filter_szip
@@ -47,7 +232,7 @@ static int interface_initialize_g = 0;
*
*-------------------------------------------------------------------------
*/
-size_t
+static size_t
H5Z_filter_szip (unsigned flags, size_t cd_nelmts, const unsigned cd_values[],
size_t nbytes, size_t *buf_size, void **buf)
{