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 ; 7zAsm.asm -- ASM macros
; 2012-12-30 : Igor Pavlov : Public domain ; 2018-02-03 : Igor Pavlov : Public domain
MY_ASM_START macro MY_ASM_START macro
ifdef x64 ifdef x64
@@ -52,6 +52,15 @@ endif
x6 equ ESI x6 equ ESI
x7 equ EDI 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 x0_L equ AL
x1_L equ CL x1_L equ CL
x2_L equ DL x2_L equ DL
@@ -63,6 +72,10 @@ endif
x3_H equ BH x3_H equ BH
ifdef x64 ifdef x64
x5_L equ BPL
x6_L equ SIL
x7_L equ DIL
r0 equ RAX r0 equ RAX
r1 equ RCX r1 equ RCX
r2 equ RDX r2 equ RDX
@@ -103,3 +116,32 @@ MY_POP_4_REGS macro
pop r5 pop r5
pop r3 pop r3
endm 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_MAJOR 18
#define MY_VER_MINOR 01 #define MY_VER_MINOR 03
#define MY_VER_BUILD 0 #define MY_VER_BUILD 0
#define MY_VERSION_NUMBERS "18.01" #define MY_VERSION_NUMBERS "18.03 beta"
#define MY_VERSION MY_VERSION_NUMBERS #define MY_VERSION MY_VERSION_NUMBERS
#ifdef MY_CPU_NAME #ifdef MY_CPU_NAME
@@ -10,7 +10,7 @@
#define MY_VERSION_CPU MY_VERSION #define MY_VERSION_CPU MY_VERSION
#endif #endif
#define MY_DATE "2018-01-28" #define MY_DATE "2018-03-04"
#undef MY_COPYRIGHT #undef MY_COPYRIGHT
#undef MY_VERSION_COPYRIGHT_DATE #undef MY_VERSION_COPYRIGHT_DATE
#define MY_AUTHOR_NAME "Igor Pavlov" #define MY_AUTHOR_NAME "Igor Pavlov"

354
C/Alloc.c
View File

