12
#endif /* defined HAVE_BZ2_LIB */
14
int register_bzip2(void)
20
#if H5_VERS_MAJOR == 1 && H5_VERS_MINOR < 7
22
H5Z_class_t filter_class = {
23
(H5Z_filter_t)(FILTER_BZIP2), /* filter_id */
24
"bzip2", /* comment */
25
NULL, /* can_apply_func */
26
NULL, /* set_local_func */
27
(H5Z_func_t)(bzip2_deflate) /* filter_func */
31
H5Z_class_t filter_class = {
32
H5Z_CLASS_T_VERS, /* H5Z_class_t version */
33
(H5Z_filter_t)(FILTER_BZIP2), /* filter_id */
34
1, 1, /* Encoding and decoding enabled */
35
"bzip2", /* comment */
36
NULL, /* can_apply_func */
37
NULL, /* set_local_func */
38
(H5Z_func_t)(bzip2_deflate) /* filter_func */
40
#endif /* if H5_VERSION < "1.7" */
42
/* Register the filter class for the bzip2 compressor. */
43
H5Zregister(&filter_class);
45
/* Get the library major version from the version string. */
46
libver = strdup(BZ2_bzlibVersion());
47
dot = strchr(libver, '.');
52
return ret; /* library is available */
55
return 0; /* library is not available */
56
#endif /* defined HAVE_BZ2_LIB */
61
/* This routine will only be called if bzip2 is present. */
62
PyObject *getBZ2VersionInfo(void)
66
char *libver, *version, *date, *sep;
69
tuple = PyTuple_New(2);
72
/* Get library version and date from version string. */
73
libver = strdup(BZ2_bzlibVersion());
74
sep = strchr(libver, ',');
76
assert(*(sep + 1) == ' ');
79
date = sep + 2; /* after the comma and a space */
81
/* Once the version string from the library has been copied,
82
* no additional copy is needed. */
83
PyTuple_SetItem(tuple, 0, PyString_FromString(version)); /* no copy needed */
84
PyTuple_SetItem(tuple, 1, PyString_FromString(date)); /* no copy needed */
89
PyTuple_SetItem(tuple, 0, Py_None);
91
PyTuple_SetItem(tuple, 1, Py_None);
92
#endif /* defined HAVE_BZ2_LIB */
98
size_t bzip2_deflate(unsigned int flags, size_t cd_nelmts,
99
const unsigned int cd_values[], size_t nbytes,
100
size_t *buf_size, void **buf)
104
size_t outbuflen, outdatalen;
107
if (flags & H5Z_FLAG_REVERSE) {
111
** This process is troublesome since the size of uncompressed data
112
** is unknown, so the low-level interface must be used.
113
** Data is decompressed to the output buffer (which is sized
114
** for the average case); if it gets full, its size is doubled
115
** and decompression continues. This avoids repeatedly trying to
116
** decompress the whole block, which could be really inefficient.
123
/* Prepare the output buffer. */
124
outbuflen = nbytes * 3 + 1; /* average bzip2 compression ratio is 3:1 */
125
outbuf = malloc(outbuflen);
126
if (outbuf == NULL) {
127
fprintf(stderr, "memory allocation failed for bzip2 decompression\n");
131
/* Use standard malloc()/free() for internal memory handling. */
132
stream.bzalloc = NULL;
133
stream.bzfree = NULL;
134
stream.opaque = NULL;
136
/* Start decompression. */
137
ret = BZ2_bzDecompressInit(&stream, 0, 0);
139
fprintf(stderr, "bzip2 decompression start failed with error %d\n", ret);
143
/* Feed data to the decompression process and get decompressed data. */
144
stream.next_out = outbuf;
145
stream.avail_out = outbuflen;
146
stream.next_in = *buf;
147
stream.avail_in = nbytes;
149
ret = BZ2_bzDecompress(&stream);
151
fprintf(stderr, "BUG: bzip2 decompression failed with error %d\n", ret);
155
if (ret != BZ_STREAM_END && stream.avail_out == 0) {
156
/* Grow the output buffer. */
157
newbuflen = outbuflen * 2;
158
newbuf = realloc(outbuf, newbuflen);
159
if (newbuf == NULL) {
160
fprintf(stderr, "memory allocation failed for bzip2 decompression\n");
163
stream.next_out = newbuf + outbuflen; /* half the new buffer behind */
164
stream.avail_out = outbuflen; /* half the new buffer ahead */
166
outbuflen = newbuflen;
168
} while (ret != BZ_STREAM_END);
170
/* End compression. */
171
outdatalen = stream.total_out_lo32;
172
ret = BZ2_bzDecompressEnd(&stream);
174
fprintf(stderr, "bzip2 compression end failed with error %d\n", ret);
182
** This is quite simple, since the size of compressed data in the worst
183
** case is known and it is not much bigger than the size of uncompressed
184
** data. This allows us to use the simplified one-shot interface to
188
int blockSize100k = 9;
190
/* Get compression block size if present. */
192
blockSize100k = cd_values[0];
193
if (blockSize100k < 1 || blockSize100k > 9) {
194
fprintf(stderr, "invalid compression block size: %d\n", blockSize100k);
199
/* Prepare the output buffer. */
200
outbuflen = nbytes + nbytes / 100 + 600; /* worst case (bzip2 docs) */
201
outbuf = malloc(outbuflen);
202
if (outbuf == NULL) {
203
fprintf(stderr, "memory allocation failed for bzip2 compression\n");
208
outdatalen = outbuflen;
209
ret = BZ2_bzBuffToBuffCompress(outbuf, &outdatalen, *buf, nbytes,
210
blockSize100k, 0, 0);
212
fprintf(stderr, "bzip2 compression failed with error %d\n", ret);
217
/* Always replace the input buffer with the output buffer. */
220
*buf_size = outbuflen;
229
#endif /* defined HAVE_BZ2_LIB */