blob: 6dc6f9a7db687ca867920afb7ecb10cfe2e1f7ec [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"
64#include "huff0.h"
65
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 Collet59d1f792016-01-23 19:28:41 +0100300 size_t litSize, litCSize;
301 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;
307 litSize = ((istart[0] & 15) << 6) + (istart[1] >> 2);
308 litCSize = ((istart[1] & 3) << 8) + istart[2];
309 break;
310 case 2:
311 /* 2 - 2 - 14 - 14 */
312 lhSize=4;
313 litSize = ((istart[0] & 15) << 10) + (istart[1] << 2) + (istart[2] >> 6);
314 litCSize = ((istart[2] & 63) << 8) + istart[3];
315 break;
316 case 3:
317 /* 2 - 2 - 18 - 18 */
318 lhSize=5;
319 litSize = ((istart[0] & 15) << 14) + (istart[1] << 6) + (istart[2] >> 2);
320 litCSize = ((istart[2] & 3) << 16) + (istart[3] << 8) + istart[4];
321 break;
322 }
323
324 if (HUF_isError( HUF_decompress(dctx->litBuffer, litSize, istart+lhSize, litCSize) ))
325 return ERROR(corruption_detected);
326
Yann Collet5be2dd22015-11-11 13:43:58 +0100327 dctx->litPtr = dctx->litBuffer;
328 dctx->litBufSize = BLOCKSIZE+8;
329 dctx->litSize = litSize;
Yann Collet59d1f792016-01-23 19:28:41 +0100330 return litCSize + lhSize;
Yann Collet5be2dd22015-11-11 13:43:58 +0100331 }
332 case IS_RAW:
333 {
Yann Collet59d1f792016-01-23 19:28:41 +0100334 size_t litSize;
335 U32 lhSize = ((istart[0]) >> 4) & 3;
336 switch(lhSize)
Yann Collet5be2dd22015-11-11 13:43:58 +0100337 {
Yann Collet59d1f792016-01-23 19:28:41 +0100338 case 0: case 1: default: /* note : default is impossible, since lhSize into [0..3] */
339 lhSize=1;
340 litSize = istart[0] & 31;
341 break;
342 case 2:
343 litSize = ((istart[0] & 15) << 8) + istart[1];
344 break;
345 case 3:
346 litSize = ((istart[0] & 15) << 16) + (istart[1] << 8) + istart[2];
347 break;
348 }
349
350 if (litSize > srcSize-11) /* risk of reading beyond src buffer with wildcopy */
351 {
352 if (litSize > srcSize-litSize) return ERROR(corruption_detected);
353 memcpy(dctx->litBuffer, istart+lhSize, litSize);
Yann Collet5be2dd22015-11-11 13:43:58 +0100354 dctx->litPtr = dctx->litBuffer;
355 dctx->litBufSize = BLOCKSIZE+8;
356 dctx->litSize = litSize;
Yann Collet59d1f792016-01-23 19:28:41 +0100357 return litSize+lhSize;
Yann Collet5be2dd22015-11-11 13:43:58 +0100358 }
359 /* direct reference into compressed stream */
Yann Collet59d1f792016-01-23 19:28:41 +0100360 dctx->litPtr = istart+lhSize;
361 dctx->litBufSize = srcSize-lhSize;
Yann Collet5be2dd22015-11-11 13:43:58 +0100362 dctx->litSize = litSize;
Yann Collet59d1f792016-01-23 19:28:41 +0100363 return lhSize+litSize;
364 }
Yann Collet5be2dd22015-11-11 13:43:58 +0100365 case IS_RLE:
366 {
Yann Collet59d1f792016-01-23 19:28:41 +0100367 size_t litSize;
368 U32 lhSize = ((istart[0]) >> 4) & 3;
369 switch(lhSize)
370 {
371 case 0: case 1: default: /* note : default is impossible, since lhSize into [0..3] */
372 lhSize = 1;
373 litSize = istart[0] & 31;
374 break;
375 case 2:
376 litSize = ((istart[0] & 15) << 8) + istart[1];
377 break;
378 case 3:
379 litSize = ((istart[0] & 15) << 16) + (istart[1] << 8) + istart[2];
380 break;
381 }
Yann Collet5be2dd22015-11-11 13:43:58 +0100382 if (litSize > BLOCKSIZE) return ERROR(corruption_detected);
Yann Collet59d1f792016-01-23 19:28:41 +0100383 memset(dctx->litBuffer, istart[lhSize], litSize);
Yann Collet5be2dd22015-11-11 13:43:58 +0100384 dctx->litPtr = dctx->litBuffer;
385 dctx->litBufSize = BLOCKSIZE+8;
386 dctx->litSize = litSize;
Yann Collet59d1f792016-01-23 19:28:41 +0100387 return lhSize+1;
Yann Collet5be2dd22015-11-11 13:43:58 +0100388 }
Yann Collet59d1f792016-01-23 19:28:41 +0100389 default: /* IS_PCH */
390 return ERROR(corruption_detected); /* not yet nominal case */
Yann Collet5be2dd22015-11-11 13:43:58 +0100391 }
392}
393
394
395size_t ZSTD_decodeSeqHeaders(int* nbSeq, const BYTE** dumpsPtr, size_t* dumpsLengthPtr,
396 FSE_DTable* DTableLL, FSE_DTable* DTableML, FSE_DTable* DTableOffb,
397 const void* src, size_t srcSize)
398{
399 const BYTE* const istart = (const BYTE* const)src;
400 const BYTE* ip = istart;
401 const BYTE* const iend = istart + srcSize;
402 U32 LLtype, Offtype, MLtype;
403 U32 LLlog, Offlog, MLlog;
404 size_t dumpsLength;
405
406 /* check */
407 if (srcSize < 5) return ERROR(srcSize_wrong);
408
409 /* SeqHead */
410 *nbSeq = MEM_readLE16(ip); ip+=2;
411 LLtype = *ip >> 6;
412 Offtype = (*ip >> 4) & 3;
413 MLtype = (*ip >> 2) & 3;
414 if (*ip & 2)
415 {
416 dumpsLength = ip[2];
417 dumpsLength += ip[1] << 8;
418 ip += 3;
419 }
420 else
421 {
422 dumpsLength = ip[1];
423 dumpsLength += (ip[0] & 1) << 8;
424 ip += 2;
425 }
426 *dumpsPtr = ip;
427 ip += dumpsLength;
428 *dumpsLengthPtr = dumpsLength;
429
430 /* check */
431 if (ip > iend-3) return ERROR(srcSize_wrong); /* min : all 3 are "raw", hence no header, but at least xxLog bits per type */
432
433 /* sequences */
434 {
Yann Collet82368cf2015-11-16 19:10:56 +0100435 S16 norm[MaxML+1]; /* assumption : MaxML >= MaxLL >= MaxOff */
Yann Collet5be2dd22015-11-11 13:43:58 +0100436 size_t headerSize;
437
438 /* Build DTables */
439 switch(LLtype)
440 {
441 U32 max;
442 case bt_rle :
443 LLlog = 0;
444 FSE_buildDTable_rle(DTableLL, *ip++); break;
445 case bt_raw :
446 LLlog = LLbits;
447 FSE_buildDTable_raw(DTableLL, LLbits); break;
448 default :
449 max = MaxLL;
450 headerSize = FSE_readNCount(norm, &max, &LLlog, ip, iend-ip);
451 if (FSE_isError(headerSize)) return ERROR(GENERIC);
452 if (LLlog > LLFSELog) return ERROR(corruption_detected);
453 ip += headerSize;
454 FSE_buildDTable(DTableLL, norm, max, LLlog);
455 }
456
457 switch(Offtype)
458 {
459 U32 max;
460 case bt_rle :
461 Offlog = 0;
462 if (ip > iend-2) return ERROR(srcSize_wrong); /* min : "raw", hence no header, but at least xxLog bits */
463 FSE_buildDTable_rle(DTableOffb, *ip++ & MaxOff); /* if *ip > MaxOff, data is corrupted */
464 break;
465 case bt_raw :
466 Offlog = Offbits;
467 FSE_buildDTable_raw(DTableOffb, Offbits); break;
468 default :
469 max = MaxOff;
470 headerSize = FSE_readNCount(norm, &max, &Offlog, ip, iend-ip);
471 if (FSE_isError(headerSize)) return ERROR(GENERIC);
472 if (Offlog > OffFSELog) return ERROR(corruption_detected);
473 ip += headerSize;
474 FSE_buildDTable(DTableOffb, norm, max, Offlog);
475 }
476
477 switch(MLtype)
478 {
479 U32 max;
480 case bt_rle :
481 MLlog = 0;
482 if (ip > iend-2) return ERROR(srcSize_wrong); /* min : "raw", hence no header, but at least xxLog bits */
483 FSE_buildDTable_rle(DTableML, *ip++); break;
484 case bt_raw :
485 MLlog = MLbits;
486 FSE_buildDTable_raw(DTableML, MLbits); break;
487 default :
488 max = MaxML;
489 headerSize = FSE_readNCount(norm, &max, &MLlog, ip, iend-ip);
490 if (FSE_isError(headerSize)) return ERROR(GENERIC);
491 if (MLlog > MLFSELog) return ERROR(corruption_detected);
492 ip += headerSize;
493 FSE_buildDTable(DTableML, norm, max, MLlog);
494 }
495 }
496
497 return ip-istart;
498}
499
500
501typedef struct {
502 size_t litLength;
503 size_t offset;
504 size_t matchLength;
505} seq_t;
506
507typedef struct {
508 BIT_DStream_t DStream;
509 FSE_DState_t stateLL;
510 FSE_DState_t stateOffb;
511 FSE_DState_t stateML;
512 size_t prevOffset;
513 const BYTE* dumps;
514 const BYTE* dumpsEnd;
515} seqState_t;
516
517
518static void ZSTD_decodeSequence(seq_t* seq, seqState_t* seqState)
519{
520 size_t litLength;
521 size_t prevOffset;
522 size_t offset;
523 size_t matchLength;
524 const BYTE* dumps = seqState->dumps;
525 const BYTE* const de = seqState->dumpsEnd;
526
527 /* Literal length */
528 litLength = FSE_decodeSymbol(&(seqState->stateLL), &(seqState->DStream));
Yann Collete4fdad52015-11-25 21:09:17 +0100529 prevOffset = litLength ? seq->offset : seqState->prevOffset;
Yann Collet5be2dd22015-11-11 13:43:58 +0100530 if (litLength == MaxLL)
531 {
532 U32 add = *dumps++;
533 if (add < 255) litLength += add;
534 else
535 {
536 litLength = MEM_readLE32(dumps) & 0xFFFFFF; /* no pb : dumps is always followed by seq tables > 1 byte */
537 dumps += 3;
538 }
539 if (dumps >= de) dumps = de-1; /* late correction, to avoid read overflow (data is now corrupted anyway) */
540 }
541
542 /* Offset */
543 {
544 static const U32 offsetPrefix[MaxOff+1] = {
545 1 /*fake*/, 1, 2, 4, 8, 16, 32, 64, 128, 256,
546 512, 1024, 2048, 4096, 8192, 16384, 32768, 65536, 131072, 262144,
547 524288, 1048576, 2097152, 4194304, 8388608, 16777216, 33554432, /*fake*/ 1, 1, 1, 1, 1 };
548 U32 offsetCode, nbBits;
549 offsetCode = FSE_decodeSymbol(&(seqState->stateOffb), &(seqState->DStream)); /* <= maxOff, by table construction */
550 if (MEM_32bits()) BIT_reloadDStream(&(seqState->DStream));
551 nbBits = offsetCode - 1;
552 if (offsetCode==0) nbBits = 0; /* cmove */
553 offset = offsetPrefix[offsetCode] + BIT_readBits(&(seqState->DStream), nbBits);
554 if (MEM_32bits()) BIT_reloadDStream(&(seqState->DStream));
555 if (offsetCode==0) offset = prevOffset; /* cmove */
Yann Collet55aa7f92015-11-20 12:04:52 +0100556 if (offsetCode | !litLength) seqState->prevOffset = seq->offset; /* cmove */
Yann Collet5be2dd22015-11-11 13:43:58 +0100557 }
558
559 /* MatchLength */
560 matchLength = FSE_decodeSymbol(&(seqState->stateML), &(seqState->DStream));
561 if (matchLength == MaxML)
562 {
563 U32 add = *dumps++;
564 if (add < 255) matchLength += add;
565 else
566 {
567 matchLength = MEM_readLE32(dumps) & 0xFFFFFF; /* no pb : dumps is always followed by seq tables > 1 byte */
568 dumps += 3;
569 }
570 if (dumps >= de) dumps = de-1; /* late correction, to avoid read overflow (data is now corrupted anyway) */
571 }
572 matchLength += MINMATCH;
573
574 /* save result */
575 seq->litLength = litLength;
576 seq->offset = offset;
577 seq->matchLength = matchLength;
578 seqState->dumps = dumps;
579}
580
581
Yann Collet5b78d2f2015-11-12 15:36:05 +0100582FORCE_INLINE size_t ZSTD_execSequence(BYTE* op,
Yann Colletb3a2af92015-11-19 17:13:19 +0100583 BYTE* const oend, seq_t sequence,
Yann Collet5be2dd22015-11-11 13:43:58 +0100584 const BYTE** litPtr, const BYTE* const litLimit_8,
Yann Collet417890c2015-12-04 17:16:37 +0100585 const BYTE* const base, const BYTE* const vBase, const BYTE* const dictEnd)
Yann Collet5be2dd22015-11-11 13:43:58 +0100586{
Yann Colletb3a2af92015-11-19 17:13:19 +0100587 static const int dec32table[] = { 0, 1, 2, 1, 4, 4, 4, 4 }; /* added */
588 static const int dec64table[] = { 8, 8, 8, 7, 8, 9,10,11 }; /* substracted */
Yann Collet5be2dd22015-11-11 13:43:58 +0100589 BYTE* const oLitEnd = op + sequence.litLength;
Yann Colletb3a2af92015-11-19 17:13:19 +0100590 const size_t sequenceLength = sequence.litLength + sequence.matchLength;
591 BYTE* const oMatchEnd = op + sequenceLength; /* risk : address space overflow (32-bits) */
Yann Collet5be2dd22015-11-11 13:43:58 +0100592 BYTE* const oend_8 = oend-8;
593 const BYTE* const litEnd = *litPtr + sequence.litLength;
Yann Colletb3a2af92015-11-19 17:13:19 +0100594 const BYTE* match = oLitEnd - sequence.offset;
Yann Collet5be2dd22015-11-11 13:43:58 +0100595
596 /* check */
597 if (oLitEnd > oend_8) return ERROR(dstSize_tooSmall); /* last match must start at a minimum distance of 8 from oend */
598 if (oMatchEnd > oend) return ERROR(dstSize_tooSmall); /* overwrite beyond dst buffer */
599 if (litEnd > litLimit_8) return ERROR(corruption_detected); /* risk read beyond lit buffer */
600
601 /* copy Literals */
602 ZSTD_wildcopy(op, *litPtr, sequence.litLength); /* note : oLitEnd <= oend-8 : no risk of overwrite beyond oend */
603 op = oLitEnd;
604 *litPtr = litEnd; /* update for next sequence */
605
606 /* copy Match */
Yann Collet9f5ab1a2015-12-11 00:27:41 +0100607 if (sequence.offset > (size_t)(oLitEnd - base))
Yann Collet44287a32015-11-30 23:13:56 +0100608 {
609 /* offset beyond prefix */
Yann Collet9f5ab1a2015-12-11 00:27:41 +0100610 if (sequence.offset > (size_t)(oLitEnd - vBase))
611 return ERROR(corruption_detected);
Yann Collet44287a32015-11-30 23:13:56 +0100612 match = dictEnd - (base-match);
613 if (match + sequence.matchLength <= dictEnd)
614 {
Yann Collet4bfe4152015-12-06 13:18:37 +0100615 memmove(oLitEnd, match, sequence.matchLength);
Yann Collet44287a32015-11-30 23:13:56 +0100616 return sequenceLength;
617 }
618 /* span extDict & currentPrefixSegment */
619 {
620 size_t length1 = dictEnd - match;
Yann Collet4bfe4152015-12-06 13:18:37 +0100621 memmove(oLitEnd, match, length1);
Yann Collet44287a32015-11-30 23:13:56 +0100622 op = oLitEnd + length1;
623 sequence.matchLength -= length1;
624 match = base;
625 }
626 }
Yann Collet0f366c62015-11-12 16:19:30 +0100627
Yann Collet44287a32015-11-30 23:13:56 +0100628 /* match within prefix */
629 if (sequence.offset < 8)
630 {
631 /* close range match, overlap */
632 const int sub2 = dec64table[sequence.offset];
633 op[0] = match[0];
634 op[1] = match[1];
635 op[2] = match[2];
636 op[3] = match[3];
637 match += dec32table[sequence.offset];
638 ZSTD_copy4(op+4, match);
639 match -= sub2;
640 }
641 else
642 {
643 ZSTD_copy8(op, match);
644 }
645 op += 8; match += 8;
Yann Collet5be2dd22015-11-11 13:43:58 +0100646
Yann Collet44287a32015-11-30 23:13:56 +0100647 if (oMatchEnd > oend-12)
648 {
649 if (op < oend_8)
650 {
651 ZSTD_wildcopy(op, match, oend_8 - op);
652 match += oend_8 - op;
653 op = oend_8;
654 }
655 while (op < oMatchEnd) *op++ = *match++;
656 }
657 else
658 {
659 ZSTD_wildcopy(op, match, sequence.matchLength-8); /* works even if matchLength < 8 */
660 }
661 return sequenceLength;
Yann Collet5be2dd22015-11-11 13:43:58 +0100662}
663
Yann Colletb3a2af92015-11-19 17:13:19 +0100664
Yann Collet5be2dd22015-11-11 13:43:58 +0100665static size_t ZSTD_decompressSequences(
Yann Collet5b78d2f2015-11-12 15:36:05 +0100666 ZSTD_DCtx* dctx,
Yann Collet5be2dd22015-11-11 13:43:58 +0100667 void* dst, size_t maxDstSize,
668 const void* seqStart, size_t seqSize)
669{
Yann Collet5be2dd22015-11-11 13:43:58 +0100670 const BYTE* ip = (const BYTE*)seqStart;
671 const BYTE* const iend = ip + seqSize;
672 BYTE* const ostart = (BYTE* const)dst;
673 BYTE* op = ostart;
674 BYTE* const oend = ostart + maxDstSize;
675 size_t errorCode, dumpsLength;
676 const BYTE* litPtr = dctx->litPtr;
677 const BYTE* const litLimit_8 = litPtr + dctx->litBufSize - 8;
678 const BYTE* const litEnd = litPtr + dctx->litSize;
679 int nbSeq;
680 const BYTE* dumps;
681 U32* DTableLL = dctx->LLTable;
682 U32* DTableML = dctx->MLTable;
683 U32* DTableOffb = dctx->OffTable;
Yann Collet417890c2015-12-04 17:16:37 +0100684 const BYTE* const base = (const BYTE*) (dctx->base);
685 const BYTE* const vBase = (const BYTE*) (dctx->vBase);
686 const BYTE* const dictEnd = (const BYTE*) (dctx->dictEnd);
Yann Collet5be2dd22015-11-11 13:43:58 +0100687
688 /* Build Decoding Tables */
689 errorCode = ZSTD_decodeSeqHeaders(&nbSeq, &dumps, &dumpsLength,
690 DTableLL, DTableML, DTableOffb,
691 ip, iend-ip);
692 if (ZSTD_isError(errorCode)) return errorCode;
693 ip += errorCode;
694
695 /* Regen sequences */
696 {
697 seq_t sequence;
698 seqState_t seqState;
699
700 memset(&sequence, 0, sizeof(sequence));
701 sequence.offset = 4;
702 seqState.dumps = dumps;
703 seqState.dumpsEnd = dumps + dumpsLength;
704 seqState.prevOffset = 4;
705 errorCode = BIT_initDStream(&(seqState.DStream), ip, iend-ip);
706 if (ERR_isError(errorCode)) return ERROR(corruption_detected);
707 FSE_initDState(&(seqState.stateLL), &(seqState.DStream), DTableLL);
708 FSE_initDState(&(seqState.stateOffb), &(seqState.DStream), DTableOffb);
709 FSE_initDState(&(seqState.stateML), &(seqState.DStream), DTableML);
710
Yann Collet44287a32015-11-30 23:13:56 +0100711 for ( ; (BIT_reloadDStream(&(seqState.DStream)) <= BIT_DStream_completed) && nbSeq ; )
Yann Colletb3a2af92015-11-19 17:13:19 +0100712 {
713 size_t oneSeqSize;
714 nbSeq--;
715 ZSTD_decodeSequence(&sequence, &seqState);
716 oneSeqSize = ZSTD_execSequence(op, oend, sequence, &litPtr, litLimit_8, base, vBase, dictEnd);
Yann Collet5be2dd22015-11-11 13:43:58 +0100717 if (ZSTD_isError(oneSeqSize)) return oneSeqSize;
718 op += oneSeqSize;
719 }
720
721 /* check if reached exact end */
Yann Collet44287a32015-11-30 23:13:56 +0100722 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 +0100723
724 /* last literal segment */
725 {
726 size_t lastLLSize = litEnd - litPtr;
727 if (litPtr > litEnd) return ERROR(corruption_detected);
728 if (op+lastLLSize > oend) return ERROR(dstSize_tooSmall);
729 if (op != litPtr) memcpy(op, litPtr, lastLLSize);
730 op += lastLLSize;
731 }
732 }
733
734 return op-ostart;
735}
736
737
Yann Colletb0125102016-01-09 02:00:10 +0100738static void ZSTD_checkContinuity(ZSTD_DCtx* dctx, const void* dst)
739{
740 if (dst != dctx->previousDstEnd) /* not contiguous */
741 {
742 dctx->dictEnd = dctx->previousDstEnd;
743 dctx->vBase = (const char*)dst - ((const char*)(dctx->previousDstEnd) - (const char*)(dctx->base));
744 dctx->base = dst;
745 dctx->previousDstEnd = dst;
746 }
747}
748
749
750static size_t ZSTD_decompressBlock_internal(ZSTD_DCtx* dctx,
Yann Collet5be2dd22015-11-11 13:43:58 +0100751 void* dst, size_t maxDstSize,
752 const void* src, size_t srcSize)
753{
754 /* blockType == blockCompressed */
755 const BYTE* ip = (const BYTE*)src;
756
757 /* Decode literals sub-block */
Yann Collet5b78d2f2015-11-12 15:36:05 +0100758 size_t litCSize = ZSTD_decodeLiteralsBlock(dctx, src, srcSize);
Yann Collet5be2dd22015-11-11 13:43:58 +0100759 if (ZSTD_isError(litCSize)) return litCSize;
760 ip += litCSize;
761 srcSize -= litCSize;
762
Yann Collet5b78d2f2015-11-12 15:36:05 +0100763 return ZSTD_decompressSequences(dctx, dst, maxDstSize, ip, srcSize);
Yann Collet5be2dd22015-11-11 13:43:58 +0100764}
765
766
Yann Colletb0125102016-01-09 02:00:10 +0100767size_t ZSTD_decompressBlock(ZSTD_DCtx* dctx,
768 void* dst, size_t maxDstSize,
769 const void* src, size_t srcSize)
770{
771 ZSTD_checkContinuity(dctx, dst);
772 return ZSTD_decompressBlock_internal(dctx, dst, maxDstSize, src, srcSize);
773}
774
775
Yann Collet31683c02015-12-18 01:26:48 +0100776size_t ZSTD_decompress_usingDict(ZSTD_DCtx* ctx,
777 void* dst, size_t maxDstSize,
778 const void* src, size_t srcSize,
779 const void* dict, size_t dictSize)
Yann Collet5be2dd22015-11-11 13:43:58 +0100780{
781 const BYTE* ip = (const BYTE*)src;
782 const BYTE* iend = ip + srcSize;
783 BYTE* const ostart = (BYTE* const)dst;
784 BYTE* op = ostart;
785 BYTE* const oend = ostart + maxDstSize;
786 size_t remainingSize = srcSize;
Yann Collet5be2dd22015-11-11 13:43:58 +0100787 blockProperties_t blockProperties;
788
Yann Colletb2549842015-11-18 11:29:32 +0100789 /* init */
Yann Collet31683c02015-12-18 01:26:48 +0100790 ZSTD_resetDCtx(ctx);
791 if (dict)
792 {
793 ZSTD_decompress_insertDictionary(ctx, dict, dictSize);
794 ctx->dictEnd = ctx->previousDstEnd;
795 ctx->vBase = (const char*)dst - ((const char*)(ctx->previousDstEnd) - (const char*)(ctx->base));
796 ctx->base = dst;
797 }
798 else
799 {
800 ctx->vBase = ctx->base = ctx->dictEnd = dst;
801 }
Yann Collet5b78d2f2015-11-12 15:36:05 +0100802
Yann Collet5be2dd22015-11-11 13:43:58 +0100803 /* Frame Header */
Yann Collet88fcd292015-11-25 14:42:45 +0100804 {
805 size_t frameHeaderSize;
806 if (srcSize < ZSTD_frameHeaderSize_min+ZSTD_blockHeaderSize) return ERROR(srcSize_wrong);
Yann Collet5be2dd22015-11-11 13:43:58 +0100807#if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT==1)
Yann Collet88fcd292015-11-25 14:42:45 +0100808 {
809 const U32 magicNumber = MEM_readLE32(src);
810 if (ZSTD_isLegacy(magicNumber))
811 return ZSTD_decompressLegacy(dst, maxDstSize, src, srcSize, magicNumber);
812 }
Yann Collet5be2dd22015-11-11 13:43:58 +0100813#endif
Yann Collet88fcd292015-11-25 14:42:45 +0100814 frameHeaderSize = ZSTD_decodeFrameHeader_Part1(ctx, src, ZSTD_frameHeaderSize_min);
815 if (ZSTD_isError(frameHeaderSize)) return frameHeaderSize;
816 if (srcSize < frameHeaderSize+ZSTD_blockHeaderSize) return ERROR(srcSize_wrong);
817 ip += frameHeaderSize; remainingSize -= frameHeaderSize;
818 frameHeaderSize = ZSTD_decodeFrameHeader_Part2(ctx, src, frameHeaderSize);
819 if (ZSTD_isError(frameHeaderSize)) return frameHeaderSize;
820 }
Yann Collet5be2dd22015-11-11 13:43:58 +0100821
822 /* Loop on each block */
823 while (1)
824 {
825 size_t decodedSize=0;
826 size_t cBlockSize = ZSTD_getcBlockSize(ip, iend-ip, &blockProperties);
827 if (ZSTD_isError(cBlockSize)) return cBlockSize;
828
829 ip += ZSTD_blockHeaderSize;
830 remainingSize -= ZSTD_blockHeaderSize;
831 if (cBlockSize > remainingSize) return ERROR(srcSize_wrong);
832
833 switch(blockProperties.blockType)
834 {
835 case bt_compressed:
Yann Colletb0125102016-01-09 02:00:10 +0100836 decodedSize = ZSTD_decompressBlock_internal(ctx, op, oend-op, ip, cBlockSize);
Yann Collet5be2dd22015-11-11 13:43:58 +0100837 break;
838 case bt_raw :
Yann Collet0f366c62015-11-12 16:19:30 +0100839 decodedSize = ZSTD_copyRawBlock(op, oend-op, ip, cBlockSize);
Yann Collet5be2dd22015-11-11 13:43:58 +0100840 break;
841 case bt_rle :
842 return ERROR(GENERIC); /* not yet supported */
843 break;
844 case bt_end :
845 /* end of frame */
846 if (remainingSize) return ERROR(srcSize_wrong);
847 break;
848 default:
849 return ERROR(GENERIC); /* impossible */
850 }
851 if (cBlockSize == 0) break; /* bt_end */
852
853 if (ZSTD_isError(decodedSize)) return decodedSize;
854 op += decodedSize;
855 ip += cBlockSize;
856 remainingSize -= cBlockSize;
857 }
858
859 return op-ostart;
860}
861
Yann Collet31683c02015-12-18 01:26:48 +0100862
863size_t ZSTD_decompressDCtx(ZSTD_DCtx* dctx, void* dst, size_t maxDstSize, const void* src, size_t srcSize)
864{
865 return ZSTD_decompress_usingDict(dctx, dst, maxDstSize, src, srcSize, NULL, 0);
866}
867
Yann Collet5be2dd22015-11-11 13:43:58 +0100868size_t ZSTD_decompress(void* dst, size_t maxDstSize, const void* src, size_t srcSize)
869{
Yann Collet3a3b72f2016-01-11 12:56:11 +0100870#if defined(ZSTD_HEAPMODE) && (ZSTD_HEAPMODE==1)
871 size_t regenSize;
872 ZSTD_DCtx* dctx = ZSTD_createDCtx();
873 if (dctx==NULL) return ERROR(memory_allocation);
874 regenSize = ZSTD_decompressDCtx(dctx, dst, maxDstSize, src, srcSize);
875 ZSTD_freeDCtx(dctx);
876 return regenSize;
877#else
Yann Collet31683c02015-12-18 01:26:48 +0100878 ZSTD_DCtx dctx;
879 return ZSTD_decompressDCtx(&dctx, dst, maxDstSize, src, srcSize);
Yann Colleta768a302016-01-21 16:04:35 +0100880#endif
Yann Collet5be2dd22015-11-11 13:43:58 +0100881}
882
883
884/* ******************************
885* Streaming Decompression API
886********************************/
Yann Collet5be2dd22015-11-11 13:43:58 +0100887size_t ZSTD_nextSrcSizeToDecompress(ZSTD_DCtx* dctx)
888{
889 return dctx->expected;
890}
891
892size_t ZSTD_decompressContinue(ZSTD_DCtx* ctx, void* dst, size_t maxDstSize, const void* src, size_t srcSize)
893{
894 /* Sanity check */
895 if (srcSize != ctx->expected) return ERROR(srcSize_wrong);
Yann Colletb0125102016-01-09 02:00:10 +0100896 ZSTD_checkContinuity(ctx, dst);
Yann Collet5be2dd22015-11-11 13:43:58 +0100897
Yann Collet88fcd292015-11-25 14:42:45 +0100898 /* Decompress : frame header; part 1 */
899 switch (ctx->stage)
Yann Collet5be2dd22015-11-11 13:43:58 +0100900 {
Yann Collet88fcd292015-11-25 14:42:45 +0100901 case ZSTDds_getFrameHeaderSize :
Yann Collet5be2dd22015-11-11 13:43:58 +0100902 {
Yann Collet88fcd292015-11-25 14:42:45 +0100903 /* get frame header size */
904 if (srcSize != ZSTD_frameHeaderSize_min) return ERROR(srcSize_wrong); /* impossible */
905 ctx->headerSize = ZSTD_decodeFrameHeader_Part1(ctx, src, ZSTD_frameHeaderSize_min);
Yann Collete4fdad52015-11-25 21:09:17 +0100906 if (ZSTD_isError(ctx->headerSize)) return ctx->headerSize;
Yann Collet88fcd292015-11-25 14:42:45 +0100907 memcpy(ctx->headerBuffer, src, ZSTD_frameHeaderSize_min);
908 if (ctx->headerSize > ZSTD_frameHeaderSize_min)
909 {
910 ctx->expected = ctx->headerSize - ZSTD_frameHeaderSize_min;
911 ctx->stage = ZSTDds_decodeFrameHeader;
912 return 0;
913 }
914 ctx->expected = 0; /* not necessary to copy more */
Yann Collet5be2dd22015-11-11 13:43:58 +0100915 }
Yann Collet88fcd292015-11-25 14:42:45 +0100916 case ZSTDds_decodeFrameHeader:
Yann Collet5be2dd22015-11-11 13:43:58 +0100917 {
Yann Collet88fcd292015-11-25 14:42:45 +0100918 /* get frame header */
919 size_t result;
920 memcpy(ctx->headerBuffer + ZSTD_frameHeaderSize_min, src, ctx->expected);
921 result = ZSTD_decodeFrameHeader_Part2(ctx, ctx->headerBuffer, ctx->headerSize);
922 if (ZSTD_isError(result)) return result;
923 ctx->expected = ZSTD_blockHeaderSize;
924 ctx->stage = ZSTDds_decodeBlockHeader;
925 return 0;
Yann Collet5be2dd22015-11-11 13:43:58 +0100926 }
Yann Collet88fcd292015-11-25 14:42:45 +0100927 case ZSTDds_decodeBlockHeader:
Yann Collet5be2dd22015-11-11 13:43:58 +0100928 {
Yann Collet88fcd292015-11-25 14:42:45 +0100929 /* Decode block header */
930 blockProperties_t bp;
931 size_t blockSize = ZSTD_getcBlockSize(src, ZSTD_blockHeaderSize, &bp);
932 if (ZSTD_isError(blockSize)) return blockSize;
933 if (bp.blockType == bt_end)
934 {
935 ctx->expected = 0;
936 ctx->stage = ZSTDds_getFrameHeaderSize;
937 }
938 else
939 {
940 ctx->expected = blockSize;
941 ctx->bType = bp.blockType;
942 ctx->stage = ZSTDds_decompressBlock;
943 }
Yann Collet88fcd292015-11-25 14:42:45 +0100944 return 0;
945 }
Yann Collet417890c2015-12-04 17:16:37 +0100946 case ZSTDds_decompressBlock:
Yann Collet88fcd292015-11-25 14:42:45 +0100947 {
948 /* Decompress : block content */
949 size_t rSize;
950 switch(ctx->bType)
951 {
952 case bt_compressed:
Yann Colletb0125102016-01-09 02:00:10 +0100953 rSize = ZSTD_decompressBlock_internal(ctx, dst, maxDstSize, src, srcSize);
Yann Collet88fcd292015-11-25 14:42:45 +0100954 break;
955 case bt_raw :
956 rSize = ZSTD_copyRawBlock(dst, maxDstSize, src, srcSize);
957 break;
958 case bt_rle :
959 return ERROR(GENERIC); /* not yet handled */
960 break;
961 case bt_end : /* should never happen (filtered at phase 1) */
962 rSize = 0;
963 break;
964 default:
965 return ERROR(GENERIC);
966 }
967 ctx->stage = ZSTDds_decodeBlockHeader;
968 ctx->expected = ZSTD_blockHeaderSize;
969 ctx->previousDstEnd = (char*)dst + rSize;
970 return rSize;
971 }
972 default:
973 return ERROR(GENERIC); /* impossible */
974 }
Yann Collet5be2dd22015-11-11 13:43:58 +0100975}
976
977
Yann Colletb0125102016-01-09 02:00:10 +0100978void ZSTD_decompress_insertDictionary(ZSTD_DCtx* ctx, const void* dict, size_t dictSize)
Yann Collet417890c2015-12-04 17:16:37 +0100979{
980 ctx->dictEnd = ctx->previousDstEnd;
Yann Colletb0125102016-01-09 02:00:10 +0100981 ctx->vBase = (const char*)dict - ((const char*)(ctx->previousDstEnd) - (const char*)(ctx->base));
982 ctx->base = dict;
983 ctx->previousDstEnd = (const char*)dict + dictSize;
Yann Collet417890c2015-12-04 17:16:37 +0100984}