blob: 5cf9c17c3ff5b1b5bc4e4d150eb3cab582480180 [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 Collet569b81a2016-03-16 15:26:51 +0100146 BYTE litBuffer[ZSTD_BLOCKSIZE_MAX + 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,
Yann Collet569b81a2016-03-16 15:26:51 +0100184 sizeof(ZSTD_DCtx) - (ZSTD_BLOCKSIZE_MAX+WILDCOPY_OVERLENGTH + ZSTD_frameHeaderSize_max)); /* no need to copy workspace */
Yann Collet7b51a292016-01-26 15:58:49 +0100185}
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,
Yann Collet1c2c2bc2016-03-15 01:33:36 +0100306* >0, `srcSize` is too small, result is expected `srcSize`,
Yann Collet03ea59b2016-03-12 01:25:40 +0100307* or an error code, which can be tested using ZSTD_isError() */
Yann Collet09b21ee2016-03-15 12:56:03 +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 const BYTE* ip = (const BYTE*)src;
Yann Collet03ea59b2016-03-12 01:25:40 +0100311
312 if (srcSize < ZSTD_frameHeaderSize_min) return ZSTD_frameHeaderSize_min;
Yann Colletd1b26842016-03-15 01:24:33 +0100313 if (MEM_readLE32(src) != ZSTD_MAGICNUMBER) return ERROR(prefix_unknown);
Yann Collet03ea59b2016-03-12 01:25:40 +0100314
Yann Collet1c2c2bc2016-03-15 01:33:36 +0100315 /* ensure there is enough `srcSize` to fully read/decode frame header */
Yann Colletd1b26842016-03-15 01:24:33 +0100316 { size_t const fhsize = ZSTD_frameHeaderSize(src, srcSize);
Yann Collet03ea59b2016-03-12 01:25:40 +0100317 if (srcSize < fhsize) return fhsize; }
318
Yann Collet0e491c02016-03-11 21:58:04 +0100319 memset(fparamsPtr, 0, sizeof(*fparamsPtr));
Yann Collet1c2c2bc2016-03-15 01:33:36 +0100320 { BYTE const frameDesc = ip[4];
321 fparamsPtr->windowLog = (frameDesc & 0xF) + ZSTD_WINDOWLOG_ABSOLUTEMIN;
322 fparamsPtr->mml = (frameDesc & 0x10) ? MINMATCH-1 : MINMATCH;
323 if ((frameDesc & 0x20) != 0) return ERROR(frameParameter_unsupported); /* reserved 1 bit */
324 switch(frameDesc >> 6) /* fcsId */
325 {
326 default: /* impossible */
327 case 0 : fparamsPtr->frameContentSize = 0; break;
328 case 1 : fparamsPtr->frameContentSize = ip[5]; break;
329 case 2 : fparamsPtr->frameContentSize = MEM_readLE16(ip+5)+256; break;
330 case 3 : fparamsPtr->frameContentSize = MEM_readLE64(ip+5); break;
331 } }
Yann Collet88fcd292015-11-25 14:42:45 +0100332 return 0;
333}
334
Yann Collet03ea59b2016-03-12 01:25:40 +0100335
336/** ZSTD_decodeFrameHeader() :
Yann Collet1c2c2bc2016-03-15 01:33:36 +0100337* `srcSize` must be the size provided by ZSTD_frameHeaderSize().
Yann Collet26415d32015-11-26 12:43:28 +0100338* @return : 0, or an error code, which can be tested using ZSTD_isError() */
Yann Collet03ea59b2016-03-12 01:25:40 +0100339static size_t ZSTD_decodeFrameHeader(ZSTD_DCtx* zc, const void* src, size_t srcSize)
Yann Collet26415d32015-11-26 12:43:28 +0100340{
Yann Collet03ea59b2016-03-12 01:25:40 +0100341 size_t result = ZSTD_getFrameParams(&(zc->fParams), src, srcSize);
Yann Collet0e491c02016-03-11 21:58:04 +0100342 if ((MEM_32bits()) && (zc->fParams.windowLog > 25)) return ERROR(frameParameter_unsupportedBy32bits);
Yann Collet00fd7a22015-11-28 16:03:22 +0100343 return result;
Yann Collet26415d32015-11-26 12:43:28 +0100344}
345
Yann Collet5be2dd22015-11-11 13:43:58 +0100346
347size_t ZSTD_getcBlockSize(const void* src, size_t srcSize, blockProperties_t* bpPtr)
348{
349 const BYTE* const in = (const BYTE* const)src;
350 BYTE headerFlags;
351 U32 cSize;
352
Yann Collet61e16ce2016-01-31 02:04:15 +0100353 if (srcSize < 3)
354 return ERROR(srcSize_wrong);
Yann Collet5be2dd22015-11-11 13:43:58 +0100355
356 headerFlags = *in;
357 cSize = in[2] + (in[1]<<8) + ((in[0] & 7)<<16);
358
359 bpPtr->blockType = (blockType_t)(headerFlags >> 6);
360 bpPtr->origSize = (bpPtr->blockType == bt_rle) ? cSize : 0;
361
362 if (bpPtr->blockType == bt_end) return 0;
363 if (bpPtr->blockType == bt_rle) return 1;
364 return cSize;
365}
366
Yann Collet59d1f792016-01-23 19:28:41 +0100367
Yann Collet0f366c62015-11-12 16:19:30 +0100368static size_t ZSTD_copyRawBlock(void* dst, size_t maxDstSize, const void* src, size_t srcSize)
Yann Collet5be2dd22015-11-11 13:43:58 +0100369{
370 if (srcSize > maxDstSize) return ERROR(dstSize_tooSmall);
371 memcpy(dst, src, srcSize);
372 return srcSize;
373}
374
375
Yann Collet953ce722016-02-04 15:28:14 +0100376/*! ZSTD_decodeLiteralsBlock() :
Yann Collet14983e72015-11-11 21:38:21 +0100377 @return : nb of bytes read from src (< srcSize ) */
Yann Collet5b78d2f2015-11-12 15:36:05 +0100378size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx,
Yann Collet5be2dd22015-11-11 13:43:58 +0100379 const void* src, size_t srcSize) /* note : srcSize < BLOCKSIZE */
380{
Yann Collet5be2dd22015-11-11 13:43:58 +0100381 const BYTE* const istart = (const BYTE*) src;
382
383 /* any compressed block with literals segment must be at least this size */
384 if (srcSize < MIN_CBLOCK_SIZE) return ERROR(corruption_detected);
385
Yann Collet59d1f792016-01-23 19:28:41 +0100386 switch(istart[0]>> 6)
Yann Collet5be2dd22015-11-11 13:43:58 +0100387 {
Yann Collet59d1f792016-01-23 19:28:41 +0100388 case IS_HUF:
Yann Collet5be2dd22015-11-11 13:43:58 +0100389 {
Yann Colletafe07092016-01-25 04:10:46 +0100390 size_t litSize, litCSize, singleStream=0;
Yann Collet59d1f792016-01-23 19:28:41 +0100391 U32 lhSize = ((istart[0]) >> 4) & 3;
392 switch(lhSize)
393 {
394 case 0: case 1: default: /* note : default is impossible, since lhSize into [0..3] */
395 /* 2 - 2 - 10 - 10 */
396 lhSize=3;
Yann Colletafe07092016-01-25 04:10:46 +0100397 singleStream = istart[0] & 16;
Yann Collet59d1f792016-01-23 19:28:41 +0100398 litSize = ((istart[0] & 15) << 6) + (istart[1] >> 2);
399 litCSize = ((istart[1] & 3) << 8) + istart[2];
400 break;
401 case 2:
402 /* 2 - 2 - 14 - 14 */
403 lhSize=4;
404 litSize = ((istart[0] & 15) << 10) + (istart[1] << 2) + (istart[2] >> 6);
405 litCSize = ((istart[2] & 63) << 8) + istart[3];
406 break;
407 case 3:
408 /* 2 - 2 - 18 - 18 */
409 lhSize=5;
410 litSize = ((istart[0] & 15) << 14) + (istart[1] << 6) + (istart[2] >> 2);
411 litCSize = ((istart[2] & 3) << 16) + (istart[3] << 8) + istart[4];
412 break;
413 }
Yann Collet569b81a2016-03-16 15:26:51 +0100414 if (litSize > ZSTD_BLOCKSIZE_MAX) return ERROR(corruption_detected);
Yann Collet59d1f792016-01-23 19:28:41 +0100415
Yann Colletafe07092016-01-25 04:10:46 +0100416 if (HUF_isError(singleStream ?
417 HUF_decompress1X2(dctx->litBuffer, litSize, istart+lhSize, litCSize) :
418 HUF_decompress (dctx->litBuffer, litSize, istart+lhSize, litCSize) ))
Yann Collet59d1f792016-01-23 19:28:41 +0100419 return ERROR(corruption_detected);
420
Yann Collet5be2dd22015-11-11 13:43:58 +0100421 dctx->litPtr = dctx->litBuffer;
Yann Collet569b81a2016-03-16 15:26:51 +0100422 dctx->litBufSize = ZSTD_BLOCKSIZE_MAX+8;
Yann Collet5be2dd22015-11-11 13:43:58 +0100423 dctx->litSize = litSize;
Yann Collet59d1f792016-01-23 19:28:41 +0100424 return litCSize + lhSize;
Yann Collet5be2dd22015-11-11 13:43:58 +0100425 }
Yann Colletb923f652016-01-26 03:14:20 +0100426 case IS_PCH:
427 {
428 size_t errorCode;
429 size_t litSize, litCSize;
430 U32 lhSize = ((istart[0]) >> 4) & 3;
431 if (lhSize != 1) /* only case supported for now : small litSize, single stream */
432 return ERROR(corruption_detected);
Yann Colletfb810d62016-01-28 00:18:06 +0100433 if (!dctx->flagStaticTables)
Yann Collet7b51a292016-01-26 15:58:49 +0100434 return ERROR(dictionary_corrupted);
Yann Colletb923f652016-01-26 03:14:20 +0100435
436 /* 2 - 2 - 10 - 10 */
437 lhSize=3;
438 litSize = ((istart[0] & 15) << 6) + (istart[1] >> 2);
439 litCSize = ((istart[1] & 3) << 8) + istart[2];
440
441 errorCode = HUF_decompress1X4_usingDTable(dctx->litBuffer, litSize, istart+lhSize, litCSize, dctx->hufTableX4);
442 if (HUF_isError(errorCode)) return ERROR(corruption_detected);
443
444 dctx->litPtr = dctx->litBuffer;
Yann Collet569b81a2016-03-16 15:26:51 +0100445 dctx->litBufSize = ZSTD_BLOCKSIZE_MAX+WILDCOPY_OVERLENGTH;
Yann Colletb923f652016-01-26 03:14:20 +0100446 dctx->litSize = litSize;
447 return litCSize + lhSize;
448 }
Yann Collet5be2dd22015-11-11 13:43:58 +0100449 case IS_RAW:
450 {
Yann Collet59d1f792016-01-23 19:28:41 +0100451 size_t litSize;
452 U32 lhSize = ((istart[0]) >> 4) & 3;
453 switch(lhSize)
Yann Collet5be2dd22015-11-11 13:43:58 +0100454 {
Yann Collet59d1f792016-01-23 19:28:41 +0100455 case 0: case 1: default: /* note : default is impossible, since lhSize into [0..3] */
456 lhSize=1;
457 litSize = istart[0] & 31;
458 break;
459 case 2:
460 litSize = ((istart[0] & 15) << 8) + istart[1];
461 break;
462 case 3:
463 litSize = ((istart[0] & 15) << 16) + (istart[1] << 8) + istart[2];
464 break;
465 }
466
Yann Collet61e16ce2016-01-31 02:04:15 +0100467 if (lhSize+litSize+WILDCOPY_OVERLENGTH > srcSize) { /* risk reading beyond src buffer with wildcopy */
Yann Colletb010b3b2016-02-03 12:39:34 +0100468 if (litSize+lhSize > srcSize) return ERROR(corruption_detected);
Yann Collet59d1f792016-01-23 19:28:41 +0100469 memcpy(dctx->litBuffer, istart+lhSize, litSize);
Yann Collet5be2dd22015-11-11 13:43:58 +0100470 dctx->litPtr = dctx->litBuffer;
Yann Collet569b81a2016-03-16 15:26:51 +0100471 dctx->litBufSize = ZSTD_BLOCKSIZE_MAX+8;
Yann Collet5be2dd22015-11-11 13:43:58 +0100472 dctx->litSize = litSize;
Yann Colletbc4c8aa2016-01-25 17:26:01 +0100473 return lhSize+litSize;
Yann Collet5be2dd22015-11-11 13:43:58 +0100474 }
475 /* direct reference into compressed stream */
Yann Collet59d1f792016-01-23 19:28:41 +0100476 dctx->litPtr = istart+lhSize;
477 dctx->litBufSize = srcSize-lhSize;
Yann Collet5be2dd22015-11-11 13:43:58 +0100478 dctx->litSize = litSize;
Yann Collet59d1f792016-01-23 19:28:41 +0100479 return lhSize+litSize;
480 }
Yann Collet5be2dd22015-11-11 13:43:58 +0100481 case IS_RLE:
482 {
Yann Collet59d1f792016-01-23 19:28:41 +0100483 size_t litSize;
484 U32 lhSize = ((istart[0]) >> 4) & 3;
485 switch(lhSize)
486 {
487 case 0: case 1: default: /* note : default is impossible, since lhSize into [0..3] */
488 lhSize = 1;
489 litSize = istart[0] & 31;
490 break;
491 case 2:
492 litSize = ((istart[0] & 15) << 8) + istart[1];
493 break;
494 case 3:
495 litSize = ((istart[0] & 15) << 16) + (istart[1] << 8) + istart[2];
496 break;
497 }
Yann Collet569b81a2016-03-16 15:26:51 +0100498 if (litSize > ZSTD_BLOCKSIZE_MAX) return ERROR(corruption_detected);
Yann Collet59d1f792016-01-23 19:28:41 +0100499 memset(dctx->litBuffer, istart[lhSize], litSize);
Yann Collet5be2dd22015-11-11 13:43:58 +0100500 dctx->litPtr = dctx->litBuffer;
Yann Collet569b81a2016-03-16 15:26:51 +0100501 dctx->litBufSize = ZSTD_BLOCKSIZE_MAX+WILDCOPY_OVERLENGTH;
Yann Collet5be2dd22015-11-11 13:43:58 +0100502 dctx->litSize = litSize;
Yann Collet59d1f792016-01-23 19:28:41 +0100503 return lhSize+1;
Yann Collet5be2dd22015-11-11 13:43:58 +0100504 }
Yann Colletb923f652016-01-26 03:14:20 +0100505 default:
506 return ERROR(corruption_detected); /* impossible */
Yann Collet5be2dd22015-11-11 13:43:58 +0100507 }
508}
509
510
Yann Collet4db09ef2016-03-18 22:23:49 +0100511/*! ZSTD_buildSeqTable() :
512 @return : nb bytes read from src,
513 or an error code if it fails, testable with ZSTD_isError()
514*/
515static size_t ZSTD_buildSeqTable(FSE_DTable* DTable, U32 type, U32 rawBits, U32 maxLog,
516 const void* src, size_t srcSize)
517{
Yann Colletd1d210f2016-03-19 12:12:07 +0100518 U32 max = (1<<rawBits)-1;
Yann Collet4db09ef2016-03-18 22:23:49 +0100519 switch(type)
520 {
521 case FSE_ENCODING_RLE :
522 if (!srcSize) return ERROR(srcSize_wrong);
Yann Colletd1d210f2016-03-19 12:12:07 +0100523 FSE_buildDTable_rle(DTable, (*(const BYTE*)src) & max); /* if *src > max, data is corrupted */
Yann Collet4db09ef2016-03-18 22:23:49 +0100524 return 1;
525 case FSE_ENCODING_RAW :
526 FSE_buildDTable_raw(DTable, rawBits);
527 return 0;
528 case FSE_ENCODING_STATIC:
529 return 0;
530 default : /* impossible */
531 case FSE_ENCODING_DYNAMIC :
Yann Colletd1d210f2016-03-19 12:12:07 +0100532 { U32 tableLog;
Yann Collet4db09ef2016-03-18 22:23:49 +0100533 S16 norm[MaxSeq+1];
534 size_t const headerSize = FSE_readNCount(norm, &max, &tableLog, src, srcSize);
535 if (FSE_isError(headerSize)) return ERROR(GENERIC);
536 if (tableLog > maxLog) return ERROR(corruption_detected);
537 FSE_buildDTable(DTable, norm, max, tableLog);
538 return headerSize;
539 } }
540}
541
542
Yann Collet5be2dd22015-11-11 13:43:58 +0100543size_t ZSTD_decodeSeqHeaders(int* nbSeq, const BYTE** dumpsPtr, size_t* dumpsLengthPtr,
544 FSE_DTable* DTableLL, FSE_DTable* DTableML, FSE_DTable* DTableOffb,
545 const void* src, size_t srcSize)
546{
547 const BYTE* const istart = (const BYTE* const)src;
548 const BYTE* ip = istart;
549 const BYTE* const iend = istart + srcSize;
550 U32 LLtype, Offtype, MLtype;
Yann Collet5be2dd22015-11-11 13:43:58 +0100551
552 /* check */
Yann Collet4db09ef2016-03-18 22:23:49 +0100553 if (srcSize < MIN_SEQUENCES_SIZE) return ERROR(srcSize_wrong);
Yann Collet5be2dd22015-11-11 13:43:58 +0100554
555 /* SeqHead */
Yann Collet61e16ce2016-01-31 02:04:15 +0100556 *nbSeq = *ip++;
557 if (*nbSeq==0) return 1;
Yann Colletd409db62016-03-04 14:45:31 +0100558 if (*nbSeq >= 0x7F) {
559 if (*nbSeq == 0xFF)
560 *nbSeq = MEM_readLE16(ip) + LONGNBSEQ, ip+=2;
561 else
562 *nbSeq = ((nbSeq[0]-0x80)<<8) + *ip++;
563 }
Yann Collete93d6ce2016-01-31 00:58:06 +0100564
Yann Colletd409db62016-03-04 14:45:31 +0100565 /* FSE table descriptors */
Yann Collet5be2dd22015-11-11 13:43:58 +0100566 LLtype = *ip >> 6;
567 Offtype = (*ip >> 4) & 3;
568 MLtype = (*ip >> 2) & 3;
Yann Collet4db09ef2016-03-18 22:23:49 +0100569 { size_t dumpsLength;
570 if (*ip & 2) {
571 dumpsLength = ip[2];
572 dumpsLength += ip[1] << 8;
573 ip += 3;
574 } else {
575 dumpsLength = ip[1];
576 dumpsLength += (ip[0] & 1) << 8;
577 ip += 2;
578 }
579 *dumpsPtr = ip;
580 ip += dumpsLength;
581 *dumpsLengthPtr = dumpsLength;
Yann Collet5be2dd22015-11-11 13:43:58 +0100582 }
Yann Collet5be2dd22015-11-11 13:43:58 +0100583
584 /* check */
585 if (ip > iend-3) return ERROR(srcSize_wrong); /* min : all 3 are "raw", hence no header, but at least xxLog bits per type */
586
Yann Collet39c596c2016-03-18 21:40:56 +0100587 /* Build DTables */
Yann Collet4db09ef2016-03-18 22:23:49 +0100588 { size_t const bhSize = ZSTD_buildSeqTable(DTableLL, LLtype, LLbits, LLFSELog, ip, iend-ip);
589 if (ZSTD_isError(bhSize)) return ERROR(corruption_detected);
590 ip += bhSize;
591 }
592 { size_t const bhSize = ZSTD_buildSeqTable(DTableOffb, Offtype, Offbits, OffFSELog, ip, iend-ip);
593 if (ZSTD_isError(bhSize)) return ERROR(corruption_detected);
594 ip += bhSize;
595 }
596 { size_t const bhSize = ZSTD_buildSeqTable(DTableML, MLtype, MLbits, MLFSELog, ip, iend-ip);
597 if (ZSTD_isError(bhSize)) return ERROR(corruption_detected);
598 ip += bhSize;
599 }
Yann Collet5be2dd22015-11-11 13:43:58 +0100600
601 return ip-istart;
602}
603
604
605typedef struct {
606 size_t litLength;
Yann Collet5be2dd22015-11-11 13:43:58 +0100607 size_t matchLength;
Yann Collete93d6ce2016-01-31 00:58:06 +0100608 size_t offset;
Yann Collet5be2dd22015-11-11 13:43:58 +0100609} seq_t;
610
611typedef struct {
612 BIT_DStream_t DStream;
613 FSE_DState_t stateLL;
614 FSE_DState_t stateOffb;
615 FSE_DState_t stateML;
616 size_t prevOffset;
617 const BYTE* dumps;
618 const BYTE* dumpsEnd;
619} seqState_t;
620
inikepe9f30ea2016-02-03 12:53:07 +0100621
622
inikep6b3739c2016-02-22 15:53:42 +0100623static void ZSTD_decodeSequence(seq_t* seq, seqState_t* seqState, const U32 mls)
Yann Collet5be2dd22015-11-11 13:43:58 +0100624{
Yann Collet5be2dd22015-11-11 13:43:58 +0100625 const BYTE* dumps = seqState->dumps;
626 const BYTE* const de = seqState->dumpsEnd;
Yann Collet3fd164e2016-03-17 12:56:46 +0100627 size_t litLength, offset;
Yann Collet5be2dd22015-11-11 13:43:58 +0100628
629 /* Literal length */
Yann Collete93d6ce2016-01-31 00:58:06 +0100630 litLength = FSE_peakSymbol(&(seqState->stateLL));
Yann Colletfb810d62016-01-28 00:18:06 +0100631 if (litLength == MaxLL) {
Yann Collet3fd164e2016-03-17 12:56:46 +0100632 const U32 add = *dumps++;
Yann Collet5be2dd22015-11-11 13:43:58 +0100633 if (add < 255) litLength += add;
Yann Colletfb810d62016-01-28 00:18:06 +0100634 else {
Yann Collet7d8e6bd2016-02-02 17:30:37 +0100635 litLength = MEM_readLE32(dumps) & 0xFFFFFF; /* no risk : dumps is always followed by seq tables > 1 byte */
636 if (litLength&1) litLength>>=1, dumps += 3;
637 else litLength = (U16)(litLength)>>1, dumps += 2;
Yann Collet5be2dd22015-11-11 13:43:58 +0100638 }
639 if (dumps >= de) dumps = de-1; /* late correction, to avoid read overflow (data is now corrupted anyway) */
640 }
641
642 /* Offset */
Yann Colletd1d210f2016-03-19 12:12:07 +0100643 { static const U32 offsetPrefix[MaxOff+1] = {
644 1 /*fake*/, 1, 2, 4, 8, 0x10, 0x20, 0x40,
645 0x80, 0x100, 0x200, 0x400, 0x800, 0x1000, 0x2000, 0x4000,
646 0x8000, 0x10000, 0x20000, 0x40000, 0x80000, 0x100000, 0x200000, 0x400000,
647 0x800000, 0x1000000, 0x2000000, 0x4000000, /*fake*/ 1, 1, 1, 1 };
648 U32 const offsetCode = FSE_peakSymbol(&(seqState->stateOffb)); /* <= maxOff, by table construction */
649 U32 const nbBits = offsetCode ? offsetCode-1 : 0;
Yann Collet5be2dd22015-11-11 13:43:58 +0100650 offset = offsetPrefix[offsetCode] + BIT_readBits(&(seqState->DStream), nbBits);
651 if (MEM_32bits()) BIT_reloadDStream(&(seqState->DStream));
Yann Colletb40287a2016-03-17 12:11:16 +0100652 if (offsetCode==0) offset = litLength ? seq->offset : seqState->prevOffset;
Yann Collet55aa7f92015-11-20 12:04:52 +0100653 if (offsetCode | !litLength) seqState->prevOffset = seq->offset; /* cmove */
Yann Collete93d6ce2016-01-31 00:58:06 +0100654 FSE_decodeSymbol(&(seqState->stateOffb), &(seqState->DStream)); /* update */
Yann Collet5be2dd22015-11-11 13:43:58 +0100655 }
656
Yann Collete93d6ce2016-01-31 00:58:06 +0100657 /* Literal length update */
658 FSE_decodeSymbol(&(seqState->stateLL), &(seqState->DStream)); /* update */
659 if (MEM_32bits()) BIT_reloadDStream(&(seqState->DStream));
660
Yann Collet5be2dd22015-11-11 13:43:58 +0100661 /* MatchLength */
Yann Collet3fd164e2016-03-17 12:56:46 +0100662 {
663 size_t matchLength = FSE_decodeSymbol(&(seqState->stateML), &(seqState->DStream));
664 if (matchLength == MaxML) {
665 const U32 add = *dumps++;
666 if (add < 255) matchLength += add;
667 else {
668 matchLength = MEM_readLE32(dumps) & 0xFFFFFF; /* no pb : dumps is always followed by seq tables > 1 byte */
669 if (matchLength&1) matchLength>>=1, dumps += 3;
670 else matchLength = (U16)(matchLength)>>1, dumps += 2;
671 }
672 if (dumps >= de) dumps = de-1; /* late correction, to avoid read overflow (data is now corrupted anyway) */
Yann Collet5be2dd22015-11-11 13:43:58 +0100673 }
Yann Collet3fd164e2016-03-17 12:56:46 +0100674 matchLength += mls;
675 seq->matchLength = matchLength;
Yann Collet5be2dd22015-11-11 13:43:58 +0100676 }
Yann Collet5be2dd22015-11-11 13:43:58 +0100677
678 /* save result */
679 seq->litLength = litLength;
680 seq->offset = offset;
Yann Collet5be2dd22015-11-11 13:43:58 +0100681 seqState->dumps = dumps;
Yann Colletfb810d62016-01-28 00:18:06 +0100682
Yann Collet7d8e6bd2016-02-02 17:30:37 +0100683#if 0 /* debug */
Yann Colletfb810d62016-01-28 00:18:06 +0100684 {
685 static U64 totalDecoded = 0;
686 printf("pos %6u : %3u literals & match %3u bytes at distance %6u \n",
687 (U32)(totalDecoded), (U32)litLength, (U32)matchLength, (U32)offset);
688 totalDecoded += litLength + matchLength;
689 }
690#endif
Yann Collet5be2dd22015-11-11 13:43:58 +0100691}
692
693
Yann Collet5b78d2f2015-11-12 15:36:05 +0100694FORCE_INLINE size_t ZSTD_execSequence(BYTE* op,
Yann Colletb3a2af92015-11-19 17:13:19 +0100695 BYTE* const oend, seq_t sequence,
Yann Collet5be2dd22015-11-11 13:43:58 +0100696 const BYTE** litPtr, const BYTE* const litLimit_8,
Yann Collet417890c2015-12-04 17:16:37 +0100697 const BYTE* const base, const BYTE* const vBase, const BYTE* const dictEnd)
Yann Collet5be2dd22015-11-11 13:43:58 +0100698{
Yann Colletb3a2af92015-11-19 17:13:19 +0100699 static const int dec32table[] = { 0, 1, 2, 1, 4, 4, 4, 4 }; /* added */
700 static const int dec64table[] = { 8, 8, 8, 7, 8, 9,10,11 }; /* substracted */
Yann Collet5be2dd22015-11-11 13:43:58 +0100701 BYTE* const oLitEnd = op + sequence.litLength;
Yann Colletb3a2af92015-11-19 17:13:19 +0100702 const size_t sequenceLength = sequence.litLength + sequence.matchLength;
703 BYTE* const oMatchEnd = op + sequenceLength; /* risk : address space overflow (32-bits) */
Yann Collet5be2dd22015-11-11 13:43:58 +0100704 BYTE* const oend_8 = oend-8;
705 const BYTE* const litEnd = *litPtr + sequence.litLength;
Yann Colletb3a2af92015-11-19 17:13:19 +0100706 const BYTE* match = oLitEnd - sequence.offset;
Yann Collet5be2dd22015-11-11 13:43:58 +0100707
708 /* check */
709 if (oLitEnd > oend_8) return ERROR(dstSize_tooSmall); /* last match must start at a minimum distance of 8 from oend */
710 if (oMatchEnd > oend) return ERROR(dstSize_tooSmall); /* overwrite beyond dst buffer */
711 if (litEnd > litLimit_8) return ERROR(corruption_detected); /* risk read beyond lit buffer */
712
713 /* copy Literals */
714 ZSTD_wildcopy(op, *litPtr, sequence.litLength); /* note : oLitEnd <= oend-8 : no risk of overwrite beyond oend */
715 op = oLitEnd;
716 *litPtr = litEnd; /* update for next sequence */
717
718 /* copy Match */
Yann Collet7b51a292016-01-26 15:58:49 +0100719 if (sequence.offset > (size_t)(oLitEnd - base)) {
Yann Collet44287a32015-11-30 23:13:56 +0100720 /* offset beyond prefix */
Yann Collet9f5ab1a2015-12-11 00:27:41 +0100721 if (sequence.offset > (size_t)(oLitEnd - vBase))
722 return ERROR(corruption_detected);
Yann Collet44287a32015-11-30 23:13:56 +0100723 match = dictEnd - (base-match);
Yann Collet7b51a292016-01-26 15:58:49 +0100724 if (match + sequence.matchLength <= dictEnd) {
Yann Collet4bfe4152015-12-06 13:18:37 +0100725 memmove(oLitEnd, match, sequence.matchLength);
Yann Collet44287a32015-11-30 23:13:56 +0100726 return sequenceLength;
727 }
728 /* span extDict & currentPrefixSegment */
Yann Colletd1d210f2016-03-19 12:12:07 +0100729 { size_t const length1 = dictEnd - match;
Yann Collet4bfe4152015-12-06 13:18:37 +0100730 memmove(oLitEnd, match, length1);
Yann Collet44287a32015-11-30 23:13:56 +0100731 op = oLitEnd + length1;
732 sequence.matchLength -= length1;
733 match = base;
Yann Colletfb810d62016-01-28 00:18:06 +0100734 } }
Yann Collet0f366c62015-11-12 16:19:30 +0100735
Yann Collet44287a32015-11-30 23:13:56 +0100736 /* match within prefix */
Yann Collet7b51a292016-01-26 15:58:49 +0100737 if (sequence.offset < 8) {
Yann Collet44287a32015-11-30 23:13:56 +0100738 /* close range match, overlap */
739 const int sub2 = dec64table[sequence.offset];
740 op[0] = match[0];
741 op[1] = match[1];
742 op[2] = match[2];
743 op[3] = match[3];
744 match += dec32table[sequence.offset];
745 ZSTD_copy4(op+4, match);
746 match -= sub2;
Yann Colletfb810d62016-01-28 00:18:06 +0100747 } else {
Yann Collet44287a32015-11-30 23:13:56 +0100748 ZSTD_copy8(op, match);
749 }
750 op += 8; match += 8;
Yann Collet5be2dd22015-11-11 13:43:58 +0100751
inikepa4dde252016-03-01 14:14:35 +0100752 if (oMatchEnd > oend-(16-3)) { // 3 = MINMATCH
Yann Collet7b51a292016-01-26 15:58:49 +0100753 if (op < oend_8) {
Yann Collet44287a32015-11-30 23:13:56 +0100754 ZSTD_wildcopy(op, match, oend_8 - op);
755 match += oend_8 - op;
756 op = oend_8;
757 }
Yann Colletfb810d62016-01-28 00:18:06 +0100758 while (op < oMatchEnd)
759 *op++ = *match++;
760 } else {
Yann Collet44287a32015-11-30 23:13:56 +0100761 ZSTD_wildcopy(op, match, sequence.matchLength-8); /* works even if matchLength < 8 */
762 }
763 return sequenceLength;
Yann Collet5be2dd22015-11-11 13:43:58 +0100764}
765
Yann Colletb3a2af92015-11-19 17:13:19 +0100766
Yann Collet5be2dd22015-11-11 13:43:58 +0100767static size_t ZSTD_decompressSequences(
Yann Collet5b78d2f2015-11-12 15:36:05 +0100768 ZSTD_DCtx* dctx,
Yann Collet5be2dd22015-11-11 13:43:58 +0100769 void* dst, size_t maxDstSize,
770 const void* seqStart, size_t seqSize)
771{
Yann Collet5be2dd22015-11-11 13:43:58 +0100772 const BYTE* ip = (const BYTE*)seqStart;
773 const BYTE* const iend = ip + seqSize;
774 BYTE* const ostart = (BYTE* const)dst;
775 BYTE* op = ostart;
776 BYTE* const oend = ostart + maxDstSize;
777 size_t errorCode, dumpsLength;
778 const BYTE* litPtr = dctx->litPtr;
779 const BYTE* const litLimit_8 = litPtr + dctx->litBufSize - 8;
780 const BYTE* const litEnd = litPtr + dctx->litSize;
781 int nbSeq;
782 const BYTE* dumps;
783 U32* DTableLL = dctx->LLTable;
784 U32* DTableML = dctx->MLTable;
785 U32* DTableOffb = dctx->OffTable;
Yann Collet417890c2015-12-04 17:16:37 +0100786 const BYTE* const base = (const BYTE*) (dctx->base);
787 const BYTE* const vBase = (const BYTE*) (dctx->vBase);
788 const BYTE* const dictEnd = (const BYTE*) (dctx->dictEnd);
Yann Collet0e491c02016-03-11 21:58:04 +0100789 const U32 mls = dctx->fParams.mml;
Yann Collet5be2dd22015-11-11 13:43:58 +0100790
791 /* Build Decoding Tables */
792 errorCode = ZSTD_decodeSeqHeaders(&nbSeq, &dumps, &dumpsLength,
793 DTableLL, DTableML, DTableOffb,
Yann Colletfb810d62016-01-28 00:18:06 +0100794 ip, seqSize);
Yann Collet5be2dd22015-11-11 13:43:58 +0100795 if (ZSTD_isError(errorCode)) return errorCode;
796 ip += errorCode;
797
798 /* Regen sequences */
Yann Collete93d6ce2016-01-31 00:58:06 +0100799 if (nbSeq) {
Yann Collet5be2dd22015-11-11 13:43:58 +0100800 seq_t sequence;
801 seqState_t seqState;
802
803 memset(&sequence, 0, sizeof(sequence));
Yann Collet61e16ce2016-01-31 02:04:15 +0100804 sequence.offset = REPCODE_STARTVALUE;
Yann Collet5be2dd22015-11-11 13:43:58 +0100805 seqState.dumps = dumps;
806 seqState.dumpsEnd = dumps + dumpsLength;
Yann Collet61e16ce2016-01-31 02:04:15 +0100807 seqState.prevOffset = REPCODE_STARTVALUE;
Yann Collet5be2dd22015-11-11 13:43:58 +0100808 errorCode = BIT_initDStream(&(seqState.DStream), ip, iend-ip);
809 if (ERR_isError(errorCode)) return ERROR(corruption_detected);
810 FSE_initDState(&(seqState.stateLL), &(seqState.DStream), DTableLL);
811 FSE_initDState(&(seqState.stateOffb), &(seqState.DStream), DTableOffb);
812 FSE_initDState(&(seqState.stateML), &(seqState.DStream), DTableML);
813
Yann Collet7b51a292016-01-26 15:58:49 +0100814 for ( ; (BIT_reloadDStream(&(seqState.DStream)) <= BIT_DStream_completed) && nbSeq ; ) {
Yann Colletb3a2af92015-11-19 17:13:19 +0100815 size_t oneSeqSize;
816 nbSeq--;
inikep6b3739c2016-02-22 15:53:42 +0100817 ZSTD_decodeSequence(&sequence, &seqState, mls);
Yann Colletb3a2af92015-11-19 17:13:19 +0100818 oneSeqSize = ZSTD_execSequence(op, oend, sequence, &litPtr, litLimit_8, base, vBase, dictEnd);
Yann Collet370b08e2016-03-08 00:03:59 +0100819 if (ZSTD_isError(oneSeqSize))
820 return oneSeqSize;
Yann Collet5be2dd22015-11-11 13:43:58 +0100821 op += oneSeqSize;
822 }
823
824 /* check if reached exact end */
Yann Collet35f7de52016-01-31 02:51:03 +0100825 if (nbSeq) return ERROR(corruption_detected);
Yann Collete93d6ce2016-01-31 00:58:06 +0100826 }
Yann Collet5be2dd22015-11-11 13:43:58 +0100827
Yann Collete93d6ce2016-01-31 00:58:06 +0100828 /* last literal segment */
829 {
830 size_t lastLLSize = litEnd - litPtr;
831 if (litPtr > litEnd) return ERROR(corruption_detected); /* too many literals already used */
832 if (op+lastLLSize > oend) return ERROR(dstSize_tooSmall);
833 memcpy(op, litPtr, lastLLSize);
834 op += lastLLSize;
835 }
Yann Collet5be2dd22015-11-11 13:43:58 +0100836
837 return op-ostart;
838}
839
840
Yann Colletb0125102016-01-09 02:00:10 +0100841static void ZSTD_checkContinuity(ZSTD_DCtx* dctx, const void* dst)
842{
Yann Collet7b51a292016-01-26 15:58:49 +0100843 if (dst != dctx->previousDstEnd) { /* not contiguous */
Yann Colletb0125102016-01-09 02:00:10 +0100844 dctx->dictEnd = dctx->previousDstEnd;
845 dctx->vBase = (const char*)dst - ((const char*)(dctx->previousDstEnd) - (const char*)(dctx->base));
846 dctx->base = dst;
847 dctx->previousDstEnd = dst;
848 }
849}
850
851
852static size_t ZSTD_decompressBlock_internal(ZSTD_DCtx* dctx,
Yann Colletb010b3b2016-02-03 12:39:34 +0100853 void* dst, size_t dstCapacity,
Yann Collet5be2dd22015-11-11 13:43:58 +0100854 const void* src, size_t srcSize)
Yann Colletb010b3b2016-02-03 12:39:34 +0100855{ /* blockType == blockCompressed */
Yann Collet5be2dd22015-11-11 13:43:58 +0100856 const BYTE* ip = (const BYTE*)src;
Yann Colletb010b3b2016-02-03 12:39:34 +0100857 size_t litCSize;
858
Yann Collet569b81a2016-03-16 15:26:51 +0100859 if (srcSize >= ZSTD_BLOCKSIZE_MAX) return ERROR(srcSize_wrong);
Yann Collet5be2dd22015-11-11 13:43:58 +0100860
inikepa4dde252016-03-01 14:14:35 +0100861 ZSTD_LOG_BLOCK("%p: ZSTD_decompressBlock_internal searchLength=%d\n", dctx->base, dctx->params.searchLength);
862
Yann Collet5be2dd22015-11-11 13:43:58 +0100863 /* Decode literals sub-block */
Yann Colletb010b3b2016-02-03 12:39:34 +0100864 litCSize = ZSTD_decodeLiteralsBlock(dctx, src, srcSize);
Yann Collet5be2dd22015-11-11 13:43:58 +0100865 if (ZSTD_isError(litCSize)) return litCSize;
866 ip += litCSize;
867 srcSize -= litCSize;
868
Yann Colletb010b3b2016-02-03 12:39:34 +0100869 return ZSTD_decompressSequences(dctx, dst, dstCapacity, ip, srcSize);
Yann Collet5be2dd22015-11-11 13:43:58 +0100870}
871
872
Yann Colletb0125102016-01-09 02:00:10 +0100873size_t ZSTD_decompressBlock(ZSTD_DCtx* dctx,
Yann Colletb010b3b2016-02-03 12:39:34 +0100874 void* dst, size_t dstCapacity,
Yann Colletb0125102016-01-09 02:00:10 +0100875 const void* src, size_t srcSize)
876{
877 ZSTD_checkContinuity(dctx, dst);
Yann Colletb010b3b2016-02-03 12:39:34 +0100878 return ZSTD_decompressBlock_internal(dctx, dst, dstCapacity, src, srcSize);
Yann Colletb0125102016-01-09 02:00:10 +0100879}
880
881
Yann Collet0e491c02016-03-11 21:58:04 +0100882/*! ZSTD_decompress_continueDCtx() :
883* `dctx` must have been properly initialized */
884static size_t ZSTD_decompressFrame(ZSTD_DCtx* dctx,
Yann Collet31683c02015-12-18 01:26:48 +0100885 void* dst, size_t maxDstSize,
Yann Collet7b51a292016-01-26 15:58:49 +0100886 const void* src, size_t srcSize)
Yann Collet5be2dd22015-11-11 13:43:58 +0100887{
888 const BYTE* ip = (const BYTE*)src;
889 const BYTE* iend = ip + srcSize;
890 BYTE* const ostart = (BYTE* const)dst;
891 BYTE* op = ostart;
892 BYTE* const oend = ostart + maxDstSize;
893 size_t remainingSize = srcSize;
Yann Collet5be2dd22015-11-11 13:43:58 +0100894 blockProperties_t blockProperties;
895
896 /* Frame Header */
Yann Collet88fcd292015-11-25 14:42:45 +0100897 {
Yann Collet03ea59b2016-03-12 01:25:40 +0100898 size_t frameHeaderSize, errorCode;
Yann Collet88fcd292015-11-25 14:42:45 +0100899 if (srcSize < ZSTD_frameHeaderSize_min+ZSTD_blockHeaderSize) return ERROR(srcSize_wrong);
Yann Collet5be2dd22015-11-11 13:43:58 +0100900#if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT==1)
Yann Collet88fcd292015-11-25 14:42:45 +0100901 {
902 const U32 magicNumber = MEM_readLE32(src);
903 if (ZSTD_isLegacy(magicNumber))
904 return ZSTD_decompressLegacy(dst, maxDstSize, src, srcSize, magicNumber);
905 }
Yann Collet5be2dd22015-11-11 13:43:58 +0100906#endif
Yann Collet03ea59b2016-03-12 01:25:40 +0100907 frameHeaderSize = ZSTD_frameHeaderSize(src, ZSTD_frameHeaderSize_min);
Yann Collet88fcd292015-11-25 14:42:45 +0100908 if (ZSTD_isError(frameHeaderSize)) return frameHeaderSize;
909 if (srcSize < frameHeaderSize+ZSTD_blockHeaderSize) return ERROR(srcSize_wrong);
Yann Collet03ea59b2016-03-12 01:25:40 +0100910 errorCode = ZSTD_decodeFrameHeader(dctx, src, frameHeaderSize);
911 if (ZSTD_isError(errorCode)) return errorCode;
Yann Collet88fcd292015-11-25 14:42:45 +0100912 ip += frameHeaderSize; remainingSize -= frameHeaderSize;
Yann Collet88fcd292015-11-25 14:42:45 +0100913 }
Yann Collet5be2dd22015-11-11 13:43:58 +0100914
915 /* Loop on each block */
916 while (1)
917 {
918 size_t decodedSize=0;
919 size_t cBlockSize = ZSTD_getcBlockSize(ip, iend-ip, &blockProperties);
920 if (ZSTD_isError(cBlockSize)) return cBlockSize;
921
922 ip += ZSTD_blockHeaderSize;
923 remainingSize -= ZSTD_blockHeaderSize;
924 if (cBlockSize > remainingSize) return ERROR(srcSize_wrong);
925
926 switch(blockProperties.blockType)
927 {
928 case bt_compressed:
Yann Collet37422192016-01-25 16:54:05 +0100929 decodedSize = ZSTD_decompressBlock_internal(dctx, op, oend-op, ip, cBlockSize);
Yann Collet5be2dd22015-11-11 13:43:58 +0100930 break;
931 case bt_raw :
Yann Collet0f366c62015-11-12 16:19:30 +0100932 decodedSize = ZSTD_copyRawBlock(op, oend-op, ip, cBlockSize);
Yann Collet5be2dd22015-11-11 13:43:58 +0100933 break;
934 case bt_rle :
935 return ERROR(GENERIC); /* not yet supported */
936 break;
937 case bt_end :
938 /* end of frame */
939 if (remainingSize) return ERROR(srcSize_wrong);
940 break;
941 default:
942 return ERROR(GENERIC); /* impossible */
943 }
944 if (cBlockSize == 0) break; /* bt_end */
945
946 if (ZSTD_isError(decodedSize)) return decodedSize;
947 op += decodedSize;
948 ip += cBlockSize;
949 remainingSize -= cBlockSize;
950 }
951
952 return op-ostart;
953}
954
Yann Collet31683c02015-12-18 01:26:48 +0100955
Yann Collet7b51a292016-01-26 15:58:49 +0100956size_t ZSTD_decompress_usingPreparedDCtx(ZSTD_DCtx* dctx, const ZSTD_DCtx* refDCtx,
957 void* dst, size_t maxDstSize,
958 const void* src, size_t srcSize)
959{
960 ZSTD_copyDCtx(dctx, refDCtx);
961 ZSTD_checkContinuity(dctx, dst);
Yann Collet0e491c02016-03-11 21:58:04 +0100962 return ZSTD_decompressFrame(dctx, dst, maxDstSize, src, srcSize);
Yann Collet7b51a292016-01-26 15:58:49 +0100963}
964
965
966size_t ZSTD_decompress_usingDict(ZSTD_DCtx* dctx,
967 void* dst, size_t maxDstSize,
968 const void* src, size_t srcSize,
969 const void* dict, size_t dictSize)
970{
971 ZSTD_decompressBegin_usingDict(dctx, dict, dictSize);
inikepa4dde252016-03-01 14:14:35 +0100972 ZSTD_LOG_BLOCK("%p: ZSTD_decompressBegin_usingDict searchLength=%d\n", dctx->base, dctx->params.searchLength);
Yann Collet7b51a292016-01-26 15:58:49 +0100973 ZSTD_checkContinuity(dctx, dst);
Yann Collet0e491c02016-03-11 21:58:04 +0100974 return ZSTD_decompressFrame(dctx, dst, maxDstSize, src, srcSize);
Yann Collet7b51a292016-01-26 15:58:49 +0100975}
976
977
Yann Collet31683c02015-12-18 01:26:48 +0100978size_t ZSTD_decompressDCtx(ZSTD_DCtx* dctx, void* dst, size_t maxDstSize, const void* src, size_t srcSize)
979{
980 return ZSTD_decompress_usingDict(dctx, dst, maxDstSize, src, srcSize, NULL, 0);
981}
982
Yann Collet0e491c02016-03-11 21:58:04 +0100983
Yann Collet5be2dd22015-11-11 13:43:58 +0100984size_t ZSTD_decompress(void* dst, size_t maxDstSize, const void* src, size_t srcSize)
985{
Yann Collet3a3b72f2016-01-11 12:56:11 +0100986#if defined(ZSTD_HEAPMODE) && (ZSTD_HEAPMODE==1)
987 size_t regenSize;
988 ZSTD_DCtx* dctx = ZSTD_createDCtx();
989 if (dctx==NULL) return ERROR(memory_allocation);
990 regenSize = ZSTD_decompressDCtx(dctx, dst, maxDstSize, src, srcSize);
991 ZSTD_freeDCtx(dctx);
992 return regenSize;
993#else
Yann Collet31683c02015-12-18 01:26:48 +0100994 ZSTD_DCtx dctx;
995 return ZSTD_decompressDCtx(&dctx, dst, maxDstSize, src, srcSize);
Yann Colleta768a302016-01-21 16:04:35 +0100996#endif
Yann Collet5be2dd22015-11-11 13:43:58 +0100997}
998
999
Yann Collet346bffb2016-03-15 15:24:52 +01001000/*_******************************
Yann Collet5be2dd22015-11-11 13:43:58 +01001001* Streaming Decompression API
1002********************************/
Yann Collet5be2dd22015-11-11 13:43:58 +01001003size_t ZSTD_nextSrcSizeToDecompress(ZSTD_DCtx* dctx)
1004{
1005 return dctx->expected;
1006}
1007
Yann Collet37422192016-01-25 16:54:05 +01001008size_t ZSTD_decompressContinue(ZSTD_DCtx* dctx, void* dst, size_t maxDstSize, const void* src, size_t srcSize)
Yann Collet5be2dd22015-11-11 13:43:58 +01001009{
1010 /* Sanity check */
Yann Collet37422192016-01-25 16:54:05 +01001011 if (srcSize != dctx->expected) return ERROR(srcSize_wrong);
1012 ZSTD_checkContinuity(dctx, dst);
Yann Collet5be2dd22015-11-11 13:43:58 +01001013
Yann Collet88fcd292015-11-25 14:42:45 +01001014 /* Decompress : frame header; part 1 */
Yann Collet37422192016-01-25 16:54:05 +01001015 switch (dctx->stage)
Yann Collet5be2dd22015-11-11 13:43:58 +01001016 {
Yann Collet88fcd292015-11-25 14:42:45 +01001017 case ZSTDds_getFrameHeaderSize :
Yann Collet5be2dd22015-11-11 13:43:58 +01001018 {
Yann Collet88fcd292015-11-25 14:42:45 +01001019 /* get frame header size */
1020 if (srcSize != ZSTD_frameHeaderSize_min) return ERROR(srcSize_wrong); /* impossible */
Yann Collet03ea59b2016-03-12 01:25:40 +01001021 dctx->headerSize = ZSTD_frameHeaderSize(src, ZSTD_frameHeaderSize_min);
Yann Collet37422192016-01-25 16:54:05 +01001022 if (ZSTD_isError(dctx->headerSize)) return dctx->headerSize;
1023 memcpy(dctx->headerBuffer, src, ZSTD_frameHeaderSize_min);
Yann Collet7b51a292016-01-26 15:58:49 +01001024 if (dctx->headerSize > ZSTD_frameHeaderSize_min) {
Yann Collet37422192016-01-25 16:54:05 +01001025 dctx->expected = dctx->headerSize - ZSTD_frameHeaderSize_min;
1026 dctx->stage = ZSTDds_decodeFrameHeader;
Yann Collet88fcd292015-11-25 14:42:45 +01001027 return 0;
1028 }
Yann Collet37422192016-01-25 16:54:05 +01001029 dctx->expected = 0; /* not necessary to copy more */
Yann Collet5be2dd22015-11-11 13:43:58 +01001030 }
Yann Collet88fcd292015-11-25 14:42:45 +01001031 case ZSTDds_decodeFrameHeader:
Yann Collet5be2dd22015-11-11 13:43:58 +01001032 {
Yann Collet88fcd292015-11-25 14:42:45 +01001033 /* get frame header */
1034 size_t result;
Yann Collet37422192016-01-25 16:54:05 +01001035 memcpy(dctx->headerBuffer + ZSTD_frameHeaderSize_min, src, dctx->expected);
Yann Collet03ea59b2016-03-12 01:25:40 +01001036 result = ZSTD_decodeFrameHeader(dctx, dctx->headerBuffer, dctx->headerSize);
Yann Collet88fcd292015-11-25 14:42:45 +01001037 if (ZSTD_isError(result)) return result;
Yann Collet37422192016-01-25 16:54:05 +01001038 dctx->expected = ZSTD_blockHeaderSize;
1039 dctx->stage = ZSTDds_decodeBlockHeader;
Yann Collet88fcd292015-11-25 14:42:45 +01001040 return 0;
Yann Collet5be2dd22015-11-11 13:43:58 +01001041 }
Yann Collet88fcd292015-11-25 14:42:45 +01001042 case ZSTDds_decodeBlockHeader:
Yann Collet5be2dd22015-11-11 13:43:58 +01001043 {
Yann Collet88fcd292015-11-25 14:42:45 +01001044 /* Decode block header */
1045 blockProperties_t bp;
1046 size_t blockSize = ZSTD_getcBlockSize(src, ZSTD_blockHeaderSize, &bp);
1047 if (ZSTD_isError(blockSize)) return blockSize;
Yann Collet7b51a292016-01-26 15:58:49 +01001048 if (bp.blockType == bt_end) {
Yann Collet37422192016-01-25 16:54:05 +01001049 dctx->expected = 0;
1050 dctx->stage = ZSTDds_getFrameHeaderSize;
Yann Collet88fcd292015-11-25 14:42:45 +01001051 }
Yann Collet7b51a292016-01-26 15:58:49 +01001052 else {
Yann Collet37422192016-01-25 16:54:05 +01001053 dctx->expected = blockSize;
1054 dctx->bType = bp.blockType;
1055 dctx->stage = ZSTDds_decompressBlock;
Yann Collet88fcd292015-11-25 14:42:45 +01001056 }
Yann Collet88fcd292015-11-25 14:42:45 +01001057 return 0;
1058 }
Yann Collet417890c2015-12-04 17:16:37 +01001059 case ZSTDds_decompressBlock:
Yann Collet88fcd292015-11-25 14:42:45 +01001060 {
1061 /* Decompress : block content */
1062 size_t rSize;
Yann Collet37422192016-01-25 16:54:05 +01001063 switch(dctx->bType)
Yann Collet88fcd292015-11-25 14:42:45 +01001064 {
1065 case bt_compressed:
Yann Collet37422192016-01-25 16:54:05 +01001066 rSize = ZSTD_decompressBlock_internal(dctx, dst, maxDstSize, src, srcSize);
Yann Collet88fcd292015-11-25 14:42:45 +01001067 break;
1068 case bt_raw :
1069 rSize = ZSTD_copyRawBlock(dst, maxDstSize, src, srcSize);
1070 break;
1071 case bt_rle :
1072 return ERROR(GENERIC); /* not yet handled */
1073 break;
1074 case bt_end : /* should never happen (filtered at phase 1) */
1075 rSize = 0;
1076 break;
1077 default:
Yann Collet7b51a292016-01-26 15:58:49 +01001078 return ERROR(GENERIC); /* impossible */
Yann Collet88fcd292015-11-25 14:42:45 +01001079 }
Yann Collet37422192016-01-25 16:54:05 +01001080 dctx->stage = ZSTDds_decodeBlockHeader;
1081 dctx->expected = ZSTD_blockHeaderSize;
1082 dctx->previousDstEnd = (char*)dst + rSize;
Yann Collet88fcd292015-11-25 14:42:45 +01001083 return rSize;
1084 }
1085 default:
1086 return ERROR(GENERIC); /* impossible */
1087 }
Yann Collet5be2dd22015-11-11 13:43:58 +01001088}
1089
1090
Yann Colletb923f652016-01-26 03:14:20 +01001091static void ZSTD_refDictContent(ZSTD_DCtx* dctx, const void* dict, size_t dictSize)
Yann Collet417890c2015-12-04 17:16:37 +01001092{
Yann Collet37422192016-01-25 16:54:05 +01001093 dctx->dictEnd = dctx->previousDstEnd;
1094 dctx->vBase = (const char*)dict - ((const char*)(dctx->previousDstEnd) - (const char*)(dctx->base));
1095 dctx->base = dict;
1096 dctx->previousDstEnd = (const char*)dict + dictSize;
Yann Collet417890c2015-12-04 17:16:37 +01001097}
Yann Colletb923f652016-01-26 03:14:20 +01001098
Yann Colletb923f652016-01-26 03:14:20 +01001099static size_t ZSTD_loadEntropy(ZSTD_DCtx* dctx, const void* dict, size_t dictSize)
1100{
Yann Colletfb810d62016-01-28 00:18:06 +01001101 size_t hSize, offcodeHeaderSize, matchlengthHeaderSize, errorCode, litlengthHeaderSize;
1102 short offcodeNCount[MaxOff+1];
1103 U32 offcodeMaxValue=MaxOff, offcodeLog=OffFSELog;
1104 short matchlengthNCount[MaxML+1];
1105 unsigned matchlengthMaxValue = MaxML, matchlengthLog = MLFSELog;
1106 short litlengthNCount[MaxLL+1];
1107 unsigned litlengthMaxValue = MaxLL, litlengthLog = LLFSELog;
1108
1109 hSize = HUF_readDTableX4(dctx->hufTableX4, dict, dictSize);
Yann Colletb923f652016-01-26 03:14:20 +01001110 if (HUF_isError(hSize)) return ERROR(dictionary_corrupted);
Yann Colletfb810d62016-01-28 00:18:06 +01001111 dict = (const char*)dict + hSize;
1112 dictSize -= hSize;
1113
1114 offcodeHeaderSize = FSE_readNCount(offcodeNCount, &offcodeMaxValue, &offcodeLog, dict, dictSize);
1115 if (FSE_isError(offcodeHeaderSize)) return ERROR(dictionary_corrupted);
1116 errorCode = FSE_buildDTable(dctx->OffTable, offcodeNCount, offcodeMaxValue, offcodeLog);
1117 if (FSE_isError(errorCode)) return ERROR(dictionary_corrupted);
1118 dict = (const char*)dict + offcodeHeaderSize;
1119 dictSize -= offcodeHeaderSize;
1120
1121 matchlengthHeaderSize = FSE_readNCount(matchlengthNCount, &matchlengthMaxValue, &matchlengthLog, dict, dictSize);
1122 if (FSE_isError(matchlengthHeaderSize)) return ERROR(dictionary_corrupted);
1123 errorCode = FSE_buildDTable(dctx->MLTable, matchlengthNCount, matchlengthMaxValue, matchlengthLog);
1124 if (FSE_isError(errorCode)) return ERROR(dictionary_corrupted);
1125 dict = (const char*)dict + matchlengthHeaderSize;
1126 dictSize -= matchlengthHeaderSize;
1127
1128 litlengthHeaderSize = FSE_readNCount(litlengthNCount, &litlengthMaxValue, &litlengthLog, dict, dictSize);
1129 if (FSE_isError(litlengthHeaderSize)) return ERROR(dictionary_corrupted);
1130 errorCode = FSE_buildDTable(dctx->LLTable, litlengthNCount, litlengthMaxValue, litlengthLog);
1131 if (FSE_isError(errorCode)) return ERROR(dictionary_corrupted);
1132
1133 dctx->flagStaticTables = 1;
1134 return hSize + offcodeHeaderSize + matchlengthHeaderSize + litlengthHeaderSize;
Yann Colletb923f652016-01-26 03:14:20 +01001135}
1136
Yann Collet7b51a292016-01-26 15:58:49 +01001137static size_t ZSTD_decompress_insertDictionary(ZSTD_DCtx* dctx, const void* dict, size_t dictSize)
Yann Colletb923f652016-01-26 03:14:20 +01001138{
1139 size_t eSize;
1140 U32 magic = MEM_readLE32(dict);
1141 if (magic != ZSTD_DICT_MAGIC) {
1142 /* pure content mode */
1143 ZSTD_refDictContent(dctx, dict, dictSize);
1144 return 0;
1145 }
1146 /* load entropy tables */
1147 dict = (const char*)dict + 4;
1148 dictSize -= 4;
1149 eSize = ZSTD_loadEntropy(dctx, dict, dictSize);
1150 if (ZSTD_isError(eSize)) return ERROR(dictionary_corrupted);
1151
1152 /* reference dictionary content */
1153 dict = (const char*)dict + eSize;
1154 dictSize -= eSize;
1155 ZSTD_refDictContent(dctx, dict, dictSize);
1156
1157 return 0;
1158}
1159
Yann Collet7b51a292016-01-26 15:58:49 +01001160
1161size_t ZSTD_decompressBegin_usingDict(ZSTD_DCtx* dctx, const void* dict, size_t dictSize)
1162{
1163 size_t errorCode;
1164 errorCode = ZSTD_decompressBegin(dctx);
1165 if (ZSTD_isError(errorCode)) return errorCode;
1166
1167 if (dict && dictSize) {
1168 errorCode = ZSTD_decompress_insertDictionary(dctx, dict, dictSize);
1169 if (ZSTD_isError(errorCode)) return ERROR(dictionary_corrupted);
1170 }
1171
1172 return 0;
1173}
1174