CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
hrydgard

CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!

GitHub Repository: hrydgard/ppsspp
Path: blob/master/ext/libzip/zip_algorithm_deflate.c
Views: 1401
1
/*
2
zip_algorithm_deflate.c -- deflate (de)compression routines
3
Copyright (C) 2017-2019 Dieter Baron and Thomas Klausner
4
5
This file is part of libzip, a library to manipulate ZIP archives.
6
The authors can be contacted at <[email protected]>
7
8
Redistribution and use in source and binary forms, with or without
9
modification, are permitted provided that the following conditions
10
are met:
11
1. Redistributions of source code must retain the above copyright
12
notice, this list of conditions and the following disclaimer.
13
2. Redistributions in binary form must reproduce the above copyright
14
notice, this list of conditions and the following disclaimer in
15
the documentation and/or other materials provided with the
16
distribution.
17
3. The names of the authors may not be used to endorse or promote
18
products derived from this software without specific prior
19
written permission.
20
21
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
22
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
23
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
25
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
27
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
29
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
30
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
31
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32
*/
33
34
#include "zipint.h"
35
36
#include <limits.h>
37
#include <stdlib.h>
38
#include <zlib.h>
39
40
struct ctx {
41
zip_error_t *error;
42
bool compress;
43
int compression_flags;
44
bool end_of_input;
45
z_stream zstr;
46
};
47
48
49
static void *
50
allocate(bool compress, int compression_flags, zip_error_t *error) {
51
struct ctx *ctx;
52
53
if ((ctx = (struct ctx *)malloc(sizeof(*ctx))) == NULL) {
54
zip_error_set(error, ZIP_ET_SYS, errno);
55
return NULL;
56
}
57
58
ctx->error = error;
59
ctx->compress = compress;
60
ctx->compression_flags = compression_flags;
61
if (ctx->compression_flags < 1 || ctx->compression_flags > 9) {
62
ctx->compression_flags = Z_BEST_COMPRESSION;
63
}
64
ctx->end_of_input = false;
65
66
ctx->zstr.zalloc = Z_NULL;
67
ctx->zstr.zfree = Z_NULL;
68
ctx->zstr.opaque = NULL;
69
70
return ctx;
71
}
72
73
74
static void *
75
compress_allocate(zip_uint16_t method, int compression_flags, zip_error_t *error) {
76
return allocate(true, compression_flags, error);
77
}
78
79
80
static void *
81
decompress_allocate(zip_uint16_t method, int compression_flags, zip_error_t *error) {
82
return allocate(false, compression_flags, error);
83
}
84
85
86
static void
87
deallocate(void *ud) {
88
struct ctx *ctx = (struct ctx *)ud;
89
90
free(ctx);
91
}
92
93
94
static zip_uint16_t
95
general_purpose_bit_flags(void *ud) {
96
struct ctx *ctx = (struct ctx *)ud;
97
98
if (!ctx->compress) {
99
return 0;
100
}
101
102
if (ctx->compression_flags < 3) {
103
return 2 << 1;
104
}
105
else if (ctx->compression_flags > 7) {
106
return 1 << 1;
107
}
108
return 0;
109
}
110
111
112
static bool
113
start(void *ud) {
114
struct ctx *ctx = (struct ctx *)ud;
115
int ret;
116
117
ctx->zstr.avail_in = 0;
118
ctx->zstr.next_in = NULL;
119
ctx->zstr.avail_out = 0;
120
ctx->zstr.next_out = NULL;
121
122
if (ctx->compress) {
123
/* negative value to tell zlib not to write a header */
124
ret = deflateInit2(&ctx->zstr, ctx->compression_flags, Z_DEFLATED, -MAX_WBITS, MAX_MEM_LEVEL, Z_DEFAULT_STRATEGY);
125
}
126
else {
127
ret = inflateInit2(&ctx->zstr, -MAX_WBITS);
128
}
129
130
if (ret != Z_OK) {
131
zip_error_set(ctx->error, ZIP_ER_ZLIB, ret);
132
return false;
133
}
134
135
136
return true;
137
}
138
139
140
static bool
141
end(void *ud) {
142
struct ctx *ctx = (struct ctx *)ud;
143
int err;
144
145
if (ctx->compress) {
146
err = deflateEnd(&ctx->zstr);
147
}
148
else {
149
err = inflateEnd(&ctx->zstr);
150
}
151
152
if (err != Z_OK) {
153
zip_error_set(ctx->error, ZIP_ER_ZLIB, err);
154
return false;
155
}
156
157
return true;
158
}
159
160
161
static bool
162
input(void *ud, zip_uint8_t *data, zip_uint64_t length) {
163
struct ctx *ctx = (struct ctx *)ud;
164
165
if (length > UINT_MAX || ctx->zstr.avail_in > 0) {
166
zip_error_set(ctx->error, ZIP_ER_INVAL, 0);
167
return false;
168
}
169
170
ctx->zstr.avail_in = (uInt)length;
171
ctx->zstr.next_in = (Bytef *)data;
172
173
return true;
174
}
175
176
177
static void
178
end_of_input(void *ud) {
179
struct ctx *ctx = (struct ctx *)ud;
180
181
ctx->end_of_input = true;
182
}
183
184
185
static zip_compression_status_t
186
process(void *ud, zip_uint8_t *data, zip_uint64_t *length) {
187
struct ctx *ctx = (struct ctx *)ud;
188
189
int ret;
190
191
ctx->zstr.avail_out = (uInt)ZIP_MIN(UINT_MAX, *length);
192
ctx->zstr.next_out = (Bytef *)data;
193
194
if (ctx->compress) {
195
ret = deflate(&ctx->zstr, ctx->end_of_input ? Z_FINISH : 0);
196
}
197
else {
198
ret = inflate(&ctx->zstr, Z_SYNC_FLUSH);
199
}
200
201
*length = *length - ctx->zstr.avail_out;
202
203
switch (ret) {
204
case Z_OK:
205
return ZIP_COMPRESSION_OK;
206
207
case Z_STREAM_END:
208
return ZIP_COMPRESSION_END;
209
210
case Z_BUF_ERROR:
211
if (ctx->zstr.avail_in == 0) {
212
return ZIP_COMPRESSION_NEED_DATA;
213
}
214
215
/* fallthrough */
216
217
default:
218
zip_error_set(ctx->error, ZIP_ER_ZLIB, ret);
219
return ZIP_COMPRESSION_ERROR;
220
}
221
}
222
223
/* clang-format off */
224
225
zip_compression_algorithm_t zip_algorithm_deflate_compress = {
226
compress_allocate,
227
deallocate,
228
general_purpose_bit_flags,
229
20,
230
start,
231
end,
232
input,
233
end_of_input,
234
process
235
};
236
237
238
zip_compression_algorithm_t zip_algorithm_deflate_decompress = {
239
decompress_allocate,
240
deallocate,
241
general_purpose_bit_flags,
242
20,
243
start,
244
end,
245
input,
246
end_of_input,
247
process
248
};
249
250
/* clang-format on */
251
252