diff options
-rw-r--r-- | src/H5Zszip.c | 212 |
1 files changed, 128 insertions, 84 deletions
diff --git a/src/H5Zszip.c b/src/H5Zszip.c index 0b58b17..b6e9972 100644 --- a/src/H5Zszip.c +++ b/src/H5Zszip.c @@ -1,14 +1,21 @@ -/* - * Copyright © 1999-2001 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" +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by the Board of Trustees of the University of Illinois. * + * All rights reserved. * + * * + * This file is part of HDF5. The full HDF5 copyright notice, including * + * terms governing use, modification, and redistribution, is contained in * + * the files COPYING and Copyright.html. COPYING can be found at the root * + * of the source code distribution tree; Copyright.html can be found at the * + * root level of an installed copy of the electronic HDF5 document set and * + * is linked from the top-level documents page. It can also be found at * + * http://hdf.ncsa.uiuc.edu/HDF5/doc/Copyright.html. If you do not have * + * access to either file, you may request a copy from hdfhelp@ncsa.uiuc.edu. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +#include "H5private.h" /* Generic Functions */ +#include "H5Eprivate.h" /* Error handling */ +#include "H5MMprivate.h" /* Memory management */ +#include "H5Zprivate.h" /* Data filters */ #ifdef H5_HAVE_FILTER_SZIP @@ -21,7 +28,6 @@ #define INTERFACE_INIT NULL static int interface_initialize_g = 0; - /*------------------------------------------------------------------------- * Function: H5Z_filter_szip @@ -29,94 +35,132 @@ static int interface_initialize_g = 0; * Purpose: Implement an I/O filter around the 'rice' algorithm in * libsz * - * Return: Success: - * - * Failure: + * Return: Success: Size of buffer filtered + * Failure: 0 * - * Programmer: Robb Matzke - * Thursday, April 16, 1998 + * Programmer: Kent Yang + * Tuesday, April 1, 2003 * * Modifications: + * Quincey Koziol, April 2, 2003 + * Cleaned up code. * *------------------------------------------------------------------------- */ size_t -H5Z_filter_szip (unsigned flags, - size_t cd_nelmts, - const unsigned cd_values[], - size_t nbytes, - size_t *buf_size, - void **buf) +H5Z_filter_szip (unsigned flags, size_t cd_nelmts, const unsigned cd_values[], + size_t nbytes, size_t *buf_size, void **buf) { + size_t ret_value = 0; /* Return value */ + size_t size_out = 0; /* Size of output buffer */ + unsigned char *outbuf = NULL; /* Pointer to new output buffer */ + unsigned char *newbuf = NULL; /* Pointer to input buffer */ + SZ_com_t sz_param; /* szip parameter block */ - size_t ret_value = 0; - size_t size_out = 0; - size_t size_in = 0; - char *outbuf = NULL; - char *newbuf = NULL; - int status; - SZ_com_t sz_param; - - sz_param.options_mask = cd_values[0]; - sz_param.bits_per_pixel = cd_values[1]; - sz_param.pixels_per_block = cd_values[2]; - sz_param.pixels_per_scanline = cd_values[3]; - - FUNC_ENTER_NOAPI(H5Z_filter_szip, 0); - - if (flags & H5Z_FLAG_REVERSE) { - /* Input; uncompress */ - - size_t nalloc; - - newbuf = *buf; - UINT32DECODE(newbuf,nalloc); + FUNC_ENTER_NOAPI(H5Z_filter_szip, 0); - size_out = nalloc; - size_in = nbytes; + /* Sanity check to make certain that we haven't drifted out of date with + * the mask options from the szlib.h header */ + assert(H5_SZIP_RAW_OPTION_MASK==SZ_RAW_OPTION_MASK); + assert(H5_SZIP_NN_OPTION_MASK==SZ_NN_OPTION_MASK); - if(NULL==(outbuf = H5MM_malloc(nalloc))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, 0, "memory allocation failed for szip decompression"); + /* Check arguments */ + if (cd_nelmts!=4) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, 0, "invalid deflate aggression level"); - status = SZ_BufftoBuffDecompress(outbuf, &size_out, newbuf, size_in-4, &sz_param); + /* Copy the filter parameters into the szip parameter block */ + sz_param.options_mask = cd_values[0]; + sz_param.bits_per_pixel = cd_values[1]; + sz_param.pixels_per_block = cd_values[2]; + sz_param.pixels_per_scanline = cd_values[3]; - if(status != SZ_OK) { - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, 0, "szip_filter: decompression failed"); + /* Input; uncompress */ + if (flags & H5Z_FLAG_REVERSE) { + uint32_t stored_nalloc; /* Number of bytes the compressed block will expand into */ + size_t nalloc; /* Number of bytes the compressed block will expand into */ + + /* Get the size of the uncompressed buffer */ + newbuf = *buf; + UINT32DECODE(newbuf,stored_nalloc); + H5_ASSIGN_OVERFLOW(nalloc,stored_nalloc,uint32_t,size_t); + + /* Check for uncompressed buffer */ + if(nalloc==0) { + /* Set the correct number of bytes to allocate */ + nalloc=nbytes-4; + + /* Allocate space for the uncompressed buffer */ + if(NULL==(outbuf = H5MM_malloc(nalloc))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, 0, "memory allocation failed for szip decompression"); + + /* Copy over the uncompressed data */ + HDmemcpy((void*)outbuf, (void*)newbuf, nalloc); + } /* end if */ + else { + /* Allocate space for the uncompressed buffer */ + if(NULL==(outbuf = H5MM_malloc(nalloc))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, 0, "memory allocation failed for szip decompression"); + + /* Decompress the buffer */ + size_out=nalloc; + if(SZ_BufftoBuffDecompress(outbuf, &size_out, newbuf, nbytes-4, &sz_param) != SZ_OK) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, 0, "szip_filter: decompression failed"); + assert(size_out==nalloc); + } /* end else */ + + /* Free the input buffer */ + H5MM_xfree(*buf); + + /* Set return values */ + *buf = outbuf; + outbuf = NULL; + *buf_size = nalloc; + ret_value = nalloc; } - - *buf = newbuf -4; - H5MM_xfree(*buf); - *buf = outbuf; - outbuf = NULL; - *buf_size = nalloc; - ret_value = size_out; - } - + /* Output; compress */ else { - - size_in = nbytes; - size_out = nbytes; - if(NULL==(outbuf = H5MM_malloc(size_out+4))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, 0, "unable to allocate szip destination buffer"); - - UINT32ENCODE(outbuf,nbytes); - status = SZ_BufftoBuffCompress(outbuf, &size_out, *buf, size_in, &sz_param); - if(SZ_OK!=status) - HGOTO_ERROR (H5E_PLINE, H5E_CANTINIT, 0, "szip_filter: Compression failed"); - - if(*buf) H5MM_xfree(*buf); - *buf = outbuf-4; - outbuf = NULL; - *buf_size = size_out+4; - ret_value = size_out+4; + unsigned char *dst = NULL; /* Temporary pointer to new output buffer */ + + /* Allocate space for the compressed buffer (assume it won't get bigger) */ + if(NULL==(dst=outbuf = H5MM_malloc(nbytes+4))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, 0, "unable to allocate szip destination buffer"); + + /* Compress the buffer */ + size_out = nbytes; + if(SZ_OK!= SZ_BufftoBuffCompress(outbuf+4, &size_out, *buf, nbytes, &sz_param)) { + /* In the event that an error occurs, assume that the buffer + * could not be compressed and just copy the input buffer to the + * proper location in the output buffer */ + /* (This is necessary for the szip filter due to the uncompressed + * size needing to be encoded for the decompression side of things) + */ + HDmemcpy((void*)(outbuf+4), (void*)(*buf), nbytes); + + /* Set correct output size (again) */ + size_out=nbytes; + + /* Reset the "nbytes" to encode, so that the decompression side knows that the buffer is uncompressed */ + nbytes=0; + } /* end if */ + + /* Encode the uncompressed length */ + H5_CHECK_OVERFLOW(nbytes,size_t,uint32_t); + UINT32ENCODE(dst,nbytes); + + /* Free the input buffer */ + H5MM_xfree(*buf); + + /* Set return values */ + *buf = outbuf; + outbuf = NULL; + *buf_size = size_out+4; + ret_value = size_out+4; } - done: - if(outbuf) H5MM_xfree(outbuf); +done: + if(outbuf) + H5MM_xfree(outbuf); FUNC_LEAVE_NOAPI(ret_value); - } - -#endif - +} +#endif /* H5_HAVE_FILTER_SZIP */ - |