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