@@ -1,8 +1,10 @@
/* Alloc.c -- Memory allocation functions /* Alloc.c -- Memory allocation functions
2017-06-15 : Igor Pavlov : Public domain */ 2018-03-01 : Igor Pavlov : Public domain */
#include "Precomp.h" #include "Precomp.h"
#include <stdio.h>
#ifdef _WIN32 #ifdef _WIN32
#include <windows.h> #include <windows.h>
#endif #endif
@@ -14,12 +16,119 @@
/* use _SZ_ALLOC_DEBUG to debug alloc/free operations */ /* use _SZ_ALLOC_DEBUG to debug alloc/free operations */
#ifdef _SZ_ALLOC_DEBUG #ifdef _SZ_ALLOC_DEBUG
#include <stdio.h> #include <stdio.h>
int g_allocCount = 0; int g_allocCount = 0;
int g_allocCountMid = 0; int g_allocCountMid = 0;
int g_allocCountBig = 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 #endif
void *MyAlloc(size_t size) void *MyAlloc(size_t size)
{ {
if (size == 0) if (size == 0)
@@ -27,7 +136,7 @@ void *MyAlloc(size_t size)
#ifdef _SZ_ALLOC_DEBUG #ifdef _SZ_ALLOC_DEBUG
{ {
void *p = malloc(size); 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; return p;
} }
#else #else
@@ -37,10 +146,8 @@ void *MyAlloc(size_t size)
void MyFree(void *address) void MyFree(void *address)
{ {
#ifdef _SZ_ALLOC_DEBUG PRINT_FREE("Free ", g_allocCount, address);
if (address)
fprintf(stderr, "\nFree; count = %10d, addr = %8X", --g_allocCount, (unsigned)address);
#endif
free(address); free(address);
} }
@@ -50,18 +157,16 @@ void *MidAlloc(size_t size)
{ {
if (size == 0) if (size == 0)
return NULL; return NULL;
#ifdef _SZ_ALLOC_DEBUG
fprintf(stderr, "\nAlloc_Mid %10d bytes; count = %10d", size, g_allocCountMid++); PRINT_ALLOC("Alloc-Mid", g_allocCountMid, size, NULL);
#endif
return VirtualAlloc(NULL, size, MEM_COMMIT, PAGE_READWRITE); return VirtualAlloc(NULL, size, MEM_COMMIT, PAGE_READWRITE);
} }
void MidFree(void *address) void MidFree(void *address)
{ {
#ifdef _SZ_ALLOC_DEBUG PRINT_FREE("Free-Mid", g_allocCountMid, address);
if (address)
fprintf(stderr, "\nFree_Mid; count = %10d", --g_allocCountMid);
#endif
if (!address) if (!address)
return; return;
VirtualFree(address, 0, MEM_RELEASE); VirtualFree(address, 0, MEM_RELEASE);
@@ -96,9 +201,8 @@ void *BigAlloc(size_t size)
{ {
if (size == 0) if (size == 0)
return NULL; return NULL;
#ifdef _SZ_ALLOC_DEBUG
fprintf(stderr, "\nAlloc_Big %10u bytes; count = %10d", size, g_allocCountBig++); PRINT_ALLOC("Alloc-Big", g_allocCountBig, size, NULL);
#endif
#ifdef _7ZIP_LARGE_PAGES #ifdef _7ZIP_LARGE_PAGES
{ {
@@ -123,10 +227,7 @@ void *BigAlloc(size_t size)
void BigFree(void *address) void BigFree(void *address)
{ {
#ifdef _SZ_ALLOC_DEBUG PRINT_FREE("Free-Big", g_allocCountBig, address);
if (address)
fprintf(stderr, "\nFree_Big; count = %10d", --g_allocCountBig);
#endif
if (!address) if (!address)
return; 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 *SzAlloc(ISzAllocPtr p, size_t size) { UNUSED_VAR(p); return MyAlloc(size); }
static void SzFree(ISzAllocPtr p, void *address) { UNUSED_VAR(p); MyFree(address); } 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 *SzBigAlloc(ISzAllocPtr p, size_t size) { UNUSED_VAR(p); return BigAlloc(size); }
static void SzBigFree(ISzAllocPtr p, void *address) { UNUSED_VAR(p); BigFree(address); } 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 /* Alloc.h -- Memory allocation functions
2017-04-03 : Igor Pavlov : Public domain */ 2018-02-19 : Igor Pavlov : Public domain */
#ifndef __COMMON_ALLOC_H #ifndef __COMMON_ALLOC_H
#define __COMMON_ALLOC_H #define __COMMON_ALLOC_H
@@ -31,6 +31,20 @@ void BigFree(void *address);
extern const ISzAlloc g_Alloc; extern const ISzAlloc g_Alloc;
extern const ISzAlloc g_BigAlloc; 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 EXTERN_C_END

View File

@@ -1,5 +1,5 @@
/* CpuArch.h -- CPU specific code /* CpuArch.h -- CPU specific code
2017-06-30 : Igor Pavlov : Public domain */ 2017-09-04 : Igor Pavlov : Public domain */
#ifndef __CPU_ARCH_H #ifndef __CPU_ARCH_H
#define __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 #ifndef MY_CPU_NAME
#ifdef MY_CPU_LE #ifdef MY_CPU_LE
#define MY_CPU_NAME "LE" #define MY_CPU_NAME "LE"
#elif MY_CPU_BE #elif defined(MY_CPU_BE)
#define MY_CPU_NAME "BE" #define MY_CPU_NAME "BE"
#else #else
/* /*

View File

@@ -1,5 +1,5 @@
/* Lzma2Dec.c -- LZMA2 Decoder /* Lzma2Dec.c -- LZMA2 Decoder
2017-04-03 : Igor Pavlov : Public domain */ 2018-02-19 : Igor Pavlov : Public domain */
/* #define SHOW_DEBUG_INFO */ /* #define SHOW_DEBUG_INFO */
@@ -14,28 +14,22 @@
#include "Lzma2Dec.h" #include "Lzma2Dec.h"
/* /*
00000000 - EOS 00000000 - End of data
00000001 U U - Uncompressed Reset Dic 00000001 U U - Uncompressed, reset dic, need reset state and set new prop
00000010 U U - Uncompressed No Reset 00000010 U U - Uncompressed, no reset
100uuuuu U U P P - LZMA no reset 100uuuuu U U P P - LZMA, no reset
101uuuuu U U P P - LZMA reset state 101uuuuu U U P P - LZMA, reset state
110uuuuu U U P P S - LZMA reset state + new prop 110uuuuu U U P P S - LZMA, reset state + set new prop
111uuuuu U U P P S - LZMA reset state + new prop + reset dic 111uuuuu U U P P S - LZMA, reset state + set new prop, reset dic
u, U - Unpack Size u, U - Unpack Size
P - Pack Size P - Pack Size
S - Props 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_COPY_RESET_DIC 1
#define LZMA2_CONTROL_EOF 0
#define LZMA2_IS_UNCOMPRESSED_STATE(p) (((p)->control & LZMA2_CONTROL_LZMA) == 0) #define LZMA2_IS_UNCOMPRESSED_STATE(p) (((p)->control & (1 << 7)) == 0)
#define LZMA2_GET_LZMA_MODE(p) (((p)->control >> 5) & 3)
#define LZMA2_IS_THERE_PROP(mode) ((mode) >= 2)
#define LZMA2_LCLP_MAX 4 #define LZMA2_LCLP_MAX 4
#define LZMA2_DIC_SIZE_FROM_PROP(p) (((UInt32)2 | ((p) & 1)) << ((p) / 2 + 11)) #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) void Lzma2Dec_Init(CLzma2Dec *p)
{ {
p->state = LZMA2_STATE_CONTROL; p->state = LZMA2_STATE_CONTROL;
p->needInitDic = True; p->needInitLevel = 0xE0;
p->needInitState = True; p->isExtraMode = False;
p->needInitProp = True; p->unpackSize = 0;
// p->decoder.dicPos = 0; // we can use it instead of full init
LzmaDec_Init(&p->decoder); LzmaDec_Init(&p->decoder);
} }
@@ -102,19 +98,26 @@ static ELzma2State Lzma2Dec_UpdateState(CLzma2Dec *p, Byte b)
switch (p->state) switch (p->state)
{ {
case LZMA2_STATE_CONTROL: case LZMA2_STATE_CONTROL:
p->isExtraMode = False;
p->control = b; p->control = b;
PRF(printf("\n %4X ", (unsigned)p->decoder.dicPos)); PRF(printf("\n %8X", (unsigned)p->decoder.dicPos));
PRF(printf(" %2X", (unsigned)b)); PRF(printf(" %02X", (unsigned)b));
if (b == 0) if (b == 0)
return LZMA2_STATE_FINISHED; return LZMA2_STATE_FINISHED;
if (LZMA2_IS_UNCOMPRESSED_STATE(p)) 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; return LZMA2_STATE_ERROR;
p->unpackSize = 0;
} }
else else
{
if (b < p->needInitLevel)
return LZMA2_STATE_ERROR;
p->needInitLevel = 0;
p->unpackSize = (UInt32)(b & 0x1F) << 16; p->unpackSize = (UInt32)(b & 0x1F) << 16;
}
return LZMA2_STATE_UNPACK0; return LZMA2_STATE_UNPACK0;
case LZMA2_STATE_UNPACK0: case LZMA2_STATE_UNPACK0:
@@ -124,8 +127,8 @@ static ELzma2State Lzma2Dec_UpdateState(CLzma2Dec *p, Byte b)
case LZMA2_STATE_UNPACK1: case LZMA2_STATE_UNPACK1:
p->unpackSize |= (UInt32)b; p->unpackSize |= (UInt32)b;
p->unpackSize++; p->unpackSize++;
PRF(printf(" %8u", (unsigned)p->unpackSize)); PRF(printf(" %7u", (unsigned)p->unpackSize));
return (LZMA2_IS_UNCOMPRESSED_STATE(p)) ? LZMA2_STATE_DATA : LZMA2_STATE_PACK0; return LZMA2_IS_UNCOMPRESSED_STATE(p) ? LZMA2_STATE_DATA : LZMA2_STATE_PACK0;
case LZMA2_STATE_PACK0: case LZMA2_STATE_PACK0:
p->packSize = (UInt32)b << 8; p->packSize = (UInt32)b << 8;
@@ -134,9 +137,9 @@ static ELzma2State Lzma2Dec_UpdateState(CLzma2Dec *p, Byte b)
case LZMA2_STATE_PACK1: case LZMA2_STATE_PACK1:
p->packSize |= (UInt32)b; p->packSize |= (UInt32)b;
p->packSize++; p->packSize++;
PRF(printf(" %8u", (unsigned)p->packSize)); // if (p->packSize < 5) return LZMA2_STATE_ERROR;
return LZMA2_IS_THERE_PROP(LZMA2_GET_LZMA_MODE(p)) ? LZMA2_STATE_PROP: PRF(printf(" %5u", (unsigned)p->packSize));
(p->needInitProp ? LZMA2_STATE_ERROR : LZMA2_STATE_DATA); return (p->control & 0x40) ? LZMA2_STATE_PROP : LZMA2_STATE_DATA;
case LZMA2_STATE_PROP: case LZMA2_STATE_PROP:
{ {
@@ -145,13 +148,12 @@ static ELzma2State Lzma2Dec_UpdateState(CLzma2Dec *p, Byte b)
return LZMA2_STATE_ERROR; return LZMA2_STATE_ERROR;
lc = b % 9; lc = b % 9;
b /= 9; b /= 9;
p->decoder.prop.pb = b / 5; p->decoder.prop.pb = (Byte)(b / 5);
lp = b % 5; lp = b % 5;
if (lc + lp > LZMA2_LCLP_MAX) if (lc + lp > LZMA2_LCLP_MAX)
return LZMA2_STATE_ERROR; return LZMA2_STATE_ERROR;
p->decoder.prop.lc = lc; p->decoder.prop.lc = (Byte)lc;
p->decoder.prop.lp = lp; p->decoder.prop.lp = (Byte)lp;
p->needInitProp = False;
return LZMA2_STATE_DATA; return LZMA2_STATE_DATA;
} }
} }
@@ -231,11 +233,6 @@ SRes Lzma2Dec_DecodeToDic(CLzma2Dec *p, SizeT dicLimit,
if (p->state == LZMA2_STATE_DATA) if (p->state == LZMA2_STATE_DATA)
{ {
Bool initDic = (p->control == LZMA2_CONTROL_COPY_RESET_DIC); 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); LzmaDec_InitDicAndState(&p->decoder, initDic, False);
} }
@@ -257,23 +254,17 @@ SRes Lzma2Dec_DecodeToDic(CLzma2Dec *p, SizeT dicLimit,
if (p->state == LZMA2_STATE_DATA) if (p->state == LZMA2_STATE_DATA)
{ {
unsigned mode = LZMA2_GET_LZMA_MODE(p); Bool initDic = (p->control >= 0xE0);
Bool initDic = (mode == 3); Bool initState = (p->control >= 0xA0);
Bool initState = (mode != 0);
if ((!initDic && p->needInitDic) || (!initState && p->needInitState))
break;
LzmaDec_InitDicAndState(&p->decoder, initDic, initState); LzmaDec_InitDicAndState(&p->decoder, initDic, initState);
p->needInitDic = False;
p->needInitState = False;
p->state = LZMA2_STATE_DATA_CONT; p->state = LZMA2_STATE_DATA_CONT;
} }
if (inCur > p->packSize) if (inCur > p->packSize)
inCur = (SizeT)p->packSize; inCur = (SizeT)p->packSize;
res = LzmaDec_DecodeToDic(&p->decoder, dicPos + outCur, src, &inCur, curFinishMode, status);
res = LzmaDec_DecodeToDic(&p->decoder, dicPos + outCur, src, &inCur, curFinishMode, status);
src += inCur; src += inCur;
*srcLen += inCur; *srcLen += inCur;
p->packSize -= (UInt32)inCur; p->packSize -= (UInt32)inCur;
@@ -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) SRes Lzma2Dec_DecodeToBuf(CLzma2Dec *p, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status)
{ {
SizeT outSize = *destLen, inSize = *srcLen; SizeT outSize = *destLen, inSize = *srcLen;

View File

@@ -1,5 +1,5 @@
/* Lzma2Dec.h -- LZMA2 Decoder /* Lzma2Dec.h -- LZMA2 Decoder
2017-04-03 : Igor Pavlov : Public domain */ 2018-02-19 : Igor Pavlov : Public domain */
#ifndef __LZMA2_DEC_H #ifndef __LZMA2_DEC_H
#define __LZMA2_DEC_H #define __LZMA2_DEC_H
@@ -12,25 +12,24 @@ EXTERN_C_BEGIN
typedef struct typedef struct
{ {
CLzmaDec decoder;
UInt32 packSize;
UInt32 unpackSize;
unsigned state; unsigned state;
Byte control; Byte control;
Bool needInitDic; Byte needInitLevel;
Bool needInitState; Byte isExtraMode;
Bool needInitProp; Byte _pad_;
UInt32 packSize;
UInt32 unpackSize;
CLzmaDec decoder;
} CLzma2Dec; } CLzma2Dec;
#define Lzma2Dec_Construct(p) LzmaDec_Construct(&(p)->decoder) #define Lzma2Dec_Construct(p) LzmaDec_Construct(&(p)->decoder)
#define Lzma2Dec_FreeProbs(p, alloc) LzmaDec_FreeProbs(&(p)->decoder, alloc); #define Lzma2Dec_FreeProbs(p, alloc) LzmaDec_FreeProbs(&(p)->decoder, alloc)
#define Lzma2Dec_Free(p, alloc) LzmaDec_Free(&(p)->decoder, alloc); #define Lzma2Dec_Free(p, alloc) LzmaDec_Free(&(p)->decoder, alloc)
SRes Lzma2Dec_AllocateProbs(CLzma2Dec *p, Byte prop, ISzAllocPtr alloc); SRes Lzma2Dec_AllocateProbs(CLzma2Dec *p, Byte prop, ISzAllocPtr alloc);
SRes Lzma2Dec_Allocate(CLzma2Dec *p, Byte prop, ISzAllocPtr alloc); SRes Lzma2Dec_Allocate(CLzma2Dec *p, Byte prop, ISzAllocPtr alloc);
void Lzma2Dec_Init(CLzma2Dec *p); void Lzma2Dec_Init(CLzma2Dec *p);
/* /*
finishMode: finishMode:
It has meaning only if the decoding reaches output limit (*destLen or dicLimit). 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); 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 ---------- */ /* ---------- 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 /* Lzma2Enc.c -- LZMA2 Encoder
2017-08-28 : Igor Pavlov : Public domain */ 2018-02-08 : Igor Pavlov : Public domain */
#include "Precomp.h" #include "Precomp.h"
@@ -666,7 +666,7 @@ static SRes Lzma2Enc_MtCallback_Code(void *pp, unsigned coderIndex, unsigned out
if (!dest) if (!dest)
{ {
dest = ISzAlloc_Alloc(me->alloc, me->outBufSize); dest = (Byte *)ISzAlloc_Alloc(me->alloc, me->outBufSize);
if (!dest) if (!dest)
return SZ_ERROR_MEM; return SZ_ERROR_MEM;
me->outBufs[outBufIndex] = dest; me->outBufs[outBufIndex] = dest;
@@ -674,7 +674,8 @@ static SRes Lzma2Enc_MtCallback_Code(void *pp, unsigned coderIndex, unsigned out
MtProgressThunk_CreateVTable(&progressThunk); MtProgressThunk_CreateVTable(&progressThunk);
progressThunk.mtProgress = &me->mtCoder.mtProgress; progressThunk.mtProgress = &me->mtCoder.mtProgress;
progressThunk.index = coderIndex; progressThunk.inSize = 0;
progressThunk.outSize = 0;
res = Lzma2Enc_EncodeMt1(me, res = Lzma2Enc_EncodeMt1(me,
&me->coders[coderIndex], &me->coders[coderIndex],
@@ -720,10 +721,10 @@ SRes Lzma2Enc_Encode2(CLzma2EncHandle pp,
CLzma2Enc *p = (CLzma2Enc *)pp; CLzma2Enc *p = (CLzma2Enc *)pp;
if (inStream && inData) if (inStream && inData)
return E_INVALIDARG; return SZ_ERROR_PARAM;
if (outStream && outBuf) if (outStream && outBuf)
return E_INVALIDARG; return SZ_ERROR_PARAM;
{ {
unsigned i; unsigned i;

View File

@@ -1,8 +1,9 @@
/* LzmaDec.c -- LZMA Decoder /* LzmaDec.c -- LZMA Decoder
2017-04-03 : Igor Pavlov : Public domain */ 2018-02-28 : Igor Pavlov : Public domain */
#include "Precomp.h" #include "Precomp.h"
/* #include "CpuArch.h" */
#include "LzmaDec.h" #include "LzmaDec.h"
#include <string.h> #include <string.h>
@@ -24,9 +25,16 @@
#define GET_BIT2(p, i, A0, A1) IF_BIT_0(p) \ #define GET_BIT2(p, i, A0, A1) IF_BIT_0(p) \
{ UPDATE_0(p); i = (i + i); A0; } else \ { UPDATE_0(p); i = (i + i); A0; } else \
{ UPDATE_1(p); i = (i + i) + 1; A1; } { 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) \ #define TREE_DECODE(probs, limit, i) \
{ i = 1; do { TREE_GET_BIT(probs, i); } while (i < limit); i -= limit; } { i = 1; do { TREE_GET_BIT(probs, i); } while (i < limit); i -= limit; }
@@ -46,12 +54,15 @@
i -= 0x40; } i -= 0x40; }
#endif #endif
#define NORMAL_LITER_DEC GET_BIT(prob + symbol, symbol) #define NORMAL_LITER_DEC TREE_GET_BIT(prob, symbol)
#define MATCHED_LITER_DEC \ #define MATCHED_LITER_DEC \
matchByte <<= 1; \ matchByte += matchByte; \
bit = (matchByte & offs); \ bit = offs; \
probLit = prob + offs + bit + symbol; \ offs &= matchByte; \
GET_BIT2(probLit, symbol, offs &= ~bit, offs &= bit) 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++); } #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; } { 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 kNumPosBitsMax 4
#define kNumPosStatesMax (1 << kNumPosBitsMax) #define kNumPosStatesMax (1 << kNumPosBitsMax)
#define kLenNumLowBits 3 #define kLenNumLowBits 3
#define kLenNumLowSymbols (1 << kLenNumLowBits) #define kLenNumLowSymbols (1 << kLenNumLowBits)
#define kLenNumMidBits 3
#define kLenNumMidSymbols (1 << kLenNumMidBits)
#define kLenNumHighBits 8 #define kLenNumHighBits 8
#define kLenNumHighSymbols (1 << kLenNumHighBits) #define kLenNumHighSymbols (1 << kLenNumHighBits)
#define LenChoice 0 #define LenLow 0
#define LenChoice2 (LenChoice + 1) #define LenHigh (LenLow + 2 * (kNumPosStatesMax << kLenNumLowBits))
#define LenLow (LenChoice2 + 1)
#define LenMid (LenLow + (kNumPosStatesMax << kLenNumLowBits))
#define LenHigh (LenMid + (kNumPosStatesMax << kLenNumMidBits))
#define kNumLenProbs (LenHigh + kLenNumHighSymbols) #define kNumLenProbs (LenHigh + kLenNumHighSymbols)
#define LenChoice LenLow
#define LenChoice2 (LenLow + (1 << kLenNumLowBits))
#define kNumStates 12 #define kNumStates 12
#define kNumStates2 16
#define kNumLitStates 7 #define kNumLitStates 7
#define kStartPosModelIndex 4 #define kStartPosModelIndex 4
@@ -98,54 +112,117 @@
#define kAlignTableSize (1 << kNumAlignBits) #define kAlignTableSize (1 << kNumAlignBits)
#define kMatchMinLen 2 #define kMatchMinLen 2
#define kMatchSpecLenStart (kMatchMinLen + kLenNumLowSymbols + kLenNumMidSymbols + kLenNumHighSymbols) #define kMatchSpecLenStart (kMatchMinLen + kLenNumLowSymbols * 2 + kLenNumHighSymbols)
#define IsMatch 0 /* External ASM code needs same CLzmaProb array layout. So don't change it. */
#define IsRep (IsMatch + (kNumStates << kNumPosBitsMax))
/* (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 IsRepG0 (IsRep + kNumStates)
#define IsRepG1 (IsRepG0 + kNumStates) #define IsRepG1 (IsRepG0 + kNumStates)
#define IsRepG2 (IsRepG1 + kNumStates) #define IsRepG2 (IsRepG1 + kNumStates)
#define IsRep0Long (IsRepG2 + kNumStates) #define PosSlot (IsRepG2 + kNumStates)
#define PosSlot (IsRep0Long + (kNumStates << kNumPosBitsMax)) #define Literal (PosSlot + (kNumLenToPosStates << kNumPosSlotBits))
#define SpecPos (PosSlot + (kNumLenToPosStates << kNumPosSlotBits)) #define NUM_BASE_PROBS (Literal + kStartOffset)
#define Align (SpecPos + kNumFullDistances - kEndPosModelIndex)
#define LenCoder (Align + kAlignTableSize)
#define RepLenCoder (LenCoder + kNumLenProbs)
#define Literal (RepLenCoder + kNumLenProbs)
#define LZMA_BASE_SIZE 1846 #if Align != 0 && kStartOffset != 0
#define LZMA_LIT_SIZE 0x300 #error Stop_Compiling_Bad_LZMA_kAlign
#if Literal != LZMA_BASE_SIZE
StopCompilingDueBUG
#endif #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) #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: Out:
RangeCoder is normalized
Result: Result:
SZ_OK - OK SZ_OK - OK
SZ_ERROR_DATA - Error SZ_ERROR_DATA - Error
p->remainLen: p->remainLen:
< kMatchSpecLenStart : normal remain < kMatchSpecLenStart : normal remain
= kMatchSpecLenStart : finished = 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]; 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 pbMask = ((unsigned)1 << (p->prop.pb)) - 1;
unsigned lpMask = ((unsigned)1 << (p->prop.lp)) - 1;
unsigned lc = p->prop.lc; unsigned lc = p->prop.lc;
unsigned lpMask = ((unsigned)0x100 << p->prop.lp) - ((unsigned)0x100 >> lc);
Byte *dic = p->dic; Byte *dic = p->dic;
SizeT dicBufSize = p->dicBufSize; SizeT dicBufSize = p->dicBufSize;
@@ -164,17 +241,16 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte
CLzmaProb *prob; CLzmaProb *prob;
UInt32 bound; UInt32 bound;
unsigned ttt; 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) IF_BIT_0(prob)
{ {
unsigned symbol; unsigned symbol;
UPDATE_0(prob); UPDATE_0(prob);
prob = probs + Literal; prob = probs + Literal;
if (processedPos != 0 || checkDicSize != 0) if (processedPos != 0 || checkDicSize != 0)
prob += ((UInt32)LZMA_LIT_SIZE * (((processedPos & lpMask) << lc) + prob += (UInt32)3 * ((((processedPos << 8) + dic[(dicPos == 0 ? dicBufSize : dicPos) - 1]) & lpMask) << lc);
(dic[(dicPos == 0 ? dicBufSize : dicPos) - 1] >> (8 - lc))));
processedPos++; processedPos++;
if (state < kNumLitStates) if (state < kNumLitStates)
@@ -240,13 +316,16 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte
else else
{ {
UPDATE_1(prob); UPDATE_1(prob);
/*
// that case was checked before with kBadRepCode
if (checkDicSize == 0 && processedPos == 0) if (checkDicSize == 0 && processedPos == 0)
return SZ_ERROR_DATA; return SZ_ERROR_DATA;
*/
prob = probs + IsRepG0 + state; prob = probs + IsRepG0 + state;
IF_BIT_0(prob) IF_BIT_0(prob)
{ {
UPDATE_0(prob); UPDATE_0(prob);
prob = probs + IsRep0Long + (state << kNumPosBitsMax) + posState; prob = probs + IsRep0Long + COMBINED_PS_STATE;
IF_BIT_0(prob) IF_BIT_0(prob)
{ {
UPDATE_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) IF_BIT_0(probLen)
{ {
UPDATE_0(probLen); UPDATE_0(probLen);
probLen = prob + LenLow + (posState << kLenNumLowBits); probLen = prob + LenLow + GET_LEN_STATE;
offset = 0; offset = 0;
lim = (1 << kLenNumLowBits); lim = (1 << kLenNumLowBits);
} }
@@ -310,15 +389,15 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte
IF_BIT_0(probLen) IF_BIT_0(probLen)
{ {
UPDATE_0(probLen); UPDATE_0(probLen);
probLen = prob + LenMid + (posState << kLenNumMidBits); probLen = prob + LenLow + GET_LEN_STATE + (1 << kLenNumLowBits);
offset = kLenNumLowSymbols; offset = kLenNumLowSymbols;
lim = (1 << kLenNumMidBits); lim = (1 << kLenNumLowBits);
} }
else else
{ {
UPDATE_1(probLen); UPDATE_1(probLen);
probLen = prob + LenHigh; probLen = prob + LenHigh;
offset = kLenNumLowSymbols + kLenNumMidSymbols; offset = kLenNumLowSymbols * 2;
lim = (1 << kLenNumHighBits); lim = (1 << kLenNumHighBits);
} }
} }
@@ -331,7 +410,7 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte
IF_BIT_0(probLen) IF_BIT_0(probLen)
{ {
UPDATE_0(probLen); UPDATE_0(probLen);
probLen = prob + LenLow + (posState << kLenNumLowBits); probLen = prob + LenLow + GET_LEN_STATE;
len = 1; len = 1;
TREE_GET_BIT(probLen, len); TREE_GET_BIT(probLen, len);
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) IF_BIT_0(probLen)
{ {
UPDATE_0(probLen); UPDATE_0(probLen);
probLen = prob + LenMid + (posState << kLenNumMidBits); probLen = prob + LenLow + GET_LEN_STATE + (1 << kLenNumLowBits);
len = 1; len = 1;
TREE_GET_BIT(probLen, len); TREE_GET_BIT(probLen, len);
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); UPDATE_1(probLen);
probLen = prob + LenHigh; probLen = prob + LenHigh;
TREE_DECODE(probLen, (1 << kLenNumHighBits), len); 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) if (posSlot < kEndPosModelIndex)
{ {
distance <<= numDirectBits; distance <<= numDirectBits;
prob = probs + SpecPos + distance - posSlot - 1; prob = probs + SpecPos;
{ {
UInt32 mask = 1; UInt32 m = 1;
unsigned i = 1; distance++;
do do
{ {
GET_BIT2(prob + i, i, ; , distance |= mask); REV_BIT_VAR(prob, distance, m);
mask <<= 1;
} }
while (--numDirectBits != 0); while (--numDirectBits);
distance -= m;
} }
} }
else 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; prob = probs + Align;
distance <<= kNumAlignBits; distance <<= kNumAlignBits;
{ {
unsigned i = 1; unsigned i = 1;
GET_BIT2(prob + i, i, ; , distance |= 1); REV_BIT_CONST(prob, i, 1);
GET_BIT2(prob + i, i, ; , distance |= 2); REV_BIT_CONST(prob, i, 2);
GET_BIT2(prob + i, i, ; , distance |= 4); REV_BIT_CONST(prob, i, 4);
GET_BIT2(prob + i, i, ; , distance |= 8); REV_BIT_LAST (prob, i, 8);
distance |= i;
} }
if (distance == (UInt32)0xFFFFFFFF) if (distance == (UInt32)0xFFFFFFFF)
{ {
len += kMatchSpecLenStart; len = kMatchSpecLenStart;
state -= kNumStates; state -= kNumStates;
break; break;
} }
@@ -435,20 +515,12 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte
rep2 = rep1; rep2 = rep1;
rep1 = rep0; rep1 = rep0;
rep0 = distance + 1; rep0 = distance + 1;
if (checkDicSize == 0) state = (state < kNumStates + kNumLitStates) ? kNumLitStates : kNumLitStates + 3;
{ if (distance >= (checkDicSize == 0 ? processedPos: checkDicSize))
if (distance >= processedPos)
{
p->dicPos = dicPos;
return SZ_ERROR_DATA;
}
}
else if (distance >= checkDicSize)
{ {
p->dicPos = dicPos; p->dicPos = dicPos;
return SZ_ERROR_DATA; return SZ_ERROR_DATA;
} }
state = (state < kNumStates + kNumLitStates) ? kNumLitStates : kNumLitStates + 3;
} }
len += kMatchMinLen; len += kMatchMinLen;
@@ -511,6 +583,7 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte
return SZ_OK; return SZ_OK;
} }
#endif
static void MY_FAST_CALL LzmaDec_WriteRem(CLzmaDec *p, SizeT limit) 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; Byte *dic = p->dic;
SizeT dicPos = p->dicPos; SizeT dicPos = p->dicPos;
SizeT dicBufSize = p->dicBufSize; 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 rep0 = p->reps[0]; /* we use SizeT to avoid the BUG of VC14 for AMD64 */
SizeT rem = limit - dicPos; SizeT rem = limit - dicPos;
if (rem < len) 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) static int MY_FAST_CALL LzmaDec_DecodeReal2(CLzmaDec *p, SizeT limit, const Byte *bufLimit)
{ {
do 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; UInt32 rem = p->prop.dicSize - p->processedPos;
if (limit - p->dicPos > rem) if (limit - p->dicPos > rem)
limit2 = 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) if (p->checkDicSize == 0 && p->processedPos >= p->prop.dicSize)
p->checkDicSize = 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); while (p->dicPos < limit && p->buf < bufLimit && p->remainLen < kMatchSpecLenStart);
if (p->remainLen > kMatchSpecLenStart)
p->remainLen = kMatchSpecLenStart;
return 0; return 0;
} }
@@ -580,17 +662,17 @@ static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inS
UInt32 range = p->range; UInt32 range = p->range;
UInt32 code = p->code; UInt32 code = p->code;
const Byte *bufLimit = buf + inSize; const Byte *bufLimit = buf + inSize;
const CLzmaProb *probs = p->probs; const CLzmaProb *probs = GET_PROBS;
unsigned state = p->state; unsigned state = (unsigned)p->state;
ELzmaDummy res; ELzmaDummy res;
{ {
const CLzmaProb *prob; const CLzmaProb *prob;
UInt32 bound; UInt32 bound;
unsigned ttt; 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) IF_BIT_0_CHECK(prob)
{ {
UPDATE_0_CHECK UPDATE_0_CHECK
@@ -618,10 +700,11 @@ static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inS
{ {
unsigned bit; unsigned bit;
const CLzmaProb *probLit; const CLzmaProb *probLit;
matchByte <<= 1; matchByte += matchByte;
bit = (matchByte & offs); bit = offs;
probLit = prob + offs + bit + symbol; offs &= matchByte;
GET_BIT2_CHECK(probLit, symbol, offs &= ~bit, offs &= bit) probLit = prob + (offs + bit + symbol);
GET_BIT2_CHECK(probLit, symbol, offs ^= bit; , ; )
} }
while (symbol < 0x100); while (symbol < 0x100);
} }
@@ -648,7 +731,7 @@ static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inS
IF_BIT_0_CHECK(prob) IF_BIT_0_CHECK(prob)
{ {
UPDATE_0_CHECK; UPDATE_0_CHECK;
prob = probs + IsRep0Long + (state << kNumPosBitsMax) + posState; prob = probs + IsRep0Long + COMBINED_PS_STATE;
IF_BIT_0_CHECK(prob) IF_BIT_0_CHECK(prob)
{ {
UPDATE_0_CHECK; UPDATE_0_CHECK;
@@ -691,7 +774,7 @@ static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inS
IF_BIT_0_CHECK(probLen) IF_BIT_0_CHECK(probLen)
{ {
UPDATE_0_CHECK; UPDATE_0_CHECK;
probLen = prob + LenLow + (posState << kLenNumLowBits); probLen = prob + LenLow + GET_LEN_STATE;
offset = 0; offset = 0;
limit = 1 << kLenNumLowBits; limit = 1 << kLenNumLowBits;
} }
@@ -702,15 +785,15 @@ static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inS
IF_BIT_0_CHECK(probLen) IF_BIT_0_CHECK(probLen)
{ {
UPDATE_0_CHECK; UPDATE_0_CHECK;
probLen = prob + LenMid + (posState << kLenNumMidBits); probLen = prob + LenLow + GET_LEN_STATE + (1 << kLenNumLowBits);
offset = kLenNumLowSymbols; offset = kLenNumLowSymbols;
limit = 1 << kLenNumMidBits; limit = 1 << kLenNumLowBits;
} }
else else
{ {
UPDATE_1_CHECK; UPDATE_1_CHECK;
probLen = prob + LenHigh; probLen = prob + LenHigh;
offset = kLenNumLowSymbols + kLenNumMidSymbols; offset = kLenNumLowSymbols * 2;
limit = 1 << kLenNumHighBits; limit = 1 << kLenNumHighBits;
} }
} }
@@ -722,7 +805,7 @@ static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inS
{ {
unsigned posSlot; unsigned posSlot;
prob = probs + PosSlot + prob = probs + PosSlot +
((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) << ((len < kNumLenToPosStates - 1 ? len : kNumLenToPosStates - 1) <<
kNumPosSlotBits); kNumPosSlotBits);
TREE_DECODE_CHECK(prob, 1 << kNumPosSlotBits, posSlot); TREE_DECODE_CHECK(prob, 1 << kNumPosSlotBits, posSlot);
if (posSlot >= kStartPosModelIndex) if (posSlot >= kStartPosModelIndex)
@@ -733,7 +816,7 @@ static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inS
if (posSlot < kEndPosModelIndex) if (posSlot < kEndPosModelIndex)
{ {
prob = probs + SpecPos + ((2 | (posSlot & 1)) << numDirectBits) - posSlot - 1; prob = probs + SpecPos + ((2 | (posSlot & 1)) << numDirectBits);
} }
else else
{ {
@@ -745,17 +828,18 @@ static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inS
code -= range & (((code - range) >> 31) - 1); code -= range & (((code - range) >> 31) - 1);
/* if (code >= range) code -= range; */ /* if (code >= range) code -= range; */
} }
while (--numDirectBits != 0); while (--numDirectBits);
prob = probs + Align; prob = probs + Align;
numDirectBits = kNumAlignBits; numDirectBits = kNumAlignBits;
} }
{ {
unsigned i = 1; unsigned i = 1;
unsigned m = 1;
do 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) void LzmaDec_InitDicAndState(CLzmaDec *p, Bool initDic, Bool initState)
{ {
p->needFlush = 1; p->remainLen = kMatchSpecLenStart + 1;
p->remainLen = 0;
p->tempBufSize = 0; p->tempBufSize = 0;
if (initDic) if (initDic)
{ {
p->processedPos = 0; p->processedPos = 0;
p->checkDicSize = 0; p->checkDicSize = 0;
p->needInitState = 1; p->remainLen = kMatchSpecLenStart + 2;
} }
if (initState) if (initState)
p->needInitState = 1; p->remainLen = kMatchSpecLenStart + 2;
} }
void LzmaDec_Init(CLzmaDec *p) void LzmaDec_Init(CLzmaDec *p)
@@ -788,53 +871,54 @@ void LzmaDec_Init(CLzmaDec *p)
LzmaDec_InitDicAndState(p, True, True); 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, SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, const Byte *src, SizeT *srcLen,
ELzmaFinishMode finishMode, ELzmaStatus *status) ELzmaFinishMode finishMode, ELzmaStatus *status)
{ {
SizeT inSize = *srcLen; SizeT inSize = *srcLen;
(*srcLen) = 0; (*srcLen) = 0;
LzmaDec_WriteRem(p, dicLimit);
*status = LZMA_STATUS_NOT_SPECIFIED; *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) 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->dicPos >= dicLimit)
{ {
if (p->remainLen == 0 && p->code == 0) 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; checkEndMarkNow = 1;
} }
if (p->needInitState)
LzmaDec_InitStateReal(p);
if (p->tempBufSize == 0) if (p->tempBufSize == 0)
{ {
SizeT processed; SizeT processed;
@@ -930,11 +1011,14 @@ SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, const Byte *src, SizeT *sr
p->tempBufSize = 0; p->tempBufSize = 0;
} }
} }
if (p->code == 0)
*status = LZMA_STATUS_FINISHED_WITH_MARK; if (p->code != 0)
return (p->code == 0) ? SZ_OK : SZ_ERROR_DATA; 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) SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status)
{ {
SizeT outSize = *destLen; SizeT outSize = *destLen;
@@ -1011,10 +1095,10 @@ SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size)
if (d >= (9 * 5 * 5)) if (d >= (9 * 5 * 5))
return SZ_ERROR_UNSUPPORTED; return SZ_ERROR_UNSUPPORTED;
p->lc = d % 9; p->lc = (Byte)(d % 9);
d /= 9; d /= 9;
p->pb = d / 5; p->pb = (Byte)(d / 5);
p->lp = d % 5; p->lp = (Byte)(d % 5);
return SZ_OK; return SZ_OK;
} }
@@ -1026,9 +1110,10 @@ static SRes LzmaDec_AllocateProbs2(CLzmaDec *p, const CLzmaProps *propNew, ISzAl
{ {
LzmaDec_FreeProbs(p, alloc); LzmaDec_FreeProbs(p, alloc);
p->probs = (CLzmaProb *)ISzAlloc_Alloc(alloc, numProbs * sizeof(CLzmaProb)); p->probs = (CLzmaProb *)ISzAlloc_Alloc(alloc, numProbs * sizeof(CLzmaProb));
p->numProbs = numProbs;
if (!p->probs) if (!p->probs)
return SZ_ERROR_MEM; return SZ_ERROR_MEM;
p->probs_1664 = p->probs + 1664;
p->numProbs = numProbs;
} }
return SZ_OK; return SZ_OK;
} }

View File

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

View File

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

View File

@@ -1,10 +1,10 @@
/* MtCoder.h -- Multi-thread Coder /* MtCoder.h -- Multi-thread Coder
2017-06-18 : Igor Pavlov : Public domain */ 2018-02-21 : Igor Pavlov : Public domain */
#ifndef __MT_CODER_H #ifndef __MT_CODER_H
#define __MT_CODER_H #define __MT_CODER_H
#include "Threads.h" #include "MtDec.h"
EXTERN_C_BEGIN EXTERN_C_BEGIN
@@ -24,33 +24,20 @@ EXTERN_C_BEGIN
#endif #endif
typedef struct #ifndef _7ZIP_ST
{
UInt64 inSize;
UInt64 outSize;
} CMtProgressSizes;
typedef struct
{
ICompressProgress *progress;
SRes res;
UInt64 totalInSize;
UInt64 totalOutSize;
CCriticalSection cs;
CMtProgressSizes sizes[MTCODER__THREADS_MAX];
} CMtProgress;
typedef struct typedef struct
{ {
ICompressProgress vt; ICompressProgress vt;
CMtProgress *mtProgress; CMtProgress *mtProgress;
unsigned index; UInt64 inSize;
UInt64 outSize;
} CMtProgressThunk; } CMtProgressThunk;
void MtProgressThunk_CreateVTable(CMtProgressThunk *p); void MtProgressThunk_CreateVTable(CMtProgressThunk *p);
#define MtProgressThunk_Init(p) { (p)->inSize = 0; (p)->outSize = 0; }
struct _CMtCoder; struct _CMtCoder;
@@ -146,6 +133,9 @@ void MtCoder_Destruct(CMtCoder *p);
SRes MtCoder_Code(CMtCoder *p); SRes MtCoder_Code(CMtCoder *p);
#endif
EXTERN_C_END EXTERN_C_END
#endif #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 /* 7zipUninstall.c - 7-Zip Uninstaller
2017-04-04 : Igor Pavlov : Public domain */ 2018-03-01 : Igor Pavlov : Public domain */
#include "Precomp.h" #include "Precomp.h"
@@ -546,7 +546,7 @@ static BOOL RemoveDir()
#define k_Lang L"Lang" #define k_Lang L"Lang"
// NUM_LANG_TXT_FILES files are placed before en.ttt // 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 #ifdef _64BIT_INSTALLER
#define NUM_EXTRA_FILES_64BIT 1 #define NUM_EXTRA_FILES_64BIT 1
@@ -558,7 +558,7 @@ static BOOL RemoveDir()
static const char * const k_Names = 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" "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" " 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" " 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" " en.ttt"

190
C/Xz.h
View File

@@ -1,5 +1,5 @@
/* Xz.h - Xz interface /* Xz.h - Xz interface
2017-07-27 : Igor Pavlov : Public domain */ 2018-02-28 : Igor Pavlov : Public domain */
#ifndef __XZ_H #ifndef __XZ_H
#define __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_GetNumBlocks(const CXzs *p);
UInt64 Xzs_GetUnpackSize(const CXzs *p); UInt64 Xzs_GetUnpackSize(const CXzs *p);
// ECoderStatus values are identical to ELzmaStatus values of LZMA2 decoder
typedef enum typedef enum
{ {
CODER_STATUS_NOT_SPECIFIED, /* use main error code instead */ 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 */ CODER_STATUS_NEEDS_MORE_INPUT /* you must provide more input bytes */
} ECoderStatus; } ECoderStatus;
// ECoderFinishMode values are identical to ELzmaFinishMode
typedef enum typedef enum
{ {
CODER_FINISH_ANY, /* finish at any point */ CODER_FINISH_ANY, /* finish at any point */
CODER_FINISH_END /* block must be finished at the end */ CODER_FINISH_END /* block must be finished at the end */
} ECoderFinishMode; } ECoderFinishMode;
typedef struct _IStateCoder typedef struct _IStateCoder
{ {
void *p; void *p;
void (*Free)(void *p, ISzAllocPtr alloc); void (*Free)(void *p, ISzAllocPtr alloc);
SRes (*SetProps)(void *p, const Byte *props, size_t propSize, ISzAllocPtr alloc); SRes (*SetProps)(void *p, const Byte *props, size_t propSize, ISzAllocPtr alloc);
void (*Init)(void *p); void (*Init)(void *p);
SRes (*Code)(void *p, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, SRes (*Code2)(void *p, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
int srcWasFinished, ECoderFinishMode finishMode, int *wasFinished); int srcWasFinished, ECoderFinishMode finishMode,
// int *wasFinished,
ECoderStatus *status);
SizeT (*Filter)(void *p, Byte *data, SizeT size);
} IStateCoder; } IStateCoder;
#define MIXCODER_NUM_FILTERS_MAX 4 #define MIXCODER_NUM_FILTERS_MAX 4
typedef struct typedef struct
@@ -170,20 +182,23 @@ typedef struct
ISzAllocPtr alloc; ISzAllocPtr alloc;
Byte *buf; Byte *buf;
unsigned numCoders; 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]; int finished[MIXCODER_NUM_FILTERS_MAX - 1];
size_t pos[MIXCODER_NUM_FILTERS_MAX - 1]; size_t pos[MIXCODER_NUM_FILTERS_MAX - 1];
size_t size[MIXCODER_NUM_FILTERS_MAX - 1]; size_t size[MIXCODER_NUM_FILTERS_MAX - 1];
UInt64 ids[MIXCODER_NUM_FILTERS_MAX]; UInt64 ids[MIXCODER_NUM_FILTERS_MAX];
SRes results[MIXCODER_NUM_FILTERS_MAX];
IStateCoder coders[MIXCODER_NUM_FILTERS_MAX]; IStateCoder coders[MIXCODER_NUM_FILTERS_MAX];
} CMixCoder; } 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 typedef enum
{ {
@@ -197,6 +212,7 @@ typedef enum
XZ_STATE_BLOCK_FOOTER XZ_STATE_BLOCK_FOOTER
} EXzState; } EXzState;
typedef struct typedef struct
{ {
EXzState state; EXzState state;
@@ -210,7 +226,7 @@ typedef struct
UInt64 packSize; UInt64 packSize;
UInt64 unpackSize; UInt64 unpackSize;
UInt64 numBlocks; UInt64 numBlocks; // number of finished blocks in current stream
UInt64 indexSize; UInt64 indexSize;
UInt64 indexPos; UInt64 indexPos;
UInt64 padSize; UInt64 padSize;
@@ -225,16 +241,64 @@ typedef struct
CXzCheck check; CXzCheck check;
CSha256 sha; CSha256 sha;
Bool parseMode;
Bool headerParsedOk;
Bool decodeToStreamSignature;
unsigned decodeOnlyOneBlock; 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 shaDigest[SHA256_DIGEST_SIZE];
Byte buf[XZ_BLOCK_HEADER_SIZE_MAX]; Byte buf[XZ_BLOCK_HEADER_SIZE_MAX];
} CXzUnpacker; } CXzUnpacker;
/* alloc : aligned for cache line allocation is better */
void XzUnpacker_Construct(CXzUnpacker *p, ISzAllocPtr alloc); void XzUnpacker_Construct(CXzUnpacker *p, ISzAllocPtr alloc);
void XzUnpacker_Init(CXzUnpacker *p); void XzUnpacker_Init(CXzUnpacker *p);
void XzUnpacker_SetOutBuf(CXzUnpacker *p, Byte *outBuf, size_t outBufSize);
void XzUnpacker_Free(CXzUnpacker *p); 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: finishMode:
It has meaning only if the decoding reaches output limit (*destLen). 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, SRes XzUnpacker_Code(CXzUnpacker *p, Byte *dest, SizeT *destLen,
const Byte *src, SizeT *srcLen, ECoderFinishMode finishMode, const Byte *src, SizeT *srcLen, int srcFinished,
ECoderStatus *status); 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); Bool XzUnpacker_IsStreamWasFinished(const CXzUnpacker *p);
/* /*
Call XzUnpacker_GetExtraSize after XzUnpacker_Code function to detect real size of XzUnpacker_GetExtraSize() returns then number of uncofirmed bytes,
xz stream in two cases: if it's in (XZ_STATE_STREAM_HEADER) state or in (XZ_STATE_STREAM_PADDING) state.
XzUnpacker_Code() returns: 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_OK && status == CODER_STATUS_NEEDS_MORE_INPUT
res == SZ_ERROR_NO_ARCHIVE 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)) #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 EXTERN_C_END
#endif #endif

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

View File

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

View File

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

View File

@@ -236,8 +236,8 @@ HRESULT CDecoder::Decode(
_7Z_DECODER_CRYPRO_VARS_DECL _7Z_DECODER_CRYPRO_VARS_DECL
#if !defined(_7ZIP_ST) && !defined(_SFX) #if !defined(_7ZIP_ST)
, bool mtMode, UInt32 numThreads , bool mtMode, UInt32 numThreads, UInt64 memUsage
#endif #endif
) )
{ {
@@ -312,7 +312,7 @@ HRESULT CDecoder::Decode(
#endif #endif
CCreatedCoder cod; CCreatedCoder cod;
RINOK(CreateCoder( RINOK(CreateCoder_Id(
EXTERNAL_CODECS_LOC_VARS EXTERNAL_CODECS_LOC_VARS
coderInfo.MethodID, false, cod)); coderInfo.MethodID, false, cod));
@@ -355,11 +355,39 @@ HRESULT CDecoder::Decode(
unsigned i; unsigned i;
bool mt_wasUsed = false;
for (i = 0; i < folderInfo.Coders.Size(); i++) for (i = 0; i < folderInfo.Coders.Size(); i++)
{ {
const CCoderInfo &coderInfo = folderInfo.Coders[i]; const CCoderInfo &coderInfo = folderInfo.Coders[i];
IUnknown *decoder = _mixer->GetCoder(i).GetUnknown(); 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; CMyComPtr<ICompressSetDecoderProperties2> setDecoderProperties;
decoder->QueryInterface(IID_ICompressSetDecoderProperties2, (void **)&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 #ifndef _NO_CRYPTO
{ {
CMyComPtr<ICryptoSetPassword> cryptoSetPassword; CMyComPtr<ICryptoSetPassword> cryptoSetPassword;

View File

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

View File

@@ -154,9 +154,18 @@ HRESULT CEncoder::CreateMixerCoder(
CCreatedCoder cod; 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 EXTERNAL_CODECS_LOC_VARS
methodFull.Id, true, cod)); methodFull.Id, true, cod));
}
if (cod.NumStreams != methodFull.NumStreams) if (cod.NumStreams != methodFull.NumStreams)
return E_FAIL; return E_FAIL;

View File

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

View File

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

View File

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

View File

@@ -13,6 +13,8 @@
#include "7zOut.h" #include "7zOut.h"
#include "7zUpdate.h" #include "7zUpdate.h"
#ifndef EXTRACT_ONLY
using namespace NWindows; using namespace NWindows;
namespace NArchive { namespace NArchive {
@@ -41,9 +43,11 @@ STDMETHODIMP CHandler::GetFileTimeType(UInt32 *type)
HRESULT CHandler::PropsMethod_To_FullMethod(CMethodFull &dest, const COneMethodInfo &m) HRESULT CHandler::PropsMethod_To_FullMethod(CMethodFull &dest, const COneMethodInfo &m)
{ {
if (!FindMethod( dest.CodecIndex = FindMethod_Index(
EXTERNAL_CODECS_VARS EXTERNAL_CODECS_VARS
m.MethodName, dest.Id, dest.NumStreams)) m.MethodName, true,
dest.Id, dest.NumStreams);
if (dest.CodecIndex < 0)
return E_INVALIDARG; return E_INVALIDARG;
(CProps &)dest = (CProps &)m; (CProps &)dest = (CProps &)m;
return S_OK; return S_OK;
@@ -699,10 +703,8 @@ static HRESULT ParseBond(UString &srcString, UInt32 &coder, UInt32 &stream)
return S_OK; return S_OK;
} }
void COutHandler::InitProps() void COutHandler::InitProps7z()
{ {
CMultiMethodProps::Init();
_removeSfxBlock = false; _removeSfxBlock = false;
_compressHeaders = true; _compressHeaders = true;
_encryptHeadersSpecified = false; _encryptHeadersSpecified = false;
@@ -722,6 +724,14 @@ void COutHandler::InitProps()
_useTypeSorting = false; _useTypeSorting = false;
} }
void COutHandler::InitProps()
{
CMultiMethodProps::Init();
InitProps7z();
}
HRESULT COutHandler::SetSolidFromString(const UString &s) HRESULT COutHandler::SetSolidFromString(const UString &s)
{ {
UString s2 = s; UString s2 = s;
@@ -762,6 +772,10 @@ HRESULT COutHandler::SetSolidFromString(const UString &s)
} }
_numSolidBytes = (v << numBits); _numSolidBytes = (v << numBits);
_numSolidBytesDefined = true; _numSolidBytesDefined = true;
/*
if (_numSolidBytes == 0)
_numSolidFiles = 1;
*/
} }
} }
return S_OK; return S_OK;
@@ -810,7 +824,7 @@ HRESULT COutHandler::SetProperty(const wchar_t *nameSpec, const PROPVARIANT &val
return E_INVALIDARG; return E_INVALIDARG;
return SetSolidFromString(name); return SetSolidFromString(name);
} }
UInt32 number; UInt32 number;
int index = ParseStringToUInt32(name, number); int index = ParseStringToUInt32(name, number);
// UString realName = name.Ptr(index); // UString realName = name.Ptr(index);
@@ -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 , dataAfterEnd_Error
_7Z_DECODER_CRYPRO_VARS _7Z_DECODER_CRYPRO_VARS
#if !defined(_7ZIP_ST) && !defined(_SFX) #if !defined(_7ZIP_ST)
, false // mtMode , false // mtMode
, 1 // numThreads , 1 // numThreads
, 0 // memUsage
#endif #endif
); );
RINOK(result); RINOK(result);

