diff options
Diffstat (limited to '3rdparty/lzma/C/Lzma2Enc.c')
-rw-r--r-- | 3rdparty/lzma/C/Lzma2Enc.c | 73 |
1 files changed, 58 insertions, 15 deletions
diff --git a/3rdparty/lzma/C/Lzma2Enc.c b/3rdparty/lzma/C/Lzma2Enc.c index e97597f63d5..1b77a2bbc1c 100644 --- a/3rdparty/lzma/C/Lzma2Enc.c +++ b/3rdparty/lzma/C/Lzma2Enc.c @@ -1,5 +1,7 @@ /* Lzma2Enc.c -- LZMA2 Encoder -2010-09-24 : Igor Pavlov : Public domain */ +2015-10-04 : Igor Pavlov : Public domain */ + +#include "Precomp.h" /* #include <stdio.h> */ #include <string.h> @@ -107,6 +109,7 @@ static SRes Lzma2EncInt_EncodeSubblock(CLzma2EncInt *p, Byte *outBuf, { size_t destPos = 0; PRF(printf("################# COPY ")); + while (unpackSize > 0) { UInt32 u = (unpackSize < LZMA2_COPY_CHUNK_SIZE) ? unpackSize : LZMA2_COPY_CHUNK_SIZE; @@ -119,6 +122,7 @@ static SRes Lzma2EncInt_EncodeSubblock(CLzma2EncInt *p, Byte *outBuf, unpackSize -= u; destPos += u; p->srcPos += u; + if (outStream) { *packSizeRes += destPos; @@ -130,9 +134,11 @@ static SRes Lzma2EncInt_EncodeSubblock(CLzma2EncInt *p, Byte *outBuf, *packSizeRes = destPos; /* needInitState = True; */ } + LzmaEnc_RestoreState(p->enc); return SZ_OK; } + { size_t destPos = 0; UInt32 u = unpackSize - 1; @@ -158,11 +164,13 @@ static SRes Lzma2EncInt_EncodeSubblock(CLzma2EncInt *p, Byte *outBuf, if (outStream) if (outStream->Write(outStream, outBuf, destPos) != destPos) return SZ_ERROR_WRITE; + *packSizeRes = destPos; return SZ_OK; } } + /* ---------- Lzma2 Props ---------- */ void Lzma2EncProps_Init(CLzma2EncProps *p) @@ -216,10 +224,11 @@ void Lzma2EncProps_Normalize(CLzma2EncProps *p) t3 = t1n * t2; p->lzmaProps.numThreads = t1; - p->numBlockThreads = t2; - p->numTotalThreads = t3; + LzmaEncProps_Normalize(&p->lzmaProps); + t1 = p->lzmaProps.numThreads; + if (p->blockSize == 0) { UInt32 dictSize = p->lzmaProps.dictSize; @@ -231,13 +240,34 @@ void Lzma2EncProps_Normalize(CLzma2EncProps *p) if (blockSize < dictSize) blockSize = dictSize; p->blockSize = (size_t)blockSize; } + + if (t2 > 1 && p->lzmaProps.reduceSize != (UInt64)(Int64)-1) + { + UInt64 temp = p->lzmaProps.reduceSize + p->blockSize - 1; + if (temp > p->lzmaProps.reduceSize) + { + UInt64 numBlocks = temp / p->blockSize; + if (numBlocks < (unsigned)t2) + { + t2 = (unsigned)numBlocks; + if (t2 == 0) + t2 = 1; + t3 = t1 * t2; + } + } + } + + p->numBlockThreads = t2; + p->numTotalThreads = t3; } + static SRes Progress(ICompressProgress *p, UInt64 inSize, UInt64 outSize) { return (p && p->Progress(p, inSize, outSize) != SZ_OK) ? SZ_ERROR_PROGRESS : SZ_OK; } + /* ---------- Lzma2 ---------- */ typedef struct @@ -267,15 +297,17 @@ static SRes Lzma2Enc_EncodeMt1(CLzma2EncInt *p, CLzma2Enc *mainEncoder, UInt64 packTotal = 0; SRes res = SZ_OK; - if (mainEncoder->outBuf == 0) + if (!mainEncoder->outBuf) { mainEncoder->outBuf = (Byte *)IAlloc_Alloc(mainEncoder->alloc, LZMA2_CHUNK_SIZE_COMPRESSED_MAX); - if (mainEncoder->outBuf == 0) + if (!mainEncoder->outBuf) return SZ_ERROR_MEM; } + RINOK(Lzma2EncInt_Init(p, &mainEncoder->props)); RINOK(LzmaEnc_PrepareForLzma2(p->enc, inStream, LZMA2_KEEP_WINDOW_SIZE, mainEncoder->alloc, mainEncoder->allocBig)); + for (;;) { size_t packSize = LZMA2_CHUNK_SIZE_COMPRESSED_MAX; @@ -289,16 +321,20 @@ static SRes Lzma2Enc_EncodeMt1(CLzma2EncInt *p, CLzma2Enc *mainEncoder, if (packSize == 0) break; } + LzmaEnc_Finish(p->enc); + if (res == SZ_OK) { Byte b = 0; if (outStream->Write(outStream, &b, 1) != 1) return SZ_ERROR_WRITE; } + return res; } + #ifndef _7ZIP_ST typedef struct @@ -346,10 +382,12 @@ static SRes MtCallbackImp_Code(void *pp, unsigned index, Byte *dest, size_t *des break; } } + LzmaEnc_Finish(p->enc); if (res != SZ_OK) return res; } + if (finished) { if (*destSize == destLim) @@ -362,12 +400,13 @@ static SRes MtCallbackImp_Code(void *pp, unsigned index, Byte *dest, size_t *des #endif + /* ---------- Lzma2Enc ---------- */ CLzma2EncHandle Lzma2Enc_Create(ISzAlloc *alloc, ISzAlloc *allocBig) { CLzma2Enc *p = (CLzma2Enc *)alloc->Alloc(alloc, sizeof(CLzma2Enc)); - if (p == 0) + if (!p) return NULL; Lzma2EncProps_Init(&p->props); Lzma2EncProps_Normalize(&p->props); @@ -379,6 +418,7 @@ CLzma2EncHandle Lzma2Enc_Create(ISzAlloc *alloc, ISzAlloc *allocBig) for (i = 0; i < NUM_MT_CODER_THREADS_MAX; i++) p->coders[i].enc = 0; } + #ifndef _7ZIP_ST MtCoder_Construct(&p->mtCoder); #endif @@ -439,22 +479,17 @@ SRes Lzma2Enc_Encode(CLzma2EncHandle pp, for (i = 0; i < p->props.numBlockThreads; i++) { - CLzma2EncInt *t = &p->coders[i]; - if (t->enc == NULL) + CLzma2EncInt *t = &p->coders[(unsigned)i]; + if (!t->enc) { t->enc = LzmaEnc_Create(p->alloc); - if (t->enc == NULL) + if (!t->enc) return SZ_ERROR_MEM; } } #ifndef _7ZIP_ST - if (p->props.numBlockThreads <= 1) - #endif - return Lzma2Enc_EncodeMt1(&p->coders[0], p, outStream, inStream, progress); - - #ifndef _7ZIP_ST - + if (p->props.numBlockThreads > 1) { CMtCallbackImp mtCallback; @@ -469,9 +504,17 @@ SRes Lzma2Enc_Encode(CLzma2EncHandle pp, p->mtCoder.blockSize = p->props.blockSize; p->mtCoder.destBlockSize = p->props.blockSize + (p->props.blockSize >> 10) + 16; + if (p->mtCoder.destBlockSize < p->props.blockSize) + { + p->mtCoder.destBlockSize = (size_t)0 - 1; + if (p->mtCoder.destBlockSize < p->props.blockSize) + return SZ_ERROR_FAIL; + } p->mtCoder.numThreads = p->props.numBlockThreads; return MtCoder_Code(&p->mtCoder); } #endif + + return Lzma2Enc_EncodeMt1(&p->coders[0], p, outStream, inStream, progress); } |