mirror of
https://github.com/Xevion/easy7zip.git
synced 2025-12-11 18:07:08 -06:00
zstd release 0.8.0
- made an extra zstd.mak file - removed Format7zZStd - SFXSetup also has zstd now - the big 7z.dll is backward compatible to: 0.5 .. 0.7 - the small 7za.dll has only support for zstd 0.8
This commit is contained in:
@@ -38,10 +38,9 @@
|
|||||||
#include "mem.h"
|
#include "mem.h"
|
||||||
#include "error_private.h" /* ERR_*, ERROR */
|
#include "error_private.h" /* ERR_*, ERROR */
|
||||||
#define FSE_STATIC_LINKING_ONLY /* FSE_MIN_TABLELOG */
|
#define FSE_STATIC_LINKING_ONLY /* FSE_MIN_TABLELOG */
|
||||||
#include "fse.h" /* FSE_isError, FSE_getErrorName */
|
#include "fse.h"
|
||||||
#define HUF_STATIC_LINKING_ONLY /* HUF_TABLELOG_ABSOLUTEMAX */
|
#define HUF_STATIC_LINKING_ONLY /* HUF_TABLELOG_ABSOLUTEMAX */
|
||||||
#include "huf.h" /* HUF_isError, HUF_getErrorName */
|
#include "huf.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*-****************************************
|
/*-****************************************
|
||||||
@@ -63,7 +62,7 @@ const char* HUF_getErrorName(size_t code) { return ERR_getErrorName(code); }
|
|||||||
/*-**************************************************************
|
/*-**************************************************************
|
||||||
* FSE NCount encoding-decoding
|
* FSE NCount encoding-decoding
|
||||||
****************************************************************/
|
****************************************************************/
|
||||||
static short FSE_abs(short a) { return a<0 ? -a : a; }
|
static short FSE_abs(short a) { return (short)(a<0 ? -a : a); }
|
||||||
|
|
||||||
size_t FSE_readNCount (short* normalizedCounter, unsigned* maxSVPtr, unsigned* tableLogPtr,
|
size_t FSE_readNCount (short* normalizedCounter, unsigned* maxSVPtr, unsigned* tableLogPtr,
|
||||||
const void* headerBuffer, size_t hbSize)
|
const void* headerBuffer, size_t hbSize)
|
||||||
@@ -90,22 +89,22 @@ size_t FSE_readNCount (short* normalizedCounter, unsigned* maxSVPtr, unsigned* t
|
|||||||
threshold = 1<<nbBits;
|
threshold = 1<<nbBits;
|
||||||
nbBits++;
|
nbBits++;
|
||||||
|
|
||||||
while ((remaining>1) && (charnum<=*maxSVPtr)) {
|
while ((remaining>1) & (charnum<=*maxSVPtr)) {
|
||||||
if (previous0) {
|
if (previous0) {
|
||||||
unsigned n0 = charnum;
|
unsigned n0 = charnum;
|
||||||
while ((bitStream & 0xFFFF) == 0xFFFF) {
|
while ((bitStream & 0xFFFF) == 0xFFFF) {
|
||||||
n0+=24;
|
n0 += 24;
|
||||||
if (ip < iend-5) {
|
if (ip < iend-5) {
|
||||||
ip+=2;
|
ip += 2;
|
||||||
bitStream = MEM_readLE32(ip) >> bitCount;
|
bitStream = MEM_readLE32(ip) >> bitCount;
|
||||||
} else {
|
} else {
|
||||||
bitStream >>= 16;
|
bitStream >>= 16;
|
||||||
bitCount+=16;
|
bitCount += 16;
|
||||||
} }
|
} }
|
||||||
while ((bitStream & 3) == 3) {
|
while ((bitStream & 3) == 3) {
|
||||||
n0+=3;
|
n0 += 3;
|
||||||
bitStream>>=2;
|
bitStream >>= 2;
|
||||||
bitCount+=2;
|
bitCount += 2;
|
||||||
}
|
}
|
||||||
n0 += bitStream & 3;
|
n0 += bitStream & 3;
|
||||||
bitCount += 2;
|
bitCount += 2;
|
||||||
@@ -115,10 +114,9 @@ size_t FSE_readNCount (short* normalizedCounter, unsigned* maxSVPtr, unsigned* t
|
|||||||
ip += bitCount>>3;
|
ip += bitCount>>3;
|
||||||
bitCount &= 7;
|
bitCount &= 7;
|
||||||
bitStream = MEM_readLE32(ip) >> bitCount;
|
bitStream = MEM_readLE32(ip) >> bitCount;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
bitStream >>= 2;
|
bitStream >>= 2;
|
||||||
}
|
} }
|
||||||
{ short const max = (short)((2*threshold-1)-remaining);
|
{ short const max = (short)((2*threshold-1)-remaining);
|
||||||
short count;
|
short count;
|
||||||
|
|
||||||
@@ -148,12 +146,12 @@ size_t FSE_readNCount (short* normalizedCounter, unsigned* maxSVPtr, unsigned* t
|
|||||||
ip = iend - 4;
|
ip = iend - 4;
|
||||||
}
|
}
|
||||||
bitStream = MEM_readLE32(ip) >> (bitCount & 31);
|
bitStream = MEM_readLE32(ip) >> (bitCount & 31);
|
||||||
} } /* while ((remaining>1) && (charnum<=*maxSVPtr)) */
|
} } /* while ((remaining>1) & (charnum<=*maxSVPtr)) */
|
||||||
if (remaining != 1) return ERROR(GENERIC);
|
if (remaining != 1) return ERROR(corruption_detected);
|
||||||
|
if (bitCount > 32) return ERROR(corruption_detected);
|
||||||
*maxSVPtr = charnum-1;
|
*maxSVPtr = charnum-1;
|
||||||
|
|
||||||
ip += (bitCount+7)>>3;
|
ip += (bitCount+7)>>3;
|
||||||
if ((size_t)(ip-istart) > hbSize) return ERROR(srcSize_wrong);
|
|
||||||
return ip-istart;
|
return ip-istart;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -162,7 +160,7 @@ size_t FSE_readNCount (short* normalizedCounter, unsigned* maxSVPtr, unsigned* t
|
|||||||
Read compact Huffman tree, saved by HUF_writeCTable().
|
Read compact Huffman tree, saved by HUF_writeCTable().
|
||||||
`huffWeight` is destination buffer.
|
`huffWeight` is destination buffer.
|
||||||
@return : size read from `src` , or an error Code .
|
@return : size read from `src` , or an error Code .
|
||||||
Note : Needed by HUF_readCTable() and HUF_readDTableXn() .
|
Note : Needed by HUF_readCTable() and HUF_readDTableX?() .
|
||||||
*/
|
*/
|
||||||
size_t HUF_readStats(BYTE* huffWeight, size_t hwSize, U32* rankStats,
|
size_t HUF_readStats(BYTE* huffWeight, size_t hwSize, U32* rankStats,
|
||||||
U32* nbSymbolsPtr, U32* tableLogPtr,
|
U32* nbSymbolsPtr, U32* tableLogPtr,
|
||||||
@@ -173,26 +171,19 @@ size_t HUF_readStats(BYTE* huffWeight, size_t hwSize, U32* rankStats,
|
|||||||
size_t iSize = ip[0];
|
size_t iSize = ip[0];
|
||||||
size_t oSize;
|
size_t oSize;
|
||||||
|
|
||||||
//memset(huffWeight, 0, hwSize); /* is not necessary, even though some analyzer complain ... */
|
/* memset(huffWeight, 0, hwSize); *//* is not necessary, even though some analyzer complain ... */
|
||||||
|
|
||||||
if (iSize >= 128) { /* special header */
|
if (iSize >= 128) { /* special header */
|
||||||
if (iSize >= (242)) { /* RLE */
|
oSize = iSize - 127;
|
||||||
static U32 l[14] = { 1, 2, 3, 4, 7, 8, 15, 16, 31, 32, 63, 64, 127, 128 };
|
iSize = ((oSize+1)/2);
|
||||||
oSize = l[iSize-242];
|
if (iSize+1 > srcSize) return ERROR(srcSize_wrong);
|
||||||
memset(huffWeight, 1, hwSize);
|
if (oSize >= hwSize) return ERROR(corruption_detected);
|
||||||
iSize = 0;
|
ip += 1;
|
||||||
}
|
{ U32 n;
|
||||||
else { /* Incompressible */
|
for (n=0; n<oSize; n+=2) {
|
||||||
oSize = iSize - 127;
|
huffWeight[n] = ip[n/2] >> 4;
|
||||||
iSize = ((oSize+1)/2);
|
huffWeight[n+1] = ip[n/2] & 15;
|
||||||
if (iSize+1 > srcSize) return ERROR(srcSize_wrong);
|
} } }
|
||||||
if (oSize >= hwSize) return ERROR(corruption_detected);
|
|
||||||
ip += 1;
|
|
||||||
{ U32 n;
|
|
||||||
for (n=0; n<oSize; n+=2) {
|
|
||||||
huffWeight[n] = ip[n/2] >> 4;
|
|
||||||
huffWeight[n+1] = ip[n/2] & 15;
|
|
||||||
} } } }
|
|
||||||
else { /* header compressed with FSE (normal case) */
|
else { /* header compressed with FSE (normal case) */
|
||||||
if (iSize+1 > srcSize) return ERROR(srcSize_wrong);
|
if (iSize+1 > srcSize) return ERROR(srcSize_wrong);
|
||||||
oSize = FSE_decompress(huffWeight, hwSize-1, ip+1, iSize); /* max (hwSize-1) values decoded, as last one is implied */
|
oSize = FSE_decompress(huffWeight, hwSize-1, ip+1, iSize); /* max (hwSize-1) values decoded, as last one is implied */
|
||||||
|
|||||||
@@ -190,7 +190,7 @@ size_t FSE_NCountWriteBound(unsigned maxSymbolValue, unsigned tableLog)
|
|||||||
return maxSymbolValue ? maxHeaderSize : FSE_NCOUNTBOUND; /* maxSymbolValue==0 ? use default */
|
return maxSymbolValue ? maxHeaderSize : FSE_NCOUNTBOUND; /* maxSymbolValue==0 ? use default */
|
||||||
}
|
}
|
||||||
|
|
||||||
static short FSE_abs(short a) { return a<0 ? -a : a; }
|
static short FSE_abs(short a) { return (short)(a<0 ? -a : a); }
|
||||||
|
|
||||||
static size_t FSE_writeNCount_generic (void* header, size_t headerBufferSize,
|
static size_t FSE_writeNCount_generic (void* header, size_t headerBufferSize,
|
||||||
const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog,
|
const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog,
|
||||||
|
|||||||
@@ -100,7 +100,7 @@ size_t HUF_compress2 (void* dst, size_t dstSize, const void* src, size_t srcSize
|
|||||||
/* *** Constants *** */
|
/* *** Constants *** */
|
||||||
#define HUF_TABLELOG_ABSOLUTEMAX 16 /* absolute limit of HUF_MAX_TABLELOG. Beyond that value, code does not work */
|
#define HUF_TABLELOG_ABSOLUTEMAX 16 /* absolute limit of HUF_MAX_TABLELOG. Beyond that value, code does not work */
|
||||||
#define HUF_TABLELOG_MAX 12 /* max configured tableLog (for static allocation); can be modified up to HUF_ABSOLUTEMAX_TABLELOG */
|
#define HUF_TABLELOG_MAX 12 /* max configured tableLog (for static allocation); can be modified up to HUF_ABSOLUTEMAX_TABLELOG */
|
||||||
#define HUF_TABLELOG_DEFAULT HUF_TABLELOG_MAX /* tableLog by default, when not specified */
|
#define HUF_TABLELOG_DEFAULT 11 /* tableLog by default, when not specified */
|
||||||
#define HUF_SYMBOLVALUE_MAX 255
|
#define HUF_SYMBOLVALUE_MAX 255
|
||||||
#if (HUF_TABLELOG_MAX > HUF_TABLELOG_ABSOLUTEMAX)
|
#if (HUF_TABLELOG_MAX > HUF_TABLELOG_ABSOLUTEMAX)
|
||||||
# error "HUF_TABLELOG_MAX is too large !"
|
# error "HUF_TABLELOG_MAX is too large !"
|
||||||
|
|||||||
@@ -105,68 +105,39 @@ size_t HUF_writeCTable (void* dst, size_t maxDstSize,
|
|||||||
const HUF_CElt* CTable, U32 maxSymbolValue, U32 huffLog)
|
const HUF_CElt* CTable, U32 maxSymbolValue, U32 huffLog)
|
||||||
{
|
{
|
||||||
BYTE bitsToWeight[HUF_TABLELOG_MAX + 1];
|
BYTE bitsToWeight[HUF_TABLELOG_MAX + 1];
|
||||||
BYTE huffWeight[HUF_SYMBOLVALUE_MAX + 1];
|
BYTE huffWeight[HUF_SYMBOLVALUE_MAX];
|
||||||
U32 n;
|
|
||||||
BYTE* op = (BYTE*)dst;
|
BYTE* op = (BYTE*)dst;
|
||||||
size_t size;
|
U32 n;
|
||||||
|
|
||||||
/* check conditions */
|
/* check conditions */
|
||||||
if (maxSymbolValue > HUF_SYMBOLVALUE_MAX + 1)
|
if (maxSymbolValue > HUF_SYMBOLVALUE_MAX) return ERROR(GENERIC);
|
||||||
return ERROR(GENERIC);
|
|
||||||
|
|
||||||
/* convert to weight */
|
/* convert to weight */
|
||||||
bitsToWeight[0] = 0;
|
bitsToWeight[0] = 0;
|
||||||
for (n=1; n<=huffLog; n++)
|
for (n=1; n<huffLog+1; n++)
|
||||||
bitsToWeight[n] = (BYTE)(huffLog + 1 - n);
|
bitsToWeight[n] = (BYTE)(huffLog + 1 - n);
|
||||||
for (n=0; n<maxSymbolValue; n++)
|
for (n=0; n<maxSymbolValue; n++)
|
||||||
huffWeight[n] = bitsToWeight[CTable[n].nbBits];
|
huffWeight[n] = bitsToWeight[CTable[n].nbBits];
|
||||||
|
|
||||||
size = FSE_compress(op+1, maxDstSize-1, huffWeight, maxSymbolValue); /* don't need last symbol stat : implied */
|
{ size_t const size = FSE_compress(op+1, maxDstSize-1, huffWeight, maxSymbolValue);
|
||||||
if (HUF_isError(size)) return size;
|
if (FSE_isError(size)) return size;
|
||||||
if (size >= 128) return ERROR(GENERIC); /* should never happen, since maxSymbolValue <= 255 */
|
if ((size>1) & (size < maxSymbolValue/2)) { /* FSE compressed */
|
||||||
if ((size <= 1) || (size >= maxSymbolValue/2)) {
|
op[0] = (BYTE)size;
|
||||||
if (size==1) { /* RLE */
|
return size+1;
|
||||||
/* only possible case : series of 1 (because there are at least 2) */
|
} }
|
||||||
/* can only be 2^n or (2^n-1), otherwise not an huffman tree */
|
|
||||||
BYTE code;
|
/* raw values */
|
||||||
switch(maxSymbolValue)
|
if (maxSymbolValue > (256-128)) return ERROR(GENERIC); /* should not happen */
|
||||||
{
|
if (((maxSymbolValue+1)/2) + 1 > maxDstSize) return ERROR(dstSize_tooSmall); /* not enough space within dst buffer */
|
||||||
case 1: code = 0; break;
|
op[0] = (BYTE)(128 /*special case*/ + (maxSymbolValue-1));
|
||||||
case 2: code = 1; break;
|
huffWeight[maxSymbolValue] = 0; /* to be sure it doesn't cause issue in final combination */
|
||||||
case 3: code = 2; break;
|
for (n=0; n<maxSymbolValue; n+=2)
|
||||||
case 4: code = 3; break;
|
op[(n/2)+1] = (BYTE)((huffWeight[n] << 4) + huffWeight[n+1]);
|
||||||
case 7: code = 4; break;
|
return ((maxSymbolValue+1)/2) + 1;
|
||||||
case 8: code = 5; break;
|
|
||||||
case 15: code = 6; break;
|
|
||||||
case 16: code = 7; break;
|
|
||||||
case 31: code = 8; break;
|
|
||||||
case 32: code = 9; break;
|
|
||||||
case 63: code = 10; break;
|
|
||||||
case 64: code = 11; break;
|
|
||||||
case 127: code = 12; break;
|
|
||||||
case 128: code = 13; break;
|
|
||||||
default : return ERROR(corruption_detected);
|
|
||||||
}
|
|
||||||
op[0] = (BYTE)(255-13 + code);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
/* Not compressible */
|
|
||||||
if (maxSymbolValue > (241-128)) return ERROR(GENERIC); /* not implemented (not possible with current format) */
|
|
||||||
if (((maxSymbolValue+1)/2) + 1 > maxDstSize) return ERROR(dstSize_tooSmall); /* not enough space within dst buffer */
|
|
||||||
op[0] = (BYTE)(128 /*special case*/ + 0 /* Not Compressible */ + (maxSymbolValue-1));
|
|
||||||
huffWeight[maxSymbolValue] = 0; /* to be sure it doesn't cause issue in final combination */
|
|
||||||
for (n=0; n<maxSymbolValue; n+=2)
|
|
||||||
op[(n/2)+1] = (BYTE)((huffWeight[n] << 4) + huffWeight[n+1]);
|
|
||||||
return ((maxSymbolValue+1)/2) + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* normal header case */
|
|
||||||
op[0] = (BYTE)size;
|
|
||||||
return size+1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
size_t HUF_readCTable (HUF_CElt* CTable, U32 maxSymbolValue, const void* src, size_t srcSize)
|
size_t HUF_readCTable (HUF_CElt* CTable, U32 maxSymbolValue, const void* src, size_t srcSize)
|
||||||
{
|
{
|
||||||
BYTE huffWeight[HUF_SYMBOLVALUE_MAX + 1];
|
BYTE huffWeight[HUF_SYMBOLVALUE_MAX + 1];
|
||||||
@@ -174,7 +145,7 @@ size_t HUF_readCTable (HUF_CElt* CTable, U32 maxSymbolValue, const void* src, si
|
|||||||
U32 tableLog = 0;
|
U32 tableLog = 0;
|
||||||
size_t readSize;
|
size_t readSize;
|
||||||
U32 nbSymbols = 0;
|
U32 nbSymbols = 0;
|
||||||
//memset(huffWeight, 0, sizeof(huffWeight)); /* is not necessary, even though some analyzer complain ... */
|
/*memset(huffWeight, 0, sizeof(huffWeight));*/ /* is not necessary, even though some analyzer complain ... */
|
||||||
|
|
||||||
/* get symbol weights */
|
/* get symbol weights */
|
||||||
readSize = HUF_readStats(huffWeight, HUF_SYMBOLVALUE_MAX+1, rankVal, &nbSymbols, &tableLog, src, srcSize);
|
readSize = HUF_readStats(huffWeight, HUF_SYMBOLVALUE_MAX+1, rankVal, &nbSymbols, &tableLog, src, srcSize);
|
||||||
@@ -193,10 +164,10 @@ size_t HUF_readCTable (HUF_CElt* CTable, U32 maxSymbolValue, const void* src, si
|
|||||||
} }
|
} }
|
||||||
|
|
||||||
/* fill nbBits */
|
/* fill nbBits */
|
||||||
{ U32 n; for (n=0; n<nbSymbols; n++) {
|
{ U32 n; for (n=0; n<nbSymbols; n++) {
|
||||||
const U32 w = huffWeight[n];
|
const U32 w = huffWeight[n];
|
||||||
CTable[n].nbBits = (BYTE)(tableLog + 1 - w);
|
CTable[n].nbBits = (BYTE)(tableLog + 1 - w);
|
||||||
}}
|
} }
|
||||||
|
|
||||||
/* fill val */
|
/* fill val */
|
||||||
{ U16 nbPerRank[HUF_TABLELOG_MAX+1] = {0};
|
{ U16 nbPerRank[HUF_TABLELOG_MAX+1] = {0};
|
||||||
|
|||||||
26
C/zstd/mem.h
26
C/zstd/mem.h
@@ -44,19 +44,17 @@ extern "C" {
|
|||||||
******************************************/
|
******************************************/
|
||||||
#include <stddef.h> /* size_t, ptrdiff_t */
|
#include <stddef.h> /* size_t, ptrdiff_t */
|
||||||
#include <string.h> /* memcpy */
|
#include <string.h> /* memcpy */
|
||||||
#if defined(_MSC_VER) /* Visual Studio */
|
|
||||||
# include <stdlib.h> /* _byteswap_ulong */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/*-****************************************
|
/*-****************************************
|
||||||
* Compiler specifics
|
* Compiler specifics
|
||||||
******************************************/
|
******************************************/
|
||||||
#if defined(_MSC_VER)
|
#if defined(_MSC_VER) /* Visual Studio */
|
||||||
# include <intrin.h> /* _byteswap_ */
|
# include <stdlib.h> /* _byteswap_ulong */
|
||||||
|
# include <intrin.h> /* _byteswap_* */
|
||||||
#endif
|
#endif
|
||||||
#if defined(__GNUC__)
|
#if defined(__GNUC__)
|
||||||
# define MEM_STATIC static __attribute__((unused))
|
# define MEM_STATIC static __inline __attribute__((unused))
|
||||||
#elif defined (__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */)
|
#elif defined (__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */)
|
||||||
# define MEM_STATIC static inline
|
# define MEM_STATIC static inline
|
||||||
#elif defined(_MSC_VER)
|
#elif defined(_MSC_VER)
|
||||||
@@ -65,6 +63,10 @@ extern "C" {
|
|||||||
# define MEM_STATIC static /* this version may generate warnings for unused static functions; disable the relevant warning */
|
# define MEM_STATIC static /* this version may generate warnings for unused static functions; disable the relevant warning */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* code only tested on 32 and 64 bits systems */
|
||||||
|
#define MEM_STATIC_ASSERT(c) { enum { XXH_static_assert = 1/(int)(!!(c)) }; }
|
||||||
|
MEM_STATIC void MEM_check(void) { MEM_STATIC_ASSERT((sizeof(size_t)==4) || (sizeof(size_t)==8)); }
|
||||||
|
|
||||||
|
|
||||||
/*-**************************************************************
|
/*-**************************************************************
|
||||||
* Basic Types
|
* Basic Types
|
||||||
@@ -256,6 +258,17 @@ MEM_STATIC void MEM_writeLE16(void* memPtr, U16 val)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MEM_STATIC U32 MEM_readLE24(const void* memPtr)
|
||||||
|
{
|
||||||
|
return MEM_readLE16(memPtr) + (((const BYTE*)memPtr)[2] << 16);
|
||||||
|
}
|
||||||
|
|
||||||
|
MEM_STATIC void MEM_writeLE24(void* memPtr, U32 val)
|
||||||
|
{
|
||||||
|
MEM_writeLE16(memPtr, (U16)val);
|
||||||
|
((BYTE*)memPtr)[2] = (BYTE)(val>>16);
|
||||||
|
}
|
||||||
|
|
||||||
MEM_STATIC U32 MEM_readLE32(const void* memPtr)
|
MEM_STATIC U32 MEM_readLE32(const void* memPtr)
|
||||||
{
|
{
|
||||||
if (MEM_isLittleEndian())
|
if (MEM_isLittleEndian())
|
||||||
@@ -374,4 +387,3 @@ MEM_STATIC U32 MEM_readMINMATCH(const void* memPtr, U32 length)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* MEM_H_MODULE */
|
#endif /* MEM_H_MODULE */
|
||||||
|
|
||||||
|
|||||||
@@ -56,6 +56,12 @@ extern "C" {
|
|||||||
/* *************************************
|
/* *************************************
|
||||||
* Streaming functions
|
* Streaming functions
|
||||||
***************************************/
|
***************************************/
|
||||||
|
/* This is the easier "buffered" streaming API,
|
||||||
|
* using an internal buffer to lift all restrictions on user-provided buffers
|
||||||
|
* which can be any size, any place, for both input and output.
|
||||||
|
* ZBUFF and ZSTD are 100% interoperable,
|
||||||
|
* frames created by one can be decoded by the other one */
|
||||||
|
|
||||||
typedef struct ZBUFF_CCtx_s ZBUFF_CCtx;
|
typedef struct ZBUFF_CCtx_s ZBUFF_CCtx;
|
||||||
ZSTDLIB_API ZBUFF_CCtx* ZBUFF_createCCtx(void);
|
ZSTDLIB_API ZBUFF_CCtx* ZBUFF_createCCtx(void);
|
||||||
ZSTDLIB_API size_t ZBUFF_freeCCtx(ZBUFF_CCtx* cctx);
|
ZSTDLIB_API size_t ZBUFF_freeCCtx(ZBUFF_CCtx* cctx);
|
||||||
@@ -133,8 +139,9 @@ ZSTDLIB_API size_t ZBUFF_decompressContinue(ZBUFF_DCtx* dctx,
|
|||||||
* The function will report how many bytes were read or written by modifying *srcSizePtr and *dstCapacityPtr.
|
* The function will report how many bytes were read or written by modifying *srcSizePtr and *dstCapacityPtr.
|
||||||
* Note that it may not consume the entire input, in which case it's up to the caller to present remaining input again.
|
* Note that it may not consume the entire input, in which case it's up to the caller to present remaining input again.
|
||||||
* The content of `dst` will be overwritten (up to *dstCapacityPtr) at each function call, so save its content if it matters, or change `dst`.
|
* The content of `dst` will be overwritten (up to *dstCapacityPtr) at each function call, so save its content if it matters, or change `dst`.
|
||||||
* @return : a hint to preferred nb of bytes to use as input for next function call (it's only a hint, to help latency),
|
* @return : 0 when a frame is completely decoded and fully flushed,
|
||||||
* or 0 when a frame is completely decoded,
|
* 1 when there is still some data left within internal buffer to flush,
|
||||||
|
* >1 when more data is expected, with value being a suggested next input size (it's just a hint, which helps latency),
|
||||||
* or an error code, which can be tested using ZBUFF_isError().
|
* or an error code, which can be tested using ZBUFF_isError().
|
||||||
*
|
*
|
||||||
* Hint : recommended buffer sizes (not compulsory) : ZBUFF_recommendedDInSize() and ZBUFF_recommendedDOutSize()
|
* Hint : recommended buffer sizes (not compulsory) : ZBUFF_recommendedDInSize() and ZBUFF_recommendedDOutSize()
|
||||||
@@ -168,11 +175,11 @@ ZSTDLIB_API size_t ZBUFF_recommendedDOutSize(void);
|
|||||||
* ==================================================================================== */
|
* ==================================================================================== */
|
||||||
|
|
||||||
/*--- Dependency ---*/
|
/*--- Dependency ---*/
|
||||||
#define ZSTD_STATIC_LINKING_ONLY /* ZSTD_parameters */
|
#define ZSTD_STATIC_LINKING_ONLY /* ZSTD_parameters, ZSTD_customMem */
|
||||||
#include "zstd.h"
|
#include "zstd.h"
|
||||||
|
|
||||||
|
|
||||||
/*--- External memory ---*/
|
/*--- Custom memory allocator ---*/
|
||||||
/*! ZBUFF_createCCtx_advanced() :
|
/*! ZBUFF_createCCtx_advanced() :
|
||||||
* Create a ZBUFF compression context using external alloc and free functions */
|
* Create a ZBUFF compression context using external alloc and free functions */
|
||||||
ZSTDLIB_API ZBUFF_CCtx* ZBUFF_createCCtx_advanced(ZSTD_customMem customMem);
|
ZSTDLIB_API ZBUFF_CCtx* ZBUFF_createCCtx_advanced(ZSTD_customMem customMem);
|
||||||
@@ -182,7 +189,7 @@ ZSTDLIB_API ZBUFF_CCtx* ZBUFF_createCCtx_advanced(ZSTD_customMem customMem);
|
|||||||
ZSTDLIB_API ZBUFF_DCtx* ZBUFF_createDCtx_advanced(ZSTD_customMem customMem);
|
ZSTDLIB_API ZBUFF_DCtx* ZBUFF_createDCtx_advanced(ZSTD_customMem customMem);
|
||||||
|
|
||||||
|
|
||||||
/*--- Advanced Streaming function ---*/
|
/*--- Advanced Streaming Initialization ---*/
|
||||||
ZSTDLIB_API size_t ZBUFF_compressInit_advanced(ZBUFF_CCtx* zbc,
|
ZSTDLIB_API size_t ZBUFF_compressInit_advanced(ZBUFF_CCtx* zbc,
|
||||||
const void* dict, size_t dictSize,
|
const void* dict, size_t dictSize,
|
||||||
ZSTD_parameters params, unsigned long long pledgedSrcSize);
|
ZSTD_parameters params, unsigned long long pledgedSrcSize);
|
||||||
|
|||||||
@@ -46,7 +46,7 @@
|
|||||||
static size_t const ZBUFF_endFrameSize = ZSTD_BLOCKHEADERSIZE;
|
static size_t const ZBUFF_endFrameSize = ZSTD_BLOCKHEADERSIZE;
|
||||||
|
|
||||||
|
|
||||||
/*_**************************************************
|
/*-***********************************************************
|
||||||
* Streaming compression
|
* Streaming compression
|
||||||
*
|
*
|
||||||
* A ZBUFF_CCtx object is required to track streaming operation.
|
* A ZBUFF_CCtx object is required to track streaming operation.
|
||||||
@@ -77,7 +77,7 @@ static size_t const ZBUFF_endFrameSize = ZSTD_BLOCKHEADERSIZE;
|
|||||||
* Hint : recommended buffer sizes (not compulsory)
|
* Hint : recommended buffer sizes (not compulsory)
|
||||||
* input : ZSTD_BLOCKSIZE_MAX (128 KB), internal unit size, it improves latency to use this value.
|
* input : ZSTD_BLOCKSIZE_MAX (128 KB), internal unit size, it improves latency to use this value.
|
||||||
* output : ZSTD_compressBound(ZSTD_BLOCKSIZE_MAX) + ZSTD_blockHeaderSize + ZBUFF_endFrameSize : ensures it's always possible to write/flush/end a full block at best speed.
|
* output : ZSTD_compressBound(ZSTD_BLOCKSIZE_MAX) + ZSTD_blockHeaderSize + ZBUFF_endFrameSize : ensures it's always possible to write/flush/end a full block at best speed.
|
||||||
* **************************************************/
|
* ***********************************************************/
|
||||||
|
|
||||||
typedef enum { ZBUFFcs_init, ZBUFFcs_load, ZBUFFcs_flush, ZBUFFcs_final } ZBUFF_cStage;
|
typedef enum { ZBUFFcs_init, ZBUFFcs_load, ZBUFFcs_flush, ZBUFFcs_final } ZBUFF_cStage;
|
||||||
|
|
||||||
@@ -95,6 +95,8 @@ struct ZBUFF_CCtx_s {
|
|||||||
size_t outBuffContentSize;
|
size_t outBuffContentSize;
|
||||||
size_t outBuffFlushedSize;
|
size_t outBuffFlushedSize;
|
||||||
ZBUFF_cStage stage;
|
ZBUFF_cStage stage;
|
||||||
|
U32 checksum;
|
||||||
|
U32 frameEnded;
|
||||||
ZSTD_customMem customMem;
|
ZSTD_customMem customMem;
|
||||||
}; /* typedef'd tp ZBUFF_CCtx within "zstd_buffered.h" */
|
}; /* typedef'd tp ZBUFF_CCtx within "zstd_buffered.h" */
|
||||||
|
|
||||||
@@ -133,7 +135,7 @@ size_t ZBUFF_freeCCtx(ZBUFF_CCtx* zbc)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* *** Initialization *** */
|
/* ====== Initialization ====== */
|
||||||
|
|
||||||
size_t ZBUFF_compressInit_advanced(ZBUFF_CCtx* zbc,
|
size_t ZBUFF_compressInit_advanced(ZBUFF_CCtx* zbc,
|
||||||
const void* dict, size_t dictSize,
|
const void* dict, size_t dictSize,
|
||||||
@@ -147,7 +149,7 @@ size_t ZBUFF_compressInit_advanced(ZBUFF_CCtx* zbc,
|
|||||||
zbc->inBuff = (char*)zbc->customMem.customAlloc(zbc->customMem.opaque, neededInBuffSize);
|
zbc->inBuff = (char*)zbc->customMem.customAlloc(zbc->customMem.opaque, neededInBuffSize);
|
||||||
if (zbc->inBuff == NULL) return ERROR(memory_allocation);
|
if (zbc->inBuff == NULL) return ERROR(memory_allocation);
|
||||||
}
|
}
|
||||||
zbc->blockSize = MIN(ZSTD_BLOCKSIZE_MAX, neededInBuffSize);
|
zbc->blockSize = MIN(ZSTD_BLOCKSIZE_ABSOLUTEMAX, neededInBuffSize);
|
||||||
}
|
}
|
||||||
if (zbc->outBuffSize < ZSTD_compressBound(zbc->blockSize)+1) {
|
if (zbc->outBuffSize < ZSTD_compressBound(zbc->blockSize)+1) {
|
||||||
zbc->outBuffSize = ZSTD_compressBound(zbc->blockSize)+1;
|
zbc->outBuffSize = ZSTD_compressBound(zbc->blockSize)+1;
|
||||||
@@ -164,6 +166,8 @@ size_t ZBUFF_compressInit_advanced(ZBUFF_CCtx* zbc,
|
|||||||
zbc->inBuffTarget = zbc->blockSize;
|
zbc->inBuffTarget = zbc->blockSize;
|
||||||
zbc->outBuffContentSize = zbc->outBuffFlushedSize = 0;
|
zbc->outBuffContentSize = zbc->outBuffFlushedSize = 0;
|
||||||
zbc->stage = ZBUFFcs_load;
|
zbc->stage = ZBUFFcs_load;
|
||||||
|
zbc->checksum = params.fParams.checksumFlag > 0;
|
||||||
|
zbc->frameEnded = 0;
|
||||||
return 0; /* ready to go */
|
return 0; /* ready to go */
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -189,14 +193,16 @@ MEM_STATIC size_t ZBUFF_limitCopy(void* dst, size_t dstCapacity, const void* src
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* *** Compression *** */
|
/* ====== Compression ====== */
|
||||||
|
|
||||||
|
typedef enum { zbf_gather, zbf_flush, zbf_end } ZBUFF_flush_e;
|
||||||
|
|
||||||
static size_t ZBUFF_compressContinue_generic(ZBUFF_CCtx* zbc,
|
static size_t ZBUFF_compressContinue_generic(ZBUFF_CCtx* zbc,
|
||||||
void* dst, size_t* dstCapacityPtr,
|
void* dst, size_t* dstCapacityPtr,
|
||||||
const void* src, size_t* srcSizePtr,
|
const void* src, size_t* srcSizePtr,
|
||||||
int flush)
|
ZBUFF_flush_e const flush)
|
||||||
{
|
{
|
||||||
U32 notDone = 1;
|
U32 someMoreWork = 1;
|
||||||
const char* const istart = (const char*)src;
|
const char* const istart = (const char*)src;
|
||||||
const char* const iend = istart + *srcSizePtr;
|
const char* const iend = istart + *srcSizePtr;
|
||||||
const char* ip = istart;
|
const char* ip = istart;
|
||||||
@@ -204,7 +210,7 @@ static size_t ZBUFF_compressContinue_generic(ZBUFF_CCtx* zbc,
|
|||||||
char* const oend = ostart + *dstCapacityPtr;
|
char* const oend = ostart + *dstCapacityPtr;
|
||||||
char* op = ostart;
|
char* op = ostart;
|
||||||
|
|
||||||
while (notDone) {
|
while (someMoreWork) {
|
||||||
switch(zbc->stage)
|
switch(zbc->stage)
|
||||||
{
|
{
|
||||||
case ZBUFFcs_init: return ERROR(init_missing); /* call ZBUFF_compressInit() first ! */
|
case ZBUFFcs_init: return ERROR(init_missing); /* call ZBUFF_compressInit() first ! */
|
||||||
@@ -216,7 +222,7 @@ static size_t ZBUFF_compressContinue_generic(ZBUFF_CCtx* zbc,
|
|||||||
zbc->inBuffPos += loaded;
|
zbc->inBuffPos += loaded;
|
||||||
ip += loaded;
|
ip += loaded;
|
||||||
if ( (zbc->inBuffPos==zbc->inToCompress) || (!flush && (toLoad != loaded)) ) {
|
if ( (zbc->inBuffPos==zbc->inToCompress) || (!flush && (toLoad != loaded)) ) {
|
||||||
notDone = 0; break; /* not enough input to get a full block : stop there, wait for more */
|
someMoreWork = 0; break; /* not enough input to get a full block : stop there, wait for more */
|
||||||
} }
|
} }
|
||||||
/* compress current block (note : this stage cannot be stopped in the middle) */
|
/* compress current block (note : this stage cannot be stopped in the middle) */
|
||||||
{ void* cDst;
|
{ void* cDst;
|
||||||
@@ -227,8 +233,11 @@ static size_t ZBUFF_compressContinue_generic(ZBUFF_CCtx* zbc,
|
|||||||
cDst = op; /* compress directly into output buffer (avoid flush stage) */
|
cDst = op; /* compress directly into output buffer (avoid flush stage) */
|
||||||
else
|
else
|
||||||
cDst = zbc->outBuff, oSize = zbc->outBuffSize;
|
cDst = zbc->outBuff, oSize = zbc->outBuffSize;
|
||||||
cSize = ZSTD_compressContinue(zbc->zc, cDst, oSize, zbc->inBuff + zbc->inToCompress, iSize);
|
cSize = (flush == zbf_end) ?
|
||||||
|
ZSTD_compressEnd(zbc->zc, cDst, oSize, zbc->inBuff + zbc->inToCompress, iSize) :
|
||||||
|
ZSTD_compressContinue(zbc->zc, cDst, oSize, zbc->inBuff + zbc->inToCompress, iSize);
|
||||||
if (ZSTD_isError(cSize)) return cSize;
|
if (ZSTD_isError(cSize)) return cSize;
|
||||||
|
if (flush == zbf_end) zbc->frameEnded = 1;
|
||||||
/* prepare next block */
|
/* prepare next block */
|
||||||
zbc->inBuffTarget = zbc->inBuffPos + zbc->blockSize;
|
zbc->inBuffTarget = zbc->inBuffPos + zbc->blockSize;
|
||||||
if (zbc->inBuffTarget > zbc->inBuffSize)
|
if (zbc->inBuffTarget > zbc->inBuffSize)
|
||||||
@@ -245,14 +254,14 @@ static size_t ZBUFF_compressContinue_generic(ZBUFF_CCtx* zbc,
|
|||||||
size_t const flushed = ZBUFF_limitCopy(op, oend-op, zbc->outBuff + zbc->outBuffFlushedSize, toFlush);
|
size_t const flushed = ZBUFF_limitCopy(op, oend-op, zbc->outBuff + zbc->outBuffFlushedSize, toFlush);
|
||||||
op += flushed;
|
op += flushed;
|
||||||
zbc->outBuffFlushedSize += flushed;
|
zbc->outBuffFlushedSize += flushed;
|
||||||
if (toFlush!=flushed) { notDone = 0; break; } /* dst too small to store flushed data : stop there */
|
if (toFlush!=flushed) { someMoreWork = 0; break; } /* dst too small to store flushed data : stop there */
|
||||||
zbc->outBuffContentSize = zbc->outBuffFlushedSize = 0;
|
zbc->outBuffContentSize = zbc->outBuffFlushedSize = 0;
|
||||||
zbc->stage = ZBUFFcs_load;
|
zbc->stage = ZBUFFcs_load;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case ZBUFFcs_final:
|
case ZBUFFcs_final:
|
||||||
notDone = 0; /* do nothing */
|
someMoreWork = 0; /* do nothing */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@@ -262,6 +271,7 @@ static size_t ZBUFF_compressContinue_generic(ZBUFF_CCtx* zbc,
|
|||||||
|
|
||||||
*srcSizePtr = ip - istart;
|
*srcSizePtr = ip - istart;
|
||||||
*dstCapacityPtr = op - ostart;
|
*dstCapacityPtr = op - ostart;
|
||||||
|
if (zbc->frameEnded) return 0;
|
||||||
{ size_t hintInSize = zbc->inBuffTarget - zbc->inBuffPos;
|
{ size_t hintInSize = zbc->inBuffTarget - zbc->inBuffPos;
|
||||||
if (hintInSize==0) hintInSize = zbc->blockSize;
|
if (hintInSize==0) hintInSize = zbc->blockSize;
|
||||||
return hintInSize;
|
return hintInSize;
|
||||||
@@ -272,17 +282,17 @@ size_t ZBUFF_compressContinue(ZBUFF_CCtx* zbc,
|
|||||||
void* dst, size_t* dstCapacityPtr,
|
void* dst, size_t* dstCapacityPtr,
|
||||||
const void* src, size_t* srcSizePtr)
|
const void* src, size_t* srcSizePtr)
|
||||||
{
|
{
|
||||||
return ZBUFF_compressContinue_generic(zbc, dst, dstCapacityPtr, src, srcSizePtr, 0);
|
return ZBUFF_compressContinue_generic(zbc, dst, dstCapacityPtr, src, srcSizePtr, zbf_gather);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* *** Finalize *** */
|
/* ====== Finalize ====== */
|
||||||
|
|
||||||
size_t ZBUFF_compressFlush(ZBUFF_CCtx* zbc, void* dst, size_t* dstCapacityPtr)
|
size_t ZBUFF_compressFlush(ZBUFF_CCtx* zbc, void* dst, size_t* dstCapacityPtr)
|
||||||
{
|
{
|
||||||
size_t srcSize = 0;
|
size_t srcSize = 0;
|
||||||
ZBUFF_compressContinue_generic(zbc, dst, dstCapacityPtr, &srcSize, &srcSize, 1); /* use a valid src address instead of NULL */
|
ZBUFF_compressContinue_generic(zbc, dst, dstCapacityPtr, &srcSize, &srcSize, zbf_flush); /* use a valid src address instead of NULL */
|
||||||
return zbc->outBuffContentSize - zbc->outBuffFlushedSize;
|
return zbc->outBuffContentSize - zbc->outBuffFlushedSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -296,15 +306,18 @@ size_t ZBUFF_compressEnd(ZBUFF_CCtx* zbc, void* dst, size_t* dstCapacityPtr)
|
|||||||
if (zbc->stage != ZBUFFcs_final) {
|
if (zbc->stage != ZBUFFcs_final) {
|
||||||
/* flush whatever remains */
|
/* flush whatever remains */
|
||||||
size_t outSize = *dstCapacityPtr;
|
size_t outSize = *dstCapacityPtr;
|
||||||
size_t const remainingToFlush = ZBUFF_compressFlush(zbc, dst, &outSize);
|
size_t srcSize = 0;
|
||||||
|
size_t const notEnded = ZBUFF_compressContinue_generic(zbc, dst, &outSize, &srcSize, &srcSize, zbf_end); /* use a valid address instead of NULL */
|
||||||
|
size_t const remainingToFlush = zbc->outBuffContentSize - zbc->outBuffFlushedSize;
|
||||||
op += outSize;
|
op += outSize;
|
||||||
if (remainingToFlush) {
|
if (remainingToFlush) {
|
||||||
*dstCapacityPtr = op-ostart;
|
*dstCapacityPtr = op-ostart;
|
||||||
return remainingToFlush + ZBUFF_endFrameSize;
|
return remainingToFlush + ZBUFF_endFrameSize + (zbc->checksum * 4);
|
||||||
}
|
}
|
||||||
/* create epilogue */
|
/* create epilogue */
|
||||||
zbc->stage = ZBUFFcs_final;
|
zbc->stage = ZBUFFcs_final;
|
||||||
zbc->outBuffContentSize = ZSTD_compressEnd(zbc->zc, zbc->outBuff, zbc->outBuffSize); /* epilogue into outBuff */
|
zbc->outBuffContentSize = !notEnded ? 0 :
|
||||||
|
ZSTD_compressEnd(zbc->zc, zbc->outBuff, zbc->outBuffSize, NULL, 0); /* write epilogue into outBuff */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* flush epilogue */
|
/* flush epilogue */
|
||||||
@@ -323,5 +336,5 @@ size_t ZBUFF_compressEnd(ZBUFF_CCtx* zbc, void* dst, size_t* dstCapacityPtr)
|
|||||||
/* *************************************
|
/* *************************************
|
||||||
* Tool functions
|
* Tool functions
|
||||||
***************************************/
|
***************************************/
|
||||||
size_t ZBUFF_recommendedCInSize(void) { return ZSTD_BLOCKSIZE_MAX; }
|
size_t ZBUFF_recommendedCInSize(void) { return ZSTD_BLOCKSIZE_ABSOLUTEMAX; }
|
||||||
size_t ZBUFF_recommendedCOutSize(void) { return ZSTD_compressBound(ZSTD_BLOCKSIZE_MAX) + ZSTD_blockHeaderSize + ZBUFF_endFrameSize; }
|
size_t ZBUFF_recommendedCOutSize(void) { return ZSTD_compressBound(ZSTD_BLOCKSIZE_ABSOLUTEMAX) + ZSTD_blockHeaderSize + ZBUFF_endFrameSize; }
|
||||||
|
|||||||
@@ -158,9 +158,9 @@ size_t ZBUFF_decompressContinue(ZBUFF_DCtx* zbd,
|
|||||||
char* const ostart = (char*)dst;
|
char* const ostart = (char*)dst;
|
||||||
char* const oend = ostart + *dstCapacityPtr;
|
char* const oend = ostart + *dstCapacityPtr;
|
||||||
char* op = ostart;
|
char* op = ostart;
|
||||||
U32 notDone = 1;
|
U32 someMoreWork = 1;
|
||||||
|
|
||||||
while (notDone) {
|
while (someMoreWork) {
|
||||||
switch(zbd->stage)
|
switch(zbd->stage)
|
||||||
{
|
{
|
||||||
case ZBUFFds_init :
|
case ZBUFFds_init :
|
||||||
@@ -168,9 +168,9 @@ size_t ZBUFF_decompressContinue(ZBUFF_DCtx* zbd,
|
|||||||
|
|
||||||
case ZBUFFds_loadHeader :
|
case ZBUFFds_loadHeader :
|
||||||
{ size_t const hSize = ZSTD_getFrameParams(&(zbd->fParams), zbd->headerBuffer, zbd->lhSize);
|
{ size_t const hSize = ZSTD_getFrameParams(&(zbd->fParams), zbd->headerBuffer, zbd->lhSize);
|
||||||
if (hSize != 0) {
|
if (ZSTD_isError(hSize)) return hSize;
|
||||||
|
if (hSize != 0) { /* need more input */
|
||||||
size_t const toLoad = hSize - zbd->lhSize; /* if hSize!=0, hSize > zbd->lhSize */
|
size_t const toLoad = hSize - zbd->lhSize; /* if hSize!=0, hSize > zbd->lhSize */
|
||||||
if (ZSTD_isError(hSize)) return hSize;
|
|
||||||
if (toLoad > (size_t)(iend-ip)) { /* not enough input to load full header */
|
if (toLoad > (size_t)(iend-ip)) { /* not enough input to load full header */
|
||||||
memcpy(zbd->headerBuffer + zbd->lhSize, ip, iend-ip);
|
memcpy(zbd->headerBuffer + zbd->lhSize, ip, iend-ip);
|
||||||
zbd->lhSize += iend-ip;
|
zbd->lhSize += iend-ip;
|
||||||
@@ -184,7 +184,7 @@ size_t ZBUFF_decompressContinue(ZBUFF_DCtx* zbd,
|
|||||||
/* Consume header */
|
/* Consume header */
|
||||||
{ size_t const h1Size = ZSTD_nextSrcSizeToDecompress(zbd->zd); /* == ZSTD_frameHeaderSize_min */
|
{ size_t const h1Size = ZSTD_nextSrcSizeToDecompress(zbd->zd); /* == ZSTD_frameHeaderSize_min */
|
||||||
size_t const h1Result = ZSTD_decompressContinue(zbd->zd, NULL, 0, zbd->headerBuffer, h1Size);
|
size_t const h1Result = ZSTD_decompressContinue(zbd->zd, NULL, 0, zbd->headerBuffer, h1Size);
|
||||||
if (ZSTD_isError(h1Result)) return h1Result;
|
if (ZSTD_isError(h1Result)) return h1Result; /* should not happen : already checked */
|
||||||
if (h1Size < zbd->lhSize) { /* long header */
|
if (h1Size < zbd->lhSize) { /* long header */
|
||||||
size_t const h2Size = ZSTD_nextSrcSizeToDecompress(zbd->zd);
|
size_t const h2Size = ZSTD_nextSrcSizeToDecompress(zbd->zd);
|
||||||
size_t const h2Result = ZSTD_decompressContinue(zbd->zd, NULL, 0, zbd->headerBuffer+h1Size, h2Size);
|
size_t const h2Result = ZSTD_decompressContinue(zbd->zd, NULL, 0, zbd->headerBuffer+h1Size, h2Size);
|
||||||
@@ -194,7 +194,8 @@ size_t ZBUFF_decompressContinue(ZBUFF_DCtx* zbd,
|
|||||||
zbd->fParams.windowSize = MAX(zbd->fParams.windowSize, 1U << ZSTD_WINDOWLOG_ABSOLUTEMIN);
|
zbd->fParams.windowSize = MAX(zbd->fParams.windowSize, 1U << ZSTD_WINDOWLOG_ABSOLUTEMIN);
|
||||||
|
|
||||||
/* Frame header instruct buffer sizes */
|
/* Frame header instruct buffer sizes */
|
||||||
{ size_t const blockSize = MIN(zbd->fParams.windowSize, ZSTD_BLOCKSIZE_MAX);
|
{ size_t const blockSize = MIN(zbd->fParams.windowSize, ZSTD_BLOCKSIZE_ABSOLUTEMAX);
|
||||||
|
size_t const neededOutSize = zbd->fParams.windowSize + blockSize;
|
||||||
zbd->blockSize = blockSize;
|
zbd->blockSize = blockSize;
|
||||||
if (zbd->inBuffSize < blockSize) {
|
if (zbd->inBuffSize < blockSize) {
|
||||||
zbd->customMem.customFree(zbd->customMem.opaque, zbd->inBuff);
|
zbd->customMem.customFree(zbd->customMem.opaque, zbd->inBuff);
|
||||||
@@ -202,20 +203,20 @@ size_t ZBUFF_decompressContinue(ZBUFF_DCtx* zbd,
|
|||||||
zbd->inBuff = (char*)zbd->customMem.customAlloc(zbd->customMem.opaque, blockSize);
|
zbd->inBuff = (char*)zbd->customMem.customAlloc(zbd->customMem.opaque, blockSize);
|
||||||
if (zbd->inBuff == NULL) return ERROR(memory_allocation);
|
if (zbd->inBuff == NULL) return ERROR(memory_allocation);
|
||||||
}
|
}
|
||||||
{ size_t const neededOutSize = zbd->fParams.windowSize + blockSize;
|
if (zbd->outBuffSize < neededOutSize) {
|
||||||
if (zbd->outBuffSize < neededOutSize) {
|
zbd->customMem.customFree(zbd->customMem.opaque, zbd->outBuff);
|
||||||
zbd->customMem.customFree(zbd->customMem.opaque, zbd->outBuff);
|
zbd->outBuffSize = neededOutSize;
|
||||||
zbd->outBuffSize = neededOutSize;
|
zbd->outBuff = (char*)zbd->customMem.customAlloc(zbd->customMem.opaque, neededOutSize);
|
||||||
zbd->outBuff = (char*)zbd->customMem.customAlloc(zbd->customMem.opaque, neededOutSize);
|
if (zbd->outBuff == NULL) return ERROR(memory_allocation);
|
||||||
if (zbd->outBuff == NULL) return ERROR(memory_allocation);
|
} }
|
||||||
} } }
|
|
||||||
zbd->stage = ZBUFFds_read;
|
zbd->stage = ZBUFFds_read;
|
||||||
|
/* pass-through */
|
||||||
|
|
||||||
case ZBUFFds_read:
|
case ZBUFFds_read:
|
||||||
{ size_t const neededInSize = ZSTD_nextSrcSizeToDecompress(zbd->zd);
|
{ size_t const neededInSize = ZSTD_nextSrcSizeToDecompress(zbd->zd);
|
||||||
if (neededInSize==0) { /* end of frame */
|
if (neededInSize==0) { /* end of frame */
|
||||||
zbd->stage = ZBUFFds_init;
|
zbd->stage = ZBUFFds_init;
|
||||||
notDone = 0;
|
someMoreWork = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if ((size_t)(iend-ip) >= neededInSize) { /* decode directly from src */
|
if ((size_t)(iend-ip) >= neededInSize) { /* decode directly from src */
|
||||||
@@ -230,8 +231,9 @@ size_t ZBUFF_decompressContinue(ZBUFF_DCtx* zbd,
|
|||||||
zbd->stage = ZBUFFds_flush;
|
zbd->stage = ZBUFFds_flush;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (ip==iend) { notDone = 0; break; } /* no more input */
|
if (ip==iend) { someMoreWork = 0; break; } /* no more input */
|
||||||
zbd->stage = ZBUFFds_load;
|
zbd->stage = ZBUFFds_load;
|
||||||
|
/* pass-through */
|
||||||
}
|
}
|
||||||
|
|
||||||
case ZBUFFds_load:
|
case ZBUFFds_load:
|
||||||
@@ -242,7 +244,7 @@ size_t ZBUFF_decompressContinue(ZBUFF_DCtx* zbd,
|
|||||||
loadedSize = ZBUFF_limitCopy(zbd->inBuff + zbd->inPos, toLoad, ip, iend-ip);
|
loadedSize = ZBUFF_limitCopy(zbd->inBuff + zbd->inPos, toLoad, ip, iend-ip);
|
||||||
ip += loadedSize;
|
ip += loadedSize;
|
||||||
zbd->inPos += loadedSize;
|
zbd->inPos += loadedSize;
|
||||||
if (loadedSize < toLoad) { notDone = 0; break; } /* not enough input, wait for more */
|
if (loadedSize < toLoad) { someMoreWork = 0; break; } /* not enough input, wait for more */
|
||||||
|
|
||||||
/* decode loaded input */
|
/* decode loaded input */
|
||||||
{ const int isSkipFrame = ZSTD_isSkipFrame(zbd->zd);
|
{ const int isSkipFrame = ZSTD_isSkipFrame(zbd->zd);
|
||||||
@@ -254,7 +256,7 @@ size_t ZBUFF_decompressContinue(ZBUFF_DCtx* zbd,
|
|||||||
if (!decodedSize && !isSkipFrame) { zbd->stage = ZBUFFds_read; break; } /* this was just a header */
|
if (!decodedSize && !isSkipFrame) { zbd->stage = ZBUFFds_read; break; } /* this was just a header */
|
||||||
zbd->outEnd = zbd->outStart + decodedSize;
|
zbd->outEnd = zbd->outStart + decodedSize;
|
||||||
zbd->stage = ZBUFFds_flush;
|
zbd->stage = ZBUFFds_flush;
|
||||||
// break; /* ZBUFFds_flush follows */
|
/* pass-through */
|
||||||
} }
|
} }
|
||||||
|
|
||||||
case ZBUFFds_flush:
|
case ZBUFFds_flush:
|
||||||
@@ -262,14 +264,14 @@ size_t ZBUFF_decompressContinue(ZBUFF_DCtx* zbd,
|
|||||||
size_t const flushedSize = ZBUFF_limitCopy(op, oend-op, zbd->outBuff + zbd->outStart, toFlushSize);
|
size_t const flushedSize = ZBUFF_limitCopy(op, oend-op, zbd->outBuff + zbd->outStart, toFlushSize);
|
||||||
op += flushedSize;
|
op += flushedSize;
|
||||||
zbd->outStart += flushedSize;
|
zbd->outStart += flushedSize;
|
||||||
if (flushedSize == toFlushSize) {
|
if (flushedSize == toFlushSize) { /* flush completed */
|
||||||
zbd->stage = ZBUFFds_read;
|
zbd->stage = ZBUFFds_read;
|
||||||
if (zbd->outStart + zbd->blockSize > zbd->outBuffSize)
|
if (zbd->outStart + zbd->blockSize > zbd->outBuffSize)
|
||||||
zbd->outStart = zbd->outEnd = 0;
|
zbd->outStart = zbd->outEnd = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
/* cannot flush everything */
|
/* cannot flush everything */
|
||||||
notDone = 0;
|
someMoreWork = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default: return ERROR(GENERIC); /* impossible */
|
default: return ERROR(GENERIC); /* impossible */
|
||||||
@@ -279,16 +281,17 @@ size_t ZBUFF_decompressContinue(ZBUFF_DCtx* zbd,
|
|||||||
*srcSizePtr = ip-istart;
|
*srcSizePtr = ip-istart;
|
||||||
*dstCapacityPtr = op-ostart;
|
*dstCapacityPtr = op-ostart;
|
||||||
{ size_t nextSrcSizeHint = ZSTD_nextSrcSizeToDecompress(zbd->zd);
|
{ size_t nextSrcSizeHint = ZSTD_nextSrcSizeToDecompress(zbd->zd);
|
||||||
// if (nextSrcSizeHint > ZSTD_blockHeaderSize) nextSrcSizeHint+= ZSTD_blockHeaderSize; /* get following block header too */
|
if (!nextSrcSizeHint) return (zbd->outEnd != zbd->outStart); /* return 0 only if fully flushed too */
|
||||||
|
nextSrcSizeHint += ZSTD_blockHeaderSize * (ZSTD_nextInputType(zbd->zd) == ZSTDnit_block);
|
||||||
|
if (zbd->inPos > nextSrcSizeHint) return ERROR(GENERIC); /* should never happen */
|
||||||
nextSrcSizeHint -= zbd->inPos; /* already loaded*/
|
nextSrcSizeHint -= zbd->inPos; /* already loaded*/
|
||||||
return nextSrcSizeHint;
|
return nextSrcSizeHint;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* *************************************
|
/* *************************************
|
||||||
* Tool functions
|
* Tool functions
|
||||||
***************************************/
|
***************************************/
|
||||||
size_t ZBUFF_recommendedDInSize(void) { return ZSTD_BLOCKSIZE_MAX + ZSTD_blockHeaderSize /* block header size*/ ; }
|
size_t ZBUFF_recommendedDInSize(void) { return ZSTD_BLOCKSIZE_ABSOLUTEMAX + ZSTD_blockHeaderSize /* block header size*/ ; }
|
||||||
size_t ZBUFF_recommendedDOutSize(void) { return ZSTD_BLOCKSIZE_MAX; }
|
size_t ZBUFF_recommendedDOutSize(void) { return ZSTD_BLOCKSIZE_ABSOLUTEMAX; }
|
||||||
|
|||||||
185
C/zstd/zstd.h
185
C/zstd/zstd.h
@@ -36,15 +36,11 @@
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*-*************************************
|
/*====== Dependency ======*/
|
||||||
* Dependencies
|
|
||||||
***************************************/
|
|
||||||
#include <stddef.h> /* size_t */
|
#include <stddef.h> /* size_t */
|
||||||
|
|
||||||
|
|
||||||
/*-***************************************************************
|
/*====== Export for Windows ======*/
|
||||||
* Export parameters
|
|
||||||
*****************************************************************/
|
|
||||||
/*!
|
/*!
|
||||||
* ZSTD_DLL_EXPORT :
|
* ZSTD_DLL_EXPORT :
|
||||||
* Enable exporting of functions when building a Windows DLL
|
* Enable exporting of functions when building a Windows DLL
|
||||||
@@ -56,12 +52,10 @@ extern "C" {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/* *************************************
|
/*====== Version ======*/
|
||||||
* Version
|
|
||||||
***************************************/
|
|
||||||
#define ZSTD_VERSION_MAJOR 0
|
#define ZSTD_VERSION_MAJOR 0
|
||||||
#define ZSTD_VERSION_MINOR 7
|
#define ZSTD_VERSION_MINOR 8
|
||||||
#define ZSTD_VERSION_RELEASE 4
|
#define ZSTD_VERSION_RELEASE 0
|
||||||
|
|
||||||
#define ZSTD_LIB_VERSION ZSTD_VERSION_MAJOR.ZSTD_VERSION_MINOR.ZSTD_VERSION_RELEASE
|
#define ZSTD_LIB_VERSION ZSTD_VERSION_MAJOR.ZSTD_VERSION_MINOR.ZSTD_VERSION_RELEASE
|
||||||
#define ZSTD_QUOTE(str) #str
|
#define ZSTD_QUOTE(str) #str
|
||||||
@@ -73,61 +67,72 @@ ZSTDLIB_API unsigned ZSTD_versionNumber (void);
|
|||||||
|
|
||||||
|
|
||||||
/* *************************************
|
/* *************************************
|
||||||
* Simple functions
|
* Simple API
|
||||||
***************************************/
|
***************************************/
|
||||||
/*! ZSTD_compress() :
|
/*! ZSTD_compress() :
|
||||||
Compresses `srcSize` bytes from buffer `src` into buffer `dst` of size `dstCapacity`.
|
Compresses `src` buffer into already allocated `dst`.
|
||||||
Destination buffer must be already allocated.
|
Hint : compression runs faster if `dstCapacity` >= `ZSTD_compressBound(srcSize)`.
|
||||||
Compression runs faster if `dstCapacity` >= `ZSTD_compressBound(srcSize)`.
|
@return : the number of bytes written into `dst` (<= `dstCapacity),
|
||||||
@return : the number of bytes written into `dst`,
|
|
||||||
or an error code if it fails (which can be tested using ZSTD_isError()) */
|
or an error code if it fails (which can be tested using ZSTD_isError()) */
|
||||||
ZSTDLIB_API size_t ZSTD_compress( void* dst, size_t dstCapacity,
|
ZSTDLIB_API size_t ZSTD_compress( void* dst, size_t dstCapacity,
|
||||||
const void* src, size_t srcSize,
|
const void* src, size_t srcSize,
|
||||||
int compressionLevel);
|
int compressionLevel);
|
||||||
|
|
||||||
/** ZSTD_getDecompressedSize() :
|
/*! ZSTD_getDecompressedSize() :
|
||||||
* @return : decompressed size if known, 0 otherwise.
|
* @return : decompressed size as a 64-bits value _if known_, 0 otherwise.
|
||||||
note : to know precise reason why result is `0`, follow up with ZSTD_getFrameParams() */
|
* note 1 : decompressed size can be very large (64-bits value),
|
||||||
|
* potentially larger than what local system can handle as a single memory segment.
|
||||||
|
* In which case, it's necessary to use streaming mode to decompress data.
|
||||||
|
* note 2 : decompressed size is an optional field, that may not be present.
|
||||||
|
* When `return==0`, consider data to decompress could have any size.
|
||||||
|
* In which case, it's necessary to use streaming mode to decompress data,
|
||||||
|
* or rely on application's implied limits.
|
||||||
|
* (For example, it may know that its own data is necessarily cut into blocks <= 16 KB).
|
||||||
|
* note 3 : decompressed size could be wrong or intentionally modified !
|
||||||
|
* Always ensure result fits within application's authorized limits !
|
||||||
|
* Each application can have its own set of conditions.
|
||||||
|
* If the intention is to decompress public data compressed by zstd command line utility,
|
||||||
|
* it is recommended to support at least 8 MB for extended compatibility.
|
||||||
|
* note 4 : when `return==0`, if precise failure cause is needed, use ZSTD_getFrameParams() to know more. */
|
||||||
unsigned long long ZSTD_getDecompressedSize(const void* src, size_t srcSize);
|
unsigned long long ZSTD_getDecompressedSize(const void* src, size_t srcSize);
|
||||||
|
|
||||||
/*! ZSTD_decompress() :
|
/*! ZSTD_decompress() :
|
||||||
`compressedSize` : is the _exact_ size of compressed input, otherwise decompression will fail.
|
`compressedSize` : must be the _exact_ size of compressed input, otherwise decompression will fail.
|
||||||
`dstCapacity` must be equal or larger than originalSize.
|
`dstCapacity` must be equal or larger than originalSize (see ZSTD_getDecompressedSize() ).
|
||||||
|
If originalSize is unknown, and if there is no implied application-specific limitations,
|
||||||
|
it's necessary to use streaming mode to decompress data.
|
||||||
@return : the number of bytes decompressed into `dst` (<= `dstCapacity`),
|
@return : the number of bytes decompressed into `dst` (<= `dstCapacity`),
|
||||||
or an errorCode if it fails (which can be tested using ZSTD_isError()) */
|
or an errorCode if it fails (which can be tested using ZSTD_isError()) */
|
||||||
ZSTDLIB_API size_t ZSTD_decompress( void* dst, size_t dstCapacity,
|
ZSTDLIB_API size_t ZSTD_decompress( void* dst, size_t dstCapacity,
|
||||||
const void* src, size_t compressedSize);
|
const void* src, size_t compressedSize);
|
||||||
|
|
||||||
|
|
||||||
/* *************************************
|
/*====== Helper functions ======*/
|
||||||
* Helper functions
|
ZSTDLIB_API int ZSTD_maxCLevel(void); /*!< maximum compression level available */
|
||||||
***************************************/
|
ZSTDLIB_API size_t ZSTD_compressBound(size_t srcSize); /*!< maximum compressed size in worst case scenario */
|
||||||
ZSTDLIB_API size_t ZSTD_compressBound(size_t srcSize); /*!< maximum compressed size (worst case scenario) */
|
|
||||||
|
|
||||||
/* Error Management */
|
|
||||||
ZSTDLIB_API unsigned ZSTD_isError(size_t code); /*!< tells if a `size_t` function result is an error code */
|
ZSTDLIB_API unsigned ZSTD_isError(size_t code); /*!< tells if a `size_t` function result is an error code */
|
||||||
ZSTDLIB_API const char* ZSTD_getErrorName(size_t code); /*!< provides readable string for an error code */
|
ZSTDLIB_API const char* ZSTD_getErrorName(size_t code); /*!< provides readable string from an error code */
|
||||||
|
|
||||||
|
|
||||||
/* *************************************
|
/*-*************************************
|
||||||
* Explicit memory management
|
* Explicit memory management
|
||||||
***************************************/
|
***************************************/
|
||||||
/** Compression context */
|
/** Compression context */
|
||||||
typedef struct ZSTD_CCtx_s ZSTD_CCtx; /*< incomplete type */
|
typedef struct ZSTD_CCtx_s ZSTD_CCtx; /*< incomplete type */
|
||||||
ZSTDLIB_API ZSTD_CCtx* ZSTD_createCCtx(void);
|
ZSTDLIB_API ZSTD_CCtx* ZSTD_createCCtx(void);
|
||||||
ZSTDLIB_API size_t ZSTD_freeCCtx(ZSTD_CCtx* cctx); /*!< @return : errorCode */
|
ZSTDLIB_API size_t ZSTD_freeCCtx(ZSTD_CCtx* cctx);
|
||||||
|
|
||||||
/** ZSTD_compressCCtx() :
|
/** ZSTD_compressCCtx() :
|
||||||
Same as ZSTD_compress(), but requires an already allocated ZSTD_CCtx (see ZSTD_createCCtx()) */
|
Same as ZSTD_compress(), requires an allocated ZSTD_CCtx (see ZSTD_createCCtx()) */
|
||||||
ZSTDLIB_API size_t ZSTD_compressCCtx(ZSTD_CCtx* ctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize, int compressionLevel);
|
ZSTDLIB_API size_t ZSTD_compressCCtx(ZSTD_CCtx* ctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize, int compressionLevel);
|
||||||
|
|
||||||
/** Decompression context */
|
/** Decompression context */
|
||||||
typedef struct ZSTD_DCtx_s ZSTD_DCtx;
|
typedef struct ZSTD_DCtx_s ZSTD_DCtx; /*< incomplete type */
|
||||||
ZSTDLIB_API ZSTD_DCtx* ZSTD_createDCtx(void);
|
ZSTDLIB_API ZSTD_DCtx* ZSTD_createDCtx(void);
|
||||||
ZSTDLIB_API size_t ZSTD_freeDCtx(ZSTD_DCtx* dctx); /*!< @return : errorCode */
|
ZSTDLIB_API size_t ZSTD_freeDCtx(ZSTD_DCtx* dctx);
|
||||||
|
|
||||||
/** ZSTD_decompressDCtx() :
|
/** ZSTD_decompressDCtx() :
|
||||||
* Same as ZSTD_decompress(), but requires an already allocated ZSTD_DCtx (see ZSTD_createDCtx()) */
|
* Same as ZSTD_decompress(), requires an allocated ZSTD_DCtx (see ZSTD_createDCtx()) */
|
||||||
ZSTDLIB_API size_t ZSTD_decompressDCtx(ZSTD_DCtx* ctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize);
|
ZSTDLIB_API size_t ZSTD_decompressDCtx(ZSTD_DCtx* ctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize);
|
||||||
|
|
||||||
|
|
||||||
@@ -135,10 +140,8 @@ ZSTDLIB_API size_t ZSTD_decompressDCtx(ZSTD_DCtx* ctx, void* dst, size_t dstCapa
|
|||||||
* Simple dictionary API
|
* Simple dictionary API
|
||||||
***************************/
|
***************************/
|
||||||
/*! ZSTD_compress_usingDict() :
|
/*! ZSTD_compress_usingDict() :
|
||||||
* Compression using a pre-defined Dictionary content (see dictBuilder).
|
* Compression using a predefined Dictionary (see dictBuilder/zdict.h).
|
||||||
* Note 1 : This function load the dictionary, resulting in a significant startup time.
|
* Note : This function load the dictionary, resulting in a significant startup time. */
|
||||||
* Note 2 : `dict` must remain accessible and unmodified during compression operation.
|
|
||||||
* Note 3 : `dict` can be `NULL`, in which case, it's equivalent to ZSTD_compressCCtx() */
|
|
||||||
ZSTDLIB_API size_t ZSTD_compress_usingDict(ZSTD_CCtx* ctx,
|
ZSTDLIB_API size_t ZSTD_compress_usingDict(ZSTD_CCtx* ctx,
|
||||||
void* dst, size_t dstCapacity,
|
void* dst, size_t dstCapacity,
|
||||||
const void* src, size_t srcSize,
|
const void* src, size_t srcSize,
|
||||||
@@ -146,11 +149,9 @@ ZSTDLIB_API size_t ZSTD_compress_usingDict(ZSTD_CCtx* ctx,
|
|||||||
int compressionLevel);
|
int compressionLevel);
|
||||||
|
|
||||||
/*! ZSTD_decompress_usingDict() :
|
/*! ZSTD_decompress_usingDict() :
|
||||||
* Decompression using a pre-defined Dictionary content (see dictBuilder).
|
* Decompression using a predefined Dictionary (see dictBuilder/zdict.h).
|
||||||
* Dictionary must be identical to the one used during compression.
|
* Dictionary must be identical to the one used during compression.
|
||||||
* Note 1 : This function load the dictionary, resulting in a significant startup time
|
* Note : This function load the dictionary, resulting in a significant startup time */
|
||||||
* Note 2 : `dict` must remain accessible and unmodified during compression operation.
|
|
||||||
* Note 3 : `dict` can be `NULL`, in which case, it's equivalent to ZSTD_decompressDCtx() */
|
|
||||||
ZSTDLIB_API size_t ZSTD_decompress_usingDict(ZSTD_DCtx* dctx,
|
ZSTDLIB_API size_t ZSTD_decompress_usingDict(ZSTD_DCtx* dctx,
|
||||||
void* dst, size_t dstCapacity,
|
void* dst, size_t dstCapacity,
|
||||||
const void* src, size_t srcSize,
|
const void* src, size_t srcSize,
|
||||||
@@ -158,7 +159,7 @@ ZSTDLIB_API size_t ZSTD_decompress_usingDict(ZSTD_DCtx* dctx,
|
|||||||
|
|
||||||
|
|
||||||
/*-**************************
|
/*-**************************
|
||||||
* Advanced Dictionary API
|
* Fast Dictionary API
|
||||||
****************************/
|
****************************/
|
||||||
/*! ZSTD_createCDict() :
|
/*! ZSTD_createCDict() :
|
||||||
* Create a digested dictionary, ready to start compression operation without startup delay.
|
* Create a digested dictionary, ready to start compression operation without startup delay.
|
||||||
@@ -168,8 +169,8 @@ ZSTDLIB_API ZSTD_CDict* ZSTD_createCDict(const void* dict, size_t dictSize, int
|
|||||||
ZSTDLIB_API size_t ZSTD_freeCDict(ZSTD_CDict* CDict);
|
ZSTDLIB_API size_t ZSTD_freeCDict(ZSTD_CDict* CDict);
|
||||||
|
|
||||||
/*! ZSTD_compress_usingCDict() :
|
/*! ZSTD_compress_usingCDict() :
|
||||||
* Compression using a pre-digested Dictionary.
|
* Compression using a digested Dictionary.
|
||||||
* Much faster than ZSTD_compress_usingDict() when same dictionary is used multiple times.
|
* Faster startup than ZSTD_compress_usingDict(), recommended when same dictionary is used multiple times.
|
||||||
* Note that compression level is decided during dictionary creation */
|
* Note that compression level is decided during dictionary creation */
|
||||||
ZSTDLIB_API size_t ZSTD_compress_usingCDict(ZSTD_CCtx* cctx,
|
ZSTDLIB_API size_t ZSTD_compress_usingCDict(ZSTD_CCtx* cctx,
|
||||||
void* dst, size_t dstCapacity,
|
void* dst, size_t dstCapacity,
|
||||||
@@ -184,15 +185,14 @@ ZSTDLIB_API ZSTD_DDict* ZSTD_createDDict(const void* dict, size_t dictSize);
|
|||||||
ZSTDLIB_API size_t ZSTD_freeDDict(ZSTD_DDict* ddict);
|
ZSTDLIB_API size_t ZSTD_freeDDict(ZSTD_DDict* ddict);
|
||||||
|
|
||||||
/*! ZSTD_decompress_usingDDict() :
|
/*! ZSTD_decompress_usingDDict() :
|
||||||
* Decompression using a pre-digested Dictionary
|
* Decompression using a digested Dictionary
|
||||||
* Much faster than ZSTD_decompress_usingDict() when same dictionary is used multiple times. */
|
* Faster startup than ZSTD_decompress_usingDict(), recommended when same dictionary is used multiple times. */
|
||||||
ZSTDLIB_API size_t ZSTD_decompress_usingDDict(ZSTD_DCtx* dctx,
|
ZSTDLIB_API size_t ZSTD_decompress_usingDDict(ZSTD_DCtx* dctx,
|
||||||
void* dst, size_t dstCapacity,
|
void* dst, size_t dstCapacity,
|
||||||
const void* src, size_t srcSize,
|
const void* src, size_t srcSize,
|
||||||
const ZSTD_DDict* ddict);
|
const ZSTD_DDict* ddict);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef ZSTD_STATIC_LINKING_ONLY
|
#ifdef ZSTD_STATIC_LINKING_ONLY
|
||||||
|
|
||||||
/* ====================================================================================
|
/* ====================================================================================
|
||||||
@@ -203,7 +203,7 @@ ZSTDLIB_API size_t ZSTD_decompress_usingDDict(ZSTD_DCtx* dctx,
|
|||||||
* ==================================================================================== */
|
* ==================================================================================== */
|
||||||
|
|
||||||
/*--- Constants ---*/
|
/*--- Constants ---*/
|
||||||
#define ZSTD_MAGICNUMBER 0xFD2FB527 /* v0.7 */
|
#define ZSTD_MAGICNUMBER 0xFD2FB528 /* v0.8 */
|
||||||
#define ZSTD_MAGIC_SKIPPABLE_START 0x184D2A50U
|
#define ZSTD_MAGIC_SKIPPABLE_START 0x184D2A50U
|
||||||
|
|
||||||
#define ZSTD_WINDOWLOG_MAX_32 25
|
#define ZSTD_WINDOWLOG_MAX_32 25
|
||||||
@@ -215,7 +215,6 @@ ZSTDLIB_API size_t ZSTD_decompress_usingDDict(ZSTD_DCtx* dctx,
|
|||||||
#define ZSTD_HASHLOG_MAX ZSTD_WINDOWLOG_MAX
|
#define ZSTD_HASHLOG_MAX ZSTD_WINDOWLOG_MAX
|
||||||
#define ZSTD_HASHLOG_MIN 12
|
#define ZSTD_HASHLOG_MIN 12
|
||||||
#define ZSTD_HASHLOG3_MAX 17
|
#define ZSTD_HASHLOG3_MAX 17
|
||||||
#define ZSTD_HASHLOG3_MIN 15
|
|
||||||
#define ZSTD_SEARCHLOG_MAX (ZSTD_WINDOWLOG_MAX-1)
|
#define ZSTD_SEARCHLOG_MAX (ZSTD_WINDOWLOG_MAX-1)
|
||||||
#define ZSTD_SEARCHLOG_MIN 1
|
#define ZSTD_SEARCHLOG_MIN 1
|
||||||
#define ZSTD_SEARCHLENGTH_MAX 7
|
#define ZSTD_SEARCHLENGTH_MAX 7
|
||||||
@@ -265,7 +264,7 @@ typedef struct { ZSTD_allocFunction customAlloc; ZSTD_freeFunction customFree; v
|
|||||||
/*! ZSTD_estimateCCtxSize() :
|
/*! ZSTD_estimateCCtxSize() :
|
||||||
* Gives the amount of memory allocated for a ZSTD_CCtx given a set of compression parameters.
|
* Gives the amount of memory allocated for a ZSTD_CCtx given a set of compression parameters.
|
||||||
* `frameContentSize` is an optional parameter, provide `0` if unknown */
|
* `frameContentSize` is an optional parameter, provide `0` if unknown */
|
||||||
ZSTDLIB_API size_t ZSTD_estimateCCtxSize(ZSTD_compressionParameters cParams, unsigned long long frameContentSize);
|
ZSTDLIB_API size_t ZSTD_estimateCCtxSize(ZSTD_compressionParameters cParams);
|
||||||
|
|
||||||
/*! ZSTD_createCCtx_advanced() :
|
/*! ZSTD_createCCtx_advanced() :
|
||||||
* Create a ZSTD compression context using external alloc and free functions */
|
* Create a ZSTD compression context using external alloc and free functions */
|
||||||
@@ -280,8 +279,6 @@ ZSTDLIB_API ZSTD_CDict* ZSTD_createCDict_advanced(const void* dict, size_t dictS
|
|||||||
* Gives the amount of memory used by a given ZSTD_CCtx */
|
* Gives the amount of memory used by a given ZSTD_CCtx */
|
||||||
ZSTDLIB_API size_t ZSTD_sizeofCCtx(const ZSTD_CCtx* cctx);
|
ZSTDLIB_API size_t ZSTD_sizeofCCtx(const ZSTD_CCtx* cctx);
|
||||||
|
|
||||||
ZSTDLIB_API unsigned ZSTD_maxCLevel (void);
|
|
||||||
|
|
||||||
/*! ZSTD_getParams() :
|
/*! ZSTD_getParams() :
|
||||||
* same as ZSTD_getCParams(), but @return a full `ZSTD_parameters` object instead of a `ZSTD_compressionParameters`.
|
* same as ZSTD_getCParams(), but @return a full `ZSTD_parameters` object instead of a `ZSTD_compressionParameters`.
|
||||||
* All fields of `ZSTD_frameParameters` are set to default (0) */
|
* All fields of `ZSTD_frameParameters` are set to default (0) */
|
||||||
@@ -326,15 +323,20 @@ ZSTDLIB_API size_t ZSTD_sizeofDCtx(const ZSTD_DCtx* dctx);
|
|||||||
|
|
||||||
|
|
||||||
/* ******************************************************************
|
/* ******************************************************************
|
||||||
* Streaming functions (direct mode - synchronous and buffer-less)
|
* Buffer-less streaming functions (synchronous mode)
|
||||||
********************************************************************/
|
********************************************************************/
|
||||||
|
/* This is an advanced API, giving full control over buffer management, for users which need direct control over memory.
|
||||||
|
* But it's also a complex one, with a lot of restrictions (documented below).
|
||||||
|
* For an easier streaming API, look into common/zbuff.h
|
||||||
|
* which removes all restrictions by allocating and managing its own internal buffer */
|
||||||
|
|
||||||
ZSTDLIB_API size_t ZSTD_compressBegin(ZSTD_CCtx* cctx, int compressionLevel);
|
ZSTDLIB_API size_t ZSTD_compressBegin(ZSTD_CCtx* cctx, int compressionLevel);
|
||||||
ZSTDLIB_API size_t ZSTD_compressBegin_usingDict(ZSTD_CCtx* cctx, const void* dict, size_t dictSize, int compressionLevel);
|
ZSTDLIB_API size_t ZSTD_compressBegin_usingDict(ZSTD_CCtx* cctx, const void* dict, size_t dictSize, int compressionLevel);
|
||||||
ZSTDLIB_API size_t ZSTD_compressBegin_advanced(ZSTD_CCtx* cctx, const void* dict, size_t dictSize, ZSTD_parameters params, unsigned long long pledgedSrcSize);
|
ZSTDLIB_API size_t ZSTD_compressBegin_advanced(ZSTD_CCtx* cctx, const void* dict, size_t dictSize, ZSTD_parameters params, unsigned long long pledgedSrcSize);
|
||||||
ZSTDLIB_API size_t ZSTD_copyCCtx(ZSTD_CCtx* cctx, const ZSTD_CCtx* preparedCCtx);
|
ZSTDLIB_API size_t ZSTD_copyCCtx(ZSTD_CCtx* cctx, const ZSTD_CCtx* preparedCCtx);
|
||||||
|
|
||||||
ZSTDLIB_API size_t ZSTD_compressContinue(ZSTD_CCtx* cctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize);
|
ZSTDLIB_API size_t ZSTD_compressContinue(ZSTD_CCtx* cctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize);
|
||||||
ZSTDLIB_API size_t ZSTD_compressEnd(ZSTD_CCtx* cctx, void* dst, size_t dstCapacity);
|
ZSTDLIB_API size_t ZSTD_compressEnd(ZSTD_CCtx* cctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
A ZSTD_CCtx object is required to track streaming operations.
|
A ZSTD_CCtx object is required to track streaming operations.
|
||||||
@@ -349,7 +351,7 @@ ZSTDLIB_API size_t ZSTD_compressEnd(ZSTD_CCtx* cctx, void* dst, size_t dstCapaci
|
|||||||
Then, consume your input using ZSTD_compressContinue().
|
Then, consume your input using ZSTD_compressContinue().
|
||||||
There are some important considerations to keep in mind when using this advanced function :
|
There are some important considerations to keep in mind when using this advanced function :
|
||||||
- ZSTD_compressContinue() has no internal buffer. It uses externally provided buffer only.
|
- ZSTD_compressContinue() has no internal buffer. It uses externally provided buffer only.
|
||||||
- Interface is synchronous : input is consumed entirely and produce 1 (or more) compressed blocks.
|
- Interface is synchronous : input is consumed entirely and produce 1+ (or more) compressed blocks.
|
||||||
- Caller must ensure there is enough space in `dst` to store compressed data under worst case scenario.
|
- Caller must ensure there is enough space in `dst` to store compressed data under worst case scenario.
|
||||||
Worst case evaluation is provided by ZSTD_compressBound().
|
Worst case evaluation is provided by ZSTD_compressBound().
|
||||||
ZSTD_compressContinue() doesn't guarantee recover after a failed compression.
|
ZSTD_compressContinue() doesn't guarantee recover after a failed compression.
|
||||||
@@ -358,9 +360,9 @@ ZSTDLIB_API size_t ZSTD_compressEnd(ZSTD_CCtx* cctx, void* dst, size_t dstCapaci
|
|||||||
- ZSTD_compressContinue() detects that prior input has been overwritten when `src` buffer overlaps.
|
- ZSTD_compressContinue() detects that prior input has been overwritten when `src` buffer overlaps.
|
||||||
In which case, it will "discard" the relevant memory section from its history.
|
In which case, it will "discard" the relevant memory section from its history.
|
||||||
|
|
||||||
|
Finish a frame with ZSTD_compressEnd(), which will write the last block(s) and optional checksum.
|
||||||
Finish a frame with ZSTD_compressEnd(), which will write the epilogue.
|
It's possible to use a NULL,0 src content, in which case, it will write a final empty block to end the frame,
|
||||||
Without epilogue, frames will be considered unfinished (broken) by decoders.
|
Without last block mark, frames will be considered unfinished (broken) by decoders.
|
||||||
|
|
||||||
You can then reuse `ZSTD_CCtx` (ZSTD_compressBegin()) to compress some new frame.
|
You can then reuse `ZSTD_CCtx` (ZSTD_compressBegin()) to compress some new frame.
|
||||||
*/
|
*/
|
||||||
@@ -372,7 +374,7 @@ typedef struct {
|
|||||||
unsigned checksumFlag;
|
unsigned checksumFlag;
|
||||||
} ZSTD_frameParams;
|
} ZSTD_frameParams;
|
||||||
|
|
||||||
ZSTDLIB_API size_t ZSTD_getFrameParams(ZSTD_frameParams* fparamsPtr, const void* src, size_t srcSize); /**< doesn't consume input */
|
ZSTDLIB_API size_t ZSTD_getFrameParams(ZSTD_frameParams* fparamsPtr, const void* src, size_t srcSize); /**< doesn't consume input, see details below */
|
||||||
|
|
||||||
ZSTDLIB_API size_t ZSTD_decompressBegin(ZSTD_DCtx* dctx);
|
ZSTDLIB_API size_t ZSTD_decompressBegin(ZSTD_DCtx* dctx);
|
||||||
ZSTDLIB_API size_t ZSTD_decompressBegin_usingDict(ZSTD_DCtx* dctx, const void* dict, size_t dictSize);
|
ZSTDLIB_API size_t ZSTD_decompressBegin_usingDict(ZSTD_DCtx* dctx, const void* dict, size_t dictSize);
|
||||||
@@ -381,49 +383,58 @@ ZSTDLIB_API void ZSTD_copyDCtx(ZSTD_DCtx* dctx, const ZSTD_DCtx* preparedDCtx)
|
|||||||
ZSTDLIB_API size_t ZSTD_nextSrcSizeToDecompress(ZSTD_DCtx* dctx);
|
ZSTDLIB_API size_t ZSTD_nextSrcSizeToDecompress(ZSTD_DCtx* dctx);
|
||||||
ZSTDLIB_API size_t ZSTD_decompressContinue(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize);
|
ZSTDLIB_API size_t ZSTD_decompressContinue(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize);
|
||||||
|
|
||||||
|
typedef enum { ZSTDnit_frameHeader, ZSTDnit_blockHeader, ZSTDnit_block, ZSTDnit_lastBlock, ZSTDnit_checksum, ZSTDnit_skippableFrame } ZSTD_nextInputType_e;
|
||||||
|
ZSTDLIB_API ZSTD_nextInputType_e ZSTD_nextInputType(ZSTD_DCtx* dctx);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Streaming decompression, direct mode (bufferless)
|
Buffer-less streaming decompression (synchronous mode)
|
||||||
|
|
||||||
A ZSTD_DCtx object is required to track streaming operations.
|
A ZSTD_DCtx object is required to track streaming operations.
|
||||||
Use ZSTD_createDCtx() / ZSTD_freeDCtx() to manage it.
|
Use ZSTD_createDCtx() / ZSTD_freeDCtx() to manage it.
|
||||||
A ZSTD_DCtx object can be re-used multiple times.
|
A ZSTD_DCtx object can be re-used multiple times.
|
||||||
|
|
||||||
First optional operation is to retrieve frame parameters, using ZSTD_getFrameParams(), which doesn't consume the input.
|
First typical operation is to retrieve frame parameters, using ZSTD_getFrameParams().
|
||||||
It can provide the minimum size of rolling buffer required to properly decompress data (`windowSize`),
|
It fills a ZSTD_frameParams structure which provide important information to correctly decode the frame,
|
||||||
and optionally the final size of uncompressed content.
|
such as the minimum rolling buffer size to allocate to decompress data (`windowSize`),
|
||||||
(Note : content size is an optional info that may not be present. 0 means : content size unknown)
|
and the dictionary ID used.
|
||||||
Frame parameters are extracted from the beginning of compressed frame.
|
(Note : content size is optional, it may not be present. 0 means : content size unknown).
|
||||||
The amount of data to read is variable, from ZSTD_frameHeaderSize_min to ZSTD_frameHeaderSize_max (so if `srcSize` >= ZSTD_frameHeaderSize_max, it will always work)
|
Note that these values could be wrong, either because of data malformation, or because an attacker is spoofing deliberate false information.
|
||||||
If `srcSize` is too small for operation to succeed, function will return the minimum size it requires to produce a result.
|
As a consequence, check that values remain within valid application range, especially `windowSize`, before allocation.
|
||||||
Result : 0 when successful, it means the ZSTD_frameParams structure has been filled.
|
Each application can set its own limit, depending on local restrictions. For extended interoperability, it is recommended to support at least 8 MB.
|
||||||
>0 : means there is not enough data into `src`. Provides the expected size to successfully decode header.
|
Frame parameters are extracted from the beginning of the compressed frame.
|
||||||
errorCode, which can be tested using ZSTD_isError()
|
Data fragment must be large enough to ensure successful decoding, typically `ZSTD_frameHeaderSize_max` bytes.
|
||||||
|
@result : 0 : successful decoding, the `ZSTD_frameParams` structure is correctly filled.
|
||||||
|
>0 : `srcSize` is too small, please provide at least @result bytes on next attempt.
|
||||||
|
errorCode, which can be tested using ZSTD_isError().
|
||||||
|
|
||||||
Start decompression, with ZSTD_decompressBegin() or ZSTD_decompressBegin_usingDict().
|
Start decompression, with ZSTD_decompressBegin() or ZSTD_decompressBegin_usingDict().
|
||||||
Alternatively, you can copy a prepared context, using ZSTD_copyDCtx().
|
Alternatively, you can copy a prepared context, using ZSTD_copyDCtx().
|
||||||
|
|
||||||
Then use ZSTD_nextSrcSizeToDecompress() and ZSTD_decompressContinue() alternatively.
|
Then use ZSTD_nextSrcSizeToDecompress() and ZSTD_decompressContinue() alternatively.
|
||||||
ZSTD_nextSrcSizeToDecompress() tells how much bytes to provide as 'srcSize' to ZSTD_decompressContinue().
|
ZSTD_nextSrcSizeToDecompress() tells how many bytes to provide as 'srcSize' to ZSTD_decompressContinue().
|
||||||
ZSTD_decompressContinue() requires this exact amount of bytes, or it will fail.
|
ZSTD_decompressContinue() requires this _exact_ amount of bytes, or it will fail.
|
||||||
|
|
||||||
@result of ZSTD_decompressContinue() is the number of bytes regenerated within 'dst' (necessarily <= dstCapacity).
|
@result of ZSTD_decompressContinue() is the number of bytes regenerated within 'dst' (necessarily <= dstCapacity).
|
||||||
It can be zero, which is not an error; it just means ZSTD_decompressContinue() has decoded some header.
|
It can be zero, which is not an error; it just means ZSTD_decompressContinue() has decoded some metadata item.
|
||||||
|
It can also be an error code, which can be tested with ZSTD_isError().
|
||||||
|
|
||||||
ZSTD_decompressContinue() needs previous data blocks during decompression, up to `windowSize`.
|
ZSTD_decompressContinue() needs previous data blocks during decompression, up to `windowSize`.
|
||||||
They should preferably be located contiguously, prior to current block.
|
They should preferably be located contiguously, prior to current block.
|
||||||
Alternatively, a round buffer of sufficient size is also possible. Sufficient size is determined by frame parameters.
|
Alternatively, a round buffer of sufficient size is also possible. Sufficient size is determined by frame parameters.
|
||||||
ZSTD_decompressContinue() is very sensitive to contiguity,
|
ZSTD_decompressContinue() is very sensitive to contiguity,
|
||||||
if 2 blocks don't follow each other, make sure that either the compressor breaks contiguity at the same place,
|
if 2 blocks don't follow each other, make sure that either the compressor breaks contiguity at the same place,
|
||||||
or that previous contiguous segment is large enough to properly handle maximum back-reference.
|
or that previous contiguous segment is large enough to properly handle maximum back-reference.
|
||||||
|
|
||||||
A frame is fully decoded when ZSTD_nextSrcSizeToDecompress() returns zero.
|
A frame is fully decoded when ZSTD_nextSrcSizeToDecompress() returns zero.
|
||||||
Context can then be reset to start a new decompression.
|
Context can then be reset to start a new decompression.
|
||||||
|
|
||||||
|
Note : it's possible to know if next input to present is a header or a block, using ZSTD_nextInputType().
|
||||||
|
This information is not required to properly decode a frame.
|
||||||
|
|
||||||
== Special case : skippable frames ==
|
== Special case : skippable frames ==
|
||||||
|
|
||||||
Skippable frames allow the integration of user-defined data into a flow of concatenated frames.
|
Skippable frames allow integration of user-defined data into a flow of concatenated frames.
|
||||||
Skippable frames will be ignored (skipped) by a decompressor. The format of skippable frame is following:
|
Skippable frames will be ignored (skipped) by a decompressor. The format of skippable frames is as follows :
|
||||||
a) Skippable frame ID - 4 Bytes, Little endian format, any value from 0x184D2A50 to 0x184D2A5F
|
a) Skippable frame ID - 4 Bytes, Little endian format, any value from 0x184D2A50 to 0x184D2A5F
|
||||||
b) Frame Size - 4 Bytes, Little endian format, unsigned 32-bits
|
b) Frame Size - 4 Bytes, Little endian format, unsigned 32-bits
|
||||||
c) Frame Content - any content (User Data) of length equal to Frame Size
|
c) Frame Content - any content (User Data) of length equal to Frame Size
|
||||||
@@ -437,13 +448,10 @@ ZSTDLIB_API size_t ZSTD_decompressContinue(ZSTD_DCtx* dctx, void* dst, size_t ds
|
|||||||
* Block functions
|
* Block functions
|
||||||
****************************************/
|
****************************************/
|
||||||
/*! Block functions produce and decode raw zstd blocks, without frame metadata.
|
/*! Block functions produce and decode raw zstd blocks, without frame metadata.
|
||||||
Frame metadata cost is typically ~18 bytes, which is non-negligible on very small blocks.
|
Frame metadata cost is typically ~18 bytes, which can be non-negligible for very small blocks (< 100 bytes).
|
||||||
User will have to take in charge required information to regenerate data, such as compressed and content sizes.
|
User will have to take in charge required information to regenerate data, such as compressed and content sizes.
|
||||||
|
|
||||||
A few rules to respect :
|
A few rules to respect :
|
||||||
- Uncompressed block size must be <= ZSTD_BLOCKSIZE_MAX (128 KB)
|
|
||||||
+ If you need to compress more, cut data into multiple blocks
|
|
||||||
+ Consider using the regular ZSTD_compress() instead, as frame metadata costs become negligible when source size is large.
|
|
||||||
- Compressing and decompressing require a context structure
|
- Compressing and decompressing require a context structure
|
||||||
+ Use ZSTD_createCCtx() and ZSTD_createDCtx()
|
+ Use ZSTD_createCCtx() and ZSTD_createDCtx()
|
||||||
- It is necessary to init context before starting
|
- It is necessary to init context before starting
|
||||||
@@ -451,19 +459,22 @@ ZSTDLIB_API size_t ZSTD_decompressContinue(ZSTD_DCtx* dctx, void* dst, size_t ds
|
|||||||
+ decompression : ZSTD_decompressBegin()
|
+ decompression : ZSTD_decompressBegin()
|
||||||
+ variants _usingDict() are also allowed
|
+ variants _usingDict() are also allowed
|
||||||
+ copyCCtx() and copyDCtx() work too
|
+ copyCCtx() and copyDCtx() work too
|
||||||
|
- Block size is limited, it must be <= ZSTD_getBlockSizeMax()
|
||||||
|
+ If you need to compress more, cut data into multiple blocks
|
||||||
|
+ Consider using the regular ZSTD_compress() instead, as frame metadata costs become negligible when source size is large.
|
||||||
- When a block is considered not compressible enough, ZSTD_compressBlock() result will be zero.
|
- When a block is considered not compressible enough, ZSTD_compressBlock() result will be zero.
|
||||||
In which case, nothing is produced into `dst`.
|
In which case, nothing is produced into `dst`.
|
||||||
+ User must test for such outcome and deal directly with uncompressed data
|
+ User must test for such outcome and deal directly with uncompressed data
|
||||||
+ ZSTD_decompressBlock() doesn't accept uncompressed data as input !!!
|
+ ZSTD_decompressBlock() doesn't accept uncompressed data as input !!!
|
||||||
+ In case of multiple successive blocks, decoder must be informed of uncompressed block existence to follow proper history.
|
+ In case of multiple successive blocks, decoder must be informed of uncompressed block existence to follow proper history.
|
||||||
Use ZSTD_insertBlock() in such a case.
|
Use ZSTD_insertBlock() in such a case.
|
||||||
Insert block once it's copied into its final position.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define ZSTD_BLOCKSIZE_MAX (128 * 1024) /* define, for static allocation */
|
#define ZSTD_BLOCKSIZE_ABSOLUTEMAX (128 * 1024) /* define, for static allocation */
|
||||||
|
ZSTDLIB_API size_t ZSTD_getBlockSizeMax(ZSTD_CCtx* cctx);
|
||||||
ZSTDLIB_API size_t ZSTD_compressBlock (ZSTD_CCtx* cctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize);
|
ZSTDLIB_API size_t ZSTD_compressBlock (ZSTD_CCtx* cctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize);
|
||||||
ZSTDLIB_API size_t ZSTD_decompressBlock(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize);
|
ZSTDLIB_API size_t ZSTD_decompressBlock(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize);
|
||||||
ZSTDLIB_API size_t ZSTD_insertBlock(ZSTD_DCtx* dctx, const void* blockStart, size_t blockSize); /**< insert block into `dctx` history. Useful to track uncompressed blocks */
|
ZSTDLIB_API size_t ZSTD_insertBlock(ZSTD_DCtx* dctx, const void* blockStart, size_t blockSize); /**< insert block into `dctx` history. Useful for uncompressed blocks */
|
||||||
|
|
||||||
|
|
||||||
#endif /* ZSTD_STATIC_LINKING_ONLY */
|
#endif /* ZSTD_STATIC_LINKING_ONLY */
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -105,6 +105,7 @@ static void ZSTD_copy4(void* dst, const void* src) { memcpy(dst, src, 4); }
|
|||||||
***************************************************************/
|
***************************************************************/
|
||||||
typedef enum { ZSTDds_getFrameHeaderSize, ZSTDds_decodeFrameHeader,
|
typedef enum { ZSTDds_getFrameHeaderSize, ZSTDds_decodeFrameHeader,
|
||||||
ZSTDds_decodeBlockHeader, ZSTDds_decompressBlock,
|
ZSTDds_decodeBlockHeader, ZSTDds_decompressBlock,
|
||||||
|
ZSTDds_decompressLastBlock, ZSTDds_checkChecksum,
|
||||||
ZSTDds_decodeSkippableHeader, ZSTDds_skipFrame } ZSTD_dStage;
|
ZSTDds_decodeSkippableHeader, ZSTDds_skipFrame } ZSTD_dStage;
|
||||||
|
|
||||||
struct ZSTD_DCtx_s
|
struct ZSTD_DCtx_s
|
||||||
@@ -118,9 +119,9 @@ struct ZSTD_DCtx_s
|
|||||||
const void* vBase;
|
const void* vBase;
|
||||||
const void* dictEnd;
|
const void* dictEnd;
|
||||||
size_t expected;
|
size_t expected;
|
||||||
U32 rep[3];
|
U32 rep[ZSTD_REP_NUM];
|
||||||
ZSTD_frameParams fParams;
|
ZSTD_frameParams fParams;
|
||||||
blockType_t bType; /* used in ZSTD_decompressContinue(), to transfer blockType between header decoding and block decoding stages */
|
blockType_e bType; /* used in ZSTD_decompressContinue(), to transfer blockType between header decoding and block decoding stages */
|
||||||
ZSTD_dStage stage;
|
ZSTD_dStage stage;
|
||||||
U32 litEntropy;
|
U32 litEntropy;
|
||||||
U32 fseEntropy;
|
U32 fseEntropy;
|
||||||
@@ -131,7 +132,8 @@ struct ZSTD_DCtx_s
|
|||||||
ZSTD_customMem customMem;
|
ZSTD_customMem customMem;
|
||||||
size_t litBufSize;
|
size_t litBufSize;
|
||||||
size_t litSize;
|
size_t litSize;
|
||||||
BYTE litBuffer[ZSTD_BLOCKSIZE_MAX + WILDCOPY_OVERLENGTH];
|
size_t rleSize;
|
||||||
|
BYTE litBuffer[ZSTD_BLOCKSIZE_ABSOLUTEMAX + WILDCOPY_OVERLENGTH];
|
||||||
BYTE headerBuffer[ZSTD_FRAMEHEADERSIZE_MAX];
|
BYTE headerBuffer[ZSTD_FRAMEHEADERSIZE_MAX];
|
||||||
}; /* typedef'd to ZSTD_DCtx within "zstd_static.h" */
|
}; /* typedef'd to ZSTD_DCtx within "zstd_static.h" */
|
||||||
|
|
||||||
@@ -186,7 +188,7 @@ size_t ZSTD_freeDCtx(ZSTD_DCtx* dctx)
|
|||||||
void ZSTD_copyDCtx(ZSTD_DCtx* dstDCtx, const ZSTD_DCtx* srcDCtx)
|
void ZSTD_copyDCtx(ZSTD_DCtx* dstDCtx, const ZSTD_DCtx* srcDCtx)
|
||||||
{
|
{
|
||||||
memcpy(dstDCtx, srcDCtx,
|
memcpy(dstDCtx, srcDCtx,
|
||||||
sizeof(ZSTD_DCtx) - (ZSTD_BLOCKSIZE_MAX+WILDCOPY_OVERLENGTH + ZSTD_frameHeaderSize_max)); /* no need to copy workspace */
|
sizeof(ZSTD_DCtx) - (ZSTD_BLOCKSIZE_ABSOLUTEMAX+WILDCOPY_OVERLENGTH + ZSTD_frameHeaderSize_max)); /* no need to copy workspace */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -194,117 +196,7 @@ void ZSTD_copyDCtx(ZSTD_DCtx* dstDCtx, const ZSTD_DCtx* srcDCtx)
|
|||||||
* Decompression section
|
* Decompression section
|
||||||
***************************************************************/
|
***************************************************************/
|
||||||
|
|
||||||
/* Frame format description
|
/* See compression format details in : zstd_compression_format.md */
|
||||||
Frame Header - [ Block Header - Block ] - Frame End
|
|
||||||
1) Frame Header
|
|
||||||
- 4 bytes - Magic Number : ZSTD_MAGICNUMBER (defined within zstd.h)
|
|
||||||
- 1 byte - Frame Descriptor
|
|
||||||
2) Block Header
|
|
||||||
- 3 bytes, starting with a 2-bits descriptor
|
|
||||||
Uncompressed, Compressed, Frame End, unused
|
|
||||||
3) Block
|
|
||||||
See Block Format Description
|
|
||||||
4) Frame End
|
|
||||||
- 3 bytes, compatible with Block Header
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
/* Frame Header :
|
|
||||||
|
|
||||||
1 byte - FrameHeaderDescription :
|
|
||||||
bit 0-1 : dictID (0, 1, 2 or 4 bytes)
|
|
||||||
bit 2 : checksumFlag
|
|
||||||
bit 3 : reserved (must be zero)
|
|
||||||
bit 4 : reserved (unused, can be any value)
|
|
||||||
bit 5 : Single Segment (if 1, WindowLog byte is not present)
|
|
||||||
bit 6-7 : FrameContentFieldSize (0, 2, 4, or 8)
|
|
||||||
if (SkippedWindowLog && !FrameContentFieldsize) FrameContentFieldsize=1;
|
|
||||||
|
|
||||||
Optional : WindowLog (0 or 1 byte)
|
|
||||||
bit 0-2 : octal Fractional (1/8th)
|
|
||||||
bit 3-7 : Power of 2, with 0 = 1 KB (up to 2 TB)
|
|
||||||
|
|
||||||
Optional : dictID (0, 1, 2 or 4 bytes)
|
|
||||||
Automatic adaptation
|
|
||||||
0 : no dictID
|
|
||||||
1 : 1 - 255
|
|
||||||
2 : 256 - 65535
|
|
||||||
4 : all other values
|
|
||||||
|
|
||||||
Optional : content size (0, 1, 2, 4 or 8 bytes)
|
|
||||||
0 : unknown (fcfs==0 and swl==0)
|
|
||||||
1 : 0-255 bytes (fcfs==0 and swl==1)
|
|
||||||
2 : 256 - 65535+256 (fcfs==1)
|
|
||||||
4 : 0 - 4GB-1 (fcfs==2)
|
|
||||||
8 : 0 - 16EB-1 (fcfs==3)
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
/* Compressed Block, format description
|
|
||||||
|
|
||||||
Block = Literal Section - Sequences Section
|
|
||||||
Prerequisite : size of (compressed) block, maximum size of regenerated data
|
|
||||||
|
|
||||||
1) Literal Section
|
|
||||||
|
|
||||||
1.1) Header : 1-5 bytes
|
|
||||||
flags: 2 bits
|
|
||||||
00 compressed by Huff0
|
|
||||||
01 unused
|
|
||||||
10 is Raw (uncompressed)
|
|
||||||
11 is Rle
|
|
||||||
Note : using 01 => Huff0 with precomputed table ?
|
|
||||||
Note : delta map ? => compressed ?
|
|
||||||
|
|
||||||
1.1.1) Huff0-compressed literal block : 3-5 bytes
|
|
||||||
srcSize < 1 KB => 3 bytes (2-2-10-10) => single stream
|
|
||||||
srcSize < 1 KB => 3 bytes (2-2-10-10)
|
|
||||||
srcSize < 16KB => 4 bytes (2-2-14-14)
|
|
||||||
else => 5 bytes (2-2-18-18)
|
|
||||||
big endian convention
|
|
||||||
|
|
||||||
1.1.2) Raw (uncompressed) literal block header : 1-3 bytes
|
|
||||||
size : 5 bits: (IS_RAW<<6) + (0<<4) + size
|
|
||||||
12 bits: (IS_RAW<<6) + (2<<4) + (size>>8)
|
|
||||||
size&255
|
|
||||||
20 bits: (IS_RAW<<6) + (3<<4) + (size>>16)
|
|
||||||
size>>8&255
|
|
||||||
size&255
|
|
||||||
|
|
||||||
1.1.3) Rle (repeated single byte) literal block header : 1-3 bytes
|
|
||||||
size : 5 bits: (IS_RLE<<6) + (0<<4) + size
|
|
||||||
12 bits: (IS_RLE<<6) + (2<<4) + (size>>8)
|
|
||||||
size&255
|
|
||||||
20 bits: (IS_RLE<<6) + (3<<4) + (size>>16)
|
|
||||||
size>>8&255
|
|
||||||
size&255
|
|
||||||
|
|
||||||
1.1.4) Huff0-compressed literal block, using precomputed CTables : 3-5 bytes
|
|
||||||
srcSize < 1 KB => 3 bytes (2-2-10-10) => single stream
|
|
||||||
srcSize < 1 KB => 3 bytes (2-2-10-10)
|
|
||||||
srcSize < 16KB => 4 bytes (2-2-14-14)
|
|
||||||
else => 5 bytes (2-2-18-18)
|
|
||||||
big endian convention
|
|
||||||
|
|
||||||
1- CTable available (stored into workspace ?)
|
|
||||||
2- Small input (fast heuristic ? Full comparison ? depend on clevel ?)
|
|
||||||
|
|
||||||
|
|
||||||
1.2) Literal block content
|
|
||||||
|
|
||||||
1.2.1) Huff0 block, using sizes from header
|
|
||||||
See Huff0 format
|
|
||||||
|
|
||||||
1.2.2) Huff0 block, using prepared table
|
|
||||||
|
|
||||||
1.2.3) Raw content
|
|
||||||
|
|
||||||
1.2.4) single byte
|
|
||||||
|
|
||||||
|
|
||||||
2) Sequences section
|
|
||||||
TO DO
|
|
||||||
*/
|
|
||||||
|
|
||||||
/** ZSTD_frameHeaderSize() :
|
/** ZSTD_frameHeaderSize() :
|
||||||
* srcSize must be >= ZSTD_frameHeaderSize_min.
|
* srcSize must be >= ZSTD_frameHeaderSize_min.
|
||||||
@@ -314,10 +206,10 @@ static size_t ZSTD_frameHeaderSize(const void* src, size_t srcSize)
|
|||||||
if (srcSize < ZSTD_frameHeaderSize_min) return ERROR(srcSize_wrong);
|
if (srcSize < ZSTD_frameHeaderSize_min) return ERROR(srcSize_wrong);
|
||||||
{ BYTE const fhd = ((const BYTE*)src)[4];
|
{ BYTE const fhd = ((const BYTE*)src)[4];
|
||||||
U32 const dictID= fhd & 3;
|
U32 const dictID= fhd & 3;
|
||||||
U32 const directMode = (fhd >> 5) & 1;
|
U32 const singleSegment = (fhd >> 5) & 1;
|
||||||
U32 const fcsId = fhd >> 6;
|
U32 const fcsId = fhd >> 6;
|
||||||
return ZSTD_frameHeaderSize_min + !directMode + ZSTD_did_fieldSize[dictID] + ZSTD_fcs_fieldSize[fcsId]
|
return ZSTD_frameHeaderSize_min + !singleSegment + ZSTD_did_fieldSize[dictID] + ZSTD_fcs_fieldSize[fcsId]
|
||||||
+ (directMode && !ZSTD_fcs_fieldSize[fcsId]);
|
+ (singleSegment && !ZSTD_fcs_fieldSize[fcsId]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -351,14 +243,14 @@ size_t ZSTD_getFrameParams(ZSTD_frameParams* fparamsPtr, const void* src, size_t
|
|||||||
size_t pos = 5;
|
size_t pos = 5;
|
||||||
U32 const dictIDSizeCode = fhdByte&3;
|
U32 const dictIDSizeCode = fhdByte&3;
|
||||||
U32 const checksumFlag = (fhdByte>>2)&1;
|
U32 const checksumFlag = (fhdByte>>2)&1;
|
||||||
U32 const directMode = (fhdByte>>5)&1;
|
U32 const singleSegment = (fhdByte>>5)&1;
|
||||||
U32 const fcsID = fhdByte>>6;
|
U32 const fcsID = fhdByte>>6;
|
||||||
U32 const windowSizeMax = 1U << ZSTD_WINDOWLOG_MAX;
|
U32 const windowSizeMax = 1U << ZSTD_WINDOWLOG_MAX;
|
||||||
U32 windowSize = 0;
|
U32 windowSize = 0;
|
||||||
U32 dictID = 0;
|
U32 dictID = 0;
|
||||||
U64 frameContentSize = 0;
|
U64 frameContentSize = 0;
|
||||||
if ((fhdByte & 0x08) != 0) return ERROR(frameParameter_unsupported); /* reserved bits, which must be zero */
|
if ((fhdByte & 0x08) != 0) return ERROR(frameParameter_unsupported); /* reserved bits, which must be zero */
|
||||||
if (!directMode) {
|
if (!singleSegment) {
|
||||||
BYTE const wlByte = ip[pos++];
|
BYTE const wlByte = ip[pos++];
|
||||||
U32 const windowLog = (wlByte >> 3) + ZSTD_WINDOWLOG_ABSOLUTEMIN;
|
U32 const windowLog = (wlByte >> 3) + ZSTD_WINDOWLOG_ABSOLUTEMIN;
|
||||||
if (windowLog > ZSTD_WINDOWLOG_MAX) return ERROR(frameParameter_unsupported);
|
if (windowLog > ZSTD_WINDOWLOG_MAX) return ERROR(frameParameter_unsupported);
|
||||||
@@ -377,7 +269,7 @@ size_t ZSTD_getFrameParams(ZSTD_frameParams* fparamsPtr, const void* src, size_t
|
|||||||
switch(fcsID)
|
switch(fcsID)
|
||||||
{
|
{
|
||||||
default: /* impossible */
|
default: /* impossible */
|
||||||
case 0 : if (directMode) frameContentSize = ip[pos]; break;
|
case 0 : if (singleSegment) frameContentSize = ip[pos]; break;
|
||||||
case 1 : frameContentSize = MEM_readLE16(ip+pos)+256; break;
|
case 1 : frameContentSize = MEM_readLE16(ip+pos)+256; break;
|
||||||
case 2 : frameContentSize = MEM_readLE32(ip+pos); break;
|
case 2 : frameContentSize = MEM_readLE32(ip+pos); break;
|
||||||
case 3 : frameContentSize = MEM_readLE64(ip+pos); break;
|
case 3 : frameContentSize = MEM_readLE64(ip+pos); break;
|
||||||
@@ -397,9 +289,9 @@ size_t ZSTD_getFrameParams(ZSTD_frameParams* fparamsPtr, const void* src, size_t
|
|||||||
* compatible with legacy mode
|
* compatible with legacy mode
|
||||||
* @return : decompressed size if known, 0 otherwise
|
* @return : decompressed size if known, 0 otherwise
|
||||||
note : 0 can mean any of the following :
|
note : 0 can mean any of the following :
|
||||||
- decompressed size is not provided within frame header
|
- decompressed size is not present within frame header
|
||||||
- frame header unknown / not supported
|
- frame header unknown / not supported
|
||||||
- frame header not completely provided (`srcSize` too small) */
|
- frame header not complete (`srcSize` too small) */
|
||||||
unsigned long long ZSTD_getDecompressedSize(const void* src, size_t srcSize)
|
unsigned long long ZSTD_getDecompressedSize(const void* src, size_t srcSize)
|
||||||
{
|
{
|
||||||
#if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT==1)
|
#if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT==1)
|
||||||
@@ -427,7 +319,8 @@ static size_t ZSTD_decodeFrameHeader(ZSTD_DCtx* dctx, const void* src, size_t sr
|
|||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
blockType_t blockType;
|
blockType_e blockType;
|
||||||
|
U32 lastBlock;
|
||||||
U32 origSize;
|
U32 origSize;
|
||||||
} blockProperties_t;
|
} blockProperties_t;
|
||||||
|
|
||||||
@@ -435,18 +328,16 @@ typedef struct
|
|||||||
* Provides the size of compressed block from block header `src` */
|
* Provides the size of compressed block from block header `src` */
|
||||||
size_t ZSTD_getcBlockSize(const void* src, size_t srcSize, blockProperties_t* bpPtr)
|
size_t ZSTD_getcBlockSize(const void* src, size_t srcSize, blockProperties_t* bpPtr)
|
||||||
{
|
{
|
||||||
const BYTE* const in = (const BYTE* const)src;
|
|
||||||
U32 cSize;
|
|
||||||
|
|
||||||
if (srcSize < ZSTD_blockHeaderSize) return ERROR(srcSize_wrong);
|
if (srcSize < ZSTD_blockHeaderSize) return ERROR(srcSize_wrong);
|
||||||
|
{ U32 const cBlockHeader = MEM_readLE24(src);
|
||||||
bpPtr->blockType = (blockType_t)((*in) >> 6);
|
U32 const cSize = cBlockHeader >> 3;
|
||||||
cSize = in[2] + (in[1]<<8) + ((in[0] & 7)<<16);
|
bpPtr->lastBlock = cBlockHeader & 1;
|
||||||
bpPtr->origSize = (bpPtr->blockType == bt_rle) ? cSize : 0;
|
bpPtr->blockType = (blockType_e)((cBlockHeader >> 1) & 3);
|
||||||
|
bpPtr->origSize = cSize; /* only useful for RLE */
|
||||||
if (bpPtr->blockType == bt_end) return 0;
|
if (bpPtr->blockType == bt_rle) return 1;
|
||||||
if (bpPtr->blockType == bt_rle) return 1;
|
if (bpPtr->blockType == bt_reserved) return ERROR(corruption_detected);
|
||||||
return cSize;
|
return cSize;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -458,136 +349,143 @@ static size_t ZSTD_copyRawBlock(void* dst, size_t dstCapacity, const void* src,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static size_t ZSTD_setRleBlock(void* dst, size_t dstCapacity, const void* src, size_t srcSize, size_t regenSize)
|
||||||
|
{
|
||||||
|
if (srcSize != 1) return ERROR(srcSize_wrong);
|
||||||
|
if (regenSize > dstCapacity) return ERROR(dstSize_tooSmall);
|
||||||
|
memset(dst, *(const BYTE*)src, regenSize);
|
||||||
|
return regenSize;
|
||||||
|
}
|
||||||
|
|
||||||
/*! ZSTD_decodeLiteralsBlock() :
|
/*! ZSTD_decodeLiteralsBlock() :
|
||||||
@return : nb of bytes read from src (< srcSize ) */
|
@return : nb of bytes read from src (< srcSize ) */
|
||||||
size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx,
|
size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx,
|
||||||
const void* src, size_t srcSize) /* note : srcSize < BLOCKSIZE */
|
const void* src, size_t srcSize) /* note : srcSize < BLOCKSIZE */
|
||||||
{
|
{
|
||||||
const BYTE* const istart = (const BYTE*) src;
|
|
||||||
|
|
||||||
if (srcSize < MIN_CBLOCK_SIZE) return ERROR(corruption_detected);
|
if (srcSize < MIN_CBLOCK_SIZE) return ERROR(corruption_detected);
|
||||||
|
|
||||||
switch((litBlockType_t)(istart[0]>> 6))
|
{ const BYTE* const istart = (const BYTE*) src;
|
||||||
{
|
symbolEncodingType_e const litEncType = (symbolEncodingType_e)(istart[0] & 3);
|
||||||
case lbt_huffman:
|
|
||||||
{ size_t litSize, litCSize, singleStream=0;
|
|
||||||
U32 lhSize = (istart[0] >> 4) & 3;
|
|
||||||
if (srcSize < 5) return ERROR(corruption_detected); /* srcSize >= MIN_CBLOCK_SIZE == 3; here we need up to 5 for lhSize, + cSize (+nbSeq) */
|
|
||||||
switch(lhSize)
|
|
||||||
{
|
|
||||||
case 0: case 1: default: /* note : default is impossible, since lhSize into [0..3] */
|
|
||||||
/* 2 - 2 - 10 - 10 */
|
|
||||||
lhSize=3;
|
|
||||||
singleStream = istart[0] & 16;
|
|
||||||
litSize = ((istart[0] & 15) << 6) + (istart[1] >> 2);
|
|
||||||
litCSize = ((istart[1] & 3) << 8) + istart[2];
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
/* 2 - 2 - 14 - 14 */
|
|
||||||
lhSize=4;
|
|
||||||
litSize = ((istart[0] & 15) << 10) + (istart[1] << 2) + (istart[2] >> 6);
|
|
||||||
litCSize = ((istart[2] & 63) << 8) + istart[3];
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
/* 2 - 2 - 18 - 18 */
|
|
||||||
lhSize=5;
|
|
||||||
litSize = ((istart[0] & 15) << 14) + (istart[1] << 6) + (istart[2] >> 2);
|
|
||||||
litCSize = ((istart[2] & 3) << 16) + (istart[3] << 8) + istart[4];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (litSize > ZSTD_BLOCKSIZE_MAX) return ERROR(corruption_detected);
|
|
||||||
if (litCSize + lhSize > srcSize) return ERROR(corruption_detected);
|
|
||||||
|
|
||||||
if (HUF_isError(singleStream ?
|
switch(litEncType)
|
||||||
HUF_decompress1X2_DCtx(dctx->hufTable, dctx->litBuffer, litSize, istart+lhSize, litCSize) :
|
{
|
||||||
HUF_decompress4X_hufOnly (dctx->hufTable, dctx->litBuffer, litSize, istart+lhSize, litCSize) ))
|
case set_repeat:
|
||||||
return ERROR(corruption_detected);
|
if (dctx->litEntropy==0) return ERROR(dictionary_corrupted);
|
||||||
|
/* fall-through */
|
||||||
|
case set_compressed:
|
||||||
|
if (srcSize < 5) return ERROR(corruption_detected); /* srcSize >= MIN_CBLOCK_SIZE == 3; here we need up to 5 for case 3 */
|
||||||
|
{ size_t lhSize, litSize, litCSize;
|
||||||
|
U32 singleStream=0;
|
||||||
|
U32 const lhlCode = (istart[0] >> 2) & 3;
|
||||||
|
U32 const lhc = MEM_readLE32(istart);
|
||||||
|
switch(lhlCode)
|
||||||
|
{
|
||||||
|
case 0: case 1: default: /* note : default is impossible, since lhlCode into [0..3] */
|
||||||
|
/* 2 - 2 - 10 - 10 */
|
||||||
|
{ singleStream = !lhlCode;
|
||||||
|
lhSize = 3;
|
||||||
|
litSize = (lhc >> 4) & 0x3FF;
|
||||||
|
litCSize = (lhc >> 14) & 0x3FF;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 2:
|
||||||
|
/* 2 - 2 - 14 - 14 */
|
||||||
|
{ lhSize = 4;
|
||||||
|
litSize = (lhc >> 4) & 0x3FFF;
|
||||||
|
litCSize = lhc >> 18;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 3:
|
||||||
|
/* 2 - 2 - 18 - 18 */
|
||||||
|
{ lhSize = 5;
|
||||||
|
litSize = (lhc >> 4) & 0x3FFFF;
|
||||||
|
litCSize = (lhc >> 22) + (istart[4] << 10);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (litSize > ZSTD_BLOCKSIZE_ABSOLUTEMAX) return ERROR(corruption_detected);
|
||||||
|
if (litCSize + lhSize > srcSize) return ERROR(corruption_detected);
|
||||||
|
|
||||||
dctx->litPtr = dctx->litBuffer;
|
if (HUF_isError((litEncType==set_repeat) ?
|
||||||
dctx->litBufSize = ZSTD_BLOCKSIZE_MAX+8;
|
( singleStream ?
|
||||||
dctx->litSize = litSize;
|
HUF_decompress1X_usingDTable(dctx->litBuffer, litSize, istart+lhSize, litCSize, dctx->hufTable) :
|
||||||
dctx->litEntropy = 1;
|
HUF_decompress4X_usingDTable(dctx->litBuffer, litSize, istart+lhSize, litCSize, dctx->hufTable) ) :
|
||||||
return litCSize + lhSize;
|
( singleStream ?
|
||||||
}
|
HUF_decompress1X2_DCtx(dctx->hufTable, dctx->litBuffer, litSize, istart+lhSize, litCSize) :
|
||||||
case lbt_repeat:
|
HUF_decompress4X_hufOnly (dctx->hufTable, dctx->litBuffer, litSize, istart+lhSize, litCSize)) ))
|
||||||
{ size_t litSize, litCSize;
|
return ERROR(corruption_detected);
|
||||||
U32 lhSize = ((istart[0]) >> 4) & 3;
|
|
||||||
if (lhSize != 1) /* only case supported for now : small litSize, single stream */
|
|
||||||
return ERROR(corruption_detected);
|
|
||||||
if (dctx->litEntropy==0)
|
|
||||||
return ERROR(dictionary_corrupted);
|
|
||||||
|
|
||||||
/* 2 - 2 - 10 - 10 */
|
|
||||||
lhSize=3;
|
|
||||||
litSize = ((istart[0] & 15) << 6) + (istart[1] >> 2);
|
|
||||||
litCSize = ((istart[1] & 3) << 8) + istart[2];
|
|
||||||
if (litCSize + lhSize > srcSize) return ERROR(corruption_detected);
|
|
||||||
|
|
||||||
{ size_t const errorCode = HUF_decompress1X4_usingDTable(dctx->litBuffer, litSize, istart+lhSize, litCSize, dctx->hufTable);
|
|
||||||
if (HUF_isError(errorCode)) return ERROR(corruption_detected);
|
|
||||||
}
|
|
||||||
dctx->litPtr = dctx->litBuffer;
|
|
||||||
dctx->litBufSize = ZSTD_BLOCKSIZE_MAX+WILDCOPY_OVERLENGTH;
|
|
||||||
dctx->litSize = litSize;
|
|
||||||
return litCSize + lhSize;
|
|
||||||
}
|
|
||||||
case lbt_raw:
|
|
||||||
{ size_t litSize;
|
|
||||||
U32 lhSize = ((istart[0]) >> 4) & 3;
|
|
||||||
switch(lhSize)
|
|
||||||
{
|
|
||||||
case 0: case 1: default: /* note : default is impossible, since lhSize into [0..3] */
|
|
||||||
lhSize=1;
|
|
||||||
litSize = istart[0] & 31;
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
litSize = ((istart[0] & 15) << 8) + istart[1];
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
litSize = ((istart[0] & 15) << 16) + (istart[1] << 8) + istart[2];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (lhSize+litSize+WILDCOPY_OVERLENGTH > srcSize) { /* risk reading beyond src buffer with wildcopy */
|
|
||||||
if (litSize+lhSize > srcSize) return ERROR(corruption_detected);
|
|
||||||
memcpy(dctx->litBuffer, istart+lhSize, litSize);
|
|
||||||
dctx->litPtr = dctx->litBuffer;
|
dctx->litPtr = dctx->litBuffer;
|
||||||
dctx->litBufSize = ZSTD_BLOCKSIZE_MAX+8;
|
dctx->litBufSize = ZSTD_BLOCKSIZE_ABSOLUTEMAX+WILDCOPY_OVERLENGTH;
|
||||||
|
dctx->litSize = litSize;
|
||||||
|
dctx->litEntropy = 1;
|
||||||
|
return litCSize + lhSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
case set_basic:
|
||||||
|
{ size_t litSize, lhSize;
|
||||||
|
U32 const lhlCode = ((istart[0]) >> 2) & 3;
|
||||||
|
switch(lhlCode)
|
||||||
|
{
|
||||||
|
case 0: case 2: default: /* note : default is impossible, since lhlCode into [0..3] */
|
||||||
|
lhSize = 1;
|
||||||
|
litSize = istart[0] >> 3;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
lhSize = 2;
|
||||||
|
litSize = MEM_readLE16(istart) >> 4;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
lhSize = 3;
|
||||||
|
litSize = MEM_readLE24(istart) >> 4;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lhSize+litSize+WILDCOPY_OVERLENGTH > srcSize) { /* risk reading beyond src buffer with wildcopy */
|
||||||
|
if (litSize+lhSize > srcSize) return ERROR(corruption_detected);
|
||||||
|
memcpy(dctx->litBuffer, istart+lhSize, litSize);
|
||||||
|
dctx->litPtr = dctx->litBuffer;
|
||||||
|
dctx->litBufSize = ZSTD_BLOCKSIZE_ABSOLUTEMAX+8;
|
||||||
|
dctx->litSize = litSize;
|
||||||
|
return lhSize+litSize;
|
||||||
|
}
|
||||||
|
/* direct reference into compressed stream */
|
||||||
|
dctx->litPtr = istart+lhSize;
|
||||||
|
dctx->litBufSize = srcSize-lhSize;
|
||||||
dctx->litSize = litSize;
|
dctx->litSize = litSize;
|
||||||
return lhSize+litSize;
|
return lhSize+litSize;
|
||||||
}
|
}
|
||||||
/* direct reference into compressed stream */
|
|
||||||
dctx->litPtr = istart+lhSize;
|
case set_rle:
|
||||||
dctx->litBufSize = srcSize-lhSize;
|
{ U32 const lhlCode = ((istart[0]) >> 2) & 3;
|
||||||
dctx->litSize = litSize;
|
size_t litSize, lhSize;
|
||||||
return lhSize+litSize;
|
switch(lhlCode)
|
||||||
}
|
{
|
||||||
case lbt_rle:
|
case 0: case 2: default: /* note : default is impossible, since lhlCode into [0..3] */
|
||||||
{ size_t litSize;
|
lhSize = 1;
|
||||||
U32 lhSize = ((istart[0]) >> 4) & 3;
|
litSize = istart[0] >> 3;
|
||||||
switch(lhSize)
|
break;
|
||||||
{
|
case 1:
|
||||||
case 0: case 1: default: /* note : default is impossible, since lhSize into [0..3] */
|
lhSize = 2;
|
||||||
lhSize = 1;
|
litSize = MEM_readLE16(istart) >> 4;
|
||||||
litSize = istart[0] & 31;
|
break;
|
||||||
break;
|
case 3:
|
||||||
case 2:
|
lhSize = 3;
|
||||||
litSize = ((istart[0] & 15) << 8) + istart[1];
|
litSize = MEM_readLE24(istart) >> 4;
|
||||||
break;
|
if (srcSize<4) return ERROR(corruption_detected); /* srcSize >= MIN_CBLOCK_SIZE == 3; here we need lhSize+1 = 4 */
|
||||||
case 3:
|
break;
|
||||||
litSize = ((istart[0] & 15) << 16) + (istart[1] << 8) + istart[2];
|
}
|
||||||
if (srcSize<4) return ERROR(corruption_detected); /* srcSize >= MIN_CBLOCK_SIZE == 3; here we need lhSize+1 = 4 */
|
if (litSize > ZSTD_BLOCKSIZE_ABSOLUTEMAX) return ERROR(corruption_detected);
|
||||||
break;
|
memset(dctx->litBuffer, istart[lhSize], litSize);
|
||||||
|
dctx->litPtr = dctx->litBuffer;
|
||||||
|
dctx->litBufSize = ZSTD_BLOCKSIZE_ABSOLUTEMAX+WILDCOPY_OVERLENGTH;
|
||||||
|
dctx->litSize = litSize;
|
||||||
|
return lhSize+1;
|
||||||
}
|
}
|
||||||
if (litSize > ZSTD_BLOCKSIZE_MAX) return ERROR(corruption_detected);
|
default:
|
||||||
memset(dctx->litBuffer, istart[lhSize], litSize);
|
return ERROR(corruption_detected); /* impossible */
|
||||||
dctx->litPtr = dctx->litBuffer;
|
|
||||||
dctx->litBufSize = ZSTD_BLOCKSIZE_MAX+WILDCOPY_OVERLENGTH;
|
|
||||||
dctx->litSize = litSize;
|
|
||||||
return lhSize+1;
|
|
||||||
}
|
}
|
||||||
default:
|
|
||||||
return ERROR(corruption_detected); /* impossible */
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -596,25 +494,25 @@ size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx,
|
|||||||
@return : nb bytes read from src,
|
@return : nb bytes read from src,
|
||||||
or an error code if it fails, testable with ZSTD_isError()
|
or an error code if it fails, testable with ZSTD_isError()
|
||||||
*/
|
*/
|
||||||
FORCE_INLINE size_t ZSTD_buildSeqTable(FSE_DTable* DTable, U32 type, U32 max, U32 maxLog,
|
FORCE_INLINE size_t ZSTD_buildSeqTable(FSE_DTable* DTable, symbolEncodingType_e type, U32 max, U32 maxLog,
|
||||||
const void* src, size_t srcSize,
|
const void* src, size_t srcSize,
|
||||||
const S16* defaultNorm, U32 defaultLog, U32 flagRepeatTable)
|
const S16* defaultNorm, U32 defaultLog, U32 flagRepeatTable)
|
||||||
{
|
{
|
||||||
switch(type)
|
switch(type)
|
||||||
{
|
{
|
||||||
case FSE_ENCODING_RLE :
|
case set_rle :
|
||||||
if (!srcSize) return ERROR(srcSize_wrong);
|
if (!srcSize) return ERROR(srcSize_wrong);
|
||||||
if ( (*(const BYTE*)src) > max) return ERROR(corruption_detected);
|
if ( (*(const BYTE*)src) > max) return ERROR(corruption_detected);
|
||||||
FSE_buildDTable_rle(DTable, *(const BYTE*)src); /* if *src > max, data is corrupted */
|
FSE_buildDTable_rle(DTable, *(const BYTE*)src); /* if *src > max, data is corrupted */
|
||||||
return 1;
|
return 1;
|
||||||
case FSE_ENCODING_RAW :
|
case set_basic :
|
||||||
FSE_buildDTable(DTable, defaultNorm, max, defaultLog);
|
FSE_buildDTable(DTable, defaultNorm, max, defaultLog);
|
||||||
return 0;
|
return 0;
|
||||||
case FSE_ENCODING_STATIC:
|
case set_repeat:
|
||||||
if (!flagRepeatTable) return ERROR(corruption_detected);
|
if (!flagRepeatTable) return ERROR(corruption_detected);
|
||||||
return 0;
|
return 0;
|
||||||
default : /* impossible */
|
default : /* impossible */
|
||||||
case FSE_ENCODING_DYNAMIC :
|
case set_compressed :
|
||||||
{ U32 tableLog;
|
{ U32 tableLog;
|
||||||
S16 norm[MaxSeq+1];
|
S16 norm[MaxSeq+1];
|
||||||
size_t const headerSize = FSE_readNCount(norm, &max, &tableLog, src, srcSize);
|
size_t const headerSize = FSE_readNCount(norm, &max, &tableLog, src, srcSize);
|
||||||
@@ -650,14 +548,12 @@ size_t ZSTD_decodeSeqHeaders(int* nbSeqPtr,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* FSE table descriptors */
|
/* FSE table descriptors */
|
||||||
{ U32 const LLtype = *ip >> 6;
|
if (ip+4 > iend) return ERROR(srcSize_wrong); /* minimum possible size */
|
||||||
U32 const OFtype = (*ip >> 4) & 3;
|
{ symbolEncodingType_e const LLtype = (symbolEncodingType_e)(*ip >> 6);
|
||||||
U32 const MLtype = (*ip >> 2) & 3;
|
symbolEncodingType_e const OFtype = (symbolEncodingType_e)((*ip >> 4) & 3);
|
||||||
|
symbolEncodingType_e const MLtype = (symbolEncodingType_e)((*ip >> 2) & 3);
|
||||||
ip++;
|
ip++;
|
||||||
|
|
||||||
/* check */
|
|
||||||
if (ip > iend-3) return ERROR(srcSize_wrong); /* min : all 3 are "raw", hence no header, but at least xxLog bits per type */
|
|
||||||
|
|
||||||
/* Build DTables */
|
/* Build DTables */
|
||||||
{ size_t const llhSize = ZSTD_buildSeqTable(DTableLL, LLtype, MaxLL, LLFSELog, ip, iend-ip, LL_defaultNorm, LL_defaultNormLog, flagRepeatTable);
|
{ size_t const llhSize = ZSTD_buildSeqTable(DTableLL, LLtype, MaxLL, LLFSELog, ip, iend-ip, LL_defaultNorm, LL_defaultNormLog, flagRepeatTable);
|
||||||
if (ZSTD_isError(llhSize)) return ERROR(corruption_detected);
|
if (ZSTD_isError(llhSize)) return ERROR(corruption_detected);
|
||||||
@@ -687,7 +583,7 @@ typedef struct {
|
|||||||
FSE_DState_t stateLL;
|
FSE_DState_t stateLL;
|
||||||
FSE_DState_t stateOffb;
|
FSE_DState_t stateOffb;
|
||||||
FSE_DState_t stateML;
|
FSE_DState_t stateML;
|
||||||
size_t prevOffset[ZSTD_REP_INIT];
|
size_t prevOffset[ZSTD_REP_NUM];
|
||||||
} seqState_t;
|
} seqState_t;
|
||||||
|
|
||||||
|
|
||||||
@@ -731,9 +627,9 @@ static seq_t ZSTD_decodeSequence(seqState_t* seqState)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (ofCode <= 1) {
|
if (ofCode <= 1) {
|
||||||
if ((llCode == 0) & (offset <= 1)) offset = 1-offset;
|
offset += (llCode==0);
|
||||||
if (offset) {
|
if (offset) {
|
||||||
size_t const temp = seqState->prevOffset[offset];
|
size_t const temp = (offset==3) ? seqState->prevOffset[0] - 1 : seqState->prevOffset[offset];
|
||||||
if (offset != 1) seqState->prevOffset[2] = seqState->prevOffset[1];
|
if (offset != 1) seqState->prevOffset[2] = seqState->prevOffset[1];
|
||||||
seqState->prevOffset[1] = seqState->prevOffset[0];
|
seqState->prevOffset[1] = seqState->prevOffset[0];
|
||||||
seqState->prevOffset[0] = offset = temp;
|
seqState->prevOffset[0] = offset = temp;
|
||||||
@@ -774,7 +670,7 @@ size_t ZSTD_execSequence(BYTE* op,
|
|||||||
BYTE* const oLitEnd = op + sequence.litLength;
|
BYTE* const oLitEnd = op + sequence.litLength;
|
||||||
size_t const sequenceLength = sequence.litLength + sequence.matchLength;
|
size_t const sequenceLength = sequence.litLength + sequence.matchLength;
|
||||||
BYTE* const oMatchEnd = op + sequenceLength; /* risk : address space overflow (32-bits) */
|
BYTE* const oMatchEnd = op + sequenceLength; /* risk : address space overflow (32-bits) */
|
||||||
BYTE* const oend_w = oend-WILDCOPY_OVERLENGTH;
|
BYTE* const oend_w = oend - WILDCOPY_OVERLENGTH;
|
||||||
const BYTE* const iLitEnd = *litPtr + sequence.litLength;
|
const BYTE* const iLitEnd = *litPtr + sequence.litLength;
|
||||||
const BYTE* match = oLitEnd - sequence.offset;
|
const BYTE* match = oLitEnd - sequence.offset;
|
||||||
|
|
||||||
@@ -867,7 +763,7 @@ static size_t ZSTD_decompressSequences(
|
|||||||
if (nbSeq) {
|
if (nbSeq) {
|
||||||
seqState_t seqState;
|
seqState_t seqState;
|
||||||
dctx->fseEntropy = 1;
|
dctx->fseEntropy = 1;
|
||||||
{ U32 i; for (i=0; i<ZSTD_REP_INIT; i++) seqState.prevOffset[i] = dctx->rep[i]; }
|
{ U32 i; for (i=0; i<ZSTD_REP_NUM; i++) seqState.prevOffset[i] = dctx->rep[i]; }
|
||||||
{ size_t const errorCode = BIT_initDStream(&(seqState.DStream), ip, iend-ip);
|
{ size_t const errorCode = BIT_initDStream(&(seqState.DStream), ip, iend-ip);
|
||||||
if (ERR_isError(errorCode)) return ERROR(corruption_detected); }
|
if (ERR_isError(errorCode)) return ERROR(corruption_detected); }
|
||||||
FSE_initDState(&(seqState.stateLL), &(seqState.DStream), DTableLL);
|
FSE_initDState(&(seqState.stateLL), &(seqState.DStream), DTableLL);
|
||||||
@@ -885,12 +781,11 @@ static size_t ZSTD_decompressSequences(
|
|||||||
/* check if reached exact end */
|
/* check if reached exact end */
|
||||||
if (nbSeq) return ERROR(corruption_detected);
|
if (nbSeq) return ERROR(corruption_detected);
|
||||||
/* save reps for next block */
|
/* save reps for next block */
|
||||||
{ U32 i; for (i=0; i<ZSTD_REP_INIT; i++) dctx->rep[i] = (U32)(seqState.prevOffset[i]); }
|
{ U32 i; for (i=0; i<ZSTD_REP_NUM; i++) dctx->rep[i] = (U32)(seqState.prevOffset[i]); }
|
||||||
}
|
}
|
||||||
|
|
||||||
/* last literal segment */
|
/* last literal segment */
|
||||||
{ size_t const lastLLSize = litEnd - litPtr;
|
{ size_t const lastLLSize = litEnd - litPtr;
|
||||||
//if (litPtr > litEnd) return ERROR(corruption_detected); /* too many literals already used */
|
|
||||||
if (lastLLSize > (size_t)(oend-op)) return ERROR(dstSize_tooSmall);
|
if (lastLLSize > (size_t)(oend-op)) return ERROR(dstSize_tooSmall);
|
||||||
memcpy(op, litPtr, lastLLSize);
|
memcpy(op, litPtr, lastLLSize);
|
||||||
op += lastLLSize;
|
op += lastLLSize;
|
||||||
@@ -917,7 +812,7 @@ static size_t ZSTD_decompressBlock_internal(ZSTD_DCtx* dctx,
|
|||||||
{ /* blockType == blockCompressed */
|
{ /* blockType == blockCompressed */
|
||||||
const BYTE* ip = (const BYTE*)src;
|
const BYTE* ip = (const BYTE*)src;
|
||||||
|
|
||||||
if (srcSize >= ZSTD_BLOCKSIZE_MAX) return ERROR(srcSize_wrong);
|
if (srcSize >= ZSTD_BLOCKSIZE_ABSOLUTEMAX) return ERROR(srcSize_wrong);
|
||||||
|
|
||||||
/* Decode literals sub-block */
|
/* Decode literals sub-block */
|
||||||
{ size_t const litCSize = ZSTD_decodeLiteralsBlock(dctx, src, srcSize);
|
{ size_t const litCSize = ZSTD_decodeLiteralsBlock(dctx, src, srcSize);
|
||||||
@@ -966,7 +861,6 @@ static size_t ZSTD_decompressFrame(ZSTD_DCtx* dctx,
|
|||||||
const void* src, size_t srcSize)
|
const void* src, size_t srcSize)
|
||||||
{
|
{
|
||||||
const BYTE* ip = (const BYTE*)src;
|
const BYTE* ip = (const BYTE*)src;
|
||||||
const BYTE* const iend = ip + srcSize;
|
|
||||||
BYTE* const ostart = (BYTE* const)dst;
|
BYTE* const ostart = (BYTE* const)dst;
|
||||||
BYTE* const oend = ostart + dstCapacity;
|
BYTE* const oend = ostart + dstCapacity;
|
||||||
BYTE* op = ostart;
|
BYTE* op = ostart;
|
||||||
@@ -977,9 +871,11 @@ static size_t ZSTD_decompressFrame(ZSTD_DCtx* dctx,
|
|||||||
|
|
||||||
/* Frame Header */
|
/* Frame Header */
|
||||||
{ size_t const frameHeaderSize = ZSTD_frameHeaderSize(src, ZSTD_frameHeaderSize_min);
|
{ size_t const frameHeaderSize = ZSTD_frameHeaderSize(src, ZSTD_frameHeaderSize_min);
|
||||||
|
size_t result;
|
||||||
if (ZSTD_isError(frameHeaderSize)) return frameHeaderSize;
|
if (ZSTD_isError(frameHeaderSize)) return frameHeaderSize;
|
||||||
if (srcSize < frameHeaderSize+ZSTD_blockHeaderSize) return ERROR(srcSize_wrong);
|
if (srcSize < frameHeaderSize+ZSTD_blockHeaderSize) return ERROR(srcSize_wrong);
|
||||||
if (ZSTD_decodeFrameHeader(dctx, src, frameHeaderSize)) return ERROR(corruption_detected);
|
result = ZSTD_decodeFrameHeader(dctx, src, frameHeaderSize);
|
||||||
|
if (ZSTD_isError(result)) return result;
|
||||||
ip += frameHeaderSize; remainingSize -= frameHeaderSize;
|
ip += frameHeaderSize; remainingSize -= frameHeaderSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -987,7 +883,7 @@ static size_t ZSTD_decompressFrame(ZSTD_DCtx* dctx,
|
|||||||
while (1) {
|
while (1) {
|
||||||
size_t decodedSize;
|
size_t decodedSize;
|
||||||
blockProperties_t blockProperties;
|
blockProperties_t blockProperties;
|
||||||
size_t const cBlockSize = ZSTD_getcBlockSize(ip, iend-ip, &blockProperties);
|
size_t const cBlockSize = ZSTD_getcBlockSize(ip, remainingSize, &blockProperties);
|
||||||
if (ZSTD_isError(cBlockSize)) return cBlockSize;
|
if (ZSTD_isError(cBlockSize)) return cBlockSize;
|
||||||
|
|
||||||
ip += ZSTD_blockHeaderSize;
|
ip += ZSTD_blockHeaderSize;
|
||||||
@@ -1005,23 +901,29 @@ static size_t ZSTD_decompressFrame(ZSTD_DCtx* dctx,
|
|||||||
case bt_rle :
|
case bt_rle :
|
||||||
decodedSize = ZSTD_generateNxBytes(op, oend-op, *ip, blockProperties.origSize);
|
decodedSize = ZSTD_generateNxBytes(op, oend-op, *ip, blockProperties.origSize);
|
||||||
break;
|
break;
|
||||||
case bt_end :
|
case bt_reserved :
|
||||||
/* end of frame */
|
|
||||||
if (remainingSize) return ERROR(srcSize_wrong);
|
|
||||||
decodedSize = 0;
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
return ERROR(GENERIC); /* impossible */
|
return ERROR(corruption_detected);
|
||||||
}
|
}
|
||||||
if (cBlockSize == 0) break; /* bt_end */
|
|
||||||
|
|
||||||
if (ZSTD_isError(decodedSize)) return decodedSize;
|
if (ZSTD_isError(decodedSize)) return decodedSize;
|
||||||
if (dctx->fParams.checksumFlag) XXH64_update(&dctx->xxhState, op, decodedSize);
|
if (dctx->fParams.checksumFlag) XXH64_update(&dctx->xxhState, op, decodedSize);
|
||||||
op += decodedSize;
|
op += decodedSize;
|
||||||
ip += cBlockSize;
|
ip += cBlockSize;
|
||||||
remainingSize -= cBlockSize;
|
remainingSize -= cBlockSize;
|
||||||
|
if (blockProperties.lastBlock) break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (dctx->fParams.checksumFlag) { /* Frame content checksum verification */
|
||||||
|
U32 const checkCalc = (U32)XXH64_digest(&dctx->xxhState);
|
||||||
|
U32 checkRead;
|
||||||
|
if (remainingSize<4) return ERROR(checksum_wrong);
|
||||||
|
checkRead = MEM_readLE32(ip);
|
||||||
|
if (checkRead != checkCalc) return ERROR(checksum_wrong);
|
||||||
|
remainingSize -= 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (remainingSize) return ERROR(srcSize_wrong);
|
||||||
return op-ostart;
|
return op-ostart;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1077,18 +979,33 @@ size_t ZSTD_decompress(void* dst, size_t dstCapacity, const void* src, size_t sr
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*_******************************
|
/*-**********************************
|
||||||
* Streaming Decompression API
|
* Streaming Decompression API
|
||||||
********************************/
|
************************************/
|
||||||
size_t ZSTD_nextSrcSizeToDecompress(ZSTD_DCtx* dctx)
|
size_t ZSTD_nextSrcSizeToDecompress(ZSTD_DCtx* dctx) { return dctx->expected; }
|
||||||
{
|
|
||||||
return dctx->expected;
|
ZSTD_nextInputType_e ZSTD_nextInputType(ZSTD_DCtx* dctx) {
|
||||||
|
switch(dctx->stage)
|
||||||
|
{
|
||||||
|
default: /* should not happen */
|
||||||
|
case ZSTDds_getFrameHeaderSize:
|
||||||
|
case ZSTDds_decodeFrameHeader:
|
||||||
|
return ZSTDnit_frameHeader;
|
||||||
|
case ZSTDds_decodeBlockHeader:
|
||||||
|
return ZSTDnit_blockHeader;
|
||||||
|
case ZSTDds_decompressBlock:
|
||||||
|
return ZSTDnit_block;
|
||||||
|
case ZSTDds_decompressLastBlock:
|
||||||
|
return ZSTDnit_lastBlock;
|
||||||
|
case ZSTDds_checkChecksum:
|
||||||
|
return ZSTDnit_checksum;
|
||||||
|
case ZSTDds_decodeSkippableHeader:
|
||||||
|
case ZSTDds_skipFrame:
|
||||||
|
return ZSTDnit_skippableFrame;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int ZSTD_isSkipFrame(ZSTD_DCtx* dctx)
|
int ZSTD_isSkipFrame(ZSTD_DCtx* dctx) { return dctx->stage == ZSTDds_skipFrame; } /* for zbuff */
|
||||||
{
|
|
||||||
return dctx->stage == ZSTDds_skipFrame;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** ZSTD_decompressContinue() :
|
/** ZSTD_decompressContinue() :
|
||||||
* @return : nb of bytes generated into `dst` (necessarily <= `dstCapacity)
|
* @return : nb of bytes generated into `dst` (necessarily <= `dstCapacity)
|
||||||
@@ -1132,23 +1049,29 @@ size_t ZSTD_decompressContinue(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, c
|
|||||||
{ blockProperties_t bp;
|
{ blockProperties_t bp;
|
||||||
size_t const cBlockSize = ZSTD_getcBlockSize(src, ZSTD_blockHeaderSize, &bp);
|
size_t const cBlockSize = ZSTD_getcBlockSize(src, ZSTD_blockHeaderSize, &bp);
|
||||||
if (ZSTD_isError(cBlockSize)) return cBlockSize;
|
if (ZSTD_isError(cBlockSize)) return cBlockSize;
|
||||||
if (bp.blockType == bt_end) {
|
dctx->expected = cBlockSize;
|
||||||
|
dctx->bType = bp.blockType;
|
||||||
|
dctx->rleSize = bp.origSize;
|
||||||
|
if (cBlockSize) {
|
||||||
|
dctx->stage = bp.lastBlock ? ZSTDds_decompressLastBlock : ZSTDds_decompressBlock;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/* empty block */
|
||||||
|
if (bp.lastBlock) {
|
||||||
if (dctx->fParams.checksumFlag) {
|
if (dctx->fParams.checksumFlag) {
|
||||||
U64 const h64 = XXH64_digest(&dctx->xxhState);
|
dctx->expected = 4;
|
||||||
U32 const h32 = (U32)(h64>>11) & ((1<<22)-1);
|
dctx->stage = ZSTDds_checkChecksum;
|
||||||
const BYTE* const ip = (const BYTE*)src;
|
} else {
|
||||||
U32 const check32 = ip[2] + (ip[1] << 8) + ((ip[0] & 0x3F) << 16);
|
dctx->expected = 0; /* end of frame */
|
||||||
if (check32 != h32) return ERROR(checksum_wrong);
|
dctx->stage = ZSTDds_getFrameHeaderSize;
|
||||||
}
|
}
|
||||||
dctx->expected = 0;
|
|
||||||
dctx->stage = ZSTDds_getFrameHeaderSize;
|
|
||||||
} else {
|
} else {
|
||||||
dctx->expected = cBlockSize;
|
dctx->expected = 3; /* go directly to next header */
|
||||||
dctx->bType = bp.blockType;
|
dctx->stage = ZSTDds_decodeBlockHeader;
|
||||||
dctx->stage = ZSTDds_decompressBlock;
|
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
case ZSTDds_decompressLastBlock:
|
||||||
case ZSTDds_decompressBlock:
|
case ZSTDds_decompressBlock:
|
||||||
{ size_t rSize;
|
{ size_t rSize;
|
||||||
switch(dctx->bType)
|
switch(dctx->bType)
|
||||||
@@ -1160,21 +1083,38 @@ size_t ZSTD_decompressContinue(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, c
|
|||||||
rSize = ZSTD_copyRawBlock(dst, dstCapacity, src, srcSize);
|
rSize = ZSTD_copyRawBlock(dst, dstCapacity, src, srcSize);
|
||||||
break;
|
break;
|
||||||
case bt_rle :
|
case bt_rle :
|
||||||
return ERROR(GENERIC); /* not yet handled */
|
rSize = ZSTD_setRleBlock(dst, dstCapacity, src, srcSize, dctx->rleSize);
|
||||||
break;
|
|
||||||
case bt_end : /* should never happen (filtered at phase 1) */
|
|
||||||
rSize = 0;
|
|
||||||
break;
|
break;
|
||||||
|
case bt_reserved : /* should never happen */
|
||||||
default:
|
default:
|
||||||
return ERROR(GENERIC); /* impossible */
|
return ERROR(corruption_detected);
|
||||||
}
|
}
|
||||||
dctx->stage = ZSTDds_decodeBlockHeader;
|
|
||||||
dctx->expected = ZSTD_blockHeaderSize;
|
|
||||||
dctx->previousDstEnd = (char*)dst + rSize;
|
|
||||||
if (ZSTD_isError(rSize)) return rSize;
|
if (ZSTD_isError(rSize)) return rSize;
|
||||||
if (dctx->fParams.checksumFlag) XXH64_update(&dctx->xxhState, dst, rSize);
|
if (dctx->fParams.checksumFlag) XXH64_update(&dctx->xxhState, dst, rSize);
|
||||||
|
|
||||||
|
if (dctx->stage == ZSTDds_decompressLastBlock) { /* end of frame */
|
||||||
|
if (dctx->fParams.checksumFlag) { /* another round for frame checksum */
|
||||||
|
dctx->expected = 4;
|
||||||
|
dctx->stage = ZSTDds_checkChecksum;
|
||||||
|
} else {
|
||||||
|
dctx->expected = 0; /* ends here */
|
||||||
|
dctx->stage = ZSTDds_getFrameHeaderSize;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
dctx->stage = ZSTDds_decodeBlockHeader;
|
||||||
|
dctx->expected = ZSTD_blockHeaderSize;
|
||||||
|
dctx->previousDstEnd = (char*)dst + rSize;
|
||||||
|
}
|
||||||
return rSize;
|
return rSize;
|
||||||
}
|
}
|
||||||
|
case ZSTDds_checkChecksum:
|
||||||
|
{ U32 const h32 = (U32)XXH64_digest(&dctx->xxhState);
|
||||||
|
U32 const check32 = MEM_readLE32(src); /* srcSize == 4, guaranteed by dctx->expected */
|
||||||
|
if (check32 != h32) return ERROR(checksum_wrong);
|
||||||
|
dctx->expected = 0;
|
||||||
|
dctx->stage = ZSTDds_getFrameHeaderSize;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
case ZSTDds_decodeSkippableHeader:
|
case ZSTDds_decodeSkippableHeader:
|
||||||
{ memcpy(dctx->headerBuffer + ZSTD_frameHeaderSize_min, src, dctx->expected);
|
{ memcpy(dctx->headerBuffer + ZSTD_frameHeaderSize_min, src, dctx->expected);
|
||||||
dctx->expected = MEM_readLE32(dctx->headerBuffer + 4);
|
dctx->expected = MEM_readLE32(dctx->headerBuffer + 4);
|
||||||
|
|||||||
@@ -52,8 +52,9 @@
|
|||||||
* Common constants
|
* Common constants
|
||||||
***************************************/
|
***************************************/
|
||||||
#define ZSTD_OPT_DEBUG 0 /* 3 = compression stats; 5 = check encoded sequences; 9 = full logs */
|
#define ZSTD_OPT_DEBUG 0 /* 3 = compression stats; 5 = check encoded sequences; 9 = full logs */
|
||||||
#include <stdio.h>
|
|
||||||
#if defined(ZSTD_OPT_DEBUG) && ZSTD_OPT_DEBUG>=9
|
#if defined(ZSTD_OPT_DEBUG) && ZSTD_OPT_DEBUG>=9
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
#define ZSTD_LOG_PARSER(...) printf(__VA_ARGS__)
|
#define ZSTD_LOG_PARSER(...) printf(__VA_ARGS__)
|
||||||
#define ZSTD_LOG_ENCODE(...) printf(__VA_ARGS__)
|
#define ZSTD_LOG_ENCODE(...) printf(__VA_ARGS__)
|
||||||
#define ZSTD_LOG_BLOCK(...) printf(__VA_ARGS__)
|
#define ZSTD_LOG_BLOCK(...) printf(__VA_ARGS__)
|
||||||
@@ -64,10 +65,10 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define ZSTD_OPT_NUM (1<<12)
|
#define ZSTD_OPT_NUM (1<<12)
|
||||||
#define ZSTD_DICT_MAGIC 0xEC30A437 /* v0.7 */
|
#define ZSTD_DICT_MAGIC 0xEC30A437 /* v0.7+ */
|
||||||
|
|
||||||
#define ZSTD_REP_NUM 3
|
#define ZSTD_REP_NUM 3 /* number of repcodes */
|
||||||
#define ZSTD_REP_INIT ZSTD_REP_NUM
|
#define ZSTD_REP_CHECK (ZSTD_REP_NUM-0) /* number of repcodes to check by the optimal parser */
|
||||||
#define ZSTD_REP_MOVE (ZSTD_REP_NUM-1)
|
#define ZSTD_REP_MOVE (ZSTD_REP_NUM-1)
|
||||||
static const U32 repStartValue[ZSTD_REP_NUM] = { 1, 4, 8 };
|
static const U32 repStartValue[ZSTD_REP_NUM] = { 1, 4, 8 };
|
||||||
|
|
||||||
@@ -88,13 +89,13 @@ static const size_t ZSTD_did_fieldSize[4] = { 0, 1, 2, 4 };
|
|||||||
|
|
||||||
#define ZSTD_BLOCKHEADERSIZE 3 /* C standard doesn't allow `static const` variable to be init using another `static const` variable */
|
#define ZSTD_BLOCKHEADERSIZE 3 /* C standard doesn't allow `static const` variable to be init using another `static const` variable */
|
||||||
static const size_t ZSTD_blockHeaderSize = ZSTD_BLOCKHEADERSIZE;
|
static const size_t ZSTD_blockHeaderSize = ZSTD_BLOCKHEADERSIZE;
|
||||||
typedef enum { bt_compressed, bt_raw, bt_rle, bt_end } blockType_t;
|
typedef enum { bt_raw, bt_rle, bt_compressed, bt_reserved } blockType_e;
|
||||||
|
|
||||||
#define MIN_SEQUENCES_SIZE 1 /* nbSeq==0 */
|
#define MIN_SEQUENCES_SIZE 1 /* nbSeq==0 */
|
||||||
#define MIN_CBLOCK_SIZE (1 /*litCSize*/ + 1 /* RLE or RAW */ + MIN_SEQUENCES_SIZE /* nbSeq==0 */) /* for a non-null block */
|
#define MIN_CBLOCK_SIZE (1 /*litCSize*/ + 1 /* RLE or RAW */ + MIN_SEQUENCES_SIZE /* nbSeq==0 */) /* for a non-null block */
|
||||||
|
|
||||||
#define HufLog 12
|
#define HufLog 12
|
||||||
typedef enum { lbt_huffman, lbt_repeat, lbt_raw, lbt_rle } litBlockType_t;
|
typedef enum { set_basic, set_rle, set_compressed, set_repeat } symbolEncodingType_e;
|
||||||
|
|
||||||
#define LONGNBSEQ 0x7F00
|
#define LONGNBSEQ 0x7F00
|
||||||
|
|
||||||
@@ -111,11 +112,6 @@ typedef enum { lbt_huffman, lbt_repeat, lbt_raw, lbt_rle } litBlockType_t;
|
|||||||
#define LLFSELog 9
|
#define LLFSELog 9
|
||||||
#define OffFSELog 8
|
#define OffFSELog 8
|
||||||
|
|
||||||
#define FSE_ENCODING_RAW 0
|
|
||||||
#define FSE_ENCODING_RLE 1
|
|
||||||
#define FSE_ENCODING_STATIC 2
|
|
||||||
#define FSE_ENCODING_DYNAMIC 3
|
|
||||||
|
|
||||||
static const U32 LL_bits[MaxLL+1] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
static const U32 LL_bits[MaxLL+1] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
1, 1, 1, 1, 2, 2, 3, 3, 4, 6, 7, 8, 9,10,11,12,
|
1, 1, 1, 1, 2, 2, 3, 3, 4, 6, 7, 8, 9,10,11,12,
|
||||||
13,14,15,16 };
|
13,14,15,16 };
|
||||||
@@ -174,7 +170,7 @@ typedef struct {
|
|||||||
U32 off;
|
U32 off;
|
||||||
U32 mlen;
|
U32 mlen;
|
||||||
U32 litlen;
|
U32 litlen;
|
||||||
U32 rep[ZSTD_REP_INIT];
|
U32 rep[ZSTD_REP_NUM];
|
||||||
} ZSTD_optimal_t;
|
} ZSTD_optimal_t;
|
||||||
|
|
||||||
#if ZSTD_OPT_DEBUG == 3
|
#if ZSTD_OPT_DEBUG == 3
|
||||||
@@ -187,19 +183,22 @@ typedef struct {
|
|||||||
MEM_STATIC void ZSTD_statsUpdatePrices(ZSTD_stats_t* stats, size_t litLength, const BYTE* literals, size_t offset, size_t matchLength) { (void)stats; (void)litLength; (void)literals; (void)offset; (void)matchLength; }
|
MEM_STATIC void ZSTD_statsUpdatePrices(ZSTD_stats_t* stats, size_t litLength, const BYTE* literals, size_t offset, size_t matchLength) { (void)stats; (void)litLength; (void)literals; (void)offset; (void)matchLength; }
|
||||||
#endif /* #if ZSTD_OPT_DEBUG == 3 */
|
#endif /* #if ZSTD_OPT_DEBUG == 3 */
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct seqDef_s {
|
||||||
|
U32 offset;
|
||||||
|
U16 litLength;
|
||||||
|
U16 matchLength;
|
||||||
|
} seqDef;
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
void* buffer;
|
seqDef* sequencesStart;
|
||||||
U32* offsetStart;
|
seqDef* sequences;
|
||||||
U32* offset;
|
|
||||||
BYTE* offCodeStart;
|
|
||||||
BYTE* litStart;
|
BYTE* litStart;
|
||||||
BYTE* lit;
|
BYTE* lit;
|
||||||
U16* litLengthStart;
|
BYTE* llCode;
|
||||||
U16* litLength;
|
BYTE* mlCode;
|
||||||
BYTE* llCodeStart;
|
BYTE* ofCode;
|
||||||
U16* matchLengthStart;
|
|
||||||
U16* matchLength;
|
|
||||||
BYTE* mlCodeStart;
|
|
||||||
U32 longLengthID; /* 0 == no longLength; 1 == Lit.longLength; 2 == Match.longLength; */
|
U32 longLengthID; /* 0 == no longLength; 1 == Lit.longLength; 2 == Match.longLength; */
|
||||||
U32 longLengthPos;
|
U32 longLengthPos;
|
||||||
/* opt */
|
/* opt */
|
||||||
@@ -227,7 +226,7 @@ typedef struct {
|
|||||||
} seqStore_t;
|
} seqStore_t;
|
||||||
|
|
||||||
const seqStore_t* ZSTD_getSeqStore(const ZSTD_CCtx* ctx);
|
const seqStore_t* ZSTD_getSeqStore(const ZSTD_CCtx* ctx);
|
||||||
void ZSTD_seqToCodes(const seqStore_t* seqStorePtr, size_t const nbSeq);
|
void ZSTD_seqToCodes(const seqStore_t* seqStorePtr);
|
||||||
int ZSTD_isSkipFrame(ZSTD_DCtx* dctx);
|
int ZSTD_isSkipFrame(ZSTD_DCtx* dctx);
|
||||||
|
|
||||||
/* custom memory allocation functions */
|
/* custom memory allocation functions */
|
||||||
@@ -235,4 +234,29 @@ void* ZSTD_defaultAllocFunction(void* opaque, size_t size);
|
|||||||
void ZSTD_defaultFreeFunction(void* opaque, void* address);
|
void ZSTD_defaultFreeFunction(void* opaque, void* address);
|
||||||
static const ZSTD_customMem defaultCustomMem = { ZSTD_defaultAllocFunction, ZSTD_defaultFreeFunction, NULL };
|
static const ZSTD_customMem defaultCustomMem = { ZSTD_defaultAllocFunction, ZSTD_defaultFreeFunction, NULL };
|
||||||
|
|
||||||
|
/*====== common function ======*/
|
||||||
|
|
||||||
|
MEM_STATIC U32 ZSTD_highbit32(U32 val)
|
||||||
|
{
|
||||||
|
# if defined(_MSC_VER) /* Visual */
|
||||||
|
unsigned long r=0;
|
||||||
|
_BitScanReverse(&r, val);
|
||||||
|
return (unsigned)r;
|
||||||
|
# elif defined(__GNUC__) && (__GNUC__ >= 3) /* GCC Intrinsic */
|
||||||
|
return 31 - __builtin_clz(val);
|
||||||
|
# else /* Software version */
|
||||||
|
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 };
|
||||||
|
U32 v = val;
|
||||||
|
int r;
|
||||||
|
v |= v >> 1;
|
||||||
|
v |= v >> 2;
|
||||||
|
v |= v >> 4;
|
||||||
|
v |= v >> 8;
|
||||||
|
v |= v >> 16;
|
||||||
|
r = DeBruijnClz[(U32)(v * 0x07C4ACDDU) >> 27];
|
||||||
|
return r;
|
||||||
|
# endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif /* ZSTD_CCOMMON_H_MODULE */
|
#endif /* ZSTD_CCOMMON_H_MODULE */
|
||||||
|
|||||||
@@ -44,32 +44,65 @@ extern "C" {
|
|||||||
#include "error_private.h" /* ERROR */
|
#include "error_private.h" /* ERROR */
|
||||||
#include "zstd_v05.h"
|
#include "zstd_v05.h"
|
||||||
#include "zstd_v06.h"
|
#include "zstd_v06.h"
|
||||||
|
#include "zstd_v07.h"
|
||||||
|
|
||||||
|
|
||||||
/** ZSTD_isLegacy() :
|
/** ZSTD_isLegacy() :
|
||||||
@return : > 0 if supported by legacy decoder. 0 otherwise.
|
@return : > 0 if supported by legacy decoder. 0 otherwise.
|
||||||
return value is the version.
|
return value is the version.
|
||||||
*/
|
*/
|
||||||
MEM_STATIC unsigned ZSTD_isLegacy (U32 magicNumberLE)
|
MEM_STATIC unsigned ZSTD_isLegacy(const void* src, size_t srcSize)
|
||||||
{
|
{
|
||||||
|
U32 magicNumberLE;
|
||||||
|
if (srcSize<4) return 0;
|
||||||
|
magicNumberLE = MEM_readLE32(src);
|
||||||
switch(magicNumberLE)
|
switch(magicNumberLE)
|
||||||
{
|
{
|
||||||
case ZSTDv05_MAGICNUMBER : return 5;
|
case ZSTDv05_MAGICNUMBER : return 5;
|
||||||
case ZSTDv06_MAGICNUMBER : return 6;
|
case ZSTDv06_MAGICNUMBER : return 6;
|
||||||
|
case ZSTDv07_MAGICNUMBER : return 7;
|
||||||
default : return 0;
|
default : return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
MEM_STATIC unsigned long long ZSTD_getDecompressedSize_legacy(const void* src, size_t srcSize)
|
||||||
|
{
|
||||||
|
if (srcSize < 4) return 0;
|
||||||
|
|
||||||
|
{ U32 const version = ZSTD_isLegacy(src, srcSize);
|
||||||
|
if (version < 5) return 0; /* no decompressed size in frame header, or not a legacy format */
|
||||||
|
if (version==5) {
|
||||||
|
ZSTDv05_parameters fParams;
|
||||||
|
size_t const frResult = ZSTDv05_getFrameParams(&fParams, src, srcSize);
|
||||||
|
if (frResult != 0) return 0;
|
||||||
|
return fParams.srcSize;
|
||||||
|
}
|
||||||
|
if (version==6) {
|
||||||
|
ZSTDv06_frameParams fParams;
|
||||||
|
size_t const frResult = ZSTDv06_getFrameParams(&fParams, src, srcSize);
|
||||||
|
if (frResult != 0) return 0;
|
||||||
|
return fParams.frameContentSize;
|
||||||
|
}
|
||||||
|
if (version==7) {
|
||||||
|
ZSTDv07_frameParams fParams;
|
||||||
|
size_t const frResult = ZSTDv07_getFrameParams(&fParams, src, srcSize);
|
||||||
|
if (frResult != 0) return 0;
|
||||||
|
return fParams.frameContentSize;
|
||||||
|
}
|
||||||
|
return 0; /* should not be possible */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
MEM_STATIC size_t ZSTD_decompressLegacy(
|
MEM_STATIC size_t ZSTD_decompressLegacy(
|
||||||
void* dst, size_t dstCapacity,
|
void* dst, size_t dstCapacity,
|
||||||
const void* src, size_t compressedSize,
|
const void* src, size_t compressedSize,
|
||||||
const void* dict,size_t dictSize,
|
const void* dict,size_t dictSize)
|
||||||
U32 magicNumberLE)
|
|
||||||
{
|
{
|
||||||
switch(magicNumberLE)
|
U32 const version = ZSTD_isLegacy(src, compressedSize);
|
||||||
|
switch(version)
|
||||||
{
|
{
|
||||||
case ZSTDv05_MAGICNUMBER :
|
case 5 :
|
||||||
{ size_t result;
|
{ size_t result;
|
||||||
ZSTDv05_DCtx* const zd = ZSTDv05_createDCtx();
|
ZSTDv05_DCtx* const zd = ZSTDv05_createDCtx();
|
||||||
if (zd==NULL) return ERROR(memory_allocation);
|
if (zd==NULL) return ERROR(memory_allocation);
|
||||||
@@ -77,7 +110,7 @@ MEM_STATIC size_t ZSTD_decompressLegacy(
|
|||||||
ZSTDv05_freeDCtx(zd);
|
ZSTDv05_freeDCtx(zd);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
case ZSTDv06_MAGICNUMBER :
|
case 6 :
|
||||||
{ size_t result;
|
{ size_t result;
|
||||||
ZSTDv06_DCtx* const zd = ZSTDv06_createDCtx();
|
ZSTDv06_DCtx* const zd = ZSTDv06_createDCtx();
|
||||||
if (zd==NULL) return ERROR(memory_allocation);
|
if (zd==NULL) return ERROR(memory_allocation);
|
||||||
@@ -85,6 +118,14 @@ MEM_STATIC size_t ZSTD_decompressLegacy(
|
|||||||
ZSTDv06_freeDCtx(zd);
|
ZSTDv06_freeDCtx(zd);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
case 7 :
|
||||||
|
{ size_t result;
|
||||||
|
ZSTDv07_DCtx* const zd = ZSTDv07_createDCtx();
|
||||||
|
if (zd==NULL) return ERROR(memory_allocation);
|
||||||
|
result = ZSTDv07_decompress_usingDict(zd, dst, dstCapacity, src, compressedSize, dict, dictSize);
|
||||||
|
ZSTDv07_freeDCtx(zd);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
default :
|
default :
|
||||||
return ERROR(prefix_unknown);
|
return ERROR(prefix_unknown);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -134,15 +134,7 @@ FORCE_INLINE U32 ZSTD_getLiteralPrice(seqStore_t* ssPtr, U32 litLength, const BY
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* literal Length */
|
/* literal Length */
|
||||||
{ static const BYTE LL_Code[64] = { 0, 1, 2, 3, 4, 5, 6, 7,
|
{ const BYTE LL_deltaCode = 19;
|
||||||
8, 9, 10, 11, 12, 13, 14, 15,
|
|
||||||
16, 16, 17, 17, 18, 18, 19, 19,
|
|
||||||
20, 20, 20, 20, 21, 21, 21, 21,
|
|
||||||
22, 22, 22, 22, 22, 22, 22, 22,
|
|
||||||
23, 23, 23, 23, 23, 23, 23, 23,
|
|
||||||
24, 24, 24, 24, 24, 24, 24, 24,
|
|
||||||
24, 24, 24, 24, 24, 24, 24, 24 };
|
|
||||||
const BYTE LL_deltaCode = 19;
|
|
||||||
const BYTE llCode = (litLength>63) ? (BYTE)ZSTD_highbit32(litLength) + LL_deltaCode : LL_Code[litLength];
|
const BYTE llCode = (litLength>63) ? (BYTE)ZSTD_highbit32(litLength) + LL_deltaCode : LL_Code[litLength];
|
||||||
price += LL_bits[llCode] + ssPtr->log2litLengthSum - ZSTD_highbit32(ssPtr->litLengthFreq[llCode]+1);
|
price += LL_bits[llCode] + ssPtr->log2litLengthSum - ZSTD_highbit32(ssPtr->litLengthFreq[llCode]+1);
|
||||||
}
|
}
|
||||||
@@ -158,15 +150,7 @@ FORCE_INLINE U32 ZSTD_getPrice(seqStore_t* seqStorePtr, U32 litLength, const BYT
|
|||||||
U32 price = offCode + seqStorePtr->log2offCodeSum - ZSTD_highbit32(seqStorePtr->offCodeFreq[offCode]+1);
|
U32 price = offCode + seqStorePtr->log2offCodeSum - ZSTD_highbit32(seqStorePtr->offCodeFreq[offCode]+1);
|
||||||
|
|
||||||
/* match Length */
|
/* match Length */
|
||||||
{ static const BYTE ML_Code[128] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
|
{ const BYTE ML_deltaCode = 36;
|
||||||
16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
|
|
||||||
32, 32, 33, 33, 34, 34, 35, 35, 36, 36, 36, 36, 37, 37, 37, 37,
|
|
||||||
38, 38, 38, 38, 38, 38, 38, 38, 39, 39, 39, 39, 39, 39, 39, 39,
|
|
||||||
40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
|
|
||||||
41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
|
|
||||||
42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42,
|
|
||||||
42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42 };
|
|
||||||
const BYTE ML_deltaCode = 36;
|
|
||||||
const BYTE mlCode = (matchLength>127) ? (BYTE)ZSTD_highbit32(matchLength) + ML_deltaCode : ML_Code[matchLength];
|
const BYTE mlCode = (matchLength>127) ? (BYTE)ZSTD_highbit32(matchLength) + ML_deltaCode : ML_Code[matchLength];
|
||||||
price += ML_bits[mlCode] + seqStorePtr->log2matchLengthSum - ZSTD_highbit32(seqStorePtr->matchLengthFreq[mlCode]+1);
|
price += ML_bits[mlCode] + seqStorePtr->log2matchLengthSum - ZSTD_highbit32(seqStorePtr->matchLengthFreq[mlCode]+1);
|
||||||
}
|
}
|
||||||
@@ -185,15 +169,7 @@ MEM_STATIC void ZSTD_updatePrice(seqStore_t* seqStorePtr, U32 litLength, const B
|
|||||||
seqStorePtr->litFreq[literals[u]]++;
|
seqStorePtr->litFreq[literals[u]]++;
|
||||||
|
|
||||||
/* literal Length */
|
/* literal Length */
|
||||||
{ static const BYTE LL_Code[64] = { 0, 1, 2, 3, 4, 5, 6, 7,
|
{ const BYTE LL_deltaCode = 19;
|
||||||
8, 9, 10, 11, 12, 13, 14, 15,
|
|
||||||
16, 16, 17, 17, 18, 18, 19, 19,
|
|
||||||
20, 20, 20, 20, 21, 21, 21, 21,
|
|
||||||
22, 22, 22, 22, 22, 22, 22, 22,
|
|
||||||
23, 23, 23, 23, 23, 23, 23, 23,
|
|
||||||
24, 24, 24, 24, 24, 24, 24, 24,
|
|
||||||
24, 24, 24, 24, 24, 24, 24, 24 };
|
|
||||||
const BYTE LL_deltaCode = 19;
|
|
||||||
const BYTE llCode = (litLength>63) ? (BYTE)ZSTD_highbit32(litLength) + LL_deltaCode : LL_Code[litLength];
|
const BYTE llCode = (litLength>63) ? (BYTE)ZSTD_highbit32(litLength) + LL_deltaCode : LL_Code[litLength];
|
||||||
seqStorePtr->litLengthFreq[llCode]++;
|
seqStorePtr->litLengthFreq[llCode]++;
|
||||||
seqStorePtr->litLengthSum++;
|
seqStorePtr->litLengthSum++;
|
||||||
@@ -206,15 +182,7 @@ MEM_STATIC void ZSTD_updatePrice(seqStore_t* seqStorePtr, U32 litLength, const B
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* match Length */
|
/* match Length */
|
||||||
{ static const BYTE ML_Code[128] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
|
{ const BYTE ML_deltaCode = 36;
|
||||||
16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
|
|
||||||
32, 32, 33, 33, 34, 34, 35, 35, 36, 36, 36, 36, 37, 37, 37, 37,
|
|
||||||
38, 38, 38, 38, 38, 38, 38, 38, 39, 39, 39, 39, 39, 39, 39, 39,
|
|
||||||
40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
|
|
||||||
41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
|
|
||||||
42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42,
|
|
||||||
42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42 };
|
|
||||||
const BYTE ML_deltaCode = 36;
|
|
||||||
const BYTE mlCode = (matchLength>127) ? (BYTE)ZSTD_highbit32(matchLength) + ML_deltaCode : ML_Code[matchLength];
|
const BYTE mlCode = (matchLength>127) ? (BYTE)ZSTD_highbit32(matchLength) + ML_deltaCode : ML_Code[matchLength];
|
||||||
seqStorePtr->matchLengthFreq[mlCode]++;
|
seqStorePtr->matchLengthFreq[mlCode]++;
|
||||||
seqStorePtr->matchLengthSum++;
|
seqStorePtr->matchLengthSum++;
|
||||||
@@ -464,13 +432,14 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx,
|
|||||||
ZSTD_optimal_t* opt = seqStorePtr->priceTable;
|
ZSTD_optimal_t* opt = seqStorePtr->priceTable;
|
||||||
ZSTD_match_t* matches = seqStorePtr->matchTable;
|
ZSTD_match_t* matches = seqStorePtr->matchTable;
|
||||||
const BYTE* inr;
|
const BYTE* inr;
|
||||||
U32 offset, rep[ZSTD_REP_INIT];
|
U32 offset, rep[ZSTD_REP_NUM];
|
||||||
|
|
||||||
/* init */
|
/* init */
|
||||||
ctx->nextToUpdate3 = ctx->nextToUpdate;
|
ctx->nextToUpdate3 = ctx->nextToUpdate;
|
||||||
ZSTD_rescaleFreqs(seqStorePtr);
|
ZSTD_rescaleFreqs(seqStorePtr);
|
||||||
ip += (ip==prefixStart);
|
ip += (ip==prefixStart);
|
||||||
{ U32 i; for (i=0; i<ZSTD_REP_INIT; i++) rep[i]=ctx->rep[i]; }
|
{ U32 i; for (i=0; i<ZSTD_REP_NUM; i++) rep[i]=ctx->rep[i]; }
|
||||||
|
inr = ip;
|
||||||
|
|
||||||
ZSTD_LOG_BLOCK("%d: COMPBLOCK_OPT_GENERIC srcSz=%d maxSrch=%d mls=%d sufLen=%d\n", (int)(ip-base), (int)srcSize, maxSearches, mls, sufficient_len);
|
ZSTD_LOG_BLOCK("%d: COMPBLOCK_OPT_GENERIC srcSz=%d maxSrch=%d mls=%d sufLen=%d\n", (int)(ip-base), (int)srcSize, maxSearches, mls, sufficient_len);
|
||||||
|
|
||||||
@@ -484,7 +453,7 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx,
|
|||||||
|
|
||||||
/* check repCode */
|
/* check repCode */
|
||||||
{ U32 i;
|
{ U32 i;
|
||||||
for (i=0; i<ZSTD_REP_NUM; i++) {
|
for (i=(ip == anchor); i<ZSTD_REP_CHECK; i++) {
|
||||||
if ((rep[i]<(U32)(ip-prefixStart))
|
if ((rep[i]<(U32)(ip-prefixStart))
|
||||||
&& (MEM_readMINMATCH(ip, minMatch) == MEM_readMINMATCH(ip - rep[i], minMatch))) {
|
&& (MEM_readMINMATCH(ip, minMatch) == MEM_readMINMATCH(ip - rep[i], minMatch))) {
|
||||||
mlen = (U32)ZSTD_count(ip+minMatch, ip+minMatch-rep[i], iend) + minMatch;
|
mlen = (U32)ZSTD_count(ip+minMatch, ip+minMatch-rep[i], iend) + minMatch;
|
||||||
@@ -493,7 +462,7 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx,
|
|||||||
best_mlen = mlen; best_off = i; cur = 0; last_pos = 1;
|
best_mlen = mlen; best_off = i; cur = 0; last_pos = 1;
|
||||||
goto _storeSequence;
|
goto _storeSequence;
|
||||||
}
|
}
|
||||||
best_off = (i<=1 && ip == anchor) ? 1-i : i;
|
best_off = i - (ip == anchor);
|
||||||
do {
|
do {
|
||||||
price = ZSTD_getPrice(seqStorePtr, litlen, anchor, best_off, mlen - MINMATCH);
|
price = ZSTD_getPrice(seqStorePtr, litlen, anchor, best_off, mlen - MINMATCH);
|
||||||
if (mlen > last_pos || price < opt[mlen].price)
|
if (mlen > last_pos || price < opt[mlen].price)
|
||||||
@@ -531,7 +500,7 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx,
|
|||||||
if (last_pos < minMatch) { ip++; continue; }
|
if (last_pos < minMatch) { ip++; continue; }
|
||||||
|
|
||||||
/* initialize opt[0] */
|
/* initialize opt[0] */
|
||||||
{ U32 i ; for (i=0; i<ZSTD_REP_INIT; i++) opt[0].rep[i] = rep[i]; }
|
{ U32 i ; for (i=0; i<ZSTD_REP_NUM; i++) opt[0].rep[i] = rep[i]; }
|
||||||
opt[0].mlen = 1;
|
opt[0].mlen = 1;
|
||||||
opt[0].litlen = litlen;
|
opt[0].litlen = litlen;
|
||||||
|
|
||||||
@@ -575,19 +544,21 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx,
|
|||||||
|
|
||||||
best_mlen = minMatch;
|
best_mlen = minMatch;
|
||||||
{ U32 i;
|
{ U32 i;
|
||||||
for (i=0; i<ZSTD_REP_NUM; i++) {
|
for (i=(opt[cur].mlen != 1); i<ZSTD_REP_CHECK; i++) { /* check rep */
|
||||||
if ((opt[cur].rep[i]<(U32)(inr-prefixStart))
|
if ((opt[cur].rep[i]<(U32)(inr-prefixStart))
|
||||||
&& (MEM_readMINMATCH(inr, minMatch) == MEM_readMINMATCH(inr - opt[cur].rep[i], minMatch))) { /* check rep */
|
&& (MEM_readMINMATCH(inr, minMatch) == MEM_readMINMATCH(inr - opt[cur].rep[i], minMatch))) {
|
||||||
mlen = (U32)ZSTD_count(inr+minMatch, inr+minMatch - opt[cur].rep[i], iend) + minMatch;
|
mlen = (U32)ZSTD_count(inr+minMatch, inr+minMatch - opt[cur].rep[i], iend) + minMatch;
|
||||||
ZSTD_LOG_PARSER("%d: Found REP %d/%d mlen=%d off=%d rep=%d opt[%d].off=%d\n", (int)(inr-base), i, ZSTD_REP_NUM, mlen, i, opt[cur].rep[i], cur, opt[cur].off);
|
ZSTD_LOG_PARSER("%d: Found REP %d/%d mlen=%d off=%d rep=%d opt[%d].off=%d\n", (int)(inr-base), i, ZSTD_REP_NUM, mlen, i, opt[cur].rep[i], cur, opt[cur].off);
|
||||||
|
|
||||||
if (mlen > sufficient_len || cur + mlen >= ZSTD_OPT_NUM) {
|
if (mlen > sufficient_len || cur + mlen >= ZSTD_OPT_NUM) {
|
||||||
ZSTD_LOG_PARSER("%d: REP sufficient_len=%d best_mlen=%d best_off=%d last_pos=%d\n", (int)(inr-base), sufficient_len, best_mlen, best_off, last_pos);
|
|
||||||
best_mlen = mlen; best_off = i; last_pos = cur + 1;
|
best_mlen = mlen; best_off = i; last_pos = cur + 1;
|
||||||
|
ZSTD_LOG_PARSER("%d: REP sufficient_len=%d best_mlen=%d best_off=%d last_pos=%d\n", (int)(inr-base), sufficient_len, best_mlen, best_off, last_pos);
|
||||||
goto _storeSequence;
|
goto _storeSequence;
|
||||||
}
|
}
|
||||||
|
|
||||||
best_off = (i<=1 && opt[cur].mlen != 1) ? 1-i : i;
|
//best_off = ((i<=1) & (opt[cur].mlen != 1)) ? 1-i : i;
|
||||||
|
best_off = i - (opt[cur].mlen != 1);
|
||||||
|
|
||||||
if (opt[cur].mlen == 1) {
|
if (opt[cur].mlen == 1) {
|
||||||
litlen = opt[cur].litlen;
|
litlen = opt[cur].litlen;
|
||||||
if (cur > litlen) {
|
if (cur > litlen) {
|
||||||
@@ -692,7 +663,8 @@ _storeSequence: /* cur, last_pos, best_mlen, best_off have to be set */
|
|||||||
rep[1] = rep[0];
|
rep[1] = rep[0];
|
||||||
rep[0] = best_off;
|
rep[0] = best_off;
|
||||||
}
|
}
|
||||||
if (litLength == 0 && offset<=1) offset = 1-offset;
|
if ((litLength == 0) & (offset==0)) offset = rep[1]; /* protection, but should never happen */
|
||||||
|
if ((litLength == 0) & (offset<=2)) offset--;
|
||||||
}
|
}
|
||||||
|
|
||||||
ZSTD_LOG_ENCODE("%d/%d: ENCODE literals=%d mlen=%d off=%d rep[0]=%d rep[1]=%d\n", (int)(ip-base), (int)(iend-base), (int)(litLength), (int)mlen, (int)(offset), (int)rep[0], (int)rep[1]);
|
ZSTD_LOG_ENCODE("%d/%d: ENCODE literals=%d mlen=%d off=%d rep[0]=%d rep[1]=%d\n", (int)(ip-base), (int)(iend-base), (int)(litLength), (int)mlen, (int)(offset), (int)rep[0], (int)rep[1]);
|
||||||
@@ -755,12 +727,13 @@ void ZSTD_compressBlock_opt_extDict_generic(ZSTD_CCtx* ctx,
|
|||||||
const BYTE* inr;
|
const BYTE* inr;
|
||||||
|
|
||||||
/* init */
|
/* init */
|
||||||
U32 offset, rep[ZSTD_REP_INIT];
|
U32 offset, rep[ZSTD_REP_NUM];
|
||||||
{ U32 i; for (i=0; i<ZSTD_REP_INIT; i++) rep[i]=ctx->rep[i]; }
|
{ U32 i; for (i=0; i<ZSTD_REP_NUM; i++) rep[i]=ctx->rep[i]; }
|
||||||
|
|
||||||
ctx->nextToUpdate3 = ctx->nextToUpdate;
|
ctx->nextToUpdate3 = ctx->nextToUpdate;
|
||||||
ZSTD_rescaleFreqs(seqStorePtr);
|
ZSTD_rescaleFreqs(seqStorePtr);
|
||||||
ip += (ip==prefixStart);
|
ip += (ip==prefixStart);
|
||||||
|
inr = ip;
|
||||||
|
|
||||||
ZSTD_LOG_BLOCK("%d: COMPBLOCK_OPT_EXTDICT srcSz=%d maxSrch=%d mls=%d sufLen=%d\n", (int)(ip-base), (int)srcSize, maxSearches, mls, sufficient_len);
|
ZSTD_LOG_BLOCK("%d: COMPBLOCK_OPT_EXTDICT srcSz=%d maxSrch=%d mls=%d sufLen=%d\n", (int)(ip-base), (int)srcSize, maxSearches, mls, sufficient_len);
|
||||||
|
|
||||||
@@ -776,11 +749,12 @@ void ZSTD_compressBlock_opt_extDict_generic(ZSTD_CCtx* ctx,
|
|||||||
|
|
||||||
/* check repCode */
|
/* check repCode */
|
||||||
{ U32 i;
|
{ U32 i;
|
||||||
for (i=0; i<ZSTD_REP_NUM; i++) {
|
for (i = (ip==anchor); i<ZSTD_REP_CHECK; i++) {
|
||||||
const U32 repIndex = (U32)(current - rep[i]);
|
const U32 repIndex = (U32)(current - rep[i]);
|
||||||
const BYTE* const repBase = repIndex < dictLimit ? dictBase : base;
|
const BYTE* const repBase = repIndex < dictLimit ? dictBase : base;
|
||||||
const BYTE* const repMatch = repBase + repIndex;
|
const BYTE* const repMatch = repBase + repIndex;
|
||||||
if ( (((U32)((dictLimit-1) - repIndex) >= 3) & (repIndex>lowestIndex)) /* intentional overflow */
|
if ( (rep[i] <= current)
|
||||||
|
&& (((U32)((dictLimit-1) - repIndex) >= 3) & (repIndex>lowestIndex)) /* intentional overflow */
|
||||||
&& (MEM_readMINMATCH(ip, minMatch) == MEM_readMINMATCH(repMatch, minMatch)) ) {
|
&& (MEM_readMINMATCH(ip, minMatch) == MEM_readMINMATCH(repMatch, minMatch)) ) {
|
||||||
/* repcode detected we should take it */
|
/* repcode detected we should take it */
|
||||||
const BYTE* const repEnd = repIndex < dictLimit ? dictEnd : iend;
|
const BYTE* const repEnd = repIndex < dictLimit ? dictEnd : iend;
|
||||||
@@ -792,7 +766,7 @@ void ZSTD_compressBlock_opt_extDict_generic(ZSTD_CCtx* ctx,
|
|||||||
goto _storeSequence;
|
goto _storeSequence;
|
||||||
}
|
}
|
||||||
|
|
||||||
best_off = (i<=1 && ip == anchor) ? 1-i : i;
|
best_off = i - (ip==anchor);
|
||||||
litlen = opt[0].litlen;
|
litlen = opt[0].litlen;
|
||||||
do {
|
do {
|
||||||
price = ZSTD_getPrice(seqStorePtr, litlen, anchor, best_off, mlen - MINMATCH);
|
price = ZSTD_getPrice(seqStorePtr, litlen, anchor, best_off, mlen - MINMATCH);
|
||||||
@@ -807,7 +781,7 @@ void ZSTD_compressBlock_opt_extDict_generic(ZSTD_CCtx* ctx,
|
|||||||
ZSTD_LOG_PARSER("%d: match_num=%d last_pos=%d\n", (int)(ip-base), match_num, last_pos);
|
ZSTD_LOG_PARSER("%d: match_num=%d last_pos=%d\n", (int)(ip-base), match_num, last_pos);
|
||||||
if (!last_pos && !match_num) { ip++; continue; }
|
if (!last_pos && !match_num) { ip++; continue; }
|
||||||
|
|
||||||
{ U32 i; for (i=0; i<ZSTD_REP_INIT; i++) opt[0].rep[i] = rep[i]; }
|
{ U32 i; for (i=0; i<ZSTD_REP_NUM; i++) opt[0].rep[i] = rep[i]; }
|
||||||
opt[0].mlen = 1;
|
opt[0].mlen = 1;
|
||||||
|
|
||||||
if (match_num && (matches[match_num-1].len > sufficient_len || matches[match_num-1].len >= ZSTD_OPT_NUM)) {
|
if (match_num && (matches[match_num-1].len > sufficient_len || matches[match_num-1].len >= ZSTD_OPT_NUM)) {
|
||||||
@@ -878,11 +852,12 @@ void ZSTD_compressBlock_opt_extDict_generic(ZSTD_CCtx* ctx,
|
|||||||
best_mlen = 0;
|
best_mlen = 0;
|
||||||
|
|
||||||
{ U32 i;
|
{ U32 i;
|
||||||
for (i=0; i<ZSTD_REP_NUM; i++) {
|
for (i = (opt[cur].mlen != 1); i<ZSTD_REP_CHECK; i++) {
|
||||||
const U32 repIndex = (U32)(current+cur - opt[cur].rep[i]);
|
const U32 repIndex = (U32)(current+cur - opt[cur].rep[i]);
|
||||||
const BYTE* const repBase = repIndex < dictLimit ? dictBase : base;
|
const BYTE* const repBase = repIndex < dictLimit ? dictBase : base;
|
||||||
const BYTE* const repMatch = repBase + repIndex;
|
const BYTE* const repMatch = repBase + repIndex;
|
||||||
if ( (((U32)((dictLimit-1) - repIndex) >= 3) & (repIndex>lowestIndex)) /* intentional overflow */
|
if ( (opt[cur].rep[i] <= current+cur)
|
||||||
|
&& (((U32)((dictLimit-1) - repIndex) >= 3) & (repIndex>lowestIndex)) /* intentional overflow */
|
||||||
&& (MEM_readMINMATCH(inr, minMatch) == MEM_readMINMATCH(repMatch, minMatch)) ) {
|
&& (MEM_readMINMATCH(inr, minMatch) == MEM_readMINMATCH(repMatch, minMatch)) ) {
|
||||||
/* repcode detected */
|
/* repcode detected */
|
||||||
const BYTE* const repEnd = repIndex < dictLimit ? dictEnd : iend;
|
const BYTE* const repEnd = repIndex < dictLimit ? dictEnd : iend;
|
||||||
@@ -890,12 +865,12 @@ void ZSTD_compressBlock_opt_extDict_generic(ZSTD_CCtx* ctx,
|
|||||||
ZSTD_LOG_PARSER("%d: Found REP %d/%d mlen=%d off=%d rep=%d opt[%d].off=%d\n", (int)(inr-base), i, ZSTD_REP_NUM, mlen, i, opt[cur].rep[i], cur, opt[cur].off);
|
ZSTD_LOG_PARSER("%d: Found REP %d/%d mlen=%d off=%d rep=%d opt[%d].off=%d\n", (int)(inr-base), i, ZSTD_REP_NUM, mlen, i, opt[cur].rep[i], cur, opt[cur].off);
|
||||||
|
|
||||||
if (mlen > sufficient_len || cur + mlen >= ZSTD_OPT_NUM) {
|
if (mlen > sufficient_len || cur + mlen >= ZSTD_OPT_NUM) {
|
||||||
ZSTD_LOG_PARSER("%d: REP sufficient_len=%d best_mlen=%d best_off=%d last_pos=%d\n", (int)(inr-base), sufficient_len, best_mlen, best_off, last_pos);
|
|
||||||
best_mlen = mlen; best_off = i; last_pos = cur + 1;
|
best_mlen = mlen; best_off = i; last_pos = cur + 1;
|
||||||
|
ZSTD_LOG_PARSER("%d: REP sufficient_len=%d best_mlen=%d best_off=%d last_pos=%d\n", (int)(inr-base), sufficient_len, best_mlen, best_off, last_pos);
|
||||||
goto _storeSequence;
|
goto _storeSequence;
|
||||||
}
|
}
|
||||||
|
|
||||||
best_off = (i<=1 && opt[cur].mlen != 1) ? 1-i : i;
|
best_off = i - (opt[cur].mlen != 1);
|
||||||
if (opt[cur].mlen == 1) {
|
if (opt[cur].mlen == 1) {
|
||||||
litlen = opt[cur].litlen;
|
litlen = opt[cur].litlen;
|
||||||
if (cur > litlen) {
|
if (cur > litlen) {
|
||||||
@@ -1001,8 +976,9 @@ _storeSequence: /* cur, last_pos, best_mlen, best_off have to be set */
|
|||||||
if (offset != 1) rep[2] = rep[1];
|
if (offset != 1) rep[2] = rep[1];
|
||||||
rep[1] = rep[0];
|
rep[1] = rep[0];
|
||||||
rep[0] = best_off;
|
rep[0] = best_off;
|
||||||
}
|
}
|
||||||
if (litLength == 0 && offset<=1) offset = 1-offset;
|
if ((litLength==0) & (offset==0)) offset = rep[1]; /* protection, but should never happen */
|
||||||
|
if ((litLength==0) & (offset<=2)) offset --;
|
||||||
}
|
}
|
||||||
|
|
||||||
ZSTD_LOG_ENCODE("%d/%d: ENCODE literals=%d mlen=%d off=%d rep[0]=%d rep[1]=%d\n", (int)(ip-base), (int)(iend-base), (int)(litLength), (int)mlen, (int)(offset), (int)rep[0], (int)rep[1]);
|
ZSTD_LOG_ENCODE("%d/%d: ENCODE literals=%d mlen=%d off=%d rep[0]=%d rep[1]=%d\n", (int)(ip-base), (int)(iend-base), (int)(litLength), (int)mlen, (int)(offset), (int)rep[0], (int)rep[1]);
|
||||||
@@ -1016,7 +992,7 @@ _storeSequence: /* cur, last_pos, best_mlen, best_off have to be set */
|
|||||||
ml2 = ZSTD_count_2segments(ip, match, iend, dictEnd, prefixStart);
|
ml2 = ZSTD_count_2segments(ip, match, iend, dictEnd, prefixStart);
|
||||||
ZSTD_LOG_PARSER("%d: ZSTD_count_2segments=%d offset=%d dictBase=%p dictEnd=%p prefixStart=%p ip=%p match=%p\n", (int)current, (int)ml2, (int)best_off, dictBase, dictEnd, prefixStart, ip, match);
|
ZSTD_LOG_PARSER("%d: ZSTD_count_2segments=%d offset=%d dictBase=%p dictEnd=%p prefixStart=%p ip=%p match=%p\n", (int)current, (int)ml2, (int)best_off, dictBase, dictEnd, prefixStart, ip, match);
|
||||||
}
|
}
|
||||||
else ml2 = (U32)ZSTD_count(ip, ip-offset, iend);
|
else ml2 = (U32)ZSTD_count(ip, ip-best_off, iend);
|
||||||
}
|
}
|
||||||
else ml2 = (U32)ZSTD_count(ip, ip-rep[0], iend);
|
else ml2 = (U32)ZSTD_count(ip, ip-rep[0], iend);
|
||||||
if ((offset >= 8) && (ml2 < mlen || ml2 < minMatch)) {
|
if ((offset >= 8) && (ml2 < mlen || ml2 < minMatch)) {
|
||||||
@@ -1033,7 +1009,7 @@ _storeSequence: /* cur, last_pos, best_mlen, best_off have to be set */
|
|||||||
} } /* for (cur=0; cur < last_pos; ) */
|
} } /* for (cur=0; cur < last_pos; ) */
|
||||||
|
|
||||||
/* Save reps for next block */
|
/* Save reps for next block */
|
||||||
ctx->savedRep[0] = rep[0]; ctx->savedRep[1] = rep[1]; ctx->savedRep[2] = rep[2];
|
{ int i; for (i=0; i<ZSTD_REP_NUM; i++) ctx->savedRep[i] = rep[i]; }
|
||||||
|
|
||||||
/* Last Literals */
|
/* Last Literals */
|
||||||
{ size_t lastLLSize = iend - anchor;
|
{ size_t lastLLSize = iend - anchor;
|
||||||
|
|||||||
@@ -436,21 +436,6 @@ extern "C" {
|
|||||||
***************************************/
|
***************************************/
|
||||||
#define ZSTDv05_WINDOWLOG_ABSOLUTEMIN 11
|
#define ZSTDv05_WINDOWLOG_ABSOLUTEMIN 11
|
||||||
|
|
||||||
/* from faster to stronger */
|
|
||||||
typedef enum { ZSTDv05_fast, ZSTDv05_greedy, ZSTDv05_lazy, ZSTDv05_lazy2, ZSTDv05_btlazy2, ZSTDv05_opt, ZSTDv05_btopt } ZSTDv05_strategy;
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
U64 srcSize; /* optional : tells how much bytes are present in the frame. Use 0 if not known. */
|
|
||||||
U32 windowLog; /* largest match distance : larger == more compression, more memory needed during decompression */
|
|
||||||
U32 contentLog; /* full search segment : larger == more compression, slower, more memory (useless for fast) */
|
|
||||||
U32 hashLog; /* dispatch table : larger == faster, more memory */
|
|
||||||
U32 searchLog; /* nb of searches : larger == more compression, slower */
|
|
||||||
U32 searchLength; /* match length searched : larger == faster decompression, sometimes less compression */
|
|
||||||
U32 targetLength; /* acceptable match size for optimal parser (only) : larger == more compression, slower */
|
|
||||||
ZSTDv05_strategy strategy;
|
|
||||||
} ZSTDv05_parameters;
|
|
||||||
|
|
||||||
|
|
||||||
/*-*************************************
|
/*-*************************************
|
||||||
* Advanced functions
|
* Advanced functions
|
||||||
@@ -2023,7 +2008,6 @@ extern "C" {
|
|||||||
******************************************/
|
******************************************/
|
||||||
size_t HUFv05_decompress4X2 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); /* single-symbol decoder */
|
size_t HUFv05_decompress4X2 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); /* single-symbol decoder */
|
||||||
size_t HUFv05_decompress4X4 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); /* double-symbols decoder */
|
size_t HUFv05_decompress4X4 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); /* double-symbols decoder */
|
||||||
size_t HUFv05_decompress4X6 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); /* quad-symbols decoder */
|
|
||||||
|
|
||||||
|
|
||||||
/* ****************************************
|
/* ****************************************
|
||||||
@@ -2037,22 +2021,18 @@ HUFv05_decompress() does the following:
|
|||||||
*/
|
*/
|
||||||
size_t HUFv05_readDTableX2 (unsigned short* DTable, const void* src, size_t srcSize);
|
size_t HUFv05_readDTableX2 (unsigned short* DTable, const void* src, size_t srcSize);
|
||||||
size_t HUFv05_readDTableX4 (unsigned* DTable, const void* src, size_t srcSize);
|
size_t HUFv05_readDTableX4 (unsigned* DTable, const void* src, size_t srcSize);
|
||||||
size_t HUFv05_readDTableX6 (unsigned* DTable, const void* src, size_t srcSize);
|
|
||||||
|
|
||||||
size_t HUFv05_decompress4X2_usingDTable(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const unsigned short* DTable);
|
size_t HUFv05_decompress4X2_usingDTable(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const unsigned short* DTable);
|
||||||
size_t HUFv05_decompress4X4_usingDTable(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const unsigned* DTable);
|
size_t HUFv05_decompress4X4_usingDTable(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const unsigned* DTable);
|
||||||
size_t HUFv05_decompress4X6_usingDTable(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const unsigned* DTable);
|
|
||||||
|
|
||||||
|
|
||||||
/* single stream variants */
|
/* single stream variants */
|
||||||
|
|
||||||
size_t HUFv05_decompress1X2 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); /* single-symbol decoder */
|
size_t HUFv05_decompress1X2 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); /* single-symbol decoder */
|
||||||
size_t HUFv05_decompress1X4 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); /* double-symbol decoder */
|
size_t HUFv05_decompress1X4 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); /* double-symbol decoder */
|
||||||
size_t HUFv05_decompress1X6 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); /* quad-symbol decoder */
|
|
||||||
|
|
||||||
size_t HUFv05_decompress1X2_usingDTable(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const unsigned short* DTable);
|
size_t HUFv05_decompress1X2_usingDTable(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const unsigned short* DTable);
|
||||||
size_t HUFv05_decompress1X4_usingDTable(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const unsigned* DTable);
|
size_t HUFv05_decompress1X4_usingDTable(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const unsigned* DTable);
|
||||||
size_t HUFv05_decompress1X6_usingDTable(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const unsigned* DTable);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -2372,9 +2352,6 @@ size_t HUFv05_decompress4X2_usingDTable(
|
|||||||
const U32 dtLog = DTable[0];
|
const U32 dtLog = DTable[0];
|
||||||
size_t errorCode;
|
size_t errorCode;
|
||||||
|
|
||||||
/* Check */
|
|
||||||
if (cSrcSize < 10) return ERROR(corruption_detected); /* strict minimum : jump table + 1 byte per stream */
|
|
||||||
|
|
||||||
/* Init */
|
/* Init */
|
||||||
BITv05_DStream_t bitD1;
|
BITv05_DStream_t bitD1;
|
||||||
BITv05_DStream_t bitD2;
|
BITv05_DStream_t bitD2;
|
||||||
@@ -2398,6 +2375,9 @@ size_t HUFv05_decompress4X2_usingDTable(
|
|||||||
BYTE* op4 = opStart4;
|
BYTE* op4 = opStart4;
|
||||||
U32 endSignal;
|
U32 endSignal;
|
||||||
|
|
||||||
|
/* Check */
|
||||||
|
if (cSrcSize < 10) return ERROR(corruption_detected); /* strict minimum : jump table + 1 byte per stream */
|
||||||
|
|
||||||
length4 = cSrcSize - (length1 + length2 + length3 + 6);
|
length4 = cSrcSize - (length1 + length2 + length3 + 6);
|
||||||
if (length4 > cSrcSize) return ERROR(corruption_detected); /* overflow */
|
if (length4 > cSrcSize) return ERROR(corruption_detected); /* overflow */
|
||||||
errorCode = BITv05_initDStream(&bitD1, istart1, length1);
|
errorCode = BITv05_initDStream(&bitD1, istart1, length1);
|
||||||
@@ -2850,376 +2830,6 @@ size_t HUFv05_decompress4X4 (void* dst, size_t dstSize, const void* cSrc, size_t
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ********************************/
|
|
||||||
/* quad-symbol decoding */
|
|
||||||
/* ********************************/
|
|
||||||
typedef struct { BYTE nbBits; BYTE nbBytes; } HUFv05_DDescX6;
|
|
||||||
typedef union { BYTE byte[4]; U32 sequence; } HUFv05_DSeqX6;
|
|
||||||
|
|
||||||
/* recursive, up to level 3; may benefit from <template>-like strategy to nest each level inline */
|
|
||||||
static void HUFv05_fillDTableX6LevelN(HUFv05_DDescX6* DDescription, HUFv05_DSeqX6* DSequence, int sizeLog,
|
|
||||||
const rankVal_t rankValOrigin, const U32 consumed, const int minWeight, const U32 maxWeight,
|
|
||||||
const sortedSymbol_t* sortedSymbols, const U32 sortedListSize, const U32* rankStart,
|
|
||||||
const U32 nbBitsBaseline, HUFv05_DSeqX6 baseSeq, HUFv05_DDescX6 DDesc)
|
|
||||||
{
|
|
||||||
const int scaleLog = nbBitsBaseline - sizeLog; /* note : targetLog >= (nbBitsBaseline-1), hence scaleLog <= 1 */
|
|
||||||
const int minBits = nbBitsBaseline - maxWeight;
|
|
||||||
const U32 level = DDesc.nbBytes;
|
|
||||||
U32 rankVal[HUFv05_ABSOLUTEMAX_TABLELOG + 1];
|
|
||||||
U32 symbolStartPos, s;
|
|
||||||
|
|
||||||
/* local rankVal, will be modified */
|
|
||||||
memcpy(rankVal, rankValOrigin[consumed], sizeof(rankVal));
|
|
||||||
|
|
||||||
/* fill skipped values */
|
|
||||||
if (minWeight>1) {
|
|
||||||
U32 i;
|
|
||||||
const U32 skipSize = rankVal[minWeight];
|
|
||||||
for (i = 0; i < skipSize; i++) {
|
|
||||||
DSequence[i] = baseSeq;
|
|
||||||
DDescription[i] = DDesc;
|
|
||||||
} }
|
|
||||||
|
|
||||||
/* fill DTable */
|
|
||||||
DDesc.nbBytes++;
|
|
||||||
symbolStartPos = rankStart[minWeight];
|
|
||||||
for (s=symbolStartPos; s<sortedListSize; s++) {
|
|
||||||
const BYTE symbol = sortedSymbols[s].symbol;
|
|
||||||
const U32 weight = sortedSymbols[s].weight; /* >= 1 (sorted) */
|
|
||||||
const int nbBits = nbBitsBaseline - weight; /* >= 1 (by construction) */
|
|
||||||
const int totalBits = consumed+nbBits;
|
|
||||||
const U32 start = rankVal[weight];
|
|
||||||
const U32 length = 1 << (sizeLog-nbBits);
|
|
||||||
baseSeq.byte[level] = symbol;
|
|
||||||
DDesc.nbBits = (BYTE)totalBits;
|
|
||||||
|
|
||||||
if ((level<3) && (sizeLog-totalBits >= minBits)) { /* enough room for another symbol */
|
|
||||||
int nextMinWeight = totalBits + scaleLog;
|
|
||||||
if (nextMinWeight < 1) nextMinWeight = 1;
|
|
||||||
HUFv05_fillDTableX6LevelN(DDescription+start, DSequence+start, sizeLog-nbBits,
|
|
||||||
rankValOrigin, totalBits, nextMinWeight, maxWeight,
|
|
||||||
sortedSymbols, sortedListSize, rankStart,
|
|
||||||
nbBitsBaseline, baseSeq, DDesc); /* recursive (max : level 3) */
|
|
||||||
} else {
|
|
||||||
U32 i;
|
|
||||||
const U32 end = start + length;
|
|
||||||
for (i = start; i < end; i++) {
|
|
||||||
DDescription[i] = DDesc;
|
|
||||||
DSequence[i] = baseSeq;
|
|
||||||
} }
|
|
||||||
rankVal[weight] += length;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* note : same preparation as X4 */
|
|
||||||
size_t HUFv05_readDTableX6 (U32* DTable, const void* src, size_t srcSize)
|
|
||||||
{
|
|
||||||
BYTE weightList[HUFv05_MAX_SYMBOL_VALUE + 1];
|
|
||||||
sortedSymbol_t sortedSymbol[HUFv05_MAX_SYMBOL_VALUE + 1];
|
|
||||||
U32 rankStats[HUFv05_ABSOLUTEMAX_TABLELOG + 1] = { 0 };
|
|
||||||
U32 rankStart0[HUFv05_ABSOLUTEMAX_TABLELOG + 2] = { 0 };
|
|
||||||
U32* const rankStart = rankStart0+1;
|
|
||||||
U32 tableLog, maxW, sizeOfSort, nbSymbols;
|
|
||||||
rankVal_t rankVal;
|
|
||||||
const U32 memLog = DTable[0];
|
|
||||||
size_t iSize;
|
|
||||||
|
|
||||||
if (memLog > HUFv05_ABSOLUTEMAX_TABLELOG) return ERROR(tableLog_tooLarge);
|
|
||||||
//memset(weightList, 0, sizeof(weightList)); /* is not necessary, even though some analyzer complain ... */
|
|
||||||
|
|
||||||
iSize = HUFv05_readStats(weightList, HUFv05_MAX_SYMBOL_VALUE + 1, rankStats, &nbSymbols, &tableLog, src, srcSize);
|
|
||||||
if (HUFv05_isError(iSize)) return iSize;
|
|
||||||
|
|
||||||
/* check result */
|
|
||||||
if (tableLog > memLog) return ERROR(tableLog_tooLarge); /* DTable is too small */
|
|
||||||
|
|
||||||
/* find maxWeight */
|
|
||||||
for (maxW = tableLog; rankStats[maxW]==0; maxW--) {} /* necessarily finds a solution before 0 */
|
|
||||||
|
|
||||||
/* Get start index of each weight */
|
|
||||||
{
|
|
||||||
U32 w, nextRankStart = 0;
|
|
||||||
for (w=1; w<=maxW; w++) {
|
|
||||||
U32 current = nextRankStart;
|
|
||||||
nextRankStart += rankStats[w];
|
|
||||||
rankStart[w] = current;
|
|
||||||
}
|
|
||||||
rankStart[0] = nextRankStart; /* put all 0w symbols at the end of sorted list*/
|
|
||||||
sizeOfSort = nextRankStart;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* sort symbols by weight */
|
|
||||||
{
|
|
||||||
U32 s;
|
|
||||||
for (s=0; s<nbSymbols; s++) {
|
|
||||||
U32 w = weightList[s];
|
|
||||||
U32 r = rankStart[w]++;
|
|
||||||
sortedSymbol[r].symbol = (BYTE)s;
|
|
||||||
sortedSymbol[r].weight = (BYTE)w;
|
|
||||||
}
|
|
||||||
rankStart[0] = 0; /* forget 0w symbols; this is beginning of weight(1) */
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Build rankVal */
|
|
||||||
{
|
|
||||||
const U32 minBits = tableLog+1 - maxW;
|
|
||||||
U32 nextRankVal = 0;
|
|
||||||
U32 w, consumed;
|
|
||||||
const int rescale = (memLog-tableLog) - 1; /* tableLog <= memLog */
|
|
||||||
U32* rankVal0 = rankVal[0];
|
|
||||||
for (w=1; w<=maxW; w++) {
|
|
||||||
U32 current = nextRankVal;
|
|
||||||
nextRankVal += rankStats[w] << (w+rescale);
|
|
||||||
rankVal0[w] = current;
|
|
||||||
}
|
|
||||||
for (consumed = minBits; consumed <= memLog - minBits; consumed++) {
|
|
||||||
U32* rankValPtr = rankVal[consumed];
|
|
||||||
for (w = 1; w <= maxW; w++) {
|
|
||||||
rankValPtr[w] = rankVal0[w] >> consumed;
|
|
||||||
} } }
|
|
||||||
|
|
||||||
/* fill tables */
|
|
||||||
{
|
|
||||||
void* ddPtr = DTable+1;
|
|
||||||
HUFv05_DDescX6* DDescription = (HUFv05_DDescX6*)ddPtr;
|
|
||||||
void* dsPtr = DTable + 1 + ((size_t)1<<(memLog-1));
|
|
||||||
HUFv05_DSeqX6* DSequence = (HUFv05_DSeqX6*)dsPtr;
|
|
||||||
HUFv05_DSeqX6 DSeq;
|
|
||||||
HUFv05_DDescX6 DDesc;
|
|
||||||
DSeq.sequence = 0;
|
|
||||||
DDesc.nbBits = 0;
|
|
||||||
DDesc.nbBytes = 0;
|
|
||||||
HUFv05_fillDTableX6LevelN(DDescription, DSequence, memLog,
|
|
||||||
(const U32 (*)[HUFv05_ABSOLUTEMAX_TABLELOG + 1])rankVal, 0, 1, maxW,
|
|
||||||
sortedSymbol, sizeOfSort, rankStart0,
|
|
||||||
tableLog+1, DSeq, DDesc);
|
|
||||||
}
|
|
||||||
|
|
||||||
return iSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static U32 HUFv05_decodeSymbolX6(void* op, BITv05_DStream_t* DStream, const HUFv05_DDescX6* dd, const HUFv05_DSeqX6* ds, const U32 dtLog)
|
|
||||||
{
|
|
||||||
const size_t val = BITv05_lookBitsFast(DStream, dtLog); /* note : dtLog >= 1 */
|
|
||||||
memcpy(op, ds+val, sizeof(HUFv05_DSeqX6));
|
|
||||||
BITv05_skipBits(DStream, dd[val].nbBits);
|
|
||||||
return dd[val].nbBytes;
|
|
||||||
}
|
|
||||||
|
|
||||||
static U32 HUFv05_decodeLastSymbolsX6(void* op, const U32 maxL, BITv05_DStream_t* DStream,
|
|
||||||
const HUFv05_DDescX6* dd, const HUFv05_DSeqX6* ds, const U32 dtLog)
|
|
||||||
{
|
|
||||||
const size_t val = BITv05_lookBitsFast(DStream, dtLog); /* note : dtLog >= 1 */
|
|
||||||
U32 length = dd[val].nbBytes;
|
|
||||||
if (length <= maxL) {
|
|
||||||
memcpy(op, ds+val, length);
|
|
||||||
BITv05_skipBits(DStream, dd[val].nbBits);
|
|
||||||
return length;
|
|
||||||
}
|
|
||||||
memcpy(op, ds+val, maxL);
|
|
||||||
if (DStream->bitsConsumed < (sizeof(DStream->bitContainer)*8)) {
|
|
||||||
BITv05_skipBits(DStream, dd[val].nbBits);
|
|
||||||
if (DStream->bitsConsumed > (sizeof(DStream->bitContainer)*8))
|
|
||||||
DStream->bitsConsumed = (sizeof(DStream->bitContainer)*8); /* ugly hack; works only because it's the last symbol. Note : can't easily extract nbBits from just this symbol */
|
|
||||||
}
|
|
||||||
return maxL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#define HUFv05_DECODE_SYMBOLX6_0(ptr, DStreamPtr) \
|
|
||||||
ptr += HUFv05_decodeSymbolX6(ptr, DStreamPtr, dd, ds, dtLog)
|
|
||||||
|
|
||||||
#define HUFv05_DECODE_SYMBOLX6_1(ptr, DStreamPtr) \
|
|
||||||
if (MEM_64bits() || (HUFv05_MAX_TABLELOG<=12)) \
|
|
||||||
HUFv05_DECODE_SYMBOLX6_0(ptr, DStreamPtr)
|
|
||||||
|
|
||||||
#define HUFv05_DECODE_SYMBOLX6_2(ptr, DStreamPtr) \
|
|
||||||
if (MEM_64bits()) \
|
|
||||||
HUFv05_DECODE_SYMBOLX6_0(ptr, DStreamPtr)
|
|
||||||
|
|
||||||
static inline size_t HUFv05_decodeStreamX6(BYTE* p, BITv05_DStream_t* bitDPtr, BYTE* const pEnd, const U32* DTable, const U32 dtLog)
|
|
||||||
{
|
|
||||||
const void* const ddPtr = DTable+1;
|
|
||||||
const HUFv05_DDescX6* dd = (const HUFv05_DDescX6*)ddPtr;
|
|
||||||
const void* const dsPtr = DTable + 1 + ((size_t)1<<(dtLog-1));
|
|
||||||
const HUFv05_DSeqX6* ds = (const HUFv05_DSeqX6*)dsPtr;
|
|
||||||
BYTE* const pStart = p;
|
|
||||||
|
|
||||||
/* up to 16 symbols at a time */
|
|
||||||
while ((BITv05_reloadDStream(bitDPtr) == BITv05_DStream_unfinished) && (p <= pEnd-16)) {
|
|
||||||
HUFv05_DECODE_SYMBOLX6_2(p, bitDPtr);
|
|
||||||
HUFv05_DECODE_SYMBOLX6_1(p, bitDPtr);
|
|
||||||
HUFv05_DECODE_SYMBOLX6_2(p, bitDPtr);
|
|
||||||
HUFv05_DECODE_SYMBOLX6_0(p, bitDPtr);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* closer to the end, up to 4 symbols at a time */
|
|
||||||
while ((BITv05_reloadDStream(bitDPtr) == BITv05_DStream_unfinished) && (p <= pEnd-4))
|
|
||||||
HUFv05_DECODE_SYMBOLX6_0(p, bitDPtr);
|
|
||||||
|
|
||||||
while ((BITv05_reloadDStream(bitDPtr) <= BITv05_DStream_endOfBuffer) && (p < pEnd))
|
|
||||||
p += HUFv05_decodeLastSymbolsX6(p, (U32)(pEnd-p), bitDPtr, dd, ds, dtLog);
|
|
||||||
|
|
||||||
return p-pStart;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
size_t HUFv05_decompress1X6_usingDTable(
|
|
||||||
void* dst, size_t dstSize,
|
|
||||||
const void* cSrc, size_t cSrcSize,
|
|
||||||
const U32* DTable)
|
|
||||||
{
|
|
||||||
const BYTE* const istart = (const BYTE*) cSrc;
|
|
||||||
BYTE* const ostart = (BYTE*) dst;
|
|
||||||
BYTE* const oend = ostart + dstSize;
|
|
||||||
|
|
||||||
const U32 dtLog = DTable[0];
|
|
||||||
size_t errorCode;
|
|
||||||
|
|
||||||
/* Init */
|
|
||||||
BITv05_DStream_t bitD;
|
|
||||||
errorCode = BITv05_initDStream(&bitD, istart, cSrcSize);
|
|
||||||
if (HUFv05_isError(errorCode)) return errorCode;
|
|
||||||
|
|
||||||
/* finish bitStreams one by one */
|
|
||||||
HUFv05_decodeStreamX6(ostart, &bitD, oend, DTable, dtLog);
|
|
||||||
|
|
||||||
/* check */
|
|
||||||
if (!BITv05_endOfDStream(&bitD)) return ERROR(corruption_detected);
|
|
||||||
|
|
||||||
/* decoded size */
|
|
||||||
return dstSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t HUFv05_decompress1X6 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize)
|
|
||||||
{
|
|
||||||
HUFv05_CREATE_STATIC_DTABLEX6(DTable, HUFv05_MAX_TABLELOG);
|
|
||||||
const BYTE* ip = (const BYTE*) cSrc;
|
|
||||||
|
|
||||||
size_t hSize = HUFv05_readDTableX6 (DTable, cSrc, cSrcSize);
|
|
||||||
if (HUFv05_isError(hSize)) return hSize;
|
|
||||||
if (hSize >= cSrcSize) return ERROR(srcSize_wrong);
|
|
||||||
ip += hSize;
|
|
||||||
cSrcSize -= hSize;
|
|
||||||
|
|
||||||
return HUFv05_decompress1X6_usingDTable (dst, dstSize, ip, cSrcSize, DTable);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
size_t HUFv05_decompress4X6_usingDTable(
|
|
||||||
void* dst, size_t dstSize,
|
|
||||||
const void* cSrc, size_t cSrcSize,
|
|
||||||
const U32* DTable)
|
|
||||||
{
|
|
||||||
const BYTE* const istart = (const BYTE*) cSrc;
|
|
||||||
BYTE* const ostart = (BYTE*) dst;
|
|
||||||
BYTE* const oend = ostart + dstSize;
|
|
||||||
|
|
||||||
const U32 dtLog = DTable[0];
|
|
||||||
const void* const ddPtr = DTable+1;
|
|
||||||
const HUFv05_DDescX6* dd = (const HUFv05_DDescX6*)ddPtr;
|
|
||||||
const void* const dsPtr = DTable + 1 + ((size_t)1<<(dtLog-1));
|
|
||||||
const HUFv05_DSeqX6* ds = (const HUFv05_DSeqX6*)dsPtr;
|
|
||||||
size_t errorCode;
|
|
||||||
|
|
||||||
/* Check */
|
|
||||||
if (cSrcSize < 10) return ERROR(corruption_detected); /* strict minimum : jump table + 1 byte per stream */
|
|
||||||
|
|
||||||
/* Init */
|
|
||||||
BITv05_DStream_t bitD1;
|
|
||||||
BITv05_DStream_t bitD2;
|
|
||||||
BITv05_DStream_t bitD3;
|
|
||||||
BITv05_DStream_t bitD4;
|
|
||||||
const size_t length1 = MEM_readLE16(istart);
|
|
||||||
const size_t length2 = MEM_readLE16(istart+2);
|
|
||||||
const size_t length3 = MEM_readLE16(istart+4);
|
|
||||||
size_t length4;
|
|
||||||
const BYTE* const istart1 = istart + 6; /* jumpTable */
|
|
||||||
const BYTE* const istart2 = istart1 + length1;
|
|
||||||
const BYTE* const istart3 = istart2 + length2;
|
|
||||||
const BYTE* const istart4 = istart3 + length3;
|
|
||||||
const size_t segmentSize = (dstSize+3) / 4;
|
|
||||||
BYTE* const opStart2 = ostart + segmentSize;
|
|
||||||
BYTE* const opStart3 = opStart2 + segmentSize;
|
|
||||||
BYTE* const opStart4 = opStart3 + segmentSize;
|
|
||||||
BYTE* op1 = ostart;
|
|
||||||
BYTE* op2 = opStart2;
|
|
||||||
BYTE* op3 = opStart3;
|
|
||||||
BYTE* op4 = opStart4;
|
|
||||||
U32 endSignal;
|
|
||||||
|
|
||||||
length4 = cSrcSize - (length1 + length2 + length3 + 6);
|
|
||||||
if (length4 > cSrcSize) return ERROR(corruption_detected); /* overflow */
|
|
||||||
errorCode = BITv05_initDStream(&bitD1, istart1, length1);
|
|
||||||
if (HUFv05_isError(errorCode)) return errorCode;
|
|
||||||
errorCode = BITv05_initDStream(&bitD2, istart2, length2);
|
|
||||||
if (HUFv05_isError(errorCode)) return errorCode;
|
|
||||||
errorCode = BITv05_initDStream(&bitD3, istart3, length3);
|
|
||||||
if (HUFv05_isError(errorCode)) return errorCode;
|
|
||||||
errorCode = BITv05_initDStream(&bitD4, istart4, length4);
|
|
||||||
if (HUFv05_isError(errorCode)) return errorCode;
|
|
||||||
|
|
||||||
/* 16-64 symbols per loop (4-16 symbols per stream) */
|
|
||||||
endSignal = BITv05_reloadDStream(&bitD1) | BITv05_reloadDStream(&bitD2) | BITv05_reloadDStream(&bitD3) | BITv05_reloadDStream(&bitD4);
|
|
||||||
for ( ; (op3 <= opStart4) && (endSignal==BITv05_DStream_unfinished) && (op4<=(oend-16)) ; ) {
|
|
||||||
HUFv05_DECODE_SYMBOLX6_2(op1, &bitD1);
|
|
||||||
HUFv05_DECODE_SYMBOLX6_2(op2, &bitD2);
|
|
||||||
HUFv05_DECODE_SYMBOLX6_2(op3, &bitD3);
|
|
||||||
HUFv05_DECODE_SYMBOLX6_2(op4, &bitD4);
|
|
||||||
HUFv05_DECODE_SYMBOLX6_1(op1, &bitD1);
|
|
||||||
HUFv05_DECODE_SYMBOLX6_1(op2, &bitD2);
|
|
||||||
HUFv05_DECODE_SYMBOLX6_1(op3, &bitD3);
|
|
||||||
HUFv05_DECODE_SYMBOLX6_1(op4, &bitD4);
|
|
||||||
HUFv05_DECODE_SYMBOLX6_2(op1, &bitD1);
|
|
||||||
HUFv05_DECODE_SYMBOLX6_2(op2, &bitD2);
|
|
||||||
HUFv05_DECODE_SYMBOLX6_2(op3, &bitD3);
|
|
||||||
HUFv05_DECODE_SYMBOLX6_2(op4, &bitD4);
|
|
||||||
HUFv05_DECODE_SYMBOLX6_0(op1, &bitD1);
|
|
||||||
HUFv05_DECODE_SYMBOLX6_0(op2, &bitD2);
|
|
||||||
HUFv05_DECODE_SYMBOLX6_0(op3, &bitD3);
|
|
||||||
HUFv05_DECODE_SYMBOLX6_0(op4, &bitD4);
|
|
||||||
|
|
||||||
endSignal = BITv05_reloadDStream(&bitD1) | BITv05_reloadDStream(&bitD2) | BITv05_reloadDStream(&bitD3) | BITv05_reloadDStream(&bitD4);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* check corruption */
|
|
||||||
if (op1 > opStart2) return ERROR(corruption_detected);
|
|
||||||
if (op2 > opStart3) return ERROR(corruption_detected);
|
|
||||||
if (op3 > opStart4) return ERROR(corruption_detected);
|
|
||||||
/* note : op4 supposed already verified within main loop */
|
|
||||||
|
|
||||||
/* finish bitStreams one by one */
|
|
||||||
HUFv05_decodeStreamX6(op1, &bitD1, opStart2, DTable, dtLog);
|
|
||||||
HUFv05_decodeStreamX6(op2, &bitD2, opStart3, DTable, dtLog);
|
|
||||||
HUFv05_decodeStreamX6(op3, &bitD3, opStart4, DTable, dtLog);
|
|
||||||
HUFv05_decodeStreamX6(op4, &bitD4, oend, DTable, dtLog);
|
|
||||||
|
|
||||||
/* check */
|
|
||||||
endSignal = BITv05_endOfDStream(&bitD1) & BITv05_endOfDStream(&bitD2) & BITv05_endOfDStream(&bitD3) & BITv05_endOfDStream(&bitD4);
|
|
||||||
if (!endSignal) return ERROR(corruption_detected);
|
|
||||||
|
|
||||||
/* decoded size */
|
|
||||||
return dstSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
size_t HUFv05_decompress4X6 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize)
|
|
||||||
{
|
|
||||||
HUFv05_CREATE_STATIC_DTABLEX6(DTable, HUFv05_MAX_TABLELOG);
|
|
||||||
const BYTE* ip = (const BYTE*) cSrc;
|
|
||||||
|
|
||||||
size_t hSize = HUFv05_readDTableX6 (DTable, cSrc, cSrcSize);
|
|
||||||
if (HUFv05_isError(hSize)) return hSize;
|
|
||||||
if (hSize >= cSrcSize) return ERROR(srcSize_wrong);
|
|
||||||
ip += hSize;
|
|
||||||
cSrcSize -= hSize;
|
|
||||||
|
|
||||||
return HUFv05_decompress4X6_usingDTable (dst, dstSize, ip, cSrcSize, DTable);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* ********************************/
|
/* ********************************/
|
||||||
/* Generic decompression selector */
|
/* Generic decompression selector */
|
||||||
/* ********************************/
|
/* ********************************/
|
||||||
@@ -3250,7 +2860,7 @@ typedef size_t (*decompressionAlgo)(void* dst, size_t dstSize, const void* cSrc,
|
|||||||
|
|
||||||
size_t HUFv05_decompress (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize)
|
size_t HUFv05_decompress (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize)
|
||||||
{
|
{
|
||||||
static const decompressionAlgo decompress[3] = { HUFv05_decompress4X2, HUFv05_decompress4X4, HUFv05_decompress4X6 };
|
static const decompressionAlgo decompress[3] = { HUFv05_decompress4X2, HUFv05_decompress4X4, NULL };
|
||||||
/* estimate decompression time */
|
/* estimate decompression time */
|
||||||
U32 Q;
|
U32 Q;
|
||||||
const U32 D256 = (U32)(dstSize >> 8);
|
const U32 D256 = (U32)(dstSize >> 8);
|
||||||
@@ -3260,8 +2870,7 @@ size_t HUFv05_decompress (void* dst, size_t dstSize, const void* cSrc, size_t cS
|
|||||||
|
|
||||||
/* validation checks */
|
/* validation checks */
|
||||||
if (dstSize == 0) return ERROR(dstSize_tooSmall);
|
if (dstSize == 0) return ERROR(dstSize_tooSmall);
|
||||||
if (cSrcSize > dstSize) return ERROR(corruption_detected); /* invalid */
|
if (cSrcSize >= dstSize) return ERROR(corruption_detected); /* invalid, or not compressed, but not compressed already dealt with */
|
||||||
if (cSrcSize == dstSize) { memcpy(dst, cSrc, dstSize); return dstSize; } /* not compressed */
|
|
||||||
if (cSrcSize == 1) { memset(dst, *(const BYTE*)cSrc, dstSize); return dstSize; } /* RLE */
|
if (cSrcSize == 1) { memset(dst, *(const BYTE*)cSrc, dstSize); return dstSize; } /* RLE */
|
||||||
|
|
||||||
/* decoder timing evaluation */
|
/* decoder timing evaluation */
|
||||||
@@ -3272,7 +2881,6 @@ size_t HUFv05_decompress (void* dst, size_t dstSize, const void* cSrc, size_t cS
|
|||||||
Dtime[1] += Dtime[1] >> 4; Dtime[2] += Dtime[2] >> 3; /* advantage to algorithms using less memory, for cache eviction */
|
Dtime[1] += Dtime[1] >> 4; Dtime[2] += Dtime[2] >> 3; /* advantage to algorithms using less memory, for cache eviction */
|
||||||
|
|
||||||
if (Dtime[1] < Dtime[0]) algoNb = 1;
|
if (Dtime[1] < Dtime[0]) algoNb = 1;
|
||||||
if (Dtime[2] < Dtime[algoNb]) algoNb = 2;
|
|
||||||
|
|
||||||
return decompress[algoNb](dst, dstSize, cSrc, cSrcSize);
|
return decompress[algoNb](dst, dstSize, cSrc, cSrcSize);
|
||||||
|
|
||||||
@@ -4264,25 +3872,17 @@ size_t ZSTDv05_decompressContinue(ZSTDv05_DCtx* dctx, void* dst, size_t maxDstSi
|
|||||||
switch (dctx->stage)
|
switch (dctx->stage)
|
||||||
{
|
{
|
||||||
case ZSTDv05ds_getFrameHeaderSize :
|
case ZSTDv05ds_getFrameHeaderSize :
|
||||||
{
|
/* get frame header size */
|
||||||
/* get frame header size */
|
if (srcSize != ZSTDv05_frameHeaderSize_min) return ERROR(srcSize_wrong); /* impossible */
|
||||||
if (srcSize != ZSTDv05_frameHeaderSize_min) return ERROR(srcSize_wrong); /* impossible */
|
dctx->headerSize = ZSTDv05_decodeFrameHeader_Part1(dctx, src, ZSTDv05_frameHeaderSize_min);
|
||||||
dctx->headerSize = ZSTDv05_decodeFrameHeader_Part1(dctx, src, ZSTDv05_frameHeaderSize_min);
|
if (ZSTDv05_isError(dctx->headerSize)) return dctx->headerSize;
|
||||||
if (ZSTDv05_isError(dctx->headerSize)) return dctx->headerSize;
|
memcpy(dctx->headerBuffer, src, ZSTDv05_frameHeaderSize_min);
|
||||||
memcpy(dctx->headerBuffer, src, ZSTDv05_frameHeaderSize_min);
|
if (dctx->headerSize > ZSTDv05_frameHeaderSize_min) return ERROR(GENERIC); /* should never happen */
|
||||||
if (dctx->headerSize > ZSTDv05_frameHeaderSize_min) {
|
dctx->expected = 0; /* not necessary to copy more */
|
||||||
dctx->expected = dctx->headerSize - ZSTDv05_frameHeaderSize_min;
|
/* fallthrough */
|
||||||
dctx->stage = ZSTDv05ds_decodeFrameHeader;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
dctx->expected = 0; /* not necessary to copy more */
|
|
||||||
}
|
|
||||||
case ZSTDv05ds_decodeFrameHeader:
|
case ZSTDv05ds_decodeFrameHeader:
|
||||||
{
|
/* get frame header */
|
||||||
/* get frame header */
|
{ size_t const result = ZSTDv05_decodeFrameHeader_Part2(dctx, dctx->headerBuffer, dctx->headerSize);
|
||||||
size_t result;
|
|
||||||
memcpy(dctx->headerBuffer + ZSTDv05_frameHeaderSize_min, src, dctx->expected);
|
|
||||||
result = ZSTDv05_decodeFrameHeader_Part2(dctx, dctx->headerBuffer, dctx->headerSize);
|
|
||||||
if (ZSTDv05_isError(result)) return result;
|
if (ZSTDv05_isError(result)) return result;
|
||||||
dctx->expected = ZSTDv05_blockHeaderSize;
|
dctx->expected = ZSTDv05_blockHeaderSize;
|
||||||
dctx->stage = ZSTDv05ds_decodeBlockHeader;
|
dctx->stage = ZSTDv05ds_decodeBlockHeader;
|
||||||
@@ -4706,8 +4306,7 @@ size_t ZBUFFv05_decompressContinue(ZBUFFv05_DCtx* zbc, void* dst, size_t* maxDst
|
|||||||
*srcSizePtr = ip-istart;
|
*srcSizePtr = ip-istart;
|
||||||
*maxDstSizePtr = op-ostart;
|
*maxDstSizePtr = op-ostart;
|
||||||
|
|
||||||
{
|
{ size_t nextSrcSizeHint = ZSTDv05_nextSrcSizeToDecompress(zbc->zc);
|
||||||
size_t nextSrcSizeHint = ZSTDv05_nextSrcSizeToDecompress(zbc->zc);
|
|
||||||
if (nextSrcSizeHint > ZBUFFv05_blockHeaderSize) nextSrcSizeHint+= ZBUFFv05_blockHeaderSize; /* get next block header too */
|
if (nextSrcSizeHint > ZBUFFv05_blockHeaderSize) nextSrcSizeHint+= ZBUFFv05_blockHeaderSize; /* get next block header too */
|
||||||
nextSrcSizeHint -= zbc->inPos; /* already loaded*/
|
nextSrcSizeHint -= zbc->inPos; /* already loaded*/
|
||||||
return nextSrcSizeHint;
|
return nextSrcSizeHint;
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ extern "C" {
|
|||||||
* Dependencies
|
* Dependencies
|
||||||
***************************************/
|
***************************************/
|
||||||
#include <stddef.h> /* size_t */
|
#include <stddef.h> /* size_t */
|
||||||
|
#include "mem.h" /* U64, U32 */
|
||||||
|
|
||||||
|
|
||||||
/* *************************************
|
/* *************************************
|
||||||
@@ -69,7 +69,7 @@ const char* ZSTDv05_getErrorName(size_t code); /*!< provides readable string
|
|||||||
/** Decompression context */
|
/** Decompression context */
|
||||||
typedef struct ZSTDv05_DCtx_s ZSTDv05_DCtx;
|
typedef struct ZSTDv05_DCtx_s ZSTDv05_DCtx;
|
||||||
ZSTDv05_DCtx* ZSTDv05_createDCtx(void);
|
ZSTDv05_DCtx* ZSTDv05_createDCtx(void);
|
||||||
size_t ZSTDv05_freeDCtx(ZSTDv05_DCtx* dctx); /*!< @return : errorCode */
|
size_t ZSTDv05_freeDCtx(ZSTDv05_DCtx* dctx); /*!< @return : errorCode */
|
||||||
|
|
||||||
/** ZSTDv05_decompressDCtx() :
|
/** ZSTDv05_decompressDCtx() :
|
||||||
* Same as ZSTDv05_decompress(), but requires an already allocated ZSTDv05_DCtx (see ZSTDv05_createDCtx()) */
|
* Same as ZSTDv05_decompress(), but requires an already allocated ZSTDv05_DCtx (see ZSTDv05_createDCtx()) */
|
||||||
@@ -77,25 +77,40 @@ size_t ZSTDv05_decompressDCtx(ZSTDv05_DCtx* ctx, void* dst, size_t dstCapacity,
|
|||||||
|
|
||||||
|
|
||||||
/*-***********************
|
/*-***********************
|
||||||
* Dictionary API
|
* Simple Dictionary API
|
||||||
*************************/
|
*************************/
|
||||||
/*! ZSTDv05_decompress_usingDict() :
|
/*! ZSTDv05_decompress_usingDict() :
|
||||||
* Decompression using a pre-defined Dictionary content (see dictBuilder).
|
* Decompression using a pre-defined Dictionary content (see dictBuilder).
|
||||||
* Dictionary must be identical to the one used during compression, otherwise regenerated data will be corrupted.
|
* Dictionary must be identical to the one used during compression, otherwise regenerated data will be corrupted.
|
||||||
* Note : dict can be NULL, in which case, it's equivalent to ZSTDv05_decompressDCtx() */
|
* Note : dict can be NULL, in which case, it's equivalent to ZSTDv05_decompressDCtx() */
|
||||||
size_t ZSTDv05_decompress_usingDict(ZSTDv05_DCtx* dctx,
|
size_t ZSTDv05_decompress_usingDict(ZSTDv05_DCtx* dctx,
|
||||||
void* dst, size_t dstCapacity,
|
void* dst, size_t dstCapacity,
|
||||||
const void* src, size_t srcSize,
|
const void* src, size_t srcSize,
|
||||||
const void* dict,size_t dictSize);
|
const void* dict,size_t dictSize);
|
||||||
|
|
||||||
|
/*-************************
|
||||||
|
* Advanced Streaming API
|
||||||
|
***************************/
|
||||||
|
typedef enum { ZSTDv05_fast, ZSTDv05_greedy, ZSTDv05_lazy, ZSTDv05_lazy2, ZSTDv05_btlazy2, ZSTDv05_opt, ZSTDv05_btopt } ZSTDv05_strategy;
|
||||||
|
typedef struct {
|
||||||
|
U64 srcSize;
|
||||||
|
U32 windowLog; /* the only useful information to retrieve */
|
||||||
|
U32 contentLog; U32 hashLog; U32 searchLog; U32 searchLength; U32 targetLength; ZSTDv05_strategy strategy;
|
||||||
|
} ZSTDv05_parameters;
|
||||||
|
size_t ZSTDv05_getFrameParams(ZSTDv05_parameters* params, const void* src, size_t srcSize);
|
||||||
|
|
||||||
|
size_t ZSTDv05_decompressBegin_usingDict(ZSTDv05_DCtx* dctx, const void* dict, size_t dictSize);
|
||||||
|
void ZSTDv05_copyDCtx(ZSTDv05_DCtx* dstDCtx, const ZSTDv05_DCtx* srcDCtx);
|
||||||
|
size_t ZSTDv05_nextSrcSizeToDecompress(ZSTDv05_DCtx* dctx);
|
||||||
|
size_t ZSTDv05_decompressContinue(ZSTDv05_DCtx* dctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize);
|
||||||
|
|
||||||
|
|
||||||
|
/*-***********************
|
||||||
|
* ZBUFF API
|
||||||
|
*************************/
|
||||||
typedef struct ZBUFFv05_DCtx_s ZBUFFv05_DCtx;
|
typedef struct ZBUFFv05_DCtx_s ZBUFFv05_DCtx;
|
||||||
ZBUFFv05_DCtx* ZBUFFv05_createDCtx(void);
|
ZBUFFv05_DCtx* ZBUFFv05_createDCtx(void);
|
||||||
size_t ZBUFFv05_freeDCtx(ZBUFFv05_DCtx* dctx);
|
size_t ZBUFFv05_freeDCtx(ZBUFFv05_DCtx* dctx);
|
||||||
|
|
||||||
size_t ZBUFFv05_decompressInit(ZBUFFv05_DCtx* dctx);
|
size_t ZBUFFv05_decompressInit(ZBUFFv05_DCtx* dctx);
|
||||||
size_t ZBUFFv05_decompressInitDictionary(ZBUFFv05_DCtx* dctx, const void* dict, size_t dictSize);
|
size_t ZBUFFv05_decompressInitDictionary(ZBUFFv05_DCtx* dctx, const void* dict, size_t dictSize);
|
||||||
|
|||||||
@@ -36,7 +36,7 @@
|
|||||||
#include "zstd_v06.h"
|
#include "zstd_v06.h"
|
||||||
#include <stddef.h> /* size_t, ptrdiff_t */
|
#include <stddef.h> /* size_t, ptrdiff_t */
|
||||||
#include <string.h> /* memcpy */
|
#include <string.h> /* memcpy */
|
||||||
#include <stdlib.h> /* malloc, free, qsort */
|
#include <stdlib.h> /* malloc, free, qsort */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -535,8 +535,6 @@ ZSTDLIB_API size_t ZSTDv06_decompress_usingPreparedDCtx(
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
struct ZSTDv06_frameParams_s { U64 frameContentSize; U32 windowLog; };
|
|
||||||
|
|
||||||
#define ZSTDv06_FRAMEHEADERSIZE_MAX 13 /* for static allocation */
|
#define ZSTDv06_FRAMEHEADERSIZE_MAX 13 /* for static allocation */
|
||||||
static const size_t ZSTDv06_frameHeaderSize_min = 5;
|
static const size_t ZSTDv06_frameHeaderSize_min = 5;
|
||||||
static const size_t ZSTDv06_frameHeaderSize_max = ZSTDv06_FRAMEHEADERSIZE_MAX;
|
static const size_t ZSTDv06_frameHeaderSize_max = ZSTDv06_FRAMEHEADERSIZE_MAX;
|
||||||
|
|||||||
@@ -107,7 +107,7 @@ ZSTDLIB_API size_t ZSTDv06_decompress_usingDict(ZSTDv06_DCtx* dctx,
|
|||||||
/*-************************
|
/*-************************
|
||||||
* Advanced Streaming API
|
* Advanced Streaming API
|
||||||
***************************/
|
***************************/
|
||||||
|
struct ZSTDv06_frameParams_s { unsigned long long frameContentSize; unsigned windowLog; };
|
||||||
typedef struct ZSTDv06_frameParams_s ZSTDv06_frameParams;
|
typedef struct ZSTDv06_frameParams_s ZSTDv06_frameParams;
|
||||||
|
|
||||||
ZSTDLIB_API size_t ZSTDv06_getFrameParams(ZSTDv06_frameParams* fparamsPtr, const void* src, size_t srcSize); /**< doesn't consume input */
|
ZSTDLIB_API size_t ZSTDv06_getFrameParams(ZSTDv06_frameParams* fparamsPtr, const void* src, size_t srcSize); /**< doesn't consume input */
|
||||||
|
|||||||
4936
C/zstd/zstd_v07.c
Normal file
4936
C/zstd/zstd_v07.c
Normal file
File diff suppressed because it is too large
Load Diff
196
C/zstd/zstd_v07.h
Normal file
196
C/zstd/zstd_v07.h
Normal file
@@ -0,0 +1,196 @@
|
|||||||
|
/*
|
||||||
|
zstd_v07 - decoder for 0.7 format
|
||||||
|
Header File
|
||||||
|
Copyright (C) 2014-2016, Yann Collet.
|
||||||
|
|
||||||
|
BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are
|
||||||
|
met:
|
||||||
|
* Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
* Redistributions in binary form must reproduce the above
|
||||||
|
copyright notice, this list of conditions and the following disclaimer
|
||||||
|
in the documentation and/or other materials provided with the
|
||||||
|
distribution.
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
You can contact the author at :
|
||||||
|
- zstd source repository : https://github.com/Cyan4973/zstd
|
||||||
|
*/
|
||||||
|
#ifndef ZSTDv07_H_235446
|
||||||
|
#define ZSTDv07_H_235446
|
||||||
|
|
||||||
|
#if defined (__cplusplus)
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*====== Dependency ======*/
|
||||||
|
#include <stddef.h> /* size_t */
|
||||||
|
|
||||||
|
|
||||||
|
/*====== Export for Windows ======*/
|
||||||
|
/*!
|
||||||
|
* ZSTDv07_DLL_EXPORT :
|
||||||
|
* Enable exporting of functions when building a Windows DLL
|
||||||
|
*/
|
||||||
|
#if defined(_WIN32) && defined(ZSTDv07_DLL_EXPORT) && (ZSTDv07_DLL_EXPORT==1)
|
||||||
|
# define ZSTDLIB_API __declspec(dllexport)
|
||||||
|
#else
|
||||||
|
# define ZSTDLIB_API
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* *************************************
|
||||||
|
* Simple API
|
||||||
|
***************************************/
|
||||||
|
/*! ZSTDv07_getDecompressedSize() :
|
||||||
|
* @return : decompressed size if known, 0 otherwise.
|
||||||
|
note 1 : if `0`, follow up with ZSTDv07_getFrameParams() to know precise failure cause.
|
||||||
|
note 2 : decompressed size could be wrong or intentionally modified !
|
||||||
|
always ensure results fit within application's authorized limits */
|
||||||
|
unsigned long long ZSTDv07_getDecompressedSize(const void* src, size_t srcSize);
|
||||||
|
|
||||||
|
/*! ZSTDv07_decompress() :
|
||||||
|
`compressedSize` : must be _exact_ size of compressed input, otherwise decompression will fail.
|
||||||
|
`dstCapacity` must be equal or larger than originalSize.
|
||||||
|
@return : the number of bytes decompressed into `dst` (<= `dstCapacity`),
|
||||||
|
or an errorCode if it fails (which can be tested using ZSTDv07_isError()) */
|
||||||
|
ZSTDLIB_API size_t ZSTDv07_decompress( void* dst, size_t dstCapacity,
|
||||||
|
const void* src, size_t compressedSize);
|
||||||
|
|
||||||
|
/*====== Helper functions ======*/
|
||||||
|
ZSTDLIB_API unsigned ZSTDv07_isError(size_t code); /*!< tells if a `size_t` function result is an error code */
|
||||||
|
ZSTDLIB_API const char* ZSTDv07_getErrorName(size_t code); /*!< provides readable string from an error code */
|
||||||
|
|
||||||
|
|
||||||
|
/*-*************************************
|
||||||
|
* Explicit memory management
|
||||||
|
***************************************/
|
||||||
|
/** Decompression context */
|
||||||
|
typedef struct ZSTDv07_DCtx_s ZSTDv07_DCtx;
|
||||||
|
ZSTDLIB_API ZSTDv07_DCtx* ZSTDv07_createDCtx(void);
|
||||||
|
ZSTDLIB_API size_t ZSTDv07_freeDCtx(ZSTDv07_DCtx* dctx); /*!< @return : errorCode */
|
||||||
|
|
||||||
|
/** ZSTDv07_decompressDCtx() :
|
||||||
|
* Same as ZSTDv07_decompress(), requires an allocated ZSTDv07_DCtx (see ZSTDv07_createDCtx()) */
|
||||||
|
ZSTDLIB_API size_t ZSTDv07_decompressDCtx(ZSTDv07_DCtx* ctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize);
|
||||||
|
|
||||||
|
|
||||||
|
/*-************************
|
||||||
|
* Simple dictionary API
|
||||||
|
***************************/
|
||||||
|
/*! ZSTDv07_decompress_usingDict() :
|
||||||
|
* Decompression using a pre-defined Dictionary content (see dictBuilder).
|
||||||
|
* Dictionary must be identical to the one used during compression.
|
||||||
|
* Note : This function load the dictionary, resulting in a significant startup time */
|
||||||
|
ZSTDLIB_API size_t ZSTDv07_decompress_usingDict(ZSTDv07_DCtx* dctx,
|
||||||
|
void* dst, size_t dstCapacity,
|
||||||
|
const void* src, size_t srcSize,
|
||||||
|
const void* dict,size_t dictSize);
|
||||||
|
|
||||||
|
|
||||||
|
/*-**************************
|
||||||
|
* Advanced Dictionary API
|
||||||
|
****************************/
|
||||||
|
/*! ZSTDv07_createDDict() :
|
||||||
|
* Create a digested dictionary, ready to start decompression operation without startup delay.
|
||||||
|
* `dict` can be released after creation */
|
||||||
|
typedef struct ZSTDv07_DDict_s ZSTDv07_DDict;
|
||||||
|
ZSTDLIB_API ZSTDv07_DDict* ZSTDv07_createDDict(const void* dict, size_t dictSize);
|
||||||
|
ZSTDLIB_API size_t ZSTDv07_freeDDict(ZSTDv07_DDict* ddict);
|
||||||
|
|
||||||
|
/*! ZSTDv07_decompress_usingDDict() :
|
||||||
|
* Decompression using a pre-digested Dictionary
|
||||||
|
* Faster startup than ZSTDv07_decompress_usingDict(), recommended when same dictionary is used multiple times. */
|
||||||
|
ZSTDLIB_API size_t ZSTDv07_decompress_usingDDict(ZSTDv07_DCtx* dctx,
|
||||||
|
void* dst, size_t dstCapacity,
|
||||||
|
const void* src, size_t srcSize,
|
||||||
|
const ZSTDv07_DDict* ddict);
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
unsigned long long frameContentSize;
|
||||||
|
unsigned windowSize;
|
||||||
|
unsigned dictID;
|
||||||
|
unsigned checksumFlag;
|
||||||
|
} ZSTDv07_frameParams;
|
||||||
|
|
||||||
|
ZSTDLIB_API size_t ZSTDv07_getFrameParams(ZSTDv07_frameParams* fparamsPtr, const void* src, size_t srcSize); /**< doesn't consume input */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* *************************************
|
||||||
|
* Streaming functions
|
||||||
|
***************************************/
|
||||||
|
typedef struct ZBUFFv07_DCtx_s ZBUFFv07_DCtx;
|
||||||
|
ZSTDLIB_API ZBUFFv07_DCtx* ZBUFFv07_createDCtx(void);
|
||||||
|
ZSTDLIB_API size_t ZBUFFv07_freeDCtx(ZBUFFv07_DCtx* dctx);
|
||||||
|
|
||||||
|
ZSTDLIB_API size_t ZBUFFv07_decompressInit(ZBUFFv07_DCtx* dctx);
|
||||||
|
ZSTDLIB_API size_t ZBUFFv07_decompressInitDictionary(ZBUFFv07_DCtx* dctx, const void* dict, size_t dictSize);
|
||||||
|
|
||||||
|
ZSTDLIB_API size_t ZBUFFv07_decompressContinue(ZBUFFv07_DCtx* dctx,
|
||||||
|
void* dst, size_t* dstCapacityPtr,
|
||||||
|
const void* src, size_t* srcSizePtr);
|
||||||
|
|
||||||
|
/*-***************************************************************************
|
||||||
|
* Streaming decompression howto
|
||||||
|
*
|
||||||
|
* A ZBUFFv07_DCtx object is required to track streaming operations.
|
||||||
|
* Use ZBUFFv07_createDCtx() and ZBUFFv07_freeDCtx() to create/release resources.
|
||||||
|
* Use ZBUFFv07_decompressInit() to start a new decompression operation,
|
||||||
|
* or ZBUFFv07_decompressInitDictionary() if decompression requires a dictionary.
|
||||||
|
* Note that ZBUFFv07_DCtx objects can be re-init multiple times.
|
||||||
|
*
|
||||||
|
* Use ZBUFFv07_decompressContinue() repetitively to consume your input.
|
||||||
|
* *srcSizePtr and *dstCapacityPtr can be any size.
|
||||||
|
* The function will report how many bytes were read or written by modifying *srcSizePtr and *dstCapacityPtr.
|
||||||
|
* Note that it may not consume the entire input, in which case it's up to the caller to present remaining input again.
|
||||||
|
* The content of `dst` will be overwritten (up to *dstCapacityPtr) at each function call, so save its content if it matters, or change `dst`.
|
||||||
|
* @return : a hint to preferred nb of bytes to use as input for next function call (it's only a hint, to help latency),
|
||||||
|
* or 0 when a frame is completely decoded,
|
||||||
|
* or an error code, which can be tested using ZBUFFv07_isError().
|
||||||
|
*
|
||||||
|
* Hint : recommended buffer sizes (not compulsory) : ZBUFFv07_recommendedDInSize() and ZBUFFv07_recommendedDOutSize()
|
||||||
|
* output : ZBUFFv07_recommendedDOutSize== 128 KB block size is the internal unit, it ensures it's always possible to write a full block when decoded.
|
||||||
|
* input : ZBUFFv07_recommendedDInSize == 128KB + 3;
|
||||||
|
* just follow indications from ZBUFFv07_decompressContinue() to minimize latency. It should always be <= 128 KB + 3 .
|
||||||
|
* *******************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/* *************************************
|
||||||
|
* Tool functions
|
||||||
|
***************************************/
|
||||||
|
ZSTDLIB_API unsigned ZBUFFv07_isError(size_t errorCode);
|
||||||
|
ZSTDLIB_API const char* ZBUFFv07_getErrorName(size_t errorCode);
|
||||||
|
|
||||||
|
/** Functions below provide recommended buffer sizes for Compression or Decompression operations.
|
||||||
|
* These sizes are just hints, they tend to offer better latency */
|
||||||
|
ZSTDLIB_API size_t ZBUFFv07_recommendedDInSize(void);
|
||||||
|
ZSTDLIB_API size_t ZBUFFv07_recommendedDOutSize(void);
|
||||||
|
|
||||||
|
|
||||||
|
/*-*************************************
|
||||||
|
* Constants
|
||||||
|
***************************************/
|
||||||
|
#define ZSTDv07_MAGICNUMBER 0xFD2FB527 /* v0.7 */
|
||||||
|
|
||||||
|
|
||||||
|
#if defined (__cplusplus)
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* ZSTDv07_H_235446 */
|
||||||
@@ -174,7 +174,7 @@ $(C_OBJS): ../../../../C/$(*B).c
|
|||||||
!ENDIF
|
!ENDIF
|
||||||
|
|
||||||
!IFDEF ZSTD_OBJS
|
!IFDEF ZSTD_OBJS
|
||||||
$(ZSTD_OBJS): ../../../../C/ZStd/$(*B).c
|
$(ZSTD_OBJS): ../../../../C/zstd/$(*B).c
|
||||||
$(COMPL_O2)
|
$(COMPL_O2)
|
||||||
!ENDIF
|
!ENDIF
|
||||||
|
|
||||||
@@ -240,7 +240,7 @@ $(ZSTD_OBJS): ../../../../C/ZStd/$(*B).c
|
|||||||
$(COMPLB_O2)
|
$(COMPLB_O2)
|
||||||
{../../../../C}.c{$O}.obj::
|
{../../../../C}.c{$O}.obj::
|
||||||
$(CCOMPLB)
|
$(CCOMPLB)
|
||||||
{../../../../C/ZStd}.c{$O}.obj::
|
{../../../../C/zstd}.c{$O}.obj::
|
||||||
$(CCOMPLB)
|
$(CCOMPLB)
|
||||||
|
|
||||||
!ENDIF
|
!ENDIF
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
PROG = 7za.dll
|
PROG = 7za.dll
|
||||||
DEF_FILE = ../../Archive/Archive2.def
|
DEF_FILE = ../../Archive/Archive2.def
|
||||||
CFLAGS = $(CFLAGS) \
|
CFLAGS = $(CFLAGS)
|
||||||
-DDEFLATE_EXTRACT_ONLY \
|
# -DDEFLATE_EXTRACT_ONLY \
|
||||||
-DBZIP2_EXTRACT_ONLY \
|
# -DBZIP2_EXTRACT_ONLY \
|
||||||
|
|
||||||
COMMON_OBJS = \
|
COMMON_OBJS = \
|
||||||
$O\CRC.obj \
|
$O\CRC.obj \
|
||||||
@@ -55,6 +55,7 @@ AR_COMMON_OBJS = \
|
|||||||
$O\OutStreamWithCRC.obj \
|
$O\OutStreamWithCRC.obj \
|
||||||
$O\ParseProperties.obj \
|
$O\ParseProperties.obj \
|
||||||
|
|
||||||
|
|
||||||
7Z_OBJS = \
|
7Z_OBJS = \
|
||||||
$O\7zCompressionMode.obj \
|
$O\7zCompressionMode.obj \
|
||||||
$O\7zDecode.obj \
|
$O\7zDecode.obj \
|
||||||
@@ -71,6 +72,7 @@ AR_COMMON_OBJS = \
|
|||||||
$O\7zUpdate.obj \
|
$O\7zUpdate.obj \
|
||||||
$O\7zRegister.obj \
|
$O\7zRegister.obj \
|
||||||
|
|
||||||
|
|
||||||
COMPRESS_OBJS = \
|
COMPRESS_OBJS = \
|
||||||
$O\CodecExports.obj \
|
$O\CodecExports.obj \
|
||||||
$O\Bcj2Coder.obj \
|
$O\Bcj2Coder.obj \
|
||||||
@@ -82,10 +84,12 @@ COMPRESS_OBJS = \
|
|||||||
$O\BranchRegister.obj \
|
$O\BranchRegister.obj \
|
||||||
$O\ByteSwap.obj \
|
$O\ByteSwap.obj \
|
||||||
$O\BZip2Crc.obj \
|
$O\BZip2Crc.obj \
|
||||||
|
$O\BZip2Encoder.obj \
|
||||||
$O\BZip2Decoder.obj \
|
$O\BZip2Decoder.obj \
|
||||||
$O\BZip2Register.obj \
|
$O\BZip2Register.obj \
|
||||||
$O\CopyCoder.obj \
|
$O\CopyCoder.obj \
|
||||||
$O\CopyRegister.obj \
|
$O\CopyRegister.obj \
|
||||||
|
$O\DeflateEncoder.obj \
|
||||||
$O\DeflateDecoder.obj \
|
$O\DeflateDecoder.obj \
|
||||||
$O\DeflateRegister.obj \
|
$O\DeflateRegister.obj \
|
||||||
$O\DeltaFilter.obj \
|
$O\DeltaFilter.obj \
|
||||||
@@ -99,9 +103,6 @@ COMPRESS_OBJS = \
|
|||||||
$O\PpmdDecoder.obj \
|
$O\PpmdDecoder.obj \
|
||||||
$O\PpmdEncoder.obj \
|
$O\PpmdEncoder.obj \
|
||||||
$O\PpmdRegister.obj \
|
$O\PpmdRegister.obj \
|
||||||
$O\ZStdDecoder.obj \
|
|
||||||
$O\ZStdEncoder.obj \
|
|
||||||
$O\ZStdRegister.obj \
|
|
||||||
|
|
||||||
CRYPTO_OBJS = \
|
CRYPTO_OBJS = \
|
||||||
$O\7zAes.obj \
|
$O\7zAes.obj \
|
||||||
@@ -135,20 +136,13 @@ C_OBJS = \
|
|||||||
$O\Sort.obj \
|
$O\Sort.obj \
|
||||||
$O\Threads.obj \
|
$O\Threads.obj \
|
||||||
|
|
||||||
ZSTD_OBJS = \
|
|
||||||
$O\entropy_common.obj \
|
|
||||||
$O\fse_compress.obj \
|
|
||||||
$O\fse_decompress.obj \
|
|
||||||
$O\huf_compress.obj \
|
|
||||||
$O\huf_decompress.obj \
|
|
||||||
$O\zbuff_compress.obj \
|
|
||||||
$O\zbuff_decompress.obj \
|
|
||||||
$O\zstd_common.obj \
|
|
||||||
$O\zstd_compress.obj \
|
|
||||||
$O\zstd_decompress.obj \
|
|
||||||
$O\zstd_v05.obj \
|
|
||||||
|
|
||||||
!include "../../Aes.mak"
|
!include "../../Aes.mak"
|
||||||
!include "../../Crc.mak"
|
!include "../../Crc.mak"
|
||||||
|
!include "../../zstd.mak"
|
||||||
|
ZSTD_OBJS = $(ZSTD_OBJS) \
|
||||||
|
$O\fse_compress.obj \
|
||||||
|
$O\huf_compress.obj \
|
||||||
|
$O\zbuff_compress.obj \
|
||||||
|
$O\zstd_compress.obj \
|
||||||
|
|
||||||
!include "../../7zip.mak"
|
!include "../../7zip.mak"
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
PROG = 7z.dll
|
PROG = 7z.dll
|
||||||
DEF_FILE = ../../Archive/Archive2.def
|
DEF_FILE = ../../Archive/Archive2.def
|
||||||
CFLAGS = $(CFLAGS) \
|
CFLAGS = $(CFLAGS) \
|
||||||
-DEXTERNAL_CODECS \
|
-DEXTERNAL_CODECS -DZSTD_LEGACY \
|
||||||
|
|
||||||
!IFNDEF UNDER_CE
|
!IFNDEF UNDER_CE
|
||||||
CFLAGS = $(CFLAGS) -D_7ZIP_LARGE_PAGES
|
CFLAGS = $(CFLAGS) -D_7ZIP_LARGE_PAGES
|
||||||
@@ -11,27 +11,20 @@ CFLAGS = $(CFLAGS) -D_7ZIP_LARGE_PAGES
|
|||||||
|
|
||||||
COMPRESS_OBJS = $(COMPRESS_OBJS) \
|
COMPRESS_OBJS = $(COMPRESS_OBJS) \
|
||||||
$O\CodecExports.obj \
|
$O\CodecExports.obj \
|
||||||
$O\ZstdDecoder.obj \
|
|
||||||
$O\ZstdEncoder.obj \
|
|
||||||
$O\ZstdRegister.obj \
|
|
||||||
|
|
||||||
AR_OBJS = $(AR_OBJS) \
|
AR_OBJS = $(AR_OBJS) \
|
||||||
$O\ArchiveExports.obj \
|
$O\ArchiveExports.obj \
|
||||||
$O\DllExports2.obj \
|
$O\DllExports2.obj \
|
||||||
|
|
||||||
ZSTD_OBJS = \
|
|
||||||
$O\entropy_common.obj \
|
!include "../../zstd.mak"
|
||||||
|
ZSTD_OBJS = $(ZSTD_OBJS) \
|
||||||
$O\fse_compress.obj \
|
$O\fse_compress.obj \
|
||||||
$O\fse_decompress.obj \
|
|
||||||
$O\huf_compress.obj \
|
$O\huf_compress.obj \
|
||||||
$O\huf_decompress.obj \
|
|
||||||
$O\zbuff_compress.obj \
|
$O\zbuff_compress.obj \
|
||||||
$O\zbuff_decompress.obj \
|
|
||||||
$O\zstd_common.obj \
|
|
||||||
$O\zstd_compress.obj \
|
$O\zstd_compress.obj \
|
||||||
$O\zstd_decompress.obj \
|
$O\zstd_v07.obj \
|
||||||
$O\zstd_v05.obj \
|
|
||||||
$O\zstd_v06.obj \
|
$O\zstd_v06.obj \
|
||||||
$O\xxhash.obj \
|
$O\zstd_v05.obj \
|
||||||
|
|
||||||
!include "../../7zip.mak"
|
!include "../../7zip.mak"
|
||||||
|
|||||||
@@ -1,3 +0,0 @@
|
|||||||
// StdAfx.cpp
|
|
||||||
|
|
||||||
#include "StdAfx.h"
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
// StdAfx.h
|
|
||||||
|
|
||||||
#ifndef __STDAFX_H
|
|
||||||
#define __STDAFX_H
|
|
||||||
|
|
||||||
#include "../../../Common/Common.h"
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,158 +0,0 @@
|
|||||||
MY_STATIC_LINK=1
|
|
||||||
PROG = 7z.dll
|
|
||||||
DEF_FILE = ../../Archive/Archive2.def
|
|
||||||
CFLAGS = $(CFLAGS) -DEXTERNAL_CODECS
|
|
||||||
|
|
||||||
COMMON_OBJS = \
|
|
||||||
$O\CRC.obj \
|
|
||||||
$O\CrcReg.obj \
|
|
||||||
$O\IntToString.obj \
|
|
||||||
$O\NewHandler.obj \
|
|
||||||
$O\MyString.obj \
|
|
||||||
$O\Sha256Reg.obj \
|
|
||||||
$O\StringConvert.obj \
|
|
||||||
$O\StringToInt.obj \
|
|
||||||
$O\MyVector.obj \
|
|
||||||
$O\Wildcard.obj \
|
|
||||||
|
|
||||||
WIN_OBJS = \
|
|
||||||
$O\FileDir.obj \
|
|
||||||
$O\FileFind.obj \
|
|
||||||
$O\FileIO.obj \
|
|
||||||
$O\FileName.obj \
|
|
||||||
$O\PropVariant.obj \
|
|
||||||
$O\Synchronization.obj \
|
|
||||||
$O\System.obj \
|
|
||||||
|
|
||||||
7ZIP_COMMON_OBJS = \
|
|
||||||
$O\CreateCoder.obj \
|
|
||||||
$O\CWrappers.obj \
|
|
||||||
$O\InBuffer.obj \
|
|
||||||
$O\InOutTempBuffer.obj \
|
|
||||||
$O\FilterCoder.obj \
|
|
||||||
$O\LimitedStreams.obj \
|
|
||||||
$O\MethodId.obj \
|
|
||||||
$O\MethodProps.obj \
|
|
||||||
$O\OutBuffer.obj \
|
|
||||||
$O\ProgressUtils.obj \
|
|
||||||
$O\PropId.obj \
|
|
||||||
$O\StreamBinder.obj \
|
|
||||||
$O\StreamObjects.obj \
|
|
||||||
$O\StreamUtils.obj \
|
|
||||||
$O\UniqBlocks.obj \
|
|
||||||
$O\VirtThread.obj \
|
|
||||||
|
|
||||||
AR_OBJS = \
|
|
||||||
$O\ArchiveExports.obj \
|
|
||||||
$O\DllExports2.obj \
|
|
||||||
|
|
||||||
AR_COMMON_OBJS = \
|
|
||||||
$O\CoderMixer2.obj \
|
|
||||||
$O\HandlerOut.obj \
|
|
||||||
$O\InStreamWithCRC.obj \
|
|
||||||
$O\ItemNameUtils.obj \
|
|
||||||
$O\OutStreamWithCRC.obj \
|
|
||||||
$O\ParseProperties.obj \
|
|
||||||
|
|
||||||
|
|
||||||
7Z_OBJS = \
|
|
||||||
$O\7zCompressionMode.obj \
|
|
||||||
$O\7zDecode.obj \
|
|
||||||
$O\7zEncode.obj \
|
|
||||||
$O\7zExtract.obj \
|
|
||||||
$O\7zFolderInStream.obj \
|
|
||||||
$O\7zHandler.obj \
|
|
||||||
$O\7zHandlerOut.obj \
|
|
||||||
$O\7zHeader.obj \
|
|
||||||
$O\7zIn.obj \
|
|
||||||
$O\7zOut.obj \
|
|
||||||
$O\7zProperties.obj \
|
|
||||||
$O\7zSpecStream.obj \
|
|
||||||
$O\7zUpdate.obj \
|
|
||||||
$O\7zRegister.obj \
|
|
||||||
|
|
||||||
|
|
||||||
COMPRESS_OBJS = \
|
|
||||||
$O\CodecExports.obj \
|
|
||||||
$O\Bcj2Coder.obj \
|
|
||||||
$O\Bcj2Register.obj \
|
|
||||||
$O\BcjCoder.obj \
|
|
||||||
$O\BcjRegister.obj \
|
|
||||||
$O\BitlDecoder.obj \
|
|
||||||
$O\BranchMisc.obj \
|
|
||||||
$O\BranchRegister.obj \
|
|
||||||
$O\ByteSwap.obj \
|
|
||||||
$O\BZip2Crc.obj \
|
|
||||||
$O\BZip2Encoder.obj \
|
|
||||||
$O\BZip2Decoder.obj \
|
|
||||||
$O\BZip2Register.obj \
|
|
||||||
$O\CopyCoder.obj \
|
|
||||||
$O\CopyRegister.obj \
|
|
||||||
$O\DeflateEncoder.obj \
|
|
||||||
$O\DeflateDecoder.obj \
|
|
||||||
$O\DeflateRegister.obj \
|
|
||||||
$O\DeltaFilter.obj \
|
|
||||||
$O\Lzma2Decoder.obj \
|
|
||||||
$O\Lzma2Encoder.obj \
|
|
||||||
$O\Lzma2Register.obj \
|
|
||||||
$O\LzmaDecoder.obj \
|
|
||||||
$O\LzmaEncoder.obj \
|
|
||||||
$O\LzmaRegister.obj \
|
|
||||||
$O\LzOutWindow.obj \
|
|
||||||
$O\PpmdDecoder.obj \
|
|
||||||
$O\PpmdEncoder.obj \
|
|
||||||
$O\PpmdRegister.obj \
|
|
||||||
$O\ZstdDecoder.obj \
|
|
||||||
$O\ZstdEncoder.obj \
|
|
||||||
$O\ZstdRegister.obj \
|
|
||||||
|
|
||||||
CRYPTO_OBJS = \
|
|
||||||
$O\7zAes.obj \
|
|
||||||
$O\7zAesRegister.obj \
|
|
||||||
$O\MyAes.obj \
|
|
||||||
$O\MyAesReg.obj \
|
|
||||||
$O\RandGen.obj \
|
|
||||||
|
|
||||||
C_OBJS = \
|
|
||||||
$O\Alloc.obj \
|
|
||||||
$O\Bcj2.obj \
|
|
||||||
$O\Bcj2Enc.obj \
|
|
||||||
$O\Bra.obj \
|
|
||||||
$O\Bra86.obj \
|
|
||||||
$O\BraIA64.obj \
|
|
||||||
$O\BwtSort.obj \
|
|
||||||
$O\CpuArch.obj \
|
|
||||||
$O\Delta.obj \
|
|
||||||
$O\HuffEnc.obj \
|
|
||||||
$O\LzFind.obj \
|
|
||||||
$O\LzFindMt.obj \
|
|
||||||
$O\Lzma2Dec.obj \
|
|
||||||
$O\Lzma2Enc.obj \
|
|
||||||
$O\LzmaDec.obj \
|
|
||||||
$O\LzmaEnc.obj \
|
|
||||||
$O\MtCoder.obj \
|
|
||||||
$O\Ppmd7.obj \
|
|
||||||
$O\Ppmd7Dec.obj \
|
|
||||||
$O\Ppmd7Enc.obj \
|
|
||||||
$O\Sha256.obj \
|
|
||||||
$O\Sort.obj \
|
|
||||||
$O\Threads.obj \
|
|
||||||
|
|
||||||
ZSTD_OBJS = \
|
|
||||||
$O\entropy_common.obj \
|
|
||||||
$O\fse_compress.obj \
|
|
||||||
$O\fse_decompress.obj \
|
|
||||||
$O\huf_compress.obj \
|
|
||||||
$O\huf_decompress.obj \
|
|
||||||
$O\zbuff_compress.obj \
|
|
||||||
$O\zbuff_decompress.obj \
|
|
||||||
$O\zstd_common.obj \
|
|
||||||
$O\zstd_compress.obj \
|
|
||||||
$O\zstd_decompress.obj \
|
|
||||||
$O\zstd_v05.obj \
|
|
||||||
$O\zstd_v06.obj \
|
|
||||||
$O\xxhash.obj \
|
|
||||||
|
|
||||||
!include "../../Aes.mak"
|
|
||||||
!include "../../Crc.mak"
|
|
||||||
!include "../../7zip.mak"
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
#include "../../MyVersionInfo.rc"
|
|
||||||
|
|
||||||
MY_VERSION_INFO_DLL("7z Standalone Plugin (ZStd)", "7z")
|
|
||||||
|
|
||||||
101 ICON "../../Archive/Icons/7z.ico"
|
|
||||||
@@ -100,8 +100,6 @@ COMPRESS_OBJS = \
|
|||||||
$O\LzmaRegister.obj \
|
$O\LzmaRegister.obj \
|
||||||
$O\PpmdDecoder.obj \
|
$O\PpmdDecoder.obj \
|
||||||
$O\PpmdRegister.obj \
|
$O\PpmdRegister.obj \
|
||||||
$O\ZstdDecoder.obj \
|
|
||||||
$O\ZStdRegister.obj \
|
|
||||||
|
|
||||||
CRYPTO_OBJS = \
|
CRYPTO_OBJS = \
|
||||||
$O\7zAes.obj \
|
$O\7zAes.obj \
|
||||||
@@ -123,15 +121,8 @@ C_OBJS = \
|
|||||||
$O\Sha256.obj \
|
$O\Sha256.obj \
|
||||||
$O\Threads.obj \
|
$O\Threads.obj \
|
||||||
|
|
||||||
ZSTD_OBJS = \
|
|
||||||
$O\entropy_common.obj \
|
|
||||||
$O\fse_decompress.obj \
|
|
||||||
$O\huf_decompress.obj \
|
|
||||||
$O\zbuff_decompress.obj \
|
|
||||||
$O\zstd_common.obj \
|
|
||||||
$O\zstd_decompress.obj \
|
|
||||||
$O\xxhash.obj \
|
|
||||||
|
|
||||||
!include "../../Aes.mak"
|
!include "../../Aes.mak"
|
||||||
!include "../../Crc.mak"
|
!include "../../Crc.mak"
|
||||||
|
|
||||||
|
!include "../../zstd.mak"
|
||||||
!include "../../7zip.mak"
|
!include "../../7zip.mak"
|
||||||
|
|||||||
@@ -106,4 +106,5 @@ C_OBJS = \
|
|||||||
|
|
||||||
!include "../../Crc.mak"
|
!include "../../Crc.mak"
|
||||||
|
|
||||||
|
!include "../../zstd.mak"
|
||||||
!include "../../7zip.mak"
|
!include "../../7zip.mak"
|
||||||
|
|||||||
@@ -119,8 +119,6 @@ COMPRESS_OBJS = \
|
|||||||
$O\LzmaRegister.obj \
|
$O\LzmaRegister.obj \
|
||||||
$O\PpmdDecoder.obj \
|
$O\PpmdDecoder.obj \
|
||||||
$O\PpmdRegister.obj \
|
$O\PpmdRegister.obj \
|
||||||
$O\ZstdDecoder.obj \
|
|
||||||
$O\ZStdRegister.obj \
|
|
||||||
|
|
||||||
CRYPTO_OBJS = \
|
CRYPTO_OBJS = \
|
||||||
$O\7zAes.obj \
|
$O\7zAes.obj \
|
||||||
@@ -142,15 +140,8 @@ C_OBJS = \
|
|||||||
$O\Sha256.obj \
|
$O\Sha256.obj \
|
||||||
$O\Threads.obj \
|
$O\Threads.obj \
|
||||||
|
|
||||||
ZSTD_OBJS = \
|
|
||||||
$O\entropy_common.obj \
|
|
||||||
$O\fse_decompress.obj \
|
|
||||||
$O\huf_decompress.obj \
|
|
||||||
$O\zbuff_decompress.obj \
|
|
||||||
$O\zstd_common.obj \
|
|
||||||
$O\zstd_decompress.obj \
|
|
||||||
$O\xxhash.obj \
|
|
||||||
|
|
||||||
!include "../../Aes.mak"
|
!include "../../Aes.mak"
|
||||||
!include "../../Crc.mak"
|
!include "../../Crc.mak"
|
||||||
|
|
||||||
|
!include "../../zstd.mak"
|
||||||
!include "../../7zip.mak"
|
!include "../../7zip.mak"
|
||||||
|
|||||||
@@ -1,405 +1,419 @@
|
|||||||
// ZstdDecoder.cpp
|
// ZstdDecoder.cpp
|
||||||
// (C) 2016 Rich Geldreich, Tino Reichardt
|
// (C) 2016 Rich Geldreich, Tino Reichardt
|
||||||
|
|
||||||
#include "StdAfx.h"
|
#include "StdAfx.h"
|
||||||
#include "ZstdDecoder.h"
|
#include "ZstdDecoder.h"
|
||||||
|
|
||||||
// #define SHOW_DEBUG_INFO
|
// #define SHOW_DEBUG_INFO
|
||||||
#ifdef SHOW_DEBUG_INFO
|
#ifdef SHOW_DEBUG_INFO
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#define PRF(x) x
|
#define PRF(x) x
|
||||||
#else
|
#else
|
||||||
#define PRF(x)
|
#define PRF(x)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define ZSTD_DEFAULT_BUFFER_SIZE (1U << 22U)
|
namespace NCompress {
|
||||||
|
namespace NZSTD {
|
||||||
namespace NCompress {
|
|
||||||
namespace NZSTD {
|
CDecoder::CDecoder ():
|
||||||
|
_inBuf (NULL),
|
||||||
CDecoder::CDecoder ():
|
_outBuf (NULL),
|
||||||
_inBuf (NULL),
|
_inPos (0),
|
||||||
_outBuf (NULL),
|
_inSize (0),
|
||||||
_inPos (0),
|
_eofFlag (false),
|
||||||
_inSize (0),
|
_state (NULL),
|
||||||
_eofFlag (false),
|
_propsWereSet (false),
|
||||||
_state (NULL),
|
_outSizeDefined (false),
|
||||||
_propsWereSet (false),
|
_outSize (0),
|
||||||
_outSizeDefined (false),
|
|
||||||
_outSize (0),
|
_inSizeProcessed (0),
|
||||||
|
_outSizeProcessed (0),
|
||||||
_inSizeProcessed (0),
|
_inBufSizeAllocated (0),
|
||||||
_outSizeProcessed (0),
|
_outBufSizeAllocated (0),
|
||||||
_inBufSizeAllocated (0),
|
|
||||||
_outBufSizeAllocated (0),
|
_inBufSize (ZBUFF_recommendedDInSize()),
|
||||||
|
_outBufSize (ZBUFF_recommendedDOutSize())
|
||||||
_inBufSize (ZSTD_DEFAULT_BUFFER_SIZE),
|
{
|
||||||
_outBufSize (ZSTD_DEFAULT_BUFFER_SIZE)
|
_props.clear ();
|
||||||
{
|
}
|
||||||
_props.clear ();
|
|
||||||
}
|
CDecoder::~CDecoder ()
|
||||||
|
{
|
||||||
CDecoder::~CDecoder ()
|
if (_state)
|
||||||
{
|
ZB_freeDCtx(_state);
|
||||||
if (_state)
|
|
||||||
ZB_freeDCtx(_state);
|
MyFree (_inBuf);
|
||||||
|
MyFree (_outBuf);
|
||||||
MyFree (_inBuf);
|
}
|
||||||
MyFree (_outBuf);
|
|
||||||
}
|
STDMETHODIMP CDecoder::SetInBufSize (UInt32, UInt32 size)
|
||||||
|
{
|
||||||
STDMETHODIMP CDecoder::SetInBufSize (UInt32, UInt32 size)
|
_inBufSize = size;
|
||||||
{
|
return S_OK;
|
||||||
_inBufSize = size;
|
}
|
||||||
return S_OK;
|
|
||||||
}
|
STDMETHODIMP CDecoder::SetOutBufSize (UInt32, UInt32 size)
|
||||||
|
{
|
||||||
STDMETHODIMP CDecoder::SetOutBufSize (UInt32, UInt32 size)
|
_outBufSize = size;
|
||||||
{
|
return S_OK;
|
||||||
_outBufSize = size;
|
}
|
||||||
return S_OK;
|
|
||||||
}
|
HRESULT CDecoder::CreateBuffers ()
|
||||||
|
{
|
||||||
HRESULT CDecoder::CreateBuffers ()
|
if (_inBuf == 0 || _inBufSize != _inBufSizeAllocated)
|
||||||
{
|
{
|
||||||
if (_inBuf == 0 || _inBufSize != _inBufSizeAllocated)
|
MyFree (_inBuf);
|
||||||
{
|
_inBuf = (Byte *) MyAlloc (_inBufSize);
|
||||||
MyFree (_inBuf);
|
if (_inBuf == 0)
|
||||||
_inBuf = (Byte *) MyAlloc (_inBufSize);
|
return E_OUTOFMEMORY;
|
||||||
if (_inBuf == 0)
|
_inBufSizeAllocated = (UInt32)_inBufSize;
|
||||||
return E_OUTOFMEMORY;
|
}
|
||||||
_inBufSizeAllocated = _inBufSize;
|
|
||||||
}
|
if (_outBuf == 0 || _outBufSize != _outBufSizeAllocated)
|
||||||
|
{
|
||||||
if (_outBuf == 0 || _outBufSize != _outBufSizeAllocated)
|
MyFree (_outBuf);
|
||||||
{
|
_outBuf = (Byte *) MyAlloc (_outBufSize);
|
||||||
MyFree (_outBuf);
|
if (_outBuf == 0)
|
||||||
_outBuf = (Byte *) MyAlloc (_outBufSize);
|
return E_OUTOFMEMORY;
|
||||||
if (_outBuf == 0)
|
_outBufSizeAllocated = (UInt32)_outBufSize;
|
||||||
return E_OUTOFMEMORY;
|
}
|
||||||
_outBufSizeAllocated = _outBufSize;
|
|
||||||
}
|
return S_OK;
|
||||||
|
}
|
||||||
return S_OK;
|
|
||||||
}
|
STDMETHODIMP CDecoder::SetDecoderProperties2 (const Byte * prop, UInt32 size)
|
||||||
|
{
|
||||||
STDMETHODIMP CDecoder::SetDecoderProperties2 (const Byte * prop, UInt32 size)
|
DProps *pProps = (DProps *) prop;
|
||||||
{
|
|
||||||
DProps *pProps = (DProps *) prop;
|
if (size != sizeof (DProps))
|
||||||
|
return E_FAIL;
|
||||||
if (size != sizeof (DProps))
|
|
||||||
return E_FAIL;
|
// version 0.x currently
|
||||||
|
if (pProps->_ver_major != ZSTD_VERSION_MAJOR)
|
||||||
// version 0.x currently
|
return E_FAIL;
|
||||||
if (pProps->_ver_major != ZSTD_VERSION_MAJOR)
|
|
||||||
return E_FAIL;
|
switch (pProps->_ver_minor) {
|
||||||
|
case ZSTD_VERSION_MINOR:
|
||||||
switch (pProps->_ver_minor) {
|
break;
|
||||||
case ZSTD_VERSION_MINOR:
|
#ifdef ZSTD_LEGACY
|
||||||
break;
|
case 5:
|
||||||
case 6:
|
break;
|
||||||
break;
|
case 6:
|
||||||
case 5:
|
break;
|
||||||
break;
|
case 7:
|
||||||
default:
|
break;
|
||||||
return E_FAIL;
|
#endif
|
||||||
}
|
default:
|
||||||
|
return E_FAIL;
|
||||||
memcpy(&_props, pProps, sizeof (DProps));
|
}
|
||||||
_propsWereSet = true;
|
|
||||||
|
memcpy(&_props, pProps, sizeof (DProps));
|
||||||
return CreateBuffers();
|
_propsWereSet = true;
|
||||||
}
|
|
||||||
|
return CreateBuffers();
|
||||||
HRESULT CDecoder::CreateDecompressor()
|
}
|
||||||
{
|
|
||||||
if (!_propsWereSet)
|
HRESULT CDecoder::CreateDecompressor()
|
||||||
return E_FAIL;
|
{
|
||||||
|
if (!_propsWereSet)
|
||||||
if (!_state) {
|
return E_FAIL;
|
||||||
_state = ZB_createDCtx();
|
|
||||||
if (!_state)
|
if (!_state) {
|
||||||
return E_FAIL;
|
_state = ZB_createDCtx();
|
||||||
}
|
if (!_state)
|
||||||
|
return E_FAIL;
|
||||||
if (ZBUFF_isError(ZB_decompressInit(_state)))
|
}
|
||||||
return E_FAIL;
|
|
||||||
|
if (ZBUFF_isError(ZB_decompressInit(_state)))
|
||||||
_eofFlag = false;
|
return E_FAIL;
|
||||||
|
|
||||||
return S_OK;
|
_eofFlag = false;
|
||||||
}
|
|
||||||
|
return S_OK;
|
||||||
HRESULT CDecoder::SetOutStreamSizeResume(const UInt64 * outSize)
|
}
|
||||||
{
|
|
||||||
_outSizeDefined = (outSize != NULL);
|
HRESULT CDecoder::SetOutStreamSizeResume(const UInt64 * outSize)
|
||||||
if (_outSizeDefined)
|
{
|
||||||
_outSize = *outSize;
|
_outSizeDefined = (outSize != NULL);
|
||||||
_outSizeProcessed = 0;
|
if (_outSizeDefined)
|
||||||
|
_outSize = *outSize;
|
||||||
RINOK (CreateDecompressor());
|
_outSizeProcessed = 0;
|
||||||
|
|
||||||
return S_OK;
|
RINOK (CreateDecompressor());
|
||||||
}
|
|
||||||
|
return S_OK;
|
||||||
STDMETHODIMP CDecoder::SetOutStreamSize (const UInt64 * outSize)
|
}
|
||||||
{
|
|
||||||
_inSizeProcessed = 0;
|
STDMETHODIMP CDecoder::SetOutStreamSize (const UInt64 * outSize)
|
||||||
_inPos = _inSize = 0;
|
{
|
||||||
RINOK (SetOutStreamSizeResume (outSize));
|
_inSizeProcessed = 0;
|
||||||
return S_OK;
|
_inPos = _inSize = 0;
|
||||||
}
|
RINOK (SetOutStreamSizeResume (outSize));
|
||||||
|
return S_OK;
|
||||||
HRESULT CDecoder::CodeSpec (ISequentialInStream * inStream,
|
}
|
||||||
ISequentialOutStream * outStream,
|
|
||||||
ICompressProgressInfo * progress)
|
HRESULT CDecoder::CodeSpec (ISequentialInStream * inStream,
|
||||||
{
|
ISequentialOutStream * outStream,
|
||||||
if (_inBuf == 0 || !_propsWereSet)
|
ICompressProgressInfo * progress)
|
||||||
return S_FALSE;
|
{
|
||||||
|
if (_inBuf == 0 || !_propsWereSet)
|
||||||
if (!_state)
|
return S_FALSE;
|
||||||
{
|
|
||||||
if (CreateDecompressor () != S_OK)
|
if (!_state)
|
||||||
return E_FAIL;
|
{
|
||||||
}
|
if (CreateDecompressor () != S_OK)
|
||||||
|
return E_FAIL;
|
||||||
UInt64 startInProgress = _inSizeProcessed;
|
}
|
||||||
|
|
||||||
for (;;)
|
UInt64 startInProgress = _inSizeProcessed;
|
||||||
{
|
|
||||||
if ((!_eofFlag) && (_inPos == _inSize))
|
for (;;)
|
||||||
{
|
{
|
||||||
_inPos = _inSize = 0;
|
if ((!_eofFlag) && (_inPos == _inSize))
|
||||||
RINOK (inStream->Read (_inBuf, _inBufSizeAllocated, &_inSize));
|
{
|
||||||
if (!_inSize)
|
_inPos = _inSize = 0;
|
||||||
_eofFlag = true;
|
RINOK (inStream->Read (_inBuf, _inBufSizeAllocated, &_inSize));
|
||||||
}
|
if (!_inSize)
|
||||||
|
_eofFlag = true;
|
||||||
Byte *pIn_bytes = _inBuf + _inPos;
|
}
|
||||||
size_t num_in_bytes = _inSize - _inPos;
|
|
||||||
Byte *pOut_bytes = _outBuf;
|
Byte *pIn_bytes = _inBuf + _inPos;
|
||||||
size_t num_out_bytes = _outBufSize;
|
size_t num_in_bytes = _inSize - _inPos;
|
||||||
if (_outSizeDefined)
|
Byte *pOut_bytes = _outBuf;
|
||||||
{
|
size_t num_out_bytes = _outBufSize;
|
||||||
UInt64 out_remaining = _outSize - _outSizeProcessed;
|
if (_outSizeDefined)
|
||||||
if (out_remaining == 0)
|
{
|
||||||
return S_OK;
|
UInt64 out_remaining = _outSize - _outSizeProcessed;
|
||||||
if (num_out_bytes > out_remaining)
|
if (out_remaining == 0)
|
||||||
num_out_bytes = static_cast < size_t > (out_remaining);
|
return S_OK;
|
||||||
}
|
if (num_out_bytes > out_remaining)
|
||||||
|
num_out_bytes = static_cast < size_t > (out_remaining);
|
||||||
size_t decomp_status =
|
}
|
||||||
ZB_decompressContinue (_state, pOut_bytes, &num_out_bytes,
|
|
||||||
pIn_bytes, &num_in_bytes);
|
size_t decomp_status =
|
||||||
bool decomp_finished = (decomp_status == 0);
|
ZB_decompressContinue (_state, pOut_bytes, &num_out_bytes,
|
||||||
bool decomp_failed = ZBUFF_isError (decomp_status) != 0;
|
pIn_bytes, &num_in_bytes);
|
||||||
|
bool decomp_finished = (decomp_status == 0);
|
||||||
if (num_in_bytes)
|
bool decomp_failed = ZBUFF_isError (decomp_status) != 0;
|
||||||
{
|
|
||||||
_inPos += (UInt32) num_in_bytes;
|
if (num_in_bytes)
|
||||||
_inSizeProcessed += (UInt32) num_in_bytes;
|
{
|
||||||
}
|
_inPos += (UInt32) num_in_bytes;
|
||||||
|
_inSizeProcessed += (UInt32) num_in_bytes;
|
||||||
if (num_out_bytes)
|
}
|
||||||
{
|
|
||||||
_outSizeProcessed += num_out_bytes;
|
if (num_out_bytes)
|
||||||
|
{
|
||||||
RINOK (WriteStream (outStream, _outBuf, num_out_bytes));
|
_outSizeProcessed += num_out_bytes;
|
||||||
}
|
|
||||||
|
RINOK (WriteStream (outStream, _outBuf, num_out_bytes));
|
||||||
if (decomp_failed)
|
}
|
||||||
{
|
|
||||||
PRF(fprintf(stderr, "zstdcodec: ZB_decompressContinue() failed: %s\n", ZBUFF_getErrorName(decomp_status)));
|
if (decomp_failed)
|
||||||
return S_FALSE;
|
{
|
||||||
}
|
PRF(fprintf(stderr, "zstdcodec: ZB_decompressContinue() failed: %s\n", ZBUFF_getErrorName(decomp_status)));
|
||||||
|
return S_FALSE;
|
||||||
if (decomp_finished)
|
}
|
||||||
break;
|
|
||||||
|
if (decomp_finished)
|
||||||
// This check is to prevent locking up if the input file is accidently truncated.
|
break;
|
||||||
bool made_forward_progress = (num_out_bytes != 0) || (num_in_bytes != 0);
|
|
||||||
if ((!made_forward_progress) && (_eofFlag))
|
// This check is to prevent locking up if the input file is accidently truncated.
|
||||||
{
|
bool made_forward_progress = (num_out_bytes != 0) || (num_in_bytes != 0);
|
||||||
return S_FALSE;
|
if ((!made_forward_progress) && (_eofFlag))
|
||||||
}
|
{
|
||||||
|
return S_FALSE;
|
||||||
UInt64 inSize = _inSizeProcessed - startInProgress;
|
}
|
||||||
if (progress)
|
|
||||||
{
|
UInt64 inSize = _inSizeProcessed - startInProgress;
|
||||||
RINOK (progress->SetRatioInfo (&inSize, &_outSizeProcessed));
|
if (progress)
|
||||||
}
|
{
|
||||||
}
|
RINOK (progress->SetRatioInfo (&inSize, &_outSizeProcessed));
|
||||||
|
}
|
||||||
return S_OK;
|
}
|
||||||
}
|
|
||||||
|
return S_OK;
|
||||||
STDMETHODIMP CDecoder::Code (ISequentialInStream * inStream,
|
}
|
||||||
ISequentialOutStream * outStream,
|
|
||||||
const UInt64 * inSize,
|
STDMETHODIMP CDecoder::Code (ISequentialInStream * inStream,
|
||||||
const UInt64 * outSize, ICompressProgressInfo * progress)
|
ISequentialOutStream * outStream,
|
||||||
{
|
const UInt64 * inSize,
|
||||||
(void) inSize;
|
const UInt64 * outSize, ICompressProgressInfo * progress)
|
||||||
if (_inBuf == 0)
|
{
|
||||||
return E_INVALIDARG;
|
(void) inSize;
|
||||||
SetOutStreamSize (outSize);
|
if (_inBuf == 0)
|
||||||
return CodeSpec (inStream, outStream, progress);
|
return E_INVALIDARG;
|
||||||
}
|
SetOutStreamSize (outSize);
|
||||||
|
return CodeSpec (inStream, outStream, progress);
|
||||||
// wrapper for different versions
|
}
|
||||||
void *CDecoder::ZB_createDCtx(void)
|
|
||||||
{
|
// wrapper for different versions
|
||||||
PRF(fprintf(stderr, "zstdcodec: ZB_createDCtx(v=%d)\n", _props._ver_minor));
|
void *CDecoder::ZB_createDCtx(void)
|
||||||
#ifndef EXTRACT_ONLY
|
{
|
||||||
switch (_props._ver_minor) {
|
PRF(fprintf(stderr, "zstdcodec: ZB_createDCtx(v=%d)\n", _props._ver_minor));
|
||||||
case 5:
|
#ifdef ZSTD_LEGACY
|
||||||
return (void*)ZBUFFv05_createDCtx();
|
switch (_props._ver_minor) {
|
||||||
break;
|
case 5:
|
||||||
case 6:
|
return (void*)ZBUFFv05_createDCtx();
|
||||||
return (void*)ZBUFFv06_createDCtx();
|
break;
|
||||||
break;
|
case 6:
|
||||||
}
|
return (void*)ZBUFFv06_createDCtx();
|
||||||
#endif
|
break;
|
||||||
return (void*)ZBUFF_createDCtx();
|
case 7:
|
||||||
}
|
return (void*)ZBUFFv07_createDCtx();
|
||||||
|
break;
|
||||||
size_t CDecoder::ZB_freeDCtx(void *dctx)
|
}
|
||||||
{
|
#endif
|
||||||
PRF(fprintf(stderr, "zstdcodec: ZB_freeDCtx(v=%d)\n", _props._ver_minor));
|
return (void*)ZBUFF_createDCtx();
|
||||||
#ifndef EXTRACT_ONLY
|
}
|
||||||
switch (_props._ver_minor) {
|
|
||||||
case 5:
|
size_t CDecoder::ZB_freeDCtx(void *dctx)
|
||||||
return ZBUFFv05_freeDCtx((ZBUFFv05_DCtx *)dctx);
|
{
|
||||||
break;
|
PRF(fprintf(stderr, "zstdcodec: ZB_freeDCtx(v=%d)\n", _props._ver_minor));
|
||||||
case 6:
|
#ifdef ZSTD_LEGACY
|
||||||
return ZBUFFv06_freeDCtx((ZBUFFv06_DCtx *)dctx);
|
switch (_props._ver_minor) {
|
||||||
break;
|
case 5:
|
||||||
}
|
return ZBUFFv05_freeDCtx((ZBUFFv05_DCtx *)dctx);
|
||||||
#endif
|
break;
|
||||||
return ZBUFF_freeDCtx((ZBUFF_DCtx *)dctx);
|
case 6:
|
||||||
}
|
return ZBUFFv06_freeDCtx((ZBUFFv06_DCtx *)dctx);
|
||||||
|
break;
|
||||||
size_t CDecoder::ZB_decompressInit(void *dctx)
|
case 7:
|
||||||
{
|
return ZBUFFv07_freeDCtx((ZBUFFv07_DCtx *)dctx);
|
||||||
PRF(fprintf(stderr, "zstdcodec: ZB_decompressInit(v=%d)\n", _props._ver_minor));
|
break;
|
||||||
#ifndef EXTRACT_ONLY
|
}
|
||||||
switch (_props._ver_minor) {
|
#endif
|
||||||
case 5:
|
return ZBUFF_freeDCtx((ZBUFF_DCtx *)dctx);
|
||||||
return ZBUFFv05_decompressInit((ZBUFFv05_DCtx *)dctx);
|
}
|
||||||
break;
|
|
||||||
case 6:
|
size_t CDecoder::ZB_decompressInit(void *dctx)
|
||||||
return ZBUFFv06_decompressInit((ZBUFFv06_DCtx *)dctx);
|
{
|
||||||
break;
|
PRF(fprintf(stderr, "zstdcodec: ZB_decompressInit(v=%d)\n", _props._ver_minor));
|
||||||
}
|
#ifdef ZSTD_LEGACY
|
||||||
#endif
|
switch (_props._ver_minor) {
|
||||||
return ZBUFF_decompressInit((ZBUFF_DCtx *)dctx);
|
case 5:
|
||||||
}
|
return ZBUFFv05_decompressInit((ZBUFFv05_DCtx *)dctx);
|
||||||
|
break;
|
||||||
size_t CDecoder::ZB_decompressContinue(void *dctx, void* dst, size_t *dstCapacityPtr, const void* src, size_t *srcSizePtr)
|
case 6:
|
||||||
{
|
return ZBUFFv06_decompressInit((ZBUFFv06_DCtx *)dctx);
|
||||||
PRF(fprintf(stderr, "zstdcodec: ZB_decompressContinue(v=%d)\n", _props._ver_minor));
|
break;
|
||||||
#ifndef EXTRACT_ONLY
|
case 7:
|
||||||
switch (_props._ver_minor) {
|
return ZBUFFv07_decompressInit((ZBUFFv07_DCtx *)dctx);
|
||||||
case 5:
|
break;
|
||||||
return ZBUFFv05_decompressContinue((ZBUFFv05_DCtx *)dctx, dst, dstCapacityPtr, src, srcSizePtr);
|
}
|
||||||
break;
|
#endif
|
||||||
case 6:
|
return ZBUFF_decompressInit((ZBUFF_DCtx *)dctx);
|
||||||
return ZBUFFv06_decompressContinue((ZBUFFv06_DCtx *)dctx, dst, dstCapacityPtr, src, srcSizePtr);
|
}
|
||||||
break;
|
|
||||||
}
|
size_t CDecoder::ZB_decompressContinue(void *dctx, void* dst, size_t *dstCapacityPtr, const void* src, size_t *srcSizePtr)
|
||||||
#endif
|
{
|
||||||
return ZBUFF_decompressContinue((ZBUFF_DCtx *)dctx, dst, dstCapacityPtr, src, srcSizePtr);
|
PRF(fprintf(stderr, "zstdcodec: ZB_decompressContinue(v=%d)\n", _props._ver_minor));
|
||||||
}
|
#ifdef ZSTD_LEGACY
|
||||||
|
switch (_props._ver_minor) {
|
||||||
#ifndef NO_READ_FROM_CODER
|
case 5:
|
||||||
STDMETHODIMP CDecoder::SetInStream (ISequentialInStream * inStream)
|
return ZBUFFv05_decompressContinue((ZBUFFv05_DCtx *)dctx, dst, dstCapacityPtr, src, srcSizePtr);
|
||||||
{
|
break;
|
||||||
_inStream = inStream;
|
case 6:
|
||||||
return S_OK;
|
return ZBUFFv06_decompressContinue((ZBUFFv06_DCtx *)dctx, dst, dstCapacityPtr, src, srcSizePtr);
|
||||||
}
|
break;
|
||||||
|
case 7:
|
||||||
STDMETHODIMP CDecoder::ReleaseInStream ()
|
return ZBUFFv07_decompressContinue((ZBUFFv07_DCtx *)dctx, dst, dstCapacityPtr, src, srcSizePtr);
|
||||||
{
|
break;
|
||||||
_inStream.Release ();
|
}
|
||||||
return S_OK;
|
#endif
|
||||||
}
|
return ZBUFF_decompressContinue((ZBUFF_DCtx *)dctx, dst, dstCapacityPtr, src, srcSizePtr);
|
||||||
|
}
|
||||||
STDMETHODIMP CDecoder::Read (void *data, UInt32 size, UInt32 * processedSize)
|
|
||||||
{
|
#ifndef NO_READ_FROM_CODER
|
||||||
if (processedSize)
|
STDMETHODIMP CDecoder::SetInStream (ISequentialInStream * inStream)
|
||||||
*processedSize = 0;
|
{
|
||||||
|
_inStream = inStream;
|
||||||
if (_inBuf == 0 || !_propsWereSet)
|
return S_OK;
|
||||||
return S_FALSE;
|
}
|
||||||
|
|
||||||
if (!_state)
|
STDMETHODIMP CDecoder::ReleaseInStream ()
|
||||||
{
|
{
|
||||||
if (CreateDecompressor () != S_OK)
|
_inStream.Release ();
|
||||||
return E_FAIL;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (size != 0)
|
STDMETHODIMP CDecoder::Read (void *data, UInt32 size, UInt32 * processedSize)
|
||||||
{
|
{
|
||||||
if ((!_eofFlag) && (_inPos == _inSize))
|
if (processedSize)
|
||||||
{
|
*processedSize = 0;
|
||||||
_inPos = _inSize = 0;
|
|
||||||
RINOK (_inStream->Read (_inBuf, _inBufSizeAllocated, &_inSize));
|
if (_inBuf == 0 || !_propsWereSet)
|
||||||
if (!_inSize)
|
return S_FALSE;
|
||||||
_eofFlag = true;
|
|
||||||
}
|
if (!_state)
|
||||||
|
{
|
||||||
Byte *pIn_bytes = _inBuf + _inPos;
|
if (CreateDecompressor () != S_OK)
|
||||||
size_t num_in_bytes = _inSize - _inPos;
|
return E_FAIL;
|
||||||
Byte *pOut_bytes = (Byte *) data;
|
}
|
||||||
size_t num_out_bytes = size;
|
|
||||||
|
while (size != 0)
|
||||||
size_t decomp_status =
|
{
|
||||||
ZB_decompressContinue (_state, pOut_bytes, &num_out_bytes,
|
if ((!_eofFlag) && (_inPos == _inSize))
|
||||||
pIn_bytes, &num_in_bytes);
|
{
|
||||||
bool
|
_inPos = _inSize = 0;
|
||||||
decomp_finished = (decomp_status == 0);
|
RINOK (_inStream->Read (_inBuf, _inBufSizeAllocated, &_inSize));
|
||||||
bool
|
if (!_inSize)
|
||||||
decomp_failed = ZBUFF_isError (decomp_status) != 0;
|
_eofFlag = true;
|
||||||
|
}
|
||||||
if (num_in_bytes)
|
|
||||||
{
|
Byte *pIn_bytes = _inBuf + _inPos;
|
||||||
_inPos += (UInt32) num_in_bytes;
|
size_t num_in_bytes = _inSize - _inPos;
|
||||||
_inSizeProcessed += num_in_bytes;
|
Byte *pOut_bytes = (Byte *) data;
|
||||||
}
|
size_t num_out_bytes = size;
|
||||||
|
|
||||||
if (num_out_bytes)
|
size_t decomp_status =
|
||||||
{
|
ZB_decompressContinue (_state, pOut_bytes, &num_out_bytes,
|
||||||
_outSizeProcessed += num_out_bytes;
|
pIn_bytes, &num_in_bytes);
|
||||||
size -= (UInt32) num_out_bytes;
|
bool
|
||||||
if (processedSize)
|
decomp_finished = (decomp_status == 0);
|
||||||
*processedSize += (UInt32) num_out_bytes;
|
bool
|
||||||
}
|
decomp_failed = ZBUFF_isError (decomp_status) != 0;
|
||||||
|
|
||||||
if (decomp_failed)
|
if (num_in_bytes)
|
||||||
{
|
{
|
||||||
return S_FALSE;
|
_inPos += (UInt32) num_in_bytes;
|
||||||
}
|
_inSizeProcessed += num_in_bytes;
|
||||||
|
}
|
||||||
if (decomp_finished)
|
|
||||||
break;
|
if (num_out_bytes)
|
||||||
|
{
|
||||||
// This check is to prevent locking up if the input file is accidently truncated.
|
_outSizeProcessed += num_out_bytes;
|
||||||
bool made_forward_progress = (num_out_bytes != 0) || (num_in_bytes != 0);
|
size -= (UInt32) num_out_bytes;
|
||||||
if ((!made_forward_progress) && (_eofFlag))
|
if (processedSize)
|
||||||
{
|
*processedSize += (UInt32) num_out_bytes;
|
||||||
return S_FALSE;
|
}
|
||||||
}
|
|
||||||
}
|
if (decomp_failed)
|
||||||
|
{
|
||||||
return S_OK;
|
return S_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT CDecoder::CodeResume (ISequentialOutStream * outStream,
|
if (decomp_finished)
|
||||||
const UInt64 * outSize,
|
break;
|
||||||
ICompressProgressInfo * progress)
|
|
||||||
{
|
// This check is to prevent locking up if the input file is accidently truncated.
|
||||||
RINOK (SetOutStreamSizeResume (outSize));
|
bool made_forward_progress = (num_out_bytes != 0) || (num_in_bytes != 0);
|
||||||
return CodeSpec (_inStream, outStream, progress);
|
if ((!made_forward_progress) && (_eofFlag))
|
||||||
}
|
{
|
||||||
#endif
|
return S_FALSE;
|
||||||
|
}
|
||||||
}}
|
}
|
||||||
|
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT CDecoder::CodeResume (ISequentialOutStream * outStream,
|
||||||
|
const UInt64 * outSize,
|
||||||
|
ICompressProgressInfo * progress)
|
||||||
|
{
|
||||||
|
RINOK (SetOutStreamSizeResume (outSize));
|
||||||
|
return CodeSpec (_inStream, outStream, progress);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
}}
|
||||||
|
|||||||
@@ -1,111 +1,109 @@
|
|||||||
// ZstdDecoder.h
|
// ZstdDecoder.h
|
||||||
// (C) 2016 Rich Geldreich, Tino Reichardt
|
// (C) 2016 Rich Geldreich, Tino Reichardt
|
||||||
|
|
||||||
#include "StdAfx.h"
|
#define ZSTD_STATIC_LINKING_ONLY
|
||||||
|
#include "../../../C/Alloc.h"
|
||||||
#define ZSTD_STATIC_LINKING_ONLY
|
#include "../../../C/ZStd/zstd.h"
|
||||||
#include "../../../C/Alloc.h"
|
#include "../../../C/ZStd/zbuff.h"
|
||||||
#include "../../../C/ZStd/zstd.h"
|
#include "../../../C/ZStd/zstd_legacy.h"
|
||||||
#include "../../../C/ZStd/zbuff.h"
|
|
||||||
#include "../../../C/ZStd/zstd_legacy.h"
|
#include "../../Common/Common.h"
|
||||||
|
#include "../../Common/MyCom.h"
|
||||||
#include "../../Common/Common.h"
|
#include "../ICoder.h"
|
||||||
#include "../../Common/MyCom.h"
|
#include "../Common/StreamUtils.h"
|
||||||
#include "../ICoder.h"
|
#include "../Common/RegisterCodec.h"
|
||||||
#include "../Common/StreamUtils.h"
|
|
||||||
#include "../Common/RegisterCodec.h"
|
namespace NCompress {
|
||||||
|
namespace NZSTD {
|
||||||
namespace NCompress {
|
|
||||||
namespace NZSTD {
|
struct DProps
|
||||||
|
{
|
||||||
struct DProps
|
DProps() { clear (); }
|
||||||
{
|
void clear ()
|
||||||
DProps() { clear (); }
|
{
|
||||||
void clear ()
|
memset (this, 0, sizeof (*this));
|
||||||
{
|
_ver_major = ZSTD_VERSION_MAJOR;
|
||||||
memset (this, 0, sizeof (*this));
|
_ver_minor = ZSTD_VERSION_MINOR;
|
||||||
_ver_major = ZSTD_VERSION_MAJOR;
|
_level = 1;
|
||||||
_ver_minor = ZSTD_VERSION_MINOR;
|
}
|
||||||
_level = 1;
|
|
||||||
}
|
Byte _ver_major;
|
||||||
|
Byte _ver_minor;
|
||||||
Byte _ver_major;
|
Byte _level;
|
||||||
Byte _ver_minor;
|
Byte _reserved[2];
|
||||||
Byte _level;
|
};
|
||||||
Byte _reserved[2];
|
|
||||||
};
|
class CDecoder:public ICompressCoder,
|
||||||
|
public ICompressSetDecoderProperties2, public ICompressSetBufSize,
|
||||||
class CDecoder:public ICompressCoder,
|
#ifndef NO_READ_FROM_CODER
|
||||||
public ICompressSetDecoderProperties2, public ICompressSetBufSize,
|
public ICompressSetInStream,
|
||||||
#ifndef NO_READ_FROM_CODER
|
public ICompressSetOutStreamSize, public ISequentialInStream,
|
||||||
public ICompressSetInStream,
|
#endif
|
||||||
public ICompressSetOutStreamSize, public ISequentialInStream,
|
public CMyUnknownImp
|
||||||
#endif
|
{
|
||||||
public CMyUnknownImp
|
CMyComPtr < ISequentialInStream > _inStream;
|
||||||
{
|
Byte *_inBuf;
|
||||||
CMyComPtr < ISequentialInStream > _inStream;
|
Byte *_outBuf;
|
||||||
Byte *_inBuf;
|
UInt32 _inPos;
|
||||||
Byte *_outBuf;
|
UInt32 _inSize;
|
||||||
UInt32 _inPos;
|
bool _eofFlag;
|
||||||
UInt32 _inSize;
|
|
||||||
bool _eofFlag;
|
void *_state;
|
||||||
|
|
||||||
void *_state;
|
DProps _props;
|
||||||
|
bool _propsWereSet;
|
||||||
DProps _props;
|
|
||||||
bool _propsWereSet;
|
bool _outSizeDefined;
|
||||||
|
UInt64 _outSize;
|
||||||
bool _outSizeDefined;
|
UInt64 _inSizeProcessed;
|
||||||
UInt64 _outSize;
|
UInt64 _outSizeProcessed;
|
||||||
UInt64 _inSizeProcessed;
|
|
||||||
UInt64 _outSizeProcessed;
|
UInt32 _inBufSizeAllocated;
|
||||||
|
UInt32 _outBufSizeAllocated;
|
||||||
UInt32 _inBufSizeAllocated;
|
size_t _inBufSize;
|
||||||
UInt32 _outBufSizeAllocated;
|
size_t _outBufSize;
|
||||||
UInt32 _inBufSize;
|
|
||||||
UInt32 _outBufSize;
|
HRESULT CreateBuffers ();
|
||||||
|
HRESULT CodeSpec (ISequentialInStream * inStream, ISequentialOutStream * outStream, ICompressProgressInfo * progress);
|
||||||
HRESULT CreateBuffers ();
|
HRESULT SetOutStreamSizeResume (const UInt64 * outSize);
|
||||||
HRESULT CodeSpec (ISequentialInStream * inStream, ISequentialOutStream * outStream, ICompressProgressInfo * progress);
|
HRESULT CreateDecompressor ();
|
||||||
HRESULT SetOutStreamSizeResume (const UInt64 * outSize);
|
|
||||||
HRESULT CreateDecompressor ();
|
// wrapper for different versions
|
||||||
|
void *ZB_createDCtx(void);
|
||||||
// wrapper for different versions
|
size_t ZB_freeDCtx(void *dctx);
|
||||||
void *ZB_createDCtx(void);
|
size_t ZB_decompressInit(void *dctx);
|
||||||
size_t ZB_freeDCtx(void *dctx);
|
size_t ZB_decompressContinue(void *dctx, void* dst, size_t *dstCapacityPtr, const void* src, size_t *srcSizePtr);
|
||||||
size_t ZB_decompressInit(void *dctx);
|
|
||||||
size_t ZB_decompressContinue(void *dctx, void* dst, size_t *dstCapacityPtr, const void* src, size_t *srcSizePtr);
|
public:
|
||||||
|
|
||||||
public:
|
MY_QUERYINTERFACE_BEGIN2 (ICompressCoder)
|
||||||
|
MY_QUERYINTERFACE_ENTRY (ICompressSetDecoderProperties2)
|
||||||
MY_QUERYINTERFACE_BEGIN2 (ICompressCoder)
|
MY_QUERYINTERFACE_ENTRY (ICompressSetBufSize)
|
||||||
MY_QUERYINTERFACE_ENTRY (ICompressSetDecoderProperties2)
|
#ifndef NO_READ_FROM_CODER
|
||||||
MY_QUERYINTERFACE_ENTRY (ICompressSetBufSize)
|
MY_QUERYINTERFACE_ENTRY (ICompressSetInStream)
|
||||||
#ifndef NO_READ_FROM_CODER
|
MY_QUERYINTERFACE_ENTRY (ICompressSetOutStreamSize)
|
||||||
MY_QUERYINTERFACE_ENTRY (ICompressSetInStream)
|
MY_QUERYINTERFACE_ENTRY (ISequentialInStream)
|
||||||
MY_QUERYINTERFACE_ENTRY (ICompressSetOutStreamSize)
|
#endif
|
||||||
MY_QUERYINTERFACE_ENTRY (ISequentialInStream)
|
MY_QUERYINTERFACE_END
|
||||||
#endif
|
|
||||||
MY_QUERYINTERFACE_END
|
MY_ADDREF_RELEASE
|
||||||
|
STDMETHOD (Code)(ISequentialInStream * inStream, ISequentialOutStream * outStream, const UInt64 * inSize, const UInt64 * outSize, ICompressProgressInfo * progress);
|
||||||
MY_ADDREF_RELEASE
|
STDMETHOD (SetDecoderProperties2) (const Byte * data, UInt32 size);
|
||||||
STDMETHOD (Code)(ISequentialInStream * inStream, ISequentialOutStream * outStream, const UInt64 * inSize, const UInt64 * outSize, ICompressProgressInfo * progress);
|
STDMETHOD (SetOutStreamSize) (const UInt64 * outSize);
|
||||||
STDMETHOD (SetDecoderProperties2) (const Byte * data, UInt32 size);
|
STDMETHOD (SetInBufSize) (UInt32 streamIndex, UInt32 size);
|
||||||
STDMETHOD (SetOutStreamSize) (const UInt64 * outSize);
|
STDMETHOD (SetOutBufSize) (UInt32 streamIndex, UInt32 size);
|
||||||
STDMETHOD (SetInBufSize) (UInt32 streamIndex, UInt32 size);
|
|
||||||
STDMETHOD (SetOutBufSize) (UInt32 streamIndex, UInt32 size);
|
#ifndef NO_READ_FROM_CODER
|
||||||
|
STDMETHOD (SetInStream) (ISequentialInStream * inStream);
|
||||||
#ifndef NO_READ_FROM_CODER
|
STDMETHOD (ReleaseInStream) ();
|
||||||
STDMETHOD (SetInStream) (ISequentialInStream * inStream);
|
STDMETHOD (Read) (void *data, UInt32 size, UInt32 * processedSize);
|
||||||
STDMETHOD (ReleaseInStream) ();
|
HRESULT CodeResume (ISequentialOutStream * outStream, const UInt64 * outSize, ICompressProgressInfo * progress);
|
||||||
STDMETHOD (Read) (void *data, UInt32 size, UInt32 * processedSize);
|
|
||||||
HRESULT CodeResume (ISequentialOutStream * outStream, const UInt64 * outSize, ICompressProgressInfo * progress);
|
UInt64 GetInputProcessedSize () const { return _inSizeProcessed; }
|
||||||
|
#endif
|
||||||
UInt64 GetInputProcessedSize () const { return _inSizeProcessed; }
|
|
||||||
#endif
|
CDecoder();
|
||||||
|
virtual ~CDecoder();
|
||||||
CDecoder();
|
};
|
||||||
virtual ~CDecoder();
|
|
||||||
};
|
}}
|
||||||
|
|
||||||
}}
|
|
||||||
|
|||||||
@@ -1,192 +1,190 @@
|
|||||||
// ZstdEncoder.cpp
|
// ZstdEncoder.cpp
|
||||||
// (C) 2016 Rich Geldreich, Tino Reichardt
|
// (C) 2016 Rich Geldreich, Tino Reichardt
|
||||||
|
|
||||||
#include "StdAfx.h"
|
#include "StdAfx.h"
|
||||||
#include "ZstdEncoder.h"
|
#include "ZstdEncoder.h"
|
||||||
|
|
||||||
// #define SHOW_DEBUG_INFO
|
// #define SHOW_DEBUG_INFO
|
||||||
#ifdef SHOW_DEBUG_INFO
|
#ifdef SHOW_DEBUG_INFO
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#define PRF(x) x
|
#define PRF(x) x
|
||||||
#else
|
#else
|
||||||
#define PRF(x)
|
#define PRF(x)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define ZSTD_DEFAULT_BUFFER_SIZE (1U << 22U)
|
#ifndef EXTRACT_ONLY
|
||||||
|
namespace NCompress {
|
||||||
#ifndef EXTRACT_ONLY
|
namespace NZSTD {
|
||||||
namespace NCompress {
|
|
||||||
namespace NZSTD {
|
CEncoder::CEncoder():
|
||||||
|
_state (NULL),
|
||||||
CEncoder::CEncoder():
|
_inBuf (NULL),
|
||||||
_state (NULL),
|
_outBuf (NULL),
|
||||||
_inBuf (NULL),
|
_inPos (0),
|
||||||
_outBuf (NULL),
|
_inSize (0),
|
||||||
_inPos (0),
|
_inBufSizeAllocated (0),
|
||||||
_inSize (0),
|
_outBufSizeAllocated (0),
|
||||||
_inBufSizeAllocated (0),
|
_inBufSize (ZBUFF_recommendedCInSize()),
|
||||||
_outBufSizeAllocated (0),
|
_outBufSize (ZBUFF_recommendedCOutSize()),
|
||||||
_inBufSize (ZSTD_DEFAULT_BUFFER_SIZE),
|
_inSizeProcessed (0),
|
||||||
_outBufSize (ZSTD_DEFAULT_BUFFER_SIZE),
|
_outSizeProcessed (0)
|
||||||
_inSizeProcessed (0),
|
{
|
||||||
_outSizeProcessed (0)
|
_props.clear ();
|
||||||
{
|
}
|
||||||
_props.clear ();
|
|
||||||
}
|
CEncoder::~CEncoder ()
|
||||||
|
{
|
||||||
CEncoder::~CEncoder ()
|
if (_state)
|
||||||
{
|
ZBUFF_freeCCtx(_state);
|
||||||
if (_state)
|
|
||||||
ZBUFF_freeCCtx(_state);
|
MyFree (_inBuf);
|
||||||
|
MyFree (_outBuf);
|
||||||
MyFree (_inBuf);
|
}
|
||||||
MyFree (_outBuf);
|
|
||||||
}
|
STDMETHODIMP CEncoder::SetCoderProperties (const PROPID * propIDs,
|
||||||
|
const PROPVARIANT * coderProps, UInt32 numProps)
|
||||||
STDMETHODIMP CEncoder::SetCoderProperties (const PROPID * propIDs,
|
{
|
||||||
const PROPVARIANT * coderProps, UInt32 numProps)
|
_props.clear ();
|
||||||
{
|
|
||||||
_props.clear ();
|
for (UInt32 i = 0; i < numProps; i++)
|
||||||
|
{
|
||||||
for (UInt32 i = 0; i < numProps; i++)
|
const PROPVARIANT & prop = coderProps[i];
|
||||||
{
|
PROPID propID = propIDs[i];
|
||||||
const PROPVARIANT & prop = coderProps[i];
|
switch (propID)
|
||||||
PROPID propID = propIDs[i];
|
{
|
||||||
switch (propID)
|
case NCoderPropID::kLevel:
|
||||||
{
|
{
|
||||||
case NCoderPropID::kLevel:
|
if (prop.vt != VT_UI4)
|
||||||
{
|
return E_INVALIDARG;
|
||||||
if (prop.vt != VT_UI4)
|
|
||||||
return E_INVALIDARG;
|
_props._level = static_cast < Byte > (prop.ulVal);
|
||||||
|
Byte zstd_level = static_cast < Byte > (ZSTD_maxCLevel());
|
||||||
_props._level = static_cast < Byte > (prop.ulVal);
|
if (_props._level > zstd_level)
|
||||||
Byte zstd_level = static_cast < Byte > (ZSTD_maxCLevel());
|
_props._level = zstd_level;
|
||||||
if (_props._level > zstd_level)
|
|
||||||
_props._level = zstd_level;
|
break;
|
||||||
|
}
|
||||||
break;
|
default:
|
||||||
}
|
{
|
||||||
default:
|
break;
|
||||||
{
|
}
|
||||||
break;
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
return S_OK;
|
||||||
|
}
|
||||||
return S_OK;
|
|
||||||
}
|
STDMETHODIMP CEncoder::WriteCoderProperties (ISequentialOutStream * outStream)
|
||||||
|
{
|
||||||
STDMETHODIMP CEncoder::WriteCoderProperties (ISequentialOutStream * outStream)
|
return WriteStream (outStream, &_props, sizeof (_props));
|
||||||
{
|
}
|
||||||
return WriteStream (outStream, &_props, sizeof (_props));
|
|
||||||
}
|
HRESULT CEncoder::CreateBuffers ()
|
||||||
|
{
|
||||||
HRESULT CEncoder::CreateBuffers ()
|
if (_inBuf == 0 || _inBufSize != _inBufSizeAllocated)
|
||||||
{
|
{
|
||||||
if (_inBuf == 0 || _inBufSize != _inBufSizeAllocated)
|
MyFree (_inBuf);
|
||||||
{
|
_inBuf = (Byte *) MyAlloc (_inBufSize);
|
||||||
MyFree (_inBuf);
|
if (_inBuf == 0)
|
||||||
_inBuf = (Byte *) MyAlloc (_inBufSize);
|
return E_OUTOFMEMORY;
|
||||||
if (_inBuf == 0)
|
_inBufSizeAllocated = (UInt32)_inBufSize;
|
||||||
return E_OUTOFMEMORY;
|
}
|
||||||
_inBufSizeAllocated = _inBufSize;
|
|
||||||
}
|
if (_outBuf == 0 || _outBufSize != _outBufSizeAllocated)
|
||||||
|
{
|
||||||
if (_outBuf == 0 || _outBufSize != _outBufSizeAllocated)
|
MyFree (_outBuf);
|
||||||
{
|
_outBuf = (Byte *) MyAlloc (_outBufSize);
|
||||||
MyFree (_outBuf);
|
if (_outBuf == 0)
|
||||||
_outBuf = (Byte *) MyAlloc (_outBufSize);
|
return E_OUTOFMEMORY;
|
||||||
if (_outBuf == 0)
|
_outBufSizeAllocated = (UInt32)_outBufSize;
|
||||||
return E_OUTOFMEMORY;
|
}
|
||||||
_outBufSizeAllocated = _outBufSize;
|
|
||||||
}
|
return S_OK;
|
||||||
|
}
|
||||||
return S_OK;
|
|
||||||
}
|
HRESULT CEncoder::CreateCompressor ()
|
||||||
|
{
|
||||||
HRESULT CEncoder::CreateCompressor ()
|
if (!_state) {
|
||||||
{
|
_state = ZBUFF_createCCtx();
|
||||||
if (!_state) {
|
if (!_state)
|
||||||
_state = ZBUFF_createCCtx();
|
return S_FALSE;
|
||||||
if (!_state)
|
}
|
||||||
return S_FALSE;
|
|
||||||
}
|
if (ZBUFF_compressInit(_state, _props._level))
|
||||||
|
return S_FALSE;
|
||||||
if (ZBUFF_compressInit(_state, _props._level))
|
|
||||||
return S_FALSE;
|
return S_OK;
|
||||||
|
}
|
||||||
return S_OK;
|
|
||||||
}
|
STDMETHODIMP CEncoder::Code (ISequentialInStream * inStream,
|
||||||
|
ISequentialOutStream * outStream, const UInt64 * /* inSize */ ,
|
||||||
STDMETHODIMP CEncoder::Code (ISequentialInStream * inStream,
|
const UInt64 * /* outSize */ , ICompressProgressInfo * progress)
|
||||||
ISequentialOutStream * outStream, const UInt64 * /* inSize */ ,
|
{
|
||||||
const UInt64 * /* outSize */ , ICompressProgressInfo * progress)
|
RINOK (CreateCompressor());
|
||||||
{
|
RINOK (CreateBuffers());
|
||||||
RINOK (CreateCompressor());
|
|
||||||
RINOK (CreateBuffers());
|
UInt64 startInProgress = _inSizeProcessed;
|
||||||
|
UInt64 startOutProgress = _outSizeProcessed;
|
||||||
UInt64 startInProgress = _inSizeProcessed;
|
|
||||||
UInt64 startOutProgress = _outSizeProcessed;
|
for (;;)
|
||||||
|
{
|
||||||
for (;;)
|
bool eofFlag = false;
|
||||||
{
|
if (_inPos == _inSize)
|
||||||
bool eofFlag = false;
|
{
|
||||||
if (_inPos == _inSize)
|
_inPos = _inSize = 0;
|
||||||
{
|
RINOK (inStream->Read (_inBuf, _inBufSizeAllocated, &_inSize));
|
||||||
_inPos = _inSize = 0;
|
if (!_inSize)
|
||||||
RINOK (inStream->Read (_inBuf, _inBufSizeAllocated, &_inSize));
|
eofFlag = true;
|
||||||
if (!_inSize)
|
}
|
||||||
eofFlag = true;
|
|
||||||
}
|
Byte *pIn_bytes = _inBuf + _inPos;
|
||||||
|
size_t num_in_bytes = _inSize - _inPos;
|
||||||
Byte *pIn_bytes = _inBuf + _inPos;
|
Byte *pOut_bytes = _outBuf;
|
||||||
size_t num_in_bytes = _inSize - _inPos;
|
size_t num_out_bytes = _outBufSize;
|
||||||
Byte *pOut_bytes = _outBuf;
|
|
||||||
size_t num_out_bytes = _outBufSize;
|
size_t comp_status;
|
||||||
|
bool comp_finished = false;
|
||||||
size_t comp_status;
|
|
||||||
bool comp_finished = false;
|
if (eofFlag)
|
||||||
|
{
|
||||||
if (eofFlag)
|
comp_status = ZBUFF_compressEnd (_state, pOut_bytes, &num_out_bytes);
|
||||||
{
|
comp_finished = (comp_status == 0);
|
||||||
comp_status = ZBUFF_compressEnd (_state, pOut_bytes, &num_out_bytes);
|
}
|
||||||
comp_finished = (comp_status == 0);
|
else
|
||||||
}
|
{
|
||||||
else
|
comp_status = ZBUFF_compressContinue(_state, pOut_bytes, &num_out_bytes, pIn_bytes, &num_in_bytes);
|
||||||
{
|
}
|
||||||
comp_status = ZBUFF_compressContinue(_state, pOut_bytes, &num_out_bytes, pIn_bytes, &num_in_bytes);
|
|
||||||
}
|
bool comp_failed = ZBUFF_isError (comp_status) != 0;
|
||||||
|
|
||||||
bool comp_failed = ZBUFF_isError (comp_status) != 0;
|
if (num_in_bytes)
|
||||||
|
{
|
||||||
if (num_in_bytes)
|
_inPos += (UInt32) num_in_bytes;
|
||||||
{
|
_inSizeProcessed += (UInt32) num_in_bytes;
|
||||||
_inPos += (UInt32) num_in_bytes;
|
}
|
||||||
_inSizeProcessed += (UInt32) num_in_bytes;
|
|
||||||
}
|
if (num_out_bytes)
|
||||||
|
{
|
||||||
if (num_out_bytes)
|
_outSizeProcessed += num_out_bytes;
|
||||||
{
|
RINOK (WriteStream (outStream, _outBuf, num_out_bytes));
|
||||||
_outSizeProcessed += num_out_bytes;
|
}
|
||||||
RINOK (WriteStream (outStream, _outBuf, num_out_bytes));
|
|
||||||
}
|
if (comp_failed)
|
||||||
|
return S_FALSE;
|
||||||
if (comp_failed)
|
|
||||||
return S_FALSE;
|
if (comp_finished)
|
||||||
|
break;
|
||||||
if (comp_finished)
|
|
||||||
break;
|
UInt64 inSize = _inSizeProcessed - startInProgress;
|
||||||
|
UInt64 outSize = _outSizeProcessed - startOutProgress;
|
||||||
UInt64 inSize = _inSizeProcessed - startInProgress;
|
if (progress)
|
||||||
UInt64 outSize = _outSizeProcessed - startOutProgress;
|
{
|
||||||
if (progress)
|
RINOK (progress->SetRatioInfo (&inSize, &outSize));
|
||||||
{
|
}
|
||||||
RINOK (progress->SetRatioInfo (&inSize, &outSize));
|
}
|
||||||
}
|
|
||||||
}
|
return S_OK;
|
||||||
|
}
|
||||||
return S_OK;
|
|
||||||
}
|
}}
|
||||||
|
#endif
|
||||||
}}
|
|
||||||
#endif
|
|
||||||
|
|||||||
@@ -1,77 +1,75 @@
|
|||||||
// ZstdEncoder.h
|
// ZstdEncoder.h
|
||||||
// (C) 2016 Rich Geldreich, Tino Reichardt
|
// (C) 2016 Rich Geldreich, Tino Reichardt
|
||||||
|
|
||||||
#include "StdAfx.h"
|
#define ZSTD_STATIC_LINKING_ONLY
|
||||||
|
#include "../../../C/Alloc.h"
|
||||||
#define ZSTD_STATIC_LINKING_ONLY
|
#include "../../../C/ZStd/zstd.h"
|
||||||
#include "../../../C/Alloc.h"
|
#include "../../../C/ZStd/zbuff.h"
|
||||||
#include "../../../C/ZStd/zstd.h"
|
|
||||||
#include "../../../C/ZStd/zbuff.h"
|
#include "../../Common/Common.h"
|
||||||
|
#include "../../Common/MyCom.h"
|
||||||
#include "../../Common/Common.h"
|
#include "../ICoder.h"
|
||||||
#include "../../Common/MyCom.h"
|
#include "../Common/StreamUtils.h"
|
||||||
#include "../ICoder.h"
|
|
||||||
#include "../Common/StreamUtils.h"
|
#ifndef EXTRACT_ONLY
|
||||||
|
namespace NCompress {
|
||||||
#ifndef EXTRACT_ONLY
|
namespace NZSTD {
|
||||||
namespace NCompress {
|
|
||||||
namespace NZSTD {
|
struct CProps
|
||||||
|
{
|
||||||
struct CProps
|
CProps() { clear (); }
|
||||||
{
|
void clear ()
|
||||||
CProps() { clear (); }
|
{
|
||||||
void clear ()
|
memset (this, 0, sizeof (*this));
|
||||||
{
|
_ver_major = ZSTD_VERSION_MAJOR;
|
||||||
memset (this, 0, sizeof (*this));
|
_ver_minor = ZSTD_VERSION_MINOR;
|
||||||
_ver_major = ZSTD_VERSION_MAJOR;
|
_level = 3;
|
||||||
_ver_minor = ZSTD_VERSION_MINOR;
|
}
|
||||||
_level = 3;
|
|
||||||
}
|
Byte _ver_major;
|
||||||
|
Byte _ver_minor;
|
||||||
Byte _ver_major;
|
Byte _level;
|
||||||
Byte _ver_minor;
|
Byte _reserved[2];
|
||||||
Byte _level;
|
};
|
||||||
Byte _reserved[2];
|
|
||||||
};
|
class CEncoder:
|
||||||
|
public ICompressCoder,
|
||||||
class CEncoder:
|
public ICompressSetCoderProperties,
|
||||||
public ICompressCoder,
|
public ICompressWriteCoderProperties,
|
||||||
public ICompressSetCoderProperties,
|
public CMyUnknownImp
|
||||||
public ICompressWriteCoderProperties,
|
{
|
||||||
public CMyUnknownImp
|
ZBUFF_CCtx *_state;
|
||||||
{
|
|
||||||
ZBUFF_CCtx *_state;
|
CProps _props;
|
||||||
|
|
||||||
CProps _props;
|
Byte *_inBuf;
|
||||||
|
Byte *_outBuf;
|
||||||
Byte *_inBuf;
|
UInt32 _inPos;
|
||||||
Byte *_outBuf;
|
UInt32 _inSize;
|
||||||
UInt32 _inPos;
|
|
||||||
UInt32 _inSize;
|
UInt32 _inBufSizeAllocated;
|
||||||
|
UInt32 _outBufSizeAllocated;
|
||||||
UInt32 _inBufSizeAllocated;
|
size_t _inBufSize;
|
||||||
UInt32 _outBufSizeAllocated;
|
size_t _outBufSize;
|
||||||
UInt32 _inBufSize;
|
|
||||||
UInt32 _outBufSize;
|
UInt64 _inSizeProcessed;
|
||||||
|
UInt64 _outSizeProcessed;
|
||||||
UInt64 _inSizeProcessed;
|
|
||||||
UInt64 _outSizeProcessed;
|
HRESULT CreateCompressor ();
|
||||||
|
HRESULT CreateBuffers ();
|
||||||
HRESULT CreateCompressor ();
|
|
||||||
HRESULT CreateBuffers ();
|
public:
|
||||||
|
MY_UNKNOWN_IMP2 (ICompressSetCoderProperties, ICompressWriteCoderProperties)
|
||||||
public:
|
STDMETHOD (Code) (ISequentialInStream * inStream, ISequentialOutStream *
|
||||||
MY_UNKNOWN_IMP2 (ICompressSetCoderProperties, ICompressWriteCoderProperties)
|
outStream, const UInt64 * inSize, const UInt64 * outSize,
|
||||||
STDMETHOD (Code) (ISequentialInStream * inStream, ISequentialOutStream *
|
ICompressProgressInfo * progress);
|
||||||
outStream, const UInt64 * inSize, const UInt64 * outSize,
|
STDMETHOD (SetCoderProperties) (const PROPID * propIDs,
|
||||||
ICompressProgressInfo * progress);
|
const PROPVARIANT *props, UInt32 numProps);
|
||||||
STDMETHOD (SetCoderProperties) (const PROPID * propIDs,
|
STDMETHOD (WriteCoderProperties) (ISequentialOutStream * outStream);
|
||||||
const PROPVARIANT *props, UInt32 numProps);
|
|
||||||
STDMETHOD (WriteCoderProperties) (ISequentialOutStream * outStream);
|
CEncoder();
|
||||||
|
virtual ~CEncoder();
|
||||||
CEncoder();
|
};
|
||||||
virtual ~CEncoder();
|
|
||||||
};
|
}}
|
||||||
|
#endif
|
||||||
}}
|
|
||||||
#endif
|
|
||||||
|
|||||||
@@ -1,18 +1,18 @@
|
|||||||
// ZstdRegister.cpp
|
// ZstdRegister.cpp
|
||||||
// (C) 2016 Rich Geldreich, Tino Reichardt
|
// (C) 2016 Rich Geldreich, Tino Reichardt
|
||||||
|
|
||||||
#include "StdAfx.h"
|
#include "StdAfx.h"
|
||||||
|
|
||||||
#include "../Common/RegisterCodec.h"
|
#include "../Common/RegisterCodec.h"
|
||||||
|
|
||||||
#include "ZstdDecoder.h"
|
#include "ZstdDecoder.h"
|
||||||
|
|
||||||
#ifndef EXTRACT_ONLY
|
#ifndef EXTRACT_ONLY
|
||||||
#include "ZstdEncoder.h"
|
#include "ZstdEncoder.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
REGISTER_CODEC_E(
|
REGISTER_CODEC_E(
|
||||||
ZSTD,
|
ZSTD,
|
||||||
NCompress::NZSTD::CDecoder(),
|
NCompress::NZSTD::CDecoder(),
|
||||||
NCompress::NZSTD::CEncoder(),
|
NCompress::NZSTD::CEncoder(),
|
||||||
0x4F71101, "ZSTD")
|
0x4F71101, "ZSTD")
|
||||||
|
|||||||
14
CPP/7zip/zstd.mak
Normal file
14
CPP/7zip/zstd.mak
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
|
||||||
|
COMPRESS_OBJS = $(COMPRESS_OBJS) \
|
||||||
|
$O\ZstdDecoder.obj \
|
||||||
|
$O\ZstdEncoder.obj \
|
||||||
|
$O\ZstdRegister.obj \
|
||||||
|
|
||||||
|
ZSTD_OBJS = \
|
||||||
|
$O\entropy_common.obj \
|
||||||
|
$O\fse_decompress.obj \
|
||||||
|
$O\huf_decompress.obj \
|
||||||
|
$O\zbuff_decompress.obj \
|
||||||
|
$O\zstd_common.obj \
|
||||||
|
$O\zstd_decompress.obj \
|
||||||
|
$O\xxhash.obj \
|
||||||
@@ -1,47 +1,60 @@
|
|||||||
@echo on
|
@echo on
|
||||||
|
|
||||||
set ROOT=Z:\projekte\7zip-ZStd\git\CPP\7zip
|
set ROOT=Z:\projekte\7zip-ZStd\git\CPP\7zip
|
||||||
|
set OUTDIR=%ROOT%\bin32
|
||||||
|
mkdir %OUTDIR%
|
||||||
|
|
||||||
set OPTS=MY_STATIC_LINK=1
|
set OPTS=MY_STATIC_LINK=1
|
||||||
set LFLAGS=/SUBSYSTEM:WINDOWS,"5.01"
|
set LFLAGS=/SUBSYSTEM:WINDOWS,"5.01"
|
||||||
|
|
||||||
mkdir %ROOT%\bin32
|
cd %ROOT%\Bundles\Format7z
|
||||||
|
nmake %OPTS%
|
||||||
|
copy O\7za.dll %OUTDIR%\7za.dll
|
||||||
|
|
||||||
|
cd %ROOT%\Bundles\Format7zExtract
|
||||||
|
nmake %OPTS%
|
||||||
|
copy O\7zxa.dll %OUTDIR%\7zxa.dll
|
||||||
|
|
||||||
|
cd %ROOT%\Bundles\Format7zExtractR
|
||||||
|
nmake %OPTS%
|
||||||
|
copy O\7zxr.dll %OUTDIR%\7zxr.dll
|
||||||
|
|
||||||
cd %ROOT%\Bundles\Format7zF
|
cd %ROOT%\Bundles\Format7zF
|
||||||
nmake %OPTS%
|
nmake %OPTS%
|
||||||
copy O\7z.dll %ROOT%\bin32\7z.dll
|
copy O\7z.dll %OUTDIR%\7z.dll
|
||||||
|
|
||||||
cd %ROOT%\Bundles\Format7zZStd
|
cd %ROOT%\Bundles\Format7zR
|
||||||
nmake %OPTS%
|
nmake %OPTS%
|
||||||
copy O\7z.dll %ROOT%\bin32\7za.dll
|
copy O\7zra.dll %OUTDIR%\7zra.dll
|
||||||
|
|
||||||
cd %ROOT%\UI\FileManager
|
cd %ROOT%\UI\FileManager
|
||||||
nmake %OPTS%
|
nmake %OPTS%
|
||||||
copy O\7zFM.exe %ROOT%\bin32\7zFM.exe
|
copy O\7zFM.exe %OUTDIR%\7zFM.exe
|
||||||
|
|
||||||
cd %ROOT%\UI\GUI
|
cd %ROOT%\UI\GUI
|
||||||
nmake %OPTS%
|
nmake %OPTS%
|
||||||
copy O\7zG.exe %ROOT%\bin32\7zG.exe
|
copy O\7zG.exe %OUTDIR%\7zG.exe
|
||||||
|
|
||||||
cd %ROOT%\Bundles\SFXWin
|
cd %ROOT%\Bundles\SFXWin
|
||||||
nmake %OPTS%
|
nmake %OPTS%
|
||||||
copy O\7z.sfx %ROOT%\bin32\7z.sfx
|
copy O\7z.sfx %OUTDIR%\7z.sfx
|
||||||
|
|
||||||
cd %ROOT%\..\..\C\Util\7zipInstall
|
cd %ROOT%\..\..\C\Util\7zipInstall
|
||||||
nmake %OPTS%
|
nmake %OPTS%
|
||||||
copy O\7zipInstall.exe %ROOT%\bin32\Install-x32.exe
|
copy O\7zipInstall.exe %OUTDIR%\Install-x32.exe
|
||||||
|
|
||||||
cd %ROOT%\..\..\C\Util\7zipUninstall
|
cd %ROOT%\..\..\C\Util\7zipUninstall
|
||||||
nmake %OPTS%
|
nmake %OPTS%
|
||||||
copy O\7zipUninstall.exe %ROOT%\bin32\Uninstall.exe
|
copy O\7zipUninstall.exe %OUTDIR%\Uninstall.exe
|
||||||
|
|
||||||
set LFLAGS=/SUBSYSTEM:CONSOLE,"5.01"
|
set LFLAGS=/SUBSYSTEM:CONSOLE,"5.01"
|
||||||
cd %ROOT%\UI\Console
|
cd %ROOT%\UI\Console
|
||||||
nmake %OPTS%
|
nmake %OPTS%
|
||||||
copy O\7z.exe %ROOT%\bin32\7z.exe
|
copy O\7z.exe %OUTDIR%\7z.exe
|
||||||
|
|
||||||
cd %ROOT%\Bundles\SFXCon
|
cd %ROOT%\Bundles\SFXCon
|
||||||
nmake %OPTS%
|
nmake %OPTS%
|
||||||
copy O\7zCon.sfx %ROOT%\bin32\7zCon.sfx
|
copy O\7zCon.sfx %OUTDIR%\7zCon.sfx
|
||||||
|
|
||||||
:ende
|
:ende
|
||||||
cd %ROOT%\..
|
cd %ROOT%\..
|
||||||
|
|||||||
@@ -1,46 +1,62 @@
|
|||||||
@echo on
|
@echo on
|
||||||
|
|
||||||
set ROOT=Z:\projekte\7zip-ZStd\git\CPP\7zip
|
set ROOT=Z:\projekte\7zip-ZStd\git\CPP\7zip
|
||||||
|
set OUTDIR=%ROOT%\bin64
|
||||||
|
mkdir %OUTDIR%
|
||||||
|
|
||||||
set OPTS=CPU=AMD64 MY_STATIC_LINK=1
|
set OPTS=CPU=AMD64 MY_STATIC_LINK=1
|
||||||
set LFLAGS=/SUBSYSTEM:WINDOWS,"5.02"
|
set LFLAGS=/SUBSYSTEM:WINDOWS,"5.02"
|
||||||
|
|
||||||
mkdir %ROOT%\bin64
|
cd %ROOT%\Bundles\Format7z
|
||||||
|
nmake %OPTS%
|
||||||
|
copy O\7za.dll %OUTDIR%\7za.dll
|
||||||
|
|
||||||
|
goto ende
|
||||||
|
|
||||||
|
cd %ROOT%\Bundles\Format7zExtract
|
||||||
|
nmake %OPTS%
|
||||||
|
copy O\7zxa.dll %OUTDIR%\7zxa.dll
|
||||||
|
|
||||||
|
cd %ROOT%\Bundles\Format7zExtractR
|
||||||
|
nmake %OPTS%
|
||||||
|
copy O\7zxr.dll %OUTDIR%\7zxr.dll
|
||||||
|
|
||||||
cd %ROOT%\Bundles\Format7zF
|
cd %ROOT%\Bundles\Format7zF
|
||||||
nmake %OPTS%
|
nmake %OPTS%
|
||||||
copy AMD64\7z.dll %ROOT%\bin64\7z.dll
|
copy O\7z.dll %OUTDIR%\7z.dll
|
||||||
|
|
||||||
cd %ROOT%\Bundles\Format7zZStd
|
cd %ROOT%\Bundles\Format7zR
|
||||||
nmake %OPTS%
|
nmake %OPTS%
|
||||||
copy AMD64\7z.dll %ROOT%\bin64\7za.dll
|
copy O\7zra.dll %OUTDIR%\7zra.dll
|
||||||
|
|
||||||
cd %ROOT%\UI\FileManager
|
cd %ROOT%\UI\FileManager
|
||||||
nmake %OPTS%
|
nmake %OPTS%
|
||||||
copy AMD64\7zFM.exe %ROOT%\bin64\7zFM.exe
|
copy AMD64\7zFM.exe %OUTDIR%\7zFM.exe
|
||||||
|
|
||||||
cd %ROOT%\UI\GUI
|
cd %ROOT%\UI\GUI
|
||||||
nmake %OPTS%
|
nmake %OPTS%
|
||||||
copy AMD64\7zG.exe %ROOT%\bin64\7zG.exe
|
copy AMD64\7zG.exe %OUTDIR%\7zG.exe
|
||||||
|
|
||||||
cd %ROOT%\Bundles\SFXWin
|
cd %ROOT%\Bundles\SFXWin
|
||||||
nmake %OPTS%
|
nmake %OPTS%
|
||||||
copy AMD64\7z.sfx %ROOT%\bin64\7z.sfx
|
copy AMD64\7z.sfx %OUTDIR%\7z.sfx
|
||||||
|
|
||||||
cd %ROOT%\..\..\C\Util\7zipInstall
|
cd %ROOT%\..\..\C\Util\7zipInstall
|
||||||
nmake %OPTS%
|
nmake %OPTS%
|
||||||
copy AMD64\7zipInstall.exe %ROOT%\bin64\Install-x64.exe
|
copy AMD64\7zipInstall.exe %OUTDIR%\Install-x64.exe
|
||||||
|
|
||||||
cd %ROOT%\..\..\C\Util\7zipUninstall
|
cd %ROOT%\..\..\C\Util\7zipUninstall
|
||||||
nmake %OPTS%
|
nmake %OPTS%
|
||||||
copy AMD64\7zipUninstall.exe %ROOT%\bin64\Uninstall.exe
|
copy AMD64\7zipUninstall.exe %OUTDIR%\Uninstall.exe
|
||||||
|
|
||||||
set LFLAGS=/SUBSYSTEM:CONSOLE,"5.02"
|
set LFLAGS=/SUBSYSTEM:CONSOLE,"5.02"
|
||||||
cd %ROOT%\UI\Console
|
cd %ROOT%\UI\Console
|
||||||
nmake %OPTS%
|
nmake %OPTS%
|
||||||
copy AMD64\7z.exe %ROOT%\bin64\7z.exe
|
copy AMD64\7z.exe %OUTDIR%\7z.exe
|
||||||
|
|
||||||
cd %ROOT%\Bundles\SFXCon
|
cd %ROOT%\Bundles\SFXCon
|
||||||
nmake %OPTS%
|
nmake %OPTS%
|
||||||
copy AMD64\7zCon.sfx %ROOT%\bin64\7zCon.sfx
|
copy AMD64\7zCon.sfx %OUTDIR%\7zCon.sfx
|
||||||
|
|
||||||
|
:ende
|
||||||
cd %ROOT%\..
|
cd %ROOT%\..
|
||||||
|
|||||||
Reference in New Issue
Block a user