blob: 17ba5822e51462b8acd088f54012983a145ab259 [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;
519 U32 LLlog, Offlog, MLlog;
520 size_t dumpsLength;
521
522 /* check */
Yann Collet61e16ce2016-01-31 02:04:15 +0100523 if (srcSize < MIN_SEQUENCES_SIZE)
524 return ERROR(srcSize_wrong);
Yann Collet5be2dd22015-11-11 13:43:58 +0100525
526 /* SeqHead */
Yann Collet61e16ce2016-01-31 02:04:15 +0100527 *nbSeq = *ip++;
528 if (*nbSeq==0) return 1;
Yann Colletd409db62016-03-04 14:45:31 +0100529 if (*nbSeq >= 0x7F) {
530 if (*nbSeq == 0xFF)
531 *nbSeq = MEM_readLE16(ip) + LONGNBSEQ, ip+=2;
532 else
533 *nbSeq = ((nbSeq[0]-0x80)<<8) + *ip++;
534 }
Yann Collete93d6ce2016-01-31 00:58:06 +0100535
Yann Colletd409db62016-03-04 14:45:31 +0100536 /* FSE table descriptors */
Yann Collet5be2dd22015-11-11 13:43:58 +0100537 LLtype = *ip >> 6;
538 Offtype = (*ip >> 4) & 3;
539 MLtype = (*ip >> 2) & 3;
Yann Colletfb810d62016-01-28 00:18:06 +0100540 if (*ip & 2) {
Yann Collet5be2dd22015-11-11 13:43:58 +0100541 dumpsLength = ip[2];
542 dumpsLength += ip[1] << 8;
543 ip += 3;
Yann Colletfb810d62016-01-28 00:18:06 +0100544 } else {
Yann Collet5be2dd22015-11-11 13:43:58 +0100545 dumpsLength = ip[1];
546 dumpsLength += (ip[0] & 1) << 8;
547 ip += 2;
548 }
549 *dumpsPtr = ip;
550 ip += dumpsLength;
551 *dumpsLengthPtr = dumpsLength;
552
553 /* check */
554 if (ip > iend-3) return ERROR(srcSize_wrong); /* min : all 3 are "raw", hence no header, but at least xxLog bits per type */
555
556 /* sequences */
557 {
Yann Collet82368cf2015-11-16 19:10:56 +0100558 S16 norm[MaxML+1]; /* assumption : MaxML >= MaxLL >= MaxOff */
Yann Collet5be2dd22015-11-11 13:43:58 +0100559 size_t headerSize;
560
561 /* Build DTables */
562 switch(LLtype)
563 {
564 U32 max;
Yann Colletfb810d62016-01-28 00:18:06 +0100565 case FSE_ENCODING_RLE :
Yann Collet5be2dd22015-11-11 13:43:58 +0100566 LLlog = 0;
Yann Colletfb810d62016-01-28 00:18:06 +0100567 FSE_buildDTable_rle(DTableLL, *ip++);
568 break;
569 case FSE_ENCODING_RAW :
Yann Collet5be2dd22015-11-11 13:43:58 +0100570 LLlog = LLbits;
Yann Colletfb810d62016-01-28 00:18:06 +0100571 FSE_buildDTable_raw(DTableLL, LLbits);
572 break;
573 case FSE_ENCODING_STATIC:
574 break;
575 case FSE_ENCODING_DYNAMIC :
576 default : /* impossible */
Yann Collet5be2dd22015-11-11 13:43:58 +0100577 max = MaxLL;
578 headerSize = FSE_readNCount(norm, &max, &LLlog, ip, iend-ip);
579 if (FSE_isError(headerSize)) return ERROR(GENERIC);
580 if (LLlog > LLFSELog) return ERROR(corruption_detected);
581 ip += headerSize;
582 FSE_buildDTable(DTableLL, norm, max, LLlog);
583 }
584
585 switch(Offtype)
586 {
587 U32 max;
Yann Colletfb810d62016-01-28 00:18:06 +0100588 case FSE_ENCODING_RLE :
Yann Collet5be2dd22015-11-11 13:43:58 +0100589 Offlog = 0;
590 if (ip > iend-2) return ERROR(srcSize_wrong); /* min : "raw", hence no header, but at least xxLog bits */
591 FSE_buildDTable_rle(DTableOffb, *ip++ & MaxOff); /* if *ip > MaxOff, data is corrupted */
592 break;
Yann Colletfb810d62016-01-28 00:18:06 +0100593 case FSE_ENCODING_RAW :
Yann Collet5be2dd22015-11-11 13:43:58 +0100594 Offlog = Offbits;
Yann Colletfb810d62016-01-28 00:18:06 +0100595 FSE_buildDTable_raw(DTableOffb, Offbits);
596 break;
597 case FSE_ENCODING_STATIC:
598 break;
599 case FSE_ENCODING_DYNAMIC :
600 default : /* impossible */
Yann Collet5be2dd22015-11-11 13:43:58 +0100601 max = MaxOff;
602 headerSize = FSE_readNCount(norm, &max, &Offlog, ip, iend-ip);
603 if (FSE_isError(headerSize)) return ERROR(GENERIC);
604 if (Offlog > OffFSELog) return ERROR(corruption_detected);
605 ip += headerSize;
606 FSE_buildDTable(DTableOffb, norm, max, Offlog);
607 }
608
609 switch(MLtype)
610 {
611 U32 max;
Yann Colletfb810d62016-01-28 00:18:06 +0100612 case FSE_ENCODING_RLE :
Yann Collet5be2dd22015-11-11 13:43:58 +0100613 MLlog = 0;
614 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 +0100615 FSE_buildDTable_rle(DTableML, *ip++);
616 break;
617 case FSE_ENCODING_RAW :
Yann Collet5be2dd22015-11-11 13:43:58 +0100618 MLlog = MLbits;
Yann Colletfb810d62016-01-28 00:18:06 +0100619 FSE_buildDTable_raw(DTableML, MLbits);
620 break;
621 case FSE_ENCODING_STATIC:
622 break;
623 case FSE_ENCODING_DYNAMIC :
624 default : /* impossible */
Yann Collet5be2dd22015-11-11 13:43:58 +0100625 max = MaxML;
626 headerSize = FSE_readNCount(norm, &max, &MLlog, ip, iend-ip);
627 if (FSE_isError(headerSize)) return ERROR(GENERIC);
628 if (MLlog > MLFSELog) return ERROR(corruption_detected);
629 ip += headerSize;
630 FSE_buildDTable(DTableML, norm, max, MLlog);
Yann Colletfb810d62016-01-28 00:18:06 +0100631 } }
Yann Collet5be2dd22015-11-11 13:43:58 +0100632
633 return ip-istart;
634}
635
636
637typedef struct {
638 size_t litLength;
Yann Collet5be2dd22015-11-11 13:43:58 +0100639 size_t matchLength;
Yann Collete93d6ce2016-01-31 00:58:06 +0100640 size_t offset;
Yann Collet5be2dd22015-11-11 13:43:58 +0100641} seq_t;
642
643typedef struct {
644 BIT_DStream_t DStream;
645 FSE_DState_t stateLL;
646 FSE_DState_t stateOffb;
647 FSE_DState_t stateML;
648 size_t prevOffset;
649 const BYTE* dumps;
650 const BYTE* dumpsEnd;
651} seqState_t;
652
inikepe9f30ea2016-02-03 12:53:07 +0100653
654
inikep6b3739c2016-02-22 15:53:42 +0100655static void ZSTD_decodeSequence(seq_t* seq, seqState_t* seqState, const U32 mls)
Yann Collet5be2dd22015-11-11 13:43:58 +0100656{
Yann Collet5be2dd22015-11-11 13:43:58 +0100657 const BYTE* dumps = seqState->dumps;
658 const BYTE* const de = seqState->dumpsEnd;
Yann Colletb40287a2016-03-17 12:11:16 +0100659 size_t litLength, offset, matchLength;
Yann Collet5be2dd22015-11-11 13:43:58 +0100660
661 /* Literal length */
Yann Collete93d6ce2016-01-31 00:58:06 +0100662 litLength = FSE_peakSymbol(&(seqState->stateLL));
Yann Colletfb810d62016-01-28 00:18:06 +0100663 if (litLength == MaxLL) {
Yann Collet5be2dd22015-11-11 13:43:58 +0100664 U32 add = *dumps++;
665 if (add < 255) litLength += add;
Yann Colletfb810d62016-01-28 00:18:06 +0100666 else {
Yann Collet7d8e6bd2016-02-02 17:30:37 +0100667 litLength = MEM_readLE32(dumps) & 0xFFFFFF; /* no risk : dumps is always followed by seq tables > 1 byte */
668 if (litLength&1) litLength>>=1, dumps += 3;
669 else litLength = (U16)(litLength)>>1, dumps += 2;
Yann Collet5be2dd22015-11-11 13:43:58 +0100670 }
671 if (dumps >= de) dumps = de-1; /* late correction, to avoid read overflow (data is now corrupted anyway) */
672 }
673
674 /* Offset */
675 {
676 static const U32 offsetPrefix[MaxOff+1] = {
Yann Collet95cd0c22016-03-08 18:24:21 +0100677 1 /*fake*/, 1, 2, 4, 8, 0x10, 0x20, 0x40, 0x80, 0x100,
678 0x200, 0x400, 0x800, 0x1000, 0x2000, 0x4000, 0x8000, 0x10000, 0x20000, 0x40000,
679 0x80000, 0x100000, 0x200000, 0x400000, 0x800000, 0x1000000, 0x2000000, 0x4000000, /*fake*/ 1, 1, 1, 1 };
Yann Collete93d6ce2016-01-31 00:58:06 +0100680 U32 offsetCode = FSE_peakSymbol(&(seqState->stateOffb)); /* <= maxOff, by table construction */
681 U32 nbBits = offsetCode - 1;
Yann Collet5be2dd22015-11-11 13:43:58 +0100682 if (offsetCode==0) nbBits = 0; /* cmove */
683 offset = offsetPrefix[offsetCode] + BIT_readBits(&(seqState->DStream), nbBits);
684 if (MEM_32bits()) BIT_reloadDStream(&(seqState->DStream));
Yann Colletb40287a2016-03-17 12:11:16 +0100685 if (offsetCode==0) offset = litLength ? seq->offset : seqState->prevOffset;
Yann Collet55aa7f92015-11-20 12:04:52 +0100686 if (offsetCode | !litLength) seqState->prevOffset = seq->offset; /* cmove */
Yann Collete93d6ce2016-01-31 00:58:06 +0100687 FSE_decodeSymbol(&(seqState->stateOffb), &(seqState->DStream)); /* update */
Yann Collet5be2dd22015-11-11 13:43:58 +0100688 }
689
Yann Collete93d6ce2016-01-31 00:58:06 +0100690 /* Literal length update */
691 FSE_decodeSymbol(&(seqState->stateLL), &(seqState->DStream)); /* update */
692 if (MEM_32bits()) BIT_reloadDStream(&(seqState->DStream));
693
Yann Collet5be2dd22015-11-11 13:43:58 +0100694 /* MatchLength */
695 matchLength = FSE_decodeSymbol(&(seqState->stateML), &(seqState->DStream));
Yann Colletfb810d62016-01-28 00:18:06 +0100696 if (matchLength == MaxML) {
Yann Collet5be2dd22015-11-11 13:43:58 +0100697 U32 add = *dumps++;
698 if (add < 255) matchLength += add;
Yann Colletfb810d62016-01-28 00:18:06 +0100699 else {
Yann Collet5be2dd22015-11-11 13:43:58 +0100700 matchLength = MEM_readLE32(dumps) & 0xFFFFFF; /* no pb : dumps is always followed by seq tables > 1 byte */
Yann Collet7d8e6bd2016-02-02 17:30:37 +0100701 if (matchLength&1) matchLength>>=1, dumps += 3;
702 else matchLength = (U16)(matchLength)>>1, dumps += 2;
Yann Collet5be2dd22015-11-11 13:43:58 +0100703 }
704 if (dumps >= de) dumps = de-1; /* late correction, to avoid read overflow (data is now corrupted anyway) */
705 }
inikep6b3739c2016-02-22 15:53:42 +0100706 matchLength += mls;
Yann Collet5be2dd22015-11-11 13:43:58 +0100707
708 /* save result */
709 seq->litLength = litLength;
710 seq->offset = offset;
711 seq->matchLength = matchLength;
712 seqState->dumps = dumps;
Yann Colletfb810d62016-01-28 00:18:06 +0100713
Yann Collet7d8e6bd2016-02-02 17:30:37 +0100714#if 0 /* debug */
Yann Colletfb810d62016-01-28 00:18:06 +0100715 {
716 static U64 totalDecoded = 0;
717 printf("pos %6u : %3u literals & match %3u bytes at distance %6u \n",
718 (U32)(totalDecoded), (U32)litLength, (U32)matchLength, (U32)offset);
719 totalDecoded += litLength + matchLength;
720 }
721#endif
Yann Collet5be2dd22015-11-11 13:43:58 +0100722}
723
724
Yann Collet5b78d2f2015-11-12 15:36:05 +0100725FORCE_INLINE size_t ZSTD_execSequence(BYTE* op,
Yann Colletb3a2af92015-11-19 17:13:19 +0100726 BYTE* const oend, seq_t sequence,
Yann Collet5be2dd22015-11-11 13:43:58 +0100727 const BYTE** litPtr, const BYTE* const litLimit_8,
Yann Collet417890c2015-12-04 17:16:37 +0100728 const BYTE* const base, const BYTE* const vBase, const BYTE* const dictEnd)
Yann Collet5be2dd22015-11-11 13:43:58 +0100729{
Yann Colletb3a2af92015-11-19 17:13:19 +0100730 static const int dec32table[] = { 0, 1, 2, 1, 4, 4, 4, 4 }; /* added */
731 static const int dec64table[] = { 8, 8, 8, 7, 8, 9,10,11 }; /* substracted */
Yann Collet5be2dd22015-11-11 13:43:58 +0100732 BYTE* const oLitEnd = op + sequence.litLength;
Yann Colletb3a2af92015-11-19 17:13:19 +0100733 const size_t sequenceLength = sequence.litLength + sequence.matchLength;
734 BYTE* const oMatchEnd = op + sequenceLength; /* risk : address space overflow (32-bits) */
Yann Collet5be2dd22015-11-11 13:43:58 +0100735 BYTE* const oend_8 = oend-8;
736 const BYTE* const litEnd = *litPtr + sequence.litLength;
Yann Colletb3a2af92015-11-19 17:13:19 +0100737 const BYTE* match = oLitEnd - sequence.offset;
Yann Collet5be2dd22015-11-11 13:43:58 +0100738
739 /* check */
740 if (oLitEnd > oend_8) return ERROR(dstSize_tooSmall); /* last match must start at a minimum distance of 8 from oend */
741 if (oMatchEnd > oend) return ERROR(dstSize_tooSmall); /* overwrite beyond dst buffer */
742 if (litEnd > litLimit_8) return ERROR(corruption_detected); /* risk read beyond lit buffer */
743
744 /* copy Literals */
745 ZSTD_wildcopy(op, *litPtr, sequence.litLength); /* note : oLitEnd <= oend-8 : no risk of overwrite beyond oend */
746 op = oLitEnd;
747 *litPtr = litEnd; /* update for next sequence */
748
749 /* copy Match */
Yann Collet7b51a292016-01-26 15:58:49 +0100750 if (sequence.offset > (size_t)(oLitEnd - base)) {
Yann Collet44287a32015-11-30 23:13:56 +0100751 /* offset beyond prefix */
Yann Collet9f5ab1a2015-12-11 00:27:41 +0100752 if (sequence.offset > (size_t)(oLitEnd - vBase))
753 return ERROR(corruption_detected);
Yann Collet44287a32015-11-30 23:13:56 +0100754 match = dictEnd - (base-match);
Yann Collet7b51a292016-01-26 15:58:49 +0100755 if (match + sequence.matchLength <= dictEnd) {
Yann Collet4bfe4152015-12-06 13:18:37 +0100756 memmove(oLitEnd, match, sequence.matchLength);
Yann Collet44287a32015-11-30 23:13:56 +0100757 return sequenceLength;
758 }
759 /* span extDict & currentPrefixSegment */
760 {
761 size_t length1 = dictEnd - match;
Yann Collet4bfe4152015-12-06 13:18:37 +0100762 memmove(oLitEnd, match, length1);
Yann Collet44287a32015-11-30 23:13:56 +0100763 op = oLitEnd + length1;
764 sequence.matchLength -= length1;
765 match = base;
Yann Colletfb810d62016-01-28 00:18:06 +0100766 } }
Yann Collet0f366c62015-11-12 16:19:30 +0100767
Yann Collet44287a32015-11-30 23:13:56 +0100768 /* match within prefix */
Yann Collet7b51a292016-01-26 15:58:49 +0100769 if (sequence.offset < 8) {
Yann Collet44287a32015-11-30 23:13:56 +0100770 /* close range match, overlap */
771 const int sub2 = dec64table[sequence.offset];
772 op[0] = match[0];
773 op[1] = match[1];
774 op[2] = match[2];
775 op[3] = match[3];
776 match += dec32table[sequence.offset];
777 ZSTD_copy4(op+4, match);
778 match -= sub2;
Yann Colletfb810d62016-01-28 00:18:06 +0100779 } else {
Yann Collet44287a32015-11-30 23:13:56 +0100780 ZSTD_copy8(op, match);
781 }
782 op += 8; match += 8;
Yann Collet5be2dd22015-11-11 13:43:58 +0100783
inikepa4dde252016-03-01 14:14:35 +0100784 if (oMatchEnd > oend-(16-3)) { // 3 = MINMATCH
Yann Collet7b51a292016-01-26 15:58:49 +0100785 if (op < oend_8) {
Yann Collet44287a32015-11-30 23:13:56 +0100786 ZSTD_wildcopy(op, match, oend_8 - op);
787 match += oend_8 - op;
788 op = oend_8;
789 }
Yann Colletfb810d62016-01-28 00:18:06 +0100790 while (op < oMatchEnd)
791 *op++ = *match++;
792 } else {
Yann Collet44287a32015-11-30 23:13:56 +0100793 ZSTD_wildcopy(op, match, sequence.matchLength-8); /* works even if matchLength < 8 */
794 }
795 return sequenceLength;
Yann Collet5be2dd22015-11-11 13:43:58 +0100796}
797
Yann Colletb3a2af92015-11-19 17:13:19 +0100798
Yann Collet5be2dd22015-11-11 13:43:58 +0100799static size_t ZSTD_decompressSequences(
Yann Collet5b78d2f2015-11-12 15:36:05 +0100800 ZSTD_DCtx* dctx,
Yann Collet5be2dd22015-11-11 13:43:58 +0100801 void* dst, size_t maxDstSize,
802 const void* seqStart, size_t seqSize)
803{
Yann Collet5be2dd22015-11-11 13:43:58 +0100804 const BYTE* ip = (const BYTE*)seqStart;
805 const BYTE* const iend = ip + seqSize;
806 BYTE* const ostart = (BYTE* const)dst;
807 BYTE* op = ostart;
808 BYTE* const oend = ostart + maxDstSize;
809 size_t errorCode, dumpsLength;
810 const BYTE* litPtr = dctx->litPtr;
811 const BYTE* const litLimit_8 = litPtr + dctx->litBufSize - 8;
812 const BYTE* const litEnd = litPtr + dctx->litSize;
813 int nbSeq;
814 const BYTE* dumps;
815 U32* DTableLL = dctx->LLTable;
816 U32* DTableML = dctx->MLTable;
817 U32* DTableOffb = dctx->OffTable;
Yann Collet417890c2015-12-04 17:16:37 +0100818 const BYTE* const base = (const BYTE*) (dctx->base);
819 const BYTE* const vBase = (const BYTE*) (dctx->vBase);
820 const BYTE* const dictEnd = (const BYTE*) (dctx->dictEnd);
Yann Collet0e491c02016-03-11 21:58:04 +0100821 const U32 mls = dctx->fParams.mml;
Yann Collet5be2dd22015-11-11 13:43:58 +0100822
823 /* Build Decoding Tables */
824 errorCode = ZSTD_decodeSeqHeaders(&nbSeq, &dumps, &dumpsLength,
825 DTableLL, DTableML, DTableOffb,
Yann Colletfb810d62016-01-28 00:18:06 +0100826 ip, seqSize);
Yann Collet5be2dd22015-11-11 13:43:58 +0100827 if (ZSTD_isError(errorCode)) return errorCode;
828 ip += errorCode;
829
830 /* Regen sequences */
Yann Collete93d6ce2016-01-31 00:58:06 +0100831 if (nbSeq) {
Yann Collet5be2dd22015-11-11 13:43:58 +0100832 seq_t sequence;
833 seqState_t seqState;
834
835 memset(&sequence, 0, sizeof(sequence));
Yann Collet61e16ce2016-01-31 02:04:15 +0100836 sequence.offset = REPCODE_STARTVALUE;
Yann Collet5be2dd22015-11-11 13:43:58 +0100837 seqState.dumps = dumps;
838 seqState.dumpsEnd = dumps + dumpsLength;
Yann Collet61e16ce2016-01-31 02:04:15 +0100839 seqState.prevOffset = REPCODE_STARTVALUE;
Yann Collet5be2dd22015-11-11 13:43:58 +0100840 errorCode = BIT_initDStream(&(seqState.DStream), ip, iend-ip);
841 if (ERR_isError(errorCode)) return ERROR(corruption_detected);
842 FSE_initDState(&(seqState.stateLL), &(seqState.DStream), DTableLL);
843 FSE_initDState(&(seqState.stateOffb), &(seqState.DStream), DTableOffb);
844 FSE_initDState(&(seqState.stateML), &(seqState.DStream), DTableML);
845
Yann Collet7b51a292016-01-26 15:58:49 +0100846 for ( ; (BIT_reloadDStream(&(seqState.DStream)) <= BIT_DStream_completed) && nbSeq ; ) {
Yann Colletb3a2af92015-11-19 17:13:19 +0100847 size_t oneSeqSize;
848 nbSeq--;
inikep6b3739c2016-02-22 15:53:42 +0100849 ZSTD_decodeSequence(&sequence, &seqState, mls);
Yann Colletb3a2af92015-11-19 17:13:19 +0100850 oneSeqSize = ZSTD_execSequence(op, oend, sequence, &litPtr, litLimit_8, base, vBase, dictEnd);
Yann Collet370b08e2016-03-08 00:03:59 +0100851 if (ZSTD_isError(oneSeqSize))
852 return oneSeqSize;
Yann Collet5be2dd22015-11-11 13:43:58 +0100853 op += oneSeqSize;
854 }
855
856 /* check if reached exact end */
Yann Collet35f7de52016-01-31 02:51:03 +0100857 if (nbSeq) return ERROR(corruption_detected);
Yann Collete93d6ce2016-01-31 00:58:06 +0100858 }
Yann Collet5be2dd22015-11-11 13:43:58 +0100859
Yann Collete93d6ce2016-01-31 00:58:06 +0100860 /* last literal segment */
861 {
862 size_t lastLLSize = litEnd - litPtr;
863 if (litPtr > litEnd) return ERROR(corruption_detected); /* too many literals already used */
864 if (op+lastLLSize > oend) return ERROR(dstSize_tooSmall);
865 memcpy(op, litPtr, lastLLSize);
866 op += lastLLSize;
867 }
Yann Collet5be2dd22015-11-11 13:43:58 +0100868
869 return op-ostart;
870}
871
872
Yann Colletb0125102016-01-09 02:00:10 +0100873static void ZSTD_checkContinuity(ZSTD_DCtx* dctx, const void* dst)
874{
Yann Collet7b51a292016-01-26 15:58:49 +0100875 if (dst != dctx->previousDstEnd) { /* not contiguous */
Yann Colletb0125102016-01-09 02:00:10 +0100876 dctx->dictEnd = dctx->previousDstEnd;
877 dctx->vBase = (const char*)dst - ((const char*)(dctx->previousDstEnd) - (const char*)(dctx->base));
878 dctx->base = dst;
879 dctx->previousDstEnd = dst;
880 }
881}
882
883
884static size_t ZSTD_decompressBlock_internal(ZSTD_DCtx* dctx,
Yann Colletb010b3b2016-02-03 12:39:34 +0100885 void* dst, size_t dstCapacity,
Yann Collet5be2dd22015-11-11 13:43:58 +0100886 const void* src, size_t srcSize)
Yann Colletb010b3b2016-02-03 12:39:34 +0100887{ /* blockType == blockCompressed */
Yann Collet5be2dd22015-11-11 13:43:58 +0100888 const BYTE* ip = (const BYTE*)src;
Yann Colletb010b3b2016-02-03 12:39:34 +0100889 size_t litCSize;
890
Yann Collet569b81a2016-03-16 15:26:51 +0100891 if (srcSize >= ZSTD_BLOCKSIZE_MAX) return ERROR(srcSize_wrong);
Yann Collet5be2dd22015-11-11 13:43:58 +0100892
inikepa4dde252016-03-01 14:14:35 +0100893 ZSTD_LOG_BLOCK("%p: ZSTD_decompressBlock_internal searchLength=%d\n", dctx->base, dctx->params.searchLength);
894
Yann Collet5be2dd22015-11-11 13:43:58 +0100895 /* Decode literals sub-block */
Yann Colletb010b3b2016-02-03 12:39:34 +0100896 litCSize = ZSTD_decodeLiteralsBlock(dctx, src, srcSize);
Yann Collet5be2dd22015-11-11 13:43:58 +0100897 if (ZSTD_isError(litCSize)) return litCSize;
898 ip += litCSize;
899 srcSize -= litCSize;
900
Yann Colletb010b3b2016-02-03 12:39:34 +0100901 return ZSTD_decompressSequences(dctx, dst, dstCapacity, ip, srcSize);
Yann Collet5be2dd22015-11-11 13:43:58 +0100902}
903
904
Yann Colletb0125102016-01-09 02:00:10 +0100905size_t ZSTD_decompressBlock(ZSTD_DCtx* dctx,
Yann Colletb010b3b2016-02-03 12:39:34 +0100906 void* dst, size_t dstCapacity,
Yann Colletb0125102016-01-09 02:00:10 +0100907 const void* src, size_t srcSize)
908{
909 ZSTD_checkContinuity(dctx, dst);
Yann Colletb010b3b2016-02-03 12:39:34 +0100910 return ZSTD_decompressBlock_internal(dctx, dst, dstCapacity, src, srcSize);
Yann Colletb0125102016-01-09 02:00:10 +0100911}
912
913
Yann Collet0e491c02016-03-11 21:58:04 +0100914/*! ZSTD_decompress_continueDCtx() :
915* `dctx` must have been properly initialized */
916static size_t ZSTD_decompressFrame(ZSTD_DCtx* dctx,
Yann Collet31683c02015-12-18 01:26:48 +0100917 void* dst, size_t maxDstSize,
Yann Collet7b51a292016-01-26 15:58:49 +0100918 const void* src, size_t srcSize)
Yann Collet5be2dd22015-11-11 13:43:58 +0100919{
920 const BYTE* ip = (const BYTE*)src;
921 const BYTE* iend = ip + srcSize;
922 BYTE* const ostart = (BYTE* const)dst;
923 BYTE* op = ostart;
924 BYTE* const oend = ostart + maxDstSize;
925 size_t remainingSize = srcSize;
Yann Collet5be2dd22015-11-11 13:43:58 +0100926 blockProperties_t blockProperties;
927
928 /* Frame Header */
Yann Collet88fcd292015-11-25 14:42:45 +0100929 {
Yann Collet03ea59b2016-03-12 01:25:40 +0100930 size_t frameHeaderSize, errorCode;
Yann Collet88fcd292015-11-25 14:42:45 +0100931 if (srcSize < ZSTD_frameHeaderSize_min+ZSTD_blockHeaderSize) return ERROR(srcSize_wrong);
Yann Collet5be2dd22015-11-11 13:43:58 +0100932#if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT==1)
Yann Collet88fcd292015-11-25 14:42:45 +0100933 {
934 const U32 magicNumber = MEM_readLE32(src);
935 if (ZSTD_isLegacy(magicNumber))
936 return ZSTD_decompressLegacy(dst, maxDstSize, src, srcSize, magicNumber);
937 }
Yann Collet5be2dd22015-11-11 13:43:58 +0100938#endif
Yann Collet03ea59b2016-03-12 01:25:40 +0100939 frameHeaderSize = ZSTD_frameHeaderSize(src, ZSTD_frameHeaderSize_min);
Yann Collet88fcd292015-11-25 14:42:45 +0100940 if (ZSTD_isError(frameHeaderSize)) return frameHeaderSize;
941 if (srcSize < frameHeaderSize+ZSTD_blockHeaderSize) return ERROR(srcSize_wrong);
Yann Collet03ea59b2016-03-12 01:25:40 +0100942 errorCode = ZSTD_decodeFrameHeader(dctx, src, frameHeaderSize);
943 if (ZSTD_isError(errorCode)) return errorCode;
Yann Collet88fcd292015-11-25 14:42:45 +0100944 ip += frameHeaderSize; remainingSize -= frameHeaderSize;
Yann Collet88fcd292015-11-25 14:42:45 +0100945 }
Yann Collet5be2dd22015-11-11 13:43:58 +0100946
947 /* Loop on each block */
948 while (1)
949 {
950 size_t decodedSize=0;
951 size_t cBlockSize = ZSTD_getcBlockSize(ip, iend-ip, &blockProperties);
952 if (ZSTD_isError(cBlockSize)) return cBlockSize;
953
954 ip += ZSTD_blockHeaderSize;
955 remainingSize -= ZSTD_blockHeaderSize;
956 if (cBlockSize > remainingSize) return ERROR(srcSize_wrong);
957
958 switch(blockProperties.blockType)
959 {
960 case bt_compressed:
Yann Collet37422192016-01-25 16:54:05 +0100961 decodedSize = ZSTD_decompressBlock_internal(dctx, op, oend-op, ip, cBlockSize);
Yann Collet5be2dd22015-11-11 13:43:58 +0100962 break;
963 case bt_raw :
Yann Collet0f366c62015-11-12 16:19:30 +0100964 decodedSize = ZSTD_copyRawBlock(op, oend-op, ip, cBlockSize);
Yann Collet5be2dd22015-11-11 13:43:58 +0100965 break;
966 case bt_rle :
967 return ERROR(GENERIC); /* not yet supported */
968 break;
969 case bt_end :
970 /* end of frame */
971 if (remainingSize) return ERROR(srcSize_wrong);
972 break;
973 default:
974 return ERROR(GENERIC); /* impossible */
975 }
976 if (cBlockSize == 0) break; /* bt_end */
977
978 if (ZSTD_isError(decodedSize)) return decodedSize;
979 op += decodedSize;
980 ip += cBlockSize;
981 remainingSize -= cBlockSize;
982 }
983
984 return op-ostart;
985}
986
Yann Collet31683c02015-12-18 01:26:48 +0100987
Yann Collet7b51a292016-01-26 15:58:49 +0100988size_t ZSTD_decompress_usingPreparedDCtx(ZSTD_DCtx* dctx, const ZSTD_DCtx* refDCtx,
989 void* dst, size_t maxDstSize,
990 const void* src, size_t srcSize)
991{
992 ZSTD_copyDCtx(dctx, refDCtx);
993 ZSTD_checkContinuity(dctx, dst);
Yann Collet0e491c02016-03-11 21:58:04 +0100994 return ZSTD_decompressFrame(dctx, dst, maxDstSize, src, srcSize);
Yann Collet7b51a292016-01-26 15:58:49 +0100995}
996
997
998size_t ZSTD_decompress_usingDict(ZSTD_DCtx* dctx,
999 void* dst, size_t maxDstSize,
1000 const void* src, size_t srcSize,
1001 const void* dict, size_t dictSize)
1002{
1003 ZSTD_decompressBegin_usingDict(dctx, dict, dictSize);
inikepa4dde252016-03-01 14:14:35 +01001004 ZSTD_LOG_BLOCK("%p: ZSTD_decompressBegin_usingDict searchLength=%d\n", dctx->base, dctx->params.searchLength);
Yann Collet7b51a292016-01-26 15:58:49 +01001005 ZSTD_checkContinuity(dctx, dst);
Yann Collet0e491c02016-03-11 21:58:04 +01001006 return ZSTD_decompressFrame(dctx, dst, maxDstSize, src, srcSize);
Yann Collet7b51a292016-01-26 15:58:49 +01001007}
1008
1009
Yann Collet31683c02015-12-18 01:26:48 +01001010size_t ZSTD_decompressDCtx(ZSTD_DCtx* dctx, void* dst, size_t maxDstSize, const void* src, size_t srcSize)
1011{
1012 return ZSTD_decompress_usingDict(dctx, dst, maxDstSize, src, srcSize, NULL, 0);
1013}
1014
Yann Collet0e491c02016-03-11 21:58:04 +01001015
Yann Collet5be2dd22015-11-11 13:43:58 +01001016size_t ZSTD_decompress(void* dst, size_t maxDstSize, const void* src, size_t srcSize)
1017{
Yann Collet3a3b72f2016-01-11 12:56:11 +01001018#if defined(ZSTD_HEAPMODE) && (ZSTD_HEAPMODE==1)
1019 size_t regenSize;
1020 ZSTD_DCtx* dctx = ZSTD_createDCtx();
1021 if (dctx==NULL) return ERROR(memory_allocation);
1022 regenSize = ZSTD_decompressDCtx(dctx, dst, maxDstSize, src, srcSize);
1023 ZSTD_freeDCtx(dctx);
1024 return regenSize;
1025#else
Yann Collet31683c02015-12-18 01:26:48 +01001026 ZSTD_DCtx dctx;
1027 return ZSTD_decompressDCtx(&dctx, dst, maxDstSize, src, srcSize);
Yann Colleta768a302016-01-21 16:04:35 +01001028#endif
Yann Collet5be2dd22015-11-11 13:43:58 +01001029}
1030
1031
Yann Collet346bffb2016-03-15 15:24:52 +01001032/*_******************************
Yann Collet5be2dd22015-11-11 13:43:58 +01001033* Streaming Decompression API
1034********************************/
Yann Collet5be2dd22015-11-11 13:43:58 +01001035size_t ZSTD_nextSrcSizeToDecompress(ZSTD_DCtx* dctx)
1036{
1037 return dctx->expected;
1038}
1039
Yann Collet37422192016-01-25 16:54:05 +01001040size_t ZSTD_decompressContinue(ZSTD_DCtx* dctx, void* dst, size_t maxDstSize, const void* src, size_t srcSize)
Yann Collet5be2dd22015-11-11 13:43:58 +01001041{
1042 /* Sanity check */
Yann Collet37422192016-01-25 16:54:05 +01001043 if (srcSize != dctx->expected) return ERROR(srcSize_wrong);
1044 ZSTD_checkContinuity(dctx, dst);
Yann Collet5be2dd22015-11-11 13:43:58 +01001045
Yann Collet88fcd292015-11-25 14:42:45 +01001046 /* Decompress : frame header; part 1 */
Yann Collet37422192016-01-25 16:54:05 +01001047 switch (dctx->stage)
Yann Collet5be2dd22015-11-11 13:43:58 +01001048 {
Yann Collet88fcd292015-11-25 14:42:45 +01001049 case ZSTDds_getFrameHeaderSize :
Yann Collet5be2dd22015-11-11 13:43:58 +01001050 {
Yann Collet88fcd292015-11-25 14:42:45 +01001051 /* get frame header size */
1052 if (srcSize != ZSTD_frameHeaderSize_min) return ERROR(srcSize_wrong); /* impossible */
Yann Collet03ea59b2016-03-12 01:25:40 +01001053 dctx->headerSize = ZSTD_frameHeaderSize(src, ZSTD_frameHeaderSize_min);
Yann Collet37422192016-01-25 16:54:05 +01001054 if (ZSTD_isError(dctx->headerSize)) return dctx->headerSize;
1055 memcpy(dctx->headerBuffer, src, ZSTD_frameHeaderSize_min);
Yann Collet7b51a292016-01-26 15:58:49 +01001056 if (dctx->headerSize > ZSTD_frameHeaderSize_min) {
Yann Collet37422192016-01-25 16:54:05 +01001057 dctx->expected = dctx->headerSize - ZSTD_frameHeaderSize_min;
1058 dctx->stage = ZSTDds_decodeFrameHeader;
Yann Collet88fcd292015-11-25 14:42:45 +01001059 return 0;
1060 }
Yann Collet37422192016-01-25 16:54:05 +01001061 dctx->expected = 0; /* not necessary to copy more */
Yann Collet5be2dd22015-11-11 13:43:58 +01001062 }
Yann Collet88fcd292015-11-25 14:42:45 +01001063 case ZSTDds_decodeFrameHeader:
Yann Collet5be2dd22015-11-11 13:43:58 +01001064 {
Yann Collet88fcd292015-11-25 14:42:45 +01001065 /* get frame header */
1066 size_t result;
Yann Collet37422192016-01-25 16:54:05 +01001067 memcpy(dctx->headerBuffer + ZSTD_frameHeaderSize_min, src, dctx->expected);
Yann Collet03ea59b2016-03-12 01:25:40 +01001068 result = ZSTD_decodeFrameHeader(dctx, dctx->headerBuffer, dctx->headerSize);
Yann Collet88fcd292015-11-25 14:42:45 +01001069 if (ZSTD_isError(result)) return result;
Yann Collet37422192016-01-25 16:54:05 +01001070 dctx->expected = ZSTD_blockHeaderSize;
1071 dctx->stage = ZSTDds_decodeBlockHeader;
Yann Collet88fcd292015-11-25 14:42:45 +01001072 return 0;
Yann Collet5be2dd22015-11-11 13:43:58 +01001073 }
Yann Collet88fcd292015-11-25 14:42:45 +01001074 case ZSTDds_decodeBlockHeader:
Yann Collet5be2dd22015-11-11 13:43:58 +01001075 {
Yann Collet88fcd292015-11-25 14:42:45 +01001076 /* Decode block header */
1077 blockProperties_t bp;
1078 size_t blockSize = ZSTD_getcBlockSize(src, ZSTD_blockHeaderSize, &bp);
1079 if (ZSTD_isError(blockSize)) return blockSize;
Yann Collet7b51a292016-01-26 15:58:49 +01001080 if (bp.blockType == bt_end) {
Yann Collet37422192016-01-25 16:54:05 +01001081 dctx->expected = 0;
1082 dctx->stage = ZSTDds_getFrameHeaderSize;
Yann Collet88fcd292015-11-25 14:42:45 +01001083 }
Yann Collet7b51a292016-01-26 15:58:49 +01001084 else {
Yann Collet37422192016-01-25 16:54:05 +01001085 dctx->expected = blockSize;
1086 dctx->bType = bp.blockType;
1087 dctx->stage = ZSTDds_decompressBlock;
Yann Collet88fcd292015-11-25 14:42:45 +01001088 }
Yann Collet88fcd292015-11-25 14:42:45 +01001089 return 0;
1090 }
Yann Collet417890c2015-12-04 17:16:37 +01001091 case ZSTDds_decompressBlock:
Yann Collet88fcd292015-11-25 14:42:45 +01001092 {
1093 /* Decompress : block content */
1094 size_t rSize;
Yann Collet37422192016-01-25 16:54:05 +01001095 switch(dctx->bType)
Yann Collet88fcd292015-11-25 14:42:45 +01001096 {
1097 case bt_compressed:
Yann Collet37422192016-01-25 16:54:05 +01001098 rSize = ZSTD_decompressBlock_internal(dctx, dst, maxDstSize, src, srcSize);
Yann Collet88fcd292015-11-25 14:42:45 +01001099 break;
1100 case bt_raw :
1101 rSize = ZSTD_copyRawBlock(dst, maxDstSize, src, srcSize);
1102 break;
1103 case bt_rle :
1104 return ERROR(GENERIC); /* not yet handled */
1105 break;
1106 case bt_end : /* should never happen (filtered at phase 1) */
1107 rSize = 0;
1108 break;
1109 default:
Yann Collet7b51a292016-01-26 15:58:49 +01001110 return ERROR(GENERIC); /* impossible */
Yann Collet88fcd292015-11-25 14:42:45 +01001111 }
Yann Collet37422192016-01-25 16:54:05 +01001112 dctx->stage = ZSTDds_decodeBlockHeader;
1113 dctx->expected = ZSTD_blockHeaderSize;
1114 dctx->previousDstEnd = (char*)dst + rSize;
Yann Collet88fcd292015-11-25 14:42:45 +01001115 return rSize;
1116 }
1117 default:
1118 return ERROR(GENERIC); /* impossible */
1119 }
Yann Collet5be2dd22015-11-11 13:43:58 +01001120}
1121
1122
Yann Colletb923f652016-01-26 03:14:20 +01001123static void ZSTD_refDictContent(ZSTD_DCtx* dctx, const void* dict, size_t dictSize)
Yann Collet417890c2015-12-04 17:16:37 +01001124{
Yann Collet37422192016-01-25 16:54:05 +01001125 dctx->dictEnd = dctx->previousDstEnd;
1126 dctx->vBase = (const char*)dict - ((const char*)(dctx->previousDstEnd) - (const char*)(dctx->base));
1127 dctx->base = dict;
1128 dctx->previousDstEnd = (const char*)dict + dictSize;
Yann Collet417890c2015-12-04 17:16:37 +01001129}
Yann Colletb923f652016-01-26 03:14:20 +01001130
Yann Colletb923f652016-01-26 03:14:20 +01001131static size_t ZSTD_loadEntropy(ZSTD_DCtx* dctx, const void* dict, size_t dictSize)
1132{
Yann Colletfb810d62016-01-28 00:18:06 +01001133 size_t hSize, offcodeHeaderSize, matchlengthHeaderSize, errorCode, litlengthHeaderSize;
1134 short offcodeNCount[MaxOff+1];
1135 U32 offcodeMaxValue=MaxOff, offcodeLog=OffFSELog;
1136 short matchlengthNCount[MaxML+1];
1137 unsigned matchlengthMaxValue = MaxML, matchlengthLog = MLFSELog;
1138 short litlengthNCount[MaxLL+1];
1139 unsigned litlengthMaxValue = MaxLL, litlengthLog = LLFSELog;
1140
1141 hSize = HUF_readDTableX4(dctx->hufTableX4, dict, dictSize);
Yann Colletb923f652016-01-26 03:14:20 +01001142 if (HUF_isError(hSize)) return ERROR(dictionary_corrupted);
Yann Colletfb810d62016-01-28 00:18:06 +01001143 dict = (const char*)dict + hSize;
1144 dictSize -= hSize;
1145
1146 offcodeHeaderSize = FSE_readNCount(offcodeNCount, &offcodeMaxValue, &offcodeLog, dict, dictSize);
1147 if (FSE_isError(offcodeHeaderSize)) return ERROR(dictionary_corrupted);
1148 errorCode = FSE_buildDTable(dctx->OffTable, offcodeNCount, offcodeMaxValue, offcodeLog);
1149 if (FSE_isError(errorCode)) return ERROR(dictionary_corrupted);
1150 dict = (const char*)dict + offcodeHeaderSize;
1151 dictSize -= offcodeHeaderSize;
1152
1153 matchlengthHeaderSize = FSE_readNCount(matchlengthNCount, &matchlengthMaxValue, &matchlengthLog, dict, dictSize);
1154 if (FSE_isError(matchlengthHeaderSize)) return ERROR(dictionary_corrupted);
1155 errorCode = FSE_buildDTable(dctx->MLTable, matchlengthNCount, matchlengthMaxValue, matchlengthLog);
1156 if (FSE_isError(errorCode)) return ERROR(dictionary_corrupted);
1157 dict = (const char*)dict + matchlengthHeaderSize;
1158 dictSize -= matchlengthHeaderSize;
1159
1160 litlengthHeaderSize = FSE_readNCount(litlengthNCount, &litlengthMaxValue, &litlengthLog, dict, dictSize);
1161 if (FSE_isError(litlengthHeaderSize)) return ERROR(dictionary_corrupted);
1162 errorCode = FSE_buildDTable(dctx->LLTable, litlengthNCount, litlengthMaxValue, litlengthLog);
1163 if (FSE_isError(errorCode)) return ERROR(dictionary_corrupted);
1164
1165 dctx->flagStaticTables = 1;
1166 return hSize + offcodeHeaderSize + matchlengthHeaderSize + litlengthHeaderSize;
Yann Colletb923f652016-01-26 03:14:20 +01001167}
1168
Yann Collet7b51a292016-01-26 15:58:49 +01001169static size_t ZSTD_decompress_insertDictionary(ZSTD_DCtx* dctx, const void* dict, size_t dictSize)
Yann Colletb923f652016-01-26 03:14:20 +01001170{
1171 size_t eSize;
1172 U32 magic = MEM_readLE32(dict);
1173 if (magic != ZSTD_DICT_MAGIC) {
1174 /* pure content mode */
1175 ZSTD_refDictContent(dctx, dict, dictSize);
1176 return 0;
1177 }
1178 /* load entropy tables */
1179 dict = (const char*)dict + 4;
1180 dictSize -= 4;
1181 eSize = ZSTD_loadEntropy(dctx, dict, dictSize);
1182 if (ZSTD_isError(eSize)) return ERROR(dictionary_corrupted);
1183
1184 /* reference dictionary content */
1185 dict = (const char*)dict + eSize;
1186 dictSize -= eSize;
1187 ZSTD_refDictContent(dctx, dict, dictSize);
1188
1189 return 0;
1190}
1191
Yann Collet7b51a292016-01-26 15:58:49 +01001192
1193size_t ZSTD_decompressBegin_usingDict(ZSTD_DCtx* dctx, const void* dict, size_t dictSize)
1194{
1195 size_t errorCode;
1196 errorCode = ZSTD_decompressBegin(dctx);
1197 if (ZSTD_isError(errorCode)) return errorCode;
1198
1199 if (dict && dictSize) {
1200 errorCode = ZSTD_decompress_insertDictionary(dctx, dict, dictSize);
1201 if (ZSTD_isError(errorCode)) return ERROR(dictionary_corrupted);
1202 }
1203
1204 return 0;
1205}
1206