blob: 5d637d2bbe714e9c60b91c1438044e9e6d2a4bcf [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
Yann Collet5be2dd22015-11-11 13:43:58 +0100613static void ZSTD_decodeSequence(seq_t* seq, seqState_t* seqState)
614{
615 size_t litLength;
616 size_t prevOffset;
617 size_t offset;
618 size_t matchLength;
619 const BYTE* dumps = seqState->dumps;
620 const BYTE* const de = seqState->dumpsEnd;
621
622 /* Literal length */
Yann Collete93d6ce2016-01-31 00:58:06 +0100623 litLength = FSE_peakSymbol(&(seqState->stateLL));
Yann Collete4fdad52015-11-25 21:09:17 +0100624 prevOffset = litLength ? seq->offset : seqState->prevOffset;
Yann Colletfb810d62016-01-28 00:18:06 +0100625 if (litLength == MaxLL) {
Yann Collet5be2dd22015-11-11 13:43:58 +0100626 U32 add = *dumps++;
627 if (add < 255) litLength += add;
Yann Colletfb810d62016-01-28 00:18:06 +0100628 else {
Yann Collet7d8e6bd2016-02-02 17:30:37 +0100629 litLength = MEM_readLE32(dumps) & 0xFFFFFF; /* no risk : dumps is always followed by seq tables > 1 byte */
630 if (litLength&1) litLength>>=1, dumps += 3;
631 else litLength = (U16)(litLength)>>1, dumps += 2;
Yann Collet5be2dd22015-11-11 13:43:58 +0100632 }
633 if (dumps >= de) dumps = de-1; /* late correction, to avoid read overflow (data is now corrupted anyway) */
634 }
635
636 /* Offset */
637 {
638 static const U32 offsetPrefix[MaxOff+1] = {
639 1 /*fake*/, 1, 2, 4, 8, 16, 32, 64, 128, 256,
640 512, 1024, 2048, 4096, 8192, 16384, 32768, 65536, 131072, 262144,
641 524288, 1048576, 2097152, 4194304, 8388608, 16777216, 33554432, /*fake*/ 1, 1, 1, 1, 1 };
Yann Collete93d6ce2016-01-31 00:58:06 +0100642 U32 offsetCode = FSE_peakSymbol(&(seqState->stateOffb)); /* <= maxOff, by table construction */
643 U32 nbBits = offsetCode - 1;
Yann Collet5be2dd22015-11-11 13:43:58 +0100644 if (offsetCode==0) nbBits = 0; /* cmove */
645 offset = offsetPrefix[offsetCode] + BIT_readBits(&(seqState->DStream), nbBits);
646 if (MEM_32bits()) BIT_reloadDStream(&(seqState->DStream));
Yann Collete93d6ce2016-01-31 00:58:06 +0100647 if (offsetCode==0) offset = prevOffset; /* repcode, cmove */
Yann Collet55aa7f92015-11-20 12:04:52 +0100648 if (offsetCode | !litLength) seqState->prevOffset = seq->offset; /* cmove */
Yann Collete93d6ce2016-01-31 00:58:06 +0100649 FSE_decodeSymbol(&(seqState->stateOffb), &(seqState->DStream)); /* update */
Yann Collet5be2dd22015-11-11 13:43:58 +0100650 }
651
Yann Collete93d6ce2016-01-31 00:58:06 +0100652 /* Literal length update */
653 FSE_decodeSymbol(&(seqState->stateLL), &(seqState->DStream)); /* update */
654 if (MEM_32bits()) BIT_reloadDStream(&(seqState->DStream));
655
Yann Collet5be2dd22015-11-11 13:43:58 +0100656 /* MatchLength */
657 matchLength = FSE_decodeSymbol(&(seqState->stateML), &(seqState->DStream));
Yann Colletfb810d62016-01-28 00:18:06 +0100658 if (matchLength == MaxML) {
Yann Collet5be2dd22015-11-11 13:43:58 +0100659 U32 add = *dumps++;
660 if (add < 255) matchLength += add;
Yann Colletfb810d62016-01-28 00:18:06 +0100661 else {
Yann Collet5be2dd22015-11-11 13:43:58 +0100662 matchLength = MEM_readLE32(dumps) & 0xFFFFFF; /* no pb : dumps is always followed by seq tables > 1 byte */
Yann Collet7d8e6bd2016-02-02 17:30:37 +0100663 if (matchLength&1) matchLength>>=1, dumps += 3;
664 else matchLength = (U16)(matchLength)>>1, dumps += 2;
Yann Collet5be2dd22015-11-11 13:43:58 +0100665 }
666 if (dumps >= de) dumps = de-1; /* late correction, to avoid read overflow (data is now corrupted anyway) */
667 }
668 matchLength += MINMATCH;
669
670 /* save result */
671 seq->litLength = litLength;
672 seq->offset = offset;
673 seq->matchLength = matchLength;
674 seqState->dumps = dumps;
Yann Colletfb810d62016-01-28 00:18:06 +0100675
Yann Collet7d8e6bd2016-02-02 17:30:37 +0100676#if 0 /* debug */
Yann Colletfb810d62016-01-28 00:18:06 +0100677 {
678 static U64 totalDecoded = 0;
679 printf("pos %6u : %3u literals & match %3u bytes at distance %6u \n",
680 (U32)(totalDecoded), (U32)litLength, (U32)matchLength, (U32)offset);
681 totalDecoded += litLength + matchLength;
682 }
683#endif
Yann Collet5be2dd22015-11-11 13:43:58 +0100684}
685
686
Yann Collet5b78d2f2015-11-12 15:36:05 +0100687FORCE_INLINE size_t ZSTD_execSequence(BYTE* op,
Yann Colletb3a2af92015-11-19 17:13:19 +0100688 BYTE* const oend, seq_t sequence,
Yann Collet5be2dd22015-11-11 13:43:58 +0100689 const BYTE** litPtr, const BYTE* const litLimit_8,
Yann Collet417890c2015-12-04 17:16:37 +0100690 const BYTE* const base, const BYTE* const vBase, const BYTE* const dictEnd)
Yann Collet5be2dd22015-11-11 13:43:58 +0100691{
Yann Colletb3a2af92015-11-19 17:13:19 +0100692 static const int dec32table[] = { 0, 1, 2, 1, 4, 4, 4, 4 }; /* added */
693 static const int dec64table[] = { 8, 8, 8, 7, 8, 9,10,11 }; /* substracted */
Yann Collet5be2dd22015-11-11 13:43:58 +0100694 BYTE* const oLitEnd = op + sequence.litLength;
Yann Colletb3a2af92015-11-19 17:13:19 +0100695 const size_t sequenceLength = sequence.litLength + sequence.matchLength;
696 BYTE* const oMatchEnd = op + sequenceLength; /* risk : address space overflow (32-bits) */
Yann Collet5be2dd22015-11-11 13:43:58 +0100697 BYTE* const oend_8 = oend-8;
698 const BYTE* const litEnd = *litPtr + sequence.litLength;
Yann Colletb3a2af92015-11-19 17:13:19 +0100699 const BYTE* match = oLitEnd - sequence.offset;
Yann Collet5be2dd22015-11-11 13:43:58 +0100700
701 /* check */
702 if (oLitEnd > oend_8) return ERROR(dstSize_tooSmall); /* last match must start at a minimum distance of 8 from oend */
703 if (oMatchEnd > oend) return ERROR(dstSize_tooSmall); /* overwrite beyond dst buffer */
704 if (litEnd > litLimit_8) return ERROR(corruption_detected); /* risk read beyond lit buffer */
705
706 /* copy Literals */
707 ZSTD_wildcopy(op, *litPtr, sequence.litLength); /* note : oLitEnd <= oend-8 : no risk of overwrite beyond oend */
708 op = oLitEnd;
709 *litPtr = litEnd; /* update for next sequence */
710
711 /* copy Match */
Yann Collet7b51a292016-01-26 15:58:49 +0100712 if (sequence.offset > (size_t)(oLitEnd - base)) {
Yann Collet44287a32015-11-30 23:13:56 +0100713 /* offset beyond prefix */
Yann Collet9f5ab1a2015-12-11 00:27:41 +0100714 if (sequence.offset > (size_t)(oLitEnd - vBase))
715 return ERROR(corruption_detected);
Yann Collet44287a32015-11-30 23:13:56 +0100716 match = dictEnd - (base-match);
Yann Collet7b51a292016-01-26 15:58:49 +0100717 if (match + sequence.matchLength <= dictEnd) {
Yann Collet4bfe4152015-12-06 13:18:37 +0100718 memmove(oLitEnd, match, sequence.matchLength);
Yann Collet44287a32015-11-30 23:13:56 +0100719 return sequenceLength;
720 }
721 /* span extDict & currentPrefixSegment */
722 {
723 size_t length1 = dictEnd - match;
Yann Collet4bfe4152015-12-06 13:18:37 +0100724 memmove(oLitEnd, match, length1);
Yann Collet44287a32015-11-30 23:13:56 +0100725 op = oLitEnd + length1;
726 sequence.matchLength -= length1;
727 match = base;
Yann Colletfb810d62016-01-28 00:18:06 +0100728 } }
Yann Collet0f366c62015-11-12 16:19:30 +0100729
Yann Collet44287a32015-11-30 23:13:56 +0100730 /* match within prefix */
Yann Collet7b51a292016-01-26 15:58:49 +0100731 if (sequence.offset < 8) {
Yann Collet44287a32015-11-30 23:13:56 +0100732 /* close range match, overlap */
733 const int sub2 = dec64table[sequence.offset];
734 op[0] = match[0];
735 op[1] = match[1];
736 op[2] = match[2];
737 op[3] = match[3];
738 match += dec32table[sequence.offset];
739 ZSTD_copy4(op+4, match);
740 match -= sub2;
Yann Colletfb810d62016-01-28 00:18:06 +0100741 } else {
Yann Collet44287a32015-11-30 23:13:56 +0100742 ZSTD_copy8(op, match);
743 }
744 op += 8; match += 8;
Yann Collet5be2dd22015-11-11 13:43:58 +0100745
Yann Collet7b51a292016-01-26 15:58:49 +0100746 if (oMatchEnd > oend-12) {
747 if (op < oend_8) {
Yann Collet44287a32015-11-30 23:13:56 +0100748 ZSTD_wildcopy(op, match, oend_8 - op);
749 match += oend_8 - op;
750 op = oend_8;
751 }
Yann Colletfb810d62016-01-28 00:18:06 +0100752 while (op < oMatchEnd)
753 *op++ = *match++;
754 } else {
Yann Collet44287a32015-11-30 23:13:56 +0100755 ZSTD_wildcopy(op, match, sequence.matchLength-8); /* works even if matchLength < 8 */
756 }
757 return sequenceLength;
Yann Collet5be2dd22015-11-11 13:43:58 +0100758}
759
Yann Colletb3a2af92015-11-19 17:13:19 +0100760
Yann Collet5be2dd22015-11-11 13:43:58 +0100761static size_t ZSTD_decompressSequences(
Yann Collet5b78d2f2015-11-12 15:36:05 +0100762 ZSTD_DCtx* dctx,
Yann Collet5be2dd22015-11-11 13:43:58 +0100763 void* dst, size_t maxDstSize,
764 const void* seqStart, size_t seqSize)
765{
Yann Collet5be2dd22015-11-11 13:43:58 +0100766 const BYTE* ip = (const BYTE*)seqStart;
767 const BYTE* const iend = ip + seqSize;
768 BYTE* const ostart = (BYTE* const)dst;
769 BYTE* op = ostart;
770 BYTE* const oend = ostart + maxDstSize;
771 size_t errorCode, dumpsLength;
772 const BYTE* litPtr = dctx->litPtr;
773 const BYTE* const litLimit_8 = litPtr + dctx->litBufSize - 8;
774 const BYTE* const litEnd = litPtr + dctx->litSize;
775 int nbSeq;
776 const BYTE* dumps;
777 U32* DTableLL = dctx->LLTable;
778 U32* DTableML = dctx->MLTable;
779 U32* DTableOffb = dctx->OffTable;
Yann Collet417890c2015-12-04 17:16:37 +0100780 const BYTE* const base = (const BYTE*) (dctx->base);
781 const BYTE* const vBase = (const BYTE*) (dctx->vBase);
782 const BYTE* const dictEnd = (const BYTE*) (dctx->dictEnd);
Yann Collet5be2dd22015-11-11 13:43:58 +0100783
784 /* Build Decoding Tables */
785 errorCode = ZSTD_decodeSeqHeaders(&nbSeq, &dumps, &dumpsLength,
786 DTableLL, DTableML, DTableOffb,
Yann Colletfb810d62016-01-28 00:18:06 +0100787 ip, seqSize);
Yann Collet5be2dd22015-11-11 13:43:58 +0100788 if (ZSTD_isError(errorCode)) return errorCode;
789 ip += errorCode;
790
791 /* Regen sequences */
Yann Collete93d6ce2016-01-31 00:58:06 +0100792 if (nbSeq) {
Yann Collet5be2dd22015-11-11 13:43:58 +0100793 seq_t sequence;
794 seqState_t seqState;
795
796 memset(&sequence, 0, sizeof(sequence));
Yann Collet61e16ce2016-01-31 02:04:15 +0100797 sequence.offset = REPCODE_STARTVALUE;
Yann Collet5be2dd22015-11-11 13:43:58 +0100798 seqState.dumps = dumps;
799 seqState.dumpsEnd = dumps + dumpsLength;
Yann Collet61e16ce2016-01-31 02:04:15 +0100800 seqState.prevOffset = REPCODE_STARTVALUE;
Yann Collet5be2dd22015-11-11 13:43:58 +0100801 errorCode = BIT_initDStream(&(seqState.DStream), ip, iend-ip);
802 if (ERR_isError(errorCode)) return ERROR(corruption_detected);
803 FSE_initDState(&(seqState.stateLL), &(seqState.DStream), DTableLL);
804 FSE_initDState(&(seqState.stateOffb), &(seqState.DStream), DTableOffb);
805 FSE_initDState(&(seqState.stateML), &(seqState.DStream), DTableML);
806
Yann Collet7b51a292016-01-26 15:58:49 +0100807 for ( ; (BIT_reloadDStream(&(seqState.DStream)) <= BIT_DStream_completed) && nbSeq ; ) {
Yann Colletb3a2af92015-11-19 17:13:19 +0100808 size_t oneSeqSize;
809 nbSeq--;
810 ZSTD_decodeSequence(&sequence, &seqState);
811 oneSeqSize = ZSTD_execSequence(op, oend, sequence, &litPtr, litLimit_8, base, vBase, dictEnd);
Yann Collet5be2dd22015-11-11 13:43:58 +0100812 if (ZSTD_isError(oneSeqSize)) return oneSeqSize;
813 op += oneSeqSize;
814 }
815
816 /* check if reached exact end */
Yann Collet35f7de52016-01-31 02:51:03 +0100817 if (nbSeq) return ERROR(corruption_detected);
Yann Collete93d6ce2016-01-31 00:58:06 +0100818 }
Yann Collet5be2dd22015-11-11 13:43:58 +0100819
Yann Collete93d6ce2016-01-31 00:58:06 +0100820 /* last literal segment */
821 {
822 size_t lastLLSize = litEnd - litPtr;
823 if (litPtr > litEnd) return ERROR(corruption_detected); /* too many literals already used */
824 if (op+lastLLSize > oend) return ERROR(dstSize_tooSmall);
825 memcpy(op, litPtr, lastLLSize);
826 op += lastLLSize;
827 }
Yann Collet5be2dd22015-11-11 13:43:58 +0100828
829 return op-ostart;
830}
831
832
Yann Colletb0125102016-01-09 02:00:10 +0100833static void ZSTD_checkContinuity(ZSTD_DCtx* dctx, const void* dst)
834{
Yann Collet7b51a292016-01-26 15:58:49 +0100835 if (dst != dctx->previousDstEnd) { /* not contiguous */
Yann Colletb0125102016-01-09 02:00:10 +0100836 dctx->dictEnd = dctx->previousDstEnd;
837 dctx->vBase = (const char*)dst - ((const char*)(dctx->previousDstEnd) - (const char*)(dctx->base));
838 dctx->base = dst;
839 dctx->previousDstEnd = dst;
840 }
841}
842
843
844static size_t ZSTD_decompressBlock_internal(ZSTD_DCtx* dctx,
Yann Collet5be2dd22015-11-11 13:43:58 +0100845 void* dst, size_t maxDstSize,
846 const void* src, size_t srcSize)
847{
848 /* blockType == blockCompressed */
849 const BYTE* ip = (const BYTE*)src;
850
851 /* Decode literals sub-block */
Yann Collet5b78d2f2015-11-12 15:36:05 +0100852 size_t litCSize = ZSTD_decodeLiteralsBlock(dctx, src, srcSize);
Yann Collet5be2dd22015-11-11 13:43:58 +0100853 if (ZSTD_isError(litCSize)) return litCSize;
854 ip += litCSize;
855 srcSize -= litCSize;
856
Yann Collet5b78d2f2015-11-12 15:36:05 +0100857 return ZSTD_decompressSequences(dctx, dst, maxDstSize, ip, srcSize);
Yann Collet5be2dd22015-11-11 13:43:58 +0100858}
859
860
Yann Colletb0125102016-01-09 02:00:10 +0100861size_t ZSTD_decompressBlock(ZSTD_DCtx* dctx,
862 void* dst, size_t maxDstSize,
863 const void* src, size_t srcSize)
864{
865 ZSTD_checkContinuity(dctx, dst);
866 return ZSTD_decompressBlock_internal(dctx, dst, maxDstSize, src, srcSize);
867}
868
869
Yann Collet7b51a292016-01-26 15:58:49 +0100870/*! ZSTD_decompress_continueDCtx
871* dctx must have been properly initialized */
872static size_t ZSTD_decompress_continueDCtx(ZSTD_DCtx* dctx,
Yann Collet31683c02015-12-18 01:26:48 +0100873 void* dst, size_t maxDstSize,
Yann Collet7b51a292016-01-26 15:58:49 +0100874 const void* src, size_t srcSize)
Yann Collet5be2dd22015-11-11 13:43:58 +0100875{
876 const BYTE* ip = (const BYTE*)src;
877 const BYTE* iend = ip + srcSize;
878 BYTE* const ostart = (BYTE* const)dst;
879 BYTE* op = ostart;
880 BYTE* const oend = ostart + maxDstSize;
881 size_t remainingSize = srcSize;
Yann Collet5be2dd22015-11-11 13:43:58 +0100882 blockProperties_t blockProperties;
883
884 /* Frame Header */
Yann Collet88fcd292015-11-25 14:42:45 +0100885 {
886 size_t frameHeaderSize;
887 if (srcSize < ZSTD_frameHeaderSize_min+ZSTD_blockHeaderSize) return ERROR(srcSize_wrong);
Yann Collet5be2dd22015-11-11 13:43:58 +0100888#if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT==1)
Yann Collet88fcd292015-11-25 14:42:45 +0100889 {
890 const U32 magicNumber = MEM_readLE32(src);
891 if (ZSTD_isLegacy(magicNumber))
892 return ZSTD_decompressLegacy(dst, maxDstSize, src, srcSize, magicNumber);
893 }
Yann Collet5be2dd22015-11-11 13:43:58 +0100894#endif
Yann Collet37422192016-01-25 16:54:05 +0100895 frameHeaderSize = ZSTD_decodeFrameHeader_Part1(dctx, src, ZSTD_frameHeaderSize_min);
Yann Collet88fcd292015-11-25 14:42:45 +0100896 if (ZSTD_isError(frameHeaderSize)) return frameHeaderSize;
897 if (srcSize < frameHeaderSize+ZSTD_blockHeaderSize) return ERROR(srcSize_wrong);
898 ip += frameHeaderSize; remainingSize -= frameHeaderSize;
Yann Collet37422192016-01-25 16:54:05 +0100899 frameHeaderSize = ZSTD_decodeFrameHeader_Part2(dctx, src, frameHeaderSize);
Yann Collet88fcd292015-11-25 14:42:45 +0100900 if (ZSTD_isError(frameHeaderSize)) return frameHeaderSize;
901 }
Yann Collet5be2dd22015-11-11 13:43:58 +0100902
903 /* Loop on each block */
904 while (1)
905 {
906 size_t decodedSize=0;
907 size_t cBlockSize = ZSTD_getcBlockSize(ip, iend-ip, &blockProperties);
908 if (ZSTD_isError(cBlockSize)) return cBlockSize;
909
910 ip += ZSTD_blockHeaderSize;
911 remainingSize -= ZSTD_blockHeaderSize;
912 if (cBlockSize > remainingSize) return ERROR(srcSize_wrong);
913
914 switch(blockProperties.blockType)
915 {
916 case bt_compressed:
Yann Collet37422192016-01-25 16:54:05 +0100917 decodedSize = ZSTD_decompressBlock_internal(dctx, op, oend-op, ip, cBlockSize);
Yann Collet5be2dd22015-11-11 13:43:58 +0100918 break;
919 case bt_raw :
Yann Collet0f366c62015-11-12 16:19:30 +0100920 decodedSize = ZSTD_copyRawBlock(op, oend-op, ip, cBlockSize);
Yann Collet5be2dd22015-11-11 13:43:58 +0100921 break;
922 case bt_rle :
923 return ERROR(GENERIC); /* not yet supported */
924 break;
925 case bt_end :
926 /* end of frame */
927 if (remainingSize) return ERROR(srcSize_wrong);
928 break;
929 default:
930 return ERROR(GENERIC); /* impossible */
931 }
932 if (cBlockSize == 0) break; /* bt_end */
933
934 if (ZSTD_isError(decodedSize)) return decodedSize;
935 op += decodedSize;
936 ip += cBlockSize;
937 remainingSize -= cBlockSize;
938 }
939
940 return op-ostart;
941}
942
Yann Collet31683c02015-12-18 01:26:48 +0100943
Yann Collet7b51a292016-01-26 15:58:49 +0100944size_t ZSTD_decompress_usingPreparedDCtx(ZSTD_DCtx* dctx, const ZSTD_DCtx* refDCtx,
945 void* dst, size_t maxDstSize,
946 const void* src, size_t srcSize)
947{
948 ZSTD_copyDCtx(dctx, refDCtx);
949 ZSTD_checkContinuity(dctx, dst);
950 return ZSTD_decompress_continueDCtx(dctx, dst, maxDstSize, src, srcSize);
951}
952
953
954size_t ZSTD_decompress_usingDict(ZSTD_DCtx* dctx,
955 void* dst, size_t maxDstSize,
956 const void* src, size_t srcSize,
957 const void* dict, size_t dictSize)
958{
959 ZSTD_decompressBegin_usingDict(dctx, dict, dictSize);
960 ZSTD_checkContinuity(dctx, dst);
961 return ZSTD_decompress_continueDCtx(dctx, dst, maxDstSize, src, srcSize);
962}
963
964
Yann Collet31683c02015-12-18 01:26:48 +0100965size_t ZSTD_decompressDCtx(ZSTD_DCtx* dctx, void* dst, size_t maxDstSize, const void* src, size_t srcSize)
966{
967 return ZSTD_decompress_usingDict(dctx, dst, maxDstSize, src, srcSize, NULL, 0);
968}
969
Yann Collet5be2dd22015-11-11 13:43:58 +0100970size_t ZSTD_decompress(void* dst, size_t maxDstSize, const void* src, size_t srcSize)
971{
Yann Collet3a3b72f2016-01-11 12:56:11 +0100972#if defined(ZSTD_HEAPMODE) && (ZSTD_HEAPMODE==1)
973 size_t regenSize;
974 ZSTD_DCtx* dctx = ZSTD_createDCtx();
975 if (dctx==NULL) return ERROR(memory_allocation);
976 regenSize = ZSTD_decompressDCtx(dctx, dst, maxDstSize, src, srcSize);
977 ZSTD_freeDCtx(dctx);
978 return regenSize;
979#else
Yann Collet31683c02015-12-18 01:26:48 +0100980 ZSTD_DCtx dctx;
981 return ZSTD_decompressDCtx(&dctx, dst, maxDstSize, src, srcSize);
Yann Colleta768a302016-01-21 16:04:35 +0100982#endif
Yann Collet5be2dd22015-11-11 13:43:58 +0100983}
984
985
986/* ******************************
987* Streaming Decompression API
988********************************/
Yann Collet5be2dd22015-11-11 13:43:58 +0100989size_t ZSTD_nextSrcSizeToDecompress(ZSTD_DCtx* dctx)
990{
991 return dctx->expected;
992}
993
Yann Collet37422192016-01-25 16:54:05 +0100994size_t ZSTD_decompressContinue(ZSTD_DCtx* dctx, void* dst, size_t maxDstSize, const void* src, size_t srcSize)
Yann Collet5be2dd22015-11-11 13:43:58 +0100995{
996 /* Sanity check */
Yann Collet37422192016-01-25 16:54:05 +0100997 if (srcSize != dctx->expected) return ERROR(srcSize_wrong);
998 ZSTD_checkContinuity(dctx, dst);
Yann Collet5be2dd22015-11-11 13:43:58 +0100999
Yann Collet88fcd292015-11-25 14:42:45 +01001000 /* Decompress : frame header; part 1 */
Yann Collet37422192016-01-25 16:54:05 +01001001 switch (dctx->stage)
Yann Collet5be2dd22015-11-11 13:43:58 +01001002 {
Yann Collet88fcd292015-11-25 14:42:45 +01001003 case ZSTDds_getFrameHeaderSize :
Yann Collet5be2dd22015-11-11 13:43:58 +01001004 {
Yann Collet88fcd292015-11-25 14:42:45 +01001005 /* get frame header size */
1006 if (srcSize != ZSTD_frameHeaderSize_min) return ERROR(srcSize_wrong); /* impossible */
Yann Collet37422192016-01-25 16:54:05 +01001007 dctx->headerSize = ZSTD_decodeFrameHeader_Part1(dctx, src, ZSTD_frameHeaderSize_min);
1008 if (ZSTD_isError(dctx->headerSize)) return dctx->headerSize;
1009 memcpy(dctx->headerBuffer, src, ZSTD_frameHeaderSize_min);
Yann Collet7b51a292016-01-26 15:58:49 +01001010 if (dctx->headerSize > ZSTD_frameHeaderSize_min) {
Yann Collet37422192016-01-25 16:54:05 +01001011 dctx->expected = dctx->headerSize - ZSTD_frameHeaderSize_min;
1012 dctx->stage = ZSTDds_decodeFrameHeader;
Yann Collet88fcd292015-11-25 14:42:45 +01001013 return 0;
1014 }
Yann Collet37422192016-01-25 16:54:05 +01001015 dctx->expected = 0; /* not necessary to copy more */
Yann Collet5be2dd22015-11-11 13:43:58 +01001016 }
Yann Collet88fcd292015-11-25 14:42:45 +01001017 case ZSTDds_decodeFrameHeader:
Yann Collet5be2dd22015-11-11 13:43:58 +01001018 {
Yann Collet88fcd292015-11-25 14:42:45 +01001019 /* get frame header */
1020 size_t result;
Yann Collet37422192016-01-25 16:54:05 +01001021 memcpy(dctx->headerBuffer + ZSTD_frameHeaderSize_min, src, dctx->expected);
1022 result = ZSTD_decodeFrameHeader_Part2(dctx, dctx->headerBuffer, dctx->headerSize);
Yann Collet88fcd292015-11-25 14:42:45 +01001023 if (ZSTD_isError(result)) return result;
Yann Collet37422192016-01-25 16:54:05 +01001024 dctx->expected = ZSTD_blockHeaderSize;
1025 dctx->stage = ZSTDds_decodeBlockHeader;
Yann Collet88fcd292015-11-25 14:42:45 +01001026 return 0;
Yann Collet5be2dd22015-11-11 13:43:58 +01001027 }
Yann Collet88fcd292015-11-25 14:42:45 +01001028 case ZSTDds_decodeBlockHeader:
Yann Collet5be2dd22015-11-11 13:43:58 +01001029 {
Yann Collet88fcd292015-11-25 14:42:45 +01001030 /* Decode block header */
1031 blockProperties_t bp;
1032 size_t blockSize = ZSTD_getcBlockSize(src, ZSTD_blockHeaderSize, &bp);
1033 if (ZSTD_isError(blockSize)) return blockSize;
Yann Collet7b51a292016-01-26 15:58:49 +01001034 if (bp.blockType == bt_end) {
Yann Collet37422192016-01-25 16:54:05 +01001035 dctx->expected = 0;
1036 dctx->stage = ZSTDds_getFrameHeaderSize;
Yann Collet88fcd292015-11-25 14:42:45 +01001037 }
Yann Collet7b51a292016-01-26 15:58:49 +01001038 else {
Yann Collet37422192016-01-25 16:54:05 +01001039 dctx->expected = blockSize;
1040 dctx->bType = bp.blockType;
1041 dctx->stage = ZSTDds_decompressBlock;
Yann Collet88fcd292015-11-25 14:42:45 +01001042 }
Yann Collet88fcd292015-11-25 14:42:45 +01001043 return 0;
1044 }
Yann Collet417890c2015-12-04 17:16:37 +01001045 case ZSTDds_decompressBlock:
Yann Collet88fcd292015-11-25 14:42:45 +01001046 {
1047 /* Decompress : block content */
1048 size_t rSize;
Yann Collet37422192016-01-25 16:54:05 +01001049 switch(dctx->bType)
Yann Collet88fcd292015-11-25 14:42:45 +01001050 {
1051 case bt_compressed:
Yann Collet37422192016-01-25 16:54:05 +01001052 rSize = ZSTD_decompressBlock_internal(dctx, dst, maxDstSize, src, srcSize);
Yann Collet88fcd292015-11-25 14:42:45 +01001053 break;
1054 case bt_raw :
1055 rSize = ZSTD_copyRawBlock(dst, maxDstSize, src, srcSize);
1056 break;
1057 case bt_rle :
1058 return ERROR(GENERIC); /* not yet handled */
1059 break;
1060 case bt_end : /* should never happen (filtered at phase 1) */
1061 rSize = 0;
1062 break;
1063 default:
Yann Collet7b51a292016-01-26 15:58:49 +01001064 return ERROR(GENERIC); /* impossible */
Yann Collet88fcd292015-11-25 14:42:45 +01001065 }
Yann Collet37422192016-01-25 16:54:05 +01001066 dctx->stage = ZSTDds_decodeBlockHeader;
1067 dctx->expected = ZSTD_blockHeaderSize;
1068 dctx->previousDstEnd = (char*)dst + rSize;
Yann Collet88fcd292015-11-25 14:42:45 +01001069 return rSize;
1070 }
1071 default:
1072 return ERROR(GENERIC); /* impossible */
1073 }
Yann Collet5be2dd22015-11-11 13:43:58 +01001074}
1075
1076
Yann Colletb923f652016-01-26 03:14:20 +01001077static void ZSTD_refDictContent(ZSTD_DCtx* dctx, const void* dict, size_t dictSize)
Yann Collet417890c2015-12-04 17:16:37 +01001078{
Yann Collet37422192016-01-25 16:54:05 +01001079 dctx->dictEnd = dctx->previousDstEnd;
1080 dctx->vBase = (const char*)dict - ((const char*)(dctx->previousDstEnd) - (const char*)(dctx->base));
1081 dctx->base = dict;
1082 dctx->previousDstEnd = (const char*)dict + dictSize;
Yann Collet417890c2015-12-04 17:16:37 +01001083}
Yann Colletb923f652016-01-26 03:14:20 +01001084
Yann Colletb923f652016-01-26 03:14:20 +01001085static size_t ZSTD_loadEntropy(ZSTD_DCtx* dctx, const void* dict, size_t dictSize)
1086{
Yann Colletfb810d62016-01-28 00:18:06 +01001087 size_t hSize, offcodeHeaderSize, matchlengthHeaderSize, errorCode, litlengthHeaderSize;
1088 short offcodeNCount[MaxOff+1];
1089 U32 offcodeMaxValue=MaxOff, offcodeLog=OffFSELog;
1090 short matchlengthNCount[MaxML+1];
1091 unsigned matchlengthMaxValue = MaxML, matchlengthLog = MLFSELog;
1092 short litlengthNCount[MaxLL+1];
1093 unsigned litlengthMaxValue = MaxLL, litlengthLog = LLFSELog;
1094
1095 hSize = HUF_readDTableX4(dctx->hufTableX4, dict, dictSize);
Yann Colletb923f652016-01-26 03:14:20 +01001096 if (HUF_isError(hSize)) return ERROR(dictionary_corrupted);
Yann Colletfb810d62016-01-28 00:18:06 +01001097 dict = (const char*)dict + hSize;
1098 dictSize -= hSize;
1099
1100 offcodeHeaderSize = FSE_readNCount(offcodeNCount, &offcodeMaxValue, &offcodeLog, dict, dictSize);
1101 if (FSE_isError(offcodeHeaderSize)) return ERROR(dictionary_corrupted);
1102 errorCode = FSE_buildDTable(dctx->OffTable, offcodeNCount, offcodeMaxValue, offcodeLog);
1103 if (FSE_isError(errorCode)) return ERROR(dictionary_corrupted);
1104 dict = (const char*)dict + offcodeHeaderSize;
1105 dictSize -= offcodeHeaderSize;
1106
1107 matchlengthHeaderSize = FSE_readNCount(matchlengthNCount, &matchlengthMaxValue, &matchlengthLog, dict, dictSize);
1108 if (FSE_isError(matchlengthHeaderSize)) return ERROR(dictionary_corrupted);
1109 errorCode = FSE_buildDTable(dctx->MLTable, matchlengthNCount, matchlengthMaxValue, matchlengthLog);
1110 if (FSE_isError(errorCode)) return ERROR(dictionary_corrupted);
1111 dict = (const char*)dict + matchlengthHeaderSize;
1112 dictSize -= matchlengthHeaderSize;
1113
1114 litlengthHeaderSize = FSE_readNCount(litlengthNCount, &litlengthMaxValue, &litlengthLog, dict, dictSize);
1115 if (FSE_isError(litlengthHeaderSize)) return ERROR(dictionary_corrupted);
1116 errorCode = FSE_buildDTable(dctx->LLTable, litlengthNCount, litlengthMaxValue, litlengthLog);
1117 if (FSE_isError(errorCode)) return ERROR(dictionary_corrupted);
1118
1119 dctx->flagStaticTables = 1;
1120 return hSize + offcodeHeaderSize + matchlengthHeaderSize + litlengthHeaderSize;
Yann Colletb923f652016-01-26 03:14:20 +01001121}
1122
Yann Collet7b51a292016-01-26 15:58:49 +01001123static size_t ZSTD_decompress_insertDictionary(ZSTD_DCtx* dctx, const void* dict, size_t dictSize)
Yann Colletb923f652016-01-26 03:14:20 +01001124{
1125 size_t eSize;
1126 U32 magic = MEM_readLE32(dict);
1127 if (magic != ZSTD_DICT_MAGIC) {
1128 /* pure content mode */
1129 ZSTD_refDictContent(dctx, dict, dictSize);
1130 return 0;
1131 }
1132 /* load entropy tables */
1133 dict = (const char*)dict + 4;
1134 dictSize -= 4;
1135 eSize = ZSTD_loadEntropy(dctx, dict, dictSize);
1136 if (ZSTD_isError(eSize)) return ERROR(dictionary_corrupted);
1137
1138 /* reference dictionary content */
1139 dict = (const char*)dict + eSize;
1140 dictSize -= eSize;
1141 ZSTD_refDictContent(dctx, dict, dictSize);
1142
1143 return 0;
1144}
1145
Yann Collet7b51a292016-01-26 15:58:49 +01001146
1147size_t ZSTD_decompressBegin_usingDict(ZSTD_DCtx* dctx, const void* dict, size_t dictSize)
1148{
1149 size_t errorCode;
1150 errorCode = ZSTD_decompressBegin(dctx);
1151 if (ZSTD_isError(errorCode)) return errorCode;
1152
1153 if (dict && dictSize) {
1154 errorCode = ZSTD_decompress_insertDictionary(dctx, dict, dictSize);
1155 if (ZSTD_isError(errorCode)) return ERROR(dictionary_corrupted);
1156 }
1157
1158 return 0;
1159}
1160