blob: b50e474fbcfc1ae8c7d6987df0de18a6a2b1c146 [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;
276 if (srcSize != ZSTD_frameHeaderSize_min) return ERROR(srcSize_wrong);
277 magicNumber = MEM_readLE32(src);
278 if (magicNumber != ZSTD_MAGICNUMBER) return ERROR(prefix_unknown);
279 zc->headerSize = ZSTD_frameHeaderSize_min;
280 return zc->headerSize;
281}
282
Yann Collet88fcd292015-11-25 14:42:45 +0100283
284size_t ZSTD_getFrameParams(ZSTD_parameters* params, const void* src, size_t srcSize)
285{
286 U32 magicNumber;
287 if (srcSize < ZSTD_frameHeaderSize_min) return ZSTD_frameHeaderSize_max;
288 magicNumber = MEM_readLE32(src);
289 if (magicNumber != ZSTD_MAGICNUMBER) return ERROR(prefix_unknown);
290 memset(params, 0, sizeof(*params));
Yann Collet26415d32015-11-26 12:43:28 +0100291 params->windowLog = (((const BYTE*)src)[4] & 15) + ZSTD_WINDOWLOG_ABSOLUTEMIN;
Yann Colletbf7aa3c2015-11-28 18:19:44 +0100292 if ((((const BYTE*)src)[4] >> 4) != 0) return ERROR(frameParameter_unsupported); /* reserved bits */
Yann Collet88fcd292015-11-25 14:42:45 +0100293 return 0;
294}
295
Yann Collet26415d32015-11-26 12:43:28 +0100296/** ZSTD_decodeFrameHeader_Part2
297* decode the full Frame Header
298* srcSize must be the size provided by ZSTD_decodeFrameHeader_Part1
299* @return : 0, or an error code, which can be tested using ZSTD_isError() */
300static size_t ZSTD_decodeFrameHeader_Part2(ZSTD_DCtx* zc, const void* src, size_t srcSize)
301{
Yann Collet00fd7a22015-11-28 16:03:22 +0100302 size_t result;
Yann Collet26415d32015-11-26 12:43:28 +0100303 if (srcSize != zc->headerSize) return ERROR(srcSize_wrong);
Yann Collet00fd7a22015-11-28 16:03:22 +0100304 result = ZSTD_getFrameParams(&(zc->params), src, srcSize);
305 if ((MEM_32bits()) && (zc->params.windowLog > 25)) return ERROR(frameParameter_unsupportedBy32bitsImplementation);
306 return result;
Yann Collet26415d32015-11-26 12:43:28 +0100307}
308
Yann Collet5be2dd22015-11-11 13:43:58 +0100309
310size_t ZSTD_getcBlockSize(const void* src, size_t srcSize, blockProperties_t* bpPtr)
311{
312 const BYTE* const in = (const BYTE* const)src;
313 BYTE headerFlags;
314 U32 cSize;
315
316 if (srcSize < 3) return ERROR(srcSize_wrong);
317
318 headerFlags = *in;
319 cSize = in[2] + (in[1]<<8) + ((in[0] & 7)<<16);
320
321 bpPtr->blockType = (blockType_t)(headerFlags >> 6);
322 bpPtr->origSize = (bpPtr->blockType == bt_rle) ? cSize : 0;
323
324 if (bpPtr->blockType == bt_end) return 0;
325 if (bpPtr->blockType == bt_rle) return 1;
326 return cSize;
327}
328
Yann Collet59d1f792016-01-23 19:28:41 +0100329
Yann Collet0f366c62015-11-12 16:19:30 +0100330static size_t ZSTD_copyRawBlock(void* dst, size_t maxDstSize, const void* src, size_t srcSize)
Yann Collet5be2dd22015-11-11 13:43:58 +0100331{
332 if (srcSize > maxDstSize) return ERROR(dstSize_tooSmall);
333 memcpy(dst, src, srcSize);
334 return srcSize;
335}
336
337
Yann Collet5be2dd22015-11-11 13:43:58 +0100338/** ZSTD_decodeLiteralsBlock
Yann Collet14983e72015-11-11 21:38:21 +0100339 @return : nb of bytes read from src (< srcSize ) */
Yann Collet5b78d2f2015-11-12 15:36:05 +0100340size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx,
Yann Collet5be2dd22015-11-11 13:43:58 +0100341 const void* src, size_t srcSize) /* note : srcSize < BLOCKSIZE */
342{
Yann Collet5be2dd22015-11-11 13:43:58 +0100343 const BYTE* const istart = (const BYTE*) src;
344
345 /* any compressed block with literals segment must be at least this size */
346 if (srcSize < MIN_CBLOCK_SIZE) return ERROR(corruption_detected);
347
Yann Collet59d1f792016-01-23 19:28:41 +0100348 switch(istart[0]>> 6)
Yann Collet5be2dd22015-11-11 13:43:58 +0100349 {
Yann Collet59d1f792016-01-23 19:28:41 +0100350 case IS_HUF:
Yann Collet5be2dd22015-11-11 13:43:58 +0100351 {
Yann Colletafe07092016-01-25 04:10:46 +0100352 size_t litSize, litCSize, singleStream=0;
Yann Collet59d1f792016-01-23 19:28:41 +0100353 U32 lhSize = ((istart[0]) >> 4) & 3;
354 switch(lhSize)
355 {
356 case 0: case 1: default: /* note : default is impossible, since lhSize into [0..3] */
357 /* 2 - 2 - 10 - 10 */
358 lhSize=3;
Yann Colletafe07092016-01-25 04:10:46 +0100359 singleStream = istart[0] & 16;
Yann Collet59d1f792016-01-23 19:28:41 +0100360 litSize = ((istart[0] & 15) << 6) + (istart[1] >> 2);
361 litCSize = ((istart[1] & 3) << 8) + istart[2];
362 break;
363 case 2:
364 /* 2 - 2 - 14 - 14 */
365 lhSize=4;
366 litSize = ((istart[0] & 15) << 10) + (istart[1] << 2) + (istart[2] >> 6);
367 litCSize = ((istart[2] & 63) << 8) + istart[3];
368 break;
369 case 3:
370 /* 2 - 2 - 18 - 18 */
371 lhSize=5;
372 litSize = ((istart[0] & 15) << 14) + (istart[1] << 6) + (istart[2] >> 2);
373 litCSize = ((istart[2] & 3) << 16) + (istart[3] << 8) + istart[4];
374 break;
375 }
Yann Colletfb810d62016-01-28 00:18:06 +0100376 if (litSize > BLOCKSIZE) return ERROR(corruption_detected);
Yann Collet59d1f792016-01-23 19:28:41 +0100377
Yann Colletafe07092016-01-25 04:10:46 +0100378 if (HUF_isError(singleStream ?
379 HUF_decompress1X2(dctx->litBuffer, litSize, istart+lhSize, litCSize) :
380 HUF_decompress (dctx->litBuffer, litSize, istart+lhSize, litCSize) ))
Yann Collet59d1f792016-01-23 19:28:41 +0100381 return ERROR(corruption_detected);
382
Yann Collet5be2dd22015-11-11 13:43:58 +0100383 dctx->litPtr = dctx->litBuffer;
384 dctx->litBufSize = BLOCKSIZE+8;
385 dctx->litSize = litSize;
Yann Collet59d1f792016-01-23 19:28:41 +0100386 return litCSize + lhSize;
Yann Collet5be2dd22015-11-11 13:43:58 +0100387 }
Yann Colletb923f652016-01-26 03:14:20 +0100388 case IS_PCH:
389 {
390 size_t errorCode;
391 size_t litSize, litCSize;
392 U32 lhSize = ((istart[0]) >> 4) & 3;
393 if (lhSize != 1) /* only case supported for now : small litSize, single stream */
394 return ERROR(corruption_detected);
Yann Colletfb810d62016-01-28 00:18:06 +0100395 if (!dctx->flagStaticTables)
Yann Collet7b51a292016-01-26 15:58:49 +0100396 return ERROR(dictionary_corrupted);
Yann Colletb923f652016-01-26 03:14:20 +0100397
398 /* 2 - 2 - 10 - 10 */
399 lhSize=3;
400 litSize = ((istart[0] & 15) << 6) + (istart[1] >> 2);
401 litCSize = ((istart[1] & 3) << 8) + istart[2];
402
403 errorCode = HUF_decompress1X4_usingDTable(dctx->litBuffer, litSize, istart+lhSize, litCSize, dctx->hufTableX4);
404 if (HUF_isError(errorCode)) return ERROR(corruption_detected);
405
406 dctx->litPtr = dctx->litBuffer;
407 dctx->litBufSize = BLOCKSIZE+WILDCOPY_OVERLENGTH;
408 dctx->litSize = litSize;
409 return litCSize + lhSize;
410 }
Yann Collet5be2dd22015-11-11 13:43:58 +0100411 case IS_RAW:
412 {
Yann Collet59d1f792016-01-23 19:28:41 +0100413 size_t litSize;
414 U32 lhSize = ((istart[0]) >> 4) & 3;
415 switch(lhSize)
Yann Collet5be2dd22015-11-11 13:43:58 +0100416 {
Yann Collet59d1f792016-01-23 19:28:41 +0100417 case 0: case 1: default: /* note : default is impossible, since lhSize into [0..3] */
418 lhSize=1;
419 litSize = istart[0] & 31;
420 break;
421 case 2:
422 litSize = ((istart[0] & 15) << 8) + istart[1];
423 break;
424 case 3:
425 litSize = ((istart[0] & 15) << 16) + (istart[1] << 8) + istart[2];
426 break;
427 }
428
Yann Colletbc4c8aa2016-01-25 17:26:01 +0100429 if (litSize+WILDCOPY_OVERLENGTH > srcSize) /* risk reading beyond src buffer with wildcopy */
Yann Collet59d1f792016-01-23 19:28:41 +0100430 {
Yann Collet37422192016-01-25 16:54:05 +0100431 if (litSize > srcSize-lhSize) return ERROR(corruption_detected);
Yann Collet59d1f792016-01-23 19:28:41 +0100432 memcpy(dctx->litBuffer, istart+lhSize, litSize);
Yann Collet5be2dd22015-11-11 13:43:58 +0100433 dctx->litPtr = dctx->litBuffer;
434 dctx->litBufSize = BLOCKSIZE+8;
435 dctx->litSize = litSize;
Yann Colletbc4c8aa2016-01-25 17:26:01 +0100436 return lhSize+litSize;
Yann Collet5be2dd22015-11-11 13:43:58 +0100437 }
438 /* direct reference into compressed stream */
Yann Collet59d1f792016-01-23 19:28:41 +0100439 dctx->litPtr = istart+lhSize;
440 dctx->litBufSize = srcSize-lhSize;
Yann Collet5be2dd22015-11-11 13:43:58 +0100441 dctx->litSize = litSize;
Yann Collet59d1f792016-01-23 19:28:41 +0100442 return lhSize+litSize;
443 }
Yann Collet5be2dd22015-11-11 13:43:58 +0100444 case IS_RLE:
445 {
Yann Collet59d1f792016-01-23 19:28:41 +0100446 size_t litSize;
447 U32 lhSize = ((istart[0]) >> 4) & 3;
448 switch(lhSize)
449 {
450 case 0: case 1: default: /* note : default is impossible, since lhSize into [0..3] */
451 lhSize = 1;
452 litSize = istart[0] & 31;
453 break;
454 case 2:
455 litSize = ((istart[0] & 15) << 8) + istart[1];
456 break;
457 case 3:
458 litSize = ((istart[0] & 15) << 16) + (istart[1] << 8) + istart[2];
459 break;
460 }
Yann Collet5be2dd22015-11-11 13:43:58 +0100461 if (litSize > BLOCKSIZE) return ERROR(corruption_detected);
Yann Collet59d1f792016-01-23 19:28:41 +0100462 memset(dctx->litBuffer, istart[lhSize], litSize);
Yann Collet5be2dd22015-11-11 13:43:58 +0100463 dctx->litPtr = dctx->litBuffer;
Yann Colletb923f652016-01-26 03:14:20 +0100464 dctx->litBufSize = BLOCKSIZE+WILDCOPY_OVERLENGTH;
Yann Collet5be2dd22015-11-11 13:43:58 +0100465 dctx->litSize = litSize;
Yann Collet59d1f792016-01-23 19:28:41 +0100466 return lhSize+1;
Yann Collet5be2dd22015-11-11 13:43:58 +0100467 }
Yann Colletb923f652016-01-26 03:14:20 +0100468 default:
469 return ERROR(corruption_detected); /* impossible */
Yann Collet5be2dd22015-11-11 13:43:58 +0100470 }
471}
472
473
474size_t ZSTD_decodeSeqHeaders(int* nbSeq, const BYTE** dumpsPtr, size_t* dumpsLengthPtr,
475 FSE_DTable* DTableLL, FSE_DTable* DTableML, FSE_DTable* DTableOffb,
476 const void* src, size_t srcSize)
477{
478 const BYTE* const istart = (const BYTE* const)src;
479 const BYTE* ip = istart;
480 const BYTE* const iend = istart + srcSize;
481 U32 LLtype, Offtype, MLtype;
482 U32 LLlog, Offlog, MLlog;
483 size_t dumpsLength;
484
485 /* check */
486 if (srcSize < 5) return ERROR(srcSize_wrong);
487
488 /* SeqHead */
489 *nbSeq = MEM_readLE16(ip); ip+=2;
490 LLtype = *ip >> 6;
491 Offtype = (*ip >> 4) & 3;
492 MLtype = (*ip >> 2) & 3;
Yann Colletfb810d62016-01-28 00:18:06 +0100493 if (*ip & 2) {
Yann Collet5be2dd22015-11-11 13:43:58 +0100494 dumpsLength = ip[2];
495 dumpsLength += ip[1] << 8;
496 ip += 3;
Yann Colletfb810d62016-01-28 00:18:06 +0100497 } else {
Yann Collet5be2dd22015-11-11 13:43:58 +0100498 dumpsLength = ip[1];
499 dumpsLength += (ip[0] & 1) << 8;
500 ip += 2;
501 }
502 *dumpsPtr = ip;
503 ip += dumpsLength;
504 *dumpsLengthPtr = dumpsLength;
505
506 /* check */
507 if (ip > iend-3) return ERROR(srcSize_wrong); /* min : all 3 are "raw", hence no header, but at least xxLog bits per type */
508
509 /* sequences */
510 {
Yann Collet82368cf2015-11-16 19:10:56 +0100511 S16 norm[MaxML+1]; /* assumption : MaxML >= MaxLL >= MaxOff */
Yann Collet5be2dd22015-11-11 13:43:58 +0100512 size_t headerSize;
513
514 /* Build DTables */
515 switch(LLtype)
516 {
517 U32 max;
Yann Colletfb810d62016-01-28 00:18:06 +0100518 case FSE_ENCODING_RLE :
Yann Collet5be2dd22015-11-11 13:43:58 +0100519 LLlog = 0;
Yann Colletfb810d62016-01-28 00:18:06 +0100520 FSE_buildDTable_rle(DTableLL, *ip++);
521 break;
522 case FSE_ENCODING_RAW :
Yann Collet5be2dd22015-11-11 13:43:58 +0100523 LLlog = LLbits;
Yann Colletfb810d62016-01-28 00:18:06 +0100524 FSE_buildDTable_raw(DTableLL, LLbits);
525 break;
526 case FSE_ENCODING_STATIC:
527 break;
528 case FSE_ENCODING_DYNAMIC :
529 default : /* impossible */
Yann Collet5be2dd22015-11-11 13:43:58 +0100530 max = MaxLL;
531 headerSize = FSE_readNCount(norm, &max, &LLlog, ip, iend-ip);
532 if (FSE_isError(headerSize)) return ERROR(GENERIC);
533 if (LLlog > LLFSELog) return ERROR(corruption_detected);
534 ip += headerSize;
535 FSE_buildDTable(DTableLL, norm, max, LLlog);
536 }
537
538 switch(Offtype)
539 {
540 U32 max;
Yann Colletfb810d62016-01-28 00:18:06 +0100541 case FSE_ENCODING_RLE :
Yann Collet5be2dd22015-11-11 13:43:58 +0100542 Offlog = 0;
543 if (ip > iend-2) return ERROR(srcSize_wrong); /* min : "raw", hence no header, but at least xxLog bits */
544 FSE_buildDTable_rle(DTableOffb, *ip++ & MaxOff); /* if *ip > MaxOff, data is corrupted */
545 break;
Yann Colletfb810d62016-01-28 00:18:06 +0100546 case FSE_ENCODING_RAW :
Yann Collet5be2dd22015-11-11 13:43:58 +0100547 Offlog = Offbits;
Yann Colletfb810d62016-01-28 00:18:06 +0100548 FSE_buildDTable_raw(DTableOffb, Offbits);
549 break;
550 case FSE_ENCODING_STATIC:
551 break;
552 case FSE_ENCODING_DYNAMIC :
553 default : /* impossible */
Yann Collet5be2dd22015-11-11 13:43:58 +0100554 max = MaxOff;
555 headerSize = FSE_readNCount(norm, &max, &Offlog, ip, iend-ip);
556 if (FSE_isError(headerSize)) return ERROR(GENERIC);
557 if (Offlog > OffFSELog) return ERROR(corruption_detected);
558 ip += headerSize;
559 FSE_buildDTable(DTableOffb, norm, max, Offlog);
560 }
561
562 switch(MLtype)
563 {
564 U32 max;
Yann Colletfb810d62016-01-28 00:18:06 +0100565 case FSE_ENCODING_RLE :
Yann Collet5be2dd22015-11-11 13:43:58 +0100566 MLlog = 0;
567 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 +0100568 FSE_buildDTable_rle(DTableML, *ip++);
569 break;
570 case FSE_ENCODING_RAW :
Yann Collet5be2dd22015-11-11 13:43:58 +0100571 MLlog = MLbits;
Yann Colletfb810d62016-01-28 00:18:06 +0100572 FSE_buildDTable_raw(DTableML, MLbits);
573 break;
574 case FSE_ENCODING_STATIC:
575 break;
576 case FSE_ENCODING_DYNAMIC :
577 default : /* impossible */
Yann Collet5be2dd22015-11-11 13:43:58 +0100578 max = MaxML;
579 headerSize = FSE_readNCount(norm, &max, &MLlog, ip, iend-ip);
580 if (FSE_isError(headerSize)) return ERROR(GENERIC);
581 if (MLlog > MLFSELog) return ERROR(corruption_detected);
582 ip += headerSize;
583 FSE_buildDTable(DTableML, norm, max, MLlog);
Yann Colletfb810d62016-01-28 00:18:06 +0100584 } }
Yann Collet5be2dd22015-11-11 13:43:58 +0100585
586 return ip-istart;
587}
588
589
590typedef struct {
591 size_t litLength;
592 size_t offset;
593 size_t matchLength;
594} seq_t;
595
596typedef struct {
597 BIT_DStream_t DStream;
598 FSE_DState_t stateLL;
599 FSE_DState_t stateOffb;
600 FSE_DState_t stateML;
601 size_t prevOffset;
602 const BYTE* dumps;
603 const BYTE* dumpsEnd;
604} seqState_t;
605
606
607static void ZSTD_decodeSequence(seq_t* seq, seqState_t* seqState)
608{
609 size_t litLength;
610 size_t prevOffset;
611 size_t offset;
612 size_t matchLength;
613 const BYTE* dumps = seqState->dumps;
614 const BYTE* const de = seqState->dumpsEnd;
615
616 /* Literal length */
617 litLength = FSE_decodeSymbol(&(seqState->stateLL), &(seqState->DStream));
Yann Collete4fdad52015-11-25 21:09:17 +0100618 prevOffset = litLength ? seq->offset : seqState->prevOffset;
Yann Colletfb810d62016-01-28 00:18:06 +0100619 if (litLength == MaxLL) {
Yann Collet5be2dd22015-11-11 13:43:58 +0100620 U32 add = *dumps++;
621 if (add < 255) litLength += add;
Yann Colletfb810d62016-01-28 00:18:06 +0100622 else {
Yann Collet5be2dd22015-11-11 13:43:58 +0100623 litLength = MEM_readLE32(dumps) & 0xFFFFFF; /* no pb : dumps is always followed by seq tables > 1 byte */
624 dumps += 3;
625 }
626 if (dumps >= de) dumps = de-1; /* late correction, to avoid read overflow (data is now corrupted anyway) */
627 }
628
629 /* Offset */
630 {
631 static const U32 offsetPrefix[MaxOff+1] = {
632 1 /*fake*/, 1, 2, 4, 8, 16, 32, 64, 128, 256,
633 512, 1024, 2048, 4096, 8192, 16384, 32768, 65536, 131072, 262144,
634 524288, 1048576, 2097152, 4194304, 8388608, 16777216, 33554432, /*fake*/ 1, 1, 1, 1, 1 };
635 U32 offsetCode, nbBits;
636 offsetCode = FSE_decodeSymbol(&(seqState->stateOffb), &(seqState->DStream)); /* <= maxOff, by table construction */
637 if (MEM_32bits()) BIT_reloadDStream(&(seqState->DStream));
638 nbBits = offsetCode - 1;
639 if (offsetCode==0) nbBits = 0; /* cmove */
640 offset = offsetPrefix[offsetCode] + BIT_readBits(&(seqState->DStream), nbBits);
641 if (MEM_32bits()) BIT_reloadDStream(&(seqState->DStream));
642 if (offsetCode==0) offset = prevOffset; /* cmove */
Yann Collet55aa7f92015-11-20 12:04:52 +0100643 if (offsetCode | !litLength) seqState->prevOffset = seq->offset; /* cmove */
Yann Collet5be2dd22015-11-11 13:43:58 +0100644 }
645
646 /* MatchLength */
647 matchLength = FSE_decodeSymbol(&(seqState->stateML), &(seqState->DStream));
Yann Colletfb810d62016-01-28 00:18:06 +0100648 if (matchLength == MaxML) {
Yann Collet5be2dd22015-11-11 13:43:58 +0100649 U32 add = *dumps++;
650 if (add < 255) matchLength += add;
Yann Colletfb810d62016-01-28 00:18:06 +0100651 else {
Yann Collet5be2dd22015-11-11 13:43:58 +0100652 matchLength = MEM_readLE32(dumps) & 0xFFFFFF; /* no pb : dumps is always followed by seq tables > 1 byte */
653 dumps += 3;
654 }
655 if (dumps >= de) dumps = de-1; /* late correction, to avoid read overflow (data is now corrupted anyway) */
656 }
657 matchLength += MINMATCH;
658
659 /* save result */
660 seq->litLength = litLength;
661 seq->offset = offset;
662 seq->matchLength = matchLength;
663 seqState->dumps = dumps;
Yann Colletfb810d62016-01-28 00:18:06 +0100664
665#if 0
666 {
667 static U64 totalDecoded = 0;
668 printf("pos %6u : %3u literals & match %3u bytes at distance %6u \n",
669 (U32)(totalDecoded), (U32)litLength, (U32)matchLength, (U32)offset);
670 totalDecoded += litLength + matchLength;
671 }
672#endif
Yann Collet5be2dd22015-11-11 13:43:58 +0100673}
674
675
Yann Collet5b78d2f2015-11-12 15:36:05 +0100676FORCE_INLINE size_t ZSTD_execSequence(BYTE* op,
Yann Colletb3a2af92015-11-19 17:13:19 +0100677 BYTE* const oend, seq_t sequence,
Yann Collet5be2dd22015-11-11 13:43:58 +0100678 const BYTE** litPtr, const BYTE* const litLimit_8,
Yann Collet417890c2015-12-04 17:16:37 +0100679 const BYTE* const base, const BYTE* const vBase, const BYTE* const dictEnd)
Yann Collet5be2dd22015-11-11 13:43:58 +0100680{
Yann Colletb3a2af92015-11-19 17:13:19 +0100681 static const int dec32table[] = { 0, 1, 2, 1, 4, 4, 4, 4 }; /* added */
682 static const int dec64table[] = { 8, 8, 8, 7, 8, 9,10,11 }; /* substracted */
Yann Collet5be2dd22015-11-11 13:43:58 +0100683 BYTE* const oLitEnd = op + sequence.litLength;
Yann Colletb3a2af92015-11-19 17:13:19 +0100684 const size_t sequenceLength = sequence.litLength + sequence.matchLength;
685 BYTE* const oMatchEnd = op + sequenceLength; /* risk : address space overflow (32-bits) */
Yann Collet5be2dd22015-11-11 13:43:58 +0100686 BYTE* const oend_8 = oend-8;
687 const BYTE* const litEnd = *litPtr + sequence.litLength;
Yann Colletb3a2af92015-11-19 17:13:19 +0100688 const BYTE* match = oLitEnd - sequence.offset;
Yann Collet5be2dd22015-11-11 13:43:58 +0100689
690 /* check */
691 if (oLitEnd > oend_8) return ERROR(dstSize_tooSmall); /* last match must start at a minimum distance of 8 from oend */
692 if (oMatchEnd > oend) return ERROR(dstSize_tooSmall); /* overwrite beyond dst buffer */
693 if (litEnd > litLimit_8) return ERROR(corruption_detected); /* risk read beyond lit buffer */
694
695 /* copy Literals */
696 ZSTD_wildcopy(op, *litPtr, sequence.litLength); /* note : oLitEnd <= oend-8 : no risk of overwrite beyond oend */
697 op = oLitEnd;
698 *litPtr = litEnd; /* update for next sequence */
699
700 /* copy Match */
Yann Collet7b51a292016-01-26 15:58:49 +0100701 if (sequence.offset > (size_t)(oLitEnd - base)) {
Yann Collet44287a32015-11-30 23:13:56 +0100702 /* offset beyond prefix */
Yann Collet9f5ab1a2015-12-11 00:27:41 +0100703 if (sequence.offset > (size_t)(oLitEnd - vBase))
704 return ERROR(corruption_detected);
Yann Collet44287a32015-11-30 23:13:56 +0100705 match = dictEnd - (base-match);
Yann Collet7b51a292016-01-26 15:58:49 +0100706 if (match + sequence.matchLength <= dictEnd) {
Yann Collet4bfe4152015-12-06 13:18:37 +0100707 memmove(oLitEnd, match, sequence.matchLength);
Yann Collet44287a32015-11-30 23:13:56 +0100708 return sequenceLength;
709 }
710 /* span extDict & currentPrefixSegment */
711 {
712 size_t length1 = dictEnd - match;
Yann Collet4bfe4152015-12-06 13:18:37 +0100713 memmove(oLitEnd, match, length1);
Yann Collet44287a32015-11-30 23:13:56 +0100714 op = oLitEnd + length1;
715 sequence.matchLength -= length1;
716 match = base;
Yann Colletfb810d62016-01-28 00:18:06 +0100717 } }
Yann Collet0f366c62015-11-12 16:19:30 +0100718
Yann Collet44287a32015-11-30 23:13:56 +0100719 /* match within prefix */
Yann Collet7b51a292016-01-26 15:58:49 +0100720 if (sequence.offset < 8) {
Yann Collet44287a32015-11-30 23:13:56 +0100721 /* close range match, overlap */
722 const int sub2 = dec64table[sequence.offset];
723 op[0] = match[0];
724 op[1] = match[1];
725 op[2] = match[2];
726 op[3] = match[3];
727 match += dec32table[sequence.offset];
728 ZSTD_copy4(op+4, match);
729 match -= sub2;
Yann Colletfb810d62016-01-28 00:18:06 +0100730 } else {
Yann Collet44287a32015-11-30 23:13:56 +0100731 ZSTD_copy8(op, match);
732 }
733 op += 8; match += 8;
Yann Collet5be2dd22015-11-11 13:43:58 +0100734
Yann Collet7b51a292016-01-26 15:58:49 +0100735 if (oMatchEnd > oend-12) {
736 if (op < oend_8) {
Yann Collet44287a32015-11-30 23:13:56 +0100737 ZSTD_wildcopy(op, match, oend_8 - op);
738 match += oend_8 - op;
739 op = oend_8;
740 }
Yann Colletfb810d62016-01-28 00:18:06 +0100741 while (op < oMatchEnd)
742 *op++ = *match++;
743 } else {
Yann Collet44287a32015-11-30 23:13:56 +0100744 ZSTD_wildcopy(op, match, sequence.matchLength-8); /* works even if matchLength < 8 */
745 }
746 return sequenceLength;
Yann Collet5be2dd22015-11-11 13:43:58 +0100747}
748
Yann Colletb3a2af92015-11-19 17:13:19 +0100749
Yann Collet5be2dd22015-11-11 13:43:58 +0100750static size_t ZSTD_decompressSequences(
Yann Collet5b78d2f2015-11-12 15:36:05 +0100751 ZSTD_DCtx* dctx,
Yann Collet5be2dd22015-11-11 13:43:58 +0100752 void* dst, size_t maxDstSize,
753 const void* seqStart, size_t seqSize)
754{
Yann Collet5be2dd22015-11-11 13:43:58 +0100755 const BYTE* ip = (const BYTE*)seqStart;
756 const BYTE* const iend = ip + seqSize;
757 BYTE* const ostart = (BYTE* const)dst;
758 BYTE* op = ostart;
759 BYTE* const oend = ostart + maxDstSize;
760 size_t errorCode, dumpsLength;
761 const BYTE* litPtr = dctx->litPtr;
762 const BYTE* const litLimit_8 = litPtr + dctx->litBufSize - 8;
763 const BYTE* const litEnd = litPtr + dctx->litSize;
764 int nbSeq;
765 const BYTE* dumps;
766 U32* DTableLL = dctx->LLTable;
767 U32* DTableML = dctx->MLTable;
768 U32* DTableOffb = dctx->OffTable;
Yann Collet417890c2015-12-04 17:16:37 +0100769 const BYTE* const base = (const BYTE*) (dctx->base);
770 const BYTE* const vBase = (const BYTE*) (dctx->vBase);
771 const BYTE* const dictEnd = (const BYTE*) (dctx->dictEnd);
Yann Collet5be2dd22015-11-11 13:43:58 +0100772
773 /* Build Decoding Tables */
774 errorCode = ZSTD_decodeSeqHeaders(&nbSeq, &dumps, &dumpsLength,
775 DTableLL, DTableML, DTableOffb,
Yann Colletfb810d62016-01-28 00:18:06 +0100776 ip, seqSize);
Yann Collet5be2dd22015-11-11 13:43:58 +0100777 if (ZSTD_isError(errorCode)) return errorCode;
778 ip += errorCode;
779
780 /* Regen sequences */
781 {
782 seq_t sequence;
783 seqState_t seqState;
784
785 memset(&sequence, 0, sizeof(sequence));
786 sequence.offset = 4;
787 seqState.dumps = dumps;
788 seqState.dumpsEnd = dumps + dumpsLength;
789 seqState.prevOffset = 4;
790 errorCode = BIT_initDStream(&(seqState.DStream), ip, iend-ip);
791 if (ERR_isError(errorCode)) return ERROR(corruption_detected);
792 FSE_initDState(&(seqState.stateLL), &(seqState.DStream), DTableLL);
793 FSE_initDState(&(seqState.stateOffb), &(seqState.DStream), DTableOffb);
794 FSE_initDState(&(seqState.stateML), &(seqState.DStream), DTableML);
795
Yann Collet7b51a292016-01-26 15:58:49 +0100796 for ( ; (BIT_reloadDStream(&(seqState.DStream)) <= BIT_DStream_completed) && nbSeq ; ) {
Yann Colletb3a2af92015-11-19 17:13:19 +0100797 size_t oneSeqSize;
798 nbSeq--;
799 ZSTD_decodeSequence(&sequence, &seqState);
800 oneSeqSize = ZSTD_execSequence(op, oend, sequence, &litPtr, litLimit_8, base, vBase, dictEnd);
Yann Collet5be2dd22015-11-11 13:43:58 +0100801 if (ZSTD_isError(oneSeqSize)) return oneSeqSize;
802 op += oneSeqSize;
803 }
804
805 /* check if reached exact end */
Yann Collet44287a32015-11-30 23:13:56 +0100806 if ( !BIT_endOfDStream(&(seqState.DStream)) ) return ERROR(corruption_detected); /* DStream should be entirely and exactly consumed; otherwise data is corrupted */
Yann Collet5be2dd22015-11-11 13:43:58 +0100807
808 /* last literal segment */
809 {
810 size_t lastLLSize = litEnd - litPtr;
811 if (litPtr > litEnd) return ERROR(corruption_detected);
812 if (op+lastLLSize > oend) return ERROR(dstSize_tooSmall);
813 if (op != litPtr) memcpy(op, litPtr, lastLLSize);
814 op += lastLLSize;
Yann Colletfb810d62016-01-28 00:18:06 +0100815 } }
Yann Collet5be2dd22015-11-11 13:43:58 +0100816
817 return op-ostart;
818}
819
820
Yann Colletb0125102016-01-09 02:00:10 +0100821static void ZSTD_checkContinuity(ZSTD_DCtx* dctx, const void* dst)
822{
Yann Collet7b51a292016-01-26 15:58:49 +0100823 if (dst != dctx->previousDstEnd) { /* not contiguous */
Yann Colletb0125102016-01-09 02:00:10 +0100824 dctx->dictEnd = dctx->previousDstEnd;
825 dctx->vBase = (const char*)dst - ((const char*)(dctx->previousDstEnd) - (const char*)(dctx->base));
826 dctx->base = dst;
827 dctx->previousDstEnd = dst;
828 }
829}
830
831
832static size_t ZSTD_decompressBlock_internal(ZSTD_DCtx* dctx,
Yann Collet5be2dd22015-11-11 13:43:58 +0100833 void* dst, size_t maxDstSize,
834 const void* src, size_t srcSize)
835{
836 /* blockType == blockCompressed */
837 const BYTE* ip = (const BYTE*)src;
838
839 /* Decode literals sub-block */
Yann Collet5b78d2f2015-11-12 15:36:05 +0100840 size_t litCSize = ZSTD_decodeLiteralsBlock(dctx, src, srcSize);
Yann Collet5be2dd22015-11-11 13:43:58 +0100841 if (ZSTD_isError(litCSize)) return litCSize;
842 ip += litCSize;
843 srcSize -= litCSize;
844
Yann Collet5b78d2f2015-11-12 15:36:05 +0100845 return ZSTD_decompressSequences(dctx, dst, maxDstSize, ip, srcSize);
Yann Collet5be2dd22015-11-11 13:43:58 +0100846}
847
848
Yann Colletb0125102016-01-09 02:00:10 +0100849size_t ZSTD_decompressBlock(ZSTD_DCtx* dctx,
850 void* dst, size_t maxDstSize,
851 const void* src, size_t srcSize)
852{
853 ZSTD_checkContinuity(dctx, dst);
854 return ZSTD_decompressBlock_internal(dctx, dst, maxDstSize, src, srcSize);
855}
856
857
Yann Collet7b51a292016-01-26 15:58:49 +0100858/*! ZSTD_decompress_continueDCtx
859* dctx must have been properly initialized */
860static size_t ZSTD_decompress_continueDCtx(ZSTD_DCtx* dctx,
Yann Collet31683c02015-12-18 01:26:48 +0100861 void* dst, size_t maxDstSize,
Yann Collet7b51a292016-01-26 15:58:49 +0100862 const void* src, size_t srcSize)
Yann Collet5be2dd22015-11-11 13:43:58 +0100863{
864 const BYTE* ip = (const BYTE*)src;
865 const BYTE* iend = ip + srcSize;
866 BYTE* const ostart = (BYTE* const)dst;
867 BYTE* op = ostart;
868 BYTE* const oend = ostart + maxDstSize;
869 size_t remainingSize = srcSize;
Yann Collet5be2dd22015-11-11 13:43:58 +0100870 blockProperties_t blockProperties;
871
872 /* Frame Header */
Yann Collet88fcd292015-11-25 14:42:45 +0100873 {
874 size_t frameHeaderSize;
875 if (srcSize < ZSTD_frameHeaderSize_min+ZSTD_blockHeaderSize) return ERROR(srcSize_wrong);
Yann Collet5be2dd22015-11-11 13:43:58 +0100876#if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT==1)
Yann Collet88fcd292015-11-25 14:42:45 +0100877 {
878 const U32 magicNumber = MEM_readLE32(src);
879 if (ZSTD_isLegacy(magicNumber))
880 return ZSTD_decompressLegacy(dst, maxDstSize, src, srcSize, magicNumber);
881 }
Yann Collet5be2dd22015-11-11 13:43:58 +0100882#endif
Yann Collet37422192016-01-25 16:54:05 +0100883 frameHeaderSize = ZSTD_decodeFrameHeader_Part1(dctx, src, ZSTD_frameHeaderSize_min);
Yann Collet88fcd292015-11-25 14:42:45 +0100884 if (ZSTD_isError(frameHeaderSize)) return frameHeaderSize;
885 if (srcSize < frameHeaderSize+ZSTD_blockHeaderSize) return ERROR(srcSize_wrong);
886 ip += frameHeaderSize; remainingSize -= frameHeaderSize;
Yann Collet37422192016-01-25 16:54:05 +0100887 frameHeaderSize = ZSTD_decodeFrameHeader_Part2(dctx, src, frameHeaderSize);
Yann Collet88fcd292015-11-25 14:42:45 +0100888 if (ZSTD_isError(frameHeaderSize)) return frameHeaderSize;
889 }
Yann Collet5be2dd22015-11-11 13:43:58 +0100890
891 /* Loop on each block */
892 while (1)
893 {
894 size_t decodedSize=0;
895 size_t cBlockSize = ZSTD_getcBlockSize(ip, iend-ip, &blockProperties);
896 if (ZSTD_isError(cBlockSize)) return cBlockSize;
897
898 ip += ZSTD_blockHeaderSize;
899 remainingSize -= ZSTD_blockHeaderSize;
900 if (cBlockSize > remainingSize) return ERROR(srcSize_wrong);
901
902 switch(blockProperties.blockType)
903 {
904 case bt_compressed:
Yann Collet37422192016-01-25 16:54:05 +0100905 decodedSize = ZSTD_decompressBlock_internal(dctx, op, oend-op, ip, cBlockSize);
Yann Collet5be2dd22015-11-11 13:43:58 +0100906 break;
907 case bt_raw :
Yann Collet0f366c62015-11-12 16:19:30 +0100908 decodedSize = ZSTD_copyRawBlock(op, oend-op, ip, cBlockSize);
Yann Collet5be2dd22015-11-11 13:43:58 +0100909 break;
910 case bt_rle :
911 return ERROR(GENERIC); /* not yet supported */
912 break;
913 case bt_end :
914 /* end of frame */
915 if (remainingSize) return ERROR(srcSize_wrong);
916 break;
917 default:
918 return ERROR(GENERIC); /* impossible */
919 }
920 if (cBlockSize == 0) break; /* bt_end */
921
922 if (ZSTD_isError(decodedSize)) return decodedSize;
923 op += decodedSize;
924 ip += cBlockSize;
925 remainingSize -= cBlockSize;
926 }
927
928 return op-ostart;
929}
930
Yann Collet31683c02015-12-18 01:26:48 +0100931
Yann Collet7b51a292016-01-26 15:58:49 +0100932size_t ZSTD_decompress_usingPreparedDCtx(ZSTD_DCtx* dctx, const ZSTD_DCtx* refDCtx,
933 void* dst, size_t maxDstSize,
934 const void* src, size_t srcSize)
935{
936 ZSTD_copyDCtx(dctx, refDCtx);
937 ZSTD_checkContinuity(dctx, dst);
938 return ZSTD_decompress_continueDCtx(dctx, dst, maxDstSize, src, srcSize);
939}
940
941
942size_t ZSTD_decompress_usingDict(ZSTD_DCtx* dctx,
943 void* dst, size_t maxDstSize,
944 const void* src, size_t srcSize,
945 const void* dict, size_t dictSize)
946{
947 ZSTD_decompressBegin_usingDict(dctx, dict, dictSize);
948 ZSTD_checkContinuity(dctx, dst);
949 return ZSTD_decompress_continueDCtx(dctx, dst, maxDstSize, src, srcSize);
950}
951
952
Yann Collet31683c02015-12-18 01:26:48 +0100953size_t ZSTD_decompressDCtx(ZSTD_DCtx* dctx, void* dst, size_t maxDstSize, const void* src, size_t srcSize)
954{
955 return ZSTD_decompress_usingDict(dctx, dst, maxDstSize, src, srcSize, NULL, 0);
956}
957
Yann Collet5be2dd22015-11-11 13:43:58 +0100958size_t ZSTD_decompress(void* dst, size_t maxDstSize, const void* src, size_t srcSize)
959{
Yann Collet3a3b72f2016-01-11 12:56:11 +0100960#if defined(ZSTD_HEAPMODE) && (ZSTD_HEAPMODE==1)
961 size_t regenSize;
962 ZSTD_DCtx* dctx = ZSTD_createDCtx();
963 if (dctx==NULL) return ERROR(memory_allocation);
964 regenSize = ZSTD_decompressDCtx(dctx, dst, maxDstSize, src, srcSize);
965 ZSTD_freeDCtx(dctx);
966 return regenSize;
967#else
Yann Collet31683c02015-12-18 01:26:48 +0100968 ZSTD_DCtx dctx;
969 return ZSTD_decompressDCtx(&dctx, dst, maxDstSize, src, srcSize);
Yann Colleta768a302016-01-21 16:04:35 +0100970#endif
Yann Collet5be2dd22015-11-11 13:43:58 +0100971}
972
973
974/* ******************************
975* Streaming Decompression API
976********************************/
Yann Collet5be2dd22015-11-11 13:43:58 +0100977size_t ZSTD_nextSrcSizeToDecompress(ZSTD_DCtx* dctx)
978{
979 return dctx->expected;
980}
981
Yann Collet37422192016-01-25 16:54:05 +0100982size_t ZSTD_decompressContinue(ZSTD_DCtx* dctx, void* dst, size_t maxDstSize, const void* src, size_t srcSize)
Yann Collet5be2dd22015-11-11 13:43:58 +0100983{
984 /* Sanity check */
Yann Collet37422192016-01-25 16:54:05 +0100985 if (srcSize != dctx->expected) return ERROR(srcSize_wrong);
986 ZSTD_checkContinuity(dctx, dst);
Yann Collet5be2dd22015-11-11 13:43:58 +0100987
Yann Collet88fcd292015-11-25 14:42:45 +0100988 /* Decompress : frame header; part 1 */
Yann Collet37422192016-01-25 16:54:05 +0100989 switch (dctx->stage)
Yann Collet5be2dd22015-11-11 13:43:58 +0100990 {
Yann Collet88fcd292015-11-25 14:42:45 +0100991 case ZSTDds_getFrameHeaderSize :
Yann Collet5be2dd22015-11-11 13:43:58 +0100992 {
Yann Collet88fcd292015-11-25 14:42:45 +0100993 /* get frame header size */
994 if (srcSize != ZSTD_frameHeaderSize_min) return ERROR(srcSize_wrong); /* impossible */
Yann Collet37422192016-01-25 16:54:05 +0100995 dctx->headerSize = ZSTD_decodeFrameHeader_Part1(dctx, src, ZSTD_frameHeaderSize_min);
996 if (ZSTD_isError(dctx->headerSize)) return dctx->headerSize;
997 memcpy(dctx->headerBuffer, src, ZSTD_frameHeaderSize_min);
Yann Collet7b51a292016-01-26 15:58:49 +0100998 if (dctx->headerSize > ZSTD_frameHeaderSize_min) {
Yann Collet37422192016-01-25 16:54:05 +0100999 dctx->expected = dctx->headerSize - ZSTD_frameHeaderSize_min;
1000 dctx->stage = ZSTDds_decodeFrameHeader;
Yann Collet88fcd292015-11-25 14:42:45 +01001001 return 0;
1002 }
Yann Collet37422192016-01-25 16:54:05 +01001003 dctx->expected = 0; /* not necessary to copy more */
Yann Collet5be2dd22015-11-11 13:43:58 +01001004 }
Yann Collet88fcd292015-11-25 14:42:45 +01001005 case ZSTDds_decodeFrameHeader:
Yann Collet5be2dd22015-11-11 13:43:58 +01001006 {
Yann Collet88fcd292015-11-25 14:42:45 +01001007 /* get frame header */
1008 size_t result;
Yann Collet37422192016-01-25 16:54:05 +01001009 memcpy(dctx->headerBuffer + ZSTD_frameHeaderSize_min, src, dctx->expected);
1010 result = ZSTD_decodeFrameHeader_Part2(dctx, dctx->headerBuffer, dctx->headerSize);
Yann Collet88fcd292015-11-25 14:42:45 +01001011 if (ZSTD_isError(result)) return result;
Yann Collet37422192016-01-25 16:54:05 +01001012 dctx->expected = ZSTD_blockHeaderSize;
1013 dctx->stage = ZSTDds_decodeBlockHeader;
Yann Collet88fcd292015-11-25 14:42:45 +01001014 return 0;
Yann Collet5be2dd22015-11-11 13:43:58 +01001015 }
Yann Collet88fcd292015-11-25 14:42:45 +01001016 case ZSTDds_decodeBlockHeader:
Yann Collet5be2dd22015-11-11 13:43:58 +01001017 {
Yann Collet88fcd292015-11-25 14:42:45 +01001018 /* Decode block header */
1019 blockProperties_t bp;
1020 size_t blockSize = ZSTD_getcBlockSize(src, ZSTD_blockHeaderSize, &bp);
1021 if (ZSTD_isError(blockSize)) return blockSize;
Yann Collet7b51a292016-01-26 15:58:49 +01001022 if (bp.blockType == bt_end) {
Yann Collet37422192016-01-25 16:54:05 +01001023 dctx->expected = 0;
1024 dctx->stage = ZSTDds_getFrameHeaderSize;
Yann Collet88fcd292015-11-25 14:42:45 +01001025 }
Yann Collet7b51a292016-01-26 15:58:49 +01001026 else {
Yann Collet37422192016-01-25 16:54:05 +01001027 dctx->expected = blockSize;
1028 dctx->bType = bp.blockType;
1029 dctx->stage = ZSTDds_decompressBlock;
Yann Collet88fcd292015-11-25 14:42:45 +01001030 }
Yann Collet88fcd292015-11-25 14:42:45 +01001031 return 0;
1032 }
Yann Collet417890c2015-12-04 17:16:37 +01001033 case ZSTDds_decompressBlock:
Yann Collet88fcd292015-11-25 14:42:45 +01001034 {
1035 /* Decompress : block content */
1036 size_t rSize;
Yann Collet37422192016-01-25 16:54:05 +01001037 switch(dctx->bType)
Yann Collet88fcd292015-11-25 14:42:45 +01001038 {
1039 case bt_compressed:
Yann Collet37422192016-01-25 16:54:05 +01001040 rSize = ZSTD_decompressBlock_internal(dctx, dst, maxDstSize, src, srcSize);
Yann Collet88fcd292015-11-25 14:42:45 +01001041 break;
1042 case bt_raw :
1043 rSize = ZSTD_copyRawBlock(dst, maxDstSize, src, srcSize);
1044 break;
1045 case bt_rle :
1046 return ERROR(GENERIC); /* not yet handled */
1047 break;
1048 case bt_end : /* should never happen (filtered at phase 1) */
1049 rSize = 0;
1050 break;
1051 default:
Yann Collet7b51a292016-01-26 15:58:49 +01001052 return ERROR(GENERIC); /* impossible */
Yann Collet88fcd292015-11-25 14:42:45 +01001053 }
Yann Collet37422192016-01-25 16:54:05 +01001054 dctx->stage = ZSTDds_decodeBlockHeader;
1055 dctx->expected = ZSTD_blockHeaderSize;
1056 dctx->previousDstEnd = (char*)dst + rSize;
Yann Collet88fcd292015-11-25 14:42:45 +01001057 return rSize;
1058 }
1059 default:
1060 return ERROR(GENERIC); /* impossible */
1061 }
Yann Collet5be2dd22015-11-11 13:43:58 +01001062}
1063
1064
Yann Colletb923f652016-01-26 03:14:20 +01001065static void ZSTD_refDictContent(ZSTD_DCtx* dctx, const void* dict, size_t dictSize)
Yann Collet417890c2015-12-04 17:16:37 +01001066{
Yann Collet37422192016-01-25 16:54:05 +01001067 dctx->dictEnd = dctx->previousDstEnd;
1068 dctx->vBase = (const char*)dict - ((const char*)(dctx->previousDstEnd) - (const char*)(dctx->base));
1069 dctx->base = dict;
1070 dctx->previousDstEnd = (const char*)dict + dictSize;
Yann Collet417890c2015-12-04 17:16:37 +01001071}
Yann Colletb923f652016-01-26 03:14:20 +01001072
Yann Colletb923f652016-01-26 03:14:20 +01001073static size_t ZSTD_loadEntropy(ZSTD_DCtx* dctx, const void* dict, size_t dictSize)
1074{
Yann Colletfb810d62016-01-28 00:18:06 +01001075 size_t hSize, offcodeHeaderSize, matchlengthHeaderSize, errorCode, litlengthHeaderSize;
1076 short offcodeNCount[MaxOff+1];
1077 U32 offcodeMaxValue=MaxOff, offcodeLog=OffFSELog;
1078 short matchlengthNCount[MaxML+1];
1079 unsigned matchlengthMaxValue = MaxML, matchlengthLog = MLFSELog;
1080 short litlengthNCount[MaxLL+1];
1081 unsigned litlengthMaxValue = MaxLL, litlengthLog = LLFSELog;
1082
1083 hSize = HUF_readDTableX4(dctx->hufTableX4, dict, dictSize);
Yann Colletb923f652016-01-26 03:14:20 +01001084 if (HUF_isError(hSize)) return ERROR(dictionary_corrupted);
Yann Colletfb810d62016-01-28 00:18:06 +01001085 dict = (const char*)dict + hSize;
1086 dictSize -= hSize;
1087
1088 offcodeHeaderSize = FSE_readNCount(offcodeNCount, &offcodeMaxValue, &offcodeLog, dict, dictSize);
1089 if (FSE_isError(offcodeHeaderSize)) return ERROR(dictionary_corrupted);
1090 errorCode = FSE_buildDTable(dctx->OffTable, offcodeNCount, offcodeMaxValue, offcodeLog);
1091 if (FSE_isError(errorCode)) return ERROR(dictionary_corrupted);
1092 dict = (const char*)dict + offcodeHeaderSize;
1093 dictSize -= offcodeHeaderSize;
1094
1095 matchlengthHeaderSize = FSE_readNCount(matchlengthNCount, &matchlengthMaxValue, &matchlengthLog, dict, dictSize);
1096 if (FSE_isError(matchlengthHeaderSize)) return ERROR(dictionary_corrupted);
1097 errorCode = FSE_buildDTable(dctx->MLTable, matchlengthNCount, matchlengthMaxValue, matchlengthLog);
1098 if (FSE_isError(errorCode)) return ERROR(dictionary_corrupted);
1099 dict = (const char*)dict + matchlengthHeaderSize;
1100 dictSize -= matchlengthHeaderSize;
1101
1102 litlengthHeaderSize = FSE_readNCount(litlengthNCount, &litlengthMaxValue, &litlengthLog, dict, dictSize);
1103 if (FSE_isError(litlengthHeaderSize)) return ERROR(dictionary_corrupted);
1104 errorCode = FSE_buildDTable(dctx->LLTable, litlengthNCount, litlengthMaxValue, litlengthLog);
1105 if (FSE_isError(errorCode)) return ERROR(dictionary_corrupted);
1106
1107 dctx->flagStaticTables = 1;
1108 return hSize + offcodeHeaderSize + matchlengthHeaderSize + litlengthHeaderSize;
Yann Colletb923f652016-01-26 03:14:20 +01001109}
1110
Yann Collet7b51a292016-01-26 15:58:49 +01001111static size_t ZSTD_decompress_insertDictionary(ZSTD_DCtx* dctx, const void* dict, size_t dictSize)
Yann Colletb923f652016-01-26 03:14:20 +01001112{
1113 size_t eSize;
1114 U32 magic = MEM_readLE32(dict);
1115 if (magic != ZSTD_DICT_MAGIC) {
1116 /* pure content mode */
1117 ZSTD_refDictContent(dctx, dict, dictSize);
1118 return 0;
1119 }
1120 /* load entropy tables */
1121 dict = (const char*)dict + 4;
1122 dictSize -= 4;
1123 eSize = ZSTD_loadEntropy(dctx, dict, dictSize);
1124 if (ZSTD_isError(eSize)) return ERROR(dictionary_corrupted);
1125
1126 /* reference dictionary content */
1127 dict = (const char*)dict + eSize;
1128 dictSize -= eSize;
1129 ZSTD_refDictContent(dctx, dict, dictSize);
1130
1131 return 0;
1132}
1133
Yann Collet7b51a292016-01-26 15:58:49 +01001134
1135size_t ZSTD_decompressBegin_usingDict(ZSTD_DCtx* dctx, const void* dict, size_t dictSize)
1136{
1137 size_t errorCode;
1138 errorCode = ZSTD_decompressBegin(dctx);
1139 if (ZSTD_isError(errorCode)) return errorCode;
1140
1141 if (dict && dictSize) {
1142 errorCode = ZSTD_decompress_insertDictionary(dctx, dict, dictSize);
1143 if (ZSTD_isError(errorCode)) return ERROR(dictionary_corrupted);
1144 }
1145
1146 return 0;
1147}
1148