blob: 7a38bf9ba96088b0117d6a31427ea660aaf48a16 [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
511size_t ZSTD_decodeSeqHeaders(int* nbSeq, const BYTE** dumpsPtr, size_t* dumpsLengthPtr,
512 FSE_DTable* DTableLL, FSE_DTable* DTableML, FSE_DTable* DTableOffb,
513 const void* src, size_t srcSize)
514{
515 const BYTE* const istart = (const BYTE* const)src;
516 const BYTE* ip = istart;
517 const BYTE* const iend = istart + srcSize;
518 U32 LLtype, Offtype, MLtype;
Yann Collet5be2dd22015-11-11 13:43:58 +0100519 size_t dumpsLength;
520
521 /* check */
Yann Collet61e16ce2016-01-31 02:04:15 +0100522 if (srcSize < MIN_SEQUENCES_SIZE)
523 return ERROR(srcSize_wrong);
Yann Collet5be2dd22015-11-11 13:43:58 +0100524
525 /* SeqHead */
Yann Collet61e16ce2016-01-31 02:04:15 +0100526 *nbSeq = *ip++;
527 if (*nbSeq==0) return 1;
Yann Colletd409db62016-03-04 14:45:31 +0100528 if (*nbSeq >= 0x7F) {
529 if (*nbSeq == 0xFF)
530 *nbSeq = MEM_readLE16(ip) + LONGNBSEQ, ip+=2;
531 else
532 *nbSeq = ((nbSeq[0]-0x80)<<8) + *ip++;
533 }
Yann Collete93d6ce2016-01-31 00:58:06 +0100534
Yann Colletd409db62016-03-04 14:45:31 +0100535 /* FSE table descriptors */
Yann Collet5be2dd22015-11-11 13:43:58 +0100536 LLtype = *ip >> 6;
537 Offtype = (*ip >> 4) & 3;
538 MLtype = (*ip >> 2) & 3;
Yann Colletfb810d62016-01-28 00:18:06 +0100539 if (*ip & 2) {
Yann Collet5be2dd22015-11-11 13:43:58 +0100540 dumpsLength = ip[2];
541 dumpsLength += ip[1] << 8;
542 ip += 3;
Yann Colletfb810d62016-01-28 00:18:06 +0100543 } else {
Yann Collet5be2dd22015-11-11 13:43:58 +0100544 dumpsLength = ip[1];
545 dumpsLength += (ip[0] & 1) << 8;
546 ip += 2;
547 }
548 *dumpsPtr = ip;
549 ip += dumpsLength;
550 *dumpsLengthPtr = dumpsLength;
551
552 /* check */
553 if (ip > iend-3) return ERROR(srcSize_wrong); /* min : all 3 are "raw", hence no header, but at least xxLog bits per type */
554
Yann Collet39c596c2016-03-18 21:40:56 +0100555 /* Build DTables */
Yann Collet5be2dd22015-11-11 13:43:58 +0100556 {
Yann Collet82368cf2015-11-16 19:10:56 +0100557 S16 norm[MaxML+1]; /* assumption : MaxML >= MaxLL >= MaxOff */
Yann Collet5be2dd22015-11-11 13:43:58 +0100558
Yann Collet5be2dd22015-11-11 13:43:58 +0100559 switch(LLtype)
560 {
Yann Colletfb810d62016-01-28 00:18:06 +0100561 case FSE_ENCODING_RLE :
Yann Colletfb810d62016-01-28 00:18:06 +0100562 FSE_buildDTable_rle(DTableLL, *ip++);
563 break;
564 case FSE_ENCODING_RAW :
Yann Colletfb810d62016-01-28 00:18:06 +0100565 FSE_buildDTable_raw(DTableLL, LLbits);
566 break;
567 case FSE_ENCODING_STATIC:
568 break;
Yann Colletfb810d62016-01-28 00:18:06 +0100569 default : /* impossible */
Yann Collet39c596c2016-03-18 21:40:56 +0100570 case FSE_ENCODING_DYNAMIC :
571 { U32 LLlog, max = MaxLL;
572 size_t const headerSize = FSE_readNCount(norm, &max, &LLlog, ip, iend-ip);
573 if (FSE_isError(headerSize)) return ERROR(GENERIC);
574 if (LLlog > LLFSELog) return ERROR(corruption_detected);
575 ip += headerSize;
576 FSE_buildDTable(DTableLL, norm, max, LLlog);
577 }
Yann Collet5be2dd22015-11-11 13:43:58 +0100578 }
579
580 switch(Offtype)
581 {
Yann Colletfb810d62016-01-28 00:18:06 +0100582 case FSE_ENCODING_RLE :
Yann Collet5be2dd22015-11-11 13:43:58 +0100583 if (ip > iend-2) return ERROR(srcSize_wrong); /* min : "raw", hence no header, but at least xxLog bits */
584 FSE_buildDTable_rle(DTableOffb, *ip++ & MaxOff); /* if *ip > MaxOff, data is corrupted */
585 break;
Yann Colletfb810d62016-01-28 00:18:06 +0100586 case FSE_ENCODING_RAW :
Yann Colletfb810d62016-01-28 00:18:06 +0100587 FSE_buildDTable_raw(DTableOffb, Offbits);
588 break;
589 case FSE_ENCODING_STATIC:
590 break;
Yann Colletfb810d62016-01-28 00:18:06 +0100591 default : /* impossible */
Yann Collet39c596c2016-03-18 21:40:56 +0100592 case FSE_ENCODING_DYNAMIC :
593 {
594 U32 Offlog, max = MaxOff;
595 size_t const headerSize = FSE_readNCount(norm, &max, &Offlog, ip, iend-ip);
596 if (FSE_isError(headerSize)) return ERROR(GENERIC);
597 if (Offlog > OffFSELog) return ERROR(corruption_detected);
598 ip += headerSize;
599 FSE_buildDTable(DTableOffb, norm, max, Offlog);
600 }
Yann Collet5be2dd22015-11-11 13:43:58 +0100601 }
602
603 switch(MLtype)
604 {
Yann Colletfb810d62016-01-28 00:18:06 +0100605 case FSE_ENCODING_RLE :
Yann Collet5be2dd22015-11-11 13:43:58 +0100606 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 +0100607 FSE_buildDTable_rle(DTableML, *ip++);
608 break;
609 case FSE_ENCODING_RAW :
Yann Colletfb810d62016-01-28 00:18:06 +0100610 FSE_buildDTable_raw(DTableML, MLbits);
611 break;
612 case FSE_ENCODING_STATIC:
613 break;
Yann Colletfb810d62016-01-28 00:18:06 +0100614 default : /* impossible */
Yann Collet39c596c2016-03-18 21:40:56 +0100615 case FSE_ENCODING_DYNAMIC :
616 { U32 MLlog, max = MaxML;
617 size_t const headerSize = FSE_readNCount(norm, &max, &MLlog, ip, iend-ip);
618 if (FSE_isError(headerSize)) return ERROR(GENERIC);
619 if (MLlog > MLFSELog) return ERROR(corruption_detected);
620 ip += headerSize;
621 FSE_buildDTable(DTableML, norm, max, MLlog);
622 }
623 } } /* Build DTables */
Yann Collet5be2dd22015-11-11 13:43:58 +0100624
625 return ip-istart;
626}
627
628
629typedef struct {
630 size_t litLength;
Yann Collet5be2dd22015-11-11 13:43:58 +0100631 size_t matchLength;
Yann Collete93d6ce2016-01-31 00:58:06 +0100632 size_t offset;
Yann Collet5be2dd22015-11-11 13:43:58 +0100633} seq_t;
634
635typedef struct {
636 BIT_DStream_t DStream;
637 FSE_DState_t stateLL;
638 FSE_DState_t stateOffb;
639 FSE_DState_t stateML;
640 size_t prevOffset;
641 const BYTE* dumps;
642 const BYTE* dumpsEnd;
643} seqState_t;
644
inikepe9f30ea2016-02-03 12:53:07 +0100645
646
inikep6b3739c2016-02-22 15:53:42 +0100647static void ZSTD_decodeSequence(seq_t* seq, seqState_t* seqState, const U32 mls)
Yann Collet5be2dd22015-11-11 13:43:58 +0100648{
Yann Collet5be2dd22015-11-11 13:43:58 +0100649 const BYTE* dumps = seqState->dumps;
650 const BYTE* const de = seqState->dumpsEnd;
Yann Collet3fd164e2016-03-17 12:56:46 +0100651 size_t litLength, offset;
Yann Collet5be2dd22015-11-11 13:43:58 +0100652
653 /* Literal length */
Yann Collete93d6ce2016-01-31 00:58:06 +0100654 litLength = FSE_peakSymbol(&(seqState->stateLL));
Yann Colletfb810d62016-01-28 00:18:06 +0100655 if (litLength == MaxLL) {
Yann Collet3fd164e2016-03-17 12:56:46 +0100656 const U32 add = *dumps++;
Yann Collet5be2dd22015-11-11 13:43:58 +0100657 if (add < 255) litLength += add;
Yann Colletfb810d62016-01-28 00:18:06 +0100658 else {
Yann Collet7d8e6bd2016-02-02 17:30:37 +0100659 litLength = MEM_readLE32(dumps) & 0xFFFFFF; /* no risk : dumps is always followed by seq tables > 1 byte */
660 if (litLength&1) litLength>>=1, dumps += 3;
661 else litLength = (U16)(litLength)>>1, dumps += 2;
Yann Collet5be2dd22015-11-11 13:43:58 +0100662 }
663 if (dumps >= de) dumps = de-1; /* late correction, to avoid read overflow (data is now corrupted anyway) */
664 }
665
666 /* Offset */
667 {
668 static const U32 offsetPrefix[MaxOff+1] = {
Yann Collet95cd0c22016-03-08 18:24:21 +0100669 1 /*fake*/, 1, 2, 4, 8, 0x10, 0x20, 0x40, 0x80, 0x100,
670 0x200, 0x400, 0x800, 0x1000, 0x2000, 0x4000, 0x8000, 0x10000, 0x20000, 0x40000,
671 0x80000, 0x100000, 0x200000, 0x400000, 0x800000, 0x1000000, 0x2000000, 0x4000000, /*fake*/ 1, 1, 1, 1 };
Yann Collet3fd164e2016-03-17 12:56:46 +0100672 const U32 offsetCode = FSE_peakSymbol(&(seqState->stateOffb)); /* <= maxOff, by table construction */
673 const U32 nbBits = offsetCode ? offsetCode-1 : 0;
Yann Collet5be2dd22015-11-11 13:43:58 +0100674 offset = offsetPrefix[offsetCode] + BIT_readBits(&(seqState->DStream), nbBits);
675 if (MEM_32bits()) BIT_reloadDStream(&(seqState->DStream));
Yann Colletb40287a2016-03-17 12:11:16 +0100676 if (offsetCode==0) offset = litLength ? seq->offset : seqState->prevOffset;
Yann Collet55aa7f92015-11-20 12:04:52 +0100677 if (offsetCode | !litLength) seqState->prevOffset = seq->offset; /* cmove */
Yann Collete93d6ce2016-01-31 00:58:06 +0100678 FSE_decodeSymbol(&(seqState->stateOffb), &(seqState->DStream)); /* update */
Yann Collet5be2dd22015-11-11 13:43:58 +0100679 }
680
Yann Collete93d6ce2016-01-31 00:58:06 +0100681 /* Literal length update */
682 FSE_decodeSymbol(&(seqState->stateLL), &(seqState->DStream)); /* update */
683 if (MEM_32bits()) BIT_reloadDStream(&(seqState->DStream));
684
Yann Collet5be2dd22015-11-11 13:43:58 +0100685 /* MatchLength */
Yann Collet3fd164e2016-03-17 12:56:46 +0100686 {
687 size_t matchLength = FSE_decodeSymbol(&(seqState->stateML), &(seqState->DStream));
688 if (matchLength == MaxML) {
689 const U32 add = *dumps++;
690 if (add < 255) matchLength += add;
691 else {
692 matchLength = MEM_readLE32(dumps) & 0xFFFFFF; /* no pb : dumps is always followed by seq tables > 1 byte */
693 if (matchLength&1) matchLength>>=1, dumps += 3;
694 else matchLength = (U16)(matchLength)>>1, dumps += 2;
695 }
696 if (dumps >= de) dumps = de-1; /* late correction, to avoid read overflow (data is now corrupted anyway) */
Yann Collet5be2dd22015-11-11 13:43:58 +0100697 }
Yann Collet3fd164e2016-03-17 12:56:46 +0100698 matchLength += mls;
699 seq->matchLength = matchLength;
Yann Collet5be2dd22015-11-11 13:43:58 +0100700 }
Yann Collet5be2dd22015-11-11 13:43:58 +0100701
702 /* save result */
703 seq->litLength = litLength;
704 seq->offset = offset;
Yann Collet5be2dd22015-11-11 13:43:58 +0100705 seqState->dumps = dumps;
Yann Colletfb810d62016-01-28 00:18:06 +0100706
Yann Collet7d8e6bd2016-02-02 17:30:37 +0100707#if 0 /* debug */
Yann Colletfb810d62016-01-28 00:18:06 +0100708 {
709 static U64 totalDecoded = 0;
710 printf("pos %6u : %3u literals & match %3u bytes at distance %6u \n",
711 (U32)(totalDecoded), (U32)litLength, (U32)matchLength, (U32)offset);
712 totalDecoded += litLength + matchLength;
713 }
714#endif
Yann Collet5be2dd22015-11-11 13:43:58 +0100715}
716
717
Yann Collet5b78d2f2015-11-12 15:36:05 +0100718FORCE_INLINE size_t ZSTD_execSequence(BYTE* op,
Yann Colletb3a2af92015-11-19 17:13:19 +0100719 BYTE* const oend, seq_t sequence,
Yann Collet5be2dd22015-11-11 13:43:58 +0100720 const BYTE** litPtr, const BYTE* const litLimit_8,
Yann Collet417890c2015-12-04 17:16:37 +0100721 const BYTE* const base, const BYTE* const vBase, const BYTE* const dictEnd)
Yann Collet5be2dd22015-11-11 13:43:58 +0100722{
Yann Colletb3a2af92015-11-19 17:13:19 +0100723 static const int dec32table[] = { 0, 1, 2, 1, 4, 4, 4, 4 }; /* added */
724 static const int dec64table[] = { 8, 8, 8, 7, 8, 9,10,11 }; /* substracted */
Yann Collet5be2dd22015-11-11 13:43:58 +0100725 BYTE* const oLitEnd = op + sequence.litLength;
Yann Colletb3a2af92015-11-19 17:13:19 +0100726 const size_t sequenceLength = sequence.litLength + sequence.matchLength;
727 BYTE* const oMatchEnd = op + sequenceLength; /* risk : address space overflow (32-bits) */
Yann Collet5be2dd22015-11-11 13:43:58 +0100728 BYTE* const oend_8 = oend-8;
729 const BYTE* const litEnd = *litPtr + sequence.litLength;
Yann Colletb3a2af92015-11-19 17:13:19 +0100730 const BYTE* match = oLitEnd - sequence.offset;
Yann Collet5be2dd22015-11-11 13:43:58 +0100731
732 /* check */
733 if (oLitEnd > oend_8) return ERROR(dstSize_tooSmall); /* last match must start at a minimum distance of 8 from oend */
734 if (oMatchEnd > oend) return ERROR(dstSize_tooSmall); /* overwrite beyond dst buffer */
735 if (litEnd > litLimit_8) return ERROR(corruption_detected); /* risk read beyond lit buffer */
736
737 /* copy Literals */
738 ZSTD_wildcopy(op, *litPtr, sequence.litLength); /* note : oLitEnd <= oend-8 : no risk of overwrite beyond oend */
739 op = oLitEnd;
740 *litPtr = litEnd; /* update for next sequence */
741
742 /* copy Match */
Yann Collet7b51a292016-01-26 15:58:49 +0100743 if (sequence.offset > (size_t)(oLitEnd - base)) {
Yann Collet44287a32015-11-30 23:13:56 +0100744 /* offset beyond prefix */
Yann Collet9f5ab1a2015-12-11 00:27:41 +0100745 if (sequence.offset > (size_t)(oLitEnd - vBase))
746 return ERROR(corruption_detected);
Yann Collet44287a32015-11-30 23:13:56 +0100747 match = dictEnd - (base-match);
Yann Collet7b51a292016-01-26 15:58:49 +0100748 if (match + sequence.matchLength <= dictEnd) {
Yann Collet4bfe4152015-12-06 13:18:37 +0100749 memmove(oLitEnd, match, sequence.matchLength);
Yann Collet44287a32015-11-30 23:13:56 +0100750 return sequenceLength;
751 }
752 /* span extDict & currentPrefixSegment */
753 {
754 size_t length1 = dictEnd - match;
Yann Collet4bfe4152015-12-06 13:18:37 +0100755 memmove(oLitEnd, match, length1);
Yann Collet44287a32015-11-30 23:13:56 +0100756 op = oLitEnd + length1;
757 sequence.matchLength -= length1;
758 match = base;
Yann Colletfb810d62016-01-28 00:18:06 +0100759 } }
Yann Collet0f366c62015-11-12 16:19:30 +0100760
Yann Collet44287a32015-11-30 23:13:56 +0100761 /* match within prefix */
Yann Collet7b51a292016-01-26 15:58:49 +0100762 if (sequence.offset < 8) {
Yann Collet44287a32015-11-30 23:13:56 +0100763 /* close range match, overlap */
764 const int sub2 = dec64table[sequence.offset];
765 op[0] = match[0];
766 op[1] = match[1];
767 op[2] = match[2];
768 op[3] = match[3];
769 match += dec32table[sequence.offset];
770 ZSTD_copy4(op+4, match);
771 match -= sub2;
Yann Colletfb810d62016-01-28 00:18:06 +0100772 } else {
Yann Collet44287a32015-11-30 23:13:56 +0100773 ZSTD_copy8(op, match);
774 }
775 op += 8; match += 8;
Yann Collet5be2dd22015-11-11 13:43:58 +0100776
inikepa4dde252016-03-01 14:14:35 +0100777 if (oMatchEnd > oend-(16-3)) { // 3 = MINMATCH
Yann Collet7b51a292016-01-26 15:58:49 +0100778 if (op < oend_8) {
Yann Collet44287a32015-11-30 23:13:56 +0100779 ZSTD_wildcopy(op, match, oend_8 - op);
780 match += oend_8 - op;
781 op = oend_8;
782 }
Yann Colletfb810d62016-01-28 00:18:06 +0100783 while (op < oMatchEnd)
784 *op++ = *match++;
785 } else {
Yann Collet44287a32015-11-30 23:13:56 +0100786 ZSTD_wildcopy(op, match, sequence.matchLength-8); /* works even if matchLength < 8 */
787 }
788 return sequenceLength;
Yann Collet5be2dd22015-11-11 13:43:58 +0100789}
790
Yann Colletb3a2af92015-11-19 17:13:19 +0100791
Yann Collet5be2dd22015-11-11 13:43:58 +0100792static size_t ZSTD_decompressSequences(
Yann Collet5b78d2f2015-11-12 15:36:05 +0100793 ZSTD_DCtx* dctx,
Yann Collet5be2dd22015-11-11 13:43:58 +0100794 void* dst, size_t maxDstSize,
795 const void* seqStart, size_t seqSize)
796{
Yann Collet5be2dd22015-11-11 13:43:58 +0100797 const BYTE* ip = (const BYTE*)seqStart;
798 const BYTE* const iend = ip + seqSize;
799 BYTE* const ostart = (BYTE* const)dst;
800 BYTE* op = ostart;
801 BYTE* const oend = ostart + maxDstSize;
802 size_t errorCode, dumpsLength;
803 const BYTE* litPtr = dctx->litPtr;
804 const BYTE* const litLimit_8 = litPtr + dctx->litBufSize - 8;
805 const BYTE* const litEnd = litPtr + dctx->litSize;
806 int nbSeq;
807 const BYTE* dumps;
808 U32* DTableLL = dctx->LLTable;
809 U32* DTableML = dctx->MLTable;
810 U32* DTableOffb = dctx->OffTable;
Yann Collet417890c2015-12-04 17:16:37 +0100811 const BYTE* const base = (const BYTE*) (dctx->base);
812 const BYTE* const vBase = (const BYTE*) (dctx->vBase);
813 const BYTE* const dictEnd = (const BYTE*) (dctx->dictEnd);
Yann Collet0e491c02016-03-11 21:58:04 +0100814 const U32 mls = dctx->fParams.mml;
Yann Collet5be2dd22015-11-11 13:43:58 +0100815
816 /* Build Decoding Tables */
817 errorCode = ZSTD_decodeSeqHeaders(&nbSeq, &dumps, &dumpsLength,
818 DTableLL, DTableML, DTableOffb,
Yann Colletfb810d62016-01-28 00:18:06 +0100819 ip, seqSize);
Yann Collet5be2dd22015-11-11 13:43:58 +0100820 if (ZSTD_isError(errorCode)) return errorCode;
821 ip += errorCode;
822
823 /* Regen sequences */
Yann Collete93d6ce2016-01-31 00:58:06 +0100824 if (nbSeq) {
Yann Collet5be2dd22015-11-11 13:43:58 +0100825 seq_t sequence;
826 seqState_t seqState;
827
828 memset(&sequence, 0, sizeof(sequence));
Yann Collet61e16ce2016-01-31 02:04:15 +0100829 sequence.offset = REPCODE_STARTVALUE;
Yann Collet5be2dd22015-11-11 13:43:58 +0100830 seqState.dumps = dumps;
831 seqState.dumpsEnd = dumps + dumpsLength;
Yann Collet61e16ce2016-01-31 02:04:15 +0100832 seqState.prevOffset = REPCODE_STARTVALUE;
Yann Collet5be2dd22015-11-11 13:43:58 +0100833 errorCode = BIT_initDStream(&(seqState.DStream), ip, iend-ip);
834 if (ERR_isError(errorCode)) return ERROR(corruption_detected);
835 FSE_initDState(&(seqState.stateLL), &(seqState.DStream), DTableLL);
836 FSE_initDState(&(seqState.stateOffb), &(seqState.DStream), DTableOffb);
837 FSE_initDState(&(seqState.stateML), &(seqState.DStream), DTableML);
838
Yann Collet7b51a292016-01-26 15:58:49 +0100839 for ( ; (BIT_reloadDStream(&(seqState.DStream)) <= BIT_DStream_completed) && nbSeq ; ) {
Yann Colletb3a2af92015-11-19 17:13:19 +0100840 size_t oneSeqSize;
841 nbSeq--;
inikep6b3739c2016-02-22 15:53:42 +0100842 ZSTD_decodeSequence(&sequence, &seqState, mls);
Yann Colletb3a2af92015-11-19 17:13:19 +0100843 oneSeqSize = ZSTD_execSequence(op, oend, sequence, &litPtr, litLimit_8, base, vBase, dictEnd);
Yann Collet370b08e2016-03-08 00:03:59 +0100844 if (ZSTD_isError(oneSeqSize))
845 return oneSeqSize;
Yann Collet5be2dd22015-11-11 13:43:58 +0100846 op += oneSeqSize;
847 }
848
849 /* check if reached exact end */
Yann Collet35f7de52016-01-31 02:51:03 +0100850 if (nbSeq) return ERROR(corruption_detected);
Yann Collete93d6ce2016-01-31 00:58:06 +0100851 }
Yann Collet5be2dd22015-11-11 13:43:58 +0100852
Yann Collete93d6ce2016-01-31 00:58:06 +0100853 /* last literal segment */
854 {
855 size_t lastLLSize = litEnd - litPtr;
856 if (litPtr > litEnd) return ERROR(corruption_detected); /* too many literals already used */
857 if (op+lastLLSize > oend) return ERROR(dstSize_tooSmall);
858 memcpy(op, litPtr, lastLLSize);
859 op += lastLLSize;
860 }
Yann Collet5be2dd22015-11-11 13:43:58 +0100861
862 return op-ostart;
863}
864
865
Yann Colletb0125102016-01-09 02:00:10 +0100866static void ZSTD_checkContinuity(ZSTD_DCtx* dctx, const void* dst)
867{
Yann Collet7b51a292016-01-26 15:58:49 +0100868 if (dst != dctx->previousDstEnd) { /* not contiguous */
Yann Colletb0125102016-01-09 02:00:10 +0100869 dctx->dictEnd = dctx->previousDstEnd;
870 dctx->vBase = (const char*)dst - ((const char*)(dctx->previousDstEnd) - (const char*)(dctx->base));
871 dctx->base = dst;
872 dctx->previousDstEnd = dst;
873 }
874}
875
876
877static size_t ZSTD_decompressBlock_internal(ZSTD_DCtx* dctx,
Yann Colletb010b3b2016-02-03 12:39:34 +0100878 void* dst, size_t dstCapacity,
Yann Collet5be2dd22015-11-11 13:43:58 +0100879 const void* src, size_t srcSize)
Yann Colletb010b3b2016-02-03 12:39:34 +0100880{ /* blockType == blockCompressed */
Yann Collet5be2dd22015-11-11 13:43:58 +0100881 const BYTE* ip = (const BYTE*)src;
Yann Colletb010b3b2016-02-03 12:39:34 +0100882 size_t litCSize;
883
Yann Collet569b81a2016-03-16 15:26:51 +0100884 if (srcSize >= ZSTD_BLOCKSIZE_MAX) return ERROR(srcSize_wrong);
Yann Collet5be2dd22015-11-11 13:43:58 +0100885
inikepa4dde252016-03-01 14:14:35 +0100886 ZSTD_LOG_BLOCK("%p: ZSTD_decompressBlock_internal searchLength=%d\n", dctx->base, dctx->params.searchLength);
887
Yann Collet5be2dd22015-11-11 13:43:58 +0100888 /* Decode literals sub-block */
Yann Colletb010b3b2016-02-03 12:39:34 +0100889 litCSize = ZSTD_decodeLiteralsBlock(dctx, src, srcSize);
Yann Collet5be2dd22015-11-11 13:43:58 +0100890 if (ZSTD_isError(litCSize)) return litCSize;
891 ip += litCSize;
892 srcSize -= litCSize;
893
Yann Colletb010b3b2016-02-03 12:39:34 +0100894 return ZSTD_decompressSequences(dctx, dst, dstCapacity, ip, srcSize);
Yann Collet5be2dd22015-11-11 13:43:58 +0100895}
896
897
Yann Colletb0125102016-01-09 02:00:10 +0100898size_t ZSTD_decompressBlock(ZSTD_DCtx* dctx,
Yann Colletb010b3b2016-02-03 12:39:34 +0100899 void* dst, size_t dstCapacity,
Yann Colletb0125102016-01-09 02:00:10 +0100900 const void* src, size_t srcSize)
901{
902 ZSTD_checkContinuity(dctx, dst);
Yann Colletb010b3b2016-02-03 12:39:34 +0100903 return ZSTD_decompressBlock_internal(dctx, dst, dstCapacity, src, srcSize);
Yann Colletb0125102016-01-09 02:00:10 +0100904}
905
906
Yann Collet0e491c02016-03-11 21:58:04 +0100907/*! ZSTD_decompress_continueDCtx() :
908* `dctx` must have been properly initialized */
909static size_t ZSTD_decompressFrame(ZSTD_DCtx* dctx,
Yann Collet31683c02015-12-18 01:26:48 +0100910 void* dst, size_t maxDstSize,
Yann Collet7b51a292016-01-26 15:58:49 +0100911 const void* src, size_t srcSize)
Yann Collet5be2dd22015-11-11 13:43:58 +0100912{
913 const BYTE* ip = (const BYTE*)src;
914 const BYTE* iend = ip + srcSize;
915 BYTE* const ostart = (BYTE* const)dst;
916 BYTE* op = ostart;
917 BYTE* const oend = ostart + maxDstSize;
918 size_t remainingSize = srcSize;
Yann Collet5be2dd22015-11-11 13:43:58 +0100919 blockProperties_t blockProperties;
920
921 /* Frame Header */
Yann Collet88fcd292015-11-25 14:42:45 +0100922 {
Yann Collet03ea59b2016-03-12 01:25:40 +0100923 size_t frameHeaderSize, errorCode;
Yann Collet88fcd292015-11-25 14:42:45 +0100924 if (srcSize < ZSTD_frameHeaderSize_min+ZSTD_blockHeaderSize) return ERROR(srcSize_wrong);
Yann Collet5be2dd22015-11-11 13:43:58 +0100925#if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT==1)
Yann Collet88fcd292015-11-25 14:42:45 +0100926 {
927 const U32 magicNumber = MEM_readLE32(src);
928 if (ZSTD_isLegacy(magicNumber))
929 return ZSTD_decompressLegacy(dst, maxDstSize, src, srcSize, magicNumber);
930 }
Yann Collet5be2dd22015-11-11 13:43:58 +0100931#endif
Yann Collet03ea59b2016-03-12 01:25:40 +0100932 frameHeaderSize = ZSTD_frameHeaderSize(src, ZSTD_frameHeaderSize_min);
Yann Collet88fcd292015-11-25 14:42:45 +0100933 if (ZSTD_isError(frameHeaderSize)) return frameHeaderSize;
934 if (srcSize < frameHeaderSize+ZSTD_blockHeaderSize) return ERROR(srcSize_wrong);
Yann Collet03ea59b2016-03-12 01:25:40 +0100935 errorCode = ZSTD_decodeFrameHeader(dctx, src, frameHeaderSize);
936 if (ZSTD_isError(errorCode)) return errorCode;
Yann Collet88fcd292015-11-25 14:42:45 +0100937 ip += frameHeaderSize; remainingSize -= frameHeaderSize;
Yann Collet88fcd292015-11-25 14:42:45 +0100938 }
Yann Collet5be2dd22015-11-11 13:43:58 +0100939
940 /* Loop on each block */
941 while (1)
942 {
943 size_t decodedSize=0;
944 size_t cBlockSize = ZSTD_getcBlockSize(ip, iend-ip, &blockProperties);
945 if (ZSTD_isError(cBlockSize)) return cBlockSize;
946
947 ip += ZSTD_blockHeaderSize;
948 remainingSize -= ZSTD_blockHeaderSize;
949 if (cBlockSize > remainingSize) return ERROR(srcSize_wrong);
950
951 switch(blockProperties.blockType)
952 {
953 case bt_compressed:
Yann Collet37422192016-01-25 16:54:05 +0100954 decodedSize = ZSTD_decompressBlock_internal(dctx, op, oend-op, ip, cBlockSize);
Yann Collet5be2dd22015-11-11 13:43:58 +0100955 break;
956 case bt_raw :
Yann Collet0f366c62015-11-12 16:19:30 +0100957 decodedSize = ZSTD_copyRawBlock(op, oend-op, ip, cBlockSize);
Yann Collet5be2dd22015-11-11 13:43:58 +0100958 break;
959 case bt_rle :
960 return ERROR(GENERIC); /* not yet supported */
961 break;
962 case bt_end :
963 /* end of frame */
964 if (remainingSize) return ERROR(srcSize_wrong);
965 break;
966 default:
967 return ERROR(GENERIC); /* impossible */
968 }
969 if (cBlockSize == 0) break; /* bt_end */
970
971 if (ZSTD_isError(decodedSize)) return decodedSize;
972 op += decodedSize;
973 ip += cBlockSize;
974 remainingSize -= cBlockSize;
975 }
976
977 return op-ostart;
978}
979
Yann Collet31683c02015-12-18 01:26:48 +0100980
Yann Collet7b51a292016-01-26 15:58:49 +0100981size_t ZSTD_decompress_usingPreparedDCtx(ZSTD_DCtx* dctx, const ZSTD_DCtx* refDCtx,
982 void* dst, size_t maxDstSize,
983 const void* src, size_t srcSize)
984{
985 ZSTD_copyDCtx(dctx, refDCtx);
986 ZSTD_checkContinuity(dctx, dst);
Yann Collet0e491c02016-03-11 21:58:04 +0100987 return ZSTD_decompressFrame(dctx, dst, maxDstSize, src, srcSize);
Yann Collet7b51a292016-01-26 15:58:49 +0100988}
989
990
991size_t ZSTD_decompress_usingDict(ZSTD_DCtx* dctx,
992 void* dst, size_t maxDstSize,
993 const void* src, size_t srcSize,
994 const void* dict, size_t dictSize)
995{
996 ZSTD_decompressBegin_usingDict(dctx, dict, dictSize);
inikepa4dde252016-03-01 14:14:35 +0100997 ZSTD_LOG_BLOCK("%p: ZSTD_decompressBegin_usingDict searchLength=%d\n", dctx->base, dctx->params.searchLength);
Yann Collet7b51a292016-01-26 15:58:49 +0100998 ZSTD_checkContinuity(dctx, dst);
Yann Collet0e491c02016-03-11 21:58:04 +0100999 return ZSTD_decompressFrame(dctx, dst, maxDstSize, src, srcSize);
Yann Collet7b51a292016-01-26 15:58:49 +01001000}
1001
1002
Yann Collet31683c02015-12-18 01:26:48 +01001003size_t ZSTD_decompressDCtx(ZSTD_DCtx* dctx, void* dst, size_t maxDstSize, const void* src, size_t srcSize)
1004{
1005 return ZSTD_decompress_usingDict(dctx, dst, maxDstSize, src, srcSize, NULL, 0);
1006}
1007
Yann Collet0e491c02016-03-11 21:58:04 +01001008
Yann Collet5be2dd22015-11-11 13:43:58 +01001009size_t ZSTD_decompress(void* dst, size_t maxDstSize, const void* src, size_t srcSize)
1010{
Yann Collet3a3b72f2016-01-11 12:56:11 +01001011#if defined(ZSTD_HEAPMODE) && (ZSTD_HEAPMODE==1)
1012 size_t regenSize;
1013 ZSTD_DCtx* dctx = ZSTD_createDCtx();
1014 if (dctx==NULL) return ERROR(memory_allocation);
1015 regenSize = ZSTD_decompressDCtx(dctx, dst, maxDstSize, src, srcSize);
1016 ZSTD_freeDCtx(dctx);
1017 return regenSize;
1018#else
Yann Collet31683c02015-12-18 01:26:48 +01001019 ZSTD_DCtx dctx;
1020 return ZSTD_decompressDCtx(&dctx, dst, maxDstSize, src, srcSize);
Yann Colleta768a302016-01-21 16:04:35 +01001021#endif
Yann Collet5be2dd22015-11-11 13:43:58 +01001022}
1023
1024
Yann Collet346bffb2016-03-15 15:24:52 +01001025/*_******************************
Yann Collet5be2dd22015-11-11 13:43:58 +01001026* Streaming Decompression API
1027********************************/
Yann Collet5be2dd22015-11-11 13:43:58 +01001028size_t ZSTD_nextSrcSizeToDecompress(ZSTD_DCtx* dctx)
1029{
1030 return dctx->expected;
1031}
1032
Yann Collet37422192016-01-25 16:54:05 +01001033size_t ZSTD_decompressContinue(ZSTD_DCtx* dctx, void* dst, size_t maxDstSize, const void* src, size_t srcSize)
Yann Collet5be2dd22015-11-11 13:43:58 +01001034{
1035 /* Sanity check */
Yann Collet37422192016-01-25 16:54:05 +01001036 if (srcSize != dctx->expected) return ERROR(srcSize_wrong);
1037 ZSTD_checkContinuity(dctx, dst);
Yann Collet5be2dd22015-11-11 13:43:58 +01001038
Yann Collet88fcd292015-11-25 14:42:45 +01001039 /* Decompress : frame header; part 1 */
Yann Collet37422192016-01-25 16:54:05 +01001040 switch (dctx->stage)
Yann Collet5be2dd22015-11-11 13:43:58 +01001041 {
Yann Collet88fcd292015-11-25 14:42:45 +01001042 case ZSTDds_getFrameHeaderSize :
Yann Collet5be2dd22015-11-11 13:43:58 +01001043 {
Yann Collet88fcd292015-11-25 14:42:45 +01001044 /* get frame header size */
1045 if (srcSize != ZSTD_frameHeaderSize_min) return ERROR(srcSize_wrong); /* impossible */
Yann Collet03ea59b2016-03-12 01:25:40 +01001046 dctx->headerSize = ZSTD_frameHeaderSize(src, ZSTD_frameHeaderSize_min);
Yann Collet37422192016-01-25 16:54:05 +01001047 if (ZSTD_isError(dctx->headerSize)) return dctx->headerSize;
1048 memcpy(dctx->headerBuffer, src, ZSTD_frameHeaderSize_min);
Yann Collet7b51a292016-01-26 15:58:49 +01001049 if (dctx->headerSize > ZSTD_frameHeaderSize_min) {
Yann Collet37422192016-01-25 16:54:05 +01001050 dctx->expected = dctx->headerSize - ZSTD_frameHeaderSize_min;
1051 dctx->stage = ZSTDds_decodeFrameHeader;
Yann Collet88fcd292015-11-25 14:42:45 +01001052 return 0;
1053 }
Yann Collet37422192016-01-25 16:54:05 +01001054 dctx->expected = 0; /* not necessary to copy more */
Yann Collet5be2dd22015-11-11 13:43:58 +01001055 }
Yann Collet88fcd292015-11-25 14:42:45 +01001056 case ZSTDds_decodeFrameHeader:
Yann Collet5be2dd22015-11-11 13:43:58 +01001057 {
Yann Collet88fcd292015-11-25 14:42:45 +01001058 /* get frame header */
1059 size_t result;
Yann Collet37422192016-01-25 16:54:05 +01001060 memcpy(dctx->headerBuffer + ZSTD_frameHeaderSize_min, src, dctx->expected);
Yann Collet03ea59b2016-03-12 01:25:40 +01001061 result = ZSTD_decodeFrameHeader(dctx, dctx->headerBuffer, dctx->headerSize);
Yann Collet88fcd292015-11-25 14:42:45 +01001062 if (ZSTD_isError(result)) return result;
Yann Collet37422192016-01-25 16:54:05 +01001063 dctx->expected = ZSTD_blockHeaderSize;
1064 dctx->stage = ZSTDds_decodeBlockHeader;
Yann Collet88fcd292015-11-25 14:42:45 +01001065 return 0;
Yann Collet5be2dd22015-11-11 13:43:58 +01001066 }
Yann Collet88fcd292015-11-25 14:42:45 +01001067 case ZSTDds_decodeBlockHeader:
Yann Collet5be2dd22015-11-11 13:43:58 +01001068 {
Yann Collet88fcd292015-11-25 14:42:45 +01001069 /* Decode block header */
1070 blockProperties_t bp;
1071 size_t blockSize = ZSTD_getcBlockSize(src, ZSTD_blockHeaderSize, &bp);
1072 if (ZSTD_isError(blockSize)) return blockSize;
Yann Collet7b51a292016-01-26 15:58:49 +01001073 if (bp.blockType == bt_end) {
Yann Collet37422192016-01-25 16:54:05 +01001074 dctx->expected = 0;
1075 dctx->stage = ZSTDds_getFrameHeaderSize;
Yann Collet88fcd292015-11-25 14:42:45 +01001076 }
Yann Collet7b51a292016-01-26 15:58:49 +01001077 else {
Yann Collet37422192016-01-25 16:54:05 +01001078 dctx->expected = blockSize;
1079 dctx->bType = bp.blockType;
1080 dctx->stage = ZSTDds_decompressBlock;
Yann Collet88fcd292015-11-25 14:42:45 +01001081 }
Yann Collet88fcd292015-11-25 14:42:45 +01001082 return 0;
1083 }
Yann Collet417890c2015-12-04 17:16:37 +01001084 case ZSTDds_decompressBlock:
Yann Collet88fcd292015-11-25 14:42:45 +01001085 {
1086 /* Decompress : block content */
1087 size_t rSize;
Yann Collet37422192016-01-25 16:54:05 +01001088 switch(dctx->bType)
Yann Collet88fcd292015-11-25 14:42:45 +01001089 {
1090 case bt_compressed:
Yann Collet37422192016-01-25 16:54:05 +01001091 rSize = ZSTD_decompressBlock_internal(dctx, dst, maxDstSize, src, srcSize);
Yann Collet88fcd292015-11-25 14:42:45 +01001092 break;
1093 case bt_raw :
1094 rSize = ZSTD_copyRawBlock(dst, maxDstSize, src, srcSize);
1095 break;
1096 case bt_rle :
1097 return ERROR(GENERIC); /* not yet handled */
1098 break;
1099 case bt_end : /* should never happen (filtered at phase 1) */
1100 rSize = 0;
1101 break;
1102 default:
Yann Collet7b51a292016-01-26 15:58:49 +01001103 return ERROR(GENERIC); /* impossible */
Yann Collet88fcd292015-11-25 14:42:45 +01001104 }
Yann Collet37422192016-01-25 16:54:05 +01001105 dctx->stage = ZSTDds_decodeBlockHeader;
1106 dctx->expected = ZSTD_blockHeaderSize;
1107 dctx->previousDstEnd = (char*)dst + rSize;
Yann Collet88fcd292015-11-25 14:42:45 +01001108 return rSize;
1109 }
1110 default:
1111 return ERROR(GENERIC); /* impossible */
1112 }
Yann Collet5be2dd22015-11-11 13:43:58 +01001113}
1114
1115
Yann Colletb923f652016-01-26 03:14:20 +01001116static void ZSTD_refDictContent(ZSTD_DCtx* dctx, const void* dict, size_t dictSize)
Yann Collet417890c2015-12-04 17:16:37 +01001117{
Yann Collet37422192016-01-25 16:54:05 +01001118 dctx->dictEnd = dctx->previousDstEnd;
1119 dctx->vBase = (const char*)dict - ((const char*)(dctx->previousDstEnd) - (const char*)(dctx->base));
1120 dctx->base = dict;
1121 dctx->previousDstEnd = (const char*)dict + dictSize;
Yann Collet417890c2015-12-04 17:16:37 +01001122}
Yann Colletb923f652016-01-26 03:14:20 +01001123
Yann Colletb923f652016-01-26 03:14:20 +01001124static size_t ZSTD_loadEntropy(ZSTD_DCtx* dctx, const void* dict, size_t dictSize)
1125{
Yann Colletfb810d62016-01-28 00:18:06 +01001126 size_t hSize, offcodeHeaderSize, matchlengthHeaderSize, errorCode, litlengthHeaderSize;
1127 short offcodeNCount[MaxOff+1];
1128 U32 offcodeMaxValue=MaxOff, offcodeLog=OffFSELog;
1129 short matchlengthNCount[MaxML+1];
1130 unsigned matchlengthMaxValue = MaxML, matchlengthLog = MLFSELog;
1131 short litlengthNCount[MaxLL+1];
1132 unsigned litlengthMaxValue = MaxLL, litlengthLog = LLFSELog;
1133
1134 hSize = HUF_readDTableX4(dctx->hufTableX4, dict, dictSize);
Yann Colletb923f652016-01-26 03:14:20 +01001135 if (HUF_isError(hSize)) return ERROR(dictionary_corrupted);
Yann Colletfb810d62016-01-28 00:18:06 +01001136 dict = (const char*)dict + hSize;
1137 dictSize -= hSize;
1138
1139 offcodeHeaderSize = FSE_readNCount(offcodeNCount, &offcodeMaxValue, &offcodeLog, dict, dictSize);
1140 if (FSE_isError(offcodeHeaderSize)) return ERROR(dictionary_corrupted);
1141 errorCode = FSE_buildDTable(dctx->OffTable, offcodeNCount, offcodeMaxValue, offcodeLog);
1142 if (FSE_isError(errorCode)) return ERROR(dictionary_corrupted);
1143 dict = (const char*)dict + offcodeHeaderSize;
1144 dictSize -= offcodeHeaderSize;
1145
1146 matchlengthHeaderSize = FSE_readNCount(matchlengthNCount, &matchlengthMaxValue, &matchlengthLog, dict, dictSize);
1147 if (FSE_isError(matchlengthHeaderSize)) return ERROR(dictionary_corrupted);
1148 errorCode = FSE_buildDTable(dctx->MLTable, matchlengthNCount, matchlengthMaxValue, matchlengthLog);
1149 if (FSE_isError(errorCode)) return ERROR(dictionary_corrupted);
1150 dict = (const char*)dict + matchlengthHeaderSize;
1151 dictSize -= matchlengthHeaderSize;
1152
1153 litlengthHeaderSize = FSE_readNCount(litlengthNCount, &litlengthMaxValue, &litlengthLog, dict, dictSize);
1154 if (FSE_isError(litlengthHeaderSize)) return ERROR(dictionary_corrupted);
1155 errorCode = FSE_buildDTable(dctx->LLTable, litlengthNCount, litlengthMaxValue, litlengthLog);
1156 if (FSE_isError(errorCode)) return ERROR(dictionary_corrupted);
1157
1158 dctx->flagStaticTables = 1;
1159 return hSize + offcodeHeaderSize + matchlengthHeaderSize + litlengthHeaderSize;
Yann Colletb923f652016-01-26 03:14:20 +01001160}
1161
Yann Collet7b51a292016-01-26 15:58:49 +01001162static size_t ZSTD_decompress_insertDictionary(ZSTD_DCtx* dctx, const void* dict, size_t dictSize)
Yann Colletb923f652016-01-26 03:14:20 +01001163{
1164 size_t eSize;
1165 U32 magic = MEM_readLE32(dict);
1166 if (magic != ZSTD_DICT_MAGIC) {
1167 /* pure content mode */
1168 ZSTD_refDictContent(dctx, dict, dictSize);
1169 return 0;
1170 }
1171 /* load entropy tables */
1172 dict = (const char*)dict + 4;
1173 dictSize -= 4;
1174 eSize = ZSTD_loadEntropy(dctx, dict, dictSize);
1175 if (ZSTD_isError(eSize)) return ERROR(dictionary_corrupted);
1176
1177 /* reference dictionary content */
1178 dict = (const char*)dict + eSize;
1179 dictSize -= eSize;
1180 ZSTD_refDictContent(dctx, dict, dictSize);
1181
1182 return 0;
1183}
1184
Yann Collet7b51a292016-01-26 15:58:49 +01001185
1186size_t ZSTD_decompressBegin_usingDict(ZSTD_DCtx* dctx, const void* dict, size_t dictSize)
1187{
1188 size_t errorCode;
1189 errorCode = ZSTD_decompressBegin(dctx);
1190 if (ZSTD_isError(errorCode)) return errorCode;
1191
1192 if (dict && dictSize) {
1193 errorCode = ZSTD_decompress_insertDictionary(dctx, dict, dictSize);
1194 if (ZSTD_isError(errorCode)) return ERROR(dictionary_corrupted);
1195 }
1196
1197 return 0;
1198}
1199