extzstd 0.0.1.CONCEPT → 0.0.2.CONCEPT
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +27 -15
- data/Rakefile +19 -8
- data/contrib/zstd/Makefile +5 -4
- data/contrib/zstd/fse.c +1528 -583
- data/contrib/zstd/fse.h +167 -227
- data/contrib/zstd/fse_static.h +197 -23
- data/contrib/zstd/zstd.c +594 -627
- data/contrib/zstd/zstd.h +7 -16
- data/contrib/zstd/zstd_static.h +24 -15
- data/ext/extconf.rb +6 -1
- data/ext/extzstd-stream.c +238 -59
- data/ext/extzstd.c +77 -18
- data/ext/extzstd.h +29 -2
- data/gemstub.rb +3 -3
- data/lib/extzstd.rb +127 -1
- data/lib/extzstd/version.rb +1 -3
- metadata +13 -7
data/contrib/zstd/fse_static.h
CHANGED
@@ -40,24 +40,32 @@ extern "C" {
|
|
40
40
|
|
41
41
|
|
42
42
|
/******************************************
|
43
|
-
*
|
43
|
+
* FSE API compatible with DLL
|
44
44
|
******************************************/
|
45
|
-
#
|
46
|
-
#define FSE_COMPRESSBOUND(size) (size + (size>>7) + FSE_MAX_HEADERSIZE) /* Macro can be useful for static allocation */
|
45
|
+
#include "fse.h"
|
47
46
|
|
48
47
|
|
49
48
|
/******************************************
|
50
49
|
* Static allocation
|
51
50
|
******************************************/
|
52
|
-
/*
|
51
|
+
/* FSE buffer bounds */
|
52
|
+
#define FSE_NCOUNTBOUND 512
|
53
|
+
#define FSE_BLOCKBOUND(size) (size + (size>>7))
|
54
|
+
#define FSE_COMPRESSBOUND(size) (FSE_NCOUNTBOUND + FSE_BLOCKBOUND(size)) /* Macro version, useful for static allocation */
|
55
|
+
|
56
|
+
/* You can statically allocate FSE CTable/DTable as a table of unsigned using below macro */
|
53
57
|
#define FSE_CTABLE_SIZE_U32(maxTableLog, maxSymbolValue) (1 + (1<<(maxTableLog-1)) + ((maxSymbolValue+1)*2))
|
54
|
-
#define FSE_DTABLE_SIZE_U32(maxTableLog) ((1<<maxTableLog)
|
58
|
+
#define FSE_DTABLE_SIZE_U32(maxTableLog) (1 + (1<<maxTableLog))
|
55
59
|
|
60
|
+
/* Huff0 buffer bounds */
|
61
|
+
#define HUF_CTABLEBOUND 129
|
62
|
+
#define HUF_BLOCKBOUND(size) (size + (size>>8) + 8) /* only true if pre-filtered with fast heuristic */
|
63
|
+
#define HUF_COMPRESSBOUND(size) (HUF_CTABLEBOUND + HUF_BLOCKBOUND(size)) /* Macro version, useful for static allocation */
|
56
64
|
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
65
|
+
/* You can statically allocate Huff0 DTable as a table of unsigned short using below macro */
|
66
|
+
#define HUF_DTABLE_SIZE_U16(maxTableLog) (1 + (1<<maxTableLog))
|
67
|
+
#define HUF_CREATE_STATIC_DTABLE(DTable, maxTableLog) \
|
68
|
+
unsigned short DTable[HUF_DTABLE_SIZE_U16(maxTableLog)] = { maxTableLog }
|
61
69
|
|
62
70
|
|
63
71
|
/******************************************
|
@@ -65,7 +73,7 @@ extern "C" {
|
|
65
73
|
******************************************/
|
66
74
|
#define FSE_LIST_ERRORS(ITEM) \
|
67
75
|
ITEM(FSE_OK_NoError) ITEM(FSE_ERROR_GENERIC) \
|
68
|
-
ITEM(FSE_ERROR_tableLog_tooLarge) ITEM(FSE_ERROR_maxSymbolValue_tooLarge) \
|
76
|
+
ITEM(FSE_ERROR_tableLog_tooLarge) ITEM(FSE_ERROR_maxSymbolValue_tooLarge) ITEM(FSE_ERROR_maxSymbolValue_tooSmall) \
|
69
77
|
ITEM(FSE_ERROR_dstSize_tooSmall) ITEM(FSE_ERROR_srcSize_wrong)\
|
70
78
|
ITEM(FSE_ERROR_corruptionDetected) \
|
71
79
|
ITEM(FSE_ERROR_maxCode)
|
@@ -77,30 +85,196 @@ typedef enum { FSE_LIST_ERRORS(FSE_GENERATE_ENUM) } FSE_errorCodes; /* enum is
|
|
77
85
|
/******************************************
|
78
86
|
* FSE advanced API
|
79
87
|
******************************************/
|
80
|
-
size_t FSE_countFast(unsigned* count, const unsigned char* src, size_t srcSize
|
81
|
-
/* same as FSE_count(), but
|
88
|
+
size_t FSE_countFast(unsigned* count, unsigned* maxSymbolValuePtr, const unsigned char* src, size_t srcSize);
|
89
|
+
/* same as FSE_count(), but blindly trust that all values within src are <= maxSymbolValuePtr[0] */
|
82
90
|
|
83
|
-
size_t FSE_buildCTable_raw (
|
84
|
-
/*
|
91
|
+
size_t FSE_buildCTable_raw (FSE_CTable* ct, unsigned nbBits);
|
92
|
+
/* build a fake FSE_CTable, designed to not compress an input, where each symbol uses nbBits */
|
85
93
|
|
86
|
-
size_t FSE_buildCTable_rle (
|
87
|
-
/*
|
94
|
+
size_t FSE_buildCTable_rle (FSE_CTable* ct, unsigned char symbolValue);
|
95
|
+
/* build a fake FSE_CTable, designed to compress always the same symbolValue */
|
88
96
|
|
89
|
-
size_t FSE_buildDTable_raw (
|
90
|
-
/*
|
97
|
+
size_t FSE_buildDTable_raw (FSE_DTable* dt, unsigned nbBits);
|
98
|
+
/* build a fake FSE_DTable, designed to read an uncompressed bitstream where each symbol uses nbBits */
|
91
99
|
|
92
|
-
size_t FSE_buildDTable_rle (
|
93
|
-
/*
|
100
|
+
size_t FSE_buildDTable_rle (FSE_DTable* dt, unsigned char symbolValue);
|
101
|
+
/* build a fake FSE_DTable, designed to always generate the same symbolValue */
|
94
102
|
|
95
103
|
|
96
104
|
/******************************************
|
97
|
-
* FSE
|
105
|
+
* FSE symbol compression API
|
98
106
|
******************************************/
|
99
|
-
|
107
|
+
/*
|
108
|
+
This API consists of small unitary functions, which highly benefit from being inlined.
|
109
|
+
You will want to enable link-time-optimization to ensure these functions are properly inlined in your binary.
|
110
|
+
Visual seems to do it automatically.
|
111
|
+
For gcc or clang, you'll need to add -flto flag at compilation and linking stages.
|
112
|
+
If none of these solutions is applicable, include "fse.c" directly.
|
113
|
+
*/
|
114
|
+
|
115
|
+
typedef struct
|
116
|
+
{
|
117
|
+
size_t bitContainer;
|
118
|
+
int bitPos;
|
119
|
+
char* startPtr;
|
120
|
+
char* ptr;
|
121
|
+
char* endPtr;
|
122
|
+
} FSE_CStream_t;
|
123
|
+
|
124
|
+
typedef struct
|
125
|
+
{
|
126
|
+
ptrdiff_t value;
|
127
|
+
const void* stateTable;
|
128
|
+
const void* symbolTT;
|
129
|
+
unsigned stateLog;
|
130
|
+
} FSE_CState_t;
|
131
|
+
|
132
|
+
size_t FSE_initCStream(FSE_CStream_t* bitC, void* dstBuffer, size_t maxDstSize);
|
133
|
+
void FSE_initCState(FSE_CState_t* CStatePtr, const FSE_CTable* ct);
|
134
|
+
|
135
|
+
void FSE_encodeSymbol(FSE_CStream_t* bitC, FSE_CState_t* CStatePtr, unsigned symbol);
|
136
|
+
void FSE_addBits(FSE_CStream_t* bitC, size_t value, unsigned nbBits);
|
137
|
+
void FSE_flushBits(FSE_CStream_t* bitC);
|
138
|
+
|
139
|
+
void FSE_flushCState(FSE_CStream_t* bitC, const FSE_CState_t* CStatePtr);
|
140
|
+
size_t FSE_closeCStream(FSE_CStream_t* bitC);
|
141
|
+
|
142
|
+
/*
|
143
|
+
These functions are inner components of FSE_compress_usingCTable().
|
144
|
+
They allow the creation of custom streams, mixing multiple tables and bit sources.
|
145
|
+
|
146
|
+
A key property to keep in mind is that encoding and decoding are done **in reverse direction**.
|
147
|
+
So the first symbol you will encode is the last you will decode, like a LIFO stack.
|
148
|
+
|
149
|
+
You will need a few variables to track your CStream. They are :
|
150
|
+
|
151
|
+
FSE_CTable ct; // Provided by FSE_buildCTable()
|
152
|
+
FSE_CStream_t bitStream; // bitStream tracking structure
|
153
|
+
FSE_CState_t state; // State tracking structure (can have several)
|
154
|
+
|
155
|
+
|
156
|
+
The first thing to do is to init bitStream and state.
|
157
|
+
size_t errorCode = FSE_initCStream(&bitStream, dstBuffer, maxDstSize);
|
158
|
+
FSE_initCState(&state, ct);
|
159
|
+
|
160
|
+
Note that FSE_initCStream() can produce an error code, so its result should be tested, using FSE_isError();
|
161
|
+
You can then encode your input data, byte after byte.
|
162
|
+
FSE_encodeSymbol() outputs a maximum of 'tableLog' bits at a time.
|
163
|
+
Remember decoding will be done in reverse direction.
|
164
|
+
FSE_encodeByte(&bitStream, &state, symbol);
|
165
|
+
|
166
|
+
At any time, you can also add any bit sequence.
|
167
|
+
Note : maximum allowed nbBits is 25, for compatibility with 32-bits decoders
|
168
|
+
FSE_addBits(&bitStream, bitField, nbBits);
|
169
|
+
|
170
|
+
The above methods don't commit data to memory, they just store it into local register, for speed.
|
171
|
+
Local register size is 64-bits on 64-bits systems, 32-bits on 32-bits systems (size_t).
|
172
|
+
Writing data to memory is a manual operation, performed by the flushBits function.
|
173
|
+
FSE_flushBits(&bitStream);
|
174
|
+
|
175
|
+
Your last FSE encoding operation shall be to flush your last state value(s).
|
176
|
+
FSE_flushState(&bitStream, &state);
|
177
|
+
|
178
|
+
Finally, you must close the bitStream.
|
179
|
+
The function returns the size of CStream in bytes.
|
180
|
+
If data couldn't fit into dstBuffer, it will return a 0 ( == not compressible)
|
181
|
+
If there is an error, it returns an errorCode (which can be tested using FSE_isError()).
|
182
|
+
size_t size = FSE_closeCStream(&bitStream);
|
183
|
+
*/
|
184
|
+
|
185
|
+
|
186
|
+
/******************************************
|
187
|
+
* FSE symbol decompression API
|
188
|
+
******************************************/
|
189
|
+
typedef struct
|
190
|
+
{
|
191
|
+
size_t bitContainer;
|
192
|
+
unsigned bitsConsumed;
|
193
|
+
const char* ptr;
|
194
|
+
const char* start;
|
195
|
+
} FSE_DStream_t;
|
196
|
+
|
197
|
+
typedef struct
|
198
|
+
{
|
199
|
+
size_t state;
|
200
|
+
const void* table; /* precise table may vary, depending on U16 */
|
201
|
+
} FSE_DState_t;
|
202
|
+
|
203
|
+
|
204
|
+
size_t FSE_initDStream(FSE_DStream_t* bitD, const void* srcBuffer, size_t srcSize);
|
205
|
+
void FSE_initDState(FSE_DState_t* DStatePtr, FSE_DStream_t* bitD, const FSE_DTable* dt);
|
206
|
+
|
207
|
+
unsigned char FSE_decodeSymbol(FSE_DState_t* DStatePtr, FSE_DStream_t* bitD);
|
208
|
+
size_t FSE_readBits(FSE_DStream_t* bitD, unsigned nbBits);
|
209
|
+
unsigned int FSE_reloadDStream(FSE_DStream_t* bitD);
|
210
|
+
|
211
|
+
unsigned FSE_endOfDStream(const FSE_DStream_t* bitD);
|
212
|
+
unsigned FSE_endOfDState(const FSE_DState_t* DStatePtr);
|
213
|
+
|
214
|
+
typedef enum { FSE_DStream_unfinished = 0,
|
215
|
+
FSE_DStream_endOfBuffer = 1,
|
216
|
+
FSE_DStream_completed = 2,
|
217
|
+
FSE_DStream_tooFar = 3 } FSE_DStream_status; /* result of FSE_reloadDStream() */
|
218
|
+
/* 1,2,4,8 would be better for bitmap combinations, but slows down performance a bit ... ?! */
|
219
|
+
|
220
|
+
/*
|
221
|
+
Let's now decompose FSE_decompress_usingDTable() into its unitary components.
|
222
|
+
You will decode FSE-encoded symbols from the bitStream,
|
223
|
+
and also any other bitFields you put in, **in reverse order**.
|
224
|
+
|
225
|
+
You will need a few variables to track your bitStream. They are :
|
226
|
+
|
227
|
+
FSE_DStream_t DStream; // Stream context
|
228
|
+
FSE_DState_t DState; // State context. Multiple ones are possible
|
229
|
+
FSE_DTable* DTablePtr; // Decoding table, provided by FSE_buildDTable()
|
230
|
+
|
231
|
+
The first thing to do is to init the bitStream.
|
232
|
+
errorCode = FSE_initDStream(&DStream, srcBuffer, srcSize);
|
233
|
+
|
234
|
+
You should then retrieve your initial state(s)
|
235
|
+
(in reverse flushing order if you have several ones) :
|
236
|
+
errorCode = FSE_initDState(&DState, &DStream, DTablePtr);
|
237
|
+
|
238
|
+
You can then decode your data, symbol after symbol.
|
239
|
+
For information the maximum number of bits read by FSE_decodeSymbol() is 'tableLog'.
|
240
|
+
Keep in mind that symbols are decoded in reverse order, like a LIFO stack (last in, first out).
|
241
|
+
unsigned char symbol = FSE_decodeSymbol(&DState, &DStream);
|
242
|
+
|
243
|
+
You can retrieve any bitfield you eventually stored into the bitStream (in reverse order)
|
244
|
+
Note : maximum allowed nbBits is 25, for 32-bits compatibility
|
245
|
+
size_t bitField = FSE_readBits(&DStream, nbBits);
|
246
|
+
|
247
|
+
All above operations only read from local register (which size depends on size_t).
|
248
|
+
Refueling the register from memory is manually performed by the reload method.
|
249
|
+
endSignal = FSE_reloadDStream(&DStream);
|
250
|
+
|
251
|
+
FSE_reloadDStream() result tells if there is still some more data to read from DStream.
|
252
|
+
FSE_DStream_unfinished : there is still some data left into the DStream.
|
253
|
+
FSE_DStream_endOfBuffer : Dstream reached end of buffer. Its container may no longer be completely filled.
|
254
|
+
FSE_DStream_completed : Dstream reached its exact end, corresponding in general to decompression completed.
|
255
|
+
FSE_DStream_tooFar : Dstream went too far. Decompression result is corrupted.
|
256
|
+
|
257
|
+
When reaching end of buffer (FSE_DStream_endOfBuffer), progress slowly, notably if you decode multiple symbols per loop,
|
258
|
+
to properly detect the exact end of stream.
|
259
|
+
After each decoded symbol, check if DStream is fully consumed using this simple test :
|
260
|
+
FSE_reloadDStream(&DStream) >= FSE_DStream_completed
|
261
|
+
|
262
|
+
When it's done, verify decompression is fully completed, by checking both DStream and the relevant states.
|
263
|
+
Checking if DStream has reached its end is performed by :
|
264
|
+
FSE_endOfDStream(&DStream);
|
265
|
+
Check also the states. There might be some symbols left there, if some high probability ones (>50%) are possible.
|
266
|
+
FSE_endOfDState(&DState);
|
267
|
+
*/
|
268
|
+
|
269
|
+
|
270
|
+
/******************************************
|
271
|
+
* FSE unsafe symbol API
|
272
|
+
******************************************/
|
273
|
+
size_t FSE_readBitsFast(FSE_DStream_t* bitD, unsigned nbBits);
|
100
274
|
/* faster, but works only if nbBits >= 1 (otherwise, result will be corrupted) */
|
101
275
|
|
102
276
|
unsigned char FSE_decodeSymbolFast(FSE_DState_t* DStatePtr, FSE_DStream_t* bitD);
|
103
|
-
/* faster, but works only if nbBits >= 1 (otherwise, result will be corrupted) */
|
277
|
+
/* faster, but works only if allways nbBits >= 1 (otherwise, result will be corrupted) */
|
104
278
|
|
105
279
|
|
106
280
|
#if defined (__cplusplus)
|
data/contrib/zstd/zstd.c
CHANGED
@@ -68,9 +68,6 @@
|
|
68
68
|
#include <stdio.h> /* debug : printf */
|
69
69
|
#include "zstd_static.h"
|
70
70
|
#if defined(__clang__) || defined(__GNUC__)
|
71
|
-
# ifdef __clang__
|
72
|
-
# pragma clang diagnostic ignored "-Wtypedef-redefinition"
|
73
|
-
# endif
|
74
71
|
# include "fse.c" /* due to GCC/Clang inlining limitations, including *.c runs noticeably faster */
|
75
72
|
#else
|
76
73
|
# include "fse_static.h"
|
@@ -80,7 +77,6 @@
|
|
80
77
|
/********************************************************
|
81
78
|
* Compiler specifics
|
82
79
|
*********************************************************/
|
83
|
-
//#if (!(defined(_MSC_VER) && (_MSC_VER<=1500))) /* exclude Visual 2008 and below */
|
84
80
|
#ifdef __AVX2__
|
85
81
|
# include <immintrin.h> /* AVX2 intrinsics */
|
86
82
|
#endif
|
@@ -100,10 +96,12 @@
|
|
100
96
|
#endif
|
101
97
|
|
102
98
|
|
99
|
+
#ifndef MEM_ACCESS_MODULE
|
100
|
+
#define MEM_ACCESS_MODULE
|
103
101
|
/********************************************************
|
104
102
|
* Basic Types
|
105
103
|
*********************************************************/
|
106
|
-
#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
|
104
|
+
#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* C99 */
|
107
105
|
# include <stdint.h>
|
108
106
|
typedef uint8_t BYTE;
|
109
107
|
typedef uint16_t U16;
|
@@ -120,19 +118,18 @@ typedef signed int S32;
|
|
120
118
|
typedef unsigned long long U64;
|
121
119
|
#endif
|
122
120
|
|
121
|
+
#endif /* MEM_ACCESS_MODULE */
|
122
|
+
|
123
123
|
|
124
124
|
/********************************************************
|
125
125
|
* Constants
|
126
126
|
*********************************************************/
|
127
|
-
static const U32 ZSTD_magicNumber =
|
127
|
+
static const U32 ZSTD_magicNumber = 0xFD2FB51E; /* 3rd version : seqNb header */
|
128
128
|
|
129
129
|
#define HASH_LOG (ZSTD_MEMORY_USAGE - 2)
|
130
130
|
#define HASH_TABLESIZE (1 << HASH_LOG)
|
131
131
|
#define HASH_MASK (HASH_TABLESIZE - 1)
|
132
132
|
|
133
|
-
#define MAXD_LOG 16
|
134
|
-
#define MAX_DISTANCE ((1 << MAXD_LOG) - 1)
|
135
|
-
|
136
133
|
#define KNUTH 2654435761
|
137
134
|
|
138
135
|
#define BIT7 128
|
@@ -142,14 +139,14 @@ static const U32 ZSTD_magicNumber = 0xFD2FB51C;
|
|
142
139
|
|
143
140
|
#define KB *(1 <<10)
|
144
141
|
#define MB *(1 <<20)
|
145
|
-
#define GB *(1U<<
|
142
|
+
#define GB *(1U<<30)
|
146
143
|
|
147
|
-
#define BLOCKSIZE (128 KB)
|
148
|
-
static const U32 g_maxDistance =
|
144
|
+
#define BLOCKSIZE (128 KB) /* define, for static allocation */
|
145
|
+
static const U32 g_maxDistance = 4 * BLOCKSIZE;
|
149
146
|
static const U32 g_maxLimit = 1 GB;
|
150
147
|
static const U32 g_searchStrength = 8;
|
151
148
|
|
152
|
-
#define WORKPLACESIZE (BLOCKSIZE*
|
149
|
+
#define WORKPLACESIZE (BLOCKSIZE*3)
|
153
150
|
#define MINMATCH 4
|
154
151
|
#define MLbits 7
|
155
152
|
#define LLbits 6
|
@@ -161,6 +158,8 @@ static const U32 g_searchStrength = 8;
|
|
161
158
|
#define MLFSELog 10
|
162
159
|
#define LLFSELog 10
|
163
160
|
#define OffFSELog 9
|
161
|
+
#define MAX(a,b) ((a)<(b)?(b):(a))
|
162
|
+
#define MaxSeq MAX(MaxLL, MaxML)
|
164
163
|
|
165
164
|
#define LITERAL_NOENTROPY 63
|
166
165
|
#define COMMAND_NOENTROPY 7 /* to remove */
|
@@ -181,11 +180,13 @@ static unsigned ZSTD_isLittleEndian(void)
|
|
181
180
|
return one.c[0];
|
182
181
|
}
|
183
182
|
|
184
|
-
static U16 ZSTD_read16(const void* p) {
|
183
|
+
static U16 ZSTD_read16(const void* p) { U16 r; memcpy(&r, p, sizeof(r)); return r; }
|
185
184
|
|
186
|
-
static U32 ZSTD_read32(const void* p) {
|
185
|
+
static U32 ZSTD_read32(const void* p) { U32 r; memcpy(&r, p, sizeof(r)); return r; }
|
187
186
|
|
188
|
-
static
|
187
|
+
static U64 ZSTD_read64(const void* p) { U64 r; memcpy(&r, p, sizeof(r)); return r; }
|
188
|
+
|
189
|
+
static size_t ZSTD_read_ARCH(const void* p) { size_t r; memcpy(&r, p, sizeof(r)); return r; }
|
189
190
|
|
190
191
|
static void ZSTD_copy4(void* dst, const void* src) { memcpy(dst, src, 4); }
|
191
192
|
|
@@ -201,6 +202,27 @@ static void ZSTD_wildcopy(void* dst, const void* src, size_t length)
|
|
201
202
|
while (op < oend) COPY8(op, ip);
|
202
203
|
}
|
203
204
|
|
205
|
+
static U16 ZSTD_readLE16(const void* memPtr)
|
206
|
+
{
|
207
|
+
if (ZSTD_isLittleEndian()) return ZSTD_read16(memPtr);
|
208
|
+
else
|
209
|
+
{
|
210
|
+
const BYTE* p = (const BYTE*)memPtr;
|
211
|
+
return (U16)((U16)p[0] + ((U16)p[1]<<8));
|
212
|
+
}
|
213
|
+
}
|
214
|
+
|
215
|
+
static void ZSTD_writeLE16(void* memPtr, U16 val)
|
216
|
+
{
|
217
|
+
if (ZSTD_isLittleEndian()) memcpy(memPtr, &val, sizeof(val));
|
218
|
+
else
|
219
|
+
{
|
220
|
+
BYTE* p = (BYTE*)memPtr;
|
221
|
+
p[0] = (BYTE)val;
|
222
|
+
p[1] = (BYTE)(val>>8);
|
223
|
+
}
|
224
|
+
}
|
225
|
+
|
204
226
|
static U32 ZSTD_readLE32(const void* memPtr)
|
205
227
|
{
|
206
228
|
if (ZSTD_isLittleEndian())
|
@@ -243,40 +265,6 @@ static void ZSTD_writeBE32(void* memPtr, U32 value)
|
|
243
265
|
p[3] = (BYTE)(value>>0);
|
244
266
|
}
|
245
267
|
|
246
|
-
static size_t ZSTD_writeProgressive(void* ptr, size_t value)
|
247
|
-
{
|
248
|
-
BYTE* const bStart = (BYTE* const)ptr;
|
249
|
-
BYTE* byte = bStart;
|
250
|
-
|
251
|
-
do
|
252
|
-
{
|
253
|
-
BYTE l = value & 127;
|
254
|
-
value >>= 7;
|
255
|
-
if (value) l += 128;
|
256
|
-
*byte++ = l;
|
257
|
-
} while (value);
|
258
|
-
|
259
|
-
return byte - bStart;
|
260
|
-
}
|
261
|
-
|
262
|
-
|
263
|
-
static size_t ZSTD_readProgressive(size_t* result, const void* ptr)
|
264
|
-
{
|
265
|
-
const BYTE* const bStart = (const BYTE* const)ptr;
|
266
|
-
const BYTE* byte = bStart;
|
267
|
-
size_t r = 0;
|
268
|
-
U32 shift = 0;
|
269
|
-
|
270
|
-
do
|
271
|
-
{
|
272
|
-
r += (*byte & 127) << shift;
|
273
|
-
shift += 7;
|
274
|
-
} while (*byte++ & 128);
|
275
|
-
|
276
|
-
*result = r;
|
277
|
-
return byte - bStart;
|
278
|
-
}
|
279
|
-
|
280
268
|
|
281
269
|
/**************************************
|
282
270
|
* Local structures
|
@@ -289,12 +277,38 @@ typedef struct
|
|
289
277
|
U32 origSize;
|
290
278
|
} blockProperties_t;
|
291
279
|
|
292
|
-
typedef struct
|
280
|
+
typedef struct {
|
281
|
+
void* buffer;
|
282
|
+
U32* offsetStart;
|
283
|
+
U32* offset;
|
284
|
+
BYTE* offCodeStart;
|
285
|
+
BYTE* offCode;
|
286
|
+
BYTE* litStart;
|
287
|
+
BYTE* lit;
|
288
|
+
BYTE* litLengthStart;
|
289
|
+
BYTE* litLength;
|
290
|
+
BYTE* matchLengthStart;
|
291
|
+
BYTE* matchLength;
|
292
|
+
BYTE* dumpsStart;
|
293
|
+
BYTE* dumps;
|
294
|
+
} seqStore_t;
|
295
|
+
|
296
|
+
void ZSTD_resetSeqStore(seqStore_t* ssPtr)
|
297
|
+
{
|
298
|
+
ssPtr->offset = ssPtr->offsetStart;
|
299
|
+
ssPtr->lit = ssPtr->litStart;
|
300
|
+
ssPtr->litLength = ssPtr->litLengthStart;
|
301
|
+
ssPtr->matchLength = ssPtr->matchLengthStart;
|
302
|
+
ssPtr->dumps = ssPtr->dumpsStart;
|
303
|
+
}
|
304
|
+
|
305
|
+
|
306
|
+
typedef struct ZSTD_Cctx_s
|
293
307
|
{
|
294
308
|
const BYTE* base;
|
295
309
|
U32 current;
|
296
310
|
U32 nextUpdate;
|
297
|
-
|
311
|
+
seqStore_t seqStore;
|
298
312
|
#ifdef __AVX2__
|
299
313
|
__m256i hashTable[HASH_TABLESIZE>>3];
|
300
314
|
#else
|
@@ -303,27 +317,35 @@ typedef struct
|
|
303
317
|
} cctxi_t;
|
304
318
|
|
305
319
|
|
306
|
-
|
320
|
+
ZSTD_Cctx* ZSTD_createCCtx(void)
|
307
321
|
{
|
308
|
-
|
309
|
-
|
310
|
-
|
322
|
+
ZSTD_Cctx* ctx = (ZSTD_Cctx*) malloc( sizeof(ZSTD_Cctx) );
|
323
|
+
if (ctx==NULL) return NULL;
|
324
|
+
ctx->seqStore.buffer = malloc(WORKPLACESIZE);
|
325
|
+
if (ctx->seqStore.buffer==NULL)
|
326
|
+
{
|
327
|
+
free(ctx);
|
328
|
+
return NULL;
|
329
|
+
}
|
330
|
+
ctx->seqStore.offsetStart = (U32*) (ctx->seqStore.buffer);
|
331
|
+
ctx->seqStore.offCodeStart = (BYTE*) (ctx->seqStore.offsetStart + (BLOCKSIZE>>2));
|
332
|
+
ctx->seqStore.litStart = ctx->seqStore.offCodeStart + (BLOCKSIZE>>2);
|
333
|
+
ctx->seqStore.litLengthStart = ctx->seqStore.litStart + BLOCKSIZE;
|
334
|
+
ctx->seqStore.matchLengthStart = ctx->seqStore.litLengthStart + (BLOCKSIZE>>2);
|
335
|
+
ctx->seqStore.dumpsStart = ctx->seqStore.matchLengthStart + (BLOCKSIZE>>2);
|
336
|
+
return ctx;
|
311
337
|
}
|
312
338
|
|
313
|
-
|
314
|
-
void ZSTD_resetCCtx(ZSTD_cctx_t ctx)
|
339
|
+
void ZSTD_resetCCtx(ZSTD_Cctx* ctx)
|
315
340
|
{
|
316
|
-
|
317
|
-
|
318
|
-
memset(srt->hashTable, 0, HASH_TABLESIZE*4);
|
341
|
+
ctx->base = NULL;
|
342
|
+
memset(ctx->hashTable, 0, HASH_TABLESIZE*4);
|
319
343
|
}
|
320
344
|
|
321
|
-
|
322
|
-
size_t ZSTD_freeCCtx(ZSTD_cctx_t ctx)
|
345
|
+
size_t ZSTD_freeCCtx(ZSTD_Cctx* ctx)
|
323
346
|
{
|
324
|
-
|
325
|
-
free(
|
326
|
-
free(srt);
|
347
|
+
free(ctx->seqStore.buffer);
|
348
|
+
free(ctx);
|
327
349
|
return 0;
|
328
350
|
}
|
329
351
|
|
@@ -360,9 +382,9 @@ static unsigned ZSTD_highbit(U32 val)
|
|
360
382
|
unsigned long r;
|
361
383
|
_BitScanReverse(&r, val);
|
362
384
|
return (unsigned)r;
|
363
|
-
# elif defined(__GNUC__) && (GCC_VERSION >= 304)
|
385
|
+
# elif defined(__GNUC__) && (GCC_VERSION >= 304) /* GCC Intrinsic */
|
364
386
|
return 31 - __builtin_clz(val);
|
365
|
-
# else
|
387
|
+
# else /* Software version */
|
366
388
|
static const int DeBruijnClz[32] = { 0, 9, 1, 10, 13, 21, 2, 29, 11, 14, 16, 18, 22, 25, 3, 30, 8, 12, 20, 28, 15, 17, 24, 7, 19, 27, 23, 6, 26, 5, 4, 31 };
|
367
389
|
U32 v = val;
|
368
390
|
int r;
|
@@ -433,7 +455,7 @@ static unsigned ZSTD_NbCommonBytes (register size_t val)
|
|
433
455
|
_BitScanReverse( &r, (unsigned long)val );
|
434
456
|
return (unsigned)(r>>3);
|
435
457
|
# elif defined(__GNUC__) && (GCC_VERSION >= 304) && !defined(LZ4_FORCE_SW_BITCOUNT)
|
436
|
-
return (__builtin_clz(val) >> 3);
|
458
|
+
return (__builtin_clz((U32)val) >> 3);
|
437
459
|
# else
|
438
460
|
unsigned r;
|
439
461
|
if (!(val>>16)) { r=2; val>>=8; } else { r=0; val>>=24; }
|
@@ -479,15 +501,13 @@ static size_t ZSTD_compressRle (void* dst, size_t maxDstSize, const void* src, s
|
|
479
501
|
/* at this stage : dstSize >= FSE_compressBound(srcSize) > (ZSTD_blockHeaderSize+1) (checked by ZSTD_compressLiterals()) */
|
480
502
|
(void)maxDstSize;
|
481
503
|
|
482
|
-
ostart[ZSTD_blockHeaderSize] = *(BYTE*)src;
|
504
|
+
ostart[ZSTD_blockHeaderSize] = *(const BYTE*)src;
|
483
505
|
|
484
|
-
|
485
|
-
|
486
|
-
|
487
|
-
|
488
|
-
|
489
|
-
ostart[0] += (BYTE)(bt_rle<<6);
|
490
|
-
}
|
506
|
+
/* Build header */
|
507
|
+
ostart[0] = (BYTE)(srcSize>>16);
|
508
|
+
ostart[1] = (BYTE)(srcSize>>8);
|
509
|
+
ostart[2] = (BYTE) srcSize;
|
510
|
+
ostart[0] += (BYTE)(bt_rle<<6);
|
491
511
|
|
492
512
|
return ZSTD_blockHeaderSize+1;
|
493
513
|
}
|
@@ -500,76 +520,16 @@ static size_t ZSTD_noCompressBlock (void* dst, size_t maxDstSize, const void* sr
|
|
500
520
|
if (srcSize + ZSTD_blockHeaderSize > maxDstSize) return (size_t)-ZSTD_ERROR_maxDstSize_tooSmall;
|
501
521
|
memcpy(ostart + ZSTD_blockHeaderSize, src, srcSize);
|
502
522
|
|
503
|
-
|
504
|
-
|
505
|
-
|
506
|
-
|
507
|
-
|
508
|
-
ostart[0] += (BYTE)(bt_raw<<6); /* is a raw (uncompressed) block */
|
509
|
-
}
|
523
|
+
/* Build header */
|
524
|
+
ostart[0] = (BYTE)(srcSize>>16);
|
525
|
+
ostart[1] = (BYTE)(srcSize>>8);
|
526
|
+
ostart[2] = (BYTE) srcSize;
|
527
|
+
ostart[0] += (BYTE)(bt_raw<<6); /* is a raw (uncompressed) block */
|
510
528
|
|
511
529
|
return ZSTD_blockHeaderSize+srcSize;
|
512
530
|
}
|
513
531
|
|
514
532
|
|
515
|
-
/* return : size of CStream in bits */
|
516
|
-
static size_t ZSTD_compressLiterals_usingCTable(void* dst, size_t dstSize,
|
517
|
-
const void* src, size_t srcSize,
|
518
|
-
const void* CTable)
|
519
|
-
{
|
520
|
-
const BYTE* const istart = (const BYTE*)src;
|
521
|
-
const BYTE* ip = istart;
|
522
|
-
const BYTE* const iend = istart + srcSize;
|
523
|
-
FSE_CStream_t bitC;
|
524
|
-
FSE_CState_t CState1, CState2;
|
525
|
-
|
526
|
-
// init
|
527
|
-
(void)dstSize; // objective : ensure it fits into dstBuffer (Todo)
|
528
|
-
FSE_initCStream(&bitC, dst);
|
529
|
-
FSE_initCState(&CState1, CTable);
|
530
|
-
CState2 = CState1;
|
531
|
-
|
532
|
-
/* Note : at this stage, srcSize > LITERALS_NOENTROPY (checked by ZSTD_compressLiterals()) */
|
533
|
-
// join to mod 2
|
534
|
-
if (srcSize & 1)
|
535
|
-
{
|
536
|
-
FSE_encodeByte(&bitC, &CState1, *ip++);
|
537
|
-
FSE_flushBits(&bitC);
|
538
|
-
}
|
539
|
-
|
540
|
-
// join to mod 4
|
541
|
-
if ((sizeof(size_t)*8 > LitFSELog*4+7 ) && (srcSize & 2)) // test bit 2
|
542
|
-
{
|
543
|
-
FSE_encodeByte(&bitC, &CState2, *ip++);
|
544
|
-
FSE_encodeByte(&bitC, &CState1, *ip++);
|
545
|
-
FSE_flushBits(&bitC);
|
546
|
-
}
|
547
|
-
|
548
|
-
// 2 or 4 encoding per loop
|
549
|
-
while (ip<iend)
|
550
|
-
{
|
551
|
-
FSE_encodeByte(&bitC, &CState2, *ip++);
|
552
|
-
|
553
|
-
if (sizeof(size_t)*8 < LitFSELog*2+7 ) // this test must be static
|
554
|
-
FSE_flushBits(&bitC);
|
555
|
-
|
556
|
-
FSE_encodeByte(&bitC, &CState1, *ip++);
|
557
|
-
|
558
|
-
if (sizeof(size_t)*8 > LitFSELog*4+7 ) // this test must be static
|
559
|
-
{
|
560
|
-
FSE_encodeByte(&bitC, &CState2, *ip++);
|
561
|
-
FSE_encodeByte(&bitC, &CState1, *ip++);
|
562
|
-
}
|
563
|
-
|
564
|
-
FSE_flushBits(&bitC);
|
565
|
-
}
|
566
|
-
|
567
|
-
FSE_flushCState(&bitC, &CState2);
|
568
|
-
FSE_flushCState(&bitC, &CState1);
|
569
|
-
return FSE_closeCStream(&bitC);
|
570
|
-
}
|
571
|
-
|
572
|
-
|
573
533
|
size_t ZSTD_minGain(size_t srcSize)
|
574
534
|
{
|
575
535
|
return (srcSize >> 6) + 1;
|
@@ -579,89 +539,58 @@ size_t ZSTD_minGain(size_t srcSize)
|
|
579
539
|
static size_t ZSTD_compressLiterals (void* dst, size_t dstSize,
|
580
540
|
const void* src, size_t srcSize)
|
581
541
|
{
|
582
|
-
const BYTE* const istart = (const BYTE*) src;
|
583
|
-
const BYTE* ip = istart;
|
584
|
-
|
585
|
-
BYTE* const ostart = (BYTE*) dst;
|
586
|
-
BYTE* op = ostart + ZSTD_blockHeaderSize;
|
587
|
-
BYTE* const oend = ostart + dstSize;
|
588
|
-
|
589
|
-
U32 maxSymbolValue = 256;
|
590
|
-
U32 tableLog = LitFSELog;
|
591
|
-
U32 count[256];
|
592
|
-
S16 norm[256];
|
593
|
-
U32 CTable[ FSE_CTABLE_SIZE_U32(LitFSELog, 256) ];
|
594
|
-
size_t errorCode;
|
595
542
|
const size_t minGain = ZSTD_minGain(srcSize);
|
543
|
+
BYTE* const ostart = (BYTE*)dst;
|
544
|
+
size_t hsize;
|
545
|
+
static const size_t LHSIZE = 5;
|
596
546
|
|
597
|
-
|
598
|
-
if (dstSize < FSE_compressBound(srcSize)) return (size_t)-ZSTD_ERROR_maxDstSize_tooSmall;
|
547
|
+
if (dstSize < LHSIZE+1) return (size_t)-ZSTD_ERROR_maxDstSize_tooSmall; /* not enough space for compression */
|
599
548
|
|
600
|
-
|
601
|
-
|
602
|
-
if (
|
603
|
-
if (errorCode == srcSize) return 1;
|
604
|
-
if (errorCode < ((srcSize * 7) >> 10)) return 0;
|
549
|
+
hsize = HUF_compress(ostart+LHSIZE, dstSize-LHSIZE, src, srcSize);
|
550
|
+
if (hsize<2) return hsize; /* special cases */
|
551
|
+
if (hsize >= srcSize - minGain) return 0;
|
605
552
|
|
606
|
-
|
607
|
-
errorCode = (int)FSE_normalizeCount (norm, tableLog, count, srcSize, maxSymbolValue);
|
608
|
-
if (FSE_isError(errorCode)) return (size_t)-ZSTD_ERROR_GENERIC;
|
609
|
-
|
610
|
-
// Write table description header
|
611
|
-
errorCode = FSE_writeHeader (op, FSE_MAX_HEADERSIZE, norm, maxSymbolValue, tableLog);
|
612
|
-
if (FSE_isError(errorCode)) return (size_t)-ZSTD_ERROR_GENERIC;
|
613
|
-
op += errorCode;
|
553
|
+
hsize += 2; /* work around vs fixed 3-bytes header */
|
614
554
|
|
615
|
-
|
616
|
-
errorCode = FSE_buildCTable (&CTable, norm, maxSymbolValue, tableLog);
|
617
|
-
if (FSE_isError(errorCode)) return (size_t)-ZSTD_ERROR_GENERIC;
|
618
|
-
errorCode = ZSTD_compressLiterals_usingCTable(op, oend - op, ip, srcSize, &CTable);
|
619
|
-
if (ZSTD_isError(errorCode)) return errorCode;
|
620
|
-
op += errorCode;
|
621
|
-
|
622
|
-
// check compressibility
|
623
|
-
if ( (size_t)(op-ostart) >= srcSize-minGain)
|
624
|
-
return 0;
|
625
|
-
|
626
|
-
// Build header
|
555
|
+
/* Build header */
|
627
556
|
{
|
628
|
-
|
629
|
-
|
630
|
-
ostart[
|
631
|
-
ostart[
|
632
|
-
ostart[
|
633
|
-
ostart[
|
557
|
+
ostart[0] = (BYTE)(bt_compressed<<6); /* is a block, is compressed */
|
558
|
+
ostart[0] += (BYTE)(hsize>>16);
|
559
|
+
ostart[1] = (BYTE)(hsize>>8);
|
560
|
+
ostart[2] = (BYTE)(hsize>>0);
|
561
|
+
ostart[0] += (BYTE)((srcSize>>16)<<3);
|
562
|
+
ostart[3] = (BYTE)(srcSize>>8);
|
563
|
+
ostart[4] = (BYTE)(srcSize>>0);
|
634
564
|
}
|
635
565
|
|
636
|
-
|
566
|
+
hsize -= 2;
|
567
|
+
return hsize+LHSIZE;
|
637
568
|
}
|
638
569
|
|
639
570
|
|
640
|
-
static size_t
|
641
|
-
|
642
|
-
|
643
|
-
const BYTE* op_matchLength_start,
|
644
|
-
const U32* op_offset_start,
|
645
|
-
const BYTE* op_dumps_start, const BYTE* op_dumps,
|
646
|
-
size_t srcSize, size_t lastLLSize
|
647
|
-
)
|
571
|
+
static size_t ZSTD_compressSequences(BYTE* dst, size_t maxDstSize,
|
572
|
+
const seqStore_t* seqStorePtr,
|
573
|
+
size_t srcSize)
|
648
574
|
{
|
649
|
-
|
650
|
-
|
651
|
-
S16 norm[256];
|
575
|
+
U32 count[MaxSeq+1];
|
576
|
+
S16 norm[MaxSeq+1];
|
652
577
|
size_t mostFrequent;
|
653
578
|
U32 max = 255;
|
654
579
|
U32 tableLog = 11;
|
655
|
-
const size_t nbSeq = op_litLength - op_litLength_start;
|
656
580
|
U32 CTable_LitLength [FSE_CTABLE_SIZE_U32(LLFSELog, MaxLL )];
|
657
|
-
U32 CTable_OffsetBits [FSE_CTABLE_SIZE_U32(OffFSELog,
|
581
|
+
U32 CTable_OffsetBits [FSE_CTABLE_SIZE_U32(OffFSELog,MaxOff)];
|
658
582
|
U32 CTable_MatchLength[FSE_CTABLE_SIZE_U32(MLFSELog, MaxML )];
|
659
|
-
U32 LLtype, Offtype, MLtype;
|
660
|
-
BYTE*
|
661
|
-
const
|
662
|
-
const BYTE*
|
663
|
-
BYTE
|
664
|
-
BYTE*
|
583
|
+
U32 LLtype, Offtype, MLtype; /* compressed, raw or rle */
|
584
|
+
const BYTE* const op_lit_start = seqStorePtr->litStart;
|
585
|
+
const BYTE* op_lit = seqStorePtr->lit;
|
586
|
+
const BYTE* const llTable = seqStorePtr->litLengthStart;
|
587
|
+
const BYTE* op_litLength = seqStorePtr->litLength;
|
588
|
+
const BYTE* const mlTable = seqStorePtr->matchLengthStart;
|
589
|
+
const U32* const offsetTable = seqStorePtr->offsetStart;
|
590
|
+
BYTE* const offCodeTable = seqStorePtr->offCodeStart;
|
591
|
+
BYTE* op = dst;
|
592
|
+
BYTE* const oend = dst + maxDstSize;
|
593
|
+
const size_t nbSeq = op_litLength - llTable;
|
665
594
|
const size_t minGain = ZSTD_minGain(srcSize);
|
666
595
|
const size_t maxCSize = srcSize - minGain;
|
667
596
|
const size_t minSeqSize = 1 /*lastL*/ + 2 /*dHead*/ + 2 /*dumpsIn*/ + 5 /*SeqHead*/ + 3 /*SeqIn*/ + 1 /*margin*/ + ZSTD_blockHeaderSize;
|
@@ -669,13 +598,11 @@ static size_t ZSTD_compressEntropy(BYTE* dst, size_t maxDstSize,
|
|
669
598
|
BYTE* seqHead;
|
670
599
|
|
671
600
|
|
672
|
-
/*
|
673
|
-
op = dst;
|
674
|
-
|
675
|
-
/* Encode literals */
|
601
|
+
/* Compress literals */
|
676
602
|
{
|
677
603
|
size_t cSize;
|
678
604
|
size_t litSize = op_lit - op_lit_start;
|
605
|
+
|
679
606
|
if (litSize <= LITERAL_NOENTROPY) cSize = ZSTD_noCompressBlock (op, maxDstSize, op_lit_start, litSize);
|
680
607
|
else
|
681
608
|
{
|
@@ -691,38 +618,39 @@ static size_t ZSTD_compressEntropy(BYTE* dst, size_t maxDstSize,
|
|
691
618
|
op += cSize;
|
692
619
|
}
|
693
620
|
|
694
|
-
/*
|
695
|
-
|
696
|
-
|
697
|
-
|
621
|
+
/* Sequences Header */
|
622
|
+
if ((oend-op) < 2+3+6) /* nbSeq + dumpsLength + 3*rleCTable*/
|
623
|
+
return (size_t)-ZSTD_ERROR_maxDstSize_tooSmall;
|
624
|
+
ZSTD_writeLE16(op, (U16)nbSeq); op+=2;
|
698
625
|
seqHead = op;
|
699
626
|
|
700
|
-
/* dumps */
|
627
|
+
/* dumps : contains too large lengths */
|
701
628
|
{
|
702
|
-
size_t dumpsLength =
|
629
|
+
size_t dumpsLength = seqStorePtr->dumps - seqStorePtr->dumpsStart;
|
703
630
|
if (dumpsLength < 512)
|
704
631
|
{
|
705
632
|
op[0] = (BYTE)(dumpsLength >> 8);
|
706
633
|
op[1] = (BYTE)(dumpsLength);
|
707
|
-
op += 2;
|
634
|
+
op += 2;
|
708
635
|
}
|
709
636
|
else
|
710
637
|
{
|
711
638
|
op[0] = 2;
|
712
639
|
op[1] = (BYTE)(dumpsLength>>8);
|
713
640
|
op[2] = (BYTE)(dumpsLength);
|
714
|
-
op += 3;
|
641
|
+
op += 3;
|
715
642
|
}
|
716
|
-
|
717
|
-
op
|
643
|
+
if ((size_t)(oend-op) < dumpsLength+6) return (size_t)-ZSTD_ERROR_maxDstSize_tooSmall;
|
644
|
+
memcpy(op, seqStorePtr->dumpsStart, dumpsLength);
|
645
|
+
op += dumpsLength;
|
718
646
|
}
|
719
647
|
|
720
|
-
/*
|
648
|
+
/* CTable for Literal Lengths */
|
721
649
|
max = MaxLL;
|
722
|
-
mostFrequent = FSE_countFast(count,
|
723
|
-
if (mostFrequent == nbSeq)
|
650
|
+
mostFrequent = FSE_countFast(count, &max, seqStorePtr->litLengthStart, nbSeq);
|
651
|
+
if ((mostFrequent == nbSeq) && (nbSeq > 2))
|
724
652
|
{
|
725
|
-
*op++ = *
|
653
|
+
*op++ = *(seqStorePtr->litLengthStart);
|
726
654
|
FSE_buildCTable_rle(CTable_LitLength, (BYTE)max);
|
727
655
|
LLtype = bt_rle;
|
728
656
|
}
|
@@ -733,29 +661,31 @@ static size_t ZSTD_compressEntropy(BYTE* dst, size_t maxDstSize,
|
|
733
661
|
}
|
734
662
|
else
|
735
663
|
{
|
664
|
+
size_t NCountSize;
|
736
665
|
tableLog = FSE_optimalTableLog(LLFSELog, nbSeq, max);
|
737
666
|
FSE_normalizeCount(norm, tableLog, count, nbSeq, max);
|
738
|
-
|
667
|
+
NCountSize = FSE_writeNCount(op, oend-op, norm, max, tableLog); /* overflow protected */
|
668
|
+
if (FSE_isError(NCountSize)) return (size_t)-ZSTD_ERROR_GENERIC;
|
669
|
+
op += NCountSize;
|
739
670
|
FSE_buildCTable(CTable_LitLength, norm, max, tableLog);
|
740
671
|
LLtype = bt_compressed;
|
741
672
|
}
|
742
673
|
|
743
|
-
/*
|
674
|
+
/* CTable for Offsets codes */
|
744
675
|
{
|
745
|
-
/* create
|
676
|
+
/* create Offset codes */
|
746
677
|
size_t i;
|
747
678
|
max = MaxOff;
|
748
679
|
for (i=0; i<nbSeq; i++)
|
749
680
|
{
|
750
|
-
|
751
|
-
if (
|
681
|
+
offCodeTable[i] = (BYTE)ZSTD_highbit(offsetTable[i]) + 1;
|
682
|
+
if (offsetTable[i]==0) offCodeTable[i]=0;
|
752
683
|
}
|
753
|
-
|
754
|
-
mostFrequent = FSE_countFast(count, offsetBits_start, nbSeq, &max);
|
684
|
+
mostFrequent = FSE_countFast(count, &max, offCodeTable, nbSeq);
|
755
685
|
}
|
756
|
-
if (mostFrequent == nbSeq)
|
686
|
+
if ((mostFrequent == nbSeq) && (nbSeq > 2))
|
757
687
|
{
|
758
|
-
*op++ = *
|
688
|
+
*op++ = *offCodeTable;
|
759
689
|
FSE_buildCTable_rle(CTable_OffsetBits, (BYTE)max);
|
760
690
|
Offtype = bt_rle;
|
761
691
|
}
|
@@ -766,19 +696,22 @@ static size_t ZSTD_compressEntropy(BYTE* dst, size_t maxDstSize,
|
|
766
696
|
}
|
767
697
|
else
|
768
698
|
{
|
699
|
+
size_t NCountSize;
|
769
700
|
tableLog = FSE_optimalTableLog(OffFSELog, nbSeq, max);
|
770
701
|
FSE_normalizeCount(norm, tableLog, count, nbSeq, max);
|
771
|
-
|
702
|
+
NCountSize = FSE_writeNCount(op, oend-op, norm, max, tableLog); /* overflow protected */
|
703
|
+
if (FSE_isError(NCountSize)) return (size_t)-ZSTD_ERROR_GENERIC;
|
704
|
+
op += NCountSize;
|
772
705
|
FSE_buildCTable(CTable_OffsetBits, norm, max, tableLog);
|
773
706
|
Offtype = bt_compressed;
|
774
707
|
}
|
775
708
|
|
776
|
-
/*
|
709
|
+
/* CTable for MatchLengths */
|
777
710
|
max = MaxML;
|
778
|
-
mostFrequent = FSE_countFast(count,
|
779
|
-
if (mostFrequent == nbSeq)
|
711
|
+
mostFrequent = FSE_countFast(count, &max, seqStorePtr->matchLengthStart, nbSeq);
|
712
|
+
if ((mostFrequent == nbSeq) && (nbSeq > 2))
|
780
713
|
{
|
781
|
-
*op++ = *
|
714
|
+
*op++ = *seqStorePtr->matchLengthStart;
|
782
715
|
FSE_buildCTable_rle(CTable_MatchLength, (BYTE)max);
|
783
716
|
MLtype = bt_rle;
|
784
717
|
}
|
@@ -789,48 +722,57 @@ static size_t ZSTD_compressEntropy(BYTE* dst, size_t maxDstSize,
|
|
789
722
|
}
|
790
723
|
else
|
791
724
|
{
|
725
|
+
size_t NCountSize;
|
792
726
|
tableLog = FSE_optimalTableLog(MLFSELog, nbSeq, max);
|
793
727
|
FSE_normalizeCount(norm, tableLog, count, nbSeq, max);
|
794
|
-
|
728
|
+
NCountSize = FSE_writeNCount(op, oend-op, norm, max, tableLog); /* overflow protected */
|
729
|
+
if (FSE_isError(NCountSize)) return (size_t)-ZSTD_ERROR_GENERIC;
|
730
|
+
op += NCountSize;
|
795
731
|
FSE_buildCTable(CTable_MatchLength, norm, max, tableLog);
|
796
732
|
MLtype = bt_compressed;
|
797
733
|
}
|
798
734
|
|
799
735
|
seqHead[0] += (BYTE)((LLtype<<6) + (Offtype<<4) + (MLtype<<2));
|
800
736
|
|
801
|
-
/* Encoding */
|
737
|
+
/* Encoding Sequences */
|
802
738
|
{
|
739
|
+
size_t streamSize, errorCode;
|
740
|
+
FSE_CStream_t blockStream;
|
803
741
|
FSE_CState_t stateMatchLength;
|
804
742
|
FSE_CState_t stateOffsetBits;
|
805
743
|
FSE_CState_t stateLitLength;
|
744
|
+
int i;
|
806
745
|
|
807
|
-
FSE_initCStream(&blockStream, op);
|
746
|
+
errorCode = FSE_initCStream(&blockStream, op, oend-op);
|
747
|
+
if (FSE_isError(errorCode)) return (size_t)-ZSTD_ERROR_maxDstSize_tooSmall; /* not enough space remaining */
|
808
748
|
FSE_initCState(&stateMatchLength, CTable_MatchLength);
|
809
749
|
FSE_initCState(&stateOffsetBits, CTable_OffsetBits);
|
810
750
|
FSE_initCState(&stateLitLength, CTable_LitLength);
|
811
751
|
|
812
|
-
|
752
|
+
for (i=(int)nbSeq-1; i>=0; i--)
|
813
753
|
{
|
814
|
-
BYTE matchLength =
|
815
|
-
U32 offset =
|
816
|
-
BYTE offCode =
|
754
|
+
BYTE matchLength = mlTable[i];
|
755
|
+
U32 offset = offsetTable[i];
|
756
|
+
BYTE offCode = offCodeTable[i]; /* 32b*/ /* 64b*/
|
817
757
|
U32 nbBits = (offCode-1) * (!!offCode);
|
818
|
-
BYTE litLength =
|
819
|
-
|
758
|
+
BYTE litLength = llTable[i]; /* (7)*/ /* (7)*/
|
759
|
+
FSE_encodeSymbol(&blockStream, &stateMatchLength, matchLength); /* 17 */ /* 17 */
|
820
760
|
if (ZSTD_32bits()) FSE_flushBits(&blockStream); /* 7 */
|
821
761
|
FSE_addBits(&blockStream, offset, nbBits); /* 32 */ /* 42 */
|
822
762
|
if (ZSTD_32bits()) FSE_flushBits(&blockStream); /* 7 */
|
823
|
-
|
824
|
-
|
763
|
+
FSE_encodeSymbol(&blockStream, &stateOffsetBits, offCode); /* 16 */ /* 51 */
|
764
|
+
FSE_encodeSymbol(&blockStream, &stateLitLength, litLength); /* 26 */ /* 61 */
|
825
765
|
FSE_flushBits(&blockStream); /* 7 */ /* 7 */
|
826
766
|
}
|
827
767
|
|
828
768
|
FSE_flushCState(&blockStream, &stateMatchLength);
|
829
769
|
FSE_flushCState(&blockStream, &stateOffsetBits);
|
830
770
|
FSE_flushCState(&blockStream, &stateLitLength);
|
831
|
-
}
|
832
771
|
|
833
|
-
|
772
|
+
streamSize = FSE_closeCStream(&blockStream);
|
773
|
+
if (streamSize==0) return (size_t)-ZSTD_ERROR_maxDstSize_tooSmall; /* not enough space */
|
774
|
+
op += streamSize;
|
775
|
+
}
|
834
776
|
|
835
777
|
/* check compressibility */
|
836
778
|
if ((size_t)(op-dst) >= maxCSize) return 0;
|
@@ -839,57 +781,45 @@ static size_t ZSTD_compressEntropy(BYTE* dst, size_t maxDstSize,
|
|
839
781
|
}
|
840
782
|
|
841
783
|
|
842
|
-
static
|
843
|
-
size_t litLength, const BYTE* srcLit, size_t offset, size_t matchLength)
|
784
|
+
static void ZSTD_storeSeq(seqStore_t* seqStorePtr, size_t litLength, const BYTE* literals, size_t offset, size_t matchLength)
|
844
785
|
{
|
845
|
-
|
846
|
-
|
847
|
-
|
786
|
+
BYTE* op_lit = seqStorePtr->lit;
|
787
|
+
BYTE* const l_end = op_lit + litLength;
|
848
788
|
|
849
789
|
/* copy Literals */
|
850
|
-
while (op_lit<l_end) COPY8(op_lit,
|
790
|
+
while (op_lit<l_end) COPY8(op_lit, literals);
|
791
|
+
seqStorePtr->lit += litLength;
|
851
792
|
|
852
793
|
/* literal Length */
|
853
794
|
if (litLength >= MaxLL)
|
854
795
|
{
|
855
|
-
*
|
796
|
+
*(seqStorePtr->litLength++) = MaxLL;
|
856
797
|
if (litLength<255 + MaxLL)
|
857
|
-
*
|
798
|
+
*(seqStorePtr->dumps++) = (BYTE)(litLength - MaxLL);
|
858
799
|
else
|
859
800
|
{
|
860
|
-
*
|
861
|
-
ZSTD_writeLE32(
|
862
|
-
|
863
|
-
//litLength |= 0xFF000000;
|
864
|
-
//ZSTD_writeBE32(op_dumps, (U32)litLength);
|
865
|
-
//op_dumps += 4;
|
801
|
+
*(seqStorePtr->dumps++) = 255;
|
802
|
+
ZSTD_writeLE32(seqStorePtr->dumps, (U32)litLength); seqStorePtr->dumps += 3;
|
866
803
|
}
|
867
804
|
}
|
868
|
-
else *
|
805
|
+
else *(seqStorePtr->litLength++) = (BYTE)litLength;
|
869
806
|
|
870
|
-
/*
|
871
|
-
*
|
807
|
+
/* match offset */
|
808
|
+
*(seqStorePtr->offset++) = (U32)offset;
|
872
809
|
|
873
810
|
/* match Length */
|
874
811
|
if (matchLength >= MaxML)
|
875
812
|
{
|
876
|
-
*
|
877
|
-
if (matchLength<255
|
878
|
-
*
|
813
|
+
*(seqStorePtr->matchLength++) = MaxML;
|
814
|
+
if (matchLength < 255+MaxML)
|
815
|
+
*(seqStorePtr->dumps++) = (BYTE)(matchLength - MaxML);
|
879
816
|
else
|
880
817
|
{
|
881
|
-
*
|
882
|
-
ZSTD_writeLE32(
|
883
|
-
//*(U32*)op_dumps = (U32)matchLength; op_dumps += 3; /* store direct result */
|
884
|
-
|
885
|
-
//matchLength |= 0xFF000000;
|
886
|
-
//ZSTD_writeBE32(op_dumps, (U32)matchLength);
|
887
|
-
//op_dumps += 4;
|
818
|
+
*(seqStorePtr->dumps++) = 255;
|
819
|
+
ZSTD_writeLE32(seqStorePtr->dumps, (U32)matchLength); seqStorePtr->dumps+=3;
|
888
820
|
}
|
889
821
|
}
|
890
|
-
else *
|
891
|
-
|
892
|
-
return op_dumps - dumpStart;
|
822
|
+
else *(seqStorePtr->matchLength++) = (BYTE)matchLength;
|
893
823
|
}
|
894
824
|
|
895
825
|
|
@@ -905,7 +835,7 @@ static const U64 prime7bytes = 58295818150454627ULL;
|
|
905
835
|
//static U32 ZSTD_hashPtr(const void* p) { return ( ((*(U64*)p & 0xFFFFFFFFFFFFFF) * prime7bytes) >> (64-HASH_LOG)); }
|
906
836
|
|
907
837
|
//static U32 ZSTD_hashPtr(const void* p) { return ( (*(U64*)p * prime8bytes) >> (64-HASH_LOG)); }
|
908
|
-
static U32 ZSTD_hashPtr(const void* p) { return ( (
|
838
|
+
static U32 ZSTD_hashPtr(const void* p) { return ( (ZSTD_read64(p) * prime7bytes) >> (56-HASH_LOG)) & HASH_MASK; }
|
909
839
|
//static U32 ZSTD_hashPtr(const void* p) { return ( (*(U64*)p * prime6bytes) >> (48-HASH_LOG)) & HASH_MASK; }
|
910
840
|
//static U32 ZSTD_hashPtr(const void* p) { return ( (*(U64*)p * prime5bytes) >> (40-HASH_LOG)) & HASH_MASK; }
|
911
841
|
//static U32 ZSTD_hashPtr(const void* p) { return ( (*(U32*)p * KNUTH) >> (32-HASH_LOG)); }
|
@@ -917,7 +847,6 @@ static const BYTE* ZSTD_updateMatch(U32* table, const BYTE* p, const BYTE* start
|
|
917
847
|
U32 h = ZSTD_hashPtr(p);
|
918
848
|
const BYTE* r;
|
919
849
|
r = table[h] + start;
|
920
|
-
//table[h] = (U32)(p - start);
|
921
850
|
ZSTD_addPtr(table, p, start);
|
922
851
|
return r;
|
923
852
|
}
|
@@ -928,12 +857,12 @@ static int ZSTD_checkMatch(const BYTE* match, const BYTE* ip)
|
|
928
857
|
}
|
929
858
|
|
930
859
|
|
931
|
-
static size_t ZSTD_compressBlock(void*
|
860
|
+
static size_t ZSTD_compressBlock(void* cctx, void* dst, size_t maxDstSize, const void* src, size_t srcSize)
|
932
861
|
{
|
933
|
-
cctxi_t*
|
934
|
-
U32* HashTable = (U32*)(
|
935
|
-
|
936
|
-
const BYTE* const base =
|
862
|
+
cctxi_t* ctx = (cctxi_t*) cctx;
|
863
|
+
U32* HashTable = (U32*)(ctx->hashTable);
|
864
|
+
seqStore_t* seqStorePtr = &(ctx->seqStore);
|
865
|
+
const BYTE* const base = ctx->base;
|
937
866
|
|
938
867
|
const BYTE* const istart = (const BYTE*)src;
|
939
868
|
const BYTE* ip = istart + 1;
|
@@ -941,19 +870,16 @@ static size_t ZSTD_compressBlock(void* ctx, void* dst, size_t maxDstSize, const
|
|
941
870
|
const BYTE* const iend = istart + srcSize;
|
942
871
|
const BYTE* const ilimit = iend - 16;
|
943
872
|
|
944
|
-
U32 *op_offset = (U32*)(workplace), *op_offset_start = op_offset;
|
945
|
-
BYTE *op_l = (BYTE*)workplace + srcSize + 4, *op_l_start = op_l;
|
946
|
-
BYTE *op_rl = op_l + srcSize + 4, *op_rl_start = op_rl;
|
947
|
-
BYTE *op_ml = op_rl + (srcSize >> 2) + 4, *op_ml_start = op_ml;
|
948
|
-
BYTE *op_dumps = op_ml + (srcSize >> 2) + 4, *op_dumps_start = op_dumps;
|
949
873
|
size_t prevOffset=0, offset=0;
|
950
|
-
size_t lastLLSize;
|
951
874
|
|
952
875
|
|
876
|
+
/* init */
|
877
|
+
ZSTD_resetSeqStore(seqStorePtr);
|
878
|
+
|
953
879
|
/* Main Search Loop */
|
954
880
|
while (ip < ilimit)
|
955
881
|
{
|
956
|
-
const BYTE* match = (BYTE*) ZSTD_updateMatch(HashTable, ip, base);
|
882
|
+
const BYTE* match = (const BYTE*) ZSTD_updateMatch(HashTable, ip, base);
|
957
883
|
|
958
884
|
if (!ZSTD_checkMatch(match,ip)) { ip += ((ip-anchor) >> g_searchStrength) + 1; continue; }
|
959
885
|
|
@@ -969,8 +895,7 @@ static size_t ZSTD_compressBlock(void* ctx, void* dst, size_t maxDstSize, const
|
|
969
895
|
if (offsetCode == prevOffset) offsetCode = 0;
|
970
896
|
prevOffset = offset;
|
971
897
|
offset = ip-match;
|
972
|
-
|
973
|
-
op_l += litLength;
|
898
|
+
ZSTD_storeSeq(seqStorePtr, litLength, anchor, offsetCode, matchLength);
|
974
899
|
|
975
900
|
/* Fill Table */
|
976
901
|
ZSTD_addPtr(HashTable, ip+1, base);
|
@@ -981,18 +906,19 @@ static size_t ZSTD_compressBlock(void* ctx, void* dst, size_t maxDstSize, const
|
|
981
906
|
}
|
982
907
|
|
983
908
|
/* Last Literals */
|
984
|
-
|
985
|
-
|
986
|
-
|
909
|
+
{
|
910
|
+
size_t lastLLSize = iend - anchor;
|
911
|
+
memcpy(seqStorePtr->lit, anchor, lastLLSize);
|
912
|
+
seqStorePtr->lit += lastLLSize;
|
913
|
+
}
|
987
914
|
|
988
915
|
/* Finale compression stage */
|
989
|
-
return
|
990
|
-
|
991
|
-
srcSize, lastLLSize);
|
916
|
+
return ZSTD_compressSequences((BYTE*)dst, maxDstSize,
|
917
|
+
seqStorePtr, srcSize);
|
992
918
|
}
|
993
919
|
|
994
920
|
|
995
|
-
size_t ZSTD_compressBegin(
|
921
|
+
size_t ZSTD_compressBegin(ZSTD_Cctx* ctx, void* dst, size_t maxDstSize)
|
996
922
|
{
|
997
923
|
/* Sanity check */
|
998
924
|
if (maxDstSize < ZSTD_frameHeaderSize) return (size_t)-ZSTD_ERROR_maxDstSize_tooSmall;
|
@@ -1007,13 +933,12 @@ size_t ZSTD_compressBegin(ZSTD_cctx_t ctx, void* dst, size_t maxDstSize)
|
|
1007
933
|
}
|
1008
934
|
|
1009
935
|
|
1010
|
-
/* this should be auto-vectorized by compiler */
|
1011
936
|
static void ZSTD_scaleDownCtx(void* cctx, const U32 limit)
|
1012
937
|
{
|
1013
938
|
cctxi_t* ctx = (cctxi_t*) cctx;
|
1014
939
|
int i;
|
1015
940
|
|
1016
|
-
#if defined(__AVX2__)
|
941
|
+
#if defined(__AVX2__)
|
1017
942
|
/* AVX2 version */
|
1018
943
|
__m256i* h = ctx->hashTable;
|
1019
944
|
const __m256i limit8 = _mm256_set1_epi32(limit);
|
@@ -1025,6 +950,7 @@ static void ZSTD_scaleDownCtx(void* cctx, const U32 limit)
|
|
1025
950
|
_mm256_storeu_si256((__m256i*)(h+i), src);
|
1026
951
|
}
|
1027
952
|
#else
|
953
|
+
/* this should be auto-vectorized by compiler */
|
1028
954
|
U32* h = ctx->hashTable;
|
1029
955
|
for (i=0; i<HASH_TABLESIZE; ++i)
|
1030
956
|
{
|
@@ -1036,7 +962,6 @@ static void ZSTD_scaleDownCtx(void* cctx, const U32 limit)
|
|
1036
962
|
}
|
1037
963
|
|
1038
964
|
|
1039
|
-
/* this should be auto-vectorized by compiler */
|
1040
965
|
static void ZSTD_limitCtx(void* cctx, const U32 limit)
|
1041
966
|
{
|
1042
967
|
cctxi_t* ctx = (cctxi_t*) cctx;
|
@@ -1051,7 +976,7 @@ static void ZSTD_limitCtx(void* cctx, const U32 limit)
|
|
1051
976
|
return;
|
1052
977
|
}
|
1053
978
|
|
1054
|
-
#if defined(__AVX2__)
|
979
|
+
#if defined(__AVX2__)
|
1055
980
|
/* AVX2 version */
|
1056
981
|
{
|
1057
982
|
__m256i* h = ctx->hashTable;
|
@@ -1065,6 +990,7 @@ static void ZSTD_limitCtx(void* cctx, const U32 limit)
|
|
1065
990
|
}
|
1066
991
|
}
|
1067
992
|
#else
|
993
|
+
/* this should be auto-vectorized by compiler */
|
1068
994
|
{
|
1069
995
|
U32* h = (U32*)(ctx->hashTable);
|
1070
996
|
for (i=0; i<HASH_TABLESIZE; ++i)
|
@@ -1076,7 +1002,7 @@ static void ZSTD_limitCtx(void* cctx, const U32 limit)
|
|
1076
1002
|
}
|
1077
1003
|
|
1078
1004
|
|
1079
|
-
size_t ZSTD_compressContinue(
|
1005
|
+
size_t ZSTD_compressContinue(ZSTD_Cctx* cctx, void* dst, size_t maxDstSize, const void* src, size_t srcSize)
|
1080
1006
|
{
|
1081
1007
|
cctxi_t* ctx = (cctxi_t*) cctx;
|
1082
1008
|
const BYTE* const istart = (const BYTE* const)src;
|
@@ -1090,9 +1016,9 @@ size_t ZSTD_compressContinue(ZSTD_cctx_t cctx, void* dst, size_t maxDstSize, con
|
|
1090
1016
|
ctx->base = (const BYTE*)src, ctx->current=0, ctx->nextUpdate = g_maxDistance;
|
1091
1017
|
if (src != ctx->base + ctx->current) /* not contiguous */
|
1092
1018
|
{
|
1093
|
-
|
1094
|
-
|
1095
|
-
|
1019
|
+
ZSTD_resetCCtx(ctx);
|
1020
|
+
ctx->base = (const BYTE*)src;
|
1021
|
+
ctx->current = 0;
|
1096
1022
|
}
|
1097
1023
|
ctx->current += (U32)srcSize;
|
1098
1024
|
|
@@ -1102,8 +1028,11 @@ size_t ZSTD_compressContinue(ZSTD_cctx_t cctx, void* dst, size_t maxDstSize, con
|
|
1102
1028
|
size_t blockSize = BLOCKSIZE;
|
1103
1029
|
if (blockSize > srcSize) blockSize = srcSize;
|
1104
1030
|
|
1031
|
+
if (maxDstSize < 2*ZSTD_blockHeaderSize+1) /* one RLE block + endMark */
|
1032
|
+
return (size_t)-ZSTD_ERROR_maxDstSize_tooSmall;
|
1033
|
+
|
1105
1034
|
/* update hash table */
|
1106
|
-
if (g_maxDistance <= BLOCKSIZE) /* static test
|
1035
|
+
if (g_maxDistance <= BLOCKSIZE) /* static test ; yes == blocks are independent */
|
1107
1036
|
{
|
1108
1037
|
ZSTD_resetCCtx(ctx);
|
1109
1038
|
ctx->base = ip;
|
@@ -1116,7 +1045,6 @@ size_t ZSTD_compressContinue(ZSTD_cctx_t cctx, void* dst, size_t maxDstSize, con
|
|
1116
1045
|
}
|
1117
1046
|
|
1118
1047
|
/* compress */
|
1119
|
-
if (maxDstSize < ZSTD_blockHeaderSize) return (size_t)-ZSTD_ERROR_maxDstSize_tooSmall;
|
1120
1048
|
cSize = ZSTD_compressBlock(ctx, op+ZSTD_blockHeaderSize, maxDstSize-ZSTD_blockHeaderSize, ip, blockSize);
|
1121
1049
|
if (cSize == 0)
|
1122
1050
|
{
|
@@ -1142,7 +1070,7 @@ size_t ZSTD_compressContinue(ZSTD_cctx_t cctx, void* dst, size_t maxDstSize, con
|
|
1142
1070
|
}
|
1143
1071
|
|
1144
1072
|
|
1145
|
-
size_t ZSTD_compressEnd(
|
1073
|
+
size_t ZSTD_compressEnd(ZSTD_Cctx* ctx, void* dst, size_t maxDstSize)
|
1146
1074
|
{
|
1147
1075
|
BYTE* op = (BYTE*)dst;
|
1148
1076
|
|
@@ -1159,7 +1087,7 @@ size_t ZSTD_compressEnd(ZSTD_cctx_t ctx, void* dst, size_t maxDstSize)
|
|
1159
1087
|
}
|
1160
1088
|
|
1161
1089
|
|
1162
|
-
static size_t ZSTD_compressCCtx(
|
1090
|
+
static size_t ZSTD_compressCCtx(ZSTD_Cctx* ctx, void* dst, size_t maxDstSize, const void* src, size_t srcSize)
|
1163
1091
|
{
|
1164
1092
|
BYTE* const ostart = (BYTE* const)dst;
|
1165
1093
|
BYTE* op = ostart;
|
@@ -1193,10 +1121,11 @@ static size_t ZSTD_compressCCtx(void* ctx, void* dst, size_t maxDstSize, const v
|
|
1193
1121
|
|
1194
1122
|
size_t ZSTD_compress(void* dst, size_t maxDstSize, const void* src, size_t srcSize)
|
1195
1123
|
{
|
1196
|
-
|
1124
|
+
ZSTD_Cctx* ctx;
|
1197
1125
|
size_t r;
|
1198
1126
|
|
1199
1127
|
ctx = ZSTD_createCCtx();
|
1128
|
+
if (ctx==NULL) return (size_t)-ZSTD_ERROR_GENERIC;
|
1200
1129
|
r = ZSTD_compressCCtx(ctx, dst, maxDstSize, src, srcSize);
|
1201
1130
|
ZSTD_freeCCtx(ctx);
|
1202
1131
|
return r;
|
@@ -1213,7 +1142,7 @@ size_t ZSTD_getcBlockSize(const void* src, size_t srcSize, blockProperties_t* bp
|
|
1213
1142
|
BYTE headerFlags;
|
1214
1143
|
U32 cSize;
|
1215
1144
|
|
1216
|
-
if (srcSize < 3) return (size_t)-
|
1145
|
+
if (srcSize < 3) return (size_t)-ZSTD_ERROR_SrcSize;
|
1217
1146
|
|
1218
1147
|
headerFlags = *in;
|
1219
1148
|
cSize = in[2] + (in[1]<<8) + ((in[0] & 7)<<16);
|
@@ -1235,106 +1164,34 @@ static size_t ZSTD_copyUncompressedBlock(void* dst, size_t maxDstSize, const voi
|
|
1235
1164
|
}
|
1236
1165
|
|
1237
1166
|
|
1238
|
-
|
1239
|
-
|
1240
|
-
void* const dst, size_t maxDstSize,
|
1241
|
-
const void* src, size_t srcSize,
|
1242
|
-
const void* DTable, U32 fast)
|
1243
|
-
{
|
1244
|
-
BYTE* op = (BYTE*) dst;
|
1245
|
-
BYTE* const olimit = op;
|
1246
|
-
BYTE* const oend = op + maxDstSize;
|
1247
|
-
FSE_DStream_t bitD;
|
1248
|
-
FSE_DState_t state1, state2;
|
1249
|
-
size_t errorCode;
|
1250
|
-
|
1251
|
-
/* Init */
|
1252
|
-
errorCode = FSE_initDStream(&bitD, src, srcSize);
|
1253
|
-
if (FSE_isError(errorCode)) return (size_t)-ZSTD_ERROR_GENERIC;
|
1254
|
-
|
1255
|
-
FSE_initDState(&state1, &bitD, DTable);
|
1256
|
-
FSE_initDState(&state2, &bitD, DTable);
|
1257
|
-
op = oend;
|
1258
|
-
|
1259
|
-
// 2 symbols per loop
|
1260
|
-
while (!FSE_reloadDStream(&bitD) && (op>olimit+3))
|
1261
|
-
{
|
1262
|
-
*--op = fast ? FSE_decodeSymbolFast(&state1, &bitD) : FSE_decodeSymbol(&state1, &bitD);
|
1263
|
-
|
1264
|
-
if (LitFSELog*2+7 > sizeof(size_t)*8) // This test must be static
|
1265
|
-
FSE_reloadDStream(&bitD);
|
1266
|
-
|
1267
|
-
*--op = fast ? FSE_decodeSymbolFast(&state2, &bitD) : FSE_decodeSymbol(&state2, &bitD);
|
1268
|
-
|
1269
|
-
if (LitFSELog*4+7 < sizeof(size_t)*8) // This test must be static
|
1270
|
-
{
|
1271
|
-
*--op = fast ? FSE_decodeSymbolFast(&state1, &bitD) : FSE_decodeSymbol(&state1, &bitD);
|
1272
|
-
*--op = fast ? FSE_decodeSymbolFast(&state2, &bitD) : FSE_decodeSymbol(&state2, &bitD);
|
1273
|
-
}
|
1274
|
-
}
|
1275
|
-
|
1276
|
-
/* tail */
|
1277
|
-
while (1)
|
1278
|
-
{
|
1279
|
-
if ( (FSE_reloadDStream(&bitD)>2) || (op==olimit) || (FSE_endOfDState(&state1) && FSE_endOfDStream(&bitD)) )
|
1280
|
-
break;
|
1281
|
-
|
1282
|
-
*--op = fast ? FSE_decodeSymbolFast(&state1, &bitD) : FSE_decodeSymbol(&state1, &bitD);
|
1283
|
-
|
1284
|
-
if ( (FSE_reloadDStream(&bitD)>2) || (op==olimit) || (FSE_endOfDState(&state2) && FSE_endOfDStream(&bitD)) )
|
1285
|
-
break;
|
1286
|
-
|
1287
|
-
*--op = fast ? FSE_decodeSymbolFast(&state2, &bitD) : FSE_decodeSymbol(&state2, &bitD);
|
1288
|
-
}
|
1289
|
-
|
1290
|
-
/* end ? */
|
1291
|
-
if (FSE_endOfDStream(&bitD) && FSE_endOfDState(&state1) && FSE_endOfDState(&state2) )
|
1292
|
-
return oend-op;
|
1293
|
-
|
1294
|
-
if (op==olimit) return (size_t)-ZSTD_ERROR_maxDstSize_tooSmall; /* dst buffer is full, but cSrc unfinished */
|
1295
|
-
|
1296
|
-
return (size_t)-ZSTD_ERROR_GENERIC;
|
1297
|
-
}
|
1298
|
-
|
1299
|
-
static size_t ZSTD_decompressLiterals_usingDTable(
|
1300
|
-
void* const dst, size_t maxDstSize,
|
1301
|
-
const void* src, size_t srcSize,
|
1302
|
-
const void* DTable, U32 fast)
|
1303
|
-
{
|
1304
|
-
if (fast) return ZSTD_decompressLiterals_usingDTable_generic(dst, maxDstSize, src, srcSize, DTable, 1);
|
1305
|
-
return ZSTD_decompressLiterals_usingDTable_generic(dst, maxDstSize, src, srcSize, DTable, 0);
|
1306
|
-
}
|
1307
|
-
|
1308
|
-
static size_t ZSTD_decompressLiterals(void* ctx, void* dst, size_t maxDstSize,
|
1167
|
+
static size_t ZSTD_decompressLiterals(void* ctx,
|
1168
|
+
void* dst, size_t maxDstSize,
|
1309
1169
|
const void* src, size_t srcSize)
|
1310
1170
|
{
|
1311
|
-
|
1171
|
+
BYTE* op = (BYTE*)dst;
|
1172
|
+
BYTE* const oend = op + maxDstSize;
|
1312
1173
|
const BYTE* ip = (const BYTE*)src;
|
1313
|
-
short norm[256];
|
1314
|
-
void* DTable = ctx;
|
1315
|
-
U32 maxSymbolValue = 255;
|
1316
|
-
U32 tableLog;
|
1317
|
-
U32 fastMode;
|
1318
1174
|
size_t errorCode;
|
1175
|
+
size_t litSize;
|
1319
1176
|
|
1320
|
-
|
1177
|
+
/* check : minimum 2, for litSize, +1, for content */
|
1178
|
+
if (srcSize <= 3) return (size_t)-ZSTD_ERROR_corruption;
|
1321
1179
|
|
1322
|
-
|
1323
|
-
|
1324
|
-
|
1325
|
-
srcSize -= errorCode;
|
1180
|
+
litSize = ip[1] + (ip[0]<<8);
|
1181
|
+
litSize += ((ip[-3] >> 3) & 7) << 16; // mmmmh....
|
1182
|
+
op = oend - litSize;
|
1326
1183
|
|
1327
|
-
|
1184
|
+
(void)ctx;
|
1185
|
+
if (litSize > maxDstSize) return (size_t)-ZSTD_ERROR_maxDstSize_tooSmall;
|
1186
|
+
errorCode = HUF_decompress(op, litSize, ip+2, srcSize-2);
|
1328
1187
|
if (FSE_isError(errorCode)) return (size_t)-ZSTD_ERROR_GENERIC;
|
1329
|
-
|
1330
|
-
|
1331
|
-
return ZSTD_decompressLiterals_usingDTable (dst, maxDstSize, ip, srcSize, DTable, fastMode);
|
1188
|
+
return litSize;
|
1332
1189
|
}
|
1333
1190
|
|
1334
1191
|
|
1335
1192
|
size_t ZSTD_decodeLiteralsBlock(void* ctx,
|
1336
1193
|
void* dst, size_t maxDstSize,
|
1337
|
-
const BYTE**
|
1194
|
+
const BYTE** litStart, size_t* litSize,
|
1338
1195
|
const void* src, size_t srcSize)
|
1339
1196
|
{
|
1340
1197
|
const BYTE* const istart = (const BYTE* const)src;
|
@@ -1345,25 +1202,32 @@ size_t ZSTD_decodeLiteralsBlock(void* ctx,
|
|
1345
1202
|
|
1346
1203
|
size_t litcSize = ZSTD_getcBlockSize(src, srcSize, &litbp);
|
1347
1204
|
if (ZSTD_isError(litcSize)) return litcSize;
|
1348
|
-
if (litcSize > srcSize - ZSTD_blockHeaderSize) return (size_t)-
|
1205
|
+
if (litcSize > srcSize - ZSTD_blockHeaderSize) return (size_t)-ZSTD_ERROR_SrcSize;
|
1349
1206
|
ip += ZSTD_blockHeaderSize;
|
1350
1207
|
|
1351
1208
|
switch(litbp.blockType)
|
1352
1209
|
{
|
1353
|
-
case bt_raw:
|
1210
|
+
case bt_raw:
|
1211
|
+
*litStart = ip;
|
1212
|
+
ip += litcSize;
|
1213
|
+
*litSize = litcSize;
|
1214
|
+
break;
|
1354
1215
|
case bt_rle:
|
1355
1216
|
{
|
1356
1217
|
size_t rleSize = litbp.origSize;
|
1218
|
+
if (rleSize>maxDstSize) return (size_t)-ZSTD_ERROR_maxDstSize_tooSmall;
|
1357
1219
|
memset(oend - rleSize, *ip, rleSize);
|
1358
|
-
*
|
1220
|
+
*litStart = oend - rleSize;
|
1221
|
+
*litSize = rleSize;
|
1359
1222
|
ip++;
|
1360
1223
|
break;
|
1361
1224
|
}
|
1362
1225
|
case bt_compressed:
|
1363
1226
|
{
|
1364
|
-
size_t
|
1365
|
-
if (ZSTD_isError(
|
1366
|
-
*
|
1227
|
+
size_t decodedLitSize = ZSTD_decompressLiterals(ctx, dst, maxDstSize, ip, litcSize);
|
1228
|
+
if (ZSTD_isError(decodedLitSize)) return decodedLitSize;
|
1229
|
+
*litStart = oend - decodedLitSize;
|
1230
|
+
*litSize = decodedLitSize;
|
1367
1231
|
ip += litcSize;
|
1368
1232
|
break;
|
1369
1233
|
}
|
@@ -1375,8 +1239,8 @@ size_t ZSTD_decodeLiteralsBlock(void* ctx,
|
|
1375
1239
|
}
|
1376
1240
|
|
1377
1241
|
|
1378
|
-
size_t ZSTD_decodeSeqHeaders(
|
1379
|
-
|
1242
|
+
size_t ZSTD_decodeSeqHeaders(int* nbSeq, const BYTE** dumpsPtr,
|
1243
|
+
FSE_DTable* DTableLL, FSE_DTable* DTableML, FSE_DTable* DTableOffb,
|
1380
1244
|
const void* src, size_t srcSize)
|
1381
1245
|
{
|
1382
1246
|
const BYTE* const istart = (const BYTE* const)src;
|
@@ -1386,8 +1250,11 @@ size_t ZSTD_decodeSeqHeaders(size_t* lastLLPtr, const BYTE** dumpsPtr,
|
|
1386
1250
|
U32 LLlog, Offlog, MLlog;
|
1387
1251
|
size_t dumpsLength;
|
1388
1252
|
|
1253
|
+
/* check */
|
1254
|
+
if (srcSize < 5) return (size_t)-ZSTD_ERROR_SrcSize;
|
1255
|
+
|
1389
1256
|
/* SeqHead */
|
1390
|
-
|
1257
|
+
*nbSeq = ZSTD_readLE16(ip); ip+=2;
|
1391
1258
|
LLtype = *ip >> 6;
|
1392
1259
|
Offtype = (*ip >> 4) & 3;
|
1393
1260
|
MLtype = (*ip >> 2) & 3;
|
@@ -1406,6 +1273,9 @@ size_t ZSTD_decodeSeqHeaders(size_t* lastLLPtr, const BYTE** dumpsPtr,
|
|
1406
1273
|
*dumpsPtr = ip;
|
1407
1274
|
ip += dumpsLength;
|
1408
1275
|
|
1276
|
+
/* check */
|
1277
|
+
if (ip > iend-3) return (size_t)-ZSTD_ERROR_SrcSize; /* min : all 3 are "raw", hence no header, but at least xxLog bits per type */
|
1278
|
+
|
1409
1279
|
/* sequences */
|
1410
1280
|
{
|
1411
1281
|
S16 norm[MaxML+1]; /* assumption : MaxML >= MaxLL and MaxOff */
|
@@ -1423,8 +1293,9 @@ size_t ZSTD_decodeSeqHeaders(size_t* lastLLPtr, const BYTE** dumpsPtr,
|
|
1423
1293
|
FSE_buildDTable_raw(DTableLL, LLbits); break;
|
1424
1294
|
default :
|
1425
1295
|
max = MaxLL;
|
1426
|
-
headerSize =
|
1296
|
+
headerSize = FSE_readNCount(norm, &max, &LLlog, ip, iend-ip);
|
1427
1297
|
if (FSE_isError(headerSize)) return (size_t)-ZSTD_ERROR_GENERIC;
|
1298
|
+
if (LLlog > LLFSELog) return (size_t)-ZSTD_ERROR_corruption;
|
1428
1299
|
ip += headerSize;
|
1429
1300
|
FSE_buildDTable(DTableLL, norm, max, LLlog);
|
1430
1301
|
}
|
@@ -1434,14 +1305,16 @@ size_t ZSTD_decodeSeqHeaders(size_t* lastLLPtr, const BYTE** dumpsPtr,
|
|
1434
1305
|
U32 max;
|
1435
1306
|
case bt_rle :
|
1436
1307
|
Offlog = 0;
|
1308
|
+
if (ip > iend-2) return (size_t)-ZSTD_ERROR_SrcSize; /* min : "raw", hence no header, but at least xxLog bits */
|
1437
1309
|
FSE_buildDTable_rle(DTableOffb, *ip++); break;
|
1438
1310
|
case bt_raw :
|
1439
1311
|
Offlog = Offbits;
|
1440
1312
|
FSE_buildDTable_raw(DTableOffb, Offbits); break;
|
1441
1313
|
default :
|
1442
1314
|
max = MaxOff;
|
1443
|
-
headerSize =
|
1315
|
+
headerSize = FSE_readNCount(norm, &max, &Offlog, ip, iend-ip);
|
1444
1316
|
if (FSE_isError(headerSize)) return (size_t)-ZSTD_ERROR_GENERIC;
|
1317
|
+
if (Offlog > OffFSELog) return (size_t)-ZSTD_ERROR_corruption;
|
1445
1318
|
ip += headerSize;
|
1446
1319
|
FSE_buildDTable(DTableOffb, norm, max, Offlog);
|
1447
1320
|
}
|
@@ -1451,14 +1324,16 @@ size_t ZSTD_decodeSeqHeaders(size_t* lastLLPtr, const BYTE** dumpsPtr,
|
|
1451
1324
|
U32 max;
|
1452
1325
|
case bt_rle :
|
1453
1326
|
MLlog = 0;
|
1327
|
+
if (ip > iend-2) return (size_t)-ZSTD_ERROR_SrcSize; /* min : "raw", hence no header, but at least xxLog bits */
|
1454
1328
|
FSE_buildDTable_rle(DTableML, *ip++); break;
|
1455
1329
|
case bt_raw :
|
1456
1330
|
MLlog = MLbits;
|
1457
1331
|
FSE_buildDTable_raw(DTableML, MLbits); break;
|
1458
1332
|
default :
|
1459
1333
|
max = MaxML;
|
1460
|
-
headerSize =
|
1334
|
+
headerSize = FSE_readNCount(norm, &max, &MLlog, ip, iend-ip);
|
1461
1335
|
if (FSE_isError(headerSize)) return (size_t)-ZSTD_ERROR_GENERIC;
|
1336
|
+
if (MLlog > MLFSELog) return (size_t)-ZSTD_ERROR_corruption;
|
1462
1337
|
ip += headerSize;
|
1463
1338
|
FSE_buildDTable(DTableML, norm, max, MLlog);
|
1464
1339
|
}
|
@@ -1468,175 +1343,262 @@ size_t ZSTD_decodeSeqHeaders(size_t* lastLLPtr, const BYTE** dumpsPtr,
|
|
1468
1343
|
}
|
1469
1344
|
|
1470
1345
|
|
1471
|
-
|
1346
|
+
typedef struct {
|
1347
|
+
size_t litLength;
|
1348
|
+
size_t offset;
|
1349
|
+
size_t matchLength;
|
1350
|
+
} seq_t;
|
1472
1351
|
|
1473
|
-
|
1474
|
-
|
1475
|
-
|
1476
|
-
|
1477
|
-
|
1478
|
-
|
1479
|
-
BYTE* op = ostart;
|
1480
|
-
BYTE* const oend = ostart + maxDstSize;
|
1481
|
-
size_t errorCode;
|
1482
|
-
size_t lastLLSize;
|
1352
|
+
typedef struct {
|
1353
|
+
FSE_DStream_t DStream;
|
1354
|
+
FSE_DState_t stateLL;
|
1355
|
+
FSE_DState_t stateOffb;
|
1356
|
+
FSE_DState_t stateML;
|
1357
|
+
size_t prevOffset;
|
1483
1358
|
const BYTE* dumps;
|
1484
|
-
|
1485
|
-
const BYTE* litEnd;
|
1486
|
-
const size_t dec32table[] = {4, 1, 2, 1, 4, 4, 4, 4}; /* added */
|
1487
|
-
const size_t dec64table[] = {8, 8, 8, 7, 8, 9,10,11}; /* substracted */
|
1488
|
-
void* DTableML = ctx;
|
1489
|
-
void* DTableLL = ((U32*)ctx) + FSE_DTABLE_SIZE_U32(MLFSELog);
|
1490
|
-
void* DTableOffb = ((U32*)DTableLL) + FSE_DTABLE_SIZE_U32(LLFSELog);
|
1359
|
+
} seqState_t;
|
1491
1360
|
|
1492
|
-
/* blockType == blockCompressed, srcSize is trusted */
|
1493
1361
|
|
1494
|
-
|
1495
|
-
|
1496
|
-
|
1497
|
-
|
1362
|
+
static void ZSTD_decodeSequence(seq_t* seq, seqState_t* seqState)
|
1363
|
+
{
|
1364
|
+
size_t litLength;
|
1365
|
+
size_t prevOffset;
|
1366
|
+
size_t offset;
|
1367
|
+
size_t matchLength;
|
1368
|
+
const BYTE* dumps = seqState->dumps;
|
1369
|
+
|
1370
|
+
/* Literal length */
|
1371
|
+
litLength = FSE_decodeSymbol(&(seqState->stateLL), &(seqState->DStream));
|
1372
|
+
prevOffset = litLength ? seq->offset : seqState->prevOffset;
|
1373
|
+
seqState->prevOffset = seq->offset;
|
1374
|
+
if (litLength == MaxLL)
|
1375
|
+
{
|
1376
|
+
U32 add = *dumps++;
|
1377
|
+
if (add < 255) litLength += add;
|
1378
|
+
else
|
1379
|
+
{
|
1380
|
+
litLength = ZSTD_readLE32(dumps) & 0xFFFFFF;
|
1381
|
+
dumps += 3;
|
1382
|
+
}
|
1383
|
+
}
|
1498
1384
|
|
1499
|
-
/*
|
1500
|
-
|
1501
|
-
|
1502
|
-
|
1503
|
-
|
1504
|
-
|
1505
|
-
|
1506
|
-
|
1385
|
+
/* Offset */
|
1386
|
+
{
|
1387
|
+
U32 offsetCode, nbBits;
|
1388
|
+
offsetCode = FSE_decodeSymbol(&(seqState->stateOffb), &(seqState->DStream));
|
1389
|
+
if (ZSTD_32bits()) FSE_reloadDStream(&(seqState->DStream));
|
1390
|
+
nbBits = offsetCode - 1;
|
1391
|
+
if (offsetCode==0) nbBits = 0; /* cmove */
|
1392
|
+
offset = ((size_t)1 << (nbBits & ((sizeof(offset)*8)-1))) + FSE_readBits(&(seqState->DStream), nbBits);
|
1393
|
+
if (ZSTD_32bits()) FSE_reloadDStream(&(seqState->DStream));
|
1394
|
+
if (offsetCode==0) offset = prevOffset;
|
1395
|
+
}
|
1396
|
+
|
1397
|
+
/* MatchLength */
|
1398
|
+
matchLength = FSE_decodeSymbol(&(seqState->stateML), &(seqState->DStream));
|
1399
|
+
if (matchLength == MaxML)
|
1400
|
+
{
|
1401
|
+
U32 add = *dumps++;
|
1402
|
+
if (add < 255) matchLength += add;
|
1403
|
+
else
|
1404
|
+
{
|
1405
|
+
matchLength = ZSTD_readLE32(dumps) & 0xFFFFFF; /* no pb : dumps is always followed by seq tables > 1 byte */
|
1406
|
+
dumps += 3;
|
1407
|
+
}
|
1408
|
+
}
|
1409
|
+
matchLength += MINMATCH;
|
1410
|
+
|
1411
|
+
/* save result */
|
1412
|
+
seq->litLength = litLength;
|
1413
|
+
seq->offset = offset;
|
1414
|
+
seq->matchLength = matchLength;
|
1415
|
+
seqState->dumps = dumps;
|
1416
|
+
}
|
1417
|
+
|
1418
|
+
|
1419
|
+
static size_t ZSTD_execSequence(BYTE* op,
|
1420
|
+
seq_t sequence,
|
1421
|
+
const BYTE** litPtr, const BYTE* const litLimit,
|
1422
|
+
BYTE* const base, BYTE* const oend)
|
1423
|
+
{
|
1424
|
+
static const int dec32table[] = {0, 1, 2, 1, 4, 4, 4, 4}; /* added */
|
1425
|
+
static const int dec64table[] = {8, 8, 8, 7, 8, 9,10,11}; /* substracted */
|
1426
|
+
const BYTE* const ostart = op;
|
1427
|
+
const size_t litLength = sequence.litLength;
|
1428
|
+
BYTE* const endMatch = op + litLength + sequence.matchLength; /* risk : address space overflow (32-bits) */
|
1429
|
+
const BYTE* const litEnd = *litPtr + litLength;
|
1430
|
+
|
1431
|
+
/* check */
|
1432
|
+
if (endMatch > oend) return (size_t)-ZSTD_ERROR_maxDstSize_tooSmall; /* overwrite beyond dst buffer */
|
1433
|
+
if (litEnd > litLimit) return (size_t)-ZSTD_ERROR_corruption;
|
1434
|
+
if (sequence.matchLength > (size_t)(*litPtr-op)) return (size_t)-ZSTD_ERROR_maxDstSize_tooSmall; /* overwrite literal segment */
|
1435
|
+
|
1436
|
+
/* copy Literals */
|
1437
|
+
if (((size_t)(*litPtr - op) < 8) || ((size_t)(oend-litEnd) < 8) || (op+litLength > oend-8))
|
1438
|
+
memmove(op, *litPtr, litLength); /* overwrite risk */
|
1507
1439
|
else
|
1508
|
-
|
1509
|
-
|
1440
|
+
ZSTD_wildcopy(op, *litPtr, litLength);
|
1441
|
+
op += litLength;
|
1442
|
+
*litPtr = litEnd; /* update for next sequence */
|
1510
1443
|
|
1511
|
-
/*
|
1444
|
+
/* check : last match must be at a minimum distance of 8 from end of dest buffer */
|
1445
|
+
if (oend-op < 8) return (size_t)-ZSTD_ERROR_maxDstSize_tooSmall;
|
1446
|
+
|
1447
|
+
/* copy Match */
|
1512
1448
|
{
|
1513
|
-
|
1514
|
-
|
1515
|
-
size_t
|
1516
|
-
|
1449
|
+
const U32 overlapRisk = (((size_t)(litEnd - endMatch)) < 12);
|
1450
|
+
const BYTE* match = op - sequence.offset; /* possible underflow at op - offset ? */
|
1451
|
+
size_t qutt = 12;
|
1452
|
+
U64 saved[2];
|
1517
1453
|
|
1518
|
-
|
1519
|
-
|
1520
|
-
|
1521
|
-
FSE_initDState(&stateML, &DStream, DTableML);
|
1454
|
+
/* check */
|
1455
|
+
if (match < base) return (size_t)-ZSTD_ERROR_corruption;
|
1456
|
+
if (sequence.offset > (size_t)base) return (size_t)-ZSTD_ERROR_corruption;
|
1522
1457
|
|
1523
|
-
|
1458
|
+
/* save beginning of literal sequence, in case of write overlap */
|
1459
|
+
if (overlapRisk)
|
1524
1460
|
{
|
1525
|
-
|
1526
|
-
|
1527
|
-
|
1528
|
-
size_t matchLength;
|
1529
|
-
size_t newOffset;
|
1530
|
-
|
1531
|
-
_another_round:
|
1461
|
+
if ((endMatch + qutt) > oend) qutt = oend-endMatch;
|
1462
|
+
memcpy(saved, endMatch, qutt);
|
1463
|
+
}
|
1532
1464
|
|
1533
|
-
|
1534
|
-
|
1535
|
-
|
1536
|
-
|
1465
|
+
if (sequence.offset < 8)
|
1466
|
+
{
|
1467
|
+
const int dec64 = dec64table[sequence.offset];
|
1468
|
+
op[0] = match[0];
|
1469
|
+
op[1] = match[1];
|
1470
|
+
op[2] = match[2];
|
1471
|
+
op[3] = match[3];
|
1472
|
+
match += dec32table[sequence.offset];
|
1473
|
+
ZSTD_copy4(op+4, match);
|
1474
|
+
match -= dec64;
|
1475
|
+
} else { ZSTD_copy8(op, match); }
|
1476
|
+
op += 8; match += 8;
|
1477
|
+
|
1478
|
+
if (endMatch > oend-12)
|
1479
|
+
{
|
1480
|
+
if (op < oend-8)
|
1537
1481
|
{
|
1538
|
-
|
1539
|
-
|
1540
|
-
|
1541
|
-
{
|
1542
|
-
//litLength = (*(U32*)dumps) & 0xFFFFFF;
|
1543
|
-
litLength = ZSTD_readLE32(dumps) & 0xFFFFFF;
|
1544
|
-
dumps += 3;
|
1545
|
-
}
|
1482
|
+
ZSTD_wildcopy(op, match, (oend-8) - op);
|
1483
|
+
match += (oend-8) - op;
|
1484
|
+
op = oend-8;
|
1546
1485
|
}
|
1547
|
-
|
1548
|
-
|
1549
|
-
|
1550
|
-
|
1551
|
-
op += litLength; CHECK_OVERFLOW(op <= (BYTE *)dst + maxDstSize);
|
1552
|
-
litPtr += litLength;
|
1553
|
-
|
1554
|
-
/* Offset */
|
1555
|
-
offsetCode = FSE_decodeSymbol(&stateOffb, &DStream);
|
1556
|
-
if (ZSTD_32bits()) FSE_reloadDStream(&DStream);
|
1557
|
-
nbBits = offsetCode - 1;
|
1558
|
-
if (offsetCode==0) nbBits = 0; /* cmove */
|
1559
|
-
newOffset = FSE_readBits(&DStream, nbBits);
|
1560
|
-
if (ZSTD_32bits()) FSE_reloadDStream(&DStream);
|
1561
|
-
newOffset += (size_t)1 << nbBits;
|
1562
|
-
if (offsetCode==0) newOffset = prevOffset;
|
1563
|
-
match = op - newOffset;
|
1564
|
-
prevOffset = offset;
|
1565
|
-
offset = newOffset;
|
1486
|
+
while (op<endMatch) *op++ = *match++;
|
1487
|
+
}
|
1488
|
+
else
|
1489
|
+
ZSTD_wildcopy(op, match, sequence.matchLength-8); /* works even if matchLength < 8 */
|
1566
1490
|
|
1567
|
-
|
1568
|
-
|
1569
|
-
|
1570
|
-
{
|
1571
|
-
BYTE add = *dumps++;
|
1572
|
-
if (add < 255) matchLength += add;
|
1573
|
-
else
|
1574
|
-
{
|
1575
|
-
//matchLength = (*(U32*)dumps) & 0xFFFFFF;
|
1576
|
-
matchLength = ZSTD_readLE32(dumps) & 0xFFFFFF;
|
1577
|
-
dumps += 3;
|
1578
|
-
}
|
1579
|
-
}
|
1580
|
-
matchLength += MINMATCH;
|
1491
|
+
/* restore, in case of overlap */
|
1492
|
+
if (overlapRisk) memcpy(endMatch, saved, qutt);
|
1493
|
+
}
|
1581
1494
|
|
1582
|
-
|
1583
|
-
|
1584
|
-
|
1585
|
-
|
1586
|
-
|
1587
|
-
|
1588
|
-
|
1589
|
-
|
1590
|
-
|
1591
|
-
|
1592
|
-
|
1593
|
-
|
1594
|
-
|
1595
|
-
|
1596
|
-
|
1597
|
-
|
1598
|
-
|
1599
|
-
|
1600
|
-
|
1601
|
-
|
1602
|
-
|
1603
|
-
|
1604
|
-
|
1605
|
-
|
1606
|
-
|
1607
|
-
|
1608
|
-
|
1609
|
-
|
1610
|
-
|
1611
|
-
|
1612
|
-
|
1613
|
-
|
1614
|
-
|
1615
|
-
|
1616
|
-
|
1617
|
-
|
1618
|
-
|
1619
|
-
|
1620
|
-
|
1621
|
-
|
1622
|
-
|
1623
|
-
|
1495
|
+
return endMatch-ostart;
|
1496
|
+
}
|
1497
|
+
|
1498
|
+
typedef struct ZSTD_Dctx_s
|
1499
|
+
{
|
1500
|
+
U32 LLTable[FSE_DTABLE_SIZE_U32(LLFSELog)];
|
1501
|
+
U32 OffTable[FSE_DTABLE_SIZE_U32(OffFSELog)];
|
1502
|
+
U32 MLTable[FSE_DTABLE_SIZE_U32(MLFSELog)];
|
1503
|
+
void* previousDstEnd;
|
1504
|
+
void* base;
|
1505
|
+
size_t expected;
|
1506
|
+
blockType_t bType;
|
1507
|
+
U32 phase;
|
1508
|
+
} dctx_t;
|
1509
|
+
|
1510
|
+
|
1511
|
+
static size_t ZSTD_decompressSequences(
|
1512
|
+
void* ctx,
|
1513
|
+
void* dst, size_t maxDstSize,
|
1514
|
+
const void* seqStart, size_t seqSize,
|
1515
|
+
const BYTE* litStart, size_t litSize)
|
1516
|
+
{
|
1517
|
+
dctx_t* dctx = (dctx_t*)ctx;
|
1518
|
+
const BYTE* ip = (const BYTE*)seqStart;
|
1519
|
+
const BYTE* const iend = ip + seqSize;
|
1520
|
+
BYTE* const ostart = (BYTE* const)dst;
|
1521
|
+
BYTE* op = ostart;
|
1522
|
+
BYTE* const oend = ostart + maxDstSize;
|
1523
|
+
size_t errorCode;
|
1524
|
+
const BYTE* litPtr = litStart;
|
1525
|
+
const BYTE* const litEnd = litStart + litSize;
|
1526
|
+
int nbSeq;
|
1527
|
+
const BYTE* dumps;
|
1528
|
+
U32* DTableLL = dctx->LLTable;
|
1529
|
+
U32* DTableML = dctx->MLTable;
|
1530
|
+
U32* DTableOffb = dctx->OffTable;
|
1531
|
+
BYTE* const base = (BYTE*) (dctx->base);
|
1532
|
+
|
1533
|
+
/* Build Decoding Tables */
|
1534
|
+
errorCode = ZSTD_decodeSeqHeaders(&nbSeq, &dumps,
|
1535
|
+
DTableLL, DTableML, DTableOffb,
|
1536
|
+
ip, iend-ip);
|
1537
|
+
if (ZSTD_isError(errorCode)) return errorCode;
|
1538
|
+
ip += errorCode;
|
1539
|
+
|
1540
|
+
/* Regen sequences */
|
1541
|
+
{
|
1542
|
+
seq_t sequence;
|
1543
|
+
seqState_t seqState;
|
1544
|
+
|
1545
|
+
memset(&sequence, 0, sizeof(sequence));
|
1546
|
+
seqState.dumps = dumps;
|
1547
|
+
seqState.prevOffset = 1;
|
1548
|
+
errorCode = FSE_initDStream(&(seqState.DStream), ip, iend-ip);
|
1549
|
+
if (FSE_isError(errorCode)) return (size_t)-ZSTD_ERROR_corruption;
|
1550
|
+
FSE_initDState(&(seqState.stateLL), &(seqState.DStream), DTableLL);
|
1551
|
+
FSE_initDState(&(seqState.stateOffb), &(seqState.DStream), DTableOffb);
|
1552
|
+
FSE_initDState(&(seqState.stateML), &(seqState.DStream), DTableML);
|
1553
|
+
|
1554
|
+
for ( ; (FSE_reloadDStream(&(seqState.DStream)) < FSE_DStream_completed) || (nbSeq>0) ; )
|
1555
|
+
{
|
1556
|
+
size_t oneSeqSize;
|
1557
|
+
nbSeq--;
|
1558
|
+
ZSTD_decodeSequence(&sequence, &seqState);
|
1559
|
+
oneSeqSize = ZSTD_execSequence(op, sequence, &litPtr, litEnd, base, oend);
|
1560
|
+
if (ZSTD_isError(oneSeqSize)) return oneSeqSize;
|
1561
|
+
op += oneSeqSize;
|
1624
1562
|
}
|
1625
1563
|
|
1626
1564
|
/* check if reached exact end */
|
1627
|
-
if (FSE_reloadDStream(&DStream) >
|
1628
|
-
if (
|
1629
|
-
if (litPtr != litEnd) goto _another_round; /* literals not entirely spent */
|
1565
|
+
if (FSE_reloadDStream(&(seqState.DStream)) > FSE_DStream_completed) return (size_t)-ZSTD_ERROR_corruption; /* requested too much : data is corrupted */
|
1566
|
+
if (nbSeq<0) return (size_t)-ZSTD_ERROR_corruption; /* requested too many sequences : data is corrupted */
|
1630
1567
|
|
1631
1568
|
/* last literal segment */
|
1632
|
-
|
1633
|
-
|
1569
|
+
{
|
1570
|
+
size_t lastLLSize = litEnd - litPtr;
|
1571
|
+
if (op+lastLLSize > oend) return (size_t)-ZSTD_ERROR_maxDstSize_tooSmall;
|
1572
|
+
if (op != litPtr) memmove(op, litPtr, lastLLSize);
|
1573
|
+
op += lastLLSize;
|
1574
|
+
}
|
1634
1575
|
}
|
1635
1576
|
|
1636
1577
|
return op-ostart;
|
1637
1578
|
}
|
1638
1579
|
|
1639
1580
|
|
1581
|
+
static size_t ZSTD_decompressBlock(
|
1582
|
+
void* ctx,
|
1583
|
+
void* dst, size_t maxDstSize,
|
1584
|
+
const void* src, size_t srcSize)
|
1585
|
+
{
|
1586
|
+
/* blockType == blockCompressed, srcSize is trusted */
|
1587
|
+
const BYTE* ip = (const BYTE*)src;
|
1588
|
+
const BYTE* litPtr;
|
1589
|
+
size_t litSize;
|
1590
|
+
size_t errorCode;
|
1591
|
+
|
1592
|
+
/* Decode literals sub-block */
|
1593
|
+
errorCode = ZSTD_decodeLiteralsBlock(ctx, dst, maxDstSize, &litPtr, &litSize, src, srcSize);
|
1594
|
+
if (ZSTD_isError(errorCode)) return errorCode;
|
1595
|
+
ip += errorCode;
|
1596
|
+
srcSize -= errorCode;
|
1597
|
+
|
1598
|
+
return ZSTD_decompressSequences(ctx, dst, maxDstSize, ip, srcSize, litPtr, litSize);
|
1599
|
+
}
|
1600
|
+
|
1601
|
+
|
1640
1602
|
static size_t ZSTD_decompressDCtx(void* ctx, void* dst, size_t maxDstSize, const void* src, size_t srcSize)
|
1641
1603
|
{
|
1642
1604
|
const BYTE* ip = (const BYTE*)src;
|
@@ -1649,22 +1611,21 @@ static size_t ZSTD_decompressDCtx(void* ctx, void* dst, size_t maxDstSize, const
|
|
1649
1611
|
size_t errorCode=0;
|
1650
1612
|
blockProperties_t blockProperties;
|
1651
1613
|
|
1652
|
-
/* Header */
|
1653
|
-
if (srcSize < ZSTD_frameHeaderSize) return (size_t)-
|
1614
|
+
/* Frame Header */
|
1615
|
+
if (srcSize < ZSTD_frameHeaderSize+ZSTD_blockHeaderSize) return (size_t)-ZSTD_ERROR_SrcSize;
|
1654
1616
|
magicNumber = ZSTD_readBE32(src);
|
1655
|
-
if (magicNumber != ZSTD_magicNumber) return (size_t)-
|
1617
|
+
if (magicNumber != ZSTD_magicNumber) return (size_t)-ZSTD_ERROR_MagicNumber;
|
1656
1618
|
ip += ZSTD_frameHeaderSize; remainingSize -= ZSTD_frameHeaderSize;
|
1657
1619
|
|
1620
|
+
/* Loop on each block */
|
1658
1621
|
while (1)
|
1659
1622
|
{
|
1660
1623
|
size_t blockSize = ZSTD_getcBlockSize(ip, iend-ip, &blockProperties);
|
1661
|
-
if (ZSTD_isError(blockSize))
|
1662
|
-
return blockSize;
|
1624
|
+
if (ZSTD_isError(blockSize)) return blockSize;
|
1663
1625
|
|
1664
1626
|
ip += ZSTD_blockHeaderSize;
|
1665
1627
|
remainingSize -= ZSTD_blockHeaderSize;
|
1666
|
-
if (
|
1667
|
-
return (size_t)-ZSTD_ERROR_wrongSrcSize;
|
1628
|
+
if (blockSize > remainingSize) return (size_t)-ZSTD_ERROR_SrcSize;
|
1668
1629
|
|
1669
1630
|
switch(blockProperties.blockType)
|
1670
1631
|
{
|
@@ -1675,11 +1636,11 @@ static size_t ZSTD_decompressDCtx(void* ctx, void* dst, size_t maxDstSize, const
|
|
1675
1636
|
errorCode = ZSTD_copyUncompressedBlock(op, oend-op, ip, blockSize);
|
1676
1637
|
break;
|
1677
1638
|
case bt_rle :
|
1678
|
-
return (size_t)-ZSTD_ERROR_GENERIC; /* not yet
|
1639
|
+
return (size_t)-ZSTD_ERROR_GENERIC; /* not yet supported */
|
1679
1640
|
break;
|
1680
1641
|
case bt_end :
|
1681
1642
|
/* end of frame */
|
1682
|
-
if (remainingSize) return (size_t)-
|
1643
|
+
if (remainingSize) return (size_t)-ZSTD_ERROR_SrcSize;
|
1683
1644
|
break;
|
1684
1645
|
default:
|
1685
1646
|
return (size_t)-ZSTD_ERROR_GENERIC;
|
@@ -1687,7 +1648,7 @@ static size_t ZSTD_decompressDCtx(void* ctx, void* dst, size_t maxDstSize, const
|
|
1687
1648
|
if (blockSize == 0) break; /* bt_end */
|
1688
1649
|
|
1689
1650
|
if (ZSTD_isError(errorCode)) return errorCode;
|
1690
|
-
op += errorCode;
|
1651
|
+
op += errorCode;
|
1691
1652
|
ip += blockSize;
|
1692
1653
|
remainingSize -= blockSize;
|
1693
1654
|
}
|
@@ -1695,107 +1656,113 @@ static size_t ZSTD_decompressDCtx(void* ctx, void* dst, size_t maxDstSize, const
|
|
1695
1656
|
return op-ostart;
|
1696
1657
|
}
|
1697
1658
|
|
1698
|
-
|
1699
1659
|
size_t ZSTD_decompress(void* dst, size_t maxDstSize, const void* src, size_t srcSize)
|
1700
1660
|
{
|
1701
|
-
|
1702
|
-
|
1661
|
+
dctx_t ctx;
|
1662
|
+
ctx.base = dst;
|
1663
|
+
return ZSTD_decompressDCtx(&ctx, dst, maxDstSize, src, srcSize);
|
1703
1664
|
}
|
1704
1665
|
|
1705
1666
|
|
1706
|
-
|
1667
|
+
/*******************************
|
1707
1668
|
* Streaming Decompression API
|
1708
|
-
|
1669
|
+
*******************************/
|
1709
1670
|
|
1710
|
-
|
1671
|
+
size_t ZSTD_resetDCtx(ZSTD_Dctx* dctx)
|
1711
1672
|
{
|
1712
|
-
|
1713
|
-
|
1714
|
-
|
1715
|
-
|
1716
|
-
|
1717
|
-
|
1673
|
+
dctx->expected = ZSTD_frameHeaderSize;
|
1674
|
+
dctx->phase = 0;
|
1675
|
+
dctx->previousDstEnd = NULL;
|
1676
|
+
dctx->base = NULL;
|
1677
|
+
return 0;
|
1678
|
+
}
|
1718
1679
|
|
1719
|
-
|
1680
|
+
ZSTD_Dctx* ZSTD_createDCtx(void)
|
1720
1681
|
{
|
1721
|
-
|
1722
|
-
dctx
|
1723
|
-
dctx
|
1724
|
-
return
|
1682
|
+
ZSTD_Dctx* dctx = (ZSTD_Dctx*)malloc(sizeof(ZSTD_Dctx));
|
1683
|
+
if (dctx==NULL) return NULL;
|
1684
|
+
ZSTD_resetDCtx(dctx);
|
1685
|
+
return dctx;
|
1725
1686
|
}
|
1726
1687
|
|
1727
|
-
size_t ZSTD_freeDCtx(
|
1688
|
+
size_t ZSTD_freeDCtx(ZSTD_Dctx* dctx)
|
1728
1689
|
{
|
1729
1690
|
free(dctx);
|
1730
1691
|
return 0;
|
1731
1692
|
}
|
1732
1693
|
|
1733
|
-
|
1734
|
-
size_t ZSTD_getNextcBlockSize(ZSTD_dctx_t dctx)
|
1694
|
+
size_t ZSTD_nextSrcSizeToDecompress(ZSTD_Dctx* dctx)
|
1735
1695
|
{
|
1736
1696
|
return ((dctx_t*)dctx)->expected;
|
1737
1697
|
}
|
1738
1698
|
|
1739
|
-
size_t ZSTD_decompressContinue(
|
1699
|
+
size_t ZSTD_decompressContinue(ZSTD_Dctx* dctx, void* dst, size_t maxDstSize, const void* src, size_t srcSize)
|
1740
1700
|
{
|
1741
1701
|
dctx_t* ctx = (dctx_t*)dctx;
|
1742
|
-
size_t cSize = srcSize - ZSTD_blockHeaderSize;
|
1743
|
-
size_t rSize;
|
1744
1702
|
|
1745
|
-
|
1746
|
-
if (srcSize != ctx->expected) return (size_t)-
|
1703
|
+
/* Sanity check */
|
1704
|
+
if (srcSize != ctx->expected) return (size_t)-ZSTD_ERROR_SrcSize;
|
1705
|
+
if (dst != ctx->previousDstEnd) /* not contiguous */
|
1706
|
+
ctx->base = dst;
|
1747
1707
|
|
1748
|
-
|
1749
|
-
if (
|
1708
|
+
/* Decompress : frame header */
|
1709
|
+
if (ctx->phase == 0)
|
1750
1710
|
{
|
1751
|
-
|
1711
|
+
/* Check frame magic header */
|
1752
1712
|
U32 magicNumber = ZSTD_readBE32(src);
|
1753
|
-
if (magicNumber != ZSTD_magicNumber) return (size_t)-
|
1754
|
-
|
1713
|
+
if (magicNumber != ZSTD_magicNumber) return (size_t)-ZSTD_ERROR_MagicNumber;
|
1714
|
+
ctx->phase = 1;
|
1715
|
+
ctx->expected = ZSTD_blockHeaderSize;
|
1716
|
+
return 0;
|
1755
1717
|
}
|
1756
|
-
|
1718
|
+
|
1719
|
+
/* Decompress : block header */
|
1720
|
+
if (ctx->phase == 1)
|
1721
|
+
{
|
1722
|
+
blockProperties_t bp;
|
1723
|
+
size_t blockSize = ZSTD_getcBlockSize(src, ZSTD_blockHeaderSize, &bp);
|
1724
|
+
if (ZSTD_isError(blockSize)) return blockSize;
|
1725
|
+
if (bp.blockType == bt_end)
|
1726
|
+
{
|
1727
|
+
ctx->expected = 0;
|
1728
|
+
ctx->phase = 0;
|
1729
|
+
}
|
1730
|
+
else
|
1731
|
+
{
|
1732
|
+
ctx->expected = blockSize;
|
1733
|
+
ctx->bType = bp.blockType;
|
1734
|
+
ctx->phase = 2;
|
1735
|
+
}
|
1736
|
+
|
1737
|
+
return 0;
|
1738
|
+
}
|
1739
|
+
|
1740
|
+
/* Decompress : block content */
|
1757
1741
|
{
|
1742
|
+
size_t rSize;
|
1758
1743
|
switch(ctx->bType)
|
1759
1744
|
{
|
1760
1745
|
case bt_compressed:
|
1761
|
-
rSize = ZSTD_decompressBlock(ctx, dst, maxDstSize, src,
|
1746
|
+
rSize = ZSTD_decompressBlock(ctx, dst, maxDstSize, src, srcSize);
|
1762
1747
|
break;
|
1763
1748
|
case bt_raw :
|
1764
|
-
rSize = ZSTD_copyUncompressedBlock(dst, maxDstSize, src,
|
1749
|
+
rSize = ZSTD_copyUncompressedBlock(dst, maxDstSize, src, srcSize);
|
1765
1750
|
break;
|
1766
1751
|
case bt_rle :
|
1767
1752
|
return (size_t)-ZSTD_ERROR_GENERIC; /* not yet handled */
|
1768
1753
|
break;
|
1769
|
-
case bt_end :
|
1754
|
+
case bt_end : /* should never happen (filtered at phase 1) */
|
1770
1755
|
rSize = 0;
|
1771
1756
|
break;
|
1772
1757
|
default:
|
1773
1758
|
return (size_t)-ZSTD_ERROR_GENERIC;
|
1774
1759
|
}
|
1760
|
+
ctx->phase = 1;
|
1761
|
+
ctx->expected = ZSTD_blockHeaderSize;
|
1762
|
+
ctx->previousDstEnd = (void*)( ((char*)dst) + rSize);
|
1763
|
+
return rSize;
|
1775
1764
|
}
|
1776
1765
|
|
1777
|
-
// Prepare next block
|
1778
|
-
{
|
1779
|
-
const BYTE* header = (const BYTE*)src;
|
1780
|
-
blockProperties_t bp;
|
1781
|
-
size_t blockSize;
|
1782
|
-
header += cSize;
|
1783
|
-
blockSize = ZSTD_getcBlockSize(header, ZSTD_blockHeaderSize, &bp);
|
1784
|
-
if (ZSTD_isError(blockSize)) return blockSize;
|
1785
|
-
if (bp.blockType == bt_end)
|
1786
|
-
{
|
1787
|
-
ctx->expected = 0;
|
1788
|
-
ctx->started = 0;
|
1789
|
-
}
|
1790
|
-
else
|
1791
|
-
{
|
1792
|
-
ctx->expected = blockSize + ZSTD_blockHeaderSize;
|
1793
|
-
ctx->bType = bp.blockType;
|
1794
|
-
ctx->started = 1;
|
1795
|
-
}
|
1796
|
-
}
|
1797
|
-
|
1798
|
-
return rSize;
|
1799
1766
|
}
|
1800
1767
|
|
1801
1768
|
|