View File

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

View File

@@ -2,18 +2,92 @@
#include "StdAfx.h" #include "StdAfx.h"
#ifndef _7ZIP_ST #include "../../../Common/StringToInt.h"
#include "../../../Windows/System.h"
#endif
#include "../Common/ParseProperties.h" #include "../Common/ParseProperties.h"
#include "HandlerOut.h" #include "HandlerOut.h"
using namespace NWindows;
namespace NArchive { 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) static void SetMethodProp32(COneMethodInfo &m, PROPID propID, UInt32 value)
{ {
if (m.FindProp(propID) < 0) if (m.FindProp(propID) < 0)
@@ -34,21 +108,23 @@ void CMultiMethodProps::SetMethodThreadsTo(COneMethodInfo &oneMethodInfo, UInt32
} }
#endif #endif
void CMultiMethodProps::Init() void CMultiMethodProps::InitMulti()
{ {
#ifndef _7ZIP_ST
_numProcessors = _numThreads = NSystem::GetNumberOfProcessors();
#endif
_level = (UInt32)(Int32)-1; _level = (UInt32)(Int32)-1;
_analysisLevel = -1; _analysisLevel = -1;
_autoFilter = true;
_crcSize = 4; _crcSize = 4;
_filterMethod.Clear(); _autoFilter = true;
_methods.Clear();
} }
void CMultiMethodProps::Init()
{
InitCommon();
InitMulti();
_methods.Clear();
_filterMethod.Clear();
}
HRESULT CMultiMethodProps::SetProperty(const wchar_t *nameSpec, const PROPVARIANT &value) HRESULT CMultiMethodProps::SetProperty(const wchar_t *nameSpec, const PROPVARIANT &value)
{ {
UString name = nameSpec; UString name = nameSpec;
@@ -78,20 +154,18 @@ HRESULT CMultiMethodProps::SetProperty(const wchar_t *nameSpec, const PROPVARIAN
_crcSize = 4; _crcSize = 4;
return ParsePropToUInt32(name, value, _crcSize); return ParsePropToUInt32(name, value, _crcSize);
} }
{
HRESULT hres;
if (SetCommonProperty(name, value, hres))
return hres;
}
UInt32 number; UInt32 number;
unsigned index = ParseStringToUInt32(name, number); unsigned index = ParseStringToUInt32(name, number);
UString realName = name.Ptr(index); UString realName = name.Ptr(index);
if (index == 0) 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")) if (name.IsEqualTo("f"))
{ {
HRESULT res = PROPVARIANT_to_bool(value, _autoFilter); 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); return _methods[number].ParseMethodFromPROPVARIANT(realName, value);
} }
void CSingleMethodProps::Init() void CSingleMethodProps::Init()
{ {
InitCommon();
InitSingle();
Clear(); 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) HRESULT CSingleMethodProps::SetProperties(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps)
{ {
Init(); Init();
for (UInt32 i = 0; i < numProps; i++) for (UInt32 i = 0; i < numProps; i++)
{ {
UString name = names[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)); RINOK(ParsePropToUInt32(name.Ptr(1), value, a));
_level = a; _level = a;
AddProp_Level(a); AddProp_Level(a);
continue;
} }
else if (name.IsPrefixedBy_Ascii_NoCase("mt"))
{ {
#ifndef _7ZIP_ST HRESULT hres;
RINOK(ParseMtProp(name.Ptr(2), value, _numProcessors, _numThreads)); if (SetCommonProperty(name, value, hres))
AddProp_NumThreads(_numThreads); {
#endif RINOK(hres)
} continue;
else }
{
RINOK(ParseMethodFromPROPVARIANT(names[i], value));
} }
RINOK(ParseMethodFromPROPVARIANT(names[i], value));
} }
return S_OK; return S_OK;
} }
#endif
} }

