blob: d8d7837a58606e99483d02d8bbd3d51c7e79774a [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
Yann Collet03ea59b2016-03-12 01:25:40 +010097/*_*******************************************************
Yann Collet5be2dd22015-11-11 13:43:58 +010098* Memory operations
99**********************************************************/
100static void ZSTD_copy4(void* dst, const void* src) { memcpy(dst, src, 4); }
101
102
Yann Collet03ea59b2016-03-12 01:25:40 +0100103/*-*************************************
Yann Collet5be2dd22015-11-11 13:43:58 +0100104* 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 Collet03ea59b2016-03-12 01:25:40 +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 Collet569b81a2016-03-16 15:26:51 +0100146 BYTE litBuffer[ZSTD_BLOCKSIZE_MAX + 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,
Yann Collet569b81a2016-03-16 15:26:51 +0100184 sizeof(ZSTD_DCtx) - (ZSTD_BLOCKSIZE_MAX+WILDCOPY_OVERLENGTH + ZSTD_frameHeaderSize_max)); /* no need to copy workspace */
Yann Collet7b51a292016-01-26 15:58:49 +0100185}
186
Yann Collet5b78d2f2015-11-12 15:36:05 +0100187
Yann Collet03ea59b2016-03-12 01:25:40 +0100188/*-*************************************************************
Yann Collet5b78d2f2015-11-12 15:36:05 +0100189* 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
Yann Collet03ea59b2016-03-12 01:25:40 +0100195 - 4 bytes - Magic Number : ZSTD_MAGICNUMBER (defined within zstd_static.h)
196 - 1 byte - Frame Descriptor
Yann Collet59d1f792016-01-23 19:28:41 +0100197 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
Yann Collet03ea59b2016-03-12 01:25:40 +0100206
207/* Frame descriptor
208
209 1 byte, using :
210 bit 0-3 : windowLog - ZSTD_WINDOWLOG_ABSOLUTEMIN (see zstd_internal.h)
211 bit 4 : minmatch 4(0) or 3(1)
212 bit 5 : reserved (must be zero)
213 bit 6-7 : Frame content size : unknown, 1 byte, 2 bytes, 8 bytes
Yann Colletfb797352016-03-13 11:08:40 +0100214
215 Optional : content size (0, 1, 2 or 8 bytes)
216 0 : unknown
217 1 : 0-255 bytes
218 2 : 256 - 65535+256
219 8 : up to 16 exa
Yann Collet03ea59b2016-03-12 01:25:40 +0100220*/
221
222
223/* Compressed Block, format description
Yann Colletfb810d62016-01-28 00:18:06 +0100224
225 Block = Literal Section - Sequences Section
226 Prerequisite : size of (compressed) block, maximum size of regenerated data
227
Yann Collet59d1f792016-01-23 19:28:41 +0100228 1) Literal Section
Yann Colletfb810d62016-01-28 00:18:06 +0100229
230 1.1) Header : 1-5 bytes
231 flags: 2 bits
Yann Collet59d1f792016-01-23 19:28:41 +0100232 00 compressed by Huff0
Yann Colletfb810d62016-01-28 00:18:06 +0100233 01 unused
234 10 is Raw (uncompressed)
235 11 is Rle
236 Note : using 01 => Huff0 with precomputed table ?
Yann Collet59d1f792016-01-23 19:28:41 +0100237 Note : delta map ? => compressed ?
Yann Colletfb810d62016-01-28 00:18:06 +0100238
239 1.1.1) Huff0-compressed literal block : 3-5 bytes
240 srcSize < 1 KB => 3 bytes (2-2-10-10) => single stream
241 srcSize < 1 KB => 3 bytes (2-2-10-10)
242 srcSize < 16KB => 4 bytes (2-2-14-14)
243 else => 5 bytes (2-2-18-18)
244 big endian convention
245
246 1.1.2) Raw (uncompressed) literal block header : 1-3 bytes
247 size : 5 bits: (IS_RAW<<6) + (0<<4) + size
248 12 bits: (IS_RAW<<6) + (2<<4) + (size>>8)
249 size&255
250 20 bits: (IS_RAW<<6) + (3<<4) + (size>>16)
251 size>>8&255
252 size&255
253
254 1.1.3) Rle (repeated single byte) literal block header : 1-3 bytes
255 size : 5 bits: (IS_RLE<<6) + (0<<4) + size
256 12 bits: (IS_RLE<<6) + (2<<4) + (size>>8)
257 size&255
258 20 bits: (IS_RLE<<6) + (3<<4) + (size>>16)
259 size>>8&255
260 size&255
261
262 1.1.4) Huff0-compressed literal block, using precomputed CTables : 3-5 bytes
263 srcSize < 1 KB => 3 bytes (2-2-10-10) => single stream
264 srcSize < 1 KB => 3 bytes (2-2-10-10)
265 srcSize < 16KB => 4 bytes (2-2-14-14)
266 else => 5 bytes (2-2-18-18)
267 big endian convention
268
269 1- CTable available (stored into workspace ?)
270 2- Small input (fast heuristic ? Full comparison ? depend on clevel ?)
271
272
273 1.2) Literal block content
Yann Collet59d1f792016-01-23 19:28:41 +0100274
275 1.2.1) Huff0 block, using sizes from header
276 See Huff0 format
277
Yann Colletfb810d62016-01-28 00:18:06 +0100278 1.2.2) Huff0 block, using prepared table
Yann Collet59d1f792016-01-23 19:28:41 +0100279
Yann Colletfb810d62016-01-28 00:18:06 +0100280 1.2.3) Raw content
281
282 1.2.4) single byte
283
Yann Collet59d1f792016-01-23 19:28:41 +0100284
285 2) Sequences section
286 TO DO
287*/
288
Yann Collet03ea59b2016-03-12 01:25:40 +0100289static const size_t ZSTD_fcs_fieldSize[4] = { 0, 1, 2, 8 };
Yann Collet59d1f792016-01-23 19:28:41 +0100290
Yann Collet03ea59b2016-03-12 01:25:40 +0100291/** ZSTD_frameHeaderSize() :
292* srcSize must be >= ZSTD_frameHeaderSize_min.
293* @return : size of the Frame Header */
294static size_t ZSTD_frameHeaderSize(const void* src, size_t srcSize)
Yann Collet88fcd292015-11-25 14:42:45 +0100295{
Yann Collet03ea59b2016-03-12 01:25:40 +0100296 U32 fcsId;
297 if (srcSize < ZSTD_frameHeaderSize_min) return ERROR(srcSize_wrong);
298 fcsId = (((const BYTE*)src)[4]) >> 6;
299 return ZSTD_frameHeaderSize_min + ZSTD_fcs_fieldSize[fcsId];
Yann Collet88fcd292015-11-25 14:42:45 +0100300}
301
Yann Collet88fcd292015-11-25 14:42:45 +0100302
Yann Collet03ea59b2016-03-12 01:25:40 +0100303/** ZSTD_getFrameParams() :
304* decode Frame Header, or provide expected `srcSize`.
305* @return : 0, `fparamsPtr` is correctly filled,
Yann Collet1c2c2bc2016-03-15 01:33:36 +0100306* >0, `srcSize` is too small, result is expected `srcSize`,
Yann Collet03ea59b2016-03-12 01:25:40 +0100307* or an error code, which can be tested using ZSTD_isError() */
Yann Collet09b21ee2016-03-15 12:56:03 +0100308size_t ZSTD_getFrameParams(ZSTD_frameParams* fparamsPtr, const void* src, size_t srcSize)
Yann Collet88fcd292015-11-25 14:42:45 +0100309{
Yann Collet03ea59b2016-03-12 01:25:40 +0100310 const BYTE* ip = (const BYTE*)src;
Yann Collet03ea59b2016-03-12 01:25:40 +0100311
312 if (srcSize < ZSTD_frameHeaderSize_min) return ZSTD_frameHeaderSize_min;
Yann Colletd1b26842016-03-15 01:24:33 +0100313 if (MEM_readLE32(src) != ZSTD_MAGICNUMBER) return ERROR(prefix_unknown);
Yann Collet03ea59b2016-03-12 01:25:40 +0100314
Yann Collet1c2c2bc2016-03-15 01:33:36 +0100315 /* ensure there is enough `srcSize` to fully read/decode frame header */
Yann Colletd1b26842016-03-15 01:24:33 +0100316 { size_t const fhsize = ZSTD_frameHeaderSize(src, srcSize);
Yann Collet03ea59b2016-03-12 01:25:40 +0100317 if (srcSize < fhsize) return fhsize; }
318
Yann Collet0e491c02016-03-11 21:58:04 +0100319 memset(fparamsPtr, 0, sizeof(*fparamsPtr));
Yann Collet1c2c2bc2016-03-15 01:33:36 +0100320 { BYTE const frameDesc = ip[4];
321 fparamsPtr->windowLog = (frameDesc & 0xF) + ZSTD_WINDOWLOG_ABSOLUTEMIN;
322 fparamsPtr->mml = (frameDesc & 0x10) ? MINMATCH-1 : MINMATCH;
323 if ((frameDesc & 0x20) != 0) return ERROR(frameParameter_unsupported); /* reserved 1 bit */
324 switch(frameDesc >> 6) /* fcsId */
325 {
326 default: /* impossible */
327 case 0 : fparamsPtr->frameContentSize = 0; break;
328 case 1 : fparamsPtr->frameContentSize = ip[5]; break;
329 case 2 : fparamsPtr->frameContentSize = MEM_readLE16(ip+5)+256; break;
330 case 3 : fparamsPtr->frameContentSize = MEM_readLE64(ip+5); break;
331 } }
Yann Collet88fcd292015-11-25 14:42:45 +0100332 return 0;
333}
334
Yann Collet03ea59b2016-03-12 01:25:40 +0100335
336/** ZSTD_decodeFrameHeader() :
Yann Collet1c2c2bc2016-03-15 01:33:36 +0100337* `srcSize` must be the size provided by ZSTD_frameHeaderSize().
Yann Collet26415d32015-11-26 12:43:28 +0100338* @return : 0, or an error code, which can be tested using ZSTD_isError() */
Yann Collet03ea59b2016-03-12 01:25:40 +0100339static size_t ZSTD_decodeFrameHeader(ZSTD_DCtx* zc, const void* src, size_t srcSize)
Yann Collet26415d32015-11-26 12:43:28 +0100340{
Yann Collet03ea59b2016-03-12 01:25:40 +0100341 size_t result = ZSTD_getFrameParams(&(zc->fParams), src, srcSize);
Yann Collet0e491c02016-03-11 21:58:04 +0100342 if ((MEM_32bits()) && (zc->fParams.windowLog > 25)) return ERROR(frameParameter_unsupportedBy32bits);
Yann Collet00fd7a22015-11-28 16:03:22 +0100343 return result;
Yann Collet26415d32015-11-26 12:43:28 +0100344}
345
Yann Collet5be2dd22015-11-11 13:43:58 +0100346
347size_t ZSTD_getcBlockSize(const void* src, size_t srcSize, blockProperties_t* bpPtr)
348{
349 const BYTE* const in = (const BYTE* const)src;
350 BYTE headerFlags;
351 U32 cSize;
352
Yann Collet61e16ce2016-01-31 02:04:15 +0100353 if (srcSize < 3)
354 return ERROR(srcSize_wrong);
Yann Collet5be2dd22015-11-11 13:43:58 +0100355
356 headerFlags = *in;
357 cSize = in[2] + (in[1]<<8) + ((in[0] & 7)<<16);
358
359 bpPtr->blockType = (blockType_t)(headerFlags >> 6);
360 bpPtr->origSize = (bpPtr->blockType == bt_rle) ? cSize : 0;
361
362 if (bpPtr->blockType == bt_end) return 0;
363 if (bpPtr->blockType == bt_rle) return 1;
364 return cSize;
365}
366
Yann Collet59d1f792016-01-23 19:28:41 +0100367
Yann Collet0f366c62015-11-12 16:19:30 +0100368static size_t ZSTD_copyRawBlock(void* dst, size_t maxDstSize, const void* src, size_t srcSize)
Yann Collet5be2dd22015-11-11 13:43:58 +0100369{
370 if (srcSize > maxDstSize) return ERROR(dstSize_tooSmall);
371 memcpy(dst, src, srcSize);
372 return srcSize;
373}
374
375
Yann Collet953ce722016-02-04 15:28:14 +0100376/*! ZSTD_decodeLiteralsBlock() :
Yann Collet14983e72015-11-11 21:38:21 +0100377 @return : nb of bytes read from src (< srcSize ) */
Yann Collet5b78d2f2015-11-12 15:36:05 +0100378size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx,
Yann Collet5be2dd22015-11-11 13:43:58 +0100379 const void* src, size_t srcSize) /* note : srcSize < BLOCKSIZE */
380{
Yann Collet5be2dd22015-11-11 13:43:58 +0100381 const BYTE* const istart = (const BYTE*) src;
382
383 /* any compressed block with literals segment must be at least this size */
384 if (srcSize < MIN_CBLOCK_SIZE) return ERROR(corruption_detected);
385
Yann Collet59d1f792016-01-23 19:28:41 +0100386 switch(istart[0]>> 6)
Yann Collet5be2dd22015-11-11 13:43:58 +0100387 {
Yann Collet59d1f792016-01-23 19:28:41 +0100388 case IS_HUF:
Yann Collet5be2dd22015-11-11 13:43:58 +0100389 {
Yann Colletafe07092016-01-25 04:10:46 +0100390 size_t litSize, litCSize, singleStream=0;
Yann Collet59d1f792016-01-23 19:28:41 +0100391 U32 lhSize = ((istart[0]) >> 4) & 3;
392 switch(lhSize)
393 {
394 case 0: case 1: default: /* note : default is impossible, since lhSize into [0..3] */
395 /* 2 - 2 - 10 - 10 */
396 lhSize=3;
Yann Colletafe07092016-01-25 04:10:46 +0100397 singleStream = istart[0] & 16;
Yann Collet59d1f792016-01-23 19:28:41 +0100398 litSize = ((istart[0] & 15) << 6) + (istart[1] >> 2);
399 litCSize = ((istart[1] & 3) << 8) + istart[2];
400 break;
401 case 2:
402 /* 2 - 2 - 14 - 14 */
403 lhSize=4;
404 litSize = ((istart[0] & 15) << 10) + (istart[1] << 2) + (istart[2] >> 6);
405 litCSize = ((istart[2] & 63) << 8) + istart[3];
406 break;
407 case 3:
408 /* 2 - 2 - 18 - 18 */
409 lhSize=5;
410 litSize = ((istart[0] & 15) << 14) + (istart[1] << 6) + (istart[2] >> 2);
411 litCSize = ((istart[2] & 3) << 16) + (istart[3] << 8) + istart[4];
412 break;
413 }
Yann Collet569b81a2016-03-16 15:26:51 +0100414 if (litSize > ZSTD_BLOCKSIZE_MAX) return ERROR(corruption_detected);
Yann Collet59d1f792016-01-23 19:28:41 +0100415
Yann Colletafe07092016-01-25 04:10:46 +0100416 if (HUF_isError(singleStream ?
417 HUF_decompress1X2(dctx->litBuffer, litSize, istart+lhSize, litCSize) :
418 HUF_decompress (dctx->litBuffer, litSize, istart+lhSize, litCSize) ))
Yann Collet59d1f792016-01-23 19:28:41 +0100419 return ERROR(corruption_detected);
420
Yann Collet5be2dd22015-11-11 13:43:58 +0100421 dctx->litPtr = dctx->litBuffer;
Yann Collet569b81a2016-03-16 15:26:51 +0100422 dctx->litBufSize = ZSTD_BLOCKSIZE_MAX+8;
Yann Collet5be2dd22015-11-11 13:43:58 +0100423 dctx->litSize = litSize;
Yann Collet59d1f792016-01-23 19:28:41 +0100424 return litCSize + lhSize;
Yann Collet5be2dd22015-11-11 13:43:58 +0100425 }
Yann Colletb923f652016-01-26 03:14:20 +0100426 case IS_PCH:
427 {
428 size_t errorCode;
429 size_t litSize, litCSize;
430 U32 lhSize = ((istart[0]) >> 4) & 3;
431 if (lhSize != 1) /* only case supported for now : small litSize, single stream */
432 return ERROR(corruption_detected);
Yann Colletfb810d62016-01-28 00:18:06 +0100433 if (!dctx->flagStaticTables)
Yann Collet7b51a292016-01-26 15:58:49 +0100434 return ERROR(dictionary_corrupted);
Yann Colletb923f652016-01-26 03:14:20 +0100435
436 /* 2 - 2 - 10 - 10 */
437 lhSize=3;
438 litSize = ((istart[0] & 15) << 6) + (istart[1] >> 2);
439 litCSize = ((istart[1] & 3) << 8) + istart[2];
440
441 errorCode = HUF_decompress1X4_usingDTable(dctx->litBuffer, litSize, istart+lhSize, litCSize, dctx->hufTableX4);
442 if (HUF_isError(errorCode)) return ERROR(corruption_detected);
443
444 dctx->litPtr = dctx->litBuffer;
Yann Collet569b81a2016-03-16 15:26:51 +0100445 dctx->litBufSize = ZSTD_BLOCKSIZE_MAX+WILDCOPY_OVERLENGTH;
Yann Colletb923f652016-01-26 03:14:20 +0100446 dctx->litSize = litSize;
447 return litCSize + lhSize;
448 }
Yann Collet5be2dd22015-11-11 13:43:58 +0100449 case IS_RAW:
450 {
Yann Collet59d1f792016-01-23 19:28:41 +0100451 size_t litSize;
452 U32 lhSize = ((istart[0]) >> 4) & 3;
453 switch(lhSize)
Yann Collet5be2dd22015-11-11 13:43:58 +0100454 {
Yann Collet59d1f792016-01-23 19:28:41 +0100455 case 0: case 1: default: /* note : default is impossible, since lhSize into [0..3] */
456 lhSize=1;
457 litSize = istart[0] & 31;
458 break;
459 case 2:
460 litSize = ((istart[0] & 15) << 8) + istart[1];
461 break;
462 case 3:
463 litSize = ((istart[0] & 15) << 16) + (istart[1] << 8) + istart[2];
464 break;
465 }
466
Yann Collet61e16ce2016-01-31 02:04:15 +0100467 if (lhSize+litSize+WILDCOPY_OVERLENGTH > srcSize) { /* risk reading beyond src buffer with wildcopy */
Yann Colletb010b3b2016-02-03 12:39:34 +0100468 if (litSize+lhSize > srcSize) return ERROR(corruption_detected);
Yann Collet59d1f792016-01-23 19:28:41 +0100469 memcpy(dctx->litBuffer, istart+lhSize, litSize);
Yann Collet5be2dd22015-11-11 13:43:58 +0100470 dctx->litPtr = dctx->litBuffer;
Yann Collet569b81a2016-03-16 15:26:51 +0100471 dctx->litBufSize = ZSTD_BLOCKSIZE_MAX+8;
Yann Collet5be2dd22015-11-11 13:43:58 +0100472 dctx->litSize = litSize;
Yann Colletbc4c8aa2016-01-25 17:26:01 +0100473 return lhSize+litSize;
Yann Collet5be2dd22015-11-11 13:43:58 +0100474 }
475 /* direct reference into compressed stream */
Yann Collet59d1f792016-01-23 19:28:41 +0100476 dctx->litPtr = istart+lhSize;
477 dctx->litBufSize = srcSize-lhSize;
Yann Collet5be2dd22015-11-11 13:43:58 +0100478 dctx->litSize = litSize;
Yann Collet59d1f792016-01-23 19:28:41 +0100479 return lhSize+litSize;
480 }
Yann Collet5be2dd22015-11-11 13:43:58 +0100481 case IS_RLE:
482 {
Yann Collet59d1f792016-01-23 19:28:41 +0100483 size_t litSize;
484 U32 lhSize = ((istart[0]) >> 4) & 3;
485 switch(lhSize)
486 {
487 case 0: case 1: default: /* note : default is impossible, since lhSize into [0..3] */
488 lhSize = 1;
489 litSize = istart[0] & 31;
490 break;
491 case 2:
492 litSize = ((istart[0] & 15) << 8) + istart[1];
493 break;
494 case 3:
495 litSize = ((istart[0] & 15) << 16) + (istart[1] << 8) + istart[2];
496 break;
497 }
Yann Collet569b81a2016-03-16 15:26:51 +0100498 if (litSize > ZSTD_BLOCKSIZE_MAX) return ERROR(corruption_detected);
Yann Collet59d1f792016-01-23 19:28:41 +0100499 memset(dctx->litBuffer, istart[lhSize], litSize);
Yann Collet5be2dd22015-11-11 13:43:58 +0100500 dctx->litPtr = dctx->litBuffer;
Yann Collet569b81a2016-03-16 15:26:51 +0100501 dctx->litBufSize = ZSTD_BLOCKSIZE_MAX+WILDCOPY_OVERLENGTH;
Yann Collet5be2dd22015-11-11 13:43:58 +0100502 dctx->litSize = litSize;
Yann Collet59d1f792016-01-23 19:28:41 +0100503 return lhSize+1;
Yann Collet5be2dd22015-11-11 13:43:58 +0100504 }
Yann Colletb923f652016-01-26 03:14:20 +0100505 default:
506 return ERROR(corruption_detected); /* impossible */
Yann Collet5be2dd22015-11-11 13:43:58 +0100507 }
508}
509
510
Yann Collet4db09ef2016-03-18 22:23:49 +0100511/*! ZSTD_buildSeqTable() :
512 @return : nb bytes read from src,
513 or an error code if it fails, testable with ZSTD_isError()
514*/
515static size_t ZSTD_buildSeqTable(FSE_DTable* DTable, U32 type, U32 rawBits, U32 maxLog,
516 const void* src, size_t srcSize)
517{
518 switch(type)
519 {
520 case FSE_ENCODING_RLE :
521 if (!srcSize) return ERROR(srcSize_wrong);
522 FSE_buildDTable_rle(DTable, *(const BYTE*)src);
523 return 1;
524 case FSE_ENCODING_RAW :
525 FSE_buildDTable_raw(DTable, rawBits);
526 return 0;
527 case FSE_ENCODING_STATIC:
528 return 0;
529 default : /* impossible */
530 case FSE_ENCODING_DYNAMIC :
531 { U32 tableLog, max = (1<<rawBits)-1;
532 S16 norm[MaxSeq+1];
533 size_t const headerSize = FSE_readNCount(norm, &max, &tableLog, src, srcSize);
534 if (FSE_isError(headerSize)) return ERROR(GENERIC);
535 if (tableLog > maxLog) return ERROR(corruption_detected);
536 FSE_buildDTable(DTable, norm, max, tableLog);
537 return headerSize;
538 } }
539}
540
541
542
543
Yann Collet5be2dd22015-11-11 13:43:58 +0100544size_t ZSTD_decodeSeqHeaders(int* nbSeq, const BYTE** dumpsPtr, size_t* dumpsLengthPtr,
545 FSE_DTable* DTableLL, FSE_DTable* DTableML, FSE_DTable* DTableOffb,
546 const void* src, size_t srcSize)
547{
548 const BYTE* const istart = (const BYTE* const)src;
549 const BYTE* ip = istart;
550 const BYTE* const iend = istart + srcSize;
551 U32 LLtype, Offtype, MLtype;
Yann Collet5be2dd22015-11-11 13:43:58 +0100552
553 /* check */
Yann Collet4db09ef2016-03-18 22:23:49 +0100554 if (srcSize < MIN_SEQUENCES_SIZE) return ERROR(srcSize_wrong);
Yann Collet5be2dd22015-11-11 13:43:58 +0100555
556 /* SeqHead */
Yann Collet61e16ce2016-01-31 02:04:15 +0100557 *nbSeq = *ip++;
558 if (*nbSeq==0) return 1;
Yann Colletd409db62016-03-04 14:45:31 +0100559 if (*nbSeq >= 0x7F) {
560 if (*nbSeq == 0xFF)
561 *nbSeq = MEM_readLE16(ip) + LONGNBSEQ, ip+=2;
562 else
563 *nbSeq = ((nbSeq[0]-0x80)<<8) + *ip++;
564 }
Yann Collete93d6ce2016-01-31 00:58:06 +0100565
Yann Colletd409db62016-03-04 14:45:31 +0100566 /* FSE table descriptors */
Yann Collet5be2dd22015-11-11 13:43:58 +0100567 LLtype = *ip >> 6;
568 Offtype = (*ip >> 4) & 3;
569 MLtype = (*ip >> 2) & 3;
Yann Collet4db09ef2016-03-18 22:23:49 +0100570 { size_t dumpsLength;
571 if (*ip & 2) {
572 dumpsLength = ip[2];
573 dumpsLength += ip[1] << 8;
574 ip += 3;
575 } else {
576 dumpsLength = ip[1];
577 dumpsLength += (ip[0] & 1) << 8;
578 ip += 2;
579 }
580 *dumpsPtr = ip;
581 ip += dumpsLength;
582 *dumpsLengthPtr = dumpsLength;
Yann Collet5be2dd22015-11-11 13:43:58 +0100583 }
Yann Collet5be2dd22015-11-11 13:43:58 +0100584
585 /* check */
586 if (ip > iend-3) return ERROR(srcSize_wrong); /* min : all 3 are "raw", hence no header, but at least xxLog bits per type */
587
Yann Collet39c596c2016-03-18 21:40:56 +0100588 /* Build DTables */
Yann Collet4db09ef2016-03-18 22:23:49 +0100589 { size_t const bhSize = ZSTD_buildSeqTable(DTableLL, LLtype, LLbits, LLFSELog, ip, iend-ip);
590 if (ZSTD_isError(bhSize)) return ERROR(corruption_detected);
591 ip += bhSize;
592 }
593 { size_t const bhSize = ZSTD_buildSeqTable(DTableOffb, Offtype, Offbits, OffFSELog, ip, iend-ip);
594 if (ZSTD_isError(bhSize)) return ERROR(corruption_detected);
595 ip += bhSize;
596 }
597 { size_t const bhSize = ZSTD_buildSeqTable(DTableML, MLtype, MLbits, MLFSELog, ip, iend-ip);
598 if (ZSTD_isError(bhSize)) return ERROR(corruption_detected);
599 ip += bhSize;
600 }
Yann Collet5be2dd22015-11-11 13:43:58 +0100601
602 return ip-istart;
603}
604
605
606typedef struct {
607 size_t litLength;
Yann Collet5be2dd22015-11-11 13:43:58 +0100608 size_t matchLength;
Yann Collete93d6ce2016-01-31 00:58:06 +0100609 size_t offset;
Yann Collet5be2dd22015-11-11 13:43:58 +0100610} seq_t;
611
612typedef struct {
613 BIT_DStream_t DStream;
614 FSE_DState_t stateLL;
615 FSE_DState_t stateOffb;
616 FSE_DState_t stateML;
617 size_t prevOffset;
618 const BYTE* dumps;
619 const BYTE* dumpsEnd;
620} seqState_t;
621
inikepe9f30ea2016-02-03 12:53:07 +0100622
623
inikep6b3739c2016-02-22 15:53:42 +0100624static void ZSTD_decodeSequence(seq_t* seq, seqState_t* seqState, const U32 mls)
Yann Collet5be2dd22015-11-11 13:43:58 +0100625{
Yann Collet5be2dd22015-11-11 13:43:58 +0100626 const BYTE* dumps = seqState->dumps;
627 const BYTE* const de = seqState->dumpsEnd;
Yann Collet3fd164e2016-03-17 12:56:46 +0100628 size_t litLength, offset;
Yann Collet5be2dd22015-11-11 13:43:58 +0100629
630 /* Literal length */
Yann Collete93d6ce2016-01-31 00:58:06 +0100631 litLength = FSE_peakSymbol(&(seqState->stateLL));
Yann Colletfb810d62016-01-28 00:18:06 +0100632 if (litLength == MaxLL) {
Yann Collet3fd164e2016-03-17 12:56:46 +0100633 const U32 add = *dumps++;
Yann Collet5be2dd22015-11-11 13:43:58 +0100634 if (add < 255) litLength += add;
Yann Colletfb810d62016-01-28 00:18:06 +0100635 else {
Yann Collet7d8e6bd2016-02-02 17:30:37 +0100636 litLength = MEM_readLE32(dumps) & 0xFFFFFF; /* no risk : dumps is always followed by seq tables > 1 byte */
637 if (litLength&1) litLength>>=1, dumps += 3;
638 else litLength = (U16)(litLength)>>1, dumps += 2;
Yann Collet5be2dd22015-11-11 13:43:58 +0100639 }
640 if (dumps >= de) dumps = de-1; /* late correction, to avoid read overflow (data is now corrupted anyway) */
641 }
642
643 /* Offset */
644 {
645 static const U32 offsetPrefix[MaxOff+1] = {
Yann Collet95cd0c22016-03-08 18:24:21 +0100646 1 /*fake*/, 1, 2, 4, 8, 0x10, 0x20, 0x40, 0x80, 0x100,
647 0x200, 0x400, 0x800, 0x1000, 0x2000, 0x4000, 0x8000, 0x10000, 0x20000, 0x40000,
648 0x80000, 0x100000, 0x200000, 0x400000, 0x800000, 0x1000000, 0x2000000, 0x4000000, /*fake*/ 1, 1, 1, 1 };
Yann Collet3fd164e2016-03-17 12:56:46 +0100649 const U32 offsetCode = FSE_peakSymbol(&(seqState->stateOffb)); /* <= maxOff, by table construction */
650 const U32 nbBits = offsetCode ? offsetCode-1 : 0;
Yann Collet5be2dd22015-11-11 13:43:58 +0100651 offset = offsetPrefix[offsetCode] + BIT_readBits(&(seqState->DStream), nbBits);
652 if (MEM_32bits()) BIT_reloadDStream(&(seqState->DStream));
Yann Colletb40287a2016-03-17 12:11:16 +0100653 if (offsetCode==0) offset = litLength ? seq->offset : seqState->prevOffset;
Yann Collet55aa7f92015-11-20 12:04:52 +0100654 if (offsetCode | !litLength) seqState->prevOffset = seq->offset; /* cmove */
Yann Collete93d6ce2016-01-31 00:58:06 +0100655 FSE_decodeSymbol(&(seqState->stateOffb), &(seqState->DStream)); /* update */
Yann Collet5be2dd22015-11-11 13:43:58 +0100656 }
657
Yann Collete93d6ce2016-01-31 00:58:06 +0100658 /* Literal length update */
659 FSE_decodeSymbol(&(seqState->stateLL), &(seqState->DStream)); /* update */
660 if (MEM_32bits()) BIT_reloadDStream(&(seqState->DStream));
661
Yann Collet5be2dd22015-11-11 13:43:58 +0100662 /* MatchLength */
Yann Collet3fd164e2016-03-17 12:56:46 +0100663 {
664 size_t matchLength = FSE_decodeSymbol(&(seqState->stateML), &(seqState->DStream));
665 if (matchLength == MaxML) {
666 const U32 add = *dumps++;
667 if (add < 255) matchLength += add;
668 else {
669 matchLength = MEM_readLE32(dumps) & 0xFFFFFF; /* no pb : dumps is always followed by seq tables > 1 byte */
670 if (matchLength&1) matchLength>>=1, dumps += 3;
671 else matchLength = (U16)(matchLength)>>1, dumps += 2;
672 }
673 if (dumps >= de) dumps = de-1; /* late correction, to avoid read overflow (data is now corrupted anyway) */
Yann Collet5be2dd22015-11-11 13:43:58 +0100674 }
Yann Collet3fd164e2016-03-17 12:56:46 +0100675 matchLength += mls;
676 seq->matchLength = matchLength;
Yann Collet5be2dd22015-11-11 13:43:58 +0100677 }
Yann Collet5be2dd22015-11-11 13:43:58 +0100678
679 /* save result */
680 seq->litLength = litLength;
681 seq->offset = offset;
Yann Collet5be2dd22015-11-11 13:43:58 +0100682 seqState->dumps = dumps;
Yann Colletfb810d62016-01-28 00:18:06 +0100683
Yann Collet7d8e6bd2016-02-02 17:30:37 +0100684#if 0 /* debug */
Yann Colletfb810d62016-01-28 00:18:06 +0100685 {
686 static U64 totalDecoded = 0;
687 printf("pos %6u : %3u literals & match %3u bytes at distance %6u \n",
688 (U32)(totalDecoded), (U32)litLength, (U32)matchLength, (U32)offset);
689 totalDecoded += litLength + matchLength;
690 }
691#endif
Yann Collet5be2dd22015-11-11 13:43:58 +0100692}
693
694
Yann Collet5b78d2f2015-11-12 15:36:05 +0100695FORCE_INLINE size_t ZSTD_execSequence(BYTE* op,
Yann Colletb3a2af92015-11-19 17:13:19 +0100696 BYTE* const oend, seq_t sequence,
Yann Collet5be2dd22015-11-11 13:43:58 +0100697 const BYTE** litPtr, const BYTE* const litLimit_8,
Yann Collet417890c2015-12-04 17:16:37 +0100698 const BYTE* const base, const BYTE* const vBase, const BYTE* const dictEnd)
Yann Collet5be2dd22015-11-11 13:43:58 +0100699{
Yann Colletb3a2af92015-11-19 17:13:19 +0100700 static const int dec32table[] = { 0, 1, 2, 1, 4, 4, 4, 4 }; /* added */
701 static const int dec64table[] = { 8, 8, 8, 7, 8, 9,10,11 }; /* substracted */
Yann Collet5be2dd22015-11-11 13:43:58 +0100702 BYTE* const oLitEnd = op + sequence.litLength;
Yann Colletb3a2af92015-11-19 17:13:19 +0100703 const size_t sequenceLength = sequence.litLength + sequence.matchLength;
704 BYTE* const oMatchEnd = op + sequenceLength; /* risk : address space overflow (32-bits) */
Yann Collet5be2dd22015-11-11 13:43:58 +0100705 BYTE* const oend_8 = oend-8;
706 const BYTE* const litEnd = *litPtr + sequence.litLength;
Yann Colletb3a2af92015-11-19 17:13:19 +0100707 const BYTE* match = oLitEnd - sequence.offset;
Yann Collet5be2dd22015-11-11 13:43:58 +0100708
709 /* check */
710 if (oLitEnd > oend_8) return ERROR(dstSize_tooSmall); /* last match must start at a minimum distance of 8 from oend */
711 if (oMatchEnd > oend) return ERROR(dstSize_tooSmall); /* overwrite beyond dst buffer */
712 if (litEnd > litLimit_8) return ERROR(corruption_detected); /* risk read beyond lit buffer */
713
714 /* copy Literals */
715 ZSTD_wildcopy(op, *litPtr, sequence.litLength); /* note : oLitEnd <= oend-8 : no risk of overwrite beyond oend */
716 op = oLitEnd;
717 *litPtr = litEnd; /* update for next sequence */
718
719 /* copy Match */
Yann Collet7b51a292016-01-26 15:58:49 +0100720 if (sequence.offset > (size_t)(oLitEnd - base)) {
Yann Collet44287a32015-11-30 23:13:56 +0100721 /* offset beyond prefix */
Yann Collet9f5ab1a2015-12-11 00:27:41 +0100722 if (sequence.offset > (size_t)(oLitEnd - vBase))
723 return ERROR(corruption_detected);
Yann Collet44287a32015-11-30 23:13:56 +0100724 match = dictEnd - (base-match);
Yann Collet7b51a292016-01-26 15:58:49 +0100725 if (match + sequence.matchLength <= dictEnd) {
Yann Collet4bfe4152015-12-06 13:18:37 +0100726 memmove(oLitEnd, match, sequence.matchLength);
Yann Collet44287a32015-11-30 23:13:56 +0100727 return sequenceLength;
728 }
729 /* span extDict & currentPrefixSegment */
730 {
731 size_t length1 = dictEnd - match;
Yann Collet4bfe4152015-12-06 13:18:37 +0100732 memmove(oLitEnd, match, length1);
Yann Collet44287a32015-11-30 23:13:56 +0100733 op = oLitEnd + length1;
734 sequence.matchLength -= length1;
735 match = base;
Yann Colletfb810d62016-01-28 00:18:06 +0100736 } }
Yann Collet0f366c62015-11-12 16:19:30 +0100737
Yann Collet44287a32015-11-30 23:13:56 +0100738 /* match within prefix */
Yann Collet7b51a292016-01-26 15:58:49 +0100739 if (sequence.offset < 8) {
Yann Collet44287a32015-11-30 23:13:56 +0100740 /* close range match, overlap */
741 const int sub2 = dec64table[sequence.offset];
742 op[0] = match[0];
743 op[1] = match[1];
744 op[2] = match[2];
745 op[3] = match[3];
746 match += dec32table[sequence.offset];
747 ZSTD_copy4(op+4, match);
748 match -= sub2;
Yann Colletfb810d62016-01-28 00:18:06 +0100749 } else {
Yann Collet44287a32015-11-30 23:13:56 +0100750 ZSTD_copy8(op, match);
751 }
752 op += 8; match += 8;
Yann Collet5be2dd22015-11-11 13:43:58 +0100753
inikepa4dde252016-03-01 14:14:35 +0100754 if (oMatchEnd > oend-(16-3)) { // 3 = MINMATCH
Yann Collet7b51a292016-01-26 15:58:49 +0100755 if (op < oend_8) {
Yann Collet44287a32015-11-30 23:13:56 +0100756 ZSTD_wildcopy(op, match, oend_8 - op);
757 match += oend_8 - op;
758 op = oend_8;
759 }
Yann Colletfb810d62016-01-28 00:18:06 +0100760 while (op < oMatchEnd)
761 *op++ = *match++;
762 } else {
Yann Collet44287a32015-11-30 23:13:56 +0100763 ZSTD_wildcopy(op, match, sequence.matchLength-8); /* works even if matchLength < 8 */
764 }
765 return sequenceLength;
Yann Collet5be2dd22015-11-11 13:43:58 +0100766}
767
Yann Colletb3a2af92015-11-19 17:13:19 +0100768
Yann Collet5be2dd22015-11-11 13:43:58 +0100769static size_t ZSTD_decompressSequences(
Yann Collet5b78d2f2015-11-12 15:36:05 +0100770 ZSTD_DCtx* dctx,
Yann Collet5be2dd22015-11-11 13:43:58 +0100771 void* dst, size_t maxDstSize,
772 const void* seqStart, size_t seqSize)
773{
Yann Collet5be2dd22015-11-11 13:43:58 +0100774 const BYTE* ip = (const BYTE*)seqStart;
775 const BYTE* const iend = ip + seqSize;
776 BYTE* const ostart = (BYTE* const)dst;
777 BYTE* op = ostart;
778 BYTE* const oend = ostart + maxDstSize;
779 size_t errorCode, dumpsLength;
780 const BYTE* litPtr = dctx->litPtr;
781 const BYTE* const litLimit_8 = litPtr + dctx->litBufSize - 8;
782 const BYTE* const litEnd = litPtr + dctx->litSize;
783 int nbSeq;
784 const BYTE* dumps;
785 U32* DTableLL = dctx->LLTable;
786 U32* DTableML = dctx->MLTable;
787 U32* DTableOffb = dctx->OffTable;
Yann Collet417890c2015-12-04 17:16:37 +0100788 const BYTE* const base = (const BYTE*) (dctx->base);
789 const BYTE* const vBase = (const BYTE*) (dctx->vBase);
790 const BYTE* const dictEnd = (const BYTE*) (dctx->dictEnd);
Yann Collet0e491c02016-03-11 21:58:04 +0100791 const U32 mls = dctx->fParams.mml;
Yann Collet5be2dd22015-11-11 13:43:58 +0100792
793 /* Build Decoding Tables */
794 errorCode = ZSTD_decodeSeqHeaders(&nbSeq, &dumps, &dumpsLength,
795 DTableLL, DTableML, DTableOffb,
Yann Colletfb810d62016-01-28 00:18:06 +0100796 ip, seqSize);
Yann Collet5be2dd22015-11-11 13:43:58 +0100797 if (ZSTD_isError(errorCode)) return errorCode;
798 ip += errorCode;
799
800 /* Regen sequences */
Yann Collete93d6ce2016-01-31 00:58:06 +0100801 if (nbSeq) {
Yann Collet5be2dd22015-11-11 13:43:58 +0100802 seq_t sequence;
803 seqState_t seqState;
804
805 memset(&sequence, 0, sizeof(sequence));
Yann Collet61e16ce2016-01-31 02:04:15 +0100806 sequence.offset = REPCODE_STARTVALUE;
Yann Collet5be2dd22015-11-11 13:43:58 +0100807 seqState.dumps = dumps;
808 seqState.dumpsEnd = dumps + dumpsLength;
Yann Collet61e16ce2016-01-31 02:04:15 +0100809 seqState.prevOffset = REPCODE_STARTVALUE;
Yann Collet5be2dd22015-11-11 13:43:58 +0100810 errorCode = BIT_initDStream(&(seqState.DStream), ip, iend-ip);
811 if (ERR_isError(errorCode)) return ERROR(corruption_detected);
812 FSE_initDState(&(seqState.stateLL), &(seqState.DStream), DTableLL);
813 FSE_initDState(&(seqState.stateOffb), &(seqState.DStream), DTableOffb);
814 FSE_initDState(&(seqState.stateML), &(seqState.DStream), DTableML);
815
Yann Collet7b51a292016-01-26 15:58:49 +0100816 for ( ; (BIT_reloadDStream(&(seqState.DStream)) <= BIT_DStream_completed) && nbSeq ; ) {
Yann Colletb3a2af92015-11-19 17:13:19 +0100817 size_t oneSeqSize;
818 nbSeq--;
inikep6b3739c2016-02-22 15:53:42 +0100819 ZSTD_decodeSequence(&sequence, &seqState, mls);
Yann Colletb3a2af92015-11-19 17:13:19 +0100820 oneSeqSize = ZSTD_execSequence(op, oend, sequence, &litPtr, litLimit_8, base, vBase, dictEnd);
Yann Collet370b08e2016-03-08 00:03:59 +0100821 if (ZSTD_isError(oneSeqSize))
822 return oneSeqSize;
Yann Collet5be2dd22015-11-11 13:43:58 +0100823 op += oneSeqSize;
824 }
825
826 /* check if reached exact end */
Yann Collet35f7de52016-01-31 02:51:03 +0100827 if (nbSeq) return ERROR(corruption_detected);
Yann Collete93d6ce2016-01-31 00:58:06 +0100828 }
Yann Collet5be2dd22015-11-11 13:43:58 +0100829
Yann Collete93d6ce2016-01-31 00:58:06 +0100830 /* last literal segment */
831 {
832 size_t lastLLSize = litEnd - litPtr;
833 if (litPtr > litEnd) return ERROR(corruption_detected); /* too many literals already used */
834 if (op+lastLLSize > oend) return ERROR(dstSize_tooSmall);
835 memcpy(op, litPtr, lastLLSize);
836 op += lastLLSize;
837 }
Yann Collet5be2dd22015-11-11 13:43:58 +0100838
839 return op-ostart;
840}
841
842
Yann Colletb0125102016-01-09 02:00:10 +0100843static void ZSTD_checkContinuity(ZSTD_DCtx* dctx, const void* dst)
844{
Yann Collet7b51a292016-01-26 15:58:49 +0100845 if (dst != dctx->previousDstEnd) { /* not contiguous */
Yann Colletb0125102016-01-09 02:00:10 +0100846 dctx->dictEnd = dctx->previousDstEnd;
847 dctx->vBase = (const char*)dst - ((const char*)(dctx->previousDstEnd) - (const char*)(dctx->base));
848 dctx->base = dst;
849 dctx->previousDstEnd = dst;
850 }
851}
852
853
854static size_t ZSTD_decompressBlock_internal(ZSTD_DCtx* dctx,
Yann Colletb010b3b2016-02-03 12:39:34 +0100855 void* dst, size_t dstCapacity,
Yann Collet5be2dd22015-11-11 13:43:58 +0100856 const void* src, size_t srcSize)
Yann Colletb010b3b2016-02-03 12:39:34 +0100857{ /* blockType == blockCompressed */
Yann Collet5be2dd22015-11-11 13:43:58 +0100858 const BYTE* ip = (const BYTE*)src;
Yann Colletb010b3b2016-02-03 12:39:34 +0100859 size_t litCSize;
860
Yann Collet569b81a2016-03-16 15:26:51 +0100861 if (srcSize >= ZSTD_BLOCKSIZE_MAX) return ERROR(srcSize_wrong);
Yann Collet5be2dd22015-11-11 13:43:58 +0100862
inikepa4dde252016-03-01 14:14:35 +0100863 ZSTD_LOG_BLOCK("%p: ZSTD_decompressBlock_internal searchLength=%d\n", dctx->base, dctx->params.searchLength);
864
Yann Collet5be2dd22015-11-11 13:43:58 +0100865 /* Decode literals sub-block */
Yann Colletb010b3b2016-02-03 12:39:34 +0100866 litCSize = ZSTD_decodeLiteralsBlock(dctx, src, srcSize);
Yann Collet5be2dd22015-11-11 13:43:58 +0100867 if (ZSTD_isError(litCSize)) return litCSize;
868 ip += litCSize;
869 srcSize -= litCSize;
870
Yann Colletb010b3b2016-02-03 12:39:34 +0100871 return ZSTD_decompressSequences(dctx, dst, dstCapacity, ip, srcSize);
Yann Collet5be2dd22015-11-11 13:43:58 +0100872}
873
874
Yann Colletb0125102016-01-09 02:00:10 +0100875size_t ZSTD_decompressBlock(ZSTD_DCtx* dctx,
Yann Colletb010b3b2016-02-03 12:39:34 +0100876 void* dst, size_t dstCapacity,
Yann Colletb0125102016-01-09 02:00:10 +0100877 const void* src, size_t srcSize)
878{
879 ZSTD_checkContinuity(dctx, dst);
Yann Colletb010b3b2016-02-03 12:39:34 +0100880 return ZSTD_decompressBlock_internal(dctx, dst, dstCapacity, src, srcSize);
Yann Colletb0125102016-01-09 02:00:10 +0100881}
882
883
Yann Collet0e491c02016-03-11 21:58:04 +0100884/*! ZSTD_decompress_continueDCtx() :
885* `dctx` must have been properly initialized */
886static size_t ZSTD_decompressFrame(ZSTD_DCtx* dctx,
Yann Collet31683c02015-12-18 01:26:48 +0100887 void* dst, size_t maxDstSize,
Yann Collet7b51a292016-01-26 15:58:49 +0100888 const void* src, size_t srcSize)
Yann Collet5be2dd22015-11-11 13:43:58 +0100889{
890 const BYTE* ip = (const BYTE*)src;
891 const BYTE* iend = ip + srcSize;
892 BYTE* const ostart = (BYTE* const)dst;
893 BYTE* op = ostart;
894 BYTE* const oend = ostart + maxDstSize;
895 size_t remainingSize = srcSize;
Yann Collet5be2dd22015-11-11 13:43:58 +0100896 blockProperties_t blockProperties;
897
898 /* Frame Header */
Yann Collet88fcd292015-11-25 14:42:45 +0100899 {
Yann Collet03ea59b2016-03-12 01:25:40 +0100900 size_t frameHeaderSize, errorCode;
Yann Collet88fcd292015-11-25 14:42:45 +0100901 if (srcSize < ZSTD_frameHeaderSize_min+ZSTD_blockHeaderSize) return ERROR(srcSize_wrong);
Yann Collet5be2dd22015-11-11 13:43:58 +0100902#if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT==1)
Yann Collet88fcd292015-11-25 14:42:45 +0100903 {
904 const U32 magicNumber = MEM_readLE32(src);
905 if (ZSTD_isLegacy(magicNumber))
906 return ZSTD_decompressLegacy(dst, maxDstSize, src, srcSize, magicNumber);
907 }
Yann Collet5be2dd22015-11-11 13:43:58 +0100908#endif
Yann Collet03ea59b2016-03-12 01:25:40 +0100909 frameHeaderSize = ZSTD_frameHeaderSize(src, ZSTD_frameHeaderSize_min);
Yann Collet88fcd292015-11-25 14:42:45 +0100910 if (ZSTD_isError(frameHeaderSize)) return frameHeaderSize;
911 if (srcSize < frameHeaderSize+ZSTD_blockHeaderSize) return ERROR(srcSize_wrong);
Yann Collet03ea59b2016-03-12 01:25:40 +0100912 errorCode = ZSTD_decodeFrameHeader(dctx, src, frameHeaderSize);
913 if (ZSTD_isError(errorCode)) return errorCode;
Yann Collet88fcd292015-11-25 14:42:45 +0100914 ip += frameHeaderSize; remainingSize -= frameHeaderSize;
Yann Collet88fcd292015-11-25 14:42:45 +0100915 }
Yann Collet5be2dd22015-11-11 13:43:58 +0100916
917 /* Loop on each block */
918 while (1)
919 {
920 size_t decodedSize=0;
921 size_t cBlockSize = ZSTD_getcBlockSize(ip, iend-ip, &blockProperties);
922 if (ZSTD_isError(cBlockSize)) return cBlockSize;
923
924 ip += ZSTD_blockHeaderSize;
925 remainingSize -= ZSTD_blockHeaderSize;
926 if (cBlockSize > remainingSize) return ERROR(srcSize_wrong);
927
928 switch(blockProperties.blockType)
929 {
930 case bt_compressed:
Yann Collet37422192016-01-25 16:54:05 +0100931 decodedSize = ZSTD_decompressBlock_internal(dctx, op, oend-op, ip, cBlockSize);
Yann Collet5be2dd22015-11-11 13:43:58 +0100932 break;
933 case bt_raw :
Yann Collet0f366c62015-11-12 16:19:30 +0100934 decodedSize = ZSTD_copyRawBlock(op, oend-op, ip, cBlockSize);
Yann Collet5be2dd22015-11-11 13:43:58 +0100935 break;
936 case bt_rle :
937 return ERROR(GENERIC); /* not yet supported */
938 break;
939 case bt_end :
940 /* end of frame */
941 if (remainingSize) return ERROR(srcSize_wrong);
942 break;
943 default:
944 return ERROR(GENERIC); /* impossible */
945 }
946 if (cBlockSize == 0) break; /* bt_end */
947
948 if (ZSTD_isError(decodedSize)) return decodedSize;
949 op += decodedSize;
950 ip += cBlockSize;
951 remainingSize -= cBlockSize;
952 }
953
954 return op-ostart;
955}
956
Yann Collet31683c02015-12-18 01:26:48 +0100957
Yann Collet7b51a292016-01-26 15:58:49 +0100958size_t ZSTD_decompress_usingPreparedDCtx(ZSTD_DCtx* dctx, const ZSTD_DCtx* refDCtx,
959 void* dst, size_t maxDstSize,
960 const void* src, size_t srcSize)
961{
962 ZSTD_copyDCtx(dctx, refDCtx);
963 ZSTD_checkContinuity(dctx, dst);
Yann Collet0e491c02016-03-11 21:58:04 +0100964 return ZSTD_decompressFrame(dctx, dst, maxDstSize, src, srcSize);
Yann Collet7b51a292016-01-26 15:58:49 +0100965}
966
967
968size_t ZSTD_decompress_usingDict(ZSTD_DCtx* dctx,
969 void* dst, size_t maxDstSize,
970 const void* src, size_t srcSize,
971 const void* dict, size_t dictSize)
972{
973 ZSTD_decompressBegin_usingDict(dctx, dict, dictSize);
inikepa4dde252016-03-01 14:14:35 +0100974 ZSTD_LOG_BLOCK("%p: ZSTD_decompressBegin_usingDict searchLength=%d\n", dctx->base, dctx->params.searchLength);
Yann Collet7b51a292016-01-26 15:58:49 +0100975 ZSTD_checkContinuity(dctx, dst);
Yann Collet0e491c02016-03-11 21:58:04 +0100976 return ZSTD_decompressFrame(dctx, dst, maxDstSize, src, srcSize);
Yann Collet7b51a292016-01-26 15:58:49 +0100977}
978
979
Yann Collet31683c02015-12-18 01:26:48 +0100980size_t ZSTD_decompressDCtx(ZSTD_DCtx* dctx, void* dst, size_t maxDstSize, const void* src, size_t srcSize)
981{
982 return ZSTD_decompress_usingDict(dctx, dst, maxDstSize, src, srcSize, NULL, 0);
983}
984
Yann Collet0e491c02016-03-11 21:58:04 +0100985
Yann Collet5be2dd22015-11-11 13:43:58 +0100986size_t ZSTD_decompress(void* dst, size_t maxDstSize, const void* src, size_t srcSize)
987{
Yann Collet3a3b72f2016-01-11 12:56:11 +0100988#if defined(ZSTD_HEAPMODE) && (ZSTD_HEAPMODE==1)
989 size_t regenSize;
990 ZSTD_DCtx* dctx = ZSTD_createDCtx();
991 if (dctx==NULL) return ERROR(memory_allocation);
992 regenSize = ZSTD_decompressDCtx(dctx, dst, maxDstSize, src, srcSize);
993 ZSTD_freeDCtx(dctx);
994 return regenSize;
995#else
Yann Collet31683c02015-12-18 01:26:48 +0100996 ZSTD_DCtx dctx;
997 return ZSTD_decompressDCtx(&dctx, dst, maxDstSize, src, srcSize);
Yann Colleta768a302016-01-21 16:04:35 +0100998#endif
Yann Collet5be2dd22015-11-11 13:43:58 +0100999}
1000
1001
Yann Collet346bffb2016-03-15 15:24:52 +01001002/*_******************************
Yann Collet5be2dd22015-11-11 13:43:58 +01001003* Streaming Decompression API
1004********************************/
Yann Collet5be2dd22015-11-11 13:43:58 +01001005size_t ZSTD_nextSrcSizeToDecompress(ZSTD_DCtx* dctx)
1006{
1007 return dctx->expected;
1008}
1009
Yann Collet37422192016-01-25 16:54:05 +01001010size_t ZSTD_decompressContinue(ZSTD_DCtx* dctx, void* dst, size_t maxDstSize, const void* src, size_t srcSize)
Yann Collet5be2dd22015-11-11 13:43:58 +01001011{
1012 /* Sanity check */
Yann Collet37422192016-01-25 16:54:05 +01001013 if (srcSize != dctx->expected) return ERROR(srcSize_wrong);
1014 ZSTD_checkContinuity(dctx, dst);
Yann Collet5be2dd22015-11-11 13:43:58 +01001015
Yann Collet88fcd292015-11-25 14:42:45 +01001016 /* Decompress : frame header; part 1 */
Yann Collet37422192016-01-25 16:54:05 +01001017 switch (dctx->stage)
Yann Collet5be2dd22015-11-11 13:43:58 +01001018 {
Yann Collet88fcd292015-11-25 14:42:45 +01001019 case ZSTDds_getFrameHeaderSize :
Yann Collet5be2dd22015-11-11 13:43:58 +01001020 {
Yann Collet88fcd292015-11-25 14:42:45 +01001021 /* get frame header size */
1022 if (srcSize != ZSTD_frameHeaderSize_min) return ERROR(srcSize_wrong); /* impossible */
Yann Collet03ea59b2016-03-12 01:25:40 +01001023 dctx->headerSize = ZSTD_frameHeaderSize(src, ZSTD_frameHeaderSize_min);
Yann Collet37422192016-01-25 16:54:05 +01001024 if (ZSTD_isError(dctx->headerSize)) return dctx->headerSize;
1025 memcpy(dctx->headerBuffer, src, ZSTD_frameHeaderSize_min);
Yann Collet7b51a292016-01-26 15:58:49 +01001026 if (dctx->headerSize > ZSTD_frameHeaderSize_min) {
Yann Collet37422192016-01-25 16:54:05 +01001027 dctx->expected = dctx->headerSize - ZSTD_frameHeaderSize_min;
1028 dctx->stage = ZSTDds_decodeFrameHeader;
Yann Collet88fcd292015-11-25 14:42:45 +01001029 return 0;
1030 }
Yann Collet37422192016-01-25 16:54:05 +01001031 dctx->expected = 0; /* not necessary to copy more */
Yann Collet5be2dd22015-11-11 13:43:58 +01001032 }
Yann Collet88fcd292015-11-25 14:42:45 +01001033 case ZSTDds_decodeFrameHeader:
Yann Collet5be2dd22015-11-11 13:43:58 +01001034 {
Yann Collet88fcd292015-11-25 14:42:45 +01001035 /* get frame header */
1036 size_t result;
Yann Collet37422192016-01-25 16:54:05 +01001037 memcpy(dctx->headerBuffer + ZSTD_frameHeaderSize_min, src, dctx->expected);
Yann Collet03ea59b2016-03-12 01:25:40 +01001038 result = ZSTD_decodeFrameHeader(dctx, dctx->headerBuffer, dctx->headerSize);
Yann Collet88fcd292015-11-25 14:42:45 +01001039 if (ZSTD_isError(result)) return result;
Yann Collet37422192016-01-25 16:54:05 +01001040 dctx->expected = ZSTD_blockHeaderSize;
1041 dctx->stage = ZSTDds_decodeBlockHeader;
Yann Collet88fcd292015-11-25 14:42:45 +01001042 return 0;
Yann Collet5be2dd22015-11-11 13:43:58 +01001043 }
Yann Collet88fcd292015-11-25 14:42:45 +01001044 case ZSTDds_decodeBlockHeader:
Yann Collet5be2dd22015-11-11 13:43:58 +01001045 {
Yann Collet88fcd292015-11-25 14:42:45 +01001046 /* Decode block header */
1047 blockProperties_t bp;
1048 size_t blockSize = ZSTD_getcBlockSize(src, ZSTD_blockHeaderSize, &bp);
1049 if (ZSTD_isError(blockSize)) return blockSize;
Yann Collet7b51a292016-01-26 15:58:49 +01001050 if (bp.blockType == bt_end) {
Yann Collet37422192016-01-25 16:54:05 +01001051 dctx->expected = 0;
1052 dctx->stage = ZSTDds_getFrameHeaderSize;
Yann Collet88fcd292015-11-25 14:42:45 +01001053 }
Yann Collet7b51a292016-01-26 15:58:49 +01001054 else {
Yann Collet37422192016-01-25 16:54:05 +01001055 dctx->expected = blockSize;
1056 dctx->bType = bp.blockType;
1057 dctx->stage = ZSTDds_decompressBlock;
Yann Collet88fcd292015-11-25 14:42:45 +01001058 }
Yann Collet88fcd292015-11-25 14:42:45 +01001059 return 0;
1060 }
Yann Collet417890c2015-12-04 17:16:37 +01001061 case ZSTDds_decompressBlock:
Yann Collet88fcd292015-11-25 14:42:45 +01001062 {
1063 /* Decompress : block content */
1064 size_t rSize;
Yann Collet37422192016-01-25 16:54:05 +01001065 switch(dctx->bType)
Yann Collet88fcd292015-11-25 14:42:45 +01001066 {
1067 case bt_compressed:
Yann Collet37422192016-01-25 16:54:05 +01001068 rSize = ZSTD_decompressBlock_internal(dctx, dst, maxDstSize, src, srcSize);
Yann Collet88fcd292015-11-25 14:42:45 +01001069 break;
1070 case bt_raw :
1071 rSize = ZSTD_copyRawBlock(dst, maxDstSize, src, srcSize);
1072 break;
1073 case bt_rle :
1074 return ERROR(GENERIC); /* not yet handled */
1075 break;
1076 case bt_end : /* should never happen (filtered at phase 1) */
1077 rSize = 0;
1078 break;
1079 default:
Yann Collet7b51a292016-01-26 15:58:49 +01001080 return ERROR(GENERIC); /* impossible */
Yann Collet88fcd292015-11-25 14:42:45 +01001081 }
Yann Collet37422192016-01-25 16:54:05 +01001082 dctx->stage = ZSTDds_decodeBlockHeader;
1083 dctx->expected = ZSTD_blockHeaderSize;
1084 dctx->previousDstEnd = (char*)dst + rSize;
Yann Collet88fcd292015-11-25 14:42:45 +01001085 return rSize;
1086 }
1087 default:
1088 return ERROR(GENERIC); /* impossible */
1089 }
Yann Collet5be2dd22015-11-11 13:43:58 +01001090}
1091
1092
Yann Colletb923f652016-01-26 03:14:20 +01001093static void ZSTD_refDictContent(ZSTD_DCtx* dctx, const void* dict, size_t dictSize)
Yann Collet417890c2015-12-04 17:16:37 +01001094{
Yann Collet37422192016-01-25 16:54:05 +01001095 dctx->dictEnd = dctx->previousDstEnd;
1096 dctx->vBase = (const char*)dict - ((const char*)(dctx->previousDstEnd) - (const char*)(dctx->base));
1097 dctx->base = dict;
1098 dctx->previousDstEnd = (const char*)dict + dictSize;
Yann Collet417890c2015-12-04 17:16:37 +01001099}
Yann Colletb923f652016-01-26 03:14:20 +01001100
Yann Colletb923f652016-01-26 03:14:20 +01001101static size_t ZSTD_loadEntropy(ZSTD_DCtx* dctx, const void* dict, size_t dictSize)
1102{
Yann Colletfb810d62016-01-28 00:18:06 +01001103 size_t hSize, offcodeHeaderSize, matchlengthHeaderSize, errorCode, litlengthHeaderSize;
1104 short offcodeNCount[MaxOff+1];
1105 U32 offcodeMaxValue=MaxOff, offcodeLog=OffFSELog;
1106 short matchlengthNCount[MaxML+1];
1107 unsigned matchlengthMaxValue = MaxML, matchlengthLog = MLFSELog;
1108 short litlengthNCount[MaxLL+1];
1109 unsigned litlengthMaxValue = MaxLL, litlengthLog = LLFSELog;
1110
1111 hSize = HUF_readDTableX4(dctx->hufTableX4, dict, dictSize);
Yann Colletb923f652016-01-26 03:14:20 +01001112 if (HUF_isError(hSize)) return ERROR(dictionary_corrupted);
Yann Colletfb810d62016-01-28 00:18:06 +01001113 dict = (const char*)dict + hSize;
1114 dictSize -= hSize;
1115
1116 offcodeHeaderSize = FSE_readNCount(offcodeNCount, &offcodeMaxValue, &offcodeLog, dict, dictSize);
1117 if (FSE_isError(offcodeHeaderSize)) return ERROR(dictionary_corrupted);
1118 errorCode = FSE_buildDTable(dctx->OffTable, offcodeNCount, offcodeMaxValue, offcodeLog);
1119 if (FSE_isError(errorCode)) return ERROR(dictionary_corrupted);
1120 dict = (const char*)dict + offcodeHeaderSize;
1121 dictSize -= offcodeHeaderSize;
1122
1123 matchlengthHeaderSize = FSE_readNCount(matchlengthNCount, &matchlengthMaxValue, &matchlengthLog, dict, dictSize);
1124 if (FSE_isError(matchlengthHeaderSize)) return ERROR(dictionary_corrupted);
1125 errorCode = FSE_buildDTable(dctx->MLTable, matchlengthNCount, matchlengthMaxValue, matchlengthLog);
1126 if (FSE_isError(errorCode)) return ERROR(dictionary_corrupted);
1127 dict = (const char*)dict + matchlengthHeaderSize;
1128 dictSize -= matchlengthHeaderSize;
1129
1130 litlengthHeaderSize = FSE_readNCount(litlengthNCount, &litlengthMaxValue, &litlengthLog, dict, dictSize);
1131 if (FSE_isError(litlengthHeaderSize)) return ERROR(dictionary_corrupted);
1132 errorCode = FSE_buildDTable(dctx->LLTable, litlengthNCount, litlengthMaxValue, litlengthLog);
1133 if (FSE_isError(errorCode)) return ERROR(dictionary_corrupted);
1134
1135 dctx->flagStaticTables = 1;
1136 return hSize + offcodeHeaderSize + matchlengthHeaderSize + litlengthHeaderSize;
Yann Colletb923f652016-01-26 03:14:20 +01001137}
1138
Yann Collet7b51a292016-01-26 15:58:49 +01001139static size_t ZSTD_decompress_insertDictionary(ZSTD_DCtx* dctx, const void* dict, size_t dictSize)
Yann Colletb923f652016-01-26 03:14:20 +01001140{
1141 size_t eSize;
1142 U32 magic = MEM_readLE32(dict);
1143 if (magic != ZSTD_DICT_MAGIC) {
1144 /* pure content mode */
1145 ZSTD_refDictContent(dctx, dict, dictSize);
1146 return 0;
1147 }
1148 /* load entropy tables */
1149 dict = (const char*)dict + 4;
1150 dictSize -= 4;
1151 eSize = ZSTD_loadEntropy(dctx, dict, dictSize);
1152 if (ZSTD_isError(eSize)) return ERROR(dictionary_corrupted);
1153
1154 /* reference dictionary content */
1155 dict = (const char*)dict + eSize;
1156 dictSize -= eSize;
1157 ZSTD_refDictContent(dctx, dict, dictSize);
1158
1159 return 0;
1160}
1161
Yann Collet7b51a292016-01-26 15:58:49 +01001162
1163size_t ZSTD_decompressBegin_usingDict(ZSTD_DCtx* dctx, const void* dict, size_t dictSize)
1164{
1165 size_t errorCode;
1166 errorCode = ZSTD_decompressBegin(dctx);
1167 if (ZSTD_isError(errorCode)) return errorCode;
1168
1169 if (dict && dictSize) {
1170 errorCode = ZSTD_decompress_insertDictionary(dctx, dict, dictSize);
1171 if (ZSTD_isError(errorCode)) return ERROR(dictionary_corrupted);
1172 }
1173
1174 return 0;
1175}
1176