forked from octalmage/robotjs
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathzlib_util.c
99 lines (81 loc) · 2.34 KB
/
zlib_util.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
#include "zlib_util.h"
#include <zlib.h>
#include <stdio.h> /* fprintf() */
#include <stdlib.h> /* malloc() */
#include <assert.h>
#define ZLIB_CHUNK (16 * 1024)
uint8_t *zlib_decompress(const uint8_t *buf, size_t *len)
{
size_t output_size = ZLIB_CHUNK;
uint8_t *output = malloc(output_size);
int err;
z_stream zst;
/* Sanity check */
if (output == NULL) return NULL;
assert(buf != NULL);
/* Set inflate state */
zst.zalloc = Z_NULL;
zst.zfree = Z_NULL;
zst.opaque = Z_NULL;
zst.next_out = (Byte *)output;
zst.next_in = (Byte *)buf;
zst.avail_out = ZLIB_CHUNK;
if (inflateInit(&zst) != Z_OK) goto error;
/* Decompress input buffer */
do {
if ((err = inflate(&zst, Z_NO_FLUSH)) == Z_OK) { /* Need more memory */
zst.avail_out = (uInt)output_size;
/* Double size each time to avoid calls to realloc() */
output_size <<= 1;
output = realloc(output, output_size + 1);
if (output == NULL) return NULL;
zst.next_out = (Byte *)(output + zst.avail_out);
} else if (err != Z_STREAM_END) { /* Error decompressing */
if (zst.msg != NULL) {
fprintf(stderr, "Could not decompress data: %s\n", zst.msg);
}
inflateEnd(&zst);
goto error;
}
} while (err != Z_STREAM_END);
if (len != NULL) *len = zst.total_out;
if (inflateEnd(&zst) != Z_OK) goto error;
return output; /* To be free()'d by caller */
error:
if (output != NULL) free(output);
return NULL;
}
uint8_t *zlib_compress(const uint8_t *buf, const size_t buflen, int level,
size_t *len)
{
z_stream zst;
uint8_t *output = NULL;
/* Sanity check */
assert(buf != NULL);
assert(len != NULL);
assert(level <= 9 && level >= 0);
zst.avail_out = (uInt)((buflen + (buflen / 10)) + 12);
output = malloc(zst.avail_out);
if (output == NULL) return NULL;
/* Set deflate state */
zst.zalloc = Z_NULL;
zst.zfree = Z_NULL;
zst.next_out = (Byte *)output;
zst.next_in = (Byte *)buf;
zst.avail_in = (uInt)buflen;
if (deflateInit(&zst, level) != Z_OK) goto error;
/* Compress input buffer */
if (deflate(&zst, Z_FINISH) != Z_STREAM_END) {
if (zst.msg != NULL) {
fprintf(stderr, "Could not compress data: %s\n", zst.msg);
}
deflateEnd(&zst);
goto error;
}
if (len != NULL) *len = zst.total_out;
if (deflateEnd(&zst) != Z_OK) goto error;
return output; /* To be free()'d by caller */
error:
if (output != NULL) free(output);
return NULL;
}