blob: 1e8aa4c0c8e79fbbb0556173665997217702f32b [file] [log] [blame]
Yann Collet5be2dd22015-11-11 13:43:58 +01001/*
2 zstd - standard compression library
Yann Colletae7aa062016-02-03 02:46:46 +01003 Copyright (C) 2014-2016, Yann Collet.
Yann Collet5be2dd22015-11-11 13:43:58 +01004
5 BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
6
7 Redistribution and use in source and binary forms, with or without
8 modification, are permitted provided that the following conditions are
9 met:
10 * Redistributions of source code must retain the above copyright
11 notice, this list of conditions and the following disclaimer.
12 * Redistributions in binary form must reproduce the above
13 copyright notice, this list of conditions and the following disclaimer
14 in the documentation and/or other materials provided with the
15 distribution.
16 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28 You can contact the author at :
29 - zstd source repository : https://github.com/Cyan4973/zstd
Yann Collet5be2dd22015-11-11 13:43:58 +010030*/
31
32/* ***************************************************************
33* Tuning parameters
34*****************************************************************/
35/*!
Yann Collet5be2dd22015-11-11 13:43:58 +010036 * HEAPMODE :
Yann Collet3a3b72f2016-01-11 12:56:11 +010037 * Select how default decompression function ZSTD_decompress() will allocate memory,
38 * in memory stack (0), or in memory heap (1, requires malloc())
Yann Collet5be2dd22015-11-11 13:43:58 +010039 */
40#ifndef ZSTD_HEAPMODE
41# define ZSTD_HEAPMODE 1
Yann Collet3a3b72f2016-01-11 12:56:11 +010042#endif
Yann Collet5be2dd22015-11-11 13:43:58 +010043
44/*!
45* LEGACY_SUPPORT :
Yann Colletae7aa062016-02-03 02:46:46 +010046* if set to 1, ZSTD_decompress() can decode older formats (v0.1+)
Yann Collet5be2dd22015-11-11 13:43:58 +010047*/
48#ifndef ZSTD_LEGACY_SUPPORT
Yann Colletfba6aed2016-01-18 12:03:27 +010049# define ZSTD_LEGACY_SUPPORT 0
Yann Collet5be2dd22015-11-11 13:43:58 +010050#endif
51
52
Yann Colletfb810d62016-01-28 00:18:06 +010053/*-*******************************************************
Yann Collet953ce722016-02-04 15:28:14 +010054* Dependencies
Yann Collet5be2dd22015-11-11 13:43:58 +010055*********************************************************/
56#include <stdlib.h> /* calloc */
57#include <string.h> /* memcpy, memmove */
Yann Collet953ce722016-02-04 15:28:14 +010058#include <stdio.h> /* debug only : printf */
Yann Collet5be2dd22015-11-11 13:43:58 +010059#include "mem.h" /* low level memory routines */
Yann Collet5be2dd22015-11-11 13:43:58 +010060#include "zstd_internal.h"
61#include "fse_static.h"
Yann Colletafe07092016-01-25 04:10:46 +010062#include "huff0_static.h"
Yann Collet5be2dd22015-11-11 13:43:58 +010063
64#if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT==1)
65# include "zstd_legacy.h"
66#endif
67
Yann Colletfb810d62016-01-28 00:18:06 +010068
69/*-*******************************************************
Yann Collet5be2dd22015-11-11 13:43:58 +010070* Compiler specifics
71*********************************************************/
Yann Collet5be2dd22015-11-11 13:43:58 +010072#ifdef _MSC_VER /* Visual Studio */
73# define FORCE_INLINE static __forceinline
74# include <intrin.h> /* For Visual 2005 */
75# pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */
76# pragma warning(disable : 4324) /* disable: C4324: padded structure */
77#else
78# define GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__)
79# ifdef __GNUC__
80# define FORCE_INLINE static inline __attribute__((always_inline))
81# else
82# define FORCE_INLINE static inline
83# endif
84#endif
85
86
Yann Colletfb810d62016-01-28 00:18:06 +010087/*-*************************************
Yann Collet14983e72015-11-11 21:38:21 +010088* Local types
89***************************************/
90typedef struct
91{
92 blockType_t blockType;
93 U32 origSize;
94} blockProperties_t;
Yann Collet5be2dd22015-11-11 13:43:58 +010095
96
97/* *******************************************************
98* Memory operations
99**********************************************************/
100static void ZSTD_copy4(void* dst, const void* src) { memcpy(dst, src, 4); }
101
102
Yann Collet5be2dd22015-11-11 13:43:58 +0100103/* *************************************
104* Error Management
105***************************************/
Yann Collet14983e72015-11-11 21:38:21 +0100106unsigned ZSTD_versionNumber (void) { return ZSTD_VERSION_NUMBER; }
107
Yann Collet953ce722016-02-04 15:28:14 +0100108/*! ZSTD_isError() :
Yann Collet5be2dd22015-11-11 13:43:58 +0100109* tells if a return value is an error code */
110unsigned ZSTD_isError(size_t code) { return ERR_isError(code); }
111
Yann Collet953ce722016-02-04 15:28:14 +0100112/*! ZSTD_getError() :
Yann Collet72bff502016-02-03 12:06:24 +0100113* convert a `size_t` function result into a proper ZSTD_errorCode enum */
114ZSTD_errorCode ZSTD_getError(size_t code) { return ERR_getError(code); }
115
Yann Collet953ce722016-02-04 15:28:14 +0100116/*! ZSTD_getErrorName() :
Yann Collet5be2dd22015-11-11 13:43:58 +0100117* provides error code string (useful for debugging) */
118const char* ZSTD_getErrorName(size_t code) { return ERR_getErrorName(code); }
119
120
Yann Collet5be2dd22015-11-11 13:43:58 +0100121/* *************************************************************
Yann Collet5b78d2f2015-11-12 15:36:05 +0100122* Context management
Yann Collet5be2dd22015-11-11 13:43:58 +0100123***************************************************************/
Yann Collete4fdad52015-11-25 21:09:17 +0100124typedef enum { ZSTDds_getFrameHeaderSize, ZSTDds_decodeFrameHeader,
Yann Collet88fcd292015-11-25 14:42:45 +0100125 ZSTDds_decodeBlockHeader, ZSTDds_decompressBlock } ZSTD_dStage;
126
Yann Collet5be2dd22015-11-11 13:43:58 +0100127struct ZSTD_DCtx_s
128{
Yann Colletfb810d62016-01-28 00:18:06 +0100129 FSE_DTable LLTable[FSE_DTABLE_SIZE_U32(LLFSELog)];
130 FSE_DTable OffTable[FSE_DTABLE_SIZE_U32(OffFSELog)];
131 FSE_DTable MLTable[FSE_DTABLE_SIZE_U32(MLFSELog)];
132 unsigned hufTableX4[HUF_DTABLE_SIZE(HufLog)];
Yann Collet417890c2015-12-04 17:16:37 +0100133 const void* previousDstEnd;
134 const void* base;
135 const void* vBase;
136 const void* dictEnd;
Yann Collet5be2dd22015-11-11 13:43:58 +0100137 size_t expected;
Yann Collet88fcd292015-11-25 14:42:45 +0100138 size_t headerSize;
139 ZSTD_parameters params;
Yann Colletfb810d62016-01-28 00:18:06 +0100140 blockType_t bType; /* used in ZSTD_decompressContinue(), to transfer blockType between header decoding and block decoding stages */
Yann Collet88fcd292015-11-25 14:42:45 +0100141 ZSTD_dStage stage;
Yann Colletfb810d62016-01-28 00:18:06 +0100142 U32 flagStaticTables;
Yann Collet5be2dd22015-11-11 13:43:58 +0100143 const BYTE* litPtr;
144 size_t litBufSize;
145 size_t litSize;
Yann Colletb923f652016-01-26 03:14:20 +0100146 BYTE litBuffer[BLOCKSIZE + WILDCOPY_OVERLENGTH];
Yann Collet88fcd292015-11-25 14:42:45 +0100147 BYTE headerBuffer[ZSTD_frameHeaderSize_max];
Yann Collet417890c2015-12-04 17:16:37 +0100148}; /* typedef'd to ZSTD_DCtx within "zstd_static.h" */
Yann Collet5be2dd22015-11-11 13:43:58 +0100149
Yann Colletfb810d62016-01-28 00:18:06 +0100150size_t sizeofDCtx (void) { return sizeof(ZSTD_DCtx); }
151
Yann Collet7b51a292016-01-26 15:58:49 +0100152size_t ZSTD_decompressBegin(ZSTD_DCtx* dctx)
Yann Collet5b78d2f2015-11-12 15:36:05 +0100153{
Yann Collet88fcd292015-11-25 14:42:45 +0100154 dctx->expected = ZSTD_frameHeaderSize_min;
155 dctx->stage = ZSTDds_getFrameHeaderSize;
Yann Collet5b78d2f2015-11-12 15:36:05 +0100156 dctx->previousDstEnd = NULL;
157 dctx->base = NULL;
158 dctx->vBase = NULL;
159 dctx->dictEnd = NULL;
Yann Colletb923f652016-01-26 03:14:20 +0100160 dctx->hufTableX4[0] = HufLog;
Yann Colletfb810d62016-01-28 00:18:06 +0100161 dctx->flagStaticTables = 0;
Yann Collet5b78d2f2015-11-12 15:36:05 +0100162 return 0;
163}
164
165ZSTD_DCtx* ZSTD_createDCtx(void)
166{
167 ZSTD_DCtx* dctx = (ZSTD_DCtx*)malloc(sizeof(ZSTD_DCtx));
168 if (dctx==NULL) return NULL;
Yann Collet7b51a292016-01-26 15:58:49 +0100169 ZSTD_decompressBegin(dctx);
Yann Collet5b78d2f2015-11-12 15:36:05 +0100170 return dctx;
171}
172
173size_t ZSTD_freeDCtx(ZSTD_DCtx* dctx)
174{
175 free(dctx);
176 return 0;
177}
178
Yann Collet7b51a292016-01-26 15:58:49 +0100179void ZSTD_copyDCtx(ZSTD_DCtx* dstDCtx, const ZSTD_DCtx* srcDCtx)
180{
181 memcpy(dstDCtx, srcDCtx,
182 sizeof(ZSTD_DCtx) - (BLOCKSIZE+WILDCOPY_OVERLENGTH + ZSTD_frameHeaderSize_max)); /* no need to copy workspace */
183}
184
Yann Collet5b78d2f2015-11-12 15:36:05 +0100185
186/* *************************************************************
187* Decompression section
188***************************************************************/
Yann Collet59d1f792016-01-23 19:28:41 +0100189
190/* Frame format description
191 Frame Header - [ Block Header - Block ] - Frame End
192 1) Frame Header
193 - 4 bytes - Magic Number : ZSTD_MAGICNUMBER (defined within zstd_internal.h)
194 - 1 byte - Window Descriptor
195 2) Block Header
196 - 3 bytes, starting with a 2-bits descriptor
197 Uncompressed, Compressed, Frame End, unused
198 3) Block
199 See Block Format Description
200 4) Frame End
201 - 3 bytes, compatible with Block Header
202*/
203
204/* Block format description
Yann Colletfb810d62016-01-28 00:18:06 +0100205
206 Block = Literal Section - Sequences Section
207 Prerequisite : size of (compressed) block, maximum size of regenerated data
208
Yann Collet59d1f792016-01-23 19:28:41 +0100209 1) Literal Section
Yann Colletfb810d62016-01-28 00:18:06 +0100210
211 1.1) Header : 1-5 bytes
212 flags: 2 bits
Yann Collet59d1f792016-01-23 19:28:41 +0100213 00 compressed by Huff0
Yann Colletfb810d62016-01-28 00:18:06 +0100214 01 unused
215 10 is Raw (uncompressed)
216 11 is Rle
217 Note : using 01 => Huff0 with precomputed table ?
Yann Collet59d1f792016-01-23 19:28:41 +0100218 Note : delta map ? => compressed ?
Yann Colletfb810d62016-01-28 00:18:06 +0100219
220 1.1.1) Huff0-compressed literal block : 3-5 bytes
221 srcSize < 1 KB => 3 bytes (2-2-10-10) => single stream
222 srcSize < 1 KB => 3 bytes (2-2-10-10)
223 srcSize < 16KB => 4 bytes (2-2-14-14)
224 else => 5 bytes (2-2-18-18)
225 big endian convention
226
227 1.1.2) Raw (uncompressed) literal block header : 1-3 bytes
228 size : 5 bits: (IS_RAW<<6) + (0<<4) + size
229 12 bits: (IS_RAW<<6) + (2<<4) + (size>>8)
230 size&255
231 20 bits: (IS_RAW<<6) + (3<<4) + (size>>16)
232 size>>8&255
233 size&255
234
235 1.1.3) Rle (repeated single byte) literal block header : 1-3 bytes
236 size : 5 bits: (IS_RLE<<6) + (0<<4) + size
237 12 bits: (IS_RLE<<6) + (2<<4) + (size>>8)
238 size&255
239 20 bits: (IS_RLE<<6) + (3<<4) + (size>>16)
240 size>>8&255
241 size&255
242
243 1.1.4) Huff0-compressed literal block, using precomputed CTables : 3-5 bytes
244 srcSize < 1 KB => 3 bytes (2-2-10-10) => single stream
245 srcSize < 1 KB => 3 bytes (2-2-10-10)
246 srcSize < 16KB => 4 bytes (2-2-14-14)
247 else => 5 bytes (2-2-18-18)
248 big endian convention
249
250 1- CTable available (stored into workspace ?)
251 2- Small input (fast heuristic ? Full comparison ? depend on clevel ?)
252
253
254 1.2) Literal block content
Yann Collet59d1f792016-01-23 19:28:41 +0100255
256 1.2.1) Huff0 block, using sizes from header
257 See Huff0 format
258
Yann Colletfb810d62016-01-28 00:18:06 +0100259 1.2.2) Huff0 block, using prepared table
Yann Collet59d1f792016-01-23 19:28:41 +0100260
Yann Colletfb810d62016-01-28 00:18:06 +0100261 1.2.3) Raw content
262
263 1.2.4) single byte
264
Yann Collet59d1f792016-01-23 19:28:41 +0100265
266 2) Sequences section
267 TO DO
268*/
269
270
Yann Collet953ce722016-02-04 15:28:14 +0100271/** ZSTD_decodeFrameHeader_Part1() :
Yann Collet88fcd292015-11-25 14:42:45 +0100272* decode the 1st part of the Frame Header, which tells Frame Header size.
Yann Collet953ce722016-02-04 15:28:14 +0100273* srcSize must be == ZSTD_frameHeaderSize_min.
Yann Collet88fcd292015-11-25 14:42:45 +0100274* @return : the full size of the Frame Header */
275static size_t ZSTD_decodeFrameHeader_Part1(ZSTD_DCtx* zc, const void* src, size_t srcSize)
276{
277 U32 magicNumber;
Yann Collet61e16ce2016-01-31 02:04:15 +0100278 if (srcSize != ZSTD_frameHeaderSize_min)
279 return ERROR(srcSize_wrong);
Yann Collet88fcd292015-11-25 14:42:45 +0100280 magicNumber = MEM_readLE32(src);
281 if (magicNumber != ZSTD_MAGICNUMBER) return ERROR(prefix_unknown);
282 zc->headerSize = ZSTD_frameHeaderSize_min;
283 return zc->headerSize;
284}
285
Yann Collet88fcd292015-11-25 14:42:45 +0100286
287size_t ZSTD_getFrameParams(ZSTD_parameters* params, const void* src, size_t srcSize)
288{
289 U32 magicNumber;
290 if (srcSize < ZSTD_frameHeaderSize_min) return ZSTD_frameHeaderSize_max;
291 magicNumber = MEM_readLE32(src);
292 if (magicNumber != ZSTD_MAGICNUMBER) return ERROR(prefix_unknown);
293 memset(params, 0, sizeof(*params));
Yann Collet26415d32015-11-26 12:43:28 +0100294 params->windowLog = (((const BYTE*)src)[4] & 15) + ZSTD_WINDOWLOG_ABSOLUTEMIN;
Yann Colletbf7aa3c2015-11-28 18:19:44 +0100295 if ((((const BYTE*)src)[4] >> 4) != 0) return ERROR(frameParameter_unsupported); /* reserved bits */
Yann Collet88fcd292015-11-25 14:42:45 +0100296 return 0;
297}
298
Yann Collet953ce722016-02-04 15:28:14 +0100299/** ZSTD_decodeFrameHeader_Part2() :
300* decode the full Frame Header.
301* srcSize must be the size provided by ZSTD_decodeFrameHeader_Part1().
Yann Collet26415d32015-11-26 12:43:28 +0100302* @return : 0, or an error code, which can be tested using ZSTD_isError() */
303static size_t ZSTD_decodeFrameHeader_Part2(ZSTD_DCtx* zc, const void* src, size_t srcSize)
304{
Yann Collet00fd7a22015-11-28 16:03:22 +0100305 size_t result;
Yann Collet61e16ce2016-01-31 02:04:15 +0100306 if (srcSize != zc->headerSize)
307 return ERROR(srcSize_wrong);
Yann Collet00fd7a22015-11-28 16:03:22 +0100308 result = ZSTD_getFrameParams(&(zc->params), src, srcSize);
Yann Collet72bff502016-02-03 12:06:24 +0100309 if ((MEM_32bits()) && (zc->params.windowLog > 25)) return ERROR(frameParameter_unsupportedBy32bits);
Yann Collet00fd7a22015-11-28 16:03:22 +0100310 return result;
Yann Collet26415d32015-11-26 12:43:28 +0100311}
312
Yann Collet5be2dd22015-11-11 13:43:58 +0100313
314size_t ZSTD_getcBlockSize(const void* src, size_t srcSize, blockProperties_t* bpPtr)
315{
316 const BYTE* const in = (const BYTE* const)src;
317 BYTE headerFlags;
318 U32 cSize;
319
Yann Collet61e16ce2016-01-31 02:04:15 +0100320 if (srcSize < 3)
321 return ERROR(srcSize_wrong);
Yann Collet5be2dd22015-11-11 13:43:58 +0100322
323 headerFlags = *in;
324 cSize = in[2] + (in[1]<<8) + ((in[0] & 7)<<16);
325
326 bpPtr->blockType = (blockType_t)(headerFlags >> 6);
327 bpPtr->origSize = (bpPtr->blockType == bt_rle) ? cSize : 0;
328
329 if (bpPtr->blockType == bt_end) return 0;
330 if (bpPtr->blockType == bt_rle) return 1;
331 return cSize;
332}
333
Yann Collet59d1f792016-01-23 19:28:41 +0100334
Yann Collet0f366c62015-11-12 16:19:30 +0100335static size_t ZSTD_copyRawBlock(void* dst, size_t maxDstSize, const void* src, size_t srcSize)
Yann Collet5be2dd22015-11-11 13:43:58 +0100336{
337 if (srcSize > maxDstSize) return ERROR(dstSize_tooSmall);
338 memcpy(dst, src, srcSize);
339 return srcSize;
340}
341
342
Yann Collet953ce722016-02-04 15:28:14 +0100343/*! ZSTD_decodeLiteralsBlock() :
Yann Collet14983e72015-11-11 21:38:21 +0100344 @return : nb of bytes read from src (< srcSize ) */
Yann Collet5b78d2f2015-11-12 15:36:05 +0100345size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx,
Yann Collet5be2dd22015-11-11 13:43:58 +0100346 const void* src, size_t srcSize) /* note : srcSize < BLOCKSIZE */
347{
Yann Collet5be2dd22015-11-11 13:43:58 +0100348 const BYTE* const istart = (const BYTE*) src;
349
350 /* any compressed block with literals segment must be at least this size */
351 if (srcSize < MIN_CBLOCK_SIZE) return ERROR(corruption_detected);
352
Yann Collet59d1f792016-01-23 19:28:41 +0100353 switch(istart[0]>> 6)
Yann Collet5be2dd22015-11-11 13:43:58 +0100354 {
Yann Collet59d1f792016-01-23 19:28:41 +0100355 case IS_HUF:
Yann Collet5be2dd22015-11-11 13:43:58 +0100356 {
Yann Colletafe07092016-01-25 04:10:46 +0100357 size_t litSize, litCSize, singleStream=0;
Yann Collet59d1f792016-01-23 19:28:41 +0100358 U32 lhSize = ((istart[0]) >> 4) & 3;
359 switch(lhSize)
360 {
361 case 0: case 1: default: /* note : default is impossible, since lhSize into [0..3] */
362 /* 2 - 2 - 10 - 10 */
363 lhSize=3;
Yann Colletafe07092016-01-25 04:10:46 +0100364 singleStream = istart[0] & 16;
Yann Collet59d1f792016-01-23 19:28:41 +0100365 litSize = ((istart[0] & 15) << 6) + (istart[1] >> 2);
366 litCSize = ((istart[1] & 3) << 8) + istart[2];
367 break;
368 case 2:
369 /* 2 - 2 - 14 - 14 */
370 lhSize=4;
371 litSize = ((istart[0] & 15) << 10) + (istart[1] << 2) + (istart[2] >> 6);
372 litCSize = ((istart[2] & 63) << 8) + istart[3];
373 break;
374 case 3:
375 /* 2 - 2 - 18 - 18 */
376 lhSize=5;
377 litSize = ((istart[0] & 15) << 14) + (istart[1] << 6) + (istart[2] >> 2);
378 litCSize = ((istart[2] & 3) << 16) + (istart[3] << 8) + istart[4];
379 break;
380 }
Yann Colletfb810d62016-01-28 00:18:06 +0100381 if (litSize > BLOCKSIZE) return ERROR(corruption_detected);
Yann Collet59d1f792016-01-23 19:28:41 +0100382
Yann Colletafe07092016-01-25 04:10:46 +0100383 if (HUF_isError(singleStream ?
384 HUF_decompress1X2(dctx->litBuffer, litSize, istart+lhSize, litCSize) :
385 HUF_decompress (dctx->litBuffer, litSize, istart+lhSize, litCSize) ))
Yann Collet59d1f792016-01-23 19:28:41 +0100386 return ERROR(corruption_detected);
387
Yann Collet5be2dd22015-11-11 13:43:58 +0100388 dctx->litPtr = dctx->litBuffer;
389 dctx->litBufSize = BLOCKSIZE+8;
390 dctx->litSize = litSize;
Yann Collet59d1f792016-01-23 19:28:41 +0100391 return litCSize + lhSize;
Yann Collet5be2dd22015-11-11 13:43:58 +0100392 }
Yann Colletb923f652016-01-26 03:14:20 +0100393 case IS_PCH:
394 {
395 size_t errorCode;
396 size_t litSize, litCSize;
397 U32 lhSize = ((istart[0]) >> 4) & 3;
398 if (lhSize != 1) /* only case supported for now : small litSize, single stream */
399 return ERROR(corruption_detected);
Yann Colletfb810d62016-01-28 00:18:06 +0100400 if (!dctx->flagStaticTables)
Yann Collet7b51a292016-01-26 15:58:49 +0100401 return ERROR(dictionary_corrupted);
Yann Colletb923f652016-01-26 03:14:20 +0100402
403 /* 2 - 2 - 10 - 10 */
404 lhSize=3;
405 litSize = ((istart[0] & 15) << 6) + (istart[1] >> 2);
406 litCSize = ((istart[1] & 3) << 8) + istart[2];
407
408 errorCode = HUF_decompress1X4_usingDTable(dctx->litBuffer, litSize, istart+lhSize, litCSize, dctx->hufTableX4);
409 if (HUF_isError(errorCode)) return ERROR(corruption_detected);
410
411 dctx->litPtr = dctx->litBuffer;
412 dctx->litBufSize = BLOCKSIZE+WILDCOPY_OVERLENGTH;
413 dctx->litSize = litSize;
414 return litCSize + lhSize;
415 }
Yann Collet5be2dd22015-11-11 13:43:58 +0100416 case IS_RAW:
417 {
Yann Collet59d1f792016-01-23 19:28:41 +0100418 size_t litSize;
419 U32 lhSize = ((istart[0]) >> 4) & 3;
420 switch(lhSize)
Yann Collet5be2dd22015-11-11 13:43:58 +0100421 {
Yann Collet59d1f792016-01-23 19:28:41 +0100422 case 0: case 1: default: /* note : default is impossible, since lhSize into [0..3] */
423 lhSize=1;
424 litSize = istart[0] & 31;
425 break;
426 case 2:
427 litSize = ((istart[0] & 15) << 8) + istart[1];
428 break;
429 case 3:
430 litSize = ((istart[0] & 15) << 16) + (istart[1] << 8) + istart[2];
431 break;
432 }
433
Yann Collet61e16ce2016-01-31 02:04:15 +0100434 if (lhSize+litSize+WILDCOPY_OVERLENGTH > srcSize) { /* risk reading beyond src buffer with wildcopy */
Yann Colletb010b3b2016-02-03 12:39:34 +0100435 if (litSize+lhSize > srcSize) return ERROR(corruption_detected);
Yann Collet59d1f792016-01-23 19:28:41 +0100436 memcpy(dctx->litBuffer, istart+lhSize, litSize);
Yann Collet5be2dd22015-11-11 13:43:58 +0100437 dctx->litPtr = dctx->litBuffer;
438 dctx->litBufSize = BLOCKSIZE+8;
439 dctx->litSize = litSize;
Yann Colletbc4c8aa2016-01-25 17:26:01 +0100440 return lhSize+litSize;
Yann Collet5be2dd22015-11-11 13:43:58 +0100441 }
442 /* direct reference into compressed stream */
Yann Collet59d1f792016-01-23 19:28:41 +0100443 dctx->litPtr = istart+lhSize;
444 dctx->litBufSize = srcSize-lhSize;
Yann Collet5be2dd22015-11-11 13:43:58 +0100445 dctx->litSize = litSize;
Yann Collet59d1f792016-01-23 19:28:41 +0100446 return lhSize+litSize;
447 }
Yann Collet5be2dd22015-11-11 13:43:58 +0100448 case IS_RLE:
449 {
Yann Collet59d1f792016-01-23 19:28:41 +0100450 size_t litSize;
451 U32 lhSize = ((istart[0]) >> 4) & 3;
452 switch(lhSize)
453 {
454 case 0: case 1: default: /* note : default is impossible, since lhSize into [0..3] */
455 lhSize = 1;
456 litSize = istart[0] & 31;
457 break;
458 case 2:
459 litSize = ((istart[0] & 15) << 8) + istart[1];
460 break;
461 case 3:
462 litSize = ((istart[0] & 15) << 16) + (istart[1] << 8) + istart[2];
463 break;
464 }
Yann Collet5be2dd22015-11-11 13:43:58 +0100465 if (litSize > BLOCKSIZE) return ERROR(corruption_detected);
Yann Collet59d1f792016-01-23 19:28:41 +0100466 memset(dctx->litBuffer, istart[lhSize], litSize);
Yann Collet5be2dd22015-11-11 13:43:58 +0100467 dctx->litPtr = dctx->litBuffer;
Yann Colletb923f652016-01-26 03:14:20 +0100468 dctx->litBufSize = BLOCKSIZE+WILDCOPY_OVERLENGTH;
Yann Collet5be2dd22015-11-11 13:43:58 +0100469 dctx->litSize = litSize;
Yann Collet59d1f792016-01-23 19:28:41 +0100470 return lhSize+1;
Yann Collet5be2dd22015-11-11 13:43:58 +0100471 }
Yann Colletb923f652016-01-26 03:14:20 +0100472 default:
473 return ERROR(corruption_detected); /* impossible */
Yann Collet5be2dd22015-11-11 13:43:58 +0100474 }
475}
476
477
478size_t ZSTD_decodeSeqHeaders(int* nbSeq, const BYTE** dumpsPtr, size_t* dumpsLengthPtr,
479 FSE_DTable* DTableLL, FSE_DTable* DTableML, FSE_DTable* DTableOffb,
480 const void* src, size_t srcSize)
481{
482 const BYTE* const istart = (const BYTE* const)src;
483 const BYTE* ip = istart;
484 const BYTE* const iend = istart + srcSize;
485 U32 LLtype, Offtype, MLtype;
486 U32 LLlog, Offlog, MLlog;
487 size_t dumpsLength;
488
489 /* check */
Yann Collet61e16ce2016-01-31 02:04:15 +0100490 if (srcSize < MIN_SEQUENCES_SIZE)
491 return ERROR(srcSize_wrong);
Yann Collet5be2dd22015-11-11 13:43:58 +0100492
493 /* SeqHead */
Yann Collet61e16ce2016-01-31 02:04:15 +0100494 *nbSeq = *ip++;
495 if (*nbSeq==0) return 1;
496 if (*nbSeq >= 128)
497 *nbSeq = ((nbSeq[0]-128)<<8) + *ip++;
Yann Collete93d6ce2016-01-31 00:58:06 +0100498
Yann Collet5be2dd22015-11-11 13:43:58 +0100499 LLtype = *ip >> 6;
500 Offtype = (*ip >> 4) & 3;
501 MLtype = (*ip >> 2) & 3;
Yann Colletfb810d62016-01-28 00:18:06 +0100502 if (*ip & 2) {
Yann Collet5be2dd22015-11-11 13:43:58 +0100503 dumpsLength = ip[2];
504 dumpsLength += ip[1] << 8;
505 ip += 3;
Yann Colletfb810d62016-01-28 00:18:06 +0100506 } else {
Yann Collet5be2dd22015-11-11 13:43:58 +0100507 dumpsLength = ip[1];
508 dumpsLength += (ip[0] & 1) << 8;
509 ip += 2;
510 }
511 *dumpsPtr = ip;
512 ip += dumpsLength;
513 *dumpsLengthPtr = dumpsLength;
514
515 /* check */
516 if (ip > iend-3) return ERROR(srcSize_wrong); /* min : all 3 are "raw", hence no header, but at least xxLog bits per type */
517
518 /* sequences */
519 {
Yann Collet82368cf2015-11-16 19:10:56 +0100520 S16 norm[MaxML+1]; /* assumption : MaxML >= MaxLL >= MaxOff */
Yann Collet5be2dd22015-11-11 13:43:58 +0100521 size_t headerSize;
522
523 /* Build DTables */
524 switch(LLtype)
525 {
526 U32 max;
Yann Colletfb810d62016-01-28 00:18:06 +0100527 case FSE_ENCODING_RLE :
Yann Collet5be2dd22015-11-11 13:43:58 +0100528 LLlog = 0;
Yann Colletfb810d62016-01-28 00:18:06 +0100529 FSE_buildDTable_rle(DTableLL, *ip++);
530 break;
531 case FSE_ENCODING_RAW :
Yann Collet5be2dd22015-11-11 13:43:58 +0100532 LLlog = LLbits;
Yann Colletfb810d62016-01-28 00:18:06 +0100533 FSE_buildDTable_raw(DTableLL, LLbits);
534 break;
535 case FSE_ENCODING_STATIC:
536 break;
537 case FSE_ENCODING_DYNAMIC :
538 default : /* impossible */
Yann Collet5be2dd22015-11-11 13:43:58 +0100539 max = MaxLL;
540 headerSize = FSE_readNCount(norm, &max, &LLlog, ip, iend-ip);
541 if (FSE_isError(headerSize)) return ERROR(GENERIC);
542 if (LLlog > LLFSELog) return ERROR(corruption_detected);
543 ip += headerSize;
544 FSE_buildDTable(DTableLL, norm, max, LLlog);
545 }
546
547 switch(Offtype)
548 {
549 U32 max;
Yann Colletfb810d62016-01-28 00:18:06 +0100550 case FSE_ENCODING_RLE :
Yann Collet5be2dd22015-11-11 13:43:58 +0100551 Offlog = 0;
552 if (ip > iend-2) return ERROR(srcSize_wrong); /* min : "raw", hence no header, but at least xxLog bits */
553 FSE_buildDTable_rle(DTableOffb, *ip++ & MaxOff); /* if *ip > MaxOff, data is corrupted */
554 break;
Yann Colletfb810d62016-01-28 00:18:06 +0100555 case FSE_ENCODING_RAW :
Yann Collet5be2dd22015-11-11 13:43:58 +0100556 Offlog = Offbits;
Yann Colletfb810d62016-01-28 00:18:06 +0100557 FSE_buildDTable_raw(DTableOffb, Offbits);
558 break;
559 case FSE_ENCODING_STATIC:
560 break;
561 case FSE_ENCODING_DYNAMIC :
562 default : /* impossible */
Yann Collet5be2dd22015-11-11 13:43:58 +0100563 max = MaxOff;
564 headerSize = FSE_readNCount(norm, &max, &Offlog, ip, iend-ip);
565 if (FSE_isError(headerSize)) return ERROR(GENERIC);
566 if (Offlog > OffFSELog) return ERROR(corruption_detected);
567 ip += headerSize;
568 FSE_buildDTable(DTableOffb, norm, max, Offlog);
569 }
570
571 switch(MLtype)
572 {
573 U32 max;
Yann Colletfb810d62016-01-28 00:18:06 +0100574 case FSE_ENCODING_RLE :
Yann Collet5be2dd22015-11-11 13:43:58 +0100575 MLlog = 0;
576 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 +0100577 FSE_buildDTable_rle(DTableML, *ip++);
578 break;
579 case FSE_ENCODING_RAW :
Yann Collet5be2dd22015-11-11 13:43:58 +0100580 MLlog = MLbits;
Yann Colletfb810d62016-01-28 00:18:06 +0100581 FSE_buildDTable_raw(DTableML, MLbits);
582 break;
583 case FSE_ENCODING_STATIC:
584 break;
585 case FSE_ENCODING_DYNAMIC :
586 default : /* impossible */
Yann Collet5be2dd22015-11-11 13:43:58 +0100587 max = MaxML;
588 headerSize = FSE_readNCount(norm, &max, &MLlog, ip, iend-ip);
589 if (FSE_isError(headerSize)) return ERROR(GENERIC);
590 if (MLlog > MLFSELog) return ERROR(corruption_detected);
591 ip += headerSize;
592 FSE_buildDTable(DTableML, norm, max, MLlog);
Yann Colletfb810d62016-01-28 00:18:06 +0100593 } }
Yann Collet5be2dd22015-11-11 13:43:58 +0100594
595 return ip-istart;
596}
597
598
599typedef struct {
600 size_t litLength;
Yann Collet5be2dd22015-11-11 13:43:58 +0100601 size_t matchLength;
Yann Collete93d6ce2016-01-31 00:58:06 +0100602 size_t offset;
Yann Collet5be2dd22015-11-11 13:43:58 +0100603} seq_t;
604
605typedef struct {
606 BIT_DStream_t DStream;
607 FSE_DState_t stateLL;
608 FSE_DState_t stateOffb;
609 FSE_DState_t stateML;
610 size_t prevOffset;
611 const BYTE* dumps;
612 const BYTE* dumpsEnd;
613} seqState_t;
614
Yann Collet5be2dd22015-11-11 13:43:58 +0100615static void ZSTD_decodeSequence(seq_t* seq, seqState_t* seqState)
616{
617 size_t litLength;
618 size_t prevOffset;
619 size_t offset;
620 size_t matchLength;
621 const BYTE* dumps = seqState->dumps;
622 const BYTE* const de = seqState->dumpsEnd;
623
624 /* Literal length */
Yann Collete93d6ce2016-01-31 00:58:06 +0100625 litLength = FSE_peakSymbol(&(seqState->stateLL));
Yann Collete4fdad52015-11-25 21:09:17 +0100626 prevOffset = litLength ? seq->offset : seqState->prevOffset;
Yann Colletfb810d62016-01-28 00:18:06 +0100627 if (litLength == MaxLL) {
Yann Collet5be2dd22015-11-11 13:43:58 +0100628 U32 add = *dumps++;
629 if (add < 255) litLength += add;
Yann Colletfb810d62016-01-28 00:18:06 +0100630 else {
Yann Collet7d8e6bd2016-02-02 17:30:37 +0100631 litLength = MEM_readLE32(dumps) & 0xFFFFFF; /* no risk : dumps is always followed by seq tables > 1 byte */
632 if (litLength&1) litLength>>=1, dumps += 3;
633 else litLength = (U16)(litLength)>>1, dumps += 2;
Yann Collet5be2dd22015-11-11 13:43:58 +0100634 }
635 if (dumps >= de) dumps = de-1; /* late correction, to avoid read overflow (data is now corrupted anyway) */
636 }
637
638 /* Offset */
639 {
640 static const U32 offsetPrefix[MaxOff+1] = {
641 1 /*fake*/, 1, 2, 4, 8, 16, 32, 64, 128, 256,
642 512, 1024, 2048, 4096, 8192, 16384, 32768, 65536, 131072, 262144,
643 524288, 1048576, 2097152, 4194304, 8388608, 16777216, 33554432, /*fake*/ 1, 1, 1, 1, 1 };
Yann Collete93d6ce2016-01-31 00:58:06 +0100644 U32 offsetCode = FSE_peakSymbol(&(seqState->stateOffb)); /* <= maxOff, by table construction */
645 U32 nbBits = offsetCode - 1;
Yann Collet5be2dd22015-11-11 13:43:58 +0100646 if (offsetCode==0) nbBits = 0; /* cmove */
647 offset = offsetPrefix[offsetCode] + BIT_readBits(&(seqState->DStream), nbBits);
648 if (MEM_32bits()) BIT_reloadDStream(&(seqState->DStream));
Yann Collete93d6ce2016-01-31 00:58:06 +0100649 if (offsetCode==0) offset = prevOffset; /* repcode, cmove */
Yann Collet55aa7f92015-11-20 12:04:52 +0100650 if (offsetCode | !litLength) seqState->prevOffset = seq->offset; /* cmove */
Yann Collete93d6ce2016-01-31 00:58:06 +0100651 FSE_decodeSymbol(&(seqState->stateOffb), &(seqState->DStream)); /* update */
Yann Collet5be2dd22015-11-11 13:43:58 +0100652 }
653
Yann Collete93d6ce2016-01-31 00:58:06 +0100654 /* Literal length update */
655 FSE_decodeSymbol(&(seqState->stateLL), &(seqState->DStream)); /* update */
656 if (MEM_32bits()) BIT_reloadDStream(&(seqState->DStream));
657
Yann Collet5be2dd22015-11-11 13:43:58 +0100658 /* MatchLength */
659 matchLength = FSE_decodeSymbol(&(seqState->stateML), &(seqState->DStream));
Yann Colletfb810d62016-01-28 00:18:06 +0100660 if (matchLength == MaxML) {
Yann Collet5be2dd22015-11-11 13:43:58 +0100661 U32 add = *dumps++;
662 if (add < 255) matchLength += add;
Yann Colletfb810d62016-01-28 00:18:06 +0100663 else {
Yann Collet5be2dd22015-11-11 13:43:58 +0100664 matchLength = MEM_readLE32(dumps) & 0xFFFFFF; /* no pb : dumps is always followed by seq tables > 1 byte */
Yann Collet7d8e6bd2016-02-02 17:30:37 +0100665 if (matchLength&1) matchLength>>=1, dumps += 3;
666 else matchLength = (U16)(matchLength)>>1, dumps += 2;
Yann Collet5be2dd22015-11-11 13:43:58 +0100667 }
668 if (dumps >= de) dumps = de-1; /* late correction, to avoid read overflow (data is now corrupted anyway) */
669 }
670 matchLength += MINMATCH;
671
672 /* save result */
673 seq->litLength = litLength;
674 seq->offset = offset;
675 seq->matchLength = matchLength;
676 seqState->dumps = dumps;
Yann Colletfb810d62016-01-28 00:18:06 +0100677
Yann Collet7d8e6bd2016-02-02 17:30:37 +0100678#if 0 /* debug */
Yann Colletfb810d62016-01-28 00:18:06 +0100679 {
680 static U64 totalDecoded = 0;
681 printf("pos %6u : %3u literals & match %3u bytes at distance %6u \n",
682 (U32)(totalDecoded), (U32)litLength, (U32)matchLength, (U32)offset);
683 totalDecoded += litLength + matchLength;
684 }
685#endif
Yann Collet5be2dd22015-11-11 13:43:58 +0100686}
687
688
Yann Collet5b78d2f2015-11-12 15:36:05 +0100689FORCE_INLINE size_t ZSTD_execSequence(BYTE* op,
Yann Colletb3a2af92015-11-19 17:13:19 +0100690 BYTE* const oend, seq_t sequence,
Yann Collet5be2dd22015-11-11 13:43:58 +0100691 const BYTE** litPtr, const BYTE* const litLimit_8,
Yann Collet417890c2015-12-04 17:16:37 +0100692 const BYTE* const base, const BYTE* const vBase, const BYTE* const dictEnd)
Yann Collet5be2dd22015-11-11 13:43:58 +0100693{
Yann Colletb3a2af92015-11-19 17:13:19 +0100694 static const int dec32table[] = { 0, 1, 2, 1, 4, 4, 4, 4 }; /* added */
695 static const int dec64table[] = { 8, 8, 8, 7, 8, 9,10,11 }; /* substracted */
Yann Collet5be2dd22015-11-11 13:43:58 +0100696 BYTE* const oLitEnd = op + sequence.litLength;
Yann Colletb3a2af92015-11-19 17:13:19 +0100697 const size_t sequenceLength = sequence.litLength + sequence.matchLength;
698 BYTE* const oMatchEnd = op + sequenceLength; /* risk : address space overflow (32-bits) */
Yann Collet5be2dd22015-11-11 13:43:58 +0100699 BYTE* const oend_8 = oend-8;
700 const BYTE* const litEnd = *litPtr + sequence.litLength;
Yann Colletb3a2af92015-11-19 17:13:19 +0100701 const BYTE* match = oLitEnd - sequence.offset;
Yann Collet5be2dd22015-11-11 13:43:58 +0100702
703 /* check */
704 if (oLitEnd > oend_8) return ERROR(dstSize_tooSmall); /* last match must start at a minimum distance of 8 from oend */
705 if (oMatchEnd > oend) return ERROR(dstSize_tooSmall); /* overwrite beyond dst buffer */
706 if (litEnd > litLimit_8) return ERROR(corruption_detected); /* risk read beyond lit buffer */
707
708 /* copy Literals */
709 ZSTD_wildcopy(op, *litPtr, sequence.litLength); /* note : oLitEnd <= oend-8 : no risk of overwrite beyond oend */
710 op = oLitEnd;
711 *litPtr = litEnd; /* update for next sequence */
712
713 /* copy Match */
Yann Collet7b51a292016-01-26 15:58:49 +0100714 if (sequence.offset > (size_t)(oLitEnd - base)) {
Yann Collet44287a32015-11-30 23:13:56 +0100715 /* offset beyond prefix */
Yann Collet9f5ab1a2015-12-11 00:27:41 +0100716 if (sequence.offset > (size_t)(oLitEnd - vBase))
717 return ERROR(corruption_detected);
Yann Collet44287a32015-11-30 23:13:56 +0100718 match = dictEnd - (base-match);
Yann Collet7b51a292016-01-26 15:58:49 +0100719 if (match + sequence.matchLength <= dictEnd) {
Yann Collet4bfe4152015-12-06 13:18:37 +0100720 memmove(oLitEnd, match, sequence.matchLength);
Yann Collet44287a32015-11-30 23:13:56 +0100721 return sequenceLength;
722 }
723 /* span extDict & currentPrefixSegment */
724 {
725 size_t length1 = dictEnd - match;
Yann Collet4bfe4152015-12-06 13:18:37 +0100726 memmove(oLitEnd, match, length1);
Yann Collet44287a32015-11-30 23:13:56 +0100727 op = oLitEnd + length1;
728 sequence.matchLength -= length1;
729 match = base;
Yann Colletfb810d62016-01-28 00:18:06 +0100730 } }
Yann Collet0f366c62015-11-12 16:19:30 +0100731
Yann Collet44287a32015-11-30 23:13:56 +0100732 /* match within prefix */
Yann Collet7b51a292016-01-26 15:58:49 +0100733 if (sequence.offset < 8) {
Yann Collet44287a32015-11-30 23:13:56 +0100734 /* close range match, overlap */
735 const int sub2 = dec64table[sequence.offset];
736 op[0] = match[0];
737 op[1] = match[1];
738 op[2] = match[2];
739 op[3] = match[3];
740 match += dec32table[sequence.offset];
741 ZSTD_copy4(op+4, match);
742 match -= sub2;
Yann Colletfb810d62016-01-28 00:18:06 +0100743 } else {
Yann Collet44287a32015-11-30 23:13:56 +0100744 ZSTD_copy8(op, match);
745 }
746 op += 8; match += 8;
Yann Collet5be2dd22015-11-11 13:43:58 +0100747
Yann Collet7b51a292016-01-26 15:58:49 +0100748 if (oMatchEnd > oend-12) {
749 if (op < oend_8) {
Yann Collet44287a32015-11-30 23:13:56 +0100750 ZSTD_wildcopy(op, match, oend_8 - op);
751 match += oend_8 - op;
752 op = oend_8;
753 }
Yann Colletfb810d62016-01-28 00:18:06 +0100754 while (op < oMatchEnd)
755 *op++ = *match++;
756 } else {
Yann Collet44287a32015-11-30 23:13:56 +0100757 ZSTD_wildcopy(op, match, sequence.matchLength-8); /* works even if matchLength < 8 */
758 }
759 return sequenceLength;
Yann Collet5be2dd22015-11-11 13:43:58 +0100760}
761
Yann Colletb3a2af92015-11-19 17:13:19 +0100762
Yann Collet5be2dd22015-11-11 13:43:58 +0100763static size_t ZSTD_decompressSequences(
Yann Collet5b78d2f2015-11-12 15:36:05 +0100764 ZSTD_DCtx* dctx,
Yann Collet5be2dd22015-11-11 13:43:58 +0100765 void* dst, size_t maxDstSize,
766 const void* seqStart, size_t seqSize)
767{
Yann Collet5be2dd22015-11-11 13:43:58 +0100768 const BYTE* ip = (const BYTE*)seqStart;
769 const BYTE* const iend = ip + seqSize;
770 BYTE* const ostart = (BYTE* const)dst;
771 BYTE* op = ostart;
772 BYTE* const oend = ostart + maxDstSize;
773 size_t errorCode, dumpsLength;
774 const BYTE* litPtr = dctx->litPtr;
775 const BYTE* const litLimit_8 = litPtr + dctx->litBufSize - 8;
776 const BYTE* const litEnd = litPtr + dctx->litSize;
777 int nbSeq;
778 const BYTE* dumps;
779 U32* DTableLL = dctx->LLTable;
780 U32* DTableML = dctx->MLTable;
781 U32* DTableOffb = dctx->OffTable;
Yann Collet417890c2015-12-04 17:16:37 +0100782 const BYTE* const base = (const BYTE*) (dctx->base);
783 const BYTE* const vBase = (const BYTE*) (dctx->vBase);
784 const BYTE* const dictEnd = (const BYTE*) (dctx->dictEnd);
Yann Collet5be2dd22015-11-11 13:43:58 +0100785
786 /* Build Decoding Tables */
787 errorCode = ZSTD_decodeSeqHeaders(&nbSeq, &dumps, &dumpsLength,
788 DTableLL, DTableML, DTableOffb,
Yann Colletfb810d62016-01-28 00:18:06 +0100789 ip, seqSize);
Yann Collet5be2dd22015-11-11 13:43:58 +0100790 if (ZSTD_isError(errorCode)) return errorCode;
791 ip += errorCode;
792
793 /* Regen sequences */
Yann Collete93d6ce2016-01-31 00:58:06 +0100794 if (nbSeq) {
Yann Collet5be2dd22015-11-11 13:43:58 +0100795 seq_t sequence;
796 seqState_t seqState;
797
798 memset(&sequence, 0, sizeof(sequence));
Yann Collet61e16ce2016-01-31 02:04:15 +0100799 sequence.offset = REPCODE_STARTVALUE;
Yann Collet5be2dd22015-11-11 13:43:58 +0100800 seqState.dumps = dumps;
801 seqState.dumpsEnd = dumps + dumpsLength;
Yann Collet61e16ce2016-01-31 02:04:15 +0100802 seqState.prevOffset = REPCODE_STARTVALUE;
Yann Collet5be2dd22015-11-11 13:43:58 +0100803 errorCode = BIT_initDStream(&(seqState.DStream), ip, iend-ip);
804 if (ERR_isError(errorCode)) return ERROR(corruption_detected);
805 FSE_initDState(&(seqState.stateLL), &(seqState.DStream), DTableLL);
806 FSE_initDState(&(seqState.stateOffb), &(seqState.DStream), DTableOffb);
807 FSE_initDState(&(seqState.stateML), &(seqState.DStream), DTableML);
808
Yann Collet7b51a292016-01-26 15:58:49 +0100809 for ( ; (BIT_reloadDStream(&(seqState.DStream)) <= BIT_DStream_completed) && nbSeq ; ) {
Yann Colletb3a2af92015-11-19 17:13:19 +0100810 size_t oneSeqSize;
811 nbSeq--;
812 ZSTD_decodeSequence(&sequence, &seqState);
813 oneSeqSize = ZSTD_execSequence(op, oend, sequence, &litPtr, litLimit_8, base, vBase, dictEnd);
Yann Collet5be2dd22015-11-11 13:43:58 +0100814 if (ZSTD_isError(oneSeqSize)) return oneSeqSize;
815 op += oneSeqSize;
816 }
817
818 /* check if reached exact end */
Yann Collet35f7de52016-01-31 02:51:03 +0100819 if (nbSeq) return ERROR(corruption_detected);
Yann Collete93d6ce2016-01-31 00:58:06 +0100820 }
Yann Collet5be2dd22015-11-11 13:43:58 +0100821
Yann Collete93d6ce2016-01-31 00:58:06 +0100822 /* last literal segment */
823 {
824 size_t lastLLSize = litEnd - litPtr;
825 if (litPtr > litEnd) return ERROR(corruption_detected); /* too many literals already used */
826 if (op+lastLLSize > oend) return ERROR(dstSize_tooSmall);
827 memcpy(op, litPtr, lastLLSize);
828 op += lastLLSize;
829 }
Yann Collet5be2dd22015-11-11 13:43:58 +0100830
831 return op-ostart;
832}
833
834
Yann Colletb0125102016-01-09 02:00:10 +0100835static void ZSTD_checkContinuity(ZSTD_DCtx* dctx, const void* dst)
836{
Yann Collet7b51a292016-01-26 15:58:49 +0100837 if (dst != dctx->previousDstEnd) { /* not contiguous */
Yann Colletb0125102016-01-09 02:00:10 +0100838 dctx->dictEnd = dctx->previousDstEnd;
839 dctx->vBase = (const char*)dst - ((const char*)(dctx->previousDstEnd) - (const char*)(dctx->base));
840 dctx->base = dst;
841 dctx->previousDstEnd = dst;
842 }
843}
844
845
846static size_t ZSTD_decompressBlock_internal(ZSTD_DCtx* dctx,
Yann Colletb010b3b2016-02-03 12:39:34 +0100847 void* dst, size_t dstCapacity,
Yann Collet5be2dd22015-11-11 13:43:58 +0100848 const void* src, size_t srcSize)
Yann Colletb010b3b2016-02-03 12:39:34 +0100849{ /* blockType == blockCompressed */
Yann Collet5be2dd22015-11-11 13:43:58 +0100850 const BYTE* ip = (const BYTE*)src;
Yann Colletb010b3b2016-02-03 12:39:34 +0100851 size_t litCSize;
852
853 if (srcSize >= BLOCKSIZE) return ERROR(srcSize_wrong);
Yann Collet5be2dd22015-11-11 13:43:58 +0100854
855 /* Decode literals sub-block */
Yann Colletb010b3b2016-02-03 12:39:34 +0100856 litCSize = ZSTD_decodeLiteralsBlock(dctx, src, srcSize);
Yann Collet5be2dd22015-11-11 13:43:58 +0100857 if (ZSTD_isError(litCSize)) return litCSize;
858 ip += litCSize;
859 srcSize -= litCSize;
860
Yann Colletb010b3b2016-02-03 12:39:34 +0100861 return ZSTD_decompressSequences(dctx, dst, dstCapacity, ip, srcSize);
Yann Collet5be2dd22015-11-11 13:43:58 +0100862}
863
864
Yann Colletb0125102016-01-09 02:00:10 +0100865size_t ZSTD_decompressBlock(ZSTD_DCtx* dctx,
Yann Colletb010b3b2016-02-03 12:39:34 +0100866 void* dst, size_t dstCapacity,
Yann Colletb0125102016-01-09 02:00:10 +0100867 const void* src, size_t srcSize)
868{
869 ZSTD_checkContinuity(dctx, dst);
Yann Colletb010b3b2016-02-03 12:39:34 +0100870 return ZSTD_decompressBlock_internal(dctx, dst, dstCapacity, src, srcSize);
Yann Colletb0125102016-01-09 02:00:10 +0100871}
872
873
Yann Collet7b51a292016-01-26 15:58:49 +0100874/*! ZSTD_decompress_continueDCtx
875* dctx must have been properly initialized */
876static size_t ZSTD_decompress_continueDCtx(ZSTD_DCtx* dctx,
Yann Collet31683c02015-12-18 01:26:48 +0100877 void* dst, size_t maxDstSize,
Yann Collet7b51a292016-01-26 15:58:49 +0100878 const void* src, size_t srcSize)
Yann Collet5be2dd22015-11-11 13:43:58 +0100879{
880 const BYTE* ip = (const BYTE*)src;
881 const BYTE* iend = ip + srcSize;
882 BYTE* const ostart = (BYTE* const)dst;
883 BYTE* op = ostart;
884 BYTE* const oend = ostart + maxDstSize;
885 size_t remainingSize = srcSize;
Yann Collet5be2dd22015-11-11 13:43:58 +0100886 blockProperties_t blockProperties;
887
888 /* Frame Header */
Yann Collet88fcd292015-11-25 14:42:45 +0100889 {
890 size_t frameHeaderSize;
891 if (srcSize < ZSTD_frameHeaderSize_min+ZSTD_blockHeaderSize) return ERROR(srcSize_wrong);
Yann Collet5be2dd22015-11-11 13:43:58 +0100892#if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT==1)
Yann Collet88fcd292015-11-25 14:42:45 +0100893 {
894 const U32 magicNumber = MEM_readLE32(src);
895 if (ZSTD_isLegacy(magicNumber))
896 return ZSTD_decompressLegacy(dst, maxDstSize, src, srcSize, magicNumber);
897 }
Yann Collet5be2dd22015-11-11 13:43:58 +0100898#endif
Yann Collet37422192016-01-25 16:54:05 +0100899 frameHeaderSize = ZSTD_decodeFrameHeader_Part1(dctx, src, ZSTD_frameHeaderSize_min);
Yann Collet88fcd292015-11-25 14:42:45 +0100900 if (ZSTD_isError(frameHeaderSize)) return frameHeaderSize;
901 if (srcSize < frameHeaderSize+ZSTD_blockHeaderSize) return ERROR(srcSize_wrong);
902 ip += frameHeaderSize; remainingSize -= frameHeaderSize;
Yann Collet37422192016-01-25 16:54:05 +0100903 frameHeaderSize = ZSTD_decodeFrameHeader_Part2(dctx, src, frameHeaderSize);
Yann Collet88fcd292015-11-25 14:42:45 +0100904 if (ZSTD_isError(frameHeaderSize)) return frameHeaderSize;
905 }
Yann Collet5be2dd22015-11-11 13:43:58 +0100906
907 /* Loop on each block */
908 while (1)
909 {
910 size_t decodedSize=0;
911 size_t cBlockSize = ZSTD_getcBlockSize(ip, iend-ip, &blockProperties);
912 if (ZSTD_isError(cBlockSize)) return cBlockSize;
913
914 ip += ZSTD_blockHeaderSize;
915 remainingSize -= ZSTD_blockHeaderSize;
916 if (cBlockSize > remainingSize) return ERROR(srcSize_wrong);
917
918 switch(blockProperties.blockType)
919 {
920 case bt_compressed:
Yann Collet37422192016-01-25 16:54:05 +0100921 decodedSize = ZSTD_decompressBlock_internal(dctx, op, oend-op, ip, cBlockSize);
Yann Collet5be2dd22015-11-11 13:43:58 +0100922 break;
923 case bt_raw :
Yann Collet0f366c62015-11-12 16:19:30 +0100924 decodedSize = ZSTD_copyRawBlock(op, oend-op, ip, cBlockSize);
Yann Collet5be2dd22015-11-11 13:43:58 +0100925 break;
926 case bt_rle :
927 return ERROR(GENERIC); /* not yet supported */
928 break;
929 case bt_end :
930 /* end of frame */
931 if (remainingSize) return ERROR(srcSize_wrong);
932 break;
933 default:
934 return ERROR(GENERIC); /* impossible */
935 }
936 if (cBlockSize == 0) break; /* bt_end */
937
938 if (ZSTD_isError(decodedSize)) return decodedSize;
939 op += decodedSize;
940 ip += cBlockSize;
941 remainingSize -= cBlockSize;
942 }
943
944 return op-ostart;
945}
946
Yann Collet31683c02015-12-18 01:26:48 +0100947
Yann Collet7b51a292016-01-26 15:58:49 +0100948size_t ZSTD_decompress_usingPreparedDCtx(ZSTD_DCtx* dctx, const ZSTD_DCtx* refDCtx,
949 void* dst, size_t maxDstSize,
950 const void* src, size_t srcSize)
951{
952 ZSTD_copyDCtx(dctx, refDCtx);
953 ZSTD_checkContinuity(dctx, dst);
954 return ZSTD_decompress_continueDCtx(dctx, dst, maxDstSize, src, srcSize);
955}
956
957
958size_t ZSTD_decompress_usingDict(ZSTD_DCtx* dctx,
959 void* dst, size_t maxDstSize,
960 const void* src, size_t srcSize,
961 const void* dict, size_t dictSize)
962{
963 ZSTD_decompressBegin_usingDict(dctx, dict, dictSize);
964 ZSTD_checkContinuity(dctx, dst);
965 return ZSTD_decompress_continueDCtx(dctx, dst, maxDstSize, src, srcSize);
966}
967
968
Yann Collet31683c02015-12-18 01:26:48 +0100969size_t ZSTD_decompressDCtx(ZSTD_DCtx* dctx, void* dst, size_t maxDstSize, const void* src, size_t srcSize)
970{
971 return ZSTD_decompress_usingDict(dctx, dst, maxDstSize, src, srcSize, NULL, 0);
972}
973
Yann Collet5be2dd22015-11-11 13:43:58 +0100974size_t ZSTD_decompress(void* dst, size_t maxDstSize, const void* src, size_t srcSize)
975{
Yann Collet3a3b72f2016-01-11 12:56:11 +0100976#if defined(ZSTD_HEAPMODE) && (ZSTD_HEAPMODE==1)
977 size_t regenSize;
978 ZSTD_DCtx* dctx = ZSTD_createDCtx();
979 if (dctx==NULL) return ERROR(memory_allocation);
980 regenSize = ZSTD_decompressDCtx(dctx, dst, maxDstSize, src, srcSize);
981 ZSTD_freeDCtx(dctx);
982 return regenSize;
983#else
Yann Collet31683c02015-12-18 01:26:48 +0100984 ZSTD_DCtx dctx;
985 return ZSTD_decompressDCtx(&dctx, dst, maxDstSize, src, srcSize);
Yann Colleta768a302016-01-21 16:04:35 +0100986#endif
Yann Collet5be2dd22015-11-11 13:43:58 +0100987}
988
989
990/* ******************************
991* Streaming Decompression API
992********************************/
Yann Collet5be2dd22015-11-11 13:43:58 +0100993size_t ZSTD_nextSrcSizeToDecompress(ZSTD_DCtx* dctx)
994{
995 return dctx->expected;
996}
997
Yann Collet37422192016-01-25 16:54:05 +0100998size_t ZSTD_decompressContinue(ZSTD_DCtx* dctx, void* dst, size_t maxDstSize, const void* src, size_t srcSize)
Yann Collet5be2dd22015-11-11 13:43:58 +0100999{
1000 /* Sanity check */
Yann Collet37422192016-01-25 16:54:05 +01001001 if (srcSize != dctx->expected) return ERROR(srcSize_wrong);
1002 ZSTD_checkContinuity(dctx, dst);
Yann Collet5be2dd22015-11-11 13:43:58 +01001003
Yann Collet88fcd292015-11-25 14:42:45 +01001004 /* Decompress : frame header; part 1 */
Yann Collet37422192016-01-25 16:54:05 +01001005 switch (dctx->stage)
Yann Collet5be2dd22015-11-11 13:43:58 +01001006 {
Yann Collet88fcd292015-11-25 14:42:45 +01001007 case ZSTDds_getFrameHeaderSize :
Yann Collet5be2dd22015-11-11 13:43:58 +01001008 {
Yann Collet88fcd292015-11-25 14:42:45 +01001009 /* get frame header size */
1010 if (srcSize != ZSTD_frameHeaderSize_min) return ERROR(srcSize_wrong); /* impossible */
Yann Collet37422192016-01-25 16:54:05 +01001011 dctx->headerSize = ZSTD_decodeFrameHeader_Part1(dctx, src, ZSTD_frameHeaderSize_min);
1012 if (ZSTD_isError(dctx->headerSize)) return dctx->headerSize;
1013 memcpy(dctx->headerBuffer, src, ZSTD_frameHeaderSize_min);
Yann Collet7b51a292016-01-26 15:58:49 +01001014 if (dctx->headerSize > ZSTD_frameHeaderSize_min) {
Yann Collet37422192016-01-25 16:54:05 +01001015 dctx->expected = dctx->headerSize - ZSTD_frameHeaderSize_min;
1016 dctx->stage = ZSTDds_decodeFrameHeader;
Yann Collet88fcd292015-11-25 14:42:45 +01001017 return 0;
1018 }
Yann Collet37422192016-01-25 16:54:05 +01001019 dctx->expected = 0; /* not necessary to copy more */
Yann Collet5be2dd22015-11-11 13:43:58 +01001020 }
Yann Collet88fcd292015-11-25 14:42:45 +01001021 case ZSTDds_decodeFrameHeader:
Yann Collet5be2dd22015-11-11 13:43:58 +01001022 {
Yann Collet88fcd292015-11-25 14:42:45 +01001023 /* get frame header */
1024 size_t result;
Yann Collet37422192016-01-25 16:54:05 +01001025 memcpy(dctx->headerBuffer + ZSTD_frameHeaderSize_min, src, dctx->expected);
1026 result = ZSTD_decodeFrameHeader_Part2(dctx, dctx->headerBuffer, dctx->headerSize);
Yann Collet88fcd292015-11-25 14:42:45 +01001027 if (ZSTD_isError(result)) return result;
Yann Collet37422192016-01-25 16:54:05 +01001028 dctx->expected = ZSTD_blockHeaderSize;
1029 dctx->stage = ZSTDds_decodeBlockHeader;
Yann Collet88fcd292015-11-25 14:42:45 +01001030 return 0;
Yann Collet5be2dd22015-11-11 13:43:58 +01001031 }
Yann Collet88fcd292015-11-25 14:42:45 +01001032 case ZSTDds_decodeBlockHeader:
Yann Collet5be2dd22015-11-11 13:43:58 +01001033 {
Yann Collet88fcd292015-11-25 14:42:45 +01001034 /* Decode block header */
1035 blockProperties_t bp;
1036 size_t blockSize = ZSTD_getcBlockSize(src, ZSTD_blockHeaderSize, &bp);
1037 if (ZSTD_isError(blockSize)) return blockSize;
Yann Collet7b51a292016-01-26 15:58:49 +01001038 if (bp.blockType == bt_end) {
Yann Collet37422192016-01-25 16:54:05 +01001039 dctx->expected = 0;
1040 dctx->stage = ZSTDds_getFrameHeaderSize;
Yann Collet88fcd292015-11-25 14:42:45 +01001041 }
Yann Collet7b51a292016-01-26 15:58:49 +01001042 else {
Yann Collet37422192016-01-25 16:54:05 +01001043 dctx->expected = blockSize;
1044 dctx->bType = bp.blockType;
1045 dctx->stage = ZSTDds_decompressBlock;
Yann Collet88fcd292015-11-25 14:42:45 +01001046 }
Yann Collet88fcd292015-11-25 14:42:45 +01001047 return 0;
1048 }
Yann Collet417890c2015-12-04 17:16:37 +01001049 case ZSTDds_decompressBlock:
Yann Collet88fcd292015-11-25 14:42:45 +01001050 {
1051 /* Decompress : block content */
1052 size_t rSize;
Yann Collet37422192016-01-25 16:54:05 +01001053 switch(dctx->bType)
Yann Collet88fcd292015-11-25 14:42:45 +01001054 {
1055 case bt_compressed:
Yann Collet37422192016-01-25 16:54:05 +01001056 rSize = ZSTD_decompressBlock_internal(dctx, dst, maxDstSize, src, srcSize);
Yann Collet88fcd292015-11-25 14:42:45 +01001057 break;
1058 case bt_raw :
1059 rSize = ZSTD_copyRawBlock(dst, maxDstSize, src, srcSize);
1060 break;
1061 case bt_rle :
1062 return ERROR(GENERIC); /* not yet handled */
1063 break;
1064 case bt_end : /* should never happen (filtered at phase 1) */
1065 rSize = 0;
1066 break;
1067 default:
Yann Collet7b51a292016-01-26 15:58:49 +01001068 return ERROR(GENERIC); /* impossible */
Yann Collet88fcd292015-11-25 14:42:45 +01001069 }
Yann Collet37422192016-01-25 16:54:05 +01001070 dctx->stage = ZSTDds_decodeBlockHeader;
1071 dctx->expected = ZSTD_blockHeaderSize;
1072 dctx->previousDstEnd = (char*)dst + rSize;
Yann Collet88fcd292015-11-25 14:42:45 +01001073 return rSize;
1074 }
1075 default:
1076 return ERROR(GENERIC); /* impossible */
1077 }
Yann Collet5be2dd22015-11-11 13:43:58 +01001078}
1079
1080
Yann Colletb923f652016-01-26 03:14:20 +01001081static void ZSTD_refDictContent(ZSTD_DCtx* dctx, const void* dict, size_t dictSize)
Yann Collet417890c2015-12-04 17:16:37 +01001082{
Yann Collet37422192016-01-25 16:54:05 +01001083 dctx->dictEnd = dctx->previousDstEnd;
1084 dctx->vBase = (const char*)dict - ((const char*)(dctx->previousDstEnd) - (const char*)(dctx->base));
1085 dctx->base = dict;
1086 dctx->previousDstEnd = (const char*)dict + dictSize;
Yann Collet417890c2015-12-04 17:16:37 +01001087}
Yann Colletb923f652016-01-26 03:14:20 +01001088
Yann Colletb923f652016-01-26 03:14:20 +01001089static size_t ZSTD_loadEntropy(ZSTD_DCtx* dctx, const void* dict, size_t dictSize)
1090{
Yann Colletfb810d62016-01-28 00:18:06 +01001091 size_t hSize, offcodeHeaderSize, matchlengthHeaderSize, errorCode, litlengthHeaderSize;
1092 short offcodeNCount[MaxOff+1];
1093 U32 offcodeMaxValue=MaxOff, offcodeLog=OffFSELog;
1094 short matchlengthNCount[MaxML+1];
1095 unsigned matchlengthMaxValue = MaxML, matchlengthLog = MLFSELog;
1096 short litlengthNCount[MaxLL+1];
1097 unsigned litlengthMaxValue = MaxLL, litlengthLog = LLFSELog;
1098
1099 hSize = HUF_readDTableX4(dctx->hufTableX4, dict, dictSize);
Yann Colletb923f652016-01-26 03:14:20 +01001100 if (HUF_isError(hSize)) return ERROR(dictionary_corrupted);
Yann Colletfb810d62016-01-28 00:18:06 +01001101 dict = (const char*)dict + hSize;
1102 dictSize -= hSize;
1103
1104 offcodeHeaderSize = FSE_readNCount(offcodeNCount, &offcodeMaxValue, &offcodeLog, dict, dictSize);
1105 if (FSE_isError(offcodeHeaderSize)) return ERROR(dictionary_corrupted);
1106 errorCode = FSE_buildDTable(dctx->OffTable, offcodeNCount, offcodeMaxValue, offcodeLog);
1107 if (FSE_isError(errorCode)) return ERROR(dictionary_corrupted);
1108 dict = (const char*)dict + offcodeHeaderSize;
1109 dictSize -= offcodeHeaderSize;
1110
1111 matchlengthHeaderSize = FSE_readNCount(matchlengthNCount, &matchlengthMaxValue, &matchlengthLog, dict, dictSize);
1112 if (FSE_isError(matchlengthHeaderSize)) return ERROR(dictionary_corrupted);
1113 errorCode = FSE_buildDTable(dctx->MLTable, matchlengthNCount, matchlengthMaxValue, matchlengthLog);
1114 if (FSE_isError(errorCode)) return ERROR(dictionary_corrupted);
1115 dict = (const char*)dict + matchlengthHeaderSize;
1116 dictSize -= matchlengthHeaderSize;
1117
1118 litlengthHeaderSize = FSE_readNCount(litlengthNCount, &litlengthMaxValue, &litlengthLog, dict, dictSize);
1119 if (FSE_isError(litlengthHeaderSize)) return ERROR(dictionary_corrupted);
1120 errorCode = FSE_buildDTable(dctx->LLTable, litlengthNCount, litlengthMaxValue, litlengthLog);
1121 if (FSE_isError(errorCode)) return ERROR(dictionary_corrupted);
1122
1123 dctx->flagStaticTables = 1;
1124 return hSize + offcodeHeaderSize + matchlengthHeaderSize + litlengthHeaderSize;
Yann Colletb923f652016-01-26 03:14:20 +01001125}
1126
Yann Collet7b51a292016-01-26 15:58:49 +01001127static size_t ZSTD_decompress_insertDictionary(ZSTD_DCtx* dctx, const void* dict, size_t dictSize)
Yann Colletb923f652016-01-26 03:14:20 +01001128{
1129 size_t eSize;
1130 U32 magic = MEM_readLE32(dict);
1131 if (magic != ZSTD_DICT_MAGIC) {
1132 /* pure content mode */
1133 ZSTD_refDictContent(dctx, dict, dictSize);
1134 return 0;
1135 }
1136 /* load entropy tables */
1137 dict = (const char*)dict + 4;
1138 dictSize -= 4;
1139 eSize = ZSTD_loadEntropy(dctx, dict, dictSize);
1140 if (ZSTD_isError(eSize)) return ERROR(dictionary_corrupted);
1141
1142 /* reference dictionary content */
1143 dict = (const char*)dict + eSize;
1144 dictSize -= eSize;
1145 ZSTD_refDictContent(dctx, dict, dictSize);
1146
1147 return 0;
1148}
1149
Yann Collet7b51a292016-01-26 15:58:49 +01001150
1151size_t ZSTD_decompressBegin_usingDict(ZSTD_DCtx* dctx, const void* dict, size_t dictSize)
1152{
1153 size_t errorCode;
1154 errorCode = ZSTD_decompressBegin(dctx);
1155 if (ZSTD_isError(errorCode)) return errorCode;
1156
1157 if (dict && dictSize) {
1158 errorCode = ZSTD_decompress_insertDictionary(dctx, dict, dictSize);
1159 if (ZSTD_isError(errorCode)) return ERROR(dictionary_corrupted);
1160 }
1161
1162 return 0;
1163}
1164