diff options
Diffstat (limited to 'src/H5Zdeflate.c')
-rw-r--r-- | src/H5Zdeflate.c | 77 |
1 files changed, 56 insertions, 21 deletions
diff --git a/src/H5Zdeflate.c b/src/H5Zdeflate.c index d94185f..144c873 100644 --- a/src/H5Zdeflate.c +++ b/src/H5Zdeflate.c @@ -16,10 +16,11 @@ * Programmer: Robb Matzke <matzke@llnl.gov> * Friday, August 27, 1999 */ -#include "H5private.h" -#include "H5Eprivate.h" -#include "H5MMprivate.h" -#include "H5Zprivate.h" + +#include "H5private.h" /* Generic Functions */ +#include "H5Eprivate.h" /* Error handling */ +#include "H5MMprivate.h" /* Memory management */ +#include "H5Zprivate.h" /* Data filters */ #ifdef H5_HAVE_FILTER_DEFLATE @@ -41,9 +42,8 @@ static int interface_initialize_g = 0; * Purpose: Implement an I/O filter around the 'deflate' algorithm in * libz * - * Return: Success: - * - * Failure: + * Return: Success: Size of buffer filtered + * Failure: 0 * * Programmer: Robb Matzke * Thursday, April 16, 1998 @@ -57,10 +57,9 @@ 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; - int aggression = 6; - int status; + void *outbuf = NULL; /* Pointer to new buffer */ + int status; /* Status from zlib operation */ + size_t ret_value; /* Return value */ FUNC_ENTER_NOAPI(H5Z_filter_deflate, 0); @@ -68,68 +67,104 @@ H5Z_filter_deflate (unsigned flags, size_t cd_nelmts, if (cd_nelmts!=1 || cd_values[0]>9) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, 0, "invalid deflate aggression level"); - aggression = cd_values[0]; if (flags & H5Z_FLAG_REVERSE) { /* Input; uncompress */ - z_stream z_strm; - size_t nalloc = *buf_size; + z_stream z_strm; /* zlib parameters */ + size_t nalloc = *buf_size; /* Number of bytes for output (compressed) buffer */ + /* Allocate space for the compressed buffer */ if (NULL==(outbuf = H5MM_malloc(nalloc))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, 0, "memory allocation failed for deflate uncompression"); + + /* Set the uncompression parameters */ HDmemset(&z_strm, 0, sizeof(z_strm)); z_strm.next_in = *buf; H5_ASSIGN_OVERFLOW(z_strm.avail_in,nbytes,size_t,uInt); z_strm.next_out = outbuf; H5_ASSIGN_OVERFLOW(z_strm.avail_out,nalloc,size_t,uInt); + + /* Initialize the uncompression routines */ if (Z_OK!=inflateInit(&z_strm)) HGOTO_ERROR(H5E_PLINE, H5E_CANTINIT, 0, "inflateInit() failed"); + + /* Loop to uncompress the buffer */ while (1) { + /* Uncompress some data */ status = inflate(&z_strm, Z_SYNC_FLUSH); + + /* Check if we are done uncompressing data */ if (Z_STREAM_END==status) break; /*done*/ + + /* Check for error */ if (Z_OK!=status) { inflateEnd(&z_strm); HGOTO_ERROR(H5E_PLINE, H5E_CANTINIT, 0, "inflate() failed"); } + + /* If we're not done and just ran out of buffer space, get more */ if (Z_OK==status && 0==z_strm.avail_out) { + /* Allocate a buffer twice as big */ 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"); } + + /* Update pointers to buffer for next set of uncompressed data */ z_strm.next_out = (unsigned char*)outbuf + z_strm.total_out; z_strm.avail_out = (uInt)(nalloc - z_strm.total_out); } } + /* Free the input buffer */ H5MM_xfree(*buf); + + /* Set return values */ *buf = outbuf; outbuf = NULL; *buf_size = nalloc; ret_value = z_strm.total_out; + + /* Finish uncompressing the stream */ inflateEnd(&z_strm); - } else { + } + 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)H5Z_DEFLATE_SIZE_ADJUST(nbytes); - uLong z_src_nbytes = (uLong)nbytes; + const Bytef *z_src = (const Bytef*)(*buf); + Bytef *z_dst; /*destination buffer */ + uLongf z_dst_nbytes = (uLongf)H5Z_DEFLATE_SIZE_ADJUST(nbytes); + uLong z_src_nbytes = (uLong)nbytes; + int aggression; /* Compression aggression setting */ + /* Set the compression aggression level */ + aggression = cd_values[0]; + + /* Allocate output (compressed) buffer */ if (NULL==(z_dst=outbuf=H5MM_malloc(z_dst_nbytes))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, 0, "unable to allocate deflate destination buffer"); + + /* Perform compression from the source to the destination buffer */ status = compress2 (z_dst, &z_dst_nbytes, z_src, z_src_nbytes, aggression); + + /* Check for various zlib errors */ 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, "other deflate error"); - } else { + } + /* Successfully uncompressed the buffer */ + else { + /* Free the input buffer */ H5MM_xfree(*buf); + + /* Set return values */ *buf = outbuf; outbuf = NULL; *buf_size = nbytes; @@ -142,5 +177,5 @@ done: H5MM_xfree(outbuf); FUNC_LEAVE_NOAPI(ret_value); } - #endif /* H5_HAVE_FILTER_DEFLATE */ + |