blob: a0f4d2d862d6acacba9d2863ccc0ab1a6db106a2 [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 Collet417890c2015-12-04 17:16:37 +0100129 const void* previousDstEnd;
130 const void* base;
131 const void* vBase;
132 const void* dictEnd;
Yann Collet5be2dd22015-11-11 13:43:58 +0100133 size_t expected;
Yann Collet88fcd292015-11-25 14:42:45 +0100134 size_t headerSize;
135 ZSTD_parameters params;
Yann Collet5be2dd22015-11-11 13:43:58 +0100136 blockType_t bType;
Yann Collet88fcd292015-11-25 14:42:45 +0100137 ZSTD_dStage stage;
Yann Collet5be2dd22015-11-11 13:43:58 +0100138 const BYTE* litPtr;
139 size_t litBufSize;
140 size_t litSize;
141 BYTE litBuffer[BLOCKSIZE + 8 /* margin for wildcopy */];
Yann Collet88fcd292015-11-25 14:42:45 +0100142 BYTE headerBuffer[ZSTD_frameHeaderSize_max];
Yann Collet417890c2015-12-04 17:16:37 +0100143}; /* typedef'd to ZSTD_DCtx within "zstd_static.h" */
Yann Collet5be2dd22015-11-11 13:43:58 +0100144
Yann Collet5b78d2f2015-11-12 15:36:05 +0100145size_t ZSTD_resetDCtx(ZSTD_DCtx* dctx)
146{
Yann Collet88fcd292015-11-25 14:42:45 +0100147 dctx->expected = ZSTD_frameHeaderSize_min;
148 dctx->stage = ZSTDds_getFrameHeaderSize;
Yann Collet5b78d2f2015-11-12 15:36:05 +0100149 dctx->previousDstEnd = NULL;
150 dctx->base = NULL;
151 dctx->vBase = NULL;
152 dctx->dictEnd = NULL;
153 return 0;
154}
155
156ZSTD_DCtx* ZSTD_createDCtx(void)
157{
158 ZSTD_DCtx* dctx = (ZSTD_DCtx*)malloc(sizeof(ZSTD_DCtx));
159 if (dctx==NULL) return NULL;
160 ZSTD_resetDCtx(dctx);
161 return dctx;
162}
163
164size_t ZSTD_freeDCtx(ZSTD_DCtx* dctx)
165{
166 free(dctx);
167 return 0;
168}
169
170
171/* *************************************************************
172* Decompression section
173***************************************************************/
Yann Collet59d1f792016-01-23 19:28:41 +0100174
175/* Frame format description
176 Frame Header - [ Block Header - Block ] - Frame End
177 1) Frame Header
178 - 4 bytes - Magic Number : ZSTD_MAGICNUMBER (defined within zstd_internal.h)
179 - 1 byte - Window Descriptor
180 2) Block Header
181 - 3 bytes, starting with a 2-bits descriptor
182 Uncompressed, Compressed, Frame End, unused
183 3) Block
184 See Block Format Description
185 4) Frame End
186 - 3 bytes, compatible with Block Header
187*/
188
189/* Block format description
190 Literal Section - Sequences Section
191 1) Literal Section
192 1.1) Header : up to 5 bytes
193 flags:
194 00 compressed by Huff0
195 01 is Raw (uncompressed)
196 10 is Rle
197 11 unused
198 Note : using 11 for Huff0 with precomputed table ?
199 Note : delta map ? => compressed ?
200 Note 2 : 19 bits for sizes, seems a bit larger than necessary
201 Note 3 : RLE blocks ?
202
203 1.2.1) Huff0 block, using sizes from header
204 See Huff0 format
205
206 1.2.2) Huff0 block, using precomputed DTable
207 _usingDTable variants
208
209 1.2.3) uncompressed blocks
210 as the name says (both 2 or 3 bytes variants)
211
212 2) Sequences section
213 TO DO
214*/
215
216
Yann Collet88fcd292015-11-25 14:42:45 +0100217/** ZSTD_decodeFrameHeader_Part1
218* decode the 1st part of the Frame Header, which tells Frame Header size.
219* srcSize must be == ZSTD_frameHeaderSize_min
220* @return : the full size of the Frame Header */
221static size_t ZSTD_decodeFrameHeader_Part1(ZSTD_DCtx* zc, const void* src, size_t srcSize)
222{
223 U32 magicNumber;
224 if (srcSize != ZSTD_frameHeaderSize_min) return ERROR(srcSize_wrong);
225 magicNumber = MEM_readLE32(src);
226 if (magicNumber != ZSTD_MAGICNUMBER) return ERROR(prefix_unknown);
227 zc->headerSize = ZSTD_frameHeaderSize_min;
228 return zc->headerSize;
229}
230
Yann Collet88fcd292015-11-25 14:42:45 +0100231
232size_t ZSTD_getFrameParams(ZSTD_parameters* params, const void* src, size_t srcSize)
233{
234 U32 magicNumber;
235 if (srcSize < ZSTD_frameHeaderSize_min) return ZSTD_frameHeaderSize_max;
236 magicNumber = MEM_readLE32(src);
237 if (magicNumber != ZSTD_MAGICNUMBER) return ERROR(prefix_unknown);
238 memset(params, 0, sizeof(*params));
Yann Collet26415d32015-11-26 12:43:28 +0100239 params->windowLog = (((const BYTE*)src)[4] & 15) + ZSTD_WINDOWLOG_ABSOLUTEMIN;
Yann Colletbf7aa3c2015-11-28 18:19:44 +0100240 if ((((const BYTE*)src)[4] >> 4) != 0) return ERROR(frameParameter_unsupported); /* reserved bits */
Yann Collet88fcd292015-11-25 14:42:45 +0100241 return 0;
242}
243
Yann Collet26415d32015-11-26 12:43:28 +0100244/** ZSTD_decodeFrameHeader_Part2
245* decode the full Frame Header
246* srcSize must be the size provided by ZSTD_decodeFrameHeader_Part1
247* @return : 0, or an error code, which can be tested using ZSTD_isError() */
248static size_t ZSTD_decodeFrameHeader_Part2(ZSTD_DCtx* zc, const void* src, size_t srcSize)
249{
Yann Collet00fd7a22015-11-28 16:03:22 +0100250 size_t result;
Yann Collet26415d32015-11-26 12:43:28 +0100251 if (srcSize != zc->headerSize) return ERROR(srcSize_wrong);
Yann Collet00fd7a22015-11-28 16:03:22 +0100252 result = ZSTD_getFrameParams(&(zc->params), src, srcSize);
253 if ((MEM_32bits()) && (zc->params.windowLog > 25)) return ERROR(frameParameter_unsupportedBy32bitsImplementation);
254 return result;
Yann Collet26415d32015-11-26 12:43:28 +0100255}
256
Yann Collet5be2dd22015-11-11 13:43:58 +0100257
258size_t ZSTD_getcBlockSize(const void* src, size_t srcSize, blockProperties_t* bpPtr)
259{
260 const BYTE* const in = (const BYTE* const)src;
261 BYTE headerFlags;
262 U32 cSize;
263
264 if (srcSize < 3) return ERROR(srcSize_wrong);
265
266 headerFlags = *in;
267 cSize = in[2] + (in[1]<<8) + ((in[0] & 7)<<16);
268
269 bpPtr->blockType = (blockType_t)(headerFlags >> 6);
270 bpPtr->origSize = (bpPtr->blockType == bt_rle) ? cSize : 0;
271
272 if (bpPtr->blockType == bt_end) return 0;
273 if (bpPtr->blockType == bt_rle) return 1;
274 return cSize;
275}
276
Yann Collet59d1f792016-01-23 19:28:41 +0100277
Yann Collet0f366c62015-11-12 16:19:30 +0100278static size_t ZSTD_copyRawBlock(void* dst, size_t maxDstSize, const void* src, size_t srcSize)
Yann Collet5be2dd22015-11-11 13:43:58 +0100279{
280 if (srcSize > maxDstSize) return ERROR(dstSize_tooSmall);
281 memcpy(dst, src, srcSize);
282 return srcSize;
283}
284
285
Yann Collet5be2dd22015-11-11 13:43:58 +0100286/** ZSTD_decodeLiteralsBlock
Yann Collet14983e72015-11-11 21:38:21 +0100287 @return : nb of bytes read from src (< srcSize ) */
Yann Collet5b78d2f2015-11-12 15:36:05 +0100288size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx,
Yann Collet5be2dd22015-11-11 13:43:58 +0100289 const void* src, size_t srcSize) /* note : srcSize < BLOCKSIZE */
290{
Yann Collet5be2dd22015-11-11 13:43:58 +0100291 const BYTE* const istart = (const BYTE*) src;
292
293 /* any compressed block with literals segment must be at least this size */
294 if (srcSize < MIN_CBLOCK_SIZE) return ERROR(corruption_detected);
295
Yann Collet59d1f792016-01-23 19:28:41 +0100296 switch(istart[0]>> 6)
Yann Collet5be2dd22015-11-11 13:43:58 +0100297 {
Yann Collet59d1f792016-01-23 19:28:41 +0100298 case IS_HUF:
Yann Collet5be2dd22015-11-11 13:43:58 +0100299 {
Yann Colletafe07092016-01-25 04:10:46 +0100300 size_t litSize, litCSize, singleStream=0;
Yann Collet59d1f792016-01-23 19:28:41 +0100301 U32 lhSize = ((istart[0]) >> 4) & 3;
302 switch(lhSize)
303 {
304 case 0: case 1: default: /* note : default is impossible, since lhSize into [0..3] */
305 /* 2 - 2 - 10 - 10 */
306 lhSize=3;
Yann Colletafe07092016-01-25 04:10:46 +0100307 singleStream = istart[0] & 16;
Yann Collet59d1f792016-01-23 19:28:41 +0100308 litSize = ((istart[0] & 15) << 6) + (istart[1] >> 2);
309 litCSize = ((istart[1] & 3) << 8) + istart[2];
310 break;
311 case 2:
312 /* 2 - 2 - 14 - 14 */
313 lhSize=4;
314 litSize = ((istart[0] & 15) << 10) + (istart[1] << 2) + (istart[2] >> 6);
315 litCSize = ((istart[2] & 63) << 8) + istart[3];
316 break;
317 case 3:
318 /* 2 - 2 - 18 - 18 */
319 lhSize=5;
320 litSize = ((istart[0] & 15) << 14) + (istart[1] << 6) + (istart[2] >> 2);
321 litCSize = ((istart[2] & 3) << 16) + (istart[3] << 8) + istart[4];
322 break;
323 }
Yann Collet37422192016-01-25 16:54:05 +0100324 if (litSize > BLOCKSIZE) return ERROR(corruption_detected);;
Yann Collet59d1f792016-01-23 19:28:41 +0100325
Yann Colletafe07092016-01-25 04:10:46 +0100326 if (HUF_isError(singleStream ?
327 HUF_decompress1X2(dctx->litBuffer, litSize, istart+lhSize, litCSize) :
328 HUF_decompress (dctx->litBuffer, litSize, istart+lhSize, litCSize) ))
Yann Collet59d1f792016-01-23 19:28:41 +0100329 return ERROR(corruption_detected);
330
Yann Collet5be2dd22015-11-11 13:43:58 +0100331 dctx->litPtr = dctx->litBuffer;
332 dctx->litBufSize = BLOCKSIZE+8;
333 dctx->litSize = litSize;
Yann Collet59d1f792016-01-23 19:28:41 +0100334 return litCSize + lhSize;
Yann Collet5be2dd22015-11-11 13:43:58 +0100335 }
336 case IS_RAW:
337 {
Yann Collet59d1f792016-01-23 19:28:41 +0100338 size_t litSize;
339 U32 lhSize = ((istart[0]) >> 4) & 3;
340 switch(lhSize)
Yann Collet5be2dd22015-11-11 13:43:58 +0100341 {
Yann Collet59d1f792016-01-23 19:28:41 +0100342 case 0: case 1: default: /* note : default is impossible, since lhSize into [0..3] */
343 lhSize=1;
344 litSize = istart[0] & 31;
345 break;
346 case 2:
347 litSize = ((istart[0] & 15) << 8) + istart[1];
348 break;
349 case 3:
350 litSize = ((istart[0] & 15) << 16) + (istart[1] << 8) + istart[2];
351 break;
352 }
353
Yann Colletbc4c8aa2016-01-25 17:26:01 +0100354 if (litSize+WILDCOPY_OVERLENGTH > srcSize) /* risk reading beyond src buffer with wildcopy */
Yann Collet59d1f792016-01-23 19:28:41 +0100355 {
Yann Collet37422192016-01-25 16:54:05 +0100356 if (litSize > srcSize-lhSize) return ERROR(corruption_detected);
Yann Collet59d1f792016-01-23 19:28:41 +0100357 memcpy(dctx->litBuffer, istart+lhSize, litSize);
Yann Collet5be2dd22015-11-11 13:43:58 +0100358 dctx->litPtr = dctx->litBuffer;
359 dctx->litBufSize = BLOCKSIZE+8;
360 dctx->litSize = litSize;
Yann Colletbc4c8aa2016-01-25 17:26:01 +0100361 return lhSize+litSize;
Yann Collet5be2dd22015-11-11 13:43:58 +0100362 }
363 /* direct reference into compressed stream */
Yann Collet59d1f792016-01-23 19:28:41 +0100364 dctx->litPtr = istart+lhSize;
365 dctx->litBufSize = srcSize-lhSize;
Yann Collet5be2dd22015-11-11 13:43:58 +0100366 dctx->litSize = litSize;
Yann Collet59d1f792016-01-23 19:28:41 +0100367 return lhSize+litSize;
368 }
Yann Collet5be2dd22015-11-11 13:43:58 +0100369 case IS_RLE:
370 {
Yann Collet59d1f792016-01-23 19:28:41 +0100371 size_t litSize;
372 U32 lhSize = ((istart[0]) >> 4) & 3;
373 switch(lhSize)
374 {
375 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 }
Yann Collet5be2dd22015-11-11 13:43:58 +0100386 if (litSize > BLOCKSIZE) return ERROR(corruption_detected);
Yann Collet59d1f792016-01-23 19:28:41 +0100387 memset(dctx->litBuffer, istart[lhSize], litSize);
Yann Collet5be2dd22015-11-11 13:43:58 +0100388 dctx->litPtr = dctx->litBuffer;
389 dctx->litBufSize = BLOCKSIZE+8;
390 dctx->litSize = litSize;
Yann Collet59d1f792016-01-23 19:28:41 +0100391 return lhSize+1;
Yann Collet5be2dd22015-11-11 13:43:58 +0100392 }
Yann Collet59d1f792016-01-23 19:28:41 +0100393 default: /* IS_PCH */
394 return ERROR(corruption_detected); /* not yet nominal case */
Yann Collet5be2dd22015-11-11 13:43:58 +0100395 }
396}
397
398
399size_t ZSTD_decodeSeqHeaders(int* nbSeq, const BYTE** dumpsPtr, size_t* dumpsLengthPtr,
400 FSE_DTable* DTableLL, FSE_DTable* DTableML, FSE_DTable* DTableOffb,
401 const void* src, size_t srcSize)
402{
403 const BYTE* const istart = (const BYTE* const)src;
404 const BYTE* ip = istart;
405 const BYTE* const iend = istart + srcSize;
406 U32 LLtype, Offtype, MLtype;
407 U32 LLlog, Offlog, MLlog;
408 size_t dumpsLength;
409
410 /* check */
411 if (srcSize < 5) return ERROR(srcSize_wrong);
412
413 /* SeqHead */
414 *nbSeq = MEM_readLE16(ip); ip+=2;
415 LLtype = *ip >> 6;
416 Offtype = (*ip >> 4) & 3;
417 MLtype = (*ip >> 2) & 3;
418 if (*ip & 2)
419 {
420 dumpsLength = ip[2];
421 dumpsLength += ip[1] << 8;
422 ip += 3;
423 }
424 else
425 {
426 dumpsLength = ip[1];
427 dumpsLength += (ip[0] & 1) << 8;
428 ip += 2;
429 }
430 *dumpsPtr = ip;
431 ip += dumpsLength;
432 *dumpsLengthPtr = dumpsLength;
433
434 /* check */
435 if (ip > iend-3) return ERROR(srcSize_wrong); /* min : all 3 are "raw", hence no header, but at least xxLog bits per type */
436
437 /* sequences */
438 {
Yann Collet82368cf2015-11-16 19:10:56 +0100439 S16 norm[MaxML+1]; /* assumption : MaxML >= MaxLL >= MaxOff */
Yann Collet5be2dd22015-11-11 13:43:58 +0100440 size_t headerSize;
441
442 /* Build DTables */
443 switch(LLtype)
444 {
445 U32 max;
446 case bt_rle :
447 LLlog = 0;
448 FSE_buildDTable_rle(DTableLL, *ip++); break;
449 case bt_raw :
450 LLlog = LLbits;
451 FSE_buildDTable_raw(DTableLL, LLbits); break;
452 default :
453 max = MaxLL;
454 headerSize = FSE_readNCount(norm, &max, &LLlog, ip, iend-ip);
455 if (FSE_isError(headerSize)) return ERROR(GENERIC);
456 if (LLlog > LLFSELog) return ERROR(corruption_detected);
457 ip += headerSize;
458 FSE_buildDTable(DTableLL, norm, max, LLlog);
459 }
460
461 switch(Offtype)
462 {
463 U32 max;
464 case bt_rle :
465 Offlog = 0;
466 if (ip > iend-2) return ERROR(srcSize_wrong); /* min : "raw", hence no header, but at least xxLog bits */
467 FSE_buildDTable_rle(DTableOffb, *ip++ & MaxOff); /* if *ip > MaxOff, data is corrupted */
468 break;
469 case bt_raw :
470 Offlog = Offbits;
471 FSE_buildDTable_raw(DTableOffb, Offbits); break;
472 default :
473 max = MaxOff;
474 headerSize = FSE_readNCount(norm, &max, &Offlog, ip, iend-ip);
475 if (FSE_isError(headerSize)) return ERROR(GENERIC);
476 if (Offlog > OffFSELog) return ERROR(corruption_detected);
477 ip += headerSize;
478 FSE_buildDTable(DTableOffb, norm, max, Offlog);
479 }
480
481 switch(MLtype)
482 {
483 U32 max;
484 case bt_rle :
485 MLlog = 0;
486 if (ip > iend-2) return ERROR(srcSize_wrong); /* min : "raw", hence no header, but at least xxLog bits */
487 FSE_buildDTable_rle(DTableML, *ip++); break;
488 case bt_raw :
489 MLlog = MLbits;
490 FSE_buildDTable_raw(DTableML, MLbits); break;
491 default :
492 max = MaxML;
493 headerSize = FSE_readNCount(norm, &max, &MLlog, ip, iend-ip);
494 if (FSE_isError(headerSize)) return ERROR(GENERIC);
495 if (MLlog > MLFSELog) return ERROR(corruption_detected);
496 ip += headerSize;
497 FSE_buildDTable(DTableML, norm, max, MLlog);
498 }
499 }
500
501 return ip-istart;
502}
503
504
505typedef struct {
506 size_t litLength;
507 size_t offset;
508 size_t matchLength;
509} seq_t;
510
511typedef struct {
512 BIT_DStream_t DStream;
513 FSE_DState_t stateLL;
514 FSE_DState_t stateOffb;
515 FSE_DState_t stateML;
516 size_t prevOffset;
517 const BYTE* dumps;
518 const BYTE* dumpsEnd;
519} seqState_t;
520
521
522static void ZSTD_decodeSequence(seq_t* seq, seqState_t* seqState)
523{
524 size_t litLength;
525 size_t prevOffset;
526 size_t offset;
527 size_t matchLength;
528 const BYTE* dumps = seqState->dumps;
529 const BYTE* const de = seqState->dumpsEnd;
530
531 /* Literal length */
532 litLength = FSE_decodeSymbol(&(seqState->stateLL), &(seqState->DStream));
Yann Collete4fdad52015-11-25 21:09:17 +0100533 prevOffset = litLength ? seq->offset : seqState->prevOffset;
Yann Collet5be2dd22015-11-11 13:43:58 +0100534 if (litLength == MaxLL)
535 {
536 U32 add = *dumps++;
537 if (add < 255) litLength += add;
538 else
539 {
540 litLength = MEM_readLE32(dumps) & 0xFFFFFF; /* no pb : dumps is always followed by seq tables > 1 byte */
541 dumps += 3;
542 }
543 if (dumps >= de) dumps = de-1; /* late correction, to avoid read overflow (data is now corrupted anyway) */
544 }
545
546 /* Offset */
547 {
548 static const U32 offsetPrefix[MaxOff+1] = {
549 1 /*fake*/, 1, 2, 4, 8, 16, 32, 64, 128, 256,
550 512, 1024, 2048, 4096, 8192, 16384, 32768, 65536, 131072, 262144,
551 524288, 1048576, 2097152, 4194304, 8388608, 16777216, 33554432, /*fake*/ 1, 1, 1, 1, 1 };
552 U32 offsetCode, nbBits;
553 offsetCode = FSE_decodeSymbol(&(seqState->stateOffb), &(seqState->DStream)); /* <= maxOff, by table construction */
554 if (MEM_32bits()) BIT_reloadDStream(&(seqState->DStream));
555 nbBits = offsetCode - 1;
556 if (offsetCode==0) nbBits = 0; /* cmove */
557 offset = offsetPrefix[offsetCode] + BIT_readBits(&(seqState->DStream), nbBits);
558 if (MEM_32bits()) BIT_reloadDStream(&(seqState->DStream));
559 if (offsetCode==0) offset = prevOffset; /* cmove */
Yann Collet55aa7f92015-11-20 12:04:52 +0100560 if (offsetCode | !litLength) seqState->prevOffset = seq->offset; /* cmove */
Yann Collet5be2dd22015-11-11 13:43:58 +0100561 }
562
563 /* MatchLength */
564 matchLength = FSE_decodeSymbol(&(seqState->stateML), &(seqState->DStream));
565 if (matchLength == MaxML)
566 {
567 U32 add = *dumps++;
568 if (add < 255) matchLength += add;
569 else
570 {
571 matchLength = MEM_readLE32(dumps) & 0xFFFFFF; /* no pb : dumps is always followed by seq tables > 1 byte */
572 dumps += 3;
573 }
574 if (dumps >= de) dumps = de-1; /* late correction, to avoid read overflow (data is now corrupted anyway) */
575 }
576 matchLength += MINMATCH;
577
578 /* save result */
579 seq->litLength = litLength;
580 seq->offset = offset;
581 seq->matchLength = matchLength;
582 seqState->dumps = dumps;
583}
584
585
Yann Collet5b78d2f2015-11-12 15:36:05 +0100586FORCE_INLINE size_t ZSTD_execSequence(BYTE* op,
Yann Colletb3a2af92015-11-19 17:13:19 +0100587 BYTE* const oend, seq_t sequence,
Yann Collet5be2dd22015-11-11 13:43:58 +0100588 const BYTE** litPtr, const BYTE* const litLimit_8,
Yann Collet417890c2015-12-04 17:16:37 +0100589 const BYTE* const base, const BYTE* const vBase, const BYTE* const dictEnd)
Yann Collet5be2dd22015-11-11 13:43:58 +0100590{
Yann Colletb3a2af92015-11-19 17:13:19 +0100591 static const int dec32table[] = { 0, 1, 2, 1, 4, 4, 4, 4 }; /* added */
592 static const int dec64table[] = { 8, 8, 8, 7, 8, 9,10,11 }; /* substracted */
Yann Collet5be2dd22015-11-11 13:43:58 +0100593 BYTE* const oLitEnd = op + sequence.litLength;
Yann Colletb3a2af92015-11-19 17:13:19 +0100594 const size_t sequenceLength = sequence.litLength + sequence.matchLength;
595 BYTE* const oMatchEnd = op + sequenceLength; /* risk : address space overflow (32-bits) */
Yann Collet5be2dd22015-11-11 13:43:58 +0100596 BYTE* const oend_8 = oend-8;
597 const BYTE* const litEnd = *litPtr + sequence.litLength;
Yann Colletb3a2af92015-11-19 17:13:19 +0100598 const BYTE* match = oLitEnd - sequence.offset;
Yann Collet5be2dd22015-11-11 13:43:58 +0100599
600 /* check */
601 if (oLitEnd > oend_8) return ERROR(dstSize_tooSmall); /* last match must start at a minimum distance of 8 from oend */
602 if (oMatchEnd > oend) return ERROR(dstSize_tooSmall); /* overwrite beyond dst buffer */
603 if (litEnd > litLimit_8) return ERROR(corruption_detected); /* risk read beyond lit buffer */
604
605 /* copy Literals */
606 ZSTD_wildcopy(op, *litPtr, sequence.litLength); /* note : oLitEnd <= oend-8 : no risk of overwrite beyond oend */
607 op = oLitEnd;
608 *litPtr = litEnd; /* update for next sequence */
609
610 /* copy Match */
Yann Collet9f5ab1a2015-12-11 00:27:41 +0100611 if (sequence.offset > (size_t)(oLitEnd - base))
Yann Collet44287a32015-11-30 23:13:56 +0100612 {
613 /* offset beyond prefix */
Yann Collet9f5ab1a2015-12-11 00:27:41 +0100614 if (sequence.offset > (size_t)(oLitEnd - vBase))
615 return ERROR(corruption_detected);
Yann Collet44287a32015-11-30 23:13:56 +0100616 match = dictEnd - (base-match);
617 if (match + sequence.matchLength <= dictEnd)
618 {
Yann Collet4bfe4152015-12-06 13:18:37 +0100619 memmove(oLitEnd, match, sequence.matchLength);
Yann Collet44287a32015-11-30 23:13:56 +0100620 return sequenceLength;
621 }
622 /* span extDict & currentPrefixSegment */
623 {
624 size_t length1 = dictEnd - match;
Yann Collet4bfe4152015-12-06 13:18:37 +0100625 memmove(oLitEnd, match, length1);
Yann Collet44287a32015-11-30 23:13:56 +0100626 op = oLitEnd + length1;
627 sequence.matchLength -= length1;
628 match = base;
629 }
630 }
Yann Collet0f366c62015-11-12 16:19:30 +0100631
Yann Collet44287a32015-11-30 23:13:56 +0100632 /* match within prefix */
633 if (sequence.offset < 8)
634 {
635 /* close range match, overlap */
636 const int sub2 = dec64table[sequence.offset];
637 op[0] = match[0];
638 op[1] = match[1];
639 op[2] = match[2];
640 op[3] = match[3];
641 match += dec32table[sequence.offset];
642 ZSTD_copy4(op+4, match);
643 match -= sub2;
644 }
645 else
646 {
647 ZSTD_copy8(op, match);
648 }
649 op += 8; match += 8;
Yann Collet5be2dd22015-11-11 13:43:58 +0100650
Yann Collet44287a32015-11-30 23:13:56 +0100651 if (oMatchEnd > oend-12)
652 {
653 if (op < oend_8)
654 {
655 ZSTD_wildcopy(op, match, oend_8 - op);
656 match += oend_8 - op;
657 op = oend_8;
658 }
659 while (op < oMatchEnd) *op++ = *match++;
660 }
661 else
662 {
663 ZSTD_wildcopy(op, match, sequence.matchLength-8); /* works even if matchLength < 8 */
664 }
665 return sequenceLength;
Yann Collet5be2dd22015-11-11 13:43:58 +0100666}
667
Yann Colletb3a2af92015-11-19 17:13:19 +0100668
Yann Collet5be2dd22015-11-11 13:43:58 +0100669static size_t ZSTD_decompressSequences(
Yann Collet5b78d2f2015-11-12 15:36:05 +0100670 ZSTD_DCtx* dctx,
Yann Collet5be2dd22015-11-11 13:43:58 +0100671 void* dst, size_t maxDstSize,
672 const void* seqStart, size_t seqSize)
673{
Yann Collet5be2dd22015-11-11 13:43:58 +0100674 const BYTE* ip = (const BYTE*)seqStart;
675 const BYTE* const iend = ip + seqSize;
676 BYTE* const ostart = (BYTE* const)dst;
677 BYTE* op = ostart;
678 BYTE* const oend = ostart + maxDstSize;
679 size_t errorCode, dumpsLength;
680 const BYTE* litPtr = dctx->litPtr;
681 const BYTE* const litLimit_8 = litPtr + dctx->litBufSize - 8;
682 const BYTE* const litEnd = litPtr + dctx->litSize;
683 int nbSeq;
684 const BYTE* dumps;
685 U32* DTableLL = dctx->LLTable;
686 U32* DTableML = dctx->MLTable;
687 U32* DTableOffb = dctx->OffTable;
Yann Collet417890c2015-12-04 17:16:37 +0100688 const BYTE* const base = (const BYTE*) (dctx->base);
689 const BYTE* const vBase = (const BYTE*) (dctx->vBase);
690 const BYTE* const dictEnd = (const BYTE*) (dctx->dictEnd);
Yann Collet5be2dd22015-11-11 13:43:58 +0100691
692 /* Build Decoding Tables */
693 errorCode = ZSTD_decodeSeqHeaders(&nbSeq, &dumps, &dumpsLength,
694 DTableLL, DTableML, DTableOffb,
695 ip, iend-ip);
696 if (ZSTD_isError(errorCode)) return errorCode;
697 ip += errorCode;
698
699 /* Regen sequences */
700 {
701 seq_t sequence;
702 seqState_t seqState;
703
704 memset(&sequence, 0, sizeof(sequence));
705 sequence.offset = 4;
706 seqState.dumps = dumps;
707 seqState.dumpsEnd = dumps + dumpsLength;
708 seqState.prevOffset = 4;
709 errorCode = BIT_initDStream(&(seqState.DStream), ip, iend-ip);
710 if (ERR_isError(errorCode)) return ERROR(corruption_detected);
711 FSE_initDState(&(seqState.stateLL), &(seqState.DStream), DTableLL);
712 FSE_initDState(&(seqState.stateOffb), &(seqState.DStream), DTableOffb);
713 FSE_initDState(&(seqState.stateML), &(seqState.DStream), DTableML);
714
Yann Collet44287a32015-11-30 23:13:56 +0100715 for ( ; (BIT_reloadDStream(&(seqState.DStream)) <= BIT_DStream_completed) && nbSeq ; )
Yann Colletb3a2af92015-11-19 17:13:19 +0100716 {
717 size_t oneSeqSize;
718 nbSeq--;
719 ZSTD_decodeSequence(&sequence, &seqState);
720 oneSeqSize = ZSTD_execSequence(op, oend, sequence, &litPtr, litLimit_8, base, vBase, dictEnd);
Yann Collet5be2dd22015-11-11 13:43:58 +0100721 if (ZSTD_isError(oneSeqSize)) return oneSeqSize;
722 op += oneSeqSize;
723 }
724
725 /* check if reached exact end */
Yann Collet44287a32015-11-30 23:13:56 +0100726 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 +0100727
728 /* last literal segment */
729 {
730 size_t lastLLSize = litEnd - litPtr;
731 if (litPtr > litEnd) return ERROR(corruption_detected);
732 if (op+lastLLSize > oend) return ERROR(dstSize_tooSmall);
733 if (op != litPtr) memcpy(op, litPtr, lastLLSize);
734 op += lastLLSize;
735 }
736 }
737
738 return op-ostart;
739}
740
741
Yann Colletb0125102016-01-09 02:00:10 +0100742static void ZSTD_checkContinuity(ZSTD_DCtx* dctx, const void* dst)
743{
744 if (dst != dctx->previousDstEnd) /* not contiguous */
745 {
746 dctx->dictEnd = dctx->previousDstEnd;
747 dctx->vBase = (const char*)dst - ((const char*)(dctx->previousDstEnd) - (const char*)(dctx->base));
748 dctx->base = dst;
749 dctx->previousDstEnd = dst;
750 }
751}
752
753
754static size_t ZSTD_decompressBlock_internal(ZSTD_DCtx* dctx,
Yann Collet5be2dd22015-11-11 13:43:58 +0100755 void* dst, size_t maxDstSize,
756 const void* src, size_t srcSize)
757{
758 /* blockType == blockCompressed */
759 const BYTE* ip = (const BYTE*)src;
760
761 /* Decode literals sub-block */
Yann Collet5b78d2f2015-11-12 15:36:05 +0100762 size_t litCSize = ZSTD_decodeLiteralsBlock(dctx, src, srcSize);
Yann Collet5be2dd22015-11-11 13:43:58 +0100763 if (ZSTD_isError(litCSize)) return litCSize;
764 ip += litCSize;
765 srcSize -= litCSize;
766
Yann Collet5b78d2f2015-11-12 15:36:05 +0100767 return ZSTD_decompressSequences(dctx, dst, maxDstSize, ip, srcSize);
Yann Collet5be2dd22015-11-11 13:43:58 +0100768}
769
770
Yann Colletb0125102016-01-09 02:00:10 +0100771size_t ZSTD_decompressBlock(ZSTD_DCtx* dctx,
772 void* dst, size_t maxDstSize,
773 const void* src, size_t srcSize)
774{
775 ZSTD_checkContinuity(dctx, dst);
776 return ZSTD_decompressBlock_internal(dctx, dst, maxDstSize, src, srcSize);
777}
778
779
Yann Collet37422192016-01-25 16:54:05 +0100780size_t ZSTD_decompress_usingDict(ZSTD_DCtx* dctx,
Yann Collet31683c02015-12-18 01:26:48 +0100781 void* dst, size_t maxDstSize,
782 const void* src, size_t srcSize,
783 const void* dict, size_t dictSize)
Yann Collet5be2dd22015-11-11 13:43:58 +0100784{
785 const BYTE* ip = (const BYTE*)src;
786 const BYTE* iend = ip + srcSize;
787 BYTE* const ostart = (BYTE* const)dst;
788 BYTE* op = ostart;
789 BYTE* const oend = ostart + maxDstSize;
790 size_t remainingSize = srcSize;
Yann Collet5be2dd22015-11-11 13:43:58 +0100791 blockProperties_t blockProperties;
792
Yann Colletb2549842015-11-18 11:29:32 +0100793 /* init */
Yann Collet37422192016-01-25 16:54:05 +0100794 ZSTD_resetDCtx(dctx);
Yann Collet31683c02015-12-18 01:26:48 +0100795 if (dict)
796 {
Yann Collet37422192016-01-25 16:54:05 +0100797 ZSTD_decompress_insertDictionary(dctx, dict, dictSize);
798 dctx->dictEnd = dctx->previousDstEnd;
799 dctx->vBase = (const char*)dst - ((const char*)(dctx->previousDstEnd) - (const char*)(dctx->base));
800 dctx->base = dst;
Yann Collet31683c02015-12-18 01:26:48 +0100801 }
802 else
803 {
Yann Collet37422192016-01-25 16:54:05 +0100804 dctx->vBase = dctx->base = dctx->dictEnd = dst;
Yann Collet31683c02015-12-18 01:26:48 +0100805 }
Yann Collet5b78d2f2015-11-12 15:36:05 +0100806
Yann Collet5be2dd22015-11-11 13:43:58 +0100807 /* Frame Header */
Yann Collet88fcd292015-11-25 14:42:45 +0100808 {
809 size_t frameHeaderSize;
810 if (srcSize < ZSTD_frameHeaderSize_min+ZSTD_blockHeaderSize) return ERROR(srcSize_wrong);
Yann Collet5be2dd22015-11-11 13:43:58 +0100811#if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT==1)
Yann Collet88fcd292015-11-25 14:42:45 +0100812 {
813 const U32 magicNumber = MEM_readLE32(src);
814 if (ZSTD_isLegacy(magicNumber))
815 return ZSTD_decompressLegacy(dst, maxDstSize, src, srcSize, magicNumber);
816 }
Yann Collet5be2dd22015-11-11 13:43:58 +0100817#endif
Yann Collet37422192016-01-25 16:54:05 +0100818 frameHeaderSize = ZSTD_decodeFrameHeader_Part1(dctx, src, ZSTD_frameHeaderSize_min);
Yann Collet88fcd292015-11-25 14:42:45 +0100819 if (ZSTD_isError(frameHeaderSize)) return frameHeaderSize;
820 if (srcSize < frameHeaderSize+ZSTD_blockHeaderSize) return ERROR(srcSize_wrong);
821 ip += frameHeaderSize; remainingSize -= frameHeaderSize;
Yann Collet37422192016-01-25 16:54:05 +0100822 frameHeaderSize = ZSTD_decodeFrameHeader_Part2(dctx, src, frameHeaderSize);
Yann Collet88fcd292015-11-25 14:42:45 +0100823 if (ZSTD_isError(frameHeaderSize)) return frameHeaderSize;
824 }
Yann Collet5be2dd22015-11-11 13:43:58 +0100825
826 /* Loop on each block */
827 while (1)
828 {
829 size_t decodedSize=0;
830 size_t cBlockSize = ZSTD_getcBlockSize(ip, iend-ip, &blockProperties);
831 if (ZSTD_isError(cBlockSize)) return cBlockSize;
832
833 ip += ZSTD_blockHeaderSize;
834 remainingSize -= ZSTD_blockHeaderSize;
835 if (cBlockSize > remainingSize) return ERROR(srcSize_wrong);
836
837 switch(blockProperties.blockType)
838 {
839 case bt_compressed:
Yann Collet37422192016-01-25 16:54:05 +0100840 decodedSize = ZSTD_decompressBlock_internal(dctx, op, oend-op, ip, cBlockSize);
Yann Collet5be2dd22015-11-11 13:43:58 +0100841 break;
842 case bt_raw :
Yann Collet0f366c62015-11-12 16:19:30 +0100843 decodedSize = ZSTD_copyRawBlock(op, oend-op, ip, cBlockSize);
Yann Collet5be2dd22015-11-11 13:43:58 +0100844 break;
845 case bt_rle :
846 return ERROR(GENERIC); /* not yet supported */
847 break;
848 case bt_end :
849 /* end of frame */
850 if (remainingSize) return ERROR(srcSize_wrong);
851 break;
852 default:
853 return ERROR(GENERIC); /* impossible */
854 }
855 if (cBlockSize == 0) break; /* bt_end */
856
857 if (ZSTD_isError(decodedSize)) return decodedSize;
858 op += decodedSize;
859 ip += cBlockSize;
860 remainingSize -= cBlockSize;
861 }
862
863 return op-ostart;
864}
865
Yann Collet31683c02015-12-18 01:26:48 +0100866
867size_t ZSTD_decompressDCtx(ZSTD_DCtx* dctx, void* dst, size_t maxDstSize, const void* src, size_t srcSize)
868{
869 return ZSTD_decompress_usingDict(dctx, dst, maxDstSize, src, srcSize, NULL, 0);
870}
871
Yann Collet5be2dd22015-11-11 13:43:58 +0100872size_t ZSTD_decompress(void* dst, size_t maxDstSize, const void* src, size_t srcSize)
873{
Yann Collet3a3b72f2016-01-11 12:56:11 +0100874#if defined(ZSTD_HEAPMODE) && (ZSTD_HEAPMODE==1)
875 size_t regenSize;
876 ZSTD_DCtx* dctx = ZSTD_createDCtx();
877 if (dctx==NULL) return ERROR(memory_allocation);
878 regenSize = ZSTD_decompressDCtx(dctx, dst, maxDstSize, src, srcSize);
879 ZSTD_freeDCtx(dctx);
880 return regenSize;
881#else
Yann Collet31683c02015-12-18 01:26:48 +0100882 ZSTD_DCtx dctx;
883 return ZSTD_decompressDCtx(&dctx, dst, maxDstSize, src, srcSize);
Yann Colleta768a302016-01-21 16:04:35 +0100884#endif
Yann Collet5be2dd22015-11-11 13:43:58 +0100885}
886
887
888/* ******************************
889* Streaming Decompression API
890********************************/
Yann Collet5be2dd22015-11-11 13:43:58 +0100891size_t ZSTD_nextSrcSizeToDecompress(ZSTD_DCtx* dctx)
892{
893 return dctx->expected;
894}
895
Yann Collet37422192016-01-25 16:54:05 +0100896size_t ZSTD_decompressContinue(ZSTD_DCtx* dctx, void* dst, size_t maxDstSize, const void* src, size_t srcSize)
Yann Collet5be2dd22015-11-11 13:43:58 +0100897{
898 /* Sanity check */
Yann Collet37422192016-01-25 16:54:05 +0100899 if (srcSize != dctx->expected) return ERROR(srcSize_wrong);
900 ZSTD_checkContinuity(dctx, dst);
Yann Collet5be2dd22015-11-11 13:43:58 +0100901
Yann Collet88fcd292015-11-25 14:42:45 +0100902 /* Decompress : frame header; part 1 */
Yann Collet37422192016-01-25 16:54:05 +0100903 switch (dctx->stage)
Yann Collet5be2dd22015-11-11 13:43:58 +0100904 {
Yann Collet88fcd292015-11-25 14:42:45 +0100905 case ZSTDds_getFrameHeaderSize :
Yann Collet5be2dd22015-11-11 13:43:58 +0100906 {
Yann Collet88fcd292015-11-25 14:42:45 +0100907 /* get frame header size */
908 if (srcSize != ZSTD_frameHeaderSize_min) return ERROR(srcSize_wrong); /* impossible */
Yann Collet37422192016-01-25 16:54:05 +0100909 dctx->headerSize = ZSTD_decodeFrameHeader_Part1(dctx, src, ZSTD_frameHeaderSize_min);
910 if (ZSTD_isError(dctx->headerSize)) return dctx->headerSize;
911 memcpy(dctx->headerBuffer, src, ZSTD_frameHeaderSize_min);
912 if (dctx->headerSize > ZSTD_frameHeaderSize_min)
Yann Collet88fcd292015-11-25 14:42:45 +0100913 {
Yann Collet37422192016-01-25 16:54:05 +0100914 dctx->expected = dctx->headerSize - ZSTD_frameHeaderSize_min;
915 dctx->stage = ZSTDds_decodeFrameHeader;
Yann Collet88fcd292015-11-25 14:42:45 +0100916 return 0;
917 }
Yann Collet37422192016-01-25 16:54:05 +0100918 dctx->expected = 0; /* not necessary to copy more */
Yann Collet5be2dd22015-11-11 13:43:58 +0100919 }
Yann Collet88fcd292015-11-25 14:42:45 +0100920 case ZSTDds_decodeFrameHeader:
Yann Collet5be2dd22015-11-11 13:43:58 +0100921 {
Yann Collet88fcd292015-11-25 14:42:45 +0100922 /* get frame header */
923 size_t result;
Yann Collet37422192016-01-25 16:54:05 +0100924 memcpy(dctx->headerBuffer + ZSTD_frameHeaderSize_min, src, dctx->expected);
925 result = ZSTD_decodeFrameHeader_Part2(dctx, dctx->headerBuffer, dctx->headerSize);
Yann Collet88fcd292015-11-25 14:42:45 +0100926 if (ZSTD_isError(result)) return result;
Yann Collet37422192016-01-25 16:54:05 +0100927 dctx->expected = ZSTD_blockHeaderSize;
928 dctx->stage = ZSTDds_decodeBlockHeader;
Yann Collet88fcd292015-11-25 14:42:45 +0100929 return 0;
Yann Collet5be2dd22015-11-11 13:43:58 +0100930 }
Yann Collet88fcd292015-11-25 14:42:45 +0100931 case ZSTDds_decodeBlockHeader:
Yann Collet5be2dd22015-11-11 13:43:58 +0100932 {
Yann Collet88fcd292015-11-25 14:42:45 +0100933 /* Decode block header */
934 blockProperties_t bp;
935 size_t blockSize = ZSTD_getcBlockSize(src, ZSTD_blockHeaderSize, &bp);
936 if (ZSTD_isError(blockSize)) return blockSize;
937 if (bp.blockType == bt_end)
938 {
Yann Collet37422192016-01-25 16:54:05 +0100939 dctx->expected = 0;
940 dctx->stage = ZSTDds_getFrameHeaderSize;
Yann Collet88fcd292015-11-25 14:42:45 +0100941 }
942 else
943 {
Yann Collet37422192016-01-25 16:54:05 +0100944 dctx->expected = blockSize;
945 dctx->bType = bp.blockType;
946 dctx->stage = ZSTDds_decompressBlock;
Yann Collet88fcd292015-11-25 14:42:45 +0100947 }
Yann Collet88fcd292015-11-25 14:42:45 +0100948 return 0;
949 }
Yann Collet417890c2015-12-04 17:16:37 +0100950 case ZSTDds_decompressBlock:
Yann Collet88fcd292015-11-25 14:42:45 +0100951 {
952 /* Decompress : block content */
953 size_t rSize;
Yann Collet37422192016-01-25 16:54:05 +0100954 switch(dctx->bType)
Yann Collet88fcd292015-11-25 14:42:45 +0100955 {
956 case bt_compressed:
Yann Collet37422192016-01-25 16:54:05 +0100957 rSize = ZSTD_decompressBlock_internal(dctx, dst, maxDstSize, src, srcSize);
Yann Collet88fcd292015-11-25 14:42:45 +0100958 break;
959 case bt_raw :
960 rSize = ZSTD_copyRawBlock(dst, maxDstSize, src, srcSize);
961 break;
962 case bt_rle :
963 return ERROR(GENERIC); /* not yet handled */
964 break;
965 case bt_end : /* should never happen (filtered at phase 1) */
966 rSize = 0;
967 break;
968 default:
969 return ERROR(GENERIC);
970 }
Yann Collet37422192016-01-25 16:54:05 +0100971 dctx->stage = ZSTDds_decodeBlockHeader;
972 dctx->expected = ZSTD_blockHeaderSize;
973 dctx->previousDstEnd = (char*)dst + rSize;
Yann Collet88fcd292015-11-25 14:42:45 +0100974 return rSize;
975 }
976 default:
977 return ERROR(GENERIC); /* impossible */
978 }
Yann Collet5be2dd22015-11-11 13:43:58 +0100979}
980
981
Yann Collet37422192016-01-25 16:54:05 +0100982void ZSTD_decompress_insertDictionary(ZSTD_DCtx* dctx, const void* dict, size_t dictSize)
Yann Collet417890c2015-12-04 17:16:37 +0100983{
Yann Collet37422192016-01-25 16:54:05 +0100984 dctx->dictEnd = dctx->previousDstEnd;
985 dctx->vBase = (const char*)dict - ((const char*)(dctx->previousDstEnd) - (const char*)(dctx->base));
986 dctx->base = dict;
987 dctx->previousDstEnd = (const char*)dict + dictSize;
Yann Collet417890c2015-12-04 17:16:37 +0100988}