blob: ce54d200ddeb8300cd90232058059c2bf1ba3436 [file] [log] [blame]
Yann Collet5be2dd22015-11-11 13:43:58 +01001/*
2 zstd - standard compression library
3 Copyright (C) 2014-2015, Yann Collet.
4
5 BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
6
7 Redistribution and use in source and binary forms, with or without
8 modification, are permitted provided that the following conditions are
9 met:
10 * Redistributions of source code must retain the above copyright
11 notice, this list of conditions and the following disclaimer.
12 * Redistributions in binary form must reproduce the above
13 copyright notice, this list of conditions and the following disclaimer
14 in the documentation and/or other materials provided with the
15 distribution.
16 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28 You can contact the author at :
29 - zstd source repository : https://github.com/Cyan4973/zstd
30 - ztsd public forum : https://groups.google.com/forum/#!forum/lz4c
31*/
32
33/* ***************************************************************
34* Tuning parameters
35*****************************************************************/
36/*!
Yann Collet5be2dd22015-11-11 13:43:58 +010037 * HEAPMODE :
Yann Collet3a3b72f2016-01-11 12:56:11 +010038 * Select how default decompression function ZSTD_decompress() will allocate memory,
39 * in memory stack (0), or in memory heap (1, requires malloc())
Yann Collet5be2dd22015-11-11 13:43:58 +010040 */
41#ifndef ZSTD_HEAPMODE
42# define ZSTD_HEAPMODE 1
Yann Collet3a3b72f2016-01-11 12:56:11 +010043#endif
Yann Collet5be2dd22015-11-11 13:43:58 +010044
45/*!
46* LEGACY_SUPPORT :
Yann Colletfba6aed2016-01-18 12:03:27 +010047* ZSTD_decompress() can decode older formats (v0.1+) if set to 1
Yann Collet5be2dd22015-11-11 13:43:58 +010048*/
49#ifndef ZSTD_LEGACY_SUPPORT
Yann Colletfba6aed2016-01-18 12:03:27 +010050# define ZSTD_LEGACY_SUPPORT 0
Yann Collet5be2dd22015-11-11 13:43:58 +010051#endif
52
53
54/* *******************************************************
55* Includes
56*********************************************************/
57#include <stdlib.h> /* calloc */
58#include <string.h> /* memcpy, memmove */
59#include <stdio.h> /* debug : printf */
60#include "mem.h" /* low level memory routines */
61#include "zstd_static.h"
62#include "zstd_internal.h"
63#include "fse_static.h"
Yann Colletafe07092016-01-25 04:10:46 +010064#include "huff0_static.h"
Yann Collet5be2dd22015-11-11 13:43:58 +010065
66#if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT==1)
67# include "zstd_legacy.h"
68#endif
69
Yann Collet5be2dd22015-11-11 13:43:58 +010070/* *******************************************************
71* Compiler specifics
72*********************************************************/
Yann Collet5be2dd22015-11-11 13:43:58 +010073#ifdef _MSC_VER /* Visual Studio */
74# define FORCE_INLINE static __forceinline
75# include <intrin.h> /* For Visual 2005 */
76# pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */
77# pragma warning(disable : 4324) /* disable: C4324: padded structure */
78#else
79# define GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__)
80# ifdef __GNUC__
81# define FORCE_INLINE static inline __attribute__((always_inline))
82# else
83# define FORCE_INLINE static inline
84# endif
85#endif
86
87
Yann Collet14983e72015-11-11 21:38:21 +010088/* *************************************
89* Local types
90***************************************/
91typedef struct
92{
93 blockType_t blockType;
94 U32 origSize;
95} blockProperties_t;
Yann Collet5be2dd22015-11-11 13:43:58 +010096
97
98/* *******************************************************
99* Memory operations
100**********************************************************/
101static void ZSTD_copy4(void* dst, const void* src) { memcpy(dst, src, 4); }
102
103
Yann Collet5be2dd22015-11-11 13:43:58 +0100104/* *************************************
105* Error Management
106***************************************/
Yann Collet14983e72015-11-11 21:38:21 +0100107unsigned ZSTD_versionNumber (void) { return ZSTD_VERSION_NUMBER; }
108
Yann Collet5be2dd22015-11-11 13:43:58 +0100109/*! ZSTD_isError
110* tells if a return value is an error code */
111unsigned ZSTD_isError(size_t code) { return ERR_isError(code); }
112
113/*! ZSTD_getErrorName
114* provides error code string (useful for debugging) */
115const char* ZSTD_getErrorName(size_t code) { return ERR_getErrorName(code); }
116
117
Yann Collet5be2dd22015-11-11 13:43:58 +0100118/* *************************************************************
Yann Collet5b78d2f2015-11-12 15:36:05 +0100119* Context management
Yann Collet5be2dd22015-11-11 13:43:58 +0100120***************************************************************/
Yann Collete4fdad52015-11-25 21:09:17 +0100121typedef enum { ZSTDds_getFrameHeaderSize, ZSTDds_decodeFrameHeader,
Yann Collet88fcd292015-11-25 14:42:45 +0100122 ZSTDds_decodeBlockHeader, ZSTDds_decompressBlock } ZSTD_dStage;
123
Yann Collet5be2dd22015-11-11 13:43:58 +0100124struct ZSTD_DCtx_s
125{
126 U32 LLTable[FSE_DTABLE_SIZE_U32(LLFSELog)];
127 U32 OffTable[FSE_DTABLE_SIZE_U32(OffFSELog)];
128 U32 MLTable[FSE_DTABLE_SIZE_U32(MLFSELog)];
Yann Colletb923f652016-01-26 03:14:20 +0100129 U32 hufTableX4[HUF_DTABLE_SIZE(HufLog)];
Yann Collet417890c2015-12-04 17:16:37 +0100130 const void* previousDstEnd;
131 const void* base;
132 const void* vBase;
133 const void* dictEnd;
Yann Collet5be2dd22015-11-11 13:43:58 +0100134 size_t expected;
Yann Collet88fcd292015-11-25 14:42:45 +0100135 size_t headerSize;
136 ZSTD_parameters params;
Yann Collet5be2dd22015-11-11 13:43:58 +0100137 blockType_t bType;
Yann Collet88fcd292015-11-25 14:42:45 +0100138 ZSTD_dStage stage;
Yann Collet5be2dd22015-11-11 13:43:58 +0100139 const BYTE* litPtr;
140 size_t litBufSize;
141 size_t litSize;
Yann Colletb923f652016-01-26 03:14:20 +0100142 BYTE litBuffer[BLOCKSIZE + WILDCOPY_OVERLENGTH];
Yann Collet88fcd292015-11-25 14:42:45 +0100143 BYTE headerBuffer[ZSTD_frameHeaderSize_max];
Yann Collet417890c2015-12-04 17:16:37 +0100144}; /* typedef'd to ZSTD_DCtx within "zstd_static.h" */
Yann Collet5be2dd22015-11-11 13:43:58 +0100145
Yann Collet5b78d2f2015-11-12 15:36:05 +0100146size_t ZSTD_resetDCtx(ZSTD_DCtx* dctx)
147{
Yann Collet88fcd292015-11-25 14:42:45 +0100148 dctx->expected = ZSTD_frameHeaderSize_min;
149 dctx->stage = ZSTDds_getFrameHeaderSize;
Yann Collet5b78d2f2015-11-12 15:36:05 +0100150 dctx->previousDstEnd = NULL;
151 dctx->base = NULL;
152 dctx->vBase = NULL;
153 dctx->dictEnd = NULL;
Yann Colletb923f652016-01-26 03:14:20 +0100154 dctx->hufTableX4[0] = HufLog;
Yann Collet5b78d2f2015-11-12 15:36:05 +0100155 return 0;
156}
157
158ZSTD_DCtx* ZSTD_createDCtx(void)
159{
160 ZSTD_DCtx* dctx = (ZSTD_DCtx*)malloc(sizeof(ZSTD_DCtx));
161 if (dctx==NULL) return NULL;
162 ZSTD_resetDCtx(dctx);
163 return dctx;
164}
165
166size_t ZSTD_freeDCtx(ZSTD_DCtx* dctx)
167{
168 free(dctx);
169 return 0;
170}
171
172
173/* *************************************************************
174* Decompression section
175***************************************************************/
Yann Collet59d1f792016-01-23 19:28:41 +0100176
177/* Frame format description
178 Frame Header - [ Block Header - Block ] - Frame End
179 1) Frame Header
180 - 4 bytes - Magic Number : ZSTD_MAGICNUMBER (defined within zstd_internal.h)
181 - 1 byte - Window Descriptor
182 2) Block Header
183 - 3 bytes, starting with a 2-bits descriptor
184 Uncompressed, Compressed, Frame End, unused
185 3) Block
186 See Block Format Description
187 4) Frame End
188 - 3 bytes, compatible with Block Header
189*/
190
191/* Block format description
192 Literal Section - Sequences Section
193 1) Literal Section
194 1.1) Header : up to 5 bytes
195 flags:
196 00 compressed by Huff0
197 01 is Raw (uncompressed)
198 10 is Rle
199 11 unused
200 Note : using 11 for Huff0 with precomputed table ?
201 Note : delta map ? => compressed ?
202 Note 2 : 19 bits for sizes, seems a bit larger than necessary
203 Note 3 : RLE blocks ?
204
205 1.2.1) Huff0 block, using sizes from header
206 See Huff0 format
207
208 1.2.2) Huff0 block, using precomputed DTable
209 _usingDTable variants
210
211 1.2.3) uncompressed blocks
212 as the name says (both 2 or 3 bytes variants)
213
214 2) Sequences section
215 TO DO
216*/
217
218
Yann Collet88fcd292015-11-25 14:42:45 +0100219/** ZSTD_decodeFrameHeader_Part1
220* decode the 1st part of the Frame Header, which tells Frame Header size.
221* srcSize must be == ZSTD_frameHeaderSize_min
222* @return : the full size of the Frame Header */
223static size_t ZSTD_decodeFrameHeader_Part1(ZSTD_DCtx* zc, const void* src, size_t srcSize)
224{
225 U32 magicNumber;
226 if (srcSize != ZSTD_frameHeaderSize_min) return ERROR(srcSize_wrong);
227 magicNumber = MEM_readLE32(src);
228 if (magicNumber != ZSTD_MAGICNUMBER) return ERROR(prefix_unknown);
229 zc->headerSize = ZSTD_frameHeaderSize_min;
230 return zc->headerSize;
231}
232
Yann Collet88fcd292015-11-25 14:42:45 +0100233
234size_t ZSTD_getFrameParams(ZSTD_parameters* params, const void* src, size_t srcSize)
235{
236 U32 magicNumber;
237 if (srcSize < ZSTD_frameHeaderSize_min) return ZSTD_frameHeaderSize_max;
238 magicNumber = MEM_readLE32(src);
239 if (magicNumber != ZSTD_MAGICNUMBER) return ERROR(prefix_unknown);
240 memset(params, 0, sizeof(*params));
Yann Collet26415d32015-11-26 12:43:28 +0100241 params->windowLog = (((const BYTE*)src)[4] & 15) + ZSTD_WINDOWLOG_ABSOLUTEMIN;
Yann Colletbf7aa3c2015-11-28 18:19:44 +0100242 if ((((const BYTE*)src)[4] >> 4) != 0) return ERROR(frameParameter_unsupported); /* reserved bits */
Yann Collet88fcd292015-11-25 14:42:45 +0100243 return 0;
244}
245
Yann Collet26415d32015-11-26 12:43:28 +0100246/** ZSTD_decodeFrameHeader_Part2
247* decode the full Frame Header
248* srcSize must be the size provided by ZSTD_decodeFrameHeader_Part1
249* @return : 0, or an error code, which can be tested using ZSTD_isError() */
250static size_t ZSTD_decodeFrameHeader_Part2(ZSTD_DCtx* zc, const void* src, size_t srcSize)
251{
Yann Collet00fd7a22015-11-28 16:03:22 +0100252 size_t result;
Yann Collet26415d32015-11-26 12:43:28 +0100253 if (srcSize != zc->headerSize) return ERROR(srcSize_wrong);
Yann Collet00fd7a22015-11-28 16:03:22 +0100254 result = ZSTD_getFrameParams(&(zc->params), src, srcSize);
255 if ((MEM_32bits()) && (zc->params.windowLog > 25)) return ERROR(frameParameter_unsupportedBy32bitsImplementation);
256 return result;
Yann Collet26415d32015-11-26 12:43:28 +0100257}
258
Yann Collet5be2dd22015-11-11 13:43:58 +0100259
260size_t ZSTD_getcBlockSize(const void* src, size_t srcSize, blockProperties_t* bpPtr)
261{
262 const BYTE* const in = (const BYTE* const)src;
263 BYTE headerFlags;
264 U32 cSize;
265
266 if (srcSize < 3) return ERROR(srcSize_wrong);
267
268 headerFlags = *in;
269 cSize = in[2] + (in[1]<<8) + ((in[0] & 7)<<16);
270
271 bpPtr->blockType = (blockType_t)(headerFlags >> 6);
272 bpPtr->origSize = (bpPtr->blockType == bt_rle) ? cSize : 0;
273
274 if (bpPtr->blockType == bt_end) return 0;
275 if (bpPtr->blockType == bt_rle) return 1;
276 return cSize;
277}
278
Yann Collet59d1f792016-01-23 19:28:41 +0100279
Yann Collet0f366c62015-11-12 16:19:30 +0100280static size_t ZSTD_copyRawBlock(void* dst, size_t maxDstSize, const void* src, size_t srcSize)
Yann Collet5be2dd22015-11-11 13:43:58 +0100281{
282 if (srcSize > maxDstSize) return ERROR(dstSize_tooSmall);
283 memcpy(dst, src, srcSize);
284 return srcSize;
285}
286
287
Yann Collet5be2dd22015-11-11 13:43:58 +0100288/** ZSTD_decodeLiteralsBlock
Yann Collet14983e72015-11-11 21:38:21 +0100289 @return : nb of bytes read from src (< srcSize ) */
Yann Collet5b78d2f2015-11-12 15:36:05 +0100290size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx,
Yann Collet5be2dd22015-11-11 13:43:58 +0100291 const void* src, size_t srcSize) /* note : srcSize < BLOCKSIZE */
292{
Yann Collet5be2dd22015-11-11 13:43:58 +0100293 const BYTE* const istart = (const BYTE*) src;
294
295 /* any compressed block with literals segment must be at least this size */
296 if (srcSize < MIN_CBLOCK_SIZE) return ERROR(corruption_detected);
297
Yann Collet59d1f792016-01-23 19:28:41 +0100298 switch(istart[0]>> 6)
Yann Collet5be2dd22015-11-11 13:43:58 +0100299 {
Yann Collet59d1f792016-01-23 19:28:41 +0100300 case IS_HUF:
Yann Collet5be2dd22015-11-11 13:43:58 +0100301 {
Yann Colletafe07092016-01-25 04:10:46 +0100302 size_t litSize, litCSize, singleStream=0;
Yann Collet59d1f792016-01-23 19:28:41 +0100303 U32 lhSize = ((istart[0]) >> 4) & 3;
304 switch(lhSize)
305 {
306 case 0: case 1: default: /* note : default is impossible, since lhSize into [0..3] */
307 /* 2 - 2 - 10 - 10 */
308 lhSize=3;
Yann Colletafe07092016-01-25 04:10:46 +0100309 singleStream = istart[0] & 16;
Yann Collet59d1f792016-01-23 19:28:41 +0100310 litSize = ((istart[0] & 15) << 6) + (istart[1] >> 2);
311 litCSize = ((istart[1] & 3) << 8) + istart[2];
312 break;
313 case 2:
314 /* 2 - 2 - 14 - 14 */
315 lhSize=4;
316 litSize = ((istart[0] & 15) << 10) + (istart[1] << 2) + (istart[2] >> 6);
317 litCSize = ((istart[2] & 63) << 8) + istart[3];
318 break;
319 case 3:
320 /* 2 - 2 - 18 - 18 */
321 lhSize=5;
322 litSize = ((istart[0] & 15) << 14) + (istart[1] << 6) + (istart[2] >> 2);
323 litCSize = ((istart[2] & 3) << 16) + (istart[3] << 8) + istart[4];
324 break;
325 }
Yann Collet37422192016-01-25 16:54:05 +0100326 if (litSize > BLOCKSIZE) return ERROR(corruption_detected);;
Yann Collet59d1f792016-01-23 19:28:41 +0100327
Yann Colletafe07092016-01-25 04:10:46 +0100328 if (HUF_isError(singleStream ?
329 HUF_decompress1X2(dctx->litBuffer, litSize, istart+lhSize, litCSize) :
330 HUF_decompress (dctx->litBuffer, litSize, istart+lhSize, litCSize) ))
Yann Collet59d1f792016-01-23 19:28:41 +0100331 return ERROR(corruption_detected);
332
Yann Collet5be2dd22015-11-11 13:43:58 +0100333 dctx->litPtr = dctx->litBuffer;
334 dctx->litBufSize = BLOCKSIZE+8;
335 dctx->litSize = litSize;
Yann Collet59d1f792016-01-23 19:28:41 +0100336 return litCSize + lhSize;
Yann Collet5be2dd22015-11-11 13:43:58 +0100337 }
Yann Colletb923f652016-01-26 03:14:20 +0100338 case IS_PCH:
339 {
340 size_t errorCode;
341 size_t litSize, litCSize;
342 U32 lhSize = ((istart[0]) >> 4) & 3;
343 if (lhSize != 1) /* only case supported for now : small litSize, single stream */
344 return ERROR(corruption_detected);
345
346 /* 2 - 2 - 10 - 10 */
347 lhSize=3;
348 litSize = ((istart[0] & 15) << 6) + (istart[1] >> 2);
349 litCSize = ((istart[1] & 3) << 8) + istart[2];
350
351 errorCode = HUF_decompress1X4_usingDTable(dctx->litBuffer, litSize, istart+lhSize, litCSize, dctx->hufTableX4);
352 if (HUF_isError(errorCode)) return ERROR(corruption_detected);
353
354 dctx->litPtr = dctx->litBuffer;
355 dctx->litBufSize = BLOCKSIZE+WILDCOPY_OVERLENGTH;
356 dctx->litSize = litSize;
357 return litCSize + lhSize;
358 }
Yann Collet5be2dd22015-11-11 13:43:58 +0100359 case IS_RAW:
360 {
Yann Collet59d1f792016-01-23 19:28:41 +0100361 size_t litSize;
362 U32 lhSize = ((istart[0]) >> 4) & 3;
363 switch(lhSize)
Yann Collet5be2dd22015-11-11 13:43:58 +0100364 {
Yann Collet59d1f792016-01-23 19:28:41 +0100365 case 0: case 1: default: /* note : default is impossible, since lhSize into [0..3] */
366 lhSize=1;
367 litSize = istart[0] & 31;
368 break;
369 case 2:
370 litSize = ((istart[0] & 15) << 8) + istart[1];
371 break;
372 case 3:
373 litSize = ((istart[0] & 15) << 16) + (istart[1] << 8) + istart[2];
374 break;
375 }
376
Yann Colletbc4c8aa2016-01-25 17:26:01 +0100377 if (litSize+WILDCOPY_OVERLENGTH > srcSize) /* risk reading beyond src buffer with wildcopy */
Yann Collet59d1f792016-01-23 19:28:41 +0100378 {
Yann Collet37422192016-01-25 16:54:05 +0100379 if (litSize > srcSize-lhSize) return ERROR(corruption_detected);
Yann Collet59d1f792016-01-23 19:28:41 +0100380 memcpy(dctx->litBuffer, istart+lhSize, litSize);
Yann Collet5be2dd22015-11-11 13:43:58 +0100381 dctx->litPtr = dctx->litBuffer;
382 dctx->litBufSize = BLOCKSIZE+8;
383 dctx->litSize = litSize;
Yann Colletbc4c8aa2016-01-25 17:26:01 +0100384 return lhSize+litSize;
Yann Collet5be2dd22015-11-11 13:43:58 +0100385 }
386 /* direct reference into compressed stream */
Yann Collet59d1f792016-01-23 19:28:41 +0100387 dctx->litPtr = istart+lhSize;
388 dctx->litBufSize = srcSize-lhSize;
Yann Collet5be2dd22015-11-11 13:43:58 +0100389 dctx->litSize = litSize;
Yann Collet59d1f792016-01-23 19:28:41 +0100390 return lhSize+litSize;
391 }
Yann Collet5be2dd22015-11-11 13:43:58 +0100392 case IS_RLE:
393 {
Yann Collet59d1f792016-01-23 19:28:41 +0100394 size_t litSize;
395 U32 lhSize = ((istart[0]) >> 4) & 3;
396 switch(lhSize)
397 {
398 case 0: case 1: default: /* note : default is impossible, since lhSize into [0..3] */
399 lhSize = 1;
400 litSize = istart[0] & 31;
401 break;
402 case 2:
403 litSize = ((istart[0] & 15) << 8) + istart[1];
404 break;
405 case 3:
406 litSize = ((istart[0] & 15) << 16) + (istart[1] << 8) + istart[2];
407 break;
408 }
Yann Collet5be2dd22015-11-11 13:43:58 +0100409 if (litSize > BLOCKSIZE) return ERROR(corruption_detected);
Yann Collet59d1f792016-01-23 19:28:41 +0100410 memset(dctx->litBuffer, istart[lhSize], litSize);
Yann Collet5be2dd22015-11-11 13:43:58 +0100411 dctx->litPtr = dctx->litBuffer;
Yann Colletb923f652016-01-26 03:14:20 +0100412 dctx->litBufSize = BLOCKSIZE+WILDCOPY_OVERLENGTH;
Yann Collet5be2dd22015-11-11 13:43:58 +0100413 dctx->litSize = litSize;
Yann Collet59d1f792016-01-23 19:28:41 +0100414 return lhSize+1;
Yann Collet5be2dd22015-11-11 13:43:58 +0100415 }
Yann Colletb923f652016-01-26 03:14:20 +0100416 default:
417 return ERROR(corruption_detected); /* impossible */
Yann Collet5be2dd22015-11-11 13:43:58 +0100418 }
419}
420
421
422size_t ZSTD_decodeSeqHeaders(int* nbSeq, const BYTE** dumpsPtr, size_t* dumpsLengthPtr,
423 FSE_DTable* DTableLL, FSE_DTable* DTableML, FSE_DTable* DTableOffb,
424 const void* src, size_t srcSize)
425{
426 const BYTE* const istart = (const BYTE* const)src;
427 const BYTE* ip = istart;
428 const BYTE* const iend = istart + srcSize;
429 U32 LLtype, Offtype, MLtype;
430 U32 LLlog, Offlog, MLlog;
431 size_t dumpsLength;
432
433 /* check */
434 if (srcSize < 5) return ERROR(srcSize_wrong);
435
436 /* SeqHead */
437 *nbSeq = MEM_readLE16(ip); ip+=2;
438 LLtype = *ip >> 6;
439 Offtype = (*ip >> 4) & 3;
440 MLtype = (*ip >> 2) & 3;
441 if (*ip & 2)
442 {
443 dumpsLength = ip[2];
444 dumpsLength += ip[1] << 8;
445 ip += 3;
446 }
447 else
448 {
449 dumpsLength = ip[1];
450 dumpsLength += (ip[0] & 1) << 8;
451 ip += 2;
452 }
453 *dumpsPtr = ip;
454 ip += dumpsLength;
455 *dumpsLengthPtr = dumpsLength;
456
457 /* check */
458 if (ip > iend-3) return ERROR(srcSize_wrong); /* min : all 3 are "raw", hence no header, but at least xxLog bits per type */
459
460 /* sequences */
461 {
Yann Collet82368cf2015-11-16 19:10:56 +0100462 S16 norm[MaxML+1]; /* assumption : MaxML >= MaxLL >= MaxOff */
Yann Collet5be2dd22015-11-11 13:43:58 +0100463 size_t headerSize;
464
465 /* Build DTables */
466 switch(LLtype)
467 {
468 U32 max;
469 case bt_rle :
470 LLlog = 0;
471 FSE_buildDTable_rle(DTableLL, *ip++); break;
472 case bt_raw :
473 LLlog = LLbits;
474 FSE_buildDTable_raw(DTableLL, LLbits); break;
475 default :
476 max = MaxLL;
477 headerSize = FSE_readNCount(norm, &max, &LLlog, ip, iend-ip);
478 if (FSE_isError(headerSize)) return ERROR(GENERIC);
479 if (LLlog > LLFSELog) return ERROR(corruption_detected);
480 ip += headerSize;
481 FSE_buildDTable(DTableLL, norm, max, LLlog);
482 }
483
484 switch(Offtype)
485 {
486 U32 max;
487 case bt_rle :
488 Offlog = 0;
489 if (ip > iend-2) return ERROR(srcSize_wrong); /* min : "raw", hence no header, but at least xxLog bits */
490 FSE_buildDTable_rle(DTableOffb, *ip++ & MaxOff); /* if *ip > MaxOff, data is corrupted */
491 break;
492 case bt_raw :
493 Offlog = Offbits;
494 FSE_buildDTable_raw(DTableOffb, Offbits); break;
495 default :
496 max = MaxOff;
497 headerSize = FSE_readNCount(norm, &max, &Offlog, ip, iend-ip);
498 if (FSE_isError(headerSize)) return ERROR(GENERIC);
499 if (Offlog > OffFSELog) return ERROR(corruption_detected);
500 ip += headerSize;
501 FSE_buildDTable(DTableOffb, norm, max, Offlog);
502 }
503
504 switch(MLtype)
505 {
506 U32 max;
507 case bt_rle :
508 MLlog = 0;
509 if (ip > iend-2) return ERROR(srcSize_wrong); /* min : "raw", hence no header, but at least xxLog bits */
510 FSE_buildDTable_rle(DTableML, *ip++); break;
511 case bt_raw :
512 MLlog = MLbits;
513 FSE_buildDTable_raw(DTableML, MLbits); break;
514 default :
515 max = MaxML;
516 headerSize = FSE_readNCount(norm, &max, &MLlog, ip, iend-ip);
517 if (FSE_isError(headerSize)) return ERROR(GENERIC);
518 if (MLlog > MLFSELog) return ERROR(corruption_detected);
519 ip += headerSize;
520 FSE_buildDTable(DTableML, norm, max, MLlog);
521 }
522 }
523
524 return ip-istart;
525}
526
527
528typedef struct {
529 size_t litLength;
530 size_t offset;
531 size_t matchLength;
532} seq_t;
533
534typedef struct {
535 BIT_DStream_t DStream;
536 FSE_DState_t stateLL;
537 FSE_DState_t stateOffb;
538 FSE_DState_t stateML;
539 size_t prevOffset;
540 const BYTE* dumps;
541 const BYTE* dumpsEnd;
542} seqState_t;
543
544
545static void ZSTD_decodeSequence(seq_t* seq, seqState_t* seqState)
546{
547 size_t litLength;
548 size_t prevOffset;
549 size_t offset;
550 size_t matchLength;
551 const BYTE* dumps = seqState->dumps;
552 const BYTE* const de = seqState->dumpsEnd;
553
554 /* Literal length */
555 litLength = FSE_decodeSymbol(&(seqState->stateLL), &(seqState->DStream));
Yann Collete4fdad52015-11-25 21:09:17 +0100556 prevOffset = litLength ? seq->offset : seqState->prevOffset;
Yann Collet5be2dd22015-11-11 13:43:58 +0100557 if (litLength == MaxLL)
558 {
559 U32 add = *dumps++;
560 if (add < 255) litLength += add;
561 else
562 {
563 litLength = MEM_readLE32(dumps) & 0xFFFFFF; /* no pb : dumps is always followed by seq tables > 1 byte */
564 dumps += 3;
565 }
566 if (dumps >= de) dumps = de-1; /* late correction, to avoid read overflow (data is now corrupted anyway) */
567 }
568
569 /* Offset */
570 {
571 static const U32 offsetPrefix[MaxOff+1] = {
572 1 /*fake*/, 1, 2, 4, 8, 16, 32, 64, 128, 256,
573 512, 1024, 2048, 4096, 8192, 16384, 32768, 65536, 131072, 262144,
574 524288, 1048576, 2097152, 4194304, 8388608, 16777216, 33554432, /*fake*/ 1, 1, 1, 1, 1 };
575 U32 offsetCode, nbBits;
576 offsetCode = FSE_decodeSymbol(&(seqState->stateOffb), &(seqState->DStream)); /* <= maxOff, by table construction */
577 if (MEM_32bits()) BIT_reloadDStream(&(seqState->DStream));
578 nbBits = offsetCode - 1;
579 if (offsetCode==0) nbBits = 0; /* cmove */
580 offset = offsetPrefix[offsetCode] + BIT_readBits(&(seqState->DStream), nbBits);
581 if (MEM_32bits()) BIT_reloadDStream(&(seqState->DStream));
582 if (offsetCode==0) offset = prevOffset; /* cmove */
Yann Collet55aa7f92015-11-20 12:04:52 +0100583 if (offsetCode | !litLength) seqState->prevOffset = seq->offset; /* cmove */
Yann Collet5be2dd22015-11-11 13:43:58 +0100584 }
585
586 /* MatchLength */
587 matchLength = FSE_decodeSymbol(&(seqState->stateML), &(seqState->DStream));
588 if (matchLength == MaxML)
589 {
590 U32 add = *dumps++;
591 if (add < 255) matchLength += add;
592 else
593 {
594 matchLength = MEM_readLE32(dumps) & 0xFFFFFF; /* no pb : dumps is always followed by seq tables > 1 byte */
595 dumps += 3;
596 }
597 if (dumps >= de) dumps = de-1; /* late correction, to avoid read overflow (data is now corrupted anyway) */
598 }
599 matchLength += MINMATCH;
600
601 /* save result */
602 seq->litLength = litLength;
603 seq->offset = offset;
604 seq->matchLength = matchLength;
605 seqState->dumps = dumps;
606}
607
608
Yann Collet5b78d2f2015-11-12 15:36:05 +0100609FORCE_INLINE size_t ZSTD_execSequence(BYTE* op,
Yann Colletb3a2af92015-11-19 17:13:19 +0100610 BYTE* const oend, seq_t sequence,
Yann Collet5be2dd22015-11-11 13:43:58 +0100611 const BYTE** litPtr, const BYTE* const litLimit_8,
Yann Collet417890c2015-12-04 17:16:37 +0100612 const BYTE* const base, const BYTE* const vBase, const BYTE* const dictEnd)
Yann Collet5be2dd22015-11-11 13:43:58 +0100613{
Yann Colletb3a2af92015-11-19 17:13:19 +0100614 static const int dec32table[] = { 0, 1, 2, 1, 4, 4, 4, 4 }; /* added */
615 static const int dec64table[] = { 8, 8, 8, 7, 8, 9,10,11 }; /* substracted */
Yann Collet5be2dd22015-11-11 13:43:58 +0100616 BYTE* const oLitEnd = op + sequence.litLength;
Yann Colletb3a2af92015-11-19 17:13:19 +0100617 const size_t sequenceLength = sequence.litLength + sequence.matchLength;
618 BYTE* const oMatchEnd = op + sequenceLength; /* risk : address space overflow (32-bits) */
Yann Collet5be2dd22015-11-11 13:43:58 +0100619 BYTE* const oend_8 = oend-8;
620 const BYTE* const litEnd = *litPtr + sequence.litLength;
Yann Colletb3a2af92015-11-19 17:13:19 +0100621 const BYTE* match = oLitEnd - sequence.offset;
Yann Collet5be2dd22015-11-11 13:43:58 +0100622
623 /* check */
624 if (oLitEnd > oend_8) return ERROR(dstSize_tooSmall); /* last match must start at a minimum distance of 8 from oend */
625 if (oMatchEnd > oend) return ERROR(dstSize_tooSmall); /* overwrite beyond dst buffer */
626 if (litEnd > litLimit_8) return ERROR(corruption_detected); /* risk read beyond lit buffer */
627
628 /* copy Literals */
629 ZSTD_wildcopy(op, *litPtr, sequence.litLength); /* note : oLitEnd <= oend-8 : no risk of overwrite beyond oend */
630 op = oLitEnd;
631 *litPtr = litEnd; /* update for next sequence */
632
633 /* copy Match */
Yann Collet9f5ab1a2015-12-11 00:27:41 +0100634 if (sequence.offset > (size_t)(oLitEnd - base))
Yann Collet44287a32015-11-30 23:13:56 +0100635 {
636 /* offset beyond prefix */
Yann Collet9f5ab1a2015-12-11 00:27:41 +0100637 if (sequence.offset > (size_t)(oLitEnd - vBase))
638 return ERROR(corruption_detected);
Yann Collet44287a32015-11-30 23:13:56 +0100639 match = dictEnd - (base-match);
640 if (match + sequence.matchLength <= dictEnd)
641 {
Yann Collet4bfe4152015-12-06 13:18:37 +0100642 memmove(oLitEnd, match, sequence.matchLength);
Yann Collet44287a32015-11-30 23:13:56 +0100643 return sequenceLength;
644 }
645 /* span extDict & currentPrefixSegment */
646 {
647 size_t length1 = dictEnd - match;
Yann Collet4bfe4152015-12-06 13:18:37 +0100648 memmove(oLitEnd, match, length1);
Yann Collet44287a32015-11-30 23:13:56 +0100649 op = oLitEnd + length1;
650 sequence.matchLength -= length1;
651 match = base;
652 }
653 }
Yann Collet0f366c62015-11-12 16:19:30 +0100654
Yann Collet44287a32015-11-30 23:13:56 +0100655 /* match within prefix */
656 if (sequence.offset < 8)
657 {
658 /* close range match, overlap */
659 const int sub2 = dec64table[sequence.offset];
660 op[0] = match[0];
661 op[1] = match[1];
662 op[2] = match[2];
663 op[3] = match[3];
664 match += dec32table[sequence.offset];
665 ZSTD_copy4(op+4, match);
666 match -= sub2;
667 }
668 else
669 {
670 ZSTD_copy8(op, match);
671 }
672 op += 8; match += 8;
Yann Collet5be2dd22015-11-11 13:43:58 +0100673
Yann Collet44287a32015-11-30 23:13:56 +0100674 if (oMatchEnd > oend-12)
675 {
676 if (op < oend_8)
677 {
678 ZSTD_wildcopy(op, match, oend_8 - op);
679 match += oend_8 - op;
680 op = oend_8;
681 }
682 while (op < oMatchEnd) *op++ = *match++;
683 }
684 else
685 {
686 ZSTD_wildcopy(op, match, sequence.matchLength-8); /* works even if matchLength < 8 */
687 }
688 return sequenceLength;
Yann Collet5be2dd22015-11-11 13:43:58 +0100689}
690
Yann Colletb3a2af92015-11-19 17:13:19 +0100691
Yann Collet5be2dd22015-11-11 13:43:58 +0100692static size_t ZSTD_decompressSequences(
Yann Collet5b78d2f2015-11-12 15:36:05 +0100693 ZSTD_DCtx* dctx,
Yann Collet5be2dd22015-11-11 13:43:58 +0100694 void* dst, size_t maxDstSize,
695 const void* seqStart, size_t seqSize)
696{
Yann Collet5be2dd22015-11-11 13:43:58 +0100697 const BYTE* ip = (const BYTE*)seqStart;
698 const BYTE* const iend = ip + seqSize;
699 BYTE* const ostart = (BYTE* const)dst;
700 BYTE* op = ostart;
701 BYTE* const oend = ostart + maxDstSize;
702 size_t errorCode, dumpsLength;
703 const BYTE* litPtr = dctx->litPtr;
704 const BYTE* const litLimit_8 = litPtr + dctx->litBufSize - 8;
705 const BYTE* const litEnd = litPtr + dctx->litSize;
706 int nbSeq;
707 const BYTE* dumps;
708 U32* DTableLL = dctx->LLTable;
709 U32* DTableML = dctx->MLTable;
710 U32* DTableOffb = dctx->OffTable;
Yann Collet417890c2015-12-04 17:16:37 +0100711 const BYTE* const base = (const BYTE*) (dctx->base);
712 const BYTE* const vBase = (const BYTE*) (dctx->vBase);
713 const BYTE* const dictEnd = (const BYTE*) (dctx->dictEnd);
Yann Collet5be2dd22015-11-11 13:43:58 +0100714
715 /* Build Decoding Tables */
716 errorCode = ZSTD_decodeSeqHeaders(&nbSeq, &dumps, &dumpsLength,
717 DTableLL, DTableML, DTableOffb,
718 ip, iend-ip);
719 if (ZSTD_isError(errorCode)) return errorCode;
720 ip += errorCode;
721
722 /* Regen sequences */
723 {
724 seq_t sequence;
725 seqState_t seqState;
726
727 memset(&sequence, 0, sizeof(sequence));
728 sequence.offset = 4;
729 seqState.dumps = dumps;
730 seqState.dumpsEnd = dumps + dumpsLength;
731 seqState.prevOffset = 4;
732 errorCode = BIT_initDStream(&(seqState.DStream), ip, iend-ip);
733 if (ERR_isError(errorCode)) return ERROR(corruption_detected);
734 FSE_initDState(&(seqState.stateLL), &(seqState.DStream), DTableLL);
735 FSE_initDState(&(seqState.stateOffb), &(seqState.DStream), DTableOffb);
736 FSE_initDState(&(seqState.stateML), &(seqState.DStream), DTableML);
737
Yann Collet44287a32015-11-30 23:13:56 +0100738 for ( ; (BIT_reloadDStream(&(seqState.DStream)) <= BIT_DStream_completed) && nbSeq ; )
Yann Colletb3a2af92015-11-19 17:13:19 +0100739 {
740 size_t oneSeqSize;
741 nbSeq--;
742 ZSTD_decodeSequence(&sequence, &seqState);
743 oneSeqSize = ZSTD_execSequence(op, oend, sequence, &litPtr, litLimit_8, base, vBase, dictEnd);
Yann Collet5be2dd22015-11-11 13:43:58 +0100744 if (ZSTD_isError(oneSeqSize)) return oneSeqSize;
745 op += oneSeqSize;
746 }
747
748 /* check if reached exact end */
Yann Collet44287a32015-11-30 23:13:56 +0100749 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 +0100750
751 /* last literal segment */
752 {
753 size_t lastLLSize = litEnd - litPtr;
754 if (litPtr > litEnd) return ERROR(corruption_detected);
755 if (op+lastLLSize > oend) return ERROR(dstSize_tooSmall);
756 if (op != litPtr) memcpy(op, litPtr, lastLLSize);
757 op += lastLLSize;
758 }
759 }
760
761 return op-ostart;
762}
763
764
Yann Colletb0125102016-01-09 02:00:10 +0100765static void ZSTD_checkContinuity(ZSTD_DCtx* dctx, const void* dst)
766{
767 if (dst != dctx->previousDstEnd) /* not contiguous */
768 {
769 dctx->dictEnd = dctx->previousDstEnd;
770 dctx->vBase = (const char*)dst - ((const char*)(dctx->previousDstEnd) - (const char*)(dctx->base));
771 dctx->base = dst;
772 dctx->previousDstEnd = dst;
773 }
774}
775
776
777static size_t ZSTD_decompressBlock_internal(ZSTD_DCtx* dctx,
Yann Collet5be2dd22015-11-11 13:43:58 +0100778 void* dst, size_t maxDstSize,
779 const void* src, size_t srcSize)
780{
781 /* blockType == blockCompressed */
782 const BYTE* ip = (const BYTE*)src;
783
784 /* Decode literals sub-block */
Yann Collet5b78d2f2015-11-12 15:36:05 +0100785 size_t litCSize = ZSTD_decodeLiteralsBlock(dctx, src, srcSize);
Yann Collet5be2dd22015-11-11 13:43:58 +0100786 if (ZSTD_isError(litCSize)) return litCSize;
787 ip += litCSize;
788 srcSize -= litCSize;
789
Yann Collet5b78d2f2015-11-12 15:36:05 +0100790 return ZSTD_decompressSequences(dctx, dst, maxDstSize, ip, srcSize);
Yann Collet5be2dd22015-11-11 13:43:58 +0100791}
792
793
Yann Colletb0125102016-01-09 02:00:10 +0100794size_t ZSTD_decompressBlock(ZSTD_DCtx* dctx,
795 void* dst, size_t maxDstSize,
796 const void* src, size_t srcSize)
797{
798 ZSTD_checkContinuity(dctx, dst);
799 return ZSTD_decompressBlock_internal(dctx, dst, maxDstSize, src, srcSize);
800}
801
802
Yann Collet37422192016-01-25 16:54:05 +0100803size_t ZSTD_decompress_usingDict(ZSTD_DCtx* dctx,
Yann Collet31683c02015-12-18 01:26:48 +0100804 void* dst, size_t maxDstSize,
805 const void* src, size_t srcSize,
806 const void* dict, size_t dictSize)
Yann Collet5be2dd22015-11-11 13:43:58 +0100807{
808 const BYTE* ip = (const BYTE*)src;
809 const BYTE* iend = ip + srcSize;
810 BYTE* const ostart = (BYTE* const)dst;
811 BYTE* op = ostart;
812 BYTE* const oend = ostart + maxDstSize;
813 size_t remainingSize = srcSize;
Yann Collet5be2dd22015-11-11 13:43:58 +0100814 blockProperties_t blockProperties;
815
Yann Colletb2549842015-11-18 11:29:32 +0100816 /* init */
Yann Collet37422192016-01-25 16:54:05 +0100817 ZSTD_resetDCtx(dctx);
Yann Collet31683c02015-12-18 01:26:48 +0100818 if (dict)
819 {
Yann Colletb923f652016-01-26 03:14:20 +0100820 size_t errorCode = ZSTD_decompress_insertDictionary(dctx, dict, dictSize);
821 if (ZSTD_isError(errorCode)) return ERROR(dictionary_corrupted);
Yann Collet37422192016-01-25 16:54:05 +0100822 dctx->dictEnd = dctx->previousDstEnd;
823 dctx->vBase = (const char*)dst - ((const char*)(dctx->previousDstEnd) - (const char*)(dctx->base));
824 dctx->base = dst;
Yann Collet31683c02015-12-18 01:26:48 +0100825 }
826 else
827 {
Yann Collet37422192016-01-25 16:54:05 +0100828 dctx->vBase = dctx->base = dctx->dictEnd = dst;
Yann Collet31683c02015-12-18 01:26:48 +0100829 }
Yann Collet5b78d2f2015-11-12 15:36:05 +0100830
Yann Collet5be2dd22015-11-11 13:43:58 +0100831 /* Frame Header */
Yann Collet88fcd292015-11-25 14:42:45 +0100832 {
833 size_t frameHeaderSize;
834 if (srcSize < ZSTD_frameHeaderSize_min+ZSTD_blockHeaderSize) return ERROR(srcSize_wrong);
Yann Collet5be2dd22015-11-11 13:43:58 +0100835#if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT==1)
Yann Collet88fcd292015-11-25 14:42:45 +0100836 {
837 const U32 magicNumber = MEM_readLE32(src);
838 if (ZSTD_isLegacy(magicNumber))
839 return ZSTD_decompressLegacy(dst, maxDstSize, src, srcSize, magicNumber);
840 }
Yann Collet5be2dd22015-11-11 13:43:58 +0100841#endif
Yann Collet37422192016-01-25 16:54:05 +0100842 frameHeaderSize = ZSTD_decodeFrameHeader_Part1(dctx, src, ZSTD_frameHeaderSize_min);
Yann Collet88fcd292015-11-25 14:42:45 +0100843 if (ZSTD_isError(frameHeaderSize)) return frameHeaderSize;
844 if (srcSize < frameHeaderSize+ZSTD_blockHeaderSize) return ERROR(srcSize_wrong);
845 ip += frameHeaderSize; remainingSize -= frameHeaderSize;
Yann Collet37422192016-01-25 16:54:05 +0100846 frameHeaderSize = ZSTD_decodeFrameHeader_Part2(dctx, src, frameHeaderSize);
Yann Collet88fcd292015-11-25 14:42:45 +0100847 if (ZSTD_isError(frameHeaderSize)) return frameHeaderSize;
848 }
Yann Collet5be2dd22015-11-11 13:43:58 +0100849
850 /* Loop on each block */
851 while (1)
852 {
853 size_t decodedSize=0;
854 size_t cBlockSize = ZSTD_getcBlockSize(ip, iend-ip, &blockProperties);
855 if (ZSTD_isError(cBlockSize)) return cBlockSize;
856
857 ip += ZSTD_blockHeaderSize;
858 remainingSize -= ZSTD_blockHeaderSize;
859 if (cBlockSize > remainingSize) return ERROR(srcSize_wrong);
860
861 switch(blockProperties.blockType)
862 {
863 case bt_compressed:
Yann Collet37422192016-01-25 16:54:05 +0100864 decodedSize = ZSTD_decompressBlock_internal(dctx, op, oend-op, ip, cBlockSize);
Yann Collet5be2dd22015-11-11 13:43:58 +0100865 break;
866 case bt_raw :
Yann Collet0f366c62015-11-12 16:19:30 +0100867 decodedSize = ZSTD_copyRawBlock(op, oend-op, ip, cBlockSize);
Yann Collet5be2dd22015-11-11 13:43:58 +0100868 break;
869 case bt_rle :
870 return ERROR(GENERIC); /* not yet supported */
871 break;
872 case bt_end :
873 /* end of frame */
874 if (remainingSize) return ERROR(srcSize_wrong);
875 break;
876 default:
877 return ERROR(GENERIC); /* impossible */
878 }
879 if (cBlockSize == 0) break; /* bt_end */
880
881 if (ZSTD_isError(decodedSize)) return decodedSize;
882 op += decodedSize;
883 ip += cBlockSize;
884 remainingSize -= cBlockSize;
885 }
886
887 return op-ostart;
888}
889
Yann Collet31683c02015-12-18 01:26:48 +0100890
891size_t ZSTD_decompressDCtx(ZSTD_DCtx* dctx, void* dst, size_t maxDstSize, const void* src, size_t srcSize)
892{
893 return ZSTD_decompress_usingDict(dctx, dst, maxDstSize, src, srcSize, NULL, 0);
894}
895
Yann Collet5be2dd22015-11-11 13:43:58 +0100896size_t ZSTD_decompress(void* dst, size_t maxDstSize, const void* src, size_t srcSize)
897{
Yann Collet3a3b72f2016-01-11 12:56:11 +0100898#if defined(ZSTD_HEAPMODE) && (ZSTD_HEAPMODE==1)
899 size_t regenSize;
900 ZSTD_DCtx* dctx = ZSTD_createDCtx();
901 if (dctx==NULL) return ERROR(memory_allocation);
902 regenSize = ZSTD_decompressDCtx(dctx, dst, maxDstSize, src, srcSize);
903 ZSTD_freeDCtx(dctx);
904 return regenSize;
905#else
Yann Collet31683c02015-12-18 01:26:48 +0100906 ZSTD_DCtx dctx;
907 return ZSTD_decompressDCtx(&dctx, dst, maxDstSize, src, srcSize);
Yann Colleta768a302016-01-21 16:04:35 +0100908#endif
Yann Collet5be2dd22015-11-11 13:43:58 +0100909}
910
911
912/* ******************************
913* Streaming Decompression API
914********************************/
Yann Collet5be2dd22015-11-11 13:43:58 +0100915size_t ZSTD_nextSrcSizeToDecompress(ZSTD_DCtx* dctx)
916{
917 return dctx->expected;
918}
919
Yann Collet37422192016-01-25 16:54:05 +0100920size_t ZSTD_decompressContinue(ZSTD_DCtx* dctx, void* dst, size_t maxDstSize, const void* src, size_t srcSize)
Yann Collet5be2dd22015-11-11 13:43:58 +0100921{
922 /* Sanity check */
Yann Collet37422192016-01-25 16:54:05 +0100923 if (srcSize != dctx->expected) return ERROR(srcSize_wrong);
924 ZSTD_checkContinuity(dctx, dst);
Yann Collet5be2dd22015-11-11 13:43:58 +0100925
Yann Collet88fcd292015-11-25 14:42:45 +0100926 /* Decompress : frame header; part 1 */
Yann Collet37422192016-01-25 16:54:05 +0100927 switch (dctx->stage)
Yann Collet5be2dd22015-11-11 13:43:58 +0100928 {
Yann Collet88fcd292015-11-25 14:42:45 +0100929 case ZSTDds_getFrameHeaderSize :
Yann Collet5be2dd22015-11-11 13:43:58 +0100930 {
Yann Collet88fcd292015-11-25 14:42:45 +0100931 /* get frame header size */
932 if (srcSize != ZSTD_frameHeaderSize_min) return ERROR(srcSize_wrong); /* impossible */
Yann Collet37422192016-01-25 16:54:05 +0100933 dctx->headerSize = ZSTD_decodeFrameHeader_Part1(dctx, src, ZSTD_frameHeaderSize_min);
934 if (ZSTD_isError(dctx->headerSize)) return dctx->headerSize;
935 memcpy(dctx->headerBuffer, src, ZSTD_frameHeaderSize_min);
936 if (dctx->headerSize > ZSTD_frameHeaderSize_min)
Yann Collet88fcd292015-11-25 14:42:45 +0100937 {
Yann Collet37422192016-01-25 16:54:05 +0100938 dctx->expected = dctx->headerSize - ZSTD_frameHeaderSize_min;
939 dctx->stage = ZSTDds_decodeFrameHeader;
Yann Collet88fcd292015-11-25 14:42:45 +0100940 return 0;
941 }
Yann Collet37422192016-01-25 16:54:05 +0100942 dctx->expected = 0; /* not necessary to copy more */
Yann Collet5be2dd22015-11-11 13:43:58 +0100943 }
Yann Collet88fcd292015-11-25 14:42:45 +0100944 case ZSTDds_decodeFrameHeader:
Yann Collet5be2dd22015-11-11 13:43:58 +0100945 {
Yann Collet88fcd292015-11-25 14:42:45 +0100946 /* get frame header */
947 size_t result;
Yann Collet37422192016-01-25 16:54:05 +0100948 memcpy(dctx->headerBuffer + ZSTD_frameHeaderSize_min, src, dctx->expected);
949 result = ZSTD_decodeFrameHeader_Part2(dctx, dctx->headerBuffer, dctx->headerSize);
Yann Collet88fcd292015-11-25 14:42:45 +0100950 if (ZSTD_isError(result)) return result;
Yann Collet37422192016-01-25 16:54:05 +0100951 dctx->expected = ZSTD_blockHeaderSize;
952 dctx->stage = ZSTDds_decodeBlockHeader;
Yann Collet88fcd292015-11-25 14:42:45 +0100953 return 0;
Yann Collet5be2dd22015-11-11 13:43:58 +0100954 }
Yann Collet88fcd292015-11-25 14:42:45 +0100955 case ZSTDds_decodeBlockHeader:
Yann Collet5be2dd22015-11-11 13:43:58 +0100956 {
Yann Collet88fcd292015-11-25 14:42:45 +0100957 /* Decode block header */
958 blockProperties_t bp;
959 size_t blockSize = ZSTD_getcBlockSize(src, ZSTD_blockHeaderSize, &bp);
960 if (ZSTD_isError(blockSize)) return blockSize;
961 if (bp.blockType == bt_end)
962 {
Yann Collet37422192016-01-25 16:54:05 +0100963 dctx->expected = 0;
964 dctx->stage = ZSTDds_getFrameHeaderSize;
Yann Collet88fcd292015-11-25 14:42:45 +0100965 }
966 else
967 {
Yann Collet37422192016-01-25 16:54:05 +0100968 dctx->expected = blockSize;
969 dctx->bType = bp.blockType;
970 dctx->stage = ZSTDds_decompressBlock;
Yann Collet88fcd292015-11-25 14:42:45 +0100971 }
Yann Collet88fcd292015-11-25 14:42:45 +0100972 return 0;
973 }
Yann Collet417890c2015-12-04 17:16:37 +0100974 case ZSTDds_decompressBlock:
Yann Collet88fcd292015-11-25 14:42:45 +0100975 {
976 /* Decompress : block content */
977 size_t rSize;
Yann Collet37422192016-01-25 16:54:05 +0100978 switch(dctx->bType)
Yann Collet88fcd292015-11-25 14:42:45 +0100979 {
980 case bt_compressed:
Yann Collet37422192016-01-25 16:54:05 +0100981 rSize = ZSTD_decompressBlock_internal(dctx, dst, maxDstSize, src, srcSize);
Yann Collet88fcd292015-11-25 14:42:45 +0100982 break;
983 case bt_raw :
984 rSize = ZSTD_copyRawBlock(dst, maxDstSize, src, srcSize);
985 break;
986 case bt_rle :
987 return ERROR(GENERIC); /* not yet handled */
988 break;
989 case bt_end : /* should never happen (filtered at phase 1) */
990 rSize = 0;
991 break;
992 default:
993 return ERROR(GENERIC);
994 }
Yann Collet37422192016-01-25 16:54:05 +0100995 dctx->stage = ZSTDds_decodeBlockHeader;
996 dctx->expected = ZSTD_blockHeaderSize;
997 dctx->previousDstEnd = (char*)dst + rSize;
Yann Collet88fcd292015-11-25 14:42:45 +0100998 return rSize;
999 }
1000 default:
1001 return ERROR(GENERIC); /* impossible */
1002 }
Yann Collet5be2dd22015-11-11 13:43:58 +01001003}
1004
1005
Yann Colletb923f652016-01-26 03:14:20 +01001006static void ZSTD_refDictContent(ZSTD_DCtx* dctx, const void* dict, size_t dictSize)
Yann Collet417890c2015-12-04 17:16:37 +01001007{
Yann Collet37422192016-01-25 16:54:05 +01001008 dctx->dictEnd = dctx->previousDstEnd;
1009 dctx->vBase = (const char*)dict - ((const char*)(dctx->previousDstEnd) - (const char*)(dctx->base));
1010 dctx->base = dict;
1011 dctx->previousDstEnd = (const char*)dict + dictSize;
Yann Collet417890c2015-12-04 17:16:37 +01001012}
Yann Colletb923f652016-01-26 03:14:20 +01001013
1014
1015static size_t ZSTD_loadEntropy(ZSTD_DCtx* dctx, const void* dict, size_t dictSize)
1016{
1017 size_t hSize = HUF_readDTableX4(dctx->hufTableX4, dict, dictSize);
1018 if (HUF_isError(hSize)) return ERROR(dictionary_corrupted);
1019 return hSize;
1020}
1021
1022size_t ZSTD_decompress_insertDictionary(ZSTD_DCtx* dctx, const void* dict, size_t dictSize)
1023{
1024 size_t eSize;
1025 U32 magic = MEM_readLE32(dict);
1026 if (magic != ZSTD_DICT_MAGIC) {
1027 /* pure content mode */
1028 ZSTD_refDictContent(dctx, dict, dictSize);
1029 return 0;
1030 }
1031 /* load entropy tables */
1032 dict = (const char*)dict + 4;
1033 dictSize -= 4;
1034 eSize = ZSTD_loadEntropy(dctx, dict, dictSize);
1035 if (ZSTD_isError(eSize)) return ERROR(dictionary_corrupted);
1036
1037 /* reference dictionary content */
1038 dict = (const char*)dict + eSize;
1039 dictSize -= eSize;
1040 ZSTD_refDictContent(dctx, dict, dictSize);
1041
1042 return 0;
1043}
1044