blob: 430dc7acad52a40d791c7a60de4d700677d04a36 [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
71
72/* *******************************************************
73* Compiler specifics
74*********************************************************/
Yann Collet5be2dd22015-11-11 13:43:58 +010075#ifdef _MSC_VER /* Visual Studio */
76# define FORCE_INLINE static __forceinline
77# include <intrin.h> /* For Visual 2005 */
78# pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */
79# pragma warning(disable : 4324) /* disable: C4324: padded structure */
80#else
81# define GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__)
82# ifdef __GNUC__
83# define FORCE_INLINE static inline __attribute__((always_inline))
84# else
85# define FORCE_INLINE static inline
86# endif
87#endif
88
89
Yann Collet14983e72015-11-11 21:38:21 +010090/* *************************************
91* Local types
92***************************************/
93typedef struct
94{
95 blockType_t blockType;
96 U32 origSize;
97} blockProperties_t;
Yann Collet5be2dd22015-11-11 13:43:58 +010098
99
100/* *******************************************************
101* Memory operations
102**********************************************************/
103static void ZSTD_copy4(void* dst, const void* src) { memcpy(dst, src, 4); }
104
105
Yann Collet5be2dd22015-11-11 13:43:58 +0100106/* *************************************
107* Error Management
108***************************************/
Yann Collet14983e72015-11-11 21:38:21 +0100109unsigned ZSTD_versionNumber (void) { return ZSTD_VERSION_NUMBER; }
110
Yann Collet5be2dd22015-11-11 13:43:58 +0100111/*! ZSTD_isError
112* tells if a return value is an error code */
113unsigned ZSTD_isError(size_t code) { return ERR_isError(code); }
114
115/*! ZSTD_getErrorName
116* provides error code string (useful for debugging) */
117const char* ZSTD_getErrorName(size_t code) { return ERR_getErrorName(code); }
118
119
Yann Collet5be2dd22015-11-11 13:43:58 +0100120/* *************************************************************
Yann Collet5b78d2f2015-11-12 15:36:05 +0100121* Context management
Yann Collet5be2dd22015-11-11 13:43:58 +0100122***************************************************************/
123struct ZSTD_DCtx_s
124{
125 U32 LLTable[FSE_DTABLE_SIZE_U32(LLFSELog)];
126 U32 OffTable[FSE_DTABLE_SIZE_U32(OffFSELog)];
127 U32 MLTable[FSE_DTABLE_SIZE_U32(MLFSELog)];
128 void* previousDstEnd;
129 void* base;
Yann Collet5b78d2f2015-11-12 15:36:05 +0100130 void* vBase;
131 void* dictEnd;
Yann Collet5be2dd22015-11-11 13:43:58 +0100132 size_t expected;
133 blockType_t bType;
134 U32 phase;
135 const BYTE* litPtr;
136 size_t litBufSize;
137 size_t litSize;
138 BYTE litBuffer[BLOCKSIZE + 8 /* margin for wildcopy */];
139}; /* typedef'd to ZSTD_Dctx within "zstd_static.h" */
140
Yann Collet5b78d2f2015-11-12 15:36:05 +0100141size_t ZSTD_resetDCtx(ZSTD_DCtx* dctx)
142{
143 dctx->expected = ZSTD_frameHeaderSize;
144 dctx->phase = 0;
145 dctx->previousDstEnd = NULL;
146 dctx->base = NULL;
147 dctx->vBase = NULL;
148 dctx->dictEnd = NULL;
149 return 0;
150}
151
152ZSTD_DCtx* ZSTD_createDCtx(void)
153{
154 ZSTD_DCtx* dctx = (ZSTD_DCtx*)malloc(sizeof(ZSTD_DCtx));
155 if (dctx==NULL) return NULL;
156 ZSTD_resetDCtx(dctx);
157 return dctx;
158}
159
160size_t ZSTD_freeDCtx(ZSTD_DCtx* dctx)
161{
162 free(dctx);
163 return 0;
164}
165
166
167/* *************************************************************
168* Decompression section
169***************************************************************/
Yann Collet5be2dd22015-11-11 13:43:58 +0100170
171size_t ZSTD_getcBlockSize(const void* src, size_t srcSize, blockProperties_t* bpPtr)
172{
173 const BYTE* const in = (const BYTE* const)src;
174 BYTE headerFlags;
175 U32 cSize;
176
177 if (srcSize < 3) return ERROR(srcSize_wrong);
178
179 headerFlags = *in;
180 cSize = in[2] + (in[1]<<8) + ((in[0] & 7)<<16);
181
182 bpPtr->blockType = (blockType_t)(headerFlags >> 6);
183 bpPtr->origSize = (bpPtr->blockType == bt_rle) ? cSize : 0;
184
185 if (bpPtr->blockType == bt_end) return 0;
186 if (bpPtr->blockType == bt_rle) return 1;
187 return cSize;
188}
189
Yann Collet0f366c62015-11-12 16:19:30 +0100190static size_t ZSTD_copyRawBlock(void* dst, size_t maxDstSize, const void* src, size_t srcSize)
Yann Collet5be2dd22015-11-11 13:43:58 +0100191{
192 if (srcSize > maxDstSize) return ERROR(dstSize_tooSmall);
193 memcpy(dst, src, srcSize);
194 return srcSize;
195}
196
197
198/** ZSTD_decompressLiterals
199 @return : nb of bytes read from src, or an error code*/
200static size_t ZSTD_decompressLiterals(void* dst, size_t* maxDstSizePtr,
201 const void* src, size_t srcSize)
202{
203 const BYTE* ip = (const BYTE*)src;
204
205 const size_t litSize = (MEM_readLE32(src) & 0x1FFFFF) >> 2; /* no buffer issue : srcSize >= MIN_CBLOCK_SIZE */
206 const size_t litCSize = (MEM_readLE32(ip+2) & 0xFFFFFF) >> 5; /* no buffer issue : srcSize >= MIN_CBLOCK_SIZE */
207
208 if (litSize > *maxDstSizePtr) return ERROR(corruption_detected);
209 if (litCSize + 5 > srcSize) return ERROR(corruption_detected);
210
211 if (HUF_isError(HUF_decompress(dst, litSize, ip+5, litCSize))) return ERROR(corruption_detected);
212
213 *maxDstSizePtr = litSize;
214 return litCSize + 5;
215}
216
217
218/** ZSTD_decodeLiteralsBlock
Yann Collet14983e72015-11-11 21:38:21 +0100219 @return : nb of bytes read from src (< srcSize ) */
Yann Collet5b78d2f2015-11-12 15:36:05 +0100220size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx,
Yann Collet5be2dd22015-11-11 13:43:58 +0100221 const void* src, size_t srcSize) /* note : srcSize < BLOCKSIZE */
222{
Yann Collet5be2dd22015-11-11 13:43:58 +0100223 const BYTE* const istart = (const BYTE*) src;
224
225 /* any compressed block with literals segment must be at least this size */
226 if (srcSize < MIN_CBLOCK_SIZE) return ERROR(corruption_detected);
227
228 switch(*istart & 3)
229 {
230 /* compressed */
231 case 0:
232 {
233 size_t litSize = BLOCKSIZE;
234 const size_t readSize = ZSTD_decompressLiterals(dctx->litBuffer, &litSize, src, srcSize);
235 dctx->litPtr = dctx->litBuffer;
236 dctx->litBufSize = BLOCKSIZE+8;
237 dctx->litSize = litSize;
238 return readSize; /* works if it's an error too */
239 }
240 case IS_RAW:
241 {
242 const size_t litSize = (MEM_readLE32(istart) & 0xFFFFFF) >> 2; /* no buffer issue : srcSize >= MIN_CBLOCK_SIZE */
243 if (litSize > srcSize-11) /* risk of reading too far with wildcopy */
244 {
245 if (litSize > srcSize-3) return ERROR(corruption_detected);
246 memcpy(dctx->litBuffer, istart, litSize);
247 dctx->litPtr = dctx->litBuffer;
248 dctx->litBufSize = BLOCKSIZE+8;
249 dctx->litSize = litSize;
250 return litSize+3;
251 }
252 /* direct reference into compressed stream */
253 dctx->litPtr = istart+3;
254 dctx->litBufSize = srcSize-3;
255 dctx->litSize = litSize;
256 return litSize+3; }
257 case IS_RLE:
258 {
259 const size_t litSize = (MEM_readLE32(istart) & 0xFFFFFF) >> 2; /* no buffer issue : srcSize >= MIN_CBLOCK_SIZE */
260 if (litSize > BLOCKSIZE) return ERROR(corruption_detected);
261 memset(dctx->litBuffer, istart[3], litSize);
262 dctx->litPtr = dctx->litBuffer;
263 dctx->litBufSize = BLOCKSIZE+8;
264 dctx->litSize = litSize;
265 return 4;
266 }
267 default:
268 return ERROR(corruption_detected); /* forbidden nominal case */
269 }
270}
271
272
273size_t ZSTD_decodeSeqHeaders(int* nbSeq, const BYTE** dumpsPtr, size_t* dumpsLengthPtr,
274 FSE_DTable* DTableLL, FSE_DTable* DTableML, FSE_DTable* DTableOffb,
275 const void* src, size_t srcSize)
276{
277 const BYTE* const istart = (const BYTE* const)src;
278 const BYTE* ip = istart;
279 const BYTE* const iend = istart + srcSize;
280 U32 LLtype, Offtype, MLtype;
281 U32 LLlog, Offlog, MLlog;
282 size_t dumpsLength;
283
284 /* check */
285 if (srcSize < 5) return ERROR(srcSize_wrong);
286
287 /* SeqHead */
288 *nbSeq = MEM_readLE16(ip); ip+=2;
289 LLtype = *ip >> 6;
290 Offtype = (*ip >> 4) & 3;
291 MLtype = (*ip >> 2) & 3;
292 if (*ip & 2)
293 {
294 dumpsLength = ip[2];
295 dumpsLength += ip[1] << 8;
296 ip += 3;
297 }
298 else
299 {
300 dumpsLength = ip[1];
301 dumpsLength += (ip[0] & 1) << 8;
302 ip += 2;
303 }
304 *dumpsPtr = ip;
305 ip += dumpsLength;
306 *dumpsLengthPtr = dumpsLength;
307
308 /* check */
309 if (ip > iend-3) return ERROR(srcSize_wrong); /* min : all 3 are "raw", hence no header, but at least xxLog bits per type */
310
311 /* sequences */
312 {
Yann Collet82368cf2015-11-16 19:10:56 +0100313 S16 norm[MaxML+1]; /* assumption : MaxML >= MaxLL >= MaxOff */
Yann Collet5be2dd22015-11-11 13:43:58 +0100314 size_t headerSize;
315
316 /* Build DTables */
317 switch(LLtype)
318 {
319 U32 max;
320 case bt_rle :
321 LLlog = 0;
322 FSE_buildDTable_rle(DTableLL, *ip++); break;
323 case bt_raw :
324 LLlog = LLbits;
325 FSE_buildDTable_raw(DTableLL, LLbits); break;
326 default :
327 max = MaxLL;
328 headerSize = FSE_readNCount(norm, &max, &LLlog, ip, iend-ip);
329 if (FSE_isError(headerSize)) return ERROR(GENERIC);
330 if (LLlog > LLFSELog) return ERROR(corruption_detected);
331 ip += headerSize;
332 FSE_buildDTable(DTableLL, norm, max, LLlog);
333 }
334
335 switch(Offtype)
336 {
337 U32 max;
338 case bt_rle :
339 Offlog = 0;
340 if (ip > iend-2) return ERROR(srcSize_wrong); /* min : "raw", hence no header, but at least xxLog bits */
341 FSE_buildDTable_rle(DTableOffb, *ip++ & MaxOff); /* if *ip > MaxOff, data is corrupted */
342 break;
343 case bt_raw :
344 Offlog = Offbits;
345 FSE_buildDTable_raw(DTableOffb, Offbits); break;
346 default :
347 max = MaxOff;
348 headerSize = FSE_readNCount(norm, &max, &Offlog, ip, iend-ip);
349 if (FSE_isError(headerSize)) return ERROR(GENERIC);
350 if (Offlog > OffFSELog) return ERROR(corruption_detected);
351 ip += headerSize;
352 FSE_buildDTable(DTableOffb, norm, max, Offlog);
353 }
354
355 switch(MLtype)
356 {
357 U32 max;
358 case bt_rle :
359 MLlog = 0;
360 if (ip > iend-2) return ERROR(srcSize_wrong); /* min : "raw", hence no header, but at least xxLog bits */
361 FSE_buildDTable_rle(DTableML, *ip++); break;
362 case bt_raw :
363 MLlog = MLbits;
364 FSE_buildDTable_raw(DTableML, MLbits); break;
365 default :
366 max = MaxML;
367 headerSize = FSE_readNCount(norm, &max, &MLlog, ip, iend-ip);
368 if (FSE_isError(headerSize)) return ERROR(GENERIC);
369 if (MLlog > MLFSELog) return ERROR(corruption_detected);
370 ip += headerSize;
371 FSE_buildDTable(DTableML, norm, max, MLlog);
372 }
373 }
374
375 return ip-istart;
376}
377
378
379typedef struct {
380 size_t litLength;
381 size_t offset;
382 size_t matchLength;
383} seq_t;
384
385typedef struct {
386 BIT_DStream_t DStream;
387 FSE_DState_t stateLL;
388 FSE_DState_t stateOffb;
389 FSE_DState_t stateML;
390 size_t prevOffset;
391 const BYTE* dumps;
392 const BYTE* dumpsEnd;
393} seqState_t;
394
395
396static void ZSTD_decodeSequence(seq_t* seq, seqState_t* seqState)
397{
398 size_t litLength;
399 size_t prevOffset;
400 size_t offset;
401 size_t matchLength;
402 const BYTE* dumps = seqState->dumps;
403 const BYTE* const de = seqState->dumpsEnd;
404
405 /* Literal length */
406 litLength = FSE_decodeSymbol(&(seqState->stateLL), &(seqState->DStream));
Yann Collet55aa7f92015-11-20 12:04:52 +0100407 prevOffset = litLength ? seq->offset : seqState->prevOffset;
Yann Collet5be2dd22015-11-11 13:43:58 +0100408 if (litLength == MaxLL)
409 {
410 U32 add = *dumps++;
411 if (add < 255) litLength += add;
412 else
413 {
414 litLength = MEM_readLE32(dumps) & 0xFFFFFF; /* no pb : dumps is always followed by seq tables > 1 byte */
415 dumps += 3;
416 }
417 if (dumps >= de) dumps = de-1; /* late correction, to avoid read overflow (data is now corrupted anyway) */
418 }
419
420 /* Offset */
421 {
422 static const U32 offsetPrefix[MaxOff+1] = {
423 1 /*fake*/, 1, 2, 4, 8, 16, 32, 64, 128, 256,
424 512, 1024, 2048, 4096, 8192, 16384, 32768, 65536, 131072, 262144,
425 524288, 1048576, 2097152, 4194304, 8388608, 16777216, 33554432, /*fake*/ 1, 1, 1, 1, 1 };
426 U32 offsetCode, nbBits;
427 offsetCode = FSE_decodeSymbol(&(seqState->stateOffb), &(seqState->DStream)); /* <= maxOff, by table construction */
428 if (MEM_32bits()) BIT_reloadDStream(&(seqState->DStream));
429 nbBits = offsetCode - 1;
430 if (offsetCode==0) nbBits = 0; /* cmove */
431 offset = offsetPrefix[offsetCode] + BIT_readBits(&(seqState->DStream), nbBits);
432 if (MEM_32bits()) BIT_reloadDStream(&(seqState->DStream));
433 if (offsetCode==0) offset = prevOffset; /* cmove */
Yann Collet55aa7f92015-11-20 12:04:52 +0100434 if (offsetCode | !litLength) seqState->prevOffset = seq->offset; /* cmove */
Yann Collet5be2dd22015-11-11 13:43:58 +0100435 }
436
437 /* MatchLength */
438 matchLength = FSE_decodeSymbol(&(seqState->stateML), &(seqState->DStream));
439 if (matchLength == MaxML)
440 {
441 U32 add = *dumps++;
442 if (add < 255) matchLength += add;
443 else
444 {
445 matchLength = MEM_readLE32(dumps) & 0xFFFFFF; /* no pb : dumps is always followed by seq tables > 1 byte */
446 dumps += 3;
447 }
448 if (dumps >= de) dumps = de-1; /* late correction, to avoid read overflow (data is now corrupted anyway) */
449 }
450 matchLength += MINMATCH;
451
452 /* save result */
453 seq->litLength = litLength;
454 seq->offset = offset;
455 seq->matchLength = matchLength;
456 seqState->dumps = dumps;
457}
458
459
Yann Collet5b78d2f2015-11-12 15:36:05 +0100460FORCE_INLINE size_t ZSTD_execSequence(BYTE* op,
Yann Colletb3a2af92015-11-19 17:13:19 +0100461 BYTE* const oend, seq_t sequence,
Yann Collet5be2dd22015-11-11 13:43:58 +0100462 const BYTE** litPtr, const BYTE* const litLimit_8,
Yann Colletb3a2af92015-11-19 17:13:19 +0100463 BYTE* const base, BYTE* const vBase, BYTE* const dictEnd)
Yann Collet5be2dd22015-11-11 13:43:58 +0100464{
Yann Colletb3a2af92015-11-19 17:13:19 +0100465 static const int dec32table[] = { 0, 1, 2, 1, 4, 4, 4, 4 }; /* added */
466 static const int dec64table[] = { 8, 8, 8, 7, 8, 9,10,11 }; /* substracted */
Yann Collet5be2dd22015-11-11 13:43:58 +0100467 BYTE* const oLitEnd = op + sequence.litLength;
Yann Colletb3a2af92015-11-19 17:13:19 +0100468 const size_t sequenceLength = sequence.litLength + sequence.matchLength;
469 BYTE* const oMatchEnd = op + sequenceLength; /* risk : address space overflow (32-bits) */
Yann Collet5be2dd22015-11-11 13:43:58 +0100470 BYTE* const oend_8 = oend-8;
471 const BYTE* const litEnd = *litPtr + sequence.litLength;
Yann Colletb3a2af92015-11-19 17:13:19 +0100472 const BYTE* match = oLitEnd - sequence.offset;
Yann Collet5be2dd22015-11-11 13:43:58 +0100473
474 /* check */
475 if (oLitEnd > oend_8) return ERROR(dstSize_tooSmall); /* last match must start at a minimum distance of 8 from oend */
476 if (oMatchEnd > oend) return ERROR(dstSize_tooSmall); /* overwrite beyond dst buffer */
477 if (litEnd > litLimit_8) return ERROR(corruption_detected); /* risk read beyond lit buffer */
478
479 /* copy Literals */
480 ZSTD_wildcopy(op, *litPtr, sequence.litLength); /* note : oLitEnd <= oend-8 : no risk of overwrite beyond oend */
481 op = oLitEnd;
482 *litPtr = litEnd; /* update for next sequence */
483
484 /* copy Match */
Yann Colletb3a2af92015-11-19 17:13:19 +0100485 /* check */
486 //if (match > oLitEnd) return ERROR(corruption_detected); /* address space overflow test (is clang optimizer wrongly removing this test ?) */
487 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 +0100488
Yann Colletb3a2af92015-11-19 17:13:19 +0100489 if (match < base)
490 {
491 /* offset beyond prefix */
492 if (match < vBase) return ERROR(corruption_detected);
493 match = dictEnd - (base-match);
494 if (match + sequence.matchLength <= dictEnd)
495 {
496 memcpy(oLitEnd, match, sequence.matchLength);
497 return sequenceLength;
498 }
499 /* span extDict & currentPrefixSegment */
500 {
501 size_t length1 = dictEnd - match;
502 memcpy(oLitEnd, match, length1);
503 op = oLitEnd + length1;
504 sequence.matchLength -= length1;
505 match = base;
506 }
507 }
Yann Collet0f366c62015-11-12 16:19:30 +0100508
Yann Colletb3a2af92015-11-19 17:13:19 +0100509 /* match within prefix */
510 if (sequence.offset < 8)
511 {
512 /* close range match, overlap */
513 const int sub2 = dec64table[sequence.offset];
514 op[0] = match[0];
515 op[1] = match[1];
516 op[2] = match[2];
517 op[3] = match[3];
518 match += dec32table[sequence.offset];
519 ZSTD_copy4(op+4, match);
520 match -= sub2;
521 }
522 else
523 {
524 ZSTD_copy8(op, match);
525 }
526 op += 8; match += 8;
Yann Collet5be2dd22015-11-11 13:43:58 +0100527
Yann Colletb3a2af92015-11-19 17:13:19 +0100528 if (oMatchEnd > oend-12)
529 {
530 if (op < oend_8)
531 {
532 ZSTD_wildcopy(op, match, oend_8 - op);
533 match += oend_8 - op;
534 op = oend_8;
535 }
536 while (op < oMatchEnd) *op++ = *match++;
537 }
538 else
539 {
540 ZSTD_wildcopy(op, match, sequence.matchLength-8); /* works even if matchLength < 8 */
541 }
542 return sequenceLength;
Yann Collet5be2dd22015-11-11 13:43:58 +0100543}
544
Yann Colletb3a2af92015-11-19 17:13:19 +0100545
Yann Collet5be2dd22015-11-11 13:43:58 +0100546static size_t ZSTD_decompressSequences(
Yann Collet5b78d2f2015-11-12 15:36:05 +0100547 ZSTD_DCtx* dctx,
Yann Collet5be2dd22015-11-11 13:43:58 +0100548 void* dst, size_t maxDstSize,
549 const void* seqStart, size_t seqSize)
550{
Yann Collet5be2dd22015-11-11 13:43:58 +0100551 const BYTE* ip = (const BYTE*)seqStart;
552 const BYTE* const iend = ip + seqSize;
553 BYTE* const ostart = (BYTE* const)dst;
554 BYTE* op = ostart;
555 BYTE* const oend = ostart + maxDstSize;
556 size_t errorCode, dumpsLength;
557 const BYTE* litPtr = dctx->litPtr;
558 const BYTE* const litLimit_8 = litPtr + dctx->litBufSize - 8;
559 const BYTE* const litEnd = litPtr + dctx->litSize;
560 int nbSeq;
561 const BYTE* dumps;
562 U32* DTableLL = dctx->LLTable;
563 U32* DTableML = dctx->MLTable;
564 U32* DTableOffb = dctx->OffTable;
565 BYTE* const base = (BYTE*) (dctx->base);
Yann Collet5b78d2f2015-11-12 15:36:05 +0100566 BYTE* const vBase = (BYTE*) (dctx->vBase);
567 BYTE* const dictEnd = (BYTE*) (dctx->dictEnd);
Yann Collet5be2dd22015-11-11 13:43:58 +0100568
569 /* Build Decoding Tables */
570 errorCode = ZSTD_decodeSeqHeaders(&nbSeq, &dumps, &dumpsLength,
571 DTableLL, DTableML, DTableOffb,
572 ip, iend-ip);
573 if (ZSTD_isError(errorCode)) return errorCode;
574 ip += errorCode;
575
576 /* Regen sequences */
577 {
578 seq_t sequence;
579 seqState_t seqState;
580
581 memset(&sequence, 0, sizeof(sequence));
582 sequence.offset = 4;
583 seqState.dumps = dumps;
584 seqState.dumpsEnd = dumps + dumpsLength;
585 seqState.prevOffset = 4;
586 errorCode = BIT_initDStream(&(seqState.DStream), ip, iend-ip);
587 if (ERR_isError(errorCode)) return ERROR(corruption_detected);
588 FSE_initDState(&(seqState.stateLL), &(seqState.DStream), DTableLL);
589 FSE_initDState(&(seqState.stateOffb), &(seqState.DStream), DTableOffb);
590 FSE_initDState(&(seqState.stateML), &(seqState.DStream), DTableML);
591
Yann Colletb3a2af92015-11-19 17:13:19 +0100592 for ( ; (BIT_reloadDStream(&(seqState.DStream)) < BIT_DStream_completed) ; )
Yann Collet5be2dd22015-11-11 13:43:58 +0100593 {
594 size_t oneSeqSize;
595 nbSeq--;
596 ZSTD_decodeSequence(&sequence, &seqState);
Yann Colletb3a2af92015-11-19 17:13:19 +0100597 oneSeqSize = ZSTD_execSequence(op, oend, sequence, &litPtr, litLimit_8, base, vBase, dictEnd);
598 if (ZSTD_isError(oneSeqSize)) return oneSeqSize;
599 op += oneSeqSize;
600 }
601
602 if (nbSeq<0) return ERROR(corruption_detected); /* requested too many sequences : data is corrupted */
603
604 /* now BIT_reloadDStream(&(seqState.DStream)) >= BIT_DStream_completed) */
605 for ( ; (BIT_reloadDStream(&(seqState.DStream)) == BIT_DStream_completed) && nbSeq ; )
606 {
607 size_t oneSeqSize;
608 nbSeq--;
609 ZSTD_decodeSequence(&sequence, &seqState);
610 oneSeqSize = ZSTD_execSequence(op, oend, sequence, &litPtr, litLimit_8, base, vBase, dictEnd);
Yann Collet5be2dd22015-11-11 13:43:58 +0100611 if (ZSTD_isError(oneSeqSize)) return oneSeqSize;
612 op += oneSeqSize;
613 }
614
615 /* check if reached exact end */
Yann Colletb3a2af92015-11-19 17:13:19 +0100616 if ( !BIT_endOfDStream(&(seqState.DStream)) ) return ERROR(corruption_detected); /* DStream should be entirely and precisely consumed; otherwise data is corrupted */
Yann Collet5be2dd22015-11-11 13:43:58 +0100617
618 /* last literal segment */
619 {
620 size_t lastLLSize = litEnd - litPtr;
621 if (litPtr > litEnd) return ERROR(corruption_detected);
622 if (op+lastLLSize > oend) return ERROR(dstSize_tooSmall);
623 if (op != litPtr) memcpy(op, litPtr, lastLLSize);
624 op += lastLLSize;
625 }
626 }
627
628 return op-ostart;
629}
630
631
632static size_t ZSTD_decompressBlock(
Yann Collet5b78d2f2015-11-12 15:36:05 +0100633 ZSTD_DCtx* dctx,
Yann Collet5be2dd22015-11-11 13:43:58 +0100634 void* dst, size_t maxDstSize,
635 const void* src, size_t srcSize)
636{
637 /* blockType == blockCompressed */
638 const BYTE* ip = (const BYTE*)src;
639
640 /* Decode literals sub-block */
Yann Collet5b78d2f2015-11-12 15:36:05 +0100641 size_t litCSize = ZSTD_decodeLiteralsBlock(dctx, src, srcSize);
Yann Collet5be2dd22015-11-11 13:43:58 +0100642 if (ZSTD_isError(litCSize)) return litCSize;
643 ip += litCSize;
644 srcSize -= litCSize;
645
Yann Collet5b78d2f2015-11-12 15:36:05 +0100646 return ZSTD_decompressSequences(dctx, dst, maxDstSize, ip, srcSize);
Yann Collet5be2dd22015-11-11 13:43:58 +0100647}
648
649
Yann Collet5b78d2f2015-11-12 15:36:05 +0100650size_t ZSTD_decompressDCtx(ZSTD_DCtx* ctx, void* dst, size_t maxDstSize, const void* src, size_t srcSize)
Yann Collet5be2dd22015-11-11 13:43:58 +0100651{
652 const BYTE* ip = (const BYTE*)src;
653 const BYTE* iend = ip + srcSize;
654 BYTE* const ostart = (BYTE* const)dst;
655 BYTE* op = ostart;
656 BYTE* const oend = ostart + maxDstSize;
657 size_t remainingSize = srcSize;
658 U32 magicNumber;
659 blockProperties_t blockProperties;
660
Yann Collet5b78d2f2015-11-12 15:36:05 +0100661
Yann Colletb2549842015-11-18 11:29:32 +0100662 /* init */
663 ctx->base = ctx->vBase = ctx->dictEnd = dst;
Yann Collet5b78d2f2015-11-12 15:36:05 +0100664
Yann Collet5be2dd22015-11-11 13:43:58 +0100665 /* Frame Header */
666 if (srcSize < ZSTD_frameHeaderSize+ZSTD_blockHeaderSize) return ERROR(srcSize_wrong);
667 magicNumber = MEM_readLE32(src);
668#if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT==1)
669 if (ZSTD_isLegacy(magicNumber))
670 return ZSTD_decompressLegacy(dst, maxDstSize, src, srcSize, magicNumber);
671#endif
672 if (magicNumber != ZSTD_magicNumber) return ERROR(prefix_unknown);
673 ip += ZSTD_frameHeaderSize; remainingSize -= ZSTD_frameHeaderSize;
674
675 /* Loop on each block */
676 while (1)
677 {
678 size_t decodedSize=0;
679 size_t cBlockSize = ZSTD_getcBlockSize(ip, iend-ip, &blockProperties);
680 if (ZSTD_isError(cBlockSize)) return cBlockSize;
681
682 ip += ZSTD_blockHeaderSize;
683 remainingSize -= ZSTD_blockHeaderSize;
684 if (cBlockSize > remainingSize) return ERROR(srcSize_wrong);
685
686 switch(blockProperties.blockType)
687 {
688 case bt_compressed:
689 decodedSize = ZSTD_decompressBlock(ctx, op, oend-op, ip, cBlockSize);
690 break;
691 case bt_raw :
Yann Collet0f366c62015-11-12 16:19:30 +0100692 decodedSize = ZSTD_copyRawBlock(op, oend-op, ip, cBlockSize);
Yann Collet5be2dd22015-11-11 13:43:58 +0100693 break;
694 case bt_rle :
695 return ERROR(GENERIC); /* not yet supported */
696 break;
697 case bt_end :
698 /* end of frame */
699 if (remainingSize) return ERROR(srcSize_wrong);
700 break;
701 default:
702 return ERROR(GENERIC); /* impossible */
703 }
704 if (cBlockSize == 0) break; /* bt_end */
705
706 if (ZSTD_isError(decodedSize)) return decodedSize;
707 op += decodedSize;
708 ip += cBlockSize;
709 remainingSize -= cBlockSize;
710 }
711
712 return op-ostart;
713}
714
715size_t ZSTD_decompress(void* dst, size_t maxDstSize, const void* src, size_t srcSize)
716{
717 ZSTD_DCtx ctx;
Yann Collet5be2dd22015-11-11 13:43:58 +0100718 return ZSTD_decompressDCtx(&ctx, dst, maxDstSize, src, srcSize);
719}
720
721
722/* ******************************
723* Streaming Decompression API
724********************************/
725
Yann Collet5be2dd22015-11-11 13:43:58 +0100726size_t ZSTD_nextSrcSizeToDecompress(ZSTD_DCtx* dctx)
727{
728 return dctx->expected;
729}
730
731size_t ZSTD_decompressContinue(ZSTD_DCtx* ctx, void* dst, size_t maxDstSize, const void* src, size_t srcSize)
732{
733 /* Sanity check */
734 if (srcSize != ctx->expected) return ERROR(srcSize_wrong);
735 if (dst != ctx->previousDstEnd) /* not contiguous */
Yann Collet5b78d2f2015-11-12 15:36:05 +0100736 {
Yann Colletb2549842015-11-18 11:29:32 +0100737 ctx->dictEnd = ctx->previousDstEnd;
738 if ((dst > ctx->base) && (dst < ctx->previousDstEnd)) /* rolling buffer : new segment right into tracked memory */
739 ctx->base = (char*)dst + maxDstSize; /* temporary affectation, for vBase calculation */
740 ctx->vBase = (char*)dst - ((char*)(ctx->dictEnd) - (char*)(ctx->base));
741 ctx->base = dst;
742 }
Yann Collet5be2dd22015-11-11 13:43:58 +0100743
744 /* Decompress : frame header */
745 if (ctx->phase == 0)
746 {
747 /* Check frame magic header */
748 U32 magicNumber = MEM_readLE32(src);
749 if (magicNumber != ZSTD_magicNumber) return ERROR(prefix_unknown);
750 ctx->phase = 1;
751 ctx->expected = ZSTD_blockHeaderSize;
752 return 0;
753 }
754
755 /* Decompress : block header */
756 if (ctx->phase == 1)
757 {
758 blockProperties_t bp;
759 size_t blockSize = ZSTD_getcBlockSize(src, ZSTD_blockHeaderSize, &bp);
760 if (ZSTD_isError(blockSize)) return blockSize;
761 if (bp.blockType == bt_end)
762 {
763 ctx->expected = 0;
764 ctx->phase = 0;
765 }
766 else
767 {
768 ctx->expected = blockSize;
769 ctx->bType = bp.blockType;
770 ctx->phase = 2;
771 }
772
Yann Collet0f366c62015-11-12 16:19:30 +0100773 ctx->previousDstEnd = dst;
Yann Collet5be2dd22015-11-11 13:43:58 +0100774 return 0;
775 }
776
777 /* Decompress : block content */
778 {
779 size_t rSize;
780 switch(ctx->bType)
781 {
782 case bt_compressed:
783 rSize = ZSTD_decompressBlock(ctx, dst, maxDstSize, src, srcSize);
784 break;
785 case bt_raw :
Yann Collet0f366c62015-11-12 16:19:30 +0100786 rSize = ZSTD_copyRawBlock(dst, maxDstSize, src, srcSize);
Yann Collet5be2dd22015-11-11 13:43:58 +0100787 break;
788 case bt_rle :
789 return ERROR(GENERIC); /* not yet handled */
790 break;
791 case bt_end : /* should never happen (filtered at phase 1) */
792 rSize = 0;
793 break;
794 default:
795 return ERROR(GENERIC);
796 }
797 ctx->phase = 1;
798 ctx->expected = ZSTD_blockHeaderSize;
Yann Collet5b78d2f2015-11-12 15:36:05 +0100799 ctx->previousDstEnd = (char*)dst + rSize;
Yann Collet5be2dd22015-11-11 13:43:58 +0100800 return rSize;
801 }
802
803}
804
805