And here's the change to H5Z-blosc (still using the private H5MM APIs):

diff --git a/src/blosc_filter.c b/src/blosc_filter.c
index bfd8c3e..9bc1a42 100644
--- a/src/blosc_filter.c
+++ b/src/blosc_filter.c
@@ -16,6 +16,7 @@
 #include <string.h>
 #include <errno.h>
 #include "hdf5.h"
+#include "H5MMprivate.h"
 #include "blosc_filter.h"

 #if defined(__GNUC__)
@@ -194,20 +195,21 @@ size_t blosc_filter(unsigned flags, size_t cd_nelmts,
   /* We're compressing */
   if (!(flags & H5Z_FLAG_REVERSE)) {

-    /* Allocate an output buffer exactly as long as the input data; if
-       the result is larger, we simply return 0.  The filter is flagged
-       as optional, so HDF5 marks the chunk as uncompressed and
-       proceeds.
+    /* Allocate an output buffer BLOSC_MAX_OVERHEAD (currently 16) bytes
+       larger than the input data, to accommodate the BLOSC header.
+       If compression with the requested parameters causes the data itself
+       to grow (thereby causing the compressed data, with header, to exceed
+       the output buffer size), fall back to memcpy mode (clevel=0).
     */

-    outbuf_size = (*buf_size);
+    outbuf_size = nbytes + BLOSC_MAX_OVERHEAD;

 #ifdef BLOSC_DEBUG
     fprintf(stderr, "Blosc: Compress %zd chunk w/buffer %zd\n",
     nbytes, outbuf_size);
 #endif

-    outbuf = malloc(outbuf_size);
+    outbuf = H5MM_malloc(outbuf_size);

     if (outbuf == NULL) {
       PUSH_ERR("blosc_filter", H5E_CALLBACK,
@@ -217,7 +219,11 @@ size_t blosc_filter(unsigned flags, size_t cd_nelmts,

     blosc_set_compressor(compname);
     status = blosc_compress(clevel, doshuffle, typesize, nbytes,
-                            *buf, outbuf, nbytes);
+                            *buf, outbuf, outbuf_size);
+    if (status < 0) {
+      status = blosc_compress(0, doshuffle, typesize, nbytes,
+                              *buf, outbuf, outbuf_size);
+    }
     if (status < 0) {
       PUSH_ERR("blosc_filter", H5E_CALLBACK, "Blosc compression error");
       goto failed;
@@ -228,7 +234,7 @@ size_t blosc_filter(unsigned flags, size_t cd_nelmts,
     /* declare dummy variables */
     size_t cbytes, blocksize;

-    free(outbuf);
+    H5MM_xfree(outbuf);

     /* Extract the exact outbuf_size from the buffer header.
      *
@@ -243,7 +249,14 @@ size_t blosc_filter(unsigned flags, size_t cd_nelmts,
     fprintf(stderr, "Blosc: Decompress %zd chunk w/buffer %zd\n",
nbytes, outbuf_size);
 #endif

-    outbuf = malloc(outbuf_size);
+    if (outbuf_size == 0) {
+      H5MM_xfree(*buf);
+      *buf = NULL;
+      *buf_size = outbuf_size;
+      return 0;  /* Size of compressed/decompressed data */
+    }
+
+    outbuf = H5MM_malloc(outbuf_size);

     if (outbuf == NULL) {
       PUSH_ERR("blosc_filter", H5E_CALLBACK, "Can't allocate
decompression buffer");
@@ -259,14 +272,14 @@ size_t blosc_filter(unsigned flags, size_t cd_nelmts,
   } /* compressing vs decompressing */

   if (status != 0) {
-    free(*buf);
+    H5MM_xfree(*buf);
     *buf = outbuf;
     *buf_size = outbuf_size;
     return status;  /* Size of compressed/decompressed data */
   }

   failed:
-  free(outbuf);
+  H5MM_xfree(outbuf);
   return 0;

 } /* End filter function */

On Thu, Nov 9, 2017 at 2:45 PM, Jordan Henderson
<jhender...@hdfgroup.org> wrote:
> As the filtered collective path simply calls through the filter pipeline by
> way of the H5Z_pipeline() function, it would seem that either the filter
> pipeline itself is not handling this case correctly, or this is somewhat
> unexpected behavior for the pipeline to deal with.
>
>
> Either way, I think a pull request/diff file would be very useful for going
> over this. If you're able to generate a diff between what you have now and
> the current develop branch/H5Z-blosc code and put it here that would be
> useful. I don't think that there should be too much in the way of logistics
> for getting this code in, we just want to make sure that we approach the
> solution in the right way without breaking something else.

_______________________________________________
Hdf-forum is for HDF software users discussion.
Hdf-forum@lists.hdfgroup.org
http://lists.hdfgroup.org/mailman/listinfo/hdf-forum_lists.hdfgroup.org
Twitter: https://twitter.com/hdf5

Reply via email to