This commit is contained in:
Igor Pavlov
2018-03-12 11:19:17 +00:00
committed by Kornel
parent 866a06f5a0
commit f19b649c73
81 changed files with 8243 additions and 1296 deletions

View File

@@ -1,5 +1,5 @@
; 7zAsm.asm -- ASM macros
; 2012-12-30 : Igor Pavlov : Public domain
; 2018-02-03 : Igor Pavlov : Public domain
MY_ASM_START macro
ifdef x64
@@ -52,6 +52,15 @@ endif
x6 equ ESI
x7 equ EDI
x0_W equ AX
x1_W equ CX
x2_W equ DX
x3_W equ BX
x5_W equ BP
x6_W equ SI
x7_W equ DI
x0_L equ AL
x1_L equ CL
x2_L equ DL
@@ -63,6 +72,10 @@ endif
x3_H equ BH
ifdef x64
x5_L equ BPL
x6_L equ SIL
x7_L equ DIL
r0 equ RAX
r1 equ RCX
r2 equ RDX
@@ -103,3 +116,32 @@ MY_POP_4_REGS macro
pop r5
pop r3
endm
ifdef x64
; for WIN64-x64 ABI:
REG_PARAM_0 equ r1
REG_PARAM_1 equ r2
REG_PARAM_2 equ r8
REG_PARAM_3 equ r9
MY_PUSH_PRESERVED_REGS macro
MY_PUSH_4_REGS
push r12
push r13
push r14
push r15
endm
MY_POP_PRESERVED_REGS macro
pop r15
pop r14
pop r13
pop r12
MY_POP_4_REGS
endm
endif

1258
Asm/x86/LzmaDecOpt.asm Normal file
View File

File diff suppressed because it is too large Load Diff

View File

@@ -1,7 +1,7 @@
#define MY_VER_MAJOR 18
#define MY_VER_MINOR 01
#define MY_VER_MINOR 03
#define MY_VER_BUILD 0
#define MY_VERSION_NUMBERS "18.01"
#define MY_VERSION_NUMBERS "18.03 beta"
#define MY_VERSION MY_VERSION_NUMBERS
#ifdef MY_CPU_NAME
@@ -10,7 +10,7 @@
#define MY_VERSION_CPU MY_VERSION
#endif
#define MY_DATE "2018-01-28"
#define MY_DATE "2018-03-04"
#undef MY_COPYRIGHT
#undef MY_VERSION_COPYRIGHT_DATE
#define MY_AUTHOR_NAME "Igor Pavlov"

354
C/Alloc.c
View File

