blob: 31fb7006955500c210607b0bd126a157538503ab [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 Collet5be2dd22015-11-11 13:43:58 +0100629 litLength = MEM_readLE32(dumps) & 0xFFFFFF; /* no pb : dumps is always followed by seq tables > 1 byte */
630 dumps += 3;
631 }
632 if (dumps >= de) dumps = de-1; /* late correction, to avoid read overflow (data is now corrupted anyway) */
633 }
634
635 /* Offset */
636 {
637 static const U32 offsetPrefix[MaxOff+1] = {
638 1 /*fake*/, 1, 2, 4, 8, 16, 32, 64, 128, 256,
639 512, 1024, 2048, 4096, 8192, 16384, 32768, 65536, 131072, 262144,
640 524288, 1048576, 2097152, 4194304, 8388608, 16777216, 33554432, /*fake*/ 1, 1, 1, 1, 1 };
Yann Collete93d6ce2016-01-31 00:58:06 +0100641 U32 offsetCode = FSE_peakSymbol(&(seqState->stateOffb)); /* <= maxOff, by table construction */
642 U32 nbBits = offsetCode - 1;
Yann Collet5be2dd22015-11-11 13:43:58 +0100643 if (offsetCode==0) nbBits = 0; /* cmove */
644 offset = offsetPrefix[offsetCode] + BIT_readBits(&(seqState->DStream), nbBits);
645 if (MEM_32bits()) BIT_reloadDStream(&(seqState->DStream));
Yann Collete93d6ce2016-01-31 00:58:06 +0100646 if (offsetCode==0) offset = prevOffset; /* repcode, cmove */
Yann Collet55aa7f92015-11-20 12:04:52 +0100647 if (offsetCode | !litLength) seqState->prevOffset = seq->offset; /* cmove */
Yann Collete93d6ce2016-01-31 00:58:06 +0100648 FSE_decodeSymbol(&(seqState->stateOffb), &(seqState->DStream)); /* update */
Yann Collet5be2dd22015-11-11 13:43:58 +0100649 }
650
Yann Collete93d6ce2016-01-31 00:58:06 +0100651 /* Literal length update */
652 FSE_decodeSymbol(&(seqState->stateLL), &(seqState->DStream)); /* update */
653 if (MEM_32bits()) BIT_reloadDStream(&(seqState->DStream));
654
Yann Collet5be2dd22015-11-11 13:43:58 +0100655 /* MatchLength */
656 matchLength = FSE_decodeSymbol(&(seqState->stateML), &(seqState->DStream));
Yann Colletfb810d62016-01-28 00:18:06 +0100657 if (matchLength == MaxML) {
Yann Collet5be2dd22015-11-11 13:43:58 +0100658 U32 add = *dumps++;
659 if (add < 255) matchLength += add;
Yann Colletfb810d62016-01-28 00:18:06 +0100660 else {
Yann Collet5be2dd22015-11-11 13:43:58 +0100661 matchLength = MEM_readLE32(dumps) & 0xFFFFFF; /* no pb : dumps is always followed by seq tables > 1 byte */
662 dumps += 3;
663 }
664 if (dumps >= de) dumps = de-1; /* late correction, to avoid read overflow (data is now corrupted anyway) */
665 }
666 matchLength += MINMATCH;
667
668 /* save result */
669 seq->litLength = litLength;
670 seq->offset = offset;
671 seq->matchLength = matchLength;
672 seqState->dumps = dumps;
Yann Colletfb810d62016-01-28 00:18:06 +0100673
674#if 0
675 {
676 static U64 totalDecoded = 0;
677 printf("pos %6u : %3u literals & match %3u bytes at distance %6u \n",
678 (U32)(totalDecoded), (U32)litLength, (U32)matchLength, (U32)offset);
679 totalDecoded += litLength + matchLength;
680 }
681#endif
Yann Collet5be2dd22015-11-11 13:43:58 +0100682}
683
684
Yann Collet5b78d2f2015-11-12 15:36:05 +0100685FORCE_INLINE size_t ZSTD_execSequence(BYTE* op,
Yann Colletb3a2af92015-11-19 17:13:19 +0100686 BYTE* const oend, seq_t sequence,
Yann Collet5be2dd22015-11-11 13:43:58 +0100687 const BYTE** litPtr, const BYTE* const litLimit_8,
Yann Collet417890c2015-12-04 17:16:37 +0100688 const BYTE* const base, const BYTE* const vBase, const BYTE* const dictEnd)
Yann Collet5be2dd22015-11-11 13:43:58 +0100689{
Yann Colletb3a2af92015-11-19 17:13:19 +0100690 static const int dec32table[] = { 0, 1, 2, 1, 4, 4, 4, 4 }; /* added */
691 static const int dec64table[] = { 8, 8, 8, 7, 8, 9,10,11 }; /* substracted */
Yann Collet5be2dd22015-11-11 13:43:58 +0100692 BYTE* const oLitEnd = op + sequence.litLength;
Yann Colletb3a2af92015-11-19 17:13:19 +0100693 const size_t sequenceLength = sequence.litLength + sequence.matchLength;
694 BYTE* const oMatchEnd = op + sequenceLength; /* risk : address space overflow (32-bits) */
Yann Collet5be2dd22015-11-11 13:43:58 +0100695 BYTE* const oend_8 = oend-8;
696 const BYTE* const litEnd = *litPtr + sequence.litLength;
Yann Colletb3a2af92015-11-19 17:13:19 +0100697 const BYTE* match = oLitEnd - sequence.offset;
Yann Collet5be2dd22015-11-11 13:43:58 +0100698
699 /* check */
inikep59140c52016-02-02 12:36:09 +0100700 // 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 +0100701 if (oMatchEnd > oend) return ERROR(dstSize_tooSmall); /* overwrite beyond dst buffer */
702 if (litEnd > litLimit_8) return ERROR(corruption_detected); /* risk read beyond lit buffer */
703
704 /* copy Literals */
705 ZSTD_wildcopy(op, *litPtr, sequence.litLength); /* note : oLitEnd <= oend-8 : no risk of overwrite beyond oend */
706 op = oLitEnd;
707 *litPtr = litEnd; /* update for next sequence */
708
709 /* copy Match */
Yann Collet7b51a292016-01-26 15:58:49 +0100710 if (sequence.offset > (size_t)(oLitEnd - base)) {
Yann Collet44287a32015-11-30 23:13:56 +0100711 /* offset beyond prefix */
Yann Collet9f5ab1a2015-12-11 00:27:41 +0100712 if (sequence.offset > (size_t)(oLitEnd - vBase))
713 return ERROR(corruption_detected);
Yann Collet44287a32015-11-30 23:13:56 +0100714 match = dictEnd - (base-match);
Yann Collet7b51a292016-01-26 15:58:49 +0100715 if (match + sequence.matchLength <= dictEnd) {
Yann Collet4bfe4152015-12-06 13:18:37 +0100716 memmove(oLitEnd, match, sequence.matchLength);
Yann Collet44287a32015-11-30 23:13:56 +0100717 return sequenceLength;
718 }
719 /* span extDict & currentPrefixSegment */
720 {
721 size_t length1 = dictEnd - match;
Yann Collet4bfe4152015-12-06 13:18:37 +0100722 memmove(oLitEnd, match, length1);
Yann Collet44287a32015-11-30 23:13:56 +0100723 op = oLitEnd + length1;
724 sequence.matchLength -= length1;
725 match = base;
Yann Colletfb810d62016-01-28 00:18:06 +0100726 } }
Yann Collet0f366c62015-11-12 16:19:30 +0100727
Yann Collet44287a32015-11-30 23:13:56 +0100728 /* match within prefix */
Yann Collet7b51a292016-01-26 15:58:49 +0100729 if (sequence.offset < 8) {
Yann Collet44287a32015-11-30 23:13:56 +0100730 /* close range match, overlap */
731 const int sub2 = dec64table[sequence.offset];
732 op[0] = match[0];
733 op[1] = match[1];
734 op[2] = match[2];
735 op[3] = match[3];
736 match += dec32table[sequence.offset];
737 ZSTD_copy4(op+4, match);
738 match -= sub2;
Yann Colletfb810d62016-01-28 00:18:06 +0100739 } else {
Yann Collet44287a32015-11-30 23:13:56 +0100740 ZSTD_copy8(op, match);
741 }
742 op += 8; match += 8;
Yann Collet5be2dd22015-11-11 13:43:58 +0100743
Yann Collet7b51a292016-01-26 15:58:49 +0100744 if (oMatchEnd > oend-12) {
745 if (op < oend_8) {
Yann Collet44287a32015-11-30 23:13:56 +0100746 ZSTD_wildcopy(op, match, oend_8 - op);
747 match += oend_8 - op;
748 op = oend_8;
749 }
Yann Colletfb810d62016-01-28 00:18:06 +0100750 while (op < oMatchEnd)
751 *op++ = *match++;
752 } else {
Yann Collet44287a32015-11-30 23:13:56 +0100753 ZSTD_wildcopy(op, match, sequence.matchLength-8); /* works even if matchLength < 8 */
754 }
755 return sequenceLength;
Yann Collet5be2dd22015-11-11 13:43:58 +0100756}
757
Yann Colletb3a2af92015-11-19 17:13:19 +0100758
Yann Collet5be2dd22015-11-11 13:43:58 +0100759static size_t ZSTD_decompressSequences(
Yann Collet5b78d2f2015-11-12 15:36:05 +0100760 ZSTD_DCtx* dctx,
Yann Collet5be2dd22015-11-11 13:43:58 +0100761 void* dst, size_t maxDstSize,
762 const void* seqStart, size_t seqSize)
763{
Yann Collet5be2dd22015-11-11 13:43:58 +0100764 const BYTE* ip = (const BYTE*)seqStart;
765 const BYTE* const iend = ip + seqSize;
766 BYTE* const ostart = (BYTE* const)dst;
767 BYTE* op = ostart;
768 BYTE* const oend = ostart + maxDstSize;
769 size_t errorCode, dumpsLength;
770 const BYTE* litPtr = dctx->litPtr;
771 const BYTE* const litLimit_8 = litPtr + dctx->litBufSize - 8;
772 const BYTE* const litEnd = litPtr + dctx->litSize;
773 int nbSeq;
774 const BYTE* dumps;
775 U32* DTableLL = dctx->LLTable;
776 U32* DTableML = dctx->MLTable;
777 U32* DTableOffb = dctx->OffTable;
Yann Collet417890c2015-12-04 17:16:37 +0100778 const BYTE* const base = (const BYTE*) (dctx->base);
779 const BYTE* const vBase = (const BYTE*) (dctx->vBase);
780 const BYTE* const dictEnd = (const BYTE*) (dctx->dictEnd);
Yann Collet5be2dd22015-11-11 13:43:58 +0100781
782 /* Build Decoding Tables */
783 errorCode = ZSTD_decodeSeqHeaders(&nbSeq, &dumps, &dumpsLength,
784 DTableLL, DTableML, DTableOffb,
Yann Colletfb810d62016-01-28 00:18:06 +0100785 ip, seqSize);
Yann Collet5be2dd22015-11-11 13:43:58 +0100786 if (ZSTD_isError(errorCode)) return errorCode;
787 ip += errorCode;
788
789 /* Regen sequences */
Yann Collete93d6ce2016-01-31 00:58:06 +0100790 if (nbSeq) {
Yann Collet5be2dd22015-11-11 13:43:58 +0100791 seq_t sequence;
792 seqState_t seqState;
793
794 memset(&sequence, 0, sizeof(sequence));
Yann Collet61e16ce2016-01-31 02:04:15 +0100795 sequence.offset = REPCODE_STARTVALUE;
Yann Collet5be2dd22015-11-11 13:43:58 +0100796 seqState.dumps = dumps;
797 seqState.dumpsEnd = dumps + dumpsLength;
Yann Collet61e16ce2016-01-31 02:04:15 +0100798 seqState.prevOffset = REPCODE_STARTVALUE;
Yann Collet5be2dd22015-11-11 13:43:58 +0100799 errorCode = BIT_initDStream(&(seqState.DStream), ip, iend-ip);
800 if (ERR_isError(errorCode)) return ERROR(corruption_detected);
801 FSE_initDState(&(seqState.stateLL), &(seqState.DStream), DTableLL);
802 FSE_initDState(&(seqState.stateOffb), &(seqState.DStream), DTableOffb);
803 FSE_initDState(&(seqState.stateML), &(seqState.DStream), DTableML);
804
Yann Collet7b51a292016-01-26 15:58:49 +0100805 for ( ; (BIT_reloadDStream(&(seqState.DStream)) <= BIT_DStream_completed) && nbSeq ; ) {
Yann Colletb3a2af92015-11-19 17:13:19 +0100806 size_t oneSeqSize;
807 nbSeq--;
808 ZSTD_decodeSequence(&sequence, &seqState);
809 oneSeqSize = ZSTD_execSequence(op, oend, sequence, &litPtr, litLimit_8, base, vBase, dictEnd);
Yann Collet5be2dd22015-11-11 13:43:58 +0100810 if (ZSTD_isError(oneSeqSize)) return oneSeqSize;
811 op += oneSeqSize;
812 }
813
814 /* check if reached exact end */
Yann Collet35f7de52016-01-31 02:51:03 +0100815 if (nbSeq) return ERROR(corruption_detected);
Yann Collete93d6ce2016-01-31 00:58:06 +0100816 }
Yann Collet5be2dd22015-11-11 13:43:58 +0100817
Yann Collete93d6ce2016-01-31 00:58:06 +0100818 /* last literal segment */
819 {
820 size_t lastLLSize = litEnd - litPtr;
821 if (litPtr > litEnd) return ERROR(corruption_detected); /* too many literals already used */
822 if (op+lastLLSize > oend) return ERROR(dstSize_tooSmall);
823 memcpy(op, litPtr, lastLLSize);
824 op += lastLLSize;
825 }
Yann Collet5be2dd22015-11-11 13:43:58 +0100826
827 return op-ostart;
828}
829
830
Yann Colletb0125102016-01-09 02:00:10 +0100831static void ZSTD_checkContinuity(ZSTD_DCtx* dctx, const void* dst)
832{
Yann Collet7b51a292016-01-26 15:58:49 +0100833 if (dst != dctx->previousDstEnd) { /* not contiguous */
Yann Colletb0125102016-01-09 02:00:10 +0100834 dctx->dictEnd = dctx->previousDstEnd;
835 dctx->vBase = (const char*)dst - ((const char*)(dctx->previousDstEnd) - (const char*)(dctx->base));
836 dctx->base = dst;
837 dctx->previousDstEnd = dst;
838 }
839}
840
841
842static size_t ZSTD_decompressBlock_internal(ZSTD_DCtx* dctx,
Yann Collet5be2dd22015-11-11 13:43:58 +0100843 void* dst, size_t maxDstSize,
844 const void* src, size_t srcSize)
845{
846 /* blockType == blockCompressed */
847 const BYTE* ip = (const BYTE*)src;
848
849 /* Decode literals sub-block */
Yann Collet5b78d2f2015-11-12 15:36:05 +0100850 size_t litCSize = ZSTD_decodeLiteralsBlock(dctx, src, srcSize);
Yann Collet5be2dd22015-11-11 13:43:58 +0100851 if (ZSTD_isError(litCSize)) return litCSize;
852 ip += litCSize;
853 srcSize -= litCSize;
854
Yann Collet5b78d2f2015-11-12 15:36:05 +0100855 return ZSTD_decompressSequences(dctx, dst, maxDstSize, ip, srcSize);
Yann Collet5be2dd22015-11-11 13:43:58 +0100856}
857
858
Yann Colletb0125102016-01-09 02:00:10 +0100859size_t ZSTD_decompressBlock(ZSTD_DCtx* dctx,
860 void* dst, size_t maxDstSize,
861 const void* src, size_t srcSize)
862{
863 ZSTD_checkContinuity(dctx, dst);
864 return ZSTD_decompressBlock_internal(dctx, dst, maxDstSize, src, srcSize);
865}
866
867
Yann Collet7b51a292016-01-26 15:58:49 +0100868/*! ZSTD_decompress_continueDCtx
869* dctx must have been properly initialized */
870static size_t ZSTD_decompress_continueDCtx(ZSTD_DCtx* dctx,
Yann Collet31683c02015-12-18 01:26:48 +0100871 void* dst, size_t maxDstSize,
Yann Collet7b51a292016-01-26 15:58:49 +0100872 const void* src, size_t srcSize)
Yann Collet5be2dd22015-11-11 13:43:58 +0100873{
874 const BYTE* ip = (const BYTE*)src;
875 const BYTE* iend = ip + srcSize;
876 BYTE* const ostart = (BYTE* const)dst;
877 BYTE* op = ostart;
878 BYTE* const oend = ostart + maxDstSize;
879 size_t remainingSize = srcSize;
Yann Collet5be2dd22015-11-11 13:43:58 +0100880 blockProperties_t blockProperties;
881
882 /* Frame Header */
Yann Collet88fcd292015-11-25 14:42:45 +0100883 {
884 size_t frameHeaderSize;
885 if (srcSize < ZSTD_frameHeaderSize_min+ZSTD_blockHeaderSize) return ERROR(srcSize_wrong);
Yann Collet5be2dd22015-11-11 13:43:58 +0100886#if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT==1)
Yann Collet88fcd292015-11-25 14:42:45 +0100887 {
888 const U32 magicNumber = MEM_readLE32(src);
889 if (ZSTD_isLegacy(magicNumber))
890 return ZSTD_decompressLegacy(dst, maxDstSize, src, srcSize, magicNumber);
891 }
Yann Collet5be2dd22015-11-11 13:43:58 +0100892#endif
Yann Collet37422192016-01-25 16:54:05 +0100893 frameHeaderSize = ZSTD_decodeFrameHeader_Part1(dctx, src, ZSTD_frameHeaderSize_min);
Yann Collet88fcd292015-11-25 14:42:45 +0100894 if (ZSTD_isError(frameHeaderSize)) return frameHeaderSize;
895 if (srcSize < frameHeaderSize+ZSTD_blockHeaderSize) return ERROR(srcSize_wrong);
896 ip += frameHeaderSize; remainingSize -= frameHeaderSize;
Yann Collet37422192016-01-25 16:54:05 +0100897 frameHeaderSize = ZSTD_decodeFrameHeader_Part2(dctx, src, frameHeaderSize);
Yann Collet88fcd292015-11-25 14:42:45 +0100898 if (ZSTD_isError(frameHeaderSize)) return frameHeaderSize;
899 }
Yann Collet5be2dd22015-11-11 13:43:58 +0100900
901 /* Loop on each block */
902 while (1)
903 {
904 size_t decodedSize=0;
905 size_t cBlockSize = ZSTD_getcBlockSize(ip, iend-ip, &blockProperties);
906 if (ZSTD_isError(cBlockSize)) return cBlockSize;
907
908 ip += ZSTD_blockHeaderSize;
909 remainingSize -= ZSTD_blockHeaderSize;
910 if (cBlockSize > remainingSize) return ERROR(srcSize_wrong);
911
912 switch(blockProperties.blockType)
913 {
914 case bt_compressed:
Yann Collet37422192016-01-25 16:54:05 +0100915 decodedSize = ZSTD_decompressBlock_internal(dctx, op, oend-op, ip, cBlockSize);
Yann Collet5be2dd22015-11-11 13:43:58 +0100916 break;
917 case bt_raw :
Yann Collet0f366c62015-11-12 16:19:30 +0100918 decodedSize = ZSTD_copyRawBlock(op, oend-op, ip, cBlockSize);
Yann Collet5be2dd22015-11-11 13:43:58 +0100919 break;
920 case bt_rle :
921 return ERROR(GENERIC); /* not yet supported */
922 break;
923 case bt_end :
924 /* end of frame */
925 if (remainingSize) return ERROR(srcSize_wrong);
926 break;
927 default:
928 return ERROR(GENERIC); /* impossible */
929 }
930 if (cBlockSize == 0) break; /* bt_end */
931
932 if (ZSTD_isError(decodedSize)) return decodedSize;
933 op += decodedSize;
934 ip += cBlockSize;
935 remainingSize -= cBlockSize;
936 }
937
938 return op-ostart;
939}
940
Yann Collet31683c02015-12-18 01:26:48 +0100941
Yann Collet7b51a292016-01-26 15:58:49 +0100942size_t ZSTD_decompress_usingPreparedDCtx(ZSTD_DCtx* dctx, const ZSTD_DCtx* refDCtx,
943 void* dst, size_t maxDstSize,
944 const void* src, size_t srcSize)
945{
946 ZSTD_copyDCtx(dctx, refDCtx);
947 ZSTD_checkContinuity(dctx, dst);
948 return ZSTD_decompress_continueDCtx(dctx, dst, maxDstSize, src, srcSize);
949}
950
951
952size_t ZSTD_decompress_usingDict(ZSTD_DCtx* dctx,
953 void* dst, size_t maxDstSize,
954 const void* src, size_t srcSize,
955 const void* dict, size_t dictSize)
956{
957 ZSTD_decompressBegin_usingDict(dctx, dict, dictSize);
958 ZSTD_checkContinuity(dctx, dst);
959 return ZSTD_decompress_continueDCtx(dctx, dst, maxDstSize, src, srcSize);
960}
961
962
Yann Collet31683c02015-12-18 01:26:48 +0100963size_t ZSTD_decompressDCtx(ZSTD_DCtx* dctx, void* dst, size_t maxDstSize, const void* src, size_t srcSize)
964{
965 return ZSTD_decompress_usingDict(dctx, dst, maxDstSize, src, srcSize, NULL, 0);
966}
967
Yann Collet5be2dd22015-11-11 13:43:58 +0100968size_t ZSTD_decompress(void* dst, size_t maxDstSize, const void* src, size_t srcSize)
969{
Yann Collet3a3b72f2016-01-11 12:56:11 +0100970#if defined(ZSTD_HEAPMODE) && (ZSTD_HEAPMODE==1)
971 size_t regenSize;
972 ZSTD_DCtx* dctx = ZSTD_createDCtx();
973 if (dctx==NULL) return ERROR(memory_allocation);
974 regenSize = ZSTD_decompressDCtx(dctx, dst, maxDstSize, src, srcSize);
975 ZSTD_freeDCtx(dctx);
976 return regenSize;
977#else
Yann Collet31683c02015-12-18 01:26:48 +0100978 ZSTD_DCtx dctx;
979 return ZSTD_decompressDCtx(&dctx, dst, maxDstSize, src, srcSize);
Yann Colleta768a302016-01-21 16:04:35 +0100980#endif
Yann Collet5be2dd22015-11-11 13:43:58 +0100981}
982
983
984/* ******************************
985* Streaming Decompression API
986********************************/
Yann Collet5be2dd22015-11-11 13:43:58 +0100987size_t ZSTD_nextSrcSizeToDecompress(ZSTD_DCtx* dctx)
988{
989 return dctx->expected;
990}
991
Yann Collet37422192016-01-25 16:54:05 +0100992size_t ZSTD_decompressContinue(ZSTD_DCtx* dctx, void* dst, size_t maxDstSize, const void* src, size_t srcSize)
Yann Collet5be2dd22015-11-11 13:43:58 +0100993{
994 /* Sanity check */
Yann Collet37422192016-01-25 16:54:05 +0100995 if (srcSize != dctx->expected) return ERROR(srcSize_wrong);
996 ZSTD_checkContinuity(dctx, dst);
Yann Collet5be2dd22015-11-11 13:43:58 +0100997
Yann Collet88fcd292015-11-25 14:42:45 +0100998 /* Decompress : frame header; part 1 */
Yann Collet37422192016-01-25 16:54:05 +0100999 switch (dctx->stage)
Yann Collet5be2dd22015-11-11 13:43:58 +01001000 {
Yann Collet88fcd292015-11-25 14:42:45 +01001001 case ZSTDds_getFrameHeaderSize :
Yann Collet5be2dd22015-11-11 13:43:58 +01001002 {
Yann Collet88fcd292015-11-25 14:42:45 +01001003 /* get frame header size */
1004 if (srcSize != ZSTD_frameHeaderSize_min) return ERROR(srcSize_wrong); /* impossible */
Yann Collet37422192016-01-25 16:54:05 +01001005 dctx->headerSize = ZSTD_decodeFrameHeader_Part1(dctx, src, ZSTD_frameHeaderSize_min);
1006 if (ZSTD_isError(dctx->headerSize)) return dctx->headerSize;
1007 memcpy(dctx->headerBuffer, src, ZSTD_frameHeaderSize_min);
Yann Collet7b51a292016-01-26 15:58:49 +01001008 if (dctx->headerSize > ZSTD_frameHeaderSize_min) {
Yann Collet37422192016-01-25 16:54:05 +01001009 dctx->expected = dctx->headerSize - ZSTD_frameHeaderSize_min;
1010 dctx->stage = ZSTDds_decodeFrameHeader;
Yann Collet88fcd292015-11-25 14:42:45 +01001011 return 0;
1012 }
Yann Collet37422192016-01-25 16:54:05 +01001013 dctx->expected = 0; /* not necessary to copy more */
Yann Collet5be2dd22015-11-11 13:43:58 +01001014 }
Yann Collet88fcd292015-11-25 14:42:45 +01001015 case ZSTDds_decodeFrameHeader:
Yann Collet5be2dd22015-11-11 13:43:58 +01001016 {
Yann Collet88fcd292015-11-25 14:42:45 +01001017 /* get frame header */
1018 size_t result;
Yann Collet37422192016-01-25 16:54:05 +01001019 memcpy(dctx->headerBuffer + ZSTD_frameHeaderSize_min, src, dctx->expected);
1020 result = ZSTD_decodeFrameHeader_Part2(dctx, dctx->headerBuffer, dctx->headerSize);
Yann Collet88fcd292015-11-25 14:42:45 +01001021 if (ZSTD_isError(result)) return result;
Yann Collet37422192016-01-25 16:54:05 +01001022 dctx->expected = ZSTD_blockHeaderSize;
1023 dctx->stage = ZSTDds_decodeBlockHeader;
Yann Collet88fcd292015-11-25 14:42:45 +01001024 return 0;
Yann Collet5be2dd22015-11-11 13:43:58 +01001025 }
Yann Collet88fcd292015-11-25 14:42:45 +01001026 case ZSTDds_decodeBlockHeader:
Yann Collet5be2dd22015-11-11 13:43:58 +01001027 {
Yann Collet88fcd292015-11-25 14:42:45 +01001028 /* Decode block header */
1029 blockProperties_t bp;
1030 size_t blockSize = ZSTD_getcBlockSize(src, ZSTD_blockHeaderSize, &bp);
1031 if (ZSTD_isError(blockSize)) return blockSize;
Yann Collet7b51a292016-01-26 15:58:49 +01001032 if (bp.blockType == bt_end) {
Yann Collet37422192016-01-25 16:54:05 +01001033 dctx->expected = 0;
1034 dctx->stage = ZSTDds_getFrameHeaderSize;
Yann Collet88fcd292015-11-25 14:42:45 +01001035 }
Yann Collet7b51a292016-01-26 15:58:49 +01001036 else {
Yann Collet37422192016-01-25 16:54:05 +01001037 dctx->expected = blockSize;
1038 dctx->bType = bp.blockType;
1039 dctx->stage = ZSTDds_decompressBlock;
Yann Collet88fcd292015-11-25 14:42:45 +01001040 }
Yann Collet88fcd292015-11-25 14:42:45 +01001041 return 0;
1042 }
Yann Collet417890c2015-12-04 17:16:37 +01001043 case ZSTDds_decompressBlock:
Yann Collet88fcd292015-11-25 14:42:45 +01001044 {
1045 /* Decompress : block content */
1046 size_t rSize;
Yann Collet37422192016-01-25 16:54:05 +01001047 switch(dctx->bType)
Yann Collet88fcd292015-11-25 14:42:45 +01001048 {
1049 case bt_compressed:
Yann Collet37422192016-01-25 16:54:05 +01001050 rSize = ZSTD_decompressBlock_internal(dctx, dst, maxDstSize, src, srcSize);
Yann Collet88fcd292015-11-25 14:42:45 +01001051 break;
1052 case bt_raw :
1053 rSize = ZSTD_copyRawBlock(dst, maxDstSize, src, srcSize);
1054 break;
1055 case bt_rle :
1056 return ERROR(GENERIC); /* not yet handled */
1057 break;
1058 case bt_end : /* should never happen (filtered at phase 1) */
1059 rSize = 0;
1060 break;
1061 default:
Yann Collet7b51a292016-01-26 15:58:49 +01001062 return ERROR(GENERIC); /* impossible */
Yann Collet88fcd292015-11-25 14:42:45 +01001063 }
Yann Collet37422192016-01-25 16:54:05 +01001064 dctx->stage = ZSTDds_decodeBlockHeader;
1065 dctx->expected = ZSTD_blockHeaderSize;
1066 dctx->previousDstEnd = (char*)dst + rSize;
Yann Collet88fcd292015-11-25 14:42:45 +01001067 return rSize;
1068 }
1069 default:
1070 return ERROR(GENERIC); /* impossible */
1071 }
Yann Collet5be2dd22015-11-11 13:43:58 +01001072}
1073
1074
Yann Colletb923f652016-01-26 03:14:20 +01001075static void ZSTD_refDictContent(ZSTD_DCtx* dctx, const void* dict, size_t dictSize)
Yann Collet417890c2015-12-04 17:16:37 +01001076{
Yann Collet37422192016-01-25 16:54:05 +01001077 dctx->dictEnd = dctx->previousDstEnd;
1078 dctx->vBase = (const char*)dict - ((const char*)(dctx->previousDstEnd) - (const char*)(dctx->base));
1079 dctx->base = dict;
1080 dctx->previousDstEnd = (const char*)dict + dictSize;
Yann Collet417890c2015-12-04 17:16:37 +01001081}
Yann Colletb923f652016-01-26 03:14:20 +01001082
Yann Colletb923f652016-01-26 03:14:20 +01001083static size_t ZSTD_loadEntropy(ZSTD_DCtx* dctx, const void* dict, size_t dictSize)
1084{
Yann Colletfb810d62016-01-28 00:18:06 +01001085 size_t hSize, offcodeHeaderSize, matchlengthHeaderSize, errorCode, litlengthHeaderSize;
1086 short offcodeNCount[MaxOff+1];
1087 U32 offcodeMaxValue=MaxOff, offcodeLog=OffFSELog;
1088 short matchlengthNCount[MaxML+1];
1089 unsigned matchlengthMaxValue = MaxML, matchlengthLog = MLFSELog;
1090 short litlengthNCount[MaxLL+1];
1091 unsigned litlengthMaxValue = MaxLL, litlengthLog = LLFSELog;
1092
1093 hSize = HUF_readDTableX4(dctx->hufTableX4, dict, dictSize);
Yann Colletb923f652016-01-26 03:14:20 +01001094 if (HUF_isError(hSize)) return ERROR(dictionary_corrupted);
Yann Colletfb810d62016-01-28 00:18:06 +01001095 dict = (const char*)dict + hSize;
1096 dictSize -= hSize;
1097
1098 offcodeHeaderSize = FSE_readNCount(offcodeNCount, &offcodeMaxValue, &offcodeLog, dict, dictSize);
1099 if (FSE_isError(offcodeHeaderSize)) return ERROR(dictionary_corrupted);
1100 errorCode = FSE_buildDTable(dctx->OffTable, offcodeNCount, offcodeMaxValue, offcodeLog);
1101 if (FSE_isError(errorCode)) return ERROR(dictionary_corrupted);
1102 dict = (const char*)dict + offcodeHeaderSize;
1103 dictSize -= offcodeHeaderSize;
1104
1105 matchlengthHeaderSize = FSE_readNCount(matchlengthNCount, &matchlengthMaxValue, &matchlengthLog, dict, dictSize);
1106 if (FSE_isError(matchlengthHeaderSize)) return ERROR(dictionary_corrupted);
1107 errorCode = FSE_buildDTable(dctx->MLTable, matchlengthNCount, matchlengthMaxValue, matchlengthLog);
1108 if (FSE_isError(errorCode)) return ERROR(dictionary_corrupted);
1109 dict = (const char*)dict + matchlengthHeaderSize;
1110 dictSize -= matchlengthHeaderSize;
1111
1112 litlengthHeaderSize = FSE_readNCount(litlengthNCount, &litlengthMaxValue, &litlengthLog, dict, dictSize);
1113 if (FSE_isError(litlengthHeaderSize)) return ERROR(dictionary_corrupted);
1114 errorCode = FSE_buildDTable(dctx->LLTable, litlengthNCount, litlengthMaxValue, litlengthLog);
1115 if (FSE_isError(errorCode)) return ERROR(dictionary_corrupted);
1116
1117 dctx->flagStaticTables = 1;
1118 return hSize + offcodeHeaderSize + matchlengthHeaderSize + litlengthHeaderSize;
Yann Colletb923f652016-01-26 03:14:20 +01001119}
1120
Yann Collet7b51a292016-01-26 15:58:49 +01001121static size_t ZSTD_decompress_insertDictionary(ZSTD_DCtx* dctx, const void* dict, size_t dictSize)
Yann Colletb923f652016-01-26 03:14:20 +01001122{
1123 size_t eSize;
1124 U32 magic = MEM_readLE32(dict);
1125 if (magic != ZSTD_DICT_MAGIC) {
1126 /* pure content mode */
1127 ZSTD_refDictContent(dctx, dict, dictSize);
1128 return 0;
1129 }
1130 /* load entropy tables */
1131 dict = (const char*)dict + 4;
1132 dictSize -= 4;
1133 eSize = ZSTD_loadEntropy(dctx, dict, dictSize);
1134 if (ZSTD_isError(eSize)) return ERROR(dictionary_corrupted);
1135
1136 /* reference dictionary content */
1137 dict = (const char*)dict + eSize;
1138 dictSize -= eSize;
1139 ZSTD_refDictContent(dctx, dict, dictSize);
1140
1141 return 0;
1142}
1143
Yann Collet7b51a292016-01-26 15:58:49 +01001144
1145size_t ZSTD_decompressBegin_usingDict(ZSTD_DCtx* dctx, const void* dict, size_t dictSize)
1146{
1147 size_t errorCode;
1148 errorCode = ZSTD_decompressBegin(dctx);
1149 if (ZSTD_isError(errorCode)) return errorCode;
1150
1151 if (dict && dictSize) {
1152 errorCode = ZSTD_decompress_insertDictionary(dctx, dict, dictSize);
1153 if (ZSTD_isError(errorCode)) return ERROR(dictionary_corrupted);
1154 }
1155
1156 return 0;
1157}
1158