blob: 93e82884cf6466e45c38bb67fc109868f569e063 [file] [log] [blame]
Yann Collet5be2dd22015-11-11 13:43:58 +01001/*
2 zstd - standard compression library
3 Copyright (C) 2014-2015, Yann Collet.
4
5 BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
6
7 Redistribution and use in source and binary forms, with or without
8 modification, are permitted provided that the following conditions are
9 met:
10 * Redistributions of source code must retain the above copyright
11 notice, this list of conditions and the following disclaimer.
12 * Redistributions in binary form must reproduce the above
13 copyright notice, this list of conditions and the following disclaimer
14 in the documentation and/or other materials provided with the
15 distribution.
16 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28 You can contact the author at :
29 - zstd source repository : https://github.com/Cyan4973/zstd
30 - ztsd public forum : https://groups.google.com/forum/#!forum/lz4c
31*/
32
33/* ***************************************************************
34* Tuning parameters
35*****************************************************************/
36/*!
Yann Collet5be2dd22015-11-11 13:43:58 +010037 * HEAPMODE :
Yann Collet3a3b72f2016-01-11 12:56:11 +010038 * Select how default decompression function ZSTD_decompress() will allocate memory,
39 * in memory stack (0), or in memory heap (1, requires malloc())
Yann Collet5be2dd22015-11-11 13:43:58 +010040 */
41#ifndef ZSTD_HEAPMODE
42# define ZSTD_HEAPMODE 1
Yann Collet3a3b72f2016-01-11 12:56:11 +010043#endif
Yann Collet5be2dd22015-11-11 13:43:58 +010044
45/*!
46* LEGACY_SUPPORT :
Yann Colletfba6aed2016-01-18 12:03:27 +010047* ZSTD_decompress() can decode older formats (v0.1+) if set to 1
Yann Collet5be2dd22015-11-11 13:43:58 +010048*/
49#ifndef ZSTD_LEGACY_SUPPORT
Yann Colletfba6aed2016-01-18 12:03:27 +010050# define ZSTD_LEGACY_SUPPORT 0
Yann Collet5be2dd22015-11-11 13:43:58 +010051#endif
52
53
54/* *******************************************************
55* Includes
56*********************************************************/
57#include <stdlib.h> /* calloc */
58#include <string.h> /* memcpy, memmove */
59#include <stdio.h> /* debug : printf */
60#include "mem.h" /* low level memory routines */
61#include "zstd_static.h"
62#include "zstd_internal.h"
63#include "fse_static.h"
Yann Colletafe07092016-01-25 04:10:46 +010064#include "huff0_static.h"
Yann Collet5be2dd22015-11-11 13:43:58 +010065
66#if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT==1)
67# include "zstd_legacy.h"
68#endif
69
Yann Collet5be2dd22015-11-11 13:43:58 +010070/* *******************************************************
71* Compiler specifics
72*********************************************************/
Yann Collet5be2dd22015-11-11 13:43:58 +010073#ifdef _MSC_VER /* Visual Studio */
74# define FORCE_INLINE static __forceinline
75# include <intrin.h> /* For Visual 2005 */
76# pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */
77# pragma warning(disable : 4324) /* disable: C4324: padded structure */
78#else
79# define GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__)
80# ifdef __GNUC__
81# define FORCE_INLINE static inline __attribute__((always_inline))
82# else
83# define FORCE_INLINE static inline
84# endif
85#endif
86
87
Yann Collet14983e72015-11-11 21:38:21 +010088/* *************************************
89* Local types
90***************************************/
91typedef struct
92{
93 blockType_t blockType;
94 U32 origSize;
95} blockProperties_t;
Yann Collet5be2dd22015-11-11 13:43:58 +010096
97
98/* *******************************************************
99* Memory operations
100**********************************************************/
101static void ZSTD_copy4(void* dst, const void* src) { memcpy(dst, src, 4); }
102
103
Yann Collet5be2dd22015-11-11 13:43:58 +0100104/* *************************************
105* Error Management
106***************************************/
Yann Collet14983e72015-11-11 21:38:21 +0100107unsigned ZSTD_versionNumber (void) { return ZSTD_VERSION_NUMBER; }
108
Yann Collet5be2dd22015-11-11 13:43:58 +0100109/*! ZSTD_isError
110* tells if a return value is an error code */
111unsigned ZSTD_isError(size_t code) { return ERR_isError(code); }
112
113/*! ZSTD_getErrorName
114* provides error code string (useful for debugging) */
115const char* ZSTD_getErrorName(size_t code) { return ERR_getErrorName(code); }
116
117
Yann Collet5be2dd22015-11-11 13:43:58 +0100118/* *************************************************************
Yann Collet5b78d2f2015-11-12 15:36:05 +0100119* Context management
Yann Collet5be2dd22015-11-11 13:43:58 +0100120***************************************************************/
Yann Collete4fdad52015-11-25 21:09:17 +0100121typedef enum { ZSTDds_getFrameHeaderSize, ZSTDds_decodeFrameHeader,
Yann Collet88fcd292015-11-25 14:42:45 +0100122 ZSTDds_decodeBlockHeader, ZSTDds_decompressBlock } ZSTD_dStage;
123
Yann Collet5be2dd22015-11-11 13:43:58 +0100124struct ZSTD_DCtx_s
125{
126 U32 LLTable[FSE_DTABLE_SIZE_U32(LLFSELog)];
127 U32 OffTable[FSE_DTABLE_SIZE_U32(OffFSELog)];
128 U32 MLTable[FSE_DTABLE_SIZE_U32(MLFSELog)];
Yann Colletb923f652016-01-26 03:14:20 +0100129 U32 hufTableX4[HUF_DTABLE_SIZE(HufLog)];
Yann Collet417890c2015-12-04 17:16:37 +0100130 const void* previousDstEnd;
131 const void* base;
132 const void* vBase;
133 const void* dictEnd;
Yann Collet5be2dd22015-11-11 13:43:58 +0100134 size_t expected;
Yann Collet88fcd292015-11-25 14:42:45 +0100135 size_t headerSize;
136 ZSTD_parameters params;
Yann Collet5be2dd22015-11-11 13:43:58 +0100137 blockType_t bType;
Yann Collet88fcd292015-11-25 14:42:45 +0100138 ZSTD_dStage stage;
Yann Collet7b51a292016-01-26 15:58:49 +0100139 U32 flagHufTable;
Yann Collet5be2dd22015-11-11 13:43:58 +0100140 const BYTE* litPtr;
141 size_t litBufSize;
142 size_t litSize;
Yann Colletb923f652016-01-26 03:14:20 +0100143 BYTE litBuffer[BLOCKSIZE + WILDCOPY_OVERLENGTH];
Yann Collet88fcd292015-11-25 14:42:45 +0100144 BYTE headerBuffer[ZSTD_frameHeaderSize_max];
Yann Collet417890c2015-12-04 17:16:37 +0100145}; /* typedef'd to ZSTD_DCtx within "zstd_static.h" */
Yann Collet5be2dd22015-11-11 13:43:58 +0100146
Yann Collet7b51a292016-01-26 15:58:49 +0100147size_t ZSTD_decompressBegin(ZSTD_DCtx* dctx)
Yann Collet5b78d2f2015-11-12 15:36:05 +0100148{
Yann Collet88fcd292015-11-25 14:42:45 +0100149 dctx->expected = ZSTD_frameHeaderSize_min;
150 dctx->stage = ZSTDds_getFrameHeaderSize;
Yann Collet5b78d2f2015-11-12 15:36:05 +0100151 dctx->previousDstEnd = NULL;
152 dctx->base = NULL;
153 dctx->vBase = NULL;
154 dctx->dictEnd = NULL;
Yann Colletb923f652016-01-26 03:14:20 +0100155 dctx->hufTableX4[0] = HufLog;
Yann Collet7b51a292016-01-26 15:58:49 +0100156 dctx->flagHufTable = 0;
Yann Collet5b78d2f2015-11-12 15:36:05 +0100157 return 0;
158}
159
160ZSTD_DCtx* ZSTD_createDCtx(void)
161{
162 ZSTD_DCtx* dctx = (ZSTD_DCtx*)malloc(sizeof(ZSTD_DCtx));
163 if (dctx==NULL) return NULL;
Yann Collet7b51a292016-01-26 15:58:49 +0100164 ZSTD_decompressBegin(dctx);
Yann Collet5b78d2f2015-11-12 15:36:05 +0100165 return dctx;
166}
167
168size_t ZSTD_freeDCtx(ZSTD_DCtx* dctx)
169{
170 free(dctx);
171 return 0;
172}
173
Yann Collet7b51a292016-01-26 15:58:49 +0100174void ZSTD_copyDCtx(ZSTD_DCtx* dstDCtx, const ZSTD_DCtx* srcDCtx)
175{
176 memcpy(dstDCtx, srcDCtx,
177 sizeof(ZSTD_DCtx) - (BLOCKSIZE+WILDCOPY_OVERLENGTH + ZSTD_frameHeaderSize_max)); /* no need to copy workspace */
178}
179
Yann Collet5b78d2f2015-11-12 15:36:05 +0100180
181/* *************************************************************
182* Decompression section
183***************************************************************/
Yann Collet59d1f792016-01-23 19:28:41 +0100184
185/* Frame format description
186 Frame Header - [ Block Header - Block ] - Frame End
187 1) Frame Header
188 - 4 bytes - Magic Number : ZSTD_MAGICNUMBER (defined within zstd_internal.h)
189 - 1 byte - Window Descriptor
190 2) Block Header
191 - 3 bytes, starting with a 2-bits descriptor
192 Uncompressed, Compressed, Frame End, unused
193 3) Block
194 See Block Format Description
195 4) Frame End
196 - 3 bytes, compatible with Block Header
197*/
198
199/* Block format description
200 Literal Section - Sequences Section
201 1) Literal Section
202 1.1) Header : up to 5 bytes
203 flags:
204 00 compressed by Huff0
205 01 is Raw (uncompressed)
206 10 is Rle
207 11 unused
208 Note : using 11 for Huff0 with precomputed table ?
209 Note : delta map ? => compressed ?
210 Note 2 : 19 bits for sizes, seems a bit larger than necessary
211 Note 3 : RLE blocks ?
212
213 1.2.1) Huff0 block, using sizes from header
214 See Huff0 format
215
216 1.2.2) Huff0 block, using precomputed DTable
217 _usingDTable variants
218
219 1.2.3) uncompressed blocks
220 as the name says (both 2 or 3 bytes variants)
221
222 2) Sequences section
223 TO DO
224*/
225
226
Yann Collet88fcd292015-11-25 14:42:45 +0100227/** ZSTD_decodeFrameHeader_Part1
228* decode the 1st part of the Frame Header, which tells Frame Header size.
229* srcSize must be == ZSTD_frameHeaderSize_min
230* @return : the full size of the Frame Header */
231static size_t ZSTD_decodeFrameHeader_Part1(ZSTD_DCtx* zc, const void* src, size_t srcSize)
232{
233 U32 magicNumber;
234 if (srcSize != ZSTD_frameHeaderSize_min) return ERROR(srcSize_wrong);
235 magicNumber = MEM_readLE32(src);
236 if (magicNumber != ZSTD_MAGICNUMBER) return ERROR(prefix_unknown);
237 zc->headerSize = ZSTD_frameHeaderSize_min;
238 return zc->headerSize;
239}
240
Yann Collet88fcd292015-11-25 14:42:45 +0100241
242size_t ZSTD_getFrameParams(ZSTD_parameters* params, const void* src, size_t srcSize)
243{
244 U32 magicNumber;
245 if (srcSize < ZSTD_frameHeaderSize_min) return ZSTD_frameHeaderSize_max;
246 magicNumber = MEM_readLE32(src);
247 if (magicNumber != ZSTD_MAGICNUMBER) return ERROR(prefix_unknown);
248 memset(params, 0, sizeof(*params));
Yann Collet26415d32015-11-26 12:43:28 +0100249 params->windowLog = (((const BYTE*)src)[4] & 15) + ZSTD_WINDOWLOG_ABSOLUTEMIN;
Yann Colletbf7aa3c2015-11-28 18:19:44 +0100250 if ((((const BYTE*)src)[4] >> 4) != 0) return ERROR(frameParameter_unsupported); /* reserved bits */
Yann Collet88fcd292015-11-25 14:42:45 +0100251 return 0;
252}
253
Yann Collet26415d32015-11-26 12:43:28 +0100254/** ZSTD_decodeFrameHeader_Part2
255* decode the full Frame Header
256* srcSize must be the size provided by ZSTD_decodeFrameHeader_Part1
257* @return : 0, or an error code, which can be tested using ZSTD_isError() */
258static size_t ZSTD_decodeFrameHeader_Part2(ZSTD_DCtx* zc, const void* src, size_t srcSize)
259{
Yann Collet00fd7a22015-11-28 16:03:22 +0100260 size_t result;
Yann Collet26415d32015-11-26 12:43:28 +0100261 if (srcSize != zc->headerSize) return ERROR(srcSize_wrong);
Yann Collet00fd7a22015-11-28 16:03:22 +0100262 result = ZSTD_getFrameParams(&(zc->params), src, srcSize);
263 if ((MEM_32bits()) && (zc->params.windowLog > 25)) return ERROR(frameParameter_unsupportedBy32bitsImplementation);
264 return result;
Yann Collet26415d32015-11-26 12:43:28 +0100265}
266
Yann Collet5be2dd22015-11-11 13:43:58 +0100267
268size_t ZSTD_getcBlockSize(const void* src, size_t srcSize, blockProperties_t* bpPtr)
269{
270 const BYTE* const in = (const BYTE* const)src;
271 BYTE headerFlags;
272 U32 cSize;
273
274 if (srcSize < 3) return ERROR(srcSize_wrong);
275
276 headerFlags = *in;
277 cSize = in[2] + (in[1]<<8) + ((in[0] & 7)<<16);
278
279 bpPtr->blockType = (blockType_t)(headerFlags >> 6);
280 bpPtr->origSize = (bpPtr->blockType == bt_rle) ? cSize : 0;
281
282 if (bpPtr->blockType == bt_end) return 0;
283 if (bpPtr->blockType == bt_rle) return 1;
284 return cSize;
285}
286
Yann Collet59d1f792016-01-23 19:28:41 +0100287
Yann Collet0f366c62015-11-12 16:19:30 +0100288static size_t ZSTD_copyRawBlock(void* dst, size_t maxDstSize, const void* src, size_t srcSize)
Yann Collet5be2dd22015-11-11 13:43:58 +0100289{
290 if (srcSize > maxDstSize) return ERROR(dstSize_tooSmall);
291 memcpy(dst, src, srcSize);
292 return srcSize;
293}
294
295
Yann Collet5be2dd22015-11-11 13:43:58 +0100296/** ZSTD_decodeLiteralsBlock
Yann Collet14983e72015-11-11 21:38:21 +0100297 @return : nb of bytes read from src (< srcSize ) */
Yann Collet5b78d2f2015-11-12 15:36:05 +0100298size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx,
Yann Collet5be2dd22015-11-11 13:43:58 +0100299 const void* src, size_t srcSize) /* note : srcSize < BLOCKSIZE */
300{
Yann Collet5be2dd22015-11-11 13:43:58 +0100301 const BYTE* const istart = (const BYTE*) src;
302
303 /* any compressed block with literals segment must be at least this size */
304 if (srcSize < MIN_CBLOCK_SIZE) return ERROR(corruption_detected);
305
Yann Collet59d1f792016-01-23 19:28:41 +0100306 switch(istart[0]>> 6)
Yann Collet5be2dd22015-11-11 13:43:58 +0100307 {
Yann Collet59d1f792016-01-23 19:28:41 +0100308 case IS_HUF:
Yann Collet5be2dd22015-11-11 13:43:58 +0100309 {
Yann Colletafe07092016-01-25 04:10:46 +0100310 size_t litSize, litCSize, singleStream=0;
Yann Collet59d1f792016-01-23 19:28:41 +0100311 U32 lhSize = ((istart[0]) >> 4) & 3;
312 switch(lhSize)
313 {
314 case 0: case 1: default: /* note : default is impossible, since lhSize into [0..3] */
315 /* 2 - 2 - 10 - 10 */
316 lhSize=3;
Yann Colletafe07092016-01-25 04:10:46 +0100317 singleStream = istart[0] & 16;
Yann Collet59d1f792016-01-23 19:28:41 +0100318 litSize = ((istart[0] & 15) << 6) + (istart[1] >> 2);
319 litCSize = ((istart[1] & 3) << 8) + istart[2];
320 break;
321 case 2:
322 /* 2 - 2 - 14 - 14 */
323 lhSize=4;
324 litSize = ((istart[0] & 15) << 10) + (istart[1] << 2) + (istart[2] >> 6);
325 litCSize = ((istart[2] & 63) << 8) + istart[3];
326 break;
327 case 3:
328 /* 2 - 2 - 18 - 18 */
329 lhSize=5;
330 litSize = ((istart[0] & 15) << 14) + (istart[1] << 6) + (istart[2] >> 2);
331 litCSize = ((istart[2] & 3) << 16) + (istart[3] << 8) + istart[4];
332 break;
333 }
Yann Collet37422192016-01-25 16:54:05 +0100334 if (litSize > BLOCKSIZE) return ERROR(corruption_detected);;
Yann Collet59d1f792016-01-23 19:28:41 +0100335
Yann Colletafe07092016-01-25 04:10:46 +0100336 if (HUF_isError(singleStream ?
337 HUF_decompress1X2(dctx->litBuffer, litSize, istart+lhSize, litCSize) :
338 HUF_decompress (dctx->litBuffer, litSize, istart+lhSize, litCSize) ))
Yann Collet59d1f792016-01-23 19:28:41 +0100339 return ERROR(corruption_detected);
340
Yann Collet5be2dd22015-11-11 13:43:58 +0100341 dctx->litPtr = dctx->litBuffer;
342 dctx->litBufSize = BLOCKSIZE+8;
343 dctx->litSize = litSize;
Yann Collet59d1f792016-01-23 19:28:41 +0100344 return litCSize + lhSize;
Yann Collet5be2dd22015-11-11 13:43:58 +0100345 }
Yann Colletb923f652016-01-26 03:14:20 +0100346 case IS_PCH:
347 {
348 size_t errorCode;
349 size_t litSize, litCSize;
350 U32 lhSize = ((istart[0]) >> 4) & 3;
351 if (lhSize != 1) /* only case supported for now : small litSize, single stream */
352 return ERROR(corruption_detected);
Yann Collet7b51a292016-01-26 15:58:49 +0100353 if (!dctx->flagHufTable)
354 return ERROR(dictionary_corrupted);
Yann Colletb923f652016-01-26 03:14:20 +0100355
356 /* 2 - 2 - 10 - 10 */
357 lhSize=3;
358 litSize = ((istart[0] & 15) << 6) + (istart[1] >> 2);
359 litCSize = ((istart[1] & 3) << 8) + istart[2];
360
361 errorCode = HUF_decompress1X4_usingDTable(dctx->litBuffer, litSize, istart+lhSize, litCSize, dctx->hufTableX4);
362 if (HUF_isError(errorCode)) return ERROR(corruption_detected);
363
364 dctx->litPtr = dctx->litBuffer;
365 dctx->litBufSize = BLOCKSIZE+WILDCOPY_OVERLENGTH;
366 dctx->litSize = litSize;
367 return litCSize + lhSize;
368 }
Yann Collet5be2dd22015-11-11 13:43:58 +0100369 case IS_RAW:
370 {
Yann Collet59d1f792016-01-23 19:28:41 +0100371 size_t litSize;
372 U32 lhSize = ((istart[0]) >> 4) & 3;
373 switch(lhSize)
Yann Collet5be2dd22015-11-11 13:43:58 +0100374 {
Yann Collet59d1f792016-01-23 19:28:41 +0100375 case 0: case 1: default: /* note : default is impossible, since lhSize into [0..3] */
376 lhSize=1;
377 litSize = istart[0] & 31;
378 break;
379 case 2:
380 litSize = ((istart[0] & 15) << 8) + istart[1];
381 break;
382 case 3:
383 litSize = ((istart[0] & 15) << 16) + (istart[1] << 8) + istart[2];
384 break;
385 }
386
Yann Colletbc4c8aa2016-01-25 17:26:01 +0100387 if (litSize+WILDCOPY_OVERLENGTH > srcSize) /* risk reading beyond src buffer with wildcopy */
Yann Collet59d1f792016-01-23 19:28:41 +0100388 {
Yann Collet37422192016-01-25 16:54:05 +0100389 if (litSize > srcSize-lhSize) return ERROR(corruption_detected);
Yann Collet59d1f792016-01-23 19:28:41 +0100390 memcpy(dctx->litBuffer, istart+lhSize, litSize);
Yann Collet5be2dd22015-11-11 13:43:58 +0100391 dctx->litPtr = dctx->litBuffer;
392 dctx->litBufSize = BLOCKSIZE+8;
393 dctx->litSize = litSize;
Yann Colletbc4c8aa2016-01-25 17:26:01 +0100394 return lhSize+litSize;
Yann Collet5be2dd22015-11-11 13:43:58 +0100395 }
396 /* direct reference into compressed stream */
Yann Collet59d1f792016-01-23 19:28:41 +0100397 dctx->litPtr = istart+lhSize;
398 dctx->litBufSize = srcSize-lhSize;
Yann Collet5be2dd22015-11-11 13:43:58 +0100399 dctx->litSize = litSize;
Yann Collet59d1f792016-01-23 19:28:41 +0100400 return lhSize+litSize;
401 }
Yann Collet5be2dd22015-11-11 13:43:58 +0100402 case IS_RLE:
403 {
Yann Collet59d1f792016-01-23 19:28:41 +0100404 size_t litSize;
405 U32 lhSize = ((istart[0]) >> 4) & 3;
406 switch(lhSize)
407 {
408 case 0: case 1: default: /* note : default is impossible, since lhSize into [0..3] */
409 lhSize = 1;
410 litSize = istart[0] & 31;
411 break;
412 case 2:
413 litSize = ((istart[0] & 15) << 8) + istart[1];
414 break;
415 case 3:
416 litSize = ((istart[0] & 15) << 16) + (istart[1] << 8) + istart[2];
417 break;
418 }
Yann Collet5be2dd22015-11-11 13:43:58 +0100419 if (litSize > BLOCKSIZE) return ERROR(corruption_detected);
Yann Collet59d1f792016-01-23 19:28:41 +0100420 memset(dctx->litBuffer, istart[lhSize], litSize);
Yann Collet5be2dd22015-11-11 13:43:58 +0100421 dctx->litPtr = dctx->litBuffer;
Yann Colletb923f652016-01-26 03:14:20 +0100422 dctx->litBufSize = BLOCKSIZE+WILDCOPY_OVERLENGTH;
Yann Collet5be2dd22015-11-11 13:43:58 +0100423 dctx->litSize = litSize;
Yann Collet59d1f792016-01-23 19:28:41 +0100424 return lhSize+1;
Yann Collet5be2dd22015-11-11 13:43:58 +0100425 }
Yann Colletb923f652016-01-26 03:14:20 +0100426 default:
427 return ERROR(corruption_detected); /* impossible */
Yann Collet5be2dd22015-11-11 13:43:58 +0100428 }
429}
430
431
432size_t ZSTD_decodeSeqHeaders(int* nbSeq, const BYTE** dumpsPtr, size_t* dumpsLengthPtr,
433 FSE_DTable* DTableLL, FSE_DTable* DTableML, FSE_DTable* DTableOffb,
434 const void* src, size_t srcSize)
435{
436 const BYTE* const istart = (const BYTE* const)src;
437 const BYTE* ip = istart;
438 const BYTE* const iend = istart + srcSize;
439 U32 LLtype, Offtype, MLtype;
440 U32 LLlog, Offlog, MLlog;
441 size_t dumpsLength;
442
443 /* check */
444 if (srcSize < 5) return ERROR(srcSize_wrong);
445
446 /* SeqHead */
447 *nbSeq = MEM_readLE16(ip); ip+=2;
448 LLtype = *ip >> 6;
449 Offtype = (*ip >> 4) & 3;
450 MLtype = (*ip >> 2) & 3;
451 if (*ip & 2)
452 {
453 dumpsLength = ip[2];
454 dumpsLength += ip[1] << 8;
455 ip += 3;
456 }
457 else
458 {
459 dumpsLength = ip[1];
460 dumpsLength += (ip[0] & 1) << 8;
461 ip += 2;
462 }
463 *dumpsPtr = ip;
464 ip += dumpsLength;
465 *dumpsLengthPtr = dumpsLength;
466
467 /* check */
468 if (ip > iend-3) return ERROR(srcSize_wrong); /* min : all 3 are "raw", hence no header, but at least xxLog bits per type */
469
470 /* sequences */
471 {
Yann Collet82368cf2015-11-16 19:10:56 +0100472 S16 norm[MaxML+1]; /* assumption : MaxML >= MaxLL >= MaxOff */
Yann Collet5be2dd22015-11-11 13:43:58 +0100473 size_t headerSize;
474
475 /* Build DTables */
476 switch(LLtype)
477 {
478 U32 max;
479 case bt_rle :
480 LLlog = 0;
481 FSE_buildDTable_rle(DTableLL, *ip++); break;
482 case bt_raw :
483 LLlog = LLbits;
484 FSE_buildDTable_raw(DTableLL, LLbits); break;
485 default :
486 max = MaxLL;
487 headerSize = FSE_readNCount(norm, &max, &LLlog, ip, iend-ip);
488 if (FSE_isError(headerSize)) return ERROR(GENERIC);
489 if (LLlog > LLFSELog) return ERROR(corruption_detected);
490 ip += headerSize;
491 FSE_buildDTable(DTableLL, norm, max, LLlog);
492 }
493
494 switch(Offtype)
495 {
496 U32 max;
497 case bt_rle :
498 Offlog = 0;
499 if (ip > iend-2) return ERROR(srcSize_wrong); /* min : "raw", hence no header, but at least xxLog bits */
500 FSE_buildDTable_rle(DTableOffb, *ip++ & MaxOff); /* if *ip > MaxOff, data is corrupted */
501 break;
502 case bt_raw :
503 Offlog = Offbits;
504 FSE_buildDTable_raw(DTableOffb, Offbits); break;
505 default :
506 max = MaxOff;
507 headerSize = FSE_readNCount(norm, &max, &Offlog, ip, iend-ip);
508 if (FSE_isError(headerSize)) return ERROR(GENERIC);
509 if (Offlog > OffFSELog) return ERROR(corruption_detected);
510 ip += headerSize;
511 FSE_buildDTable(DTableOffb, norm, max, Offlog);
512 }
513
514 switch(MLtype)
515 {
516 U32 max;
517 case bt_rle :
518 MLlog = 0;
519 if (ip > iend-2) return ERROR(srcSize_wrong); /* min : "raw", hence no header, but at least xxLog bits */
520 FSE_buildDTable_rle(DTableML, *ip++); break;
521 case bt_raw :
522 MLlog = MLbits;
523 FSE_buildDTable_raw(DTableML, MLbits); break;
524 default :
525 max = MaxML;
526 headerSize = FSE_readNCount(norm, &max, &MLlog, ip, iend-ip);
527 if (FSE_isError(headerSize)) return ERROR(GENERIC);
528 if (MLlog > MLFSELog) return ERROR(corruption_detected);
529 ip += headerSize;
530 FSE_buildDTable(DTableML, norm, max, MLlog);
531 }
532 }
533
534 return ip-istart;
535}
536
537
538typedef struct {
539 size_t litLength;
540 size_t offset;
541 size_t matchLength;
542} seq_t;
543
544typedef struct {
545 BIT_DStream_t DStream;
546 FSE_DState_t stateLL;
547 FSE_DState_t stateOffb;
548 FSE_DState_t stateML;
549 size_t prevOffset;
550 const BYTE* dumps;
551 const BYTE* dumpsEnd;
552} seqState_t;
553
554
555static void ZSTD_decodeSequence(seq_t* seq, seqState_t* seqState)
556{
557 size_t litLength;
558 size_t prevOffset;
559 size_t offset;
560 size_t matchLength;
561 const BYTE* dumps = seqState->dumps;
562 const BYTE* const de = seqState->dumpsEnd;
563
564 /* Literal length */
565 litLength = FSE_decodeSymbol(&(seqState->stateLL), &(seqState->DStream));
Yann Collete4fdad52015-11-25 21:09:17 +0100566 prevOffset = litLength ? seq->offset : seqState->prevOffset;
Yann Collet5be2dd22015-11-11 13:43:58 +0100567 if (litLength == MaxLL)
568 {
569 U32 add = *dumps++;
570 if (add < 255) litLength += add;
571 else
572 {
573 litLength = MEM_readLE32(dumps) & 0xFFFFFF; /* no pb : dumps is always followed by seq tables > 1 byte */
574 dumps += 3;
575 }
576 if (dumps >= de) dumps = de-1; /* late correction, to avoid read overflow (data is now corrupted anyway) */
577 }
578
579 /* Offset */
580 {
581 static const U32 offsetPrefix[MaxOff+1] = {
582 1 /*fake*/, 1, 2, 4, 8, 16, 32, 64, 128, 256,
583 512, 1024, 2048, 4096, 8192, 16384, 32768, 65536, 131072, 262144,
584 524288, 1048576, 2097152, 4194304, 8388608, 16777216, 33554432, /*fake*/ 1, 1, 1, 1, 1 };
585 U32 offsetCode, nbBits;
586 offsetCode = FSE_decodeSymbol(&(seqState->stateOffb), &(seqState->DStream)); /* <= maxOff, by table construction */
587 if (MEM_32bits()) BIT_reloadDStream(&(seqState->DStream));
588 nbBits = offsetCode - 1;
589 if (offsetCode==0) nbBits = 0; /* cmove */
590 offset = offsetPrefix[offsetCode] + BIT_readBits(&(seqState->DStream), nbBits);
591 if (MEM_32bits()) BIT_reloadDStream(&(seqState->DStream));
592 if (offsetCode==0) offset = prevOffset; /* cmove */
Yann Collet55aa7f92015-11-20 12:04:52 +0100593 if (offsetCode | !litLength) seqState->prevOffset = seq->offset; /* cmove */
Yann Collet5be2dd22015-11-11 13:43:58 +0100594 }
595
596 /* MatchLength */
597 matchLength = FSE_decodeSymbol(&(seqState->stateML), &(seqState->DStream));
598 if (matchLength == MaxML)
599 {
600 U32 add = *dumps++;
601 if (add < 255) matchLength += add;
602 else
603 {
604 matchLength = MEM_readLE32(dumps) & 0xFFFFFF; /* no pb : dumps is always followed by seq tables > 1 byte */
605 dumps += 3;
606 }
607 if (dumps >= de) dumps = de-1; /* late correction, to avoid read overflow (data is now corrupted anyway) */
608 }
609 matchLength += MINMATCH;
610
611 /* save result */
612 seq->litLength = litLength;
613 seq->offset = offset;
614 seq->matchLength = matchLength;
615 seqState->dumps = dumps;
616}
617
618
Yann Collet5b78d2f2015-11-12 15:36:05 +0100619FORCE_INLINE size_t ZSTD_execSequence(BYTE* op,
Yann Colletb3a2af92015-11-19 17:13:19 +0100620 BYTE* const oend, seq_t sequence,
Yann Collet5be2dd22015-11-11 13:43:58 +0100621 const BYTE** litPtr, const BYTE* const litLimit_8,
Yann Collet417890c2015-12-04 17:16:37 +0100622 const BYTE* const base, const BYTE* const vBase, const BYTE* const dictEnd)
Yann Collet5be2dd22015-11-11 13:43:58 +0100623{
Yann Colletb3a2af92015-11-19 17:13:19 +0100624 static const int dec32table[] = { 0, 1, 2, 1, 4, 4, 4, 4 }; /* added */
625 static const int dec64table[] = { 8, 8, 8, 7, 8, 9,10,11 }; /* substracted */
Yann Collet5be2dd22015-11-11 13:43:58 +0100626 BYTE* const oLitEnd = op + sequence.litLength;
Yann Colletb3a2af92015-11-19 17:13:19 +0100627 const size_t sequenceLength = sequence.litLength + sequence.matchLength;
628 BYTE* const oMatchEnd = op + sequenceLength; /* risk : address space overflow (32-bits) */
Yann Collet5be2dd22015-11-11 13:43:58 +0100629 BYTE* const oend_8 = oend-8;
630 const BYTE* const litEnd = *litPtr + sequence.litLength;
Yann Colletb3a2af92015-11-19 17:13:19 +0100631 const BYTE* match = oLitEnd - sequence.offset;
Yann Collet5be2dd22015-11-11 13:43:58 +0100632
633 /* check */
634 if (oLitEnd > oend_8) return ERROR(dstSize_tooSmall); /* last match must start at a minimum distance of 8 from oend */
635 if (oMatchEnd > oend) return ERROR(dstSize_tooSmall); /* overwrite beyond dst buffer */
636 if (litEnd > litLimit_8) return ERROR(corruption_detected); /* risk read beyond lit buffer */
637
638 /* copy Literals */
639 ZSTD_wildcopy(op, *litPtr, sequence.litLength); /* note : oLitEnd <= oend-8 : no risk of overwrite beyond oend */
640 op = oLitEnd;
641 *litPtr = litEnd; /* update for next sequence */
642
643 /* copy Match */
Yann Collet7b51a292016-01-26 15:58:49 +0100644 if (sequence.offset > (size_t)(oLitEnd - base)) {
Yann Collet44287a32015-11-30 23:13:56 +0100645 /* offset beyond prefix */
Yann Collet9f5ab1a2015-12-11 00:27:41 +0100646 if (sequence.offset > (size_t)(oLitEnd - vBase))
647 return ERROR(corruption_detected);
Yann Collet44287a32015-11-30 23:13:56 +0100648 match = dictEnd - (base-match);
Yann Collet7b51a292016-01-26 15:58:49 +0100649 if (match + sequence.matchLength <= dictEnd) {
Yann Collet4bfe4152015-12-06 13:18:37 +0100650 memmove(oLitEnd, match, sequence.matchLength);
Yann Collet44287a32015-11-30 23:13:56 +0100651 return sequenceLength;
652 }
653 /* span extDict & currentPrefixSegment */
654 {
655 size_t length1 = dictEnd - match;
Yann Collet4bfe4152015-12-06 13:18:37 +0100656 memmove(oLitEnd, match, length1);
Yann Collet44287a32015-11-30 23:13:56 +0100657 op = oLitEnd + length1;
658 sequence.matchLength -= length1;
659 match = base;
660 }
661 }
Yann Collet0f366c62015-11-12 16:19:30 +0100662
Yann Collet44287a32015-11-30 23:13:56 +0100663 /* match within prefix */
Yann Collet7b51a292016-01-26 15:58:49 +0100664 if (sequence.offset < 8) {
Yann Collet44287a32015-11-30 23:13:56 +0100665 /* close range match, overlap */
666 const int sub2 = dec64table[sequence.offset];
667 op[0] = match[0];
668 op[1] = match[1];
669 op[2] = match[2];
670 op[3] = match[3];
671 match += dec32table[sequence.offset];
672 ZSTD_copy4(op+4, match);
673 match -= sub2;
674 }
Yann Collet7b51a292016-01-26 15:58:49 +0100675 else {
Yann Collet44287a32015-11-30 23:13:56 +0100676 ZSTD_copy8(op, match);
677 }
678 op += 8; match += 8;
Yann Collet5be2dd22015-11-11 13:43:58 +0100679
Yann Collet7b51a292016-01-26 15:58:49 +0100680 if (oMatchEnd > oend-12) {
681 if (op < oend_8) {
Yann Collet44287a32015-11-30 23:13:56 +0100682 ZSTD_wildcopy(op, match, oend_8 - op);
683 match += oend_8 - op;
684 op = oend_8;
685 }
686 while (op < oMatchEnd) *op++ = *match++;
687 }
Yann Collet7b51a292016-01-26 15:58:49 +0100688 else {
Yann Collet44287a32015-11-30 23:13:56 +0100689 ZSTD_wildcopy(op, match, sequence.matchLength-8); /* works even if matchLength < 8 */
690 }
691 return sequenceLength;
Yann Collet5be2dd22015-11-11 13:43:58 +0100692}
693
Yann Colletb3a2af92015-11-19 17:13:19 +0100694
Yann Collet5be2dd22015-11-11 13:43:58 +0100695static size_t ZSTD_decompressSequences(
Yann Collet5b78d2f2015-11-12 15:36:05 +0100696 ZSTD_DCtx* dctx,
Yann Collet5be2dd22015-11-11 13:43:58 +0100697 void* dst, size_t maxDstSize,
698 const void* seqStart, size_t seqSize)
699{
Yann Collet5be2dd22015-11-11 13:43:58 +0100700 const BYTE* ip = (const BYTE*)seqStart;
701 const BYTE* const iend = ip + seqSize;
702 BYTE* const ostart = (BYTE* const)dst;
703 BYTE* op = ostart;
704 BYTE* const oend = ostart + maxDstSize;
705 size_t errorCode, dumpsLength;
706 const BYTE* litPtr = dctx->litPtr;
707 const BYTE* const litLimit_8 = litPtr + dctx->litBufSize - 8;
708 const BYTE* const litEnd = litPtr + dctx->litSize;
709 int nbSeq;
710 const BYTE* dumps;
711 U32* DTableLL = dctx->LLTable;
712 U32* DTableML = dctx->MLTable;
713 U32* DTableOffb = dctx->OffTable;
Yann Collet417890c2015-12-04 17:16:37 +0100714 const BYTE* const base = (const BYTE*) (dctx->base);
715 const BYTE* const vBase = (const BYTE*) (dctx->vBase);
716 const BYTE* const dictEnd = (const BYTE*) (dctx->dictEnd);
Yann Collet5be2dd22015-11-11 13:43:58 +0100717
718 /* Build Decoding Tables */
719 errorCode = ZSTD_decodeSeqHeaders(&nbSeq, &dumps, &dumpsLength,
720 DTableLL, DTableML, DTableOffb,
721 ip, iend-ip);
722 if (ZSTD_isError(errorCode)) return errorCode;
723 ip += errorCode;
724
725 /* Regen sequences */
726 {
727 seq_t sequence;
728 seqState_t seqState;
729
730 memset(&sequence, 0, sizeof(sequence));
731 sequence.offset = 4;
732 seqState.dumps = dumps;
733 seqState.dumpsEnd = dumps + dumpsLength;
734 seqState.prevOffset = 4;
735 errorCode = BIT_initDStream(&(seqState.DStream), ip, iend-ip);
736 if (ERR_isError(errorCode)) return ERROR(corruption_detected);
737 FSE_initDState(&(seqState.stateLL), &(seqState.DStream), DTableLL);
738 FSE_initDState(&(seqState.stateOffb), &(seqState.DStream), DTableOffb);
739 FSE_initDState(&(seqState.stateML), &(seqState.DStream), DTableML);
740
Yann Collet7b51a292016-01-26 15:58:49 +0100741 for ( ; (BIT_reloadDStream(&(seqState.DStream)) <= BIT_DStream_completed) && nbSeq ; ) {
Yann Colletb3a2af92015-11-19 17:13:19 +0100742 size_t oneSeqSize;
743 nbSeq--;
744 ZSTD_decodeSequence(&sequence, &seqState);
745 oneSeqSize = ZSTD_execSequence(op, oend, sequence, &litPtr, litLimit_8, base, vBase, dictEnd);
Yann Collet5be2dd22015-11-11 13:43:58 +0100746 if (ZSTD_isError(oneSeqSize)) return oneSeqSize;
747 op += oneSeqSize;
748 }
749
750 /* check if reached exact end */
Yann Collet44287a32015-11-30 23:13:56 +0100751 if ( !BIT_endOfDStream(&(seqState.DStream)) ) return ERROR(corruption_detected); /* DStream should be entirely and exactly consumed; otherwise data is corrupted */
Yann Collet5be2dd22015-11-11 13:43:58 +0100752
753 /* last literal segment */
754 {
755 size_t lastLLSize = litEnd - litPtr;
756 if (litPtr > litEnd) return ERROR(corruption_detected);
757 if (op+lastLLSize > oend) return ERROR(dstSize_tooSmall);
758 if (op != litPtr) memcpy(op, litPtr, lastLLSize);
759 op += lastLLSize;
760 }
761 }
762
763 return op-ostart;
764}
765
766
Yann Colletb0125102016-01-09 02:00:10 +0100767static void ZSTD_checkContinuity(ZSTD_DCtx* dctx, const void* dst)
768{
Yann Collet7b51a292016-01-26 15:58:49 +0100769 if (dst != dctx->previousDstEnd) { /* not contiguous */
Yann Colletb0125102016-01-09 02:00:10 +0100770 dctx->dictEnd = dctx->previousDstEnd;
771 dctx->vBase = (const char*)dst - ((const char*)(dctx->previousDstEnd) - (const char*)(dctx->base));
772 dctx->base = dst;
773 dctx->previousDstEnd = dst;
774 }
775}
776
777
778static size_t ZSTD_decompressBlock_internal(ZSTD_DCtx* dctx,
Yann Collet5be2dd22015-11-11 13:43:58 +0100779 void* dst, size_t maxDstSize,
780 const void* src, size_t srcSize)
781{
782 /* blockType == blockCompressed */
783 const BYTE* ip = (const BYTE*)src;
784
785 /* Decode literals sub-block */
Yann Collet5b78d2f2015-11-12 15:36:05 +0100786 size_t litCSize = ZSTD_decodeLiteralsBlock(dctx, src, srcSize);
Yann Collet5be2dd22015-11-11 13:43:58 +0100787 if (ZSTD_isError(litCSize)) return litCSize;
788 ip += litCSize;
789 srcSize -= litCSize;
790
Yann Collet5b78d2f2015-11-12 15:36:05 +0100791 return ZSTD_decompressSequences(dctx, dst, maxDstSize, ip, srcSize);
Yann Collet5be2dd22015-11-11 13:43:58 +0100792}
793
794
Yann Colletb0125102016-01-09 02:00:10 +0100795size_t ZSTD_decompressBlock(ZSTD_DCtx* dctx,
796 void* dst, size_t maxDstSize,
797 const void* src, size_t srcSize)
798{
799 ZSTD_checkContinuity(dctx, dst);
800 return ZSTD_decompressBlock_internal(dctx, dst, maxDstSize, src, srcSize);
801}
802
803
Yann Collet7b51a292016-01-26 15:58:49 +0100804/*! ZSTD_decompress_continueDCtx
805* dctx must have been properly initialized */
806static size_t ZSTD_decompress_continueDCtx(ZSTD_DCtx* dctx,
Yann Collet31683c02015-12-18 01:26:48 +0100807 void* dst, size_t maxDstSize,
Yann Collet7b51a292016-01-26 15:58:49 +0100808 const void* src, size_t srcSize)
Yann Collet5be2dd22015-11-11 13:43:58 +0100809{
810 const BYTE* ip = (const BYTE*)src;
811 const BYTE* iend = ip + srcSize;
812 BYTE* const ostart = (BYTE* const)dst;
813 BYTE* op = ostart;
814 BYTE* const oend = ostart + maxDstSize;
815 size_t remainingSize = srcSize;
Yann Collet5be2dd22015-11-11 13:43:58 +0100816 blockProperties_t blockProperties;
817
818 /* Frame Header */
Yann Collet88fcd292015-11-25 14:42:45 +0100819 {
820 size_t frameHeaderSize;
821 if (srcSize < ZSTD_frameHeaderSize_min+ZSTD_blockHeaderSize) return ERROR(srcSize_wrong);
Yann Collet5be2dd22015-11-11 13:43:58 +0100822#if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT==1)
Yann Collet88fcd292015-11-25 14:42:45 +0100823 {
824 const U32 magicNumber = MEM_readLE32(src);
825 if (ZSTD_isLegacy(magicNumber))
826 return ZSTD_decompressLegacy(dst, maxDstSize, src, srcSize, magicNumber);
827 }
Yann Collet5be2dd22015-11-11 13:43:58 +0100828#endif
Yann Collet37422192016-01-25 16:54:05 +0100829 frameHeaderSize = ZSTD_decodeFrameHeader_Part1(dctx, src, ZSTD_frameHeaderSize_min);
Yann Collet88fcd292015-11-25 14:42:45 +0100830 if (ZSTD_isError(frameHeaderSize)) return frameHeaderSize;
831 if (srcSize < frameHeaderSize+ZSTD_blockHeaderSize) return ERROR(srcSize_wrong);
832 ip += frameHeaderSize; remainingSize -= frameHeaderSize;
Yann Collet37422192016-01-25 16:54:05 +0100833 frameHeaderSize = ZSTD_decodeFrameHeader_Part2(dctx, src, frameHeaderSize);
Yann Collet88fcd292015-11-25 14:42:45 +0100834 if (ZSTD_isError(frameHeaderSize)) return frameHeaderSize;
835 }
Yann Collet5be2dd22015-11-11 13:43:58 +0100836
837 /* Loop on each block */
838 while (1)
839 {
840 size_t decodedSize=0;
841 size_t cBlockSize = ZSTD_getcBlockSize(ip, iend-ip, &blockProperties);
842 if (ZSTD_isError(cBlockSize)) return cBlockSize;
843
844 ip += ZSTD_blockHeaderSize;
845 remainingSize -= ZSTD_blockHeaderSize;
846 if (cBlockSize > remainingSize) return ERROR(srcSize_wrong);
847
848 switch(blockProperties.blockType)
849 {
850 case bt_compressed:
Yann Collet37422192016-01-25 16:54:05 +0100851 decodedSize = ZSTD_decompressBlock_internal(dctx, op, oend-op, ip, cBlockSize);
Yann Collet5be2dd22015-11-11 13:43:58 +0100852 break;
853 case bt_raw :
Yann Collet0f366c62015-11-12 16:19:30 +0100854 decodedSize = ZSTD_copyRawBlock(op, oend-op, ip, cBlockSize);
Yann Collet5be2dd22015-11-11 13:43:58 +0100855 break;
856 case bt_rle :
857 return ERROR(GENERIC); /* not yet supported */
858 break;
859 case bt_end :
860 /* end of frame */
861 if (remainingSize) return ERROR(srcSize_wrong);
862 break;
863 default:
864 return ERROR(GENERIC); /* impossible */
865 }
866 if (cBlockSize == 0) break; /* bt_end */
867
868 if (ZSTD_isError(decodedSize)) return decodedSize;
869 op += decodedSize;
870 ip += cBlockSize;
871 remainingSize -= cBlockSize;
872 }
873
874 return op-ostart;
875}
876
Yann Collet31683c02015-12-18 01:26:48 +0100877
Yann Collet7b51a292016-01-26 15:58:49 +0100878size_t ZSTD_decompress_usingPreparedDCtx(ZSTD_DCtx* dctx, const ZSTD_DCtx* refDCtx,
879 void* dst, size_t maxDstSize,
880 const void* src, size_t srcSize)
881{
882 ZSTD_copyDCtx(dctx, refDCtx);
883 ZSTD_checkContinuity(dctx, dst);
884 return ZSTD_decompress_continueDCtx(dctx, dst, maxDstSize, src, srcSize);
885}
886
887
888size_t ZSTD_decompress_usingDict(ZSTD_DCtx* dctx,
889 void* dst, size_t maxDstSize,
890 const void* src, size_t srcSize,
891 const void* dict, size_t dictSize)
892{
893 ZSTD_decompressBegin_usingDict(dctx, dict, dictSize);
894 ZSTD_checkContinuity(dctx, dst);
895 return ZSTD_decompress_continueDCtx(dctx, dst, maxDstSize, src, srcSize);
896}
897
898
Yann Collet31683c02015-12-18 01:26:48 +0100899size_t ZSTD_decompressDCtx(ZSTD_DCtx* dctx, void* dst, size_t maxDstSize, const void* src, size_t srcSize)
900{
901 return ZSTD_decompress_usingDict(dctx, dst, maxDstSize, src, srcSize, NULL, 0);
902}
903
Yann Collet5be2dd22015-11-11 13:43:58 +0100904size_t ZSTD_decompress(void* dst, size_t maxDstSize, const void* src, size_t srcSize)
905{
Yann Collet3a3b72f2016-01-11 12:56:11 +0100906#if defined(ZSTD_HEAPMODE) && (ZSTD_HEAPMODE==1)
907 size_t regenSize;
908 ZSTD_DCtx* dctx = ZSTD_createDCtx();
909 if (dctx==NULL) return ERROR(memory_allocation);
910 regenSize = ZSTD_decompressDCtx(dctx, dst, maxDstSize, src, srcSize);
911 ZSTD_freeDCtx(dctx);
912 return regenSize;
913#else
Yann Collet31683c02015-12-18 01:26:48 +0100914 ZSTD_DCtx dctx;
915 return ZSTD_decompressDCtx(&dctx, dst, maxDstSize, src, srcSize);
Yann Colleta768a302016-01-21 16:04:35 +0100916#endif
Yann Collet5be2dd22015-11-11 13:43:58 +0100917}
918
919
920/* ******************************
921* Streaming Decompression API
922********************************/
Yann Collet5be2dd22015-11-11 13:43:58 +0100923size_t ZSTD_nextSrcSizeToDecompress(ZSTD_DCtx* dctx)
924{
925 return dctx->expected;
926}
927
Yann Collet37422192016-01-25 16:54:05 +0100928size_t ZSTD_decompressContinue(ZSTD_DCtx* dctx, void* dst, size_t maxDstSize, const void* src, size_t srcSize)
Yann Collet5be2dd22015-11-11 13:43:58 +0100929{
930 /* Sanity check */
Yann Collet37422192016-01-25 16:54:05 +0100931 if (srcSize != dctx->expected) return ERROR(srcSize_wrong);
932 ZSTD_checkContinuity(dctx, dst);
Yann Collet5be2dd22015-11-11 13:43:58 +0100933
Yann Collet88fcd292015-11-25 14:42:45 +0100934 /* Decompress : frame header; part 1 */
Yann Collet37422192016-01-25 16:54:05 +0100935 switch (dctx->stage)
Yann Collet5be2dd22015-11-11 13:43:58 +0100936 {
Yann Collet88fcd292015-11-25 14:42:45 +0100937 case ZSTDds_getFrameHeaderSize :
Yann Collet5be2dd22015-11-11 13:43:58 +0100938 {
Yann Collet88fcd292015-11-25 14:42:45 +0100939 /* get frame header size */
940 if (srcSize != ZSTD_frameHeaderSize_min) return ERROR(srcSize_wrong); /* impossible */
Yann Collet37422192016-01-25 16:54:05 +0100941 dctx->headerSize = ZSTD_decodeFrameHeader_Part1(dctx, src, ZSTD_frameHeaderSize_min);
942 if (ZSTD_isError(dctx->headerSize)) return dctx->headerSize;
943 memcpy(dctx->headerBuffer, src, ZSTD_frameHeaderSize_min);
Yann Collet7b51a292016-01-26 15:58:49 +0100944 if (dctx->headerSize > ZSTD_frameHeaderSize_min) {
Yann Collet37422192016-01-25 16:54:05 +0100945 dctx->expected = dctx->headerSize - ZSTD_frameHeaderSize_min;
946 dctx->stage = ZSTDds_decodeFrameHeader;
Yann Collet88fcd292015-11-25 14:42:45 +0100947 return 0;
948 }
Yann Collet37422192016-01-25 16:54:05 +0100949 dctx->expected = 0; /* not necessary to copy more */
Yann Collet5be2dd22015-11-11 13:43:58 +0100950 }
Yann Collet88fcd292015-11-25 14:42:45 +0100951 case ZSTDds_decodeFrameHeader:
Yann Collet5be2dd22015-11-11 13:43:58 +0100952 {
Yann Collet88fcd292015-11-25 14:42:45 +0100953 /* get frame header */
954 size_t result;
Yann Collet37422192016-01-25 16:54:05 +0100955 memcpy(dctx->headerBuffer + ZSTD_frameHeaderSize_min, src, dctx->expected);
956 result = ZSTD_decodeFrameHeader_Part2(dctx, dctx->headerBuffer, dctx->headerSize);
Yann Collet88fcd292015-11-25 14:42:45 +0100957 if (ZSTD_isError(result)) return result;
Yann Collet37422192016-01-25 16:54:05 +0100958 dctx->expected = ZSTD_blockHeaderSize;
959 dctx->stage = ZSTDds_decodeBlockHeader;
Yann Collet88fcd292015-11-25 14:42:45 +0100960 return 0;
Yann Collet5be2dd22015-11-11 13:43:58 +0100961 }
Yann Collet88fcd292015-11-25 14:42:45 +0100962 case ZSTDds_decodeBlockHeader:
Yann Collet5be2dd22015-11-11 13:43:58 +0100963 {
Yann Collet88fcd292015-11-25 14:42:45 +0100964 /* Decode block header */
965 blockProperties_t bp;
966 size_t blockSize = ZSTD_getcBlockSize(src, ZSTD_blockHeaderSize, &bp);
967 if (ZSTD_isError(blockSize)) return blockSize;
Yann Collet7b51a292016-01-26 15:58:49 +0100968 if (bp.blockType == bt_end) {
Yann Collet37422192016-01-25 16:54:05 +0100969 dctx->expected = 0;
970 dctx->stage = ZSTDds_getFrameHeaderSize;
Yann Collet88fcd292015-11-25 14:42:45 +0100971 }
Yann Collet7b51a292016-01-26 15:58:49 +0100972 else {
Yann Collet37422192016-01-25 16:54:05 +0100973 dctx->expected = blockSize;
974 dctx->bType = bp.blockType;
975 dctx->stage = ZSTDds_decompressBlock;
Yann Collet88fcd292015-11-25 14:42:45 +0100976 }
Yann Collet88fcd292015-11-25 14:42:45 +0100977 return 0;
978 }
Yann Collet417890c2015-12-04 17:16:37 +0100979 case ZSTDds_decompressBlock:
Yann Collet88fcd292015-11-25 14:42:45 +0100980 {
981 /* Decompress : block content */
982 size_t rSize;
Yann Collet37422192016-01-25 16:54:05 +0100983 switch(dctx->bType)
Yann Collet88fcd292015-11-25 14:42:45 +0100984 {
985 case bt_compressed:
Yann Collet37422192016-01-25 16:54:05 +0100986 rSize = ZSTD_decompressBlock_internal(dctx, dst, maxDstSize, src, srcSize);
Yann Collet88fcd292015-11-25 14:42:45 +0100987 break;
988 case bt_raw :
989 rSize = ZSTD_copyRawBlock(dst, maxDstSize, src, srcSize);
990 break;
991 case bt_rle :
992 return ERROR(GENERIC); /* not yet handled */
993 break;
994 case bt_end : /* should never happen (filtered at phase 1) */
995 rSize = 0;
996 break;
997 default:
Yann Collet7b51a292016-01-26 15:58:49 +0100998 return ERROR(GENERIC); /* impossible */
Yann Collet88fcd292015-11-25 14:42:45 +0100999 }
Yann Collet37422192016-01-25 16:54:05 +01001000 dctx->stage = ZSTDds_decodeBlockHeader;
1001 dctx->expected = ZSTD_blockHeaderSize;
1002 dctx->previousDstEnd = (char*)dst + rSize;
Yann Collet88fcd292015-11-25 14:42:45 +01001003 return rSize;
1004 }
1005 default:
1006 return ERROR(GENERIC); /* impossible */
1007 }
Yann Collet5be2dd22015-11-11 13:43:58 +01001008}
1009
1010
Yann Colletb923f652016-01-26 03:14:20 +01001011static void ZSTD_refDictContent(ZSTD_DCtx* dctx, const void* dict, size_t dictSize)
Yann Collet417890c2015-12-04 17:16:37 +01001012{
Yann Collet37422192016-01-25 16:54:05 +01001013 dctx->dictEnd = dctx->previousDstEnd;
1014 dctx->vBase = (const char*)dict - ((const char*)(dctx->previousDstEnd) - (const char*)(dctx->base));
1015 dctx->base = dict;
1016 dctx->previousDstEnd = (const char*)dict + dictSize;
Yann Collet417890c2015-12-04 17:16:37 +01001017}
Yann Colletb923f652016-01-26 03:14:20 +01001018
Yann Colletb923f652016-01-26 03:14:20 +01001019static size_t ZSTD_loadEntropy(ZSTD_DCtx* dctx, const void* dict, size_t dictSize)
1020{
1021 size_t hSize = HUF_readDTableX4(dctx->hufTableX4, dict, dictSize);
1022 if (HUF_isError(hSize)) return ERROR(dictionary_corrupted);
Yann Collet7b51a292016-01-26 15:58:49 +01001023 dctx->flagHufTable = 1;
Yann Colletb923f652016-01-26 03:14:20 +01001024 return hSize;
1025}
1026
Yann Collet7b51a292016-01-26 15:58:49 +01001027static size_t ZSTD_decompress_insertDictionary(ZSTD_DCtx* dctx, const void* dict, size_t dictSize)
Yann Colletb923f652016-01-26 03:14:20 +01001028{
1029 size_t eSize;
1030 U32 magic = MEM_readLE32(dict);
1031 if (magic != ZSTD_DICT_MAGIC) {
1032 /* pure content mode */
1033 ZSTD_refDictContent(dctx, dict, dictSize);
1034 return 0;
1035 }
1036 /* load entropy tables */
1037 dict = (const char*)dict + 4;
1038 dictSize -= 4;
1039 eSize = ZSTD_loadEntropy(dctx, dict, dictSize);
1040 if (ZSTD_isError(eSize)) return ERROR(dictionary_corrupted);
1041
1042 /* reference dictionary content */
1043 dict = (const char*)dict + eSize;
1044 dictSize -= eSize;
1045 ZSTD_refDictContent(dctx, dict, dictSize);
1046
1047 return 0;
1048}
1049
Yann Collet7b51a292016-01-26 15:58:49 +01001050
1051size_t ZSTD_decompressBegin_usingDict(ZSTD_DCtx* dctx, const void* dict, size_t dictSize)
1052{
1053 size_t errorCode;
1054 errorCode = ZSTD_decompressBegin(dctx);
1055 if (ZSTD_isError(errorCode)) return errorCode;
1056
1057 if (dict && dictSize) {
1058 errorCode = ZSTD_decompress_insertDictionary(dctx, dict, dictSize);
1059 if (ZSTD_isError(errorCode)) return ERROR(dictionary_corrupted);
1060 }
1061
1062 return 0;
1063}
1064