mirror of
https://github.com/Xevion/easy7zip.git
synced 2025-12-06 15:14:59 -06:00
Update fast-lzma2
This commit is contained in:
@@ -249,7 +249,7 @@ typedef struct {
|
||||
* The radix match finder allows compressed data to be stored in its match table during encoding.
|
||||
* Applications may call streaming compression functions with output == NULL. In this case,
|
||||
* when the function returns 1, the compressed data must be read from the internal buffers.
|
||||
* Call FL2_getNextCStreamBuffer() repeatedly until it returns 0.
|
||||
* Call FL2_getNextCompressedBuffer() repeatedly until it returns 0.
|
||||
* Each call returns buffer information in the FL2_inBuffer parameter. Applications typically will
|
||||
* passed this to an I/O write function or downstream filter.
|
||||
* Alternately, applications may pass an FL2_outBuffer object pointer to receive the output. In this
|
||||
@@ -279,11 +279,12 @@ FL2LIB_API size_t FL2LIB_CALL FL2_initCStream(FL2_CStream* fcs, int compressionL
|
||||
|
||||
/*! FL2_setCStreamTimeout() :
|
||||
* Sets a timeout in milliseconds. Zero disables the timeout (default). If a nonzero timout is set, functions
|
||||
* FL2_compressStream(), FL2_updateDictionary(), FL2_getNextCStreamBuffer(), FL2_flushStream(), and
|
||||
* FL2_endStream() may return a timeout code before compression of the current dictionary of data
|
||||
* completes. FL2_isError() returns true for the timeout code, so check the code with FL2_isTimedOut() before
|
||||
* testing for errors. With the exception of FL2_updateDictionary(), the above functions may be called again
|
||||
* to wait for completion. A typical application for timeouts is to update the user on compression progress. */
|
||||
* FL2_compressStream(), FL2_getDictionaryBuffer(), FL2_updateDictionary(), FL2_getNextCompressedBuffer(),
|
||||
* FL2_flushStream(), and FL2_endStream() may return a timeout code before compression of the current
|
||||
* dictionary of data completes. FL2_isError() returns true for the timeout code, so check the code with
|
||||
* FL2_isTimedOut() before testing for errors. With the exception of FL2_updateDictionary(), the above
|
||||
* functions may be called again to wait for completion. A typical application for timeouts is to update the
|
||||
* user on compression progress. */
|
||||
FL2LIB_API size_t FL2LIB_CALL FL2_setCStreamTimeout(FL2_CStream * fcs, unsigned timeout);
|
||||
|
||||
/*! FL2_compressStream() :
|
||||
@@ -295,6 +296,12 @@ FL2LIB_API size_t FL2LIB_CALL FL2_setCStreamTimeout(FL2_CStream * fcs, unsigned
|
||||
* Returns 1 to indicate compressed data must be read (or output is full), or 0 otherwise. */
|
||||
FL2LIB_API size_t FL2LIB_CALL FL2_compressStream(FL2_CStream* fcs, FL2_outBuffer *output, FL2_inBuffer* input);
|
||||
|
||||
/*! FL2_copyCStreamOutput() :
|
||||
* Copies compressed data to the output buffer until the buffer is full or all available data is copied.
|
||||
* If asynchronous compression is in progress, the function returns 0 without waiting.
|
||||
* Returns 1 to indicate some compressed data remains, or 0 otherwise. */
|
||||
FL2LIB_API size_t FL2LIB_CALL FL2_copyCStreamOutput(FL2_CStream* fcs, FL2_outBuffer *output);
|
||||
|
||||
/*** Push/pull functions ***/
|
||||
|
||||
/*! FL2_getDictionaryBuffer() :
|
||||
@@ -308,12 +315,12 @@ FL2LIB_API size_t FL2LIB_CALL FL2_getDictionaryBuffer(FL2_CStream* fcs, FL2_dict
|
||||
* was filled. Returns 1 to indicate compressed data must be read, 0 if not, or an error code. */
|
||||
FL2LIB_API size_t FL2LIB_CALL FL2_updateDictionary(FL2_CStream* fcs, size_t addedSize);
|
||||
|
||||
/*! FL2_getNextCStreamBuffer() :
|
||||
/*! FL2_getNextCompressedBuffer() :
|
||||
* Returns a buffer containing a slice of the compressed data. Call this function and process the data
|
||||
* until the function returns zero. In most cases it will return a buffer for each compression thread
|
||||
* used. It is sometimes less but never more than nbThreads. If asynchronous compression is in progress,
|
||||
* this function will wait for completion before returning, or it will return the timeout code. */
|
||||
FL2LIB_API size_t FL2LIB_CALL FL2_getNextCStreamBuffer(FL2_CStream* fcs, FL2_cBuffer* cbuf);
|
||||
FL2LIB_API size_t FL2LIB_CALL FL2_getNextCompressedBuffer(FL2_CStream* fcs, FL2_cBuffer* cbuf);
|
||||
|
||||
/******/
|
||||
|
||||
@@ -368,17 +375,12 @@ FL2LIB_API size_t FL2LIB_CALL FL2_endStream(FL2_CStream* fcs, FL2_outBuffer *out
|
||||
* The function will update both `pos` fields.
|
||||
* If `input.pos < input.size`, some input has not been consumed.
|
||||
* It's up to the caller to present again the remaining data.
|
||||
* More data must be loaded if `input.pos + LZMA_REQUIRED_INPUT_MAX >= input.size`. In this case,
|
||||
* move the remaining input (<= LZMA_REQUIRED_INPUT_MAX bytes) to the start of the buffer and
|
||||
* load new data after it.
|
||||
* If `output.pos < output.size`, decoder has flushed everything it could.
|
||||
* @return : 0 when a stream is completely decoded and fully flushed,
|
||||
* 1, which means there is still some decoding to do to complete the stream,
|
||||
* or an error code, which can be tested using FL2_isError().
|
||||
* *******************************************************************************/
|
||||
|
||||
#define LZMA_REQUIRED_INPUT_MAX 20
|
||||
|
||||
typedef struct FL2_DStream_s FL2_DStream;
|
||||
|
||||
/*===== FL2_DStream management functions =====*/
|
||||
@@ -434,9 +436,7 @@ FL2LIB_API size_t FL2LIB_CALL FL2_initDStream_withProp(FL2_DStream* fds, unsigne
|
||||
* Reads data from input and decompresses to output.
|
||||
* Returns 1 if the stream is unfinished, 0 if the terminator was encountered (he'll be back)
|
||||
* and all data was written to output, or an error code. Call this function repeatedly if
|
||||
* necessary, removing data from output and/or loading data into input before each call.
|
||||
* Note the requirement for LZMA_REQUIRED_INPUT_MAX bytes of input if the input data is
|
||||
* incomplete (see intro above). */
|
||||
* necessary, removing data from output and/or loading data into input before each call. */
|
||||
FL2LIB_API size_t FL2LIB_CALL FL2_decompressStream(FL2_DStream* fds, FL2_outBuffer* output, FL2_inBuffer* input);
|
||||
|
||||
/*-***************************************************************************
|
||||
|
||||
@@ -446,7 +446,7 @@ static size_t FL2_beginFrame(FL2_CCtx* const cctx, size_t const dictReduce)
|
||||
if (FL2_initEncoders(cctx) != 0) /* Create hash objects together, leaving the (large) match table last */
|
||||
return FL2_ERROR(memory_allocation);
|
||||
|
||||
if (!cctx->matchTable) {
|
||||
if (cctx->matchTable == NULL) {
|
||||
cctx->matchTable = RMF_createMatchTable(&cctx->params.rParams, dictReduce, cctx->jobCount);
|
||||
if (cctx->matchTable == NULL)
|
||||
return FL2_ERROR(memory_allocation);
|
||||
@@ -938,7 +938,7 @@ static size_t FL2_compressStream_internal(FL2_CStream* const fcs, int const endi
|
||||
/* Copy the compressed output stored in the match table buffer.
|
||||
* One slice exists per thread.
|
||||
*/
|
||||
static void FL2_copyCStreamOutput(FL2_CStream* fcs, FL2_outBuffer *output)
|
||||
FL2LIB_API size_t FL2LIB_CALL FL2_copyCStreamOutput(FL2_CStream* fcs, FL2_outBuffer *output)
|
||||
{
|
||||
for (; fcs->outThread < fcs->threadCount; ++fcs->outThread) {
|
||||
const BYTE* const outBuf = RMF_getTableAsOutputBuffer(fcs->matchTable, fcs->jobs[fcs->outThread].block.start) + fcs->outPos;
|
||||
@@ -956,10 +956,11 @@ static void FL2_copyCStreamOutput(FL2_CStream* fcs, FL2_outBuffer *output)
|
||||
|
||||
/* If the slice is not flushed, the output is full */
|
||||
if (fcs->outPos < fcs->jobs[fcs->outThread].cSize)
|
||||
break;
|
||||
return 1;
|
||||
|
||||
fcs->outPos = 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static size_t FL2_compressStream_input(FL2_CStream* fcs, FL2_inBuffer* input)
|
||||
@@ -999,8 +1000,10 @@ static size_t FL2_loopCheck(FL2_CStream* fcs, int unchanged)
|
||||
{
|
||||
if (unchanged) {
|
||||
++fcs->loopCount;
|
||||
if (fcs->loopCount > FL2_MAX_LOOPS)
|
||||
if (fcs->loopCount > FL2_MAX_LOOPS) {
|
||||
FL2_cancelCStream(fcs);
|
||||
return FL2_ERROR(buffer);
|
||||
}
|
||||
}
|
||||
else {
|
||||
fcs->loopCount = 0;
|
||||
@@ -1057,14 +1060,13 @@ FL2LIB_API size_t FL2LIB_CALL FL2_updateDictionary(FL2_CStream * fcs, size_t add
|
||||
return fcs->outThread < fcs->threadCount;
|
||||
}
|
||||
|
||||
FL2LIB_API size_t FL2LIB_CALL FL2_getNextCStreamBuffer(FL2_CStream* fcs, FL2_cBuffer* cbuf)
|
||||
FL2LIB_API size_t FL2LIB_CALL FL2_getNextCompressedBuffer(FL2_CStream* fcs, FL2_cBuffer* cbuf)
|
||||
{
|
||||
cbuf->src = NULL;
|
||||
cbuf->size = 0;
|
||||
|
||||
#ifndef FL2_SINGLETHREAD
|
||||
FL2POOL_waitAll(fcs->compressThread, 0);
|
||||
CHECK_F(fcs->asyncRes);
|
||||
CHECK_F(FL2_waitCStream(fcs));
|
||||
#endif
|
||||
|
||||
if (fcs->outThread < fcs->threadCount) {
|
||||
|
||||
@@ -78,7 +78,8 @@ Public domain
|
||||
|
||||
#define kChunkSize ((1UL << 16U) - 8192U)
|
||||
#define kSqrtChunkSize 239U
|
||||
#define kTempMinOutput (LZMA_REQUIRED_INPUT_MAX * 4U)
|
||||
#define kMaxMatchEncodeSize 20
|
||||
#define kTempMinOutput (kMaxMatchEncodeSize * 4U)
|
||||
#define kTempBufferSize (kTempMinOutput + kOptimizerBufferSize + kOptimizerBufferSize / 16U)
|
||||
#define kMaxChunkUncompressedSize ((1UL << 21U) - kMatchLenMax)
|
||||
#define kMaxChunkCompressedSize (1UL << 16U)
|
||||
|
||||
@@ -197,7 +197,8 @@ FL2_matchTable* RMF_createMatchTable(const RMF_parameters* const p, size_t const
|
||||
size_t const table_bytes = is_struct ? ((dictionary_size + 3U) / 4U) * sizeof(RMF_unit)
|
||||
: dictionary_size * sizeof(U32);
|
||||
FL2_matchTable* const tbl = malloc(sizeof(FL2_matchTable) + table_bytes - sizeof(U32));
|
||||
if (!tbl) return NULL;
|
||||
if (tbl == NULL)
|
||||
return NULL;
|
||||
|
||||
tbl->is_struct = is_struct;
|
||||
tbl->alloc_struct = is_struct;
|
||||
@@ -707,7 +708,7 @@ BYTE* RMF_getTableAsOutputBuffer(FL2_matchTable* const tbl, size_t const index)
|
||||
size_t RMF_memoryUsage(size_t const dict_size, unsigned const buffer_log, unsigned const thread_count)
|
||||
{
|
||||
size_t size = (size_t)(4U + RMF_isStruct(dict_size)) * dict_size;
|
||||
size_t const buf_size = dict_size >> buffer_log;
|
||||
size_t const buf_size = dict_size >> (RMF_BUFFER_LOG_BASE - buffer_log);
|
||||
size += ((buf_size - 1) * sizeof(RMF_buildMatch) + sizeof(RMF_builder)) * thread_count;
|
||||
return size;
|
||||
}
|
||||
|
||||
@@ -272,9 +272,10 @@ HRESULT CFastEncoder::FastLzma2::WriteBuffers(ISequentialOutStream *outStream)
|
||||
size_t csize;
|
||||
for (;;) {
|
||||
FL2_cBuffer cbuf;
|
||||
// Waits if compression in progress
|
||||
csize = FL2_getNextCStreamBuffer(fcs, &cbuf);
|
||||
CHECK_S(csize);
|
||||
do {
|
||||
csize = FL2_getNextCompressedBuffer(fcs, &cbuf);
|
||||
} while (FL2_isTimedOut(csize));
|
||||
CHECK_S(csize);
|
||||
if (csize == 0)
|
||||
break;
|
||||
HRESULT err = WriteStream(outStream, cbuf.src, cbuf.size);
|
||||
|
||||
Reference in New Issue
Block a user