blob: 736e0a275e699cf9307c15b11514fa70b780f511 [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 Colletb923f652016-01-26 03:14:20 +0100146 BYTE litBuffer[BLOCKSIZE + WILDCOPY_OVERLENGTH];
Yann Collet0e491c02016-03-11 21:58:04 +0100147 BYTE headerBuffer[ZSTD_FRAMEHEADERSIZE_MAX];
Yann Collet417890c2015-12-04 17:16:37 +0100148}; /* typedef'd to ZSTD_DCtx within "zstd_static.h" */
Yann Collet5be2dd22015-11-11 13:43:58 +0100149
Yann Colletfb810d62016-01-28 00:18:06 +0100150size_t sizeofDCtx (void) { return sizeof(ZSTD_DCtx); }
151
Yann Collet7b51a292016-01-26 15:58:49 +0100152size_t ZSTD_decompressBegin(ZSTD_DCtx* dctx)
Yann Collet5b78d2f2015-11-12 15:36:05 +0100153{
Yann Collet88fcd292015-11-25 14:42:45 +0100154 dctx->expected = ZSTD_frameHeaderSize_min;
155 dctx->stage = ZSTDds_getFrameHeaderSize;
Yann Collet5b78d2f2015-11-12 15:36:05 +0100156 dctx->previousDstEnd = NULL;
157 dctx->base = NULL;
158 dctx->vBase = NULL;
159 dctx->dictEnd = NULL;
Yann Colletb923f652016-01-26 03:14:20 +0100160 dctx->hufTableX4[0] = HufLog;
Yann Colletfb810d62016-01-28 00:18:06 +0100161 dctx->flagStaticTables = 0;
Yann Collet0e491c02016-03-11 21:58:04 +0100162 dctx->fParams.mml = MINMATCH; /* overwritten by frame but forces ZSTD_btopt to MINMATCH in block mode */
inikepa4dde252016-03-01 14:14:35 +0100163 ZSTD_LOG_BLOCK("%p: ZSTD_decompressBegin searchLength=%d\n", dctx->base, dctx->params.searchLength);
Yann Collet5b78d2f2015-11-12 15:36:05 +0100164 return 0;
165}
166
167ZSTD_DCtx* ZSTD_createDCtx(void)
168{
169 ZSTD_DCtx* dctx = (ZSTD_DCtx*)malloc(sizeof(ZSTD_DCtx));
170 if (dctx==NULL) return NULL;
Yann Collet7b51a292016-01-26 15:58:49 +0100171 ZSTD_decompressBegin(dctx);
Yann Collet5b78d2f2015-11-12 15:36:05 +0100172 return dctx;
173}
174
175size_t ZSTD_freeDCtx(ZSTD_DCtx* dctx)
176{
177 free(dctx);
Yann Collet982ffc72016-02-05 02:33:10 +0100178 return 0; /* reserved as a potential error code in the future */
Yann Collet5b78d2f2015-11-12 15:36:05 +0100179}
180
Yann Collet7b51a292016-01-26 15:58:49 +0100181void ZSTD_copyDCtx(ZSTD_DCtx* dstDCtx, const ZSTD_DCtx* srcDCtx)
182{
183 memcpy(dstDCtx, srcDCtx,
184 sizeof(ZSTD_DCtx) - (BLOCKSIZE+WILDCOPY_OVERLENGTH + ZSTD_frameHeaderSize_max)); /* no need to copy workspace */
185}
186
Yann Collet5b78d2f2015-11-12 15:36:05 +0100187
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,
306* >0, not enough srcSize, provide expected `srcSize`,
307* or an error code, which can be tested using ZSTD_isError() */
Yann Collet0e491c02016-03-11 21:58:04 +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;
311 BYTE frameDesc;
312
313 if (srcSize < ZSTD_frameHeaderSize_min) return ZSTD_frameHeaderSize_min;
Yann Colletd1b26842016-03-15 01:24:33 +0100314 if (MEM_readLE32(src) != ZSTD_MAGICNUMBER) return ERROR(prefix_unknown);
Yann Collet03ea59b2016-03-12 01:25:40 +0100315
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 Collet03ea59b2016-03-12 01:25:40 +0100320 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 */
Yann Colletd1b26842016-03-15 01:24:33 +0100324 switch(frameDesc >> 6) /* fcsId */
Yann Collet03ea59b2016-03-12 01:25:40 +0100325 {
326 default: /* impossible */
327 case 0 : fparamsPtr->frameContentSize = 0; break;
328 case 1 : fparamsPtr->frameContentSize = ip[5]; break;
Yann Colletd1b26842016-03-15 01:24:33 +0100329 case 2 : fparamsPtr->frameContentSize = MEM_readLE16(ip+5)+256; break;
Yann Collet03ea59b2016-03-12 01:25:40 +0100330 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() :
337* decode Frame Header.
Yann Collet953ce722016-02-04 15:28:14 +0100338* srcSize must be the size provided by ZSTD_decodeFrameHeader_Part1().
Yann Collet26415d32015-11-26 12:43:28 +0100339* @return : 0, or an error code, which can be tested using ZSTD_isError() */
Yann Collet03ea59b2016-03-12 01:25:40 +0100340static size_t ZSTD_decodeFrameHeader(ZSTD_DCtx* zc, const void* src, size_t srcSize)
Yann Collet26415d32015-11-26 12:43:28 +0100341{
Yann Collet03ea59b2016-03-12 01:25:40 +0100342 size_t result = ZSTD_getFrameParams(&(zc->fParams), src, srcSize);
Yann Collet0e491c02016-03-11 21:58:04 +0100343 if ((MEM_32bits()) && (zc->fParams.windowLog > 25)) return ERROR(frameParameter_unsupportedBy32bits);
Yann Collet00fd7a22015-11-28 16:03:22 +0100344 return result;
Yann Collet26415d32015-11-26 12:43:28 +0100345}
346
Yann Collet5be2dd22015-11-11 13:43:58 +0100347
348size_t ZSTD_getcBlockSize(const void* src, size_t srcSize, blockProperties_t* bpPtr)
349{
350 const BYTE* const in = (const BYTE* const)src;
351 BYTE headerFlags;
352 U32 cSize;
353
Yann Collet61e16ce2016-01-31 02:04:15 +0100354 if (srcSize < 3)
355 return ERROR(srcSize_wrong);
Yann Collet5be2dd22015-11-11 13:43:58 +0100356
357 headerFlags = *in;
358 cSize = in[2] + (in[1]<<8) + ((in[0] & 7)<<16);
359
360 bpPtr->blockType = (blockType_t)(headerFlags >> 6);
361 bpPtr->origSize = (bpPtr->blockType == bt_rle) ? cSize : 0;
362
363 if (bpPtr->blockType == bt_end) return 0;
364 if (bpPtr->blockType == bt_rle) return 1;
365 return cSize;
366}
367
Yann Collet59d1f792016-01-23 19:28:41 +0100368
Yann Collet0f366c62015-11-12 16:19:30 +0100369static size_t ZSTD_copyRawBlock(void* dst, size_t maxDstSize, const void* src, size_t srcSize)
Yann Collet5be2dd22015-11-11 13:43:58 +0100370{
371 if (srcSize > maxDstSize) return ERROR(dstSize_tooSmall);
372 memcpy(dst, src, srcSize);
373 return srcSize;
374}
375
376
Yann Collet953ce722016-02-04 15:28:14 +0100377/*! ZSTD_decodeLiteralsBlock() :
Yann Collet14983e72015-11-11 21:38:21 +0100378 @return : nb of bytes read from src (< srcSize ) */
Yann Collet5b78d2f2015-11-12 15:36:05 +0100379size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx,
Yann Collet5be2dd22015-11-11 13:43:58 +0100380 const void* src, size_t srcSize) /* note : srcSize < BLOCKSIZE */
381{
Yann Collet5be2dd22015-11-11 13:43:58 +0100382 const BYTE* const istart = (const BYTE*) src;
383
384 /* any compressed block with literals segment must be at least this size */
385 if (srcSize < MIN_CBLOCK_SIZE) return ERROR(corruption_detected);
386
Yann Collet59d1f792016-01-23 19:28:41 +0100387 switch(istart[0]>> 6)
Yann Collet5be2dd22015-11-11 13:43:58 +0100388 {
Yann Collet59d1f792016-01-23 19:28:41 +0100389 case IS_HUF:
Yann Collet5be2dd22015-11-11 13:43:58 +0100390 {
Yann Colletafe07092016-01-25 04:10:46 +0100391 size_t litSize, litCSize, singleStream=0;
Yann Collet59d1f792016-01-23 19:28:41 +0100392 U32 lhSize = ((istart[0]) >> 4) & 3;
393 switch(lhSize)
394 {
395 case 0: case 1: default: /* note : default is impossible, since lhSize into [0..3] */
396 /* 2 - 2 - 10 - 10 */
397 lhSize=3;
Yann Colletafe07092016-01-25 04:10:46 +0100398 singleStream = istart[0] & 16;
Yann Collet59d1f792016-01-23 19:28:41 +0100399 litSize = ((istart[0] & 15) << 6) + (istart[1] >> 2);
400 litCSize = ((istart[1] & 3) << 8) + istart[2];
401 break;
402 case 2:
403 /* 2 - 2 - 14 - 14 */
404 lhSize=4;
405 litSize = ((istart[0] & 15) << 10) + (istart[1] << 2) + (istart[2] >> 6);
406 litCSize = ((istart[2] & 63) << 8) + istart[3];
407 break;
408 case 3:
409 /* 2 - 2 - 18 - 18 */
410 lhSize=5;
411 litSize = ((istart[0] & 15) << 14) + (istart[1] << 6) + (istart[2] >> 2);
412 litCSize = ((istart[2] & 3) << 16) + (istart[3] << 8) + istart[4];
413 break;
414 }
Yann Colletfb810d62016-01-28 00:18:06 +0100415 if (litSize > BLOCKSIZE) return ERROR(corruption_detected);
Yann Collet59d1f792016-01-23 19:28:41 +0100416
Yann Colletafe07092016-01-25 04:10:46 +0100417 if (HUF_isError(singleStream ?
418 HUF_decompress1X2(dctx->litBuffer, litSize, istart+lhSize, litCSize) :
419 HUF_decompress (dctx->litBuffer, litSize, istart+lhSize, litCSize) ))
Yann Collet59d1f792016-01-23 19:28:41 +0100420 return ERROR(corruption_detected);
421
Yann Collet5be2dd22015-11-11 13:43:58 +0100422 dctx->litPtr = dctx->litBuffer;
423 dctx->litBufSize = BLOCKSIZE+8;
424 dctx->litSize = litSize;
Yann Collet59d1f792016-01-23 19:28:41 +0100425 return litCSize + lhSize;
Yann Collet5be2dd22015-11-11 13:43:58 +0100426 }
Yann Colletb923f652016-01-26 03:14:20 +0100427 case IS_PCH:
428 {
429 size_t errorCode;
430 size_t litSize, litCSize;
431 U32 lhSize = ((istart[0]) >> 4) & 3;
432 if (lhSize != 1) /* only case supported for now : small litSize, single stream */
433 return ERROR(corruption_detected);
Yann Colletfb810d62016-01-28 00:18:06 +0100434 if (!dctx->flagStaticTables)
Yann Collet7b51a292016-01-26 15:58:49 +0100435 return ERROR(dictionary_corrupted);
Yann Colletb923f652016-01-26 03:14:20 +0100436
437 /* 2 - 2 - 10 - 10 */
438 lhSize=3;
439 litSize = ((istart[0] & 15) << 6) + (istart[1] >> 2);
440 litCSize = ((istart[1] & 3) << 8) + istart[2];
441
442 errorCode = HUF_decompress1X4_usingDTable(dctx->litBuffer, litSize, istart+lhSize, litCSize, dctx->hufTableX4);
443 if (HUF_isError(errorCode)) return ERROR(corruption_detected);
444
445 dctx->litPtr = dctx->litBuffer;
446 dctx->litBufSize = BLOCKSIZE+WILDCOPY_OVERLENGTH;
447 dctx->litSize = litSize;
448 return litCSize + lhSize;
449 }
Yann Collet5be2dd22015-11-11 13:43:58 +0100450 case IS_RAW:
451 {
Yann Collet59d1f792016-01-23 19:28:41 +0100452 size_t litSize;
453 U32 lhSize = ((istart[0]) >> 4) & 3;
454 switch(lhSize)
Yann Collet5be2dd22015-11-11 13:43:58 +0100455 {
Yann Collet59d1f792016-01-23 19:28:41 +0100456 case 0: case 1: default: /* note : default is impossible, since lhSize into [0..3] */
457 lhSize=1;
458 litSize = istart[0] & 31;
459 break;
460 case 2:
461 litSize = ((istart[0] & 15) << 8) + istart[1];
462 break;
463 case 3:
464 litSize = ((istart[0] & 15) << 16) + (istart[1] << 8) + istart[2];
465 break;
466 }
467
Yann Collet61e16ce2016-01-31 02:04:15 +0100468 if (lhSize+litSize+WILDCOPY_OVERLENGTH > srcSize) { /* risk reading beyond src buffer with wildcopy */
Yann Colletb010b3b2016-02-03 12:39:34 +0100469 if (litSize+lhSize > srcSize) return ERROR(corruption_detected);
Yann Collet59d1f792016-01-23 19:28:41 +0100470 memcpy(dctx->litBuffer, istart+lhSize, litSize);
Yann Collet5be2dd22015-11-11 13:43:58 +0100471 dctx->litPtr = dctx->litBuffer;
472 dctx->litBufSize = BLOCKSIZE+8;
473 dctx->litSize = litSize;
Yann Colletbc4c8aa2016-01-25 17:26:01 +0100474 return lhSize+litSize;
Yann Collet5be2dd22015-11-11 13:43:58 +0100475 }
476 /* direct reference into compressed stream */
Yann Collet59d1f792016-01-23 19:28:41 +0100477 dctx->litPtr = istart+lhSize;
478 dctx->litBufSize = srcSize-lhSize;
Yann Collet5be2dd22015-11-11 13:43:58 +0100479 dctx->litSize = litSize;
Yann Collet59d1f792016-01-23 19:28:41 +0100480 return lhSize+litSize;
481 }
Yann Collet5be2dd22015-11-11 13:43:58 +0100482 case IS_RLE:
483 {
Yann Collet59d1f792016-01-23 19:28:41 +0100484 size_t litSize;
485 U32 lhSize = ((istart[0]) >> 4) & 3;
486 switch(lhSize)
487 {
488 case 0: case 1: default: /* note : default is impossible, since lhSize into [0..3] */
489 lhSize = 1;
490 litSize = istart[0] & 31;
491 break;
492 case 2:
493 litSize = ((istart[0] & 15) << 8) + istart[1];
494 break;
495 case 3:
496 litSize = ((istart[0] & 15) << 16) + (istart[1] << 8) + istart[2];
497 break;
498 }
Yann Collet5be2dd22015-11-11 13:43:58 +0100499 if (litSize > BLOCKSIZE) return ERROR(corruption_detected);
Yann Collet59d1f792016-01-23 19:28:41 +0100500 memset(dctx->litBuffer, istart[lhSize], litSize);
Yann Collet5be2dd22015-11-11 13:43:58 +0100501 dctx->litPtr = dctx->litBuffer;
Yann Colletb923f652016-01-26 03:14:20 +0100502 dctx->litBufSize = BLOCKSIZE+WILDCOPY_OVERLENGTH;
Yann Collet5be2dd22015-11-11 13:43:58 +0100503 dctx->litSize = litSize;
Yann Collet59d1f792016-01-23 19:28:41 +0100504 return lhSize+1;
Yann Collet5be2dd22015-11-11 13:43:58 +0100505 }
Yann Colletb923f652016-01-26 03:14:20 +0100506 default:
507 return ERROR(corruption_detected); /* impossible */
Yann Collet5be2dd22015-11-11 13:43:58 +0100508 }
509}
510
511
512size_t ZSTD_decodeSeqHeaders(int* nbSeq, const BYTE** dumpsPtr, size_t* dumpsLengthPtr,
513 FSE_DTable* DTableLL, FSE_DTable* DTableML, FSE_DTable* DTableOffb,
514 const void* src, size_t srcSize)
515{
516 const BYTE* const istart = (const BYTE* const)src;
517 const BYTE* ip = istart;
518 const BYTE* const iend = istart + srcSize;
519 U32 LLtype, Offtype, MLtype;
520 U32 LLlog, Offlog, MLlog;
521 size_t dumpsLength;
522
523 /* check */
Yann Collet61e16ce2016-01-31 02:04:15 +0100524 if (srcSize < MIN_SEQUENCES_SIZE)
525 return ERROR(srcSize_wrong);
Yann Collet5be2dd22015-11-11 13:43:58 +0100526
527 /* SeqHead */
Yann Collet61e16ce2016-01-31 02:04:15 +0100528 *nbSeq = *ip++;
529 if (*nbSeq==0) return 1;
Yann Colletd409db62016-03-04 14:45:31 +0100530 if (*nbSeq >= 0x7F) {
531 if (*nbSeq == 0xFF)
532 *nbSeq = MEM_readLE16(ip) + LONGNBSEQ, ip+=2;
533 else
534 *nbSeq = ((nbSeq[0]-0x80)<<8) + *ip++;
535 }
Yann Collete93d6ce2016-01-31 00:58:06 +0100536
Yann Colletd409db62016-03-04 14:45:31 +0100537 /* FSE table descriptors */
Yann Collet5be2dd22015-11-11 13:43:58 +0100538 LLtype = *ip >> 6;
539 Offtype = (*ip >> 4) & 3;
540 MLtype = (*ip >> 2) & 3;
Yann Colletfb810d62016-01-28 00:18:06 +0100541 if (*ip & 2) {
Yann Collet5be2dd22015-11-11 13:43:58 +0100542 dumpsLength = ip[2];
543 dumpsLength += ip[1] << 8;
544 ip += 3;
Yann Colletfb810d62016-01-28 00:18:06 +0100545 } else {
Yann Collet5be2dd22015-11-11 13:43:58 +0100546 dumpsLength = ip[1];
547 dumpsLength += (ip[0] & 1) << 8;
548 ip += 2;
549 }
550 *dumpsPtr = ip;
551 ip += dumpsLength;
552 *dumpsLengthPtr = dumpsLength;
553
554 /* check */
555 if (ip > iend-3) return ERROR(srcSize_wrong); /* min : all 3 are "raw", hence no header, but at least xxLog bits per type */
556
557 /* sequences */
558 {
Yann Collet82368cf2015-11-16 19:10:56 +0100559 S16 norm[MaxML+1]; /* assumption : MaxML >= MaxLL >= MaxOff */
Yann Collet5be2dd22015-11-11 13:43:58 +0100560 size_t headerSize;
561
562 /* Build DTables */
563 switch(LLtype)
564 {
565 U32 max;
Yann Colletfb810d62016-01-28 00:18:06 +0100566 case FSE_ENCODING_RLE :
Yann Collet5be2dd22015-11-11 13:43:58 +0100567 LLlog = 0;
Yann Colletfb810d62016-01-28 00:18:06 +0100568 FSE_buildDTable_rle(DTableLL, *ip++);
569 break;
570 case FSE_ENCODING_RAW :
Yann Collet5be2dd22015-11-11 13:43:58 +0100571 LLlog = LLbits;
Yann Colletfb810d62016-01-28 00:18:06 +0100572 FSE_buildDTable_raw(DTableLL, LLbits);
573 break;
574 case FSE_ENCODING_STATIC:
575 break;
576 case FSE_ENCODING_DYNAMIC :
577 default : /* impossible */
Yann Collet5be2dd22015-11-11 13:43:58 +0100578 max = MaxLL;
579 headerSize = FSE_readNCount(norm, &max, &LLlog, ip, iend-ip);
580 if (FSE_isError(headerSize)) return ERROR(GENERIC);
581 if (LLlog > LLFSELog) return ERROR(corruption_detected);
582 ip += headerSize;
583 FSE_buildDTable(DTableLL, norm, max, LLlog);
584 }
585
586 switch(Offtype)
587 {
588 U32 max;
Yann Colletfb810d62016-01-28 00:18:06 +0100589 case FSE_ENCODING_RLE :
Yann Collet5be2dd22015-11-11 13:43:58 +0100590 Offlog = 0;
591 if (ip > iend-2) return ERROR(srcSize_wrong); /* min : "raw", hence no header, but at least xxLog bits */
592 FSE_buildDTable_rle(DTableOffb, *ip++ & MaxOff); /* if *ip > MaxOff, data is corrupted */
593 break;
Yann Colletfb810d62016-01-28 00:18:06 +0100594 case FSE_ENCODING_RAW :
Yann Collet5be2dd22015-11-11 13:43:58 +0100595 Offlog = Offbits;
Yann Colletfb810d62016-01-28 00:18:06 +0100596 FSE_buildDTable_raw(DTableOffb, Offbits);
597 break;
598 case FSE_ENCODING_STATIC:
599 break;
600 case FSE_ENCODING_DYNAMIC :
601 default : /* impossible */
Yann Collet5be2dd22015-11-11 13:43:58 +0100602 max = MaxOff;
603 headerSize = FSE_readNCount(norm, &max, &Offlog, ip, iend-ip);
604 if (FSE_isError(headerSize)) return ERROR(GENERIC);
605 if (Offlog > OffFSELog) return ERROR(corruption_detected);
606 ip += headerSize;
607 FSE_buildDTable(DTableOffb, norm, max, Offlog);
608 }
609
610 switch(MLtype)
611 {
612 U32 max;
Yann Colletfb810d62016-01-28 00:18:06 +0100613 case FSE_ENCODING_RLE :
Yann Collet5be2dd22015-11-11 13:43:58 +0100614 MLlog = 0;
615 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 +0100616 FSE_buildDTable_rle(DTableML, *ip++);
617 break;
618 case FSE_ENCODING_RAW :
Yann Collet5be2dd22015-11-11 13:43:58 +0100619 MLlog = MLbits;
Yann Colletfb810d62016-01-28 00:18:06 +0100620 FSE_buildDTable_raw(DTableML, MLbits);
621 break;
622 case FSE_ENCODING_STATIC:
623 break;
624 case FSE_ENCODING_DYNAMIC :
625 default : /* impossible */
Yann Collet5be2dd22015-11-11 13:43:58 +0100626 max = MaxML;
627 headerSize = FSE_readNCount(norm, &max, &MLlog, ip, iend-ip);
628 if (FSE_isError(headerSize)) return ERROR(GENERIC);
629 if (MLlog > MLFSELog) return ERROR(corruption_detected);
630 ip += headerSize;
631 FSE_buildDTable(DTableML, norm, max, MLlog);
Yann Colletfb810d62016-01-28 00:18:06 +0100632 } }
Yann Collet5be2dd22015-11-11 13:43:58 +0100633
634 return ip-istart;
635}
636
637
638typedef struct {
639 size_t litLength;
Yann Collet5be2dd22015-11-11 13:43:58 +0100640 size_t matchLength;
Yann Collete93d6ce2016-01-31 00:58:06 +0100641 size_t offset;
Yann Collet5be2dd22015-11-11 13:43:58 +0100642} seq_t;
643
644typedef struct {
645 BIT_DStream_t DStream;
646 FSE_DState_t stateLL;
647 FSE_DState_t stateOffb;
648 FSE_DState_t stateML;
649 size_t prevOffset;
650 const BYTE* dumps;
651 const BYTE* dumpsEnd;
652} seqState_t;
653
inikepe9f30ea2016-02-03 12:53:07 +0100654
655
inikep6b3739c2016-02-22 15:53:42 +0100656static void ZSTD_decodeSequence(seq_t* seq, seqState_t* seqState, const U32 mls)
Yann Collet5be2dd22015-11-11 13:43:58 +0100657{
658 size_t litLength;
659 size_t prevOffset;
660 size_t offset;
661 size_t matchLength;
662 const BYTE* dumps = seqState->dumps;
663 const BYTE* const de = seqState->dumpsEnd;
664
665 /* Literal length */
Yann Collete93d6ce2016-01-31 00:58:06 +0100666 litLength = FSE_peakSymbol(&(seqState->stateLL));
Yann Collete4fdad52015-11-25 21:09:17 +0100667 prevOffset = litLength ? seq->offset : seqState->prevOffset;
Yann Colletfb810d62016-01-28 00:18:06 +0100668 if (litLength == MaxLL) {
Yann Collet5be2dd22015-11-11 13:43:58 +0100669 U32 add = *dumps++;
670 if (add < 255) litLength += add;
Yann Colletfb810d62016-01-28 00:18:06 +0100671 else {
Yann Collet7d8e6bd2016-02-02 17:30:37 +0100672 litLength = MEM_readLE32(dumps) & 0xFFFFFF; /* no risk : dumps is always followed by seq tables > 1 byte */
673 if (litLength&1) litLength>>=1, dumps += 3;
674 else litLength = (U16)(litLength)>>1, dumps += 2;
Yann Collet5be2dd22015-11-11 13:43:58 +0100675 }
676 if (dumps >= de) dumps = de-1; /* late correction, to avoid read overflow (data is now corrupted anyway) */
677 }
678
679 /* Offset */
680 {
681 static const U32 offsetPrefix[MaxOff+1] = {
Yann Collet95cd0c22016-03-08 18:24:21 +0100682 1 /*fake*/, 1, 2, 4, 8, 0x10, 0x20, 0x40, 0x80, 0x100,
683 0x200, 0x400, 0x800, 0x1000, 0x2000, 0x4000, 0x8000, 0x10000, 0x20000, 0x40000,
684 0x80000, 0x100000, 0x200000, 0x400000, 0x800000, 0x1000000, 0x2000000, 0x4000000, /*fake*/ 1, 1, 1, 1 };
Yann Collete93d6ce2016-01-31 00:58:06 +0100685 U32 offsetCode = FSE_peakSymbol(&(seqState->stateOffb)); /* <= maxOff, by table construction */
686 U32 nbBits = offsetCode - 1;
Yann Collet5be2dd22015-11-11 13:43:58 +0100687 if (offsetCode==0) nbBits = 0; /* cmove */
688 offset = offsetPrefix[offsetCode] + BIT_readBits(&(seqState->DStream), nbBits);
689 if (MEM_32bits()) BIT_reloadDStream(&(seqState->DStream));
Yann Collete93d6ce2016-01-31 00:58:06 +0100690 if (offsetCode==0) offset = prevOffset; /* repcode, cmove */
Yann Collet55aa7f92015-11-20 12:04:52 +0100691 if (offsetCode | !litLength) seqState->prevOffset = seq->offset; /* cmove */
Yann Collete93d6ce2016-01-31 00:58:06 +0100692 FSE_decodeSymbol(&(seqState->stateOffb), &(seqState->DStream)); /* update */
Yann Collet5be2dd22015-11-11 13:43:58 +0100693 }
694
Yann Collete93d6ce2016-01-31 00:58:06 +0100695 /* Literal length update */
696 FSE_decodeSymbol(&(seqState->stateLL), &(seqState->DStream)); /* update */
697 if (MEM_32bits()) BIT_reloadDStream(&(seqState->DStream));
698
Yann Collet5be2dd22015-11-11 13:43:58 +0100699 /* MatchLength */
700 matchLength = FSE_decodeSymbol(&(seqState->stateML), &(seqState->DStream));
Yann Colletfb810d62016-01-28 00:18:06 +0100701 if (matchLength == MaxML) {
Yann Collet5be2dd22015-11-11 13:43:58 +0100702 U32 add = *dumps++;
703 if (add < 255) matchLength += add;
Yann Colletfb810d62016-01-28 00:18:06 +0100704 else {
Yann Collet5be2dd22015-11-11 13:43:58 +0100705 matchLength = MEM_readLE32(dumps) & 0xFFFFFF; /* no pb : dumps is always followed by seq tables > 1 byte */
Yann Collet7d8e6bd2016-02-02 17:30:37 +0100706 if (matchLength&1) matchLength>>=1, dumps += 3;
707 else matchLength = (U16)(matchLength)>>1, dumps += 2;
Yann Collet5be2dd22015-11-11 13:43:58 +0100708 }
709 if (dumps >= de) dumps = de-1; /* late correction, to avoid read overflow (data is now corrupted anyway) */
710 }
inikep6b3739c2016-02-22 15:53:42 +0100711 matchLength += mls;
Yann Collet5be2dd22015-11-11 13:43:58 +0100712
713 /* save result */
714 seq->litLength = litLength;
715 seq->offset = offset;
716 seq->matchLength = matchLength;
717 seqState->dumps = dumps;
Yann Colletfb810d62016-01-28 00:18:06 +0100718
Yann Collet7d8e6bd2016-02-02 17:30:37 +0100719#if 0 /* debug */
Yann Colletfb810d62016-01-28 00:18:06 +0100720 {
721 static U64 totalDecoded = 0;
722 printf("pos %6u : %3u literals & match %3u bytes at distance %6u \n",
723 (U32)(totalDecoded), (U32)litLength, (U32)matchLength, (U32)offset);
724 totalDecoded += litLength + matchLength;
725 }
726#endif
Yann Collet5be2dd22015-11-11 13:43:58 +0100727}
728
729
Yann Collet5b78d2f2015-11-12 15:36:05 +0100730FORCE_INLINE size_t ZSTD_execSequence(BYTE* op,
Yann Colletb3a2af92015-11-19 17:13:19 +0100731 BYTE* const oend, seq_t sequence,
Yann Collet5be2dd22015-11-11 13:43:58 +0100732 const BYTE** litPtr, const BYTE* const litLimit_8,
Yann Collet417890c2015-12-04 17:16:37 +0100733 const BYTE* const base, const BYTE* const vBase, const BYTE* const dictEnd)
Yann Collet5be2dd22015-11-11 13:43:58 +0100734{
Yann Colletb3a2af92015-11-19 17:13:19 +0100735 static const int dec32table[] = { 0, 1, 2, 1, 4, 4, 4, 4 }; /* added */
736 static const int dec64table[] = { 8, 8, 8, 7, 8, 9,10,11 }; /* substracted */
Yann Collet5be2dd22015-11-11 13:43:58 +0100737 BYTE* const oLitEnd = op + sequence.litLength;
Yann Colletb3a2af92015-11-19 17:13:19 +0100738 const size_t sequenceLength = sequence.litLength + sequence.matchLength;
739 BYTE* const oMatchEnd = op + sequenceLength; /* risk : address space overflow (32-bits) */
Yann Collet5be2dd22015-11-11 13:43:58 +0100740 BYTE* const oend_8 = oend-8;
741 const BYTE* const litEnd = *litPtr + sequence.litLength;
Yann Colletb3a2af92015-11-19 17:13:19 +0100742 const BYTE* match = oLitEnd - sequence.offset;
Yann Collet5be2dd22015-11-11 13:43:58 +0100743
744 /* check */
745 if (oLitEnd > oend_8) return ERROR(dstSize_tooSmall); /* last match must start at a minimum distance of 8 from oend */
746 if (oMatchEnd > oend) return ERROR(dstSize_tooSmall); /* overwrite beyond dst buffer */
747 if (litEnd > litLimit_8) return ERROR(corruption_detected); /* risk read beyond lit buffer */
748
749 /* copy Literals */
750 ZSTD_wildcopy(op, *litPtr, sequence.litLength); /* note : oLitEnd <= oend-8 : no risk of overwrite beyond oend */
751 op = oLitEnd;
752 *litPtr = litEnd; /* update for next sequence */
753
754 /* copy Match */
Yann Collet7b51a292016-01-26 15:58:49 +0100755 if (sequence.offset > (size_t)(oLitEnd - base)) {
Yann Collet44287a32015-11-30 23:13:56 +0100756 /* offset beyond prefix */
Yann Collet9f5ab1a2015-12-11 00:27:41 +0100757 if (sequence.offset > (size_t)(oLitEnd - vBase))
758 return ERROR(corruption_detected);
Yann Collet44287a32015-11-30 23:13:56 +0100759 match = dictEnd - (base-match);
Yann Collet7b51a292016-01-26 15:58:49 +0100760 if (match + sequence.matchLength <= dictEnd) {
Yann Collet4bfe4152015-12-06 13:18:37 +0100761 memmove(oLitEnd, match, sequence.matchLength);
Yann Collet44287a32015-11-30 23:13:56 +0100762 return sequenceLength;
763 }
764 /* span extDict & currentPrefixSegment */
765 {
766 size_t length1 = dictEnd - match;
Yann Collet4bfe4152015-12-06 13:18:37 +0100767 memmove(oLitEnd, match, length1);
Yann Collet44287a32015-11-30 23:13:56 +0100768 op = oLitEnd + length1;
769 sequence.matchLength -= length1;
770 match = base;
Yann Colletfb810d62016-01-28 00:18:06 +0100771 } }
Yann Collet0f366c62015-11-12 16:19:30 +0100772
Yann Collet44287a32015-11-30 23:13:56 +0100773 /* match within prefix */
Yann Collet7b51a292016-01-26 15:58:49 +0100774 if (sequence.offset < 8) {
Yann Collet44287a32015-11-30 23:13:56 +0100775 /* close range match, overlap */
776 const int sub2 = dec64table[sequence.offset];
777 op[0] = match[0];
778 op[1] = match[1];
779 op[2] = match[2];
780 op[3] = match[3];
781 match += dec32table[sequence.offset];
782 ZSTD_copy4(op+4, match);
783 match -= sub2;
Yann Colletfb810d62016-01-28 00:18:06 +0100784 } else {
Yann Collet44287a32015-11-30 23:13:56 +0100785 ZSTD_copy8(op, match);
786 }
787 op += 8; match += 8;
Yann Collet5be2dd22015-11-11 13:43:58 +0100788
inikepa4dde252016-03-01 14:14:35 +0100789 if (oMatchEnd > oend-(16-3)) { // 3 = MINMATCH
Yann Collet7b51a292016-01-26 15:58:49 +0100790 if (op < oend_8) {
Yann Collet44287a32015-11-30 23:13:56 +0100791 ZSTD_wildcopy(op, match, oend_8 - op);
792 match += oend_8 - op;
793 op = oend_8;
794 }
Yann Colletfb810d62016-01-28 00:18:06 +0100795 while (op < oMatchEnd)
796 *op++ = *match++;
797 } else {
Yann Collet44287a32015-11-30 23:13:56 +0100798 ZSTD_wildcopy(op, match, sequence.matchLength-8); /* works even if matchLength < 8 */
799 }
800 return sequenceLength;
Yann Collet5be2dd22015-11-11 13:43:58 +0100801}
802
Yann Colletb3a2af92015-11-19 17:13:19 +0100803
Yann Collet5be2dd22015-11-11 13:43:58 +0100804static size_t ZSTD_decompressSequences(
Yann Collet5b78d2f2015-11-12 15:36:05 +0100805 ZSTD_DCtx* dctx,
Yann Collet5be2dd22015-11-11 13:43:58 +0100806 void* dst, size_t maxDstSize,
807 const void* seqStart, size_t seqSize)
808{
Yann Collet5be2dd22015-11-11 13:43:58 +0100809 const BYTE* ip = (const BYTE*)seqStart;
810 const BYTE* const iend = ip + seqSize;
811 BYTE* const ostart = (BYTE* const)dst;
812 BYTE* op = ostart;
813 BYTE* const oend = ostart + maxDstSize;
814 size_t errorCode, dumpsLength;
815 const BYTE* litPtr = dctx->litPtr;
816 const BYTE* const litLimit_8 = litPtr + dctx->litBufSize - 8;
817 const BYTE* const litEnd = litPtr + dctx->litSize;
818 int nbSeq;
819 const BYTE* dumps;
820 U32* DTableLL = dctx->LLTable;
821 U32* DTableML = dctx->MLTable;
822 U32* DTableOffb = dctx->OffTable;
Yann Collet417890c2015-12-04 17:16:37 +0100823 const BYTE* const base = (const BYTE*) (dctx->base);
824 const BYTE* const vBase = (const BYTE*) (dctx->vBase);
825 const BYTE* const dictEnd = (const BYTE*) (dctx->dictEnd);
Yann Collet0e491c02016-03-11 21:58:04 +0100826 const U32 mls = dctx->fParams.mml;
Yann Collet5be2dd22015-11-11 13:43:58 +0100827
828 /* Build Decoding Tables */
829 errorCode = ZSTD_decodeSeqHeaders(&nbSeq, &dumps, &dumpsLength,
830 DTableLL, DTableML, DTableOffb,
Yann Colletfb810d62016-01-28 00:18:06 +0100831 ip, seqSize);
Yann Collet5be2dd22015-11-11 13:43:58 +0100832 if (ZSTD_isError(errorCode)) return errorCode;
833 ip += errorCode;
834
835 /* Regen sequences */
Yann Collete93d6ce2016-01-31 00:58:06 +0100836 if (nbSeq) {
Yann Collet5be2dd22015-11-11 13:43:58 +0100837 seq_t sequence;
838 seqState_t seqState;
839
840 memset(&sequence, 0, sizeof(sequence));
Yann Collet61e16ce2016-01-31 02:04:15 +0100841 sequence.offset = REPCODE_STARTVALUE;
Yann Collet5be2dd22015-11-11 13:43:58 +0100842 seqState.dumps = dumps;
843 seqState.dumpsEnd = dumps + dumpsLength;
Yann Collet61e16ce2016-01-31 02:04:15 +0100844 seqState.prevOffset = REPCODE_STARTVALUE;
Yann Collet5be2dd22015-11-11 13:43:58 +0100845 errorCode = BIT_initDStream(&(seqState.DStream), ip, iend-ip);
846 if (ERR_isError(errorCode)) return ERROR(corruption_detected);
847 FSE_initDState(&(seqState.stateLL), &(seqState.DStream), DTableLL);
848 FSE_initDState(&(seqState.stateOffb), &(seqState.DStream), DTableOffb);
849 FSE_initDState(&(seqState.stateML), &(seqState.DStream), DTableML);
850
Yann Collet7b51a292016-01-26 15:58:49 +0100851 for ( ; (BIT_reloadDStream(&(seqState.DStream)) <= BIT_DStream_completed) && nbSeq ; ) {
Yann Colletb3a2af92015-11-19 17:13:19 +0100852 size_t oneSeqSize;
853 nbSeq--;
inikep6b3739c2016-02-22 15:53:42 +0100854 ZSTD_decodeSequence(&sequence, &seqState, mls);
Yann Colletb3a2af92015-11-19 17:13:19 +0100855 oneSeqSize = ZSTD_execSequence(op, oend, sequence, &litPtr, litLimit_8, base, vBase, dictEnd);
Yann Collet370b08e2016-03-08 00:03:59 +0100856 if (ZSTD_isError(oneSeqSize))
857 return oneSeqSize;
Yann Collet5be2dd22015-11-11 13:43:58 +0100858 op += oneSeqSize;
859 }
860
861 /* check if reached exact end */
Yann Collet35f7de52016-01-31 02:51:03 +0100862 if (nbSeq) return ERROR(corruption_detected);
Yann Collete93d6ce2016-01-31 00:58:06 +0100863 }
Yann Collet5be2dd22015-11-11 13:43:58 +0100864
Yann Collete93d6ce2016-01-31 00:58:06 +0100865 /* last literal segment */
866 {
867 size_t lastLLSize = litEnd - litPtr;
868 if (litPtr > litEnd) return ERROR(corruption_detected); /* too many literals already used */
869 if (op+lastLLSize > oend) return ERROR(dstSize_tooSmall);
870 memcpy(op, litPtr, lastLLSize);
871 op += lastLLSize;
872 }
Yann Collet5be2dd22015-11-11 13:43:58 +0100873
874 return op-ostart;
875}
876
877
Yann Colletb0125102016-01-09 02:00:10 +0100878static void ZSTD_checkContinuity(ZSTD_DCtx* dctx, const void* dst)
879{
Yann Collet7b51a292016-01-26 15:58:49 +0100880 if (dst != dctx->previousDstEnd) { /* not contiguous */
Yann Colletb0125102016-01-09 02:00:10 +0100881 dctx->dictEnd = dctx->previousDstEnd;
882 dctx->vBase = (const char*)dst - ((const char*)(dctx->previousDstEnd) - (const char*)(dctx->base));
883 dctx->base = dst;
884 dctx->previousDstEnd = dst;
885 }
886}
887
888
889static size_t ZSTD_decompressBlock_internal(ZSTD_DCtx* dctx,
Yann Colletb010b3b2016-02-03 12:39:34 +0100890 void* dst, size_t dstCapacity,
Yann Collet5be2dd22015-11-11 13:43:58 +0100891 const void* src, size_t srcSize)
Yann Colletb010b3b2016-02-03 12:39:34 +0100892{ /* blockType == blockCompressed */
Yann Collet5be2dd22015-11-11 13:43:58 +0100893 const BYTE* ip = (const BYTE*)src;
Yann Colletb010b3b2016-02-03 12:39:34 +0100894 size_t litCSize;
895
896 if (srcSize >= BLOCKSIZE) return ERROR(srcSize_wrong);
Yann Collet5be2dd22015-11-11 13:43:58 +0100897
inikepa4dde252016-03-01 14:14:35 +0100898 ZSTD_LOG_BLOCK("%p: ZSTD_decompressBlock_internal searchLength=%d\n", dctx->base, dctx->params.searchLength);
899
Yann Collet5be2dd22015-11-11 13:43:58 +0100900 /* Decode literals sub-block */
Yann Colletb010b3b2016-02-03 12:39:34 +0100901 litCSize = ZSTD_decodeLiteralsBlock(dctx, src, srcSize);
Yann Collet5be2dd22015-11-11 13:43:58 +0100902 if (ZSTD_isError(litCSize)) return litCSize;
903 ip += litCSize;
904 srcSize -= litCSize;
905
Yann Colletb010b3b2016-02-03 12:39:34 +0100906 return ZSTD_decompressSequences(dctx, dst, dstCapacity, ip, srcSize);
Yann Collet5be2dd22015-11-11 13:43:58 +0100907}
908
909
Yann Colletb0125102016-01-09 02:00:10 +0100910size_t ZSTD_decompressBlock(ZSTD_DCtx* dctx,
Yann Colletb010b3b2016-02-03 12:39:34 +0100911 void* dst, size_t dstCapacity,
Yann Colletb0125102016-01-09 02:00:10 +0100912 const void* src, size_t srcSize)
913{
914 ZSTD_checkContinuity(dctx, dst);
Yann Colletb010b3b2016-02-03 12:39:34 +0100915 return ZSTD_decompressBlock_internal(dctx, dst, dstCapacity, src, srcSize);
Yann Colletb0125102016-01-09 02:00:10 +0100916}
917
918
Yann Collet0e491c02016-03-11 21:58:04 +0100919/*! ZSTD_decompress_continueDCtx() :
920* `dctx` must have been properly initialized */
921static size_t ZSTD_decompressFrame(ZSTD_DCtx* dctx,
Yann Collet31683c02015-12-18 01:26:48 +0100922 void* dst, size_t maxDstSize,
Yann Collet7b51a292016-01-26 15:58:49 +0100923 const void* src, size_t srcSize)
Yann Collet5be2dd22015-11-11 13:43:58 +0100924{
925 const BYTE* ip = (const BYTE*)src;
926 const BYTE* iend = ip + srcSize;
927 BYTE* const ostart = (BYTE* const)dst;
928 BYTE* op = ostart;
929 BYTE* const oend = ostart + maxDstSize;
930 size_t remainingSize = srcSize;
Yann Collet5be2dd22015-11-11 13:43:58 +0100931 blockProperties_t blockProperties;
932
933 /* Frame Header */
Yann Collet88fcd292015-11-25 14:42:45 +0100934 {
Yann Collet03ea59b2016-03-12 01:25:40 +0100935 size_t frameHeaderSize, errorCode;
Yann Collet88fcd292015-11-25 14:42:45 +0100936 if (srcSize < ZSTD_frameHeaderSize_min+ZSTD_blockHeaderSize) return ERROR(srcSize_wrong);
Yann Collet5be2dd22015-11-11 13:43:58 +0100937#if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT==1)
Yann Collet88fcd292015-11-25 14:42:45 +0100938 {
939 const U32 magicNumber = MEM_readLE32(src);
940 if (ZSTD_isLegacy(magicNumber))
941 return ZSTD_decompressLegacy(dst, maxDstSize, src, srcSize, magicNumber);
942 }
Yann Collet5be2dd22015-11-11 13:43:58 +0100943#endif
Yann Collet03ea59b2016-03-12 01:25:40 +0100944 frameHeaderSize = ZSTD_frameHeaderSize(src, ZSTD_frameHeaderSize_min);
Yann Collet88fcd292015-11-25 14:42:45 +0100945 if (ZSTD_isError(frameHeaderSize)) return frameHeaderSize;
946 if (srcSize < frameHeaderSize+ZSTD_blockHeaderSize) return ERROR(srcSize_wrong);
Yann Collet03ea59b2016-03-12 01:25:40 +0100947 errorCode = ZSTD_decodeFrameHeader(dctx, src, frameHeaderSize);
948 if (ZSTD_isError(errorCode)) return errorCode;
Yann Collet88fcd292015-11-25 14:42:45 +0100949 ip += frameHeaderSize; remainingSize -= frameHeaderSize;
Yann Collet88fcd292015-11-25 14:42:45 +0100950 }
Yann Collet5be2dd22015-11-11 13:43:58 +0100951
952 /* Loop on each block */
953 while (1)
954 {
955 size_t decodedSize=0;
956 size_t cBlockSize = ZSTD_getcBlockSize(ip, iend-ip, &blockProperties);
957 if (ZSTD_isError(cBlockSize)) return cBlockSize;
958
959 ip += ZSTD_blockHeaderSize;
960 remainingSize -= ZSTD_blockHeaderSize;
961 if (cBlockSize > remainingSize) return ERROR(srcSize_wrong);
962
963 switch(blockProperties.blockType)
964 {
965 case bt_compressed:
Yann Collet37422192016-01-25 16:54:05 +0100966 decodedSize = ZSTD_decompressBlock_internal(dctx, op, oend-op, ip, cBlockSize);
Yann Collet5be2dd22015-11-11 13:43:58 +0100967 break;
968 case bt_raw :
Yann Collet0f366c62015-11-12 16:19:30 +0100969 decodedSize = ZSTD_copyRawBlock(op, oend-op, ip, cBlockSize);
Yann Collet5be2dd22015-11-11 13:43:58 +0100970 break;
971 case bt_rle :
972 return ERROR(GENERIC); /* not yet supported */
973 break;
974 case bt_end :
975 /* end of frame */
976 if (remainingSize) return ERROR(srcSize_wrong);
977 break;
978 default:
979 return ERROR(GENERIC); /* impossible */
980 }
981 if (cBlockSize == 0) break; /* bt_end */
982
983 if (ZSTD_isError(decodedSize)) return decodedSize;
984 op += decodedSize;
985 ip += cBlockSize;
986 remainingSize -= cBlockSize;
987 }
988
989 return op-ostart;
990}
991
Yann Collet31683c02015-12-18 01:26:48 +0100992
Yann Collet7b51a292016-01-26 15:58:49 +0100993size_t ZSTD_decompress_usingPreparedDCtx(ZSTD_DCtx* dctx, const ZSTD_DCtx* refDCtx,
994 void* dst, size_t maxDstSize,
995 const void* src, size_t srcSize)
996{
997 ZSTD_copyDCtx(dctx, refDCtx);
998 ZSTD_checkContinuity(dctx, dst);
Yann Collet0e491c02016-03-11 21:58:04 +0100999 return ZSTD_decompressFrame(dctx, dst, maxDstSize, src, srcSize);
Yann Collet7b51a292016-01-26 15:58:49 +01001000}
1001
1002
1003size_t ZSTD_decompress_usingDict(ZSTD_DCtx* dctx,
1004 void* dst, size_t maxDstSize,
1005 const void* src, size_t srcSize,
1006 const void* dict, size_t dictSize)
1007{
1008 ZSTD_decompressBegin_usingDict(dctx, dict, dictSize);
inikepa4dde252016-03-01 14:14:35 +01001009 ZSTD_LOG_BLOCK("%p: ZSTD_decompressBegin_usingDict searchLength=%d\n", dctx->base, dctx->params.searchLength);
Yann Collet7b51a292016-01-26 15:58:49 +01001010 ZSTD_checkContinuity(dctx, dst);
Yann Collet0e491c02016-03-11 21:58:04 +01001011 return ZSTD_decompressFrame(dctx, dst, maxDstSize, src, srcSize);
Yann Collet7b51a292016-01-26 15:58:49 +01001012}
1013
1014
Yann Collet31683c02015-12-18 01:26:48 +01001015size_t ZSTD_decompressDCtx(ZSTD_DCtx* dctx, void* dst, size_t maxDstSize, const void* src, size_t srcSize)
1016{
1017 return ZSTD_decompress_usingDict(dctx, dst, maxDstSize, src, srcSize, NULL, 0);
1018}
1019
Yann Collet0e491c02016-03-11 21:58:04 +01001020
Yann Collet5be2dd22015-11-11 13:43:58 +01001021size_t ZSTD_decompress(void* dst, size_t maxDstSize, const void* src, size_t srcSize)
1022{
Yann Collet3a3b72f2016-01-11 12:56:11 +01001023#if defined(ZSTD_HEAPMODE) && (ZSTD_HEAPMODE==1)
1024 size_t regenSize;
1025 ZSTD_DCtx* dctx = ZSTD_createDCtx();
1026 if (dctx==NULL) return ERROR(memory_allocation);
1027 regenSize = ZSTD_decompressDCtx(dctx, dst, maxDstSize, src, srcSize);
1028 ZSTD_freeDCtx(dctx);
1029 return regenSize;
1030#else
Yann Collet31683c02015-12-18 01:26:48 +01001031 ZSTD_DCtx dctx;
1032 return ZSTD_decompressDCtx(&dctx, dst, maxDstSize, src, srcSize);
Yann Colleta768a302016-01-21 16:04:35 +01001033#endif
Yann Collet5be2dd22015-11-11 13:43:58 +01001034}
1035
1036
1037/* ******************************
1038* Streaming Decompression API
1039********************************/
Yann Collet5be2dd22015-11-11 13:43:58 +01001040size_t ZSTD_nextSrcSizeToDecompress(ZSTD_DCtx* dctx)
1041{
1042 return dctx->expected;
1043}
1044
Yann Collet37422192016-01-25 16:54:05 +01001045size_t ZSTD_decompressContinue(ZSTD_DCtx* dctx, void* dst, size_t maxDstSize, const void* src, size_t srcSize)
Yann Collet5be2dd22015-11-11 13:43:58 +01001046{
1047 /* Sanity check */
Yann Collet37422192016-01-25 16:54:05 +01001048 if (srcSize != dctx->expected) return ERROR(srcSize_wrong);
1049 ZSTD_checkContinuity(dctx, dst);
Yann Collet5be2dd22015-11-11 13:43:58 +01001050
Yann Collet88fcd292015-11-25 14:42:45 +01001051 /* Decompress : frame header; part 1 */
Yann Collet37422192016-01-25 16:54:05 +01001052 switch (dctx->stage)
Yann Collet5be2dd22015-11-11 13:43:58 +01001053 {
Yann Collet88fcd292015-11-25 14:42:45 +01001054 case ZSTDds_getFrameHeaderSize :
Yann Collet5be2dd22015-11-11 13:43:58 +01001055 {
Yann Collet88fcd292015-11-25 14:42:45 +01001056 /* get frame header size */
1057 if (srcSize != ZSTD_frameHeaderSize_min) return ERROR(srcSize_wrong); /* impossible */
Yann Collet03ea59b2016-03-12 01:25:40 +01001058 dctx->headerSize = ZSTD_frameHeaderSize(src, ZSTD_frameHeaderSize_min);
Yann Collet37422192016-01-25 16:54:05 +01001059 if (ZSTD_isError(dctx->headerSize)) return dctx->headerSize;
1060 memcpy(dctx->headerBuffer, src, ZSTD_frameHeaderSize_min);
Yann Collet7b51a292016-01-26 15:58:49 +01001061 if (dctx->headerSize > ZSTD_frameHeaderSize_min) {
Yann Collet37422192016-01-25 16:54:05 +01001062 dctx->expected = dctx->headerSize - ZSTD_frameHeaderSize_min;
1063 dctx->stage = ZSTDds_decodeFrameHeader;
Yann Collet88fcd292015-11-25 14:42:45 +01001064 return 0;
1065 }
Yann Collet37422192016-01-25 16:54:05 +01001066 dctx->expected = 0; /* not necessary to copy more */
Yann Collet5be2dd22015-11-11 13:43:58 +01001067 }
Yann Collet88fcd292015-11-25 14:42:45 +01001068 case ZSTDds_decodeFrameHeader:
Yann Collet5be2dd22015-11-11 13:43:58 +01001069 {
Yann Collet88fcd292015-11-25 14:42:45 +01001070 /* get frame header */
1071 size_t result;
Yann Collet37422192016-01-25 16:54:05 +01001072 memcpy(dctx->headerBuffer + ZSTD_frameHeaderSize_min, src, dctx->expected);
Yann Collet03ea59b2016-03-12 01:25:40 +01001073 result = ZSTD_decodeFrameHeader(dctx, dctx->headerBuffer, dctx->headerSize);
Yann Collet88fcd292015-11-25 14:42:45 +01001074 if (ZSTD_isError(result)) return result;
Yann Collet37422192016-01-25 16:54:05 +01001075 dctx->expected = ZSTD_blockHeaderSize;
1076 dctx->stage = ZSTDds_decodeBlockHeader;
Yann Collet88fcd292015-11-25 14:42:45 +01001077 return 0;
Yann Collet5be2dd22015-11-11 13:43:58 +01001078 }
Yann Collet88fcd292015-11-25 14:42:45 +01001079 case ZSTDds_decodeBlockHeader:
Yann Collet5be2dd22015-11-11 13:43:58 +01001080 {
Yann Collet88fcd292015-11-25 14:42:45 +01001081 /* Decode block header */
1082 blockProperties_t bp;
1083 size_t blockSize = ZSTD_getcBlockSize(src, ZSTD_blockHeaderSize, &bp);
1084 if (ZSTD_isError(blockSize)) return blockSize;
Yann Collet7b51a292016-01-26 15:58:49 +01001085 if (bp.blockType == bt_end) {
Yann Collet37422192016-01-25 16:54:05 +01001086 dctx->expected = 0;
1087 dctx->stage = ZSTDds_getFrameHeaderSize;
Yann Collet88fcd292015-11-25 14:42:45 +01001088 }
Yann Collet7b51a292016-01-26 15:58:49 +01001089 else {
Yann Collet37422192016-01-25 16:54:05 +01001090 dctx->expected = blockSize;
1091 dctx->bType = bp.blockType;
1092 dctx->stage = ZSTDds_decompressBlock;
Yann Collet88fcd292015-11-25 14:42:45 +01001093 }
Yann Collet88fcd292015-11-25 14:42:45 +01001094 return 0;
1095 }
Yann Collet417890c2015-12-04 17:16:37 +01001096 case ZSTDds_decompressBlock:
Yann Collet88fcd292015-11-25 14:42:45 +01001097 {
1098 /* Decompress : block content */
1099 size_t rSize;
Yann Collet37422192016-01-25 16:54:05 +01001100 switch(dctx->bType)
Yann Collet88fcd292015-11-25 14:42:45 +01001101 {
1102 case bt_compressed:
Yann Collet37422192016-01-25 16:54:05 +01001103 rSize = ZSTD_decompressBlock_internal(dctx, dst, maxDstSize, src, srcSize);
Yann Collet88fcd292015-11-25 14:42:45 +01001104 break;
1105 case bt_raw :
1106 rSize = ZSTD_copyRawBlock(dst, maxDstSize, src, srcSize);
1107 break;
1108 case bt_rle :
1109 return ERROR(GENERIC); /* not yet handled */
1110 break;
1111 case bt_end : /* should never happen (filtered at phase 1) */
1112 rSize = 0;
1113 break;
1114 default:
Yann Collet7b51a292016-01-26 15:58:49 +01001115 return ERROR(GENERIC); /* impossible */
Yann Collet88fcd292015-11-25 14:42:45 +01001116 }
Yann Collet37422192016-01-25 16:54:05 +01001117 dctx->stage = ZSTDds_decodeBlockHeader;
1118 dctx->expected = ZSTD_blockHeaderSize;
1119 dctx->previousDstEnd = (char*)dst + rSize;
Yann Collet88fcd292015-11-25 14:42:45 +01001120 return rSize;
1121 }
1122 default:
1123 return ERROR(GENERIC); /* impossible */
1124 }
Yann Collet5be2dd22015-11-11 13:43:58 +01001125}
1126
1127
Yann Colletb923f652016-01-26 03:14:20 +01001128static void ZSTD_refDictContent(ZSTD_DCtx* dctx, const void* dict, size_t dictSize)
Yann Collet417890c2015-12-04 17:16:37 +01001129{
Yann Collet37422192016-01-25 16:54:05 +01001130 dctx->dictEnd = dctx->previousDstEnd;
1131 dctx->vBase = (const char*)dict - ((const char*)(dctx->previousDstEnd) - (const char*)(dctx->base));
1132 dctx->base = dict;
1133 dctx->previousDstEnd = (const char*)dict + dictSize;
Yann Collet417890c2015-12-04 17:16:37 +01001134}
Yann Colletb923f652016-01-26 03:14:20 +01001135
Yann Colletb923f652016-01-26 03:14:20 +01001136static size_t ZSTD_loadEntropy(ZSTD_DCtx* dctx, const void* dict, size_t dictSize)
1137{
Yann Colletfb810d62016-01-28 00:18:06 +01001138 size_t hSize, offcodeHeaderSize, matchlengthHeaderSize, errorCode, litlengthHeaderSize;
1139 short offcodeNCount[MaxOff+1];
1140 U32 offcodeMaxValue=MaxOff, offcodeLog=OffFSELog;
1141 short matchlengthNCount[MaxML+1];
1142 unsigned matchlengthMaxValue = MaxML, matchlengthLog = MLFSELog;
1143 short litlengthNCount[MaxLL+1];
1144 unsigned litlengthMaxValue = MaxLL, litlengthLog = LLFSELog;
1145
1146 hSize = HUF_readDTableX4(dctx->hufTableX4, dict, dictSize);
Yann Colletb923f652016-01-26 03:14:20 +01001147 if (HUF_isError(hSize)) return ERROR(dictionary_corrupted);
Yann Colletfb810d62016-01-28 00:18:06 +01001148 dict = (const char*)dict + hSize;
1149 dictSize -= hSize;
1150
1151 offcodeHeaderSize = FSE_readNCount(offcodeNCount, &offcodeMaxValue, &offcodeLog, dict, dictSize);
1152 if (FSE_isError(offcodeHeaderSize)) return ERROR(dictionary_corrupted);
1153 errorCode = FSE_buildDTable(dctx->OffTable, offcodeNCount, offcodeMaxValue, offcodeLog);
1154 if (FSE_isError(errorCode)) return ERROR(dictionary_corrupted);
1155 dict = (const char*)dict + offcodeHeaderSize;
1156 dictSize -= offcodeHeaderSize;
1157
1158 matchlengthHeaderSize = FSE_readNCount(matchlengthNCount, &matchlengthMaxValue, &matchlengthLog, dict, dictSize);
1159 if (FSE_isError(matchlengthHeaderSize)) return ERROR(dictionary_corrupted);
1160 errorCode = FSE_buildDTable(dctx->MLTable, matchlengthNCount, matchlengthMaxValue, matchlengthLog);
1161 if (FSE_isError(errorCode)) return ERROR(dictionary_corrupted);
1162 dict = (const char*)dict + matchlengthHeaderSize;
1163 dictSize -= matchlengthHeaderSize;
1164
1165 litlengthHeaderSize = FSE_readNCount(litlengthNCount, &litlengthMaxValue, &litlengthLog, dict, dictSize);
1166 if (FSE_isError(litlengthHeaderSize)) return ERROR(dictionary_corrupted);
1167 errorCode = FSE_buildDTable(dctx->LLTable, litlengthNCount, litlengthMaxValue, litlengthLog);
1168 if (FSE_isError(errorCode)) return ERROR(dictionary_corrupted);
1169
1170 dctx->flagStaticTables = 1;
1171 return hSize + offcodeHeaderSize + matchlengthHeaderSize + litlengthHeaderSize;
Yann Colletb923f652016-01-26 03:14:20 +01001172}
1173
Yann Collet7b51a292016-01-26 15:58:49 +01001174static size_t ZSTD_decompress_insertDictionary(ZSTD_DCtx* dctx, const void* dict, size_t dictSize)
Yann Colletb923f652016-01-26 03:14:20 +01001175{
1176 size_t eSize;
1177 U32 magic = MEM_readLE32(dict);
1178 if (magic != ZSTD_DICT_MAGIC) {
1179 /* pure content mode */
1180 ZSTD_refDictContent(dctx, dict, dictSize);
1181 return 0;
1182 }
1183 /* load entropy tables */
1184 dict = (const char*)dict + 4;
1185 dictSize -= 4;
1186 eSize = ZSTD_loadEntropy(dctx, dict, dictSize);
1187 if (ZSTD_isError(eSize)) return ERROR(dictionary_corrupted);
1188
1189 /* reference dictionary content */
1190 dict = (const char*)dict + eSize;
1191 dictSize -= eSize;
1192 ZSTD_refDictContent(dctx, dict, dictSize);
1193
1194 return 0;
1195}
1196
Yann Collet7b51a292016-01-26 15:58:49 +01001197
1198size_t ZSTD_decompressBegin_usingDict(ZSTD_DCtx* dctx, const void* dict, size_t dictSize)
1199{
1200 size_t errorCode;
1201 errorCode = ZSTD_decompressBegin(dctx);
1202 if (ZSTD_isError(errorCode)) return errorCode;
1203
1204 if (dict && dictSize) {
1205 errorCode = ZSTD_decompress_insertDictionary(dctx, dict, dictSize);
1206 if (ZSTD_isError(errorCode)) return ERROR(dictionary_corrupted);
1207 }
1208
1209 return 0;
1210}
1211