blob: 88ec78e6c9ca4931fe6c3948fe054e9ba1f228b5 [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 }
324
Yann Colletafe07092016-01-25 04:10:46 +0100325 if (HUF_isError(singleStream ?
326 HUF_decompress1X2(dctx->litBuffer, litSize, istart+lhSize, litCSize) :
327 HUF_decompress (dctx->litBuffer, litSize, istart+lhSize, litCSize) ))
Yann Collet59d1f792016-01-23 19:28:41 +0100328 return ERROR(corruption_detected);
329
Yann Collet5be2dd22015-11-11 13:43:58 +0100330 dctx->litPtr = dctx->litBuffer;
331 dctx->litBufSize = BLOCKSIZE+8;
332 dctx->litSize = litSize;
Yann Collet59d1f792016-01-23 19:28:41 +0100333 return litCSize + lhSize;
Yann Collet5be2dd22015-11-11 13:43:58 +0100334 }
335 case IS_RAW:
336 {
Yann Collet59d1f792016-01-23 19:28:41 +0100337 size_t litSize;
338 U32 lhSize = ((istart[0]) >> 4) & 3;
339 switch(lhSize)
Yann Collet5be2dd22015-11-11 13:43:58 +0100340 {
Yann Collet59d1f792016-01-23 19:28:41 +0100341 case 0: case 1: default: /* note : default is impossible, since lhSize into [0..3] */
342 lhSize=1;
343 litSize = istart[0] & 31;
344 break;
345 case 2:
346 litSize = ((istart[0] & 15) << 8) + istart[1];
347 break;
348 case 3:
349 litSize = ((istart[0] & 15) << 16) + (istart[1] << 8) + istart[2];
350 break;
351 }
352
353 if (litSize > srcSize-11) /* risk of reading beyond src buffer with wildcopy */
354 {
355 if (litSize > srcSize-litSize) return ERROR(corruption_detected);
356 memcpy(dctx->litBuffer, istart+lhSize, litSize);
Yann Collet5be2dd22015-11-11 13:43:58 +0100357 dctx->litPtr = dctx->litBuffer;
358 dctx->litBufSize = BLOCKSIZE+8;
359 dctx->litSize = litSize;
Yann Collet59d1f792016-01-23 19:28:41 +0100360 return litSize+lhSize;
Yann Collet5be2dd22015-11-11 13:43:58 +0100361 }
362 /* direct reference into compressed stream */
Yann Collet59d1f792016-01-23 19:28:41 +0100363 dctx->litPtr = istart+lhSize;
364 dctx->litBufSize = srcSize-lhSize;
Yann Collet5be2dd22015-11-11 13:43:58 +0100365 dctx->litSize = litSize;
Yann Collet59d1f792016-01-23 19:28:41 +0100366 return lhSize+litSize;
367 }
Yann Collet5be2dd22015-11-11 13:43:58 +0100368 case IS_RLE:
369 {
Yann Collet59d1f792016-01-23 19:28:41 +0100370 size_t litSize;
371 U32 lhSize = ((istart[0]) >> 4) & 3;
372 switch(lhSize)
373 {
374 case 0: case 1: default: /* note : default is impossible, since lhSize into [0..3] */
375 lhSize = 1;
376 litSize = istart[0] & 31;
377 break;
378 case 2:
379 litSize = ((istart[0] & 15) << 8) + istart[1];
380 break;
381 case 3:
382 litSize = ((istart[0] & 15) << 16) + (istart[1] << 8) + istart[2];
383 break;
384 }
Yann Collet5be2dd22015-11-11 13:43:58 +0100385 if (litSize > BLOCKSIZE) return ERROR(corruption_detected);
Yann Collet59d1f792016-01-23 19:28:41 +0100386 memset(dctx->litBuffer, istart[lhSize], litSize);
Yann Collet5be2dd22015-11-11 13:43:58 +0100387 dctx->litPtr = dctx->litBuffer;
388 dctx->litBufSize = BLOCKSIZE+8;
389 dctx->litSize = litSize;
Yann Collet59d1f792016-01-23 19:28:41 +0100390 return lhSize+1;
Yann Collet5be2dd22015-11-11 13:43:58 +0100391 }
Yann Collet59d1f792016-01-23 19:28:41 +0100392 default: /* IS_PCH */
393 return ERROR(corruption_detected); /* not yet nominal case */
Yann Collet5be2dd22015-11-11 13:43:58 +0100394 }
395}
396
397
398size_t ZSTD_decodeSeqHeaders(int* nbSeq, const BYTE** dumpsPtr, size_t* dumpsLengthPtr,
399 FSE_DTable* DTableLL, FSE_DTable* DTableML, FSE_DTable* DTableOffb,
400 const void* src, size_t srcSize)
401{
402 const BYTE* const istart = (const BYTE* const)src;
403 const BYTE* ip = istart;
404 const BYTE* const iend = istart + srcSize;
405 U32 LLtype, Offtype, MLtype;
406 U32 LLlog, Offlog, MLlog;
407 size_t dumpsLength;
408
409 /* check */
410 if (srcSize < 5) return ERROR(srcSize_wrong);
411
412 /* SeqHead */
413 *nbSeq = MEM_readLE16(ip); ip+=2;
414 LLtype = *ip >> 6;
415 Offtype = (*ip >> 4) & 3;
416 MLtype = (*ip >> 2) & 3;
417 if (*ip & 2)
418 {
419 dumpsLength = ip[2];
420 dumpsLength += ip[1] << 8;
421 ip += 3;
422 }
423 else
424 {
425 dumpsLength = ip[1];
426 dumpsLength += (ip[0] & 1) << 8;
427 ip += 2;
428 }
429 *dumpsPtr = ip;
430 ip += dumpsLength;
431 *dumpsLengthPtr = dumpsLength;
432
433 /* check */
434 if (ip > iend-3) return ERROR(srcSize_wrong); /* min : all 3 are "raw", hence no header, but at least xxLog bits per type */
435
436 /* sequences */
437 {
Yann Collet82368cf2015-11-16 19:10:56 +0100438 S16 norm[MaxML+1]; /* assumption : MaxML >= MaxLL >= MaxOff */
Yann Collet5be2dd22015-11-11 13:43:58 +0100439 size_t headerSize;
440
441 /* Build DTables */
442 switch(LLtype)
443 {
444 U32 max;
445 case bt_rle :
446 LLlog = 0;
447 FSE_buildDTable_rle(DTableLL, *ip++); break;
448 case bt_raw :
449 LLlog = LLbits;
450 FSE_buildDTable_raw(DTableLL, LLbits); break;
451 default :
452 max = MaxLL;
453 headerSize = FSE_readNCount(norm, &max, &LLlog, ip, iend-ip);
454 if (FSE_isError(headerSize)) return ERROR(GENERIC);
455 if (LLlog > LLFSELog) return ERROR(corruption_detected);
456 ip += headerSize;
457 FSE_buildDTable(DTableLL, norm, max, LLlog);
458 }
459
460 switch(Offtype)
461 {
462 U32 max;
463 case bt_rle :
464 Offlog = 0;
465 if (ip > iend-2) return ERROR(srcSize_wrong); /* min : "raw", hence no header, but at least xxLog bits */
466 FSE_buildDTable_rle(DTableOffb, *ip++ & MaxOff); /* if *ip > MaxOff, data is corrupted */
467 break;
468 case bt_raw :
469 Offlog = Offbits;
470 FSE_buildDTable_raw(DTableOffb, Offbits); break;
471 default :
472 max = MaxOff;
473 headerSize = FSE_readNCount(norm, &max, &Offlog, ip, iend-ip);
474 if (FSE_isError(headerSize)) return ERROR(GENERIC);
475 if (Offlog > OffFSELog) return ERROR(corruption_detected);
476 ip += headerSize;
477 FSE_buildDTable(DTableOffb, norm, max, Offlog);
478 }
479
480 switch(MLtype)
481 {
482 U32 max;
483 case bt_rle :
484 MLlog = 0;
485 if (ip > iend-2) return ERROR(srcSize_wrong); /* min : "raw", hence no header, but at least xxLog bits */
486 FSE_buildDTable_rle(DTableML, *ip++); break;
487 case bt_raw :
488 MLlog = MLbits;
489 FSE_buildDTable_raw(DTableML, MLbits); break;
490 default :
491 max = MaxML;
492 headerSize = FSE_readNCount(norm, &max, &MLlog, ip, iend-ip);
493 if (FSE_isError(headerSize)) return ERROR(GENERIC);
494 if (MLlog > MLFSELog) return ERROR(corruption_detected);
495 ip += headerSize;
496 FSE_buildDTable(DTableML, norm, max, MLlog);
497 }
498 }
499
500 return ip-istart;
501}
502
503
504typedef struct {
505 size_t litLength;
506 size_t offset;
507 size_t matchLength;
508} seq_t;
509
510typedef struct {
511 BIT_DStream_t DStream;
512 FSE_DState_t stateLL;
513 FSE_DState_t stateOffb;
514 FSE_DState_t stateML;
515 size_t prevOffset;
516 const BYTE* dumps;
517 const BYTE* dumpsEnd;
518} seqState_t;
519
520
521static void ZSTD_decodeSequence(seq_t* seq, seqState_t* seqState)
522{
523 size_t litLength;
524 size_t prevOffset;
525 size_t offset;
526 size_t matchLength;
527 const BYTE* dumps = seqState->dumps;
528 const BYTE* const de = seqState->dumpsEnd;
529
530 /* Literal length */
531 litLength = FSE_decodeSymbol(&(seqState->stateLL), &(seqState->DStream));
Yann Collete4fdad52015-11-25 21:09:17 +0100532 prevOffset = litLength ? seq->offset : seqState->prevOffset;
Yann Collet5be2dd22015-11-11 13:43:58 +0100533 if (litLength == MaxLL)
534 {
535 U32 add = *dumps++;
536 if (add < 255) litLength += add;
537 else
538 {
539 litLength = MEM_readLE32(dumps) & 0xFFFFFF; /* no pb : dumps is always followed by seq tables > 1 byte */
540 dumps += 3;
541 }
542 if (dumps >= de) dumps = de-1; /* late correction, to avoid read overflow (data is now corrupted anyway) */
543 }
544
545 /* Offset */
546 {
547 static const U32 offsetPrefix[MaxOff+1] = {
548 1 /*fake*/, 1, 2, 4, 8, 16, 32, 64, 128, 256,
549 512, 1024, 2048, 4096, 8192, 16384, 32768, 65536, 131072, 262144,
550 524288, 1048576, 2097152, 4194304, 8388608, 16777216, 33554432, /*fake*/ 1, 1, 1, 1, 1 };
551 U32 offsetCode, nbBits;
552 offsetCode = FSE_decodeSymbol(&(seqState->stateOffb), &(seqState->DStream)); /* <= maxOff, by table construction */
553 if (MEM_32bits()) BIT_reloadDStream(&(seqState->DStream));
554 nbBits = offsetCode - 1;
555 if (offsetCode==0) nbBits = 0; /* cmove */
556 offset = offsetPrefix[offsetCode] + BIT_readBits(&(seqState->DStream), nbBits);
557 if (MEM_32bits()) BIT_reloadDStream(&(seqState->DStream));
558 if (offsetCode==0) offset = prevOffset; /* cmove */
Yann Collet55aa7f92015-11-20 12:04:52 +0100559 if (offsetCode | !litLength) seqState->prevOffset = seq->offset; /* cmove */
Yann Collet5be2dd22015-11-11 13:43:58 +0100560 }
561
562 /* MatchLength */
563 matchLength = FSE_decodeSymbol(&(seqState->stateML), &(seqState->DStream));
564 if (matchLength == MaxML)
565 {
566 U32 add = *dumps++;
567 if (add < 255) matchLength += add;
568 else
569 {
570 matchLength = MEM_readLE32(dumps) & 0xFFFFFF; /* no pb : dumps is always followed by seq tables > 1 byte */
571 dumps += 3;
572 }
573 if (dumps >= de) dumps = de-1; /* late correction, to avoid read overflow (data is now corrupted anyway) */
574 }
575 matchLength += MINMATCH;
576
577 /* save result */
578 seq->litLength = litLength;
579 seq->offset = offset;
580 seq->matchLength = matchLength;
581 seqState->dumps = dumps;
582}
583
584
Yann Collet5b78d2f2015-11-12 15:36:05 +0100585FORCE_INLINE size_t ZSTD_execSequence(BYTE* op,
Yann Colletb3a2af92015-11-19 17:13:19 +0100586 BYTE* const oend, seq_t sequence,
Yann Collet5be2dd22015-11-11 13:43:58 +0100587 const BYTE** litPtr, const BYTE* const litLimit_8,
Yann Collet417890c2015-12-04 17:16:37 +0100588 const BYTE* const base, const BYTE* const vBase, const BYTE* const dictEnd)
Yann Collet5be2dd22015-11-11 13:43:58 +0100589{
Yann Colletb3a2af92015-11-19 17:13:19 +0100590 static const int dec32table[] = { 0, 1, 2, 1, 4, 4, 4, 4 }; /* added */
591 static const int dec64table[] = { 8, 8, 8, 7, 8, 9,10,11 }; /* substracted */
Yann Collet5be2dd22015-11-11 13:43:58 +0100592 BYTE* const oLitEnd = op + sequence.litLength;
Yann Colletb3a2af92015-11-19 17:13:19 +0100593 const size_t sequenceLength = sequence.litLength + sequence.matchLength;
594 BYTE* const oMatchEnd = op + sequenceLength; /* risk : address space overflow (32-bits) */
Yann Collet5be2dd22015-11-11 13:43:58 +0100595 BYTE* const oend_8 = oend-8;
596 const BYTE* const litEnd = *litPtr + sequence.litLength;
Yann Colletb3a2af92015-11-19 17:13:19 +0100597 const BYTE* match = oLitEnd - sequence.offset;
Yann Collet5be2dd22015-11-11 13:43:58 +0100598
599 /* check */
600 if (oLitEnd > oend_8) return ERROR(dstSize_tooSmall); /* last match must start at a minimum distance of 8 from oend */
601 if (oMatchEnd > oend) return ERROR(dstSize_tooSmall); /* overwrite beyond dst buffer */
602 if (litEnd > litLimit_8) return ERROR(corruption_detected); /* risk read beyond lit buffer */
603
604 /* copy Literals */
605 ZSTD_wildcopy(op, *litPtr, sequence.litLength); /* note : oLitEnd <= oend-8 : no risk of overwrite beyond oend */
606 op = oLitEnd;
607 *litPtr = litEnd; /* update for next sequence */
608
609 /* copy Match */
Yann Collet9f5ab1a2015-12-11 00:27:41 +0100610 if (sequence.offset > (size_t)(oLitEnd - base))
Yann Collet44287a32015-11-30 23:13:56 +0100611 {
612 /* offset beyond prefix */
Yann Collet9f5ab1a2015-12-11 00:27:41 +0100613 if (sequence.offset > (size_t)(oLitEnd - vBase))
614 return ERROR(corruption_detected);
Yann Collet44287a32015-11-30 23:13:56 +0100615 match = dictEnd - (base-match);
616 if (match + sequence.matchLength <= dictEnd)
617 {
Yann Collet4bfe4152015-12-06 13:18:37 +0100618 memmove(oLitEnd, match, sequence.matchLength);
Yann Collet44287a32015-11-30 23:13:56 +0100619 return sequenceLength;
620 }
621 /* span extDict & currentPrefixSegment */
622 {
623 size_t length1 = dictEnd - match;
Yann Collet4bfe4152015-12-06 13:18:37 +0100624 memmove(oLitEnd, match, length1);
Yann Collet44287a32015-11-30 23:13:56 +0100625 op = oLitEnd + length1;
626 sequence.matchLength -= length1;
627 match = base;
628 }
629 }
Yann Collet0f366c62015-11-12 16:19:30 +0100630
Yann Collet44287a32015-11-30 23:13:56 +0100631 /* match within prefix */
632 if (sequence.offset < 8)
633 {
634 /* close range match, overlap */
635 const int sub2 = dec64table[sequence.offset];
636 op[0] = match[0];
637 op[1] = match[1];
638 op[2] = match[2];
639 op[3] = match[3];
640 match += dec32table[sequence.offset];
641 ZSTD_copy4(op+4, match);
642 match -= sub2;
643 }
644 else
645 {
646 ZSTD_copy8(op, match);
647 }
648 op += 8; match += 8;
Yann Collet5be2dd22015-11-11 13:43:58 +0100649
Yann Collet44287a32015-11-30 23:13:56 +0100650 if (oMatchEnd > oend-12)
651 {
652 if (op < oend_8)
653 {
654 ZSTD_wildcopy(op, match, oend_8 - op);
655 match += oend_8 - op;
656 op = oend_8;
657 }
658 while (op < oMatchEnd) *op++ = *match++;
659 }
660 else
661 {
662 ZSTD_wildcopy(op, match, sequence.matchLength-8); /* works even if matchLength < 8 */
663 }
664 return sequenceLength;
Yann Collet5be2dd22015-11-11 13:43:58 +0100665}
666
Yann Colletb3a2af92015-11-19 17:13:19 +0100667
Yann Collet5be2dd22015-11-11 13:43:58 +0100668static size_t ZSTD_decompressSequences(
Yann Collet5b78d2f2015-11-12 15:36:05 +0100669 ZSTD_DCtx* dctx,
Yann Collet5be2dd22015-11-11 13:43:58 +0100670 void* dst, size_t maxDstSize,
671 const void* seqStart, size_t seqSize)
672{
Yann Collet5be2dd22015-11-11 13:43:58 +0100673 const BYTE* ip = (const BYTE*)seqStart;
674 const BYTE* const iend = ip + seqSize;
675 BYTE* const ostart = (BYTE* const)dst;
676 BYTE* op = ostart;
677 BYTE* const oend = ostart + maxDstSize;
678 size_t errorCode, dumpsLength;
679 const BYTE* litPtr = dctx->litPtr;
680 const BYTE* const litLimit_8 = litPtr + dctx->litBufSize - 8;
681 const BYTE* const litEnd = litPtr + dctx->litSize;
682 int nbSeq;
683 const BYTE* dumps;
684 U32* DTableLL = dctx->LLTable;
685 U32* DTableML = dctx->MLTable;
686 U32* DTableOffb = dctx->OffTable;
Yann Collet417890c2015-12-04 17:16:37 +0100687 const BYTE* const base = (const BYTE*) (dctx->base);
688 const BYTE* const vBase = (const BYTE*) (dctx->vBase);
689 const BYTE* const dictEnd = (const BYTE*) (dctx->dictEnd);
Yann Collet5be2dd22015-11-11 13:43:58 +0100690
691 /* Build Decoding Tables */
692 errorCode = ZSTD_decodeSeqHeaders(&nbSeq, &dumps, &dumpsLength,
693 DTableLL, DTableML, DTableOffb,
694 ip, iend-ip);
695 if (ZSTD_isError(errorCode)) return errorCode;
696 ip += errorCode;
697
698 /* Regen sequences */
699 {
700 seq_t sequence;
701 seqState_t seqState;
702
703 memset(&sequence, 0, sizeof(sequence));
704 sequence.offset = 4;
705 seqState.dumps = dumps;
706 seqState.dumpsEnd = dumps + dumpsLength;
707 seqState.prevOffset = 4;
708 errorCode = BIT_initDStream(&(seqState.DStream), ip, iend-ip);
709 if (ERR_isError(errorCode)) return ERROR(corruption_detected);
710 FSE_initDState(&(seqState.stateLL), &(seqState.DStream), DTableLL);
711 FSE_initDState(&(seqState.stateOffb), &(seqState.DStream), DTableOffb);
712 FSE_initDState(&(seqState.stateML), &(seqState.DStream), DTableML);
713
Yann Collet44287a32015-11-30 23:13:56 +0100714 for ( ; (BIT_reloadDStream(&(seqState.DStream)) <= BIT_DStream_completed) && nbSeq ; )
Yann Colletb3a2af92015-11-19 17:13:19 +0100715 {
716 size_t oneSeqSize;
717 nbSeq--;
718 ZSTD_decodeSequence(&sequence, &seqState);
719 oneSeqSize = ZSTD_execSequence(op, oend, sequence, &litPtr, litLimit_8, base, vBase, dictEnd);
Yann Collet5be2dd22015-11-11 13:43:58 +0100720 if (ZSTD_isError(oneSeqSize)) return oneSeqSize;
721 op += oneSeqSize;
722 }
723
724 /* check if reached exact end */
Yann Collet44287a32015-11-30 23:13:56 +0100725 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 +0100726
727 /* last literal segment */
728 {
729 size_t lastLLSize = litEnd - litPtr;
730 if (litPtr > litEnd) return ERROR(corruption_detected);
731 if (op+lastLLSize > oend) return ERROR(dstSize_tooSmall);
732 if (op != litPtr) memcpy(op, litPtr, lastLLSize);
733 op += lastLLSize;
734 }
735 }
736
737 return op-ostart;
738}
739
740
Yann Colletb0125102016-01-09 02:00:10 +0100741static void ZSTD_checkContinuity(ZSTD_DCtx* dctx, const void* dst)
742{
743 if (dst != dctx->previousDstEnd) /* not contiguous */
744 {
745 dctx->dictEnd = dctx->previousDstEnd;
746 dctx->vBase = (const char*)dst - ((const char*)(dctx->previousDstEnd) - (const char*)(dctx->base));
747 dctx->base = dst;
748 dctx->previousDstEnd = dst;
749 }
750}
751
752
753static size_t ZSTD_decompressBlock_internal(ZSTD_DCtx* dctx,
Yann Collet5be2dd22015-11-11 13:43:58 +0100754 void* dst, size_t maxDstSize,
755 const void* src, size_t srcSize)
756{
757 /* blockType == blockCompressed */
758 const BYTE* ip = (const BYTE*)src;
759
760 /* Decode literals sub-block */
Yann Collet5b78d2f2015-11-12 15:36:05 +0100761 size_t litCSize = ZSTD_decodeLiteralsBlock(dctx, src, srcSize);
Yann Collet5be2dd22015-11-11 13:43:58 +0100762 if (ZSTD_isError(litCSize)) return litCSize;
763 ip += litCSize;
764 srcSize -= litCSize;
765
Yann Collet5b78d2f2015-11-12 15:36:05 +0100766 return ZSTD_decompressSequences(dctx, dst, maxDstSize, ip, srcSize);
Yann Collet5be2dd22015-11-11 13:43:58 +0100767}
768
769
Yann Colletb0125102016-01-09 02:00:10 +0100770size_t ZSTD_decompressBlock(ZSTD_DCtx* dctx,
771 void* dst, size_t maxDstSize,
772 const void* src, size_t srcSize)
773{
774 ZSTD_checkContinuity(dctx, dst);
775 return ZSTD_decompressBlock_internal(dctx, dst, maxDstSize, src, srcSize);
776}
777
778
Yann Collet31683c02015-12-18 01:26:48 +0100779size_t ZSTD_decompress_usingDict(ZSTD_DCtx* ctx,
780 void* dst, size_t maxDstSize,
781 const void* src, size_t srcSize,
782 const void* dict, size_t dictSize)
Yann Collet5be2dd22015-11-11 13:43:58 +0100783{
784 const BYTE* ip = (const BYTE*)src;
785 const BYTE* iend = ip + srcSize;
786 BYTE* const ostart = (BYTE* const)dst;
787 BYTE* op = ostart;
788 BYTE* const oend = ostart + maxDstSize;
789 size_t remainingSize = srcSize;
Yann Collet5be2dd22015-11-11 13:43:58 +0100790 blockProperties_t blockProperties;
791
Yann Colletb2549842015-11-18 11:29:32 +0100792 /* init */
Yann Collet31683c02015-12-18 01:26:48 +0100793 ZSTD_resetDCtx(ctx);
794 if (dict)
795 {
796 ZSTD_decompress_insertDictionary(ctx, dict, dictSize);
797 ctx->dictEnd = ctx->previousDstEnd;
798 ctx->vBase = (const char*)dst - ((const char*)(ctx->previousDstEnd) - (const char*)(ctx->base));
799 ctx->base = dst;
800 }
801 else
802 {
803 ctx->vBase = ctx->base = ctx->dictEnd = dst;
804 }
Yann Collet5b78d2f2015-11-12 15:36:05 +0100805
Yann Collet5be2dd22015-11-11 13:43:58 +0100806 /* Frame Header */
Yann Collet88fcd292015-11-25 14:42:45 +0100807 {
808 size_t frameHeaderSize;
809 if (srcSize < ZSTD_frameHeaderSize_min+ZSTD_blockHeaderSize) return ERROR(srcSize_wrong);
Yann Collet5be2dd22015-11-11 13:43:58 +0100810#if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT==1)
Yann Collet88fcd292015-11-25 14:42:45 +0100811 {
812 const U32 magicNumber = MEM_readLE32(src);
813 if (ZSTD_isLegacy(magicNumber))
814 return ZSTD_decompressLegacy(dst, maxDstSize, src, srcSize, magicNumber);
815 }
Yann Collet5be2dd22015-11-11 13:43:58 +0100816#endif
Yann Collet88fcd292015-11-25 14:42:45 +0100817 frameHeaderSize = ZSTD_decodeFrameHeader_Part1(ctx, src, ZSTD_frameHeaderSize_min);
818 if (ZSTD_isError(frameHeaderSize)) return frameHeaderSize;
819 if (srcSize < frameHeaderSize+ZSTD_blockHeaderSize) return ERROR(srcSize_wrong);
820 ip += frameHeaderSize; remainingSize -= frameHeaderSize;
821 frameHeaderSize = ZSTD_decodeFrameHeader_Part2(ctx, src, frameHeaderSize);
822 if (ZSTD_isError(frameHeaderSize)) return frameHeaderSize;
823 }
Yann Collet5be2dd22015-11-11 13:43:58 +0100824
825 /* Loop on each block */
826 while (1)
827 {
828 size_t decodedSize=0;
829 size_t cBlockSize = ZSTD_getcBlockSize(ip, iend-ip, &blockProperties);
830 if (ZSTD_isError(cBlockSize)) return cBlockSize;
831
832 ip += ZSTD_blockHeaderSize;
833 remainingSize -= ZSTD_blockHeaderSize;
834 if (cBlockSize > remainingSize) return ERROR(srcSize_wrong);
835
836 switch(blockProperties.blockType)
837 {
838 case bt_compressed:
Yann Colletb0125102016-01-09 02:00:10 +0100839 decodedSize = ZSTD_decompressBlock_internal(ctx, op, oend-op, ip, cBlockSize);
Yann Collet5be2dd22015-11-11 13:43:58 +0100840 break;
841 case bt_raw :
Yann Collet0f366c62015-11-12 16:19:30 +0100842 decodedSize = ZSTD_copyRawBlock(op, oend-op, ip, cBlockSize);
Yann Collet5be2dd22015-11-11 13:43:58 +0100843 break;
844 case bt_rle :
845 return ERROR(GENERIC); /* not yet supported */
846 break;
847 case bt_end :
848 /* end of frame */
849 if (remainingSize) return ERROR(srcSize_wrong);
850 break;
851 default:
852 return ERROR(GENERIC); /* impossible */
853 }
854 if (cBlockSize == 0) break; /* bt_end */
855
856 if (ZSTD_isError(decodedSize)) return decodedSize;
857 op += decodedSize;
858 ip += cBlockSize;
859 remainingSize -= cBlockSize;
860 }
861
862 return op-ostart;
863}
864
Yann Collet31683c02015-12-18 01:26:48 +0100865
866size_t ZSTD_decompressDCtx(ZSTD_DCtx* dctx, void* dst, size_t maxDstSize, const void* src, size_t srcSize)
867{
868 return ZSTD_decompress_usingDict(dctx, dst, maxDstSize, src, srcSize, NULL, 0);
869}
870
Yann Collet5be2dd22015-11-11 13:43:58 +0100871size_t ZSTD_decompress(void* dst, size_t maxDstSize, const void* src, size_t srcSize)
872{
Yann Collet3a3b72f2016-01-11 12:56:11 +0100873#if defined(ZSTD_HEAPMODE) && (ZSTD_HEAPMODE==1)
874 size_t regenSize;
875 ZSTD_DCtx* dctx = ZSTD_createDCtx();
876 if (dctx==NULL) return ERROR(memory_allocation);
877 regenSize = ZSTD_decompressDCtx(dctx, dst, maxDstSize, src, srcSize);
878 ZSTD_freeDCtx(dctx);
879 return regenSize;
880#else
Yann Collet31683c02015-12-18 01:26:48 +0100881 ZSTD_DCtx dctx;
882 return ZSTD_decompressDCtx(&dctx, dst, maxDstSize, src, srcSize);
Yann Colleta768a302016-01-21 16:04:35 +0100883#endif
Yann Collet5be2dd22015-11-11 13:43:58 +0100884}
885
886
887/* ******************************
888* Streaming Decompression API
889********************************/
Yann Collet5be2dd22015-11-11 13:43:58 +0100890size_t ZSTD_nextSrcSizeToDecompress(ZSTD_DCtx* dctx)
891{
892 return dctx->expected;
893}
894
895size_t ZSTD_decompressContinue(ZSTD_DCtx* ctx, void* dst, size_t maxDstSize, const void* src, size_t srcSize)
896{
897 /* Sanity check */
898 if (srcSize != ctx->expected) return ERROR(srcSize_wrong);
Yann Colletb0125102016-01-09 02:00:10 +0100899 ZSTD_checkContinuity(ctx, dst);
Yann Collet5be2dd22015-11-11 13:43:58 +0100900
Yann Collet88fcd292015-11-25 14:42:45 +0100901 /* Decompress : frame header; part 1 */
902 switch (ctx->stage)
Yann Collet5be2dd22015-11-11 13:43:58 +0100903 {
Yann Collet88fcd292015-11-25 14:42:45 +0100904 case ZSTDds_getFrameHeaderSize :
Yann Collet5be2dd22015-11-11 13:43:58 +0100905 {
Yann Collet88fcd292015-11-25 14:42:45 +0100906 /* get frame header size */
907 if (srcSize != ZSTD_frameHeaderSize_min) return ERROR(srcSize_wrong); /* impossible */
908 ctx->headerSize = ZSTD_decodeFrameHeader_Part1(ctx, src, ZSTD_frameHeaderSize_min);
Yann Collete4fdad52015-11-25 21:09:17 +0100909 if (ZSTD_isError(ctx->headerSize)) return ctx->headerSize;
Yann Collet88fcd292015-11-25 14:42:45 +0100910 memcpy(ctx->headerBuffer, src, ZSTD_frameHeaderSize_min);
911 if (ctx->headerSize > ZSTD_frameHeaderSize_min)
912 {
913 ctx->expected = ctx->headerSize - ZSTD_frameHeaderSize_min;
914 ctx->stage = ZSTDds_decodeFrameHeader;
915 return 0;
916 }
917 ctx->expected = 0; /* not necessary to copy more */
Yann Collet5be2dd22015-11-11 13:43:58 +0100918 }
Yann Collet88fcd292015-11-25 14:42:45 +0100919 case ZSTDds_decodeFrameHeader:
Yann Collet5be2dd22015-11-11 13:43:58 +0100920 {
Yann Collet88fcd292015-11-25 14:42:45 +0100921 /* get frame header */
922 size_t result;
923 memcpy(ctx->headerBuffer + ZSTD_frameHeaderSize_min, src, ctx->expected);
924 result = ZSTD_decodeFrameHeader_Part2(ctx, ctx->headerBuffer, ctx->headerSize);
925 if (ZSTD_isError(result)) return result;
926 ctx->expected = ZSTD_blockHeaderSize;
927 ctx->stage = ZSTDds_decodeBlockHeader;
928 return 0;
Yann Collet5be2dd22015-11-11 13:43:58 +0100929 }
Yann Collet88fcd292015-11-25 14:42:45 +0100930 case ZSTDds_decodeBlockHeader:
Yann Collet5be2dd22015-11-11 13:43:58 +0100931 {
Yann Collet88fcd292015-11-25 14:42:45 +0100932 /* Decode block header */
933 blockProperties_t bp;
934 size_t blockSize = ZSTD_getcBlockSize(src, ZSTD_blockHeaderSize, &bp);
935 if (ZSTD_isError(blockSize)) return blockSize;
936 if (bp.blockType == bt_end)
937 {
938 ctx->expected = 0;
939 ctx->stage = ZSTDds_getFrameHeaderSize;
940 }
941 else
942 {
943 ctx->expected = blockSize;
944 ctx->bType = bp.blockType;
945 ctx->stage = ZSTDds_decompressBlock;
946 }
Yann Collet88fcd292015-11-25 14:42:45 +0100947 return 0;
948 }
Yann Collet417890c2015-12-04 17:16:37 +0100949 case ZSTDds_decompressBlock:
Yann Collet88fcd292015-11-25 14:42:45 +0100950 {
951 /* Decompress : block content */
952 size_t rSize;
953 switch(ctx->bType)
954 {
955 case bt_compressed:
Yann Colletb0125102016-01-09 02:00:10 +0100956 rSize = ZSTD_decompressBlock_internal(ctx, dst, maxDstSize, src, srcSize);
Yann Collet88fcd292015-11-25 14:42:45 +0100957 break;
958 case bt_raw :
959 rSize = ZSTD_copyRawBlock(dst, maxDstSize, src, srcSize);
960 break;
961 case bt_rle :
962 return ERROR(GENERIC); /* not yet handled */
963 break;
964 case bt_end : /* should never happen (filtered at phase 1) */
965 rSize = 0;
966 break;
967 default:
968 return ERROR(GENERIC);
969 }
970 ctx->stage = ZSTDds_decodeBlockHeader;
971 ctx->expected = ZSTD_blockHeaderSize;
972 ctx->previousDstEnd = (char*)dst + rSize;
973 return rSize;
974 }
975 default:
976 return ERROR(GENERIC); /* impossible */
977 }
Yann Collet5be2dd22015-11-11 13:43:58 +0100978}
979
980
Yann Colletb0125102016-01-09 02:00:10 +0100981void ZSTD_decompress_insertDictionary(ZSTD_DCtx* ctx, const void* dict, size_t dictSize)
Yann Collet417890c2015-12-04 17:16:37 +0100982{
983 ctx->dictEnd = ctx->previousDstEnd;
Yann Colletb0125102016-01-09 02:00:10 +0100984 ctx->vBase = (const char*)dict - ((const char*)(ctx->previousDstEnd) - (const char*)(ctx->base));
985 ctx->base = dict;
986 ctx->previousDstEnd = (const char*)dict + dictSize;
Yann Collet417890c2015-12-04 17:16:37 +0100987}