blob: 2625f547625e871847a12d1a7da25988dbc52c9b [file] [log] [blame]
Yann Collet5be2dd22015-11-11 13:43:58 +01001/*
2 zstd - standard compression library
Yann Colletae7aa062016-02-03 02:46:46 +01003 Copyright (C) 2014-2016, Yann Collet.
Yann Collet5be2dd22015-11-11 13:43:58 +01004
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
Yann Collet5be2dd22015-11-11 13:43:58 +010030*/
31
32/* ***************************************************************
33* Tuning parameters
34*****************************************************************/
35/*!
Yann Collet5be2dd22015-11-11 13:43:58 +010036 * HEAPMODE :
Yann Collet3a3b72f2016-01-11 12:56:11 +010037 * Select how default decompression function ZSTD_decompress() will allocate memory,
38 * in memory stack (0), or in memory heap (1, requires malloc())
Yann Collet5be2dd22015-11-11 13:43:58 +010039 */
40#ifndef ZSTD_HEAPMODE
41# define ZSTD_HEAPMODE 1
Yann Collet3a3b72f2016-01-11 12:56:11 +010042#endif
Yann Collet5be2dd22015-11-11 13:43:58 +010043
44/*!
45* LEGACY_SUPPORT :
Yann Colletae7aa062016-02-03 02:46:46 +010046* if set to 1, ZSTD_decompress() can decode older formats (v0.1+)
Yann Collet5be2dd22015-11-11 13:43:58 +010047*/
48#ifndef ZSTD_LEGACY_SUPPORT
Yann Colletfba6aed2016-01-18 12:03:27 +010049# define ZSTD_LEGACY_SUPPORT 0
Yann Collet5be2dd22015-11-11 13:43:58 +010050#endif
51
52
Yann Colletfb810d62016-01-28 00:18:06 +010053/*-*******************************************************
Yann Collet953ce722016-02-04 15:28:14 +010054* Dependencies
Yann Collet5be2dd22015-11-11 13:43:58 +010055*********************************************************/
56#include <stdlib.h> /* calloc */
57#include <string.h> /* memcpy, memmove */
Yann Collet953ce722016-02-04 15:28:14 +010058#include <stdio.h> /* debug only : printf */
Yann Collet5be2dd22015-11-11 13:43:58 +010059#include "mem.h" /* low level memory routines */
Yann Collet5be2dd22015-11-11 13:43:58 +010060#include "zstd_internal.h"
61#include "fse_static.h"
Yann Colletafe07092016-01-25 04:10:46 +010062#include "huff0_static.h"
Yann Collet5be2dd22015-11-11 13:43:58 +010063
64#if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT==1)
65# include "zstd_legacy.h"
66#endif
67
Yann Colletfb810d62016-01-28 00:18:06 +010068
69/*-*******************************************************
Yann Collet5be2dd22015-11-11 13:43:58 +010070* Compiler specifics
71*********************************************************/
Yann Collet5be2dd22015-11-11 13:43:58 +010072#ifdef _MSC_VER /* Visual Studio */
73# define FORCE_INLINE static __forceinline
74# include <intrin.h> /* For Visual 2005 */
75# pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */
76# pragma warning(disable : 4324) /* disable: C4324: padded structure */
77#else
78# define GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__)
79# ifdef __GNUC__
80# define FORCE_INLINE static inline __attribute__((always_inline))
81# else
82# define FORCE_INLINE static inline
83# endif
84#endif
85
86
Yann Colletfb810d62016-01-28 00:18:06 +010087/*-*************************************
Yann Collet14983e72015-11-11 21:38:21 +010088* Local types
89***************************************/
90typedef struct
91{
92 blockType_t blockType;
93 U32 origSize;
94} blockProperties_t;
Yann Collet5be2dd22015-11-11 13:43:58 +010095
96
97/* *******************************************************
98* Memory operations
99**********************************************************/
100static void ZSTD_copy4(void* dst, const void* src) { memcpy(dst, src, 4); }
101
102
Yann Collet5be2dd22015-11-11 13:43:58 +0100103/* *************************************
104* Error Management
105***************************************/
Yann Collet14983e72015-11-11 21:38:21 +0100106unsigned ZSTD_versionNumber (void) { return ZSTD_VERSION_NUMBER; }
107
Yann Collet953ce722016-02-04 15:28:14 +0100108/*! ZSTD_isError() :
Yann Collet5be2dd22015-11-11 13:43:58 +0100109* tells if a return value is an error code */
110unsigned ZSTD_isError(size_t code) { return ERR_isError(code); }
111
Yann Collet953ce722016-02-04 15:28:14 +0100112/*! ZSTD_getError() :
Yann Collet72bff502016-02-03 12:06:24 +0100113* convert a `size_t` function result into a proper ZSTD_errorCode enum */
Yann Collet982ffc72016-02-05 02:33:10 +0100114ZSTD_ErrorCode ZSTD_getError(size_t code) { return ERR_getError(code); }
Yann Collet72bff502016-02-03 12:06:24 +0100115
Yann Collet953ce722016-02-04 15:28:14 +0100116/*! ZSTD_getErrorName() :
Yann Collet5be2dd22015-11-11 13:43:58 +0100117* provides error code string (useful for debugging) */
118const char* ZSTD_getErrorName(size_t code) { return ERR_getErrorName(code); }
119
120
Yann Collet5be2dd22015-11-11 13:43:58 +0100121/* *************************************************************
Yann Collet5b78d2f2015-11-12 15:36:05 +0100122* Context management
Yann Collet5be2dd22015-11-11 13:43:58 +0100123***************************************************************/
Yann Collete4fdad52015-11-25 21:09:17 +0100124typedef enum { ZSTDds_getFrameHeaderSize, ZSTDds_decodeFrameHeader,
Yann Collet88fcd292015-11-25 14:42:45 +0100125 ZSTDds_decodeBlockHeader, ZSTDds_decompressBlock } ZSTD_dStage;
126
Yann Collet5be2dd22015-11-11 13:43:58 +0100127struct ZSTD_DCtx_s
128{
Yann Colletfb810d62016-01-28 00:18:06 +0100129 FSE_DTable LLTable[FSE_DTABLE_SIZE_U32(LLFSELog)];
130 FSE_DTable OffTable[FSE_DTABLE_SIZE_U32(OffFSELog)];
131 FSE_DTable MLTable[FSE_DTABLE_SIZE_U32(MLFSELog)];
132 unsigned hufTableX4[HUF_DTABLE_SIZE(HufLog)];
Yann Collet417890c2015-12-04 17:16:37 +0100133 const void* previousDstEnd;
134 const void* base;
135 const void* vBase;
136 const void* dictEnd;
Yann Collet5be2dd22015-11-11 13:43:58 +0100137 size_t expected;
Yann Collet88fcd292015-11-25 14:42:45 +0100138 size_t headerSize;
Yann Collet0e491c02016-03-11 21:58:04 +0100139 ZSTD_frameParams fParams;
Yann Colletfb810d62016-01-28 00:18:06 +0100140 blockType_t bType; /* used in ZSTD_decompressContinue(), to transfer blockType between header decoding and block decoding stages */
Yann Collet88fcd292015-11-25 14:42:45 +0100141 ZSTD_dStage stage;
Yann Colletfb810d62016-01-28 00:18:06 +0100142 U32 flagStaticTables;
Yann Collet5be2dd22015-11-11 13:43:58 +0100143 const BYTE* litPtr;
144 size_t litBufSize;
145 size_t litSize;
Yann Colletb923f652016-01-26 03:14:20 +0100146 BYTE litBuffer[BLOCKSIZE + WILDCOPY_OVERLENGTH];
Yann Collet0e491c02016-03-11 21:58:04 +0100147 BYTE headerBuffer[ZSTD_FRAMEHEADERSIZE_MAX];
Yann Collet417890c2015-12-04 17:16:37 +0100148}; /* typedef'd to ZSTD_DCtx within "zstd_static.h" */
Yann Collet5be2dd22015-11-11 13:43:58 +0100149
Yann Colletfb810d62016-01-28 00:18:06 +0100150size_t sizeofDCtx (void) { return sizeof(ZSTD_DCtx); }
151
Yann Collet7b51a292016-01-26 15:58:49 +0100152size_t ZSTD_decompressBegin(ZSTD_DCtx* dctx)
Yann Collet5b78d2f2015-11-12 15:36:05 +0100153{
Yann Collet88fcd292015-11-25 14:42:45 +0100154 dctx->expected = ZSTD_frameHeaderSize_min;
155 dctx->stage = ZSTDds_getFrameHeaderSize;
Yann Collet5b78d2f2015-11-12 15:36:05 +0100156 dctx->previousDstEnd = NULL;
157 dctx->base = NULL;
158 dctx->vBase = NULL;
159 dctx->dictEnd = NULL;
Yann Colletb923f652016-01-26 03:14:20 +0100160 dctx->hufTableX4[0] = HufLog;
Yann Colletfb810d62016-01-28 00:18:06 +0100161 dctx->flagStaticTables = 0;
Yann Collet0e491c02016-03-11 21:58:04 +0100162 dctx->fParams.mml = MINMATCH; /* overwritten by frame but forces ZSTD_btopt to MINMATCH in block mode */
inikepa4dde252016-03-01 14:14:35 +0100163 ZSTD_LOG_BLOCK("%p: ZSTD_decompressBegin searchLength=%d\n", dctx->base, dctx->params.searchLength);
Yann Collet5b78d2f2015-11-12 15:36:05 +0100164 return 0;
165}
166
167ZSTD_DCtx* ZSTD_createDCtx(void)
168{
169 ZSTD_DCtx* dctx = (ZSTD_DCtx*)malloc(sizeof(ZSTD_DCtx));
170 if (dctx==NULL) return NULL;
Yann Collet7b51a292016-01-26 15:58:49 +0100171 ZSTD_decompressBegin(dctx);
Yann Collet5b78d2f2015-11-12 15:36:05 +0100172 return dctx;
173}
174
175size_t ZSTD_freeDCtx(ZSTD_DCtx* dctx)
176{
177 free(dctx);
Yann Collet982ffc72016-02-05 02:33:10 +0100178 return 0; /* reserved as a potential error code in the future */
Yann Collet5b78d2f2015-11-12 15:36:05 +0100179}
180
Yann Collet7b51a292016-01-26 15:58:49 +0100181void ZSTD_copyDCtx(ZSTD_DCtx* dstDCtx, const ZSTD_DCtx* srcDCtx)
182{
183 memcpy(dstDCtx, srcDCtx,
184 sizeof(ZSTD_DCtx) - (BLOCKSIZE+WILDCOPY_OVERLENGTH + ZSTD_frameHeaderSize_max)); /* no need to copy workspace */
185}
186
Yann Collet5b78d2f2015-11-12 15:36:05 +0100187
188/* *************************************************************
189* Decompression section
190***************************************************************/
Yann Collet59d1f792016-01-23 19:28:41 +0100191
192/* Frame format description
193 Frame Header - [ Block Header - Block ] - Frame End
194 1) Frame Header
195 - 4 bytes - Magic Number : ZSTD_MAGICNUMBER (defined within zstd_internal.h)
196 - 1 byte - Window Descriptor
197 2) Block Header
198 - 3 bytes, starting with a 2-bits descriptor
199 Uncompressed, Compressed, Frame End, unused
200 3) Block
201 See Block Format Description
202 4) Frame End
203 - 3 bytes, compatible with Block Header
204*/
205
206/* Block format description
Yann Colletfb810d62016-01-28 00:18:06 +0100207
208 Block = Literal Section - Sequences Section
209 Prerequisite : size of (compressed) block, maximum size of regenerated data
210
Yann Collet59d1f792016-01-23 19:28:41 +0100211 1) Literal Section
Yann Colletfb810d62016-01-28 00:18:06 +0100212
213 1.1) Header : 1-5 bytes
214 flags: 2 bits
Yann Collet59d1f792016-01-23 19:28:41 +0100215 00 compressed by Huff0
Yann Colletfb810d62016-01-28 00:18:06 +0100216 01 unused
217 10 is Raw (uncompressed)
218 11 is Rle
219 Note : using 01 => Huff0 with precomputed table ?
Yann Collet59d1f792016-01-23 19:28:41 +0100220 Note : delta map ? => compressed ?
Yann Colletfb810d62016-01-28 00:18:06 +0100221
222 1.1.1) Huff0-compressed literal block : 3-5 bytes
223 srcSize < 1 KB => 3 bytes (2-2-10-10) => single stream
224 srcSize < 1 KB => 3 bytes (2-2-10-10)
225 srcSize < 16KB => 4 bytes (2-2-14-14)
226 else => 5 bytes (2-2-18-18)
227 big endian convention
228
229 1.1.2) Raw (uncompressed) literal block header : 1-3 bytes
230 size : 5 bits: (IS_RAW<<6) + (0<<4) + size
231 12 bits: (IS_RAW<<6) + (2<<4) + (size>>8)
232 size&255
233 20 bits: (IS_RAW<<6) + (3<<4) + (size>>16)
234 size>>8&255
235 size&255
236
237 1.1.3) Rle (repeated single byte) literal block header : 1-3 bytes
238 size : 5 bits: (IS_RLE<<6) + (0<<4) + size
239 12 bits: (IS_RLE<<6) + (2<<4) + (size>>8)
240 size&255
241 20 bits: (IS_RLE<<6) + (3<<4) + (size>>16)
242 size>>8&255
243 size&255
244
245 1.1.4) Huff0-compressed literal block, using precomputed CTables : 3-5 bytes
246 srcSize < 1 KB => 3 bytes (2-2-10-10) => single stream
247 srcSize < 1 KB => 3 bytes (2-2-10-10)
248 srcSize < 16KB => 4 bytes (2-2-14-14)
249 else => 5 bytes (2-2-18-18)
250 big endian convention
251
252 1- CTable available (stored into workspace ?)
253 2- Small input (fast heuristic ? Full comparison ? depend on clevel ?)
254
255
256 1.2) Literal block content
Yann Collet59d1f792016-01-23 19:28:41 +0100257
258 1.2.1) Huff0 block, using sizes from header
259 See Huff0 format
260
Yann Colletfb810d62016-01-28 00:18:06 +0100261 1.2.2) Huff0 block, using prepared table
Yann Collet59d1f792016-01-23 19:28:41 +0100262
Yann Colletfb810d62016-01-28 00:18:06 +0100263 1.2.3) Raw content
264
265 1.2.4) single byte
266
Yann Collet59d1f792016-01-23 19:28:41 +0100267
268 2) Sequences section
269 TO DO
270*/
271
272
Yann Collet953ce722016-02-04 15:28:14 +0100273/** ZSTD_decodeFrameHeader_Part1() :
Yann Collet88fcd292015-11-25 14:42:45 +0100274* decode the 1st part of the Frame Header, which tells Frame Header size.
Yann Collet953ce722016-02-04 15:28:14 +0100275* srcSize must be == ZSTD_frameHeaderSize_min.
Yann Collet88fcd292015-11-25 14:42:45 +0100276* @return : the full size of the Frame Header */
277static size_t ZSTD_decodeFrameHeader_Part1(ZSTD_DCtx* zc, const void* src, size_t srcSize)
278{
279 U32 magicNumber;
Yann Collet61e16ce2016-01-31 02:04:15 +0100280 if (srcSize != ZSTD_frameHeaderSize_min)
281 return ERROR(srcSize_wrong);
Yann Collet88fcd292015-11-25 14:42:45 +0100282 magicNumber = MEM_readLE32(src);
283 if (magicNumber != ZSTD_MAGICNUMBER) return ERROR(prefix_unknown);
284 zc->headerSize = ZSTD_frameHeaderSize_min;
285 return zc->headerSize;
286}
287
Yann Collet88fcd292015-11-25 14:42:45 +0100288
Yann Collet0e491c02016-03-11 21:58:04 +0100289size_t ZSTD_getFrameParams(ZSTD_frameParams* fparamsPtr, const void* src, size_t srcSize)
Yann Collet88fcd292015-11-25 14:42:45 +0100290{
291 U32 magicNumber;
292 if (srcSize < ZSTD_frameHeaderSize_min) return ZSTD_frameHeaderSize_max;
293 magicNumber = MEM_readLE32(src);
294 if (magicNumber != ZSTD_MAGICNUMBER) return ERROR(prefix_unknown);
Yann Collet0e491c02016-03-11 21:58:04 +0100295 memset(fparamsPtr, 0, sizeof(*fparamsPtr));
296 fparamsPtr->windowLog = (((const BYTE*)src)[4] & 15) + ZSTD_WINDOWLOG_ABSOLUTEMIN;
297 fparamsPtr->mml = (((const BYTE*)src)[4] & 16) ? MINMATCH-1 : MINMATCH;
inikep6b3739c2016-02-22 15:53:42 +0100298 if ((((const BYTE*)src)[4] >> 5) != 0) return ERROR(frameParameter_unsupported); /* reserved 3 bits */
Yann Collet88fcd292015-11-25 14:42:45 +0100299 return 0;
300}
301
Yann Collet953ce722016-02-04 15:28:14 +0100302/** ZSTD_decodeFrameHeader_Part2() :
303* decode the full Frame Header.
304* srcSize must be the size provided by ZSTD_decodeFrameHeader_Part1().
Yann Collet26415d32015-11-26 12:43:28 +0100305* @return : 0, or an error code, which can be tested using ZSTD_isError() */
306static size_t ZSTD_decodeFrameHeader_Part2(ZSTD_DCtx* zc, const void* src, size_t srcSize)
307{
Yann Collet00fd7a22015-11-28 16:03:22 +0100308 size_t result;
Yann Collet61e16ce2016-01-31 02:04:15 +0100309 if (srcSize != zc->headerSize)
310 return ERROR(srcSize_wrong);
Yann Collet0e491c02016-03-11 21:58:04 +0100311 result = ZSTD_getFrameParams(&(zc->fParams), src, srcSize);
312 if ((MEM_32bits()) && (zc->fParams.windowLog > 25)) return ERROR(frameParameter_unsupportedBy32bits);
Yann Collet00fd7a22015-11-28 16:03:22 +0100313 return result;
Yann Collet26415d32015-11-26 12:43:28 +0100314}
315
Yann Collet5be2dd22015-11-11 13:43:58 +0100316
317size_t ZSTD_getcBlockSize(const void* src, size_t srcSize, blockProperties_t* bpPtr)
318{
319 const BYTE* const in = (const BYTE* const)src;
320 BYTE headerFlags;
321 U32 cSize;
322
Yann Collet61e16ce2016-01-31 02:04:15 +0100323 if (srcSize < 3)
324 return ERROR(srcSize_wrong);
Yann Collet5be2dd22015-11-11 13:43:58 +0100325
326 headerFlags = *in;
327 cSize = in[2] + (in[1]<<8) + ((in[0] & 7)<<16);
328
329 bpPtr->blockType = (blockType_t)(headerFlags >> 6);
330 bpPtr->origSize = (bpPtr->blockType == bt_rle) ? cSize : 0;
331
332 if (bpPtr->blockType == bt_end) return 0;
333 if (bpPtr->blockType == bt_rle) return 1;
334 return cSize;
335}
336
Yann Collet59d1f792016-01-23 19:28:41 +0100337
Yann Collet0f366c62015-11-12 16:19:30 +0100338static size_t ZSTD_copyRawBlock(void* dst, size_t maxDstSize, const void* src, size_t srcSize)
Yann Collet5be2dd22015-11-11 13:43:58 +0100339{
340 if (srcSize > maxDstSize) return ERROR(dstSize_tooSmall);
341 memcpy(dst, src, srcSize);
342 return srcSize;
343}
344
345
Yann Collet953ce722016-02-04 15:28:14 +0100346/*! ZSTD_decodeLiteralsBlock() :
Yann Collet14983e72015-11-11 21:38:21 +0100347 @return : nb of bytes read from src (< srcSize ) */
Yann Collet5b78d2f2015-11-12 15:36:05 +0100348size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx,
Yann Collet5be2dd22015-11-11 13:43:58 +0100349 const void* src, size_t srcSize) /* note : srcSize < BLOCKSIZE */
350{
Yann Collet5be2dd22015-11-11 13:43:58 +0100351 const BYTE* const istart = (const BYTE*) src;
352
353 /* any compressed block with literals segment must be at least this size */
354 if (srcSize < MIN_CBLOCK_SIZE) return ERROR(corruption_detected);
355
Yann Collet59d1f792016-01-23 19:28:41 +0100356 switch(istart[0]>> 6)
Yann Collet5be2dd22015-11-11 13:43:58 +0100357 {
Yann Collet59d1f792016-01-23 19:28:41 +0100358 case IS_HUF:
Yann Collet5be2dd22015-11-11 13:43:58 +0100359 {
Yann Colletafe07092016-01-25 04:10:46 +0100360 size_t litSize, litCSize, singleStream=0;
Yann Collet59d1f792016-01-23 19:28:41 +0100361 U32 lhSize = ((istart[0]) >> 4) & 3;
362 switch(lhSize)
363 {
364 case 0: case 1: default: /* note : default is impossible, since lhSize into [0..3] */
365 /* 2 - 2 - 10 - 10 */
366 lhSize=3;
Yann Colletafe07092016-01-25 04:10:46 +0100367 singleStream = istart[0] & 16;
Yann Collet59d1f792016-01-23 19:28:41 +0100368 litSize = ((istart[0] & 15) << 6) + (istart[1] >> 2);
369 litCSize = ((istart[1] & 3) << 8) + istart[2];
370 break;
371 case 2:
372 /* 2 - 2 - 14 - 14 */
373 lhSize=4;
374 litSize = ((istart[0] & 15) << 10) + (istart[1] << 2) + (istart[2] >> 6);
375 litCSize = ((istart[2] & 63) << 8) + istart[3];
376 break;
377 case 3:
378 /* 2 - 2 - 18 - 18 */
379 lhSize=5;
380 litSize = ((istart[0] & 15) << 14) + (istart[1] << 6) + (istart[2] >> 2);
381 litCSize = ((istart[2] & 3) << 16) + (istart[3] << 8) + istart[4];
382 break;
383 }
Yann Colletfb810d62016-01-28 00:18:06 +0100384 if (litSize > BLOCKSIZE) return ERROR(corruption_detected);
Yann Collet59d1f792016-01-23 19:28:41 +0100385
Yann Colletafe07092016-01-25 04:10:46 +0100386 if (HUF_isError(singleStream ?
387 HUF_decompress1X2(dctx->litBuffer, litSize, istart+lhSize, litCSize) :
388 HUF_decompress (dctx->litBuffer, litSize, istart+lhSize, litCSize) ))
Yann Collet59d1f792016-01-23 19:28:41 +0100389 return ERROR(corruption_detected);
390
Yann Collet5be2dd22015-11-11 13:43:58 +0100391 dctx->litPtr = dctx->litBuffer;
392 dctx->litBufSize = BLOCKSIZE+8;
393 dctx->litSize = litSize;
Yann Collet59d1f792016-01-23 19:28:41 +0100394 return litCSize + lhSize;
Yann Collet5be2dd22015-11-11 13:43:58 +0100395 }
Yann Colletb923f652016-01-26 03:14:20 +0100396 case IS_PCH:
397 {
398 size_t errorCode;
399 size_t litSize, litCSize;
400 U32 lhSize = ((istart[0]) >> 4) & 3;
401 if (lhSize != 1) /* only case supported for now : small litSize, single stream */
402 return ERROR(corruption_detected);
Yann Colletfb810d62016-01-28 00:18:06 +0100403 if (!dctx->flagStaticTables)
Yann Collet7b51a292016-01-26 15:58:49 +0100404 return ERROR(dictionary_corrupted);
Yann Colletb923f652016-01-26 03:14:20 +0100405
406 /* 2 - 2 - 10 - 10 */
407 lhSize=3;
408 litSize = ((istart[0] & 15) << 6) + (istart[1] >> 2);
409 litCSize = ((istart[1] & 3) << 8) + istart[2];
410
411 errorCode = HUF_decompress1X4_usingDTable(dctx->litBuffer, litSize, istart+lhSize, litCSize, dctx->hufTableX4);
412 if (HUF_isError(errorCode)) return ERROR(corruption_detected);
413
414 dctx->litPtr = dctx->litBuffer;
415 dctx->litBufSize = BLOCKSIZE+WILDCOPY_OVERLENGTH;
416 dctx->litSize = litSize;
417 return litCSize + lhSize;
418 }
Yann Collet5be2dd22015-11-11 13:43:58 +0100419 case IS_RAW:
420 {
Yann Collet59d1f792016-01-23 19:28:41 +0100421 size_t litSize;
422 U32 lhSize = ((istart[0]) >> 4) & 3;
423 switch(lhSize)
Yann Collet5be2dd22015-11-11 13:43:58 +0100424 {
Yann Collet59d1f792016-01-23 19:28:41 +0100425 case 0: case 1: default: /* note : default is impossible, since lhSize into [0..3] */
426 lhSize=1;
427 litSize = istart[0] & 31;
428 break;
429 case 2:
430 litSize = ((istart[0] & 15) << 8) + istart[1];
431 break;
432 case 3:
433 litSize = ((istart[0] & 15) << 16) + (istart[1] << 8) + istart[2];
434 break;
435 }
436
Yann Collet61e16ce2016-01-31 02:04:15 +0100437 if (lhSize+litSize+WILDCOPY_OVERLENGTH > srcSize) { /* risk reading beyond src buffer with wildcopy */
Yann Colletb010b3b2016-02-03 12:39:34 +0100438 if (litSize+lhSize > srcSize) return ERROR(corruption_detected);
Yann Collet59d1f792016-01-23 19:28:41 +0100439 memcpy(dctx->litBuffer, istart+lhSize, litSize);
Yann Collet5be2dd22015-11-11 13:43:58 +0100440 dctx->litPtr = dctx->litBuffer;
441 dctx->litBufSize = BLOCKSIZE+8;
442 dctx->litSize = litSize;
Yann Colletbc4c8aa2016-01-25 17:26:01 +0100443 return lhSize+litSize;
Yann Collet5be2dd22015-11-11 13:43:58 +0100444 }
445 /* direct reference into compressed stream */
Yann Collet59d1f792016-01-23 19:28:41 +0100446 dctx->litPtr = istart+lhSize;
447 dctx->litBufSize = srcSize-lhSize;
Yann Collet5be2dd22015-11-11 13:43:58 +0100448 dctx->litSize = litSize;
Yann Collet59d1f792016-01-23 19:28:41 +0100449 return lhSize+litSize;
450 }
Yann Collet5be2dd22015-11-11 13:43:58 +0100451 case IS_RLE:
452 {
Yann Collet59d1f792016-01-23 19:28:41 +0100453 size_t litSize;
454 U32 lhSize = ((istart[0]) >> 4) & 3;
455 switch(lhSize)
456 {
457 case 0: case 1: default: /* note : default is impossible, since lhSize into [0..3] */
458 lhSize = 1;
459 litSize = istart[0] & 31;
460 break;
461 case 2:
462 litSize = ((istart[0] & 15) << 8) + istart[1];
463 break;
464 case 3:
465 litSize = ((istart[0] & 15) << 16) + (istart[1] << 8) + istart[2];
466 break;
467 }
Yann Collet5be2dd22015-11-11 13:43:58 +0100468 if (litSize > BLOCKSIZE) return ERROR(corruption_detected);
Yann Collet59d1f792016-01-23 19:28:41 +0100469 memset(dctx->litBuffer, istart[lhSize], litSize);
Yann Collet5be2dd22015-11-11 13:43:58 +0100470 dctx->litPtr = dctx->litBuffer;
Yann Colletb923f652016-01-26 03:14:20 +0100471 dctx->litBufSize = BLOCKSIZE+WILDCOPY_OVERLENGTH;
Yann Collet5be2dd22015-11-11 13:43:58 +0100472 dctx->litSize = litSize;
Yann Collet59d1f792016-01-23 19:28:41 +0100473 return lhSize+1;
Yann Collet5be2dd22015-11-11 13:43:58 +0100474 }
Yann Colletb923f652016-01-26 03:14:20 +0100475 default:
476 return ERROR(corruption_detected); /* impossible */
Yann Collet5be2dd22015-11-11 13:43:58 +0100477 }
478}
479
480
481size_t ZSTD_decodeSeqHeaders(int* nbSeq, const BYTE** dumpsPtr, size_t* dumpsLengthPtr,
482 FSE_DTable* DTableLL, FSE_DTable* DTableML, FSE_DTable* DTableOffb,
483 const void* src, size_t srcSize)
484{
485 const BYTE* const istart = (const BYTE* const)src;
486 const BYTE* ip = istart;
487 const BYTE* const iend = istart + srcSize;
488 U32 LLtype, Offtype, MLtype;
489 U32 LLlog, Offlog, MLlog;
490 size_t dumpsLength;
491
492 /* check */
Yann Collet61e16ce2016-01-31 02:04:15 +0100493 if (srcSize < MIN_SEQUENCES_SIZE)
494 return ERROR(srcSize_wrong);
Yann Collet5be2dd22015-11-11 13:43:58 +0100495
496 /* SeqHead */
Yann Collet61e16ce2016-01-31 02:04:15 +0100497 *nbSeq = *ip++;
498 if (*nbSeq==0) return 1;
Yann Colletd409db62016-03-04 14:45:31 +0100499 if (*nbSeq >= 0x7F) {
500 if (*nbSeq == 0xFF)
501 *nbSeq = MEM_readLE16(ip) + LONGNBSEQ, ip+=2;
502 else
503 *nbSeq = ((nbSeq[0]-0x80)<<8) + *ip++;
504 }
Yann Collete93d6ce2016-01-31 00:58:06 +0100505
Yann Colletd409db62016-03-04 14:45:31 +0100506 /* FSE table descriptors */
Yann Collet5be2dd22015-11-11 13:43:58 +0100507 LLtype = *ip >> 6;
508 Offtype = (*ip >> 4) & 3;
509 MLtype = (*ip >> 2) & 3;
Yann Colletfb810d62016-01-28 00:18:06 +0100510 if (*ip & 2) {
Yann Collet5be2dd22015-11-11 13:43:58 +0100511 dumpsLength = ip[2];
512 dumpsLength += ip[1] << 8;
513 ip += 3;
Yann Colletfb810d62016-01-28 00:18:06 +0100514 } else {
Yann Collet5be2dd22015-11-11 13:43:58 +0100515 dumpsLength = ip[1];
516 dumpsLength += (ip[0] & 1) << 8;
517 ip += 2;
518 }
519 *dumpsPtr = ip;
520 ip += dumpsLength;
521 *dumpsLengthPtr = dumpsLength;
522
523 /* check */
524 if (ip > iend-3) return ERROR(srcSize_wrong); /* min : all 3 are "raw", hence no header, but at least xxLog bits per type */
525
526 /* sequences */
527 {
Yann Collet82368cf2015-11-16 19:10:56 +0100528 S16 norm[MaxML+1]; /* assumption : MaxML >= MaxLL >= MaxOff */
Yann Collet5be2dd22015-11-11 13:43:58 +0100529 size_t headerSize;
530
531 /* Build DTables */
532 switch(LLtype)
533 {
534 U32 max;
Yann Colletfb810d62016-01-28 00:18:06 +0100535 case FSE_ENCODING_RLE :
Yann Collet5be2dd22015-11-11 13:43:58 +0100536 LLlog = 0;
Yann Colletfb810d62016-01-28 00:18:06 +0100537 FSE_buildDTable_rle(DTableLL, *ip++);
538 break;
539 case FSE_ENCODING_RAW :
Yann Collet5be2dd22015-11-11 13:43:58 +0100540 LLlog = LLbits;
Yann Colletfb810d62016-01-28 00:18:06 +0100541 FSE_buildDTable_raw(DTableLL, LLbits);
542 break;
543 case FSE_ENCODING_STATIC:
544 break;
545 case FSE_ENCODING_DYNAMIC :
546 default : /* impossible */
Yann Collet5be2dd22015-11-11 13:43:58 +0100547 max = MaxLL;
548 headerSize = FSE_readNCount(norm, &max, &LLlog, ip, iend-ip);
549 if (FSE_isError(headerSize)) return ERROR(GENERIC);
550 if (LLlog > LLFSELog) return ERROR(corruption_detected);
551 ip += headerSize;
552 FSE_buildDTable(DTableLL, norm, max, LLlog);
553 }
554
555 switch(Offtype)
556 {
557 U32 max;
Yann Colletfb810d62016-01-28 00:18:06 +0100558 case FSE_ENCODING_RLE :
Yann Collet5be2dd22015-11-11 13:43:58 +0100559 Offlog = 0;
560 if (ip > iend-2) return ERROR(srcSize_wrong); /* min : "raw", hence no header, but at least xxLog bits */
561 FSE_buildDTable_rle(DTableOffb, *ip++ & MaxOff); /* if *ip > MaxOff, data is corrupted */
562 break;
Yann Colletfb810d62016-01-28 00:18:06 +0100563 case FSE_ENCODING_RAW :
Yann Collet5be2dd22015-11-11 13:43:58 +0100564 Offlog = Offbits;
Yann Colletfb810d62016-01-28 00:18:06 +0100565 FSE_buildDTable_raw(DTableOffb, Offbits);
566 break;
567 case FSE_ENCODING_STATIC:
568 break;
569 case FSE_ENCODING_DYNAMIC :
570 default : /* impossible */
Yann Collet5be2dd22015-11-11 13:43:58 +0100571 max = MaxOff;
572 headerSize = FSE_readNCount(norm, &max, &Offlog, ip, iend-ip);
573 if (FSE_isError(headerSize)) return ERROR(GENERIC);
574 if (Offlog > OffFSELog) return ERROR(corruption_detected);
575 ip += headerSize;
576 FSE_buildDTable(DTableOffb, norm, max, Offlog);
577 }
578
579 switch(MLtype)
580 {
581 U32 max;
Yann Colletfb810d62016-01-28 00:18:06 +0100582 case FSE_ENCODING_RLE :
Yann Collet5be2dd22015-11-11 13:43:58 +0100583 MLlog = 0;
584 if (ip > iend-2) return ERROR(srcSize_wrong); /* min : "raw", hence no header, but at least xxLog bits */
Yann Colletfb810d62016-01-28 00:18:06 +0100585 FSE_buildDTable_rle(DTableML, *ip++);
586 break;
587 case FSE_ENCODING_RAW :
Yann Collet5be2dd22015-11-11 13:43:58 +0100588 MLlog = MLbits;
Yann Colletfb810d62016-01-28 00:18:06 +0100589 FSE_buildDTable_raw(DTableML, MLbits);
590 break;
591 case FSE_ENCODING_STATIC:
592 break;
593 case FSE_ENCODING_DYNAMIC :
594 default : /* impossible */
Yann Collet5be2dd22015-11-11 13:43:58 +0100595 max = MaxML;
596 headerSize = FSE_readNCount(norm, &max, &MLlog, ip, iend-ip);
597 if (FSE_isError(headerSize)) return ERROR(GENERIC);
598 if (MLlog > MLFSELog) return ERROR(corruption_detected);
599 ip += headerSize;
600 FSE_buildDTable(DTableML, norm, max, MLlog);
Yann Colletfb810d62016-01-28 00:18:06 +0100601 } }
Yann Collet5be2dd22015-11-11 13:43:58 +0100602
603 return ip-istart;
604}
605
606
607typedef struct {
608 size_t litLength;
Yann Collet5be2dd22015-11-11 13:43:58 +0100609 size_t matchLength;
Yann Collete93d6ce2016-01-31 00:58:06 +0100610 size_t offset;
Yann Collet5be2dd22015-11-11 13:43:58 +0100611} seq_t;
612
613typedef struct {
614 BIT_DStream_t DStream;
615 FSE_DState_t stateLL;
616 FSE_DState_t stateOffb;
617 FSE_DState_t stateML;
618 size_t prevOffset;
619 const BYTE* dumps;
620 const BYTE* dumpsEnd;
621} seqState_t;
622
inikepe9f30ea2016-02-03 12:53:07 +0100623
624
inikep6b3739c2016-02-22 15:53:42 +0100625static void ZSTD_decodeSequence(seq_t* seq, seqState_t* seqState, const U32 mls)
Yann Collet5be2dd22015-11-11 13:43:58 +0100626{
627 size_t litLength;
628 size_t prevOffset;
629 size_t offset;
630 size_t matchLength;
631 const BYTE* dumps = seqState->dumps;
632 const BYTE* const de = seqState->dumpsEnd;
633
634 /* Literal length */
Yann Collete93d6ce2016-01-31 00:58:06 +0100635 litLength = FSE_peakSymbol(&(seqState->stateLL));
Yann Collete4fdad52015-11-25 21:09:17 +0100636 prevOffset = litLength ? seq->offset : seqState->prevOffset;
Yann Colletfb810d62016-01-28 00:18:06 +0100637 if (litLength == MaxLL) {
Yann Collet5be2dd22015-11-11 13:43:58 +0100638 U32 add = *dumps++;
639 if (add < 255) litLength += add;
Yann Colletfb810d62016-01-28 00:18:06 +0100640 else {
Yann Collet7d8e6bd2016-02-02 17:30:37 +0100641 litLength = MEM_readLE32(dumps) & 0xFFFFFF; /* no risk : dumps is always followed by seq tables > 1 byte */
642 if (litLength&1) litLength>>=1, dumps += 3;
643 else litLength = (U16)(litLength)>>1, dumps += 2;
Yann Collet5be2dd22015-11-11 13:43:58 +0100644 }
645 if (dumps >= de) dumps = de-1; /* late correction, to avoid read overflow (data is now corrupted anyway) */
646 }
647
648 /* Offset */
649 {
650 static const U32 offsetPrefix[MaxOff+1] = {
Yann Collet95cd0c22016-03-08 18:24:21 +0100651 1 /*fake*/, 1, 2, 4, 8, 0x10, 0x20, 0x40, 0x80, 0x100,
652 0x200, 0x400, 0x800, 0x1000, 0x2000, 0x4000, 0x8000, 0x10000, 0x20000, 0x40000,
653 0x80000, 0x100000, 0x200000, 0x400000, 0x800000, 0x1000000, 0x2000000, 0x4000000, /*fake*/ 1, 1, 1, 1 };
Yann Collete93d6ce2016-01-31 00:58:06 +0100654 U32 offsetCode = FSE_peakSymbol(&(seqState->stateOffb)); /* <= maxOff, by table construction */
655 U32 nbBits = offsetCode - 1;
Yann Collet5be2dd22015-11-11 13:43:58 +0100656 if (offsetCode==0) nbBits = 0; /* cmove */
657 offset = offsetPrefix[offsetCode] + BIT_readBits(&(seqState->DStream), nbBits);
658 if (MEM_32bits()) BIT_reloadDStream(&(seqState->DStream));
Yann Collete93d6ce2016-01-31 00:58:06 +0100659 if (offsetCode==0) offset = prevOffset; /* repcode, cmove */
Yann Collet55aa7f92015-11-20 12:04:52 +0100660 if (offsetCode | !litLength) seqState->prevOffset = seq->offset; /* cmove */
Yann Collete93d6ce2016-01-31 00:58:06 +0100661 FSE_decodeSymbol(&(seqState->stateOffb), &(seqState->DStream)); /* update */
Yann Collet5be2dd22015-11-11 13:43:58 +0100662 }
663
Yann Collete93d6ce2016-01-31 00:58:06 +0100664 /* Literal length update */
665 FSE_decodeSymbol(&(seqState->stateLL), &(seqState->DStream)); /* update */
666 if (MEM_32bits()) BIT_reloadDStream(&(seqState->DStream));
667
Yann Collet5be2dd22015-11-11 13:43:58 +0100668 /* MatchLength */
669 matchLength = FSE_decodeSymbol(&(seqState->stateML), &(seqState->DStream));
Yann Colletfb810d62016-01-28 00:18:06 +0100670 if (matchLength == MaxML) {
Yann Collet5be2dd22015-11-11 13:43:58 +0100671 U32 add = *dumps++;
672 if (add < 255) matchLength += add;
Yann Colletfb810d62016-01-28 00:18:06 +0100673 else {
Yann Collet5be2dd22015-11-11 13:43:58 +0100674 matchLength = MEM_readLE32(dumps) & 0xFFFFFF; /* no pb : dumps is always followed by seq tables > 1 byte */
Yann Collet7d8e6bd2016-02-02 17:30:37 +0100675 if (matchLength&1) matchLength>>=1, dumps += 3;
676 else matchLength = (U16)(matchLength)>>1, dumps += 2;
Yann Collet5be2dd22015-11-11 13:43:58 +0100677 }
678 if (dumps >= de) dumps = de-1; /* late correction, to avoid read overflow (data is now corrupted anyway) */
679 }
inikep6b3739c2016-02-22 15:53:42 +0100680 matchLength += mls;
Yann Collet5be2dd22015-11-11 13:43:58 +0100681
682 /* save result */
683 seq->litLength = litLength;
684 seq->offset = offset;
685 seq->matchLength = matchLength;
686 seqState->dumps = dumps;
Yann Colletfb810d62016-01-28 00:18:06 +0100687
Yann Collet7d8e6bd2016-02-02 17:30:37 +0100688#if 0 /* debug */
Yann Colletfb810d62016-01-28 00:18:06 +0100689 {
690 static U64 totalDecoded = 0;
691 printf("pos %6u : %3u literals & match %3u bytes at distance %6u \n",
692 (U32)(totalDecoded), (U32)litLength, (U32)matchLength, (U32)offset);
693 totalDecoded += litLength + matchLength;
694 }
695#endif
Yann Collet5be2dd22015-11-11 13:43:58 +0100696}
697
698
Yann Collet5b78d2f2015-11-12 15:36:05 +0100699FORCE_INLINE size_t ZSTD_execSequence(BYTE* op,
Yann Colletb3a2af92015-11-19 17:13:19 +0100700 BYTE* const oend, seq_t sequence,
Yann Collet5be2dd22015-11-11 13:43:58 +0100701 const BYTE** litPtr, const BYTE* const litLimit_8,
Yann Collet417890c2015-12-04 17:16:37 +0100702 const BYTE* const base, const BYTE* const vBase, const BYTE* const dictEnd)
Yann Collet5be2dd22015-11-11 13:43:58 +0100703{
Yann Colletb3a2af92015-11-19 17:13:19 +0100704 static const int dec32table[] = { 0, 1, 2, 1, 4, 4, 4, 4 }; /* added */
705 static const int dec64table[] = { 8, 8, 8, 7, 8, 9,10,11 }; /* substracted */
Yann Collet5be2dd22015-11-11 13:43:58 +0100706 BYTE* const oLitEnd = op + sequence.litLength;
Yann Colletb3a2af92015-11-19 17:13:19 +0100707 const size_t sequenceLength = sequence.litLength + sequence.matchLength;
708 BYTE* const oMatchEnd = op + sequenceLength; /* risk : address space overflow (32-bits) */
Yann Collet5be2dd22015-11-11 13:43:58 +0100709 BYTE* const oend_8 = oend-8;
710 const BYTE* const litEnd = *litPtr + sequence.litLength;
Yann Colletb3a2af92015-11-19 17:13:19 +0100711 const BYTE* match = oLitEnd - sequence.offset;
Yann Collet5be2dd22015-11-11 13:43:58 +0100712
713 /* check */
714 if (oLitEnd > oend_8) return ERROR(dstSize_tooSmall); /* last match must start at a minimum distance of 8 from oend */
715 if (oMatchEnd > oend) return ERROR(dstSize_tooSmall); /* overwrite beyond dst buffer */
716 if (litEnd > litLimit_8) return ERROR(corruption_detected); /* risk read beyond lit buffer */
717
718 /* copy Literals */
719 ZSTD_wildcopy(op, *litPtr, sequence.litLength); /* note : oLitEnd <= oend-8 : no risk of overwrite beyond oend */
720 op = oLitEnd;
721 *litPtr = litEnd; /* update for next sequence */
722
723 /* copy Match */
Yann Collet7b51a292016-01-26 15:58:49 +0100724 if (sequence.offset > (size_t)(oLitEnd - base)) {
Yann Collet44287a32015-11-30 23:13:56 +0100725 /* offset beyond prefix */
Yann Collet9f5ab1a2015-12-11 00:27:41 +0100726 if (sequence.offset > (size_t)(oLitEnd - vBase))
727 return ERROR(corruption_detected);
Yann Collet44287a32015-11-30 23:13:56 +0100728 match = dictEnd - (base-match);
Yann Collet7b51a292016-01-26 15:58:49 +0100729 if (match + sequence.matchLength <= dictEnd) {
Yann Collet4bfe4152015-12-06 13:18:37 +0100730 memmove(oLitEnd, match, sequence.matchLength);
Yann Collet44287a32015-11-30 23:13:56 +0100731 return sequenceLength;
732 }
733 /* span extDict & currentPrefixSegment */
734 {
735 size_t length1 = dictEnd - match;
Yann Collet4bfe4152015-12-06 13:18:37 +0100736 memmove(oLitEnd, match, length1);
Yann Collet44287a32015-11-30 23:13:56 +0100737 op = oLitEnd + length1;
738 sequence.matchLength -= length1;
739 match = base;
Yann Colletfb810d62016-01-28 00:18:06 +0100740 } }
Yann Collet0f366c62015-11-12 16:19:30 +0100741
Yann Collet44287a32015-11-30 23:13:56 +0100742 /* match within prefix */
Yann Collet7b51a292016-01-26 15:58:49 +0100743 if (sequence.offset < 8) {
Yann Collet44287a32015-11-30 23:13:56 +0100744 /* close range match, overlap */
745 const int sub2 = dec64table[sequence.offset];
746 op[0] = match[0];
747 op[1] = match[1];
748 op[2] = match[2];
749 op[3] = match[3];
750 match += dec32table[sequence.offset];
751 ZSTD_copy4(op+4, match);
752 match -= sub2;
Yann Colletfb810d62016-01-28 00:18:06 +0100753 } else {
Yann Collet44287a32015-11-30 23:13:56 +0100754 ZSTD_copy8(op, match);
755 }
756 op += 8; match += 8;
Yann Collet5be2dd22015-11-11 13:43:58 +0100757
inikepa4dde252016-03-01 14:14:35 +0100758 if (oMatchEnd > oend-(16-3)) { // 3 = MINMATCH
Yann Collet7b51a292016-01-26 15:58:49 +0100759 if (op < oend_8) {
Yann Collet44287a32015-11-30 23:13:56 +0100760 ZSTD_wildcopy(op, match, oend_8 - op);
761 match += oend_8 - op;
762 op = oend_8;
763 }
Yann Colletfb810d62016-01-28 00:18:06 +0100764 while (op < oMatchEnd)
765 *op++ = *match++;
766 } else {
Yann Collet44287a32015-11-30 23:13:56 +0100767 ZSTD_wildcopy(op, match, sequence.matchLength-8); /* works even if matchLength < 8 */
768 }
769 return sequenceLength;
Yann Collet5be2dd22015-11-11 13:43:58 +0100770}
771
Yann Colletb3a2af92015-11-19 17:13:19 +0100772
Yann Collet5be2dd22015-11-11 13:43:58 +0100773static size_t ZSTD_decompressSequences(
Yann Collet5b78d2f2015-11-12 15:36:05 +0100774 ZSTD_DCtx* dctx,
Yann Collet5be2dd22015-11-11 13:43:58 +0100775 void* dst, size_t maxDstSize,
776 const void* seqStart, size_t seqSize)
777{
Yann Collet5be2dd22015-11-11 13:43:58 +0100778 const BYTE* ip = (const BYTE*)seqStart;
779 const BYTE* const iend = ip + seqSize;
780 BYTE* const ostart = (BYTE* const)dst;
781 BYTE* op = ostart;
782 BYTE* const oend = ostart + maxDstSize;
783 size_t errorCode, dumpsLength;
784 const BYTE* litPtr = dctx->litPtr;
785 const BYTE* const litLimit_8 = litPtr + dctx->litBufSize - 8;
786 const BYTE* const litEnd = litPtr + dctx->litSize;
787 int nbSeq;
788 const BYTE* dumps;
789 U32* DTableLL = dctx->LLTable;
790 U32* DTableML = dctx->MLTable;
791 U32* DTableOffb = dctx->OffTable;
Yann Collet417890c2015-12-04 17:16:37 +0100792 const BYTE* const base = (const BYTE*) (dctx->base);
793 const BYTE* const vBase = (const BYTE*) (dctx->vBase);
794 const BYTE* const dictEnd = (const BYTE*) (dctx->dictEnd);
Yann Collet0e491c02016-03-11 21:58:04 +0100795 const U32 mls = dctx->fParams.mml;
Yann Collet5be2dd22015-11-11 13:43:58 +0100796
797 /* Build Decoding Tables */
798 errorCode = ZSTD_decodeSeqHeaders(&nbSeq, &dumps, &dumpsLength,
799 DTableLL, DTableML, DTableOffb,
Yann Colletfb810d62016-01-28 00:18:06 +0100800 ip, seqSize);
Yann Collet5be2dd22015-11-11 13:43:58 +0100801 if (ZSTD_isError(errorCode)) return errorCode;
802 ip += errorCode;
803
804 /* Regen sequences */
Yann Collete93d6ce2016-01-31 00:58:06 +0100805 if (nbSeq) {
Yann Collet5be2dd22015-11-11 13:43:58 +0100806 seq_t sequence;
807 seqState_t seqState;
808
809 memset(&sequence, 0, sizeof(sequence));
Yann Collet61e16ce2016-01-31 02:04:15 +0100810 sequence.offset = REPCODE_STARTVALUE;
Yann Collet5be2dd22015-11-11 13:43:58 +0100811 seqState.dumps = dumps;
812 seqState.dumpsEnd = dumps + dumpsLength;
Yann Collet61e16ce2016-01-31 02:04:15 +0100813 seqState.prevOffset = REPCODE_STARTVALUE;
Yann Collet5be2dd22015-11-11 13:43:58 +0100814 errorCode = BIT_initDStream(&(seqState.DStream), ip, iend-ip);
815 if (ERR_isError(errorCode)) return ERROR(corruption_detected);
816 FSE_initDState(&(seqState.stateLL), &(seqState.DStream), DTableLL);
817 FSE_initDState(&(seqState.stateOffb), &(seqState.DStream), DTableOffb);
818 FSE_initDState(&(seqState.stateML), &(seqState.DStream), DTableML);
819
Yann Collet7b51a292016-01-26 15:58:49 +0100820 for ( ; (BIT_reloadDStream(&(seqState.DStream)) <= BIT_DStream_completed) && nbSeq ; ) {
Yann Colletb3a2af92015-11-19 17:13:19 +0100821 size_t oneSeqSize;
822 nbSeq--;
inikep6b3739c2016-02-22 15:53:42 +0100823 ZSTD_decodeSequence(&sequence, &seqState, mls);
Yann Colletb3a2af92015-11-19 17:13:19 +0100824 oneSeqSize = ZSTD_execSequence(op, oend, sequence, &litPtr, litLimit_8, base, vBase, dictEnd);
Yann Collet370b08e2016-03-08 00:03:59 +0100825 if (ZSTD_isError(oneSeqSize))
826 return oneSeqSize;
Yann Collet5be2dd22015-11-11 13:43:58 +0100827 op += oneSeqSize;
828 }
829
830 /* check if reached exact end */
Yann Collet35f7de52016-01-31 02:51:03 +0100831 if (nbSeq) return ERROR(corruption_detected);
Yann Collete93d6ce2016-01-31 00:58:06 +0100832 }
Yann Collet5be2dd22015-11-11 13:43:58 +0100833
Yann Collete93d6ce2016-01-31 00:58:06 +0100834 /* last literal segment */
835 {
836 size_t lastLLSize = litEnd - litPtr;
837 if (litPtr > litEnd) return ERROR(corruption_detected); /* too many literals already used */
838 if (op+lastLLSize > oend) return ERROR(dstSize_tooSmall);
839 memcpy(op, litPtr, lastLLSize);
840 op += lastLLSize;
841 }
Yann Collet5be2dd22015-11-11 13:43:58 +0100842
843 return op-ostart;
844}
845
846
Yann Colletb0125102016-01-09 02:00:10 +0100847static void ZSTD_checkContinuity(ZSTD_DCtx* dctx, const void* dst)
848{
Yann Collet7b51a292016-01-26 15:58:49 +0100849 if (dst != dctx->previousDstEnd) { /* not contiguous */
Yann Colletb0125102016-01-09 02:00:10 +0100850 dctx->dictEnd = dctx->previousDstEnd;
851 dctx->vBase = (const char*)dst - ((const char*)(dctx->previousDstEnd) - (const char*)(dctx->base));
852 dctx->base = dst;
853 dctx->previousDstEnd = dst;
854 }
855}
856
857
858static size_t ZSTD_decompressBlock_internal(ZSTD_DCtx* dctx,
Yann Colletb010b3b2016-02-03 12:39:34 +0100859 void* dst, size_t dstCapacity,
Yann Collet5be2dd22015-11-11 13:43:58 +0100860 const void* src, size_t srcSize)
Yann Colletb010b3b2016-02-03 12:39:34 +0100861{ /* blockType == blockCompressed */
Yann Collet5be2dd22015-11-11 13:43:58 +0100862 const BYTE* ip = (const BYTE*)src;
Yann Colletb010b3b2016-02-03 12:39:34 +0100863 size_t litCSize;
864
865 if (srcSize >= BLOCKSIZE) return ERROR(srcSize_wrong);
Yann Collet5be2dd22015-11-11 13:43:58 +0100866
inikepa4dde252016-03-01 14:14:35 +0100867 ZSTD_LOG_BLOCK("%p: ZSTD_decompressBlock_internal searchLength=%d\n", dctx->base, dctx->params.searchLength);
868
Yann Collet5be2dd22015-11-11 13:43:58 +0100869 /* Decode literals sub-block */
Yann Colletb010b3b2016-02-03 12:39:34 +0100870 litCSize = ZSTD_decodeLiteralsBlock(dctx, src, srcSize);
Yann Collet5be2dd22015-11-11 13:43:58 +0100871 if (ZSTD_isError(litCSize)) return litCSize;
872 ip += litCSize;
873 srcSize -= litCSize;
874
Yann Colletb010b3b2016-02-03 12:39:34 +0100875 return ZSTD_decompressSequences(dctx, dst, dstCapacity, ip, srcSize);
Yann Collet5be2dd22015-11-11 13:43:58 +0100876}
877
878
Yann Colletb0125102016-01-09 02:00:10 +0100879size_t ZSTD_decompressBlock(ZSTD_DCtx* dctx,
Yann Colletb010b3b2016-02-03 12:39:34 +0100880 void* dst, size_t dstCapacity,
Yann Colletb0125102016-01-09 02:00:10 +0100881 const void* src, size_t srcSize)
882{
883 ZSTD_checkContinuity(dctx, dst);
Yann Colletb010b3b2016-02-03 12:39:34 +0100884 return ZSTD_decompressBlock_internal(dctx, dst, dstCapacity, src, srcSize);
Yann Colletb0125102016-01-09 02:00:10 +0100885}
886
887
Yann Collet0e491c02016-03-11 21:58:04 +0100888/*! ZSTD_decompress_continueDCtx() :
889* `dctx` must have been properly initialized */
890static size_t ZSTD_decompressFrame(ZSTD_DCtx* dctx,
Yann Collet31683c02015-12-18 01:26:48 +0100891 void* dst, size_t maxDstSize,
Yann Collet7b51a292016-01-26 15:58:49 +0100892 const void* src, size_t srcSize)
Yann Collet5be2dd22015-11-11 13:43:58 +0100893{
894 const BYTE* ip = (const BYTE*)src;
895 const BYTE* iend = ip + srcSize;
896 BYTE* const ostart = (BYTE* const)dst;
897 BYTE* op = ostart;
898 BYTE* const oend = ostart + maxDstSize;
899 size_t remainingSize = srcSize;
Yann Collet5be2dd22015-11-11 13:43:58 +0100900 blockProperties_t blockProperties;
901
902 /* Frame Header */
Yann Collet88fcd292015-11-25 14:42:45 +0100903 {
904 size_t frameHeaderSize;
905 if (srcSize < ZSTD_frameHeaderSize_min+ZSTD_blockHeaderSize) return ERROR(srcSize_wrong);
Yann Collet5be2dd22015-11-11 13:43:58 +0100906#if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT==1)
Yann Collet88fcd292015-11-25 14:42:45 +0100907 {
908 const U32 magicNumber = MEM_readLE32(src);
909 if (ZSTD_isLegacy(magicNumber))
910 return ZSTD_decompressLegacy(dst, maxDstSize, src, srcSize, magicNumber);
911 }
Yann Collet5be2dd22015-11-11 13:43:58 +0100912#endif
Yann Collet37422192016-01-25 16:54:05 +0100913 frameHeaderSize = ZSTD_decodeFrameHeader_Part1(dctx, src, ZSTD_frameHeaderSize_min);
Yann Collet88fcd292015-11-25 14:42:45 +0100914 if (ZSTD_isError(frameHeaderSize)) return frameHeaderSize;
915 if (srcSize < frameHeaderSize+ZSTD_blockHeaderSize) return ERROR(srcSize_wrong);
916 ip += frameHeaderSize; remainingSize -= frameHeaderSize;
Yann Collet37422192016-01-25 16:54:05 +0100917 frameHeaderSize = ZSTD_decodeFrameHeader_Part2(dctx, src, frameHeaderSize);
Yann Collet88fcd292015-11-25 14:42:45 +0100918 if (ZSTD_isError(frameHeaderSize)) return frameHeaderSize;
919 }
Yann Collet5be2dd22015-11-11 13:43:58 +0100920
921 /* Loop on each block */
922 while (1)
923 {
924 size_t decodedSize=0;
925 size_t cBlockSize = ZSTD_getcBlockSize(ip, iend-ip, &blockProperties);
926 if (ZSTD_isError(cBlockSize)) return cBlockSize;
927
928 ip += ZSTD_blockHeaderSize;
929 remainingSize -= ZSTD_blockHeaderSize;
930 if (cBlockSize > remainingSize) return ERROR(srcSize_wrong);
931
932 switch(blockProperties.blockType)
933 {
934 case bt_compressed:
Yann Collet37422192016-01-25 16:54:05 +0100935 decodedSize = ZSTD_decompressBlock_internal(dctx, op, oend-op, ip, cBlockSize);
Yann Collet5be2dd22015-11-11 13:43:58 +0100936 break;
937 case bt_raw :
Yann Collet0f366c62015-11-12 16:19:30 +0100938 decodedSize = ZSTD_copyRawBlock(op, oend-op, ip, cBlockSize);
Yann Collet5be2dd22015-11-11 13:43:58 +0100939 break;
940 case bt_rle :
941 return ERROR(GENERIC); /* not yet supported */
942 break;
943 case bt_end :
944 /* end of frame */
945 if (remainingSize) return ERROR(srcSize_wrong);
946 break;
947 default:
948 return ERROR(GENERIC); /* impossible */
949 }
950 if (cBlockSize == 0) break; /* bt_end */
951
952 if (ZSTD_isError(decodedSize)) return decodedSize;
953 op += decodedSize;
954 ip += cBlockSize;
955 remainingSize -= cBlockSize;
956 }
957
958 return op-ostart;
959}
960
Yann Collet31683c02015-12-18 01:26:48 +0100961
Yann Collet7b51a292016-01-26 15:58:49 +0100962size_t ZSTD_decompress_usingPreparedDCtx(ZSTD_DCtx* dctx, const ZSTD_DCtx* refDCtx,
963 void* dst, size_t maxDstSize,
964 const void* src, size_t srcSize)
965{
966 ZSTD_copyDCtx(dctx, refDCtx);
967 ZSTD_checkContinuity(dctx, dst);
Yann Collet0e491c02016-03-11 21:58:04 +0100968 return ZSTD_decompressFrame(dctx, dst, maxDstSize, src, srcSize);
Yann Collet7b51a292016-01-26 15:58:49 +0100969}
970
971
972size_t ZSTD_decompress_usingDict(ZSTD_DCtx* dctx,
973 void* dst, size_t maxDstSize,
974 const void* src, size_t srcSize,
975 const void* dict, size_t dictSize)
976{
977 ZSTD_decompressBegin_usingDict(dctx, dict, dictSize);
inikepa4dde252016-03-01 14:14:35 +0100978 ZSTD_LOG_BLOCK("%p: ZSTD_decompressBegin_usingDict searchLength=%d\n", dctx->base, dctx->params.searchLength);
Yann Collet7b51a292016-01-26 15:58:49 +0100979 ZSTD_checkContinuity(dctx, dst);
Yann Collet0e491c02016-03-11 21:58:04 +0100980 return ZSTD_decompressFrame(dctx, dst, maxDstSize, src, srcSize);
Yann Collet7b51a292016-01-26 15:58:49 +0100981}
982
983
Yann Collet31683c02015-12-18 01:26:48 +0100984size_t ZSTD_decompressDCtx(ZSTD_DCtx* dctx, void* dst, size_t maxDstSize, const void* src, size_t srcSize)
985{
986 return ZSTD_decompress_usingDict(dctx, dst, maxDstSize, src, srcSize, NULL, 0);
987}
988
Yann Collet0e491c02016-03-11 21:58:04 +0100989
Yann Collet5be2dd22015-11-11 13:43:58 +0100990size_t ZSTD_decompress(void* dst, size_t maxDstSize, const void* src, size_t srcSize)
991{
Yann Collet3a3b72f2016-01-11 12:56:11 +0100992#if defined(ZSTD_HEAPMODE) && (ZSTD_HEAPMODE==1)
993 size_t regenSize;
994 ZSTD_DCtx* dctx = ZSTD_createDCtx();
995 if (dctx==NULL) return ERROR(memory_allocation);
996 regenSize = ZSTD_decompressDCtx(dctx, dst, maxDstSize, src, srcSize);
997 ZSTD_freeDCtx(dctx);
998 return regenSize;
999#else
Yann Collet31683c02015-12-18 01:26:48 +01001000 ZSTD_DCtx dctx;
1001 return ZSTD_decompressDCtx(&dctx, dst, maxDstSize, src, srcSize);
Yann Colleta768a302016-01-21 16:04:35 +01001002#endif
Yann Collet5be2dd22015-11-11 13:43:58 +01001003}
1004
1005
1006/* ******************************
1007* Streaming Decompression API
1008********************************/
Yann Collet5be2dd22015-11-11 13:43:58 +01001009size_t ZSTD_nextSrcSizeToDecompress(ZSTD_DCtx* dctx)
1010{
1011 return dctx->expected;
1012}
1013
Yann Collet37422192016-01-25 16:54:05 +01001014size_t ZSTD_decompressContinue(ZSTD_DCtx* dctx, void* dst, size_t maxDstSize, const void* src, size_t srcSize)
Yann Collet5be2dd22015-11-11 13:43:58 +01001015{
1016 /* Sanity check */
Yann Collet37422192016-01-25 16:54:05 +01001017 if (srcSize != dctx->expected) return ERROR(srcSize_wrong);
1018 ZSTD_checkContinuity(dctx, dst);
Yann Collet5be2dd22015-11-11 13:43:58 +01001019
Yann Collet88fcd292015-11-25 14:42:45 +01001020 /* Decompress : frame header; part 1 */
Yann Collet37422192016-01-25 16:54:05 +01001021 switch (dctx->stage)
Yann Collet5be2dd22015-11-11 13:43:58 +01001022 {
Yann Collet88fcd292015-11-25 14:42:45 +01001023 case ZSTDds_getFrameHeaderSize :
Yann Collet5be2dd22015-11-11 13:43:58 +01001024 {
Yann Collet88fcd292015-11-25 14:42:45 +01001025 /* get frame header size */
1026 if (srcSize != ZSTD_frameHeaderSize_min) return ERROR(srcSize_wrong); /* impossible */
Yann Collet37422192016-01-25 16:54:05 +01001027 dctx->headerSize = ZSTD_decodeFrameHeader_Part1(dctx, src, ZSTD_frameHeaderSize_min);
1028 if (ZSTD_isError(dctx->headerSize)) return dctx->headerSize;
1029 memcpy(dctx->headerBuffer, src, ZSTD_frameHeaderSize_min);
Yann Collet7b51a292016-01-26 15:58:49 +01001030 if (dctx->headerSize > ZSTD_frameHeaderSize_min) {
Yann Collet37422192016-01-25 16:54:05 +01001031 dctx->expected = dctx->headerSize - ZSTD_frameHeaderSize_min;
1032 dctx->stage = ZSTDds_decodeFrameHeader;
Yann Collet88fcd292015-11-25 14:42:45 +01001033 return 0;
1034 }
Yann Collet37422192016-01-25 16:54:05 +01001035 dctx->expected = 0; /* not necessary to copy more */
Yann Collet5be2dd22015-11-11 13:43:58 +01001036 }
Yann Collet88fcd292015-11-25 14:42:45 +01001037 case ZSTDds_decodeFrameHeader:
Yann Collet5be2dd22015-11-11 13:43:58 +01001038 {
Yann Collet88fcd292015-11-25 14:42:45 +01001039 /* get frame header */
1040 size_t result;
Yann Collet37422192016-01-25 16:54:05 +01001041 memcpy(dctx->headerBuffer + ZSTD_frameHeaderSize_min, src, dctx->expected);
1042 result = ZSTD_decodeFrameHeader_Part2(dctx, dctx->headerBuffer, dctx->headerSize);
Yann Collet88fcd292015-11-25 14:42:45 +01001043 if (ZSTD_isError(result)) return result;
Yann Collet37422192016-01-25 16:54:05 +01001044 dctx->expected = ZSTD_blockHeaderSize;
1045 dctx->stage = ZSTDds_decodeBlockHeader;
Yann Collet88fcd292015-11-25 14:42:45 +01001046 return 0;
Yann Collet5be2dd22015-11-11 13:43:58 +01001047 }
Yann Collet88fcd292015-11-25 14:42:45 +01001048 case ZSTDds_decodeBlockHeader:
Yann Collet5be2dd22015-11-11 13:43:58 +01001049 {
Yann Collet88fcd292015-11-25 14:42:45 +01001050 /* Decode block header */
1051 blockProperties_t bp;
1052 size_t blockSize = ZSTD_getcBlockSize(src, ZSTD_blockHeaderSize, &bp);
1053 if (ZSTD_isError(blockSize)) return blockSize;
Yann Collet7b51a292016-01-26 15:58:49 +01001054 if (bp.blockType == bt_end) {
Yann Collet37422192016-01-25 16:54:05 +01001055 dctx->expected = 0;
1056 dctx->stage = ZSTDds_getFrameHeaderSize;
Yann Collet88fcd292015-11-25 14:42:45 +01001057 }
Yann Collet7b51a292016-01-26 15:58:49 +01001058 else {
Yann Collet37422192016-01-25 16:54:05 +01001059 dctx->expected = blockSize;
1060 dctx->bType = bp.blockType;
1061 dctx->stage = ZSTDds_decompressBlock;
Yann Collet88fcd292015-11-25 14:42:45 +01001062 }
Yann Collet88fcd292015-11-25 14:42:45 +01001063 return 0;
1064 }
Yann Collet417890c2015-12-04 17:16:37 +01001065 case ZSTDds_decompressBlock:
Yann Collet88fcd292015-11-25 14:42:45 +01001066 {
1067 /* Decompress : block content */
1068 size_t rSize;
Yann Collet37422192016-01-25 16:54:05 +01001069 switch(dctx->bType)
Yann Collet88fcd292015-11-25 14:42:45 +01001070 {
1071 case bt_compressed:
Yann Collet37422192016-01-25 16:54:05 +01001072 rSize = ZSTD_decompressBlock_internal(dctx, dst, maxDstSize, src, srcSize);
Yann Collet88fcd292015-11-25 14:42:45 +01001073 break;
1074 case bt_raw :
1075 rSize = ZSTD_copyRawBlock(dst, maxDstSize, src, srcSize);
1076 break;
1077 case bt_rle :
1078 return ERROR(GENERIC); /* not yet handled */
1079 break;
1080 case bt_end : /* should never happen (filtered at phase 1) */
1081 rSize = 0;
1082 break;
1083 default:
Yann Collet7b51a292016-01-26 15:58:49 +01001084 return ERROR(GENERIC); /* impossible */
Yann Collet88fcd292015-11-25 14:42:45 +01001085 }
Yann Collet37422192016-01-25 16:54:05 +01001086 dctx->stage = ZSTDds_decodeBlockHeader;
1087 dctx->expected = ZSTD_blockHeaderSize;
1088 dctx->previousDstEnd = (char*)dst + rSize;
Yann Collet88fcd292015-11-25 14:42:45 +01001089 return rSize;
1090 }
1091 default:
1092 return ERROR(GENERIC); /* impossible */
1093 }
Yann Collet5be2dd22015-11-11 13:43:58 +01001094}
1095
1096
Yann Colletb923f652016-01-26 03:14:20 +01001097static void ZSTD_refDictContent(ZSTD_DCtx* dctx, const void* dict, size_t dictSize)
Yann Collet417890c2015-12-04 17:16:37 +01001098{
Yann Collet37422192016-01-25 16:54:05 +01001099 dctx->dictEnd = dctx->previousDstEnd;
1100 dctx->vBase = (const char*)dict - ((const char*)(dctx->previousDstEnd) - (const char*)(dctx->base));
1101 dctx->base = dict;
1102 dctx->previousDstEnd = (const char*)dict + dictSize;
Yann Collet417890c2015-12-04 17:16:37 +01001103}
Yann Colletb923f652016-01-26 03:14:20 +01001104
Yann Colletb923f652016-01-26 03:14:20 +01001105static size_t ZSTD_loadEntropy(ZSTD_DCtx* dctx, const void* dict, size_t dictSize)
1106{
Yann Colletfb810d62016-01-28 00:18:06 +01001107 size_t hSize, offcodeHeaderSize, matchlengthHeaderSize, errorCode, litlengthHeaderSize;
1108 short offcodeNCount[MaxOff+1];
1109 U32 offcodeMaxValue=MaxOff, offcodeLog=OffFSELog;
1110 short matchlengthNCount[MaxML+1];
1111 unsigned matchlengthMaxValue = MaxML, matchlengthLog = MLFSELog;
1112 short litlengthNCount[MaxLL+1];
1113 unsigned litlengthMaxValue = MaxLL, litlengthLog = LLFSELog;
1114
1115 hSize = HUF_readDTableX4(dctx->hufTableX4, dict, dictSize);
Yann Colletb923f652016-01-26 03:14:20 +01001116 if (HUF_isError(hSize)) return ERROR(dictionary_corrupted);
Yann Colletfb810d62016-01-28 00:18:06 +01001117 dict = (const char*)dict + hSize;
1118 dictSize -= hSize;
1119
1120 offcodeHeaderSize = FSE_readNCount(offcodeNCount, &offcodeMaxValue, &offcodeLog, dict, dictSize);
1121 if (FSE_isError(offcodeHeaderSize)) return ERROR(dictionary_corrupted);
1122 errorCode = FSE_buildDTable(dctx->OffTable, offcodeNCount, offcodeMaxValue, offcodeLog);
1123 if (FSE_isError(errorCode)) return ERROR(dictionary_corrupted);
1124 dict = (const char*)dict + offcodeHeaderSize;
1125 dictSize -= offcodeHeaderSize;
1126
1127 matchlengthHeaderSize = FSE_readNCount(matchlengthNCount, &matchlengthMaxValue, &matchlengthLog, dict, dictSize);
1128 if (FSE_isError(matchlengthHeaderSize)) return ERROR(dictionary_corrupted);
1129 errorCode = FSE_buildDTable(dctx->MLTable, matchlengthNCount, matchlengthMaxValue, matchlengthLog);
1130 if (FSE_isError(errorCode)) return ERROR(dictionary_corrupted);
1131 dict = (const char*)dict + matchlengthHeaderSize;
1132 dictSize -= matchlengthHeaderSize;
1133
1134 litlengthHeaderSize = FSE_readNCount(litlengthNCount, &litlengthMaxValue, &litlengthLog, dict, dictSize);
1135 if (FSE_isError(litlengthHeaderSize)) return ERROR(dictionary_corrupted);
1136 errorCode = FSE_buildDTable(dctx->LLTable, litlengthNCount, litlengthMaxValue, litlengthLog);
1137 if (FSE_isError(errorCode)) return ERROR(dictionary_corrupted);
1138
1139 dctx->flagStaticTables = 1;
1140 return hSize + offcodeHeaderSize + matchlengthHeaderSize + litlengthHeaderSize;
Yann Colletb923f652016-01-26 03:14:20 +01001141}
1142
Yann Collet7b51a292016-01-26 15:58:49 +01001143static size_t ZSTD_decompress_insertDictionary(ZSTD_DCtx* dctx, const void* dict, size_t dictSize)
Yann Colletb923f652016-01-26 03:14:20 +01001144{
1145 size_t eSize;
1146 U32 magic = MEM_readLE32(dict);
1147 if (magic != ZSTD_DICT_MAGIC) {
1148 /* pure content mode */
1149 ZSTD_refDictContent(dctx, dict, dictSize);
1150 return 0;
1151 }
1152 /* load entropy tables */
1153 dict = (const char*)dict + 4;
1154 dictSize -= 4;
1155 eSize = ZSTD_loadEntropy(dctx, dict, dictSize);
1156 if (ZSTD_isError(eSize)) return ERROR(dictionary_corrupted);
1157
1158 /* reference dictionary content */
1159 dict = (const char*)dict + eSize;
1160 dictSize -= eSize;
1161 ZSTD_refDictContent(dctx, dict, dictSize);
1162
1163 return 0;
1164}
1165
Yann Collet7b51a292016-01-26 15:58:49 +01001166
1167size_t ZSTD_decompressBegin_usingDict(ZSTD_DCtx* dctx, const void* dict, size_t dictSize)
1168{
1169 size_t errorCode;
1170 errorCode = ZSTD_decompressBegin(dctx);
1171 if (ZSTD_isError(errorCode)) return errorCode;
1172
1173 if (dict && dictSize) {
1174 errorCode = ZSTD_decompress_insertDictionary(dctx, dict, dictSize);
1175 if (ZSTD_isError(errorCode)) return ERROR(dictionary_corrupted);
1176 }
1177
1178 return 0;
1179}
1180