View File

@@ -3,20 +3,57 @@
#ifndef __HANDLER_OUT_H #ifndef __HANDLER_OUT_H
#define __HANDLER_OUT_H #define __HANDLER_OUT_H
#include "../../../Windows/System.h"
#include "../../Common/MethodProps.h" #include "../../Common/MethodProps.h"
namespace NArchive { namespace NArchive {
class CMultiMethodProps bool ParseSizeString(const wchar_t *name, const PROPVARIANT &prop, UInt64 percentsBase, UInt64 &res);
class CCommonMethodProps
{ {
UInt32 _level; protected:
int _analysisLevel; 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: public:
#ifndef _7ZIP_ST #ifndef _7ZIP_ST
UInt32 _numThreads; UInt32 _numThreads;
UInt32 _numProcessors; UInt32 _numProcessors;
#endif #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; UInt32 _crcSize;
CObjectVector<COneMethodInfo> _methods; CObjectVector<COneMethodInfo> _methods;
COneMethodInfo _filterMethod; COneMethodInfo _filterMethod;
@@ -43,27 +80,31 @@ public:
int GetAnalysisLevel() const { return _analysisLevel; } int GetAnalysisLevel() const { return _analysisLevel; }
void Init(); void Init();
CMultiMethodProps() { InitMulti(); }
CMultiMethodProps() { Init(); }
HRESULT SetProperty(const wchar_t *name, const PROPVARIANT &value); HRESULT SetProperty(const wchar_t *name, const PROPVARIANT &value);
}; };
class CSingleMethodProps: public COneMethodInfo
class CSingleMethodProps: public COneMethodInfo, public CCommonMethodProps
{ {
UInt32 _level; UInt32 _level;
public:
#ifndef _7ZIP_ST
UInt32 _numThreads;
UInt32 _numProcessors;
#endif
void InitSingle()
{
_level = (UInt32)(Int32)-1;
}
public:
void Init(); void Init();
CSingleMethodProps() { Init(); } CSingleMethodProps() { InitSingle(); }
int GetLevel() const { return _level == (UInt32)(Int32)-1 ? 5 : (int)_level; } int GetLevel() const { return _level == (UInt32)(Int32)-1 ? 5 : (int)_level; }
HRESULT SetProperties(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps); HRESULT SetProperties(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps);
}; };
#endif
} }
#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) ARCHIVE_INTERFACE(ISetProperties, 0x03)
{ {
STDMETHOD(SetProperties)(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps) PURE; 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) if (!lzCoder)
{ {
const UInt32 methodID = 0x40305; 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) if (!lzCoder)
return E_NOTIMPL; return E_NOTIMPL;
} }

View File

@@ -1691,7 +1691,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
methodID += 2; methodID += 2;
else else
methodID += 3; 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) if (mi.Coder == 0)

View File

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

View File

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

View File

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

View File

@@ -112,7 +112,8 @@ static const CUInt32PCharPair g_HeaderCharacts[] =
{ 3, "Descriptor" }, { 3, "Descriptor" },
// { 5, "Patched" }, // { 5, "Patched" },
{ 6, kMethod_StrongCrypto }, { 6, kMethod_StrongCrypto },
{ 11, "UTF8" } { 11, "UTF8" },
{ 14, "Alt" }
}; };
struct CIdToNamePair struct CIdToNamePair
@@ -169,6 +170,7 @@ static const Byte kProps[] =
kpidUnpackVer, kpidUnpackVer,
kpidVolumeIndex, kpidVolumeIndex,
kpidOffset kpidOffset
// kpidIsAltStream
}; };
static const Byte kArcProps[] = static const Byte kArcProps[] =
@@ -307,6 +309,8 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
prop = true; prop = true;
break; break;
} }
// case kpidIsAltStream: prop = true; break;
} }
prop.Detach(value); prop.Detach(value);
COM_TRY_END COM_TRY_END
@@ -333,6 +337,21 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
UString res; UString res;
item.GetUnicodeString(res, item.Name, false, _forceCodePage, _specifiedCodePage); item.GetUnicodeString(res, item.Name, false, _forceCodePage, _specifiedCodePage);
NItemName::ReplaceToOsSlashes_Remove_TailSlash(res); 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; prop = res;
break; break;
} }
@@ -596,6 +615,19 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
case kpidOffset: case kpidOffset:
prop = item.LocalHeaderPos; prop = item.LocalHeaderPos;
break; 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); 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, STDMETHODIMP CHandler::Open(IInStream *inStream,
const UInt64 *maxCheckStartPosition, IArchiveOpenCallback *callback) const UInt64 *maxCheckStartPosition, IArchiveOpenCallback *callback)
{ {
@@ -617,6 +728,7 @@ STDMETHODIMP CHandler::Open(IInStream *inStream,
m_Items.Clear(); m_Items.Clear();
m_Archive.ClearRefs(); // we don't want to clear error flags m_Archive.ClearRefs(); // we don't want to clear error flags
} }
// MarkAltStreams(m_Items);
return res; return res;
} }
catch(...) { Close(); throw; } catch(...) { Close(); throw; }
@@ -738,7 +850,7 @@ public:
IArchiveExtractCallback *extractCallback, IArchiveExtractCallback *extractCallback,
ICompressProgressInfo *compressProgress, ICompressProgressInfo *compressProgress,
#ifndef _7ZIP_ST #ifndef _7ZIP_ST
UInt32 numThreads, UInt32 numThreads, UInt64 memUsage,
#endif #endif
Int32 &res); Int32 &res);
}; };
@@ -767,7 +879,7 @@ HRESULT CZipDecoder::Decode(
IArchiveExtractCallback *extractCallback, IArchiveExtractCallback *extractCallback,
ICompressProgressInfo *compressProgress, ICompressProgressInfo *compressProgress,
#ifndef _7ZIP_ST #ifndef _7ZIP_ST
UInt32 numThreads, UInt32 numThreads, UInt64 memUsage,
#endif #endif
Int32 &res) Int32 &res)
{ {
@@ -962,7 +1074,7 @@ HRESULT CZipDecoder::Decode(
szMethodID = kMethodId_ZipBase + (Byte)id; 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) if (!mi.Coder)
{ {
@@ -974,16 +1086,7 @@ HRESULT CZipDecoder::Decode(
} }
ICompressCoder *coder = methodItems[m].Coder; 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 #ifndef _7ZIP_ST
{ {
@@ -994,7 +1097,27 @@ HRESULT CZipDecoder::Decode(
RINOK(setCoderMt->SetNumberOfThreads(numThreads)); RINOK(setCoderMt->SetNumberOfThreads(numThreads));
} }
} }
// if (memUsage != 0)
{
CMyComPtr<ICompressSetMemLimit> setMemLimit;
coder->QueryInterface(IID_ICompressSetMemLimit, (void **)&setMemLimit);
if (setMemLimit)
{
RINOK(setMemLimit->SetMemLimit(memUsage));
}
}
#endif #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; CMyComPtr<ISequentialInStream> inStreamNew;
@@ -1319,7 +1442,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
m_Archive, item, realOutStream, extractCallback, m_Archive, item, realOutStream, extractCallback,
progress, progress,
#ifndef _7ZIP_ST #ifndef _7ZIP_ST
_props._numThreads, _props._numThreads, _props._memUsage,
#endif #endif
res); res);

View File

@@ -25,6 +25,7 @@ extern const char * const kMethodNames2[kNumMethodNames2];
class CHandler: class CHandler:
public IInArchive, public IInArchive,
// public IArchiveGetRawProps,
public IOutArchive, public IOutArchive,
public ISetProperties, public ISetProperties,
PUBLIC_ISetCompressCodecsInfo PUBLIC_ISetCompressCodecsInfo
@@ -32,6 +33,7 @@ class CHandler:
{ {
public: public:
MY_QUERYINTERFACE_BEGIN2(IInArchive) MY_QUERYINTERFACE_BEGIN2(IInArchive)
// MY_QUERYINTERFACE_ENTRY(IArchiveGetRawProps)
MY_QUERYINTERFACE_ENTRY(IOutArchive) MY_QUERYINTERFACE_ENTRY(IOutArchive)
MY_QUERYINTERFACE_ENTRY(ISetProperties) MY_QUERYINTERFACE_ENTRY(ISetProperties)
QUERY_ENTRY_ISetCompressCodecsInfo QUERY_ENTRY_ISetCompressCodecsInfo
@@ -39,6 +41,7 @@ public:
MY_ADDREF_RELEASE MY_ADDREF_RELEASE
INTERFACE_IInArchive(;) INTERFACE_IInArchive(;)
// INTERFACE_IArchiveGetRawProps(;)
INTERFACE_IOutArchive(;) INTERFACE_IOutArchive(;)
STDMETHOD(SetProperties)(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps); STDMETHOD(SetProperties)(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps);
@@ -75,6 +78,10 @@ private:
_forceCodePage = false; _forceCodePage = false;
_specifiedCodePage = CP_OEMCP; _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; CMethodId methodId;
UInt32 numStreams; UInt32 numStreams;
if (!FindMethod(EXTERNAL_CODECS_VARS methodName, methodId, numStreams)) if (FindMethod_Index(EXTERNAL_CODECS_VARS methodName, true,
methodId, numStreams) < 0)
return E_NOTIMPL; return E_NOTIMPL;
if (numStreams != 1) if (numStreams != 1)
return E_NOTIMPL; return E_NOTIMPL;

View File

@@ -2632,6 +2632,34 @@ SOURCE=..\..\..\..\C\Lzma2Dec.h
# End Source File # End Source File
# Begin 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 SOURCE=..\..\..\..\C\Lzma2Enc.c
!IF "$(CFG)" == "Alone - Win32 Release" !IF "$(CFG)" == "Alone - Win32 Release"
@@ -2744,6 +2772,34 @@ SOURCE=..\..\..\..\C\MtCoder.h
# End Source File # End Source File
# Begin 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 SOURCE=..\..\..\..\C\Ppmd.h
# End Source File # End Source File
# Begin Source File # Begin Source File

View File

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

View File

@@ -1696,6 +1696,34 @@ SOURCE=..\..\..\..\C\Lzma2Dec.h
# End Source File # End Source File
# Begin 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 SOURCE=..\..\..\..\C\Lzma2Enc.c
!IF "$(CFG)" == "Alone - Win32 Release" !IF "$(CFG)" == "Alone - Win32 Release"
@@ -1789,6 +1817,34 @@ SOURCE=..\..\..\..\C\MtCoder.h
# End Source File # End Source File
# Begin 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 SOURCE=..\..\..\..\C\Threads.c
# SUBTRACT CPP /YX /Yc /Yu # SUBTRACT CPP /YX /Yc /Yu
# End Source File # End Source File

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -1805,6 +1805,26 @@ SOURCE=..\..\..\..\C\Lzma2Dec.h
# End Source File # End Source File
# Begin 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 SOURCE=..\..\..\..\C\Lzma2Enc.c
!IF "$(CFG)" == "7z - Win32 Release" !IF "$(CFG)" == "7z - Win32 Release"
@@ -1874,6 +1894,26 @@ SOURCE=..\..\..\..\C\MtCoder.h
# End Source File # End Source File
# Begin 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 SOURCE=..\..\..\..\C\Ppmd.h
# End Source File # End Source File
# Begin Source File # Begin Source File

View File

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

View File

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

View File

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

View File

@@ -449,6 +449,14 @@ SOURCE=..\..\..\Windows\Synchronization.h
# End Source File # End Source File
# Begin 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 SOURCE=..\..\..\Windows\Window.cpp
# End Source File # End Source File
# Begin Source File # Begin Source File
@@ -469,6 +477,14 @@ SOURCE=..\..\Common\CreateCoder.h
# End Source File # End Source File
# Begin 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 SOURCE=..\..\Common\FileStreams.cpp
# End Source File # End Source File
# Begin Source File # Begin Source File
@@ -724,6 +740,15 @@ SOURCE=..\..\..\..\C\Lzma2Dec.h
# End Source File # End Source File
# Begin 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 SOURCE=..\..\..\..\C\LzmaDec.c
# SUBTRACT CPP /YX /Yc /Yu # SUBTRACT CPP /YX /Yc /Yu
# End Source File # End Source File
@@ -733,6 +758,15 @@ SOURCE=..\..\..\..\C\LzmaDec.h
# End Source File # End Source File
# Begin 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 SOURCE=..\..\..\..\C\Threads.c
# SUBTRACT CPP /YX /Yc /Yu # SUBTRACT CPP /YX /Yc /Yu
# End Source File # End Source File

View File

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

View File

@@ -633,6 +633,14 @@ SOURCE=..\..\..\Windows\Synchronization.h
# End Source File # End Source File
# Begin 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 SOURCE=..\..\..\Windows\Window.cpp
# End Source File # End Source File
# Begin Source File # Begin Source File
@@ -906,6 +914,15 @@ SOURCE=..\..\..\..\C\Lzma2Dec.h
# End Source File # End Source File
# Begin 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 SOURCE=..\..\..\..\C\LzmaDec.c
# SUBTRACT CPP /YX /Yc /Yu # SUBTRACT CPP /YX /Yc /Yu
# End Source File # End Source File
@@ -915,6 +932,15 @@ SOURCE=..\..\..\..\C\LzmaDec.h
# End Source File # End Source File
# Begin 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 SOURCE=..\..\..\..\C\Ppmd7.c
# SUBTRACT CPP /YX /Yc /Yu # SUBTRACT CPP /YX /Yc /Yu
# End Source File # End Source File

View File

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

View File

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

View File

@@ -116,13 +116,12 @@ extern CExternalCodecs g_ExternalCodecs;
#endif #endif
int FindMethod_Index(
bool FindMethod(
DECL_EXTERNAL_CODECS_LOC_VARS DECL_EXTERNAL_CODECS_LOC_VARS
const AString &name, const AString &name,
CMethodId &methodId, UInt32 &numStreams); bool encode,
CMethodId &methodId,
UInt32 &numStreams);
bool FindMethod( bool FindMethod(
DECL_EXTERNAL_CODECS_LOC_VARS 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 DECL_EXTERNAL_CODECS_LOC_VARS
CMethodId methodId, bool encode, CMethodId methodId, bool encode,
CMyComPtr<ICompressFilter> &filter, CMyComPtr<ICompressFilter> &filter,
CCreatedCoder &cod); CCreatedCoder &cod);
HRESULT CreateCoder( HRESULT CreateCoder_Id(
DECL_EXTERNAL_CODECS_LOC_VARS DECL_EXTERNAL_CODECS_LOC_VARS
CMethodId methodId, bool encode, CMethodId methodId, bool encode,
CCreatedCoder &cod); CCreatedCoder &cod);
HRESULT CreateCoder( HRESULT CreateCoder_Id(
DECL_EXTERNAL_CODECS_LOC_VARS DECL_EXTERNAL_CODECS_LOC_VARS
CMethodId methodId, bool encode, CMethodId methodId, bool encode,
CMyComPtr<ICompressCoder> &coder); CMyComPtr<ICompressCoder> &coder);

View File

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

View File

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

View File

@@ -2,81 +2,48 @@
#include "StdAfx.h" #include "StdAfx.h"
// #include <stdio.h>
#include "../../../C/Alloc.h" #include "../../../C/Alloc.h"
// #include "../../../C/CpuTicks.h"
#include "../Common/StreamUtils.h" #include "../Common/StreamUtils.h"
#include "Lzma2Decoder.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 NCompress {
namespace NLzma2 { namespace NLzma2 {
CDecoder::CDecoder(): CDecoder::CDecoder():
_inBuf(NULL), _dec(NULL)
_finishMode(false), , _inProcessed(0)
_outSizeDefined(false), , _prop(0xFF)
_outStep(1 << 22), , _finishMode(false)
_inBufSize(0), , _inBufSize(1 << 20)
_inBufSizeNew(1 << 20) , _outStep(1 << 20)
{ #ifndef _7ZIP_ST
Lzma2Dec_Construct(&_state); , _tryMt(1)
} , _numThreads(1)
, _memUsage((UInt64)(sizeof(size_t)) << 28)
#endif
{}
CDecoder::~CDecoder() CDecoder::~CDecoder()
{ {
Lzma2Dec_Free(&_state, &g_Alloc); if (_dec)
MidFree(_inBuf); 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::SetOutBufSize(UInt32 , UInt32 size) { _outStep = size; return S_OK; }
STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *prop, UInt32 size) STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *prop, UInt32 size)
{ {
if (size != 1) if (size != 1)
return E_NOTIMPL; return E_NOTIMPL;
if (prop[0] > 40)
RINOK(SResToHRESULT(Lzma2Dec_Allocate(&_state, prop[0], &g_Alloc))); return E_NOTIMPL;
_prop = prop[0];
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);
return S_OK; 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) STDMETHODIMP CDecoder::GetInStreamProcessedSize(UInt64 *value)
{ {
*value = _inProcessed; *value = _inProcessed;
@@ -95,109 +193,51 @@ STDMETHODIMP CDecoder::GetInStreamProcessedSize(UInt64 *value)
} }
STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, #ifndef _7ZIP_ST
const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress)
STDMETHODIMP CDecoder::SetNumberOfThreads(UInt32 numThreads)
{ {
if (!_inBuf) _numThreads = numThreads;
return S_FALSE; return S_OK;
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));
}
}
} }
STDMETHODIMP CDecoder::SetMemLimit(UInt64 memUsage)
{
_memUsage = memUsage;
return S_OK;
}
#endif
#ifndef NO_READ_FROM_CODER #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::SetInStream(ISequentialInStream *inStream) { _inStream = inStream; return S_OK; }
STDMETHODIMP CDecoder::ReleaseInStream() { _inStream.Release(); 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) if (processedSize)
*processedSize = 0; *processedSize = 0;
ELzmaFinishMode finishMode = LZMA_FINISH_ANY; size_t size2 = size;
if (_outSizeDefined) UInt64 inProcessed = 0;
{
const UInt64 rem = _outSize - _outProcessed;
if (size >= rem)
{
size = (UInt32)rem;
if (_finishMode)
finishMode = LZMA_FINISH_END;
}
}
HRESULT readRes = S_OK; SRes res = Lzma2DecMt_Read(_dec, (Byte *)data, &size2, &inProcessed);
for (;;) _inProcessed += inProcessed;
{ if (processedSize)
if (_inPos == _inLim && readRes == S_OK) *processedSize = (UInt32)size2;
{ if (res != SZ_OK)
_inPos = _inLim = 0; return SResToHRESULT(res);
readRes = _inStream->Read(_inBuf, _inBufSize, &_inLim); return S_OK;
}
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;
}
} }
#endif #endif

View File

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

View File

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

View File

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

View File

@@ -4,248 +4,119 @@
#include "../../../C/Alloc.h" #include "../../../C/Alloc.h"
#include "../Common/StreamUtils.h" #include "../Common/CWrappers.h"
#include "../Archive/IArchive.h"
#include "XzDecoder.h" #include "XzDecoder.h"
using namespace NArchive;
namespace NCompress { namespace NCompress {
namespace NXz { 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); if (res < 0)
} return res;
switch (res)
CXzUnpackerCPP::~CXzUnpackerCPP() {
{ case SZ_OK: return S_OK;
XzUnpacker_Free(&p); case SZ_ERROR_MEM: return E_OUTOFMEMORY;
MidFree(InBuf); case SZ_ERROR_UNSUPPORTED: return E_NOTIMPL;
MidFree(OutBuf); }
} return S_FALSE;
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;
} }
HRESULT CDecoder::Decode(ISequentialInStream *seqInStream, ISequentialOutStream *outStream, HRESULT CDecoder::Decode(ISequentialInStream *seqInStream, ISequentialOutStream *outStream,
const UInt64 *outSizeLimit, bool finishStream, ICompressProgressInfo *progress) const UInt64 *outSizeLimit, bool finishStream, ICompressProgressInfo *progress)
{ {
const size_t kInBufSize = (size_t)1 << 20; MainDecodeSRes = S_OK;
const size_t kOutBufSize = (size_t)1 << 21; MainDecodeSRes_wasUsed = false;
XzStatInfo_Clear(&Stat);
Clear(); if (!xz)
DecodeRes = SZ_OK;
XzUnpacker_Init(&xzu.p);
if (!xzu.InBuf)
{ {
xzu.InBuf = (Byte *)MidAlloc(kInBufSize); xz = XzDecMt_Create(&g_Alloc, &g_MidAlloc);
if (!xzu.InBuf) if (!xz)
return E_OUTOFMEMORY; return E_OUTOFMEMORY;
} }
if (!xzu.OutBuf)
{
xzu.OutBuf = (Byte *)MidAlloc(kOutBufSize);
if (!xzu.OutBuf)
return E_OUTOFMEMORY;
}
UInt32 inSize = 0;
UInt32 inPos = 0;
SizeT outPos = 0;
HRESULT readRes = S_OK; CXzDecMtProps props;
XzDecMtProps_Init(&props);
for (;;) int isMT = False;
#ifndef _7ZIP_ST
{ {
if (inPos == inSize && readRes == S_OK) props.numThreads = 1;
UInt32 numThreads = _numThreads;
if (_tryMt && numThreads > 1)
{ {
inPos = inSize = 0; size_t memUsage = (size_t)_memUsage;
readRes = seqInStream->Read(xzu.InBuf, kInBufSize, &inSize); if (memUsage != _memUsage)
memUsage = (size_t)0 - 1;
props.memUseMax = memUsage;
isMT = (numThreads > 1);
} }
SizeT inLen = inSize - inPos; props.numThreads = numThreads;
SizeT outLen = kOutBufSize - outPos; }
ECoderFinishMode finishMode = CODER_FINISH_ANY; #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 && *inSize != Stat.PhySize)
if (inSize == 0) res = SZ_ERROR_DATA;
finishMode = CODER_FINISH_END;
*/ */
if (outSizeLimit && *outSizeLimit != outWrap.Processed)
if (outSizeLimit) res = SZ_ERROR_DATA;
{
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;
}
} }
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, HRESULT CComDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream,
const UInt64 * /* inSize */, const UInt64 *outSize, ICompressProgressInfo *progress) const UInt64 * /* inSize */, const UInt64 *outSize, ICompressProgressInfo *progress)
{ {
RINOK(_decoder.Decode(inStream, outStream, outSize, _finishStream, progress)); return 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;
} }
STDMETHODIMP CComDecoder::SetFinishMode(UInt32 finishMode) STDMETHODIMP CComDecoder::SetFinishMode(UInt32 finishMode)
@@ -256,8 +127,24 @@ STDMETHODIMP CComDecoder::SetFinishMode(UInt32 finishMode)
STDMETHODIMP CComDecoder::GetInStreamProcessedSize(UInt64 *value) STDMETHODIMP CComDecoder::GetInStreamProcessedSize(UInt64 *value)
{ {
*value = _decoder.InSize; *value = Stat.InSize;
return S_OK; 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 NCompress {
namespace NXz { namespace NXz {
struct CXzUnpackerCPP struct CDecoder
{ {
Byte *InBuf; CXzDecMtHandle xz;
Byte *OutBuf; int _tryMt;
CXzUnpacker p; UInt32 _numThreads;
UInt64 _memUsage;
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)
{}
CXzUnpackerCPP(); ~CDecoder()
~CXzUnpackerCPP(); {
}; if (xz)
XzDecMt_Destroy(xz);
}
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) {}
/* Decode() can return ERROR code only if there is progress or stream error. /* 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 */ Decode() returns S_OK in case of xz decoding error, but DecodeRes and CStatInfo contain error information */
HRESULT Decode(ISequentialInStream *seqInStream, ISequentialOutStream *outStream, HRESULT Decode(ISequentialInStream *seqInStream, ISequentialOutStream *outStream,
const UInt64 *outSizeLimit, bool finishStream, ICompressProgressInfo *compressProgress); const UInt64 *outSizeLimit, bool finishStream, ICompressProgressInfo *compressProgress);
Int32 Get_Extract_OperationResult() const;
}; };
@@ -70,21 +49,41 @@ class CComDecoder:
public ICompressCoder, public ICompressCoder,
public ICompressSetFinishMode, public ICompressSetFinishMode,
public ICompressGetInStreamProcessedSize, public ICompressGetInStreamProcessedSize,
public CMyUnknownImp
#ifndef _7ZIP_ST
public ICompressSetCoderMt,
public ICompressSetMemLimit,
#endif
public CMyUnknownImp,
public CDecoder
{ {
CDecoder _decoder;
bool _finishStream; bool _finishStream;
public: public:
MY_UNKNOWN_IMP2( MY_QUERYINTERFACE_BEGIN2(ICompressCoder)
ICompressSetFinishMode,
ICompressGetInStreamProcessedSize) 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, STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream,
const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress);
STDMETHOD(SetFinishMode)(UInt32 finishMode); STDMETHOD(SetFinishMode)(UInt32 finishMode);
STDMETHOD(GetInStreamProcessedSize)(UInt64 *value); STDMETHOD(GetInStreamProcessedSize)(UInt64 *value);
#ifndef _7ZIP_ST
STDMETHOD(SetNumberOfThreads)(UInt32 numThreads);
STDMETHOD(SetMemLimit)(UInt64 memUsage);
#endif
CComDecoder(): _finishStream(false) {} CComDecoder(): _finishStream(false) {}
}; };

View File

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

View File

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

@@ -253,8 +253,8 @@ public:
IInArchive *GetArchive() const { if ( _archiveLink.Arcs.IsEmpty()) return 0; return GetArc().Archive; } IInArchive *GetArchive() const { if ( _archiveLink.Arcs.IsEmpty()) return 0; return GetArc().Archive; }
bool CanUpdate() const; bool CanUpdate() const;
bool Is_Attrib_ReadOnly() const bool Is_Attrib_ReadOnly() const
{ {
return _attrib != INVALID_FILE_ATTRIBUTES && (_attrib & FILE_ATTRIBUTE_READONLY); return _attrib != INVALID_FILE_ATTRIBUTES && (_attrib & FILE_ATTRIBUTE_READONLY);
} }

View File

@@ -1183,9 +1183,11 @@ static HRESULT MethodBench(
COneMethodInfo method = method2; COneMethodInfo method = method2;
UInt64 methodId; UInt64 methodId;
UInt32 numStreams; UInt32 numStreams;
if (!FindMethod( int codecIndex = FindMethod_Index(
EXTERNAL_CODECS_LOC_VARS EXTERNAL_CODECS_LOC_VARS
method.MethodName, methodId, numStreams)) method.MethodName, true,
methodId, numStreams);
if (codecIndex < 0)
return E_NOTIMPL; return E_NOTIMPL;
if (numStreams != 1) if (numStreams != 1)
return E_INVALIDARG; return E_INVALIDARG;
@@ -1222,7 +1224,7 @@ static HRESULT MethodBench(
{ {
CCreatedCoder cod; 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; encoder._encoder = cod.Coder;
if (!encoder._encoder && !encoder._encoderFilter) if (!encoder._encoder && !encoder._encoderFilter)
return E_NOTIMPL; return E_NOTIMPL;
@@ -1239,7 +1241,7 @@ static HRESULT MethodBench(
{ {
CCreatedCoder cod; CCreatedCoder cod;
CMyComPtr<ICompressCoder> &decoder = encoder._decoders[j]; 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; decoder = cod.Coder;
if (!encoder._decoderFilter && !decoder) if (!encoder._decoderFilter && !decoder)
return E_NOTIMPL; 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) -Yu"StdAfx.h" -Fp$O/a.pch $<
COMPLB_O2 = $(CC) $(CFLAGS_O2) $< COMPLB_O2 = $(CC) $(CFLAGS_O2) $<
CCOMPL_PCH = $(CC) $(CFLAGS_O2) -Yc"Precomp.h" -Fp$O/a.pch $** CFLAGS_C_ALL = $(CFLAGS_O2) $(CFLAGS_C_SPEC)
CCOMPL_USE = $(CC) $(CFLAGS_O2) -Yu"Precomp.h" -Fp$O/a.pch $** CCOMPL_PCH = $(CC) $(CFLAGS_C_ALL) -Yc"Precomp.h" -Fp$O/a.pch $**
CCOMPL = $(CC) $(CFLAGS_O2) $** CCOMPL_USE = $(CC) $(CFLAGS_C_ALL) -Yu"Precomp.h" -Fp$O/a.pch $**
CCOMPLB = $(CC) $(CFLAGS_O2) $< CCOMPL = $(CC) $(CFLAGS_C_ALL) $**
CCOMPLB = $(CC) $(CFLAGS_C_ALL) $<
all: $(PROGPATH) all: $(PROGPATH)

View File

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

View File

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

View File

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

View File

@@ -1,6 +1,17 @@
HISTORY of the 7-Zip source code 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 17.00 beta 2017-04-29
------------------------- -------------------------
- NewHandler.h / NewHandler.cpp: - NewHandler.h / NewHandler.cpp: