13
#endif /* defined HAVE_BZ2_LIB */
15
size_t bzip2_deflate(unsigned int flags, size_t cd_nelmts,
16
const unsigned int cd_values[], size_t nbytes,
17
size_t *buf_size, void **buf);
20
int register_bzip2(char **version, char **date)
23
char *libver, *versionp, *datep, *sep;
25
#if H5_VERS_MAJOR == 1 && H5_VERS_MINOR < 7
27
H5Z_class_t filter_class = {
28
(H5Z_filter_t)(FILTER_BZIP2), /* filter_id */
29
"bzip2", /* comment */
30
NULL, /* can_apply_func */
31
NULL, /* set_local_func */
32
(H5Z_func_t)(bzip2_deflate) /* filter_func */
36
H5Z_class_t filter_class = {
37
H5Z_CLASS_T_VERS, /* H5Z_class_t version */
38
(H5Z_filter_t)(FILTER_BZIP2), /* filter_id */
39
1, 1, /* Encoding and decoding enabled */
40
"bzip2", /* comment */
41
NULL, /* can_apply_func */
42
NULL, /* set_local_func */
43
(H5Z_func_t)(bzip2_deflate) /* filter_func */
45
#endif /* if H5_VERSION < "1.7" */
47
/* Register the filter class for the bzip2 compressor. */
48
H5Zregister(&filter_class);
50
/* Get the library major version from the version string. */
51
libver = strdup(BZ2_bzlibVersion());
52
sep = strchr(libver, ',');
54
assert(*(sep + 1) == ' ');
57
datep = sep + 2; /* after the comma and a space */
59
*version = strdup(versionp);
60
*date = strdup(datep);
63
return 1; /* library is available */
66
return 0; /* library is not available */
67
#endif /* defined HAVE_BZ2_LIB */
72
size_t bzip2_deflate(unsigned int flags, size_t cd_nelmts,
73
const unsigned int cd_values[], size_t nbytes,
74
size_t *buf_size, void **buf)
78
size_t outbuflen, outdatalen;
81
if (flags & H5Z_FLAG_REVERSE) {
85
** This process is troublesome since the size of uncompressed data
86
** is unknown, so the low-level interface must be used.
87
** Data is decompressed to the output buffer (which is sized
88
** for the average case); if it gets full, its size is doubled
89
** and decompression continues. This avoids repeatedly trying to
90
** decompress the whole block, which could be really inefficient.
97
/* Prepare the output buffer. */
98
outbuflen = nbytes * 3 + 1; /* average bzip2 compression ratio is 3:1 */
99
outbuf = malloc(outbuflen);
100
if (outbuf == NULL) {
101
fprintf(stderr, "memory allocation failed for bzip2 decompression\n");
105
/* Use standard malloc()/free() for internal memory handling. */
106
stream.bzalloc = NULL;
107
stream.bzfree = NULL;
108
stream.opaque = NULL;
110
/* Start decompression. */
111
ret = BZ2_bzDecompressInit(&stream, 0, 0);
113
fprintf(stderr, "bzip2 decompression start failed with error %d\n", ret);
117
/* Feed data to the decompression process and get decompressed data. */
118
stream.next_out = outbuf;
119
stream.avail_out = outbuflen;
120
stream.next_in = *buf;
121
stream.avail_in = nbytes;
123
ret = BZ2_bzDecompress(&stream);
125
fprintf(stderr, "BUG: bzip2 decompression failed with error %d\n", ret);
129
if (ret != BZ_STREAM_END && stream.avail_out == 0) {
130
/* Grow the output buffer. */
131
newbuflen = outbuflen * 2;
132
newbuf = realloc(outbuf, newbuflen);
133
if (newbuf == NULL) {
134
fprintf(stderr, "memory allocation failed for bzip2 decompression\n");
137
stream.next_out = newbuf + outbuflen; /* half the new buffer behind */
138
stream.avail_out = outbuflen; /* half the new buffer ahead */
140
outbuflen = newbuflen;
142
} while (ret != BZ_STREAM_END);
144
/* End compression. */
145
outdatalen = stream.total_out_lo32;
146
ret = BZ2_bzDecompressEnd(&stream);
148
fprintf(stderr, "bzip2 compression end failed with error %d\n", ret);
156
** This is quite simple, since the size of compressed data in the worst
157
** case is known and it is not much bigger than the size of uncompressed
158
** data. This allows us to use the simplified one-shot interface to
162
int blockSize100k = 9;
164
/* Get compression block size if present. */
166
blockSize100k = cd_values[0];
167
if (blockSize100k < 1 || blockSize100k > 9) {
168
fprintf(stderr, "invalid compression block size: %d\n", blockSize100k);
173
/* Prepare the output buffer. */
174
outbuflen = nbytes + nbytes / 100 + 600; /* worst case (bzip2 docs) */
175
outbuf = malloc(outbuflen);
176
if (outbuf == NULL) {
177
fprintf(stderr, "memory allocation failed for bzip2 compression\n");
182
outdatalen = outbuflen;
183
ret = BZ2_bzBuffToBuffCompress(outbuf, &outdatalen, *buf, nbytes,
184
blockSize100k, 0, 0);
186
fprintf(stderr, "bzip2 compression failed with error %d\n", ret);
191
/* Always replace the input buffer with the output buffer. */
194
*buf_size = outbuflen;
203
#endif /* defined HAVE_BZ2_LIB */