blob: d1e01c3e587fe36f8d727ddec642a7cab5821396 [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 Colletb3a2af92015-11-19 17:13:19 +010038 * Select how default compression functions will allocate memory for their hash table,
Yann Collet5be2dd22015-11-11 13:43:58 +010039 * in memory stack (0, fastest), or in memory heap (1, requires malloc())
Yann Colletb3a2af92015-11-19 17:13:19 +010040 * Note that compression context is fairly large, as a consequence heap memory is recommended.
Yann Collet5be2dd22015-11-11 13:43:58 +010041 */
42#ifndef ZSTD_HEAPMODE
43# define ZSTD_HEAPMODE 1
44#endif /* ZSTD_HEAPMODE */
45
46/*!
47* LEGACY_SUPPORT :
Yann Collet14983e72015-11-11 21:38:21 +010048* ZSTD_decompress() can decode older formats (starting from zstd 0.1+)
Yann Collet5be2dd22015-11-11 13:43:58 +010049*/
50#ifndef ZSTD_LEGACY_SUPPORT
51# define ZSTD_LEGACY_SUPPORT 1
52#endif
53
54
55/* *******************************************************
56* Includes
57*********************************************************/
58#include <stdlib.h> /* calloc */
59#include <string.h> /* memcpy, memmove */
60#include <stdio.h> /* debug : printf */
61#include "mem.h" /* low level memory routines */
62#include "zstd_static.h"
63#include "zstd_internal.h"
64#include "fse_static.h"
65#include "huff0.h"
66
67#if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT==1)
68# include "zstd_legacy.h"
69#endif
70
Yann Collet5be2dd22015-11-11 13:43:58 +010071/* *******************************************************
72* 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 Collet14983e72015-11-11 21:38:21 +010089/* *************************************
90* 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{
127 U32 LLTable[FSE_DTABLE_SIZE_U32(LLFSELog)];
128 U32 OffTable[FSE_DTABLE_SIZE_U32(OffFSELog)];
129 U32 MLTable[FSE_DTABLE_SIZE_U32(MLFSELog)];
Yann Collet417890c2015-12-04 17:16:37 +0100130 const void* previousDstEnd;
131 const void* base;
132 const void* vBase;
133 const void* dictEnd;
Yann Collet5be2dd22015-11-11 13:43:58 +0100134 size_t expected;
Yann Collet88fcd292015-11-25 14:42:45 +0100135 size_t headerSize;
136 ZSTD_parameters params;
Yann Collet5be2dd22015-11-11 13:43:58 +0100137 blockType_t bType;
Yann Collet88fcd292015-11-25 14:42:45 +0100138 ZSTD_dStage stage;
Yann Collet5be2dd22015-11-11 13:43:58 +0100139 const BYTE* litPtr;
140 size_t litBufSize;
141 size_t litSize;
142 BYTE litBuffer[BLOCKSIZE + 8 /* margin for wildcopy */];
Yann Collet88fcd292015-11-25 14:42:45 +0100143 BYTE headerBuffer[ZSTD_frameHeaderSize_max];
Yann Collet417890c2015-12-04 17:16:37 +0100144}; /* typedef'd to ZSTD_DCtx within "zstd_static.h" */
Yann Collet5be2dd22015-11-11 13:43:58 +0100145
Yann Collet5b78d2f2015-11-12 15:36:05 +0100146size_t ZSTD_resetDCtx(ZSTD_DCtx* dctx)
147{
Yann Collet88fcd292015-11-25 14:42:45 +0100148 dctx->expected = ZSTD_frameHeaderSize_min;
149 dctx->stage = ZSTDds_getFrameHeaderSize;
Yann Collet5b78d2f2015-11-12 15:36:05 +0100150 dctx->previousDstEnd = NULL;
151 dctx->base = NULL;
152 dctx->vBase = NULL;
153 dctx->dictEnd = NULL;
154 return 0;
155}
156
157ZSTD_DCtx* ZSTD_createDCtx(void)
158{
159 ZSTD_DCtx* dctx = (ZSTD_DCtx*)malloc(sizeof(ZSTD_DCtx));
160 if (dctx==NULL) return NULL;
161 ZSTD_resetDCtx(dctx);
162 return dctx;
163}
164
165size_t ZSTD_freeDCtx(ZSTD_DCtx* dctx)
166{
167 free(dctx);
168 return 0;
169}
170
171
172/* *************************************************************
173* Decompression section
174***************************************************************/
Yann Collet88fcd292015-11-25 14:42:45 +0100175/** ZSTD_decodeFrameHeader_Part1
176* decode the 1st part of the Frame Header, which tells Frame Header size.
177* srcSize must be == ZSTD_frameHeaderSize_min
178* @return : the full size of the Frame Header */
179static size_t ZSTD_decodeFrameHeader_Part1(ZSTD_DCtx* zc, const void* src, size_t srcSize)
180{
181 U32 magicNumber;
182 if (srcSize != ZSTD_frameHeaderSize_min) return ERROR(srcSize_wrong);
183 magicNumber = MEM_readLE32(src);
184 if (magicNumber != ZSTD_MAGICNUMBER) return ERROR(prefix_unknown);
185 zc->headerSize = ZSTD_frameHeaderSize_min;
186 return zc->headerSize;
187}
188
Yann Collet88fcd292015-11-25 14:42:45 +0100189
190size_t ZSTD_getFrameParams(ZSTD_parameters* params, const void* src, size_t srcSize)
191{
192 U32 magicNumber;
193 if (srcSize < ZSTD_frameHeaderSize_min) return ZSTD_frameHeaderSize_max;
194 magicNumber = MEM_readLE32(src);
195 if (magicNumber != ZSTD_MAGICNUMBER) return ERROR(prefix_unknown);
196 memset(params, 0, sizeof(*params));
Yann Collet26415d32015-11-26 12:43:28 +0100197 params->windowLog = (((const BYTE*)src)[4] & 15) + ZSTD_WINDOWLOG_ABSOLUTEMIN;
Yann Colletbf7aa3c2015-11-28 18:19:44 +0100198 if ((((const BYTE*)src)[4] >> 4) != 0) return ERROR(frameParameter_unsupported); /* reserved bits */
Yann Collet88fcd292015-11-25 14:42:45 +0100199 return 0;
200}
201
Yann Collet26415d32015-11-26 12:43:28 +0100202/** ZSTD_decodeFrameHeader_Part2
203* decode the full Frame Header
204* srcSize must be the size provided by ZSTD_decodeFrameHeader_Part1
205* @return : 0, or an error code, which can be tested using ZSTD_isError() */
206static size_t ZSTD_decodeFrameHeader_Part2(ZSTD_DCtx* zc, const void* src, size_t srcSize)
207{
Yann Collet00fd7a22015-11-28 16:03:22 +0100208 size_t result;
Yann Collet26415d32015-11-26 12:43:28 +0100209 if (srcSize != zc->headerSize) return ERROR(srcSize_wrong);
Yann Collet00fd7a22015-11-28 16:03:22 +0100210 result = ZSTD_getFrameParams(&(zc->params), src, srcSize);
211 if ((MEM_32bits()) && (zc->params.windowLog > 25)) return ERROR(frameParameter_unsupportedBy32bitsImplementation);
212 return result;
Yann Collet26415d32015-11-26 12:43:28 +0100213}
214
Yann Collet5be2dd22015-11-11 13:43:58 +0100215
216size_t ZSTD_getcBlockSize(const void* src, size_t srcSize, blockProperties_t* bpPtr)
217{
218 const BYTE* const in = (const BYTE* const)src;
219 BYTE headerFlags;
220 U32 cSize;
221
222 if (srcSize < 3) return ERROR(srcSize_wrong);
223
224 headerFlags = *in;
225 cSize = in[2] + (in[1]<<8) + ((in[0] & 7)<<16);
226
227 bpPtr->blockType = (blockType_t)(headerFlags >> 6);
228 bpPtr->origSize = (bpPtr->blockType == bt_rle) ? cSize : 0;
229
230 if (bpPtr->blockType == bt_end) return 0;
231 if (bpPtr->blockType == bt_rle) return 1;
232 return cSize;
233}
234
Yann Collet0f366c62015-11-12 16:19:30 +0100235static size_t ZSTD_copyRawBlock(void* dst, size_t maxDstSize, const void* src, size_t srcSize)
Yann Collet5be2dd22015-11-11 13:43:58 +0100236{
237 if (srcSize > maxDstSize) return ERROR(dstSize_tooSmall);
238 memcpy(dst, src, srcSize);
239 return srcSize;
240}
241
242
243/** ZSTD_decompressLiterals
244 @return : nb of bytes read from src, or an error code*/
245static size_t ZSTD_decompressLiterals(void* dst, size_t* maxDstSizePtr,
246 const void* src, size_t srcSize)
247{
248 const BYTE* ip = (const BYTE*)src;
249
250 const size_t litSize = (MEM_readLE32(src) & 0x1FFFFF) >> 2; /* no buffer issue : srcSize >= MIN_CBLOCK_SIZE */
251 const size_t litCSize = (MEM_readLE32(ip+2) & 0xFFFFFF) >> 5; /* no buffer issue : srcSize >= MIN_CBLOCK_SIZE */
252
253 if (litSize > *maxDstSizePtr) return ERROR(corruption_detected);
254 if (litCSize + 5 > srcSize) return ERROR(corruption_detected);
255
256 if (HUF_isError(HUF_decompress(dst, litSize, ip+5, litCSize))) return ERROR(corruption_detected);
257
258 *maxDstSizePtr = litSize;
259 return litCSize + 5;
260}
261
262
263/** ZSTD_decodeLiteralsBlock
Yann Collet14983e72015-11-11 21:38:21 +0100264 @return : nb of bytes read from src (< srcSize ) */
Yann Collet5b78d2f2015-11-12 15:36:05 +0100265size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx,
Yann Collet5be2dd22015-11-11 13:43:58 +0100266 const void* src, size_t srcSize) /* note : srcSize < BLOCKSIZE */
267{
Yann Collet5be2dd22015-11-11 13:43:58 +0100268 const BYTE* const istart = (const BYTE*) src;
269
270 /* any compressed block with literals segment must be at least this size */
271 if (srcSize < MIN_CBLOCK_SIZE) return ERROR(corruption_detected);
272
273 switch(*istart & 3)
274 {
275 /* compressed */
276 case 0:
277 {
278 size_t litSize = BLOCKSIZE;
279 const size_t readSize = ZSTD_decompressLiterals(dctx->litBuffer, &litSize, src, srcSize);
280 dctx->litPtr = dctx->litBuffer;
281 dctx->litBufSize = BLOCKSIZE+8;
282 dctx->litSize = litSize;
283 return readSize; /* works if it's an error too */
284 }
285 case IS_RAW:
286 {
287 const size_t litSize = (MEM_readLE32(istart) & 0xFFFFFF) >> 2; /* no buffer issue : srcSize >= MIN_CBLOCK_SIZE */
288 if (litSize > srcSize-11) /* risk of reading too far with wildcopy */
289 {
290 if (litSize > srcSize-3) return ERROR(corruption_detected);
291 memcpy(dctx->litBuffer, istart, litSize);
292 dctx->litPtr = dctx->litBuffer;
293 dctx->litBufSize = BLOCKSIZE+8;
294 dctx->litSize = litSize;
295 return litSize+3;
296 }
297 /* direct reference into compressed stream */
298 dctx->litPtr = istart+3;
299 dctx->litBufSize = srcSize-3;
300 dctx->litSize = litSize;
301 return litSize+3; }
302 case IS_RLE:
303 {
304 const size_t litSize = (MEM_readLE32(istart) & 0xFFFFFF) >> 2; /* no buffer issue : srcSize >= MIN_CBLOCK_SIZE */
305 if (litSize > BLOCKSIZE) return ERROR(corruption_detected);
306 memset(dctx->litBuffer, istart[3], litSize);
307 dctx->litPtr = dctx->litBuffer;
308 dctx->litBufSize = BLOCKSIZE+8;
309 dctx->litSize = litSize;
310 return 4;
311 }
312 default:
313 return ERROR(corruption_detected); /* forbidden nominal case */
314 }
315}
316
317
318size_t ZSTD_decodeSeqHeaders(int* nbSeq, const BYTE** dumpsPtr, size_t* dumpsLengthPtr,
319 FSE_DTable* DTableLL, FSE_DTable* DTableML, FSE_DTable* DTableOffb,
320 const void* src, size_t srcSize)
321{
322 const BYTE* const istart = (const BYTE* const)src;
323 const BYTE* ip = istart;
324 const BYTE* const iend = istart + srcSize;
325 U32 LLtype, Offtype, MLtype;
326 U32 LLlog, Offlog, MLlog;
327 size_t dumpsLength;
328
329 /* check */
330 if (srcSize < 5) return ERROR(srcSize_wrong);
331
332 /* SeqHead */
333 *nbSeq = MEM_readLE16(ip); ip+=2;
334 LLtype = *ip >> 6;
335 Offtype = (*ip >> 4) & 3;
336 MLtype = (*ip >> 2) & 3;
337 if (*ip & 2)
338 {
339 dumpsLength = ip[2];
340 dumpsLength += ip[1] << 8;
341 ip += 3;
342 }
343 else
344 {
345 dumpsLength = ip[1];
346 dumpsLength += (ip[0] & 1) << 8;
347 ip += 2;
348 }
349 *dumpsPtr = ip;
350 ip += dumpsLength;
351 *dumpsLengthPtr = dumpsLength;
352
353 /* check */
354 if (ip > iend-3) return ERROR(srcSize_wrong); /* min : all 3 are "raw", hence no header, but at least xxLog bits per type */
355
356 /* sequences */
357 {
Yann Collet82368cf2015-11-16 19:10:56 +0100358 S16 norm[MaxML+1]; /* assumption : MaxML >= MaxLL >= MaxOff */
Yann Collet5be2dd22015-11-11 13:43:58 +0100359 size_t headerSize;
360
361 /* Build DTables */
362 switch(LLtype)
363 {
364 U32 max;
365 case bt_rle :
366 LLlog = 0;
367 FSE_buildDTable_rle(DTableLL, *ip++); break;
368 case bt_raw :
369 LLlog = LLbits;
370 FSE_buildDTable_raw(DTableLL, LLbits); break;
371 default :
372 max = MaxLL;
373 headerSize = FSE_readNCount(norm, &max, &LLlog, ip, iend-ip);
374 if (FSE_isError(headerSize)) return ERROR(GENERIC);
375 if (LLlog > LLFSELog) return ERROR(corruption_detected);
376 ip += headerSize;
377 FSE_buildDTable(DTableLL, norm, max, LLlog);
378 }
379
380 switch(Offtype)
381 {
382 U32 max;
383 case bt_rle :
384 Offlog = 0;
385 if (ip > iend-2) return ERROR(srcSize_wrong); /* min : "raw", hence no header, but at least xxLog bits */
386 FSE_buildDTable_rle(DTableOffb, *ip++ & MaxOff); /* if *ip > MaxOff, data is corrupted */
387 break;
388 case bt_raw :
389 Offlog = Offbits;
390 FSE_buildDTable_raw(DTableOffb, Offbits); break;
391 default :
392 max = MaxOff;
393 headerSize = FSE_readNCount(norm, &max, &Offlog, ip, iend-ip);
394 if (FSE_isError(headerSize)) return ERROR(GENERIC);
395 if (Offlog > OffFSELog) return ERROR(corruption_detected);
396 ip += headerSize;
397 FSE_buildDTable(DTableOffb, norm, max, Offlog);
398 }
399
400 switch(MLtype)
401 {
402 U32 max;
403 case bt_rle :
404 MLlog = 0;
405 if (ip > iend-2) return ERROR(srcSize_wrong); /* min : "raw", hence no header, but at least xxLog bits */
406 FSE_buildDTable_rle(DTableML, *ip++); break;
407 case bt_raw :
408 MLlog = MLbits;
409 FSE_buildDTable_raw(DTableML, MLbits); break;
410 default :
411 max = MaxML;
412 headerSize = FSE_readNCount(norm, &max, &MLlog, ip, iend-ip);
413 if (FSE_isError(headerSize)) return ERROR(GENERIC);
414 if (MLlog > MLFSELog) return ERROR(corruption_detected);
415 ip += headerSize;
416 FSE_buildDTable(DTableML, norm, max, MLlog);
417 }
418 }
419
420 return ip-istart;
421}
422
423
424typedef struct {
425 size_t litLength;
426 size_t offset;
427 size_t matchLength;
428} seq_t;
429
430typedef struct {
431 BIT_DStream_t DStream;
432 FSE_DState_t stateLL;
433 FSE_DState_t stateOffb;
434 FSE_DState_t stateML;
435 size_t prevOffset;
436 const BYTE* dumps;
437 const BYTE* dumpsEnd;
438} seqState_t;
439
440
441static void ZSTD_decodeSequence(seq_t* seq, seqState_t* seqState)
442{
443 size_t litLength;
444 size_t prevOffset;
445 size_t offset;
446 size_t matchLength;
447 const BYTE* dumps = seqState->dumps;
448 const BYTE* const de = seqState->dumpsEnd;
449
450 /* Literal length */
451 litLength = FSE_decodeSymbol(&(seqState->stateLL), &(seqState->DStream));
Yann Collete4fdad52015-11-25 21:09:17 +0100452 prevOffset = litLength ? seq->offset : seqState->prevOffset;
Yann Collet5be2dd22015-11-11 13:43:58 +0100453 if (litLength == MaxLL)
454 {
455 U32 add = *dumps++;
456 if (add < 255) litLength += add;
457 else
458 {
459 litLength = MEM_readLE32(dumps) & 0xFFFFFF; /* no pb : dumps is always followed by seq tables > 1 byte */
460 dumps += 3;
461 }
462 if (dumps >= de) dumps = de-1; /* late correction, to avoid read overflow (data is now corrupted anyway) */
463 }
464
465 /* Offset */
466 {
467 static const U32 offsetPrefix[MaxOff+1] = {
468 1 /*fake*/, 1, 2, 4, 8, 16, 32, 64, 128, 256,
469 512, 1024, 2048, 4096, 8192, 16384, 32768, 65536, 131072, 262144,
470 524288, 1048576, 2097152, 4194304, 8388608, 16777216, 33554432, /*fake*/ 1, 1, 1, 1, 1 };
471 U32 offsetCode, nbBits;
472 offsetCode = FSE_decodeSymbol(&(seqState->stateOffb), &(seqState->DStream)); /* <= maxOff, by table construction */
473 if (MEM_32bits()) BIT_reloadDStream(&(seqState->DStream));
474 nbBits = offsetCode - 1;
475 if (offsetCode==0) nbBits = 0; /* cmove */
476 offset = offsetPrefix[offsetCode] + BIT_readBits(&(seqState->DStream), nbBits);
477 if (MEM_32bits()) BIT_reloadDStream(&(seqState->DStream));
478 if (offsetCode==0) offset = prevOffset; /* cmove */
Yann Collet55aa7f92015-11-20 12:04:52 +0100479 if (offsetCode | !litLength) seqState->prevOffset = seq->offset; /* cmove */
Yann Collet5be2dd22015-11-11 13:43:58 +0100480 }
481
482 /* MatchLength */
483 matchLength = FSE_decodeSymbol(&(seqState->stateML), &(seqState->DStream));
484 if (matchLength == MaxML)
485 {
486 U32 add = *dumps++;
487 if (add < 255) matchLength += add;
488 else
489 {
490 matchLength = MEM_readLE32(dumps) & 0xFFFFFF; /* no pb : dumps is always followed by seq tables > 1 byte */
491 dumps += 3;
492 }
493 if (dumps >= de) dumps = de-1; /* late correction, to avoid read overflow (data is now corrupted anyway) */
494 }
495 matchLength += MINMATCH;
496
497 /* save result */
498 seq->litLength = litLength;
499 seq->offset = offset;
500 seq->matchLength = matchLength;
501 seqState->dumps = dumps;
502}
503
504
Yann Collet5b78d2f2015-11-12 15:36:05 +0100505FORCE_INLINE size_t ZSTD_execSequence(BYTE* op,
Yann Colletb3a2af92015-11-19 17:13:19 +0100506 BYTE* const oend, seq_t sequence,
Yann Collet5be2dd22015-11-11 13:43:58 +0100507 const BYTE** litPtr, const BYTE* const litLimit_8,
Yann Collet417890c2015-12-04 17:16:37 +0100508 const BYTE* const base, const BYTE* const vBase, const BYTE* const dictEnd)
Yann Collet5be2dd22015-11-11 13:43:58 +0100509{
Yann Colletb3a2af92015-11-19 17:13:19 +0100510 static const int dec32table[] = { 0, 1, 2, 1, 4, 4, 4, 4 }; /* added */
511 static const int dec64table[] = { 8, 8, 8, 7, 8, 9,10,11 }; /* substracted */
Yann Collet5be2dd22015-11-11 13:43:58 +0100512 BYTE* const oLitEnd = op + sequence.litLength;
Yann Colletb3a2af92015-11-19 17:13:19 +0100513 const size_t sequenceLength = sequence.litLength + sequence.matchLength;
514 BYTE* const oMatchEnd = op + sequenceLength; /* risk : address space overflow (32-bits) */
Yann Collet5be2dd22015-11-11 13:43:58 +0100515 BYTE* const oend_8 = oend-8;
516 const BYTE* const litEnd = *litPtr + sequence.litLength;
Yann Colletb3a2af92015-11-19 17:13:19 +0100517 const BYTE* match = oLitEnd - sequence.offset;
Yann Collet5be2dd22015-11-11 13:43:58 +0100518
519 /* check */
520 if (oLitEnd > oend_8) return ERROR(dstSize_tooSmall); /* last match must start at a minimum distance of 8 from oend */
521 if (oMatchEnd > oend) return ERROR(dstSize_tooSmall); /* overwrite beyond dst buffer */
522 if (litEnd > litLimit_8) return ERROR(corruption_detected); /* risk read beyond lit buffer */
523
524 /* copy Literals */
525 ZSTD_wildcopy(op, *litPtr, sequence.litLength); /* note : oLitEnd <= oend-8 : no risk of overwrite beyond oend */
526 op = oLitEnd;
527 *litPtr = litEnd; /* update for next sequence */
528
529 /* copy Match */
Yann Collet44287a32015-11-30 23:13:56 +0100530 /* check */
531 //if (match > oLitEnd) return ERROR(corruption_detected); /* address space overflow test (is clang optimizer wrongly removing this test ?) */
532 if (sequence.offset > (size_t)oLitEnd) return ERROR(corruption_detected); /* address space overflow test (this test seems preserved by clang optimizer) */
Yann Collet5be2dd22015-11-11 13:43:58 +0100533
Yann Collet44287a32015-11-30 23:13:56 +0100534 if (match < base)
535 {
536 /* offset beyond prefix */
537 if (match < vBase) return ERROR(corruption_detected);
538 match = dictEnd - (base-match);
539 if (match + sequence.matchLength <= dictEnd)
540 {
Yann Collet4bfe4152015-12-06 13:18:37 +0100541 memmove(oLitEnd, match, sequence.matchLength);
Yann Collet44287a32015-11-30 23:13:56 +0100542 return sequenceLength;
543 }
544 /* span extDict & currentPrefixSegment */
545 {
546 size_t length1 = dictEnd - match;
Yann Collet4bfe4152015-12-06 13:18:37 +0100547 memmove(oLitEnd, match, length1);
Yann Collet44287a32015-11-30 23:13:56 +0100548 op = oLitEnd + length1;
549 sequence.matchLength -= length1;
550 match = base;
551 }
552 }
Yann Collet0f366c62015-11-12 16:19:30 +0100553
Yann Collet44287a32015-11-30 23:13:56 +0100554 /* match within prefix */
555 if (sequence.offset < 8)
556 {
557 /* close range match, overlap */
558 const int sub2 = dec64table[sequence.offset];
559 op[0] = match[0];
560 op[1] = match[1];
561 op[2] = match[2];
562 op[3] = match[3];
563 match += dec32table[sequence.offset];
564 ZSTD_copy4(op+4, match);
565 match -= sub2;
566 }
567 else
568 {
569 ZSTD_copy8(op, match);
570 }
571 op += 8; match += 8;
Yann Collet5be2dd22015-11-11 13:43:58 +0100572
Yann Collet44287a32015-11-30 23:13:56 +0100573 if (oMatchEnd > oend-12)
574 {
575 if (op < oend_8)
576 {
577 ZSTD_wildcopy(op, match, oend_8 - op);
578 match += oend_8 - op;
579 op = oend_8;
580 }
581 while (op < oMatchEnd) *op++ = *match++;
582 }
583 else
584 {
585 ZSTD_wildcopy(op, match, sequence.matchLength-8); /* works even if matchLength < 8 */
586 }
587 return sequenceLength;
Yann Collet5be2dd22015-11-11 13:43:58 +0100588}
589
Yann Colletb3a2af92015-11-19 17:13:19 +0100590
Yann Collet5be2dd22015-11-11 13:43:58 +0100591static size_t ZSTD_decompressSequences(
Yann Collet5b78d2f2015-11-12 15:36:05 +0100592 ZSTD_DCtx* dctx,
Yann Collet5be2dd22015-11-11 13:43:58 +0100593 void* dst, size_t maxDstSize,
594 const void* seqStart, size_t seqSize)
595{
Yann Collet5be2dd22015-11-11 13:43:58 +0100596 const BYTE* ip = (const BYTE*)seqStart;
597 const BYTE* const iend = ip + seqSize;
598 BYTE* const ostart = (BYTE* const)dst;
599 BYTE* op = ostart;
600 BYTE* const oend = ostart + maxDstSize;
601 size_t errorCode, dumpsLength;
602 const BYTE* litPtr = dctx->litPtr;
603 const BYTE* const litLimit_8 = litPtr + dctx->litBufSize - 8;
604 const BYTE* const litEnd = litPtr + dctx->litSize;
605 int nbSeq;
606 const BYTE* dumps;
607 U32* DTableLL = dctx->LLTable;
608 U32* DTableML = dctx->MLTable;
609 U32* DTableOffb = dctx->OffTable;
Yann Collet417890c2015-12-04 17:16:37 +0100610 const BYTE* const base = (const BYTE*) (dctx->base);
611 const BYTE* const vBase = (const BYTE*) (dctx->vBase);
612 const BYTE* const dictEnd = (const BYTE*) (dctx->dictEnd);
Yann Collet5be2dd22015-11-11 13:43:58 +0100613
614 /* Build Decoding Tables */
615 errorCode = ZSTD_decodeSeqHeaders(&nbSeq, &dumps, &dumpsLength,
616 DTableLL, DTableML, DTableOffb,
617 ip, iend-ip);
618 if (ZSTD_isError(errorCode)) return errorCode;
619 ip += errorCode;
620
621 /* Regen sequences */
622 {
623 seq_t sequence;
624 seqState_t seqState;
625
626 memset(&sequence, 0, sizeof(sequence));
627 sequence.offset = 4;
628 seqState.dumps = dumps;
629 seqState.dumpsEnd = dumps + dumpsLength;
630 seqState.prevOffset = 4;
631 errorCode = BIT_initDStream(&(seqState.DStream), ip, iend-ip);
632 if (ERR_isError(errorCode)) return ERROR(corruption_detected);
633 FSE_initDState(&(seqState.stateLL), &(seqState.DStream), DTableLL);
634 FSE_initDState(&(seqState.stateOffb), &(seqState.DStream), DTableOffb);
635 FSE_initDState(&(seqState.stateML), &(seqState.DStream), DTableML);
636
Yann Collet44287a32015-11-30 23:13:56 +0100637 for ( ; (BIT_reloadDStream(&(seqState.DStream)) <= BIT_DStream_completed) && nbSeq ; )
Yann Colletb3a2af92015-11-19 17:13:19 +0100638 {
639 size_t oneSeqSize;
640 nbSeq--;
641 ZSTD_decodeSequence(&sequence, &seqState);
642 oneSeqSize = ZSTD_execSequence(op, oend, sequence, &litPtr, litLimit_8, base, vBase, dictEnd);
Yann Collet5be2dd22015-11-11 13:43:58 +0100643 if (ZSTD_isError(oneSeqSize)) return oneSeqSize;
644 op += oneSeqSize;
645 }
646
647 /* check if reached exact end */
Yann Collet44287a32015-11-30 23:13:56 +0100648 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 +0100649
650 /* last literal segment */
651 {
652 size_t lastLLSize = litEnd - litPtr;
653 if (litPtr > litEnd) return ERROR(corruption_detected);
654 if (op+lastLLSize > oend) return ERROR(dstSize_tooSmall);
655 if (op != litPtr) memcpy(op, litPtr, lastLLSize);
656 op += lastLLSize;
657 }
658 }
659
660 return op-ostart;
661}
662
663
664static size_t ZSTD_decompressBlock(
Yann Collet5b78d2f2015-11-12 15:36:05 +0100665 ZSTD_DCtx* dctx,
Yann Collet5be2dd22015-11-11 13:43:58 +0100666 void* dst, size_t maxDstSize,
667 const void* src, size_t srcSize)
668{
669 /* blockType == blockCompressed */
670 const BYTE* ip = (const BYTE*)src;
671
672 /* Decode literals sub-block */
Yann Collet5b78d2f2015-11-12 15:36:05 +0100673 size_t litCSize = ZSTD_decodeLiteralsBlock(dctx, src, srcSize);
Yann Collet5be2dd22015-11-11 13:43:58 +0100674 if (ZSTD_isError(litCSize)) return litCSize;
675 ip += litCSize;
676 srcSize -= litCSize;
677
Yann Collet5b78d2f2015-11-12 15:36:05 +0100678 return ZSTD_decompressSequences(dctx, dst, maxDstSize, ip, srcSize);
Yann Collet5be2dd22015-11-11 13:43:58 +0100679}
680
681
Yann Collet5b78d2f2015-11-12 15:36:05 +0100682size_t ZSTD_decompressDCtx(ZSTD_DCtx* ctx, void* dst, size_t maxDstSize, const void* src, size_t srcSize)
Yann Collet5be2dd22015-11-11 13:43:58 +0100683{
684 const BYTE* ip = (const BYTE*)src;
685 const BYTE* iend = ip + srcSize;
686 BYTE* const ostart = (BYTE* const)dst;
687 BYTE* op = ostart;
688 BYTE* const oend = ostart + maxDstSize;
689 size_t remainingSize = srcSize;
Yann Collet5be2dd22015-11-11 13:43:58 +0100690 blockProperties_t blockProperties;
691
Yann Collet5b78d2f2015-11-12 15:36:05 +0100692
Yann Colletb2549842015-11-18 11:29:32 +0100693 /* init */
Yann Collet417890c2015-12-04 17:16:37 +0100694 ctx->vBase = ctx->base = ctx->dictEnd = dst;
Yann Collet5b78d2f2015-11-12 15:36:05 +0100695
Yann Collet5be2dd22015-11-11 13:43:58 +0100696 /* Frame Header */
Yann Collet88fcd292015-11-25 14:42:45 +0100697 {
698 size_t frameHeaderSize;
699 if (srcSize < ZSTD_frameHeaderSize_min+ZSTD_blockHeaderSize) return ERROR(srcSize_wrong);
Yann Collet5be2dd22015-11-11 13:43:58 +0100700#if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT==1)
Yann Collet88fcd292015-11-25 14:42:45 +0100701 {
702 const U32 magicNumber = MEM_readLE32(src);
703 if (ZSTD_isLegacy(magicNumber))
704 return ZSTD_decompressLegacy(dst, maxDstSize, src, srcSize, magicNumber);
705 }
Yann Collet5be2dd22015-11-11 13:43:58 +0100706#endif
Yann Collet88fcd292015-11-25 14:42:45 +0100707 frameHeaderSize = ZSTD_decodeFrameHeader_Part1(ctx, src, ZSTD_frameHeaderSize_min);
708 if (ZSTD_isError(frameHeaderSize)) return frameHeaderSize;
709 if (srcSize < frameHeaderSize+ZSTD_blockHeaderSize) return ERROR(srcSize_wrong);
710 ip += frameHeaderSize; remainingSize -= frameHeaderSize;
711 frameHeaderSize = ZSTD_decodeFrameHeader_Part2(ctx, src, frameHeaderSize);
712 if (ZSTD_isError(frameHeaderSize)) return frameHeaderSize;
713 }
Yann Collet5be2dd22015-11-11 13:43:58 +0100714
715 /* Loop on each block */
716 while (1)
717 {
718 size_t decodedSize=0;
719 size_t cBlockSize = ZSTD_getcBlockSize(ip, iend-ip, &blockProperties);
720 if (ZSTD_isError(cBlockSize)) return cBlockSize;
721
722 ip += ZSTD_blockHeaderSize;
723 remainingSize -= ZSTD_blockHeaderSize;
724 if (cBlockSize > remainingSize) return ERROR(srcSize_wrong);
725
726 switch(blockProperties.blockType)
727 {
728 case bt_compressed:
729 decodedSize = ZSTD_decompressBlock(ctx, op, oend-op, ip, cBlockSize);
730 break;
731 case bt_raw :
Yann Collet0f366c62015-11-12 16:19:30 +0100732 decodedSize = ZSTD_copyRawBlock(op, oend-op, ip, cBlockSize);
Yann Collet5be2dd22015-11-11 13:43:58 +0100733 break;
734 case bt_rle :
735 return ERROR(GENERIC); /* not yet supported */
736 break;
737 case bt_end :
738 /* end of frame */
739 if (remainingSize) return ERROR(srcSize_wrong);
740 break;
741 default:
742 return ERROR(GENERIC); /* impossible */
743 }
744 if (cBlockSize == 0) break; /* bt_end */
745
746 if (ZSTD_isError(decodedSize)) return decodedSize;
747 op += decodedSize;
748 ip += cBlockSize;
749 remainingSize -= cBlockSize;
750 }
751
752 return op-ostart;
753}
754
755size_t ZSTD_decompress(void* dst, size_t maxDstSize, const void* src, size_t srcSize)
756{
757 ZSTD_DCtx ctx;
Yann Collet5be2dd22015-11-11 13:43:58 +0100758 return ZSTD_decompressDCtx(&ctx, dst, maxDstSize, src, srcSize);
759}
760
761
762/* ******************************
763* Streaming Decompression API
764********************************/
Yann Collet5be2dd22015-11-11 13:43:58 +0100765size_t ZSTD_nextSrcSizeToDecompress(ZSTD_DCtx* dctx)
766{
767 return dctx->expected;
768}
769
770size_t ZSTD_decompressContinue(ZSTD_DCtx* ctx, void* dst, size_t maxDstSize, const void* src, size_t srcSize)
771{
772 /* Sanity check */
773 if (srcSize != ctx->expected) return ERROR(srcSize_wrong);
Yann Collet88fcd292015-11-25 14:42:45 +0100774 if (dst != ctx->previousDstEnd) /* not contiguous */
Yann Collet5b78d2f2015-11-12 15:36:05 +0100775 {
Yann Colletbf7aa3c2015-11-28 18:19:44 +0100776 if ((dst > ctx->base) && (dst < ctx->previousDstEnd)) /* rolling buffer : new segment into dictionary */
777 ctx->base = (char*)dst; /* temporary affectation, for vBase calculation */
Yann Colletad50c592015-11-28 17:09:28 +0100778 ctx->dictEnd = ctx->previousDstEnd;
Yann Collet417890c2015-12-04 17:16:37 +0100779 ctx->vBase = (const char*)dst - ((const char*)(ctx->previousDstEnd) - (const char*)(ctx->base));
Yann Colletb2549842015-11-18 11:29:32 +0100780 ctx->base = dst;
Yann Colletad50c592015-11-28 17:09:28 +0100781 ctx->previousDstEnd = dst;
Yann Colletb2549842015-11-18 11:29:32 +0100782 }
Yann Collet5be2dd22015-11-11 13:43:58 +0100783
Yann Collet88fcd292015-11-25 14:42:45 +0100784 /* Decompress : frame header; part 1 */
785 switch (ctx->stage)
Yann Collet5be2dd22015-11-11 13:43:58 +0100786 {
Yann Collet88fcd292015-11-25 14:42:45 +0100787 case ZSTDds_getFrameHeaderSize :
Yann Collet5be2dd22015-11-11 13:43:58 +0100788 {
Yann Collet88fcd292015-11-25 14:42:45 +0100789 /* get frame header size */
790 if (srcSize != ZSTD_frameHeaderSize_min) return ERROR(srcSize_wrong); /* impossible */
791 ctx->headerSize = ZSTD_decodeFrameHeader_Part1(ctx, src, ZSTD_frameHeaderSize_min);
Yann Collete4fdad52015-11-25 21:09:17 +0100792 if (ZSTD_isError(ctx->headerSize)) return ctx->headerSize;
Yann Collet88fcd292015-11-25 14:42:45 +0100793 memcpy(ctx->headerBuffer, src, ZSTD_frameHeaderSize_min);
794 if (ctx->headerSize > ZSTD_frameHeaderSize_min)
795 {
796 ctx->expected = ctx->headerSize - ZSTD_frameHeaderSize_min;
797 ctx->stage = ZSTDds_decodeFrameHeader;
798 return 0;
799 }
800 ctx->expected = 0; /* not necessary to copy more */
Yann Collet5be2dd22015-11-11 13:43:58 +0100801 }
Yann Collet88fcd292015-11-25 14:42:45 +0100802 case ZSTDds_decodeFrameHeader:
Yann Collet5be2dd22015-11-11 13:43:58 +0100803 {
Yann Collet88fcd292015-11-25 14:42:45 +0100804 /* get frame header */
805 size_t result;
806 memcpy(ctx->headerBuffer + ZSTD_frameHeaderSize_min, src, ctx->expected);
807 result = ZSTD_decodeFrameHeader_Part2(ctx, ctx->headerBuffer, ctx->headerSize);
808 if (ZSTD_isError(result)) return result;
809 ctx->expected = ZSTD_blockHeaderSize;
810 ctx->stage = ZSTDds_decodeBlockHeader;
811 return 0;
Yann Collet5be2dd22015-11-11 13:43:58 +0100812 }
Yann Collet88fcd292015-11-25 14:42:45 +0100813 case ZSTDds_decodeBlockHeader:
Yann Collet5be2dd22015-11-11 13:43:58 +0100814 {
Yann Collet88fcd292015-11-25 14:42:45 +0100815 /* Decode block header */
816 blockProperties_t bp;
817 size_t blockSize = ZSTD_getcBlockSize(src, ZSTD_blockHeaderSize, &bp);
818 if (ZSTD_isError(blockSize)) return blockSize;
819 if (bp.blockType == bt_end)
820 {
821 ctx->expected = 0;
822 ctx->stage = ZSTDds_getFrameHeaderSize;
823 }
824 else
825 {
826 ctx->expected = blockSize;
827 ctx->bType = bp.blockType;
828 ctx->stage = ZSTDds_decompressBlock;
829 }
Yann Collet88fcd292015-11-25 14:42:45 +0100830 return 0;
831 }
Yann Collet417890c2015-12-04 17:16:37 +0100832 case ZSTDds_decompressBlock:
Yann Collet88fcd292015-11-25 14:42:45 +0100833 {
834 /* Decompress : block content */
835 size_t rSize;
836 switch(ctx->bType)
837 {
838 case bt_compressed:
839 rSize = ZSTD_decompressBlock(ctx, dst, maxDstSize, src, srcSize);
840 break;
841 case bt_raw :
842 rSize = ZSTD_copyRawBlock(dst, maxDstSize, src, srcSize);
843 break;
844 case bt_rle :
845 return ERROR(GENERIC); /* not yet handled */
846 break;
847 case bt_end : /* should never happen (filtered at phase 1) */
848 rSize = 0;
849 break;
850 default:
851 return ERROR(GENERIC);
852 }
853 ctx->stage = ZSTDds_decodeBlockHeader;
854 ctx->expected = ZSTD_blockHeaderSize;
855 ctx->previousDstEnd = (char*)dst + rSize;
856 return rSize;
857 }
858 default:
859 return ERROR(GENERIC); /* impossible */
860 }
Yann Collet5be2dd22015-11-11 13:43:58 +0100861}
862
863
Yann Collet417890c2015-12-04 17:16:37 +0100864void ZSTD_decompress_insertDictionary(ZSTD_DCtx* ctx, const void* src, size_t srcSize)
865{
866 ctx->dictEnd = ctx->previousDstEnd;
867 ctx->vBase = (const char*)src - ((const char*)(ctx->previousDstEnd) - (const char*)(ctx->base));
868 ctx->base = src;
869 ctx->previousDstEnd = (const char*)src + srcSize;
870}