diff options
Diffstat (limited to 'src/H5Zdeflate.c')
-rw-r--r-- | src/H5Zdeflate.c | 144 |
1 files changed, 144 insertions, 0 deletions
diff --git a/src/H5Zdeflate.c b/src/H5Zdeflate.c new file mode 100644 index 0000000..1d3928a --- /dev/null +++ b/src/H5Zdeflate.c @@ -0,0 +1,144 @@ +/* + * Copyright © 1999 NCSA + * All rights reserved. + * + * Programmer: Robb Matzke <matzke@llnl.gov> + * Friday, August 27, 1999 + */ +#include <H5private.h> +#include <H5Eprivate.h> +#include <H5MMprivate.h> +#include <H5Zprivate.h> + +#ifdef HAVE_ZLIB_H +# include <zlib.h> +#endif + +/* Interface initialization */ +#define PABLO_MASK H5Z_deflate_mask +#define INTERFACE_INIT NULL +static intn interface_initialize_g = 0; + + +/*------------------------------------------------------------------------- + * Function: H5Z_filter_deflate + * + * Purpose: + * + * Return: Success: + * + * Failure: + * + * Programmer: Robb Matzke + * Thursday, April 16, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +size_t +H5Z_filter_deflate (unsigned flags, size_t cd_nelmts, + const unsigned cd_values[], size_t nbytes, + size_t *buf_size, void **buf) +{ + size_t ret_value = 0; + void *outbuf = NULL; +#if defined(HAVE_COMPRESS2) + int aggression = 6; + int status; +#endif + + FUNC_ENTER (H5Z_filter_deflate, 0); + + /* Check arguments */ + if (cd_nelmts!=1 || cd_values[0]>9) { + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, 0, + "invalid deflate aggression level"); + } + +#if defined(HAVE_COMPRESS2) + aggression = cd_values[0]; + if (flags & H5Z_FLAG_REVERSE) { + /* Input; uncompress */ + z_stream z_strm; + size_t nalloc = *buf_size; + + if (NULL==(outbuf = H5MM_malloc(nalloc))) { + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, 0, + "memory allocation failed for deflate uncompression"); + } + HDmemset(&z_strm, 0, sizeof(z_strm)); + z_strm.next_in = *buf; + z_strm.avail_in = nbytes; + z_strm.next_out = outbuf; + z_strm.avail_out = nalloc; + if (Z_OK!=inflateInit(&z_strm)) { + HGOTO_ERROR(H5E_PLINE, H5E_CANTINIT, 0, "inflateInit() failed"); + } + while (1) { + status = inflate(&z_strm, Z_SYNC_FLUSH); + if (Z_STREAM_END==status) break; /*done*/ + if (Z_OK!=status) { + inflateEnd(&z_strm); + HGOTO_ERROR(H5E_PLINE, H5E_CANTINIT, 0, "inflate() failed"); + } + if (Z_OK==status && 0==z_strm.avail_out) { + nalloc *= 2; + if (NULL==(outbuf = H5MM_realloc(outbuf, nalloc))) { + inflateEnd(&z_strm); + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, 0, + "memory allocation failed for deflate " + "uncompression"); + } + z_strm.next_out = (char*)outbuf + z_strm.total_out; + z_strm.avail_out = nalloc - z_strm.total_out; + } + } + + H5MM_xfree(*buf); + *buf = outbuf; + outbuf = NULL; + *buf_size = nalloc; + ret_value = z_strm.total_out; + inflateEnd(&z_strm); + + } else { + /* + * Output; compress but fail if the result would be larger than the + * input. The library doesn't provide in-place compression, so we + * must allocate a separate buffer for the result. + */ + const Bytef *z_src = (const Bytef*)(*buf); + Bytef *z_dst; /*destination buffer */ + uLongf z_dst_nbytes = (uLongf)nbytes; + uLong z_src_nbytes = (uLong)nbytes; + + if (NULL==(z_dst=outbuf=H5MM_malloc(nbytes))) { + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, 0, + "unable to allocate deflate destination buffer"); + } + status = compress2 (z_dst, &z_dst_nbytes, z_src, z_src_nbytes, + aggression); + if (Z_BUF_ERROR==status) { + HGOTO_ERROR(H5E_PLINE, H5E_CANTINIT, 0, "overflow"); + } else if (Z_MEM_ERROR==status) { + HGOTO_ERROR (H5E_PLINE, H5E_CANTINIT, 0, "deflate memory error"); + } else if (Z_OK!=status) { + HGOTO_ERROR (H5E_PLINE, H5E_CANTINIT, 0, "deflate error"); + } else { + H5MM_xfree(*buf); + *buf = outbuf; + outbuf = NULL; + *buf_size = nbytes; + ret_value = z_dst_nbytes; + } + } +#else + HGOTO_ERROR (H5E_PLINE, H5E_UNSUPPORTED, 0, + "hdf5 was not compiled with zlib-1.0.2 or better"); +#endif + + done: + H5MM_xfree(outbuf); + FUNC_LEAVE (ret_value); +} |