summaryrefslogtreecommitdiffstats
path: root/src/H5Ocomp.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/H5Ocomp.c')
-rw-r--r--src/H5Ocomp.c380
1 files changed, 258 insertions, 122 deletions
diff --git a/src/H5Ocomp.c b/src/H5Ocomp.c
index 3f341ea..a30eb6f 100644
--- a/src/H5Ocomp.c
+++ b/src/H5Ocomp.c
@@ -5,48 +5,49 @@
* Programmer: Robb Matzke <matzke@llnl.gov>
* Wednesday, April 15, 1998
*
- * Purpose: Data compression message.
+ * Purpose: Data filter pipeline message.
*/
#include <H5private.h>
#include <H5Eprivate.h>
#include <H5MMprivate.h>
#include <H5Oprivate.h>
-#define PABLO_MASK H5O_comp_mask
+/* Interface initialization */
+#define PABLO_MASK H5O_pline_mask
+static hbool_t interface_initialize_g = FALSE;
+#define INTERFACE_INIT NULL
-/* PRIVATE PROTOTYPES */
-static herr_t H5O_comp_encode (H5F_t *f, uint8 *p, const void *mesg);
-static void *H5O_comp_decode (H5F_t *f, const uint8 *p, H5O_shared_t *sh);
-static void *H5O_comp_copy (const void *_mesg, void *_dest);
-static size_t H5O_comp_size (H5F_t *f, const void *_mesg);
-static herr_t H5O_comp_reset (void *_mesg);
-static herr_t H5O_comp_debug (H5F_t *f, const void *_mesg,
- FILE * stream, intn indent, intn fwidth);
+#define H5O_PLINE_VERSION 1
+
+static herr_t H5O_pline_encode (H5F_t *f, uint8 *p, const void *mesg);
+static void *H5O_pline_decode (H5F_t *f, const uint8 *p, H5O_shared_t *sh);
+static void *H5O_pline_copy (const void *_mesg, void *_dest);
+static size_t H5O_pline_size (H5F_t *f, const void *_mesg);
+static herr_t H5O_pline_reset (void *_mesg);
+static herr_t H5O_pline_debug (H5F_t *f, const void *_mesg,
+ FILE * stream, intn indent, intn fwidth);
/* This message derives from H5O */
-const H5O_class_t H5O_COMPRESS[1] = {{
- H5O_COMPRESS_ID, /* message id number */
- "compression", /* message name for debugging */
- sizeof(H5O_compress_t), /* native message size */
- H5O_comp_decode, /* decode message */
- H5O_comp_encode, /* encode message */
- H5O_comp_copy, /* copy the native value */
- H5O_comp_size, /* size of raw message */
- H5O_comp_reset, /* reset method */
+const H5O_class_t H5O_PLINE[1] = {{
+ H5O_PLINE_ID, /* message id number */
+ "filter pipeline", /* message name for debugging */
+ sizeof(H5O_pline_t), /* native message size */
+ H5O_pline_decode, /* decode message */
+ H5O_pline_encode, /* encode message */
+ H5O_pline_copy, /* copy the native value */
+ H5O_pline_size, /* size of raw message */
+ H5O_pline_reset, /* reset method */
NULL, /* get share method */
NULL, /* set share method */
- H5O_comp_debug, /* debug the message */
+ H5O_pline_debug, /* debug the message */
}};
-/* Interface initialization */
-static hbool_t interface_initialize_g = FALSE;
-#define INTERFACE_INIT NULL
/*-------------------------------------------------------------------------
- * Function: H5O_comp_decode
+ * Function: H5O_pline_decode
*
- * Purpose: Decodes a compression message.
+ * Purpose: Decodes a filter pipeline message.
*
* Return: Success: Ptr to the native message.
*
@@ -60,46 +61,97 @@ static hbool_t interface_initialize_g = FALSE;
*-------------------------------------------------------------------------
*/
static void *
-H5O_comp_decode(H5F_t __unused__ *f, const uint8 *p,
+H5O_pline_decode(H5F_t __unused__ *f, const uint8 *p,
H5O_shared_t __unused__ *sh)
{
- H5O_compress_t *comp = NULL;
+ H5O_pline_t *pline = NULL;
void *ret_value = NULL;
+ uintn version;
+ size_t i, j, n, name_length;
- FUNC_ENTER(H5O_comp_decode, NULL);
+ FUNC_ENTER(H5O_pline_decode, NULL);
/* check args */
assert(p);
/* Decode */
- if (NULL==(comp = H5MM_calloc(sizeof *comp))) {
+ if (NULL==(pline = H5MM_calloc(sizeof *pline))) {
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL,
"memory allocation failed");
}
- comp->method = *p++;
- comp->flags = *p++;
- UINT16DECODE (p, comp->cd_size);
-
- if (comp->cd_size>0) {
- if (NULL==(comp->client_data = H5MM_malloc (comp->cd_size))) {
- HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL,
- "memory allocation failed");
+ version = *p++;
+ if (version!=H5O_PLINE_VERSION) {
+ HGOTO_ERROR(H5E_PLINE, H5E_CANTLOAD, NULL,
+ "bad version number for filter pipeline message");
+ }
+ pline->nfilters = *p++;
+ if (pline->nfilters>32) {
+ HGOTO_ERROR(H5E_PLINE, H5E_CANTLOAD, NULL,
+ "filter pipeline message has too many filters");
+ }
+ p += 6; /*reserved*/
+ pline->nalloc = pline->nfilters;
+ pline->filter = H5MM_calloc(pline->nalloc*sizeof(pline->filter[0]));
+ if (NULL==pline->filter) {
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL,
+ "memory allocation failed");
+ }
+ for (i=0; i<pline->nfilters; i++) {
+ UINT16DECODE(p, pline->filter[i].id);
+ UINT16DECODE(p, name_length);
+ if (name_length % 8) {
+ HGOTO_ERROR(H5E_PLINE, H5E_CANTLOAD, NULL,
+ "filter name length is not a multiple of eight");
+ }
+ UINT16DECODE(p, pline->filter[i].flags);
+ UINT16DECODE(p, pline->filter[i].cd_nelmts);
+ if (name_length) {
+ /*
+ * Get the name, allocating an extra byte for an extra null
+ * terminator just in case there isn't one in the file (there
+ * should be, but to be safe...)
+ */
+ pline->filter[i].name = H5MM_malloc(name_length+1);
+ memcpy(pline->filter[i].name, p, name_length);
+ pline->filter[i].name[name_length] = '\0';
+ p += name_length;
+ }
+ if ((n=pline->filter[i].cd_nelmts)) {
+ /*
+ * Read the client data values and the padding
+ */
+ pline->filter[i].cd_values = H5MM_malloc(n*sizeof(uintn));
+ if (NULL==pline->filter[i].cd_values) {
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL,
+ "memory allocation failed for client data");
+ }
+ for (j=0; j<pline->filter[i].cd_nelmts; j++) {
+ UINT32DECODE(p, pline->filter[i].cd_values[j]);
+ }
+ if (pline->filter[i].cd_nelmts % 2) {
+ p += 4; /*padding*/
+ }
}
- HDmemcpy (comp->client_data, p, comp->cd_size);
}
- ret_value = comp;
+ ret_value = pline;
done:
- if (NULL==ret_value && comp) {
- H5MM_xfree (comp->client_data);
- H5MM_xfree (comp);
+ if (NULL==ret_value && pline) {
+ if (pline->filter) {
+ for (i=0; i<pline->nfilters; i++) {
+ H5MM_xfree(pline->filter[i].name);
+ H5MM_xfree(pline->filter[i].cd_values);
+ }
+ H5MM_xfree(pline->filter);
+ }
+ H5MM_xfree(pline);
}
FUNC_LEAVE(ret_value);
}
/*-------------------------------------------------------------------------
- * Function: H5O_comp_encode
+ * Function: H5O_pline_encode
*
* Purpose: Encodes message MESG into buffer P.
*
@@ -115,21 +167,47 @@ H5O_comp_decode(H5F_t __unused__ *f, const uint8 *p,
*-------------------------------------------------------------------------
*/
static herr_t
-H5O_comp_encode (H5F_t __unused__ *f, uint8 *p/*out*/, const void *mesg)
+H5O_pline_encode (H5F_t __unused__ *f, uint8 *p/*out*/, const void *mesg)
{
- const H5O_compress_t *comp = (const H5O_compress_t*)mesg;
+ const H5O_pline_t *pline = (const H5O_pline_t*)mesg;
+ size_t i, j, name_length;
- FUNC_ENTER (H5O_comp_encode, FAIL);
+ FUNC_ENTER (H5O_pline_encode, FAIL);
/* Check args */
assert (p);
assert (mesg);
- *p++ = comp->method;
- *p++ = comp->flags;
- UINT16ENCODE (p, comp->cd_size);
- if (comp->cd_size) {
- HDmemcpy (p, comp->client_data, comp->cd_size);
+ *p++ = H5O_PLINE_VERSION;
+ *p++ = pline->nfilters;
+ *p++ = 0; /*reserved 1*/
+ *p++ = 0; /*reserved 2*/
+ *p++ = 0; /*reserved 3*/
+ *p++ = 0; /*reserved 4*/
+ *p++ = 0; /*reserved 5*/
+ *p++ = 0; /*reserved 6*/
+
+ for (i=0; i<pline->nfilters; i++) {
+ if (pline->filter[i].name) {
+ name_length = strlen(pline->filter[i].name)+1;
+ } else {
+ name_length = 0;
+ }
+ UINT16ENCODE(p, pline->filter[i].id);
+ UINT16ENCODE(p, H5O_ALIGN(name_length));
+ UINT16ENCODE(p, pline->filter[i].flags);
+ UINT16ENCODE(p, pline->filter[i].cd_nelmts);
+ if (name_length>0) {
+ memcpy(p, pline->filter[i].name, name_length);
+ p += name_length;
+ while (name_length++ % 8) *p++ = 0;
+ }
+ for (j=0; j<pline->filter[i].cd_nelmts; j++) {
+ UINT32ENCODE(p, pline->filter[i].cd_values[j]);
+ }
+ if (pline->filter[i].cd_nelmts % 2) {
+ UINT32ENCODE(p, 0);
+ }
}
FUNC_LEAVE (SUCCEED);
@@ -137,10 +215,10 @@ H5O_comp_encode (H5F_t __unused__ *f, uint8 *p/*out*/, const void *mesg)
/*-------------------------------------------------------------------------
- * Function: H5O_comp_copy
+ * Function: H5O_pline_copy
*
- * Purpose: Copies a compression message from SRC to DST allocating DST
- * if necessary. If DST is already allocated then we assume
+ * Purpose: Copies a filter pipeline message from SRC to DST allocating
+ * DST if necessary. If DST is already allocated then we assume
* that it isn't initialized.
*
* Return: Success: Ptr to DST or allocated result.
@@ -155,34 +233,70 @@ H5O_comp_encode (H5F_t __unused__ *f, uint8 *p/*out*/, const void *mesg)
*-------------------------------------------------------------------------
*/
static void *
-H5O_comp_copy (const void *_src, void *_dst/*out*/)
+H5O_pline_copy (const void *_src, void *_dst/*out*/)
{
- const H5O_compress_t *src = (const H5O_compress_t *)_src;
- H5O_compress_t *dst = (H5O_compress_t *)_dst;
+ const H5O_pline_t *src = (const H5O_pline_t *)_src;
+ H5O_pline_t *dst = (H5O_pline_t *)_dst;
+ size_t i;
+ H5O_pline_t *ret_value = NULL;
- FUNC_ENTER (H5O_comp_copy, NULL);
+ FUNC_ENTER (H5O_pline_copy, NULL);
if (!dst && NULL==(dst = H5MM_malloc (sizeof *dst))) {
HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL,
"memory allocation failed");
}
+
*dst = *src;
- if (src->cd_size>0) {
- if (NULL==(dst->client_data = H5MM_malloc (src->cd_size))) {
- HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL,
- "memory allocation failed");
+ dst->nalloc = dst->nfilters;
+ if (dst->nalloc>0) {
+ dst->filter = H5MM_calloc(dst->nalloc * sizeof(dst->filter[0]));
+ if (NULL==dst->filter) {
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL,
+ "memory allocation failed");
+ }
+ } else {
+ dst->filter = NULL;
+ }
+
+ for (i=0; i<src->nfilters; i++) {
+ dst->filter[i] = src->filter[i];
+ if (src->filter[i].name) {
+ dst->filter[i].name = H5MM_xstrdup(src->filter[i].name);
+ }
+ if (src->filter[i].cd_nelmts>0) {
+ dst->filter[i].cd_values = H5MM_malloc(src->filter[i].cd_nelmts*
+ sizeof(uintn));
+ if (NULL==dst->filter[i].cd_values) {
+ HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL,
+ "memory allocation failed");
+ }
+ HDmemcpy (dst->filter[i].cd_values, src->filter[i].cd_values,
+ src->filter[i].cd_nelmts * sizeof(uintn));
}
- HDmemcpy (dst->client_data, src->client_data, src->cd_size);
}
+ ret_value = dst;
- FUNC_LEAVE (dst);
+ done:
+ if (!ret_value && dst) {
+ if (dst->filter) {
+ for (i=0; i<dst->nfilters; i++) {
+ H5MM_xfree(dst->filter[i].name);
+ H5MM_xfree(dst->filter[i].cd_values);
+ }
+ H5MM_xfree(dst->filter);
+ }
+ if (!_dst) H5MM_xfree(dst);
+ }
+
+ FUNC_LEAVE (ret_value);
}
/*-------------------------------------------------------------------------
- * Function: H5O_comp_size
+ * Function: H5O_pline_size
*
- * Purpose: Determines the size of a raw compression message.
+ * Purpose: Determines the size of a raw filter pipeline message.
*
* Return: Success: Size of message.
*
@@ -196,20 +310,39 @@ H5O_comp_copy (const void *_src, void *_dst/*out*/)
*-------------------------------------------------------------------------
*/
static size_t
-H5O_comp_size (H5F_t __unused__ *f, const void *mesg)
+H5O_pline_size (H5F_t __unused__ *f, const void *mesg)
{
- const H5O_compress_t *comp = (const H5O_compress_t*)mesg;
-
- FUNC_ENTER (H5O_comp_size, 0);
- FUNC_LEAVE (4+comp->cd_size);
+ const H5O_pline_t *pline = (const H5O_pline_t*)mesg;
+ size_t i, size;
+
+ FUNC_ENTER (H5O_pline_size, 0);
+
+ size = 1 + /*version */
+ 1 + /*number of filters */
+ 6; /*reserved */
+
+ for (i=0; i<pline->nfilters; i++) {
+ size += 2 + /*filter identification number */
+ 2 + /*name length */
+ 2 + /*flags */
+ 2; /*number of client data values */
+ if (pline->filter[i].name) {
+ size_t n = strlen(pline->filter[i].name) + 1;
+ size += H5O_ALIGN(n);
+ }
+ size += pline->filter[i].cd_nelmts * 4;
+ if (pline->filter[i].cd_nelmts % 2) size += 4;
+ }
+
+ FUNC_LEAVE (size);
}
/*-------------------------------------------------------------------------
- * Function: H5O_comp_reset
+ * Function: H5O_pline_reset
*
- * Purpose: Resets a compression message by freeing the client data and
- * setting all fields to zero. The MESG buffer is not freed.
+ * Purpose: Resets a filter pipeline message by clearing all filters.
+ * The MESG buffer is not freed.
*
* Return: Success: SUCCEED
*
@@ -223,25 +356,30 @@ H5O_comp_size (H5F_t __unused__ *f, const void *mesg)
*-------------------------------------------------------------------------
*/
static herr_t
-H5O_comp_reset (void *mesg)
+H5O_pline_reset (void *mesg)
{
- H5O_compress_t *comp = (H5O_compress_t*)mesg;
+ H5O_pline_t *pline = (H5O_pline_t*)mesg;
+ size_t i;
- FUNC_ENTER (H5O_comp_reset, FAIL);
+ FUNC_ENTER (H5O_pline_reset, FAIL);
- assert (comp);
- H5MM_xfree (comp->client_data);
- HDmemset (comp, 0, sizeof *comp);
+ assert (pline);
+ for (i=0; i<pline->nfilters; i++) {
+ H5MM_xfree(pline->filter[i].name);
+ H5MM_xfree(pline->filter[i].cd_values);
+ }
+ H5MM_xfree(pline->filter);
+ HDmemset(pline, 0, sizeof *pline);
FUNC_LEAVE (SUCCEED);
}
/*-------------------------------------------------------------------------
- * Function: H5O_comp_debug
+ * Function: H5O_pline_debug
*
- * Purpose: Prints debugging information for compression message MESG on
- * output stream STREAM. Each line is indented INDENT
+ * Purpose: Prints debugging information for filter pipeline message MESG
+ * on output stream STREAM. Each line is indented INDENT
* characters and the field name takes up FWIDTH characters.
*
* Return: Success: SUCCEED
@@ -256,56 +394,54 @@ H5O_comp_reset (void *mesg)
*-------------------------------------------------------------------------
*/
static herr_t
-H5O_comp_debug (H5F_t __unused__ *f, const void *mesg, FILE *stream,
+H5O_pline_debug (H5F_t __unused__ *f, const void *mesg, FILE *stream,
intn indent, intn fwidth)
{
- const H5O_compress_t *comp = (const H5O_compress_t *)mesg;
- size_t i, j;
+ const H5O_pline_t *pline = (const H5O_pline_t *)mesg;
+ size_t i, j;
- FUNC_ENTER(H5O_comp_debug, FAIL);
+ FUNC_ENTER(H5O_pline_debug, FAIL);
/* check args */
assert(f);
- assert(comp);
+ assert(pline);
assert(stream);
assert(indent >= 0);
assert(fwidth >= 0);
- fprintf (stream, "%*s%-*s %d\n", indent, "", fwidth,
- "Method:",
- (int)(comp->method));
- fprintf (stream, "%*s%-*s 0x%02x\n", indent, "", fwidth,
- "Flags:",
- (unsigned)(comp->flags));
- fprintf (stream, "%*s%-*s %lu\n", indent, "", fwidth,
- "Size of client data:",
- (unsigned long)(comp->cd_size));
-
- if (comp->cd_size>0) {
- fprintf (stream, "%*s%s\n", indent, "", "Client Data:");
- for (i=0; i<comp->cd_size; i+=16) {
- fprintf (stream, "%*s%04d: ", indent+3, "", i);
- for (j=0; j<16; j++) {
- if (8==j) putc (' ', stream);
- if (i+j<comp->cd_size) {
- fprintf (stream, "%02x ", comp->client_data[i+j]);
- } else {
- fputs (" ", stream);
- }
- }
- for (j=0; j<16 && i+j<comp->cd_size; j++) {
- if (8==j) putc (' ', stream);
- if (comp->client_data[i+j]>' ' &&
- comp->client_data[i+j]<='~') {
- putc (comp->client_data[i+j], stream);
- } else {
- putc ('.', stream);
- }
- putc ('\n', stream);
- }
+ fprintf(stream, "%*s%-*s %lu/%lu\n", indent, "", fwidth,
+ "Number of filters:",
+ (unsigned long)(pline->nfilters),
+ (unsigned long)(pline->nalloc));
+
+ for (i=0; i<pline->nfilters; i++) {
+ char name[32];
+ sprintf(name, "Filter at position %lu", (unsigned long)i);
+ fprintf(stream, "%*s%-*s\n", indent, "", fwidth, name);
+ fprintf(stream, "%*s%-*s 0x%04x\n", indent+3, "", MAX(0, fwidth-3),
+ "Filter identification:",
+ (unsigned)(pline->filter[i].id));
+ if (pline->filter[i].name) {
+ fprintf(stream, "%*s%-*s \"%s\"\n", indent+3, "", MAX(0, fwidth-3),
+ "Filter name:",
+ pline->filter[i].name);
+ } else {
+ fprintf(stream, "%*s%-*s NONE\n", indent+3, "", MAX(0, fwidth-3),
+ "Filter name:");
+ }
+ fprintf(stream, "%*s%-*s 0x%04x\n", indent+3, "", MAX(0, fwidth-3),
+ "Flags:",
+ (unsigned)(pline->filter[i].flags));
+ fprintf(stream, "%*s%-*s %lu\n", indent+3, "", MAX(0, fwidth-3),
+ "Num CD values:",
+ (unsigned long)(pline->filter[i].cd_nelmts));
+ for (j=0; j<pline->filter[i].cd_nelmts; j++) {
+ char field_name[32];
+ sprintf(field_name, "CD value %d", j);
+ fprintf(stream, "%*s%-*s %lu\n", indent+6, "", MAX(0, fwidth-6),
+ field_name,
+ (unsigned long)(pline->filter[i].cd_values[j]));
}
- } else {
- fprintf (stream, "%*s%-*s None\n", indent, "", fwidth, "Client Data:");
}
FUNC_LEAVE(SUCCEED);