]>
Commit | Line | Data |
---|---|---|
11fdf7f2 | 1 | /* |
f67539c2 | 2 | * Copyright (c) 2016-2020, Przemyslaw Skibinski, Yann Collet, Facebook, Inc. |
7c673cae FG |
3 | * All rights reserved. |
4 | * | |
11fdf7f2 TL |
5 | * This source code is licensed under both the BSD-style license (found in the |
6 | * LICENSE file in the root directory of this source tree) and the GPLv2 (found | |
7 | * in the COPYING file in the root directory of this source tree). | |
8 | * You may select, at your option, one of the above-listed licenses. | |
7c673cae FG |
9 | */ |
10 | ||
11 | ||
11fdf7f2 TL |
12 | /* === Tuning parameters === */ |
13 | #ifndef ZWRAP_USE_ZSTD | |
14 | #define ZWRAP_USE_ZSTD 0 | |
15 | #endif | |
16 | ||
17 | ||
18 | /* === Dependencies === */ | |
19 | #include <stdlib.h> | |
7c673cae FG |
20 | #include <stdio.h> /* vsprintf */ |
21 | #include <stdarg.h> /* va_list, for z_gzprintf */ | |
22 | #define NO_DUMMY_DECL | |
23 | #define ZLIB_CONST | |
24 | #include <zlib.h> /* without #define Z_PREFIX */ | |
25 | #include "zstd_zlibwrapper.h" | |
11fdf7f2 | 26 | #define ZSTD_STATIC_LINKING_ONLY /* ZSTD_isFrame, ZSTD_MAGICNUMBER */ |
7c673cae | 27 | #include "zstd.h" |
11fdf7f2 | 28 | #include "zstd_internal.h" /* ZSTD_malloc, ZSTD_free */ |
7c673cae FG |
29 | |
30 | ||
11fdf7f2 | 31 | /* === Constants === */ |
7c673cae FG |
32 | #define Z_INFLATE_SYNC 8 |
33 | #define ZLIB_HEADERSIZE 4 | |
f67539c2 | 34 | #define ZSTD_HEADERSIZE ZSTD_FRAMEHEADERSIZE_MIN(ZSTD_f_zstd1) |
7c673cae FG |
35 | #define ZWRAP_DEFAULT_CLEVEL 3 /* Z_DEFAULT_COMPRESSION is translated to ZWRAP_DEFAULT_CLEVEL for zstd */ |
36 | ||
11fdf7f2 TL |
37 | |
38 | /* === Debug === */ | |
39 | #define LOG_WRAPPERC(...) /* fprintf(stderr, __VA_ARGS__) */ | |
40 | #define LOG_WRAPPERD(...) /* fprintf(stderr, __VA_ARGS__) */ | |
7c673cae FG |
41 | |
42 | #define FINISH_WITH_GZ_ERR(msg) { (void)msg; return Z_STREAM_ERROR; } | |
43 | #define FINISH_WITH_NULL_ERR(msg) { (void)msg; return NULL; } | |
44 | ||
45 | ||
11fdf7f2 TL |
46 | /* === Wrapper === */ |
47 | static int g_ZWRAP_useZSTDcompression = ZWRAP_USE_ZSTD; /* 0 = don't use ZSTD */ | |
7c673cae FG |
48 | |
49 | void ZWRAP_useZSTDcompression(int turn_on) { g_ZWRAP_useZSTDcompression = turn_on; } | |
50 | ||
51 | int ZWRAP_isUsingZSTDcompression(void) { return g_ZWRAP_useZSTDcompression; } | |
52 | ||
53 | ||
54 | ||
55 | static ZWRAP_decompress_type g_ZWRAPdecompressionType = ZWRAP_AUTO; | |
56 | ||
f67539c2 | 57 | void ZWRAP_setDecompressionType(ZWRAP_decompress_type type) { g_ZWRAPdecompressionType = type; } |
7c673cae FG |
58 | |
59 | ZWRAP_decompress_type ZWRAP_getDecompressionType(void) { return g_ZWRAPdecompressionType; } | |
60 | ||
61 | ||
62 | ||
63 | const char * zstdVersion(void) { return ZSTD_VERSION_STRING; } | |
64 | ||
65 | ZEXTERN const char * ZEXPORT z_zlibVersion OF((void)) { return zlibVersion(); } | |
66 | ||
67 | ||
68 | ||
69 | static void* ZWRAP_allocFunction(void* opaque, size_t size) | |
70 | { | |
71 | z_streamp strm = (z_streamp) opaque; | |
11fdf7f2 TL |
72 | void* address = strm->zalloc(strm->opaque, 1, (uInt)size); |
73 | /* LOG_WRAPPERC("ZWRAP alloc %p, %d \n", address, (int)size); */ | |
7c673cae FG |
74 | return address; |
75 | } | |
76 | ||
77 | static void ZWRAP_freeFunction(void* opaque, void* address) | |
78 | { | |
79 | z_streamp strm = (z_streamp) opaque; | |
80 | strm->zfree(strm->opaque, address); | |
11fdf7f2 | 81 | /* if (address) LOG_WRAPPERC("ZWRAP free %p \n", address); */ |
7c673cae FG |
82 | } |
83 | ||
84 | ||
85 | ||
11fdf7f2 | 86 | /* === Compression === */ |
7c673cae FG |
87 | typedef enum { ZWRAP_useInit, ZWRAP_useReset, ZWRAP_streamEnd } ZWRAP_state_t; |
88 | ||
89 | typedef struct { | |
90 | ZSTD_CStream* zbc; | |
91 | int compressionLevel; | |
11fdf7f2 TL |
92 | int streamEnd; /* a flag to signal the end of a stream */ |
93 | unsigned long long totalInBytes; /* we need it as strm->total_in can be reset by user */ | |
7c673cae FG |
94 | ZSTD_customMem customMem; |
95 | z_stream allocFunc; /* copy of zalloc, zfree, opaque */ | |
96 | ZSTD_inBuffer inBuffer; | |
97 | ZSTD_outBuffer outBuffer; | |
98 | ZWRAP_state_t comprState; | |
99 | unsigned long long pledgedSrcSize; | |
100 | } ZWRAP_CCtx; | |
101 | ||
f67539c2 | 102 | /* typedef ZWRAP_CCtx internal_state; */ |
7c673cae FG |
103 | |
104 | ||
105 | ||
11fdf7f2 | 106 | static size_t ZWRAP_freeCCtx(ZWRAP_CCtx* zwc) |
7c673cae FG |
107 | { |
108 | if (zwc==NULL) return 0; /* support free on NULL */ | |
11fdf7f2 TL |
109 | ZSTD_freeCStream(zwc->zbc); |
110 | ZSTD_free(zwc, zwc->customMem); | |
7c673cae FG |
111 | return 0; |
112 | } | |
113 | ||
114 | ||
11fdf7f2 | 115 | static ZWRAP_CCtx* ZWRAP_createCCtx(z_streamp strm) |
7c673cae FG |
116 | { |
117 | ZWRAP_CCtx* zwc; | |
118 | ||
119 | if (strm->zalloc && strm->zfree) { | |
120 | zwc = (ZWRAP_CCtx*)strm->zalloc(strm->opaque, 1, sizeof(ZWRAP_CCtx)); | |
121 | if (zwc==NULL) return NULL; | |
122 | memset(zwc, 0, sizeof(ZWRAP_CCtx)); | |
123 | memcpy(&zwc->allocFunc, strm, sizeof(z_stream)); | |
f67539c2 TL |
124 | { ZSTD_customMem ZWRAP_customMem = { ZWRAP_allocFunction, ZWRAP_freeFunction, NULL }; |
125 | ZWRAP_customMem.opaque = &zwc->allocFunc; | |
126 | zwc->customMem = ZWRAP_customMem; | |
127 | } | |
7c673cae | 128 | } else { |
11fdf7f2 | 129 | zwc = (ZWRAP_CCtx*)calloc(1, sizeof(*zwc)); |
7c673cae | 130 | if (zwc==NULL) return NULL; |
7c673cae FG |
131 | } |
132 | ||
133 | return zwc; | |
134 | } | |
135 | ||
136 | ||
11fdf7f2 | 137 | static int ZWRAP_initializeCStream(ZWRAP_CCtx* zwc, const void* dict, size_t dictSize, unsigned long long pledgedSrcSize) |
7c673cae FG |
138 | { |
139 | LOG_WRAPPERC("- ZWRAP_initializeCStream=%p\n", zwc); | |
140 | if (zwc == NULL || zwc->zbc == NULL) return Z_STREAM_ERROR; | |
11fdf7f2 | 141 | |
7c673cae | 142 | if (!pledgedSrcSize) pledgedSrcSize = zwc->pledgedSrcSize; |
11fdf7f2 TL |
143 | { ZSTD_parameters const params = ZSTD_getParams(zwc->compressionLevel, pledgedSrcSize, dictSize); |
144 | size_t initErr; | |
9f95a23c TL |
145 | LOG_WRAPPERC("pledgedSrcSize=%d windowLog=%d chainLog=%d hashLog=%d searchLog=%d minMatch=%d strategy=%d\n", |
146 | (int)pledgedSrcSize, params.cParams.windowLog, params.cParams.chainLog, params.cParams.hashLog, params.cParams.searchLog, params.cParams.minMatch, params.cParams.strategy); | |
11fdf7f2 TL |
147 | initErr = ZSTD_initCStream_advanced(zwc->zbc, dict, dictSize, params, pledgedSrcSize); |
148 | if (ZSTD_isError(initErr)) return Z_STREAM_ERROR; | |
149 | } | |
7c673cae FG |
150 | |
151 | return Z_OK; | |
152 | } | |
153 | ||
154 | ||
11fdf7f2 | 155 | static int ZWRAPC_finishWithError(ZWRAP_CCtx* zwc, z_streamp strm, int error) |
7c673cae FG |
156 | { |
157 | LOG_WRAPPERC("- ZWRAPC_finishWithError=%d\n", error); | |
158 | if (zwc) ZWRAP_freeCCtx(zwc); | |
159 | if (strm) strm->state = NULL; | |
160 | return (error) ? error : Z_STREAM_ERROR; | |
161 | } | |
162 | ||
163 | ||
11fdf7f2 | 164 | static int ZWRAPC_finishWithErrorMsg(z_streamp strm, char* message) |
7c673cae FG |
165 | { |
166 | ZWRAP_CCtx* zwc = (ZWRAP_CCtx*) strm->state; | |
167 | strm->msg = message; | |
168 | if (zwc == NULL) return Z_STREAM_ERROR; | |
11fdf7f2 | 169 | |
7c673cae FG |
170 | return ZWRAPC_finishWithError(zwc, strm, 0); |
171 | } | |
172 | ||
173 | ||
174 | int ZWRAP_setPledgedSrcSize(z_streamp strm, unsigned long long pledgedSrcSize) | |
175 | { | |
176 | ZWRAP_CCtx* zwc = (ZWRAP_CCtx*) strm->state; | |
177 | if (zwc == NULL) return Z_STREAM_ERROR; | |
11fdf7f2 | 178 | |
7c673cae FG |
179 | zwc->pledgedSrcSize = pledgedSrcSize; |
180 | zwc->comprState = ZWRAP_useInit; | |
181 | return Z_OK; | |
182 | } | |
183 | ||
184 | ||
185 | ZEXTERN int ZEXPORT z_deflateInit_ OF((z_streamp strm, int level, | |
186 | const char *version, int stream_size)) | |
187 | { | |
188 | ZWRAP_CCtx* zwc; | |
189 | ||
190 | LOG_WRAPPERC("- deflateInit level=%d\n", level); | |
191 | if (!g_ZWRAP_useZSTDcompression) { | |
192 | return deflateInit_((strm), (level), version, stream_size); | |
193 | } | |
194 | ||
195 | zwc = ZWRAP_createCCtx(strm); | |
196 | if (zwc == NULL) return Z_MEM_ERROR; | |
197 | ||
198 | if (level == Z_DEFAULT_COMPRESSION) | |
199 | level = ZWRAP_DEFAULT_CLEVEL; | |
200 | ||
201 | zwc->streamEnd = 0; | |
11fdf7f2 | 202 | zwc->totalInBytes = 0; |
7c673cae FG |
203 | zwc->compressionLevel = level; |
204 | strm->state = (struct internal_state*) zwc; /* use state which in not used by user */ | |
205 | strm->total_in = 0; | |
206 | strm->total_out = 0; | |
207 | strm->adler = 0; | |
208 | return Z_OK; | |
209 | } | |
210 | ||
211 | ||
212 | ZEXTERN int ZEXPORT z_deflateInit2_ OF((z_streamp strm, int level, int method, | |
213 | int windowBits, int memLevel, | |
214 | int strategy, const char *version, | |
215 | int stream_size)) | |
216 | { | |
217 | if (!g_ZWRAP_useZSTDcompression) | |
218 | return deflateInit2_(strm, level, method, windowBits, memLevel, strategy, version, stream_size); | |
219 | ||
220 | return z_deflateInit_ (strm, level, version, stream_size); | |
221 | } | |
222 | ||
223 | ||
224 | int ZWRAP_deflateReset_keepDict(z_streamp strm) | |
225 | { | |
226 | LOG_WRAPPERC("- ZWRAP_deflateReset_keepDict\n"); | |
227 | if (!g_ZWRAP_useZSTDcompression) | |
228 | return deflateReset(strm); | |
229 | ||
230 | { ZWRAP_CCtx* zwc = (ZWRAP_CCtx*) strm->state; | |
11fdf7f2 TL |
231 | if (zwc) { |
232 | zwc->streamEnd = 0; | |
233 | zwc->totalInBytes = 0; | |
234 | } | |
7c673cae FG |
235 | } |
236 | ||
237 | strm->total_in = 0; | |
238 | strm->total_out = 0; | |
239 | strm->adler = 0; | |
240 | return Z_OK; | |
241 | } | |
242 | ||
243 | ||
244 | ZEXTERN int ZEXPORT z_deflateReset OF((z_streamp strm)) | |
245 | { | |
246 | LOG_WRAPPERC("- deflateReset\n"); | |
247 | if (!g_ZWRAP_useZSTDcompression) | |
248 | return deflateReset(strm); | |
11fdf7f2 | 249 | |
7c673cae FG |
250 | ZWRAP_deflateReset_keepDict(strm); |
251 | ||
252 | { ZWRAP_CCtx* zwc = (ZWRAP_CCtx*) strm->state; | |
253 | if (zwc) zwc->comprState = ZWRAP_useInit; | |
254 | } | |
255 | return Z_OK; | |
256 | } | |
257 | ||
258 | ||
259 | ZEXTERN int ZEXPORT z_deflateSetDictionary OF((z_streamp strm, | |
260 | const Bytef *dictionary, | |
261 | uInt dictLength)) | |
262 | { | |
263 | if (!g_ZWRAP_useZSTDcompression) { | |
264 | LOG_WRAPPERC("- deflateSetDictionary\n"); | |
265 | return deflateSetDictionary(strm, dictionary, dictLength); | |
266 | } | |
267 | ||
268 | { ZWRAP_CCtx* zwc = (ZWRAP_CCtx*) strm->state; | |
269 | LOG_WRAPPERC("- deflateSetDictionary level=%d\n", (int)zwc->compressionLevel); | |
270 | if (!zwc) return Z_STREAM_ERROR; | |
271 | if (zwc->zbc == NULL) { | |
272 | zwc->zbc = ZSTD_createCStream_advanced(zwc->customMem); | |
273 | if (zwc->zbc == NULL) return ZWRAPC_finishWithError(zwc, strm, 0); | |
274 | } | |
9f95a23c | 275 | { int res = ZWRAP_initializeCStream(zwc, dictionary, dictLength, ZSTD_CONTENTSIZE_UNKNOWN); |
7c673cae FG |
276 | if (res != Z_OK) return ZWRAPC_finishWithError(zwc, strm, res); } |
277 | zwc->comprState = ZWRAP_useReset; | |
278 | } | |
279 | ||
280 | return Z_OK; | |
281 | } | |
282 | ||
283 | ||
284 | ZEXTERN int ZEXPORT z_deflate OF((z_streamp strm, int flush)) | |
285 | { | |
286 | ZWRAP_CCtx* zwc; | |
287 | ||
288 | if (!g_ZWRAP_useZSTDcompression) { | |
11fdf7f2 TL |
289 | LOG_WRAPPERC("- deflate1 flush=%d avail_in=%d avail_out=%d total_in=%d total_out=%d\n", |
290 | (int)flush, (int)strm->avail_in, (int)strm->avail_out, (int)strm->total_in, (int)strm->total_out); | |
291 | return deflate(strm, flush); | |
7c673cae FG |
292 | } |
293 | ||
294 | zwc = (ZWRAP_CCtx*) strm->state; | |
295 | if (zwc == NULL) { LOG_WRAPPERC("zwc == NULL\n"); return Z_STREAM_ERROR; } | |
296 | ||
297 | if (zwc->zbc == NULL) { | |
7c673cae | 298 | zwc->zbc = ZSTD_createCStream_advanced(zwc->customMem); |
11fdf7f2 | 299 | if (zwc->zbc == NULL) return ZWRAPC_finishWithError(zwc, strm, 0); |
9f95a23c | 300 | { int const initErr = ZWRAP_initializeCStream(zwc, NULL, 0, (flush == Z_FINISH) ? strm->avail_in : ZSTD_CONTENTSIZE_UNKNOWN); |
11fdf7f2 | 301 | if (initErr != Z_OK) return ZWRAPC_finishWithError(zwc, strm, initErr); } |
7c673cae FG |
302 | if (flush != Z_FINISH) zwc->comprState = ZWRAP_useReset; |
303 | } else { | |
11fdf7f2 | 304 | if (zwc->totalInBytes == 0) { |
7c673cae | 305 | if (zwc->comprState == ZWRAP_useReset) { |
11fdf7f2 TL |
306 | size_t const resetErr = ZSTD_resetCStream(zwc->zbc, (flush == Z_FINISH) ? strm->avail_in : zwc->pledgedSrcSize); |
307 | if (ZSTD_isError(resetErr)) { | |
308 | LOG_WRAPPERC("ERROR: ZSTD_resetCStream errorCode=%s\n", | |
309 | ZSTD_getErrorName(resetErr)); | |
310 | return ZWRAPC_finishWithError(zwc, strm, 0); | |
311 | } | |
7c673cae | 312 | } else { |
9f95a23c | 313 | int const res = ZWRAP_initializeCStream(zwc, NULL, 0, (flush == Z_FINISH) ? strm->avail_in : ZSTD_CONTENTSIZE_UNKNOWN); |
7c673cae FG |
314 | if (res != Z_OK) return ZWRAPC_finishWithError(zwc, strm, res); |
315 | if (flush != Z_FINISH) zwc->comprState = ZWRAP_useReset; | |
316 | } | |
11fdf7f2 TL |
317 | } /* (zwc->totalInBytes == 0) */ |
318 | } /* ! (zwc->zbc == NULL) */ | |
7c673cae FG |
319 | |
320 | LOG_WRAPPERC("- deflate2 flush=%d avail_in=%d avail_out=%d total_in=%d total_out=%d\n", (int)flush, (int)strm->avail_in, (int)strm->avail_out, (int)strm->total_in, (int)strm->total_out); | |
321 | if (strm->avail_in > 0) { | |
322 | zwc->inBuffer.src = strm->next_in; | |
323 | zwc->inBuffer.size = strm->avail_in; | |
324 | zwc->inBuffer.pos = 0; | |
325 | zwc->outBuffer.dst = strm->next_out; | |
326 | zwc->outBuffer.size = strm->avail_out; | |
327 | zwc->outBuffer.pos = 0; | |
11fdf7f2 | 328 | { size_t const cErr = ZSTD_compressStream(zwc->zbc, &zwc->outBuffer, &zwc->inBuffer); |
7c673cae | 329 | LOG_WRAPPERC("deflate ZSTD_compressStream srcSize=%d dstCapacity=%d\n", (int)zwc->inBuffer.size, (int)zwc->outBuffer.size); |
11fdf7f2 | 330 | if (ZSTD_isError(cErr)) return ZWRAPC_finishWithError(zwc, strm, 0); |
7c673cae FG |
331 | } |
332 | strm->next_out += zwc->outBuffer.pos; | |
333 | strm->total_out += zwc->outBuffer.pos; | |
334 | strm->avail_out -= zwc->outBuffer.pos; | |
335 | strm->total_in += zwc->inBuffer.pos; | |
11fdf7f2 | 336 | zwc->totalInBytes += zwc->inBuffer.pos; |
7c673cae FG |
337 | strm->next_in += zwc->inBuffer.pos; |
338 | strm->avail_in -= zwc->inBuffer.pos; | |
339 | } | |
340 | ||
11fdf7f2 | 341 | if (flush == Z_FULL_FLUSH |
7c673cae | 342 | #if ZLIB_VERNUM >= 0x1240 |
11fdf7f2 | 343 | || flush == Z_TREES |
7c673cae FG |
344 | #endif |
345 | || flush == Z_BLOCK) | |
346 | return ZWRAPC_finishWithErrorMsg(strm, "Z_FULL_FLUSH, Z_BLOCK and Z_TREES are not supported!"); | |
347 | ||
348 | if (flush == Z_FINISH) { | |
349 | size_t bytesLeft; | |
350 | if (zwc->streamEnd) return Z_STREAM_END; | |
351 | zwc->outBuffer.dst = strm->next_out; | |
352 | zwc->outBuffer.size = strm->avail_out; | |
353 | zwc->outBuffer.pos = 0; | |
354 | bytesLeft = ZSTD_endStream(zwc->zbc, &zwc->outBuffer); | |
355 | LOG_WRAPPERC("deflate ZSTD_endStream dstCapacity=%d bytesLeft=%d\n", (int)strm->avail_out, (int)bytesLeft); | |
356 | if (ZSTD_isError(bytesLeft)) return ZWRAPC_finishWithError(zwc, strm, 0); | |
357 | strm->next_out += zwc->outBuffer.pos; | |
358 | strm->total_out += zwc->outBuffer.pos; | |
359 | strm->avail_out -= zwc->outBuffer.pos; | |
11fdf7f2 TL |
360 | if (bytesLeft == 0) { |
361 | zwc->streamEnd = 1; | |
362 | LOG_WRAPPERC("Z_STREAM_END2 strm->total_in=%d strm->avail_out=%d strm->total_out=%d\n", | |
363 | (int)strm->total_in, (int)strm->avail_out, (int)strm->total_out); | |
364 | return Z_STREAM_END; | |
365 | } } | |
7c673cae FG |
366 | else |
367 | if (flush == Z_SYNC_FLUSH || flush == Z_PARTIAL_FLUSH) { | |
368 | size_t bytesLeft; | |
369 | zwc->outBuffer.dst = strm->next_out; | |
370 | zwc->outBuffer.size = strm->avail_out; | |
371 | zwc->outBuffer.pos = 0; | |
372 | bytesLeft = ZSTD_flushStream(zwc->zbc, &zwc->outBuffer); | |
373 | LOG_WRAPPERC("deflate ZSTD_flushStream dstCapacity=%d bytesLeft=%d\n", (int)strm->avail_out, (int)bytesLeft); | |
374 | if (ZSTD_isError(bytesLeft)) return ZWRAPC_finishWithError(zwc, strm, 0); | |
375 | strm->next_out += zwc->outBuffer.pos; | |
376 | strm->total_out += zwc->outBuffer.pos; | |
377 | strm->avail_out -= zwc->outBuffer.pos; | |
378 | } | |
379 | LOG_WRAPPERC("- deflate3 flush=%d avail_in=%d avail_out=%d total_in=%d total_out=%d\n", (int)flush, (int)strm->avail_in, (int)strm->avail_out, (int)strm->total_in, (int)strm->total_out); | |
380 | return Z_OK; | |
381 | } | |
382 | ||
383 | ||
384 | ZEXTERN int ZEXPORT z_deflateEnd OF((z_streamp strm)) | |
385 | { | |
386 | if (!g_ZWRAP_useZSTDcompression) { | |
387 | LOG_WRAPPERC("- deflateEnd\n"); | |
388 | return deflateEnd(strm); | |
389 | } | |
390 | LOG_WRAPPERC("- deflateEnd total_in=%d total_out=%d\n", (int)(strm->total_in), (int)(strm->total_out)); | |
391 | { size_t errorCode; | |
392 | ZWRAP_CCtx* zwc = (ZWRAP_CCtx*) strm->state; | |
393 | if (zwc == NULL) return Z_OK; /* structures are already freed */ | |
394 | strm->state = NULL; | |
395 | errorCode = ZWRAP_freeCCtx(zwc); | |
396 | if (ZSTD_isError(errorCode)) return Z_STREAM_ERROR; | |
397 | } | |
398 | return Z_OK; | |
399 | } | |
400 | ||
401 | ||
402 | ZEXTERN uLong ZEXPORT z_deflateBound OF((z_streamp strm, | |
403 | uLong sourceLen)) | |
404 | { | |
405 | if (!g_ZWRAP_useZSTDcompression) | |
406 | return deflateBound(strm, sourceLen); | |
407 | ||
408 | return ZSTD_compressBound(sourceLen); | |
409 | } | |
410 | ||
411 | ||
412 | ZEXTERN int ZEXPORT z_deflateParams OF((z_streamp strm, | |
413 | int level, | |
414 | int strategy)) | |
415 | { | |
416 | if (!g_ZWRAP_useZSTDcompression) { | |
417 | LOG_WRAPPERC("- deflateParams level=%d strategy=%d\n", level, strategy); | |
418 | return deflateParams(strm, level, strategy); | |
419 | } | |
420 | ||
421 | return Z_OK; | |
422 | } | |
423 | ||
424 | ||
425 | ||
426 | ||
427 | ||
11fdf7f2 TL |
428 | /* === Decompression === */ |
429 | ||
7c673cae FG |
430 | typedef enum { ZWRAP_ZLIB_STREAM, ZWRAP_ZSTD_STREAM, ZWRAP_UNKNOWN_STREAM } ZWRAP_stream_type; |
431 | ||
432 | typedef struct { | |
433 | ZSTD_DStream* zbd; | |
11fdf7f2 | 434 | char headerBuf[16]; /* must be >= ZSTD_frameHeaderSize_min */ |
7c673cae | 435 | int errorCount; |
11fdf7f2 | 436 | unsigned long long totalInBytes; /* we need it as strm->total_in can be reset by user */ |
7c673cae FG |
437 | ZWRAP_state_t decompState; |
438 | ZSTD_inBuffer inBuffer; | |
439 | ZSTD_outBuffer outBuffer; | |
440 | ||
441 | /* zlib params */ | |
442 | int stream_size; | |
443 | char *version; | |
444 | int windowBits; | |
445 | ZSTD_customMem customMem; | |
11fdf7f2 | 446 | z_stream allocFunc; /* just to copy zalloc, zfree, opaque */ |
7c673cae FG |
447 | } ZWRAP_DCtx; |
448 | ||
449 | ||
11fdf7f2 | 450 | static void ZWRAP_initDCtx(ZWRAP_DCtx* zwd) |
7c673cae FG |
451 | { |
452 | zwd->errorCount = 0; | |
453 | zwd->outBuffer.pos = 0; | |
454 | zwd->outBuffer.size = 0; | |
455 | } | |
456 | ||
11fdf7f2 | 457 | static ZWRAP_DCtx* ZWRAP_createDCtx(z_streamp strm) |
7c673cae FG |
458 | { |
459 | ZWRAP_DCtx* zwd; | |
f67539c2 | 460 | MEM_STATIC_ASSERT(sizeof(zwd->headerBuf) >= ZSTD_HEADERSIZE); /* check static buffer size condition */ |
7c673cae FG |
461 | |
462 | if (strm->zalloc && strm->zfree) { | |
463 | zwd = (ZWRAP_DCtx*)strm->zalloc(strm->opaque, 1, sizeof(ZWRAP_DCtx)); | |
464 | if (zwd==NULL) return NULL; | |
465 | memset(zwd, 0, sizeof(ZWRAP_DCtx)); | |
11fdf7f2 | 466 | zwd->allocFunc = *strm; /* just to copy zalloc, zfree & opaque */ |
f67539c2 TL |
467 | { ZSTD_customMem ZWRAP_customMem = { ZWRAP_allocFunction, ZWRAP_freeFunction, NULL }; |
468 | ZWRAP_customMem.opaque = &zwd->allocFunc; | |
469 | zwd->customMem = ZWRAP_customMem; | |
470 | } | |
7c673cae | 471 | } else { |
11fdf7f2 | 472 | zwd = (ZWRAP_DCtx*)calloc(1, sizeof(*zwd)); |
7c673cae | 473 | if (zwd==NULL) return NULL; |
7c673cae FG |
474 | } |
475 | ||
7c673cae FG |
476 | ZWRAP_initDCtx(zwd); |
477 | return zwd; | |
478 | } | |
479 | ||
11fdf7f2 | 480 | static size_t ZWRAP_freeDCtx(ZWRAP_DCtx* zwd) |
7c673cae FG |
481 | { |
482 | if (zwd==NULL) return 0; /* support free on null */ | |
11fdf7f2 TL |
483 | ZSTD_freeDStream(zwd->zbd); |
484 | ZSTD_free(zwd->version, zwd->customMem); | |
485 | ZSTD_free(zwd, zwd->customMem); | |
7c673cae FG |
486 | return 0; |
487 | } | |
488 | ||
489 | ||
11fdf7f2 TL |
490 | int ZWRAP_isUsingZSTDdecompression(z_streamp strm) |
491 | { | |
492 | if (strm == NULL) return 0; | |
493 | return (strm->reserved == ZWRAP_ZSTD_STREAM); | |
494 | } | |
495 | ||
496 | ||
497 | static int ZWRAPD_finishWithError(ZWRAP_DCtx* zwd, z_streamp strm, int error) | |
7c673cae FG |
498 | { |
499 | LOG_WRAPPERD("- ZWRAPD_finishWithError=%d\n", error); | |
11fdf7f2 TL |
500 | ZWRAP_freeDCtx(zwd); |
501 | strm->state = NULL; | |
7c673cae FG |
502 | return (error) ? error : Z_STREAM_ERROR; |
503 | } | |
504 | ||
11fdf7f2 | 505 | static int ZWRAPD_finishWithErrorMsg(z_streamp strm, char* message) |
7c673cae | 506 | { |
11fdf7f2 | 507 | ZWRAP_DCtx* const zwd = (ZWRAP_DCtx*) strm->state; |
7c673cae FG |
508 | strm->msg = message; |
509 | if (zwd == NULL) return Z_STREAM_ERROR; | |
11fdf7f2 | 510 | |
7c673cae FG |
511 | return ZWRAPD_finishWithError(zwd, strm, 0); |
512 | } | |
513 | ||
514 | ||
515 | ZEXTERN int ZEXPORT z_inflateInit_ OF((z_streamp strm, | |
f67539c2 | 516 | const char* version, int stream_size)) |
7c673cae FG |
517 | { |
518 | if (g_ZWRAPdecompressionType == ZWRAP_FORCE_ZLIB) { | |
11fdf7f2 | 519 | strm->reserved = ZWRAP_ZLIB_STREAM; |
7c673cae FG |
520 | return inflateInit(strm); |
521 | } | |
522 | ||
11fdf7f2 TL |
523 | { ZWRAP_DCtx* const zwd = ZWRAP_createDCtx(strm); |
524 | LOG_WRAPPERD("- inflateInit\n"); | |
525 | if (zwd == NULL) return ZWRAPD_finishWithError(zwd, strm, 0); | |
526 | ||
f67539c2 | 527 | zwd->version = (char*)ZSTD_malloc(strlen(version)+1, zwd->customMem); |
11fdf7f2 TL |
528 | if (zwd->version == NULL) return ZWRAPD_finishWithError(zwd, strm, 0); |
529 | strcpy(zwd->version, version); | |
530 | ||
531 | zwd->stream_size = stream_size; | |
532 | zwd->totalInBytes = 0; | |
533 | strm->state = (struct internal_state*) zwd; | |
534 | strm->total_in = 0; | |
535 | strm->total_out = 0; | |
536 | strm->reserved = ZWRAP_UNKNOWN_STREAM; | |
537 | strm->adler = 0; | |
7c673cae FG |
538 | } |
539 | ||
540 | return Z_OK; | |
541 | } | |
542 | ||
543 | ||
544 | ZEXTERN int ZEXPORT z_inflateInit2_ OF((z_streamp strm, int windowBits, | |
545 | const char *version, int stream_size)) | |
546 | { | |
547 | if (g_ZWRAPdecompressionType == ZWRAP_FORCE_ZLIB) { | |
548 | return inflateInit2_(strm, windowBits, version, stream_size); | |
549 | } | |
11fdf7f2 TL |
550 | |
551 | { int const ret = z_inflateInit_ (strm, version, stream_size); | |
552 | LOG_WRAPPERD("- inflateInit2 windowBits=%d\n", windowBits); | |
553 | if (ret == Z_OK) { | |
554 | ZWRAP_DCtx* const zwd = (ZWRAP_DCtx*)strm->state; | |
555 | if (zwd == NULL) return Z_STREAM_ERROR; | |
556 | zwd->windowBits = windowBits; | |
557 | } | |
558 | return ret; | |
7c673cae FG |
559 | } |
560 | } | |
561 | ||
562 | int ZWRAP_inflateReset_keepDict(z_streamp strm) | |
563 | { | |
564 | LOG_WRAPPERD("- ZWRAP_inflateReset_keepDict\n"); | |
565 | if (g_ZWRAPdecompressionType == ZWRAP_FORCE_ZLIB || !strm->reserved) | |
566 | return inflateReset(strm); | |
567 | ||
11fdf7f2 | 568 | { ZWRAP_DCtx* const zwd = (ZWRAP_DCtx*) strm->state; |
7c673cae FG |
569 | if (zwd == NULL) return Z_STREAM_ERROR; |
570 | ZWRAP_initDCtx(zwd); | |
571 | zwd->decompState = ZWRAP_useReset; | |
11fdf7f2 | 572 | zwd->totalInBytes = 0; |
7c673cae | 573 | } |
11fdf7f2 | 574 | |
7c673cae FG |
575 | strm->total_in = 0; |
576 | strm->total_out = 0; | |
577 | return Z_OK; | |
578 | } | |
579 | ||
580 | ||
581 | ZEXTERN int ZEXPORT z_inflateReset OF((z_streamp strm)) | |
582 | { | |
583 | LOG_WRAPPERD("- inflateReset\n"); | |
584 | if (g_ZWRAPdecompressionType == ZWRAP_FORCE_ZLIB || !strm->reserved) | |
585 | return inflateReset(strm); | |
586 | ||
11fdf7f2 | 587 | { int const ret = ZWRAP_inflateReset_keepDict(strm); |
7c673cae FG |
588 | if (ret != Z_OK) return ret; } |
589 | ||
11fdf7f2 TL |
590 | { ZWRAP_DCtx* const zwd = (ZWRAP_DCtx*) strm->state; |
591 | if (zwd == NULL) return Z_STREAM_ERROR; | |
7c673cae FG |
592 | zwd->decompState = ZWRAP_useInit; } |
593 | ||
594 | return Z_OK; | |
595 | } | |
596 | ||
597 | ||
598 | #if ZLIB_VERNUM >= 0x1240 | |
599 | ZEXTERN int ZEXPORT z_inflateReset2 OF((z_streamp strm, | |
600 | int windowBits)) | |
601 | { | |
602 | if (g_ZWRAPdecompressionType == ZWRAP_FORCE_ZLIB || !strm->reserved) | |
603 | return inflateReset2(strm, windowBits); | |
604 | ||
11fdf7f2 | 605 | { int const ret = z_inflateReset (strm); |
7c673cae | 606 | if (ret == Z_OK) { |
11fdf7f2 | 607 | ZWRAP_DCtx* const zwd = (ZWRAP_DCtx*)strm->state; |
7c673cae FG |
608 | if (zwd == NULL) return Z_STREAM_ERROR; |
609 | zwd->windowBits = windowBits; | |
610 | } | |
611 | return ret; | |
612 | } | |
613 | } | |
614 | #endif | |
615 | ||
616 | ||
617 | ZEXTERN int ZEXPORT z_inflateSetDictionary OF((z_streamp strm, | |
618 | const Bytef *dictionary, | |
619 | uInt dictLength)) | |
620 | { | |
621 | LOG_WRAPPERD("- inflateSetDictionary\n"); | |
622 | if (g_ZWRAPdecompressionType == ZWRAP_FORCE_ZLIB || !strm->reserved) | |
623 | return inflateSetDictionary(strm, dictionary, dictLength); | |
624 | ||
11fdf7f2 | 625 | { ZWRAP_DCtx* const zwd = (ZWRAP_DCtx*) strm->state; |
7c673cae | 626 | if (zwd == NULL || zwd->zbd == NULL) return Z_STREAM_ERROR; |
11fdf7f2 TL |
627 | { size_t const initErr = ZSTD_initDStream_usingDict(zwd->zbd, dictionary, dictLength); |
628 | if (ZSTD_isError(initErr)) return ZWRAPD_finishWithError(zwd, strm, 0); } | |
629 | zwd->decompState = ZWRAP_useReset; | |
7c673cae | 630 | |
11fdf7f2 | 631 | if (zwd->totalInBytes == ZSTD_HEADERSIZE) { |
7c673cae | 632 | zwd->inBuffer.src = zwd->headerBuf; |
11fdf7f2 | 633 | zwd->inBuffer.size = zwd->totalInBytes; |
7c673cae FG |
634 | zwd->inBuffer.pos = 0; |
635 | zwd->outBuffer.dst = strm->next_out; | |
636 | zwd->outBuffer.size = 0; | |
637 | zwd->outBuffer.pos = 0; | |
11fdf7f2 TL |
638 | { size_t const errorCode = ZSTD_decompressStream(zwd->zbd, &zwd->outBuffer, &zwd->inBuffer); |
639 | LOG_WRAPPERD("inflateSetDictionary ZSTD_decompressStream errorCode=%d srcSize=%d dstCapacity=%d\n", | |
640 | (int)errorCode, (int)zwd->inBuffer.size, (int)zwd->outBuffer.size); | |
641 | if (zwd->inBuffer.pos < zwd->outBuffer.size || ZSTD_isError(errorCode)) { | |
642 | LOG_WRAPPERD("ERROR: ZSTD_decompressStream %s\n", | |
643 | ZSTD_getErrorName(errorCode)); | |
644 | return ZWRAPD_finishWithError(zwd, strm, 0); | |
645 | } } } } | |
7c673cae FG |
646 | |
647 | return Z_OK; | |
648 | } | |
649 | ||
650 | ||
651 | ZEXTERN int ZEXPORT z_inflate OF((z_streamp strm, int flush)) | |
652 | { | |
653 | ZWRAP_DCtx* zwd; | |
11fdf7f2 | 654 | |
7c673cae | 655 | if (g_ZWRAPdecompressionType == ZWRAP_FORCE_ZLIB || !strm->reserved) { |
11fdf7f2 TL |
656 | int const result = inflate(strm, flush); |
657 | LOG_WRAPPERD("- inflate2 flush=%d avail_in=%d avail_out=%d total_in=%d total_out=%d res=%d\n", | |
658 | (int)flush, (int)strm->avail_in, (int)strm->avail_out, (int)strm->total_in, (int)strm->total_out, result); | |
659 | return result; | |
7c673cae FG |
660 | } |
661 | ||
662 | if (strm->avail_in <= 0) return Z_OK; | |
663 | ||
11fdf7f2 TL |
664 | zwd = (ZWRAP_DCtx*) strm->state; |
665 | LOG_WRAPPERD("- inflate1 flush=%d avail_in=%d avail_out=%d total_in=%d total_out=%d\n", | |
666 | (int)flush, (int)strm->avail_in, (int)strm->avail_out, (int)strm->total_in, (int)strm->total_out); | |
7c673cae | 667 | |
11fdf7f2 TL |
668 | if (zwd == NULL) return Z_STREAM_ERROR; |
669 | if (zwd->decompState == ZWRAP_streamEnd) return Z_STREAM_END; | |
670 | ||
671 | if (zwd->totalInBytes < ZLIB_HEADERSIZE) { | |
672 | if (zwd->totalInBytes == 0 && strm->avail_in >= ZLIB_HEADERSIZE) { | |
673 | if (MEM_readLE32(strm->next_in) != ZSTD_MAGICNUMBER) { | |
674 | { int const initErr = (zwd->windowBits) ? | |
675 | inflateInit2_(strm, zwd->windowBits, zwd->version, zwd->stream_size) : | |
676 | inflateInit_(strm, zwd->version, zwd->stream_size); | |
677 | LOG_WRAPPERD("ZLIB inflateInit errorCode=%d\n", initErr); | |
678 | if (initErr != Z_OK) return ZWRAPD_finishWithError(zwd, strm, initErr); | |
7c673cae | 679 | } |
7c673cae | 680 | |
11fdf7f2 TL |
681 | strm->reserved = ZWRAP_ZLIB_STREAM; |
682 | { size_t const freeErr = ZWRAP_freeDCtx(zwd); | |
683 | if (ZSTD_isError(freeErr)) goto error; } | |
684 | ||
685 | { int const result = (flush == Z_INFLATE_SYNC) ? | |
686 | inflateSync(strm) : | |
687 | inflate(strm, flush); | |
688 | LOG_WRAPPERD("- inflate3 flush=%d avail_in=%d avail_out=%d total_in=%d total_out=%d res=%d\n", | |
689 | (int)flush, (int)strm->avail_in, (int)strm->avail_out, (int)strm->total_in, (int)strm->total_out, res); | |
690 | return result; | |
691 | } } | |
692 | } else { /* ! (zwd->totalInBytes == 0 && strm->avail_in >= ZLIB_HEADERSIZE) */ | |
693 | size_t const srcSize = MIN(strm->avail_in, ZLIB_HEADERSIZE - zwd->totalInBytes); | |
694 | memcpy(zwd->headerBuf+zwd->totalInBytes, strm->next_in, srcSize); | |
695 | strm->total_in += srcSize; | |
696 | zwd->totalInBytes += srcSize; | |
697 | strm->next_in += srcSize; | |
698 | strm->avail_in -= srcSize; | |
699 | if (zwd->totalInBytes < ZLIB_HEADERSIZE) return Z_OK; | |
700 | ||
701 | if (MEM_readLE32(zwd->headerBuf) != ZSTD_MAGICNUMBER) { | |
702 | z_stream strm2; | |
703 | strm2.next_in = strm->next_in; | |
704 | strm2.avail_in = strm->avail_in; | |
705 | strm2.next_out = strm->next_out; | |
706 | strm2.avail_out = strm->avail_out; | |
707 | ||
708 | { int const initErr = (zwd->windowBits) ? | |
709 | inflateInit2_(strm, zwd->windowBits, zwd->version, zwd->stream_size) : | |
710 | inflateInit_(strm, zwd->version, zwd->stream_size); | |
711 | LOG_WRAPPERD("ZLIB inflateInit errorCode=%d\n", initErr); | |
712 | if (initErr != Z_OK) return ZWRAPD_finishWithError(zwd, strm, initErr); | |
713 | } | |
7c673cae | 714 | |
11fdf7f2 TL |
715 | /* inflate header */ |
716 | strm->next_in = (unsigned char*)zwd->headerBuf; | |
717 | strm->avail_in = ZLIB_HEADERSIZE; | |
718 | strm->avail_out = 0; | |
719 | { int const dErr = inflate(strm, Z_NO_FLUSH); | |
720 | LOG_WRAPPERD("ZLIB inflate errorCode=%d strm->avail_in=%d\n", | |
721 | dErr, (int)strm->avail_in); | |
722 | if (dErr != Z_OK) | |
723 | return ZWRAPD_finishWithError(zwd, strm, dErr); | |
724 | } | |
725 | if (strm->avail_in > 0) goto error; | |
726 | ||
727 | strm->next_in = strm2.next_in; | |
728 | strm->avail_in = strm2.avail_in; | |
729 | strm->next_out = strm2.next_out; | |
730 | strm->avail_out = strm2.avail_out; | |
731 | ||
732 | strm->reserved = ZWRAP_ZLIB_STREAM; /* mark as zlib stream */ | |
733 | { size_t const freeErr = ZWRAP_freeDCtx(zwd); | |
734 | if (ZSTD_isError(freeErr)) goto error; } | |
735 | ||
736 | { int const result = (flush == Z_INFLATE_SYNC) ? | |
737 | inflateSync(strm) : | |
738 | inflate(strm, flush); | |
739 | LOG_WRAPPERD("- inflate2 flush=%d avail_in=%d avail_out=%d total_in=%d total_out=%d res=%d\n", | |
740 | (int)flush, (int)strm->avail_in, (int)strm->avail_out, (int)strm->total_in, (int)strm->total_out, res); | |
741 | return result; | |
742 | } } } /* if ! (zwd->totalInBytes == 0 && strm->avail_in >= ZLIB_HEADERSIZE) */ | |
743 | } /* (zwd->totalInBytes < ZLIB_HEADERSIZE) */ | |
744 | ||
745 | strm->reserved = ZWRAP_ZSTD_STREAM; /* mark as zstd steam */ | |
746 | ||
747 | if (flush == Z_INFLATE_SYNC) { strm->msg = "inflateSync is not supported!"; goto error; } | |
748 | ||
749 | if (!zwd->zbd) { | |
750 | zwd->zbd = ZSTD_createDStream_advanced(zwd->customMem); | |
751 | if (zwd->zbd == NULL) { LOG_WRAPPERD("ERROR: ZSTD_createDStream_advanced\n"); goto error; } | |
752 | zwd->decompState = ZWRAP_useInit; | |
753 | } | |
7c673cae | 754 | |
11fdf7f2 TL |
755 | if (zwd->totalInBytes < ZSTD_HEADERSIZE) { |
756 | if (zwd->totalInBytes == 0 && strm->avail_in >= ZSTD_HEADERSIZE) { | |
757 | if (zwd->decompState == ZWRAP_useInit) { | |
758 | size_t const initErr = ZSTD_initDStream(zwd->zbd); | |
759 | if (ZSTD_isError(initErr)) { | |
760 | LOG_WRAPPERD("ERROR: ZSTD_initDStream errorCode=%s\n", | |
761 | ZSTD_getErrorName(initErr)); | |
762 | goto error; | |
7c673cae FG |
763 | } |
764 | } else { | |
11fdf7f2 TL |
765 | size_t const resetErr = ZSTD_resetDStream(zwd->zbd); |
766 | if (ZSTD_isError(resetErr)) goto error; | |
767 | } | |
768 | } else { | |
769 | size_t const srcSize = MIN(strm->avail_in, ZSTD_HEADERSIZE - zwd->totalInBytes); | |
770 | memcpy(zwd->headerBuf+zwd->totalInBytes, strm->next_in, srcSize); | |
771 | strm->total_in += srcSize; | |
772 | zwd->totalInBytes += srcSize; | |
773 | strm->next_in += srcSize; | |
774 | strm->avail_in -= srcSize; | |
775 | if (zwd->totalInBytes < ZSTD_HEADERSIZE) return Z_OK; | |
776 | ||
777 | if (zwd->decompState == ZWRAP_useInit) { | |
778 | size_t const initErr = ZSTD_initDStream(zwd->zbd); | |
779 | if (ZSTD_isError(initErr)) { | |
780 | LOG_WRAPPERD("ERROR: ZSTD_initDStream errorCode=%s\n", | |
781 | ZSTD_getErrorName(initErr)); | |
7c673cae FG |
782 | goto error; |
783 | } | |
11fdf7f2 TL |
784 | } else { |
785 | size_t const resetErr = ZSTD_resetDStream(zwd->zbd); | |
786 | if (ZSTD_isError(resetErr)) goto error; | |
7c673cae | 787 | } |
11fdf7f2 TL |
788 | |
789 | zwd->inBuffer.src = zwd->headerBuf; | |
790 | zwd->inBuffer.size = ZSTD_HEADERSIZE; | |
791 | zwd->inBuffer.pos = 0; | |
792 | zwd->outBuffer.dst = strm->next_out; | |
793 | zwd->outBuffer.size = 0; | |
794 | zwd->outBuffer.pos = 0; | |
795 | { size_t const dErr = ZSTD_decompressStream(zwd->zbd, &zwd->outBuffer, &zwd->inBuffer); | |
796 | LOG_WRAPPERD("inflate ZSTD_decompressStream1 errorCode=%d srcSize=%d dstCapacity=%d\n", | |
797 | (int)dErr, (int)zwd->inBuffer.size, (int)zwd->outBuffer.size); | |
798 | if (ZSTD_isError(dErr)) { | |
799 | LOG_WRAPPERD("ERROR: ZSTD_decompressStream1 %s\n", ZSTD_getErrorName(dErr)); | |
800 | goto error; | |
801 | } } | |
802 | if (zwd->inBuffer.pos != zwd->inBuffer.size) goto error; /* not consumed */ | |
7c673cae | 803 | } |
11fdf7f2 | 804 | } /* (zwd->totalInBytes < ZSTD_HEADERSIZE) */ |
7c673cae | 805 | |
11fdf7f2 TL |
806 | zwd->inBuffer.src = strm->next_in; |
807 | zwd->inBuffer.size = strm->avail_in; | |
808 | zwd->inBuffer.pos = 0; | |
809 | zwd->outBuffer.dst = strm->next_out; | |
810 | zwd->outBuffer.size = strm->avail_out; | |
811 | zwd->outBuffer.pos = 0; | |
812 | { size_t const dErr = ZSTD_decompressStream(zwd->zbd, &zwd->outBuffer, &zwd->inBuffer); | |
813 | LOG_WRAPPERD("inflate ZSTD_decompressStream2 errorCode=%d srcSize=%d dstCapacity=%d\n", | |
814 | (int)dErr, (int)strm->avail_in, (int)strm->avail_out); | |
815 | if (ZSTD_isError(dErr)) { | |
7c673cae | 816 | zwd->errorCount++; |
11fdf7f2 TL |
817 | LOG_WRAPPERD("ERROR: ZSTD_decompressStream2 %s zwd->errorCount=%d\n", |
818 | ZSTD_getErrorName(dErr), zwd->errorCount); | |
7c673cae FG |
819 | if (zwd->errorCount<=1) return Z_NEED_DICT; else goto error; |
820 | } | |
11fdf7f2 TL |
821 | LOG_WRAPPERD("inflate inBuffer.pos=%d inBuffer.size=%d outBuffer.pos=%d outBuffer.size=%d o\n", |
822 | (int)zwd->inBuffer.pos, (int)zwd->inBuffer.size, (int)zwd->outBuffer.pos, (int)zwd->outBuffer.size); | |
7c673cae FG |
823 | strm->next_out += zwd->outBuffer.pos; |
824 | strm->total_out += zwd->outBuffer.pos; | |
825 | strm->avail_out -= zwd->outBuffer.pos; | |
826 | strm->total_in += zwd->inBuffer.pos; | |
11fdf7f2 | 827 | zwd->totalInBytes += zwd->inBuffer.pos; |
7c673cae FG |
828 | strm->next_in += zwd->inBuffer.pos; |
829 | strm->avail_in -= zwd->inBuffer.pos; | |
11fdf7f2 TL |
830 | if (dErr == 0) { |
831 | LOG_WRAPPERD("inflate Z_STREAM_END1 avail_in=%d avail_out=%d total_in=%d total_out=%d\n", | |
832 | (int)strm->avail_in, (int)strm->avail_out, (int)strm->total_in, (int)strm->total_out); | |
833 | zwd->decompState = ZWRAP_streamEnd; | |
7c673cae FG |
834 | return Z_STREAM_END; |
835 | } | |
11fdf7f2 TL |
836 | } /* dErr lifetime */ |
837 | ||
838 | LOG_WRAPPERD("- inflate2 flush=%d avail_in=%d avail_out=%d total_in=%d total_out=%d res=%d\n", | |
839 | (int)flush, (int)strm->avail_in, (int)strm->avail_out, (int)strm->total_in, (int)strm->total_out, Z_OK); | |
7c673cae FG |
840 | return Z_OK; |
841 | ||
842 | error: | |
843 | return ZWRAPD_finishWithError(zwd, strm, 0); | |
844 | } | |
845 | ||
846 | ||
847 | ZEXTERN int ZEXPORT z_inflateEnd OF((z_streamp strm)) | |
848 | { | |
849 | if (g_ZWRAPdecompressionType == ZWRAP_FORCE_ZLIB || !strm->reserved) | |
850 | return inflateEnd(strm); | |
851 | ||
11fdf7f2 TL |
852 | LOG_WRAPPERD("- inflateEnd total_in=%d total_out=%d\n", |
853 | (int)(strm->total_in), (int)(strm->total_out)); | |
854 | { ZWRAP_DCtx* const zwd = (ZWRAP_DCtx*) strm->state; | |
7c673cae | 855 | if (zwd == NULL) return Z_OK; /* structures are already freed */ |
11fdf7f2 TL |
856 | { size_t const freeErr = ZWRAP_freeDCtx(zwd); |
857 | if (ZSTD_isError(freeErr)) return Z_STREAM_ERROR; } | |
7c673cae | 858 | strm->state = NULL; |
7c673cae FG |
859 | } |
860 | return Z_OK; | |
861 | } | |
862 | ||
863 | ||
864 | ZEXTERN int ZEXPORT z_inflateSync OF((z_streamp strm)) | |
865 | { | |
866 | if (g_ZWRAPdecompressionType == ZWRAP_FORCE_ZLIB || !strm->reserved) { | |
867 | return inflateSync(strm); | |
868 | } | |
869 | ||
870 | return z_inflate(strm, Z_INFLATE_SYNC); | |
871 | } | |
872 | ||
873 | ||
874 | ||
7c673cae FG |
875 | /* Advanced compression functions */ |
876 | ZEXTERN int ZEXPORT z_deflateCopy OF((z_streamp dest, | |
877 | z_streamp source)) | |
878 | { | |
879 | if (!g_ZWRAP_useZSTDcompression) | |
880 | return deflateCopy(dest, source); | |
881 | return ZWRAPC_finishWithErrorMsg(source, "deflateCopy is not supported!"); | |
882 | } | |
883 | ||
884 | ||
885 | ZEXTERN int ZEXPORT z_deflateTune OF((z_streamp strm, | |
886 | int good_length, | |
887 | int max_lazy, | |
888 | int nice_length, | |
889 | int max_chain)) | |
890 | { | |
891 | if (!g_ZWRAP_useZSTDcompression) | |
892 | return deflateTune(strm, good_length, max_lazy, nice_length, max_chain); | |
893 | return ZWRAPC_finishWithErrorMsg(strm, "deflateTune is not supported!"); | |
894 | } | |
895 | ||
896 | ||
897 | #if ZLIB_VERNUM >= 0x1260 | |
898 | ZEXTERN int ZEXPORT z_deflatePending OF((z_streamp strm, | |
899 | unsigned *pending, | |
900 | int *bits)) | |
901 | { | |
902 | if (!g_ZWRAP_useZSTDcompression) | |
903 | return deflatePending(strm, pending, bits); | |
904 | return ZWRAPC_finishWithErrorMsg(strm, "deflatePending is not supported!"); | |
905 | } | |
906 | #endif | |
907 | ||
908 | ||
909 | ZEXTERN int ZEXPORT z_deflatePrime OF((z_streamp strm, | |
910 | int bits, | |
911 | int value)) | |
912 | { | |
913 | if (!g_ZWRAP_useZSTDcompression) | |
914 | return deflatePrime(strm, bits, value); | |
915 | return ZWRAPC_finishWithErrorMsg(strm, "deflatePrime is not supported!"); | |
916 | } | |
917 | ||
918 | ||
919 | ZEXTERN int ZEXPORT z_deflateSetHeader OF((z_streamp strm, | |
920 | gz_headerp head)) | |
921 | { | |
922 | if (!g_ZWRAP_useZSTDcompression) | |
923 | return deflateSetHeader(strm, head); | |
924 | return ZWRAPC_finishWithErrorMsg(strm, "deflateSetHeader is not supported!"); | |
925 | } | |
926 | ||
927 | ||
928 | ||
929 | ||
930 | /* Advanced decompression functions */ | |
931 | #if ZLIB_VERNUM >= 0x1280 | |
932 | ZEXTERN int ZEXPORT z_inflateGetDictionary OF((z_streamp strm, | |
933 | Bytef *dictionary, | |
934 | uInt *dictLength)) | |
935 | { | |
936 | if (g_ZWRAPdecompressionType == ZWRAP_FORCE_ZLIB || !strm->reserved) | |
937 | return inflateGetDictionary(strm, dictionary, dictLength); | |
938 | return ZWRAPD_finishWithErrorMsg(strm, "inflateGetDictionary is not supported!"); | |
939 | } | |
940 | #endif | |
941 | ||
942 | ||
943 | ZEXTERN int ZEXPORT z_inflateCopy OF((z_streamp dest, | |
944 | z_streamp source)) | |
945 | { | |
946 | if (g_ZWRAPdecompressionType == ZWRAP_FORCE_ZLIB || !source->reserved) | |
947 | return inflateCopy(dest, source); | |
948 | return ZWRAPD_finishWithErrorMsg(source, "inflateCopy is not supported!"); | |
949 | } | |
950 | ||
951 | ||
952 | #if ZLIB_VERNUM >= 0x1240 | |
953 | ZEXTERN long ZEXPORT z_inflateMark OF((z_streamp strm)) | |
954 | { | |
955 | if (g_ZWRAPdecompressionType == ZWRAP_FORCE_ZLIB || !strm->reserved) | |
956 | return inflateMark(strm); | |
957 | return ZWRAPD_finishWithErrorMsg(strm, "inflateMark is not supported!"); | |
958 | } | |
959 | #endif | |
960 | ||
961 | ||
962 | ZEXTERN int ZEXPORT z_inflatePrime OF((z_streamp strm, | |
963 | int bits, | |
964 | int value)) | |
965 | { | |
966 | if (g_ZWRAPdecompressionType == ZWRAP_FORCE_ZLIB || !strm->reserved) | |
967 | return inflatePrime(strm, bits, value); | |
968 | return ZWRAPD_finishWithErrorMsg(strm, "inflatePrime is not supported!"); | |
969 | } | |
970 | ||
971 | ||
972 | ZEXTERN int ZEXPORT z_inflateGetHeader OF((z_streamp strm, | |
973 | gz_headerp head)) | |
974 | { | |
975 | if (g_ZWRAPdecompressionType == ZWRAP_FORCE_ZLIB || !strm->reserved) | |
976 | return inflateGetHeader(strm, head); | |
977 | return ZWRAPD_finishWithErrorMsg(strm, "inflateGetHeader is not supported!"); | |
978 | } | |
979 | ||
980 | ||
981 | ZEXTERN int ZEXPORT z_inflateBackInit_ OF((z_streamp strm, int windowBits, | |
982 | unsigned char FAR *window, | |
983 | const char *version, | |
984 | int stream_size)) | |
985 | { | |
986 | if (g_ZWRAPdecompressionType == ZWRAP_FORCE_ZLIB || !strm->reserved) | |
987 | return inflateBackInit_(strm, windowBits, window, version, stream_size); | |
988 | return ZWRAPD_finishWithErrorMsg(strm, "inflateBackInit is not supported!"); | |
989 | } | |
990 | ||
991 | ||
992 | ZEXTERN int ZEXPORT z_inflateBack OF((z_streamp strm, | |
993 | in_func in, void FAR *in_desc, | |
994 | out_func out, void FAR *out_desc)) | |
995 | { | |
996 | if (g_ZWRAPdecompressionType == ZWRAP_FORCE_ZLIB || !strm->reserved) | |
997 | return inflateBack(strm, in, in_desc, out, out_desc); | |
998 | return ZWRAPD_finishWithErrorMsg(strm, "inflateBack is not supported!"); | |
999 | } | |
1000 | ||
1001 | ||
1002 | ZEXTERN int ZEXPORT z_inflateBackEnd OF((z_streamp strm)) | |
1003 | { | |
1004 | if (g_ZWRAPdecompressionType == ZWRAP_FORCE_ZLIB || !strm->reserved) | |
1005 | return inflateBackEnd(strm); | |
1006 | return ZWRAPD_finishWithErrorMsg(strm, "inflateBackEnd is not supported!"); | |
1007 | } | |
1008 | ||
1009 | ||
f67539c2 | 1010 | ZEXTERN uLong ZEXPORT z_zlibCompileFlags OF((void)) { return zlibCompileFlags(); } |
7c673cae FG |
1011 | |
1012 | ||
1013 | ||
11fdf7f2 | 1014 | /* === utility functions === */ |
7c673cae FG |
1015 | #ifndef Z_SOLO |
1016 | ||
1017 | ZEXTERN int ZEXPORT z_compress OF((Bytef *dest, uLongf *destLen, | |
1018 | const Bytef *source, uLong sourceLen)) | |
1019 | { | |
1020 | if (!g_ZWRAP_useZSTDcompression) | |
1021 | return compress(dest, destLen, source, sourceLen); | |
1022 | ||
11fdf7f2 TL |
1023 | { size_t dstCapacity = *destLen; |
1024 | size_t const cSize = ZSTD_compress(dest, dstCapacity, | |
1025 | source, sourceLen, | |
1026 | ZWRAP_DEFAULT_CLEVEL); | |
1027 | LOG_WRAPPERD("z_compress sourceLen=%d dstCapacity=%d\n", | |
1028 | (int)sourceLen, (int)dstCapacity); | |
1029 | if (ZSTD_isError(cSize)) return Z_STREAM_ERROR; | |
1030 | *destLen = cSize; | |
7c673cae FG |
1031 | } |
1032 | return Z_OK; | |
1033 | } | |
1034 | ||
1035 | ||
1036 | ZEXTERN int ZEXPORT z_compress2 OF((Bytef *dest, uLongf *destLen, | |
1037 | const Bytef *source, uLong sourceLen, | |
1038 | int level)) | |
1039 | { | |
1040 | if (!g_ZWRAP_useZSTDcompression) | |
1041 | return compress2(dest, destLen, source, sourceLen, level); | |
1042 | ||
1043 | { size_t dstCapacity = *destLen; | |
11fdf7f2 TL |
1044 | size_t const cSize = ZSTD_compress(dest, dstCapacity, source, sourceLen, level); |
1045 | if (ZSTD_isError(cSize)) return Z_STREAM_ERROR; | |
1046 | *destLen = cSize; | |
7c673cae FG |
1047 | } |
1048 | return Z_OK; | |
1049 | } | |
1050 | ||
1051 | ||
1052 | ZEXTERN uLong ZEXPORT z_compressBound OF((uLong sourceLen)) | |
1053 | { | |
1054 | if (!g_ZWRAP_useZSTDcompression) | |
1055 | return compressBound(sourceLen); | |
1056 | ||
1057 | return ZSTD_compressBound(sourceLen); | |
1058 | } | |
1059 | ||
1060 | ||
1061 | ZEXTERN int ZEXPORT z_uncompress OF((Bytef *dest, uLongf *destLen, | |
1062 | const Bytef *source, uLong sourceLen)) | |
1063 | { | |
11fdf7f2 | 1064 | if (!ZSTD_isFrame(source, sourceLen)) |
7c673cae FG |
1065 | return uncompress(dest, destLen, source, sourceLen); |
1066 | ||
1067 | { size_t dstCapacity = *destLen; | |
11fdf7f2 TL |
1068 | size_t const dSize = ZSTD_decompress(dest, dstCapacity, source, sourceLen); |
1069 | if (ZSTD_isError(dSize)) return Z_STREAM_ERROR; | |
1070 | *destLen = dSize; | |
7c673cae FG |
1071 | } |
1072 | return Z_OK; | |
1073 | } | |
1074 | ||
1075 | #endif /* !Z_SOLO */ | |
1076 | ||
1077 | ||
1078 | /* checksum functions */ | |
1079 | ||
1080 | ZEXTERN uLong ZEXPORT z_adler32 OF((uLong adler, const Bytef *buf, uInt len)) | |
1081 | { | |
1082 | return adler32(adler, buf, len); | |
1083 | } | |
1084 | ||
1085 | ZEXTERN uLong ZEXPORT z_crc32 OF((uLong crc, const Bytef *buf, uInt len)) | |
1086 | { | |
1087 | return crc32(crc, buf, len); | |
1088 | } | |
11fdf7f2 TL |
1089 | |
1090 | ||
1091 | #if ZLIB_VERNUM >= 0x12B0 | |
1092 | ZEXTERN uLong ZEXPORT z_adler32_z OF((uLong adler, const Bytef *buf, z_size_t len)) | |
1093 | { | |
1094 | return adler32_z(adler, buf, len); | |
1095 | } | |
1096 | ||
1097 | ZEXTERN uLong ZEXPORT z_crc32_z OF((uLong crc, const Bytef *buf, z_size_t len)) | |
1098 | { | |
1099 | return crc32_z(crc, buf, len); | |
1100 | } | |
1101 | #endif | |
1102 | ||
1103 | ||
1104 | #if ZLIB_VERNUM >= 0x1270 | |
1105 | ZEXTERN const z_crc_t FAR * ZEXPORT z_get_crc_table OF((void)) | |
1106 | { | |
1107 | return get_crc_table(); | |
1108 | } | |
1109 | #endif |