v2 / vlib / compress / deflate / interop / deflate_ref.c
135 lines · 128 sloc · 2.81 KB · 96c365159d037716a7097f6b02e4b4b82edd0a8a
Raw
1#include <stdio.h>
2#include <stdlib.h>
3#include <string.h>
4#include <zlib.h>
5
6static int rf(const char *p, unsigned char **o, size_t *n) {
7 FILE *f = fopen(p, "rb");
8 if (!f) return 1;
9 fseek(f, 0, SEEK_END);
10 long s = ftell(f);
11 fseek(f, 0, SEEK_SET);
12 *o = malloc(*n = (size_t)s);
13 if (!*o) {
14 fclose(f);
15 return 1;
16 }
17 if (fread(*o, 1, *n, f) != *n) {
18 free(*o);
19 fclose(f);
20 return 1;
21 }
22 fclose(f);
23 return 0;
24}
25
26static int wf(const char *p, const unsigned char *b, size_t n) {
27 FILE *f = fopen(p, "wb");
28 if (!f) return 1;
29 if (fwrite(b, 1, n, f) != n) {
30 fclose(f);
31 return 1;
32 }
33 fclose(f);
34 return 0;
35}
36
37int main(int argc, char **argv) {
38 if (argc != 4) {
39 fputs("usage: xval compress|decompress|gzip|gunzip in out\n", stderr);
40 return 2;
41 }
42 unsigned char *in;
43 size_t in_n;
44 if (rf(argv[2], &in, &in_n)) {
45 fputs("read error\n", stderr);
46 return 1;
47 }
48
49 if (strcmp(argv[1], "compress") == 0) {
50 uLongf cap = compressBound((uLong)in_n);
51 unsigned char *out = malloc(cap);
52 if (!out) return 1;
53 if (compress2(out, &cap, in, (uLong)in_n, Z_DEFAULT_COMPRESSION) != Z_OK) {
54 fputs("compress2 failed\n", stderr);
55 free(in);
56 free(out);
57 return 1;
58 }
59 wf(argv[3], out, (size_t)cap);
60 free(out);
61 } else if (strcmp(argv[1], "decompress") == 0) {
62 uLongf cap = in_n * 8 + 65536;
63 unsigned char *out = malloc(cap);
64 if (!out) return 1;
65 if (uncompress(out, &cap, in, (uLong)in_n) != Z_OK) {
66 fputs("uncompress failed\n", stderr);
67 free(in);
68 free(out);
69 return 1;
70 }
71 wf(argv[3], out, (size_t)cap);
72 free(out);
73 } else if (strcmp(argv[1], "gzip") == 0) {
74 z_stream s;
75 memset(&s, 0, sizeof(s));
76 if (deflateInit2(&s, Z_DEFAULT_COMPRESSION, Z_DEFLATED, 15 | 16, 8, Z_DEFAULT_STRATEGY) != Z_OK) {
77 free(in);
78 return 1;
79 }
80 uLongf cap = deflateBound(&s, (uLong)in_n) + 32;
81 unsigned char *out = malloc(cap);
82 if (!out) {
83 deflateEnd(&s);
84 free(in);
85 return 1;
86 }
87 s.next_in = in;
88 s.avail_in = (uInt)in_n;
89 s.next_out = out;
90 s.avail_out = (uInt)cap;
91 if (deflate(&s, Z_FINISH) != Z_STREAM_END) {
92 fputs("gzip deflate failed\n", stderr);
93 deflateEnd(&s);
94 free(in);
95 free(out);
96 return 1;
97 }
98 wf(argv[3], out, (size_t)s.total_out);
99 deflateEnd(&s);
100 free(out);
101 } else if (strcmp(argv[1], "gunzip") == 0) {
102 z_stream s;
103 memset(&s, 0, sizeof(s));
104 if (inflateInit2(&s, 15 | 16) != Z_OK) {
105 free(in);
106 return 1;
107 }
108 uLongf cap = in_n * 8 + 65536;
109 unsigned char *out = malloc(cap);
110 if (!out) {
111 inflateEnd(&s);
112 free(in);
113 return 1;
114 }
115 s.next_in = in;
116 s.avail_in = (uInt)in_n;
117 s.next_out = out;
118 s.avail_out = (uInt)cap;
119 if (inflate(&s, Z_FINISH) != Z_STREAM_END) {
120 fputs("gunzip inflate failed\n", stderr);
121 inflateEnd(&s);
122 free(in);
123 free(out);
124 return 1;
125 }
126 wf(argv[3], out, (size_t)s.total_out);
127 inflateEnd(&s);
128 free(out);
129 }
130
131 free(in);
132 return 0;
133}
134
135
136