blob: 6e595228f0f85ba45a2b2aeaf97e1d40243f7dea [file] [log] [blame]
Yann Collet5be2dd22015-11-11 13:43:58 +01001/*
2 zstd - standard compression library
Yann Colletae7aa062016-02-03 02:46:46 +01003 Copyright (C) 2014-2016, Yann Collet.
Yann Collet5be2dd22015-11-11 13:43:58 +01004
5 BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
6
7 Redistribution and use in source and binary forms, with or without
8 modification, are permitted provided that the following conditions are
9 met:
10 * Redistributions of source code must retain the above copyright
11 notice, this list of conditions and the following disclaimer.
12 * Redistributions in binary form must reproduce the above
13 copyright notice, this list of conditions and the following disclaimer
14 in the documentation and/or other materials provided with the
15 distribution.
16 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28 You can contact the author at :
29 - zstd source repository : https://github.com/Cyan4973/zstd
Yann Collet5be2dd22015-11-11 13:43:58 +010030*/
31
32/* ***************************************************************
33* Tuning parameters
34*****************************************************************/
35/*!
Yann Collet5be2dd22015-11-11 13:43:58 +010036 * HEAPMODE :
Yann Collet3a3b72f2016-01-11 12:56:11 +010037 * Select how default decompression function ZSTD_decompress() will allocate memory,
38 * in memory stack (0), or in memory heap (1, requires malloc())
Yann Collet5be2dd22015-11-11 13:43:58 +010039 */
40#ifndef ZSTD_HEAPMODE
41# define ZSTD_HEAPMODE 1
Yann Collet3a3b72f2016-01-11 12:56:11 +010042#endif
Yann Collet5be2dd22015-11-11 13:43:58 +010043
44/*!
45* LEGACY_SUPPORT :
Yann Colletae7aa062016-02-03 02:46:46 +010046* if set to 1, ZSTD_decompress() can decode older formats (v0.1+)
Yann Collet5be2dd22015-11-11 13:43:58 +010047*/
48#ifndef ZSTD_LEGACY_SUPPORT
Yann Colletfba6aed2016-01-18 12:03:27 +010049# define ZSTD_LEGACY_SUPPORT 0
Yann Collet5be2dd22015-11-11 13:43:58 +010050#endif
51
52
Yann Colletfb810d62016-01-28 00:18:06 +010053/*-*******************************************************
Yann Collet953ce722016-02-04 15:28:14 +010054* Dependencies
Yann Collet5be2dd22015-11-11 13:43:58 +010055*********************************************************/
56#include <stdlib.h> /* calloc */
57#include <string.h> /* memcpy, memmove */
Yann Collet953ce722016-02-04 15:28:14 +010058#include <stdio.h> /* debug only : printf */
Yann Collet5be2dd22015-11-11 13:43:58 +010059#include "mem.h" /* low level memory routines */
Yann Collet5be2dd22015-11-11 13:43:58 +010060#include "zstd_internal.h"
61#include "fse_static.h"
Yann Colletafe07092016-01-25 04:10:46 +010062#include "huff0_static.h"
Yann Collet5be2dd22015-11-11 13:43:58 +010063
64#if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT==1)
65# include "zstd_legacy.h"
66#endif
67
Yann Colletfb810d62016-01-28 00:18:06 +010068
69/*-*******************************************************
Yann Collet5be2dd22015-11-11 13:43:58 +010070* Compiler specifics
71*********************************************************/
Yann Collet5be2dd22015-11-11 13:43:58 +010072#ifdef _MSC_VER /* Visual Studio */
73# define FORCE_INLINE static __forceinline
74# include <intrin.h> /* For Visual 2005 */
75# pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */
76# pragma warning(disable : 4324) /* disable: C4324: padded structure */
77#else
78# define GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__)
79# ifdef __GNUC__
80# define FORCE_INLINE static inline __attribute__((always_inline))
81# else
82# define FORCE_INLINE static inline
83# endif
84#endif
85
86
Yann Colletfb810d62016-01-28 00:18:06 +010087/*-*************************************
Yann Collet14983e72015-11-11 21:38:21 +010088* Local types
89***************************************/
90typedef struct
91{
92 blockType_t blockType;
93 U32 origSize;
94} blockProperties_t;
Yann Collet5be2dd22015-11-11 13:43:58 +010095
96
Yann Collet03ea59b2016-03-12 01:25:40 +010097/*_*******************************************************
Yann Collet5be2dd22015-11-11 13:43:58 +010098* Memory operations
99**********************************************************/
100static void ZSTD_copy4(void* dst, const void* src) { memcpy(dst, src, 4); }
101
102
Yann Collet03ea59b2016-03-12 01:25:40 +0100103/*-*************************************
Yann Collet5be2dd22015-11-11 13:43:58 +0100104* Error Management
105***************************************/
Yann Collet14983e72015-11-11 21:38:21 +0100106unsigned ZSTD_versionNumber (void) { return ZSTD_VERSION_NUMBER; }
107
Yann Collet953ce722016-02-04 15:28:14 +0100108/*! ZSTD_isError() :
Yann Collet5be2dd22015-11-11 13:43:58 +0100109* tells if a return value is an error code */
110unsigned ZSTD_isError(size_t code) { return ERR_isError(code); }
111
Yann Collet953ce722016-02-04 15:28:14 +0100112/*! ZSTD_getError() :
Yann Collet72bff502016-02-03 12:06:24 +0100113* convert a `size_t` function result into a proper ZSTD_errorCode enum */
Yann Collet982ffc72016-02-05 02:33:10 +0100114ZSTD_ErrorCode ZSTD_getError(size_t code) { return ERR_getError(code); }
Yann Collet72bff502016-02-03 12:06:24 +0100115
Yann Collet953ce722016-02-04 15:28:14 +0100116/*! ZSTD_getErrorName() :
Yann Collet5be2dd22015-11-11 13:43:58 +0100117* provides error code string (useful for debugging) */
118const char* ZSTD_getErrorName(size_t code) { return ERR_getErrorName(code); }
119
120
Yann Collet03ea59b2016-03-12 01:25:40 +0100121/*-*************************************************************
Yann Collet5b78d2f2015-11-12 15:36:05 +0100122* Context management
Yann Collet5be2dd22015-11-11 13:43:58 +0100123***************************************************************/
Yann Collete4fdad52015-11-25 21:09:17 +0100124typedef enum { ZSTDds_getFrameHeaderSize, ZSTDds_decodeFrameHeader,
Yann Collet88fcd292015-11-25 14:42:45 +0100125 ZSTDds_decodeBlockHeader, ZSTDds_decompressBlock } ZSTD_dStage;
126
Yann Collet5be2dd22015-11-11 13:43:58 +0100127struct ZSTD_DCtx_s
128{
Yann Colletfb810d62016-01-28 00:18:06 +0100129 FSE_DTable LLTable[FSE_DTABLE_SIZE_U32(LLFSELog)];
130 FSE_DTable OffTable[FSE_DTABLE_SIZE_U32(OffFSELog)];
131 FSE_DTable MLTable[FSE_DTABLE_SIZE_U32(MLFSELog)];
132 unsigned hufTableX4[HUF_DTABLE_SIZE(HufLog)];
Yann Collet417890c2015-12-04 17:16:37 +0100133 const void* previousDstEnd;
134 const void* base;
135 const void* vBase;
136 const void* dictEnd;
Yann Collet5be2dd22015-11-11 13:43:58 +0100137 size_t expected;
Yann Collet88fcd292015-11-25 14:42:45 +0100138 size_t headerSize;
Yann Collet0e491c02016-03-11 21:58:04 +0100139 ZSTD_frameParams fParams;
Yann Colletfb810d62016-01-28 00:18:06 +0100140 blockType_t bType; /* used in ZSTD_decompressContinue(), to transfer blockType between header decoding and block decoding stages */
Yann Collet88fcd292015-11-25 14:42:45 +0100141 ZSTD_dStage stage;
Yann Colletfb810d62016-01-28 00:18:06 +0100142 U32 flagStaticTables;
Yann Collet5be2dd22015-11-11 13:43:58 +0100143 const BYTE* litPtr;
144 size_t litBufSize;
145 size_t litSize;
Yann Colletb923f652016-01-26 03:14:20 +0100146 BYTE litBuffer[BLOCKSIZE + WILDCOPY_OVERLENGTH];
Yann Collet0e491c02016-03-11 21:58:04 +0100147 BYTE headerBuffer[ZSTD_FRAMEHEADERSIZE_MAX];
Yann Collet417890c2015-12-04 17:16:37 +0100148}; /* typedef'd to ZSTD_DCtx within "zstd_static.h" */
Yann Collet5be2dd22015-11-11 13:43:58 +0100149
Yann Colletfb810d62016-01-28 00:18:06 +0100150size_t sizeofDCtx (void) { return sizeof(ZSTD_DCtx); }
151
Yann Collet7b51a292016-01-26 15:58:49 +0100152size_t ZSTD_decompressBegin(ZSTD_DCtx* dctx)
Yann Collet5b78d2f2015-11-12 15:36:05 +0100153{
Yann Collet88fcd292015-11-25 14:42:45 +0100154 dctx->expected = ZSTD_frameHeaderSize_min;
155 dctx->stage = ZSTDds_getFrameHeaderSize;
Yann Collet5b78d2f2015-11-12 15:36:05 +0100156 dctx->previousDstEnd = NULL;
157 dctx->base = NULL;
158 dctx->vBase = NULL;
159 dctx->dictEnd = NULL;
Yann Colletb923f652016-01-26 03:14:20 +0100160 dctx->hufTableX4[0] = HufLog;
Yann Colletfb810d62016-01-28 00:18:06 +0100161 dctx->flagStaticTables = 0;
Yann Collet0e491c02016-03-11 21:58:04 +0100162 dctx->fParams.mml = MINMATCH; /* overwritten by frame but forces ZSTD_btopt to MINMATCH in block mode */
inikepa4dde252016-03-01 14:14:35 +0100163 ZSTD_LOG_BLOCK("%p: ZSTD_decompressBegin searchLength=%d\n", dctx->base, dctx->params.searchLength);
Yann Collet5b78d2f2015-11-12 15:36:05 +0100164 return 0;
165}
166
167ZSTD_DCtx* ZSTD_createDCtx(void)
168{
169 ZSTD_DCtx* dctx = (ZSTD_DCtx*)malloc(sizeof(ZSTD_DCtx));
170 if (dctx==NULL) return NULL;
Yann Collet7b51a292016-01-26 15:58:49 +0100171 ZSTD_decompressBegin(dctx);
Yann Collet5b78d2f2015-11-12 15:36:05 +0100172 return dctx;
173}
174
175size_t ZSTD_freeDCtx(ZSTD_DCtx* dctx)
176{
177 free(dctx);
Yann Collet982ffc72016-02-05 02:33:10 +0100178 return 0; /* reserved as a potential error code in the future */
Yann Collet5b78d2f2015-11-12 15:36:05 +0100179}
180
Yann Collet7b51a292016-01-26 15:58:49 +0100181void ZSTD_copyDCtx(ZSTD_DCtx* dstDCtx, const ZSTD_DCtx* srcDCtx)
182{
183 memcpy(dstDCtx, srcDCtx,
184 sizeof(ZSTD_DCtx) - (BLOCKSIZE+WILDCOPY_OVERLENGTH + ZSTD_frameHeaderSize_max)); /* no need to copy workspace */
185}
186
Yann Collet5b78d2f2015-11-12 15:36:05 +0100187
Yann Collet03ea59b2016-03-12 01:25:40 +0100188/*-*************************************************************
Yann Collet5b78d2f2015-11-12 15:36:05 +0100189* Decompression section
190***************************************************************/
Yann Collet59d1f792016-01-23 19:28:41 +0100191
192/* Frame format description
193 Frame Header - [ Block Header - Block ] - Frame End
194 1) Frame Header
Yann Collet03ea59b2016-03-12 01:25:40 +0100195 - 4 bytes - Magic Number : ZSTD_MAGICNUMBER (defined within zstd_static.h)
196 - 1 byte - Frame Descriptor
Yann Collet59d1f792016-01-23 19:28:41 +0100197 2) Block Header
198 - 3 bytes, starting with a 2-bits descriptor
199 Uncompressed, Compressed, Frame End, unused
200 3) Block
201 See Block Format Description
202 4) Frame End
203 - 3 bytes, compatible with Block Header
204*/
205
Yann Collet03ea59b2016-03-12 01:25:40 +0100206
207/* Frame descriptor
208
209 1 byte, using :
210 bit 0-3 : windowLog - ZSTD_WINDOWLOG_ABSOLUTEMIN (see zstd_internal.h)
211 bit 4 : minmatch 4(0) or 3(1)
212 bit 5 : reserved (must be zero)
213 bit 6-7 : Frame content size : unknown, 1 byte, 2 bytes, 8 bytes
Yann Colletfb797352016-03-13 11:08:40 +0100214
215 Optional : content size (0, 1, 2 or 8 bytes)
216 0 : unknown
217 1 : 0-255 bytes
218 2 : 256 - 65535+256
219 8 : up to 16 exa
Yann Collet03ea59b2016-03-12 01:25:40 +0100220*/
221
222
223/* Compressed Block, format description
Yann Colletfb810d62016-01-28 00:18:06 +0100224
225 Block = Literal Section - Sequences Section
226 Prerequisite : size of (compressed) block, maximum size of regenerated data
227
Yann Collet59d1f792016-01-23 19:28:41 +0100228 1) Literal Section
Yann Colletfb810d62016-01-28 00:18:06 +0100229
230 1.1) Header : 1-5 bytes
231 flags: 2 bits
Yann Collet59d1f792016-01-23 19:28:41 +0100232 00 compressed by Huff0
Yann Colletfb810d62016-01-28 00:18:06 +0100233 01 unused
234 10 is Raw (uncompressed)
235 11 is Rle
236 Note : using 01 => Huff0 with precomputed table ?
Yann Collet59d1f792016-01-23 19:28:41 +0100237 Note : delta map ? => compressed ?
Yann Colletfb810d62016-01-28 00:18:06 +0100238
239 1.1.1) Huff0-compressed literal block : 3-5 bytes
240 srcSize < 1 KB => 3 bytes (2-2-10-10) => single stream
241 srcSize < 1 KB => 3 bytes (2-2-10-10)
242 srcSize < 16KB => 4 bytes (2-2-14-14)
243 else => 5 bytes (2-2-18-18)
244 big endian convention
245
246 1.1.2) Raw (uncompressed) literal block header : 1-3 bytes
247 size : 5 bits: (IS_RAW<<6) + (0<<4) + size
248 12 bits: (IS_RAW<<6) + (2<<4) + (size>>8)
249 size&255
250 20 bits: (IS_RAW<<6) + (3<<4) + (size>>16)
251 size>>8&255
252 size&255
253
254 1.1.3) Rle (repeated single byte) literal block header : 1-3 bytes
255 size : 5 bits: (IS_RLE<<6) + (0<<4) + size
256 12 bits: (IS_RLE<<6) + (2<<4) + (size>>8)
257 size&255
258 20 bits: (IS_RLE<<6) + (3<<4) + (size>>16)
259 size>>8&255
260 size&255
261
262 1.1.4) Huff0-compressed literal block, using precomputed CTables : 3-5 bytes
263 srcSize < 1 KB => 3 bytes (2-2-10-10) => single stream
264 srcSize < 1 KB => 3 bytes (2-2-10-10)
265 srcSize < 16KB => 4 bytes (2-2-14-14)
266 else => 5 bytes (2-2-18-18)
267 big endian convention
268
269 1- CTable available (stored into workspace ?)
270 2- Small input (fast heuristic ? Full comparison ? depend on clevel ?)
271
272
273 1.2) Literal block content
Yann Collet59d1f792016-01-23 19:28:41 +0100274
275 1.2.1) Huff0 block, using sizes from header
276 See Huff0 format
277
Yann Colletfb810d62016-01-28 00:18:06 +0100278 1.2.2) Huff0 block, using prepared table
Yann Collet59d1f792016-01-23 19:28:41 +0100279
Yann Colletfb810d62016-01-28 00:18:06 +0100280 1.2.3) Raw content
281
282 1.2.4) single byte
283
Yann Collet59d1f792016-01-23 19:28:41 +0100284
285 2) Sequences section
286 TO DO
287*/
288
Yann Collet03ea59b2016-03-12 01:25:40 +0100289static const size_t ZSTD_fcs_fieldSize[4] = { 0, 1, 2, 8 };
Yann Collet59d1f792016-01-23 19:28:41 +0100290
Yann Collet03ea59b2016-03-12 01:25:40 +0100291/** ZSTD_frameHeaderSize() :
292* srcSize must be >= ZSTD_frameHeaderSize_min.
293* @return : size of the Frame Header */
294static size_t ZSTD_frameHeaderSize(const void* src, size_t srcSize)
Yann Collet88fcd292015-11-25 14:42:45 +0100295{
Yann Collet03ea59b2016-03-12 01:25:40 +0100296 U32 fcsId;
297 if (srcSize < ZSTD_frameHeaderSize_min) return ERROR(srcSize_wrong);
298 fcsId = (((const BYTE*)src)[4]) >> 6;
299 return ZSTD_frameHeaderSize_min + ZSTD_fcs_fieldSize[fcsId];
Yann Collet88fcd292015-11-25 14:42:45 +0100300}
301
Yann Collet88fcd292015-11-25 14:42:45 +0100302
Yann Collet03ea59b2016-03-12 01:25:40 +0100303/** ZSTD_getFrameParams() :
304* decode Frame Header, or provide expected `srcSize`.
305* @return : 0, `fparamsPtr` is correctly filled,
306* >0, not enough srcSize, provide expected `srcSize`,
307* or an error code, which can be tested using ZSTD_isError() */
Yann Collet0e491c02016-03-11 21:58:04 +0100308size_t ZSTD_getFrameParams(ZSTD_frameParams* fparamsPtr, const void* src, size_t srcSize)
Yann Collet88fcd292015-11-25 14:42:45 +0100309{
Yann Collet03ea59b2016-03-12 01:25:40 +0100310 U32 magicNumber, fcsId;
311 const BYTE* ip = (const BYTE*)src;
312 BYTE frameDesc;
313
314 if (srcSize < ZSTD_frameHeaderSize_min) return ZSTD_frameHeaderSize_min;
Yann Collet88fcd292015-11-25 14:42:45 +0100315 magicNumber = MEM_readLE32(src);
316 if (magicNumber != ZSTD_MAGICNUMBER) return ERROR(prefix_unknown);
Yann Collet03ea59b2016-03-12 01:25:40 +0100317
318 { size_t fhsize = ZSTD_frameHeaderSize(src, srcSize);
319 if (srcSize < fhsize) return fhsize; }
320
Yann Collet0e491c02016-03-11 21:58:04 +0100321 memset(fparamsPtr, 0, sizeof(*fparamsPtr));
Yann Collet03ea59b2016-03-12 01:25:40 +0100322 frameDesc = ip[4];
323 fparamsPtr->windowLog = (frameDesc & 0xF) + ZSTD_WINDOWLOG_ABSOLUTEMIN;
324 fparamsPtr->mml = (frameDesc & 0x10) ? MINMATCH-1 : MINMATCH;
325 if ((frameDesc & 0x20) != 0) return ERROR(frameParameter_unsupported); /* reserved 1 bit */
326 fcsId = frameDesc >> 6;
327 switch(fcsId)
328 {
329 default: /* impossible */
330 case 0 : fparamsPtr->frameContentSize = 0; break;
331 case 1 : fparamsPtr->frameContentSize = ip[5]; break;
332 case 2 : fparamsPtr->frameContentSize = MEM_readLE16(ip+5); break;
333 case 3 : fparamsPtr->frameContentSize = MEM_readLE64(ip+5); break;
334 }
Yann Collet88fcd292015-11-25 14:42:45 +0100335 return 0;
336}
337
Yann Collet03ea59b2016-03-12 01:25:40 +0100338
339/** ZSTD_decodeFrameHeader() :
340* decode Frame Header.
Yann Collet953ce722016-02-04 15:28:14 +0100341* srcSize must be the size provided by ZSTD_decodeFrameHeader_Part1().
Yann Collet26415d32015-11-26 12:43:28 +0100342* @return : 0, or an error code, which can be tested using ZSTD_isError() */
Yann Collet03ea59b2016-03-12 01:25:40 +0100343static size_t ZSTD_decodeFrameHeader(ZSTD_DCtx* zc, const void* src, size_t srcSize)
Yann Collet26415d32015-11-26 12:43:28 +0100344{
Yann Collet03ea59b2016-03-12 01:25:40 +0100345 size_t result = ZSTD_getFrameParams(&(zc->fParams), src, srcSize);
Yann Collet0e491c02016-03-11 21:58:04 +0100346 if ((MEM_32bits()) && (zc->fParams.windowLog > 25)) return ERROR(frameParameter_unsupportedBy32bits);
Yann Collet00fd7a22015-11-28 16:03:22 +0100347 return result;
Yann Collet26415d32015-11-26 12:43:28 +0100348}
349
Yann Collet5be2dd22015-11-11 13:43:58 +0100350
351size_t ZSTD_getcBlockSize(const void* src, size_t srcSize, blockProperties_t* bpPtr)
352{
353 const BYTE* const in = (const BYTE* const)src;
354 BYTE headerFlags;
355 U32 cSize;
356
Yann Collet61e16ce2016-01-31 02:04:15 +0100357 if (srcSize < 3)
358 return ERROR(srcSize_wrong);
Yann Collet5be2dd22015-11-11 13:43:58 +0100359
360 headerFlags = *in;
361 cSize = in[2] + (in[1]<<8) + ((in[0] & 7)<<16);
362
363 bpPtr->blockType = (blockType_t)(headerFlags >> 6);
364 bpPtr->origSize = (bpPtr->blockType == bt_rle) ? cSize : 0;
365
366 if (bpPtr->blockType == bt_end) return 0;
367 if (bpPtr->blockType == bt_rle) return 1;
368 return cSize;
369}
370
Yann Collet59d1f792016-01-23 19:28:41 +0100371
Yann Collet0f366c62015-11-12 16:19:30 +0100372static size_t ZSTD_copyRawBlock(void* dst, size_t maxDstSize, const void* src, size_t srcSize)
Yann Collet5be2dd22015-11-11 13:43:58 +0100373{
374 if (srcSize > maxDstSize) return ERROR(dstSize_tooSmall);
375 memcpy(dst, src, srcSize);
376 return srcSize;
377}
378
379
Yann Collet953ce722016-02-04 15:28:14 +0100380/*! ZSTD_decodeLiteralsBlock() :
Yann Collet14983e72015-11-11 21:38:21 +0100381 @return : nb of bytes read from src (< srcSize ) */
Yann Collet5b78d2f2015-11-12 15:36:05 +0100382size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx,
Yann Collet5be2dd22015-11-11 13:43:58 +0100383 const void* src, size_t srcSize) /* note : srcSize < BLOCKSIZE */
384{
Yann Collet5be2dd22015-11-11 13:43:58 +0100385 const BYTE* const istart = (const BYTE*) src;
386
387 /* any compressed block with literals segment must be at least this size */
388 if (srcSize < MIN_CBLOCK_SIZE) return ERROR(corruption_detected);
389
Yann Collet59d1f792016-01-23 19:28:41 +0100390 switch(istart[0]>> 6)
Yann Collet5be2dd22015-11-11 13:43:58 +0100391 {
Yann Collet59d1f792016-01-23 19:28:41 +0100392 case IS_HUF:
Yann Collet5be2dd22015-11-11 13:43:58 +0100393 {
Yann Colletafe07092016-01-25 04:10:46 +0100394 size_t litSize, litCSize, singleStream=0;
Yann Collet59d1f792016-01-23 19:28:41 +0100395 U32 lhSize = ((istart[0]) >> 4) & 3;
396 switch(lhSize)
397 {
398 case 0: case 1: default: /* note : default is impossible, since lhSize into [0..3] */
399 /* 2 - 2 - 10 - 10 */
400 lhSize=3;
Yann Colletafe07092016-01-25 04:10:46 +0100401 singleStream = istart[0] & 16;
Yann Collet59d1f792016-01-23 19:28:41 +0100402 litSize = ((istart[0] & 15) << 6) + (istart[1] >> 2);
403 litCSize = ((istart[1] & 3) << 8) + istart[2];
404 break;
405 case 2:
406 /* 2 - 2 - 14 - 14 */
407 lhSize=4;
408 litSize = ((istart[0] & 15) << 10) + (istart[1] << 2) + (istart[2] >> 6);
409 litCSize = ((istart[2] & 63) << 8) + istart[3];
410 break;
411 case 3:
412 /* 2 - 2 - 18 - 18 */
413 lhSize=5;
414 litSize = ((istart[0] & 15) << 14) + (istart[1] << 6) + (istart[2] >> 2);
415 litCSize = ((istart[2] & 3) << 16) + (istart[3] << 8) + istart[4];
416 break;
417 }
Yann Colletfb810d62016-01-28 00:18:06 +0100418 if (litSize > BLOCKSIZE) return ERROR(corruption_detected);
Yann Collet59d1f792016-01-23 19:28:41 +0100419
Yann Colletafe07092016-01-25 04:10:46 +0100420 if (HUF_isError(singleStream ?
421 HUF_decompress1X2(dctx->litBuffer, litSize, istart+lhSize, litCSize) :
422 HUF_decompress (dctx->litBuffer, litSize, istart+lhSize, litCSize) ))
Yann Collet59d1f792016-01-23 19:28:41 +0100423 return ERROR(corruption_detected);
424
Yann Collet5be2dd22015-11-11 13:43:58 +0100425 dctx->litPtr = dctx->litBuffer;
426 dctx->litBufSize = BLOCKSIZE+8;
427 dctx->litSize = litSize;
Yann Collet59d1f792016-01-23 19:28:41 +0100428 return litCSize + lhSize;
Yann Collet5be2dd22015-11-11 13:43:58 +0100429 }
Yann Colletb923f652016-01-26 03:14:20 +0100430 case IS_PCH:
431 {
432 size_t errorCode;
433 size_t litSize, litCSize;
434 U32 lhSize = ((istart[0]) >> 4) & 3;
435 if (lhSize != 1) /* only case supported for now : small litSize, single stream */
436 return ERROR(corruption_detected);
Yann Colletfb810d62016-01-28 00:18:06 +0100437 if (!dctx->flagStaticTables)
Yann Collet7b51a292016-01-26 15:58:49 +0100438 return ERROR(dictionary_corrupted);
Yann Colletb923f652016-01-26 03:14:20 +0100439
440 /* 2 - 2 - 10 - 10 */
441 lhSize=3;
442 litSize = ((istart[0] & 15) << 6) + (istart[1] >> 2);
443 litCSize = ((istart[1] & 3) << 8) + istart[2];
444
445 errorCode = HUF_decompress1X4_usingDTable(dctx->litBuffer, litSize, istart+lhSize, litCSize, dctx->hufTableX4);
446 if (HUF_isError(errorCode)) return ERROR(corruption_detected);
447
448 dctx->litPtr = dctx->litBuffer;
449 dctx->litBufSize = BLOCKSIZE+WILDCOPY_OVERLENGTH;
450 dctx->litSize = litSize;
451 return litCSize + lhSize;
452 }
Yann Collet5be2dd22015-11-11 13:43:58 +0100453 case IS_RAW:
454 {
Yann Collet59d1f792016-01-23 19:28:41 +0100455 size_t litSize;
456 U32 lhSize = ((istart[0]) >> 4) & 3;
457 switch(lhSize)
Yann Collet5be2dd22015-11-11 13:43:58 +0100458 {
Yann Collet59d1f792016-01-23 19:28:41 +0100459 case 0: case 1: default: /* note : default is impossible, since lhSize into [0..3] */
460 lhSize=1;
461 litSize = istart[0] & 31;
462 break;
463 case 2:
464 litSize = ((istart[0] & 15) << 8) + istart[1];
465 break;
466 case 3:
467 litSize = ((istart[0] & 15) << 16) + (istart[1] << 8) + istart[2];
468 break;
469 }
470
Yann Collet61e16ce2016-01-31 02:04:15 +0100471 if (lhSize+litSize+WILDCOPY_OVERLENGTH > srcSize) { /* risk reading beyond src buffer with wildcopy */
Yann Colletb010b3b2016-02-03 12:39:34 +0100472 if (litSize+lhSize > srcSize) return ERROR(corruption_detected);
Yann Collet59d1f792016-01-23 19:28:41 +0100473 memcpy(dctx->litBuffer, istart+lhSize, litSize);
Yann Collet5be2dd22015-11-11 13:43:58 +0100474 dctx->litPtr = dctx->litBuffer;
475 dctx->litBufSize = BLOCKSIZE+8;
476 dctx->litSize = litSize;
Yann Colletbc4c8aa2016-01-25 17:26:01 +0100477 return lhSize+litSize;
Yann Collet5be2dd22015-11-11 13:43:58 +0100478 }
479 /* direct reference into compressed stream */
Yann Collet59d1f792016-01-23 19:28:41 +0100480 dctx->litPtr = istart+lhSize;
481 dctx->litBufSize = srcSize-lhSize;
Yann Collet5be2dd22015-11-11 13:43:58 +0100482 dctx->litSize = litSize;
Yann Collet59d1f792016-01-23 19:28:41 +0100483 return lhSize+litSize;
484 }
Yann Collet5be2dd22015-11-11 13:43:58 +0100485 case IS_RLE:
486 {
Yann Collet59d1f792016-01-23 19:28:41 +0100487 size_t litSize;
488 U32 lhSize = ((istart[0]) >> 4) & 3;
489 switch(lhSize)
490 {
491 case 0: case 1: default: /* note : default is impossible, since lhSize into [0..3] */
492 lhSize = 1;
493 litSize = istart[0] & 31;
494 break;
495 case 2:
496 litSize = ((istart[0] & 15) << 8) + istart[1];
497 break;
498 case 3:
499 litSize = ((istart[0] & 15) << 16) + (istart[1] << 8) + istart[2];
500 break;
501 }
Yann Collet5be2dd22015-11-11 13:43:58 +0100502 if (litSize > BLOCKSIZE) return ERROR(corruption_detected);
Yann Collet59d1f792016-01-23 19:28:41 +0100503 memset(dctx->litBuffer, istart[lhSize], litSize);
Yann Collet5be2dd22015-11-11 13:43:58 +0100504 dctx->litPtr = dctx->litBuffer;
Yann Colletb923f652016-01-26 03:14:20 +0100505 dctx->litBufSize = BLOCKSIZE+WILDCOPY_OVERLENGTH;
Yann Collet5be2dd22015-11-11 13:43:58 +0100506 dctx->litSize = litSize;
Yann Collet59d1f792016-01-23 19:28:41 +0100507 return lhSize+1;
Yann Collet5be2dd22015-11-11 13:43:58 +0100508 }
Yann Colletb923f652016-01-26 03:14:20 +0100509 default:
510 return ERROR(corruption_detected); /* impossible */
Yann Collet5be2dd22015-11-11 13:43:58 +0100511 }
512}
513
514
515size_t ZSTD_decodeSeqHeaders(int* nbSeq, const BYTE** dumpsPtr, size_t* dumpsLengthPtr,
516 FSE_DTable* DTableLL, FSE_DTable* DTableML, FSE_DTable* DTableOffb,
517 const void* src, size_t srcSize)
518{
519 const BYTE* const istart = (const BYTE* const)src;
520 const BYTE* ip = istart;
521 const BYTE* const iend = istart + srcSize;
522 U32 LLtype, Offtype, MLtype;
523 U32 LLlog, Offlog, MLlog;
524 size_t dumpsLength;
525
526 /* check */
Yann Collet61e16ce2016-01-31 02:04:15 +0100527 if (srcSize < MIN_SEQUENCES_SIZE)
528 return ERROR(srcSize_wrong);
Yann Collet5be2dd22015-11-11 13:43:58 +0100529
530 /* SeqHead */
Yann Collet61e16ce2016-01-31 02:04:15 +0100531 *nbSeq = *ip++;
532 if (*nbSeq==0) return 1;
Yann Colletd409db62016-03-04 14:45:31 +0100533 if (*nbSeq >= 0x7F) {
534 if (*nbSeq == 0xFF)
535 *nbSeq = MEM_readLE16(ip) + LONGNBSEQ, ip+=2;
536 else
537 *nbSeq = ((nbSeq[0]-0x80)<<8) + *ip++;
538 }
Yann Collete93d6ce2016-01-31 00:58:06 +0100539
Yann Colletd409db62016-03-04 14:45:31 +0100540 /* FSE table descriptors */
Yann Collet5be2dd22015-11-11 13:43:58 +0100541 LLtype = *ip >> 6;
542 Offtype = (*ip >> 4) & 3;
543 MLtype = (*ip >> 2) & 3;
Yann Colletfb810d62016-01-28 00:18:06 +0100544 if (*ip & 2) {
Yann Collet5be2dd22015-11-11 13:43:58 +0100545 dumpsLength = ip[2];
546 dumpsLength += ip[1] << 8;
547 ip += 3;
Yann Colletfb810d62016-01-28 00:18:06 +0100548 } else {
Yann Collet5be2dd22015-11-11 13:43:58 +0100549 dumpsLength = ip[1];
550 dumpsLength += (ip[0] & 1) << 8;
551 ip += 2;
552 }
553 *dumpsPtr = ip;
554 ip += dumpsLength;
555 *dumpsLengthPtr = dumpsLength;
556
557 /* check */
558 if (ip > iend-3) return ERROR(srcSize_wrong); /* min : all 3 are "raw", hence no header, but at least xxLog bits per type */
559
560 /* sequences */
561 {
Yann Collet82368cf2015-11-16 19:10:56 +0100562 S16 norm[MaxML+1]; /* assumption : MaxML >= MaxLL >= MaxOff */
Yann Collet5be2dd22015-11-11 13:43:58 +0100563 size_t headerSize;
564
565 /* Build DTables */
566 switch(LLtype)
567 {
568 U32 max;
Yann Colletfb810d62016-01-28 00:18:06 +0100569 case FSE_ENCODING_RLE :
Yann Collet5be2dd22015-11-11 13:43:58 +0100570 LLlog = 0;
Yann Colletfb810d62016-01-28 00:18:06 +0100571 FSE_buildDTable_rle(DTableLL, *ip++);
572 break;
573 case FSE_ENCODING_RAW :
Yann Collet5be2dd22015-11-11 13:43:58 +0100574 LLlog = LLbits;
Yann Colletfb810d62016-01-28 00:18:06 +0100575 FSE_buildDTable_raw(DTableLL, LLbits);
576 break;
577 case FSE_ENCODING_STATIC:
578 break;
579 case FSE_ENCODING_DYNAMIC :
580 default : /* impossible */
Yann Collet5be2dd22015-11-11 13:43:58 +0100581 max = MaxLL;
582 headerSize = FSE_readNCount(norm, &max, &LLlog, ip, iend-ip);
583 if (FSE_isError(headerSize)) return ERROR(GENERIC);
584 if (LLlog > LLFSELog) return ERROR(corruption_detected);
585 ip += headerSize;
586 FSE_buildDTable(DTableLL, norm, max, LLlog);
587 }
588
589 switch(Offtype)
590 {
591 U32 max;
Yann Colletfb810d62016-01-28 00:18:06 +0100592 case FSE_ENCODING_RLE :
Yann Collet5be2dd22015-11-11 13:43:58 +0100593 Offlog = 0;
594 if (ip > iend-2) return ERROR(srcSize_wrong); /* min : "raw", hence no header, but at least xxLog bits */
595 FSE_buildDTable_rle(DTableOffb, *ip++ & MaxOff); /* if *ip > MaxOff, data is corrupted */
596 break;
Yann Colletfb810d62016-01-28 00:18:06 +0100597 case FSE_ENCODING_RAW :
Yann Collet5be2dd22015-11-11 13:43:58 +0100598 Offlog = Offbits;
Yann Colletfb810d62016-01-28 00:18:06 +0100599 FSE_buildDTable_raw(DTableOffb, Offbits);
600 break;
601 case FSE_ENCODING_STATIC:
602 break;
603 case FSE_ENCODING_DYNAMIC :
604 default : /* impossible */
Yann Collet5be2dd22015-11-11 13:43:58 +0100605 max = MaxOff;
606 headerSize = FSE_readNCount(norm, &max, &Offlog, ip, iend-ip);
607 if (FSE_isError(headerSize)) return ERROR(GENERIC);
608 if (Offlog > OffFSELog) return ERROR(corruption_detected);
609 ip += headerSize;
610 FSE_buildDTable(DTableOffb, norm, max, Offlog);
611 }
612
613 switch(MLtype)
614 {
615 U32 max;
Yann Colletfb810d62016-01-28 00:18:06 +0100616 case FSE_ENCODING_RLE :
Yann Collet5be2dd22015-11-11 13:43:58 +0100617 MLlog = 0;
618 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 +0100619 FSE_buildDTable_rle(DTableML, *ip++);
620 break;
621 case FSE_ENCODING_RAW :
Yann Collet5be2dd22015-11-11 13:43:58 +0100622 MLlog = MLbits;
Yann Colletfb810d62016-01-28 00:18:06 +0100623 FSE_buildDTable_raw(DTableML, MLbits);
624 break;
625 case FSE_ENCODING_STATIC:
626 break;
627 case FSE_ENCODING_DYNAMIC :
628 default : /* impossible */
Yann Collet5be2dd22015-11-11 13:43:58 +0100629 max = MaxML;
630 headerSize = FSE_readNCount(norm, &max, &MLlog, ip, iend-ip);
631 if (FSE_isError(headerSize)) return ERROR(GENERIC);
632 if (MLlog > MLFSELog) return ERROR(corruption_detected);
633 ip += headerSize;
634 FSE_buildDTable(DTableML, norm, max, MLlog);
Yann Colletfb810d62016-01-28 00:18:06 +0100635 } }
Yann Collet5be2dd22015-11-11 13:43:58 +0100636
637 return ip-istart;
638}
639
640
641typedef struct {
642 size_t litLength;
Yann Collet5be2dd22015-11-11 13:43:58 +0100643 size_t matchLength;
Yann Collete93d6ce2016-01-31 00:58:06 +0100644 size_t offset;
Yann Collet5be2dd22015-11-11 13:43:58 +0100645} seq_t;
646
647typedef struct {
648 BIT_DStream_t DStream;
649 FSE_DState_t stateLL;
650 FSE_DState_t stateOffb;
651 FSE_DState_t stateML;
652 size_t prevOffset;
653 const BYTE* dumps;
654 const BYTE* dumpsEnd;
655} seqState_t;
656
inikepe9f30ea2016-02-03 12:53:07 +0100657
658
inikep6b3739c2016-02-22 15:53:42 +0100659static void ZSTD_decodeSequence(seq_t* seq, seqState_t* seqState, const U32 mls)
Yann Collet5be2dd22015-11-11 13:43:58 +0100660{
661 size_t litLength;
662 size_t prevOffset;
663 size_t offset;
664 size_t matchLength;
665 const BYTE* dumps = seqState->dumps;
666 const BYTE* const de = seqState->dumpsEnd;
667
668 /* Literal length */
Yann Collete93d6ce2016-01-31 00:58:06 +0100669 litLength = FSE_peakSymbol(&(seqState->stateLL));
Yann Collete4fdad52015-11-25 21:09:17 +0100670 prevOffset = litLength ? seq->offset : seqState->prevOffset;
Yann Colletfb810d62016-01-28 00:18:06 +0100671 if (litLength == MaxLL) {
Yann Collet5be2dd22015-11-11 13:43:58 +0100672 U32 add = *dumps++;
673 if (add < 255) litLength += add;
Yann Colletfb810d62016-01-28 00:18:06 +0100674 else {
Yann Collet7d8e6bd2016-02-02 17:30:37 +0100675 litLength = MEM_readLE32(dumps) & 0xFFFFFF; /* no risk : dumps is always followed by seq tables > 1 byte */
676 if (litLength&1) litLength>>=1, dumps += 3;
677 else litLength = (U16)(litLength)>>1, dumps += 2;
Yann Collet5be2dd22015-11-11 13:43:58 +0100678 }
679 if (dumps >= de) dumps = de-1; /* late correction, to avoid read overflow (data is now corrupted anyway) */
680 }
681
682 /* Offset */
683 {
684 static const U32 offsetPrefix[MaxOff+1] = {
Yann Collet95cd0c22016-03-08 18:24:21 +0100685 1 /*fake*/, 1, 2, 4, 8, 0x10, 0x20, 0x40, 0x80, 0x100,
686 0x200, 0x400, 0x800, 0x1000, 0x2000, 0x4000, 0x8000, 0x10000, 0x20000, 0x40000,
687 0x80000, 0x100000, 0x200000, 0x400000, 0x800000, 0x1000000, 0x2000000, 0x4000000, /*fake*/ 1, 1, 1, 1 };
Yann Collete93d6ce2016-01-31 00:58:06 +0100688 U32 offsetCode = FSE_peakSymbol(&(seqState->stateOffb)); /* <= maxOff, by table construction */
689 U32 nbBits = offsetCode - 1;
Yann Collet5be2dd22015-11-11 13:43:58 +0100690 if (offsetCode==0) nbBits = 0; /* cmove */
691 offset = offsetPrefix[offsetCode] + BIT_readBits(&(seqState->DStream), nbBits);
692 if (MEM_32bits()) BIT_reloadDStream(&(seqState->DStream));
Yann Collete93d6ce2016-01-31 00:58:06 +0100693 if (offsetCode==0) offset = prevOffset; /* repcode, cmove */
Yann Collet55aa7f92015-11-20 12:04:52 +0100694 if (offsetCode | !litLength) seqState->prevOffset = seq->offset; /* cmove */
Yann Collete93d6ce2016-01-31 00:58:06 +0100695 FSE_decodeSymbol(&(seqState->stateOffb), &(seqState->DStream)); /* update */
Yann Collet5be2dd22015-11-11 13:43:58 +0100696 }
697
Yann Collete93d6ce2016-01-31 00:58:06 +0100698 /* Literal length update */
699 FSE_decodeSymbol(&(seqState->stateLL), &(seqState->DStream)); /* update */
700 if (MEM_32bits()) BIT_reloadDStream(&(seqState->DStream));
701
Yann Collet5be2dd22015-11-11 13:43:58 +0100702 /* MatchLength */
703 matchLength = FSE_decodeSymbol(&(seqState->stateML), &(seqState->DStream));
Yann Colletfb810d62016-01-28 00:18:06 +0100704 if (matchLength == MaxML) {
Yann Collet5be2dd22015-11-11 13:43:58 +0100705 U32 add = *dumps++;
706 if (add < 255) matchLength += add;
Yann Colletfb810d62016-01-28 00:18:06 +0100707 else {
Yann Collet5be2dd22015-11-11 13:43:58 +0100708 matchLength = MEM_readLE32(dumps) & 0xFFFFFF; /* no pb : dumps is always followed by seq tables > 1 byte */
Yann Collet7d8e6bd2016-02-02 17:30:37 +0100709 if (matchLength&1) matchLength>>=1, dumps += 3;
710 else matchLength = (U16)(matchLength)>>1, dumps += 2;
Yann Collet5be2dd22015-11-11 13:43:58 +0100711 }
712 if (dumps >= de) dumps = de-1; /* late correction, to avoid read overflow (data is now corrupted anyway) */
713 }
inikep6b3739c2016-02-22 15:53:42 +0100714 matchLength += mls;
Yann Collet5be2dd22015-11-11 13:43:58 +0100715
716 /* save result */
717 seq->litLength = litLength;
718 seq->offset = offset;
719 seq->matchLength = matchLength;
720 seqState->dumps = dumps;
Yann Colletfb810d62016-01-28 00:18:06 +0100721
Yann Collet7d8e6bd2016-02-02 17:30:37 +0100722#if 0 /* debug */
Yann Colletfb810d62016-01-28 00:18:06 +0100723 {
724 static U64 totalDecoded = 0;
725 printf("pos %6u : %3u literals & match %3u bytes at distance %6u \n",
726 (U32)(totalDecoded), (U32)litLength, (U32)matchLength, (U32)offset);
727 totalDecoded += litLength + matchLength;
728 }
729#endif
Yann Collet5be2dd22015-11-11 13:43:58 +0100730}
731
732
Yann Collet5b78d2f2015-11-12 15:36:05 +0100733FORCE_INLINE size_t ZSTD_execSequence(BYTE* op,
Yann Colletb3a2af92015-11-19 17:13:19 +0100734 BYTE* const oend, seq_t sequence,
Yann Collet5be2dd22015-11-11 13:43:58 +0100735 const BYTE** litPtr, const BYTE* const litLimit_8,
Yann Collet417890c2015-12-04 17:16:37 +0100736 const BYTE* const base, const BYTE* const vBase, const BYTE* const dictEnd)
Yann Collet5be2dd22015-11-11 13:43:58 +0100737{
Yann Colletb3a2af92015-11-19 17:13:19 +0100738 static const int dec32table[] = { 0, 1, 2, 1, 4, 4, 4, 4 }; /* added */
739 static const int dec64table[] = { 8, 8, 8, 7, 8, 9,10,11 }; /* substracted */
Yann Collet5be2dd22015-11-11 13:43:58 +0100740 BYTE* const oLitEnd = op + sequence.litLength;
Yann Colletb3a2af92015-11-19 17:13:19 +0100741 const size_t sequenceLength = sequence.litLength + sequence.matchLength;
742 BYTE* const oMatchEnd = op + sequenceLength; /* risk : address space overflow (32-bits) */
Yann Collet5be2dd22015-11-11 13:43:58 +0100743 BYTE* const oend_8 = oend-8;
744 const BYTE* const litEnd = *litPtr + sequence.litLength;
Yann Colletb3a2af92015-11-19 17:13:19 +0100745 const BYTE* match = oLitEnd - sequence.offset;
Yann Collet5be2dd22015-11-11 13:43:58 +0100746
747 /* check */
748 if (oLitEnd > oend_8) return ERROR(dstSize_tooSmall); /* last match must start at a minimum distance of 8 from oend */
749 if (oMatchEnd > oend) return ERROR(dstSize_tooSmall); /* overwrite beyond dst buffer */
750 if (litEnd > litLimit_8) return ERROR(corruption_detected); /* risk read beyond lit buffer */
751
752 /* copy Literals */
753 ZSTD_wildcopy(op, *litPtr, sequence.litLength); /* note : oLitEnd <= oend-8 : no risk of overwrite beyond oend */
754 op = oLitEnd;
755 *litPtr = litEnd; /* update for next sequence */
756
757 /* copy Match */
Yann Collet7b51a292016-01-26 15:58:49 +0100758 if (sequence.offset > (size_t)(oLitEnd - base)) {
Yann Collet44287a32015-11-30 23:13:56 +0100759 /* offset beyond prefix */
Yann Collet9f5ab1a2015-12-11 00:27:41 +0100760 if (sequence.offset > (size_t)(oLitEnd - vBase))
761 return ERROR(corruption_detected);
Yann Collet44287a32015-11-30 23:13:56 +0100762 match = dictEnd - (base-match);
Yann Collet7b51a292016-01-26 15:58:49 +0100763 if (match + sequence.matchLength <= dictEnd) {
Yann Collet4bfe4152015-12-06 13:18:37 +0100764 memmove(oLitEnd, match, sequence.matchLength);
Yann Collet44287a32015-11-30 23:13:56 +0100765 return sequenceLength;
766 }
767 /* span extDict & currentPrefixSegment */
768 {
769 size_t length1 = dictEnd - match;
Yann Collet4bfe4152015-12-06 13:18:37 +0100770 memmove(oLitEnd, match, length1);
Yann Collet44287a32015-11-30 23:13:56 +0100771 op = oLitEnd + length1;
772 sequence.matchLength -= length1;
773 match = base;
Yann Colletfb810d62016-01-28 00:18:06 +0100774 } }
Yann Collet0f366c62015-11-12 16:19:30 +0100775
Yann Collet44287a32015-11-30 23:13:56 +0100776 /* match within prefix */
Yann Collet7b51a292016-01-26 15:58:49 +0100777 if (sequence.offset < 8) {
Yann Collet44287a32015-11-30 23:13:56 +0100778 /* close range match, overlap */
779 const int sub2 = dec64table[sequence.offset];
780 op[0] = match[0];
781 op[1] = match[1];
782 op[2] = match[2];
783 op[3] = match[3];
784 match += dec32table[sequence.offset];
785 ZSTD_copy4(op+4, match);
786 match -= sub2;
Yann Colletfb810d62016-01-28 00:18:06 +0100787 } else {
Yann Collet44287a32015-11-30 23:13:56 +0100788 ZSTD_copy8(op, match);
789 }
790 op += 8; match += 8;
Yann Collet5be2dd22015-11-11 13:43:58 +0100791
inikepa4dde252016-03-01 14:14:35 +0100792 if (oMatchEnd > oend-(16-3)) { // 3 = MINMATCH
Yann Collet7b51a292016-01-26 15:58:49 +0100793 if (op < oend_8) {
Yann Collet44287a32015-11-30 23:13:56 +0100794 ZSTD_wildcopy(op, match, oend_8 - op);
795 match += oend_8 - op;
796 op = oend_8;
797 }
Yann Colletfb810d62016-01-28 00:18:06 +0100798 while (op < oMatchEnd)
799 *op++ = *match++;
800 } else {
Yann Collet44287a32015-11-30 23:13:56 +0100801 ZSTD_wildcopy(op, match, sequence.matchLength-8); /* works even if matchLength < 8 */
802 }
803 return sequenceLength;
Yann Collet5be2dd22015-11-11 13:43:58 +0100804}
805
Yann Colletb3a2af92015-11-19 17:13:19 +0100806
Yann Collet5be2dd22015-11-11 13:43:58 +0100807static size_t ZSTD_decompressSequences(
Yann Collet5b78d2f2015-11-12 15:36:05 +0100808 ZSTD_DCtx* dctx,
Yann Collet5be2dd22015-11-11 13:43:58 +0100809 void* dst, size_t maxDstSize,
810 const void* seqStart, size_t seqSize)
811{
Yann Collet5be2dd22015-11-11 13:43:58 +0100812 const BYTE* ip = (const BYTE*)seqStart;
813 const BYTE* const iend = ip + seqSize;
814 BYTE* const ostart = (BYTE* const)dst;
815 BYTE* op = ostart;
816 BYTE* const oend = ostart + maxDstSize;
817 size_t errorCode, dumpsLength;
818 const BYTE* litPtr = dctx->litPtr;
819 const BYTE* const litLimit_8 = litPtr + dctx->litBufSize - 8;
820 const BYTE* const litEnd = litPtr + dctx->litSize;
821 int nbSeq;
822 const BYTE* dumps;
823 U32* DTableLL = dctx->LLTable;
824 U32* DTableML = dctx->MLTable;
825 U32* DTableOffb = dctx->OffTable;
Yann Collet417890c2015-12-04 17:16:37 +0100826 const BYTE* const base = (const BYTE*) (dctx->base);
827 const BYTE* const vBase = (const BYTE*) (dctx->vBase);
828 const BYTE* const dictEnd = (const BYTE*) (dctx->dictEnd);
Yann Collet0e491c02016-03-11 21:58:04 +0100829 const U32 mls = dctx->fParams.mml;
Yann Collet5be2dd22015-11-11 13:43:58 +0100830
831 /* Build Decoding Tables */
832 errorCode = ZSTD_decodeSeqHeaders(&nbSeq, &dumps, &dumpsLength,
833 DTableLL, DTableML, DTableOffb,
Yann Colletfb810d62016-01-28 00:18:06 +0100834 ip, seqSize);
Yann Collet5be2dd22015-11-11 13:43:58 +0100835 if (ZSTD_isError(errorCode)) return errorCode;
836 ip += errorCode;
837
838 /* Regen sequences */
Yann Collete93d6ce2016-01-31 00:58:06 +0100839 if (nbSeq) {
Yann Collet5be2dd22015-11-11 13:43:58 +0100840 seq_t sequence;
841 seqState_t seqState;
842
843 memset(&sequence, 0, sizeof(sequence));
Yann Collet61e16ce2016-01-31 02:04:15 +0100844 sequence.offset = REPCODE_STARTVALUE;
Yann Collet5be2dd22015-11-11 13:43:58 +0100845 seqState.dumps = dumps;
846 seqState.dumpsEnd = dumps + dumpsLength;
Yann Collet61e16ce2016-01-31 02:04:15 +0100847 seqState.prevOffset = REPCODE_STARTVALUE;
Yann Collet5be2dd22015-11-11 13:43:58 +0100848 errorCode = BIT_initDStream(&(seqState.DStream), ip, iend-ip);
849 if (ERR_isError(errorCode)) return ERROR(corruption_detected);
850 FSE_initDState(&(seqState.stateLL), &(seqState.DStream), DTableLL);
851 FSE_initDState(&(seqState.stateOffb), &(seqState.DStream), DTableOffb);
852 FSE_initDState(&(seqState.stateML), &(seqState.DStream), DTableML);
853
Yann Collet7b51a292016-01-26 15:58:49 +0100854 for ( ; (BIT_reloadDStream(&(seqState.DStream)) <= BIT_DStream_completed) && nbSeq ; ) {
Yann Colletb3a2af92015-11-19 17:13:19 +0100855 size_t oneSeqSize;
856 nbSeq--;
inikep6b3739c2016-02-22 15:53:42 +0100857 ZSTD_decodeSequence(&sequence, &seqState, mls);
Yann Colletb3a2af92015-11-19 17:13:19 +0100858 oneSeqSize = ZSTD_execSequence(op, oend, sequence, &litPtr, litLimit_8, base, vBase, dictEnd);
Yann Collet370b08e2016-03-08 00:03:59 +0100859 if (ZSTD_isError(oneSeqSize))
860 return oneSeqSize;
Yann Collet5be2dd22015-11-11 13:43:58 +0100861 op += oneSeqSize;
862 }
863
864 /* check if reached exact end */
Yann Collet35f7de52016-01-31 02:51:03 +0100865 if (nbSeq) return ERROR(corruption_detected);
Yann Collete93d6ce2016-01-31 00:58:06 +0100866 }
Yann Collet5be2dd22015-11-11 13:43:58 +0100867
Yann Collete93d6ce2016-01-31 00:58:06 +0100868 /* last literal segment */
869 {
870 size_t lastLLSize = litEnd - litPtr;
871 if (litPtr > litEnd) return ERROR(corruption_detected); /* too many literals already used */
872 if (op+lastLLSize > oend) return ERROR(dstSize_tooSmall);
873 memcpy(op, litPtr, lastLLSize);
874 op += lastLLSize;
875 }
Yann Collet5be2dd22015-11-11 13:43:58 +0100876
877 return op-ostart;
878}
879
880
Yann Colletb0125102016-01-09 02:00:10 +0100881static void ZSTD_checkContinuity(ZSTD_DCtx* dctx, const void* dst)
882{
Yann Collet7b51a292016-01-26 15:58:49 +0100883 if (dst != dctx->previousDstEnd) { /* not contiguous */
Yann Colletb0125102016-01-09 02:00:10 +0100884 dctx->dictEnd = dctx->previousDstEnd;
885 dctx->vBase = (const char*)dst - ((const char*)(dctx->previousDstEnd) - (const char*)(dctx->base));
886 dctx->base = dst;
887 dctx->previousDstEnd = dst;
888 }
889}
890
891
892static size_t ZSTD_decompressBlock_internal(ZSTD_DCtx* dctx,
Yann Colletb010b3b2016-02-03 12:39:34 +0100893 void* dst, size_t dstCapacity,
Yann Collet5be2dd22015-11-11 13:43:58 +0100894 const void* src, size_t srcSize)
Yann Colletb010b3b2016-02-03 12:39:34 +0100895{ /* blockType == blockCompressed */
Yann Collet5be2dd22015-11-11 13:43:58 +0100896 const BYTE* ip = (const BYTE*)src;
Yann Colletb010b3b2016-02-03 12:39:34 +0100897 size_t litCSize;
898
899 if (srcSize >= BLOCKSIZE) return ERROR(srcSize_wrong);
Yann Collet5be2dd22015-11-11 13:43:58 +0100900
inikepa4dde252016-03-01 14:14:35 +0100901 ZSTD_LOG_BLOCK("%p: ZSTD_decompressBlock_internal searchLength=%d\n", dctx->base, dctx->params.searchLength);
902
Yann Collet5be2dd22015-11-11 13:43:58 +0100903 /* Decode literals sub-block */
Yann Colletb010b3b2016-02-03 12:39:34 +0100904 litCSize = ZSTD_decodeLiteralsBlock(dctx, src, srcSize);
Yann Collet5be2dd22015-11-11 13:43:58 +0100905 if (ZSTD_isError(litCSize)) return litCSize;
906 ip += litCSize;
907 srcSize -= litCSize;
908
Yann Colletb010b3b2016-02-03 12:39:34 +0100909 return ZSTD_decompressSequences(dctx, dst, dstCapacity, ip, srcSize);
Yann Collet5be2dd22015-11-11 13:43:58 +0100910}
911
912
Yann Colletb0125102016-01-09 02:00:10 +0100913size_t ZSTD_decompressBlock(ZSTD_DCtx* dctx,
Yann Colletb010b3b2016-02-03 12:39:34 +0100914 void* dst, size_t dstCapacity,
Yann Colletb0125102016-01-09 02:00:10 +0100915 const void* src, size_t srcSize)
916{
917 ZSTD_checkContinuity(dctx, dst);
Yann Colletb010b3b2016-02-03 12:39:34 +0100918 return ZSTD_decompressBlock_internal(dctx, dst, dstCapacity, src, srcSize);
Yann Colletb0125102016-01-09 02:00:10 +0100919}
920
921
Yann Collet0e491c02016-03-11 21:58:04 +0100922/*! ZSTD_decompress_continueDCtx() :
923* `dctx` must have been properly initialized */
924static size_t ZSTD_decompressFrame(ZSTD_DCtx* dctx,
Yann Collet31683c02015-12-18 01:26:48 +0100925 void* dst, size_t maxDstSize,
Yann Collet7b51a292016-01-26 15:58:49 +0100926 const void* src, size_t srcSize)
Yann Collet5be2dd22015-11-11 13:43:58 +0100927{
928 const BYTE* ip = (const BYTE*)src;
929 const BYTE* iend = ip + srcSize;
930 BYTE* const ostart = (BYTE* const)dst;
931 BYTE* op = ostart;
932 BYTE* const oend = ostart + maxDstSize;
933 size_t remainingSize = srcSize;
Yann Collet5be2dd22015-11-11 13:43:58 +0100934 blockProperties_t blockProperties;
935
936 /* Frame Header */
Yann Collet88fcd292015-11-25 14:42:45 +0100937 {
Yann Collet03ea59b2016-03-12 01:25:40 +0100938 size_t frameHeaderSize, errorCode;
Yann Collet88fcd292015-11-25 14:42:45 +0100939 if (srcSize < ZSTD_frameHeaderSize_min+ZSTD_blockHeaderSize) return ERROR(srcSize_wrong);
Yann Collet5be2dd22015-11-11 13:43:58 +0100940#if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT==1)
Yann Collet88fcd292015-11-25 14:42:45 +0100941 {
942 const U32 magicNumber = MEM_readLE32(src);
943 if (ZSTD_isLegacy(magicNumber))
944 return ZSTD_decompressLegacy(dst, maxDstSize, src, srcSize, magicNumber);
945 }
Yann Collet5be2dd22015-11-11 13:43:58 +0100946#endif
Yann Collet03ea59b2016-03-12 01:25:40 +0100947 frameHeaderSize = ZSTD_frameHeaderSize(src, ZSTD_frameHeaderSize_min);
Yann Collet88fcd292015-11-25 14:42:45 +0100948 if (ZSTD_isError(frameHeaderSize)) return frameHeaderSize;
949 if (srcSize < frameHeaderSize+ZSTD_blockHeaderSize) return ERROR(srcSize_wrong);
Yann Collet03ea59b2016-03-12 01:25:40 +0100950 errorCode = ZSTD_decodeFrameHeader(dctx, src, frameHeaderSize);
951 if (ZSTD_isError(errorCode)) return errorCode;
Yann Collet88fcd292015-11-25 14:42:45 +0100952 ip += frameHeaderSize; remainingSize -= frameHeaderSize;
Yann Collet88fcd292015-11-25 14:42:45 +0100953 }
Yann Collet5be2dd22015-11-11 13:43:58 +0100954
955 /* Loop on each block */
956 while (1)
957 {
958 size_t decodedSize=0;
959 size_t cBlockSize = ZSTD_getcBlockSize(ip, iend-ip, &blockProperties);
960 if (ZSTD_isError(cBlockSize)) return cBlockSize;
961
962 ip += ZSTD_blockHeaderSize;
963 remainingSize -= ZSTD_blockHeaderSize;
964 if (cBlockSize > remainingSize) return ERROR(srcSize_wrong);
965
966 switch(blockProperties.blockType)
967 {
968 case bt_compressed:
Yann Collet37422192016-01-25 16:54:05 +0100969 decodedSize = ZSTD_decompressBlock_internal(dctx, op, oend-op, ip, cBlockSize);
Yann Collet5be2dd22015-11-11 13:43:58 +0100970 break;
971 case bt_raw :
Yann Collet0f366c62015-11-12 16:19:30 +0100972 decodedSize = ZSTD_copyRawBlock(op, oend-op, ip, cBlockSize);
Yann Collet5be2dd22015-11-11 13:43:58 +0100973 break;
974 case bt_rle :
975 return ERROR(GENERIC); /* not yet supported */
976 break;
977 case bt_end :
978 /* end of frame */
979 if (remainingSize) return ERROR(srcSize_wrong);
980 break;
981 default:
982 return ERROR(GENERIC); /* impossible */
983 }
984 if (cBlockSize == 0) break; /* bt_end */
985
986 if (ZSTD_isError(decodedSize)) return decodedSize;
987 op += decodedSize;
988 ip += cBlockSize;
989 remainingSize -= cBlockSize;
990 }
991
992 return op-ostart;
993}
994
Yann Collet31683c02015-12-18 01:26:48 +0100995
Yann Collet7b51a292016-01-26 15:58:49 +0100996size_t ZSTD_decompress_usingPreparedDCtx(ZSTD_DCtx* dctx, const ZSTD_DCtx* refDCtx,
997 void* dst, size_t maxDstSize,
998 const void* src, size_t srcSize)
999{
1000 ZSTD_copyDCtx(dctx, refDCtx);
1001 ZSTD_checkContinuity(dctx, dst);
Yann Collet0e491c02016-03-11 21:58:04 +01001002 return ZSTD_decompressFrame(dctx, dst, maxDstSize, src, srcSize);
Yann Collet7b51a292016-01-26 15:58:49 +01001003}
1004
1005
1006size_t ZSTD_decompress_usingDict(ZSTD_DCtx* dctx,
1007 void* dst, size_t maxDstSize,
1008 const void* src, size_t srcSize,
1009 const void* dict, size_t dictSize)
1010{
1011 ZSTD_decompressBegin_usingDict(dctx, dict, dictSize);
inikepa4dde252016-03-01 14:14:35 +01001012 ZSTD_LOG_BLOCK("%p: ZSTD_decompressBegin_usingDict searchLength=%d\n", dctx->base, dctx->params.searchLength);
Yann Collet7b51a292016-01-26 15:58:49 +01001013 ZSTD_checkContinuity(dctx, dst);
Yann Collet0e491c02016-03-11 21:58:04 +01001014 return ZSTD_decompressFrame(dctx, dst, maxDstSize, src, srcSize);
Yann Collet7b51a292016-01-26 15:58:49 +01001015}
1016
1017
Yann Collet31683c02015-12-18 01:26:48 +01001018size_t ZSTD_decompressDCtx(ZSTD_DCtx* dctx, void* dst, size_t maxDstSize, const void* src, size_t srcSize)
1019{
1020 return ZSTD_decompress_usingDict(dctx, dst, maxDstSize, src, srcSize, NULL, 0);
1021}
1022
Yann Collet0e491c02016-03-11 21:58:04 +01001023
Yann Collet5be2dd22015-11-11 13:43:58 +01001024size_t ZSTD_decompress(void* dst, size_t maxDstSize, const void* src, size_t srcSize)
1025{
Yann Collet3a3b72f2016-01-11 12:56:11 +01001026#if defined(ZSTD_HEAPMODE) && (ZSTD_HEAPMODE==1)
1027 size_t regenSize;
1028 ZSTD_DCtx* dctx = ZSTD_createDCtx();
1029 if (dctx==NULL) return ERROR(memory_allocation);
1030 regenSize = ZSTD_decompressDCtx(dctx, dst, maxDstSize, src, srcSize);
1031 ZSTD_freeDCtx(dctx);
1032 return regenSize;
1033#else
Yann Collet31683c02015-12-18 01:26:48 +01001034 ZSTD_DCtx dctx;
1035 return ZSTD_decompressDCtx(&dctx, dst, maxDstSize, src, srcSize);
Yann Colleta768a302016-01-21 16:04:35 +01001036#endif
Yann Collet5be2dd22015-11-11 13:43:58 +01001037}
1038
1039
1040/* ******************************
1041* Streaming Decompression API
1042********************************/
Yann Collet5be2dd22015-11-11 13:43:58 +01001043size_t ZSTD_nextSrcSizeToDecompress(ZSTD_DCtx* dctx)
1044{
1045 return dctx->expected;
1046}
1047
Yann Collet37422192016-01-25 16:54:05 +01001048size_t ZSTD_decompressContinue(ZSTD_DCtx* dctx, void* dst, size_t maxDstSize, const void* src, size_t srcSize)
Yann Collet5be2dd22015-11-11 13:43:58 +01001049{
1050 /* Sanity check */
Yann Collet37422192016-01-25 16:54:05 +01001051 if (srcSize != dctx->expected) return ERROR(srcSize_wrong);
1052 ZSTD_checkContinuity(dctx, dst);
Yann Collet5be2dd22015-11-11 13:43:58 +01001053
Yann Collet88fcd292015-11-25 14:42:45 +01001054 /* Decompress : frame header; part 1 */
Yann Collet37422192016-01-25 16:54:05 +01001055 switch (dctx->stage)
Yann Collet5be2dd22015-11-11 13:43:58 +01001056 {
Yann Collet88fcd292015-11-25 14:42:45 +01001057 case ZSTDds_getFrameHeaderSize :
Yann Collet5be2dd22015-11-11 13:43:58 +01001058 {
Yann Collet88fcd292015-11-25 14:42:45 +01001059 /* get frame header size */
1060 if (srcSize != ZSTD_frameHeaderSize_min) return ERROR(srcSize_wrong); /* impossible */
Yann Collet03ea59b2016-03-12 01:25:40 +01001061 dctx->headerSize = ZSTD_frameHeaderSize(src, ZSTD_frameHeaderSize_min);
Yann Collet37422192016-01-25 16:54:05 +01001062 if (ZSTD_isError(dctx->headerSize)) return dctx->headerSize;
1063 memcpy(dctx->headerBuffer, src, ZSTD_frameHeaderSize_min);
Yann Collet7b51a292016-01-26 15:58:49 +01001064 if (dctx->headerSize > ZSTD_frameHeaderSize_min) {
Yann Collet37422192016-01-25 16:54:05 +01001065 dctx->expected = dctx->headerSize - ZSTD_frameHeaderSize_min;
1066 dctx->stage = ZSTDds_decodeFrameHeader;
Yann Collet88fcd292015-11-25 14:42:45 +01001067 return 0;
1068 }
Yann Collet37422192016-01-25 16:54:05 +01001069 dctx->expected = 0; /* not necessary to copy more */
Yann Collet5be2dd22015-11-11 13:43:58 +01001070 }
Yann Collet88fcd292015-11-25 14:42:45 +01001071 case ZSTDds_decodeFrameHeader:
Yann Collet5be2dd22015-11-11 13:43:58 +01001072 {
Yann Collet88fcd292015-11-25 14:42:45 +01001073 /* get frame header */
1074 size_t result;
Yann Collet37422192016-01-25 16:54:05 +01001075 memcpy(dctx->headerBuffer + ZSTD_frameHeaderSize_min, src, dctx->expected);
Yann Collet03ea59b2016-03-12 01:25:40 +01001076 result = ZSTD_decodeFrameHeader(dctx, dctx->headerBuffer, dctx->headerSize);
Yann Collet88fcd292015-11-25 14:42:45 +01001077 if (ZSTD_isError(result)) return result;
Yann Collet37422192016-01-25 16:54:05 +01001078 dctx->expected = ZSTD_blockHeaderSize;
1079 dctx->stage = ZSTDds_decodeBlockHeader;
Yann Collet88fcd292015-11-25 14:42:45 +01001080 return 0;
Yann Collet5be2dd22015-11-11 13:43:58 +01001081 }
Yann Collet88fcd292015-11-25 14:42:45 +01001082 case ZSTDds_decodeBlockHeader:
Yann Collet5be2dd22015-11-11 13:43:58 +01001083 {
Yann Collet88fcd292015-11-25 14:42:45 +01001084 /* Decode block header */
1085 blockProperties_t bp;
1086 size_t blockSize = ZSTD_getcBlockSize(src, ZSTD_blockHeaderSize, &bp);
1087 if (ZSTD_isError(blockSize)) return blockSize;
Yann Collet7b51a292016-01-26 15:58:49 +01001088 if (bp.blockType == bt_end) {
Yann Collet37422192016-01-25 16:54:05 +01001089 dctx->expected = 0;
1090 dctx->stage = ZSTDds_getFrameHeaderSize;
Yann Collet88fcd292015-11-25 14:42:45 +01001091 }
Yann Collet7b51a292016-01-26 15:58:49 +01001092 else {
Yann Collet37422192016-01-25 16:54:05 +01001093 dctx->expected = blockSize;
1094 dctx->bType = bp.blockType;
1095 dctx->stage = ZSTDds_decompressBlock;
Yann Collet88fcd292015-11-25 14:42:45 +01001096 }
Yann Collet88fcd292015-11-25 14:42:45 +01001097 return 0;
1098 }
Yann Collet417890c2015-12-04 17:16:37 +01001099 case ZSTDds_decompressBlock:
Yann Collet88fcd292015-11-25 14:42:45 +01001100 {
1101 /* Decompress : block content */
1102 size_t rSize;
Yann Collet37422192016-01-25 16:54:05 +01001103 switch(dctx->bType)
Yann Collet88fcd292015-11-25 14:42:45 +01001104 {
1105 case bt_compressed:
Yann Collet37422192016-01-25 16:54:05 +01001106 rSize = ZSTD_decompressBlock_internal(dctx, dst, maxDstSize, src, srcSize);
Yann Collet88fcd292015-11-25 14:42:45 +01001107 break;
1108 case bt_raw :
1109 rSize = ZSTD_copyRawBlock(dst, maxDstSize, src, srcSize);
1110 break;
1111 case bt_rle :
1112 return ERROR(GENERIC); /* not yet handled */
1113 break;
1114 case bt_end : /* should never happen (filtered at phase 1) */
1115 rSize = 0;
1116 break;
1117 default:
Yann Collet7b51a292016-01-26 15:58:49 +01001118 return ERROR(GENERIC); /* impossible */
Yann Collet88fcd292015-11-25 14:42:45 +01001119 }
Yann Collet37422192016-01-25 16:54:05 +01001120 dctx->stage = ZSTDds_decodeBlockHeader;
1121 dctx->expected = ZSTD_blockHeaderSize;
1122 dctx->previousDstEnd = (char*)dst + rSize;
Yann Collet88fcd292015-11-25 14:42:45 +01001123 return rSize;
1124 }
1125 default:
1126 return ERROR(GENERIC); /* impossible */
1127 }
Yann Collet5be2dd22015-11-11 13:43:58 +01001128}
1129
1130
Yann Colletb923f652016-01-26 03:14:20 +01001131static void ZSTD_refDictContent(ZSTD_DCtx* dctx, const void* dict, size_t dictSize)
Yann Collet417890c2015-12-04 17:16:37 +01001132{
Yann Collet37422192016-01-25 16:54:05 +01001133 dctx->dictEnd = dctx->previousDstEnd;
1134 dctx->vBase = (const char*)dict - ((const char*)(dctx->previousDstEnd) - (const char*)(dctx->base));
1135 dctx->base = dict;
1136 dctx->previousDstEnd = (const char*)dict + dictSize;
Yann Collet417890c2015-12-04 17:16:37 +01001137}
Yann Colletb923f652016-01-26 03:14:20 +01001138
Yann Colletb923f652016-01-26 03:14:20 +01001139static size_t ZSTD_loadEntropy(ZSTD_DCtx* dctx, const void* dict, size_t dictSize)
1140{
Yann Colletfb810d62016-01-28 00:18:06 +01001141 size_t hSize, offcodeHeaderSize, matchlengthHeaderSize, errorCode, litlengthHeaderSize;
1142 short offcodeNCount[MaxOff+1];
1143 U32 offcodeMaxValue=MaxOff, offcodeLog=OffFSELog;
1144 short matchlengthNCount[MaxML+1];
1145 unsigned matchlengthMaxValue = MaxML, matchlengthLog = MLFSELog;
1146 short litlengthNCount[MaxLL+1];
1147 unsigned litlengthMaxValue = MaxLL, litlengthLog = LLFSELog;
1148
1149 hSize = HUF_readDTableX4(dctx->hufTableX4, dict, dictSize);
Yann Colletb923f652016-01-26 03:14:20 +01001150 if (HUF_isError(hSize)) return ERROR(dictionary_corrupted);
Yann Colletfb810d62016-01-28 00:18:06 +01001151 dict = (const char*)dict + hSize;
1152 dictSize -= hSize;
1153
1154 offcodeHeaderSize = FSE_readNCount(offcodeNCount, &offcodeMaxValue, &offcodeLog, dict, dictSize);
1155 if (FSE_isError(offcodeHeaderSize)) return ERROR(dictionary_corrupted);
1156 errorCode = FSE_buildDTable(dctx->OffTable, offcodeNCount, offcodeMaxValue, offcodeLog);
1157 if (FSE_isError(errorCode)) return ERROR(dictionary_corrupted);
1158 dict = (const char*)dict + offcodeHeaderSize;
1159 dictSize -= offcodeHeaderSize;
1160
1161 matchlengthHeaderSize = FSE_readNCount(matchlengthNCount, &matchlengthMaxValue, &matchlengthLog, dict, dictSize);
1162 if (FSE_isError(matchlengthHeaderSize)) return ERROR(dictionary_corrupted);
1163 errorCode = FSE_buildDTable(dctx->MLTable, matchlengthNCount, matchlengthMaxValue, matchlengthLog);
1164 if (FSE_isError(errorCode)) return ERROR(dictionary_corrupted);
1165 dict = (const char*)dict + matchlengthHeaderSize;
1166 dictSize -= matchlengthHeaderSize;
1167
1168 litlengthHeaderSize = FSE_readNCount(litlengthNCount, &litlengthMaxValue, &litlengthLog, dict, dictSize);
1169 if (FSE_isError(litlengthHeaderSize)) return ERROR(dictionary_corrupted);
1170 errorCode = FSE_buildDTable(dctx->LLTable, litlengthNCount, litlengthMaxValue, litlengthLog);
1171 if (FSE_isError(errorCode)) return ERROR(dictionary_corrupted);
1172
1173 dctx->flagStaticTables = 1;
1174 return hSize + offcodeHeaderSize + matchlengthHeaderSize + litlengthHeaderSize;
Yann Colletb923f652016-01-26 03:14:20 +01001175}
1176
Yann Collet7b51a292016-01-26 15:58:49 +01001177static size_t ZSTD_decompress_insertDictionary(ZSTD_DCtx* dctx, const void* dict, size_t dictSize)
Yann Colletb923f652016-01-26 03:14:20 +01001178{
1179 size_t eSize;
1180 U32 magic = MEM_readLE32(dict);
1181 if (magic != ZSTD_DICT_MAGIC) {
1182 /* pure content mode */
1183 ZSTD_refDictContent(dctx, dict, dictSize);
1184 return 0;
1185 }
1186 /* load entropy tables */
1187 dict = (const char*)dict + 4;
1188 dictSize -= 4;
1189 eSize = ZSTD_loadEntropy(dctx, dict, dictSize);
1190 if (ZSTD_isError(eSize)) return ERROR(dictionary_corrupted);
1191
1192 /* reference dictionary content */
1193 dict = (const char*)dict + eSize;
1194 dictSize -= eSize;
1195 ZSTD_refDictContent(dctx, dict, dictSize);
1196
1197 return 0;
1198}
1199
Yann Collet7b51a292016-01-26 15:58:49 +01001200
1201size_t ZSTD_decompressBegin_usingDict(ZSTD_DCtx* dctx, const void* dict, size_t dictSize)
1202{
1203 size_t errorCode;
1204 errorCode = ZSTD_decompressBegin(dctx);
1205 if (ZSTD_isError(errorCode)) return errorCode;
1206
1207 if (dict && dictSize) {
1208 errorCode = ZSTD_decompress_insertDictionary(dctx, dict, dictSize);
1209 if (ZSTD_isError(errorCode)) return ERROR(dictionary_corrupted);
1210 }
1211
1212 return 0;
1213}
1214