v / vlib / compress / zlib / interop / zlib_ref.c
150 lines · 147 sloc · 3.27 KB · 83fd036a98cc7d2e91992898416169f47329240f
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{
8 FILE* f = fopen(p, "rb");
9 if (!f) return 1;
10 if (fseek(f, 0, SEEK_END) != 0)
11 {
12 fclose(f);
13 return 1;
14 }
15 long s = ftell(f);
16 if (s < 0)
17 {
18 fclose(f);
19 return 1;
20 }
21 if (fseek(f, 0, SEEK_SET) != 0)
22 {
23 fclose(f);
24 return 1;
25 }
26 *n = (size_t)s;
27 *o = *n ? (unsigned char*)malloc(*n) : NULL;
28 if (*n && !*o)
29 {
30 fclose(f);
31 return 1;
32 }
33 if (*n && fread(*o, 1, *n, f) != *n)
34 {
35 free(*o);
36 fclose(f);
37 return 1;
38 }
39 fclose(f);
40 return 0;
41}
42
43static int wf(const char* p, const unsigned char* b, size_t n)
44{
45 FILE* f = fopen(p, "wb");
46 if (!f) return 1;
47 if (n && fwrite(b, 1, n, f) != n)
48 {
49 fclose(f);
50 return 1;
51 }
52 fclose(f);
53 return 0;
54}
55
56int main(int argc, char** argv)
57{
58 static const unsigned char dummy = 0;
59 if (argc != 4)
60 {
61 fputs("usage: zlib_ref compress|decompress in out\n", stderr);
62 return 2;
63 }
64 unsigned char* in = NULL;
65 size_t in_n = 0;
66 if (rf(argv[2], &in, &in_n))
67 {
68 fputs("read error\n", stderr);
69 return 1;
70 }
71 const unsigned char* in_ptr = in_n ? in : &dummy;
72 if (strcmp(argv[1], "compress") == 0)
73 {
74 uLongf out_n = compressBound((uLong)in_n);
75 unsigned char* out = (unsigned char*)malloc(out_n ? out_n : 1);
76 if (!out)
77 {
78 free(in);
79 return 1;
80 }
81 if (compress2(out, &out_n, in_ptr, (uLong)in_n, Z_DEFAULT_COMPRESSION) != Z_OK)
82 {
83 fputs("compress2 failed\n", stderr);
84 free(in);
85 free(out);
86 return 1;
87 }
88 if (wf(argv[3], out, (size_t)out_n))
89 {
90 fputs("write error\n", stderr);
91 free(in);
92 free(out);
93 return 1;
94 }
95 free(out);
96 }
97 else if (strcmp(argv[1], "decompress") == 0)
98 {
99 uLongf out_n = in_n * 8 + 64;
100 if (out_n < 256) out_n = 256;
101 unsigned char* out = NULL;
102 int rc = Z_BUF_ERROR;
103 while (rc == Z_BUF_ERROR)
104 {
105 unsigned char* next = (unsigned char*)realloc(out, out_n);
106 if (!next)
107 {
108 free(in);
109 free(out);
110 return 1;
111 }
112 out = next;
113 uLongf cap = out_n;
114 rc = uncompress(out, &cap, in_ptr, (uLong)in_n);
115 if (rc == Z_OK)
116 {
117 out_n = cap;
118 break;
119 }
120 if (rc == Z_BUF_ERROR)
121 {
122 out_n *= 2;
123 if (out_n < 256) out_n = 256;
124 }
125 }
126 if (rc != Z_OK)
127 {
128 fputs("uncompress failed\n", stderr);
129 free(in);
130 free(out);
131 return 1;
132 }
133 if (wf(argv[3], out, (size_t)out_n))
134 {
135 fputs("write error\n", stderr);
136 free(in);
137 free(out);
138 return 1;
139 }
140 free(out);
141 }
142 else
143 {
144 fputs("unknown mode\n", stderr);
145 free(in);
146 return 2;
147 }
148 free(in);
149 return 0;
150}
151