blob: a26d95fc16ca023d576ac94e6508bb4eefe8ade9 [file] [log] [blame]
Yann Collet5be2dd22015-11-11 13:43:58 +01001/*
2 zstd - standard compression library
3 Copyright (C) 2014-2015, Yann Collet.
4
5 BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
6
7 Redistribution and use in source and binary forms, with or without
8 modification, are permitted provided that the following conditions are
9 met:
10 * Redistributions of source code must retain the above copyright
11 notice, this list of conditions and the following disclaimer.
12 * Redistributions in binary form must reproduce the above
13 copyright notice, this list of conditions and the following disclaimer
14 in the documentation and/or other materials provided with the
15 distribution.
16 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28 You can contact the author at :
29 - zstd source repository : https://github.com/Cyan4973/zstd
30 - ztsd public forum : https://groups.google.com/forum/#!forum/lz4c
31*/
32
33/* ***************************************************************
34* Tuning parameters
35*****************************************************************/
36/*!
Yann Collet5be2dd22015-11-11 13:43:58 +010037 * HEAPMODE :
Yann Collet3a3b72f2016-01-11 12:56:11 +010038 * Select how default decompression function ZSTD_decompress() will allocate memory,
39 * in memory stack (0), or in memory heap (1, requires malloc())
Yann Collet5be2dd22015-11-11 13:43:58 +010040 */
41#ifndef ZSTD_HEAPMODE
42# define ZSTD_HEAPMODE 1
Yann Collet3a3b72f2016-01-11 12:56:11 +010043#endif
Yann Collet5be2dd22015-11-11 13:43:58 +010044
45/*!
46* LEGACY_SUPPORT :
Yann Colletfba6aed2016-01-18 12:03:27 +010047* ZSTD_decompress() can decode older formats (v0.1+) if set to 1
Yann Collet5be2dd22015-11-11 13:43:58 +010048*/
49#ifndef ZSTD_LEGACY_SUPPORT
Yann Colletfba6aed2016-01-18 12:03:27 +010050# define ZSTD_LEGACY_SUPPORT 0
Yann Collet5be2dd22015-11-11 13:43:58 +010051#endif
52
53
Yann Colletfb810d62016-01-28 00:18:06 +010054/*-*******************************************************
Yann Collet5be2dd22015-11-11 13:43:58 +010055* Includes
56*********************************************************/
57#include <stdlib.h> /* calloc */
58#include <string.h> /* memcpy, memmove */
59#include <stdio.h> /* debug : printf */
60#include "mem.h" /* low level memory routines */
61#include "zstd_static.h"
62#include "zstd_internal.h"
63#include "fse_static.h"
Yann Colletafe07092016-01-25 04:10:46 +010064#include "huff0_static.h"
Yann Collet5be2dd22015-11-11 13:43:58 +010065
66#if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT==1)
67# include "zstd_legacy.h"
68#endif
69
Yann Colletfb810d62016-01-28 00:18:06 +010070
71/*-*******************************************************
Yann Collet5be2dd22015-11-11 13:43:58 +010072* Compiler specifics
73*********************************************************/
Yann Collet5be2dd22015-11-11 13:43:58 +010074#ifdef _MSC_VER /* Visual Studio */
75# define FORCE_INLINE static __forceinline
76# include <intrin.h> /* For Visual 2005 */
77# pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */
78# pragma warning(disable : 4324) /* disable: C4324: padded structure */
79#else
80# define GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__)
81# ifdef __GNUC__
82# define FORCE_INLINE static inline __attribute__((always_inline))
83# else
84# define FORCE_INLINE static inline
85# endif
86#endif
87
88
Yann Colletfb810d62016-01-28 00:18:06 +010089/*-*************************************
Yann Collet14983e72015-11-11 21:38:21 +010090* Local types
91***************************************/
92typedef struct
93{
94 blockType_t blockType;
95 U32 origSize;
96} blockProperties_t;
Yann Collet5be2dd22015-11-11 13:43:58 +010097
98
99/* *******************************************************
100* Memory operations
101**********************************************************/
102static void ZSTD_copy4(void* dst, const void* src) { memcpy(dst, src, 4); }
103
104
Yann Collet5be2dd22015-11-11 13:43:58 +0100105/* *************************************
106* Error Management
107***************************************/
Yann Collet14983e72015-11-11 21:38:21 +0100108unsigned ZSTD_versionNumber (void) { return ZSTD_VERSION_NUMBER; }
109
Yann Collet5be2dd22015-11-11 13:43:58 +0100110/*! ZSTD_isError
111* tells if a return value is an error code */
112unsigned ZSTD_isError(size_t code) { return ERR_isError(code); }
113
114/*! ZSTD_getErrorName
115* provides error code string (useful for debugging) */
116const char* ZSTD_getErrorName(size_t code) { return ERR_getErrorName(code); }
117
118
Yann Collet5be2dd22015-11-11 13:43:58 +0100119/* *************************************************************
Yann Collet5b78d2f2015-11-12 15:36:05 +0100120* Context management
Yann Collet5be2dd22015-11-11 13:43:58 +0100121***************************************************************/
Yann Collete4fdad52015-11-25 21:09:17 +0100122typedef enum { ZSTDds_getFrameHeaderSize, ZSTDds_decodeFrameHeader,
Yann Collet88fcd292015-11-25 14:42:45 +0100123 ZSTDds_decodeBlockHeader, ZSTDds_decompressBlock } ZSTD_dStage;
124
Yann Collet5be2dd22015-11-11 13:43:58 +0100125struct ZSTD_DCtx_s
126{
Yann Colletfb810d62016-01-28 00:18:06 +0100127 FSE_DTable LLTable[FSE_DTABLE_SIZE_U32(LLFSELog)];
128 FSE_DTable OffTable[FSE_DTABLE_SIZE_U32(OffFSELog)];
129 FSE_DTable MLTable[FSE_DTABLE_SIZE_U32(MLFSELog)];
130 unsigned hufTableX4[HUF_DTABLE_SIZE(HufLog)];
Yann Collet417890c2015-12-04 17:16:37 +0100131 const void* previousDstEnd;
132 const void* base;
133 const void* vBase;
134 const void* dictEnd;
Yann Collet5be2dd22015-11-11 13:43:58 +0100135 size_t expected;
Yann Collet88fcd292015-11-25 14:42:45 +0100136 size_t headerSize;
137 ZSTD_parameters params;
Yann Colletfb810d62016-01-28 00:18:06 +0100138 blockType_t bType; /* used in ZSTD_decompressContinue(), to transfer blockType between header decoding and block decoding stages */
Yann Collet88fcd292015-11-25 14:42:45 +0100139 ZSTD_dStage stage;
Yann Colletfb810d62016-01-28 00:18:06 +0100140 U32 flagStaticTables;
Yann Collet5be2dd22015-11-11 13:43:58 +0100141 const BYTE* litPtr;
142 size_t litBufSize;
143 size_t litSize;
Yann Colletb923f652016-01-26 03:14:20 +0100144 BYTE litBuffer[BLOCKSIZE + WILDCOPY_OVERLENGTH];
Yann Collet88fcd292015-11-25 14:42:45 +0100145 BYTE headerBuffer[ZSTD_frameHeaderSize_max];
Yann Collet417890c2015-12-04 17:16:37 +0100146}; /* typedef'd to ZSTD_DCtx within "zstd_static.h" */
Yann Collet5be2dd22015-11-11 13:43:58 +0100147
Yann Colletfb810d62016-01-28 00:18:06 +0100148size_t sizeofDCtx (void) { return sizeof(ZSTD_DCtx); }
149
Yann Collet7b51a292016-01-26 15:58:49 +0100150size_t ZSTD_decompressBegin(ZSTD_DCtx* dctx)
Yann Collet5b78d2f2015-11-12 15:36:05 +0100151{
Yann Collet88fcd292015-11-25 14:42:45 +0100152 dctx->expected = ZSTD_frameHeaderSize_min;
153 dctx->stage = ZSTDds_getFrameHeaderSize;
Yann Collet5b78d2f2015-11-12 15:36:05 +0100154 dctx->previousDstEnd = NULL;
155 dctx->base = NULL;
156 dctx->vBase = NULL;
157 dctx->dictEnd = NULL;
Yann Colletb923f652016-01-26 03:14:20 +0100158 dctx->hufTableX4[0] = HufLog;
Yann Colletfb810d62016-01-28 00:18:06 +0100159 dctx->flagStaticTables = 0;
Yann Collet5b78d2f2015-11-12 15:36:05 +0100160 return 0;
161}
162
163ZSTD_DCtx* ZSTD_createDCtx(void)
164{
165 ZSTD_DCtx* dctx = (ZSTD_DCtx*)malloc(sizeof(ZSTD_DCtx));
166 if (dctx==NULL) return NULL;
Yann Collet7b51a292016-01-26 15:58:49 +0100167 ZSTD_decompressBegin(dctx);
Yann Collet5b78d2f2015-11-12 15:36:05 +0100168 return dctx;
169}
170
171size_t ZSTD_freeDCtx(ZSTD_DCtx* dctx)
172{
173 free(dctx);
174 return 0;
175}
176
Yann Collet7b51a292016-01-26 15:58:49 +0100177void ZSTD_copyDCtx(ZSTD_DCtx* dstDCtx, const ZSTD_DCtx* srcDCtx)
178{
179 memcpy(dstDCtx, srcDCtx,
180 sizeof(ZSTD_DCtx) - (BLOCKSIZE+WILDCOPY_OVERLENGTH + ZSTD_frameHeaderSize_max)); /* no need to copy workspace */
181}
182
Yann Collet5b78d2f2015-11-12 15:36:05 +0100183
184/* *************************************************************
185* Decompression section
186***************************************************************/
Yann Collet59d1f792016-01-23 19:28:41 +0100187
188/* Frame format description
189 Frame Header - [ Block Header - Block ] - Frame End
190 1) Frame Header
191 - 4 bytes - Magic Number : ZSTD_MAGICNUMBER (defined within zstd_internal.h)
192 - 1 byte - Window Descriptor
193 2) Block Header
194 - 3 bytes, starting with a 2-bits descriptor
195 Uncompressed, Compressed, Frame End, unused
196 3) Block
197 See Block Format Description
198 4) Frame End
199 - 3 bytes, compatible with Block Header
200*/
201
202/* Block format description
Yann Colletfb810d62016-01-28 00:18:06 +0100203
204 Block = Literal Section - Sequences Section
205 Prerequisite : size of (compressed) block, maximum size of regenerated data
206
Yann Collet59d1f792016-01-23 19:28:41 +0100207 1) Literal Section
Yann Colletfb810d62016-01-28 00:18:06 +0100208
209 1.1) Header : 1-5 bytes
210 flags: 2 bits
Yann Collet59d1f792016-01-23 19:28:41 +0100211 00 compressed by Huff0
Yann Colletfb810d62016-01-28 00:18:06 +0100212 01 unused
213 10 is Raw (uncompressed)
214 11 is Rle
215 Note : using 01 => Huff0 with precomputed table ?
Yann Collet59d1f792016-01-23 19:28:41 +0100216 Note : delta map ? => compressed ?
Yann Colletfb810d62016-01-28 00:18:06 +0100217
218 1.1.1) Huff0-compressed literal block : 3-5 bytes
219 srcSize < 1 KB => 3 bytes (2-2-10-10) => single stream
220 srcSize < 1 KB => 3 bytes (2-2-10-10)
221 srcSize < 16KB => 4 bytes (2-2-14-14)
222 else => 5 bytes (2-2-18-18)
223 big endian convention
224
225 1.1.2) Raw (uncompressed) literal block header : 1-3 bytes
226 size : 5 bits: (IS_RAW<<6) + (0<<4) + size
227 12 bits: (IS_RAW<<6) + (2<<4) + (size>>8)
228 size&255
229 20 bits: (IS_RAW<<6) + (3<<4) + (size>>16)
230 size>>8&255
231 size&255
232
233 1.1.3) Rle (repeated single byte) literal block header : 1-3 bytes
234 size : 5 bits: (IS_RLE<<6) + (0<<4) + size
235 12 bits: (IS_RLE<<6) + (2<<4) + (size>>8)
236 size&255
237 20 bits: (IS_RLE<<6) + (3<<4) + (size>>16)
238 size>>8&255
239 size&255
240
241 1.1.4) Huff0-compressed literal block, using precomputed CTables : 3-5 bytes
242 srcSize < 1 KB => 3 bytes (2-2-10-10) => single stream
243 srcSize < 1 KB => 3 bytes (2-2-10-10)
244 srcSize < 16KB => 4 bytes (2-2-14-14)
245 else => 5 bytes (2-2-18-18)
246 big endian convention
247
248 1- CTable available (stored into workspace ?)
249 2- Small input (fast heuristic ? Full comparison ? depend on clevel ?)
250
251
252 1.2) Literal block content
Yann Collet59d1f792016-01-23 19:28:41 +0100253
254 1.2.1) Huff0 block, using sizes from header
255 See Huff0 format
256
Yann Colletfb810d62016-01-28 00:18:06 +0100257 1.2.2) Huff0 block, using prepared table
Yann Collet59d1f792016-01-23 19:28:41 +0100258
Yann Colletfb810d62016-01-28 00:18:06 +0100259 1.2.3) Raw content
260
261 1.2.4) single byte
262
Yann Collet59d1f792016-01-23 19:28:41 +0100263
264 2) Sequences section
265 TO DO
266*/
267
268
Yann Collet88fcd292015-11-25 14:42:45 +0100269/** ZSTD_decodeFrameHeader_Part1
270* decode the 1st part of the Frame Header, which tells Frame Header size.
271* srcSize must be == ZSTD_frameHeaderSize_min
272* @return : the full size of the Frame Header */
273static size_t ZSTD_decodeFrameHeader_Part1(ZSTD_DCtx* zc, const void* src, size_t srcSize)
274{
275 U32 magicNumber;
Yann Collet61e16ce2016-01-31 02:04:15 +0100276 if (srcSize != ZSTD_frameHeaderSize_min)
277 return ERROR(srcSize_wrong);
Yann Collet88fcd292015-11-25 14:42:45 +0100278 magicNumber = MEM_readLE32(src);
279 if (magicNumber != ZSTD_MAGICNUMBER) return ERROR(prefix_unknown);
280 zc->headerSize = ZSTD_frameHeaderSize_min;
281 return zc->headerSize;
282}
283
Yann Collet88fcd292015-11-25 14:42:45 +0100284
285size_t ZSTD_getFrameParams(ZSTD_parameters* params, const void* src, size_t srcSize)
286{
287 U32 magicNumber;
288 if (srcSize < ZSTD_frameHeaderSize_min) return ZSTD_frameHeaderSize_max;
289 magicNumber = MEM_readLE32(src);
290 if (magicNumber != ZSTD_MAGICNUMBER) return ERROR(prefix_unknown);
291 memset(params, 0, sizeof(*params));
Yann Collet26415d32015-11-26 12:43:28 +0100292 params->windowLog = (((const BYTE*)src)[4] & 15) + ZSTD_WINDOWLOG_ABSOLUTEMIN;
Yann Colletbf7aa3c2015-11-28 18:19:44 +0100293 if ((((const BYTE*)src)[4] >> 4) != 0) return ERROR(frameParameter_unsupported); /* reserved bits */
Yann Collet88fcd292015-11-25 14:42:45 +0100294 return 0;
295}
296
Yann Collet26415d32015-11-26 12:43:28 +0100297/** ZSTD_decodeFrameHeader_Part2
298* decode the full Frame Header
299* srcSize must be the size provided by ZSTD_decodeFrameHeader_Part1
300* @return : 0, or an error code, which can be tested using ZSTD_isError() */
301static size_t ZSTD_decodeFrameHeader_Part2(ZSTD_DCtx* zc, const void* src, size_t srcSize)
302{
Yann Collet00fd7a22015-11-28 16:03:22 +0100303 size_t result;
Yann Collet61e16ce2016-01-31 02:04:15 +0100304 if (srcSize != zc->headerSize)
305 return ERROR(srcSize_wrong);
Yann Collet00fd7a22015-11-28 16:03:22 +0100306 result = ZSTD_getFrameParams(&(zc->params), src, srcSize);
307 if ((MEM_32bits()) && (zc->params.windowLog > 25)) return ERROR(frameParameter_unsupportedBy32bitsImplementation);
308 return result;
Yann Collet26415d32015-11-26 12:43:28 +0100309}
310
Yann Collet5be2dd22015-11-11 13:43:58 +0100311
312size_t ZSTD_getcBlockSize(const void* src, size_t srcSize, blockProperties_t* bpPtr)
313{
314 const BYTE* const in = (const BYTE* const)src;
315 BYTE headerFlags;
316 U32 cSize;
317
Yann Collet61e16ce2016-01-31 02:04:15 +0100318 if (srcSize < 3)
319 return ERROR(srcSize_wrong);
Yann Collet5be2dd22015-11-11 13:43:58 +0100320
321 headerFlags = *in;
322 cSize = in[2] + (in[1]<<8) + ((in[0] & 7)<<16);
323
324 bpPtr->blockType = (blockType_t)(headerFlags >> 6);
325 bpPtr->origSize = (bpPtr->blockType == bt_rle) ? cSize : 0;
326
327 if (bpPtr->blockType == bt_end) return 0;
328 if (bpPtr->blockType == bt_rle) return 1;
329 return cSize;
330}
331
Yann Collet59d1f792016-01-23 19:28:41 +0100332
Yann Collet0f366c62015-11-12 16:19:30 +0100333static size_t ZSTD_copyRawBlock(void* dst, size_t maxDstSize, const void* src, size_t srcSize)
Yann Collet5be2dd22015-11-11 13:43:58 +0100334{
335 if (srcSize > maxDstSize) return ERROR(dstSize_tooSmall);
336 memcpy(dst, src, srcSize);
337 return srcSize;
338}
339
340
Yann Collet61e16ce2016-01-31 02:04:15 +0100341/*! ZSTD_decodeLiteralsBlock
Yann Collet14983e72015-11-11 21:38:21 +0100342 @return : nb of bytes read from src (< srcSize ) */
Yann Collet5b78d2f2015-11-12 15:36:05 +0100343size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx,
Yann Collet5be2dd22015-11-11 13:43:58 +0100344 const void* src, size_t srcSize) /* note : srcSize < BLOCKSIZE */
345{
Yann Collet5be2dd22015-11-11 13:43:58 +0100346 const BYTE* const istart = (const BYTE*) src;
347
348 /* any compressed block with literals segment must be at least this size */
349 if (srcSize < MIN_CBLOCK_SIZE) return ERROR(corruption_detected);
350
Yann Collet59d1f792016-01-23 19:28:41 +0100351 switch(istart[0]>> 6)
Yann Collet5be2dd22015-11-11 13:43:58 +0100352 {
Yann Collet59d1f792016-01-23 19:28:41 +0100353 case IS_HUF:
Yann Collet5be2dd22015-11-11 13:43:58 +0100354 {
Yann Colletafe07092016-01-25 04:10:46 +0100355 size_t litSize, litCSize, singleStream=0;
Yann Collet59d1f792016-01-23 19:28:41 +0100356 U32 lhSize = ((istart[0]) >> 4) & 3;
357 switch(lhSize)
358 {
359 case 0: case 1: default: /* note : default is impossible, since lhSize into [0..3] */
360 /* 2 - 2 - 10 - 10 */
361 lhSize=3;
Yann Colletafe07092016-01-25 04:10:46 +0100362 singleStream = istart[0] & 16;
Yann Collet59d1f792016-01-23 19:28:41 +0100363 litSize = ((istart[0] & 15) << 6) + (istart[1] >> 2);
364 litCSize = ((istart[1] & 3) << 8) + istart[2];
365 break;
366 case 2:
367 /* 2 - 2 - 14 - 14 */
368 lhSize=4;
369 litSize = ((istart[0] & 15) << 10) + (istart[1] << 2) + (istart[2] >> 6);
370 litCSize = ((istart[2] & 63) << 8) + istart[3];
371 break;
372 case 3:
373 /* 2 - 2 - 18 - 18 */
374 lhSize=5;
375 litSize = ((istart[0] & 15) << 14) + (istart[1] << 6) + (istart[2] >> 2);
376 litCSize = ((istart[2] & 3) << 16) + (istart[3] << 8) + istart[4];
377 break;
378 }
Yann Colletfb810d62016-01-28 00:18:06 +0100379 if (litSize > BLOCKSIZE) return ERROR(corruption_detected);
Yann Collet59d1f792016-01-23 19:28:41 +0100380
Yann Colletafe07092016-01-25 04:10:46 +0100381 if (HUF_isError(singleStream ?
382 HUF_decompress1X2(dctx->litBuffer, litSize, istart+lhSize, litCSize) :
383 HUF_decompress (dctx->litBuffer, litSize, istart+lhSize, litCSize) ))
Yann Collet59d1f792016-01-23 19:28:41 +0100384 return ERROR(corruption_detected);
385
Yann Collet5be2dd22015-11-11 13:43:58 +0100386 dctx->litPtr = dctx->litBuffer;
387 dctx->litBufSize = BLOCKSIZE+8;
388 dctx->litSize = litSize;
Yann Collet59d1f792016-01-23 19:28:41 +0100389 return litCSize + lhSize;
Yann Collet5be2dd22015-11-11 13:43:58 +0100390 }
Yann Colletb923f652016-01-26 03:14:20 +0100391 case IS_PCH:
392 {
393 size_t errorCode;
394 size_t litSize, litCSize;
395 U32 lhSize = ((istart[0]) >> 4) & 3;
396 if (lhSize != 1) /* only case supported for now : small litSize, single stream */
397 return ERROR(corruption_detected);
Yann Colletfb810d62016-01-28 00:18:06 +0100398 if (!dctx->flagStaticTables)
Yann Collet7b51a292016-01-26 15:58:49 +0100399 return ERROR(dictionary_corrupted);
Yann Colletb923f652016-01-26 03:14:20 +0100400
401 /* 2 - 2 - 10 - 10 */
402 lhSize=3;
403 litSize = ((istart[0] & 15) << 6) + (istart[1] >> 2);
404 litCSize = ((istart[1] & 3) << 8) + istart[2];
405
406 errorCode = HUF_decompress1X4_usingDTable(dctx->litBuffer, litSize, istart+lhSize, litCSize, dctx->hufTableX4);
407 if (HUF_isError(errorCode)) return ERROR(corruption_detected);
408
409 dctx->litPtr = dctx->litBuffer;
410 dctx->litBufSize = BLOCKSIZE+WILDCOPY_OVERLENGTH;
411 dctx->litSize = litSize;
412 return litCSize + lhSize;
413 }
Yann Collet5be2dd22015-11-11 13:43:58 +0100414 case IS_RAW:
415 {
Yann Collet59d1f792016-01-23 19:28:41 +0100416 size_t litSize;
417 U32 lhSize = ((istart[0]) >> 4) & 3;
418 switch(lhSize)
Yann Collet5be2dd22015-11-11 13:43:58 +0100419 {
Yann Collet59d1f792016-01-23 19:28:41 +0100420 case 0: case 1: default: /* note : default is impossible, since lhSize into [0..3] */
421 lhSize=1;
422 litSize = istart[0] & 31;
423 break;
424 case 2:
425 litSize = ((istart[0] & 15) << 8) + istart[1];
426 break;
427 case 3:
428 litSize = ((istart[0] & 15) << 16) + (istart[1] << 8) + istart[2];
429 break;
430 }
431
Yann Collet61e16ce2016-01-31 02:04:15 +0100432 if (lhSize+litSize+WILDCOPY_OVERLENGTH > srcSize) { /* risk reading beyond src buffer with wildcopy */
Yann Collet37422192016-01-25 16:54:05 +0100433 if (litSize > srcSize-lhSize) return ERROR(corruption_detected);
Yann Collet59d1f792016-01-23 19:28:41 +0100434 memcpy(dctx->litBuffer, istart+lhSize, litSize);
Yann Collet5be2dd22015-11-11 13:43:58 +0100435 dctx->litPtr = dctx->litBuffer;
436 dctx->litBufSize = BLOCKSIZE+8;
437 dctx->litSize = litSize;
Yann Colletbc4c8aa2016-01-25 17:26:01 +0100438 return lhSize+litSize;
Yann Collet5be2dd22015-11-11 13:43:58 +0100439 }
440 /* direct reference into compressed stream */
Yann Collet59d1f792016-01-23 19:28:41 +0100441 dctx->litPtr = istart+lhSize;
442 dctx->litBufSize = srcSize-lhSize;
Yann Collet5be2dd22015-11-11 13:43:58 +0100443 dctx->litSize = litSize;
Yann Collet59d1f792016-01-23 19:28:41 +0100444 return lhSize+litSize;
445 }
Yann Collet5be2dd22015-11-11 13:43:58 +0100446 case IS_RLE:
447 {
Yann Collet59d1f792016-01-23 19:28:41 +0100448 size_t litSize;
449 U32 lhSize = ((istart[0]) >> 4) & 3;
450 switch(lhSize)
451 {
452 case 0: case 1: default: /* note : default is impossible, since lhSize into [0..3] */
453 lhSize = 1;
454 litSize = istart[0] & 31;
455 break;
456 case 2:
457 litSize = ((istart[0] & 15) << 8) + istart[1];
458 break;
459 case 3:
460 litSize = ((istart[0] & 15) << 16) + (istart[1] << 8) + istart[2];
461 break;
462 }
Yann Collet5be2dd22015-11-11 13:43:58 +0100463 if (litSize > BLOCKSIZE) return ERROR(corruption_detected);
Yann Collet59d1f792016-01-23 19:28:41 +0100464 memset(dctx->litBuffer, istart[lhSize], litSize);
Yann Collet5be2dd22015-11-11 13:43:58 +0100465 dctx->litPtr = dctx->litBuffer;
Yann Colletb923f652016-01-26 03:14:20 +0100466 dctx->litBufSize = BLOCKSIZE+WILDCOPY_OVERLENGTH;
Yann Collet5be2dd22015-11-11 13:43:58 +0100467 dctx->litSize = litSize;
Yann Collet59d1f792016-01-23 19:28:41 +0100468 return lhSize+1;
Yann Collet5be2dd22015-11-11 13:43:58 +0100469 }
Yann Colletb923f652016-01-26 03:14:20 +0100470 default:
471 return ERROR(corruption_detected); /* impossible */
Yann Collet5be2dd22015-11-11 13:43:58 +0100472 }
473}
474
475
476size_t ZSTD_decodeSeqHeaders(int* nbSeq, const BYTE** dumpsPtr, size_t* dumpsLengthPtr,
477 FSE_DTable* DTableLL, FSE_DTable* DTableML, FSE_DTable* DTableOffb,
478 const void* src, size_t srcSize)
479{
480 const BYTE* const istart = (const BYTE* const)src;
481 const BYTE* ip = istart;
482 const BYTE* const iend = istart + srcSize;
483 U32 LLtype, Offtype, MLtype;
484 U32 LLlog, Offlog, MLlog;
485 size_t dumpsLength;
486
487 /* check */
Yann Collet61e16ce2016-01-31 02:04:15 +0100488 if (srcSize < MIN_SEQUENCES_SIZE)
489 return ERROR(srcSize_wrong);
Yann Collet5be2dd22015-11-11 13:43:58 +0100490
491 /* SeqHead */
Yann Collet61e16ce2016-01-31 02:04:15 +0100492 *nbSeq = *ip++;
493 if (*nbSeq==0) return 1;
494 if (*nbSeq >= 128)
495 *nbSeq = ((nbSeq[0]-128)<<8) + *ip++;
Yann Collete93d6ce2016-01-31 00:58:06 +0100496
Yann Collet5be2dd22015-11-11 13:43:58 +0100497 LLtype = *ip >> 6;
498 Offtype = (*ip >> 4) & 3;
499 MLtype = (*ip >> 2) & 3;
Yann Colletfb810d62016-01-28 00:18:06 +0100500 if (*ip & 2) {
Yann Collet5be2dd22015-11-11 13:43:58 +0100501 dumpsLength = ip[2];
502 dumpsLength += ip[1] << 8;
503 ip += 3;
Yann Colletfb810d62016-01-28 00:18:06 +0100504 } else {
Yann Collet5be2dd22015-11-11 13:43:58 +0100505 dumpsLength = ip[1];
506 dumpsLength += (ip[0] & 1) << 8;
507 ip += 2;
508 }
509 *dumpsPtr = ip;
510 ip += dumpsLength;
511 *dumpsLengthPtr = dumpsLength;
512
513 /* check */
514 if (ip > iend-3) return ERROR(srcSize_wrong); /* min : all 3 are "raw", hence no header, but at least xxLog bits per type */
515
516 /* sequences */
517 {
Yann Collet82368cf2015-11-16 19:10:56 +0100518 S16 norm[MaxML+1]; /* assumption : MaxML >= MaxLL >= MaxOff */
Yann Collet5be2dd22015-11-11 13:43:58 +0100519 size_t headerSize;
520
521 /* Build DTables */
522 switch(LLtype)
523 {
524 U32 max;
Yann Colletfb810d62016-01-28 00:18:06 +0100525 case FSE_ENCODING_RLE :
Yann Collet5be2dd22015-11-11 13:43:58 +0100526 LLlog = 0;
Yann Colletfb810d62016-01-28 00:18:06 +0100527 FSE_buildDTable_rle(DTableLL, *ip++);
528 break;
529 case FSE_ENCODING_RAW :
Yann Collet5be2dd22015-11-11 13:43:58 +0100530 LLlog = LLbits;
Yann Colletfb810d62016-01-28 00:18:06 +0100531 FSE_buildDTable_raw(DTableLL, LLbits);
532 break;
533 case FSE_ENCODING_STATIC:
534 break;
535 case FSE_ENCODING_DYNAMIC :
536 default : /* impossible */
Yann Collet5be2dd22015-11-11 13:43:58 +0100537 max = MaxLL;
538 headerSize = FSE_readNCount(norm, &max, &LLlog, ip, iend-ip);
539 if (FSE_isError(headerSize)) return ERROR(GENERIC);
540 if (LLlog > LLFSELog) return ERROR(corruption_detected);
541 ip += headerSize;
542 FSE_buildDTable(DTableLL, norm, max, LLlog);
543 }
544
545 switch(Offtype)
546 {
547 U32 max;
Yann Colletfb810d62016-01-28 00:18:06 +0100548 case FSE_ENCODING_RLE :
Yann Collet5be2dd22015-11-11 13:43:58 +0100549 Offlog = 0;
550 if (ip > iend-2) return ERROR(srcSize_wrong); /* min : "raw", hence no header, but at least xxLog bits */
551 FSE_buildDTable_rle(DTableOffb, *ip++ & MaxOff); /* if *ip > MaxOff, data is corrupted */
552 break;
Yann Colletfb810d62016-01-28 00:18:06 +0100553 case FSE_ENCODING_RAW :
Yann Collet5be2dd22015-11-11 13:43:58 +0100554 Offlog = Offbits;
Yann Colletfb810d62016-01-28 00:18:06 +0100555 FSE_buildDTable_raw(DTableOffb, Offbits);
556 break;
557 case FSE_ENCODING_STATIC:
558 break;
559 case FSE_ENCODING_DYNAMIC :
560 default : /* impossible */
Yann Collet5be2dd22015-11-11 13:43:58 +0100561 max = MaxOff;
562 headerSize = FSE_readNCount(norm, &max, &Offlog, ip, iend-ip);
563 if (FSE_isError(headerSize)) return ERROR(GENERIC);
564 if (Offlog > OffFSELog) return ERROR(corruption_detected);
565 ip += headerSize;
566 FSE_buildDTable(DTableOffb, norm, max, Offlog);
567 }
568
569 switch(MLtype)
570 {
571 U32 max;
Yann Colletfb810d62016-01-28 00:18:06 +0100572 case FSE_ENCODING_RLE :
Yann Collet5be2dd22015-11-11 13:43:58 +0100573 MLlog = 0;
574 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 +0100575 FSE_buildDTable_rle(DTableML, *ip++);
576 break;
577 case FSE_ENCODING_RAW :
Yann Collet5be2dd22015-11-11 13:43:58 +0100578 MLlog = MLbits;
Yann Colletfb810d62016-01-28 00:18:06 +0100579 FSE_buildDTable_raw(DTableML, MLbits);
580 break;
581 case FSE_ENCODING_STATIC:
582 break;
583 case FSE_ENCODING_DYNAMIC :
584 default : /* impossible */
Yann Collet5be2dd22015-11-11 13:43:58 +0100585 max = MaxML;
586 headerSize = FSE_readNCount(norm, &max, &MLlog, ip, iend-ip);
587 if (FSE_isError(headerSize)) return ERROR(GENERIC);
588 if (MLlog > MLFSELog) return ERROR(corruption_detected);
589 ip += headerSize;
590 FSE_buildDTable(DTableML, norm, max, MLlog);
Yann Colletfb810d62016-01-28 00:18:06 +0100591 } }
Yann Collet5be2dd22015-11-11 13:43:58 +0100592
593 return ip-istart;
594}
595
596
597typedef struct {
598 size_t litLength;
Yann Collet5be2dd22015-11-11 13:43:58 +0100599 size_t matchLength;
Yann Collete93d6ce2016-01-31 00:58:06 +0100600 size_t offset;
Yann Collet5be2dd22015-11-11 13:43:58 +0100601} seq_t;
602
603typedef struct {
604 BIT_DStream_t DStream;
605 FSE_DState_t stateLL;
606 FSE_DState_t stateOffb;
607 FSE_DState_t stateML;
608 size_t prevOffset;
609 const BYTE* dumps;
610 const BYTE* dumpsEnd;
611} seqState_t;
612
inikepe9f30ea2016-02-03 12:53:07 +0100613
614
Yann Collet5be2dd22015-11-11 13:43:58 +0100615static void ZSTD_decodeSequence(seq_t* seq, seqState_t* seqState)
616{
617 size_t litLength;
618 size_t prevOffset;
619 size_t offset;
620 size_t matchLength;
621 const BYTE* dumps = seqState->dumps;
622 const BYTE* const de = seqState->dumpsEnd;
623
624 /* Literal length */
Yann Collete93d6ce2016-01-31 00:58:06 +0100625 litLength = FSE_peakSymbol(&(seqState->stateLL));
Yann Collete4fdad52015-11-25 21:09:17 +0100626 prevOffset = litLength ? seq->offset : seqState->prevOffset;
Yann Colletfb810d62016-01-28 00:18:06 +0100627 if (litLength == MaxLL) {
Yann Collet5be2dd22015-11-11 13:43:58 +0100628 U32 add = *dumps++;
629 if (add < 255) litLength += add;
Yann Colletfb810d62016-01-28 00:18:06 +0100630 else {
Yann Collet5be2dd22015-11-11 13:43:58 +0100631 litLength = MEM_readLE32(dumps) & 0xFFFFFF; /* no pb : dumps is always followed by seq tables > 1 byte */
632 dumps += 3;
633 }
634 if (dumps >= de) dumps = de-1; /* late correction, to avoid read overflow (data is now corrupted anyway) */
635 }
636
inikepe9f30ea2016-02-03 12:53:07 +0100637// litLength==0 offsetCode==0 offset = seqState->prevOffset seqState->prevOffset = seq->offset
638// litLength==0 offsetCode>0 seqState->prevOffset = seq->offset;
639// litLength>0 offsetCode==0
640// litLength>0 offsetCode>0 seqState->prevOffset = seq->offset;
641
Yann Collet5be2dd22015-11-11 13:43:58 +0100642 /* Offset */
643 {
644 static const U32 offsetPrefix[MaxOff+1] = {
645 1 /*fake*/, 1, 2, 4, 8, 16, 32, 64, 128, 256,
646 512, 1024, 2048, 4096, 8192, 16384, 32768, 65536, 131072, 262144,
647 524288, 1048576, 2097152, 4194304, 8388608, 16777216, 33554432, /*fake*/ 1, 1, 1, 1, 1 };
Yann Collete93d6ce2016-01-31 00:58:06 +0100648 U32 offsetCode = FSE_peakSymbol(&(seqState->stateOffb)); /* <= maxOff, by table construction */
649 U32 nbBits = offsetCode - 1;
Yann Collet5be2dd22015-11-11 13:43:58 +0100650 if (offsetCode==0) nbBits = 0; /* cmove */
651 offset = offsetPrefix[offsetCode] + BIT_readBits(&(seqState->DStream), nbBits);
652 if (MEM_32bits()) BIT_reloadDStream(&(seqState->DStream));
Yann Collete93d6ce2016-01-31 00:58:06 +0100653 if (offsetCode==0) offset = prevOffset; /* repcode, cmove */
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 */
663 matchLength = FSE_decodeSymbol(&(seqState->stateML), &(seqState->DStream));
Yann Colletfb810d62016-01-28 00:18:06 +0100664 if (matchLength == MaxML) {
Yann Collet5be2dd22015-11-11 13:43:58 +0100665 U32 add = *dumps++;
666 if (add < 255) matchLength += add;
Yann Colletfb810d62016-01-28 00:18:06 +0100667 else {
Yann Collet5be2dd22015-11-11 13:43:58 +0100668 matchLength = MEM_readLE32(dumps) & 0xFFFFFF; /* no pb : dumps is always followed by seq tables > 1 byte */
669 dumps += 3;
670 }
671 if (dumps >= de) dumps = de-1; /* late correction, to avoid read overflow (data is now corrupted anyway) */
672 }
673 matchLength += MINMATCH;
674
675 /* save result */
676 seq->litLength = litLength;
677 seq->offset = offset;
678 seq->matchLength = matchLength;
679 seqState->dumps = dumps;
Yann Colletfb810d62016-01-28 00:18:06 +0100680
681#if 0
682 {
683 static U64 totalDecoded = 0;
684 printf("pos %6u : %3u literals & match %3u bytes at distance %6u \n",
685 (U32)(totalDecoded), (U32)litLength, (U32)matchLength, (U32)offset);
686 totalDecoded += litLength + matchLength;
687 }
688#endif
Yann Collet5be2dd22015-11-11 13:43:58 +0100689}
690
691
Yann Collet5b78d2f2015-11-12 15:36:05 +0100692FORCE_INLINE size_t ZSTD_execSequence(BYTE* op,
Yann Colletb3a2af92015-11-19 17:13:19 +0100693 BYTE* const oend, seq_t sequence,
Yann Collet5be2dd22015-11-11 13:43:58 +0100694 const BYTE** litPtr, const BYTE* const litLimit_8,
Yann Collet417890c2015-12-04 17:16:37 +0100695 const BYTE* const base, const BYTE* const vBase, const BYTE* const dictEnd)
Yann Collet5be2dd22015-11-11 13:43:58 +0100696{
Yann Colletb3a2af92015-11-19 17:13:19 +0100697 static const int dec32table[] = { 0, 1, 2, 1, 4, 4, 4, 4 }; /* added */
698 static const int dec64table[] = { 8, 8, 8, 7, 8, 9,10,11 }; /* substracted */
Yann Collet5be2dd22015-11-11 13:43:58 +0100699 BYTE* const oLitEnd = op + sequence.litLength;
Yann Colletb3a2af92015-11-19 17:13:19 +0100700 const size_t sequenceLength = sequence.litLength + sequence.matchLength;
701 BYTE* const oMatchEnd = op + sequenceLength; /* risk : address space overflow (32-bits) */
Yann Collet5be2dd22015-11-11 13:43:58 +0100702 BYTE* const oend_8 = oend-8;
703 const BYTE* const litEnd = *litPtr + sequence.litLength;
Yann Colletb3a2af92015-11-19 17:13:19 +0100704 const BYTE* match = oLitEnd - sequence.offset;
Yann Collet5be2dd22015-11-11 13:43:58 +0100705
706 /* check */
inikep59140c52016-02-02 12:36:09 +0100707 // if (oLitEnd > oend_8) return ERROR(dstSize_tooSmall); /* last match must start at a minimum distance of 8 from oend */
Yann Collet5be2dd22015-11-11 13:43:58 +0100708 if (oMatchEnd > oend) return ERROR(dstSize_tooSmall); /* overwrite beyond dst buffer */
709 if (litEnd > litLimit_8) return ERROR(corruption_detected); /* risk read beyond lit buffer */
710
711 /* copy Literals */
712 ZSTD_wildcopy(op, *litPtr, sequence.litLength); /* note : oLitEnd <= oend-8 : no risk of overwrite beyond oend */
713 op = oLitEnd;
714 *litPtr = litEnd; /* update for next sequence */
715
716 /* copy Match */
Yann Collet7b51a292016-01-26 15:58:49 +0100717 if (sequence.offset > (size_t)(oLitEnd - base)) {
Yann Collet44287a32015-11-30 23:13:56 +0100718 /* offset beyond prefix */
Yann Collet9f5ab1a2015-12-11 00:27:41 +0100719 if (sequence.offset > (size_t)(oLitEnd - vBase))
720 return ERROR(corruption_detected);
Yann Collet44287a32015-11-30 23:13:56 +0100721 match = dictEnd - (base-match);
Yann Collet7b51a292016-01-26 15:58:49 +0100722 if (match + sequence.matchLength <= dictEnd) {
Yann Collet4bfe4152015-12-06 13:18:37 +0100723 memmove(oLitEnd, match, sequence.matchLength);
Yann Collet44287a32015-11-30 23:13:56 +0100724 return sequenceLength;
725 }
726 /* span extDict & currentPrefixSegment */
727 {
728 size_t length1 = dictEnd - match;
Yann Collet4bfe4152015-12-06 13:18:37 +0100729 memmove(oLitEnd, match, length1);
Yann Collet44287a32015-11-30 23:13:56 +0100730 op = oLitEnd + length1;
731 sequence.matchLength -= length1;
732 match = base;
Yann Colletfb810d62016-01-28 00:18:06 +0100733 } }
Yann Collet0f366c62015-11-12 16:19:30 +0100734
Yann Collet44287a32015-11-30 23:13:56 +0100735 /* match within prefix */
Yann Collet7b51a292016-01-26 15:58:49 +0100736 if (sequence.offset < 8) {
Yann Collet44287a32015-11-30 23:13:56 +0100737 /* close range match, overlap */
738 const int sub2 = dec64table[sequence.offset];
739 op[0] = match[0];
740 op[1] = match[1];
741 op[2] = match[2];
742 op[3] = match[3];
743 match += dec32table[sequence.offset];
744 ZSTD_copy4(op+4, match);
745 match -= sub2;
Yann Colletfb810d62016-01-28 00:18:06 +0100746 } else {
Yann Collet44287a32015-11-30 23:13:56 +0100747 ZSTD_copy8(op, match);
748 }
749 op += 8; match += 8;
Yann Collet5be2dd22015-11-11 13:43:58 +0100750
Yann Collet7b51a292016-01-26 15:58:49 +0100751 if (oMatchEnd > oend-12) {
752 if (op < oend_8) {
Yann Collet44287a32015-11-30 23:13:56 +0100753 ZSTD_wildcopy(op, match, oend_8 - op);
754 match += oend_8 - op;
755 op = oend_8;
756 }
Yann Colletfb810d62016-01-28 00:18:06 +0100757 while (op < oMatchEnd)
758 *op++ = *match++;
759 } else {
Yann Collet44287a32015-11-30 23:13:56 +0100760 ZSTD_wildcopy(op, match, sequence.matchLength-8); /* works even if matchLength < 8 */
761 }
762 return sequenceLength;
Yann Collet5be2dd22015-11-11 13:43:58 +0100763}
764
Yann Colletb3a2af92015-11-19 17:13:19 +0100765
Yann Collet5be2dd22015-11-11 13:43:58 +0100766static size_t ZSTD_decompressSequences(
Yann Collet5b78d2f2015-11-12 15:36:05 +0100767 ZSTD_DCtx* dctx,
Yann Collet5be2dd22015-11-11 13:43:58 +0100768 void* dst, size_t maxDstSize,
769 const void* seqStart, size_t seqSize)
770{
Yann Collet5be2dd22015-11-11 13:43:58 +0100771 const BYTE* ip = (const BYTE*)seqStart;
772 const BYTE* const iend = ip + seqSize;
773 BYTE* const ostart = (BYTE* const)dst;
774 BYTE* op = ostart;
775 BYTE* const oend = ostart + maxDstSize;
776 size_t errorCode, dumpsLength;
777 const BYTE* litPtr = dctx->litPtr;
778 const BYTE* const litLimit_8 = litPtr + dctx->litBufSize - 8;
779 const BYTE* const litEnd = litPtr + dctx->litSize;
780 int nbSeq;
781 const BYTE* dumps;
782 U32* DTableLL = dctx->LLTable;
783 U32* DTableML = dctx->MLTable;
784 U32* DTableOffb = dctx->OffTable;
Yann Collet417890c2015-12-04 17:16:37 +0100785 const BYTE* const base = (const BYTE*) (dctx->base);
786 const BYTE* const vBase = (const BYTE*) (dctx->vBase);
787 const BYTE* const dictEnd = (const BYTE*) (dctx->dictEnd);
Yann Collet5be2dd22015-11-11 13:43:58 +0100788
789 /* Build Decoding Tables */
790 errorCode = ZSTD_decodeSeqHeaders(&nbSeq, &dumps, &dumpsLength,
791 DTableLL, DTableML, DTableOffb,
Yann Colletfb810d62016-01-28 00:18:06 +0100792 ip, seqSize);
Yann Collet5be2dd22015-11-11 13:43:58 +0100793 if (ZSTD_isError(errorCode)) return errorCode;
794 ip += errorCode;
795
796 /* Regen sequences */
Yann Collete93d6ce2016-01-31 00:58:06 +0100797 if (nbSeq) {
Yann Collet5be2dd22015-11-11 13:43:58 +0100798 seq_t sequence;
799 seqState_t seqState;
800
801 memset(&sequence, 0, sizeof(sequence));
Yann Collet61e16ce2016-01-31 02:04:15 +0100802 sequence.offset = REPCODE_STARTVALUE;
Yann Collet5be2dd22015-11-11 13:43:58 +0100803 seqState.dumps = dumps;
804 seqState.dumpsEnd = dumps + dumpsLength;
Yann Collet61e16ce2016-01-31 02:04:15 +0100805 seqState.prevOffset = REPCODE_STARTVALUE;
Yann Collet5be2dd22015-11-11 13:43:58 +0100806 errorCode = BIT_initDStream(&(seqState.DStream), ip, iend-ip);
807 if (ERR_isError(errorCode)) return ERROR(corruption_detected);
808 FSE_initDState(&(seqState.stateLL), &(seqState.DStream), DTableLL);
809 FSE_initDState(&(seqState.stateOffb), &(seqState.DStream), DTableOffb);
810 FSE_initDState(&(seqState.stateML), &(seqState.DStream), DTableML);
811
Yann Collet7b51a292016-01-26 15:58:49 +0100812 for ( ; (BIT_reloadDStream(&(seqState.DStream)) <= BIT_DStream_completed) && nbSeq ; ) {
Yann Colletb3a2af92015-11-19 17:13:19 +0100813 size_t oneSeqSize;
814 nbSeq--;
815 ZSTD_decodeSequence(&sequence, &seqState);
816 oneSeqSize = ZSTD_execSequence(op, oend, sequence, &litPtr, litLimit_8, base, vBase, dictEnd);
Yann Collet5be2dd22015-11-11 13:43:58 +0100817 if (ZSTD_isError(oneSeqSize)) return oneSeqSize;
818 op += oneSeqSize;
819 }
820
821 /* check if reached exact end */
Yann Collet35f7de52016-01-31 02:51:03 +0100822 if (nbSeq) return ERROR(corruption_detected);
Yann Collete93d6ce2016-01-31 00:58:06 +0100823 }
Yann Collet5be2dd22015-11-11 13:43:58 +0100824
Yann Collete93d6ce2016-01-31 00:58:06 +0100825 /* last literal segment */
826 {
827 size_t lastLLSize = litEnd - litPtr;
828 if (litPtr > litEnd) return ERROR(corruption_detected); /* too many literals already used */
829 if (op+lastLLSize > oend) return ERROR(dstSize_tooSmall);
830 memcpy(op, litPtr, lastLLSize);
831 op += lastLLSize;
832 }
Yann Collet5be2dd22015-11-11 13:43:58 +0100833
834 return op-ostart;
835}
836
837
Yann Colletb0125102016-01-09 02:00:10 +0100838static void ZSTD_checkContinuity(ZSTD_DCtx* dctx, const void* dst)
839{
Yann Collet7b51a292016-01-26 15:58:49 +0100840 if (dst != dctx->previousDstEnd) { /* not contiguous */
Yann Colletb0125102016-01-09 02:00:10 +0100841 dctx->dictEnd = dctx->previousDstEnd;
842 dctx->vBase = (const char*)dst - ((const char*)(dctx->previousDstEnd) - (const char*)(dctx->base));
843 dctx->base = dst;
844 dctx->previousDstEnd = dst;
845 }
846}
847
848
849static size_t ZSTD_decompressBlock_internal(ZSTD_DCtx* dctx,
Yann Collet5be2dd22015-11-11 13:43:58 +0100850 void* dst, size_t maxDstSize,
851 const void* src, size_t srcSize)
852{
853 /* blockType == blockCompressed */
854 const BYTE* ip = (const BYTE*)src;
855
856 /* Decode literals sub-block */
Yann Collet5b78d2f2015-11-12 15:36:05 +0100857 size_t litCSize = ZSTD_decodeLiteralsBlock(dctx, src, srcSize);
Yann Collet5be2dd22015-11-11 13:43:58 +0100858 if (ZSTD_isError(litCSize)) return litCSize;
859 ip += litCSize;
860 srcSize -= litCSize;
861
Yann Collet5b78d2f2015-11-12 15:36:05 +0100862 return ZSTD_decompressSequences(dctx, dst, maxDstSize, ip, srcSize);
Yann Collet5be2dd22015-11-11 13:43:58 +0100863}
864
865
Yann Colletb0125102016-01-09 02:00:10 +0100866size_t ZSTD_decompressBlock(ZSTD_DCtx* dctx,
867 void* dst, size_t maxDstSize,
868 const void* src, size_t srcSize)
869{
870 ZSTD_checkContinuity(dctx, dst);
871 return ZSTD_decompressBlock_internal(dctx, dst, maxDstSize, src, srcSize);
872}
873
874
Yann Collet7b51a292016-01-26 15:58:49 +0100875/*! ZSTD_decompress_continueDCtx
876* dctx must have been properly initialized */
877static size_t ZSTD_decompress_continueDCtx(ZSTD_DCtx* dctx,
Yann Collet31683c02015-12-18 01:26:48 +0100878 void* dst, size_t maxDstSize,
Yann Collet7b51a292016-01-26 15:58:49 +0100879 const void* src, size_t srcSize)
Yann Collet5be2dd22015-11-11 13:43:58 +0100880{
881 const BYTE* ip = (const BYTE*)src;
882 const BYTE* iend = ip + srcSize;
883 BYTE* const ostart = (BYTE* const)dst;
884 BYTE* op = ostart;
885 BYTE* const oend = ostart + maxDstSize;
886 size_t remainingSize = srcSize;
Yann Collet5be2dd22015-11-11 13:43:58 +0100887 blockProperties_t blockProperties;
888
889 /* Frame Header */
Yann Collet88fcd292015-11-25 14:42:45 +0100890 {
891 size_t frameHeaderSize;
892 if (srcSize < ZSTD_frameHeaderSize_min+ZSTD_blockHeaderSize) return ERROR(srcSize_wrong);
Yann Collet5be2dd22015-11-11 13:43:58 +0100893#if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT==1)
Yann Collet88fcd292015-11-25 14:42:45 +0100894 {
895 const U32 magicNumber = MEM_readLE32(src);
896 if (ZSTD_isLegacy(magicNumber))
897 return ZSTD_decompressLegacy(dst, maxDstSize, src, srcSize, magicNumber);
898 }
Yann Collet5be2dd22015-11-11 13:43:58 +0100899#endif
Yann Collet37422192016-01-25 16:54:05 +0100900 frameHeaderSize = ZSTD_decodeFrameHeader_Part1(dctx, src, ZSTD_frameHeaderSize_min);
Yann Collet88fcd292015-11-25 14:42:45 +0100901 if (ZSTD_isError(frameHeaderSize)) return frameHeaderSize;
902 if (srcSize < frameHeaderSize+ZSTD_blockHeaderSize) return ERROR(srcSize_wrong);
903 ip += frameHeaderSize; remainingSize -= frameHeaderSize;
Yann Collet37422192016-01-25 16:54:05 +0100904 frameHeaderSize = ZSTD_decodeFrameHeader_Part2(dctx, src, frameHeaderSize);
Yann Collet88fcd292015-11-25 14:42:45 +0100905 if (ZSTD_isError(frameHeaderSize)) return frameHeaderSize;
906 }
Yann Collet5be2dd22015-11-11 13:43:58 +0100907
908 /* Loop on each block */
909 while (1)
910 {
911 size_t decodedSize=0;
912 size_t cBlockSize = ZSTD_getcBlockSize(ip, iend-ip, &blockProperties);
913 if (ZSTD_isError(cBlockSize)) return cBlockSize;
914
915 ip += ZSTD_blockHeaderSize;
916 remainingSize -= ZSTD_blockHeaderSize;
917 if (cBlockSize > remainingSize) return ERROR(srcSize_wrong);
918
919 switch(blockProperties.blockType)
920 {
921 case bt_compressed:
Yann Collet37422192016-01-25 16:54:05 +0100922 decodedSize = ZSTD_decompressBlock_internal(dctx, op, oend-op, ip, cBlockSize);
Yann Collet5be2dd22015-11-11 13:43:58 +0100923 break;
924 case bt_raw :
Yann Collet0f366c62015-11-12 16:19:30 +0100925 decodedSize = ZSTD_copyRawBlock(op, oend-op, ip, cBlockSize);
Yann Collet5be2dd22015-11-11 13:43:58 +0100926 break;
927 case bt_rle :
928 return ERROR(GENERIC); /* not yet supported */
929 break;
930 case bt_end :
931 /* end of frame */
932 if (remainingSize) return ERROR(srcSize_wrong);
933 break;
934 default:
935 return ERROR(GENERIC); /* impossible */
936 }
937 if (cBlockSize == 0) break; /* bt_end */
938
939 if (ZSTD_isError(decodedSize)) return decodedSize;
940 op += decodedSize;
941 ip += cBlockSize;
942 remainingSize -= cBlockSize;
943 }
944
945 return op-ostart;
946}
947
Yann Collet31683c02015-12-18 01:26:48 +0100948
Yann Collet7b51a292016-01-26 15:58:49 +0100949size_t ZSTD_decompress_usingPreparedDCtx(ZSTD_DCtx* dctx, const ZSTD_DCtx* refDCtx,
950 void* dst, size_t maxDstSize,
951 const void* src, size_t srcSize)
952{
953 ZSTD_copyDCtx(dctx, refDCtx);
954 ZSTD_checkContinuity(dctx, dst);
955 return ZSTD_decompress_continueDCtx(dctx, dst, maxDstSize, src, srcSize);
956}
957
958
959size_t ZSTD_decompress_usingDict(ZSTD_DCtx* dctx,
960 void* dst, size_t maxDstSize,
961 const void* src, size_t srcSize,
962 const void* dict, size_t dictSize)
963{
964 ZSTD_decompressBegin_usingDict(dctx, dict, dictSize);
965 ZSTD_checkContinuity(dctx, dst);
966 return ZSTD_decompress_continueDCtx(dctx, dst, maxDstSize, src, srcSize);
967}
968
969
Yann Collet31683c02015-12-18 01:26:48 +0100970size_t ZSTD_decompressDCtx(ZSTD_DCtx* dctx, void* dst, size_t maxDstSize, const void* src, size_t srcSize)
971{
972 return ZSTD_decompress_usingDict(dctx, dst, maxDstSize, src, srcSize, NULL, 0);
973}
974
Yann Collet5be2dd22015-11-11 13:43:58 +0100975size_t ZSTD_decompress(void* dst, size_t maxDstSize, const void* src, size_t srcSize)
976{
Yann Collet3a3b72f2016-01-11 12:56:11 +0100977#if defined(ZSTD_HEAPMODE) && (ZSTD_HEAPMODE==1)
978 size_t regenSize;
979 ZSTD_DCtx* dctx = ZSTD_createDCtx();
980 if (dctx==NULL) return ERROR(memory_allocation);
981 regenSize = ZSTD_decompressDCtx(dctx, dst, maxDstSize, src, srcSize);
982 ZSTD_freeDCtx(dctx);
983 return regenSize;
984#else
Yann Collet31683c02015-12-18 01:26:48 +0100985 ZSTD_DCtx dctx;
986 return ZSTD_decompressDCtx(&dctx, dst, maxDstSize, src, srcSize);
Yann Colleta768a302016-01-21 16:04:35 +0100987#endif
Yann Collet5be2dd22015-11-11 13:43:58 +0100988}
989
990
991/* ******************************
992* Streaming Decompression API
993********************************/
Yann Collet5be2dd22015-11-11 13:43:58 +0100994size_t ZSTD_nextSrcSizeToDecompress(ZSTD_DCtx* dctx)
995{
996 return dctx->expected;
997}
998
Yann Collet37422192016-01-25 16:54:05 +0100999size_t ZSTD_decompressContinue(ZSTD_DCtx* dctx, void* dst, size_t maxDstSize, const void* src, size_t srcSize)
Yann Collet5be2dd22015-11-11 13:43:58 +01001000{
1001 /* Sanity check */
Yann Collet37422192016-01-25 16:54:05 +01001002 if (srcSize != dctx->expected) return ERROR(srcSize_wrong);
1003 ZSTD_checkContinuity(dctx, dst);
Yann Collet5be2dd22015-11-11 13:43:58 +01001004
Yann Collet88fcd292015-11-25 14:42:45 +01001005 /* Decompress : frame header; part 1 */
Yann Collet37422192016-01-25 16:54:05 +01001006 switch (dctx->stage)
Yann Collet5be2dd22015-11-11 13:43:58 +01001007 {
Yann Collet88fcd292015-11-25 14:42:45 +01001008 case ZSTDds_getFrameHeaderSize :
Yann Collet5be2dd22015-11-11 13:43:58 +01001009 {
Yann Collet88fcd292015-11-25 14:42:45 +01001010 /* get frame header size */
1011 if (srcSize != ZSTD_frameHeaderSize_min) return ERROR(srcSize_wrong); /* impossible */
Yann Collet37422192016-01-25 16:54:05 +01001012 dctx->headerSize = ZSTD_decodeFrameHeader_Part1(dctx, src, ZSTD_frameHeaderSize_min);
1013 if (ZSTD_isError(dctx->headerSize)) return dctx->headerSize;
1014 memcpy(dctx->headerBuffer, src, ZSTD_frameHeaderSize_min);
Yann Collet7b51a292016-01-26 15:58:49 +01001015 if (dctx->headerSize > ZSTD_frameHeaderSize_min) {
Yann Collet37422192016-01-25 16:54:05 +01001016 dctx->expected = dctx->headerSize - ZSTD_frameHeaderSize_min;
1017 dctx->stage = ZSTDds_decodeFrameHeader;
Yann Collet88fcd292015-11-25 14:42:45 +01001018 return 0;
1019 }
Yann Collet37422192016-01-25 16:54:05 +01001020 dctx->expected = 0; /* not necessary to copy more */
Yann Collet5be2dd22015-11-11 13:43:58 +01001021 }
Yann Collet88fcd292015-11-25 14:42:45 +01001022 case ZSTDds_decodeFrameHeader:
Yann Collet5be2dd22015-11-11 13:43:58 +01001023 {
Yann Collet88fcd292015-11-25 14:42:45 +01001024 /* get frame header */
1025 size_t result;
Yann Collet37422192016-01-25 16:54:05 +01001026 memcpy(dctx->headerBuffer + ZSTD_frameHeaderSize_min, src, dctx->expected);
1027 result = ZSTD_decodeFrameHeader_Part2(dctx, dctx->headerBuffer, dctx->headerSize);
Yann Collet88fcd292015-11-25 14:42:45 +01001028 if (ZSTD_isError(result)) return result;
Yann Collet37422192016-01-25 16:54:05 +01001029 dctx->expected = ZSTD_blockHeaderSize;
1030 dctx->stage = ZSTDds_decodeBlockHeader;
Yann Collet88fcd292015-11-25 14:42:45 +01001031 return 0;
Yann Collet5be2dd22015-11-11 13:43:58 +01001032 }
Yann Collet88fcd292015-11-25 14:42:45 +01001033 case ZSTDds_decodeBlockHeader:
Yann Collet5be2dd22015-11-11 13:43:58 +01001034 {
Yann Collet88fcd292015-11-25 14:42:45 +01001035 /* Decode block header */
1036 blockProperties_t bp;
1037 size_t blockSize = ZSTD_getcBlockSize(src, ZSTD_blockHeaderSize, &bp);
1038 if (ZSTD_isError(blockSize)) return blockSize;
Yann Collet7b51a292016-01-26 15:58:49 +01001039 if (bp.blockType == bt_end) {
Yann Collet37422192016-01-25 16:54:05 +01001040 dctx->expected = 0;
1041 dctx->stage = ZSTDds_getFrameHeaderSize;
Yann Collet88fcd292015-11-25 14:42:45 +01001042 }
Yann Collet7b51a292016-01-26 15:58:49 +01001043 else {
Yann Collet37422192016-01-25 16:54:05 +01001044 dctx->expected = blockSize;
1045 dctx->bType = bp.blockType;
1046 dctx->stage = ZSTDds_decompressBlock;
Yann Collet88fcd292015-11-25 14:42:45 +01001047 }
Yann Collet88fcd292015-11-25 14:42:45 +01001048 return 0;
1049 }
Yann Collet417890c2015-12-04 17:16:37 +01001050 case ZSTDds_decompressBlock:
Yann Collet88fcd292015-11-25 14:42:45 +01001051 {
1052 /* Decompress : block content */
1053 size_t rSize;
Yann Collet37422192016-01-25 16:54:05 +01001054 switch(dctx->bType)
Yann Collet88fcd292015-11-25 14:42:45 +01001055 {
1056 case bt_compressed:
Yann Collet37422192016-01-25 16:54:05 +01001057 rSize = ZSTD_decompressBlock_internal(dctx, dst, maxDstSize, src, srcSize);
Yann Collet88fcd292015-11-25 14:42:45 +01001058 break;
1059 case bt_raw :
1060 rSize = ZSTD_copyRawBlock(dst, maxDstSize, src, srcSize);
1061 break;
1062 case bt_rle :
1063 return ERROR(GENERIC); /* not yet handled */
1064 break;
1065 case bt_end : /* should never happen (filtered at phase 1) */
1066 rSize = 0;
1067 break;
1068 default:
Yann Collet7b51a292016-01-26 15:58:49 +01001069 return ERROR(GENERIC); /* impossible */
Yann Collet88fcd292015-11-25 14:42:45 +01001070 }
Yann Collet37422192016-01-25 16:54:05 +01001071 dctx->stage = ZSTDds_decodeBlockHeader;
1072 dctx->expected = ZSTD_blockHeaderSize;
1073 dctx->previousDstEnd = (char*)dst + rSize;
Yann Collet88fcd292015-11-25 14:42:45 +01001074 return rSize;
1075 }
1076 default:
1077 return ERROR(GENERIC); /* impossible */
1078 }
Yann Collet5be2dd22015-11-11 13:43:58 +01001079}
1080
1081
Yann Colletb923f652016-01-26 03:14:20 +01001082static void ZSTD_refDictContent(ZSTD_DCtx* dctx, const void* dict, size_t dictSize)
Yann Collet417890c2015-12-04 17:16:37 +01001083{
Yann Collet37422192016-01-25 16:54:05 +01001084 dctx->dictEnd = dctx->previousDstEnd;
1085 dctx->vBase = (const char*)dict - ((const char*)(dctx->previousDstEnd) - (const char*)(dctx->base));
1086 dctx->base = dict;
1087 dctx->previousDstEnd = (const char*)dict + dictSize;
Yann Collet417890c2015-12-04 17:16:37 +01001088}
Yann Colletb923f652016-01-26 03:14:20 +01001089
Yann Colletb923f652016-01-26 03:14:20 +01001090static size_t ZSTD_loadEntropy(ZSTD_DCtx* dctx, const void* dict, size_t dictSize)
1091{
Yann Colletfb810d62016-01-28 00:18:06 +01001092 size_t hSize, offcodeHeaderSize, matchlengthHeaderSize, errorCode, litlengthHeaderSize;
1093 short offcodeNCount[MaxOff+1];
1094 U32 offcodeMaxValue=MaxOff, offcodeLog=OffFSELog;
1095 short matchlengthNCount[MaxML+1];
1096 unsigned matchlengthMaxValue = MaxML, matchlengthLog = MLFSELog;
1097 short litlengthNCount[MaxLL+1];
1098 unsigned litlengthMaxValue = MaxLL, litlengthLog = LLFSELog;
1099
1100 hSize = HUF_readDTableX4(dctx->hufTableX4, dict, dictSize);
Yann Colletb923f652016-01-26 03:14:20 +01001101 if (HUF_isError(hSize)) return ERROR(dictionary_corrupted);
Yann Colletfb810d62016-01-28 00:18:06 +01001102 dict = (const char*)dict + hSize;
1103 dictSize -= hSize;
1104
1105 offcodeHeaderSize = FSE_readNCount(offcodeNCount, &offcodeMaxValue, &offcodeLog, dict, dictSize);
1106 if (FSE_isError(offcodeHeaderSize)) return ERROR(dictionary_corrupted);
1107 errorCode = FSE_buildDTable(dctx->OffTable, offcodeNCount, offcodeMaxValue, offcodeLog);
1108 if (FSE_isError(errorCode)) return ERROR(dictionary_corrupted);
1109 dict = (const char*)dict + offcodeHeaderSize;
1110 dictSize -= offcodeHeaderSize;
1111
1112 matchlengthHeaderSize = FSE_readNCount(matchlengthNCount, &matchlengthMaxValue, &matchlengthLog, dict, dictSize);
1113 if (FSE_isError(matchlengthHeaderSize)) return ERROR(dictionary_corrupted);
1114 errorCode = FSE_buildDTable(dctx->MLTable, matchlengthNCount, matchlengthMaxValue, matchlengthLog);
1115 if (FSE_isError(errorCode)) return ERROR(dictionary_corrupted);
1116 dict = (const char*)dict + matchlengthHeaderSize;
1117 dictSize -= matchlengthHeaderSize;
1118
1119 litlengthHeaderSize = FSE_readNCount(litlengthNCount, &litlengthMaxValue, &litlengthLog, dict, dictSize);
1120 if (FSE_isError(litlengthHeaderSize)) return ERROR(dictionary_corrupted);
1121 errorCode = FSE_buildDTable(dctx->LLTable, litlengthNCount, litlengthMaxValue, litlengthLog);
1122 if (FSE_isError(errorCode)) return ERROR(dictionary_corrupted);
1123
1124 dctx->flagStaticTables = 1;
1125 return hSize + offcodeHeaderSize + matchlengthHeaderSize + litlengthHeaderSize;
Yann Colletb923f652016-01-26 03:14:20 +01001126}
1127
Yann Collet7b51a292016-01-26 15:58:49 +01001128static size_t ZSTD_decompress_insertDictionary(ZSTD_DCtx* dctx, const void* dict, size_t dictSize)
Yann Colletb923f652016-01-26 03:14:20 +01001129{
1130 size_t eSize;
1131 U32 magic = MEM_readLE32(dict);
1132 if (magic != ZSTD_DICT_MAGIC) {
1133 /* pure content mode */
1134 ZSTD_refDictContent(dctx, dict, dictSize);
1135 return 0;
1136 }
1137 /* load entropy tables */
1138 dict = (const char*)dict + 4;
1139 dictSize -= 4;
1140 eSize = ZSTD_loadEntropy(dctx, dict, dictSize);
1141 if (ZSTD_isError(eSize)) return ERROR(dictionary_corrupted);
1142
1143 /* reference dictionary content */
1144 dict = (const char*)dict + eSize;
1145 dictSize -= eSize;
1146 ZSTD_refDictContent(dctx, dict, dictSize);
1147
1148 return 0;
1149}
1150
Yann Collet7b51a292016-01-26 15:58:49 +01001151
1152size_t ZSTD_decompressBegin_usingDict(ZSTD_DCtx* dctx, const void* dict, size_t dictSize)
1153{
1154 size_t errorCode;
1155 errorCode = ZSTD_decompressBegin(dctx);
1156 if (ZSTD_isError(errorCode)) return errorCode;
1157
1158 if (dict && dictSize) {
1159 errorCode = ZSTD_decompress_insertDictionary(dctx, dict, dictSize);
1160 if (ZSTD_isError(errorCode)) return ERROR(dictionary_corrupted);
1161 }
1162
1163 return 0;
1164}
1165