blob: 60136b6155d5362941779d05fe25491300e6f947 [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;
139 ZSTD_parameters params;
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 Collet88fcd292015-11-25 14:42:45 +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;
inikepa4dde252016-03-01 14:14:35 +0100162 dctx->params.searchLength = MINMATCH; /* overwritten by frame but forces ZSTD_btopt to MINMATCH in block mode */
163 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
289size_t ZSTD_getFrameParams(ZSTD_parameters* params, const void* src, size_t srcSize)
290{
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);
295 memset(params, 0, sizeof(*params));
Yann Collet26415d32015-11-26 12:43:28 +0100296 params->windowLog = (((const BYTE*)src)[4] & 15) + ZSTD_WINDOWLOG_ABSOLUTEMIN;
inikep6b3739c2016-02-22 15:53:42 +0100297 params->searchLength = (((const BYTE*)src)[4] & 16) ? MINMATCH-1 : MINMATCH;
298 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 Collet00fd7a22015-11-28 16:03:22 +0100311 result = ZSTD_getFrameParams(&(zc->params), src, srcSize);
Yann Collet72bff502016-02-03 12:06:24 +0100312 if ((MEM_32bits()) && (zc->params.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);
inikep6b3739c2016-02-22 15:53:42 +0100795 const U32 mls = dctx->params.searchLength;
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 Collet7b51a292016-01-26 15:58:49 +0100888/*! ZSTD_decompress_continueDCtx
889* dctx must have been properly initialized */
890static size_t ZSTD_decompress_continueDCtx(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);
968 return ZSTD_decompress_continueDCtx(dctx, dst, maxDstSize, src, srcSize);
969}
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);
980 return ZSTD_decompress_continueDCtx(dctx, dst, maxDstSize, src, srcSize);
981}
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 Collet5be2dd22015-11-11 13:43:58 +0100989size_t ZSTD_decompress(void* dst, size_t maxDstSize, const void* src, size_t srcSize)
990{
Yann Collet3a3b72f2016-01-11 12:56:11 +0100991#if defined(ZSTD_HEAPMODE) && (ZSTD_HEAPMODE==1)
992 size_t regenSize;
993 ZSTD_DCtx* dctx = ZSTD_createDCtx();
994 if (dctx==NULL) return ERROR(memory_allocation);
995 regenSize = ZSTD_decompressDCtx(dctx, dst, maxDstSize, src, srcSize);
996 ZSTD_freeDCtx(dctx);
997 return regenSize;
998#else
Yann Collet31683c02015-12-18 01:26:48 +0100999 ZSTD_DCtx dctx;
1000 return ZSTD_decompressDCtx(&dctx, dst, maxDstSize, src, srcSize);
Yann Colleta768a302016-01-21 16:04:35 +01001001#endif
Yann Collet5be2dd22015-11-11 13:43:58 +01001002}
1003
1004
1005/* ******************************
1006* Streaming Decompression API
1007********************************/
Yann Collet5be2dd22015-11-11 13:43:58 +01001008size_t ZSTD_nextSrcSizeToDecompress(ZSTD_DCtx* dctx)
1009{
1010 return dctx->expected;
1011}
1012
Yann Collet37422192016-01-25 16:54:05 +01001013size_t ZSTD_decompressContinue(ZSTD_DCtx* dctx, void* dst, size_t maxDstSize, const void* src, size_t srcSize)
Yann Collet5be2dd22015-11-11 13:43:58 +01001014{
1015 /* Sanity check */
Yann Collet37422192016-01-25 16:54:05 +01001016 if (srcSize != dctx->expected) return ERROR(srcSize_wrong);
1017 ZSTD_checkContinuity(dctx, dst);
Yann Collet5be2dd22015-11-11 13:43:58 +01001018
Yann Collet88fcd292015-11-25 14:42:45 +01001019 /* Decompress : frame header; part 1 */
Yann Collet37422192016-01-25 16:54:05 +01001020 switch (dctx->stage)
Yann Collet5be2dd22015-11-11 13:43:58 +01001021 {
Yann Collet88fcd292015-11-25 14:42:45 +01001022 case ZSTDds_getFrameHeaderSize :
Yann Collet5be2dd22015-11-11 13:43:58 +01001023 {
Yann Collet88fcd292015-11-25 14:42:45 +01001024 /* get frame header size */
1025 if (srcSize != ZSTD_frameHeaderSize_min) return ERROR(srcSize_wrong); /* impossible */
Yann Collet37422192016-01-25 16:54:05 +01001026 dctx->headerSize = ZSTD_decodeFrameHeader_Part1(dctx, src, ZSTD_frameHeaderSize_min);
1027 if (ZSTD_isError(dctx->headerSize)) return dctx->headerSize;
1028 memcpy(dctx->headerBuffer, src, ZSTD_frameHeaderSize_min);
Yann Collet7b51a292016-01-26 15:58:49 +01001029 if (dctx->headerSize > ZSTD_frameHeaderSize_min) {
Yann Collet37422192016-01-25 16:54:05 +01001030 dctx->expected = dctx->headerSize - ZSTD_frameHeaderSize_min;
1031 dctx->stage = ZSTDds_decodeFrameHeader;
Yann Collet88fcd292015-11-25 14:42:45 +01001032 return 0;
1033 }
Yann Collet37422192016-01-25 16:54:05 +01001034 dctx->expected = 0; /* not necessary to copy more */
Yann Collet5be2dd22015-11-11 13:43:58 +01001035 }
Yann Collet88fcd292015-11-25 14:42:45 +01001036 case ZSTDds_decodeFrameHeader:
Yann Collet5be2dd22015-11-11 13:43:58 +01001037 {
Yann Collet88fcd292015-11-25 14:42:45 +01001038 /* get frame header */
1039 size_t result;
Yann Collet37422192016-01-25 16:54:05 +01001040 memcpy(dctx->headerBuffer + ZSTD_frameHeaderSize_min, src, dctx->expected);
1041 result = ZSTD_decodeFrameHeader_Part2(dctx, dctx->headerBuffer, dctx->headerSize);
Yann Collet88fcd292015-11-25 14:42:45 +01001042 if (ZSTD_isError(result)) return result;
Yann Collet37422192016-01-25 16:54:05 +01001043 dctx->expected = ZSTD_blockHeaderSize;
1044 dctx->stage = ZSTDds_decodeBlockHeader;
Yann Collet88fcd292015-11-25 14:42:45 +01001045 return 0;
Yann Collet5be2dd22015-11-11 13:43:58 +01001046 }
Yann Collet88fcd292015-11-25 14:42:45 +01001047 case ZSTDds_decodeBlockHeader:
Yann Collet5be2dd22015-11-11 13:43:58 +01001048 {
Yann Collet88fcd292015-11-25 14:42:45 +01001049 /* Decode block header */
1050 blockProperties_t bp;
1051 size_t blockSize = ZSTD_getcBlockSize(src, ZSTD_blockHeaderSize, &bp);
1052 if (ZSTD_isError(blockSize)) return blockSize;
Yann Collet7b51a292016-01-26 15:58:49 +01001053 if (bp.blockType == bt_end) {
Yann Collet37422192016-01-25 16:54:05 +01001054 dctx->expected = 0;
1055 dctx->stage = ZSTDds_getFrameHeaderSize;
Yann Collet88fcd292015-11-25 14:42:45 +01001056 }
Yann Collet7b51a292016-01-26 15:58:49 +01001057 else {
Yann Collet37422192016-01-25 16:54:05 +01001058 dctx->expected = blockSize;
1059 dctx->bType = bp.blockType;
1060 dctx->stage = ZSTDds_decompressBlock;
Yann Collet88fcd292015-11-25 14:42:45 +01001061 }
Yann Collet88fcd292015-11-25 14:42:45 +01001062 return 0;
1063 }
Yann Collet417890c2015-12-04 17:16:37 +01001064 case ZSTDds_decompressBlock:
Yann Collet88fcd292015-11-25 14:42:45 +01001065 {
1066 /* Decompress : block content */
1067 size_t rSize;
Yann Collet37422192016-01-25 16:54:05 +01001068 switch(dctx->bType)
Yann Collet88fcd292015-11-25 14:42:45 +01001069 {
1070 case bt_compressed:
Yann Collet37422192016-01-25 16:54:05 +01001071 rSize = ZSTD_decompressBlock_internal(dctx, dst, maxDstSize, src, srcSize);
Yann Collet88fcd292015-11-25 14:42:45 +01001072 break;
1073 case bt_raw :
1074 rSize = ZSTD_copyRawBlock(dst, maxDstSize, src, srcSize);
1075 break;
1076 case bt_rle :
1077 return ERROR(GENERIC); /* not yet handled */
1078 break;
1079 case bt_end : /* should never happen (filtered at phase 1) */
1080 rSize = 0;
1081 break;
1082 default:
Yann Collet7b51a292016-01-26 15:58:49 +01001083 return ERROR(GENERIC); /* impossible */
Yann Collet88fcd292015-11-25 14:42:45 +01001084 }
Yann Collet37422192016-01-25 16:54:05 +01001085 dctx->stage = ZSTDds_decodeBlockHeader;
1086 dctx->expected = ZSTD_blockHeaderSize;
1087 dctx->previousDstEnd = (char*)dst + rSize;
Yann Collet88fcd292015-11-25 14:42:45 +01001088 return rSize;
1089 }
1090 default:
1091 return ERROR(GENERIC); /* impossible */
1092 }
Yann Collet5be2dd22015-11-11 13:43:58 +01001093}
1094
1095
Yann Colletb923f652016-01-26 03:14:20 +01001096static void ZSTD_refDictContent(ZSTD_DCtx* dctx, const void* dict, size_t dictSize)
Yann Collet417890c2015-12-04 17:16:37 +01001097{
Yann Collet37422192016-01-25 16:54:05 +01001098 dctx->dictEnd = dctx->previousDstEnd;
1099 dctx->vBase = (const char*)dict - ((const char*)(dctx->previousDstEnd) - (const char*)(dctx->base));
1100 dctx->base = dict;
1101 dctx->previousDstEnd = (const char*)dict + dictSize;
Yann Collet417890c2015-12-04 17:16:37 +01001102}
Yann Colletb923f652016-01-26 03:14:20 +01001103
Yann Colletb923f652016-01-26 03:14:20 +01001104static size_t ZSTD_loadEntropy(ZSTD_DCtx* dctx, const void* dict, size_t dictSize)
1105{
Yann Colletfb810d62016-01-28 00:18:06 +01001106 size_t hSize, offcodeHeaderSize, matchlengthHeaderSize, errorCode, litlengthHeaderSize;
1107 short offcodeNCount[MaxOff+1];
1108 U32 offcodeMaxValue=MaxOff, offcodeLog=OffFSELog;
1109 short matchlengthNCount[MaxML+1];
1110 unsigned matchlengthMaxValue = MaxML, matchlengthLog = MLFSELog;
1111 short litlengthNCount[MaxLL+1];
1112 unsigned litlengthMaxValue = MaxLL, litlengthLog = LLFSELog;
1113
1114 hSize = HUF_readDTableX4(dctx->hufTableX4, dict, dictSize);
Yann Colletb923f652016-01-26 03:14:20 +01001115 if (HUF_isError(hSize)) return ERROR(dictionary_corrupted);
Yann Colletfb810d62016-01-28 00:18:06 +01001116 dict = (const char*)dict + hSize;
1117 dictSize -= hSize;
1118
1119 offcodeHeaderSize = FSE_readNCount(offcodeNCount, &offcodeMaxValue, &offcodeLog, dict, dictSize);
1120 if (FSE_isError(offcodeHeaderSize)) return ERROR(dictionary_corrupted);
1121 errorCode = FSE_buildDTable(dctx->OffTable, offcodeNCount, offcodeMaxValue, offcodeLog);
1122 if (FSE_isError(errorCode)) return ERROR(dictionary_corrupted);
1123 dict = (const char*)dict + offcodeHeaderSize;
1124 dictSize -= offcodeHeaderSize;
1125
1126 matchlengthHeaderSize = FSE_readNCount(matchlengthNCount, &matchlengthMaxValue, &matchlengthLog, dict, dictSize);
1127 if (FSE_isError(matchlengthHeaderSize)) return ERROR(dictionary_corrupted);
1128 errorCode = FSE_buildDTable(dctx->MLTable, matchlengthNCount, matchlengthMaxValue, matchlengthLog);
1129 if (FSE_isError(errorCode)) return ERROR(dictionary_corrupted);
1130 dict = (const char*)dict + matchlengthHeaderSize;
1131 dictSize -= matchlengthHeaderSize;
1132
1133 litlengthHeaderSize = FSE_readNCount(litlengthNCount, &litlengthMaxValue, &litlengthLog, dict, dictSize);
1134 if (FSE_isError(litlengthHeaderSize)) return ERROR(dictionary_corrupted);
1135 errorCode = FSE_buildDTable(dctx->LLTable, litlengthNCount, litlengthMaxValue, litlengthLog);
1136 if (FSE_isError(errorCode)) return ERROR(dictionary_corrupted);
1137
1138 dctx->flagStaticTables = 1;
1139 return hSize + offcodeHeaderSize + matchlengthHeaderSize + litlengthHeaderSize;
Yann Colletb923f652016-01-26 03:14:20 +01001140}
1141
Yann Collet7b51a292016-01-26 15:58:49 +01001142static size_t ZSTD_decompress_insertDictionary(ZSTD_DCtx* dctx, const void* dict, size_t dictSize)
Yann Colletb923f652016-01-26 03:14:20 +01001143{
1144 size_t eSize;
1145 U32 magic = MEM_readLE32(dict);
1146 if (magic != ZSTD_DICT_MAGIC) {
1147 /* pure content mode */
1148 ZSTD_refDictContent(dctx, dict, dictSize);
1149 return 0;
1150 }
1151 /* load entropy tables */
1152 dict = (const char*)dict + 4;
1153 dictSize -= 4;
1154 eSize = ZSTD_loadEntropy(dctx, dict, dictSize);
1155 if (ZSTD_isError(eSize)) return ERROR(dictionary_corrupted);
1156
1157 /* reference dictionary content */
1158 dict = (const char*)dict + eSize;
1159 dictSize -= eSize;
1160 ZSTD_refDictContent(dctx, dict, dictSize);
1161
1162 return 0;
1163}
1164
Yann Collet7b51a292016-01-26 15:58:49 +01001165
1166size_t ZSTD_decompressBegin_usingDict(ZSTD_DCtx* dctx, const void* dict, size_t dictSize)
1167{
1168 size_t errorCode;
1169 errorCode = ZSTD_decompressBegin(dctx);
1170 if (ZSTD_isError(errorCode)) return errorCode;
1171
1172 if (dict && dictSize) {
1173 errorCode = ZSTD_decompress_insertDictionary(dctx, dict, dictSize);
1174 if (ZSTD_isError(errorCode)) return ERROR(dictionary_corrupted);
1175 }
1176
1177 return 0;
1178}
1179