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)
include_directories("${PROJECT_SOURCE_DIR}/blosc")
# dependencies
-find_package(HDF5 REQUIRED)
-include_directories(HDF5_INCLIDE_DIRS)
+if(MSVC)
+ # 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.
+ file(TO_CMAKE_PATH "$ENV{HDF5_DIR}" HDF5_HINT)
+ set(HDF5_DIR ${HDF5_HINT} CACHE STRING "Path to HDF5 CMake config directory.")
+ find_package(HDF5 REQUIRED HINTS ${HDF5_DIR})
+else(MSVC)
+ find_package(HDF5 REQUIRED)
+endif(MSVC)
+include_directories(${HDF5_INCLUDE_DIRS})
# targets
@@ -17,16 +28,26 @@ if(BUILD_STATIC)
add_library(blosc_filter_static ${SOURCES})
set_target_properties(
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})
endif(BUILD_STATIC)
+# have to copy blosc dlls for Visual Studio
+if(MSVC)
+ add_custom_command(
+ TARGET blosc_filter_shared
+ POST_BUILD
+ COMMAND ${CMAKE_COMMAND}
+ ARGS -E copy_if_different
+ "${PROJECT_BINARY_DIR}/blosc/\$\(Configuration\)/blosc.dll"
+ "${CMAKE_CURRENT_BINARY_DIR}/\$\(Configuration\)/blosc.dll")
+endif(MSVC)
# 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)
if(BUILD_STATIC)
install(
- TARGETS blosc_filter_shared DESTINATION lib COMPONENT HDF5_FILTER_DEV)
+ TARGETS blosc_filter_static DESTINATION lib COMPONENT HDF5_FILTER_DEV)
endif(BUILD_STATIC)
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
details).
+.. _`HDF5 filter plugin`: http://www.hdfgroup.org/HDF5/doc/Advanced/DynamicallyLoadedFilters/HDF5DynamicallyLoadedFilters.pdf
+
Compiling
=========
@@ -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 libblosch5plugin.so
+
+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.
+
+
+IMPORTANT WINDOWS NOTE
+======================
+
+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
+crashes.
+
+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
+crashing.
+
+
Acknowledgments
===============
This HDF5 filter interface and its example is based in the LZF interface
(http://h5py.alfven.org) by Andrew Collette.
+
+Dana Robinson made nice improvements on existing CMake files for
+Windows/MSVC.
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,
}
#if ( (BLOSC_VERSION_MAJOR <= 1) && (BLOSC_VERSION_MINOR < 5) )
- /* Select the correct compressor to use */
- if (compname != NULL)
- blosc_set_compressor(compname);
-
status = blosc_compress(clevel, doshuffle, typesize, nbytes,
*buf, outbuf, nbytes);
#else
@@ -281,7 +277,7 @@ size_t blosc_filter(unsigned flags, size_t cd_nelmts,
}
#if ( (BLOSC_VERSION_MAJOR <= 1) && (BLOSC_VERSION_MINOR < 5) )
- status = blosc_decompress(*buf, outbuf, outbuf_size);
+ status = blosc_decompress(*buf, outbuf, outbuf_size);
#else
/* 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
- http://blosc.pytables.org
+ http://blosc.org
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. */