Blob Blame History Raw
diff --git a/c-blosc/hdf5/CMakeLists.txt b/c-blosc/hdf5/CMakeLists.txt
index d9cd847e89..d91194fcf7 100644
--- a/c-blosc/hdf5/CMakeLists.txt
+++ b/c-blosc/hdf5/CMakeLists.txt
@@ -4,8 +4,19 @@ set(SOURCES blosc_filter.c)
 # dependencies
-find_package(HDF5 REQUIRED)
+    # FindHDF5.cmake does not find Windows installations. Try to
+    # use an environment variable instead until the official "find"
+    # file can be updated for Windows.
+    #
+    # Note that you have to set this environment variable by hand.
+    set(HDF5_DIR ${HDF5_HINT} CACHE STRING "Path to HDF5 CMake config directory.")
+    find_package(HDF5 REQUIRED HINTS ${HDF5_DIR})
+    find_package(HDF5 REQUIRED)
 # targets
@@ -17,16 +28,26 @@ if(BUILD_STATIC)
     add_library(blosc_filter_static ${SOURCES})
         blosc_filter_static PROPERTIES OUTPUT_NAME blosc_filter)
-    target_link_libraries(blosc_filter_static blosc_static)
+    target_link_libraries(blosc_filter_static blosc_static ${HDF5_LIBRARIES})
+# have to copy blosc dlls for Visual Studio
+    add_custom_command(
+        TARGET      blosc_filter_shared
+        POST_BUILD
+        ARGS        -E copy_if_different
+                    "${PROJECT_BINARY_DIR}/blosc/\$\(Configuration\)/blosc.dll"
+                    "${CMAKE_CURRENT_BINARY_DIR}/\$\(Configuration\)/blosc.dll")
 # install
 install(FILES blosc_filter.h DESTINATION include COMPONENT HDF5_FILTER_DEV)
-install(TARGETS blosc_filter_static DESTINATION lib COMPONENT HDF5_FILTER)
+install(TARGETS blosc_filter_shared DESTINATION lib COMPONENT HDF5_FILTER)
-        TARGETS blosc_filter_shared DESTINATION lib COMPONENT HDF5_FILTER_DEV)
+        TARGETS blosc_filter_static DESTINATION lib COMPONENT HDF5_FILTER_DEV)
diff --git a/c-blosc/hdf5/README.rst b/c-blosc/hdf5/README.rst
index 15c6b35fc0..7aae585b2a 100644
--- a/c-blosc/hdf5/README.rst
+++ b/c-blosc/hdf5/README.rst
@@ -17,10 +17,16 @@ value is returned.
 An example C program ("example.c") is included which demonstrates the
 proper use of the filter.
+Alternatively, instead of registering the Blosc filter,  you can use the
+automatically detectable `HDF5 filter plugin`_ which is supported in HDF5
+1.8.11 and later.
 This filter has been tested against HDF5 versions 1.6.5 through
 1.8.10.  It is released under the MIT license (see LICENSE.txt for
+.. _`HDF5 filter plugin`:
@@ -50,13 +56,101 @@ Using Windows and MSVC (2008 or higher recommended):
 Intel ICC compilers should work too.
+On Windows, you'll need to copy hdf5.dll and possibly the msvc*.dll files
+to your filter's directory if you do not have HDF5 installed in your PATH.
 For activating the support for other compressors than the integrated
 BloscLZ (like LZ4, LZ4HC, Snappy or Zlib) see the README file in the
 main Blosc directory.
+Compiling dynamically loadable filter plugin
+Compile blosc_plugin.c and blosc_filter.c to a shared library and then
+let HDF5 know where to find it.
+To complie using GCC on UNIX:
+    gcc -O3 -msse2 -lhdf5 -lpthread ../blosc/*.c \
+        blosc_filter.c blosc_plugin.c -fPIC -shared \
+        -o
+Then ether move the shared library to HDF5's default search location for
+plugins (on UNIX ``/usr/local/hdf5/lib/plugin``) or to a directory pointed to
+by the ``HDF5_PLUGIN_PATH`` environment variable.
+On Windows, the configuration (Release vs. Debug) and Visual Studio version
+of HDF5 and the c-blosc filter must match EXACTLY or you will experience
+crashes. You should also ensure that the C run-time is dynamically linked
+to both HDF5 and c-blosc.
+This is due to the way Microsoft implements its C library. On Windows, the
+standard C library is not a fundamental part of the operating system, as it
+is on Unix-like systems. Instead, the C library is implemented in separate
+shared libraries (dlls - called the C run-time (CRT) by Microsoft), which
+differ by Visual Studio and configuration. For example, msvcr110d.dll is the
+Visual Studio 2012 debug C run-time and msvcr90.dll is the Visual Studio
+2008 release C run-time. Since there is no shared state between these
+independent libraries, allocating memory in one library and freeing it in
+another (as the c-blosc HDF5 filter does) will corrupt the heap and cause
+There is currently no way around this issue since a fix involves exposing
+the HDF5 library's memory management functions for filter author use, which
+would ensure that both the filter and HDF5 use the same allocation and
+free functions. The HDF Group is aware of the problem and hopes to have a
+fix in HDF5 1.8.15 (May 2015).
+To duplicate the problem
+* Install the HDF5 binary distribution. The HDF5 binaries are built in release mode (even though they include debugging symbols) and link to the release C run-time.
+* Configure and build c-blosc using the debug configuration. Ensure that CMake uses the installed release-configuration HDF5.
+* You may need to copy hdf5.dll and the msvc*.dll libraries to the filter's binary directory if the HDF5 bin directory is not in your PATH.
+* At this point, HDF5 will be using the release C run-time and c-blosc will be using the debug C run-time. You can confirm this using the Visual Studio tool 'dumpbin /imports'.
+* Run example.exe. It should crash.
+If you build the HDF5 library from source in the debug configuration,
+you can confirm that debug HDF5 and release c-blosc will also cause
+example.exe to fail.
+Note that the crashes may not be deterministic. Your mileage may vary.
+Regardless of the behavior on your particular system, this is a serious
+problem and will crash many, if not most, systems.
+To demonstrate proper behavior
+* Build c-blosc in the configuration that matches HDF5.
+* example.exe should now run normally.
+To confirm that it is a C run-time mismatch issue, you can modify the
+src/H5.c and src/H5public.h files in the HDF5 source distribution to
+expose the HDF5 library's allocator (H5free_memory() already exists).
+Simply copy and modify the H5free_memory() function to something like
+H5malloc() that wraps malloc(). You'll need to run 'bin/trace src/H5.c'
+in the source root to generate a TRACE macro for the new API call
+(requires Perl). Modify the filter to use H5malloc() and H5free_memory()
+in place of malloc() and free() and rebuild c-blosc. You will now be
+able to combine release and debug configurations without example.exe
 This HDF5 filter interface and its example is based in the LZF interface
 ( by Andrew Collette.
+Dana Robinson made nice improvements on existing CMake files for
diff --git a/c-blosc/hdf5/blosc_filter.c b/c-blosc/hdf5/blosc_filter.c
index aa3521545d..3ab5237365 100644
--- a/c-blosc/hdf5/blosc_filter.c
+++ b/c-blosc/hdf5/blosc_filter.c
@@ -105,7 +105,7 @@ herr_t blosc_set_local(hid_t dcpl, hid_t type, hid_t space){
     size_t nelements = 8;
     unsigned int values[] = {0,0,0,0,0,0,0,0};
     hid_t super_type;
-    H5T_class_t class;
+    H5T_class_t classt;
     r = GET_FILTER(dcpl, FILTER_BLOSC, &flags, &nelements, values, 0, NULL);
     if(r<0) return -1;
@@ -126,8 +126,8 @@ herr_t blosc_set_local(hid_t dcpl, hid_t type, hid_t space){
     typesize = H5Tget_size(type);
     if (typesize==0) return -1;
     /* Get the size of the base type, even for ARRAY types */
-    class = H5Tget_class(type);
-    if (class == H5T_ARRAY) {
+    classt = H5Tget_class(type);
+    if (classt == H5T_ARRAY) {
       /* Get the array base component */
       super_type = H5Tget_super(type);
       basetypesize = H5Tget_size(super_type);
@@ -175,7 +175,7 @@ size_t blosc_filter(unsigned flags, size_t cd_nelmts,
     int doshuffle = 1;             /* Shuffle default */
     int compcode;                  /* Blosc compressor */
     int code;
-    char *compname = NULL;
+    char *compname = "blosclz";    /* The compressor by default */
     char *complist;
     char errmsg[256];
@@ -234,10 +234,6 @@ size_t blosc_filter(unsigned flags, size_t cd_nelmts,
-	/* Select the correct compressor to use */
-        if (compname != NULL)
-	  blosc_set_compressor(compname);
         status = blosc_compress(clevel, doshuffle, typesize, nbytes,
                                 *buf, outbuf, nbytes);
@@ -281,7 +277,7 @@ size_t blosc_filter(unsigned flags, size_t cd_nelmts,
-        status = blosc_decompress(*buf, outbuf, outbuf_size);
+	status = blosc_decompress(*buf, outbuf, outbuf_size);
         /* Starting from Blosc 1.5 on, there is not an internal global
 	   lock anymore, so do not try to run in multithreading mode
diff --git a/c-blosc/hdf5/example.c b/c-blosc/hdf5/example.c
index 3b386e330d..d72b3fc7b8 100644
--- a/c-blosc/hdf5/example.c
+++ b/c-blosc/hdf5/example.c
@@ -1,6 +1,6 @@
     Copyright (C) 2010  Francesc Alted
     License: MIT (see LICENSE.txt)
     Example program demonstrating use of the Blosc filter from C code.
@@ -9,8 +9,7 @@
     To compile this program:
-    h5cc [-DH5_USE_16_API] -lblosc blosc_filter.c example.c \
-         -o example -lpthread
+    h5cc blosc_filter.c example.c -o example -lblosc -lpthread
     To run:
@@ -73,7 +72,7 @@ int main(){
     r = H5Pset_chunk(plist, 3, chunkshape);
     if(r<0) goto failed;
-    /* Using the blosc filter in combianation with other ones also works */
+    /* Using the blosc filter in combination with other ones also works */
     r = H5Pset_fletcher32(plist);
     if(r<0) goto failed;
@@ -81,7 +80,7 @@ int main(){
     /* This is the easiest way to call Blosc with default values: 5
      for BloscLZ and shuffle active. */
-    /* r = H5Pset_filter(plist, FILTER_BLOSC, H5Z_FLAG_OPTIONAL, 0, NULL);  */
+    /* r = H5Pset_filter(plist, FILTER_BLOSC, H5Z_FLAG_OPTIONAL, 0, NULL); */
     /* But you can also taylor Blosc parameters to your needs */
     /* 0 to 3 (inclusive) param slots are reserved. */