@@ -1,8 +1,10 @@
/* Alloc.c -- Memory allocation functions
2017-06-15 : Igor Pavlov : Public domain */
2018-03-01 : Igor Pavlov : Public domain */
#include "Precomp.h"
#include <stdio.h>
#ifdef _WIN32
#include <windows.h>
#endif
@@ -14,12 +16,119 @@
/* use _SZ_ALLOC_DEBUG to debug alloc/free operations */
#ifdef _SZ_ALLOC_DEBUG
#include <stdio.h>
int g_allocCount = 0;
int g_allocCountMid = 0;
int g_allocCountBig = 0;
#define CONVERT_INT_TO_STR(charType, tempSize) \
unsigned char temp[tempSize]; unsigned i = 0; \
while (val >= 10) { temp[i++] = (unsigned char)('0' + (unsigned)(val % 10)); val /= 10; } \
*s++ = (charType)('0' + (unsigned)val); \
while (i != 0) { i--; *s++ = temp[i]; } \
*s = 0;
static void ConvertUInt64ToString(UInt64 val, char *s)
{
CONVERT_INT_TO_STR(char, 24);
}
#define GET_HEX_CHAR(t) ((char)(((t < 10) ? ('0' + t) : ('A' + (t - 10)))))
static void ConvertUInt64ToHex(UInt64 val, char *s)
{
UInt64 v = val;
unsigned i;
for (i = 1;; i++)
{
v >>= 4;
if (v == 0)
break;
}
s[i] = 0;
do
{
unsigned t = (unsigned)(val & 0xF);
val >>= 4;
s[--i] = GET_HEX_CHAR(t);
}
while (i);
}
#define DEBUG_OUT_STREAM stderr
static void Print(const char *s)
{
fputs(s, DEBUG_OUT_STREAM);
}
static void PrintAligned(const char *s, size_t align)
{
size_t len = strlen(s);
for(;;)
{
fputc(' ', DEBUG_OUT_STREAM);
if (len >= align)
break;
++len;
}
Print(s);
}
static void PrintLn()
{
Print("\n");
}
static void PrintHex(UInt64 v, size_t align)
{
char s[32];
ConvertUInt64ToHex(v, s);
PrintAligned(s, align);
}
static void PrintDec(UInt64 v, size_t align)
{
char s[32];
ConvertUInt64ToString(v, s);
PrintAligned(s, align);
}
static void PrintAddr(void *p)
{
PrintHex((UInt64)(size_t)(ptrdiff_t)p, 12);
}
#define PRINT_ALLOC(name, cnt, size, ptr) \
Print(name " "); \
PrintDec(cnt++, 10); \
PrintHex(size, 10); \
PrintAddr(ptr); \
PrintLn();
#define PRINT_FREE(name, cnt, ptr) if (ptr) { \
Print(name " "); \
PrintDec(--cnt, 10); \
PrintAddr(ptr); \
PrintLn(); }
#else
#define PRINT_ALLOC(name, cnt, size, ptr)
#define PRINT_FREE(name, cnt, ptr)
#define Print(s)
#define PrintLn()
#define PrintHex(v, align)
#define PrintDec(v, align)
#define PrintAddr(p)
#endif
void *MyAlloc(size_t size)
{
if (size == 0)
@@ -27,7 +136,7 @@ void *MyAlloc(size_t size)
#ifdef _SZ_ALLOC_DEBUG
{
void *p = malloc(size);
fprintf(stderr, "\nAlloc %10u bytes, count = %10d, addr = %8X", size, g_allocCount++, (unsigned)p);
PRINT_ALLOC("Alloc ", g_allocCount, size, p);
return p;
}
#else
@@ -37,10 +146,8 @@ void *MyAlloc(size_t size)
void MyFree(void *address)
{
#ifdef _SZ_ALLOC_DEBUG
if (address)
fprintf(stderr, "\nFree; count = %10d, addr = %8X", --g_allocCount, (unsigned)address);
#endif
PRINT_FREE("Free ", g_allocCount, address);
free(address);
}
@@ -50,18 +157,16 @@ void *MidAlloc(size_t size)
{
if (size == 0)
return NULL;
#ifdef _SZ_ALLOC_DEBUG
fprintf(stderr, "\nAlloc_Mid %10d bytes; count = %10d", size, g_allocCountMid++);
#endif
PRINT_ALLOC("Alloc-Mid", g_allocCountMid, size, NULL);
return VirtualAlloc(NULL, size, MEM_COMMIT, PAGE_READWRITE);
}
void MidFree(void *address)
{
#ifdef _SZ_ALLOC_DEBUG
if (address)
fprintf(stderr, "\nFree_Mid; count = %10d", --g_allocCountMid);
#endif
PRINT_FREE("Free-Mid", g_allocCountMid, address);
if (!address)
return;
VirtualFree(address, 0, MEM_RELEASE);
@@ -96,9 +201,8 @@ void *BigAlloc(size_t size)
{
if (size == 0)
return NULL;
#ifdef _SZ_ALLOC_DEBUG
fprintf(stderr, "\nAlloc_Big %10u bytes; count = %10d", size, g_allocCountBig++);
#endif
PRINT_ALLOC("Alloc-Big", g_allocCountBig, size, NULL);
#ifdef _7ZIP_LARGE_PAGES
{
@@ -123,10 +227,7 @@ void *BigAlloc(size_t size)
void BigFree(void *address)
{
#ifdef _SZ_ALLOC_DEBUG
if (address)
fprintf(stderr, "\nFree_Big; count = %10d", --g_allocCountBig);
#endif
PRINT_FREE("Free-Big", g_allocCountBig, address);
if (!address)
return;
@@ -138,8 +239,217 @@ void BigFree(void *address)
static void *SzAlloc(ISzAllocPtr p, size_t size) { UNUSED_VAR(p); return MyAlloc(size); }
static void SzFree(ISzAllocPtr p, void *address) { UNUSED_VAR(p); MyFree(address); }
ISzAlloc const g_Alloc = { SzAlloc, SzFree };
const ISzAlloc g_Alloc = { SzAlloc, SzFree };
static void *SzMidAlloc(ISzAllocPtr p, size_t size) { UNUSED_VAR(p); return MidAlloc(size); }
static void SzMidFree(ISzAllocPtr p, void *address) { UNUSED_VAR(p); MidFree(address); }
const ISzAlloc g_MidAlloc = { SzMidAlloc, SzMidFree };
static void *SzBigAlloc(ISzAllocPtr p, size_t size) { UNUSED_VAR(p); return BigAlloc(size); }
static void SzBigFree(ISzAllocPtr p, void *address) { UNUSED_VAR(p); BigFree(address); }
ISzAlloc const g_BigAlloc = { SzBigAlloc, SzBigFree };
const ISzAlloc g_BigAlloc = { SzBigAlloc, SzBigFree };
/*
uintptr_t : <stdint.h> C99 (optional)
: unsupported in VS6
*/
#ifdef _WIN32
typedef UINT_PTR UIntPtr;
#else
/*
typedef uintptr_t UIntPtr;
*/
typedef ptrdiff_t UIntPtr;
#endif
#define ADJUST_ALLOC_SIZE 0
/*
#define ADJUST_ALLOC_SIZE (sizeof(void *) - 1)
*/
/*
Use (ADJUST_ALLOC_SIZE = (sizeof(void *) - 1)), if
MyAlloc() can return address that is NOT multiple of sizeof(void *).
*/
/*
#define MY_ALIGN_PTR_DOWN(p, align) ((void *)((char *)(p) - ((size_t)(UIntPtr)(p) & ((align) - 1))))
*/
#define MY_ALIGN_PTR_DOWN(p, align) ((void *)((((UIntPtr)(p)) & ~((UIntPtr)(align) - 1))))
#define MY_ALIGN_PTR_UP_PLUS(p, align) MY_ALIGN_PTR_DOWN(((char *)(p) + (align) + ADJUST_ALLOC_SIZE), align)
#if (_POSIX_C_SOURCE >= 200112L)
#define USE_posix_memalign
#endif
/*
This posix_memalign() is for test purposes only.
We also need special Free() function instead of free(),
if this posix_memalign() is used.
*/
/*
static int posix_memalign(void **ptr, size_t align, size_t size)
{
size_t newSize = size + align;
void *p;
void *pAligned;
*ptr = NULL;
if (newSize < size)
return 12; // ENOMEM
p = MyAlloc(newSize);
if (!p)
return 12; // ENOMEM
pAligned = MY_ALIGN_PTR_UP_PLUS(p, align);
((void **)pAligned)[-1] = p;
*ptr = pAligned;
return 0;
}
*/
/*
ALLOC_ALIGN_SIZE >= sizeof(void *)
ALLOC_ALIGN_SIZE >= cache_line_size
*/
#define ALLOC_ALIGN_SIZE ((size_t)1 << 7)
static void *SzAlignedAlloc(ISzAllocPtr pp, size_t size)
{
#ifndef USE_posix_memalign
void *p;
void *pAligned;
size_t newSize;
UNUSED_VAR(pp);
/* also we can allocate additional dummy ALLOC_ALIGN_SIZE bytes after aligned
block to prevent cache line sharing with another allocated blocks */
newSize = size + ALLOC_ALIGN_SIZE * 1 + ADJUST_ALLOC_SIZE;
if (newSize < size)
return NULL;
p = MyAlloc(newSize);
if (!p)
return NULL;
pAligned = MY_ALIGN_PTR_UP_PLUS(p, ALLOC_ALIGN_SIZE);
Print(" size="); PrintHex(size, 8);
Print(" a_size="); PrintHex(newSize, 8);
Print(" ptr="); PrintAddr(p);
Print(" a_ptr="); PrintAddr(pAligned);
PrintLn();
((void **)pAligned)[-1] = p;
return pAligned;
#else
void *p;
UNUSED_VAR(pp);
if (posix_memalign(&p, ALLOC_ALIGN_SIZE, size))
return NULL;
Print(" posix_memalign="); PrintAddr(p);
PrintLn();
return p;
#endif
}
static void SzAlignedFree(ISzAllocPtr pp, void *address)
{
UNUSED_VAR(pp);
#ifndef USE_posix_memalign
if (address)
MyFree(((void **)address)[-1]);
#else
free(address);
#endif
}
const ISzAlloc g_AlignedAlloc = { SzAlignedAlloc, SzAlignedFree };
#define MY_ALIGN_PTR_DOWN_1(p) MY_ALIGN_PTR_DOWN(p, sizeof(void *))
/* we align ptr to support cases where CAlignOffsetAlloc::offset is not multiply of sizeof(void *) */
#define REAL_BLOCK_PTR_VAR(p) ((void **)MY_ALIGN_PTR_DOWN_1(p))[-1]
/*
#define REAL_BLOCK_PTR_VAR(p) ((void **)(p))[-1]
*/
static void *AlignOffsetAlloc_Alloc(ISzAllocPtr pp, size_t size)
{
CAlignOffsetAlloc *p = CONTAINER_FROM_VTBL(pp, CAlignOffsetAlloc, vt);
void *adr;
void *pAligned;
size_t newSize;
size_t extra;
size_t alignSize = (size_t)1 << p->numAlignBits;
if (alignSize < sizeof(void *))
alignSize = sizeof(void *);
if (p->offset >= alignSize)
return NULL;
/* also we can allocate additional dummy ALLOC_ALIGN_SIZE bytes after aligned
block to prevent cache line sharing with another allocated blocks */
extra = p->offset & (sizeof(void *) - 1);
newSize = size + alignSize + extra + ADJUST_ALLOC_SIZE;
if (newSize < size)
return NULL;
adr = ISzAlloc_Alloc(p->baseAlloc, newSize);
if (!adr)
return NULL;
pAligned = (char *)MY_ALIGN_PTR_DOWN((char *)adr +
alignSize - p->offset + extra + ADJUST_ALLOC_SIZE, alignSize) + p->offset;
PrintLn();
Print("- Aligned: ");
Print(" size="); PrintHex(size, 8);
Print(" a_size="); PrintHex(newSize, 8);
Print(" ptr="); PrintAddr(adr);
Print(" a_ptr="); PrintAddr(pAligned);
PrintLn();
REAL_BLOCK_PTR_VAR(pAligned) = adr;
return pAligned;
}
static void AlignOffsetAlloc_Free(ISzAllocPtr pp, void *address)
{
if (address)
{
CAlignOffsetAlloc *p = CONTAINER_FROM_VTBL(pp, CAlignOffsetAlloc, vt);
PrintLn();
Print("- Aligned Free: ");
PrintLn();
ISzAlloc_Free(p->baseAlloc, REAL_BLOCK_PTR_VAR(address));
}
}
void AlignOffsetAlloc_CreateVTable(CAlignOffsetAlloc *p)
{
p->vt.Alloc = AlignOffsetAlloc_Alloc;
p->vt.Free = AlignOffsetAlloc_Free;
}

View File

@@ -1,5 +1,5 @@
/* Alloc.h -- Memory allocation functions
2017-04-03 : Igor Pavlov : Public domain */
2018-02-19 : Igor Pavlov : Public domain */
#ifndef __COMMON_ALLOC_H
#define __COMMON_ALLOC_H
@@ -31,6 +31,20 @@ void BigFree(void *address);
extern const ISzAlloc g_Alloc;
extern const ISzAlloc g_BigAlloc;
extern const ISzAlloc g_MidAlloc;
extern const ISzAlloc g_AlignedAlloc;
typedef struct
{
ISzAlloc vt;
ISzAllocPtr baseAlloc;
unsigned numAlignBits; /* ((1 << numAlignBits) >= sizeof(void *)) */
size_t offset; /* (offset == (k * sizeof(void *)) && offset < (1 << numAlignBits) */
} CAlignOffsetAlloc;
void AlignOffsetAlloc_CreateVTable(CAlignOffsetAlloc *p);
EXTERN_C_END

View File

@@ -1,5 +1,5 @@
/* CpuArch.h -- CPU specific code
2017-06-30 : Igor Pavlov : Public domain */
2017-09-04 : Igor Pavlov : Public domain */
#ifndef __CPU_ARCH_H
#define __CPU_ARCH_H
@@ -174,7 +174,7 @@ MY_CPU_LE_UNALIGN means that CPU is LITTLE ENDIAN and CPU supports unaligned mem
#ifndef MY_CPU_NAME
#ifdef MY_CPU_LE
#define MY_CPU_NAME "LE"
#elif MY_CPU_BE
#elif defined(MY_CPU_BE)
#define MY_CPU_NAME "BE"
#else
/*

View File

@@ -1,5 +1,5 @@
/* Lzma2Dec.c -- LZMA2 Decoder
2017-04-03 : Igor Pavlov : Public domain */
2018-02-19 : Igor Pavlov : Public domain */
/* #define SHOW_DEBUG_INFO */
@@ -14,28 +14,22 @@
#include "Lzma2Dec.h"
/*
00000000 - EOS
00000001 U U - Uncompressed Reset Dic
00000010 U U - Uncompressed No Reset
100uuuuu U U P P - LZMA no reset
101uuuuu U U P P - LZMA reset state
110uuuuu U U P P S - LZMA reset state + new prop
111uuuuu U U P P S - LZMA reset state + new prop + reset dic
00000000 - End of data
00000001 U U - Uncompressed, reset dic, need reset state and set new prop
00000010 U U - Uncompressed, no reset
100uuuuu U U P P - LZMA, no reset
101uuuuu U U P P - LZMA, reset state
110uuuuu U U P P S - LZMA, reset state + set new prop
111uuuuu U U P P S - LZMA, reset state + set new prop, reset dic
u, U - Unpack Size
P - Pack Size
S - Props
*/
#define LZMA2_CONTROL_LZMA (1 << 7)
#define LZMA2_CONTROL_COPY_NO_RESET 2
#define LZMA2_CONTROL_COPY_RESET_DIC 1
#define LZMA2_CONTROL_EOF 0
#define LZMA2_IS_UNCOMPRESSED_STATE(p) (((p)->control & LZMA2_CONTROL_LZMA) == 0)
#define LZMA2_GET_LZMA_MODE(p) (((p)->control >> 5) & 3)
#define LZMA2_IS_THERE_PROP(mode) ((mode) >= 2)
#define LZMA2_IS_UNCOMPRESSED_STATE(p) (((p)->control & (1 << 7)) == 0)
#define LZMA2_LCLP_MAX 4
#define LZMA2_DIC_SIZE_FROM_PROP(p) (((UInt32)2 | ((p) & 1)) << ((p) / 2 + 11))
@@ -91,9 +85,11 @@ SRes Lzma2Dec_Allocate(CLzma2Dec *p, Byte prop, ISzAllocPtr alloc)
void Lzma2Dec_Init(CLzma2Dec *p)
{
p->state = LZMA2_STATE_CONTROL;
p->needInitDic = True;
p->needInitState = True;
p->needInitProp = True;
p->needInitLevel = 0xE0;
p->isExtraMode = False;
p->unpackSize = 0;
// p->decoder.dicPos = 0; // we can use it instead of full init
LzmaDec_Init(&p->decoder);
}
@@ -102,19 +98,26 @@ static ELzma2State Lzma2Dec_UpdateState(CLzma2Dec *p, Byte b)
switch (p->state)
{
case LZMA2_STATE_CONTROL:
p->isExtraMode = False;
p->control = b;
PRF(printf("\n %4X ", (unsigned)p->decoder.dicPos));
PRF(printf(" %2X", (unsigned)b));
PRF(printf("\n %8X", (unsigned)p->decoder.dicPos));
PRF(printf(" %02X", (unsigned)b));
if (b == 0)
return LZMA2_STATE_FINISHED;
if (LZMA2_IS_UNCOMPRESSED_STATE(p))
{
if (b > 2)
if (b == LZMA2_CONTROL_COPY_RESET_DIC)
p->needInitLevel = 0xC0;
else if (b > 2 || p->needInitLevel == 0xE0)
return LZMA2_STATE_ERROR;
p->unpackSize = 0;
}
else
{
if (b < p->needInitLevel)
return LZMA2_STATE_ERROR;
p->needInitLevel = 0;
p->unpackSize = (UInt32)(b & 0x1F) << 16;
}
return LZMA2_STATE_UNPACK0;
case LZMA2_STATE_UNPACK0:
@@ -124,8 +127,8 @@ static ELzma2State Lzma2Dec_UpdateState(CLzma2Dec *p, Byte b)
case LZMA2_STATE_UNPACK1:
p->unpackSize |= (UInt32)b;
p->unpackSize++;
PRF(printf(" %8u", (unsigned)p->unpackSize));
return (LZMA2_IS_UNCOMPRESSED_STATE(p)) ? LZMA2_STATE_DATA : LZMA2_STATE_PACK0;
PRF(printf(" %7u", (unsigned)p->unpackSize));
return LZMA2_IS_UNCOMPRESSED_STATE(p) ? LZMA2_STATE_DATA : LZMA2_STATE_PACK0;
case LZMA2_STATE_PACK0:
p->packSize = (UInt32)b << 8;
@@ -134,9 +137,9 @@ static ELzma2State Lzma2Dec_UpdateState(CLzma2Dec *p, Byte b)
case LZMA2_STATE_PACK1:
p->packSize |= (UInt32)b;
p->packSize++;
PRF(printf(" %8u", (unsigned)p->packSize));
return LZMA2_IS_THERE_PROP(LZMA2_GET_LZMA_MODE(p)) ? LZMA2_STATE_PROP:
(p->needInitProp ? LZMA2_STATE_ERROR : LZMA2_STATE_DATA);
// if (p->packSize < 5) return LZMA2_STATE_ERROR;
PRF(printf(" %5u", (unsigned)p->packSize));
return (p->control & 0x40) ? LZMA2_STATE_PROP : LZMA2_STATE_DATA;
case LZMA2_STATE_PROP:
{
@@ -145,13 +148,12 @@ static ELzma2State Lzma2Dec_UpdateState(CLzma2Dec *p, Byte b)
return LZMA2_STATE_ERROR;
lc = b % 9;
b /= 9;
p->decoder.prop.pb = b / 5;
p->decoder.prop.pb = (Byte)(b / 5);
lp = b % 5;
if (lc + lp > LZMA2_LCLP_MAX)
return LZMA2_STATE_ERROR;
p->decoder.prop.lc = lc;
p->decoder.prop.lp = lp;
p->needInitProp = False;
p->decoder.prop.lc = (Byte)lc;
p->decoder.prop.lp = (Byte)lp;
return LZMA2_STATE_DATA;
}
}
@@ -231,11 +233,6 @@ SRes Lzma2Dec_DecodeToDic(CLzma2Dec *p, SizeT dicLimit,
if (p->state == LZMA2_STATE_DATA)
{
Bool initDic = (p->control == LZMA2_CONTROL_COPY_RESET_DIC);
if (initDic)
p->needInitProp = p->needInitState = True;
else if (p->needInitDic)
break;
p->needInitDic = False;
LzmaDec_InitDicAndState(&p->decoder, initDic, False);
}
@@ -257,15 +254,9 @@ SRes Lzma2Dec_DecodeToDic(CLzma2Dec *p, SizeT dicLimit,
if (p->state == LZMA2_STATE_DATA)
{
unsigned mode = LZMA2_GET_LZMA_MODE(p);
Bool initDic = (mode == 3);
Bool initState = (mode != 0);
if ((!initDic && p->needInitDic) || (!initState && p->needInitState))
break;
Bool initDic = (p->control >= 0xE0);
Bool initState = (p->control >= 0xA0);
LzmaDec_InitDicAndState(&p->decoder, initDic, initState);
p->needInitDic = False;
p->needInitState = False;
p->state = LZMA2_STATE_DATA_CONT;
}
@@ -310,6 +301,129 @@ SRes Lzma2Dec_DecodeToDic(CLzma2Dec *p, SizeT dicLimit,
}
ELzma2ParseStatus Lzma2Dec_Parse(CLzma2Dec *p,
SizeT outSize,
const Byte *src, SizeT *srcLen,
int checkFinishBlock)
{
SizeT inSize = *srcLen;
*srcLen = 0;
while (p->state != LZMA2_STATE_ERROR)
{
if (p->state == LZMA2_STATE_FINISHED)
return LZMA_STATUS_FINISHED_WITH_MARK;
if (outSize == 0 && !checkFinishBlock)
return LZMA_STATUS_NOT_FINISHED;
if (p->state != LZMA2_STATE_DATA && p->state != LZMA2_STATE_DATA_CONT)
{
if (*srcLen == inSize)
return LZMA_STATUS_NEEDS_MORE_INPUT;
(*srcLen)++;
p->state = Lzma2Dec_UpdateState(p, *src++);
if (p->state == LZMA2_STATE_UNPACK0)
{
// if (p->decoder.dicPos != 0)
if (p->control == LZMA2_CONTROL_COPY_RESET_DIC || p->control >= 0xE0)
return LZMA2_PARSE_STATUS_NEW_BLOCK;
// if (outSize == 0) return LZMA_STATUS_NOT_FINISHED;
}
// The following code can be commented.
// It's not big problem, if we read additional input bytes.
// It will be stopped later in LZMA2_STATE_DATA / LZMA2_STATE_DATA_CONT state.
if (outSize == 0 && p->state != LZMA2_STATE_FINISHED)
{
// checkFinishBlock is true. So we expect that block must be finished,
// We can return LZMA_STATUS_NOT_SPECIFIED or LZMA_STATUS_NOT_FINISHED here
// break;
return LZMA_STATUS_NOT_FINISHED;
}
if (p->state == LZMA2_STATE_DATA)
return LZMA2_PARSE_STATUS_NEW_CHUNK;
continue;
}
if (outSize == 0)
return LZMA_STATUS_NOT_FINISHED;
{
SizeT inCur = inSize - *srcLen;
if (LZMA2_IS_UNCOMPRESSED_STATE(p))
{
if (inCur == 0)
return LZMA_STATUS_NEEDS_MORE_INPUT;
if (inCur > p->unpackSize)
inCur = p->unpackSize;
if (inCur > outSize)
inCur = outSize;
p->decoder.dicPos += inCur;
src += inCur;
*srcLen += inCur;
outSize -= inCur;
p->unpackSize -= (UInt32)inCur;
p->state = (p->unpackSize == 0) ? LZMA2_STATE_CONTROL : LZMA2_STATE_DATA_CONT;
}
else
{
p->isExtraMode = True;
if (inCur == 0)
{
if (p->packSize != 0)
return LZMA_STATUS_NEEDS_MORE_INPUT;
}
else if (p->state == LZMA2_STATE_DATA)
{
p->state = LZMA2_STATE_DATA_CONT;
if (*src != 0)
{
// first byte of lzma chunk must be Zero
*srcLen += 1;
p->packSize--;
break;
}
}
if (inCur > p->packSize)
inCur = (SizeT)p->packSize;
src += inCur;
*srcLen += inCur;
p->packSize -= (UInt32)inCur;
if (p->packSize == 0)
{
SizeT rem = outSize;
if (rem > p->unpackSize)
rem = p->unpackSize;
p->decoder.dicPos += rem;
p->unpackSize -= (UInt32)rem;
outSize -= rem;
if (p->unpackSize == 0)
p->state = LZMA2_STATE_CONTROL;
}
}
}
}
p->state = LZMA2_STATE_ERROR;
return LZMA_STATUS_NOT_SPECIFIED;
}
SRes Lzma2Dec_DecodeToBuf(CLzma2Dec *p, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status)
{
SizeT outSize = *destLen, inSize = *srcLen;

View File

@@ -1,5 +1,5 @@
/* Lzma2Dec.h -- LZMA2 Decoder
2017-04-03 : Igor Pavlov : Public domain */
2018-02-19 : Igor Pavlov : Public domain */
#ifndef __LZMA2_DEC_H
#define __LZMA2_DEC_H
@@ -12,25 +12,24 @@ EXTERN_C_BEGIN
typedef struct
{
CLzmaDec decoder;
UInt32 packSize;
UInt32 unpackSize;
unsigned state;
Byte control;
Bool needInitDic;
Bool needInitState;
Bool needInitProp;
Byte needInitLevel;
Byte isExtraMode;
Byte _pad_;
UInt32 packSize;
UInt32 unpackSize;
CLzmaDec decoder;
} CLzma2Dec;
#define Lzma2Dec_Construct(p) LzmaDec_Construct(&(p)->decoder)
#define Lzma2Dec_FreeProbs(p, alloc) LzmaDec_FreeProbs(&(p)->decoder, alloc);
#define Lzma2Dec_Free(p, alloc) LzmaDec_Free(&(p)->decoder, alloc);
#define Lzma2Dec_FreeProbs(p, alloc) LzmaDec_FreeProbs(&(p)->decoder, alloc)
#define Lzma2Dec_Free(p, alloc) LzmaDec_Free(&(p)->decoder, alloc)
SRes Lzma2Dec_AllocateProbs(CLzma2Dec *p, Byte prop, ISzAllocPtr alloc);
SRes Lzma2Dec_Allocate(CLzma2Dec *p, Byte prop, ISzAllocPtr alloc);
void Lzma2Dec_Init(CLzma2Dec *p);
/*
finishMode:
It has meaning only if the decoding reaches output limit (*destLen or dicLimit).
@@ -53,6 +52,47 @@ SRes Lzma2Dec_DecodeToBuf(CLzma2Dec *p, Byte *dest, SizeT *destLen,
const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status);
/* ---------- LZMA2 block and chunk parsing ---------- */
/*
Lzma2Dec_Parse() parses compressed data stream up to next independent block or next chunk data.
It can return LZMA_STATUS_* code or LZMA2_PARSE_STATUS_* code:
- LZMA2_PARSE_STATUS_NEW_BLOCK - there is new block, and 1 additional byte (control byte of next block header) was read from input.
- LZMA2_PARSE_STATUS_NEW_CHUNK - there is new chunk, and only lzma2 header of new chunk was read.
CLzma2Dec::unpackSize contains unpack size of that chunk
*/
typedef enum
{
/*
LZMA_STATUS_NOT_SPECIFIED // data error
LZMA_STATUS_FINISHED_WITH_MARK
LZMA_STATUS_NOT_FINISHED //
LZMA_STATUS_NEEDS_MORE_INPUT
LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK // unused
*/
LZMA2_PARSE_STATUS_NEW_BLOCK = LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK + 1,
LZMA2_PARSE_STATUS_NEW_CHUNK
} ELzma2ParseStatus;
ELzma2ParseStatus Lzma2Dec_Parse(CLzma2Dec *p,
SizeT outSize, // output size
const Byte *src, SizeT *srcLen,
int checkFinishBlock // set (checkFinishBlock = 1), if it must read full input data, if decoder.dicPos reaches blockMax position.
);
/*
LZMA2 parser doesn't decode LZMA chunks, so we must read
full input LZMA chunk to decode some part of LZMA chunk.
Lzma2Dec_GetUnpackExtra() returns the value that shows
max possible number of output bytes that can be output by decoder
at current input positon.
*/
#define Lzma2Dec_GetUnpackExtra(p) ((p)->isExtraMode ? (p)->unpackSize : 0);
/* ---------- One Call Interface ---------- */
/*

1082
C/Lzma2DecMt.c Normal file
View File

File diff suppressed because it is too large Load Diff

79
C/Lzma2DecMt.h Normal file
View File

@@ -0,0 +1,79 @@
/* Lzma2DecMt.h -- LZMA2 Decoder Multi-thread
2018-02-17 : Igor Pavlov : Public domain */
#ifndef __LZMA2_DEC_MT_H
#define __LZMA2_DEC_MT_H
#include "7zTypes.h"
EXTERN_C_BEGIN
typedef struct
{
size_t inBufSize_ST;
size_t outStep_ST;
#ifndef _7ZIP_ST
unsigned numThreads;
size_t inBufSize_MT;
size_t outBlockMax;
size_t inBlockMax;
#endif
} CLzma2DecMtProps;
/* init to single-thread mode */
void Lzma2DecMtProps_Init(CLzma2DecMtProps *p);
/* ---------- CLzma2DecMtHandle Interface ---------- */
/* Lzma2DecMt_ * functions can return the following exit codes:
SRes:
SZ_OK - OK
SZ_ERROR_MEM - Memory allocation error
SZ_ERROR_PARAM - Incorrect paramater in props
SZ_ERROR_WRITE - ISeqOutStream write callback error
// SZ_ERROR_OUTPUT_EOF - output buffer overflow - version with (Byte *) output
SZ_ERROR_PROGRESS - some break from progress callback
SZ_ERROR_THREAD - error in multithreading functions (only for Mt version)
*/
typedef void * CLzma2DecMtHandle;
CLzma2DecMtHandle Lzma2DecMt_Create(ISzAllocPtr alloc, ISzAllocPtr allocMid);
void Lzma2DecMt_Destroy(CLzma2DecMtHandle p);
SRes Lzma2DecMt_Decode(CLzma2DecMtHandle p,
Byte prop,
const CLzma2DecMtProps *props,
ISeqOutStream *outStream,
const UInt64 *outDataSize, // NULL means undefined
int finishMode, // 0 - partial unpacking is allowed, 1 - if lzma2 stream must be finished
// Byte *outBuf, size_t *outBufSize,
ISeqInStream *inStream,
// const Byte *inData, size_t inDataSize,
// out variables:
UInt64 *inProcessed,
int *isMT, /* out: (*isMT == 0), if single thread decoding was used */
// UInt64 *outProcessed,
ICompressProgress *progress);
/* ---------- Read from CLzma2DecMtHandle Interface ---------- */
SRes Lzma2DecMt_Init(CLzma2DecMtHandle pp,
Byte prop,
const CLzma2DecMtProps *props,
const UInt64 *outDataSize, int finishMode,
ISeqInStream *inStream);
SRes Lzma2DecMt_Read(CLzma2DecMtHandle pp,
Byte *data, size_t *outSize,
UInt64 *inStreamProcessed);
EXTERN_C_END
#endif

View File

@@ -1,5 +1,5 @@
/* Lzma2Enc.c -- LZMA2 Encoder
2017-08-28 : Igor Pavlov : Public domain */
2018-02-08 : Igor Pavlov : Public domain */
#include "Precomp.h"
@@ -666,7 +666,7 @@ static SRes Lzma2Enc_MtCallback_Code(void *pp, unsigned coderIndex, unsigned out
if (!dest)
{
dest = ISzAlloc_Alloc(me->alloc, me->outBufSize);
dest = (Byte *)ISzAlloc_Alloc(me->alloc, me->outBufSize);
if (!dest)
return SZ_ERROR_MEM;
me->outBufs[outBufIndex] = dest;
@@ -674,7 +674,8 @@ static SRes Lzma2Enc_MtCallback_Code(void *pp, unsigned coderIndex, unsigned out
MtProgressThunk_CreateVTable(&progressThunk);
progressThunk.mtProgress = &me->mtCoder.mtProgress;
progressThunk.index = coderIndex;
progressThunk.inSize = 0;
progressThunk.outSize = 0;
res = Lzma2Enc_EncodeMt1(me,
&me->coders[coderIndex],
@@ -720,10 +721,10 @@ SRes Lzma2Enc_Encode2(CLzma2EncHandle pp,
CLzma2Enc *p = (CLzma2Enc *)pp;
if (inStream && inData)
return E_INVALIDARG;
return SZ_ERROR_PARAM;
if (outStream && outBuf)
return E_INVALIDARG;
return SZ_ERROR_PARAM;
{
unsigned i;

View File

@@ -1,8 +1,9 @@
/* LzmaDec.c -- LZMA Decoder
2017-04-03 : Igor Pavlov : Public domain */
2018-02-28 : Igor Pavlov : Public domain */
#include "Precomp.h"
/* #include "CpuArch.h" */
#include "LzmaDec.h"
#include <string.h>
@@ -24,9 +25,16 @@
#define GET_BIT2(p, i, A0, A1) IF_BIT_0(p) \
{ UPDATE_0(p); i = (i + i); A0; } else \
{ UPDATE_1(p); i = (i + i) + 1; A1; }
#define GET_BIT(p, i) GET_BIT2(p, i, ; , ;)
#define TREE_GET_BIT(probs, i) { GET_BIT((probs + i), i); }
#define TREE_GET_BIT(probs, i) { GET_BIT2(probs + i, i, ;, ;); }
#define REV_BIT(p, i, A0, A1) IF_BIT_0(p + i) \
{ UPDATE_0(p + i); A0; } else \
{ UPDATE_1(p + i); A1; }
#define REV_BIT_VAR( p, i, m) REV_BIT(p, i, i += m; m += m, m += m; i += m; )
#define REV_BIT_CONST(p, i, m) REV_BIT(p, i, i += m; , i += m * 2; )
#define REV_BIT_LAST( p, i, m) REV_BIT(p, i, i -= m , ; )
#define TREE_DECODE(probs, limit, i) \
{ i = 1; do { TREE_GET_BIT(probs, i); } while (i < limit); i -= limit; }
@@ -46,12 +54,15 @@
i -= 0x40; }
#endif
#define NORMAL_LITER_DEC GET_BIT(prob + symbol, symbol)
#define NORMAL_LITER_DEC TREE_GET_BIT(prob, symbol)
#define MATCHED_LITER_DEC \
matchByte <<= 1; \
bit = (matchByte & offs); \
probLit = prob + offs + bit + symbol; \
GET_BIT2(probLit, symbol, offs &= ~bit, offs &= bit)
matchByte += matchByte; \
bit = offs; \
offs &= matchByte; \
probLit = prob + (offs + bit + symbol); \
GET_BIT2(probLit, symbol, offs ^= bit; , ;)
#define NORMALIZE_CHECK if (range < kTopValue) { if (buf >= bufLimit) return DUMMY_ERROR; range <<= 8; code = (code << 8) | (*buf++); }
@@ -66,25 +77,28 @@
{ i = 1; do { GET_BIT_CHECK(probs + i, i) } while (i < limit); i -= limit; }
#define REV_BIT_CHECK(p, i, m) IF_BIT_0_CHECK(p + i) \
{ UPDATE_0_CHECK; i += m; m += m; } else \
{ UPDATE_1_CHECK; m += m; i += m; }
#define kNumPosBitsMax 4
#define kNumPosStatesMax (1 << kNumPosBitsMax)
#define kLenNumLowBits 3
#define kLenNumLowSymbols (1 << kLenNumLowBits)
#define kLenNumMidBits 3
#define kLenNumMidSymbols (1 << kLenNumMidBits)
#define kLenNumHighBits 8
#define kLenNumHighSymbols (1 << kLenNumHighBits)
#define LenChoice 0
#define LenChoice2 (LenChoice + 1)
#define LenLow (LenChoice2 + 1)
#define LenMid (LenLow + (kNumPosStatesMax << kLenNumLowBits))
#define LenHigh (LenMid + (kNumPosStatesMax << kLenNumMidBits))
#define LenLow 0
#define LenHigh (LenLow + 2 * (kNumPosStatesMax << kLenNumLowBits))
#define kNumLenProbs (LenHigh + kLenNumHighSymbols)
#define LenChoice LenLow
#define LenChoice2 (LenLow + (1 << kLenNumLowBits))
#define kNumStates 12
#define kNumStates2 16
#define kNumLitStates 7
#define kStartPosModelIndex 4
@@ -98,54 +112,117 @@
#define kAlignTableSize (1 << kNumAlignBits)
#define kMatchMinLen 2
#define kMatchSpecLenStart (kMatchMinLen + kLenNumLowSymbols + kLenNumMidSymbols + kLenNumHighSymbols)
#define kMatchSpecLenStart (kMatchMinLen + kLenNumLowSymbols * 2 + kLenNumHighSymbols)
#define IsMatch 0
#define IsRep (IsMatch + (kNumStates << kNumPosBitsMax))
/* External ASM code needs same CLzmaProb array layout. So don't change it. */
/* (probs_1664) is faster and better for code size at some platforms */
/*
#ifdef MY_CPU_X86_OR_AMD64
*/
#define kStartOffset 1664
#define GET_PROBS p->probs_1664
/*
#define GET_PROBS p->probs + kStartOffset
#else
#define kStartOffset 0
#define GET_PROBS p->probs
#endif
*/
#define SpecPos (-kStartOffset)
#define IsRep0Long (SpecPos + kNumFullDistances)
#define RepLenCoder (IsRep0Long + (kNumStates2 << kNumPosBitsMax))
#define LenCoder (RepLenCoder + kNumLenProbs)
#define IsMatch (LenCoder + kNumLenProbs)
#define Align (IsMatch + (kNumStates2 << kNumPosBitsMax))
#define IsRep (Align + kAlignTableSize)
#define IsRepG0 (IsRep + kNumStates)
#define IsRepG1 (IsRepG0 + kNumStates)
#define IsRepG2 (IsRepG1 + kNumStates)
#define IsRep0Long (IsRepG2 + kNumStates)
#define PosSlot (IsRep0Long + (kNumStates << kNumPosBitsMax))
#define SpecPos (PosSlot + (kNumLenToPosStates << kNumPosSlotBits))
#define Align (SpecPos + kNumFullDistances - kEndPosModelIndex)
#define LenCoder (Align + kAlignTableSize)
#define RepLenCoder (LenCoder + kNumLenProbs)
#define Literal (RepLenCoder + kNumLenProbs)
#define PosSlot (IsRepG2 + kNumStates)
#define Literal (PosSlot + (kNumLenToPosStates << kNumPosSlotBits))
#define NUM_BASE_PROBS (Literal + kStartOffset)
#define LZMA_BASE_SIZE 1846
#define LZMA_LIT_SIZE 0x300
#if Literal != LZMA_BASE_SIZE
StopCompilingDueBUG
#if Align != 0 && kStartOffset != 0
#error Stop_Compiling_Bad_LZMA_kAlign
#endif
#define LzmaProps_GetNumProbs(p) (Literal + ((UInt32)LZMA_LIT_SIZE << ((p)->lc + (p)->lp)))
#if NUM_BASE_PROBS != 1984
#error Stop_Compiling_Bad_LZMA_PROBS
#endif
#define LZMA_LIT_SIZE 0x300
#define LzmaProps_GetNumProbs(p) (NUM_BASE_PROBS + ((UInt32)LZMA_LIT_SIZE << ((p)->lc + (p)->lp)))
#define CALC_POS_STATE(processedPos, pbMask) (((processedPos) & (pbMask)) << 4)
#define COMBINED_PS_STATE (posState + state)
#define GET_LEN_STATE (posState)
#define LZMA_DIC_MIN (1 << 12)
/* First LZMA-symbol is always decoded.
And it decodes new LZMA-symbols while (buf < bufLimit), but "buf" is without last normalization
/*
p->remainLen : shows status of LZMA decoder:
< kMatchSpecLenStart : normal remain
= kMatchSpecLenStart : finished
= kMatchSpecLenStart + 1 : need init range coder
= kMatchSpecLenStart + 2 : need init range coder and state
*/
/* ---------- LZMA_DECODE_REAL ---------- */
/*
LzmaDec_DecodeReal_3() can be implemented in external ASM file.
3 - is the code compatibility version of that function for check at link time.
*/
#define LZMA_DECODE_REAL LzmaDec_DecodeReal_3
/*
LZMA_DECODE_REAL()
In:
RangeCoder is normalized
if (p->dicPos == limit)
{
LzmaDec_TryDummy() was called before to exclude LITERAL and MATCH-REP cases.
So first symbol can be only MATCH-NON-REP. And if that MATCH-NON-REP symbol
is not END_OF_PAYALOAD_MARKER, then function returns error code.
}
Processing:
first LZMA symbol will be decoded in any case
All checks for limits are at the end of main loop,
It will decode new LZMA-symbols while (p->buf < bufLimit && dicPos < limit),
RangeCoder is still without last normalization when (p->buf < bufLimit) is being checked.
Out:
RangeCoder is normalized
Result:
SZ_OK - OK
SZ_ERROR_DATA - Error
p->remainLen:
< kMatchSpecLenStart : normal remain
= kMatchSpecLenStart : finished
= kMatchSpecLenStart + 1 : Flush marker (unused now)
= kMatchSpecLenStart + 2 : State Init Marker (unused now)
*/
static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte *bufLimit)
{
CLzmaProb *probs = p->probs;
unsigned state = p->state;
#ifdef _LZMA_DEC_OPT
int MY_FAST_CALL LZMA_DECODE_REAL(CLzmaDec *p, SizeT limit, const Byte *bufLimit);
#else
static
int MY_FAST_CALL LZMA_DECODE_REAL(CLzmaDec *p, SizeT limit, const Byte *bufLimit)
{
CLzmaProb *probs = GET_PROBS;
unsigned state = (unsigned)p->state;
UInt32 rep0 = p->reps[0], rep1 = p->reps[1], rep2 = p->reps[2], rep3 = p->reps[3];
unsigned pbMask = ((unsigned)1 << (p->prop.pb)) - 1;
unsigned lpMask = ((unsigned)1 << (p->prop.lp)) - 1;
unsigned lc = p->prop.lc;
unsigned lpMask = ((unsigned)0x100 << p->prop.lp) - ((unsigned)0x100 >> lc);
Byte *dic = p->dic;
SizeT dicBufSize = p->dicBufSize;
@@ -164,17 +241,16 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte
CLzmaProb *prob;
UInt32 bound;
unsigned ttt;
unsigned posState = processedPos & pbMask;
unsigned posState = CALC_POS_STATE(processedPos, pbMask);
prob = probs + IsMatch + (state << kNumPosBitsMax) + posState;
prob = probs + IsMatch + COMBINED_PS_STATE;
IF_BIT_0(prob)
{
unsigned symbol;
UPDATE_0(prob);
prob = probs + Literal;
if (processedPos != 0 || checkDicSize != 0)
prob += ((UInt32)LZMA_LIT_SIZE * (((processedPos & lpMask) << lc) +
(dic[(dicPos == 0 ? dicBufSize : dicPos) - 1] >> (8 - lc))));
prob += (UInt32)3 * ((((processedPos << 8) + dic[(dicPos == 0 ? dicBufSize : dicPos) - 1]) & lpMask) << lc);
processedPos++;
if (state < kNumLitStates)
@@ -240,13 +316,16 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte
else
{
UPDATE_1(prob);
/*
// that case was checked before with kBadRepCode
if (checkDicSize == 0 && processedPos == 0)
return SZ_ERROR_DATA;
*/
prob = probs + IsRepG0 + state;
IF_BIT_0(prob)
{
UPDATE_0(prob);
prob = probs + IsRep0Long + (state << kNumPosBitsMax) + posState;
prob = probs + IsRep0Long + COMBINED_PS_STATE;
IF_BIT_0(prob)
{
UPDATE_0(prob);
@@ -299,7 +378,7 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte
IF_BIT_0(probLen)
{
UPDATE_0(probLen);
probLen = prob + LenLow + (posState << kLenNumLowBits);
probLen = prob + LenLow + GET_LEN_STATE;
offset = 0;
lim = (1 << kLenNumLowBits);
}
@@ -310,15 +389,15 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte
IF_BIT_0(probLen)
{
UPDATE_0(probLen);
probLen = prob + LenMid + (posState << kLenNumMidBits);
probLen = prob + LenLow + GET_LEN_STATE + (1 << kLenNumLowBits);
offset = kLenNumLowSymbols;
lim = (1 << kLenNumMidBits);
lim = (1 << kLenNumLowBits);
}
else
{
UPDATE_1(probLen);
probLen = prob + LenHigh;
offset = kLenNumLowSymbols + kLenNumMidSymbols;
offset = kLenNumLowSymbols * 2;
lim = (1 << kLenNumHighBits);
}
}
@@ -331,7 +410,7 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte
IF_BIT_0(probLen)
{
UPDATE_0(probLen);
probLen = prob + LenLow + (posState << kLenNumLowBits);
probLen = prob + LenLow + GET_LEN_STATE;
len = 1;
TREE_GET_BIT(probLen, len);
TREE_GET_BIT(probLen, len);
@@ -345,7 +424,7 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte
IF_BIT_0(probLen)
{
UPDATE_0(probLen);
probLen = prob + LenMid + (posState << kLenNumMidBits);
probLen = prob + LenLow + GET_LEN_STATE + (1 << kLenNumLowBits);
len = 1;
TREE_GET_BIT(probLen, len);
TREE_GET_BIT(probLen, len);
@@ -356,7 +435,7 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte
UPDATE_1(probLen);
probLen = prob + LenHigh;
TREE_DECODE(probLen, (1 << kLenNumHighBits), len);
len += kLenNumLowSymbols + kLenNumMidSymbols;
len += kLenNumLowSymbols * 2;
}
}
}
@@ -376,16 +455,16 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte
if (posSlot < kEndPosModelIndex)
{
distance <<= numDirectBits;
prob = probs + SpecPos + distance - posSlot - 1;
prob = probs + SpecPos;
{
UInt32 mask = 1;
unsigned i = 1;
UInt32 m = 1;
distance++;
do
{
GET_BIT2(prob + i, i, ; , distance |= mask);
mask <<= 1;
REV_BIT_VAR(prob, distance, m);
}
while (--numDirectBits != 0);
while (--numDirectBits);
distance -= m;
}
}
else
@@ -412,19 +491,20 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte
}
*/
}
while (--numDirectBits != 0);
while (--numDirectBits);
prob = probs + Align;
distance <<= kNumAlignBits;
{
unsigned i = 1;
GET_BIT2(prob + i, i, ; , distance |= 1);
GET_BIT2(prob + i, i, ; , distance |= 2);
GET_BIT2(prob + i, i, ; , distance |= 4);
GET_BIT2(prob + i, i, ; , distance |= 8);
REV_BIT_CONST(prob, i, 1);
REV_BIT_CONST(prob, i, 2);
REV_BIT_CONST(prob, i, 4);
REV_BIT_LAST (prob, i, 8);
distance |= i;
}
if (distance == (UInt32)0xFFFFFFFF)
{
len += kMatchSpecLenStart;
len = kMatchSpecLenStart;
state -= kNumStates;
break;
}
@@ -435,20 +515,12 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte
rep2 = rep1;
rep1 = rep0;
rep0 = distance + 1;
if (checkDicSize == 0)
{
if (distance >= processedPos)
{
p->dicPos = dicPos;
return SZ_ERROR_DATA;
}
}
else if (distance >= checkDicSize)
state = (state < kNumStates + kNumLitStates) ? kNumLitStates : kNumLitStates + 3;
if (distance >= (checkDicSize == 0 ? processedPos: checkDicSize))
{
p->dicPos = dicPos;
return SZ_ERROR_DATA;
}
state = (state < kNumStates + kNumLitStates) ? kNumLitStates : kNumLitStates + 3;
}
len += kMatchMinLen;
@@ -511,6 +583,7 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte
return SZ_OK;
}
#endif
static void MY_FAST_CALL LzmaDec_WriteRem(CLzmaDec *p, SizeT limit)
{
@@ -519,7 +592,7 @@ static void MY_FAST_CALL LzmaDec_WriteRem(CLzmaDec *p, SizeT limit)
Byte *dic = p->dic;
SizeT dicPos = p->dicPos;
SizeT dicBufSize = p->dicBufSize;
unsigned len = p->remainLen;
unsigned len = (unsigned)p->remainLen;
SizeT rep0 = p->reps[0]; /* we use SizeT to avoid the BUG of VC14 for AMD64 */
SizeT rem = limit - dicPos;
if (rem < len)
@@ -540,6 +613,14 @@ static void MY_FAST_CALL LzmaDec_WriteRem(CLzmaDec *p, SizeT limit)
}
}
#define kRange0 0xFFFFFFFF
#define kBound0 ((kRange0 >> kNumBitModelTotalBits) << (kNumBitModelTotalBits - 1))
#define kBadRepCode (kBound0 + (((kRange0 - kBound0) >> kNumBitModelTotalBits) << (kNumBitModelTotalBits - 1)))
#if kBadRepCode != (0xC0000000 - 0x400)
#error Stop_Compiling_Bad_LZMA_Check
#endif
static int MY_FAST_CALL LzmaDec_DecodeReal2(CLzmaDec *p, SizeT limit, const Byte *bufLimit)
{
do
@@ -550,9 +631,13 @@ static int MY_FAST_CALL LzmaDec_DecodeReal2(CLzmaDec *p, SizeT limit, const Byte
UInt32 rem = p->prop.dicSize - p->processedPos;
if (limit - p->dicPos > rem)
limit2 = p->dicPos + rem;
if (p->processedPos == 0)
if (p->code >= kBadRepCode)
return SZ_ERROR_DATA;
}
RINOK(LzmaDec_DecodeReal(p, limit2, bufLimit));
RINOK(LZMA_DECODE_REAL(p, limit2, bufLimit));
if (p->checkDicSize == 0 && p->processedPos >= p->prop.dicSize)
p->checkDicSize = p->prop.dicSize;
@@ -561,9 +646,6 @@ static int MY_FAST_CALL LzmaDec_DecodeReal2(CLzmaDec *p, SizeT limit, const Byte
}
while (p->dicPos < limit && p->buf < bufLimit && p->remainLen < kMatchSpecLenStart);
if (p->remainLen > kMatchSpecLenStart)
p->remainLen = kMatchSpecLenStart;
return 0;
}
@@ -580,17 +662,17 @@ static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inS
UInt32 range = p->range;
UInt32 code = p->code;
const Byte *bufLimit = buf + inSize;
const CLzmaProb *probs = p->probs;
unsigned state = p->state;
const CLzmaProb *probs = GET_PROBS;
unsigned state = (unsigned)p->state;
ELzmaDummy res;
{
const CLzmaProb *prob;
UInt32 bound;
unsigned ttt;
unsigned posState = (p->processedPos) & ((1 << p->prop.pb) - 1);
unsigned posState = CALC_POS_STATE(p->processedPos, (1 << p->prop.pb) - 1);
prob = probs + IsMatch + (state << kNumPosBitsMax) + posState;
prob = probs + IsMatch + COMBINED_PS_STATE;
IF_BIT_0_CHECK(prob)
{
UPDATE_0_CHECK
@@ -618,10 +700,11 @@ static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inS
{
unsigned bit;
const CLzmaProb *probLit;
matchByte <<= 1;
bit = (matchByte & offs);
probLit = prob + offs + bit + symbol;
GET_BIT2_CHECK(probLit, symbol, offs &= ~bit, offs &= bit)
matchByte += matchByte;
bit = offs;
offs &= matchByte;
probLit = prob + (offs + bit + symbol);
GET_BIT2_CHECK(probLit, symbol, offs ^= bit; , ; )
}
while (symbol < 0x100);
}
@@ -648,7 +731,7 @@ static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inS
IF_BIT_0_CHECK(prob)
{
UPDATE_0_CHECK;
prob = probs + IsRep0Long + (state << kNumPosBitsMax) + posState;
prob = probs + IsRep0Long + COMBINED_PS_STATE;
IF_BIT_0_CHECK(prob)
{
UPDATE_0_CHECK;
@@ -691,7 +774,7 @@ static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inS
IF_BIT_0_CHECK(probLen)
{
UPDATE_0_CHECK;
probLen = prob + LenLow + (posState << kLenNumLowBits);
probLen = prob + LenLow + GET_LEN_STATE;
offset = 0;
limit = 1 << kLenNumLowBits;
}
@@ -702,15 +785,15 @@ static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inS
IF_BIT_0_CHECK(probLen)
{
UPDATE_0_CHECK;
probLen = prob + LenMid + (posState << kLenNumMidBits);
probLen = prob + LenLow + GET_LEN_STATE + (1 << kLenNumLowBits);
offset = kLenNumLowSymbols;
limit = 1 << kLenNumMidBits;
limit = 1 << kLenNumLowBits;
}
else
{
UPDATE_1_CHECK;
probLen = prob + LenHigh;
offset = kLenNumLowSymbols + kLenNumMidSymbols;
offset = kLenNumLowSymbols * 2;
limit = 1 << kLenNumHighBits;
}
}
@@ -722,7 +805,7 @@ static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inS
{
unsigned posSlot;
prob = probs + PosSlot +
((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) <<
((len < kNumLenToPosStates - 1 ? len : kNumLenToPosStates - 1) <<
kNumPosSlotBits);
TREE_DECODE_CHECK(prob, 1 << kNumPosSlotBits, posSlot);
if (posSlot >= kStartPosModelIndex)
@@ -733,7 +816,7 @@ static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inS
if (posSlot < kEndPosModelIndex)
{
prob = probs + SpecPos + ((2 | (posSlot & 1)) << numDirectBits) - posSlot - 1;
prob = probs + SpecPos + ((2 | (posSlot & 1)) << numDirectBits);
}
else
{
@@ -745,17 +828,18 @@ static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inS
code -= range & (((code - range) >> 31) - 1);
/* if (code >= range) code -= range; */
}
while (--numDirectBits != 0);
while (--numDirectBits);
prob = probs + Align;
numDirectBits = kNumAlignBits;
}
{
unsigned i = 1;
unsigned m = 1;
do
{
GET_BIT_CHECK(prob + i, i);
REV_BIT_CHECK(prob, i, m);
}
while (--numDirectBits != 0);
while (--numDirectBits);
}
}
}
@@ -768,18 +852,17 @@ static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inS
void LzmaDec_InitDicAndState(CLzmaDec *p, Bool initDic, Bool initState)
{
p->needFlush = 1;
p->remainLen = 0;
p->remainLen = kMatchSpecLenStart + 1;
p->tempBufSize = 0;
if (initDic)
{
p->processedPos = 0;
p->checkDicSize = 0;
p->needInitState = 1;
p->remainLen = kMatchSpecLenStart + 2;
}
if (initState)
p->needInitState = 1;
p->remainLen = kMatchSpecLenStart + 2;
}
void LzmaDec_Init(CLzmaDec *p)
@@ -788,53 +871,54 @@ void LzmaDec_Init(CLzmaDec *p)
LzmaDec_InitDicAndState(p, True, True);
}
static void LzmaDec_InitStateReal(CLzmaDec *p)
{
SizeT numProbs = LzmaProps_GetNumProbs(&p->prop);
SizeT i;
CLzmaProb *probs = p->probs;
for (i = 0; i < numProbs; i++)
probs[i] = kBitModelTotal >> 1;
p->reps[0] = p->reps[1] = p->reps[2] = p->reps[3] = 1;
p->state = 0;
p->needInitState = 0;
}
SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, const Byte *src, SizeT *srcLen,
ELzmaFinishMode finishMode, ELzmaStatus *status)
{
SizeT inSize = *srcLen;
(*srcLen) = 0;
LzmaDec_WriteRem(p, dicLimit);
*status = LZMA_STATUS_NOT_SPECIFIED;
if (p->remainLen > kMatchSpecLenStart)
{
for (; inSize > 0 && p->tempBufSize < RC_INIT_SIZE; (*srcLen)++, inSize--)
p->tempBuf[p->tempBufSize++] = *src++;
if (p->tempBufSize != 0 && p->tempBuf[0] != 0)
return SZ_ERROR_DATA;
if (p->tempBufSize < RC_INIT_SIZE)
{
*status = LZMA_STATUS_NEEDS_MORE_INPUT;
return SZ_OK;
}
p->code =
((UInt32)p->tempBuf[1] << 24)
| ((UInt32)p->tempBuf[2] << 16)
| ((UInt32)p->tempBuf[3] << 8)
| ((UInt32)p->tempBuf[4]);
p->range = 0xFFFFFFFF;
p->tempBufSize = 0;
if (p->remainLen > kMatchSpecLenStart + 1)
{
SizeT numProbs = LzmaProps_GetNumProbs(&p->prop);
SizeT i;
CLzmaProb *probs = p->probs;
for (i = 0; i < numProbs; i++)
probs[i] = kBitModelTotal >> 1;
p->reps[0] = p->reps[1] = p->reps[2] = p->reps[3] = 1;
p->state = 0;
}
p->remainLen = 0;
}
LzmaDec_WriteRem(p, dicLimit);
while (p->remainLen != kMatchSpecLenStart)
{
int checkEndMarkNow;
int checkEndMarkNow = 0;
if (p->needFlush)
{
for (; inSize > 0 && p->tempBufSize < RC_INIT_SIZE; (*srcLen)++, inSize--)
p->tempBuf[p->tempBufSize++] = *src++;
if (p->tempBufSize < RC_INIT_SIZE)
{
*status = LZMA_STATUS_NEEDS_MORE_INPUT;
return SZ_OK;
}
if (p->tempBuf[0] != 0)
return SZ_ERROR_DATA;
p->code =
((UInt32)p->tempBuf[1] << 24)
| ((UInt32)p->tempBuf[2] << 16)
| ((UInt32)p->tempBuf[3] << 8)
| ((UInt32)p->tempBuf[4]);
p->range = 0xFFFFFFFF;
p->needFlush = 0;
p->tempBufSize = 0;
}
checkEndMarkNow = 0;
if (p->dicPos >= dicLimit)
{
if (p->remainLen == 0 && p->code == 0)
@@ -855,9 +939,6 @@ SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, const Byte *src, SizeT *sr
checkEndMarkNow = 1;
}
if (p->needInitState)
LzmaDec_InitStateReal(p);
if (p->tempBufSize == 0)
{
SizeT processed;
@@ -930,11 +1011,14 @@ SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, const Byte *src, SizeT *sr
p->tempBufSize = 0;
}
}
if (p->code == 0)
*status = LZMA_STATUS_FINISHED_WITH_MARK;
return (p->code == 0) ? SZ_OK : SZ_ERROR_DATA;
if (p->code != 0)
return SZ_ERROR_DATA;
*status = LZMA_STATUS_FINISHED_WITH_MARK;
return SZ_OK;
}
SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status)
{
SizeT outSize = *destLen;
@@ -1011,10 +1095,10 @@ SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size)
if (d >= (9 * 5 * 5))
return SZ_ERROR_UNSUPPORTED;
p->lc = d % 9;
p->lc = (Byte)(d % 9);
d /= 9;
p->pb = d / 5;
p->lp = d % 5;
p->pb = (Byte)(d / 5);
p->lp = (Byte)(d % 5);
return SZ_OK;
}
@@ -1026,9 +1110,10 @@ static SRes LzmaDec_AllocateProbs2(CLzmaDec *p, const CLzmaProps *propNew, ISzAl
{
LzmaDec_FreeProbs(p, alloc);
p->probs = (CLzmaProb *)ISzAlloc_Alloc(alloc, numProbs * sizeof(CLzmaProb));
p->numProbs = numProbs;
if (!p->probs)
return SZ_ERROR_MEM;
p->probs_1664 = p->probs + 1664;
p->numProbs = numProbs;
}
return SZ_OK;
}

View File

@@ -1,5 +1,5 @@
/* LzmaDec.h -- LZMA Decoder
2017-04-03 : Igor Pavlov : Public domain */
2018-02-06 : Igor Pavlov : Public domain */
#ifndef __LZMA_DEC_H
#define __LZMA_DEC_H
@@ -25,7 +25,10 @@ EXTERN_C_BEGIN
typedef struct _CLzmaProps
{
unsigned lc, lp, pb;
Byte lc;
Byte lp;
Byte pb;
Byte _pad_;
UInt32 dicSize;
} CLzmaProps;
@@ -47,26 +50,28 @@ SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size);
typedef struct
{
/* Don't change this structure. ASM code can use it. */
CLzmaProps prop;
CLzmaProb *probs;
CLzmaProb *probs_1664;
Byte *dic;
const Byte *buf;
UInt32 range, code;
SizeT dicPos;
SizeT dicBufSize;
SizeT dicPos;
const Byte *buf;
UInt32 range;
UInt32 code;
UInt32 processedPos;
UInt32 checkDicSize;
unsigned state;
UInt32 reps[4];
unsigned remainLen;
int needFlush;
int needInitState;
UInt32 state;
UInt32 remainLen;
UInt32 numProbs;
unsigned tempBufSize;
Byte tempBuf[LZMA_REQUIRED_INPUT_MAX];
} CLzmaDec;
#define LzmaDec_Construct(p) { (p)->dic = 0; (p)->probs = 0; }
#define LzmaDec_Construct(p) { (p)->dic = NULL; (p)->probs = NULL; }
void LzmaDec_Init(CLzmaDec *p);
@@ -132,8 +137,8 @@ LzmaDec_Allocate* can return:
SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAllocPtr alloc);
void LzmaDec_FreeProbs(CLzmaDec *p, ISzAllocPtr alloc);
SRes LzmaDec_Allocate(CLzmaDec *state, const Byte *prop, unsigned propsSize, ISzAllocPtr alloc);
void LzmaDec_Free(CLzmaDec *state, ISzAllocPtr alloc);
SRes LzmaDec_Allocate(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAllocPtr alloc);
void LzmaDec_Free(CLzmaDec *p, ISzAllocPtr alloc);
/* ---------- Dictionary Interface ---------- */

View File

@@ -1,85 +1,28 @@
/* MtCoder.c -- Multi-thread Coder
2017-07-17 : Igor Pavlov : Public domain */
2018-02-21 : Igor Pavlov : Public domain */
#include "Precomp.h"
#include "MtCoder.h"
static void MtProgress_Init(CMtProgress *p, ICompressProgress *progress)
#ifndef _7ZIP_ST
SRes MtProgressThunk_Progress(const ICompressProgress *pp, UInt64 inSize, UInt64 outSize)
{
unsigned i;
p->progress = progress;
p->res = SZ_OK;
p->totalInSize = 0;
p->totalOutSize = 0;
for (i = 0; i < MTCODER__THREADS_MAX; i++)
CMtProgressThunk *thunk = CONTAINER_FROM_VTBL(pp, CMtProgressThunk, vt);
UInt64 inSize2 = 0;
UInt64 outSize2 = 0;
if (inSize != (UInt64)(Int64)-1)
{
CMtProgressSizes *pair = &p->sizes[i];
pair->inSize = 0;
pair->outSize = 0;
inSize2 = inSize - thunk->inSize;
thunk->inSize = inSize;
}
}
static void MtProgress_Reinit(CMtProgress *p, unsigned index)
{
CMtProgressSizes *pair = &p->sizes[index];
pair->inSize = 0;
pair->outSize = 0;
}
#define UPDATE_PROGRESS(size, prev, total) \
if (size != (UInt64)(Int64)-1) { total += size - prev; prev = size; }
SRes MtProgress_Set(CMtProgress *p, unsigned index, UInt64 inSize, UInt64 outSize)
{
SRes res;
CMtProgressSizes *pair;
CriticalSection_Enter(&p->cs);
pair = &p->sizes[index];
UPDATE_PROGRESS(inSize, pair->inSize, p->totalInSize)
UPDATE_PROGRESS(outSize, pair->outSize, p->totalOutSize)
if (p->res == SZ_OK && p->progress)
if (outSize != (UInt64)(Int64)-1)
{
if (ICompressProgress_Progress(p->progress, p->totalInSize, p->totalOutSize) != SZ_OK)
p->res = SZ_ERROR_PROGRESS;
outSize2 = outSize - thunk->outSize;
thunk->outSize = outSize;
}
res = p->res;
CriticalSection_Leave(&p->cs);
return res;
}
static SRes MtProgress_GetError(CMtProgress *p)
{
SRes res;
CriticalSection_Enter(&p->cs);
res = p->res;
CriticalSection_Leave(&p->cs);
return res;
}
static void MtProgress_SetError(CMtProgress *p, SRes res)
{
CriticalSection_Enter(&p->cs);
if (p->res == SZ_OK)
p->res = res;
CriticalSection_Leave(&p->cs);
}
static SRes MtProgressThunk_Progress(const ICompressProgress *pp, UInt64 inSize, UInt64 outSize)
{
CMtProgressThunk *p = CONTAINER_FROM_VTBL(pp, CMtProgressThunk, vt);
return MtProgress_Set(p->mtProgress, p->index, inSize, outSize);
return MtProgress_ProgressAdd(thunk->mtProgress, inSize2, outSize2);
}
@@ -298,7 +241,7 @@ static SRes ThreadFunc2(CMtCoderThread *t)
res = mtc->mtCallback->Code(mtc->mtCallbackObject, t->index, bufIndex,
mtc->inStream ? t->inBuf : inData, size, finished);
MtProgress_Reinit(&mtc->mtProgress, t->index);
// MtProgress_Reinit(&mtc->mtProgress, t->index);
if (res != SZ_OK)
MtProgress_SetError(&mtc->mtProgress, res);
@@ -654,3 +597,5 @@ SRes MtCoder_Code(CMtCoder *p)
MtCoder_Free(p);
return res;
}
#endif

View File

@@ -1,10 +1,10 @@
/* MtCoder.h -- Multi-thread Coder
2017-06-18 : Igor Pavlov : Public domain */
2018-02-21 : Igor Pavlov : Public domain */
#ifndef __MT_CODER_H
#define __MT_CODER_H
#include "Threads.h"
#include "MtDec.h"
EXTERN_C_BEGIN
@@ -24,33 +24,20 @@ EXTERN_C_BEGIN
#endif
typedef struct
{
UInt64 inSize;
UInt64 outSize;
} CMtProgressSizes;
typedef struct
{
ICompressProgress *progress;
SRes res;
UInt64 totalInSize;
UInt64 totalOutSize;
CCriticalSection cs;
CMtProgressSizes sizes[MTCODER__THREADS_MAX];
} CMtProgress;
#ifndef _7ZIP_ST
typedef struct
{
ICompressProgress vt;
CMtProgress *mtProgress;
unsigned index;
UInt64 inSize;
UInt64 outSize;
} CMtProgressThunk;
void MtProgressThunk_CreateVTable(CMtProgressThunk *p);
#define MtProgressThunk_Init(p) { (p)->inSize = 0; (p)->outSize = 0; }
struct _CMtCoder;
@@ -146,6 +133,9 @@ void MtCoder_Destruct(CMtCoder *p);
SRes MtCoder_Code(CMtCoder *p);
#endif
EXTERN_C_END
#endif

1137
C/MtDec.c Normal file
View File

File diff suppressed because it is too large Load Diff

201
C/MtDec.h Normal file
View File

@@ -0,0 +1,201 @@
/* MtDec.h -- Multi-thread Decoder
2018-03-02 : Igor Pavlov : Public domain */
#ifndef __MT_DEC_H
#define __MT_DEC_H
#include "7zTypes.h"
#ifndef _7ZIP_ST
#include "Threads.h"
#endif
EXTERN_C_BEGIN
#ifndef _7ZIP_ST
#ifndef _7ZIP_ST
#define MTDEC__THREADS_MAX 32
#else
#define MTDEC__THREADS_MAX 1
#endif
typedef struct
{
ICompressProgress *progress;
SRes res;
UInt64 totalInSize;
UInt64 totalOutSize;
CCriticalSection cs;
} CMtProgress;
void MtProgress_Init(CMtProgress *p, ICompressProgress *progress);
SRes MtProgress_Progress_ST(CMtProgress *p);
SRes MtProgress_ProgressAdd(CMtProgress *p, UInt64 inSize, UInt64 outSize);
SRes MtProgress_GetError(CMtProgress *p);
void MtProgress_SetError(CMtProgress *p, SRes res);
struct _CMtDec;
typedef struct
{
struct _CMtDec *mtDec;
unsigned index;
void *inBuf;
size_t inDataSize_Start; // size of input data in start block
UInt64 inDataSize; // total size of input data in all blocks
CThread thread;
CAutoResetEvent canRead;
CAutoResetEvent canWrite;
void *allocaPtr;
} CMtDecThread;
void MtDecThread_FreeInBufs(CMtDecThread *t);
typedef enum
{
MTDEC_PARSE_CONTINUE, // continue this block with more input data
MTDEC_PARSE_OVERFLOW, // MT buffers overflow, need switch to single-thread
MTDEC_PARSE_NEW, // new block
MTDEC_PARSE_END // end of block threading. But we still can return to threading after Write(&needContinue)
} EMtDecParseState;
typedef struct
{
// in
int startCall;
const Byte *src;
size_t srcSize;
// in : (srcSize == 0) is allowed
// out : it's allowed to return less that actually was used ?
int srcFinished;
// out
EMtDecParseState state;
Bool canCreateNewThread;
UInt64 outPos; // check it (size_t)
} CMtDecCallbackInfo;
typedef struct
{
void (*Parse)(void *p, unsigned coderIndex, CMtDecCallbackInfo *ci);
// PreCode() and Code():
// (SRes_return_result != SZ_OK) means stop decoding, no need another blocks
SRes (*PreCode)(void *p, unsigned coderIndex);
SRes (*Code)(void *p, unsigned coderIndex,
const Byte *src, size_t srcSize, int srcFinished,
UInt64 *inCodePos, UInt64 *outCodePos, int *stop);
// stop - means stop another Code calls
/* Write() must be called, if Parse() was called
set (needWrite) if
{
&& (was not interrupted by progress)
&& (was not interrupted in previous block)
}
out:
if (*needContinue), decoder still need to continue decoding with new iteration,
even after MTDEC_PARSE_END
if (*canRecode), we didn't flush current block data, so we still can decode current block later.
*/
SRes (*Write)(void *p, unsigned coderIndex,
Bool needWriteToStream,
const Byte *src, size_t srcSize,
// int srcFinished,
Bool *needContinue,
Bool *canRecode);
} IMtDecCallback;
typedef struct _CMtDec
{
/* input variables */
size_t inBufSize; /* size of input block */
unsigned numThreadsMax;
// size_t inBlockMax;
unsigned numThreadsMax_2;
ISeqInStream *inStream;
// const Byte *inData;
// size_t inDataSize;
ICompressProgress *progress;
ISzAllocPtr alloc;
IMtDecCallback *mtCallback;
void *mtCallbackObject;
/* internal variables */
size_t allocatedBufsSize;
Bool exitThread;
WRes exitThreadWRes;
UInt64 blockIndex;
Bool isAllocError;
Bool overflow;
SRes threadingErrorSRes;
Bool needContinue;
// CAutoResetEvent finishedEvent;
SRes readRes;
SRes codeRes;
Bool wasInterrupted;
unsigned numStartedThreads_Limit;
unsigned numStartedThreads;
Byte *crossBlock;
size_t crossStart;
size_t crossEnd;
UInt64 readProcessed;
Bool readWasFinished;
UInt64 inProcessed;
unsigned filledThreadStart;
unsigned numFilledThreads;
#ifndef _7ZIP_ST
Bool needInterrupt;
UInt64 interruptIndex;
CMtProgress mtProgress;
CMtDecThread threads[MTDEC__THREADS_MAX];
#endif
} CMtDec;
void MtDec_Construct(CMtDec *p);
void MtDec_Destruct(CMtDec *p);
/*
MtDec_Code() returns:
SZ_OK - in most cases
MY_SRes_HRESULT_FROM_WRes(WRes_error) - in case of unexpected error in threading function
*/
SRes MtDec_Code(CMtDec *p);
Byte *MtDec_GetCrossBuff(CMtDec *p);
int MtDec_PrepareRead(CMtDec *p);
const Byte *MtDec_Read(CMtDec *p, size_t *inLim);
#endif
EXTERN_C_END
#endif

View File

@@ -1,5 +1,5 @@
/* 7zipUninstall.c - 7-Zip Uninstaller
2017-04-04 : Igor Pavlov : Public domain */
2018-03-01 : Igor Pavlov : Public domain */
#include "Precomp.h"
@@ -546,7 +546,7 @@ static BOOL RemoveDir()
#define k_Lang L"Lang"
// NUM_LANG_TXT_FILES files are placed before en.ttt
#define NUM_LANG_TXT_FILES 87
#define NUM_LANG_TXT_FILES 88
#ifdef _64BIT_INSTALLER
#define NUM_EXTRA_FILES_64BIT 1
@@ -558,7 +558,7 @@ static BOOL RemoveDir()
static const char * const k_Names =
"af an ar ast az ba be bg bn br ca co cs cy da de el eo es et eu ext"
" fa fi fr fur fy ga gl gu he hi hr hu hy id io is it ja ka kaa kk ko ku ku-ckb ky"
" fa fi fr fur fy ga gl gu he hi hr hu hy id io is it ja ka kaa kab kk ko ku ku-ckb ky"
" lij lt lv mk mn mng mng2 mr ms nb ne nl nn pa-in pl ps pt pt-br ro ru"
" sa si sk sl sq sr-spc sr-spl sv ta th tr tt ug uk uz va vi yo zh-cn zh-tw"
" en.ttt"

190
C/Xz.h
View File

@@ -1,5 +1,5 @@
/* Xz.h - Xz interface
2017-07-27 : Igor Pavlov : Public domain */
2018-02-28 : Igor Pavlov : Public domain */
#ifndef __XZ_H
#define __XZ_H
@@ -139,6 +139,9 @@ SRes Xzs_ReadBackward(CXzs *p, ILookInStream *inStream, Int64 *startOffset, ICom
UInt64 Xzs_GetNumBlocks(const CXzs *p);
UInt64 Xzs_GetUnpackSize(const CXzs *p);
// ECoderStatus values are identical to ELzmaStatus values of LZMA2 decoder
typedef enum
{
CODER_STATUS_NOT_SPECIFIED, /* use main error code instead */
@@ -147,22 +150,31 @@ typedef enum
CODER_STATUS_NEEDS_MORE_INPUT /* you must provide more input bytes */
} ECoderStatus;
// ECoderFinishMode values are identical to ELzmaFinishMode
typedef enum
{
CODER_FINISH_ANY, /* finish at any point */
CODER_FINISH_END /* block must be finished at the end */
} ECoderFinishMode;
typedef struct _IStateCoder
{
void *p;
void (*Free)(void *p, ISzAllocPtr alloc);
SRes (*SetProps)(void *p, const Byte *props, size_t propSize, ISzAllocPtr alloc);
void (*Init)(void *p);
SRes (*Code)(void *p, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
int srcWasFinished, ECoderFinishMode finishMode, int *wasFinished);
SRes (*Code2)(void *p, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
int srcWasFinished, ECoderFinishMode finishMode,
// int *wasFinished,
ECoderStatus *status);
SizeT (*Filter)(void *p, Byte *data, SizeT size);
} IStateCoder;
#define MIXCODER_NUM_FILTERS_MAX 4
typedef struct
@@ -170,20 +182,23 @@ typedef struct
ISzAllocPtr alloc;
Byte *buf;
unsigned numCoders;
Byte *outBuf;
size_t outBufSize;
size_t outWritten; // is equal to lzmaDecoder.dicPos (in outBuf mode)
Bool wasFinished;
SRes res;
ECoderStatus status;
// Bool SingleBufMode;
int finished[MIXCODER_NUM_FILTERS_MAX - 1];
size_t pos[MIXCODER_NUM_FILTERS_MAX - 1];
size_t size[MIXCODER_NUM_FILTERS_MAX - 1];
UInt64 ids[MIXCODER_NUM_FILTERS_MAX];
SRes results[MIXCODER_NUM_FILTERS_MAX];
IStateCoder coders[MIXCODER_NUM_FILTERS_MAX];
} CMixCoder;
void MixCoder_Construct(CMixCoder *p, ISzAllocPtr alloc);
void MixCoder_Free(CMixCoder *p);
void MixCoder_Init(CMixCoder *p);
SRes MixCoder_SetFromMethod(CMixCoder *p, unsigned coderIndex, UInt64 methodId);
SRes MixCoder_Code(CMixCoder *p, Byte *dest, SizeT *destLen,
const Byte *src, SizeT *srcLen, int srcWasFinished,
ECoderFinishMode finishMode, ECoderStatus *status);
typedef enum
{
@@ -197,6 +212,7 @@ typedef enum
XZ_STATE_BLOCK_FOOTER
} EXzState;
typedef struct
{
EXzState state;
@@ -210,7 +226,7 @@ typedef struct
UInt64 packSize;
UInt64 unpackSize;
UInt64 numBlocks;
UInt64 numBlocks; // number of finished blocks in current stream
UInt64 indexSize;
UInt64 indexPos;
UInt64 padSize;
@@ -225,16 +241,64 @@ typedef struct
CXzCheck check;
CSha256 sha;
Bool parseMode;
Bool headerParsedOk;
Bool decodeToStreamSignature;
unsigned decodeOnlyOneBlock;
Byte *outBuf;
size_t outBufSize;
size_t outDataWritten; // the size of data in (outBuf) that were fully unpacked
Byte shaDigest[SHA256_DIGEST_SIZE];
Byte buf[XZ_BLOCK_HEADER_SIZE_MAX];
} CXzUnpacker;
/* alloc : aligned for cache line allocation is better */
void XzUnpacker_Construct(CXzUnpacker *p, ISzAllocPtr alloc);
void XzUnpacker_Init(CXzUnpacker *p);
void XzUnpacker_SetOutBuf(CXzUnpacker *p, Byte *outBuf, size_t outBufSize);
void XzUnpacker_Free(CXzUnpacker *p);
/*
XzUnpacker
The sequence for decoding functions:
{
XzUnpacker_Construct()
[Decoding_Calls]
XzUnpacker_Free()
}
[Decoding_Calls]
There are 3 types of interfaces for [Decoding_Calls] calls:
Interface-1 : Partial output buffers:
{
XzUnpacker_Init()
for()
XzUnpacker_Code();
}
Interface-2 : Direct output buffer:
Use it, if you know exact size of decoded data, and you need
whole xz unpacked data in one output buffer.
xz unpacker doesn't allocate additional buffer for lzma2 dictionary in that mode.
{
XzUnpacker_Init()
XzUnpacker_SetOutBufMode(); // to set output buffer and size
for()
XzUnpacker_Code(); // (dest = NULL) in XzUnpacker_Code()
}
Interface-3 : Direct output buffer : One call full decoding
It unpacks whole input buffer to output buffer in one call.
It uses Interface-2 internally.
{
XzUnpacker_CodeFull()
}
*/
/*
finishMode:
It has meaning only if the decoding reaches output limit (*destLen).
@@ -264,15 +328,23 @@ Returns:
SRes XzUnpacker_Code(CXzUnpacker *p, Byte *dest, SizeT *destLen,
const Byte *src, SizeT *srcLen, ECoderFinishMode finishMode,
ECoderStatus *status);
const Byte *src, SizeT *srcLen, int srcFinished,
ECoderFinishMode finishMode, ECoderStatus *status);
SRes XzUnpacker_CodeFull(CXzUnpacker *p, Byte *dest, SizeT *destLen,
const Byte *src, SizeT *srcLen,
ECoderFinishMode finishMode, ECoderStatus *status);
Bool XzUnpacker_IsStreamWasFinished(const CXzUnpacker *p);
/*
Call XzUnpacker_GetExtraSize after XzUnpacker_Code function to detect real size of
xz stream in two cases:
XzUnpacker_Code() returns:
XzUnpacker_GetExtraSize() returns then number of uncofirmed bytes,
if it's in (XZ_STATE_STREAM_HEADER) state or in (XZ_STATE_STREAM_PADDING) state.
These bytes can be some bytes after xz archive, or
it can be start of new xz stream.
Call XzUnpacker_GetExtraSize() after XzUnpacker_Code() function to detect real size of
xz stream in two cases, if XzUnpacker_Code() returns:
res == SZ_OK && status == CODER_STATUS_NEEDS_MORE_INPUT
res == SZ_ERROR_NO_ARCHIVE
*/
@@ -297,6 +369,92 @@ Bool XzUnpacker_IsBlockFinished(const CXzUnpacker *p);
#define XzUnpacker_GetPackSizeForIndex(p) ((p)->packSize + (p)->blockHeaderSize + XzFlags_GetCheckSize((p)->streamFlags))
/* ---------- Multi Threading Decoding ---------- */
typedef struct
{
size_t inBufSize_ST;
size_t outStep_ST;
Bool ignoreErrors;
#ifndef _7ZIP_ST
unsigned numThreads;
size_t inBufSize_MT;
size_t memUseMax;
#endif
} CXzDecMtProps;
void XzDecMtProps_Init(CXzDecMtProps *p);
typedef void * CXzDecMtHandle;
/*
alloc : XzDecMt uses CAlignOffsetAlloc for addresses allocated by (alloc).
allocMid : for big allocations, aligned allocation is better
*/
CXzDecMtHandle XzDecMt_Create(ISzAllocPtr alloc, ISzAllocPtr allocMid);
void XzDecMt_Destroy(CXzDecMtHandle p);
typedef struct
{
Byte UnpackSize_Defined;
Byte NumStreams_Defined;
Byte NumBlocks_Defined;
Byte DataAfterEnd;
Byte DecodingTruncated; // Decoding was Truncated, we need only partial output data
UInt64 InSize; // pack size processed
UInt64 OutSize;
UInt64 NumStreams;
UInt64 NumBlocks;
SRes DecodeRes;
SRes ReadRes;
SRes ProgressRes;
SRes CombinedRes;
SRes CombinedRes_Type;
} CXzStatInfo;
void XzStatInfo_Clear(CXzStatInfo *p);
/*
XzDecMt_Decode()
SRes:
SZ_OK - OK
SZ_ERROR_MEM - Memory allocation error
SZ_ERROR_NO_ARCHIVE - is not xz archive
SZ_ERROR_ARCHIVE - Headers error
SZ_ERROR_DATA - Data Error
SZ_ERROR_CRC - CRC Error
SZ_ERROR_INPUT_EOF - it needs more input data
SZ_ERROR_WRITE - ISeqOutStream error
(SZ_ERROR_READ) - ISeqInStream errors
(SZ_ERROR_PROGRESS) - ICompressProgress errors
// SZ_ERROR_THREAD - error in multi-threading functions
MY_SRes_HRESULT_FROM_WRes(WRes_error) - error in multi-threading function
*/
SRes XzDecMt_Decode(CXzDecMtHandle p,
const CXzDecMtProps *props,
const UInt64 *outDataSize, // NULL means undefined
int finishMode, // 0 - partial unpacking is allowed, 1 - xz stream(s) must be finished
ISeqOutStream *outStream,
// Byte *outBuf, size_t *outBufSize,
ISeqInStream *inStream,
// const Byte *inData, size_t inDataSize,
CXzStatInfo *stat,
int *isMT, // 0 means that ST (Single-Thread) version was used
ICompressProgress *progress);
EXTERN_C_END
#endif

2102
C/XzDec.c
View File

File diff suppressed because it is too large Load Diff

View File

@@ -1,5 +1,5 @@
/* XzEnc.c -- Xz Encode
2017-08-25 : Igor Pavlov : Public domain */
2018-02-21 : Igor Pavlov : Public domain */
#include "Precomp.h"
@@ -136,7 +136,7 @@ static void XzEncIndex_Free(CXzEncIndex *p, ISzAllocPtr alloc)
static SRes XzEncIndex_ReAlloc(CXzEncIndex *p, size_t newSize, ISzAllocPtr alloc)
{
Byte *blocks = ISzAlloc_Alloc(alloc, newSize);
Byte *blocks = (Byte *)ISzAlloc_Alloc(alloc, newSize);
if (!blocks)
return SZ_ERROR_MEM;
if (p->size != 0)
@@ -329,7 +329,7 @@ static SRes SeqInFilter_Init(CSeqInFilter *p, const CXzFilter *props, ISzAllocPt
{
if (!p->buf)
{
p->buf = ISzAlloc_Alloc(alloc, FILTER_BUF_SIZE);
p->buf = (Byte *)ISzAlloc_Alloc(alloc, FILTER_BUF_SIZE);
if (!p->buf)
return SZ_ERROR_MEM;
}
@@ -362,13 +362,16 @@ static SRes SeqInFilter_Read(const ISeqInStream *pp, void *data, size_t *size)
}
{
SizeT srcLen = p->endPos - p->curPos;
int wasFinished;
ECoderStatus status;
SRes res;
*size = sizeOriginal;
res = p->StateCoder.Code(p->StateCoder.p, data, size, p->buf + p->curPos, &srcLen,
p->srcWasFinished, CODER_FINISH_ANY, &wasFinished);
res = p->StateCoder.Code2(p->StateCoder.p,
data, size,
p->buf + p->curPos, &srcLen,
p->srcWasFinished, CODER_FINISH_ANY,
&status);
p->curPos += srcLen;
if (*size != 0 || srcLen == 0 || res != 0)
if (*size != 0 || srcLen == 0 || res != SZ_OK)
return res;
}
}
@@ -1061,7 +1064,7 @@ static SRes XzEnc_MtCallback_Code(void *pp, unsigned coderIndex, unsigned outBuf
if (!dest)
{
dest = ISzAlloc_Alloc(me->alloc, me->outBufSize);
dest = (Byte *)ISzAlloc_Alloc(me->alloc, me->outBufSize);
if (!dest)
return SZ_ERROR_MEM;
me->outBufs[outBufIndex] = dest;
@@ -1069,7 +1072,7 @@ static SRes XzEnc_MtCallback_Code(void *pp, unsigned coderIndex, unsigned outBuf
MtProgressThunk_CreateVTable(&progressThunk);
progressThunk.mtProgress = &me->mtCoder.mtProgress;
progressThunk.index = coderIndex;
MtProgressThunk_Init(&progressThunk);
{
CXzEncBlockInfo blockSizes;
@@ -1230,7 +1233,7 @@ SRes XzEnc_Encode(CXzEncHandle pp, ISeqOutStream *outStream, ISeqInStream *inStr
if (!p->outBufs[0] || t2 != p->outBufSize)
{
XzEnc_FreeOutBufs(p);
p->outBufs[0] = ISzAlloc_Alloc(p->alloc, t2);
p->outBufs[0] = (Byte *)ISzAlloc_Alloc(p->alloc, t2);
if (!p->outBufs[0])
return SZ_ERROR_MEM;
p->outBufSize = t2;

View File

@@ -1,5 +1,5 @@
/* XzIn.c - Xz input
2017-05-11 : Igor Pavlov : Public domain */
2018-02-02 : Igor Pavlov : Public domain */
#include "Precomp.h"
@@ -103,7 +103,7 @@ static SRes Xz_ReadIndex2(CXzStream *p, const Byte *buf, size_t size, ISzAllocPt
{
size_t i;
p->numBlocks = numBlocks;
p->blocks = ISzAlloc_Alloc(alloc, sizeof(CXzBlockSizes) * numBlocks);
p->blocks = (CXzBlockSizes *)ISzAlloc_Alloc(alloc, sizeof(CXzBlockSizes) * numBlocks);
if (!p->blocks)
return SZ_ERROR_MEM;
for (i = 0; i < numBlocks; i++)
@@ -131,7 +131,7 @@ static SRes Xz_ReadIndex(CXzStream *p, ILookInStream *stream, UInt64 indexSize,
size = (size_t)indexSize;
if (size != indexSize)
return SZ_ERROR_UNSUPPORTED;
buf = ISzAlloc_Alloc(alloc, size);
buf = (Byte *)ISzAlloc_Alloc(alloc, size);
if (!buf)
return SZ_ERROR_MEM;
res = LookInStream_Read2(stream, buf, size, SZ_ERROR_UNSUPPORTED);

View File

@@ -13,7 +13,9 @@ struct CMethodFull: public CMethodProps
{
CMethodId Id;
UInt32 NumStreams;
int CodecIndex;
CMethodFull(): CodecIndex(-1) {}
bool IsSimpleCoder() const { return NumStreams == 1; }
};

View File

@@ -236,8 +236,8 @@ HRESULT CDecoder::Decode(
_7Z_DECODER_CRYPRO_VARS_DECL
#if !defined(_7ZIP_ST) && !defined(_SFX)
, bool mtMode, UInt32 numThreads
#if !defined(_7ZIP_ST)
, bool mtMode, UInt32 numThreads, UInt64 memUsage
#endif
)
{
@@ -312,7 +312,7 @@ HRESULT CDecoder::Decode(
#endif
CCreatedCoder cod;
RINOK(CreateCoder(
RINOK(CreateCoder_Id(
EXTERNAL_CODECS_LOC_VARS
coderInfo.MethodID, false, cod));
@@ -355,11 +355,39 @@ HRESULT CDecoder::Decode(
unsigned i;
bool mt_wasUsed = false;
for (i = 0; i < folderInfo.Coders.Size(); i++)
{
const CCoderInfo &coderInfo = folderInfo.Coders[i];
IUnknown *decoder = _mixer->GetCoder(i).GetUnknown();
#if !defined(_7ZIP_ST)
if (!mt_wasUsed)
{
if (mtMode)
{
CMyComPtr<ICompressSetCoderMt> setCoderMt;
decoder->QueryInterface(IID_ICompressSetCoderMt, (void **)&setCoderMt);
if (setCoderMt)
{
mt_wasUsed = true;
RINOK(setCoderMt->SetNumberOfThreads(numThreads));
}
}
// if (memUsage != 0)
{
CMyComPtr<ICompressSetMemLimit> setMemLimit;
decoder->QueryInterface(IID_ICompressSetMemLimit, (void **)&setMemLimit);
if (setMemLimit)
{
mt_wasUsed = true;
RINOK(setMemLimit->SetMemLimit(memUsage));
}
}
}
#endif
{
CMyComPtr<ICompressSetDecoderProperties2> setDecoderProperties;
decoder->QueryInterface(IID_ICompressSetDecoderProperties2, (void **)&setDecoderProperties);
@@ -376,18 +404,6 @@ HRESULT CDecoder::Decode(
}
}
#if !defined(_7ZIP_ST) && !defined(_SFX)
if (mtMode)
{
CMyComPtr<ICompressSetCoderMt> setCoderMt;
decoder->QueryInterface(IID_ICompressSetCoderMt, (void **)&setCoderMt);
if (setCoderMt)
{
RINOK(setCoderMt->SetNumberOfThreads(numThreads));
}
}
#endif
#ifndef _NO_CRYPTO
{
CMyComPtr<ICryptoSetPassword> cryptoSetPassword;

View File

@@ -59,8 +59,8 @@ public:
_7Z_DECODER_CRYPRO_VARS_DECL
#if !defined(_7ZIP_ST) && !defined(_SFX)
, bool mtMode, UInt32 numThreads
#if !defined(_7ZIP_ST)
, bool mtMode, UInt32 numThreads, UInt64 memUsage
#endif
);
};

View File

@@ -154,9 +154,18 @@ HRESULT CEncoder::CreateMixerCoder(
CCreatedCoder cod;
RINOK(CreateCoder(
if (methodFull.CodecIndex >= 0)
{
RINOK(CreateCoder_Index(
EXTERNAL_CODECS_LOC_VARS
methodFull.CodecIndex, true, cod));
}
else
{
RINOK(CreateCoder_Id(
EXTERNAL_CODECS_LOC_VARS
methodFull.Id, true, cod));
}
if (cod.NumStreams != methodFull.NumStreams)
return E_FAIL;

View File

@@ -152,6 +152,12 @@ STDMETHODIMP CFolderOutStream::Write(const void *data, UInt32 size, UInt32 *proc
if (_fileIsOpen)
{
UInt32 cur = (size < _rem ? size : (UInt32)_rem);
if (_calcCrc)
{
const UInt32 k_Step = (UInt32)1 << 20;
if (cur > k_Step)
cur = k_Step;
}
HRESULT result = S_OK;
if (_stream)
result = _stream->Write(data, cur, &cur);
@@ -363,8 +369,8 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
, dataAfterEnd_Error
_7Z_DECODER_CRYPRO_VARS
#if !defined(_7ZIP_ST) && !defined(_SFX)
, true, _numThreads
#if !defined(_7ZIP_ST)
, true, _numThreads, _memUsage
#endif
);

View File

@@ -40,7 +40,6 @@ CHandler::CHandler()
_crcSize = 4;
#ifdef __7Z_SET_PROPERTIES
_numThreads = NSystem::GetNumberOfProcessors();
_useMultiThreadMixer = true;
#endif
@@ -714,8 +713,8 @@ STDMETHODIMP CHandler::Close()
STDMETHODIMP CHandler::SetProperties(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps)
{
COM_TRY_BEGIN
const UInt32 numProcessors = NSystem::GetNumberOfProcessors();
_numThreads = numProcessors;
InitCommon();
_useMultiThreadMixer = true;
for (UInt32 i = 0; i < numProps; i++)
@@ -734,13 +733,15 @@ STDMETHODIMP CHandler::SetProperties(const wchar_t * const *names, const PROPVAR
RINOK(PROPVARIANT_to_bool(value, _useMultiThreadMixer));
continue;
}
if (name.IsPrefixedBy_Ascii_NoCase("mt"))
{
RINOK(ParseMtProp(name.Ptr(2), value, numProcessors, _numThreads));
continue;
HRESULT hres;
if (SetCommonProperty(name, value, hres))
{
RINOK(hres);
continue;
}
}
else
return E_INVALIDARG;
return E_INVALIDARG;
}
}
return S_OK;

View File

@@ -8,16 +8,6 @@
#include "../../Common/CreateCoder.h"
#ifndef EXTRACT_ONLY
#include "../Common/HandlerOut.h"
#endif
#include "7zCompressionMode.h"
#include "7zIn.h"
namespace NArchive {
namespace N7z {
#ifndef __7Z_SET_PROPERTIES
#ifdef EXTRACT_ONLY
@@ -30,6 +20,16 @@ namespace N7z {
#endif
// #ifdef __7Z_SET_PROPERTIES
#include "../Common/HandlerOut.h"
// #endif
#include "7zCompressionMode.h"
#include "7zIn.h"
namespace NArchive {
namespace N7z {
#ifndef EXTRACT_ONLY
@@ -38,8 +38,6 @@ class COutHandler: public CMultiMethodProps
HRESULT SetSolidFromString(const UString &s);
HRESULT SetSolidFromPROPVARIANT(const PROPVARIANT &value);
public:
bool _removeSfxBlock;
UInt64 _numSolidFiles;
UInt64 _numSolidBytes;
bool _numSolidBytesDefined;
@@ -58,6 +56,8 @@ public:
bool _useMultiThreadMixer;
bool _removeSfxBlock;
// bool _volumeMode;
void InitSolidFiles() { _numSolidFiles = (UInt64)(Int64)(-1); }
@@ -70,9 +70,10 @@ public:
_numSolidBytesDefined = false;
}
void InitProps7z();
void InitProps();
COutHandler() { InitProps(); }
COutHandler() { InitProps7z(); }
HRESULT SetProperty(const wchar_t *name, const PROPVARIANT &value);
};
@@ -82,16 +83,23 @@ public:
class CHandler:
public IInArchive,
public IArchiveGetRawProps,
#ifdef __7Z_SET_PROPERTIES
public ISetProperties,
#endif
#ifndef EXTRACT_ONLY
public IOutArchive,
#endif
PUBLIC_ISetCompressCodecsInfo
public CMyUnknownImp
public CMyUnknownImp,
#ifndef EXTRACT_ONLY
, public COutHandler
public COutHandler
#else
public CCommonMethodProps
#endif
{
public:
@@ -135,7 +143,6 @@ private:
#ifdef EXTRACT_ONLY
#ifdef __7Z_SET_PROPERTIES
UInt32 _numThreads;
bool _useMultiThreadMixer;
#endif

View File

@@ -13,6 +13,8 @@
#include "7zOut.h"
#include "7zUpdate.h"
#ifndef EXTRACT_ONLY
using namespace NWindows;
namespace NArchive {
@@ -41,9 +43,11 @@ STDMETHODIMP CHandler::GetFileTimeType(UInt32 *type)
HRESULT CHandler::PropsMethod_To_FullMethod(CMethodFull &dest, const COneMethodInfo &m)
{
if (!FindMethod(
dest.CodecIndex = FindMethod_Index(
EXTERNAL_CODECS_VARS
m.MethodName, dest.Id, dest.NumStreams))
m.MethodName, true,
dest.Id, dest.NumStreams);
if (dest.CodecIndex < 0)
return E_INVALIDARG;
(CProps &)dest = (CProps &)m;
return S_OK;
@@ -699,10 +703,8 @@ static HRESULT ParseBond(UString &srcString, UInt32 &coder, UInt32 &stream)
return S_OK;
}
void COutHandler::InitProps()
void COutHandler::InitProps7z()
{
CMultiMethodProps::Init();
_removeSfxBlock = false;
_compressHeaders = true;
_encryptHeadersSpecified = false;
@@ -722,6 +724,14 @@ void COutHandler::InitProps()
_useTypeSorting = false;
}
void COutHandler::InitProps()
{
CMultiMethodProps::Init();
InitProps7z();
}
HRESULT COutHandler::SetSolidFromString(const UString &s)
{
UString s2 = s;
@@ -762,6 +772,10 @@ HRESULT COutHandler::SetSolidFromString(const UString &s)
}
_numSolidBytes = (v << numBits);
_numSolidBytesDefined = true;
/*
if (_numSolidBytes == 0)
_numSolidFiles = 1;
*/
}
}
return S_OK;
@@ -921,3 +935,5 @@ STDMETHODIMP CHandler::SetProperties(const wchar_t * const *names, const PROPVAR
}
}}
#endif

View File

@@ -1115,11 +1115,11 @@ HRESULT CInArchive::ReadAndDecodePackedStreams(
, dataAfterEnd_Error
_7Z_DECODER_CRYPRO_VARS
#if !defined(_7ZIP_ST) && !defined(_SFX)
#if !defined(_7ZIP_ST)
, false // mtMode
, 1 // numThreads
, 0 // memUsage
#endif
);
RINOK(result);

View File

@@ -1507,7 +1507,8 @@ void CThreadDecoder::Execute()
_7Z_DECODER_CRYPRO_VARS
#ifndef _7ZIP_ST
, MtMode, NumThreads
, MtMode, NumThreads,
0 // MemUsage
#endif
);
@@ -1696,13 +1697,14 @@ HRESULT Update(
UInt64 inSizeForReduce = 0;
{
bool isSolid = (numSolidFiles > 1 && options.NumSolidBytes != 0);
FOR_VECTOR (i, updateItems)
{
const CUpdateItem &ui = updateItems[i];
if (ui.NewData)
{
complexity += ui.Size;
if (numSolidFiles != 1)
if (isSolid)
inSizeForReduce += ui.Size;
else if (inSizeForReduce < ui.Size)
inSizeForReduce = ui.Size;
@@ -2142,8 +2144,8 @@ HRESULT Update(
#ifndef _7ZIP_ST
, false // mtMode
, 1 // numThreads
, 0 // memUsage
#endif
);
RINOK(res);
@@ -2293,7 +2295,8 @@ HRESULT Update(
continue;
CRecordVector<CRefItem> refItems;
refItems.ClearAndSetSize(numFiles);
bool sortByType = (options.UseTypeSorting && numSolidFiles > 1);
// bool sortByType = (options.UseTypeSorting && isSoid); // numSolidFiles > 1
bool sortByType = options.UseTypeSorting;
unsigned i;

View File

@@ -2,18 +2,92 @@
#include "StdAfx.h"
#ifndef _7ZIP_ST
#include "../../../Windows/System.h"
#endif
#include "../../../Common/StringToInt.h"
#include "../Common/ParseProperties.h"
#include "HandlerOut.h"
using namespace NWindows;
namespace NArchive {
bool ParseSizeString(const wchar_t *s, const PROPVARIANT &prop, UInt64 percentsBase, UInt64 &res)
{
if (*s == 0)
{
switch (prop.vt)
{
case VT_UI4: res = prop.ulVal; return true;
case VT_UI8: res = prop.uhVal.QuadPart; return true;
case VT_BSTR:
s = prop.bstrVal;
break;
default: return false;
}
}
else if (prop.vt != VT_EMPTY)
return false;
const wchar_t *end;
UInt64 v = ConvertStringToUInt64(s, &end);
if (s == end)
return false;
wchar_t c = *end;
if (c == 0)
{
res = v;
return true;
}
if (end[1] != 0)
return false;
if (c == '%')
{
res = percentsBase / 100 * v;
return true;
}
unsigned numBits;
switch (MyCharLower_Ascii(c))
{
case 'b': numBits = 0; break;
case 'k': numBits = 10; break;
case 'm': numBits = 20; break;
case 'g': numBits = 30; break;
case 't': numBits = 40; break;
default: return false;
}
UInt64 val2 = v << numBits;
if ((val2 >> numBits) != v)
return false;
res = val2;
return true;
}
bool CCommonMethodProps::SetCommonProperty(const UString &name, const PROPVARIANT &value, HRESULT &hres)
{
hres = S_OK;
if (name.IsPrefixedBy_Ascii_NoCase("mt"))
{
#ifndef _7ZIP_ST
hres = ParseMtProp(name.Ptr(2), value, _numProcessors, _numThreads);
#endif
return true;
}
if (name.IsPrefixedBy_Ascii_NoCase("memuse"))
{
if (!ParseSizeString(name.Ptr(6), value, _memAvail, _memUsage))
hres = E_INVALIDARG;
return true;
}
return false;
}
#ifndef EXTRACT_ONLY
static void SetMethodProp32(COneMethodInfo &m, PROPID propID, UInt32 value)
{
if (m.FindProp(propID) < 0)
@@ -34,21 +108,23 @@ void CMultiMethodProps::SetMethodThreadsTo(COneMethodInfo &oneMethodInfo, UInt32
}
#endif
void CMultiMethodProps::Init()
void CMultiMethodProps::InitMulti()
{
#ifndef _7ZIP_ST
_numProcessors = _numThreads = NSystem::GetNumberOfProcessors();
#endif
_level = (UInt32)(Int32)-1;
_analysisLevel = -1;
_autoFilter = true;
_crcSize = 4;
_filterMethod.Clear();
_methods.Clear();
_autoFilter = true;
}
void CMultiMethodProps::Init()
{
InitCommon();
InitMulti();
_methods.Clear();
_filterMethod.Clear();
}
HRESULT CMultiMethodProps::SetProperty(const wchar_t *nameSpec, const PROPVARIANT &value)
{
UString name = nameSpec;
@@ -79,19 +155,17 @@ HRESULT CMultiMethodProps::SetProperty(const wchar_t *nameSpec, const PROPVARIAN
return ParsePropToUInt32(name, value, _crcSize);
}
{
HRESULT hres;
if (SetCommonProperty(name, value, hres))
return hres;
}
UInt32 number;
unsigned index = ParseStringToUInt32(name, number);
UString realName = name.Ptr(index);
if (index == 0)
{
if (name.IsPrefixedBy_Ascii_NoCase("mt"))
{
#ifndef _7ZIP_ST
RINOK(ParseMtProp(name.Ptr(2), value, _numProcessors, _numThreads));
#endif
return S_OK;
}
if (name.IsEqualTo("f"))
{
HRESULT res = PROPVARIANT_to_bool(value, _autoFilter);
@@ -110,20 +184,20 @@ HRESULT CMultiMethodProps::SetProperty(const wchar_t *nameSpec, const PROPVARIAN
return _methods[number].ParseMethodFromPROPVARIANT(realName, value);
}
void CSingleMethodProps::Init()
{
InitCommon();
InitSingle();
Clear();
_level = (UInt32)(Int32)-1;
#ifndef _7ZIP_ST
_numProcessors = _numThreads = NWindows::NSystem::GetNumberOfProcessors();
AddProp_NumThreads(_numThreads);
#endif
}
HRESULT CSingleMethodProps::SetProperties(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps)
{
Init();
for (UInt32 i = 0; i < numProps; i++)
{
UString name = names[i];
@@ -137,20 +211,22 @@ HRESULT CSingleMethodProps::SetProperties(const wchar_t * const *names, const PR
RINOK(ParsePropToUInt32(name.Ptr(1), value, a));
_level = a;
AddProp_Level(a);
continue;
}
else if (name.IsPrefixedBy_Ascii_NoCase("mt"))
{
#ifndef _7ZIP_ST
RINOK(ParseMtProp(name.Ptr(2), value, _numProcessors, _numThreads));
AddProp_NumThreads(_numThreads);
#endif
}
else
{
RINOK(ParseMethodFromPROPVARIANT(names[i], value));
HRESULT hres;
if (SetCommonProperty(name, value, hres))
{
RINOK(hres)
continue;
}
}
RINOK(ParseMethodFromPROPVARIANT(names[i], value));
}
return S_OK;
}
#endif
}

View File

@@ -3,20 +3,57 @@
#ifndef __HANDLER_OUT_H
#define __HANDLER_OUT_H
#include "../../../Windows/System.h"
#include "../../Common/MethodProps.h"
namespace NArchive {
class CMultiMethodProps
bool ParseSizeString(const wchar_t *name, const PROPVARIANT &prop, UInt64 percentsBase, UInt64 &res);
class CCommonMethodProps
{
UInt32 _level;
int _analysisLevel;
protected:
void InitCommon()
{
#ifndef _7ZIP_ST
_numProcessors = _numThreads = NWindows::NSystem::GetNumberOfProcessors();
#endif
UInt64 memAvail = (UInt64)(sizeof(size_t)) << 28;
_memAvail = memAvail;
_memUsage = memAvail;
if (NWindows::NSystem::GetRamSize(memAvail))
{
_memAvail = memAvail;
_memUsage = memAvail / 32 * 17;
}
}
public:
#ifndef _7ZIP_ST
UInt32 _numThreads;
UInt32 _numProcessors;
#endif
UInt64 _memUsage;
UInt64 _memAvail;
bool SetCommonProperty(const UString &name, const PROPVARIANT &value, HRESULT &hres);
CCommonMethodProps() { InitCommon(); }
};
#ifndef EXTRACT_ONLY
class CMultiMethodProps: public CCommonMethodProps
{
UInt32 _level;
int _analysisLevel;
void InitMulti();
public:
UInt32 _crcSize;
CObjectVector<COneMethodInfo> _methods;
COneMethodInfo _filterMethod;
@@ -43,27 +80,31 @@ public:
int GetAnalysisLevel() const { return _analysisLevel; }
void Init();
CMultiMethodProps() { InitMulti(); }
CMultiMethodProps() { Init(); }
HRESULT SetProperty(const wchar_t *name, const PROPVARIANT &value);
};
class CSingleMethodProps: public COneMethodInfo
class CSingleMethodProps: public COneMethodInfo, public CCommonMethodProps
{
UInt32 _level;
public:
#ifndef _7ZIP_ST
UInt32 _numThreads;
UInt32 _numProcessors;
#endif
void InitSingle()
{
_level = (UInt32)(Int32)-1;
}
public:
void Init();
CSingleMethodProps() { Init(); }
CSingleMethodProps() { InitSingle(); }
int GetLevel() const { return _level == (UInt32)(Int32)-1 ? 5 : (int)_level; }
HRESULT SetProperties(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps);
};
#endif
}
#endif

View File

@@ -488,6 +488,16 @@ ARCHIVE_INTERFACE(IOutArchive, 0xA0)
};
/*
ISetProperties::SetProperties()
PROPVARIANT values[i].vt:
VT_EMPTY
VT_BOOL
VT_UI4 - if 32-bit number
VT_UI8 - if 64-bit number
VT_BSTR
*/
ARCHIVE_INTERFACE(ISetProperties, 0x03)
{
STDMETHOD(SetProperties)(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps) PURE;

View File

@@ -1086,7 +1086,7 @@ HRESULT CUnpacker::Create(DECL_EXTERNAL_CODECS_LOC_VARS const CItem &item, bool
if (!lzCoder)
{
const UInt32 methodID = 0x40305;
RINOK(CreateCoder(EXTERNAL_CODECS_LOC_VARS methodID, false, lzCoder));
RINOK(CreateCoder_Id(EXTERNAL_CODECS_LOC_VARS methodID, false, lzCoder));
if (!lzCoder)
return E_NOTIMPL;
}

View File

@@ -1691,7 +1691,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
methodID += 2;
else
methodID += 3;
RINOK(CreateCoder(EXTERNAL_CODECS_VARS methodID, false, mi.Coder));
RINOK(CreateCoder_Id(EXTERNAL_CODECS_VARS methodID, false, mi.Coder));
}
if (mi.Coder == 0)

View File

@@ -2,7 +2,6 @@
#include "StdAfx.h"
#include "../../../C/7zCrc.h"
#include "../../../C/Alloc.h"
#include "../../../C/CpuArch.h"
#include "../../../C/Xz.h"
@@ -1209,8 +1208,10 @@ HRESULT CHandler::Decompress(ISequentialOutStream *outStream, Byte *outBuf, bool
else
{
ECoderStatus status;
XzUnpacker_Init(&_xz);
SRes res = XzUnpacker_Code(&_xz, dest, &destLen, _inputBuffer, &srcLen, CODER_FINISH_END, &status);
SRes res = XzUnpacker_CodeFull(&_xz,
dest, &destLen,
_inputBuffer, &srcLen,
CODER_FINISH_END, &status);
if (res != 0)
return SResToHRESULT(res);
if (status != CODER_STATUS_NEEDS_MORE_INPUT || !XzUnpacker_IsStreamWasFinished(&_xz))

View File

@@ -24,9 +24,7 @@
#include "IArchive.h"
#ifndef EXTRACT_ONLY
#include "Common/HandlerOut.h"
#endif
using namespace NWindows;
@@ -49,14 +47,22 @@ class CHandler:
public IInArchive,
public IArchiveOpenSeq,
public IInArchiveGetStream,
public ISetProperties,
#ifndef EXTRACT_ONLY
public IOutArchive,
public ISetProperties,
public CMultiMethodProps,
#endif
public CMyUnknownImp
public CMyUnknownImp,
#ifndef EXTRACT_ONLY
public CMultiMethodProps
#else
public CCommonMethodProps
#endif
{
NCompress::NXz::CStatInfo _stat;
CXzStatInfo _stat;
SRes MainDecodeSRes;
bool _isArc;
bool _needSeekToStart;
@@ -71,34 +77,48 @@ class CHandler:
UInt64 _numSolidBytes;
HRESULT SetSolidFromString(const UString &s);
HRESULT SetSolidFromPROPVARIANT(const PROPVARIANT &value);
HRESULT SetProperty(const wchar_t *name, const PROPVARIANT &value);
void InitSolid()
void InitXz()
{
_numSolidBytes = XZ_PROPS__BLOCK_SIZE__AUTO;
}
void Init()
{
InitSolid();
_filterId = 0;
CMultiMethodProps::Init();
_numSolidBytes = XZ_PROPS__BLOCK_SIZE__AUTO;
}
#endif
void Init()
{
#ifndef EXTRACT_ONLY
InitXz();
CMultiMethodProps::Init();
#else
CCommonMethodProps::InitCommon();
#endif
}
HRESULT SetProperty(const wchar_t *name, const PROPVARIANT &value);
HRESULT Open2(IInStream *inStream, /* UInt32 flags, */ IArchiveOpenCallback *callback);
HRESULT Decode2(ISequentialInStream *seqInStream, ISequentialOutStream *outStream,
NCompress::NXz::CDecoder &decoder, ICompressProgressInfo *progress)
HRESULT Decode(NCompress::NXz::CDecoder &decoder,
ISequentialInStream *seqInStream,
ISequentialOutStream *outStream,
ICompressProgressInfo *progress)
{
#ifndef _7ZIP_ST
decoder._numThreads = _numThreads;
#endif
decoder._memUsage = _memUsage;
MainDecodeSRes = SZ_OK;
RINOK(decoder.Decode(seqInStream, outStream,
NULL, // *outSizeLimit
true, // finishStream
progress));
_stat = decoder;
_stat = decoder.Stat;
MainDecodeSRes = decoder.MainDecodeSRes;
_phySize_Defined = true;
return S_OK;
}
@@ -107,9 +127,9 @@ public:
MY_QUERYINTERFACE_BEGIN2(IInArchive)
MY_QUERYINTERFACE_ENTRY(IArchiveOpenSeq)
MY_QUERYINTERFACE_ENTRY(IInArchiveGetStream)
MY_QUERYINTERFACE_ENTRY(ISetProperties)
#ifndef EXTRACT_ONLY
MY_QUERYINTERFACE_ENTRY(IOutArchive)
MY_QUERYINTERFACE_ENTRY(ISetProperties)
#endif
MY_QUERYINTERFACE_END
MY_ADDREF_RELEASE
@@ -117,10 +137,10 @@ public:
INTERFACE_IInArchive(;)
STDMETHOD(OpenSeq)(ISequentialInStream *stream);
STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **stream);
STDMETHOD(SetProperties)(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps);
#ifndef EXTRACT_ONLY
INTERFACE_IOutArchive(;)
STDMETHOD(SetProperties)(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps);
#endif
size_t _blocksArraySize;
@@ -146,7 +166,7 @@ CHandler::CHandler():
_blocksArraySize(0)
{
#ifndef EXTRACT_ONLY
Init();
InitXz();
#endif
}
@@ -307,7 +327,7 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
NCOM::CPropVariant prop;
switch (propID)
{
case kpidPhySize: if (_phySize_Defined) prop = _stat.PhySize; break;
case kpidPhySize: if (_phySize_Defined) prop = _stat.InSize; break;
case kpidNumStreams: if (_stat.NumStreams_Defined) prop = _stat.NumStreams; break;
case kpidNumBlocks: if (_stat.NumBlocks_Defined) prop = _stat.NumBlocks; break;
case kpidUnpackSize: if (_stat.UnpackSize_Defined) prop = _stat.OutSize; break;
@@ -330,19 +350,22 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
case kpidErrorFlags:
{
UInt32 v = 0;
SRes sres = MainDecodeSRes; // _stat.DecodeRes2; //
if (!_isArc) v |= kpv_ErrorFlags_IsNotArc;
if (_stat.UnexpectedEnd) v |= kpv_ErrorFlags_UnexpectedEnd;
if (/*_stat.UnexpectedEnd */ sres == SZ_ERROR_INPUT_EOF) v |= kpv_ErrorFlags_UnexpectedEnd;
if (_stat.DataAfterEnd) v |= kpv_ErrorFlags_DataAfterEnd;
if (_stat.HeadersError) v |= kpv_ErrorFlags_HeadersError;
if (_stat.Unsupported) v |= kpv_ErrorFlags_UnsupportedMethod;
if (_stat.DataError) v |= kpv_ErrorFlags_DataError;
if (_stat.CrcError) v |= kpv_ErrorFlags_CrcError;
prop = v;
if (/* _stat.HeadersError */ sres == SZ_ERROR_ARCHIVE) v |= kpv_ErrorFlags_HeadersError;
if (/* _stat.Unsupported */ sres == SZ_ERROR_UNSUPPORTED) v |= kpv_ErrorFlags_UnsupportedMethod;
if (/* _stat.DataError */ sres == SZ_ERROR_DATA) v |= kpv_ErrorFlags_DataError;
if (/* _stat.CrcError */ sres == SZ_ERROR_CRC) v |= kpv_ErrorFlags_CrcError;
if (v != 0)
prop = v;
break;
}
case kpidMainSubfile:
{
// debug only, comment it:
// if (_blocks) prop = (UInt32)0;
break;
}
@@ -365,7 +388,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32, PROPID propID, PROPVARIANT *value)
switch (propID)
{
case kpidSize: if (_stat.UnpackSize_Defined) prop = _stat.OutSize; break;
case kpidPackSize: if (_phySize_Defined) prop = _stat.PhySize; break;
case kpidPackSize: if (_phySize_Defined) prop = _stat.InSize; break;
case kpidMethod: if (!_methodsString.IsEmpty()) prop = _methodsString; break;
}
prop.Detach(value);
@@ -483,10 +506,10 @@ HRESULT CHandler::Open2(IInStream *inStream, /* UInt32 flags, */ IArchiveOpenCal
}
}
RINOK(inStream->Seek(0, STREAM_SEEK_END, &_stat.PhySize));
RINOK(inStream->Seek(0, STREAM_SEEK_END, &_stat.InSize));
if (callback)
{
RINOK(callback->SetTotal(NULL, &_stat.PhySize));
RINOK(callback->SetTotal(NULL, &_stat.InSize));
}
CSeekInStreamWrap inStreamImp;
@@ -621,7 +644,7 @@ STDMETHODIMP CHandler::OpenSeq(ISequentialInStream *stream)
STDMETHODIMP CHandler::Close()
{
_stat.Clear();
XzStatInfo_Clear(&_stat);
_isArc = false;
_needSeekToStart = false;
@@ -637,6 +660,8 @@ STDMETHODIMP CHandler::Close()
_blocksArraySize = 0;
_maxBlocksSize = 0;
MainDecodeSRes = SZ_OK;
return S_OK;
}
@@ -743,6 +768,8 @@ static HRESULT DecodeBlock(CXzUnpackerCPP2 &xzu,
xzu.p.streamFlags = (UInt16)streamFlags;
XzUnpacker_PrepareToRandomBlockDecoding(&xzu.p);
XzUnpacker_SetOutBuf(&xzu.p, dest, unpackSize);
const UInt64 packSizeAligned = packSize + ((0 - (unsigned)packSize) & 3);
UInt64 packRem = packSizeAligned;
@@ -771,8 +798,11 @@ static HRESULT DecodeBlock(CXzUnpackerCPP2 &xzu,
ECoderStatus status;
SRes res = XzUnpacker_Code(&xzu.p,
dest + outPos, &outLen,
// dest + outPos,
NULL,
&outLen,
xzu.InBuf + inPos, &inLen,
(inLen == 0), // srcFinished
CODER_FINISH_END, &status);
// return E_OUTOFMEMORY;
@@ -890,15 +920,16 @@ STDMETHODIMP CHandler::GetStream(UInt32 index, ISequentialInStream **stream)
return E_INVALIDARG;
if (!_stat.UnpackSize_Defined
|| _maxBlocksSize == 0 // 18.02
|| _maxBlocksSize > kMaxBlockSize_for_GetStream
|| _maxBlocksSize != (size_t)_maxBlocksSize)
return S_FALSE;
UInt64 physSize = (UInt64)(sizeof(size_t)) << 29;
bool ramSize_Defined = NSystem::GetRamSize(physSize);
if (ramSize_Defined)
UInt64 memSize;
if (!NSystem::GetRamSize(memSize))
memSize = (UInt64)(sizeof(size_t)) << 28;
{
if (_maxBlocksSize > physSize / 4)
if (_maxBlocksSize > memSize / 4)
return S_FALSE;
}
@@ -917,6 +948,31 @@ STDMETHODIMP CHandler::GetStream(UInt32 index, ISequentialInStream **stream)
}
static Int32 Get_Extract_OperationResult(const NCompress::NXz::CDecoder &decoder)
{
Int32 opRes;
SRes sres = decoder.MainDecodeSRes; // decoder.Stat.DecodeRes2;
if (sres == SZ_ERROR_NO_ARCHIVE) // (!IsArc)
opRes = NExtract::NOperationResult::kIsNotArc;
else if (sres == SZ_ERROR_INPUT_EOF) // (UnexpectedEnd)
opRes = NExtract::NOperationResult::kUnexpectedEnd;
else if (decoder.Stat.DataAfterEnd)
opRes = NExtract::NOperationResult::kDataAfterEnd;
else if (sres == SZ_ERROR_CRC) // (CrcError)
opRes = NExtract::NOperationResult::kCRCError;
else if (sres == SZ_ERROR_UNSUPPORTED) // (Unsupported)
opRes = NExtract::NOperationResult::kUnsupportedMethod;
else if (sres == SZ_ERROR_ARCHIVE) // (HeadersError)
opRes = NExtract::NOperationResult::kDataError;
else if (sres == SZ_ERROR_DATA) // (DataError)
opRes = NExtract::NOperationResult::kDataError;
else if (sres != SZ_OK)
opRes = NExtract::NOperationResult::kDataError;
else
opRes = NExtract::NOperationResult::kOK;
return opRes;
}
@@ -930,7 +986,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
return E_INVALIDARG;
if (_phySize_Defined)
extractCallback->SetTotal(_stat.PhySize);
extractCallback->SetTotal(_stat.InSize);
UInt64 currentTotalPacked = 0;
RINOK(extractCallback->SetCompleted(&currentTotalPacked));
@@ -959,9 +1015,18 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
else
_needSeekToStart = true;
NCompress::NXz::CDecoder decoder;
RINOK(Decode2(_seqStream, realOutStream, decoder, lpsRef));
Int32 opRes = decoder.Get_Extract_OperationResult();
HRESULT hres = Decode(decoder, _seqStream, realOutStream, lpsRef);
if (!decoder.MainDecodeSRes_wasUsed)
return hres == S_OK ? E_FAIL : hres;
Int32 opRes = Get_Extract_OperationResult(decoder);
if (opRes == NExtract::NOperationResult::kOK
&& hres != S_OK)
opRes = NExtract::NOperationResult::kDataError;
realOutStream.Release();
return extractCallback->SetOperationResult(opRes);
@@ -1112,7 +1177,7 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
if (_stream)
{
if (_phySize_Defined)
RINOK(updateCallback->SetTotal(_stat.PhySize));
RINOK(updateCallback->SetTotal(_stat.InSize));
RINOK(_stream->Seek(0, STREAM_SEEK_SET, NULL));
}
@@ -1125,55 +1190,7 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
COM_TRY_END
}
HRESULT CHandler::SetSolidFromString(const UString &s)
{
UString s2 = s;
s2.MakeLower_Ascii();
{
const wchar_t *start = ((const wchar_t *)s2);
const wchar_t *end;
UInt64 v = ConvertStringToUInt64(start, &end);
if (start == end)
return E_INVALIDARG;
if ((unsigned)(end - start) + 1 != s2.Len())
return E_INVALIDARG;
wchar_t c = *end;
{
unsigned numBits;
switch (c)
{
case 'b': numBits = 0; break;
case 'k': numBits = 10; break;
case 'm': numBits = 20; break;
case 'g': numBits = 30; break;
case 't': numBits = 40; break;
default: return E_INVALIDARG;
}
_numSolidBytes = (v << numBits);
}
}
return S_OK;
}
HRESULT CHandler::SetSolidFromPROPVARIANT(const PROPVARIANT &value)
{
bool isSolid;
switch (value.vt)
{
case VT_EMPTY: isSolid = true; break;
case VT_BOOL: isSolid = (value.boolVal != VARIANT_FALSE); break;
case VT_BSTR:
if (StringToBool(value.bstrVal, isSolid))
break;
return SetSolidFromString(value.bstrVal);
default: return E_INVALIDARG;
}
_numSolidBytes = (isSolid ? XZ_PROPS__BLOCK_SIZE__SOLID : XZ_PROPS__BLOCK_SIZE__AUTO);
return S_OK;
}
#endif
HRESULT CHandler::SetProperty(const wchar_t *nameSpec, const PROPVARIANT &value)
@@ -1183,20 +1200,53 @@ HRESULT CHandler::SetProperty(const wchar_t *nameSpec, const PROPVARIANT &value)
if (name.IsEmpty())
return E_INVALIDARG;
#ifndef EXTRACT_ONLY
if (name[0] == L's')
{
name.Delete(0);
if (name.IsEmpty())
return SetSolidFromPROPVARIANT(value);
if (value.vt != VT_EMPTY)
return E_INVALIDARG;
return SetSolidFromString(name);
const wchar_t *s = name.Ptr(1);
if (*s == 0)
{
bool useStr = false;
bool isSolid;
switch (value.vt)
{
case VT_EMPTY: isSolid = true; break;
case VT_BOOL: isSolid = (value.boolVal != VARIANT_FALSE); break;
case VT_BSTR:
if (!StringToBool(value.bstrVal, isSolid))
useStr = true;
break;
default: return E_INVALIDARG;
}
if (!useStr)
{
_numSolidBytes = (isSolid ? XZ_PROPS__BLOCK_SIZE__SOLID : XZ_PROPS__BLOCK_SIZE__AUTO);
return S_OK;
}
}
return ParseSizeString(s, value,
0, // percentsBase
_numSolidBytes) ? S_OK: E_INVALIDARG;
}
return CMultiMethodProps::SetProperty(name, value);
#else
{
HRESULT hres;
if (SetCommonProperty(name, value, hres))
return hres;
}
return E_INVALIDARG;
#endif
}
STDMETHODIMP CHandler::SetProperties(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps)
{
COM_TRY_BEGIN
@@ -1208,6 +1258,8 @@ STDMETHODIMP CHandler::SetProperties(const wchar_t * const *names, const PROPVAR
RINOK(SetProperty(names[i], values[i]));
}
#ifndef EXTRACT_ONLY
if (!_filterMethod.MethodName.IsEmpty())
{
unsigned k;
@@ -1238,12 +1290,13 @@ STDMETHODIMP CHandler::SetProperties(const wchar_t * const *names, const PROPVAR
return E_INVALIDARG;
}
#endif
return S_OK;
COM_TRY_END
}
#endif
REGISTER_ARC_IO(
"xz", "xz txz", "* .tar", 0xC,

View File

@@ -384,7 +384,7 @@ HRESULT CAddCommon::Compress(
methodId = kMethodId_ZipBase + method;
break;
}
RINOK(CreateCoder(
RINOK(CreateCoder_Id(
EXTERNAL_CODECS_LOC_VARS
methodId, true, _compressEncoder));
if (!_compressEncoder)

View File

@@ -112,7 +112,8 @@ static const CUInt32PCharPair g_HeaderCharacts[] =
{ 3, "Descriptor" },
// { 5, "Patched" },
{ 6, kMethod_StrongCrypto },
{ 11, "UTF8" }
{ 11, "UTF8" },
{ 14, "Alt" }
};
struct CIdToNamePair
@@ -169,6 +170,7 @@ static const Byte kProps[] =
kpidUnpackVer,
kpidVolumeIndex,
kpidOffset
// kpidIsAltStream
};
static const Byte kArcProps[] =
@@ -307,6 +309,8 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
prop = true;
break;
}
// case kpidIsAltStream: prop = true; break;
}
prop.Detach(value);
COM_TRY_END
@@ -333,6 +337,21 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
UString res;
item.GetUnicodeString(res, item.Name, false, _forceCodePage, _specifiedCodePage);
NItemName::ReplaceToOsSlashes_Remove_TailSlash(res);
/*
if (item.ParentOfAltStream >= 0)
{
const CItemEx &prevItem = m_Items[item.ParentOfAltStream];
UString prevName;
prevItem.GetUnicodeString(prevName, prevItem.Name, false, _forceCodePage, _specifiedCodePage);
NItemName::ReplaceToOsSlashes_Remove_TailSlash(prevName);
if (res.IsPrefixedBy(prevName))
if (IsString1PrefixedByString2(res.Ptr(prevName.Len()), k_SpecName_NTFS_STREAM))
{
res.Delete(prevName.Len(), (unsigned)strlen(k_SpecName_NTFS_STREAM));
res.Insert(prevName.Len(), L":");
}
}
*/
prop = res;
break;
}
@@ -596,6 +615,19 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
case kpidOffset:
prop = item.LocalHeaderPos;
break;
/*
case kpidIsAltStream:
prop = (bool)(item.ParentOfAltStream >= 0); // item.IsAltStream();
break;
case kpidName:
if (item.ParentOfAltStream >= 0)
{
// extract name of stream here
}
break;
*/
}
prop.Detach(value);
@@ -604,6 +636,85 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
}
/*
STDMETHODIMP CHandler::GetNumRawProps(UInt32 *numProps)
{
*numProps = 0;
return S_OK;
}
STDMETHODIMP CHandler::GetRawPropInfo(UInt32 index, BSTR *name, PROPID *propID)
{
UNUSED_VAR(index);
*propID = 0;
*name = 0;
return S_OK;
}
STDMETHODIMP CHandler::GetParent(UInt32 index, UInt32 *parent, UInt32 *parentType)
{
*parentType = NParentType::kDir;
*parent = (UInt32)(Int32)-1;
if (index >= m_Items.Size())
return S_OK;
const CItemEx &item = m_Items[index];
if (item.ParentOfAltStream >= 0)
{
*parentType = NParentType::kAltStream;
*parent = item.ParentOfAltStream;
}
return S_OK;
}
STDMETHODIMP CHandler::GetRawProp(UInt32 index, PROPID propID, const void **data, UInt32 *dataSize, UInt32 *propType)
{
UNUSED_VAR(index);
UNUSED_VAR(propID);
*data = NULL;
*dataSize = 0;
*propType = 0;
return S_OK;
}
void CHandler::MarkAltStreams(CObjectVector<CItemEx> &items)
{
int prevIndex = -1;
UString prevName;
UString name;
for (unsigned i = 0; i < items.Size(); i++)
{
CItemEx &item = m_Items[i];
if (item.IsAltStream())
{
if (prevIndex == -1)
continue;
if (prevName.IsEmpty())
{
const CItemEx &prevItem = m_Items[prevIndex];
prevItem.GetUnicodeString(prevName, prevItem.Name, false, _forceCodePage, _specifiedCodePage);
NItemName::ReplaceToOsSlashes_Remove_TailSlash(prevName);
}
name.Empty();
item.GetUnicodeString(name, item.Name, false, _forceCodePage, _specifiedCodePage);
NItemName::ReplaceToOsSlashes_Remove_TailSlash(name);
if (name.IsPrefixedBy(prevName))
if (IsString1PrefixedByString2(name.Ptr(prevName.Len()), k_SpecName_NTFS_STREAM))
item.ParentOfAltStream = prevIndex;
}
else
{
prevIndex = i;
prevName.Empty();
}
}
}
*/
STDMETHODIMP CHandler::Open(IInStream *inStream,
const UInt64 *maxCheckStartPosition, IArchiveOpenCallback *callback)
{
@@ -617,6 +728,7 @@ STDMETHODIMP CHandler::Open(IInStream *inStream,
m_Items.Clear();
m_Archive.ClearRefs(); // we don't want to clear error flags
}
// MarkAltStreams(m_Items);
return res;
}
catch(...) { Close(); throw; }
@@ -738,7 +850,7 @@ public:
IArchiveExtractCallback *extractCallback,
ICompressProgressInfo *compressProgress,
#ifndef _7ZIP_ST
UInt32 numThreads,
UInt32 numThreads, UInt64 memUsage,
#endif
Int32 &res);
};
@@ -767,7 +879,7 @@ HRESULT CZipDecoder::Decode(
IArchiveExtractCallback *extractCallback,
ICompressProgressInfo *compressProgress,
#ifndef _7ZIP_ST
UInt32 numThreads,
UInt32 numThreads, UInt64 memUsage,
#endif
Int32 &res)
{
@@ -962,7 +1074,7 @@ HRESULT CZipDecoder::Decode(
szMethodID = kMethodId_ZipBase + (Byte)id;
}
RINOK(CreateCoder(EXTERNAL_CODECS_LOC_VARS szMethodID, false, mi.Coder));
RINOK(CreateCoder_Id(EXTERNAL_CODECS_LOC_VARS szMethodID, false, mi.Coder));
if (!mi.Coder)
{
@@ -975,15 +1087,6 @@ HRESULT CZipDecoder::Decode(
ICompressCoder *coder = methodItems[m].Coder;
{
CMyComPtr<ICompressSetDecoderProperties2> setDecoderProperties;
coder->QueryInterface(IID_ICompressSetDecoderProperties2, (void **)&setDecoderProperties);
if (setDecoderProperties)
{
Byte properties = (Byte)item.Flags;
RINOK(setDecoderProperties->SetDecoderProperties2(&properties, 1));
}
}
#ifndef _7ZIP_ST
{
@@ -994,8 +1097,28 @@ HRESULT CZipDecoder::Decode(
RINOK(setCoderMt->SetNumberOfThreads(numThreads));
}
}
// if (memUsage != 0)
{
CMyComPtr<ICompressSetMemLimit> setMemLimit;
coder->QueryInterface(IID_ICompressSetMemLimit, (void **)&setMemLimit);
if (setMemLimit)
{
RINOK(setMemLimit->SetMemLimit(memUsage));
}
}
#endif
{
CMyComPtr<ICompressSetDecoderProperties2> setDecoderProperties;
coder->QueryInterface(IID_ICompressSetDecoderProperties2, (void **)&setDecoderProperties);
if (setDecoderProperties)
{
Byte properties = (Byte)item.Flags;
RINOK(setDecoderProperties->SetDecoderProperties2(&properties, 1));
}
}
CMyComPtr<ISequentialInStream> inStreamNew;
bool isFullStreamExpected = (!item.HasDescriptor() || item.PackSize != 0);
@@ -1319,7 +1442,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
m_Archive, item, realOutStream, extractCallback,
progress,
#ifndef _7ZIP_ST
_props._numThreads,
_props._numThreads, _props._memUsage,
#endif
res);

View File

@@ -25,6 +25,7 @@ extern const char * const kMethodNames2[kNumMethodNames2];
class CHandler:
public IInArchive,
// public IArchiveGetRawProps,
public IOutArchive,
public ISetProperties,
PUBLIC_ISetCompressCodecsInfo
@@ -32,6 +33,7 @@ class CHandler:
{
public:
MY_QUERYINTERFACE_BEGIN2(IInArchive)
// MY_QUERYINTERFACE_ENTRY(IArchiveGetRawProps)
MY_QUERYINTERFACE_ENTRY(IOutArchive)
MY_QUERYINTERFACE_ENTRY(ISetProperties)
QUERY_ENTRY_ISetCompressCodecsInfo
@@ -39,6 +41,7 @@ public:
MY_ADDREF_RELEASE
INTERFACE_IInArchive(;)
// INTERFACE_IArchiveGetRawProps(;)
INTERFACE_IOutArchive(;)
STDMETHOD(SetProperties)(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps);
@@ -75,6 +78,10 @@ private:
_forceCodePage = false;
_specifiedCodePage = CP_OEMCP;
}
// void MarkAltStreams(CObjectVector<CItemEx> &items);
HRESULT GetOutProperty(IArchiveUpdateCallback *callback, UInt32 callbackIndex, Int32 arcIndex, PROPID propID, PROPVARIANT *value);
};
}}

View File

@@ -376,7 +376,8 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
{
CMethodId methodId;
UInt32 numStreams;
if (!FindMethod(EXTERNAL_CODECS_VARS methodName, methodId, numStreams))
if (FindMethod_Index(EXTERNAL_CODECS_VARS methodName, true,
methodId, numStreams) < 0)
return E_NOTIMPL;
if (numStreams != 1)
return E_NOTIMPL;

View File

@@ -2632,6 +2632,34 @@ SOURCE=..\..\..\..\C\Lzma2Dec.h
# End Source File
# Begin Source File
SOURCE=..\..\..\..\C\Lzma2DecMt.c
!IF "$(CFG)" == "Alone - Win32 Release"
# ADD CPP /O2
# SUBTRACT CPP /YX /Yc /Yu
!ELSEIF "$(CFG)" == "Alone - Win32 Debug"
# SUBTRACT CPP /YX /Yc /Yu
!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU"
# SUBTRACT CPP /YX /Yc /Yu
!ELSEIF "$(CFG)" == "Alone - Win32 DebugU"
# SUBTRACT CPP /YX /Yc /Yu
!ENDIF
# End Source File
# Begin Source File
SOURCE=..\..\..\..\C\Lzma2DecMt.h
# End Source File
# Begin Source File
SOURCE=..\..\..\..\C\Lzma2Enc.c
!IF "$(CFG)" == "Alone - Win32 Release"
@@ -2744,6 +2772,34 @@ SOURCE=..\..\..\..\C\MtCoder.h
# End Source File
# Begin Source File
SOURCE=..\..\..\..\C\MtDec.c
!IF "$(CFG)" == "Alone - Win32 Release"
# ADD CPP /O2
# SUBTRACT CPP /YX /Yc /Yu
!ELSEIF "$(CFG)" == "Alone - Win32 Debug"
# SUBTRACT CPP /YX /Yc /Yu
!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU"
# SUBTRACT CPP /YX /Yc /Yu
!ELSEIF "$(CFG)" == "Alone - Win32 DebugU"
# SUBTRACT CPP /YX /Yc /Yu
!ENDIF
# End Source File
# Begin Source File
SOURCE=..\..\..\..\C\MtDec.h
# End Source File
# Begin Source File
SOURCE=..\..\..\..\C\Ppmd.h
# End Source File
# Begin Source File

View File

@@ -198,10 +198,12 @@ C_OBJS = \
$O\LzFind.obj \
$O\LzFindMt.obj \
$O\Lzma2Dec.obj \
$O\Lzma2DecMt.obj \
$O\Lzma2Enc.obj \
$O\LzmaDec.obj \
$O\LzmaEnc.obj \
$O\MtCoder.obj \
$O\MtDec.obj \
$O\Ppmd7.obj \
$O\Ppmd7Dec.obj \
$O\Ppmd7Enc.obj \
@@ -222,5 +224,6 @@ C_OBJS = \
!include "../../Aes.mak"
!include "../../Crc.mak"
!include "../../Crc64.mak"
!include "../../LzmaDec.mak"
!include "../../7zip.mak"

View File

@@ -1696,6 +1696,34 @@ SOURCE=..\..\..\..\C\Lzma2Dec.h
# End Source File
# Begin Source File
SOURCE=..\..\..\..\C\Lzma2DecMt.c
!IF "$(CFG)" == "Alone - Win32 Release"
# ADD CPP /O2
# SUBTRACT CPP /YX /Yc /Yu
!ELSEIF "$(CFG)" == "Alone - Win32 Debug"
# SUBTRACT CPP /YX /Yc /Yu
!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU"
# SUBTRACT CPP /YX /Yc /Yu
!ELSEIF "$(CFG)" == "Alone - Win32 DebugU"
# SUBTRACT CPP /YX /Yc /Yu
!ENDIF
# End Source File
# Begin Source File
SOURCE=..\..\..\..\C\Lzma2DecMt.h
# End Source File
# Begin Source File
SOURCE=..\..\..\..\C\Lzma2Enc.c
!IF "$(CFG)" == "Alone - Win32 Release"
@@ -1789,6 +1817,34 @@ SOURCE=..\..\..\..\C\MtCoder.h
# End Source File
# Begin Source File
SOURCE=..\..\..\..\C\MtDec.c
!IF "$(CFG)" == "Alone - Win32 Release"
# ADD CPP /O2
# SUBTRACT CPP /YX /Yc /Yu
!ELSEIF "$(CFG)" == "Alone - Win32 Debug"
# SUBTRACT CPP /YX /Yc /Yu
!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU"
# SUBTRACT CPP /YX /Yc /Yu
!ELSEIF "$(CFG)" == "Alone - Win32 DebugU"
# SUBTRACT CPP /YX /Yc /Yu
!ENDIF
# End Source File
# Begin Source File
SOURCE=..\..\..\..\C\MtDec.h
# End Source File
# Begin Source File
SOURCE=..\..\..\..\C\Threads.c
# SUBTRACT CPP /YX /Yc /Yu
# End Source File

View File

@@ -133,10 +133,12 @@ C_OBJS = \
$O\LzFind.obj \
$O\LzFindMt.obj \
$O\Lzma2Dec.obj \
$O\Lzma2DecMt.obj \
$O\Lzma2Enc.obj \
$O\LzmaDec.obj \
$O\LzmaEnc.obj \
$O\MtCoder.obj \
$O\MtDec.obj \
$O\Sha256.obj \
$O\Sort.obj \
$O\Threads.obj \
@@ -150,5 +152,6 @@ C_OBJS = \
!include "../../Aes.mak"
!include "../../Crc.mak"
!include "../../Crc64.mak"
!include "../../LzmaDec.mak"
!include "../../7zip.mak"

View File

@@ -1004,6 +1004,15 @@ SOURCE=..\..\..\..\C\Lzma2Dec.h
# End Source File
# Begin Source File
SOURCE=..\..\..\..\C\Lzma2DecMt.c
# SUBTRACT CPP /YX /Yc /Yu
# End Source File
# Begin Source File
SOURCE=..\..\..\..\C\Lzma2DecMt.h
# End Source File
# Begin Source File
SOURCE=..\..\..\..\C\Lzma2Enc.c
# SUBTRACT CPP /YX /Yc /Yu
# End Source File
@@ -1040,6 +1049,15 @@ SOURCE=..\..\..\..\C\MtCoder.h
# End Source File
# Begin Source File
SOURCE=..\..\..\..\C\MtDec.c
# SUBTRACT CPP /YX /Yc /Yu
# End Source File
# Begin Source File
SOURCE=..\..\..\..\C\MtDec.h
# End Source File
# Begin Source File
SOURCE=..\..\..\..\C\Sha256.c
!IF "$(CFG)" == "FM - Win32 Release"

View File

@@ -123,10 +123,12 @@ C_OBJS = \
$O\LzFind.obj \
$O\LzFindMt.obj \
$O\Lzma2Dec.obj \
$O\Lzma2DecMt.obj \
$O\Lzma2Enc.obj \
$O\LzmaDec.obj \
$O\LzmaEnc.obj \
$O\MtCoder.obj \
$O\MtDec.obj \
$O\Ppmd7.obj \
$O\Ppmd7Dec.obj \
$O\Ppmd7Enc.obj \
@@ -136,5 +138,6 @@ C_OBJS = \
!include "../../Aes.mak"
!include "../../Crc.mak"
!include "../../LzmaDec.mak"
!include "../../7zip.mak"

View File

@@ -42,6 +42,7 @@ AR_OBJS = \
AR_COMMON_OBJS = \
$O\CoderMixer2.obj \
$O\HandlerOut.obj \
$O\ItemNameUtils.obj \
$O\OutStreamWithCRC.obj \
$O\ParseProperties.obj \
@@ -98,7 +99,9 @@ C_OBJS = \
$O\CpuArch.obj \
$O\Delta.obj \
$O\Lzma2Dec.obj \
$O\Lzma2DecMt.obj \
$O\LzmaDec.obj \
$O\MtDec.obj \
$O\Ppmd7.obj \
$O\Ppmd7Dec.obj \
$O\Sha256.obj \
@@ -106,5 +109,6 @@ C_OBJS = \
!include "../../Aes.mak"
!include "../../Crc.mak"
!include "../../LzmaDec.mak"
!include "../../7zip.mak"

View File

@@ -85,9 +85,12 @@ C_OBJS = \
$O\CpuArch.obj \
$O\Delta.obj \
$O\Lzma2Dec.obj \
$O\Lzma2DecMt.obj \
$O\LzmaDec.obj \
$O\MtDec.obj \
$O\Threads.obj \
!include "../../Crc.mak"
!include "../../LzmaDec.mak"
!include "../../7zip.mak"

View File

@@ -263,10 +263,12 @@ C_OBJS = \
$O\LzFind.obj \
$O\LzFindMt.obj \
$O\Lzma2Dec.obj \
$O\Lzma2DecMt.obj \
$O\Lzma2Enc.obj \
$O\LzmaDec.obj \
$O\LzmaEnc.obj \
$O\MtCoder.obj \
$O\MtDec.obj \
$O\Ppmd7.obj \
$O\Ppmd7Dec.obj \
$O\Ppmd7Enc.obj \
@@ -285,3 +287,4 @@ C_OBJS = \
!include "../../Aes.mak"
!include "../../Crc.mak"
!include "../../Crc64.mak"
!include "../../LzmaDec.mak"

View File

@@ -1805,6 +1805,26 @@ SOURCE=..\..\..\..\C\Lzma2Dec.h
# End Source File
# Begin Source File
SOURCE=..\..\..\..\C\Lzma2DecMt.c
!IF "$(CFG)" == "7z - Win32 Release"
# ADD CPP /O2
# SUBTRACT CPP /YX /Yc /Yu
!ELSEIF "$(CFG)" == "7z - Win32 Debug"
# SUBTRACT CPP /YX /Yc /Yu
!ENDIF
# End Source File
# Begin Source File
SOURCE=..\..\..\..\C\Lzma2DecMt.h
# End Source File
# Begin Source File
SOURCE=..\..\..\..\C\Lzma2Enc.c
!IF "$(CFG)" == "7z - Win32 Release"
@@ -1874,6 +1894,26 @@ SOURCE=..\..\..\..\C\MtCoder.h
# End Source File
# Begin Source File
SOURCE=..\..\..\..\C\MtDec.c
!IF "$(CFG)" == "7z - Win32 Release"
# ADD CPP /O2
# SUBTRACT CPP /YX /Yc /Yu
!ELSEIF "$(CFG)" == "7z - Win32 Debug"
# SUBTRACT CPP /YX /Yc /Yu
!ENDIF
# End Source File
# Begin Source File
SOURCE=..\..\..\..\C\MtDec.h
# End Source File
# Begin Source File
SOURCE=..\..\..\..\C\Ppmd.h
# End Source File
# Begin Source File

View File

@@ -102,12 +102,15 @@ C_OBJS = \
$O\LzFind.obj \
$O\LzFindMt.obj \
$O\Lzma2Dec.obj \
$O\Lzma2DecMt.obj \
$O\Lzma2Enc.obj \
$O\LzmaDec.obj \
$O\LzmaEnc.obj \
$O\MtCoder.obj \
$O\MtDec.obj \
$O\Threads.obj \
!include "../../Crc.mak"
!include "../../LzmaDec.mak"
!include "../../7zip.mak"

View File

@@ -117,6 +117,14 @@ SOURCE=..\..\Archive\Common\CoderMixer2.h
# End Source File
# Begin Source File
SOURCE=..\..\Archive\Common\HandlerOut.cpp
# End Source File
# Begin Source File
SOURCE=..\..\Archive\Common\HandlerOut.h
# End Source File
# Begin Source File
SOURCE=..\..\Archive\Common\ItemNameUtils.cpp
# End Source File
# Begin Source File
@@ -293,6 +301,10 @@ SOURCE=..\..\Compress\Lzma2Decoder.cpp
# End Source File
# Begin Source File
SOURCE=..\..\Compress\Lzma2Decoder.h
# End Source File
# Begin Source File
SOURCE=..\..\Compress\Lzma2Register.cpp
# End Source File
# Begin Source File
@@ -411,6 +423,14 @@ SOURCE=..\..\..\Windows\Synchronization.cpp
SOURCE=..\..\..\Windows\Synchronization.h
# End Source File
# Begin Source File
SOURCE=..\..\..\Windows\System.cpp
# End Source File
# Begin Source File
SOURCE=..\..\..\Windows\System.h
# End Source File
# End Group
# Begin Group "Common"
@@ -822,6 +842,15 @@ SOURCE=..\..\..\..\C\Lzma2Dec.h
# End Source File
# Begin Source File
SOURCE=..\..\..\..\C\Lzma2DecMt.c
# SUBTRACT CPP /YX /Yc /Yu
# End Source File
# Begin Source File
SOURCE=..\..\..\..\C\Lzma2DecMt.h
# End Source File
# Begin Source File
SOURCE=..\..\..\..\C\LzmaDec.c
# SUBTRACT CPP /YX /Yc /Yu
# End Source File
@@ -831,6 +860,15 @@ SOURCE=..\..\..\..\C\LzmaDec.h
# End Source File
# Begin Source File
SOURCE=..\..\..\..\C\MtDec.c
# SUBTRACT CPP /YX /Yc /Yu
# End Source File
# Begin Source File
SOURCE=..\..\..\..\C\MtDec.h
# End Source File
# Begin Source File
SOURCE=..\..\..\..\C\Ppmd7.c
# SUBTRACT CPP /YX /Yc /Yu
# End Source File

View File

@@ -41,6 +41,7 @@ WIN_OBJS = \
$O\PropVariant.obj \
$O\PropVariantConv.obj \
$O\Synchronization.obj \
$O\System.obj \
7ZIP_COMMON_OBJS = \
$O\CreateCoder.obj \
@@ -117,7 +118,9 @@ C_OBJS = \
$O\Delta.obj \
$O\DllSecur.obj \
$O\Lzma2Dec.obj \
$O\Lzma2DecMt.obj \
$O\LzmaDec.obj \
$O\MtDec.obj \
$O\Ppmd7.obj \
$O\Ppmd7Dec.obj \
$O\Sha256.obj \
@@ -125,5 +128,6 @@ C_OBJS = \
!include "../../Aes.mak"
!include "../../Crc.mak"
!include "../../LzmaDec.mak"
!include "../../7zip.mak"

View File

@@ -449,6 +449,14 @@ SOURCE=..\..\..\Windows\Synchronization.h
# End Source File
# Begin Source File
SOURCE=..\..\..\Windows\System.cpp
# End Source File
# Begin Source File
SOURCE=..\..\..\Windows\System.h
# End Source File
# Begin Source File
SOURCE=..\..\..\Windows\Window.cpp
# End Source File
# Begin Source File
@@ -469,6 +477,14 @@ SOURCE=..\..\Common\CreateCoder.h
# End Source File
# Begin Source File
SOURCE=..\..\Common\CWrappers.cpp
# End Source File
# Begin Source File
SOURCE=..\..\Common\CWrappers.h
# End Source File
# Begin Source File
SOURCE=..\..\Common\FileStreams.cpp
# End Source File
# Begin Source File
@@ -724,6 +740,15 @@ SOURCE=..\..\..\..\C\Lzma2Dec.h
# End Source File
# Begin Source File
SOURCE=..\..\..\..\C\Lzma2DecMt.c
# SUBTRACT CPP /YX /Yc /Yu
# End Source File
# Begin Source File
SOURCE=..\..\..\..\C\Lzma2DecMt.h
# End Source File
# Begin Source File
SOURCE=..\..\..\..\C\LzmaDec.c
# SUBTRACT CPP /YX /Yc /Yu
# End Source File
@@ -733,6 +758,15 @@ SOURCE=..\..\..\..\C\LzmaDec.h
# End Source File
# Begin Source File
SOURCE=..\..\..\..\C\MtDec.c
# SUBTRACT CPP /YX /Yc /Yu
# End Source File
# Begin Source File
SOURCE=..\..\..\..\C\MtDec.h
# End Source File
# Begin Source File
SOURCE=..\..\..\..\C\Threads.c
# SUBTRACT CPP /YX /Yc /Yu
# End Source File

View File

@@ -33,6 +33,7 @@ WIN_OBJS = \
$O\PropVariant.obj \
$O\ResourceString.obj \
$O\Synchronization.obj \
$O\System.obj \
$O\Window.obj \
WIN_CTRL_OBJS = \
@@ -40,6 +41,7 @@ WIN_CTRL_OBJS = \
7ZIP_COMMON_OBJS = \
$O\CreateCoder.obj \
$O\CWrappers.obj \
$O\FileStreams.obj \
$O\InBuffer.obj \
$O\FilterCoder.obj \
@@ -102,9 +104,12 @@ C_OBJS = \
$O\Delta.obj \
$O\DllSecur.obj \
$O\Lzma2Dec.obj \
$O\Lzma2DecMt.obj \
$O\LzmaDec.obj \
$O\MtDec.obj \
$O\Threads.obj \
!include "../../Crc.mak"
!include "../../LzmaDec.mak"
!include "../../7zip.mak"

View File

@@ -633,6 +633,14 @@ SOURCE=..\..\..\Windows\Synchronization.h
# End Source File
# Begin Source File
SOURCE=..\..\..\Windows\System.cpp
# End Source File
# Begin Source File
SOURCE=..\..\..\Windows\System.h
# End Source File
# Begin Source File
SOURCE=..\..\..\Windows\Window.cpp
# End Source File
# Begin Source File
@@ -906,6 +914,15 @@ SOURCE=..\..\..\..\C\Lzma2Dec.h
# End Source File
# Begin Source File
SOURCE=..\..\..\..\C\Lzma2DecMt.c
# SUBTRACT CPP /YX /Yc /Yu
# End Source File
# Begin Source File
SOURCE=..\..\..\..\C\Lzma2DecMt.h
# End Source File
# Begin Source File
SOURCE=..\..\..\..\C\LzmaDec.c
# SUBTRACT CPP /YX /Yc /Yu
# End Source File
@@ -915,6 +932,15 @@ SOURCE=..\..\..\..\C\LzmaDec.h
# End Source File
# Begin Source File
SOURCE=..\..\..\..\C\MtDec.c
# SUBTRACT CPP /YX /Yc /Yu
# End Source File
# Begin Source File
SOURCE=..\..\..\..\C\MtDec.h
# End Source File
# Begin Source File
SOURCE=..\..\..\..\C\Ppmd7.c
# SUBTRACT CPP /YX /Yc /Yu
# End Source File

View File

@@ -41,6 +41,7 @@ WIN_OBJS = \
$O\ResourceString.obj \
$O\Shell.obj \
$O\Synchronization.obj \
$O\System.obj \
$O\Window.obj \
WIN_CTRL_OBJS = \
@@ -135,7 +136,9 @@ C_OBJS = \
$O\Delta.obj \
$O\DllSecur.obj \
$O\Lzma2Dec.obj \
$O\Lzma2DecMt.obj \
$O\LzmaDec.obj \
$O\MtDec.obj \
$O\Ppmd7.obj \
$O\Ppmd7Dec.obj \
$O\Sha256.obj \
@@ -143,5 +146,6 @@ C_OBJS = \
!include "../../Aes.mak"
!include "../../Crc.mak"
!include "../../LzmaDec.mak"
!include "../../7zip.mak"

View File

@@ -148,20 +148,23 @@ HRESULT CExternalCodecs::Load()
#endif
bool FindMethod(
int FindMethod_Index(
DECL_EXTERNAL_CODECS_LOC_VARS
const AString &name,
CMethodId &methodId, UInt32 &numStreams)
bool encode,
CMethodId &methodId,
UInt32 &numStreams)
{
unsigned i;
for (i = 0; i < g_NumCodecs; i++)
{
const CCodecInfo &codec = *g_Codecs[i];
if (StringsAreEqualNoCase_Ascii(name, codec.Name))
if ((encode ? codec.CreateEncoder : codec.CreateDecoder)
&& StringsAreEqualNoCase_Ascii(name, codec.Name))
{
methodId = codec.Id;
numStreams = codec.NumStreams;
return true;
return i;
}
}
@@ -173,19 +176,51 @@ bool FindMethod(
for (i = 0; i < __externalCodecs->Codecs.Size(); i++)
{
const CCodecInfoEx &codec = __externalCodecs->Codecs[i];
if (StringsAreEqualNoCase_Ascii(name, codec.Name))
if ((encode ? codec.EncoderIsAssigned : codec.DecoderIsAssigned)
&& StringsAreEqualNoCase_Ascii(name, codec.Name))
{
methodId = codec.Id;
numStreams = codec.NumStreams;
return true;
return g_NumCodecs + i;
}
}
#endif
return false;
return -1;
}
static int FindMethod_Index(
DECL_EXTERNAL_CODECS_LOC_VARS
CMethodId methodId, bool encode)
{
unsigned i;
for (i = 0; i < g_NumCodecs; i++)
{
const CCodecInfo &codec = *g_Codecs[i];
if (codec.Id == methodId && (encode ? codec.CreateEncoder : codec.CreateDecoder))
return i;
}
#ifdef EXTERNAL_CODECS
CHECK_GLOBAL_CODECS
if (__externalCodecs)
for (i = 0; i < __externalCodecs->Codecs.Size(); i++)
{
const CCodecInfoEx &codec = __externalCodecs->Codecs[i];
if (codec.Id == methodId && (encode ? codec.EncoderIsAssigned : codec.DecoderIsAssigned))
return g_NumCodecs + i;
}
#endif
return -1;
}
bool FindMethod(
DECL_EXTERNAL_CODECS_LOC_VARS
CMethodId methodId,
@@ -280,9 +315,11 @@ void GetHashMethods(
#endif
}
HRESULT CreateCoder(
HRESULT CreateCoder_Index(
DECL_EXTERNAL_CODECS_LOC_VARS
CMethodId methodId, bool encode,
unsigned i, bool encode,
CMyComPtr<ICompressFilter> &filter,
CCreatedCoder &cod)
{
@@ -290,11 +327,10 @@ HRESULT CreateCoder(
cod.IsFilter = false;
cod.NumStreams = 1;
unsigned i;
for (i = 0; i < g_NumCodecs; i++)
if (i < g_NumCodecs)
{
const CCodecInfo &codec = *g_Codecs[i];
if (codec.Id == methodId)
// if (codec.Id == methodId)
{
if (encode)
{
@@ -325,11 +361,12 @@ HRESULT CreateCoder(
if (__externalCodecs)
{
i -= g_NumCodecs;
cod.IsExternal = true;
for (i = 0; i < __externalCodecs->Codecs.Size(); i++)
if (i < __externalCodecs->Codecs.Size())
{
const CCodecInfoEx &codec = __externalCodecs->Codecs[i];
if (codec.Id == methodId)
// if (codec.Id == methodId)
{
if (encode)
{
@@ -371,13 +408,50 @@ HRESULT CreateCoder(
return S_OK;
}
HRESULT CreateCoder(
HRESULT CreateCoder_Index(
DECL_EXTERNAL_CODECS_LOC_VARS
unsigned index, bool encode,
CCreatedCoder &cod)
{
CMyComPtr<ICompressFilter> filter;
HRESULT res = CreateCoder_Index(
EXTERNAL_CODECS_LOC_VARS
index, encode,
filter, cod);
if (filter)
{
cod.IsFilter = true;
CFilterCoder *coderSpec = new CFilterCoder(encode);
cod.Coder = coderSpec;
coderSpec->Filter = filter;
}
return res;
}
HRESULT CreateCoder_Id(
DECL_EXTERNAL_CODECS_LOC_VARS
CMethodId methodId, bool encode,
CMyComPtr<ICompressFilter> &filter,
CCreatedCoder &cod)
{
int index = FindMethod_Index(EXTERNAL_CODECS_LOC_VARS methodId, encode);
if (index < 0)
return S_OK;
return CreateCoder_Index(EXTERNAL_CODECS_LOC_VARS index, encode, filter, cod);
}
HRESULT CreateCoder_Id(
DECL_EXTERNAL_CODECS_LOC_VARS
CMethodId methodId, bool encode,
CCreatedCoder &cod)
{
CMyComPtr<ICompressFilter> filter;
HRESULT res = CreateCoder(
HRESULT res = CreateCoder_Id(
EXTERNAL_CODECS_LOC_VARS
methodId, encode,
filter, cod);
@@ -393,13 +467,14 @@ HRESULT CreateCoder(
return res;
}
HRESULT CreateCoder(
HRESULT CreateCoder_Id(
DECL_EXTERNAL_CODECS_LOC_VARS
CMethodId methodId, bool encode,
CMyComPtr<ICompressCoder> &coder)
{
CCreatedCoder cod;
HRESULT res = CreateCoder(
HRESULT res = CreateCoder_Id(
EXTERNAL_CODECS_LOC_VARS
methodId, encode,
cod);
@@ -413,7 +488,7 @@ HRESULT CreateFilter(
CMyComPtr<ICompressFilter> &filter)
{
CCreatedCoder cod;
return CreateCoder(
return CreateCoder_Id(
EXTERNAL_CODECS_LOC_VARS
methodId, encode,
filter, cod);

View File

@@ -116,13 +116,12 @@ extern CExternalCodecs g_ExternalCodecs;
#endif
bool FindMethod(
int FindMethod_Index(
DECL_EXTERNAL_CODECS_LOC_VARS
const AString &name,
CMethodId &methodId, UInt32 &numStreams);
bool encode,
CMethodId &methodId,
UInt32 &numStreams);
bool FindMethod(
DECL_EXTERNAL_CODECS_LOC_VARS
@@ -152,18 +151,29 @@ struct CCreatedCoder
};
HRESULT CreateCoder(
HRESULT CreateCoder_Index(
DECL_EXTERNAL_CODECS_LOC_VARS
unsigned codecIndex, bool encode,
CMyComPtr<ICompressFilter> &filter,
CCreatedCoder &cod);
HRESULT CreateCoder_Index(
DECL_EXTERNAL_CODECS_LOC_VARS
unsigned index, bool encode,
CCreatedCoder &cod);
HRESULT CreateCoder_Id(
DECL_EXTERNAL_CODECS_LOC_VARS
CMethodId methodId, bool encode,
CMyComPtr<ICompressFilter> &filter,
CCreatedCoder &cod);
HRESULT CreateCoder(
HRESULT CreateCoder_Id(
DECL_EXTERNAL_CODECS_LOC_VARS
CMethodId methodId, bool encode,
CCreatedCoder &cod);
HRESULT CreateCoder(
HRESULT CreateCoder_Id(
DECL_EXTERNAL_CODECS_LOC_VARS
CMethodId methodId, bool encode,
CMyComPtr<ICompressCoder> &coder);

View File

@@ -253,6 +253,9 @@ struct CNameToPropID
const char *Name;
};
// the following are related to NCoderPropID::EEnum values
static const CNameToPropID g_NameToPropID[] =
{
{ VT_UI4, "" },
@@ -275,7 +278,8 @@ static const CNameToPropID g_NameToPropID[] =
{ VT_UI8, "expect" },
{ VT_UI4, "b" },
{ VT_UI4, "check" },
{ VT_BSTR, "filter" }
{ VT_BSTR, "filter" },
{ VT_UI8, "memuse" }
};
static int FindPropIdExact(const UString &name)
@@ -293,6 +297,13 @@ static bool ConvertProperty(const PROPVARIANT &srcProp, VARTYPE varType, NCOM::C
destProp = srcProp;
return true;
}
if (varType == VT_UI8 && srcProp.vt == VT_UI4)
{
destProp = (UInt64)srcProp.ulVal;
return true;
}
if (varType == VT_BOOL)
{
bool res;

View File

@@ -969,6 +969,10 @@ HRESULT CCoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream *ou
}
}
while (Inline_MatchFinder_GetNumAvailableBytes(&_lzInWindow) != 0);
if (_seqInStream.Res != S_OK)
return _seqInStream.Res;
if (_lzInWindow.result != SZ_OK)
return SResToHRESULT(_lzInWindow.result);
return m_OutStream.Flush();

View File

@@ -2,81 +2,48 @@
#include "StdAfx.h"
// #include <stdio.h>
#include "../../../C/Alloc.h"
// #include "../../../C/CpuTicks.h"
#include "../Common/StreamUtils.h"
#include "Lzma2Decoder.h"
static HRESULT SResToHRESULT(SRes res)
{
switch (res)
{
case SZ_OK: return S_OK;
case SZ_ERROR_MEM: return E_OUTOFMEMORY;
case SZ_ERROR_PARAM: return E_INVALIDARG;
case SZ_ERROR_UNSUPPORTED: return E_NOTIMPL;
case SZ_ERROR_DATA: return S_FALSE;
}
return E_FAIL;
}
namespace NCompress {
namespace NLzma2 {
CDecoder::CDecoder():
_inBuf(NULL),
_finishMode(false),
_outSizeDefined(false),
_outStep(1 << 22),
_inBufSize(0),
_inBufSizeNew(1 << 20)
{
Lzma2Dec_Construct(&_state);
}
_dec(NULL)
, _inProcessed(0)
, _prop(0xFF)
, _finishMode(false)
, _inBufSize(1 << 20)
, _outStep(1 << 20)
#ifndef _7ZIP_ST
, _tryMt(1)
, _numThreads(1)
, _memUsage((UInt64)(sizeof(size_t)) << 28)
#endif
{}
CDecoder::~CDecoder()
{
Lzma2Dec_Free(&_state, &g_Alloc);
MidFree(_inBuf);
if (_dec)
Lzma2DecMt_Destroy(_dec);
}
STDMETHODIMP CDecoder::SetInBufSize(UInt32 , UInt32 size) { _inBufSizeNew = size; return S_OK; }
STDMETHODIMP CDecoder::SetInBufSize(UInt32 , UInt32 size) { _inBufSize = size; return S_OK; }
STDMETHODIMP CDecoder::SetOutBufSize(UInt32 , UInt32 size) { _outStep = size; return S_OK; }
STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *prop, UInt32 size)
{
if (size != 1)
return E_NOTIMPL;
RINOK(SResToHRESULT(Lzma2Dec_Allocate(&_state, prop[0], &g_Alloc)));
if (!_inBuf || _inBufSize != _inBufSizeNew)
{
MidFree(_inBuf);
_inBufSize = 0;
_inBuf = (Byte *)MidAlloc(_inBufSizeNew);
if (!_inBuf)
return E_OUTOFMEMORY;
_inBufSize = _inBufSizeNew;
}
return S_OK;
}
STDMETHODIMP CDecoder::SetOutStreamSize(const UInt64 *outSize)
{
_outSizeDefined = (outSize != NULL);
_outSize = 0;
if (_outSizeDefined)
_outSize = *outSize;
_inPos = _inLim = 0;
_inProcessed = 0;
_outProcessed = 0;
Lzma2Dec_Init(&_state);
if (prop[0] > 40)
return E_NOTIMPL;
_prop = prop[0];
return S_OK;
}
@@ -88,6 +55,137 @@ STDMETHODIMP CDecoder::SetFinishMode(UInt32 finishMode)
}
#ifndef _7ZIP_ST
static UInt64 Get_ExpectedBlockSize_From_Dict(UInt32 dictSize)
{
const UInt32 kMinSize = (UInt32)1 << 20;
const UInt32 kMaxSize = (UInt32)1 << 28;
UInt64 blockSize = (UInt64)dictSize << 2;
if (blockSize < kMinSize) blockSize = kMinSize;
if (blockSize > kMaxSize) blockSize = kMaxSize;
if (blockSize < dictSize) blockSize = dictSize;
blockSize += (kMinSize - 1);
blockSize &= ~(UInt64)(kMinSize - 1);
return blockSize;
}
#define LZMA2_DIC_SIZE_FROM_PROP_FULL(p) ((p) == 40 ? 0xFFFFFFFF : (((UInt32)2 | ((p) & 1)) << ((p) / 2 + 11)))
#endif
#define RET_IF_WRAP_ERROR_CONFIRMED(wrapRes, sRes, sResErrorCode) \
if (wrapRes != S_OK && sRes == sResErrorCode) return wrapRes;
#define RET_IF_WRAP_ERROR(wrapRes, sRes, sResErrorCode) \
if (wrapRes != S_OK /* && (sRes == SZ_OK || sRes == sResErrorCode) */) return wrapRes;
STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream,
const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress)
{
_inProcessed = 0;
if (!_dec)
{
_dec = Lzma2DecMt_Create(
// &g_AlignedAlloc,
&g_Alloc,
&g_MidAlloc);
if (!_dec)
return E_OUTOFMEMORY;
}
CLzma2DecMtProps props;
Lzma2DecMtProps_Init(&props);
props.inBufSize_ST = _inBufSize;
props.outStep_ST = _outStep;
#ifndef _7ZIP_ST
{
props.numThreads = 1;
UInt32 numThreads = _numThreads;
if (_tryMt && numThreads >= 1)
{
UInt64 useLimit = _memUsage;
UInt32 dictSize = LZMA2_DIC_SIZE_FROM_PROP_FULL(_prop);
UInt64 expectedBlockSize64 = Get_ExpectedBlockSize_From_Dict(dictSize);
size_t expectedBlockSize = (size_t)expectedBlockSize64;
size_t inBlockMax = expectedBlockSize + expectedBlockSize / 16;
if (expectedBlockSize == expectedBlockSize64 && inBlockMax >= expectedBlockSize)
{
props.outBlockMax = expectedBlockSize;
props.inBlockMax = inBlockMax;
const size_t kOverheadSize = props.inBufSize_MT + (1 << 16);
UInt64 okThreads = useLimit / (props.outBlockMax + props.inBlockMax + kOverheadSize);
if (numThreads > okThreads)
numThreads = (UInt32)okThreads;
if (numThreads == 0)
numThreads = 1;
props.numThreads = numThreads;
}
}
}
#endif
CSeqInStreamWrap inWrap;
CSeqOutStreamWrap outWrap;
CCompressProgressWrap progressWrap;
inWrap.Init(inStream);
outWrap.Init(outStream);
progressWrap.Init(progress);
SRes res;
UInt64 inProcessed = 0;
int isMT = False;
#ifndef _7ZIP_ST
isMT = _tryMt;
#endif
// UInt64 cpuTicks = GetCpuTicks();
res = Lzma2DecMt_Decode(_dec, _prop, &props,
&outWrap.vt, outSize, _finishMode,
&inWrap.vt,
&inProcessed,
&isMT,
progress ? &progressWrap.vt : NULL);
/*
cpuTicks = GetCpuTicks() - cpuTicks;
printf("\n ticks = %10I64u\n", cpuTicks / 1000000);
*/
#ifndef _7ZIP_ST
/* we reset _tryMt, only if p->props.numThreads was changed */
if (props.numThreads > 1)
_tryMt = isMT;
#endif
_inProcessed = inProcessed;
RET_IF_WRAP_ERROR(progressWrap.Res, res, SZ_ERROR_PROGRESS)
RET_IF_WRAP_ERROR(outWrap.Res, res, SZ_ERROR_WRITE)
RET_IF_WRAP_ERROR_CONFIRMED(inWrap.Res, res, SZ_ERROR_READ)
if (res == SZ_OK && _finishMode)
{
if (inSize && *inSize != inProcessed)
res = SZ_ERROR_DATA;
if (outSize && *outSize != outWrap.Processed)
res = SZ_ERROR_DATA;
}
return SResToHRESULT(res);
}
STDMETHODIMP CDecoder::GetInStreamProcessedSize(UInt64 *value)
{
*value = _inProcessed;
@@ -95,109 +193,51 @@ STDMETHODIMP CDecoder::GetInStreamProcessedSize(UInt64 *value)
}
STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream,
const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress)
#ifndef _7ZIP_ST
STDMETHODIMP CDecoder::SetNumberOfThreads(UInt32 numThreads)
{
if (!_inBuf)
return S_FALSE;
SetOutStreamSize(outSize);
SizeT wrPos = _state.decoder.dicPos;
HRESULT readRes = S_OK;
for (;;)
{
if (_inPos == _inLim && readRes == S_OK)
{
_inPos = _inLim = 0;
readRes = inStream->Read(_inBuf, _inBufSize, &_inLim);
}
const SizeT dicPos = _state.decoder.dicPos;
SizeT size;
{
SizeT next = _state.decoder.dicBufSize;
if (next - wrPos > _outStep)
next = wrPos + _outStep;
size = next - dicPos;
}
ELzmaFinishMode finishMode = LZMA_FINISH_ANY;
if (_outSizeDefined)
{
const UInt64 rem = _outSize - _outProcessed;
if (size >= rem)
{
size = (SizeT)rem;
if (_finishMode)
finishMode = LZMA_FINISH_END;
}
}
SizeT inProcessed = _inLim - _inPos;
ELzmaStatus status;
SRes res = Lzma2Dec_DecodeToDic(&_state, dicPos + size, _inBuf + _inPos, &inProcessed, finishMode, &status);
_inPos += (UInt32)inProcessed;
_inProcessed += inProcessed;
const SizeT outProcessed = _state.decoder.dicPos - dicPos;
_outProcessed += outProcessed;
bool outFinished = (_outSizeDefined && _outProcessed >= _outSize);
bool needStop = (res != 0
|| (inProcessed == 0 && outProcessed == 0)
|| status == LZMA_STATUS_FINISHED_WITH_MARK
|| (!_finishMode && outFinished));
if (needStop || outProcessed >= size)
{
HRESULT res2 = WriteStream(outStream, _state.decoder.dic + wrPos, _state.decoder.dicPos - wrPos);
if (_state.decoder.dicPos == _state.decoder.dicBufSize)
_state.decoder.dicPos = 0;
wrPos = _state.decoder.dicPos;
RINOK(res2);
if (needStop)
{
if (res != 0)
return S_FALSE;
if (status == LZMA_STATUS_FINISHED_WITH_MARK)
{
if (_finishMode)
{
if (inSize && *inSize != _inProcessed)
return S_FALSE;
if (_outSizeDefined && _outSize != _outProcessed)
return S_FALSE;
}
return readRes;
}
if (!_finishMode && outFinished)
return readRes;
return S_FALSE;
}
}
if (progress)
{
RINOK(progress->SetRatioInfo(&_inProcessed, &_outProcessed));
}
}
_numThreads = numThreads;
return S_OK;
}
STDMETHODIMP CDecoder::SetMemLimit(UInt64 memUsage)
{
_memUsage = memUsage;
return S_OK;
}
#endif
#ifndef NO_READ_FROM_CODER
STDMETHODIMP CDecoder::SetOutStreamSize(const UInt64 *outSize)
{
CLzma2DecMtProps props;
Lzma2DecMtProps_Init(&props);
props.inBufSize_ST = _inBufSize;
props.outStep_ST = _outStep;
_inProcessed = 0;
if (!_dec)
{
_dec = Lzma2DecMt_Create(&g_AlignedAlloc, &g_MidAlloc);
if (!_dec)
return E_OUTOFMEMORY;
}
_inWrap.Init(_inStream);
SRes res = Lzma2DecMt_Init(_dec, _prop, &props, outSize, _finishMode, &_inWrap.vt);
if (res != SZ_OK)
return SResToHRESULT(res);
return S_OK;
}
STDMETHODIMP CDecoder::SetInStream(ISequentialInStream *inStream) { _inStream = inStream; return S_OK; }
STDMETHODIMP CDecoder::ReleaseInStream() { _inStream.Release(); return S_OK; }
@@ -207,62 +247,17 @@ STDMETHODIMP CDecoder::Read(void *data, UInt32 size, UInt32 *processedSize)
if (processedSize)
*processedSize = 0;
ELzmaFinishMode finishMode = LZMA_FINISH_ANY;
if (_outSizeDefined)
{
const UInt64 rem = _outSize - _outProcessed;
if (size >= rem)
{
size = (UInt32)rem;
if (_finishMode)
finishMode = LZMA_FINISH_END;
}
}
size_t size2 = size;
UInt64 inProcessed = 0;
HRESULT readRes = S_OK;
SRes res = Lzma2DecMt_Read(_dec, (Byte *)data, &size2, &inProcessed);
for (;;)
{
if (_inPos == _inLim && readRes == S_OK)
{
_inPos = _inLim = 0;
readRes = _inStream->Read(_inBuf, _inBufSize, &_inLim);
}
SizeT inProcessed = _inLim - _inPos;
SizeT outProcessed = size;
ELzmaStatus status;
SRes res = Lzma2Dec_DecodeToBuf(&_state, (Byte *)data, &outProcessed,
_inBuf + _inPos, &inProcessed, finishMode, &status);
_inPos += (UInt32)inProcessed;
_inProcessed += inProcessed;
_outProcessed += outProcessed;
size -= (UInt32)outProcessed;
data = (Byte *)data + outProcessed;
if (processedSize)
*processedSize += (UInt32)outProcessed;
if (res != 0)
return S_FALSE;
/*
if (status == LZMA_STATUS_FINISHED_WITH_MARK)
return readRes;
if (size == 0 && status != LZMA_STATUS_NEEDS_MORE_INPUT)
{
if (_finishMode && _outSizeDefined && _outProcessed >= _outSize)
return S_FALSE;
return readRes;
}
*/
if (inProcessed == 0 && outProcessed == 0)
return readRes;
}
_inProcessed += inProcessed;
if (processedSize)
*processedSize = (UInt32)size2;
if (res != SZ_OK)
return SResToHRESULT(res);
return S_OK;
}
#endif

View File

@@ -3,10 +3,9 @@
#ifndef __LZMA2_DECODER_H
#define __LZMA2_DECODER_H
#include "../../../C/Lzma2Dec.h"
#include "../../../C/Lzma2DecMt.h"
#include "../../Common/MyCom.h"
#include "../ICoder.h"
#include "../Common/CWrappers.h"
namespace NCompress {
namespace NLzma2 {
@@ -17,28 +16,26 @@ class CDecoder:
public ICompressSetFinishMode,
public ICompressGetInStreamProcessedSize,
public ICompressSetBufSize,
#ifndef NO_READ_FROM_CODER
public ICompressSetInStream,
public ICompressSetOutStreamSize,
public ISequentialInStream,
#endif
#ifndef _7ZIP_ST
public ICompressSetCoderMt,
public ICompressSetMemLimit,
#endif
public CMyUnknownImp
{
Byte *_inBuf;
UInt32 _inPos;
UInt32 _inLim;
bool _finishMode;
bool _outSizeDefined;
UInt64 _outSize;
CLzma2DecMtHandle _dec;
UInt64 _inProcessed;
UInt64 _outProcessed;
UInt32 _outStep;
Byte _prop;
int _finishMode;
UInt32 _inBufSize;
UInt32 _inBufSizeNew;
CLzma2Dec _state;
UInt32 _outStep;
public:
MY_QUERYINTERFACE_BEGIN2(ICompressCoder)
@@ -46,11 +43,18 @@ public:
MY_QUERYINTERFACE_ENTRY(ICompressSetFinishMode)
MY_QUERYINTERFACE_ENTRY(ICompressGetInStreamProcessedSize)
MY_QUERYINTERFACE_ENTRY(ICompressSetBufSize)
#ifndef NO_READ_FROM_CODER
MY_QUERYINTERFACE_ENTRY(ICompressSetInStream)
MY_QUERYINTERFACE_ENTRY(ICompressSetOutStreamSize)
MY_QUERYINTERFACE_ENTRY(ISequentialInStream)
#endif
#ifndef _7ZIP_ST
MY_QUERYINTERFACE_ENTRY(ICompressSetCoderMt)
MY_QUERYINTERFACE_ENTRY(ICompressSetMemLimit)
#endif
MY_QUERYINTERFACE_END
MY_ADDREF_RELEASE
@@ -59,20 +63,28 @@ public:
STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size);
STDMETHOD(SetFinishMode)(UInt32 finishMode);
STDMETHOD(GetInStreamProcessedSize)(UInt64 *value);
STDMETHOD(SetOutStreamSize)(const UInt64 *outSize);
STDMETHOD(SetInBufSize)(UInt32 streamIndex, UInt32 size);
STDMETHOD(SetOutBufSize)(UInt32 streamIndex, UInt32 size);
#ifndef NO_READ_FROM_CODER
#ifndef _7ZIP_ST
private:
int _tryMt;
UInt32 _numThreads;
UInt64 _memUsage;
public:
STDMETHOD(SetNumberOfThreads)(UInt32 numThreads);
STDMETHOD(SetMemLimit)(UInt64 memUsage);
#endif
#ifndef NO_READ_FROM_CODER
private:
CMyComPtr<ISequentialInStream> _inStream;
CSeqInStreamWrap _inWrap;
public:
STDMETHOD(SetOutStreamSize)(const UInt64 *outSize);
STDMETHOD(SetInStream)(ISequentialInStream *inStream);
STDMETHOD(ReleaseInStream)();
STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
#endif
CDecoder();

View File

@@ -30,19 +30,24 @@ CDecoder::CDecoder():
FinishStream(false),
_propsWereSet(false),
_outSizeDefined(false),
_outStep(1 << 22),
_outStep(1 << 20),
_inBufSize(0),
_inBufSizeNew(1 << 20)
{
_inProcessed = 0;
_inPos = _inLim = 0;
/*
AlignOffsetAlloc_CreateVTable(&_alloc);
_alloc.numAlignBits = 7;
_alloc.offset = 0;
*/
LzmaDec_Construct(&_state);
}
CDecoder::~CDecoder()
{
LzmaDec_Free(&_state, &g_Alloc);
LzmaDec_Free(&_state, &g_AlignedAlloc); // &_alloc.vt
MyFree(_inBuf);
}
@@ -66,7 +71,7 @@ HRESULT CDecoder::CreateInputBuffer()
STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *prop, UInt32 size)
{
RINOK(SResToHRESULT(LzmaDec_Allocate(&_state, prop, size, &g_Alloc)));
RINOK(SResToHRESULT(LzmaDec_Allocate(&_state, prop, size, &g_AlignedAlloc))) // &_alloc.vt
_propsWereSet = true;
return CreateInputBuffer();
}

View File

@@ -3,6 +3,7 @@
#ifndef __LZMA_DECODER_H
#define __LZMA_DECODER_H
// #include "../../../C/Alloc.h"
#include "../../../C/LzmaDec.h"
#include "../../Common/MyCom.h"
@@ -28,7 +29,6 @@ class CDecoder:
UInt32 _inPos;
UInt32 _inLim;
CLzmaDec _state;
ELzmaStatus _lzmaStatus;
public:
@@ -45,6 +45,10 @@ private:
UInt32 _inBufSize;
UInt32 _inBufSizeNew;
// CAlignOffsetAlloc _alloc;
CLzmaDec _state;
HRESULT CreateInputBuffer();
HRESULT CodeSpec(ISequentialInStream *inStream, ISequentialOutStream *outStream, ICompressProgressInfo *progress);
void SetOutStreamSizeResume(const UInt64 *outSize);

View File

@@ -4,248 +4,119 @@
#include "../../../C/Alloc.h"
#include "../Common/StreamUtils.h"
#include "../Archive/IArchive.h"
#include "../Common/CWrappers.h"
#include "XzDecoder.h"
using namespace NArchive;
namespace NCompress {
namespace NXz {
#define RET_IF_WRAP_ERROR_CONFIRMED(wrapRes, sRes, sResErrorCode) \
if (wrapRes != S_OK && sRes == sResErrorCode) return wrapRes;
CXzUnpackerCPP::CXzUnpackerCPP(): InBuf(NULL), OutBuf(NULL)
#define RET_IF_WRAP_ERROR(wrapRes, sRes, sResErrorCode) \
if (wrapRes != S_OK /* && (sRes == SZ_OK || sRes == sResErrorCode) */) return wrapRes;
static HRESULT SResToHRESULT_Code(SRes res) throw()
{
XzUnpacker_Construct(&p, &g_Alloc);
}
CXzUnpackerCPP::~CXzUnpackerCPP()
{
XzUnpacker_Free(&p);
MidFree(InBuf);
MidFree(OutBuf);
}
void CStatInfo::Clear()
{
InSize = 0;
OutSize = 0;
PhySize = 0;
NumStreams = 0;
NumBlocks = 0;
UnpackSize_Defined = false;
NumStreams_Defined = false;
NumBlocks_Defined = false;
IsArc = false;
UnexpectedEnd = false;
DataAfterEnd = false;
Unsupported = false;
HeadersError = false;
DataError = false;
CrcError = false;
if (res < 0)
return res;
switch (res)
{
case SZ_OK: return S_OK;
case SZ_ERROR_MEM: return E_OUTOFMEMORY;
case SZ_ERROR_UNSUPPORTED: return E_NOTIMPL;
}
return S_FALSE;
}
HRESULT CDecoder::Decode(ISequentialInStream *seqInStream, ISequentialOutStream *outStream,
const UInt64 *outSizeLimit, bool finishStream, ICompressProgressInfo *progress)
{
const size_t kInBufSize = (size_t)1 << 20;
const size_t kOutBufSize = (size_t)1 << 21;
MainDecodeSRes = S_OK;
MainDecodeSRes_wasUsed = false;
XzStatInfo_Clear(&Stat);
Clear();
DecodeRes = SZ_OK;
XzUnpacker_Init(&xzu.p);
if (!xzu.InBuf)
if (!xz)
{
xzu.InBuf = (Byte *)MidAlloc(kInBufSize);
if (!xzu.InBuf)
return E_OUTOFMEMORY;
}
if (!xzu.OutBuf)
{
xzu.OutBuf = (Byte *)MidAlloc(kOutBufSize);
if (!xzu.OutBuf)
xz = XzDecMt_Create(&g_Alloc, &g_MidAlloc);
if (!xz)
return E_OUTOFMEMORY;
}
UInt32 inSize = 0;
UInt32 inPos = 0;
SizeT outPos = 0;
CXzDecMtProps props;
XzDecMtProps_Init(&props);
HRESULT readRes = S_OK;
int isMT = False;
for (;;)
#ifndef _7ZIP_ST
{
if (inPos == inSize && readRes == S_OK)
props.numThreads = 1;
UInt32 numThreads = _numThreads;
if (_tryMt && numThreads > 1)
{
inPos = inSize = 0;
readRes = seqInStream->Read(xzu.InBuf, kInBufSize, &inSize);
size_t memUsage = (size_t)_memUsage;
if (memUsage != _memUsage)
memUsage = (size_t)0 - 1;
props.memUseMax = memUsage;
isMT = (numThreads > 1);
}
SizeT inLen = inSize - inPos;
SizeT outLen = kOutBufSize - outPos;
ECoderFinishMode finishMode = CODER_FINISH_ANY;
props.numThreads = numThreads;
}
#endif
CSeqInStreamWrap inWrap;
CSeqOutStreamWrap outWrap;
CCompressProgressWrap progressWrap;
inWrap.Init(seqInStream);
outWrap.Init(outStream);
progressWrap.Init(progress);
SRes res = XzDecMt_Decode(xz,
&props,
outSizeLimit, finishStream,
&outWrap.vt,
&inWrap.vt,
&Stat,
&isMT,
progress ? &progressWrap.vt : NULL);
MainDecodeSRes = res;
#ifndef _7ZIP_ST
// _tryMt = isMT;
#endif
RET_IF_WRAP_ERROR(outWrap.Res, res, SZ_ERROR_WRITE)
RET_IF_WRAP_ERROR(progressWrap.Res, res, SZ_ERROR_PROGRESS)
RET_IF_WRAP_ERROR_CONFIRMED(inWrap.Res, res, SZ_ERROR_READ)
// return E_OUTOFMEMORY;
MainDecodeSRes_wasUsed = true;
if (res == SZ_OK && finishStream)
{
/*
// 17.01 : the code was disabled:
if (inSize == 0)
finishMode = CODER_FINISH_END;
if (inSize && *inSize != Stat.PhySize)
res = SZ_ERROR_DATA;
*/
if (outSizeLimit)
{
const UInt64 rem = *outSizeLimit - OutSize;
if (outLen >= rem)
{
outLen = (SizeT)rem;
if (finishStream)
finishMode = CODER_FINISH_END;
}
}
ECoderStatus status;
const SizeT outLenRequested = outLen;
SRes res = XzUnpacker_Code(&xzu.p,
xzu.OutBuf + outPos, &outLen,
xzu.InBuf + inPos, &inLen,
finishMode, &status);
DecodeRes = res;
inPos += (UInt32)inLen;
outPos += outLen;
InSize += inLen;
OutSize += outLen;
bool finished = ((inLen == 0 && outLen == 0) || res != SZ_OK);
if (outLen >= outLenRequested || finished)
{
if (outStream && outPos != 0)
{
RINOK(WriteStream(outStream, xzu.OutBuf, outPos));
}
outPos = 0;
}
if (progress)
{
RINOK(progress->SetRatioInfo(&InSize, &OutSize));
}
if (!finished)
continue;
{
PhySize = InSize;
NumStreams = xzu.p.numStartedStreams;
if (NumStreams > 0)
IsArc = true;
NumBlocks = xzu.p.numTotalBlocks;
UnpackSize_Defined = true;
NumStreams_Defined = true;
NumBlocks_Defined = true;
UInt64 extraSize = XzUnpacker_GetExtraSize(&xzu.p);
if (res == SZ_OK)
{
if (status == CODER_STATUS_NEEDS_MORE_INPUT)
{
extraSize = 0;
if (!XzUnpacker_IsStreamWasFinished(&xzu.p))
{
// finished at padding bytes, but padding is not aligned for 4
UnexpectedEnd = true;
res = SZ_ERROR_DATA;
}
}
else // status == CODER_STATUS_NOT_FINISHED
res = SZ_ERROR_DATA;
}
else if (res == SZ_ERROR_NO_ARCHIVE)
{
if (InSize == extraSize)
IsArc = false;
else
{
if (extraSize != 0 || inPos != inSize)
{
DataAfterEnd = true;
res = SZ_OK;
}
}
}
DecodeRes = res;
PhySize -= extraSize;
switch (res)
{
case SZ_OK: break;
case SZ_ERROR_NO_ARCHIVE: IsArc = false; break;
case SZ_ERROR_ARCHIVE: HeadersError = true; break;
case SZ_ERROR_UNSUPPORTED: Unsupported = true; break;
case SZ_ERROR_CRC: CrcError = true; break;
case SZ_ERROR_DATA: DataError = true; break;
default: DataError = true; break;
}
return readRes;
}
if (outSizeLimit && *outSizeLimit != outWrap.Processed)
res = SZ_ERROR_DATA;
}
return SResToHRESULT_Code(res);
}
Int32 CDecoder::Get_Extract_OperationResult() const
{
Int32 opRes;
if (!IsArc)
opRes = NExtract::NOperationResult::kIsNotArc;
else if (UnexpectedEnd)
opRes = NExtract::NOperationResult::kUnexpectedEnd;
else if (DataAfterEnd)
opRes = NExtract::NOperationResult::kDataAfterEnd;
else if (CrcError)
opRes = NExtract::NOperationResult::kCRCError;
else if (Unsupported)
opRes = NExtract::NOperationResult::kUnsupportedMethod;
else if (HeadersError)
opRes = NExtract::NOperationResult::kDataError;
else if (DataError)
opRes = NExtract::NOperationResult::kDataError;
else if (DecodeRes != SZ_OK)
opRes = NExtract::NOperationResult::kDataError;
else
opRes = NExtract::NOperationResult::kOK;
return opRes;
}
HRESULT CComDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream,
const UInt64 * /* inSize */, const UInt64 *outSize, ICompressProgressInfo *progress)
{
RINOK(_decoder.Decode(inStream, outStream, outSize, _finishStream, progress));
Int32 opRes = _decoder.Get_Extract_OperationResult();
if (opRes == NArchive::NExtract::NOperationResult::kUnsupportedMethod)
return E_NOTIMPL;
if (opRes != NArchive::NExtract::NOperationResult::kOK)
return S_FALSE;
return S_OK;
return Decode(inStream, outStream, outSize, _finishStream, progress);
}
STDMETHODIMP CComDecoder::SetFinishMode(UInt32 finishMode)
@@ -256,8 +127,24 @@ STDMETHODIMP CComDecoder::SetFinishMode(UInt32 finishMode)
STDMETHODIMP CComDecoder::GetInStreamProcessedSize(UInt64 *value)
{
*value = _decoder.InSize;
*value = Stat.InSize;
return S_OK;
}
#ifndef _7ZIP_ST
STDMETHODIMP CComDecoder::SetNumberOfThreads(UInt32 numThreads)
{
_numThreads = numThreads;
return S_OK;
}
STDMETHODIMP CComDecoder::SetMemLimit(UInt64 memUsage)
{
_memUsage = memUsage;
return S_OK;
}
#endif
}}

View File

@@ -12,57 +12,36 @@
namespace NCompress {
namespace NXz {
struct CXzUnpackerCPP
struct CDecoder
{
Byte *InBuf;
Byte *OutBuf;
CXzUnpacker p;
CXzDecMtHandle xz;
int _tryMt;
UInt32 _numThreads;
UInt64 _memUsage;
CXzUnpackerCPP();
~CXzUnpackerCPP();
};
SRes MainDecodeSRes; // it's not HRESULT
bool MainDecodeSRes_wasUsed;
CXzStatInfo Stat;
CDecoder():
xz(NULL),
_tryMt(True),
_numThreads(1),
_memUsage((UInt64)(sizeof(size_t)) << 28),
MainDecodeSRes(SZ_OK),
MainDecodeSRes_wasUsed(false)
{}
struct CStatInfo
{
UInt64 InSize;
UInt64 OutSize;
UInt64 PhySize;
UInt64 NumStreams;
UInt64 NumBlocks;
bool UnpackSize_Defined;
bool NumStreams_Defined;
bool NumBlocks_Defined;
bool IsArc;
bool UnexpectedEnd;
bool DataAfterEnd;
bool Unsupported;
bool HeadersError;
bool DataError;
bool CrcError;
CStatInfo() { Clear(); }
void Clear();
};
struct CDecoder: public CStatInfo
{
CXzUnpackerCPP xzu;
SRes DecodeRes; // it's not HRESULT
CDecoder(): DecodeRes(SZ_OK) {}
~CDecoder()
{
if (xz)
XzDecMt_Destroy(xz);
}
/* Decode() can return ERROR code only if there is progress or stream error.
Decode() returns S_OK in case of xz decoding error, but DecodeRes and CStatInfo contain error information */
HRESULT Decode(ISequentialInStream *seqInStream, ISequentialOutStream *outStream,
const UInt64 *outSizeLimit, bool finishStream, ICompressProgressInfo *compressProgress);
Int32 Get_Extract_OperationResult() const;
};
@@ -70,21 +49,41 @@ class CComDecoder:
public ICompressCoder,
public ICompressSetFinishMode,
public ICompressGetInStreamProcessedSize,
public CMyUnknownImp
#ifndef _7ZIP_ST
public ICompressSetCoderMt,
public ICompressSetMemLimit,
#endif
public CMyUnknownImp,
public CDecoder
{
CDecoder _decoder;
bool _finishStream;
public:
MY_UNKNOWN_IMP2(
ICompressSetFinishMode,
ICompressGetInStreamProcessedSize)
MY_QUERYINTERFACE_BEGIN2(ICompressCoder)
MY_QUERYINTERFACE_ENTRY(ICompressSetFinishMode)
MY_QUERYINTERFACE_ENTRY(ICompressGetInStreamProcessedSize)
#ifndef _7ZIP_ST
MY_QUERYINTERFACE_ENTRY(ICompressSetCoderMt)
MY_QUERYINTERFACE_ENTRY(ICompressSetMemLimit)
#endif
MY_QUERYINTERFACE_END
MY_ADDREF_RELEASE
STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream,
const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress);
STDMETHOD(SetFinishMode)(UInt32 finishMode);
STDMETHOD(GetInStreamProcessedSize)(UInt64 *value);
#ifndef _7ZIP_ST
STDMETHOD(SetNumberOfThreads)(UInt32 numThreads);
STDMETHOD(SetMemLimit)(UInt64 memUsage);
#endif
CComDecoder(): _finishStream(false) {}
};

View File

@@ -49,6 +49,7 @@
25 ICompressSetCoderMt
26 ICompressSetFinishMode
27 ICompressGetInStreamProcessedSize2
28 ICompressSetMemLimit
30 ICompressGetSubStreamSize
31 ICompressSetInStream
@@ -165,6 +166,7 @@ Handler GUIDs:
0C xz
0D ppmd
C6 COFF
C7 Ext
C8 VMDK
C9 VDI

View File

@@ -43,6 +43,7 @@ CODER_INTERFACE(ICompressCoder2, 0x18)
S_OK : OK
S_FALSE : data error (for decoders)
E_OUTOFMEMORY : memory allocation error
E_NOTIMPL : unsupported encoding method (for decoders)
another error code : some error. For example, it can be error code received from inStream or outStream function.
Parameters:
@@ -129,7 +130,8 @@ namespace NCoderPropID
kBlockSize2, // VT_UI4 or VT_UI8
kCheckSize, // VT_UI4 : size of digest in bytes
kFilter // VT_BSTR
kFilter, // VT_BSTR
kMemUse // VT_UI8
};
}
@@ -190,6 +192,12 @@ CODER_INTERFACE(ICompressGetInStreamProcessedSize2, 0x27)
STDMETHOD(GetInStreamProcessedSize2)(UInt32 streamIndex, UInt64 *value) PURE;
};
CODER_INTERFACE(ICompressSetMemLimit, 0x28)
{
STDMETHOD(SetMemLimit)(UInt64 memUsage) PURE;
};
CODER_INTERFACE(ICompressGetSubStreamSize, 0x30)
{

5
CPP/7zip/LzmaDec.mak Normal file
View File

@@ -0,0 +1,5 @@
!IF "$(CPU)" == "AMD64"
CFLAGS_C_SPEC = -D_LZMA_DEC_OPT
ASM_OBJS = $(ASM_OBJS) \
$O\LzmaDecOpt.obj
!ENDIF

View File

@@ -1183,9 +1183,11 @@ static HRESULT MethodBench(
COneMethodInfo method = method2;
UInt64 methodId;
UInt32 numStreams;
if (!FindMethod(
int codecIndex = FindMethod_Index(
EXTERNAL_CODECS_LOC_VARS
method.MethodName, methodId, numStreams))
method.MethodName, true,
methodId, numStreams);
if (codecIndex < 0)
return E_NOTIMPL;
if (numStreams != 1)
return E_INVALIDARG;
@@ -1222,7 +1224,7 @@ static HRESULT MethodBench(
{
CCreatedCoder cod;
RINOK(CreateCoder(EXTERNAL_CODECS_LOC_VARS methodId, true, encoder._encoderFilter, cod));
RINOK(CreateCoder_Index(EXTERNAL_CODECS_LOC_VARS codecIndex, true, encoder._encoderFilter, cod));
encoder._encoder = cod.Coder;
if (!encoder._encoder && !encoder._encoderFilter)
return E_NOTIMPL;
@@ -1239,7 +1241,7 @@ static HRESULT MethodBench(
{
CCreatedCoder cod;
CMyComPtr<ICompressCoder> &decoder = encoder._decoders[j];
RINOK(CreateCoder(EXTERNAL_CODECS_LOC_VARS methodId, false, encoder._decoderFilter, cod));
RINOK(CreateCoder_Id(EXTERNAL_CODECS_LOC_VARS methodId, false, encoder._decoderFilter, cod));
decoder = cod.Coder;
if (!encoder._decoderFilter && !decoder)
return E_NOTIMPL;

View File

@@ -115,10 +115,11 @@ COMPLB = $(CC) $(CFLAGS_O1) -Yu"StdAfx.h" -Fp$O/a.pch $<
# COMPLB_O2 = $(CC) $(CFLAGS_O2) -Yu"StdAfx.h" -Fp$O/a.pch $<
COMPLB_O2 = $(CC) $(CFLAGS_O2) $<
CCOMPL_PCH = $(CC) $(CFLAGS_O2) -Yc"Precomp.h" -Fp$O/a.pch $**
CCOMPL_USE = $(CC) $(CFLAGS_O2) -Yu"Precomp.h" -Fp$O/a.pch $**
CCOMPL = $(CC) $(CFLAGS_O2) $**
CCOMPLB = $(CC) $(CFLAGS_O2) $<
CFLAGS_C_ALL = $(CFLAGS_O2) $(CFLAGS_C_SPEC)
CCOMPL_PCH = $(CC) $(CFLAGS_C_ALL) -Yc"Precomp.h" -Fp$O/a.pch $**
CCOMPL_USE = $(CC) $(CFLAGS_C_ALL) -Yu"Precomp.h" -Fp$O/a.pch $**
CCOMPL = $(CC) $(CFLAGS_C_ALL) $**
CCOMPLB = $(CC) $(CFLAGS_C_ALL) $<
all: $(PROGPATH)

View File

@@ -10,8 +10,8 @@ AppName = "7-Zip"
InstallDir = %CE1%\%AppName%
[Strings]
AppVer = "18.01"
AppDate = "2018-01-28"
AppVer = "18.03"
AppDate = "2018-03-04"
[CEDevice]
; ProcessorType = 2577 ; ARM

View File

@@ -2,7 +2,7 @@
;Defines
!define VERSION_MAJOR 18
!define VERSION_MINOR 01
!define VERSION_MINOR 03
!define VERSION_POSTFIX_FULL ""
!ifdef WIN64
!ifdef IA64
@@ -220,6 +220,7 @@ Section
File ja.txt
File ka.txt
File kaa.txt
File kab.txt
File kk.txt
File ko.txt
File ku.txt
@@ -421,6 +422,7 @@ Section Uninstall
Delete $INSTDIR\Lang\ja.txt
Delete $INSTDIR\Lang\ka.txt
Delete $INSTDIR\Lang\kaa.txt
Delete $INSTDIR\Lang\kab.txt
Delete $INSTDIR\Lang\kk.txt
Delete $INSTDIR\Lang\ko.txt
Delete $INSTDIR\Lang\ku.txt

View File

@@ -1,7 +1,7 @@
<?xml version="1.0"?>
<?define VerMajor = "18" ?>
<?define VerMinor = "01" ?>
<?define VerMinor = "03" ?>
<?define VerBuild = "00" ?>
<?define MmVer = "$(var.VerMajor).$(var.VerMinor)" ?>
<?define MmHex = "$(var.VerMajor)$(var.VerMinor)" ?>
@@ -104,6 +104,8 @@
<Media Id="1" Cabinet="product.cab" EmbedCab="yes" CompressionLevel="high" />
<Property Id="MSIRMSHUTDOWN" Value="2"/>
<Property Id="INSTALLDIR">
<RegistrySearch Id="My7zipPathLM" Type="raw" Root="HKLM" Key="Software\7-Zip" Name="Path" />
<RegistrySearch Id="My7zipPathLM2" Type="raw" Root="HKLM" Key="Software\7-Zip" Name="Path$(var.NumBits)" />
@@ -294,6 +296,7 @@
<File Id="ja.txt" Name="ja.txt" />
<File Id="ka.txt" Name="ka.txt" />
<File Id="kaa.txt" Name="kaa.txt" />
<File Id="kab.txt" Name="kab.txt" />
<File Id="kk.txt" Name="kk.txt" />
<File Id="ko.txt" Name="ko.txt" />
<File Id="ku.txt" Name="ku.txt" />

View File

@@ -1,4 +1,4 @@
7-Zip 18.01 Sources
7-Zip 18.03 Sources
-------------------
7-Zip is a file archiver for Windows.

View File

@@ -1,6 +1,17 @@
HISTORY of the 7-Zip source code
--------------------------------
18.03 beta 2018-03-04
-------------------------
- Asm\x86\LzmaDecOpt.asm: new optimized LZMA decoder written in asm
for x64 with about 30% higher speed than main version of LZMA decoder written in C.
- The speed for single-thread LZMA/LZMA2 decoder written in C was increased by 3%.
- 7-Zip now can use multi-threading for 7z/LZMA2 decoding,
if there are multiple independent data chunks in LZMA2 stream.
- 7-Zip now can use multi-threading for xz decoding,
if there are multiple blocks in xz stream.
17.00 beta 2017-04-29
-------------------------
- NewHandler.h / NewHandler.cpp: